static void *open_cdf_read(const char *filename, const char *filetype, 
                           int *natoms) {
  int ncid, rc;
  size_t len;
  cdfdata *cdf;
 
  rc = nc_open(filename, NC_NOWRITE, &ncid);
  if (rc != NC_NOERR) return NULL;

  cdf = (cdfdata *) malloc(sizeof(cdfdata));
  memset(cdf, 0, sizeof(cdfdata));

  cdf->ncid = ncid;
  cdf->type = CDF_TYPE_UNKNOWN;

  /* Determine what NetCDF conventions apply to this data, if any */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "Conventions", &len);
  if (rc == NC_NOERR && len > 0) {
    cdf->conventions = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "Conventions", cdf->conventions);
    cdf->conventions[len] = '\0';
    printf("netcdfplugin) conventions: '%s'\n", cdf->conventions);
  } 

  if (cdf->conventions != NULL) {
    /* Check if this is a file generated by AMBER */
    if (strstr(cdf->conventions, "AMBER") != NULL) {
      if (!open_amber_cdf_read(cdf)) {
        *natoms = cdf->natoms;
        return cdf;
      }
    } 

    /* Check if this is a file generated by MMTK */
    if (strstr(cdf->conventions, "MMTK") != NULL) {
      if (!open_mmtk_cdf_read(cdf, 1)) {
        *natoms = cdf->natoms;
        return cdf;
      }
    } 
  } 

  printf("netcdfplugin) Missing or unrecognized conventions attribute\n");
  printf("netcdfplugin) checking for old format MMTK NetCDF file...\n");

  /* If no conventions are specified, then maybe it's from MMTK */
  if (!open_mmtk_cdf_read(cdf, 0)) {
    *natoms = cdf->natoms;
    return cdf;
  } 

  /* if no conventions are recognized, then we free everything */
  /* and return failure                                        */
  close_cdf_read(cdf);

  return NULL; 
}
Exemple #2
0
EXTERNL int
nccf_inq_transform(int ncid, int transform_varid, char *name, size_t *type_len, 
		 char *transform_type, size_t *name_len, char *transform_name)
{
   int ret;

   /* Find the name of the transform var, if desired. */
   if (name)
      if ((ret = nc_inq_varname(ncid, transform_varid, name)))
	 return ret;

   /* If the user wants the length of the transform_type, find it. */
   if (type_len)
      if ((ret = nc_inq_attlen(ncid, transform_varid, TRANSFORM_TYPE, 
				  type_len)))
	 return ret;

   /* If the user wants the transform type string, get it. */
   if (transform_type)
      if ((ret = nc_get_att_text(ncid, transform_varid, 
				    TRANSFORM_TYPE, transform_type)))
	 return ret;

   /* If the user wants the length of the transform_name, find it. */
   if (type_len)
      if ((ret = nc_inq_attlen(ncid, transform_varid, TRANSFORM_NAME, 
				  name_len)))
	 return ret;

   /* If the user wants the transform name string, get it. */
   if (transform_name)
      if ((ret = nc_get_att_text(ncid, transform_varid, 
				   TRANSFORM_NAME, transform_name)))
	 return ret;

   return NC_NOERR;
}
Exemple #3
0
std::string FileNetcdf::getGlobalAttribute(std::string iName) {
   size_t len;
   int status = nc_inq_attlen(mFile, NC_GLOBAL, iName.c_str(), &len);
   handleNetcdfError(status, "could not determine global attribute length");

   char* value = new char[len+1];
   status = nc_get_att_text(mFile, NC_GLOBAL, iName.c_str(), value);
   handleNetcdfError(status, "could not get global attribute");
   value[len] = '\0';
   std::string ret = "";
   if(status == NC_NOERR)
      ret = std::string(value);
   delete[] value;
   return ret;
}
Exemple #4
0
int
nccf_inq_convention(int ncid, int *cf_convention)
{
    size_t len, new_len;
    char *existing_att = NULL;
    int ret = CF_NOERR;

    /* Find out if there is a conventions attribute. */
    ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_CONVENTIONS, &len);

    if (ret == NC_NOERR)
    {
        /* Get memory to hold the existing att plus our version
         * string. */
        new_len = len + strlen(CF_CONVENTION_STRING) + 1;
        if (!(existing_att = malloc(new_len)))
            return CF_ENOMEM;

        /* Get the existing att. */
        if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_CONVENTIONS,
                                   existing_att)))
            BAIL(CF_ENETCDF);

        /* If it's already in the string, our work is done.*/
        if (strstr(existing_att, CF_CONVENTION_STRING))
        {
            if (cf_convention)
                *cf_convention = 1;
            ret = CF_NOERR;
        }
    }
    else if (ret == NC_ENOTATT)
    {
        /* No conventions att means no cf conventions. ;-( But this is
         * not an error. */
        if (cf_convention)
            *cf_convention = 0;
        ret = NC_NOERR;
    }
    else
        BAIL(CF_ENETCDF);

exit:
    if (existing_att)
        free(existing_att);
    return ret;
}
Exemple #5
0
/*
 * Get the value of a netCDF character attribute given its variable
 * ID and name.
 */
static void
c_ncagtc(
    int		ncid,		/* netCDF ID */
    int		varid,		/* variable ID */
    const char*	attname,	/* attribute name */
    char*	value,		/* pointer to data values */
    int		attlen,		/* length of string argument */
    int*	rcode		/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_atttype(ncid, varid, attname, &datatype)) == 0)
    {
	if (datatype != NC_CHAR)
	    status = NC_ECHAR;
	else
	{
	    size_t	len;

	    status = nc_inq_attlen(ncid, varid, attname, &len);
	    if (status == 0)
	    {
		if (attlen < len)
		    status = NC_ESTS;
		else
		{
		    status = nc_get_att_text(ncid, varid, attname, 
					       value);
		    if (status == 0)
			(void) memset(value+len, ' ', attlen - len);
		}
	    }
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCAGTC", status, "");
	*rcode = ncerr;
    }
}
Exemple #6
0
char *NCdataGetTextAttribute(int ncid, int varid, const char *attName) {
    int status;
    char *att;
    size_t attlen;

    if ((status = nc_inq_attlen(ncid, varid, attName, &attlen)) != NC_NOERR) return ("undefined");

    if ((att = (char *) malloc(attlen + 1)) == (char *) NULL) {
        CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__);
        return ((char *) NULL);
    }
    if ((status = nc_get_att_text(ncid, varid, attName, att)) != NC_NOERR) {
        NCprintNCError (status, "NCdataGetTextAttribute");
        free(att);
        return ((char *) NULL);
    }
    att[attlen] = '\0';
    return (att);
}
Exemple #7
0
Fichier : ncdf.c Projet : cran/ncdf
/* NOTE that space for the attribute must already be allocated! */
void R_nc_get_att_text( int *ncid, int *varid, char **attname, 
			char **attribute, int *retval )
{
	int	err;
	size_t	attlen;

	*retval = nc_get_att_text(*ncid, *varid, attname[0], 
		attribute[0] );
	/* append a NULL */
	if( *retval != NC_NOERR ) {
		strcpy( attribute[0], "\0" );
		return;
		}
	err = nc_inq_attlen( *ncid, *varid, attname[0], &attlen );
	if( err != NC_NOERR ) {
		strcpy( attribute[0], "\0" );
		return;
		}
	attribute[0][attlen] = '\0';
}
Exemple #8
0
/******************************************************************************
 * @brief    Get netCDF dimension.
 *****************************************************************************/
void
get_nc_var_attr(char  *nc_name,
                char  *var_name,
                char  *attr_name,
                char **attr)
{
    int    nc_id;
    int    var_id;
    int    status;
    size_t attr_len;

    // open the netcdf file
    status = nc_open(nc_name, NC_NOWRITE, &nc_id);
    check_nc_status(status, "Error opening %s", nc_name);

    // get variable id
    status = nc_inq_varid(nc_id, var_name, &var_id);
    check_nc_status(status, "Error getting variable id %s in %s", var_name, nc_name);

    // get size of the attribute
    status = nc_inq_attlen(nc_id, var_id, attr_name, &attr_len);
    check_nc_status(status, "Error getting attribute length for %s:%s in %s", var_name,
                attr_name, nc_name);

    // allocate memory for attribute
    *attr = malloc((attr_len + 1) * sizeof(**attr));
    check_alloc_status(*attr, "Memory allocation error.");

    // read attribute text
    status = nc_get_att_text(nc_id, var_id, attr_name, *attr);
    check_nc_status(status, "Error getting netCDF attribute %s for var %s in %s", attr_name,
                var_name, nc_name);

    // we need to null terminate the string ourselves according to NetCDF docs
    (*attr)[attr_len] = '\0';

    // close the netcdf file
    status = nc_close(nc_id);
    check_nc_status(status, "Error closing %s", nc_name);
}
Exemple #9
0
  // Will return an emptry string if the attribute is not found
  // May want to consider special exception for type errors...
  std::string AmberNetcdf::readGlobalAttribute(const std::string& name) {
    size_t len;
    
    int retval = nc_inq_attlen(_ncid, NC_GLOBAL, name.c_str(), &len);
    if (retval)
      return(std::string());

    nc_type type;
    retval = nc_inq_atttype(_ncid, NC_GLOBAL, name.c_str(), &type);
    if (type != NC_CHAR)
      throw(FileOpenError(_filename, "Only character data is supported for global attributes", retval));

    char* buf = new char[len+1];
    retval = nc_get_att_text(_ncid, NC_GLOBAL, name.c_str(), buf);
    if (retval) {
      delete[] buf;
      throw(FileOpenError(_filename, "Cannot read attribute " + name, retval));
    }
    buf[len]='\0';

    return(std::string(buf));
  }
Exemple #10
0
static void
test_small_atts(const char *testfile)
{
   int ncid;
   char att[MAX_LEN + 1], att_in[MAX_LEN + 1], source[MAX_LEN + 1] = "0123456";
   int ndims, nvars, natts, unlimdimid;
   size_t len_in;
   int t, l, f;

   
   /* Run this with and without fill mode. */
   for (f = 0; f < 2; f++)
   {
      /* Create small files with an attribute that grows by one each
       * time. */
      for (t = 1; t < MAX_LEN; t++)
      {
	 /* Create null-terminated text string of correct length. */
	 strncpy(att, source, t);
	 
	 /* Create a file with one attribute. */
	 if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR;
	 if (nc_put_att_text(ncid, NC_GLOBAL, ATT_NAME, t + 1, att)) ERR;
	 if (f && nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
	 if (nc_close(ncid)) ERR;
	 
	 /* Reopen the file and check it. */
	 if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR;
	 if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
	 if (ndims != 0 && nvars != 0 && natts != 1 && unlimdimid != -1) ERR;
	 if (nc_inq_attlen(ncid, NC_GLOBAL, ATT_NAME, &len_in)) ERR;
	 if (len_in != t + 1) ERR;
	 if (nc_get_att_text(ncid, NC_GLOBAL, ATT_NAME, att_in));
	 l = strlen(att_in);
	 if (strncmp(att_in, att, t)) ERR;
	 if (nc_close(ncid)) ERR; 
      }
   }
}
Exemple #11
0
/** Get the information about a netcdf attribute with given vid and
  * attribute text.
  * Since there is no guarantee that null char at the end of retrieved string
  * append one.
  */
std::string NetcdfFile::GetAttrText(int vid, const char *attribute) {
    size_t attlen;
    std::string attrOut;
    // Get attr length
    if ( checkNCerr(nc_inq_attlen(ncid_, vid, attribute, &attlen)) ) {
        mprintf("Warning: Getting length for attribute '%s'\n",attribute);
        return attrOut;
    }
    // Allocate space for attr text, plus one for null char
    char *attrText = new char[ (attlen + 1) ];
    // Get attr text
    if ( checkNCerr(nc_get_att_text(ncid_, vid, attribute, attrText)) ) {
        mprintf("Warning: Getting attribute text for '%s'\n",attribute);
        delete[] attrText;
        return attrOut;
    }
    // Append null char - NECESSARY?
    attrText[attlen]='\0';
    attrOut.assign( attrText );
    delete[] attrText;

    return attrOut;
}
Exemple #12
0
NCstate NCdsHandleGContDefine(NCdsHandleGCont_t *gCont, int *ncids, size_t n) {
    int status, varid, i;
    int missingInt, fillInt;
    double missingFloat, fillFloat, scale, offset;
    size_t unitlen, row, col;
    char unitstr[NC_MAX_NAME], gunitstr[NC_MAX_NAME];

    gCont->Data = (double *) NULL;
    gCont->AuxData = (double *) NULL;
    gCont->ObsNum = (size_t *) NULL;
    gCont->MeanIds = gCont->MinIds = gCont->MaxIds = gCont->StdIds = (int *) NULL;

    if (n < 1) return (NCfailed);
    if (NCdsHandleGridDefine((NCdsHandleGrid_t *) gCont, ncids, n) == NCfailed) return (NCfailed);

    if (gCont->DataType != NCtypeGCont) {
        CMmsgPrint(CMmsgAppError, "Invalid grid data in: %s %d", __FILE__, __LINE__);
        NCdsHandleGridClear((NCdsHandleGrid_t *) gCont);
        return (NCfailed);
    }
    if (((gCont->MeanIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->MinIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->MaxIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->StdIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->Data = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) ||
        ((gCont->AuxData = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) ||
        ((gCont->ObsNum = (size_t *) calloc(gCont->ColNum * gCont->RowNum, sizeof(size_t))) == (size_t *) NULL)) {
        CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__);
        if (gCont->MeanIds != (int *) NULL) free(gCont->MeanIds);
        if (gCont->MinIds != (int *) NULL) free(gCont->MinIds);
        if (gCont->MaxIds != (int *) NULL) free(gCont->MaxIds);
        if (gCont->StdIds != (int *) NULL) free(gCont->StdIds);
        NCdsHandleGridClear((NCdsHandleGrid_t *) gCont);
        return (NCfailed);
    }
    for (i = 0; i < n; ++i) gCont->MeanIds[i] = gCont->MinIds[i] = gCont->MaxIds[i] = gCont->StdIds[i] = NCundefined;

    for (i = 0; i < n; ++i) {
        switch (gCont->GType) {
            default:
                gCont->FillValue.Float = gCont->MissingVal.Float = FLOAT_NOVALUE;
                break;
            case NC_BYTE:
            case NC_SHORT:
            case NC_INT:
                if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillInt)) !=
                    NC_NOERR) {
                    if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                 &missingInt)) != NC_NOERR)
                        missingInt = fillInt = INT_NOVALUE;
                    else fillInt = missingInt;
                }
                else if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                  &missingInt)) != NC_NOERR)
                    missingInt = fillInt;
                break;
            case NC_FLOAT:
            case NC_DOUBLE:
                if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillFloat)) !=
                    NC_NOERR) {
                    if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                    &missingFloat)) != NC_NOERR)
                        missingFloat = fillFloat = FLOAT_NOVALUE;
                    else
                        fillFloat = missingFloat;
                }
                else if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                     &missingFloat)) != NC_NOERR)
                    missingFloat = fillFloat;
                break;
        }
        if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAScaleFactor, &scale)) !=
            NC_NOERR)
            scale = 1.0;
        if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAAddOffset, &offset)) !=
            NC_NOERR)
            offset = 0.0;
        if (((status = nc_inq_attlen(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, &unitlen)) == NC_NOERR) &&
            ((status = nc_get_att_text(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, unitstr)) == NC_NOERR))
            unitstr[unitlen] = '\0';
        if (i == 0) {
            if ((status == NC_NOERR) && (utScan(unitstr, &(gCont->GUnit)) == 0)) {
                gCont->DoGUnit = true;
                strcpy (gunitstr, unitstr);
            }
            else gCont->DoGUnit = false;
            switch (gCont->GType) {
                case NC_BYTE:
                case NC_SHORT:
                case NC_INT:
                    gCont->FillValue.Int = fillInt;
                    gCont->MissingVal.Int = missingInt;
                    break;
                default:
                case NC_FLOAT:
                case NC_DOUBLE:
                    gCont->FillValue.Float = fillFloat;
                    gCont->MissingVal.Float = missingFloat;
                    break;
            }
            gCont->Scale = scale;
            gCont->Offset = offset;
        }
        else {
            if (gCont->DoGUnit && ((status != NC_NOERR) || strcmp(unitstr, gunitstr) != 0)) {
                CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (units) in: %s %d", __FILE__, __LINE__);
                return (NCfailed);
            }
            switch (gCont->GType) {
                case NC_BYTE:
                case NC_SHORT:
                case NC_INT:
                    if ((gCont->FillValue.Int != fillInt) || (gCont->MissingVal.Int != missingInt)) {
                        CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (int fill value) in: %s %d", __FILE__,
                                   __LINE__);
                        return (NCfailed);
                    }
                    break;
                default:
                case NC_FLOAT:
                case NC_DOUBLE:
                    if ((NCmathEqualValues(gCont->FillValue.Float, fillFloat) == false) ||
                        (NCmathEqualValues(gCont->MissingVal.Float, missingFloat) == false)) {
                        CMmsgPrint(CMmsgAppError, "Inconsistent bundle (float fill value) in: %s %d", __FILE__,
                                   __LINE__);
                        return (NCfailed);
                    }
                    break;
            }
            if ((NCmathEqualValues(gCont->Scale, scale) == false) ||
                (NCmathEqualValues(gCont->Offset, offset) == false)) {
                CMmsgPrint(CMmsgAppError, "Inconsistent bundle (scale and offset) in: %s %d", __FILE__, __LINE__);
                return (NCfailed);
            }
        }
        gCont->MeanIds[i] = nc_inq_varid(ncids[i], NCnameVAAverage, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->MaxIds[i] = nc_inq_varid(ncids[i], NCnameVAMaximum, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->MinIds[i] = nc_inq_varid(ncids[i], NCnameVAMinimum, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->StdIds[i] = nc_inq_varid(ncids[i], NCnameVAStdDev, &varid) == NC_NOERR ? varid : NCundefined;
    }
    for (row = 0; row < gCont->RowNum; row++)
        for (col = 0; col < gCont->ColNum; col++)
            NCdsHandleGContSetFill(gCont, row, col);
    return (NCsucceeded);
}
Exemple #13
0
void im_rcdf ( char imgfil[], int *kx, int *ky, int *isorc, int *itype, 
		int *idate, int *itime, int *iproj, float *clat, 
		float *clon, float *xmin, float *xmax, float *ymin, 
		float *ymax, int *iret )
/************************************************************************
 * im_rcdf								*
 *									*
 * This subroutine opens a NetCDF file and reads the header information *
 * and returns it to the calling function.                              *
 *                                                                      *
 * im_rcdf ( imgfil, kx, ky, isorc, itype, idate, itime, iproj,         *
 *	  clat, clon, xmin, xmax, ymin, ymax, iret )                    *
 *                                                                      *
 * Input parameters:                                                    *
 *	imgfil[]	char		Name of image file              *
 *                                                                      *
 * Output parameters:                                                   *
 *	*kx		int		x dimension of image		*
 *     	*ky		int		y dimension of image		*
 *	*isorc		int						*
 *	*itype		int		type of channel			*
 * 	*idate		int		date				*
 *	*itime		int		time				*
 *	*iproj		int		projection type			*
 *	*clat		float		central latitude		*
 * 	*clon		float		central longitude		*
 *	*xmin		float		x - minimum for image		*
 * 	*xmax	 	float		x - maximum for image		*
 *	*ymin 		float		y - minimum for image		*
 *	*ymax		float		y - maximum for image		*
 *	*iret 		int		return value			*
 *                                                                      *
 *                                                                      *
 **									*
 * Log:									*
 * S. Jacobs/NCEP	 6/99	Created					*
 * R. Curtis/EAI  	 8/00   Updated and implemented in GEMPAK       *
 * T. Piper/GSC		 9/00	Modified for Lambert Conformal		*
 * A. Hardy/GSC		 7/01   Modified to use the channel table       *
 ***********************************************************************/
{
	int		ncid, iy, im, id, ih, in, is;
	size_t		lenp, jx, jy;
	double		dsec;
	time_t		isec;
	struct tm	*tarr;
	char		chanl[81];
/*---------------------------------------------------------------------*/
	*iret = 0;
/*
 *	Open the NetCDF file.
 */
	nc_open ( imgfil, NC_NOWRITE, &ncid );
/*
 *	Get the x and y dimensions of the image.
 */
	nc_inq_dimlen ( ncid, 0, &jy );
	nc_inq_dimlen ( ncid, 1, &jx );
	*kx = (int) jx;
	*ky = (int) jy;
/*
 *	Get the date/time. It is stored as the number of seconds
 *	since 00:00:00 UTC, January 1, 1970.
 */
	nc_get_var1_double ( ncid, 1, 0, &dsec );
	isec = (time_t) dsec;
	tarr = gmtime ( &isec );
	iy = (*tarr).tm_year + 1900;
	im = (*tarr).tm_mon + 1;
	id = (*tarr).tm_mday;
	ih = (*tarr).tm_hour;
	in = (*tarr).tm_min;
	is = (*tarr).tm_sec;
	*idate = iy * 10000 + im * 100 + id;
	*itime = ih * 10000 + in * 100 + is;
/*
 *	Get the channel information.
 */
	nc_inq_attlen ( ncid, NC_GLOBAL, "channel", &lenp );
	nc_get_att_text ( ncid, NC_GLOBAL, "channel", chanl );
	chanl[lenp] = CHNULL;
/*
 *       ITYPE  Channel String(s)
 *      -----------------------------
 *          1   VIS
 *          2   3.9 micron (IR2)
 *          4   6.7 micron (WV)
 *          8   11  micron (IR)
 *         16   12  micron (IR5)
 */
	im_chtb ( chanl, itype, iret, strlen(chanl) );
/*
 *	Get the projection and central lat/lon.
 */
	nc_get_att_int ( ncid, NC_GLOBAL, "projIndex", iproj );
	nc_get_att_float ( ncid, NC_GLOBAL, "centralLat", clat );
	nc_get_att_float ( ncid, NC_GLOBAL, "centralLon", clon );
/*
 *	If the center longitude is east of -100, assume that the image
 *	is from GOES-8. Otherwise, assume that it is from GOES-9.
 */
	if  ( *clon > -100.0 )  {
	    *isorc = 70;
	}
	else {
	    *isorc = 72;
	}
/*
 *	Get the corner lat/lons. The values are for the upper left
 *	and lower right corners.
 */
	nc_get_att_float ( ncid, NC_GLOBAL, "xMin",   xmin );
	nc_get_att_float ( ncid, NC_GLOBAL, "xMax",   xmax );
	nc_get_att_float ( ncid, NC_GLOBAL, "yMin",   ymin );
	nc_get_att_float ( ncid, NC_GLOBAL, "yMax",   ymax );
/*
 *	Close the NetCDF file.
 */
 	nc_close ( ncid );
}
Exemple #14
0
int
main()
{
   int ncid, lon_dimid, lat_dimid, pres_varid, temp_varid;
   int dimids[NDIMS];
   float pres_out[LAT_LEN][LON_LEN], pres_in[LAT_LEN][LON_LEN];
   float temp_out[LAT_LEN][LON_LEN], temp_in[LAT_LEN][LON_LEN];
   char *att_in;
   size_t len_in;
   int error = 0;
   int lat, lon, retval;

   /* Create phoney data. If this wasn't an example program, we would
    * have some real data to write, for example, model output. */
   for (lat = 0; lat < LAT_LEN; lat++)
      for (lon = 0; lon < LON_LEN; lon++)
      {
	 pres_out[lat][lon] = 1013.1;
	 temp_out[lat][lon] = 12.5;
      }

   /* These are the latitudes and longitudes which correspond with
    * ticks on the dimension axes. */
   for (lat = 0; lat < LAT_LEN; lat++)
      latitude[lat] = 40. + lat * 2.5;
   for (lon = 0; lon < LON_LEN; lon++)
      longitude[lon] = -90. - lon * 5;

   /* Create the file. */
   if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid)))
      return retval;

   /* Add data sonnet. By using NC_GLOBAL we mean that this attribute
    * applies to the entire file, not just to one variable. Don't
    * forget that sizeof does not include the null terminator, so if
    * you want it, you need to add one more byte. */
   if ((retval = nc_put_att_text(ncid, NC_GLOBAL, SONNET_NAME,
				 sizeof(poem) + 1, poem)))
      return retval;

   /* Define the dimensions. */
   if ((retval = nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)))
      return retval;
   if ((retval = nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)))
      return retval;

   /* Save the dimension information, in variables of the same
    * name. First we need to define these variables. */
   dimids[0] = lat_dimid;
   if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)))
      return retval;
   dimids[0] = lon_dimid;
   if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)))
      return retval;

   /* Define the variables. */
   dimids[0] = lat_dimid;
   dimids[1] = lon_dimid;
   if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS, dimids, &pres_varid)))
      return retval;
   if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS, dimids, &temp_varid)))
      return retval;

   /* End define mode. */
   if ((retval = nc_enddef(ncid)))
      return retval;

   /* Write the dimension metadata. */
   if ((retval = nc_put_var_float(ncid, lat_varid, latitude_out)))
      return retval;
   if ((retval = nc_put_var_float(ncid, lon_varid, longitude_out)))
      return retval;

   /* Write the phoney data. */
   if ((retval = nc_put_var_float(ncid, pres_varid, pres_out)))
      return retval;
   if ((retval = nc_put_var_float(ncid, temp_varid, temp_out)))
      return retval;

   /* Close the file. */
   if ((retval = nc_close(ncid)))
      return retval;

   /* Open the file and check that everything's OK. */
   if ((retval = nc_open(FILE_NAME, 0, &ncid)))
      return retval;

   /* Read the attribute. First find it's length to allocate storage
    * for it. */
   if ((retval = nc_inq_attlen(ncid, NC_GLOBAL, SONNET_NAME, &len_in)))
      return retval;
   if (!(att_in = malloc(len_in)))
      return NC_ENOMEM;
   if (strcmp(att_in, data_poem))
      error++;
   free(att_in);
   if (error)
      return -2;

   /* Read the data. */
   if ((retval = nc_get_var_float(ncid, pres_varid, pres_in)))
      return retval;
   if ((retval = nc_get_var_float(ncid, temp_varid, temp_in)))
      return retval;

   /* Check the data. */
   for (lat = 0; lat < LAT_LEN; lat++)
      for (lon = 0; lon < LON_LEN; lon++)
	 if (pres_in[lat][lon] != pres_out[lat][lon] ||
	     temp_in[lat][lon] != temp_out[lat][lon])
	    return -2;

   /* Close the file. */
   if ((retval = nc_close(ncid)))
      return retval;

   return 0;
}
Exemple #15
0
int
main(int argc, char **argv)
{
    printf("\n*** Testing 'Fileinfo attributes.\n");

    {
	hid_t fileid;
	hid_t fcplid;
	hid_t scalar_spaceid;

        printf("*** creating test file using HDF5 directly %s...", HDFFILE);

        /* Create scalar dataspace */
        if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;

        /* Set creation ordering for file, so we can revise its contents later */
        if((fcplid = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
        if(H5Pset_link_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
        if(H5Pset_attr_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;

        /* Create new file, using default properties */
        if((fileid = H5Fcreate(HDFFILE, H5F_ACC_TRUNC, fcplid, H5P_DEFAULT)) < 0) ERR;
        /* Close file creation property list */
        if(H5Pclose(fcplid) < 0) ERR;

        /* Add attributes to root group */
        {
            hid_t scalar_spaceid = -1;
            hid_t attid = -1;

            /* Create scalar dataspace */
            if((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;

            /* Create attribute with native integer datatype on object */
            if((attid = H5Acreate2(fileid, INT_ATT_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
            if(H5Aclose(attid) < 0) ERR;

            /* Clean up objects created */
            if(H5Sclose(scalar_spaceid) < 0) ERR;
        }

        /* Close rest */
        if(H5Sclose(scalar_spaceid) < 0) ERR;
        if(H5Fclose(fileid) < 0) ERR;
    }

    {
	int root, grpid, varid, stat, natts, id;
	int data = 17;
	const char* sdata = "text";
	char ncprops[8192];
	size_t len;
	int dimid;
        nc_type xtype;
	char name[NC_MAX_NAME];

        printf("\n*** creating netcdf-4 test file using netCDF %s...", NC4FILE);

	if(nc_create(NC4FILE,NC_WRITE|NC_CLOBBER|NC_NETCDF4,&root)!=0) ERR;
	/* Create global attribute */
	if(nc_put_att_int(root,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
	/* Create global variable */
	if(nc_def_var(root,INT_VAR_NAME,NC_INT,0,NULL,&varid)!=0) ERR;
	/* Create attribute on var */
	if(nc_put_att_int(root,varid,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
	/* Create global subgroup */
	if(nc_def_grp(root,GROUPNAME,&grpid)!=0) ERR;
	/* Create global attribute in the group */
	if(nc_put_att_int(grpid,NC_GLOBAL,INT_ATT_NAME,NC_INT,1,&data)!=0) ERR;
	/* Create _NCProperties as var attr and as subgroup attribute */
	if(nc_put_att_text(grpid,NC_GLOBAL,NCPROPS,strlen(sdata),sdata)!=0) ERR;
	if(nc_put_att_text(root,varid,NCPROPS,strlen(sdata),sdata)!=0) ERR;
	/* Create var + dimension to cause e.g. dimscales to appear */
	if(nc_def_dim(root,DIMNAME,(size_t)4,&dimid)!=0) ERR;
	if(nc_def_var(root,DIMNAME,NC_INT,1,&dimid,&varid)!=0) ERR; /* same name */
	/* Close, then re-open */
	if(nc_close(root)) ERR;
	if(nc_open(NC4FILE,NC_WRITE|NC_NETCDF4,&root)!=0) ERR;

	/* Is all invisible attributes actually invisible vis-a-vis nc_inq? */
        if(nc_inq(root,NULL,NULL,&natts,NULL)!=0) ERR;
	if(natts != 1) ERR;

	/* Now, fiddle with the NCPROPS attribute */

	/* Get its metadata */
	if(nc_inq_att(root,NC_GLOBAL,NCPROPS,&xtype,&len)!=0) ERR;
	if(xtype != NC_CHAR) ERR;

	/* Read in two ways */
	if(nc_get_att_text(root,NC_GLOBAL,NCPROPS,ncprops)!=0) ERR;
	if(strlen(ncprops) != len) ERR;

	/* Attempt to get attribute metadata piecemeal; some will fail */
	id = -1;
	stat = nc_inq_attid(root,NC_GLOBAL,NCPROPS,&id);
	if(stat == NC_NOERR) ERR;
	stat = nc_inq_attname(root,NC_GLOBAL,id,name);
	if(stat == NC_NOERR) ERR;
	if(nc_inq_atttype(root,NC_GLOBAL,NCPROPS,&xtype)!=0) ERR;
	if(xtype != NC_CHAR) ERR;
	if(nc_inq_attlen(root,NC_GLOBAL,NCPROPS,&len)!=0) ERR;
	if(len != strlen(ncprops)) ERR;

	/*Overwrite _NCProperties root attribute; should fail */
	stat = nc_put_att_text(root,NC_GLOBAL,NCPROPS,strlen(sdata),sdata);
	if(stat == NC_NOERR) ERR;

	/* Delete; should fail */
	stat = nc_del_att(root,NC_GLOBAL,NCPROPS);
        if(stat != NC_ENOTATT) ERR;

	/* Ditto _SuperblockVersion */

	/* Get its metadata */
	if(nc_inq_att(root,NC_GLOBAL,SUPERBLOCKATT,&xtype,&len)!=0) ERR;
	if(xtype != NC_INT) ERR;
	if(len != 1) ERR;

	if(nc_get_att_int(root,NC_GLOBAL,SUPERBLOCKATT,&data)!=0) ERR;

	/* Attempt to get attribute metadata piecemeal */
	stat = nc_inq_attid(root,NC_GLOBAL,SUPERBLOCKATT,&id);
	if(stat == NC_NOERR) ERR;
	stat = nc_inq_attname(root,NC_GLOBAL,id,name);
	if(stat == NC_NOERR) ERR;
	if(nc_inq_atttype(root,NC_GLOBAL,SUPERBLOCKATT,&xtype)!=0) ERR;
	if(xtype != NC_INT) ERR;
	if(nc_inq_attlen(root,NC_GLOBAL,SUPERBLOCKATT,&len)!=0) ERR;
	if(len != 1) ERR;

	/*Overwrite; should fail */
	stat = nc_put_att_int(root,NC_GLOBAL,NCPROPS,NC_INT,1,&data);
	if(stat == NC_NOERR) ERR;

	/* Delete; should fail */
	stat = nc_del_att(root,NC_GLOBAL,SUPERBLOCKATT);
        if(stat == NC_NOERR) ERR;

	/* Ditto _IsNetcdf4 */

	/* Get its metadata */
	if(nc_inq_att(root,NC_GLOBAL,ISNETCDF4ATT,&xtype,&len)!=0) ERR;
	if(xtype != NC_INT) ERR;
	if(len != 1) ERR;

	if(nc_get_att_int(root,NC_GLOBAL,ISNETCDF4ATT,&data)!=0) ERR;

	/* Attempt to get attribute metadata piecemeal */
	stat = nc_inq_attid(root,NC_GLOBAL,ISNETCDF4ATT,&id);
	if(stat == NC_NOERR) ERR;
	stat = nc_inq_attname(root,NC_GLOBAL,id,name);
	if(stat == NC_NOERR) ERR;
	if(nc_inq_atttype(root,NC_GLOBAL,ISNETCDF4ATT,&xtype)!=0) ERR;
	if(xtype != NC_INT) ERR;
	if(nc_inq_attlen(root,NC_GLOBAL,ISNETCDF4ATT,&len)!=0) ERR;
	if(len != 1) ERR;

	/*Overwrite; should fail */
	stat = nc_put_att_int(root,NC_GLOBAL,ISNETCDF4ATT,NC_INT,1,&data);
	if(stat == NC_NOERR) ERR;

	/* Delete; should fail */
	stat = nc_del_att(root,NC_GLOBAL,ISNETCDF4ATT);
        if(stat == NC_NOERR) ERR;

	if(nc_close(root)!=0) ERR;
    }

    SUMMARIZE_ERR;
    FINAL_RESULTS;
}
static int open_amber_cdf_read(cdfdata *cdf) {
  int rc;
  size_t len; 
  amberdata *amber = &cdf->amber;

  /* global attrib: "ConventionVersion" -- required */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "ConventionVersion", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->conventionversion = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "ConventionVersion", amber->conventionversion);
    amber->conventionversion[len] = '\0';
    printf("netcdfplugin) trajectory follows AMBER conventions version '%s'\n", amber->conventionversion);
  } else {
    return CDF_ERR;
  }

  /* at this point we know that this is an AMBER trajectory */
  cdf->type = CDF_TYPE_AMBER;

  /* initialize default scaling factors so they are always set to a sane */
  /* value even if problems occur later */
  amber->coordinates_scalefactor = 1.0;
  amber->cell_lengths_scalefactor = 1.0;
  amber->cell_angles_scalefactor = 1.0;


  /* global attrib: "program" -- required */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "program", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->program = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "program", amber->program);
    amber->program[len] = '\0';
    printf("netcdfplugin) AMBER: program '%s'\n", amber->program);
  } else {
    printf("netcdfplugin) AMBER: Missing required 'program' global attribute, corrupt file?\n");
  }


  /* global attrib: "programVersion" -- required */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "programVersion", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->programversion = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "programVersion", amber->programversion);
    amber->programversion[len] = '\0';
    printf("netcdfplugin) AMBER: program version '%s'\n", amber->programversion);
  } else {
    printf("netcdfplugin) AMBER: Missing required 'programVersion' global attribute, corrupt file?\n");
  }


  /* global attrib: "title" -- optional */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "title", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->title = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "title", amber->title);
    amber->title[len] = '\0';
    printf("netcdfplugin) AMBER: title '%s'\n", amber->title);
  } 


  /* global attrib: "application" -- optional */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "application", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->application = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "application", amber->application);
    amber->application[len] = '\0';
    printf("netcdfplugin) AMBER: application '%s'\n", amber->application);
  } 


/* XXX lots of additional error checking is needed below... */

  /* read in spatial dimension */
  rc = nc_inq_dimid(cdf->ncid, "spatial", &amber->spatialdimid);
  if (rc == NC_NOERR) {    
    rc = nc_inq_dimlen(cdf->ncid, amber->spatialdimid, &amber->spatialdim);
    if (rc == NC_NOERR) {
      printf("netcdfplugin) AMBER: spatial dimension: %ld\n", (long)amber->spatialdim);
    } else {
      printf("netcdfplugin) AMBER: Missing spatial dimension, corrupt file?\n");
      printf("netcdfplugin) AMBER: Fixing by guessing spatialdim as '3'\n");
      amber->spatialdim = 3;
    }
  } else {
    printf("netcdfplugin) AMBER: Missing spatial dimension, corrupt file?\n");
    printf("netcdfplugin) AMBER: Fixing by guessing spatialdim as '3'\n");
    amber->spatialdim = 3;
  }
 
  /* read in atom dimension */
  rc = nc_inq_dimid(cdf->ncid, "atom", &amber->atomdimid);
  if (rc == NC_NOERR) {    
    rc = nc_inq_dimlen(cdf->ncid, amber->atomdimid, &amber->atomdim);
    if (rc == NC_NOERR) {
      printf("netcdfplugin) AMBER: atom dimension: %ld\n", (long)amber->atomdim);
      cdf->natoms = amber->atomdim; /* copy to format independent part */
    } else  {
      printf("netcdfplugin) AMBER: missing atom dimension, aborting\n");
      return CDF_ERR;
    }
  } else {
    printf("netcdfplugin) AMBER: missing atom dimension, aborting\n");
    return CDF_ERR;
  }
 

  /* read in frame dimension */
  rc = nc_inq_dimid(cdf->ncid, "frame", &amber->framedimid);
  if (rc == NC_NOERR) {    
    rc = nc_inq_dimlen(cdf->ncid, amber->framedimid, &amber->framedim);
    if (rc == NC_NOERR) {
      printf("netcdfplugin) AMBER: frame dimension: %ld\n", (long)amber->framedim);
    } else {
      printf("netcdfplugin) AMBER: missing frame dimension, aborting\n");
      return CDF_ERR;
    }
  } else {
    printf("netcdfplugin) AMBER: missing frame dimension, aborting\n");
    return CDF_ERR;
  }

  /* 
   * get ID values for all of the variables we're interested in 
   */
#if 0
  /* VMD can live without the various human readable label variables. */
  rc = nc_inq_varid(cdf->ncid, "spatial", &amber->spatial_id);
  if (rc != NC_NOERR)
    return CDF_ERR;

  rc = nc_inq_varid(cdf->ncid, "cell_spatial", &amber->cell_spatial_id);
  if (rc != NC_NOERR)
    return CDF_ERR;

  rc = nc_inq_varid(cdf->ncid, "cell_angular", &amber->cell_angular_id);
  if (rc != NC_NOERR)
    return CDF_ERR;
#endif

  /* VMD requires coordinates at a minimum */
  rc = nc_inq_varid(cdf->ncid, "coordinates", &amber->coordinates_id);
  if (rc != NC_NOERR) {
    printf("netcdfplugin) AMBER: no coordinates variable, nothing to load\n");
    return CDF_ERR;
  }

  /* Coordinate units */
  rc = nc_inq_attlen(cdf->ncid, amber->coordinates_id, "units", &len);
  if (rc == NC_NOERR && len > 0) {
    amber->coordinates_units = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, amber->coordinates_id, "units", amber->coordinates_units);
    amber->coordinates_units[len] = '\0';
    printf("netcdfplugin) AMBER: coordinates units: '%s'\n", amber->coordinates_units);
  } else {
    printf("netcdfplugin) AMBER: no coordinates units attribute, Angstroms assumed\n");
  }

  /* Coordinate scaling factor to get to Angstroms */
  rc = nc_get_att_float(cdf->ncid, amber->coordinates_id, "scale_factor", &amber->coordinates_scalefactor);
  if (rc == NC_NOERR) {
    printf("netcdfplugin) AMBER: coordinates scalefactor: %f\n", amber->coordinates_scalefactor);
  } else {
    amber->coordinates_scalefactor = 1.0;
  }

#if 0
  /* we don't need velocities at this time */
  rc = nc_inq_varid(cdf->ncid, "velocities", &amber->velocities_id);
  if (rc != NC_NOERR) {
    printf("netcdfplugin) AMBER: missing velocities variable, aborting\n");
    return CDF_ERR;
  }
#endif

  /* optional periodic cell info */
  rc = nc_inq_varid(cdf->ncid, "cell_lengths", &amber->cell_lengths_id);
  if (rc == NC_NOERR) {
    rc = nc_inq_varid(cdf->ncid, "cell_angles", &amber->cell_angles_id);
    if (rc == NC_NOERR) {
      printf("netcdfplugin) AMBER trajectory contains periodic cell information\n");
      amber->has_box = 1;

      /* Cell lengths units */
      rc = nc_inq_attlen(cdf->ncid, amber->cell_lengths_id, "units", &len);
      if (rc == NC_NOERR && len > 0) {
        amber->cell_lengths_units = (char *) malloc((len+1) * sizeof(char));
        nc_get_att_text(cdf->ncid, amber->cell_lengths_id, "units", amber->cell_lengths_units);
        amber->cell_lengths_units[len] = '\0';
        printf("netcdfplugin) AMBER: cell lengths units: '%s'\n", amber->cell_lengths_units);
      } else {
        printf("netcdfplugin) AMBER: no cell lengths units attribute, Angstroms assumed\n");
      }

      /* Cell lengths scaling factor to get to Angstroms */
      rc = nc_get_att_float(cdf->ncid, amber->cell_lengths_id, "scale_factor", &amber->cell_lengths_scalefactor);
      if (rc == NC_NOERR) {
        printf("netcdfplugin) AMBER: cell lengths scalefactor: %f\n", amber->cell_lengths_scalefactor);
      } else {
        amber->cell_lengths_scalefactor = 1.0;
      }

      /* Cell angles units */
      rc = nc_inq_attlen(cdf->ncid, amber->cell_angles_id, "units", &len);
      if (rc == NC_NOERR && len > 0) {
        amber->cell_angles_units = (char *) malloc((len+1) * sizeof(char));
        nc_get_att_text(cdf->ncid, amber->cell_angles_id, "units", amber->cell_angles_units);
        amber->cell_angles_units[len] = '\0';
        printf("netcdfplugin) AMBER: cell angles units: '%s'\n", amber->cell_angles_units);
      } else {
        printf("netcdfplugin) AMBER: no cell angles units attribute, Degrees assumed\n");
      }

      /* Cell angles scaling factor to get to degrees */
      rc = nc_get_att_float(cdf->ncid, amber->cell_angles_id, "scale_factor", &amber->cell_angles_scalefactor);
      if (rc == NC_NOERR) {
        printf("netcdfplugin) AMBER: cell angles scalefactor: %f\n", amber->cell_angles_scalefactor);
      } else {
        amber->cell_angles_scalefactor = 1.0;
      }
    }
  }

  return CDF_SUCCESS;
}
sta_struct *decode_fsl2(int cdfid, long miss, int *iret)
{
int ndims,nvars,natts,nunlim;
int tmpint[20];
int ier,i,j,unlimsiz;
int wmoStaNum_id,wmoStaNum,staName_id;
char staName[20];
int staLat_id,staLon_id,staElev_id,timeObs_id,levels_id;
int uwnd_id,vwnd_id,wwnd_id,uv_qual_id,w_qual_id,levelMode_id;
int sigma_uv_id,sigma_w_id;
int sfc_sped_id,sfc_drct_id,sfc_pres_id,sfc_temp_id,sfc_relh_id,sfc_rain_id;
float staLat,staLon,staElev,level;
float uwnd,vwnd,wwnd,sigma_uv,sigma_w;
int uv_qual,w_qual,levelMode;
float sfc_sped,sfc_drct,sfc_pres,sfc_temp,sfc_relh,sfc_rain;
double timeObs;
nc_type xtype;
int nvdims,nvatts,time_interval;
size_t dimsiz,var_i[5],vc[5],namelen;
float ufill,vfill,wfill;
float pfill,tfill,dfill,sfill,rfill,rrfill;
float fmiss,e;

time_t obs_time;
char timestr[80],*atttext;
int year,month,day,hour,minute;
struct tm *gmt_time=NULL,new_time;
sta_struct *stadat,*head=NULL;
prof_data *plev,*plast;


udebug("decoding fsl2\0");
fmiss = (float)miss;

ier = nc_inq(cdfid,&ndims,&nvars,&natts,&nunlim);

ier = nc_inq_atttype(cdfid,NC_GLOBAL,"avgTimePeriod",&xtype);
if(xtype == NC_CHAR)
   {
   ier = nc_inq_attlen(cdfid,NC_GLOBAL,"avgTimePeriod",&namelen);
   udebug("AvgTimPeriod name len is %d",namelen);
   atttext = (char *)malloc(namelen + 1);
   ier = nc_get_att_text(cdfid,NC_GLOBAL,"avgTimePeriod",atttext);
   sscanf(atttext,"%d",tmpint);
   udebug("AvgTimPeriod type is NC_CHAR %s VAL %d",atttext,tmpint[0]);
   free(atttext);
   }
else
   {
   ier = nc_get_att_int(cdfid,NC_GLOBAL,"avgTimePeriod",tmpint);
   }
udebug("AvgTimPeriod is %d\0",tmpint[0]);
time_interval = tmpint[0];

ier = 0;
ier += nc_inq_varid(cdfid,"wmoStaNum",&wmoStaNum_id);
ier += nc_inq_varid(cdfid,"staName",&staName_id);
ier += nc_inq_varid(cdfid,"staLat",&staLat_id);
ier += nc_inq_varid(cdfid,"staLon",&staLon_id);
ier += nc_inq_varid(cdfid,"staElev",&staElev_id);
ier += nc_inq_varid(cdfid,"timeObs",&timeObs_id);
ier += nc_inq_varid(cdfid,"levels",&levels_id);
ier += nc_inq_varid(cdfid,"uComponent",&uwnd_id);
ier += nc_inq_varid(cdfid,"vComponent",&vwnd_id);
ier += nc_inq_varid(cdfid,"wComponent",&wwnd_id);
ier += nc_get_att_float(cdfid,uwnd_id,"_FillValue",&ufill);
ier += nc_get_att_float(cdfid,vwnd_id,"_FillValue",&vfill);
ier += nc_get_att_float(cdfid,wwnd_id,"_FillValue",&wfill);

ier += nc_inq_varid(cdfid,"uvQualityCode",&uv_qual_id);
ier += nc_inq_varid(cdfid,"wQualityCode",&w_qual_id);
ier += nc_inq_varid(cdfid,"windSpeedStdDev",&sigma_uv_id);
ier += nc_inq_varid(cdfid,"wStdDev",&sigma_w_id);
ier += nc_inq_varid(cdfid,"levelMode",&levelMode_id);

ier += nc_inq_varid(cdfid,"windSpeedSfc",&sfc_sped_id);
ier += nc_inq_varid(cdfid,"windDirSfc",&sfc_drct_id);
ier += nc_inq_varid(cdfid,"pressure",&sfc_pres_id);
ier += nc_inq_varid(cdfid,"temperature",&sfc_temp_id);
ier += nc_inq_varid(cdfid,"relHumidity",&sfc_relh_id);
ier += nc_inq_varid(cdfid,"rainRate",&sfc_rain_id);
ier += nc_get_att_float(cdfid,sfc_sped_id,"_FillValue",&sfill);
ier += nc_get_att_float(cdfid,sfc_drct_id,"_FillValue",&dfill);
ier += nc_get_att_float(cdfid,sfc_pres_id,"_FillValue",&pfill);
ier += nc_get_att_float(cdfid,sfc_temp_id,"_FillValue",&tfill);
ier += nc_get_att_float(cdfid,sfc_relh_id,"_FillValue",&rfill);
ier += nc_get_att_float(cdfid,sfc_rain_id,"_FillValue",&rrfill);

if(ier != 0)
   {
   uerror("could not get station information\0");
   *iret = -1;
   return(NULL);
   }

ier = nc_inq_vardimid(cdfid,staName_id,tmpint);
ier += nc_inq_dimlen(cdfid,tmpint[1],&namelen);

tmpint[0] = 0;tmpint[1] = 0;
ier += nc_inq_var(cdfid,wmoStaNum_id,NULL, &xtype, &nvdims, tmpint, &nvatts);
ier += nc_inq_dimlen(cdfid,tmpint[0],&dimsiz);
if(ier == 0)
   unlimsiz = dimsiz;
   for(i=0;i<unlimsiz;i++)
      {
      var_i[0] = i; var_i[1] = 0; vc[0] = 1; vc[1] = namelen-1;
      memset(staName,'\0',20);
      ier = nc_get_vara_text(cdfid,staName_id,var_i,vc,staName);
      ier = nc_get_var1_int(cdfid,wmoStaNum_id,var_i,&wmoStaNum);
      ier = nc_get_var1_float(cdfid,staLat_id,var_i,&staLat);
      ier = nc_get_var1_float(cdfid,staLon_id,var_i,&staLon);
      ier = nc_get_var1_float(cdfid,staElev_id,var_i,&staElev);
      ier = nc_get_var1_float(cdfid,sfc_sped_id,var_i,&sfc_sped);
      ier = nc_get_var1_float(cdfid,sfc_drct_id,var_i,&sfc_drct);
      ier = nc_get_var1_float(cdfid,sfc_pres_id,var_i,&sfc_pres);
      ier = nc_get_var1_float(cdfid,sfc_temp_id,var_i,&sfc_temp);
      ier = nc_get_var1_float(cdfid,sfc_relh_id,var_i,&sfc_relh);
      ier = nc_get_var1_float(cdfid,sfc_rain_id,var_i,&sfc_rain);
      ier = nc_get_var1_double(cdfid,timeObs_id,var_i,&timeObs);
      obs_time = (time_t) timeObs;
      gmt_time = gmtime(&obs_time);
      new_time = *gmt_time;
      timestr[0] = '\0';
      strftime(timestr,80,"%Y %m %d %H %M",&new_time);
      sscanf(timestr,"%d %d %d %d %d",&year,&month,&day,&hour,&minute);
      udebug("Station %3d %8d %s = %6.2f %7.2f %5.0f %s\0",i,wmoStaNum,
         staName,staLat,staLon,staElev,timestr);

      stadat = (sta_struct *)malloc(sizeof(sta_struct));
      if(stadat == NULL)
         {
         uerror("Could not allocate station data structure\0");
         exit(-2);
         }
      stadat->wmoStaNum = wmoStaNum;
      stadat->staName = (char *)malloc(strlen(staName)+1);
      strcpy(stadat->staName,staName);
      stadat->staLat = staLat;      
      stadat->staLon = staLon;      
      stadat->staElev = staElev;      
      stadat->timeObs = timeObs;      
      stadat->year = year;
      stadat->month = month;
      stadat->day = day;
      stadat->hour = hour;
      stadat->minute = minute;
      stadat->time_interval = time_interval;
      stadat->pdata = NULL;
      stadat->rdata = NULL;
      stadat->sfc_pres = fmiss;
      stadat->sfc_temp = fmiss;
      stadat->sfc_sped = fmiss;
      stadat->sfc_drct = fmiss;
      stadat->sfc_relh = fmiss;
      stadat->sfc_rain_rate = fmiss;
      stadat->sfc_rain_amt = fmiss;
      stadat->sfc_dwpc = fmiss;
      if(sfc_pres != pfill) stadat->sfc_pres = sfc_pres;
      if(sfc_temp != tfill) stadat->sfc_temp = sfc_temp - 273.15;
      if(sfc_sped != sfill) stadat->sfc_sped = sfc_sped;
      if(sfc_drct != dfill) stadat->sfc_drct = sfc_drct;
      if(sfc_relh != rfill) stadat->sfc_relh = sfc_relh;
      if(sfc_rain != rrfill) stadat->sfc_rain_rate = sfc_rain;
      if((stadat->sfc_temp != fmiss)&&(stadat->sfc_relh != fmiss))
         {
         VAPOR_PRES(stadat->sfc_temp+273.15,&e);
         e = e * (stadat->sfc_relh / 100.);
         t_from_e(e,&stadat->sfc_dwpc);
         stadat->sfc_dwpc = stadat->sfc_dwpc - 273.15;
         }

      ier = nc_inq_var(cdfid,levels_id,NULL, &xtype, &nvdims, tmpint, &nvatts);
      if(ier == 0)
         {
         ier = nc_inq_dimlen(cdfid,tmpint[0],&dimsiz);
         stadat->numlevs = dimsiz;
         plast = stadat->pdata;
         for(j=0;j<stadat->numlevs;j++)
            {
            var_i[0] = j;
            ier = nc_get_var1_float(cdfid,levels_id,var_i,&level);
            ier = nc_get_var1_int(cdfid,levelMode_id,var_i,&levelMode);
            var_i[0] = i;
            var_i[1] = j;
            ier = nc_get_var1_float(cdfid,uwnd_id,var_i,&uwnd);
            ier = nc_get_var1_float(cdfid,vwnd_id,var_i,&vwnd);
            ier = nc_get_var1_float(cdfid,wwnd_id,var_i,&wwnd);
            ier = nc_get_var1_int(cdfid,uv_qual_id,var_i,&uv_qual);
            ier = nc_get_var1_int(cdfid,w_qual_id,var_i,&w_qual);
            ier = nc_get_var1_float(cdfid,sigma_uv_id,var_i,&sigma_uv);
            ier = nc_get_var1_float(cdfid,sigma_w_id,var_i,&sigma_w);
            plev = (prof_data *)malloc(sizeof(prof_data));
            if(plev != NULL)
               {
               plev->level = level;
               if(uwnd == ufill) uwnd = fmiss;
               if(vwnd == vfill) vwnd = fmiss;
               if(wwnd == wfill) wwnd = fmiss;
               if(uv_qual != 0) 
                  {
                  uwnd = fmiss;
                  vwnd = fmiss;
                  }
               if(w_qual != 0) wwnd = fmiss;
               if((uwnd == fmiss)||(vwnd == fmiss))
                  sigma_uv = fmiss;
               if(wwnd == fmiss) sigma_w = fmiss;
               plev->u = uwnd; plev->v = vwnd; plev->w = wwnd;
               plev->sigma_uv = sigma_uv;
               plev->sigma_w = sigma_w;
               plev->levmode = levelMode;
               plev->nextlev = NULL;
               if(plast == NULL)
                  stadat->pdata = plev;
               else
                  plast->nextlev = plev;
               plast = plev;
               }
            }
         }
      else
         stadat->numlevs = 0;

      stadat->next = head;
      head = stadat;
      }

return(head);

} 
OSErr NetCDFWindMoverCurv::TextRead(char *path, TMap **newMap, char *topFilePath) // don't want a map  
{
	// this code is for curvilinear grids
	OSErr err = 0;
	long i,j, numScanned, indexOfStart = 0;
	int status, ncid, latIndexid, lonIndexid, latid, lonid, recid, timeid, numdims;
	size_t latLength, lonLength, recs, t_len, t_len2;
	float timeVal;
	char recname[NC_MAX_NAME], *timeUnits=0, month[10];	
	char dimname[NC_MAX_NAME], s[256], topPath[256];
	WORLDPOINTFH vertexPtsH=0;
	float *lat_vals=0,*lon_vals=0,yearShift=0.;
	static size_t timeIndex,ptIndex[2]={0,0};
	static size_t pt_count[2];
	Seconds startTime, startTime2;
	double timeConversion = 1.;
	char errmsg[256] = "",className[256]="";
	char fileName[64],*modelTypeStr=0;
	Point where;
	OSType typeList[] = { 'NULL', 'NULL', 'NULL', 'NULL' };
	MySFReply reply;
	Boolean bTopFile = false, fIsNavy = false;	// for now keep code around but probably don't need Navy curvilinear wind
	//VelocityFH velocityH = 0;
	char outPath[256];
	
	if (!path || !path[0]) return 0;
	strcpy(fPathName,path);
	
	strcpy(s,path);
	SplitPathFile (s, fileName);
	strcpy(fFileName, fileName); // maybe use a name from the file
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR) 
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	// check number of dimensions - 2D or 3D
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	status = nc_inq_attlen(ncid,NC_GLOBAL,"generating_model",&t_len2);
	if (status != NC_NOERR) {fIsNavy = false; /*goto done;*/}	
	else 
	{
		fIsNavy = true;
		// may only need to see keyword is there, since already checked grid type
		modelTypeStr = new char[t_len2+1];
		status = nc_get_att_text(ncid, NC_GLOBAL, "generating_model", modelTypeStr);
		if (status != NC_NOERR) {fIsNavy = false; goto done;}	
		modelTypeStr[t_len2] = '\0';
		
		strcpy(fFileName, modelTypeStr); 
	}
	GetClassName(className);
	if (!strcmp("NetCDF Wind",className))
		SetClassName(fFileName); //first check that name is now the default and not set by command file ("NetCDF Wind")
	
	//if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "time", &recid); //Navy
		//if (status != NC_NOERR) {err = -1; goto done;}
		if (status != NC_NOERR) 
		{	status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
			if (status != NC_NOERR) {err = -1; goto done;}
		}			
	}
	/*else
	 {
	 status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
	 if (status != NC_NOERR) {err = -1; goto done;}
	 }*/
	
	//if (fIsNavy)
	status = nc_inq_varid(ncid, "time", &timeid); 
	if (status != NC_NOERR) 
	{	
		status = nc_inq_varid(ncid, "ProjectionHr", &timeid); 
		if (status != NC_NOERR) {err = -1; goto done;}
	}			
	//	if (status != NC_NOERR) {/*err = -1; goto done;*/timeid=recid;} 
	
	//if (!fIsNavy)
	//status = nc_inq_attlen(ncid, recid, "units", &t_len);	// recid is the dimension id not the variable id
	//else	// LAS has them in order, and time is unlimited, but variable/dimension names keep changing so leave this way for now
	status = nc_inq_attlen(ncid, timeid, "units", &t_len);
	if (status != NC_NOERR) 
	{
		timeUnits = 0;	// files should always have this info
		timeConversion = 3600.;		// default is hours
		startTime2 = model->GetStartTime();	// default to model start time
		//err = -1; goto done;
	}
	else
	{
		DateTimeRec time;
		char unitStr[24], junk[10];
		
		timeUnits = new char[t_len+1];
		//if (!fIsNavy)
		//status = nc_get_att_text(ncid, recid, "units", timeUnits);	// recid is the dimension id not the variable id
		//else
		status = nc_get_att_text(ncid, timeid, "units", timeUnits);
		if (status != NC_NOERR) {err = -1; goto done;} 
		timeUnits[t_len] = '\0'; // moved this statement before StringSubstitute, JLM 5/2/10
		StringSubstitute(timeUnits, ':', ' ');
		StringSubstitute(timeUnits, '-', ' ');
		StringSubstitute(timeUnits, 'T', ' ');
		StringSubstitute(timeUnits, 'Z', ' ');
		
		numScanned=sscanf(timeUnits, "%s %s %hd %hd %hd %hd %hd %hd",
						  unitStr, junk, &time.year, &time.month, &time.day,
						  &time.hour, &time.minute, &time.second) ;
		if (numScanned==5)	
		{time.hour = 0; time.minute = 0; time.second = 0; }
		else if (numScanned==7) // has two extra time entries ??	
			time.second = 0;
		else if (numScanned<8)	
		//else if (numScanned!=8)	
		{ 
			//timeUnits = 0;	// files should always have this info
			//timeConversion = 3600.;		// default is hours
			//startTime2 = model->GetStartTime();	// default to model start time
			err = -1; TechError("NetCDFWindMoverCurv::TextRead()", "sscanf() == 8", 0); goto done;
		}
		else
		{
			// code goes here, trouble with the DAYS since 1900 format, since converts to seconds since 1904
			if (time.year ==1900) {time.year += 40; time.day += 1; /*for the 1900 non-leap yr issue*/ yearShift = 40.;}
			DateToSeconds (&time, &startTime2);	// code goes here, which start Time to use ??
			if (!strcmpnocase(unitStr,"HOURS") || !strcmpnocase(unitStr,"HOUR"))
				timeConversion = 3600.;
			else if (!strcmpnocase(unitStr,"MINUTES") || !strcmpnocase(unitStr,"MINUTE"))
				timeConversion = 60.;
			else if (!strcmpnocase(unitStr,"SECONDS") || !strcmpnocase(unitStr,"SECOND"))
				timeConversion = 1.;
			else if (!strcmpnocase(unitStr,"DAYS") || !strcmpnocase(unitStr,"DAY"))
				timeConversion = 24.*3600.;
		}
	} 
	
	if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "gridy", &latIndexid); //Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimid(ncid, "gridx", &lonIndexid);	//Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		// option to use index values?
		status = nc_inq_varid(ncid, "grid_lat", &latid);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_lon", &lonid);
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	else
	{
		for (i=0;i<numdims;i++)
		{
			if (i == recid) continue;
			status = nc_inq_dimname(ncid,i,dimname);
			if (status != NC_NOERR) {err = -1; goto done;}
			if (!strncmpnocase(dimname,"X",1) || !strncmpnocase(dimname,"LON",3) || !strncmpnocase(dimname,"nx",2))
			{
				lonIndexid = i;
			}
			if (!strncmpnocase(dimname,"Y",1) || !strncmpnocase(dimname,"LAT",3) || !strncmpnocase(dimname,"ny",2))
			{
				latIndexid = i;
			}
		}
		
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_inq_varid(ncid, "LATITUDE", &latid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lat", &latid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "latitude", &latid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
		status = nc_inq_varid(ncid, "LONGITUDE", &lonid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lon", &lonid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "longitude", &lonid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
	}
	
	pt_count[0] = latLength;
	pt_count[1] = lonLength;
	vertexPtsH = (WorldPointF**)_NewHandleClear(latLength*lonLength*sizeof(WorldPointF));
	if (!vertexPtsH) {err = memFullErr; goto done;}
	lat_vals = new float[latLength*lonLength]; 
	lon_vals = new float[latLength*lonLength]; 
	if (!lat_vals || !lon_vals) {err = memFullErr; goto done;}
	status = nc_get_vara_float(ncid, latid, ptIndex, pt_count, lat_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	status = nc_get_vara_float(ncid, lonid, ptIndex, pt_count, lon_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	for (i=0;i<latLength;i++)
	{
		for (j=0;j<lonLength;j++)
		{
			//if (lat_vals[(latLength-i-1)*lonLength+j]==fill_value)	// this would be an error
			//lat_vals[(latLength-i-1)*lonLength+j]=0.;
			//if (lon_vals[(latLength-i-1)*lonLength+j]==fill_value)
			//lon_vals[(latLength-i-1)*lonLength+j]=0.;
			INDEXH(vertexPtsH,i*lonLength+j).pLat = lat_vals[(latLength-i-1)*lonLength+j];	
			INDEXH(vertexPtsH,i*lonLength+j).pLong = lon_vals[(latLength-i-1)*lonLength+j];
		}
	}
	fVertexPtsH	 = vertexPtsH;
	
	status = nc_inq_dim(ncid, recid, recname, &recs);
	if (status != NC_NOERR) {err = -1; goto done;}
	if (recs<=0) {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1; goto done;}
	
	fTimeHdl = (Seconds**)_NewHandleClear(recs*sizeof(Seconds));
	if (!fTimeHdl) {err = memFullErr; goto done;}
	for (i=0;i<recs;i++)
	{
		Seconds newTime;
		// possible units are, HOURS, MINUTES, SECONDS,...
		timeIndex = i;
		//if (!fIsNavy)
		//status = nc_get_var1_float(ncid, recid, &timeIndex, &timeVal);	// recid is the dimension id not the variable id
		//else
		status = nc_get_var1_float(ncid, timeid, &timeIndex, &timeVal);
		if (status != NC_NOERR) {err = -1; goto done;}
		newTime = RoundDateSeconds(round(startTime2+timeVal*timeConversion));
		//INDEXH(fTimeHdl,i) = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);	// which start time where?
		//if (i==0) startTime = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);
		INDEXH(fTimeHdl,i) = newTime-yearShift*3600.*24.*365.25;	// which start time where?
		if (i==0) startTime = newTime-yearShift*3600.*24.*365.25;
	}
	if (model->GetStartTime() != startTime || model->GetModelTime()!=model->GetStartTime())
	{
		if (true)	// maybe use NOAA.ver here?
		{
			short buttonSelected;
			//buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			if(!gCommandFileRun)	// also may want to skip for location files...
				buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			else buttonSelected = 1;	// TAP user doesn't want to see any dialogs, always reset (or maybe never reset? or send message to errorlog?)
			switch(buttonSelected){
				case 1: // reset model start time
					//bTopFile = true;
					model->SetModelTime(startTime);
					model->SetStartTime(startTime);
					model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
					break;  
				case 3: // don't reset model start time
					//bTopFile = false;
					break;
				case 4: // cancel
					err=-1;// user cancel
					goto done;
			}
		}
		//model->SetModelTime(startTime);
		//model->SetStartTime(startTime);
		//model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
	}
	
	fNumRows = latLength;
	fNumCols = lonLength;
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	//err = this -> SetInterval(errmsg);
	//if(err) goto done;
	
	// look for topology in the file
	// for now ask for an ascii file, output from Topology save option
	// need dialog to ask for file
	//if (fIsNavy)	// for now don't allow for wind files
	{if (topFilePath[0]) {err = ReadTopology(topFilePath,newMap); goto done;}}
	if (!gCommandFileRun)
	{
		short buttonSelected;
		buttonSelected  = MULTICHOICEALERT(1688,"Do you have an extended topology file to load?",FALSE);
		switch(buttonSelected){
			case 1: // there is an extended top file
				bTopFile = true;
				break;  
			case 3: // no extended top file
				bTopFile = false;
				break;
			case 4: // cancel
				err=-1;// stay at this dialog
				goto done;
		}
	}
	if(bTopFile)
	{
#if TARGET_API_MAC_CARBON
		mysfpgetfile(&where, "", -1, typeList,
					 (MyDlgHookUPP)0, &reply, M38c, MakeModalFilterUPP(STDFilter));
		if (!reply.good)/* return USERCANCEL;*/
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	// if u, v input separately only do this once?
	 		goto done;
		}
		else
			strcpy(topPath, reply.fullPath);
		
#else
		where = CenteredDialogUpLeft(M38c);
		sfpgetfile(&where, "",
				   (FileFilterUPP)0,
				   -1, typeList,
				   (DlgHookUPP)0,
				   &reply, M38c,
				   (ModalFilterUPP)MakeUPP((ProcPtr)STDFilter, uppModalFilterProcInfo));
		if (!reply.good) 
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	 		/*if (err)*/ goto done;
		}
		
		my_p2cstr(reply.fName);
		
#ifdef MAC
		GetFullPath(reply.vRefNum, 0, (char *)reply.fName, topPath);
#else
		strcpy(topPath, reply.fName);
#endif
#endif		
		strcpy (s, topPath);
		err = ReadTopology(topPath,newMap);	
		goto done;
	}
	
	/*if (recs>0)
		err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
	else {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1;}
	if(err) goto done;*/
	err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
	//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	
done:
	if (err)
	{
		printNote("Error opening NetCDF wind file");
		if(fGrid)
		{
			fGrid ->Dispose();
			delete fGrid;
			fGrid = 0;
		}
		if(vertexPtsH) {DisposeHandle((Handle)vertexPtsH); vertexPtsH = 0;	fVertexPtsH	 = 0;}
	}
	
	if (timeUnits) delete [] timeUnits;
	if (lat_vals) delete [] lat_vals;
	if (lon_vals) delete [] lon_vals;
	if (modelTypeStr) delete [] modelTypeStr;
	//if (velocityH) {DisposeHandle((Handle)velocityH); velocityH = 0;}
	return err;
}
Exemple #19
0
/* -------------------------------------------------------------------- */
void ComputeStats(DATASET_INFO *set)
{
  size_t i, missCnt, len = 0;
  double y, sum, sigma;
 
  /* Read in variables units from file.
   */
  buffer[0] = '\0';

  if (set->varInfo->inVarID != COMPUTED)
    {
    nc_inq_attlen(dataFile[set->fileIndex].ncid, set->varInfo->inVarID,
						"units", (size_t *)&len);
    nc_get_att_text(dataFile[set->fileIndex].ncid, set->varInfo->inVarID,
						"units", buffer);
    buffer[len] = '\0';
    while (isspace(buffer[--len]) || buffer[len] == 0) // Strip trailing spaces.
      buffer[len] = '\0';

    if (strcmp(buffer, "C") == 0 ||
        strcmp(buffer, "deg_C") == 0)
      {
      buffer[0] = 0xb0;
      buffer[1] = 'C';
      buffer[2] = '\0';
      }
    }
  else
    strcpy(buffer, "Unknown");

  set->stats.units = buffer;

  missCnt = 0;
  sum = sigma = 0.0;
 
  set->stats.min = FLT_MAX;
  set->stats.max = -FLT_MAX;
 
  for (i = 0; i < set->nPoints; ++i)
    {
    if (isMissingValue((y = set->data[i]), set->missingValue) ||
        y < set->stats.outlierMin || y > set->stats.outlierMax)
      {
      ++missCnt;
      continue;
      }
 
    set->stats.min = std::min(set->stats.min, y);
    set->stats.max = std::max(set->stats.max, y);

    sum += y;
    }
 
  if (set->nPoints == missCnt)
    {
    set->stats.mean = 0.0;
    set->stats.min = 0.0;
    set->stats.max = 0.0;
    }
  else
    {
    set->stats.nPoints = set->nPoints - missCnt;
    set->stats.mean = sum / set->stats.nPoints;
    }

  for (i = 0; i < set->nPoints; ++i)
    if (!isMissingValue((y = set->data[i]), set->missingValue) ||
        y < set->stats.outlierMin || y > set->stats.outlierMax)
      sigma += pow(y - set->stats.mean, 2.0);
 
  set->stats.variance = sigma / (set->stats.nPoints - 1);
  set->stats.sigma = (float)sqrt(sigma / (set->stats.nPoints - 1));

}   /* END COMPUTESTATS */
OSErr NetCDFWindMoverCurv::ReadTimeData(long index,VelocityFH *velocityH, char* errmsg) 
{
	OSErr err = 0;
	long i,j;
	char path[256], outPath[256]; 
	char *velUnits=0;
	int status, ncid, numdims;
	int wind_ucmp_id, wind_vcmp_id, angle_id, uv_ndims;
	static size_t wind_index[] = {0,0,0,0}, angle_index[] = {0,0};
	static size_t wind_count[4], angle_count[2];
	size_t velunit_len;
	float *wind_uvals = 0,*wind_vvals = 0, fill_value=-1e-72, velConversion=1.;
	short *wind_uvals_Navy = 0,*wind_vvals_Navy = 0, fill_value_Navy;
	float *angle_vals = 0;
	long totalNumberOfVels = fNumRows * fNumCols;
	VelocityFH velH = 0;
	long latlength = fNumRows;
	long lonlength = fNumCols;
	float scale_factor = 1.,angle = 0.,u_grid,v_grid;
	Boolean bRotated = true, fIsNavy = false, bIsNWSSpeedDirData = false;
	
	errmsg[0]=0;
	
	strcpy(path,fPathName);
	if (!path || !path[0]) return -1;
	
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR)
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	wind_index[0] = index;	// time 
	wind_count[0] = 1;	// take one at a time
	if (numdims>=4)	// should check what the dimensions are, CO-OPS uses sigma
	{
		wind_count[1] = 1;	// depth
		wind_count[2] = latlength;
		wind_count[3] = lonlength;
	}
	else
	{
		wind_count[1] = latlength;	
		wind_count[2] = lonlength;
	}
	angle_count[0] = latlength;
	angle_count[1] = lonlength;
	
	//wind_count[0] = latlength;		// a fudge for the PWS format which has u(lat,lon) not u(time,lat,lon)
	//wind_count[1] = lonlength;
	
	if (fIsNavy)
	{
		// need to check if type is float or short, if float no scale factor?
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		
		angle_vals = new float[latlength*lonlength]; 
		if(!angle_vals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_gridu", &wind_ucmp_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "air_gridv", &wind_vcmp_id);	
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "scale_factor", &scale_factor);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_orient", &angle_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, angle_id, angle_index, angle_count, angle_vals);
		if (status != NC_NOERR) {/*err = -1; goto done;*/bRotated = false;}
	}
	else
	{
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_u", &wind_ucmp_id);
		if (status != NC_NOERR)
		{
			status = nc_inq_varid(ncid, "u", &wind_ucmp_id);
			if (status != NC_NOERR)
			{
				status = nc_inq_varid(ncid, "U", &wind_ucmp_id);
				if (status != NC_NOERR)
				{
					status = nc_inq_varid(ncid, "WindSpd_SFC", &wind_ucmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
					bIsNWSSpeedDirData = true;
				}
				//{err = -1; goto done;}
			}
			//{err = -1; goto done;}
		}
		if (bIsNWSSpeedDirData)
		{
			status = nc_inq_varid(ncid, "WindDir_SFC", &wind_vcmp_id);
			if (status != NC_NOERR)
			{err = -2; goto done;}
		}
		else
		{
			status = nc_inq_varid(ncid, "air_v", &wind_vcmp_id);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "v", &wind_vcmp_id);
				if (status != NC_NOERR) 
				{
					status = nc_inq_varid(ncid, "V", &wind_vcmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
				}
				//{err = -1; goto done;}
			}
		}
		
		status = nc_inq_varndims(ncid, wind_ucmp_id, &uv_ndims);
		if (status==NC_NOERR){if (uv_ndims < numdims && uv_ndims==3) {wind_count[1] = latlength; wind_count[2] = lonlength;}}	// could have more dimensions than are used in u,v
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		if (status != NC_NOERR) 
		{
			status = nc_get_att_float(ncid, wind_ucmp_id, "Fill_Value", &fill_value);
			if (status != NC_NOERR)
			{
				status = nc_get_att_float(ncid, wind_ucmp_id, "fillValue", &fill_value);// nws 2.5km
				if (status != NC_NOERR)
				{
					status = nc_get_att_float(ncid, wind_ucmp_id, "missing_value", &fill_value);
				}
				/*if (status != NC_NOERR)*//*err = -1; goto done;*/}}	// don't require
		//if (status != NC_NOERR) {err = -1; goto done;}	// don't require
	}	
	
	status = nc_inq_attlen(ncid, wind_ucmp_id, "units", &velunit_len);
	if (status == NC_NOERR)
	{
		velUnits = new char[velunit_len+1];
		status = nc_get_att_text(ncid, wind_ucmp_id, "units", velUnits);
		if (status == NC_NOERR)
		{
			velUnits[velunit_len] = '\0'; 
			if (!strcmpnocase(velUnits,"knots"))
				velConversion = KNOTSTOMETERSPERSEC;
			else if (!strcmpnocase(velUnits,"m/s"))
				velConversion = 1.0;
		}
	}
	
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	velH = (VelocityFH)_NewHandleClear(totalNumberOfVels * sizeof(VelocityFRec));
	if (!velH) {err = memFullErr; goto done;}
	//for (i=0;i<totalNumberOfVels;i++)
	for (i=0;i<latlength;i++)
	{
		for (j=0;j<lonlength;j++)
		{
			if (wind_uvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (wind_vvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_uvals[(latlength-i-1)*lonlength+j])) 
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_vvals[(latlength-i-1)*lonlength+j])) 
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;

			if (fIsNavy)
			{
				u_grid = (float)wind_uvals[(latlength-i-1)*lonlength+j];
				v_grid = (float)wind_vvals[(latlength-i-1)*lonlength+j];
				if (bRotated) angle = angle_vals[(latlength-i-1)*lonlength+j];
				INDEXH(velH,i*lonlength+j).u = u_grid*cos(angle*PI/180.)-v_grid*sin(angle*PI/180.);
				INDEXH(velH,i*lonlength+j).v = u_grid*sin(angle*PI/180.)+v_grid*cos(angle*PI/180.);
			}
			else if (bIsNWSSpeedDirData)
			{
				//INDEXH(velH,i*lonlength+j).u = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				// since direction is from rather than to need to switch the sign
				//INDEXH(velH,i*lonlength+j).u = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				INDEXH(velH,i*lonlength+j).u = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				INDEXH(velH,i*lonlength+j).v = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
			}
			else
			{
				// Look for a land mask, but do this if don't find one - float mask(lat,lon) - 1,0 which is which?
				//if (wind_uvals[(latlength-i-1)*lonlength+j]==0. && wind_vvals[(latlength-i-1)*lonlength+j]==0.)
				//wind_uvals[(latlength-i-1)*lonlength+j] = wind_vvals[(latlength-i-1)*lonlength+j] = 1e-06;
				
				// just leave fillValue as velocity for new algorithm - comment following lines out
				// should eliminate the above problem, assuming fill_value is a land mask
				// leave for now since not using a map...use the entire grid
				/////////////////////////////////////////////////
				
				INDEXH(velH,i*lonlength+j).u = /*KNOTSTOMETERSPERSEC**/velConversion*wind_uvals[(latlength-i-1)*lonlength+j];	// need units
				INDEXH(velH,i*lonlength+j).v = /*KNOTSTOMETERSPERSEC**/velConversion*wind_vvals[(latlength-i-1)*lonlength+j];
			}
		}
	}
	*velocityH = velH;
	fFillValue = fill_value;
	
	fWindScale = scale_factor;	// hmm, this forces a reset of scale factor each time, overriding any set by hand
	
done:
	if (err)
	{
		if (err==-2)
			strcpy(errmsg,"Error reading wind data from NetCDF file");
		else
			strcpy(errmsg,"Error reading wind direction data from NetCDF file");
		// We don't want to put up an error message here because it can lead to an infinite loop of messages.
		//printNote("Error opening NetCDF file");
		if(velH) {DisposeHandle((Handle)velH); velH = 0;}
	}
	if (wind_uvals) {delete [] wind_uvals; wind_uvals = 0;}
	if (wind_vvals) {delete [] wind_vvals; wind_vvals = 0;}
	if (angle_vals) {delete [] angle_vals; angle_vals = 0;}
	return err;
}
Exemple #21
0
void process_auswave(e *E){

  // netcdf vars
  int ncid;
  int varid;
  int retval;
  size_t attlen = 0;
  size_t from[3];
  size_t to[3];

  // for time conversion
  static char *calendar = "Standard";
  ut_system *u_system;
  double sec;
  int ierr, yr, mo, day, hr, min;

  int i,j,t;
  int count;


  // read in the auswave data so we can estimate wave setup
  //time = UNLIMITED ; // (192 currently)
  //lat = 411 ;
  //lon = 441 ;
  // open the file
  if((retval = nc_open(E->wave_input, NC_NOWRITE, &ncid)))
          fail("failed to open wave setup input file: error is %d\n",retval);

  // get the time data
  if((retval = nc_inq_dimid(ncid, "time", &varid)))
          fail("failed to get auswave dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nTimeWaves)))
          fail("failed to get auswave lat dimlen: error is %d\n",retval);

  //printf("aus waves_times = %zu\n", E->nTimeWaves);

  // get the auswave lat data
  if((retval = nc_inq_dimid(ncid, "lat", &varid)))
          fail("failed to get auswave lat dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nLatWaves)))
          fail("failed to get auswave lat dimlen: error is %d\n",retval);

  //printf("auswave lat = %zu\n", E->nLatWaves);

  // get the auswave lon data
  if((retval = nc_inq_dimid(ncid, "lon", &varid)))
          fail("failed to get auswave lon dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nLonWaves)))
          fail("failed to get auswave lon dimlen: error is %d\n",retval);

  //printf("auswave lat = %zu\n", E->nLonWaves);

  // process spatial dimensions
  // malloc room for the dim variable arrays
  E->wavesLat = malloc(E->nLatWaves*sizeof(double));
  E->wavesLon = malloc(E->nLonWaves*sizeof(double));

  nc_inq_varid(ncid, "lat", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesLat[0])))
          fail("failed to read waves lat data: error is %d\n", retval);

  //printf("waves lat[0] = %f\n", E->wavesLat[0]);
  nc_inq_varid(ncid, "lon", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesLon[0])))
          fail("failed to read waves lon data: error is %d\n", retval);

  //printf("waves lon[0] = %f\n", E->wavesLon[0]);

  // find the dimension indexes that cover the spatial region we need
  int lat_end;
  double dLatWaves, dLonWaves; // grid spacings for lat, lon for auswave
  dLatWaves = fabs(E->wavesLat[1] - E->wavesLat[0])*2.0;
  dLonWaves = fabs(E->wavesLon[1] - E->wavesLon[0])*2.0;
  for(i=0; i<E->nLatWaves; i++) {
          if(E->wavesLat[i] > (E->roms_min_lat-dLatWaves)) // greater than because auswave lat is monotonically decreasing
                  lat_end = i;
  }
  int lat_start;
  for(i=E->nLatWaves-1; i>=0; i--) {
          if(E->wavesLat[i] < (E->roms_max_lat+dLatWaves)) // less than because auswave lat is monotonically decreasing
                  lat_start = i;
  }
  //printf("wave data start lat = %f (%d), end lat = %f (%d)\n", E->wavesLat[lat_start],lat_start, E->wavesLat[lat_end],lat_end);
  int lon_start;
  for(i=0; i<E->nLonWaves; i++) {
          if(E->wavesLon[i] < (E->roms_min_lon-dLonWaves))
                  lon_start = i;
  }
  int lon_end;
  for(i=E->nLonWaves-1; i>=0; i--) {
          if(E->wavesLon[i] > (E->roms_max_lon+dLonWaves))
                  lon_end = i;
  }

  //printf("wave data start lon = %f, end lon = %f\n", E->wavesLon[lon_start], E->wavesLon[lon_end]);

  // TODO: add some error checking to the bounds code.
  // for example, if the spatial extent does not overlap then throw an exception

  // now just read in what we want from the files

  // reading in the whole dataset to avoid gaps in the interpolation
  lat_start = 0;
  lat_end = E->nLatWaves-1;
  lon_start = 0;
  lon_end = E->nLonWaves-1;

  free(E->wavesLat);
  free(E->wavesLon);
  E->nLatWaves = (lat_end - lat_start);
  E->nLonWaves = (lon_end - lon_start);
  E->wavesLat = malloc(E->nLatWaves*sizeof(double));
  E->wavesLon = malloc(E->nLonWaves*sizeof(double));
  // now re-read the lat and lon data
  size_t spatial_from[1], spatial_to[1];
  spatial_from[0] = lat_start;    spatial_to[0] = lat_end-lat_start;
  nc_inq_varid(ncid, "lat", &varid);
  if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLat[0])))
          fail("failed to read waves lat data: error is %d\n", retval);
  spatial_from[0] = lon_start;    spatial_to[0] = lon_end-lon_start;
  nc_inq_varid(ncid, "lon", &varid);
  if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLon[0])))
          fail("failed to read waves lon data: error is %d\n", retval);

  // process time
  E->wavesTime = malloc(E->nTimeWaves*sizeof(double));
  // read the data from the waves output file
  nc_inq_varid(ncid, "time", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesTime[0])))
          fail("failed to read auswave time data: error is %d\n", retval);

  // normalize the time information between the roms_his file
  // and the tide data file
  // get everything in ROMS ocean_time
  // get the time metadata units
  nc_inq_attlen (ncid, varid, "units", &attlen);
  E->waves_time_units = (char *) malloc(attlen + 1); /* + 1 for trailing null */
  E->waves_time_units[attlen] = '\x0';
  nc_get_att_text(ncid, varid, "units", E->waves_time_units);
  //printf("waves time units = %s\n", E->waves_time_units);

  //printf("wavesTime[0] = %f\n", E->wavesTime[0]);
  // Make the Calendar calls
  //tval = 86460.0;	/* in seconds, this is 1 day and 1 minute */
  //tval = 8580;


  // Parse the units strings
  if( (E->waves_ref_time = ut_parse( E->u_system, E->waves_time_units, UT_ASCII )) == NULL ) {
          fprintf( stderr, "Error parsing units string \"%s\"\n", E->waves_time_units );
          exit(-1);
  }

  /*
     if( (ierr = utCalendar2_cal( E->wavesTime[0], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, calendar )) != 0 ) {
        fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
        exit(-1);
        }
     printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec );
   */

  // put the waves time on the same time units as the roms time
  for(t=0; t<E->nTimeWaves; t++) {

          //printf("PRE: waveTimes[t] = %f  ", E->wavesTime[t]);
          // convert tide time into year, month, day, hour, minute and seconds
          if( (ierr = utCalendar2_cal( E->wavesTime[t], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, E->calendar )) != 0 ) {
                  fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
                  exit(-1);
          }
          //printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec );

          // convert this date to be on the same units as the roms time
          if( (ierr = utInvCalendar2_cal( yr, mo, day, hr, min, sec, E->roms_ref_time, &E->wavesTime[t], E->calendar )) != 0 ) {
                  fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
                  exit(-1);
          }
          //printf( "POST: %04d-%02d-%02d %02d:%02d:%06.3lf is %lf %s in the %s calendar\n",
          //	yr, mo, day, hr, min, sec, E->wavesTime[t], E->roms_time_units, E->calendar );
  }


  // find the index bounds where the waves time overlaps the roms time
  // the waves times should fully cover the roms times
  E->waves_start_time_index = -1;
  E->start_time_roms = E->romsTime[0];

  // get the time start index for the tide file
  for(t=0; t<E->nTimeWaves; t++) {
          if(E->wavesTime[t]<=E->start_time_roms)
                  E->waves_start_time_index = t;
  }
  if(E->waves_start_time_index == -1) {
          fprintf(stderr,"couldn't find a matching start time in the waves file.\n");
          fprintf(stderr,"check to make sure the waves file times sufficiently overlap\n");
          fprintf(stderr,"the ROMS times.\n\n");
          exit(1);
  }

  // get the end index for the tide file
  E->waves_end_time_index = -1;
  E->end_time_roms = E->romsTime[E->nTimeRoms-1];
  for(t=E->nTimeWaves-1; t>=0; t--) {
          //printf("t = %d, wave_time = %f\n",t,E->wavesTime[t]);
          if(E->wavesTime[t] >= E->end_time_roms)
                  E->waves_end_time_index = t;
  }

  if(E->waves_end_time_index == -1) {
          fprintf(stderr,"couldn't find a matching end time in the waves file.\n");
          fprintf(stderr,"check to make sure the wave file times sufficiently overlap\n");
          fprintf(stderr,"the ROMS times.\n\n");
          fprintf(stderr,"end time ROMS = %f\n", E->end_time_roms);
          fprintf(stderr,"end time waves = %f\n", E->wavesTime[E->nTimeWaves-1]);
          exit(1);
  }

  //printf("start index = %d\n", E->waves_start_time_index);
  //printf("end index = %d\n", E->waves_end_time_index);
  E->nTimeWavesSubset = (E->waves_end_time_index - E->waves_start_time_index)+1;
  // malloc enough room for the variable arrays
  //sig_wav_ht(time, lat, lon)
  E->Hs = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);
  E->Tp = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);

  // make the time vector for the output file
  E->waves_interp_time = malloc(E->nTimeWavesSubset*sizeof(double));
  count=0;
  for(t=E->waves_start_time_index; t<=E->waves_end_time_index; t++) {
          E->waves_interp_time[count] = E->wavesTime[t];
          count++;
  }


  // get the sig wave height
  nc_inq_varid(ncid, "sig_wav_ht", &varid);
  //if((retval = nc_get_var_double(ncid, varid, &E->Hs[0][0][0])))
  //	fail("failed to read waves setup data: error is %d\n", retval);

  from[0] = E->waves_start_time_index;    to[0] = E->nTimeWavesSubset;
  from[1] = lat_start;                    to[1] = lat_end - lat_start;
  from[2] = lon_start;                    to[2] = lon_end - lon_start;
  if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Hs[0][0][0])))
          fail("failed to read waves Hs data: error is %d\n", retval);

  //printf("sig_wave_ht[0][0][0] = %f\n", E->Hs[0][0][0]);

  // get the peak period
  nc_inq_varid(ncid, "pk_wav_per", &varid);
  if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Tp[0][0][0])))
          fail("failed to read waves Hs data: error is %d\n", retval);

  //printf("pk_wav_per[0][0][0] = %f\n", E->Tp[0][0][0]);

  // close the file
  nc_close(ncid);



  // flip the auswave data so the lat vector is monotonically increasing
  double ***flipData = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);
  double  *flipLat = malloc(E->nLatWaves*sizeof(double));
  // flip the lat vector
  for(i=0; i<E->nLatWaves; i++) {
          flipLat[i] = E->wavesLat[E->nLatWaves-1-i];
  }
  // copy the flipped data back
  for(i=0; i<E->nLatWaves; i++) {
          E->wavesLat[i] = flipLat[i];
  }
  // flip the Hs data array
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          flipData[t][i][j] = E->Hs[t][E->nLatWaves-1-i][j];
                  }
          }
  }
  // copy it back
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Hs[t][i][j] = flipData[t][i][j];
                  }
          }
  }
  // flip the Tp data array
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          flipData[t][i][j] = E->Tp[t][E->nLatWaves-1-i][j];
                  }
          }
  }
  // copy it back
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Tp[t][i][j] = flipData[t][i][j];
                  }
          }
  }
  free(flipData);
  free(flipLat);

#ifdef CHECK
  // temporarily mess with this input data to check!
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Tp[t][i][j] = (double)t;
                          E->Hs[t][i][j] = (double)t;
                  }
          }
  }
#endif

  // malloc room for the output nearest neighbor interp auswave  data
  // target grid for auswave data data

  // do a natural neighbour interpolation on the tide data we just read in
  // to fill in the land masked values before interpolating onto the ROMS grid

  E->Hs_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  E->Tp_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  // just for writing the netcdf file - trash this!
  //double *time_vector = malloc(E->nTimeWavesSubset*sizeof(double));
  //printf("(E->waves_end_time_index-E->waves_start_time_index) = %d\n", E->nTimeWavesSubset);


  // set up variables for the lib-nn calls
  // nn optimized
  E->pin = malloc(E->nLonWaves * E->nLatWaves * sizeof(point));
  E->zin = malloc(E->nLonWaves * E->nLatWaves * sizeof(double));

  E->xout = malloc(E->nLonRho * E->nLatRho * sizeof(double));
  E->yout = malloc(E->nLonRho * E->nLatRho * sizeof(double));
  E->zout = malloc(E->nLonRho * E->nLatRho * sizeof(double));



  // find out how many valid data points we have
  // and setup the input array for lib-nn
  //time_vector[t] = (double)t;
  //printf("setting up source grid for nn...\n");
  E->nin = 0;
  for(i=0; i<E->nLatWaves; i++) {
          for(j=0; j<E->nLonWaves; j++) {
                  if(E->Hs[0][i][j] > -999.0) {
                          E->pin[E->nin].x = E->wavesLon[j];
                          E->pin[E->nin].y = E->wavesLat[i];
                          //E->nn_diff[E->nn_n].z = E->Hs[t][i][j];
                          //printf("i = %d, j = %d, lat = %.15g lon = %.15g Hs = %.15g\n", E->nn_diff[E->nn_n].x, E->nn_diff[E->nn_n].y, E->nn_diff[E->nn_n].z);
                          E->nin++;
                  }
          }
  }
  //printf("done\n");fflush(stdout);


  // now set up the output array for the nn interpolation
  // this is the roms grid

  E->nout = 0;
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                E->xout[E->nout] = E->lon_rho[i][j];
                E->yout[E->nout] = E->lat_rho[i][j];
                E->zout[E->nout] = NaN;
                E->nout++;
          }
  }
  //printf("done\n");fflush(stdout);

  // setup the natural neighbour interpolation
  // only need to do this once
  E->d = delaunay_build(E->nin, E->pin, 0, NULL, 0, NULL);

  // create interpolator
  E->nn = nnai_build(E->d, E->nout, E->xout, E->yout);

  // for each time level
  for(t=0; t<E->nTimeWavesSubset; t++) {
      //printf("Hs: t = %d\n",t);
          // setup nodal values for the nn interps
          E->nin = 0;
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          if(E->Hs[t][i][j] > -999.0) {
                                  E->pin[E->nin].z = E->Hs[t][i][j];
                                  E->zin[E->nin] = E->pin[E->nin].z;
                                  E->nin++;
                          }
                  }
          }

          // do the interpolation
          nnai_interpolate(E->nn, E->zin, E->zout);

          // splat interpolated values onto the roms grid and apply land-sea mask
          count = 0;
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          if(E->mask_rho[i][j] == 0){
                                  E->Hs_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                          else{
                                  E->Hs_on_roms[t][i][j] = E->zout[count];
                          }
                          count++;
                  }
          }

          /*
             // write it out to check
             //E->nn_nx * E->nn_ny, E->nn_interp,
             int lat_dimid, lon_dimid, time_dimid, dimIds[2];
             int lat_varid, lon_varid, time_varid, interp_varid;
             // create the file
             nc_create("hs_interp.nc", NC_CLOBBER, &ncid);
             // def dimensions
             nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid);
             nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid);
             // def vars
             dimIds[0] = lat_dimid;
             dimIds[1] = lon_dimid;
             //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid);
             //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid);
             nc_def_var(ncid, "hs_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid);
             nc_enddef(ncid);
             // write the data
             //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]);
             //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]);
             nc_put_var_double(ncid, interp_varid, &E->Hs_on_roms[0][0][0]);
             // close the file
             nc_close(ncid);
             exit(1);
        */

  } // end of loop over Hs time levels


  // now interp the Tp variable

  // for each time level
  for(t=0; t<E->nTimeWavesSubset; t++) {
        //printf("Tp: t = %d\n", t);
          E->nin = 0;
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          if(E->Tp[t][i][j] > -999.0) {
                                  E->pin[E->nin].z = E->Tp[t][i][j];
                                  E->zin[E->nin] = E->pin[E->nin].z;
                                  E->nin++;
                          }
                  }
          }

          // do the interpolation
          nnai_interpolate(E->nn, E->zin, E->zout);

          // splat interpolated values onto the roms grid and apply land-sea mask
          count = 0;
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          if(E->mask_rho[i][j] == 0){
                                  E->Tp_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                          else{
                                  E->Tp_on_roms[t][i][j] = E->zout[count];
                          }
                          count++;
                  }
          }

          /*
          // write it out to check
          //E->nn_nx * E->nn_ny, E->nn_interp,
          int lat_dimid, lon_dimid, time_dimid, dimIds[2];
          int lat_varid, lon_varid, time_varid, interp_varid;
          // create the file
          nc_create("tp_interp.nc", NC_CLOBBER, &ncid);
          // def dimensions
          nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid);
          nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid);
          // def vars
          dimIds[0] = lat_dimid;
          dimIds[1] = lon_dimid;
          //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid);
          //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid);
          nc_def_var(ncid, "tp_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid);
          nc_enddef(ncid);
          // write the data
          //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]);
          //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]);
          nc_put_var_double(ncid, interp_varid, &E->Tp_on_roms[0][0][0]);
          // close the file
          nc_close(ncid);
          exit(1);
          */



  } // end of loop over Tp time levels

  free(E->pin);
  free(E->zin);

  free(E->xout);
  free(E->yout);
  free(E->zout);

  free(E->d);
  free(E->nn);

  //printf("done nn interp for waves\n");

  // estimate wave setup on roms
  // setup is only calculates at the coastal points
  // to calculate setup, we need Hs, Tp and slope at coastal pointers

  // read in the slope data
  //printf("calculating wave setup...");
  get_coastal_slope(E);

  // malloc room for the setup field
  // jNOTE: fix up the size of the time dimension here!
  E->setup_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  // malloc room for the time interpolated data


  // assign closest slope value to costline derived from the roms rho_mask
  double this_time;
  double this_lat;
  double this_lon;
  int **nearest_index = malloc2d_int(E->nLonRho, E->nLatRho);

  // first get the index mapping for each coastal cell
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                  if(E->coastline_mask[i][j] == 1) { // if this point is a coastal point
                          // get longitude and latitude of the point
                          this_time = t;
                          this_lat = E->lat_rho[i][j];
                          this_lon = E->lat_rho[i][j];
                          nearest_index[i][j] = get_nearest_slope_index(E, this_lat, this_lon, E->slopeLat, E->slopeLon);
                  }
                  else{
                          //printf("fill it: i = %d, j = %d\n",i,j);
                          nearest_index[i][j] = -999;
                  }
          }
  }


  for(t=0; t<E->nTimeWavesSubset; t++) {
          //printf("#### t = %d\n",t);
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {

                          if(E->coastline_mask[i][j] == 1.0) { // if this point is a coastal point
                                  /*
                                     // get longitude and latitude of the point
                                     this_time = t;
                                     this_lat = E->lat_rho[i][j];
                                     this_lon = E->lon_rho[i][j];
                                     E->setup_on_roms[t][i][j] = get_nearest_setup(E, this_time, this_lat, this_lon, E->setup, E->wavesLat, E->wavesLon);
                                     //exit(1);
                                   */
                                   // some cases for Hs and Tp are zero.
                                   // don't call get_setup() for these because it will divide by zero
                                  if( (E->Hs_on_roms[t][i][j] == 0.0) || (E->Tp_on_roms[t][i][j] == 0.0))
                                    E->setup_on_roms[t][i][j] = 0.0;
                                  else
                                    E->setup_on_roms[t][i][j] = get_setup(E->Hs_on_roms[t][i][j], E->Tp_on_roms[t][i][j], E->slope[nearest_index[i][j]]);

              #ifdef CHECK
                                  // temporarily splat with Hs to check
                                  E->setup_on_roms[t][i][j] = E->Hs_on_roms[t][i][j];
              #endif
                          }
                          else{
                                  //printf("fill it: i = %d, j = %d\n",i,j);
                                  E->setup_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                  }
          }
  }
  //printf("...done\n");

  // time interpolate the wavesetup data onto the roms time vector
  //printf("creating %d interpolated time levels for the setup field\n", E->nTimeRoms);
  E->setup_on_roms_time_interp = malloc3d_double(E->nTimeRoms, E->nLonRho, E->nLatRho);
  // initialize this array
  for(t=0; t<E->nTimeRoms; t++) {
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          E->setup_on_roms_time_interp[t][i][j] = NC_FILL_DOUBLE;
                  }
          }
  }
  // target time vector = E->romsTime
  // source time vector = E->wavesTime
  // y value vector
  double *ypts = malloc(E->nTimeWavesSubset*sizeof(double));
  double *interp_y = malloc(E->nTimeRoms*sizeof(double));
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                  if(E->setup_on_roms[0][i][j] != NC_FILL_DOUBLE) {
                          for(t=0; t<E->nTimeWavesSubset; t++) {
                                  // get the wave setup vector at this location
                                  ypts[t] = E->setup_on_roms[t][i][j];
                          }
                          time_interp_field(&E->wavesTime[E->waves_start_time_index], &ypts[0], E->nTimeWavesSubset, &E->romsTime[0], &interp_y[0], E->nTimeRoms);

                          // now put this data into the time interp array
                          for(t=0; t<E->nTimeRoms; t++) {
                                  // get the wave setup vector at this location
                                  E->setup_on_roms_time_interp[t][i][j] = interp_y[t];
                          }
                  }
          }
  }
  //printf("done\n");
  free(ypts);
  free(interp_y);

  free(E->Hs);
  free(E->Tp);
  free(E->Hs_on_roms);
  free(E->Tp_on_roms);
  free(E->wavesLon);
  free(E->wavesLat);
  free(E->setup_on_roms);

  free(E->slope);
  free(E->slopeLat);
  free(E->slopeLon);
}
Exemple #22
0
int ex_get_block_param( int exoid,
			ex_block *block )
{
  int dimid, connid, blk_id_ndx;
  size_t len, i;
  char  errmsg[MAX_ERR_LENGTH];
  int status;
  const char* dnument;
  const char* dnumnod;
  const char* dnumedg;
  const char* dnumfac;
  const char* dnumatt;
  const char* ablknam;
  const char* vblkcon;

  struct ex_file_item* file = ex_find_file_item(exoid);
  if (!file ) {
    char errmsg[MAX_ERR_LENGTH];
    exerrval = EX_BADFILEID;
    sprintf(errmsg,"Error: unknown file id %d in ex_get_block_param().",exoid);
    ex_err("ex_get_block_param",errmsg,exerrval);
  }
  
  exerrval = 0;

  /* First, locate index of element block id in VAR_ID_EL_BLK array */
  blk_id_ndx = ex_id_lkup(exoid,block->type,block->id);
  if (exerrval != 0)  {
    strcpy(block->topology, "NULL");     	/* NULL element type name */
    block->num_entry = 0;  /* no elements            */
    block->num_nodes_per_entry = 0;   /* no nodes               */
    block->num_edges_per_entry = 0;
    block->num_faces_per_entry = 0;
    block->num_attribute = 0;    /* no attributes          */
    if (exerrval == EX_NULLENTITY) {    /* NULL element block?    */
      return (EX_NOERR);
    } 
      sprintf(errmsg,
	      "Error: failed to locate %s id  %"PRId64" in id array in file id %d",
	      ex_name_of_object(block->type), block->id,exoid);
      ex_err("ex_get_block_param",errmsg,exerrval);
      return (EX_FATAL);
    
  }

  switch (block->type) {
  case EX_EDGE_BLOCK:
    dnument = DIM_NUM_ED_IN_EBLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_ED(blk_id_ndx);
    dnumedg = 0;
    dnumfac = 0;
    dnumatt = DIM_NUM_ATT_IN_EBLK(blk_id_ndx);
    vblkcon = VAR_EBCONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  case EX_FACE_BLOCK:
    dnument = DIM_NUM_FA_IN_FBLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_FA(blk_id_ndx);
    dnumedg = 0; /* it is possible this might be non-NULL some day */
    dnumfac = 0;
    dnumatt = DIM_NUM_ATT_IN_FBLK(blk_id_ndx);
    vblkcon = VAR_FBCONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  case EX_ELEM_BLOCK:
    dnument = DIM_NUM_EL_IN_BLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_EL(blk_id_ndx);
    dnumedg = DIM_NUM_EDG_PER_EL(blk_id_ndx);
    dnumfac = DIM_NUM_FAC_PER_EL(blk_id_ndx);
    dnumatt = DIM_NUM_ATT_IN_BLK(blk_id_ndx);
    vblkcon = VAR_CONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  default:
    exerrval = EX_BADPARAM;
    sprintf( errmsg, "Bad block type parameter (%d) specified for file id %d.",
	     block->type, exoid );
    return (EX_FATAL);
  }

  /* inquire values of some dimensions */
  if ((status = nc_inq_dimid (exoid, dnument, &dimid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to locate number of entities in %s  %"PRId64" in file id %d",
	    ex_name_of_object(block->type),block->id,exoid);
    ex_err("ex_get_block_param",errmsg, exerrval);
    return(EX_FATAL);
  }
  
  if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
	    "Error: failed to get number of %ss in block  %"PRId64" in file id %d",
	    ex_name_of_object(block->type),block->id, exoid);
    ex_err("ex_get_block_param",errmsg, exerrval);
    return(EX_FATAL);
  }
  block->num_entry = len;

  if ((status = nc_inq_dimid (exoid, dnumnod, &dimid)) != NC_NOERR) {
    /* undefined => no node entries per element */
    len = 0;
  } else {
    if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get number of nodes/entity in %s  %"PRId64" in file id %d",
	      ex_name_of_object(block->type),block->id, exoid);
      ex_err("ex_get_block_param",errmsg, exerrval);
      return(EX_FATAL);
    }
  }
  block->num_nodes_per_entry = len;

  if (!file->has_edges || block->type != EX_ELEM_BLOCK) {
    block->num_edges_per_entry = 0;
  } else {
    if ((status = nc_inq_dimid (exoid, dnumedg, &dimid)) != NC_NOERR) {
      /* undefined => no edge entries per element */
      len = 0;
    } else {
      if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get number of edges/entry in %s  %"PRId64" in file id %d",
		ex_name_of_object(block->type),block->id, exoid);
	ex_err("ex_get_block_param",errmsg, exerrval);
	return(EX_FATAL);
      }
    }
    block->num_edges_per_entry = len;
  }

  if (!file->has_faces || block->type != EX_ELEM_BLOCK ) {
    block->num_faces_per_entry = 0;
  } else {
    if ((status = nc_inq_dimid (exoid, dnumfac, &dimid)) != NC_NOERR) {
      /* undefined => no face entries per element */
      len = 0;
    } else {
      if ((status = nc_inq_dimlen(exoid, dimid, &len)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get number of faces/entity in %s  %"PRId64" in file id %d",
		ex_name_of_object(block->type),block->id, exoid);
	ex_err("ex_get_block_param",errmsg, exerrval);
	return(EX_FATAL);
      }
    }
    block->num_faces_per_entry = len;
  }

  if ((status = nc_inq_dimid (exoid, dnumatt, &dimid)) != NC_NOERR) {
    /* dimension is undefined */
    block->num_attribute = 0;
  } else {
    if ((status = nc_inq_dimlen(exoid, dimid, &len)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get number of attributes in %s  %"PRId64" in file id %d",
	      ex_name_of_object(block->type),block->id, exoid);
      ex_err("ex_get_block_param",errmsg, exerrval);
      return(EX_FATAL);
    }
    block->num_attribute = len;
  }

  if (block->num_nodes_per_entry > 0) {
    ; /* Do nothing, vblkcon should be correctly set already */
  } else if (block->num_edges_per_entry > 0) {
    vblkcon = VAR_EBCONN(blk_id_ndx);
  } else if (block->num_faces_per_entry > 0) {
    vblkcon = VAR_FCONN(blk_id_ndx);
  }

  if (vblkcon) {
    /* look up connectivity array for this element block id */
    if ((status = nc_inq_varid (exoid, vblkcon, &connid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to locate connectivity array for %s  %"PRId64" in file id %d",
	      ex_name_of_object(block->type), block->id,exoid);
      ex_err("ex_get_block_param",errmsg, exerrval);
      return(EX_FATAL);
    }
    
    if ((status = nc_inq_attlen (exoid, connid, ablknam, &len)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get %s  %"PRId64" type in file id %d",
	      ex_name_of_object(block->type), block->id,exoid);
      ex_err("ex_get_block_param",errmsg, exerrval);
      return(EX_FATAL);
    }
    
    if (len > (MAX_STR_LENGTH+1)) {
      len = MAX_STR_LENGTH;
      sprintf (errmsg,
	       "Warning: %s  %"PRId64" type will be truncated to %ld chars", 
	       ex_name_of_object(block->type), block->id, (long)len);
      ex_err("ex_get_block_param",errmsg,EX_MSG);
    }
    
    for (i=0; i < MAX_STR_LENGTH+1; i++) {
      block->topology[i] = '\0';

    /* get the element type name */
    
}if ((status = nc_get_att_text (exoid, connid, ablknam, block->topology)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,"Error: failed to get %s  %"PRId64" type in file id %d",
	      ex_name_of_object(block->type), block->id, exoid);
      ex_err("ex_get_block_param",errmsg, exerrval);
      return(EX_FATAL);
    }
    
    /* get rid of trailing blanks */
    ex_trim_internal(block->topology);
  }
  return (EX_NOERR);
}
Exemple #23
0
bool NCaxisInitialize (int ncid, NCaxis_p axis, NCaxisType axisType, ut_system *utSystem) {
	int status;
	int varid;
	int ndims;
	size_t attlen, i;
	char text [NC_MAX_NAME + 1];
	double interval;
	bool doUnits = true;

	switch (axis->AxisType = axisType) {
	case NCaxisX:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"x")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"X")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing x axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	case NCaxisY:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"y")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"Y")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing y axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	case NCaxisZ:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"z")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"Z")) == CMfailed)) {
			axis->Dimid = 0;
			if (((axis->Data   = (double *) malloc (sizeof (double)))     == (double *) NULL) ||
				((axis->Bounds = (double *) malloc (sizeof (double) * 2)) == (double *) NULL)) {
				CMmsgPrint (CMmsgSysError, "Memory allocation error in %s:%d!\n",__FILE__,__LINE__);
				return (false);
			}
			axis->N     = 1;
			axis->Dimid = CMfailed;
			axis->Data [0] = axis->Bounds [0] = axis->Bounds [1] = 0.0;
			return (true);
		}
		break;
	case NCaxisTime:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"t"))    == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"time")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing time axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	}
	if (((status = nc_inq_varndims (ncid,varid,&ndims))           != NC_NOERR) || (ndims != 1) ||
		((status = nc_inq_vardimid (ncid,varid,&(axis->Dimid)))   != NC_NOERR) ||
	    ((status = nc_inq_dimlen   (ncid,axis->Dimid,&(axis->N))) != NC_NOERR)) {
		CMmsgPrint (CMmsgAppError,"NetCDF variable dimension inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
		return (false);
	}
	if ((status = nc_inq_attlen   (ncid,varid,NCaxisStr,&attlen)) == NC_NOERR) {
		if ((axis->Axis = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NCaxisStr,axis->Axis)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->Axis [attlen] = '\0';
	}
	if ((status = nc_inq_attlen   (ncid,varid,NClongNameStr,&attlen)) == NC_NOERR) {
		if ((axis->LongName = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NClongNameStr,axis->LongName)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->LongName [attlen] = '\0';
	}
	if ((status = nc_inq_attlen   (ncid,varid,NCstandardNameStr,&attlen)) == NC_NOERR) {
		if ((axis->StandardName = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NCstandardNameStr,axis->StandardName)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->StandardName [attlen] = '\0';
	}
	if (doUnits) {
		if ((status = nc_inq_attlen   (ncid,varid,NCunitsStr,&attlen)) == NC_NOERR) {
			if (attlen > 0) {
				if ((status = nc_get_att_text (ncid,varid,NCunitsStr,text)) != NC_NOERR) {
					CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
					return (false);
				}
				else text [attlen] = '\0';
				if ((axis->Unit = ut_parse (utSystem, ut_trim (text, UT_ASCII), UT_ASCII)) == (ut_unit *) NULL) {
					switch (ut_get_status ()) {
					case UT_BAD_ARG: CMmsgPrint (CMmsgAppError, "System or string is NULL!\n");               break;
					case UT_SYNTAX:  CMmsgPrint (CMmsgAppError, "String contained a syntax error!n");         break;
					case UT_UNKNOWN: CMmsgPrint (CMmsgAppError, "String contained an unknown identifier!\n"); break;
					default:         CMmsgPrint (CMmsgSysError, "System error in %s:%d!n",__FILE__,__LINE__);
					}
				}
			}
		}
	}
	if (((status = nc_inq_attlen   (ncid,varid,NCpositiveStr,&attlen)) == NC_NOERR) && (attlen < NC_MAX_NAME)) {
		if ((status = nc_get_att_text (ncid,varid,NCpositiveStr,text)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else text [attlen] = '\0';
		axis->Direction = strcmp (text,NCpositiveUpStr) == 0 ? NCdirUp : NCdirDown;
	}
	else axis->Direction = NCdirUp;
	if (((axis->Data   = (double *) malloc (axis->N * sizeof (double)))     == (double *) NULL) ||
	    ((axis->Bounds = (double *) malloc (axis->N * sizeof (double) * 2)) == (double *) NULL)) {
		CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
		return (false);
	}
	if ((status = nc_get_var_double (ncid,varid,axis->Data)) != NC_NOERR) {
		CMmsgPrint (CMmsgAppError,"NetCDF %s axis data loading error \"%s\" in %s:%d!\n",_NCaxisGetTypeString (axis->AxisType),nc_strerror (status),__FILE__,__LINE__);
		return (false);
	}
	if (((status = nc_inq_attlen (ncid,varid,NCboundsStr, &attlen)) == NC_NOERR) && (attlen < NC_MAX_NAME)) {
		if ((status = nc_get_att_text (ncid,varid,NCboundsStr,text)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF bounds attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else text [attlen] = '\0';
		if ((status = nc_inq_varid (ncid,text,&varid)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF bounds variable inquery error \"%s\" in %s:%d!\n",   nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_var_double (ncid,varid,axis->Bounds)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF %s axis bounds loading error \"%s\" in %s:%d!\n",_NCaxisGetTypeString (axis->AxisType),nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		
	}
	else {
		for (i = 1;i < axis->N - 1; ++i) {
			axis->Bounds [i * 2]     = (axis->Data [i]     + axis->Data [i - 1]) / 2.0;
			axis->Bounds [i * 2 + 1] = (axis->Data [i + 1] + axis->Data [i])     / 2.0;
		}
		axis->Bounds [1]         = axis->Bounds [2];
		axis->Bounds [0]         = axis->Data [0] - (axis->Bounds [1] - axis->Data [0]);
		axis->Bounds [i * 2]     = axis->Bounds [(i - 1) * 2 + 1];
		axis->Bounds [i * 2 + 1] = axis->Data [i] + (axis->Data [i]   - axis->Bounds [i * 2]);
	}
	axis->IntervalMin = axis->Bounds [i * 2 + 1] - axis->Bounds [0];
	axis->IntervalMax = 0.0;
	for (i = 0;i < axis->N; ++i) {
		interval = axis->Bounds [i * 2 + 1] - axis->Bounds [i * 2];
		axis->IntervalMin = CMmathMinimum (axis->IntervalMin,interval);
		axis->IntervalMax = CMmathMaximum (axis->IntervalMax,interval);
	}
	axis->Regular = axis->N > 1 ? CMmathEqualValues (axis->IntervalMin,axis->IntervalMax) : true;
	return (true);
}
int ex_get_elem_type (int exoid,
		      ex_entity_id elem_blk_id,
		      char *elem_type)
/*
 *      Reads the element type for a specific element block
 *           elem_type is assumed to have a length of MAX_STR_LENGTH+1
 */
{
  const char   *func_name="ex_get_elem_type";

  int     connid, el_blk_id_ndx, status;
  size_t  len;
  char    errmsg[MAX_ERR_LENGTH];

/*****************************************************************************/

  /* inquire id's of previously defined dimensions */
  if ((el_blk_id_ndx=ex_id_lkup(exoid, EX_ELEM_BLOCK, elem_blk_id)) == -1) {
    sprintf(errmsg,
            "Error: failed to find element block ID %"PRId64" in file %d",
            elem_blk_id, exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }
  
  if ((status = nc_inq_varid(exoid, VAR_CONN(el_blk_id_ndx), &connid)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to find connectivity variable in file ID %d",
            exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
   }
  
  /* get the element type name */
  if ((status = nc_inq_attlen(exoid, connid, ATT_NAME_ELB, &len)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to find attribute in file ID %d", exoid);
    ex_err(func_name, errmsg, exerrval);

    return (EX_FATAL);
  }

  if (len > (MAX_STR_LENGTH+1)) {
    exerrval = EX_MSG;
    sprintf(errmsg,
            "Error: Element type must be of length %d in file ID %d",
            (int)len, exoid);
    ex_err(func_name, errmsg, exerrval);

    return (EX_FATAL);
  }
  
  /* Make sure the end of the string is terminated with a null character */
  elem_type[MAX_STR_LENGTH] = '\0';
  
  if ((status = nc_get_att_text(exoid, connid, ATT_NAME_ELB, elem_type)) != NC_NOERR ) {
    exerrval = status;
    sprintf(errmsg, 
            "Error: failed to get attribute \"%s\" in file ID %d",
            ATT_NAME_ELB, exoid);
    ex_err(func_name, errmsg, exerrval);

    return (EX_FATAL);
  }
  return (EX_NOERR);
}
Exemple #25
0
int
main(int argc, char **argv)
{
   char *valid[] = {
       /* pressure in 23 languages */
       "\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7",
       "\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5",
       "\xe5\x8e\x8b\xe5\x8a\x9b",
       "\xe5\xa3\x93\xe5\x8a\x9b",
       "pritisak",
       "tlaku",
       "pres",
       "druk",
       "pressure",
       "paine",
       "pression",
       "Druck",
       "\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7",
       "\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5",
       "pressione",
       "\xe5\x9c\xa7\xe5\x8a\x9b",
       "\xec\x95\x95\xeb\xa0\xa5",
       "press",
       "ci\xc5\x9bnienie",
       "Press\xc3\xa3o",
       "presiune",
       "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5",
       "presi\xc3\xb3n",
       /* special characters in names, numeric characters at the start of names */
       "has blank",
       "has:colon",
       "a",
       "A",
       "0leading_numeric_char",
       "1",
       "0x123"
   };
   char *notvalid[] = {
       "-leading_special_char",
       "trailing_space ",
       "trailing_tab\t",
       "trailing_newline\n",
       "has_control_char_\a_in_name",
       "has ascii_del_\x7f_in name",
       /* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */
       "\xA0\xB0\xC0\xD0",
       "xyz\x80", 		/* unexpected continuation bytes */
       "\x80xyz",
       "xyz\xBF",
       "\xBFxyz",
       "\xC0xyz",		/* lonely start characters */
       "x\xC0yz",
       "xy\xC0z",
       "xyz\xC0",
       "\xDFxyz",
       "x\xDFyz",
       "xy\xDFz",
       "xyz\xDF",
       "\xE0xyz",
       "x\xE0yz",
       "xy\xE0z",
       "xyz\xE0",
       "\xE0\xBFxy",
       "x\xE0\xBFy",
       "xy\xE0\xBF",
       "\xEFxyz",
       "x\xEFyz",
       "xy\xEFz",
       "xyz\xEF",
       "\xEF\x80xy",
       "x\xEF\x80y",
       "xy\xEF\x80",
       "\xF0xyz",
       "x\xF0yz",
       "xy\xF0z",
       "xyz\xF0",
       "\xF7xyz",
       "x\xF7yz",
       "xy\xF7z",
       "xyz\xF7",
       "\xF8xyz",
       "x\xF8yz",
       "xy\xF8z",
       "xyz\xF8",
       "\xFBxyz",
       "x\xFByz",
       "xy\xFBz",
       "xyz\xFB",
       "\xFCxyz",
       "x\xFCyz",
       "xy\xFCz",
       "xyz\xFC",
       "\xFDxyz",
       "x\xFDyz",
       "xy\xFDz",
       "xyz\xFD",
       "\xC0\xC0xy",		/* last continuation byte missing */
       "x\xC0\xC0y",
       "xy\xC0\xC0",
       "\xDF\xDFxy",
       "x\xDF\xDFy",
       "xy\xDF\xDF",
       "\xE0\x80xy",
       "x\xE0\x80y",
       "xy\xE0\x80",
       "\xEF\x80xy",
       "x\xEF\x80y",
       "xy\xEF\x80",
       "\xF0\x80\x80x",
       "x\xF0\x80\x80",
       "\xF7\x80\x80x",
       "x\xF7\x80\x80",
       "\xF8\x80\x80\x80x",
       "x\xF8\x80\x80\x80",
       "\xFB\x80\x80\x80x",
       "x\xFB\x80\x80\x80",
       "\xFC\x80\x80\x80\x80x",
       "x\xFC\x80\x80\x80\x80",
       "\xFD\x80\x80\x80\x80x",
       "x\xFD\x80\x80\x80\x80",
       "\xFExyz",		/* impossible bytes */
       "x\xFEyz",
       "xy\xFEz",
       "xyz\xFE",
       "\xFFxyz",
       "x\xFFyz",
       "xy\xFFz",
       "xyz\xFF",
       "\xC0\xAFxy",		/* overlong sequences */
       "x\xC0\xAFy",
       "xy\xC0\xAF",
       "\xE0\x80\xAFx",
       "x\xE0\x80\xAF",
       "\xF0\x80\x80\xAFx",
       "x\xF0\x80\x80\xAF",
       "\xF8\x80\x80\x80\xAFx",
       "x\xF8\x80\x80\x80\xAF",
       "\xFC\x80\x80\x80\x80\xAFx",
       "x\xFC\x80\x80\x80\x80\xAF",
       "\xC1\xBFxy",
       "x\xC1\xBFy",
       "xy\xC1\xBF",
       "\xE0\x9F\xBFx",
       "x\xE0\x9F\xBF",
       "\xF0\x8F\xBF\xBFx",
       "x\xF0\x8F\xBF\xBF",
       "\xF8\x87\xBF\xBF\xBFx",
       "x\xF8\x87\xBF\xBF\xBF",
       "\xFC\x83\xBF\xBF\xBF\xBFx",
       "x\xFC\x83\xBF\xBF\xBF\xBF",
       "x\xC0\x80",		/* overlong NULs */
       "x\xE0\x80\x80",
       "x\xF0\x80\x80\x80",
       "x\xF8\x80\x80\x80\x80",
       "x\xFC\x80\x80\x80\x80\x80",
       /* single UTF-16 surrogates */
       "x\xED\xA0\x80",
       "x\xED\xAD\xBF",
       "x\xED\xAE\x80",
       "x\xED\xAF\xBF",
       "x\xED\xB0\x80",
       "x\xED\xBE\x80",
       "x\xED\xBF\xBF",
       "x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */
       "x\xED\xA0\x80\xED\xBF\xBF",
       "x\xED\xAD\xBF\xED\xB0\x80",
       "x\xED\xAD\xBF\xED\xBF\xBF",
       "x\xED\xAE\x80\xED\xB0\x80",
       "x\xED\xAE\x80\xED\xBF\xBF",
       "x\xED\xAF\xBF\xED\xB0\x80",
       "x\xED\xAF\xBF\xED\xBF\xBF",
       "x\xEF\xBF\xBE",		/* other illegal code positions */
       "x\xEF\xBF\xBF"
   };
   int i, j;
#define NUM_BAD (sizeof notvalid / sizeof notvalid[0])
#define NUM_GOOD (sizeof valid / sizeof valid[0])
   int ncid, dimid, varid, res;
   double attvals[] = {-2.0};
   double attvals_in[1];
#define NATTVALS (sizeof attvals / sizeof attvals[0])
   char *attstring = "text";
#define MAX_ATTSTRING_LEN 100
   char attstr_in[MAX_ATTSTRING_LEN];
   int dimids[NUM_GOOD];
   int varids[NUM_GOOD];
#if 0
   int attnums[NUM_GOOD];
#endif
   char *testfile = FILE_NAME;
   int formats[] = {
       NC_FORMAT_CLASSIC
       ,
       NC_FORMAT_64BIT
#ifdef USE_NETCDF4
       ,
       NC_FORMAT_NETCDF4
       ,
       NC_FORMAT_NETCDF4_CLASSIC
#endif	/* USE_NETCDF4 */
   };
   int num_formats = (sizeof formats) / (sizeof formats[0]);
   char *format_names[] = {
       "classic", "64-bit offset", "netCDF-4/HDF5", "netCDF-4 classic model"
   };

   printf("\n*** testing names with file %s...\n", testfile);
   for (j = 0; j < num_formats; j++)
   {
       printf("*** switching to netCDF %s format...", format_names[j]);
       nc_set_default_format(formats[j], NULL);
       if((res = nc_create(testfile, NC_CLOBBER, &ncid)))
	   ERR;

       /* Define dimensions, variables, and attributes with various
	* acceptable names */
       for (i = 0; i < NUM_GOOD; i++) {
	   if ((res = nc_def_dim(ncid, valid[i], DIMLEN, &dimid)))
	       ERR;
	   dimids[i] = dimid;
	   /* Define variable with same name */
	   if ((res = nc_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i],
				 &varid)))
	       ERR;
	   varids[i] = varid;
	   /* Define variable and global attributes with same name and value */
	   if ((res = nc_put_att_text(ncid, varid, valid[i],
				      strlen(valid[i]), valid[i])))
	       ERR;
	   if ((res = nc_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE,
					NATTVALS, attvals)))
	       ERR;
#if 0
	   attnums[i] = i;
#endif
       }

       /* Try defining dimensions, variables, and attributes with various
	* bad names and make sure these are rejected */
       for (i = 0; i < NUM_BAD; i++) {
	   if ((res = nc_def_dim(ncid, notvalid[i], DIMLEN, &dimid))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids,
				 &varid))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_put_att_text(ncid, varid, notvalid[i],
				      strlen(attstring), attstring))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE,
					NATTVALS, attvals))
	       != NC_EBADNAME) ERR;
       }
       if ((res = nc_enddef(ncid)))
	   ERR;
       if ((res = nc_close(ncid)))
	   ERR;

       /* Check it out, make sure all objects with good names were defined OK */
       if ((res = nc_open(testfile, NC_NOWRITE, &ncid)))
	   ERR;
       for (i = 0; i < NUM_GOOD; i++) {
	   size_t attlen;
	   if ((res = nc_inq_dimid(ncid, valid[i], &dimid)) ||
	       dimid != dimids[i])
	       ERR;
	   if ((res = nc_inq_varid(ncid, valid[i], &varid)) ||
	       varid != varids[i])
	       ERR;
	   res = nc_inq_attlen(ncid, varid, valid[i], &attlen);
	   if ((res = nc_get_att_text(ncid, varid, valid[i], attstr_in)))
	       ERR;
	   attstr_in[attlen] = '\0';
	   if (strcmp(valid[i], attstr_in) != 0)
	       ERR;
	   if ((res = nc_get_att_double(ncid, NC_GLOBAL, valid[i],
					attvals_in))
	       || attvals[0] != attvals_in[0])
	       ERR;
       }
       if ((res = nc_close(ncid)))
	   ERR;
/*        (void) remove(testfile); */
       SUMMARIZE_ERR;
   }
   FINAL_RESULTS;

   return 0;
}
static int open_mmtk_cdf_read(cdfdata *cdf, int conventionsknown) {
  int rc;
  size_t len; 
  mmtkdata *mmtk = &cdf->mmtk;

  /* If conventions specify MMTK then we're safe to continue */
  /* and we know what we're dealing with */
  if (conventionsknown) {
    cdf->type = CDF_TYPE_MMTK;
  }

  /* global attrib: "trajectory_type" (new format) */
  rc = nc_get_att_int(cdf->ncid, NC_GLOBAL, "trajectory_type", &mmtk->trajectorytype);
  if (rc == NC_NOERR) {
    printf("netcdfplugin) MMTK trajectory type: %d\n", mmtk->trajectorytype);
  } else {
    printf("netcdfplugin) Assuming MMTK trajectory type: %d\n", mmtk->trajectorytype);
    mmtk->trajectorytype = 0;
  }

  /* read in spatial dimension */
  rc = nc_inq_dimid(cdf->ncid, "xyz", &mmtk->xyzdimid);
  if (rc == NC_NOERR) {
    rc = nc_inq_dimlen(cdf->ncid, mmtk->xyzdimid, &mmtk->xyzdim);
    if (rc == NC_NOERR)
      printf("netcdfplugin) MMTK: xyz dimension: %ld\n", (long)mmtk->xyzdim);
    else 
      return CDF_ERR;
  } else {
    return CDF_ERR;
  }

  /* read in atom dimension */
  rc = nc_inq_dimid(cdf->ncid, "atom_number", &mmtk->atom_numberdimid); 
  if (rc == NC_NOERR) {
    rc = nc_inq_dimlen(cdf->ncid, mmtk->atom_numberdimid, &mmtk->atom_numberdim);
    if (rc == NC_NOERR) {
      printf("netcdfplugin) MMTK: atom_number dimension: %ld\n", (long)mmtk->atom_numberdim);
      cdf->natoms = mmtk->atom_numberdim; /* copy to format independent part */
    } else {
      return CDF_ERR;
    }
  } else {
    return CDF_ERR;
  }


  /* read in frame dimension */
  rc = nc_inq_dimid(cdf->ncid, "step_number", &mmtk->step_numberdimid);
  if (rc == NC_NOERR) {
    rc = nc_inq_dimlen(cdf->ncid, mmtk->step_numberdimid, &mmtk->step_numberdim);
    if (rc == NC_NOERR)
      printf("netcdfplugin) MMTK: step_number dimension: %ld\n", (long)mmtk->step_numberdim);
    else 
      return CDF_ERR;
  } else {
    return CDF_ERR;
  }


  /* read in minor step number dimension */
  rc = nc_inq_dimid(cdf->ncid, "minor_step_number", &mmtk->minor_step_numberdimid);
  if (rc == NC_NOERR) {
    rc = nc_inq_dimlen(cdf->ncid, mmtk->minor_step_numberdimid, &mmtk->minor_step_numberdim);
    if (rc == NC_NOERR)
      printf("netcdfplugin) MMTK: minor_step_number dimension: %ld\n", (long)mmtk->minor_step_numberdim);
    else 
      return CDF_ERR;
  } else if (rc == NC_EBADDIM) {
    printf("netcdfplugin) MMTK: no minor_step_number dimension\n");
    mmtk->minor_step_numberdim = 0;
  } else {
    return CDF_ERR;
  }


  /* read in description_length dimension */
  rc = nc_inq_dimid(cdf->ncid, "description_length", &mmtk->description_lengthdimid); 
  if (rc == NC_NOERR) {
    rc = nc_inq_dimlen(cdf->ncid, mmtk->description_lengthdimid, &mmtk->description_lengthdim);
    if (rc == NC_NOERR)
      printf("netcdfplugin) MMTK: description_length dimension: %ld\n", (long)mmtk->description_lengthdim);
    else
      return CDF_ERR;
  } else {
    return CDF_ERR;
  }


  /* get ID values for all of the variables we're interested in */
  rc = nc_inq_varid(cdf->ncid, "configuration", &mmtk->configuration_id);
  if (rc != NC_NOERR)
    return CDF_ERR;

  rc = nc_inq_varid(cdf->ncid, "description", &mmtk->description_id);
  if (rc != NC_NOERR)
    return CDF_ERR;

  /* check for PBC */
  rc = nc_inq_varid(cdf->ncid, "box_size", &mmtk->box_size_id);
  if (rc == NC_NOERR) {
    mmtk->has_box = 1;
    printf("netcdfplugin) MMTK: system has periodic boundary conditions\n");
  }
  else if (rc == NC_ENOTVAR)
    mmtk->has_box = 0;
  else
    return CDF_ERR;


  /* global attrib: "comment" -- optional */
  rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "comment", &len);
  if (rc == NC_NOERR && len > 0) {
    mmtk->comment = (char *) malloc((len+1) * sizeof(char));
    nc_get_att_text(cdf->ncid, NC_GLOBAL, "comment", mmtk->comment);
    mmtk->comment[len] = '\0';
    printf("netcdfplugin) MMTK: comment '%s'\n", mmtk->comment);
  } 

  /* at this point we know that this is an MMTK trajectory */
  if (!conventionsknown) {
    printf("netcdfplugin) File is an old format MMTK trajectory without conventions\n");    
    cdf->type = CDF_TYPE_MMTK;
  }

  return CDF_SUCCESS;
}
Exemple #27
0
int
check_attrs(int ncid, int obj)
{
    int attid;
    int natts = 0;
    size_t len;
    nc_type type;
    char *vlstr;
    char fixstr[10];
    int x;

    /* Check the object's attributes are OK */
    if (nc_inq_varnatts(ncid, obj, &natts )) ERR_GOTO;
    if (natts != 6) ERR_GOTO;

    if (nc_inq_attid(ncid, obj, VSTR_ATT1_NAME, &attid)) ERR_GOTO;
    if (attid != 0) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, VSTR_ATT1_NAME, &type)) ERR_GOTO;
    if (type != NC_STRING) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, VSTR_ATT1_NAME, &len)) ERR_GOTO;
    if (len != 1) ERR_GOTO;
    vlstr = NULL;
    if (nc_get_att(ncid, obj, VSTR_ATT1_NAME, &vlstr)) ERR_GOTO;
    if (NULL != vlstr) ERR_GOTO;

    if (nc_inq_attid(ncid, obj, VSTR_ATT2_NAME, &attid)) ERR_GOTO;
    if (attid != 1) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, VSTR_ATT2_NAME, &type)) ERR_GOTO;
    if (type != NC_STRING) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, VSTR_ATT2_NAME, &len)) ERR_GOTO;
    if (len != 1) ERR_GOTO;
    vlstr = NULL;
    if (nc_get_att(ncid, obj, VSTR_ATT2_NAME, &vlstr)) ERR_GOTO;
    if (NULL != vlstr) ERR_GOTO;

    if (nc_inq_attid(ncid, obj, VSTR_ATT3_NAME, &attid)) ERR_GOTO;
    if (attid != 2) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, VSTR_ATT3_NAME, &type)) ERR_GOTO;
    if (type != NC_STRING) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, VSTR_ATT3_NAME, &len)) ERR_GOTO;
    if (len != 1) ERR_GOTO;
    vlstr = NULL;
    if (nc_get_att(ncid, obj, VSTR_ATT3_NAME, &vlstr)) ERR_GOTO;
    if (strcmp(vlstr, "")) ERR_GOTO;
    free(vlstr);

    if (nc_inq_attid(ncid, obj, VSTR_ATT4_NAME, &attid)) ERR_GOTO;
    if (attid != 3) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, VSTR_ATT4_NAME, &type)) ERR_GOTO;
    if (type != NC_STRING) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, VSTR_ATT4_NAME, &len)) ERR_GOTO;
    if (len != 1) ERR_GOTO;
    vlstr = NULL;
    if (nc_get_att(ncid, obj, VSTR_ATT4_NAME, &vlstr)) ERR_GOTO;
    if (strcmp(vlstr, "foo")) ERR_GOTO;
    free(vlstr);

    if (nc_inq_attid(ncid, obj, FSTR_ATT_NAME, &attid)) ERR_GOTO;
    if (attid != 4) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, FSTR_ATT_NAME, &type)) ERR_GOTO;
    if (type != NC_CHAR) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, FSTR_ATT_NAME, &len)) ERR_GOTO;
    if (len != 10) ERR_GOTO;
    memset(fixstr, 1, sizeof(fixstr));
    if (nc_get_att(ncid, obj, FSTR_ATT_NAME, fixstr)) ERR_GOTO;
    if ('\0' != fixstr[0]) ERR_GOTO;

    if (nc_inq_attid(ncid, obj, INT_ATT_NAME, &attid)) ERR_GOTO;
    if (attid != 5) ERR_GOTO;
    if (nc_inq_atttype(ncid, obj, INT_ATT_NAME, &type)) ERR_GOTO;
    if (type != NC_INT) ERR_GOTO;
    if (nc_inq_attlen(ncid, obj, INT_ATT_NAME, &len)) ERR_GOTO;
    if (len != 1) ERR_GOTO;
    x = -1;
    if (nc_get_att(ncid, obj, INT_ATT_NAME, &x)) ERR_GOTO;
    if (0 != x) ERR_GOTO;


    return(0);

error:
    return(-1);
}
Exemple #28
0
int NETCDF_setup(coordinateInfo *trajInfo, int *actualAtoms) {
#ifdef BINTRAJ
  int err,spatial,i;
  netcdfTrajectoryInfo *NCInfo;
  char *filename;
#  ifdef MPI
  MPI_Offset ist;
#  else
  size_t ist;
#  endif

  if (prnlev>0) fprintf(stdout,"NETCDF_setup(): Setting up %s\n",trajInfo->filename);

  NCInfo=trajInfo->NCInfo;
  if (NCInfo == NULL) return 1;

  filename=trajInfo->filename;

  /* DAN ROE: For DEBUG of netcdf files, prints what vars are stored */
  if (prnlev>3) dan_netcdf_debug(NCInfo->ncid);

  /*
   *  Get global attributes (after initializing a structure to hold the data), 
   */
  trajInfo->title =           netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "title");
  trajInfo->application =     netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "application");
  trajInfo->program =         netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "program");
  trajInfo->version =         netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "programVersion");
  NCInfo->Conventions =       netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "Conventions");
  NCInfo->ConventionVersion = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "ConventionVersion");
  if (strstr(NCInfo->Conventions, "AMBER") == NULL) {
    printfone("WARNING: NetCDF file has Conventions that do not include the string \"AMBER\"\n");
  }
  if (strcmp(NCInfo->ConventionVersion, "1.0") != 0) {
    printfone("WARNING: NetCDF file has ConventionVersion differing from \"1.0\"\n");
  }

  /*
   *  get the NetCDF dimension ID's and sizes for the frames, spatial and atoms
   */
    
  NCInfo->frameDID   = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_FRAME, &(trajInfo->stop));
  NCInfo->spatialDID = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &spatial);
  NCInfo->atomDID    = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_ATOM, actualAtoms);

  if (spatial != 3) {
    printfone("ptraj cannot handle NetCDF files with other than 3 dims\n");
    return 1;
  }

  /*
   *  perform a sanity check on time variable and units.
   * DAN ROE: Should errors here really terminate ptraj?
   */
  err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_TIME, &NCInfo->timeVID);
  if (err != NC_NOERR) {
    printfone("Error: NetCDF time variable: %s", nc_strerror(err));
    return 1;
  }
  //  error(ROUTINE, "NetCDF time variable, error: %s", nc_strerror(err));

  err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->timeVID, &i);
  if ( err != NC_NOERR ) {
    printfone("Error: Getting number of time attributes in NetCDF file %s\n", filename);
    return 1;
  }
  //  error(ROUTINE, "Getting number of time attributes in NetCDF file %s\n", filename);
  if ( i != 1 ) {
    printfone("Error: Only one time attribute is expected in NetCDF file %s\n", filename);
    return 1;
  }
  //  error(ROUTINE, "Only one time attribute is expected in NetCDF file %s\n", filename);

  err =    nc_inq_attlen(NCInfo->ncid, NCInfo->timeVID, "units", &ist);
  if (err != NC_NOERR) {
    printfone("Error: Grabbing time units attribute length in NetCDF file: %s\n", 
              nc_strerror(err));
    return 1;
  }
  NCInfo->timeUnits = (char *) safe_malloc(sizeof(char) * (ist+1));

  err =    nc_get_att_text(NCInfo->ncid, NCInfo->timeVID, "units", NCInfo->timeUnits);
  if (err != NC_NOERR) {
    printfone("Error: Could not get time units from NetCDF file %s: %s", 
              filename, nc_strerror(err));
    safe_free(NCInfo->timeUnits);
    return 1;
  }
  if (strcmp("picosecond",NCInfo->timeUnits) != 0)
    printfone("WARNING: Expecting time units in picoseconds, got -%s-\n", NCInfo->timeUnits);

  err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &NCInfo->spatialVID);
  if (err != NC_NOERR) {
    printfone("Error: Getting spatialVID in the NetCDF file %s: %s\n", 
            filename, nc_strerror(err));
    return 1;
  }

  /*
   *  NETCDF: check to see what trajectory data is within the NetCDF file
   *  and perform sanity checks...
   *
   *  ARE COORDINATES PRESENT?
   */ 
    err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_COORDS, &NCInfo->coordinateVID);
    if (err != NC_NOERR) {
      printfone("Error: No coordinates are present in the NetCDF file %s\n", filename);
      return 1;
    } 

    err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->coordinateVID, &i);
    if ( err != NC_NOERR ) {
      printfone("Error: Getting number of coordinate attributes in NetCDF file %s\n", filename);
      return 1;
    }
    if ( i != 1 ) {
      printfone("Error: Only a single coordinate attribute is expected in NetCDF file %s\n", 
                filename);
      return 1;
    }

    err =    nc_inq_attlen(NCInfo->ncid, NCInfo->coordinateVID, "units", &ist);
    if (err != NC_NOERR) {
      printfone("Error: Getting coordinateVID attribute length. %s\n",nc_strerror(err));
      return 1;
    }    
    NCInfo->coordinateUnits = (char *) safe_malloc(sizeof(char) * (ist+1));

    err =    nc_get_att_text(NCInfo->ncid, NCInfo->coordinateVID, "units", NCInfo->coordinateUnits);
    if (err != NC_NOERR) {
      printfone("Error: Could not get coordinate units from NetCDF file %s", filename);
      safe_free(NCInfo->coordinateUnits);
      return 1;
    }
    if (strcmp("angstrom",NCInfo->coordinateUnits) != 0)
      printfone("WARNING: Expecting coordinate units in angstroms, got %s\n", 
                NCInfo->coordinateUnits);

  /*
   *  ARE CELL_LENGTHS (i.e. box info) PRESENT?
   */ 
    err =    nc_inq_varid(NCInfo->ncid, "cell_angles", &NCInfo->cellAngleVID);
    if ((err != NC_NOERR)&&(prnlev>0)) 
      printfone("Warning: NetCDF cell angle variable ID: %s\n", nc_strerror(err));
    err =    nc_inq_varid(NCInfo->ncid, "cell_lengths", &NCInfo->cellLengthVID);
    if ((err != NC_NOERR)&&(prnlev>0)) 
      printfone("Warning: NetCDF cell length variable ID: %s\n", nc_strerror(err));

    // Set up box information
    if (err == NC_NOERR) {
      // Angle information
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->cellAngleVID, &i);
      if ( i > 0 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->cellAngleVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->cellAngleUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err=nc_get_att_text(NCInfo->ncid, NCInfo->cellAngleVID, "units", NCInfo->cellAngleUnits);
        }
      }

      // Cell length information
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->cellLengthVID, &i);
      if ( i > 0 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->cellLengthVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->cellLengthUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err=nc_get_att_text(NCInfo->ncid, NCInfo->cellLengthVID, "units", 
                              NCInfo->cellLengthUnits);
        }
      }
      trajInfo->isBox = 1;
    } // End box information setup

  /*
   *  ARE VELOCITIES PRESENT?
   */ 

    err =    nc_inq_varid(NCInfo->ncid, "velocities", &NCInfo->velocityVID);
    if (err == NC_NOERR) {
      trajInfo->isVelocity = 1;
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->velocityVID, &i);
      if ( i > 1 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->velocityVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->velocityUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err = nc_get_att_text(NCInfo->ncid, NCInfo->velocityVID, "units", NCInfo->velocityUnits);
        }
        err = nc_get_att_double(NCInfo->ncid, NCInfo->velocityVID, "scale_factor", 
                                &NCInfo->velocityScale);
      }
    }

    /*
     * Are replica temperatures present?
     */
    err=   nc_inq_varid(NCInfo->ncid,"temp0",&NCInfo->TempVarID);
    if (err == NC_NOERR) {
      if (prnlev>0) printfone("\nNetCDF file has replica temperatures.\n");
    } else {
      if (prnlev>0) printfone("\nNetCDF file does not have replica temperatures.\n");
      NCInfo->TempVarID=-1;
    }

  return 0;
#endif //BINTRAJ

  return 1;
}
Exemple #29
0
int ex_get_block( int exoid,
      ex_entity_type blk_type,
      int blk_id,
      char* elem_type,
      int* num_entries_this_blk,
      int* num_nodes_per_entry,
      int* num_edges_per_entry,
      int* num_faces_per_entry,
      int* num_attr_per_entry )
{
  int dimid, connid, blk_id_ndx;
  size_t len;
  char *ptr;
  char  errmsg[MAX_ERR_LENGTH];
  int status;
  const char* dnument;
  const char* dnumnod;
  const char* dnumedg;
  const char* dnumfac;
  const char* dnumatt;
  const char* ablknam;
  const char* vblkcon;

  exerrval = 0;

  /* First, locate index of element block id in VAR_ID_EL_BLK array */
  blk_id_ndx = ex_id_lkup(exoid,blk_type,blk_id);
  if (exerrval != 0)  {
    if (exerrval == EX_NULLENTITY) {    /* NULL element block?    */
      if ( elem_type )
  strcpy(elem_type, "NULL");     /* NULL element type name */
      *num_entries_this_blk = 0;       /* no elements            */
      *num_nodes_per_entry = 0;        /* no nodes               */
      *num_attr_per_entry = 0;         /* no attributes          */
      return (EX_NOERR);
    } else {
      sprintf(errmsg,
        "Error: failed to locate %s id %d in id array in file id %d",
        ex_name_of_object(blk_type), blk_id,exoid);
      ex_err("ex_get_block",errmsg,exerrval);
      return (EX_FATAL);
    }
  }

  switch (blk_type) {
  case EX_EDGE_BLOCK:
    dnument = DIM_NUM_ED_IN_EBLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_ED(blk_id_ndx);
    dnumedg = 0;
    dnumfac = 0;
    dnumatt = DIM_NUM_ATT_IN_EBLK(blk_id_ndx);
    vblkcon = VAR_EBCONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  case EX_FACE_BLOCK:
    dnument = DIM_NUM_FA_IN_FBLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_FA(blk_id_ndx);
    dnumedg = 0; /* it is possible this might be non-NULL some day */
    dnumfac = 0;
    dnumatt = DIM_NUM_ATT_IN_FBLK(blk_id_ndx);
    vblkcon = VAR_FBCONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  case EX_ELEM_BLOCK:
    dnument = DIM_NUM_EL_IN_BLK(blk_id_ndx);
    dnumnod = DIM_NUM_NOD_PER_EL(blk_id_ndx);
    dnumedg = DIM_NUM_EDG_PER_EL(blk_id_ndx);
    dnumfac = DIM_NUM_FAC_PER_EL(blk_id_ndx);
    dnumatt = DIM_NUM_ATT_IN_BLK(blk_id_ndx);
    vblkcon = VAR_CONN(blk_id_ndx);
    ablknam = ATT_NAME_ELB;
    break;
  default:
    exerrval = EX_BADPARAM;
    sprintf( errmsg, "Bad block type parameter (%d) specified for file id %d.",
       blk_type, exoid );
    return (EX_FATAL);
  }

  /* inquire values of some dimensions */
  if ( num_entries_this_blk ) {
    if ((status = nc_inq_dimid (exoid, dnument, &dimid)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
        "Error: failed to locate number of entities in %s %d in file id %d",
        ex_name_of_object(blk_type),blk_id,exoid);
      ex_err("ex_get_block",errmsg, exerrval);
      return(EX_FATAL);
    }

    if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
        "Error: failed to get number of %ss in block %d in file id %d",
        ex_name_of_object(blk_type),blk_id, exoid);
      ex_err("ex_get_block",errmsg, exerrval);
      return(EX_FATAL);
    }
    *num_entries_this_blk = len;
  }

  if ( num_nodes_per_entry ) {
    if ((status = nc_inq_dimid (exoid, dnumnod, &dimid)) != NC_NOERR) {
      /* undefined => no node entries per element */
      len = 0;
    } else {
      if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
  exerrval = status;
  sprintf(errmsg,
    "Error: failed to get number of nodes/entity in %s %d in file id %d",
    ex_name_of_object(blk_type),blk_id, exoid);
  ex_err("ex_get_block",errmsg, exerrval);
  return(EX_FATAL);
      }
    }
    *num_nodes_per_entry = len;
  }

  if ( num_edges_per_entry ) {
    if ( blk_type != EX_ELEM_BLOCK ) {
      exerrval = (EX_WARN);
      sprintf(errmsg,
        "Warning: non-NULL pointer passed to num_edges_per_entry for %s query in file id %d",
        ex_name_of_object(blk_type),exoid);
      ex_err("ex_get_block",errmsg,exerrval);
    } else {
      if ((status = nc_inq_dimid (exoid, dnumedg, &dimid)) != NC_NOERR) {
  /* undefined => no edge entries per element */
  len = 0;
      } else {
  if ((status = nc_inq_dimlen (exoid, dimid, &len)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
      "Error: failed to get number of edges/entry in %s %d in file id %d",
      ex_name_of_object(blk_type),blk_id, exoid);
    ex_err("ex_get_block",errmsg, exerrval);
    return(EX_FATAL);
  }
      }
      *num_edges_per_entry = len;
    }
  }

  if ( num_faces_per_entry ) {
    if ( blk_type != EX_ELEM_BLOCK ) {
      exerrval = (EX_WARN);
      sprintf(errmsg,
        "Warning: non-NULL pointer passed to num_faces_per_entry for %s query in file id %d",
        ex_name_of_object(blk_type),exoid);
      ex_err("ex_get_block",errmsg,exerrval);
    } else {
      if ((status = nc_inq_dimid (exoid, dnumfac, &dimid)) != NC_NOERR) {
  /* undefined => no face entries per element */
  len = 0;
      } else {
  if ((status = nc_inq_dimlen(exoid, dimid, &len)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
      "Error: failed to get number of faces/entity in %s %d in file id %d",
      ex_name_of_object(blk_type),blk_id, exoid);
    ex_err("ex_get_block",errmsg, exerrval);
    return(EX_FATAL);
  }
      }
      *num_faces_per_entry = len;
    }
  }

  if ( num_attr_per_entry ) {
    if ((status = nc_inq_dimid (exoid, dnumatt, &dimid)) != NC_NOERR) {
      /* dimension is undefined */
      *num_attr_per_entry = 0;
    } else {
      if ((status = nc_inq_dimlen(exoid, dimid, &len)) != NC_NOERR) {
  exerrval = status;
  sprintf(errmsg,
    "Error: failed to get number of attributes in %s %d in file id %d",
    ex_name_of_object(blk_type),blk_id, exoid);
  ex_err("ex_get_block",errmsg, exerrval);
  return(EX_FATAL);
      }
      *num_attr_per_entry = len;
    }
  }

  if ( elem_type ) {
    if (*num_nodes_per_entry > 0) {
      ; /* Do nothing, vblkcon should be correctly set already */
    } else if (*num_edges_per_entry > 0) {
      vblkcon = VAR_EBCONN(blk_id_ndx);
    } else if (*num_faces_per_entry > 0) {
      vblkcon = VAR_FCONN(blk_id_ndx);
    }

    if (vblkcon) {
      /* look up connectivity array for this element block id */
      if ((status = nc_inq_varid (exoid, vblkcon, &connid)) != NC_NOERR) {
  exerrval = status;
  sprintf(errmsg,
    "Error: failed to locate connectivity array for %s %d in file id %d",
    ex_name_of_object(blk_type), blk_id,exoid);
  ex_err("ex_get_block",errmsg, exerrval);
  return(EX_FATAL);
      }

      if ((status = nc_inq_attlen (exoid, connid, ablknam, &len)) != NC_NOERR) {
  exerrval = status;
  sprintf(errmsg,
    "Error: failed to get %s %d type in file id %d",
    ex_name_of_object(blk_type), blk_id,exoid);
  ex_err("ex_get_block",errmsg, exerrval);
  return(EX_FATAL);
      }

      if (len > (MAX_STR_LENGTH+1)) {
  len = MAX_STR_LENGTH;
  sprintf (errmsg,
     "Warning: %s %d type will be truncated to %ld chars", 
     ex_name_of_object(blk_type), blk_id, (long)len);
  ex_err("ex_get_block",errmsg,EX_MSG);
      }
      
      /* get the element type name */
      if ((status = nc_get_att_text (exoid, connid, ablknam, elem_type)) != NC_NOERR) {
  exerrval = status;
  sprintf(errmsg,"Error: failed to get %s %d type in file id %d",
    ex_name_of_object(blk_type), blk_id, exoid);
  ex_err("ex_get_block",errmsg, exerrval);
  return(EX_FATAL);
      }
      
      /* get rid of trailing blanks */
      ptr = elem_type;
      /* fprintf(stderr,"[exgblk] %s, len: %d\n",ptr,len); */
      while (ptr < elem_type + len && *ptr != ' ') {
  ptr++;
      }
      *(ptr) = '\0';
    }
  }
  return (EX_NOERR);
}