Example #1
0
float FileNetcdf::getMissingValue(int iVar) const {
   float fillValue;
   int status = nc_get_att_float(mFile, iVar, "_FillValue", &fillValue);
   if(status != NC_NOERR)
      fillValue  = NC_FILL_FLOAT;
   return fillValue;
}
Example #2
0
float FileNetcdf::getScale(int iVar) const {
   float scale;
   int status = nc_get_att_float(mFile, iVar, "scale_factor", &scale);
   if(status != NC_NOERR)
      scale  = 1;
   return scale;
}
Example #3
0
int ne_check_file_version(int exoid)
{
#if 0
  const char  *func_name="ne_check_file_version";

  float  file_ver;

  int    status;
  char   errmsg[MAX_ERR_LENGTH];

  exerrval = 0;  /* clear error code */

  /* Get the file version */
  if ((status = nc_get_att_float(exoid, NC_GLOBAL, "nemesis_file_version", &file_ver)) != NC_NOERR) {
    exerrval = status;
    sprintf(errmsg,
            "Error: failed to get the nemesis file version from file ID %d",
            exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }

  if (fabs(NEMESIS_FILE_VERSION-file_ver) > 0.001) {
    exerrval = EX_MSG;
    sprintf(errmsg,
            "Error: Nemesis version mismatch in file ID %d!\n", exoid);
    ex_err(func_name, errmsg, exerrval);
    return (EX_FATAL);
  }
#endif
  return (EX_NOERR);
}
Example #4
0
float FileNetcdf::getOffset(int iVar) const {
   float offset;
   int status = nc_get_att_float(mFile, iVar, "add_offset", &offset);
   if(status != NC_NOERR)
      offset  = 0;
   return offset;
}
Example #5
0
static int read_numeric_attribute(int ncid, int varid, const char *name, harp_data_type *data_type, harp_scalar *data)
{
    nc_type netcdf_data_type;
    size_t netcdf_num_elements;
    int result;

    result = nc_inq_att(ncid, varid, name, &netcdf_data_type, &netcdf_num_elements);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (netcdf_num_elements != 1)
    {
        harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid format", name);
        return -1;
    }

    if (get_harp_type(netcdf_data_type, data_type) != 0)
    {
        harp_add_error_message(" (attribute '%s')", name);
        return -1;
    }

    switch (netcdf_data_type)
    {
        case NC_BYTE:
            result = nc_get_att_schar(ncid, varid, name, &data->int8_data);
            break;
        case NC_SHORT:
            result = nc_get_att_short(ncid, varid, name, &data->int16_data);
            break;
        case NC_INT:
            result = nc_get_att_int(ncid, varid, name, &data->int32_data);
            break;
        case NC_FLOAT:
            result = nc_get_att_float(ncid, varid, name, &data->float_data);
            break;
        case NC_DOUBLE:
            result = nc_get_att_double(ncid, varid, name, &data->double_data);
            break;
        default:
            harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid type", name);
            return -1;
    }

    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    return 0;
}
Example #6
0
NcValues* NcAtt::values( void ) const
{
    NcValues* valp = get_space();
    int status;
    switch (type()) {
    case ncFloat:
	status = NcError::set_err(
				  nc_get_att_float(the_file->id(), the_variable->id(), the_name,
				   (float *)valp->base())
				  );
	break;
    case ncDouble:
	status = NcError::set_err(
				  nc_get_att_double(the_file->id(), the_variable->id(), the_name,
				   (double *)valp->base())
				  );
	break;
    case ncInt:
	status = NcError::set_err(
				  nc_get_att_int(the_file->id(), the_variable->id(), the_name,
				(int *)valp->base())
				  );
	break;
    case ncShort:
	status = NcError::set_err(
				  nc_get_att_short(the_file->id(), the_variable->id(), the_name,
				  (short *)valp->base())
				  );
	break;
    case ncByte:
	status = NcError::set_err(
				  nc_get_att_schar(the_file->id(), the_variable->id(), the_name,
				  (signed char *)valp->base())
				  );
	break;
    case ncChar:
	status = NcError::set_err(
				  nc_get_att_text(the_file->id(), the_variable->id(), the_name,
				  (char *)valp->base())
				  );
	break;
    case ncNoType:
    default:
	return 0;
    }
    if (status != NC_NOERR) {
	delete valp;
	return 0;
    }
    return valp;
}
Example #7
0
  WrfGrid::Parameters DataFile::getGridParameters()
  {
    WrfGrid::Parameters parameters;

    std::map<const char *, int*> intParameters;
    intParameters["WEST-EAST_GRID_DIMENSION"] = &parameters.nWestEast;
    intParameters["SOUTH-NORTH_GRID_DIMENSION"] = &parameters.nSouthNorth;
    intParameters["BOTTOM-TOP_GRID_DIMENSION"] = &parameters.nBottomTop;
    intParameters["MAP_PROJ"] = &parameters.mapProj;

    std::map<const char *, int*>::iterator iterInt;
    for (iterInt = intParameters.begin();
         iterInt != intParameters.end();
         ++iterInt)
    {
      int status = nc_get_att_int
                          (handle_, NC_GLOBAL, iterInt->first, iterInt->second);

      if (status != NC_NOERR)
      {
        throw NetCdfException (nc_strerror(status));
        // FIXME throw NetCdfException ("error reading " + iterInt->first + " from #" + handle_ + ":\n" + nc_strerror(status));
      }
    }

    std::map<const char *, float*> floatParameters;
    floatParameters["DX"] = &parameters.dX;
    floatParameters["DY"] = &parameters.dY;
    floatParameters["CEN_LAT"] = &parameters.cenLat;
    floatParameters["CEN_LON"] = &parameters.cenLon;
    floatParameters["TRUELAT1"] = &parameters.trueLat1;
    floatParameters["TRUELAT2"] = &parameters.trueLat2;
    floatParameters["MOAD_CEN_LAT"] = &parameters.moadCenLat;
    floatParameters["STAND_LON"] = &parameters.standLon;
    floatParameters["POLE_LAT"] = &parameters.poleLat;
    floatParameters["POLE_LON"] = &parameters.poleLon;

    std::map<const char *, float*>::iterator iterFloat;
    for (iterFloat = floatParameters.begin(); iterFloat != floatParameters.end(); ++iterFloat)
    {
      int status = nc_get_att_float (handle_, NC_GLOBAL, iterFloat->first, iterFloat->second);
      if (status != NC_NOERR)
      {
        throw NetCdfException (nc_strerror(status));
        // FIXME throw NetCdfException ("error reading " + iterInt->first + " from #"+ handle_ +":\n" + nc_strerror(status));
      }
    }

    return parameters;
  }
Example #8
0
int ex_put_nemesis_version(int exoid)
{
  const char  *func_name="ex_put_nemesis_version";
  int    status;
  float  file_ver, api_ver;

  char   errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear the error code */

  file_ver = NEMESIS_FILE_VERSION;
  api_ver  = NEMESIS_API_VERSION;

  /* Check to see if the nemesis file version is already in the file */
  if (nc_get_att_float(exoid, NC_GLOBAL, "nemesis_file_version", &file_ver) != NC_NOERR) {

    /* Output the Nemesis file version */
    if ((status = nc_put_att_float(exoid, NC_GLOBAL, "nemesis_file_version", NC_FLOAT,
				   1, &file_ver)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to output nemesis file version in file ID %d",
              exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }

    /* Output the Nemesis API version */
    if ((status = nc_put_att_float(exoid, NC_GLOBAL, "nemesis_api_version", NC_FLOAT,
				   1, &api_ver)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
              "Error: failed to output nemesis api version in file ID %d",
              exoid);
      ex_err(func_name, errmsg, exerrval);
      return (EX_FATAL);
    }
  }
  return (EX_NOERR);
}
float *
avtNETCDFReaderBase::ReadTimeAttribute()
{
    float *times_array = 0;

    //
    // See if the global attribute time exists. If it does and is
    // either a float or double, then return the first value of it
    // as the time array.
    //
    int     status;
    nc_type atttype;
    size_t  attsize;
    if((status = nc_inq_att(fileObject->GetFileHandle(), NC_GLOBAL,
        "Time", &atttype, &attsize)) == NC_NOERR)
    {
        if (atttype == NC_FLOAT)
        {
            times_array = new float[1];
            float *value = new float[attsize];
            nc_get_att_float(fileObject->GetFileHandle(), NC_GLOBAL,
                "Time", value); 
            times_array[0] = value[0];
            delete [] value;
        }
        else if (atttype == NC_DOUBLE)
        {
            times_array = new float[1];
            double *value = new double[attsize];
            nc_get_att_double(fileObject->GetFileHandle(), NC_GLOBAL,
                "Time", value); 
            times_array[0] = value[0];
            delete [] value;
        }
    }

    return times_array;
}
Example #10
0
File: exinq.c Project: hpcdev/xdm
int ex_inquire (int   exoid,
                int   req_info,
                int  *ret_int,
                void *ret_float,
                char *ret_char)
{
  int dimid, varid, tmp_num, *ids;
  size_t i;
  size_t ldum = 0;
  size_t num_sets, idum;
  int *stat_vals;
  char  errmsg[MAX_ERR_LENGTH];
  int status;
  
  exerrval = 0; /* clear error code */

  switch (req_info)
    {
    case EX_INQ_FILE_TYPE:

      /* obsolete call */
      /*returns "r" for regular EXODUS II file or "h" for history EXODUS file*/

      *ret_char = '\0';
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
              "Warning: file type inquire is obsolete");
      ex_err("ex_inquire",errmsg,exerrval);
      return (EX_WARN);

    case EX_INQ_API_VERS:
      /* returns the EXODUS II API version number */
      if (nc_get_att_float(exoid, NC_GLOBAL, ATT_API_VERSION, ret_float) != NC_NOERR)
	{  /* try old (prior to db version 2.02) attribute name */
	  if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_API_VERSION_BLANK,ret_float)) != NC_NOERR) {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to get EXODUS API version for file id %d", exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	}

      break;

    case EX_INQ_DB_VERS:
      /* returns the EXODUS II database version number */
      if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_VERSION, ret_float)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get EXODUS database version for file id %d", exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }
      break;

    case EX_INQ_LIB_VERS:
      /* returns the EXODUS II Library version number */
      if (ret_float)
	flt_cvt((float *)ret_float, EX_API_VERS);

      if (ret_int)
	*ret_int = EX_API_VERS_NODOT;
      break;

    case EX_INQ_TITLE:
      /* returns the title of the database */
      if ((status = nc_get_att_text (exoid, NC_GLOBAL, ATT_TITLE, ret_char)) != NC_NOERR) {
	*ret_char = '\0';
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get database title for file id %d", exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }
      break;

    case EX_INQ_DIM:
      /* returns the dimensionality (2 or 3, for 2-d or 3-d) of the database */
      if (ex_get_dimension(exoid, DIM_NUM_DIM, "database dimensionality", &ldum, &dimid, "ex_inquire") != NC_NOERR)
	return EX_FATAL;
      *ret_int = ldum;
      break;

    case EX_INQ_NODES:
      /* returns the number of nodes */
      if (ex_get_dimension(exoid, DIM_NUM_NODES, "nodes", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_ELEM:
      /* returns the number of elements */
      if (ex_get_dimension(exoid, DIM_NUM_ELEM, "elements", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_ELEM_BLK:
      /* returns the number of element blocks */
      if (ex_get_dimension(exoid, DIM_NUM_EL_BLK, "element blocks", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_NODE_SETS:
      /* returns the number of node sets */
      if (ex_get_dimension(exoid, DIM_NUM_NS, "node sets", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_NS_NODE_LEN:
      /* returns the length of the concatenated node sets node list */
      EX_GET_CONCAT_SET_LEN(ret_int,"node",EX_NODE_SET,DIM_NUM_NS,VAR_NS_STAT,DIM_NUM_NOD_NS,0);
      break;

    case EX_INQ_NS_DF_LEN:
      /*     returns the length of the concatenated node sets dist factor list */

      /*
	Determine the concatenated node sets distribution factor length:

        1. Get the node set ids list.
        2. Check see if the dist factor variable for a node set id exists.
        3. If it exists, goto step 4, else the length is zero.
        4. Get the dimension of the number of nodes in the node set -0
	use this value as the length as by definition they are the same.
        5. Sum the individual lengths for the total list length.
      */

      *ret_int = 0;    /* default value if no node sets defined */

      if (nc_inq_dimid (exoid, DIM_NUM_NS, &dimid) == NC_NOERR) {
	if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get number of node sets in file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}


	if (!(ids = malloc(num_sets*sizeof(int))))
	  {
	    exerrval = EX_MEMFAIL;
	    sprintf(errmsg,
		    "Error: failed to allocate memory for node set ids for file id %d",
		    exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }

	if (ex_get_node_set_ids (exoid, ids) == EX_FATAL)
	  {
	    sprintf(errmsg,
		    "Error: failed to get node sets in file id %d",
		    exoid);
	    /* pass back error code from ex_get_node_set_ids (in exerrval) */
	    ex_err("ex_inquire",errmsg,exerrval);
	    free (ids);
	    return (EX_FATAL);
	  }

	for (i=0; i<num_sets; i++) {
	  if ((status = nc_inq_varid (exoid, VAR_FACT_NS(i+1), &varid)) != NC_NOERR) {
	    if (status == NC_ENOTVAR) {
	      idum = 0;        /* this dist factor doesn't exist */
	    } else {
	      *ret_int = 0;
	      exerrval = status;
	      sprintf(errmsg,
		      "Error: failed to locate number of dist fact for node set %d in file id %d",
		      ids[i], exoid);
	      ex_err("ex_inquire",errmsg,exerrval);
	      free (ids);
	      return (EX_FATAL);
	    }
	  } else {
	    if ((status = nc_inq_dimid (exoid, DIM_NUM_NOD_NS(i+1), &dimid)) != NC_NOERR) {
	      *ret_int = 0;
	      exerrval = status;
	      sprintf(errmsg,
		      "Error: failed to locate number of nodes in node set %d in file id %d",
		      ids[i], exoid);
	      ex_err("ex_inquire",errmsg,exerrval);
	      free (ids);
	      return (EX_FATAL);
	    }
	    if ((status = nc_inq_dimlen (exoid, dimid, &idum)) != NC_NOERR) {
	      *ret_int = 0;
	      exerrval = status;
	      sprintf(errmsg,
		      "Error: failed to get number of nodes in node set %d in file id %d",
		      ids[i],exoid);
	      ex_err("ex_inquire",errmsg,exerrval);
	      free(ids);
	      return (EX_FATAL);
	    }
	  }
	  *ret_int += idum;
	}
	free(ids);
      }

      break;

    case EX_INQ_SIDE_SETS:
      /* returns the number of side sets */
      if (ex_get_dimension(exoid, DIM_NUM_SS, "side sets", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_SS_NODE_LEN:

      /*     returns the length of the concatenated side sets node list */

      *ret_int = 0;     /* default return value */

      if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) {
	if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get number of side sets in file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}


	if (!(ids = malloc(num_sets*sizeof(int)))) {
	  exerrval = EX_MEMFAIL;
	  sprintf(errmsg,
		  "Error: failed to allocate memory for side set ids for file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}

	if (ex_get_side_set_ids (exoid, ids) == EX_FATAL) {
	  sprintf(errmsg,
		  "Error: failed to get side set ids in file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  free(ids);
	  return (EX_FATAL);
	}

	/* allocate space for stat array */
	if (!(stat_vals = malloc((int)num_sets*sizeof(int)))) {
	  exerrval = EX_MEMFAIL;
	  free (ids);
	  sprintf(errmsg,
		  "Error: failed to allocate memory for side set status array for file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}
	/* get variable id of status array */
	if ((status = nc_inq_varid (exoid, VAR_SS_STAT, &varid)) == NC_NOERR) {
	  /* if status array exists, use it, otherwise assume, object exists
	     to be backward compatible */

	  if ((status = nc_get_var_int(exoid, varid, stat_vals)) != NC_NOERR) {
	    exerrval = status;
	    free (ids);
	    free(stat_vals);
	    sprintf(errmsg,
		    "Error: failed to get element block status array from file id %d",
		    exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	}
	else /* default: status is true */
	  for(i=0;i<num_sets;i++)
	    stat_vals[i]=1;

	/* walk id list, get each side set node length and sum for total */

	for (i=0; i<num_sets; i++) {
	  if (stat_vals[i] == 0) /* is this object null? */
	    continue;

	  if ((status = ex_get_side_set_node_list_len(exoid, ids[i], &tmp_num)) != NC_NOERR) {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to side set %d node length in file id %d",
		    ids[i],exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    free(stat_vals);
	    free(ids);
	    return (EX_FATAL);
	  }
	  *ret_int += tmp_num;
	}

	free(stat_vals);
	free (ids);
      }

      break;

    case EX_INQ_SS_ELEM_LEN:
      /*     returns the length of the concatenated side sets element list */
      EX_GET_CONCAT_SET_LEN(ret_int,"side",EX_SIDE_SET,DIM_NUM_SS,VAR_SS_STAT,DIM_NUM_SIDE_SS,0);
      break;

    case EX_INQ_SS_DF_LEN:

      /*     returns the length of the concatenated side sets dist factor list */

      /*
	Determine the concatenated side sets distribution factor length:

        1. Get the side set ids list.
        2. Check see if the dist factor dimension for a side set id exists.
        3. If it exists, goto step 4, else set the individual length to zero.
        4. Sum the dimension value into the running total length.
      */

      *ret_int = 0;

      /* first check see if any side sets exist */

      if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) {
	if ((status = nc_inq_dimlen (exoid, dimid, &num_sets)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get number of side sets in file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}


	if (!(ids = malloc(num_sets*sizeof(int)))) {
	  exerrval = EX_MEMFAIL;
	  sprintf(errmsg,
		  "Error: failed to allocate memory for side set ids for file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}

	if (ex_get_side_set_ids (exoid, ids) == EX_FATAL) {
	  sprintf(errmsg,
		  "Error: failed to get side sets in file id %d",
		  exoid);
	  /* pass back error code from ex_get_side_set_ids (in exerrval) */
	  ex_err("ex_inquire",errmsg,exerrval);
	  free (ids);
	  return (EX_FATAL);
	}

	for (i=0; i<num_sets; i++) {
	  if ((status = nc_inq_dimid (exoid, DIM_NUM_DF_SS(i+1), &dimid)) != NC_NOERR) {
	    if (status == NC_EBADDIM) {
	      ldum = 0;        /* this dist factor doesn't exist */
	    } else {
	      *ret_int = 0;
	      exerrval = status;
	      sprintf(errmsg,
		      "Error: failed to locate number of dist fact for side set %d in file id %d",
		      ids[i], exoid);
	      ex_err("ex_inquire",errmsg,exerrval);
	      free (ids);
	      return (EX_FATAL);
	    }
	  } else {
	    if ((status = nc_inq_dimlen (exoid, dimid, &ldum)) != NC_NOERR) {
	      *ret_int = 0;
	      exerrval = status;
	      sprintf(errmsg,
		      "Error: failed to get number of dist factors in side set %d in file id %d",
		      ids[i], exoid);
	      ex_err("ex_inquire",errmsg,exerrval);
	      free (ids);
	      return (EX_FATAL);
	    }
	  }
	  *ret_int += ldum;
	}
	free (ids);
      }

      break;

    case EX_INQ_QA:
      /* returns the number of QA records */
      if (ex_get_dimension(exoid, DIM_NUM_QA, "QA records", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_INFO:
      /* returns the number of information records */
      if (ex_get_dimension(exoid, DIM_NUM_INFO, "info records", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_TIME:
      /*     returns the number of time steps stored in the database */
      if (ex_get_dimension(exoid, DIM_TIME, "time dimension", &ldum, &dimid, "ex_inquire") != NC_NOERR)
	return EX_FATAL;
      *ret_int = ldum;
      break;

    case EX_INQ_EB_PROP:
      /* returns the number of element block properties */
      *ret_int = ex_get_num_props (exoid, EX_ELEM_BLOCK);
      break;

    case EX_INQ_NS_PROP:
      /* returns the number of node set properties */
      *ret_int = ex_get_num_props (exoid, EX_NODE_SET);
      break;

    case EX_INQ_SS_PROP:
      /* returns the number of side set properties */
      *ret_int = ex_get_num_props (exoid, EX_SIDE_SET);
      break;

    case EX_INQ_ELEM_MAP:
      /* returns the number of element maps */
      if (ex_get_dimension(exoid, DIM_NUM_EM, "element maps", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_EM_PROP:
      /* returns the number of element map properties */
      *ret_int = ex_get_num_props (exoid, EX_ELEM_MAP);
      break;

    case EX_INQ_NODE_MAP:
      /* returns the number of node maps */
      if (ex_get_dimension(exoid, DIM_NUM_NM, "node maps", &ldum, &dimid, NULL) != NC_NOERR)
	*ret_int = 0;
      else
	*ret_int = ldum;
      break;

    case EX_INQ_NM_PROP:
      /* returns the number of node map properties */
      *ret_int = ex_get_num_props (exoid, EX_NODE_MAP);
      break;

    case EX_INQ_EDGE:
      /* returns the number of edges (defined across all edge blocks). */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_EDGE, 1);
      break;

    case EX_INQ_EDGE_BLK:
      /* returns the number of edge blocks. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_ED_BLK, 1);
      break;

    case EX_INQ_EDGE_SETS:
      /* returns the number of edge sets. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_ES, 1);
      break;

    case EX_INQ_ES_LEN:
      /* returns the length of the concatenated edge set edge list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,DIM_NUM_EDGE_ES,0);
      break;

    case EX_INQ_ES_DF_LEN:
      /* returns the length of the concatenated edge set distribution factor list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,DIM_NUM_DF_ES,1);
      break;

    case EX_INQ_EDGE_PROP:
      /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */
      *ret_int = ex_get_num_props( exoid, EX_EDGE_BLOCK );
      break;

    case EX_INQ_ES_PROP:
      /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */
      *ret_int = ex_get_num_props( exoid, EX_EDGE_SET );
      break;

    case EX_INQ_FACE:
      /* returns the number of faces (defined across all face blocks). */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_FACE, 1);
      break;

    case EX_INQ_FACE_BLK:
      /* returns the number of face blocks. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_FA_BLK, 1);
      break;

    case EX_INQ_FACE_SETS:
      /* returns the number of face sets. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_FS, 1);
      break;

    case EX_INQ_FS_LEN:
      /* returns the length of the concatenated edge set edge list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,DIM_NUM_FACE_FS,0);
      break;

    case EX_INQ_FS_DF_LEN:
      /* returns the length of the concatenated edge set distribution factor list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,DIM_NUM_DF_FS,1);
      break;

    case EX_INQ_FACE_PROP:
      /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */
      *ret_int = ex_get_num_props( exoid, EX_FACE_BLOCK );
      break;

    case EX_INQ_FS_PROP:
      /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */
      *ret_int = ex_get_num_props( exoid, EX_FACE_SET );
      break;

    case EX_INQ_ELEM_SETS:
      /* returns the number of element sets. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_ELS, 1);
      break;

    case EX_INQ_ELS_LEN:
      /* returns the length of the concatenated element set element list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,DIM_NUM_ELE_ELS,0);
      break;

    case EX_INQ_ELS_DF_LEN:
      /* returns the length of the concatenated element set distribution factor list. */
      EX_GET_CONCAT_SET_LEN(ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,DIM_NUM_DF_ELS,1);
      break;

    case EX_INQ_ELS_PROP:
      /* returns the number of integer properties stored for each element set. */
      *ret_int = ex_get_num_props( exoid, EX_ELEM_SET );
      break;

    case EX_INQ_EDGE_MAP:
      /* returns the number of edge maps. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_EDM, 1);
      break;

    case EX_INQ_FACE_MAP:
      /*     returns the number of face maps. */
      EX_GET_DIMENSION_VALUE(ret_int, 0, DIM_NUM_FAM, 1);
      break;

    default:
      *ret_int = 0;
      exerrval = EX_FATAL;
      sprintf(errmsg, "Error: invalid inquiry %d", req_info);
      ex_err("ex_inquire",errmsg,exerrval);
      return(EX_FATAL);
    }
  return (EX_NOERR);
}
Example #11
0
static int ex_inquire_internal (int      exoid,
				int      req_info,
				int64_t *ret_int,
				float   *ret_float,
				char    *ret_char)
{
  int dimid, varid, tmp_num;
  void_int *ids = NULL;
  size_t i;
  size_t ldum = 0;
  size_t num_sets, idum;
  int *stat_vals;
  char  errmsg[MAX_ERR_LENGTH];
  int status;
  char tmp_title[2048];

  exerrval = 0; /* clear error code */

  if (ret_char)  *ret_char  = '\0';  /* Only needs to be non-null for TITLE */
  
  if (!ret_int) {
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Warning: integer argument is NULL which is not allowed.");
    ex_err("ex_inquire",errmsg,exerrval);
    return (EX_FATAL);
  }
    

  switch (req_info) {
  case EX_INQ_FILE_TYPE:

    /* obsolete call */
    /*returns "r" for regular EXODUS II file or "h" for history EXODUS file*/
    exerrval = EX_BADPARAM;
    sprintf(errmsg,
	    "Warning: file type inquire is obsolete");
    ex_err("ex_inquire",errmsg,exerrval);
    return (EX_WARN);

  case EX_INQ_API_VERS:
    /* returns the EXODUS II API version number */
    if (!ret_float) {
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
	      "Warning: float argument is NULL for EX_INQ_API_VERS which is not allowed.");
      ex_err("ex_inquire",errmsg,exerrval);
      return (EX_FATAL);
    }

    if (nc_get_att_float(exoid, NC_GLOBAL, ATT_API_VERSION, ret_float) != NC_NOERR)
      {  /* try old (prior to db version 2.02) attribute name */
	if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_API_VERSION_BLANK,ret_float)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to get EXODUS API version for file id %d", exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}
      }

    break;

  case EX_INQ_DB_VERS:
    /* returns the EXODUS II database version number */
    if (!ret_float) {
      exerrval = EX_BADPARAM;
      sprintf(errmsg,
	      "Warning: float argument is NULL for EX_INQ_DB_VERS which is not allowed.");
      ex_err("ex_inquire",errmsg,exerrval);
      return (EX_FATAL);
    }

    if ((status = nc_get_att_float (exoid, NC_GLOBAL, ATT_VERSION, ret_float)) != NC_NOERR) {
      exerrval = status;
      sprintf(errmsg,
	      "Error: failed to get EXODUS database version for file id %d", exoid);
      ex_err("ex_inquire",errmsg,exerrval);
      return (EX_FATAL);
    }
    break;

  case EX_INQ_LIB_VERS:
    /* returns the EXODUS II Library version number */
    if (ret_float)
      flt_cvt(ret_float, EX_API_VERS);

    *ret_int = EX_API_VERS_NODOT;
    break;

  case EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH:
    /* Return the MAX_NAME_LENGTH size for this database
       It will not include the space for the trailing null, so if it
       is defined as 33 on the database, 32 will be returned.
    */
    if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &dimid)) != NC_NOERR) {
      /* If not found, then an older database */
      *ret_int = 32;
    }
    else {
      /* Get the name string length */
      size_t name_length = 0;
      if ((status = nc_inq_dimlen(exoid,dimid,&name_length)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get name string length in file id %d", exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }
      else {
	*ret_int = name_length-1;
      }
    }
    break;

  case EX_INQ_DB_MAX_USED_NAME_LENGTH:
    /* Return the value of the ATT_MAX_NAME_LENGTH attribute (if it
       exists) which is the maximum length of any entity, variable,
       attribute, property name written to this database.  If the
       attribute does not exist, then '32' is returned.  The length
       does not include the trailing null.
    */
    {
      nc_type att_type = NC_NAT;
      size_t att_len = 0;
	
      *ret_int = 32; /* Default size consistent with older databases */

      status = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
      if (status == NC_NOERR && att_type == NC_INT) {
	/* The attribute exists, return it... */
	nc_get_att_longlong(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, (long long*)ret_int);
      }
    }
    break;

  case EX_INQ_MAX_READ_NAME_LENGTH:
    {
      /* Returns the user-specified maximum size of names that will be
       * returned to the user by any of the ex_get_ routines.  If the
       * name is longer than this value, it will be truncated. The
       * default if not set by the client is 32 characters. The value
       * does not include the trailing null.
       */
      struct file_item* file = ex_find_file_item(exoid);

      if (!file ) {
	exerrval = EX_BADFILEID;
	sprintf(errmsg,"Error: unknown file id %d for ex_inquire_int().",exoid);
	ex_err("ex_intquire",errmsg,exerrval);
	*ret_int = 0;
      }
      else {
	*ret_int = file->maximum_name_length;
      }
    }
    break;

  case EX_INQ_TITLE:
    if (!ret_char) {
      sprintf(errmsg,
	      "Error: Requested title, but character pointer was null for file id %d", exoid);
      ex_err("ex_inquire",errmsg,exerrval);
      return (EX_FATAL);
    } else {
      /* returns the title of the database */
      if ((status = nc_get_att_text (exoid, NC_GLOBAL, ATT_TITLE, tmp_title)) != NC_NOERR) {
	*ret_char = '\0';
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get database title for file id %d", exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      } else {
	strncpy(ret_char, tmp_title, MAX_LINE_LENGTH+1);
	ret_char[MAX_LINE_LENGTH] = '\0';
      }
    }
    break;

  case EX_INQ_DIM:
    /* returns the dimensionality (2 or 3, for 2-d or 3-d) of the database */
    if (ex_get_dimension(exoid, DIM_NUM_DIM, "database dimensionality", &ldum, &dimid, "ex_inquire") != NC_NOERR)
      return EX_FATAL;
    *ret_int = ldum;
    break;

  case EX_INQ_NODES:
    /* returns the number of nodes */
    if (ex_get_dimension(exoid, DIM_NUM_NODES, "nodes", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_ELEM:
    /* returns the number of elements */
    if (ex_get_dimension(exoid, DIM_NUM_ELEM, "elements", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_ELEM_BLK:
    /* returns the number of element blocks */
    if (ex_get_dimension(exoid, DIM_NUM_EL_BLK, "element blocks", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_NODE_SETS:
    /* returns the number of node sets */
    if (ex_get_dimension(exoid, DIM_NUM_NS, "node sets", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_NS_NODE_LEN:
    /* returns the length of the concatenated node sets node list */
    ex_get_concat_set_len(exoid, ret_int,"node",EX_NODE_SET,DIM_NUM_NS,VAR_NS_STAT,"num_nod_ns",0);
    break;

  case EX_INQ_NS_DF_LEN:
    /*     returns the length of the concatenated node sets dist factor list */

    /*
      Determine the concatenated node sets distribution factor length:

      2. Check see if the dist factor variable for a node set id exists.
      3. If it exists, goto step 4, else the length is zero.
      4. Get the dimension of the number of nodes in the node set -0
      use this value as the length as by definition they are the same.
      5. Sum the individual lengths for the total list length.
    */

    *ret_int = 0;    /* default value if no node sets defined */

    if (nc_inq_dimid (exoid, DIM_NUM_NS, &dimid) == NC_NOERR) {
      if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get number of node sets in file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }


      for (i=0; i<num_sets; i++) {
	if ((status = nc_inq_varid (exoid, VAR_FACT_NS(i+1), &varid)) != NC_NOERR) {
	  if (status == NC_ENOTVAR) {
	    idum = 0;        /* this dist factor doesn't exist */
	  } else {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to locate number of dist fact for %"ST_ZU"'th node set in file id %d",
		    i, exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	} else {
	  if ((status = nc_inq_dimid (exoid, DIM_NUM_NOD_NS(i+1), &dimid)) != NC_NOERR) {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to locate number of nodes in %"ST_ZU"'th node set in file id %d",
		    i, exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	  if ((status = nc_inq_dimlen (exoid, dimid, &idum)) != NC_NOERR) {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to get number of nodes in %"ST_ZU"'th node set in file id %d",
		    i,exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	}
	*ret_int += idum;
      }
    }

    break;

  case EX_INQ_SIDE_SETS:
    /* returns the number of side sets */
    if (ex_get_dimension(exoid, DIM_NUM_SS, "side sets", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_SS_NODE_LEN:

    /*     returns the length of the concatenated side sets node list */

    *ret_int = 0;     /* default return value */

    if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) {
      if ((status = nc_inq_dimlen(exoid, dimid, &num_sets)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get number of side sets in file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }


      if (!(ids = malloc(num_sets*sizeof(int64_t)))) { /* May be getting 2x what is needed, but should be OK */
	exerrval = EX_MEMFAIL;
	sprintf(errmsg,
		"Error: failed to allocate memory for side set ids for file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }

      if (ex_get_side_set_ids (exoid, ids) == EX_FATAL) {
	sprintf(errmsg,
		"Error: failed to get side set ids in file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	free(ids);
	return (EX_FATAL);
      }

      /* allocate space for stat array */
      if (!(stat_vals = malloc((int)num_sets*sizeof(int)))) {
	exerrval = EX_MEMFAIL;
	free (ids);
	sprintf(errmsg,
		"Error: failed to allocate memory for side set status array for file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }
      /* get variable id of status array */
      if ((status = nc_inq_varid (exoid, VAR_SS_STAT, &varid)) == NC_NOERR) {
	/* if status array exists, use it, otherwise assume, object exists
	   to be backward compatible */

	if ((status = nc_get_var_int(exoid, varid, stat_vals)) != NC_NOERR) {
	  exerrval = status;
	  free (ids);
	  free(stat_vals);
	  sprintf(errmsg,
		  "Error: failed to get element block status array from file id %d",
		  exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  return (EX_FATAL);
	}
      }
      else /* default: status is true */
	for(i=0;i<num_sets;i++)
	  stat_vals[i]=1;

      /* walk id list, get each side set node length and sum for total */

      for (i=0; i<num_sets; i++) {
	ex_entity_id id;
	if (stat_vals[i] == 0) /* is this object null? */
	  continue;

	if (ex_int64_status(exoid) & EX_IDS_INT64_API)
	  id = ((int64_t*)ids)[i];
	else
	  id = ((int*)ids)[i];
	  
	if ((status = ex_get_side_set_node_list_len(exoid, id, &tmp_num)) != NC_NOERR) {
	  *ret_int = 0;
	  exerrval = status;
	  sprintf(errmsg,
		  "Error: failed to side set %"PRId64" node length in file id %d",
		  id,exoid);
	  ex_err("ex_inquire",errmsg,exerrval);
	  free(stat_vals);
	  free(ids);
	  return (EX_FATAL);
	}
	*ret_int += tmp_num;
      }

      free(stat_vals);
      free (ids);
    }

    break;

  case EX_INQ_SS_ELEM_LEN:
    /*     returns the length of the concatenated side sets element list */
    ex_get_concat_set_len(exoid, ret_int,"side",EX_SIDE_SET,DIM_NUM_SS,VAR_SS_STAT,"num_side_ss",0);
    break;

  case EX_INQ_SS_DF_LEN:

    /*     returns the length of the concatenated side sets dist factor list */

    /*
      Determine the concatenated side sets distribution factor length:

      1. Get the side set ids list.
      2. Check see if the dist factor dimension for a side set id exists.
      3. If it exists, goto step 4, else set the individual length to zero.
      4. Sum the dimension value into the running total length.
    */

    *ret_int = 0;

    /* first check see if any side sets exist */

    if (nc_inq_dimid (exoid, DIM_NUM_SS, &dimid) == NC_NOERR) {
      if ((status = nc_inq_dimlen (exoid, dimid, &num_sets)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to get number of side sets in file id %d",
		exoid);
	ex_err("ex_inquire",errmsg,exerrval);
	return (EX_FATAL);
      }

      for (i=0; i<num_sets; i++) {
	if ((status = nc_inq_dimid (exoid, DIM_NUM_DF_SS(i+1), &dimid)) != NC_NOERR) {
	  if (status == NC_EBADDIM) {
	    ldum = 0;        /* this dist factor doesn't exist */
	  } else {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to locate number of dist fact for %"ST_ZU"'th side set in file id %d",
		    i, exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	} else {
	  if ((status = nc_inq_dimlen (exoid, dimid, &ldum)) != NC_NOERR) {
	    *ret_int = 0;
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to get number of dist factors in %"ST_ZU"'th side set in file id %d",
		    i, exoid);
	    ex_err("ex_inquire",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	}
	*ret_int += ldum;
      }
    }

    break;

  case EX_INQ_QA:
    /* returns the number of QA records */
    if (ex_get_dimension(exoid, DIM_NUM_QA, "QA records", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_INFO:
    /* returns the number of information records */
    if (ex_get_dimension(exoid, DIM_NUM_INFO, "info records", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_TIME:
    /*     returns the number of time steps stored in the database */
    if (ex_get_dimension(exoid, DIM_TIME, "time dimension", &ldum, &dimid, "ex_inquire") != NC_NOERR)
      return EX_FATAL;
    *ret_int = ldum;
    break;

  case EX_INQ_EB_PROP:
    /* returns the number of element block properties */
    *ret_int = ex_get_num_props (exoid, EX_ELEM_BLOCK);
    break;

  case EX_INQ_NS_PROP:
    /* returns the number of node set properties */
    *ret_int = ex_get_num_props (exoid, EX_NODE_SET);
    break;

  case EX_INQ_SS_PROP:
    /* returns the number of side set properties */
    *ret_int = ex_get_num_props (exoid, EX_SIDE_SET);
    break;

  case EX_INQ_ELEM_MAP:
    /* returns the number of element maps */
    if (ex_get_dimension(exoid, DIM_NUM_EM, "element maps", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_EM_PROP:
    /* returns the number of element map properties */
    *ret_int = ex_get_num_props (exoid, EX_ELEM_MAP);
    break;

  case EX_INQ_NODE_MAP:
    /* returns the number of node maps */
    if (ex_get_dimension(exoid, DIM_NUM_NM, "node maps", &ldum, &dimid, NULL) != NC_NOERR)
      *ret_int = 0;
    else
      *ret_int = ldum;
    break;

  case EX_INQ_NM_PROP:
    /* returns the number of node map properties */
    *ret_int = ex_get_num_props (exoid, EX_NODE_MAP);
    break;

  case EX_INQ_EDGE:
    /* returns the number of edges (defined across all edge blocks). */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_EDGE, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_EDGE_BLK:
    /* returns the number of edge blocks. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ED_BLK, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_EDGE_SETS:
    /* returns the number of edge sets. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ES, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_ES_LEN:
    /* returns the length of the concatenated edge set edge list. */
    ex_get_concat_set_len(exoid, ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,"num_edge_es",0);
    break;

  case EX_INQ_ES_DF_LEN:
    /* returns the length of the concatenated edge set distribution factor list. */
    ex_get_concat_set_len(exoid, ret_int,"edge",EX_EDGE_SET,DIM_NUM_ES,VAR_ES_STAT,"num_df_es",1);
    break;

  case EX_INQ_EDGE_PROP:
    /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */
    *ret_int = ex_get_num_props( exoid, EX_EDGE_BLOCK );
    break;

  case EX_INQ_ES_PROP:
    /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */
    *ret_int = ex_get_num_props( exoid, EX_EDGE_SET );
    break;

  case EX_INQ_FACE:
    /* returns the number of faces (defined across all face blocks). */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FACE, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_FACE_BLK:
    /* returns the number of face blocks. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FA_BLK, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_FACE_SETS:
    /* returns the number of face sets. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FS, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_FS_LEN:
    /* returns the length of the concatenated edge set edge list. */
    ex_get_concat_set_len(exoid, ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,"num_face_fs",0);
    break;

  case EX_INQ_FS_DF_LEN:
    /* returns the length of the concatenated edge set distribution factor list. */
    ex_get_concat_set_len(exoid, ret_int,"face",EX_FACE_SET,DIM_NUM_FS,VAR_FS_STAT,"num_df_fs",1);
    break;

  case EX_INQ_FACE_PROP:
    /* returns the number of integer properties stored for each edge block. This includes the "ID" property. */
    *ret_int = ex_get_num_props( exoid, EX_FACE_BLOCK );
    break;

  case EX_INQ_FS_PROP:
    /* returns the number of integer properties stored for each edge set.. This includes the "ID" property */
    *ret_int = ex_get_num_props( exoid, EX_FACE_SET );
    break;

  case EX_INQ_ELEM_SETS:
    /* returns the number of element sets. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_ELS, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_ELS_LEN:
    /* returns the length of the concatenated element set element list. */
    ex_get_concat_set_len(exoid, ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,"num_ele_els",0);
    break;

  case EX_INQ_ELS_DF_LEN:
    /* returns the length of the concatenated element set distribution factor list. */
    ex_get_concat_set_len(exoid, ret_int,"element",EX_ELEM_SET,DIM_NUM_ELS,VAR_ELS_STAT,"num_df_els",1);
    break;

  case EX_INQ_ELS_PROP:
    /* returns the number of integer properties stored for each element set. */
    *ret_int = ex_get_num_props( exoid, EX_ELEM_SET );
    break;

  case EX_INQ_EDGE_MAP:
    /* returns the number of edge maps. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_EDM, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_FACE_MAP:
    /*     returns the number of face maps. */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_FAM, 1) != EX_NOERR) return EX_FATAL;
    break;

  case EX_INQ_COORD_FRAMES:
    /* return the number of coordinate frames */
    if (ex_get_dimension_value(exoid, ret_int, 0, DIM_NUM_CFRAMES, 1) != EX_NOERR) return EX_FATAL;
    break;

  default:
    *ret_int = 0;
    exerrval = EX_FATAL;
    sprintf(errmsg, "Error: invalid inquiry %d", req_info);
    ex_err("ex_inquire",errmsg,exerrval);
    return(EX_FATAL);
  }
  return (EX_NOERR);
}
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;
}
int
test_redef(int format)   
{
   int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS];
   int ndims, nvars, natts, unlimdimid;
   int dimids_var[REDEF_NDIMS], var_type;
   int cflags = 0;
   size_t dim_len;
   char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
   float float_in;
   double double_out = 99E99;
   int int_in;
   unsigned char uchar_in, uchar_out = 255;
   short short_out = -999;
   nc_type xtype_in;
   size_t cache_size_in, cache_nelems_in;
   float cache_preemption_in;
   int ret;

   if (format == NC_FORMAT_64BIT)
      cflags |= NC_64BIT_OFFSET;
   else if (format == NC_FORMAT_NETCDF4_CLASSIC)
      cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL);
   else if (format == NC_FORMAT_NETCDF4)
      cflags |= NC_NETCDF4;

   /* Change chunk cache. */
   if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS, 
			  NEW_CACHE_PREEMPTION)) ERR;

   /* Create a file with two dims, two vars, and two atts. */
   if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;

   /* Retrieve the chunk cache settings, just for fun. */
   if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in, 
			  &cache_preemption_in)) ERR;
   if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
       cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;

   /* This will fail, except for netcdf-4/hdf5, which permits any
    * name. */
   if (format != NC_FORMAT_NETCDF4)
      if ((ret = nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN, 
			    &dimids[1])) != NC_EBADNAME) ERR;

   if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
   if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
   if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR;
   if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* Close it up. */
   if (format != NC_FORMAT_NETCDF4)
      if (nc_enddef(ncid)) ERR;
   if (nc_close(ncid)) ERR;

   /* Reopen as read only - make sure it doesn't let us change file. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* This will fail. */
   ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS, 
			  dimids, &varid);
   if(format == NC_FORMAT_NETCDF4) {
	if(ret != NC_EPERM) {
	    ERR;
	}
   } else {
	if(ret != NC_ENOTINDEFINE) {
	    ERR;
	}
   }
   /* This will fail. */
   if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
   if (nc_close(ncid)) ERR;      

   /* Make sure we can't redef a file opened for NOWRITE. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_redef(ncid) != NC_EPERM) ERR;

   /* Check it out again. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen the file and check it, add a variable and attribute. */
   if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;

   /* Add var. */
   if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;

   /* Add att. */
   ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out);
   if (format != NC_FORMAT_NETCDF4 && ret) ERR;
   else if (format == NC_FORMAT_NETCDF4 && ret != NC_ERANGE) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen it and check each dim, var, and att. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR;
   if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR;
   if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR;
   if (int_in != short_out) ERR;
   ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in);
   if (format == NC_FORMAT_NETCDF4)
   {
      if (ret != NC_ERANGE) ERR;
   }
   else if (ret) ERR;
	 
   if (uchar_in != uchar_out) ERR;
   if (nc_close(ncid)) ERR;      
   return NC_NOERR;
}
Example #14
0
int ex_open_int (const char  *path,
		 int    mode,
		 int   *comp_ws,
		 int   *io_ws,
		 float *version,
		 int    run_version)
{
  int exoid;
  int status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t att_len = 0;
  int old_fill;
  int file_wordsize;
  int dim_str_name;
  int int64_status = 0;
  
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */
 
  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus version %d.%02d,\n          but was linked with exodus library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }
  

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    exerrval = EX_BADFILEMODE;
    sprintf(errmsg,"Error: Cannot specify both EX_READ and EX_WRITE");
    ex_err("ex_open",errmsg,exerrval); 
    return (EX_FATAL);
  }

  /* The EX_READ mode is the default if EX_WRITE is not specified... */
  if (!(mode & EX_WRITE)) { /* READ ONLY */
#if defined(__LIBCATAMOUNT__)
    if ((status = nc_open (path, NC_NOWRITE, &exoid)) != NC_NOERR)
#else
      if ((status = nc_open (path, NC_NOWRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	{
	  /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	  if (status == 0) {
	    exerrval = EX_FATAL;
	  }
	  else {
	    /* It is possible that the user is trying to open a netcdf4
	       file, but the netcdf4 capabilities aren't available in the
	       netcdf linked to this library. Note that we can't just use a
	       compile-time define since we could be using a shareable
	       netcdf library, so the netcdf4 capabilities aren't known
	       until runtime...
	  
	       Netcdf-4.X does not (yet?) have a function that can be
	       queried to determine whether the library being used was
	       compiled with --enable-netcdf4, so that isn't very
	       helpful.. 

	       At this time, query the beginning of the file and see if it
	       is an HDF-5 file and if it is assume that the open failure
	       is due to the netcdf library not enabling netcdf4 features...
	    */
	    int type = 0;
	    ex_check_file_type(path, &type);
	  
	    if (type == 5) {
	      /* This is an hdf5 (netcdf4) file. Since the nc_open failed,
		 the assumption is that the netcdf doesn't have netcdf4
		 capabilities enabled.  Tell the user...
	      */
	      fprintf(stderr,
		      "EXODUS: Error: Attempting to open the netcdf-4 file:\n\t'%s'\n\twith a netcdf library that does not support netcdf-4\n",
		      path);
	    }
	    exerrval = status;
	  }
	  sprintf(errmsg,"Error: failed to open %s read only",path);
	  ex_err("ex_open",errmsg,exerrval); 
	  return(EX_FATAL);
	} 
  }
  else /* (mode & EX_WRITE) READ/WRITE */
    {
#if defined(__LIBCATAMOUNT__)
      if ((status = nc_open (path, NC_WRITE, &exoid)) != NC_NOERR)
#else
	if ((status = nc_open (path, NC_WRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	  {
	    /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	    if (status == 0)
	      exerrval = EX_FATAL;
	    else
	      exerrval = status;
	    sprintf(errmsg,"Error: failed to open %s write only",path);
	    ex_err("ex_open",errmsg,exerrval); 
	    return(EX_FATAL);
	  } 

      /* turn off automatic filling of netCDF variables */
      if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to set nofill mode in file id %d",
		exoid);
	ex_err("ex_open", errmsg, exerrval);
	return (EX_FATAL);
      }

      stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
      stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
      if(stat_att != NC_NOERR || stat_dim != NC_NOERR) {
	nc_redef(exoid);
	if (stat_att != NC_NOERR) {
	  int max_so_far = 32;
	  nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
	}

	/* If the DIM_STR_NAME variable does not exist on the database, we need to add it now. */
	if(stat_dim != NC_NOERR) {
	  /* Not found; set to default value of 32+1. */
	  int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
	  nc_def_dim(exoid, DIM_STR_NAME, max_name+1, &dim_str_name);
	}
	nc_enddef (exoid);
      }
    }

  /* determine version of EXODUS II file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    exerrval  = status;
    sprintf(errmsg,"Error: failed to get database version for file id: %d",
	    exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    exerrval  = EX_FATAL;
    sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d",
	    *version, exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR)
    {  /* try old (prior to db version 2.02) attribute name */
      if (nc_get_att_int (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) != NC_NOERR)
	{
	  exerrval  = EX_FATAL;
	  sprintf(errmsg,"Error: failed to get file wordsize from file id: %d",
		  exoid);
	  ex_err("ex_open",errmsg,exerrval);
	  return(exerrval);
	}
    }

  /* See if int64 status attribute exists and if so, what data is stored as int64 
   * Older files don't have the attribute, so it is not an error if it is missing
   */
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }
  
  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);
  
  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini( exoid, comp_ws, io_ws, file_wordsize, int64_status ) != EX_NOERR ) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to initialize conversion routines in file id %d",
            exoid);
    ex_err("ex_open", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
Example #15
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 );
}
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 file functions.\n");
   {
      char str[NC_MAX_NAME+1];
      
      /* Actually we never make any promises about the length of the
       * version string, but it is always smaller than NC_MAX_NAME. */
      if (strlen(nc_inq_libvers()) > NC_MAX_NAME) ERR;
      strcpy(str, nc_inq_libvers());
      printf("*** testing version %s...", str);
   }
   SUMMARIZE_ERR;
   printf("*** testing with bad inputs...");
   {
      int ncid;

      /* Make sure bad create mode causes failure. */
      /*if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;*/
      
      /* Create an empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;

      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_NETCDF4, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple opens and creates...");
   {
      int ncid, ncid2, ncid3, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[1], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      unsigned char uchar_out[DIM1_LEN] = {0, 128, 255};

      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open three copies of the same file. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid2)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid3)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid2, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid3, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_close(ncid2)) ERR;
      if (nc_close(ncid3)) ERR;
      
      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a file with one dimension and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a simple file, and write some data to it. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out) != NC_ERANGE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_BYTE ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate the file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it, then make sure NOCLOBBER works. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_NOCLOBBER, &ncid) != NC_EEXIST) ERR;

      /* Recreate it again. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again with netcdf-3 rules turned on. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Check that netcdf-3 rules are in effect. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid) != NC_ENOTINDEFINE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check some other stuff about it. Closing and reopening the
       * file forces HDF5 to tell us if we forgot to free some HDF5
       * resource associated with the file. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing more complex opens and creates...");
   {
      int ncid, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[2], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      float float_in, float_out = 99.99;
      int int_in, int_out = -9999;

      /* Create a file, this time with attributes. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT1_NAME, NC_FLOAT, 1, &float_out)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT2_NAME, NC_INT, 1, &int_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check it. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen it and check each dim, var, and att. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
      if (dim_len != DIM2_LEN || strcmp(dim_name, DIM2_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR2_NAME) || var_type != NC_UINT ||
	  dimids_var[1] != dimids[1] || natts != 0) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT1_NAME, &float_in)) ERR;
      if (float_in != float_out) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT2_NAME, &int_in)) ERR;
      if (int_in != int_out) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

   printf("*** testing redef for netCDF classic...");
   test_redef(NC_FORMAT_CLASSIC);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF 64-bit offset...");
   test_redef(NC_FORMAT_64BIT);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF-4 ...");
   test_redef(NC_FORMAT_NETCDF4);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF-4, with strict netCDF-3 rules...");
   test_redef(NC_FORMAT_NETCDF4_CLASSIC);
   SUMMARIZE_ERR;
   printf("*** testing different formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-4 file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_NETCDF4) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing CLASSIC_MODEL flag with classic formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing multiple open files...");
   {
#define VAR_NAME "Captain_Kirk"
#define NDIMS 1
#define NUM_FILES 30
#define TEXT_LEN 15
#define D1_NAME "tl"
      int ncid[NUM_FILES], varid;
      int dimid;
      size_t count[NDIMS], index[NDIMS] = {0};
      const char ttext[TEXT_LEN + 1] = "20051224.150000";
      char ttext_in[TEXT_LEN + 1];
      char file_name[NC_MAX_NAME + 1];
      size_t chunks[NDIMS] = {TEXT_LEN + 1};
      int f;

      /* Create a bunch of files. */
      for (f = 0; f < NUM_FILES; f++)
      {
	 sprintf(file_name, "tst_files2_%d.nc", f);
	 if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
	 if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
	 if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
	 if (f % 2 == 0)
	    if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;
	 
	 /* Write one time to the coordinate variable. */
	 count[0] = TEXT_LEN + 1;
	 if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
      }

      /* Read something from each file. */
      for (f = 0; f < NUM_FILES; f++)
      {
	 if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
	 if (strcmp(ttext_in, ttext)) ERR;
      }

      /* Close all open files. */
      for (f = 0; f < NUM_FILES; f++)
	 if (nc_close(ncid[f])) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #17
0
int
main(int argc, char **argv)
{
    int ncid, dimid, fvarid, dvarid;
    int dimids[NDIMS];
    float fvals[NVALS], fvals_in[NVALS];
    double dvals[NVALS], dvals_in[NVALS];

    float fnan = 0.f/0.f;
    double dnan = 0.0/0.0;
    float fpinf = 1.0f/0.0f;
    float fninf = -fpinf;
    double dpinf = 1.0/0.0;
    double dninf = -dpinf;
    nc_type att_type;
    size_t att_len;
    float att_fvals[NVALS];
    double att_dvals[NVALS];

#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif
    printf("*** creating NaN test file %s...", FILE8_NAME);
    if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR;
    
    if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR;
    dimids[0] = dimid;
    
    if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, NULL, &fvarid)) ERR;
    if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, NULL, &dvarid)) ERR;

    fvals[0] = fninf;
    fvals[1] = fnan;
    fvals[2] = fpinf;
    dvals[0] = dninf;
    dvals[1] = dnan;
    dvals[2] = dpinf;
    
    /* Create float and double attributes */
    if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR;
    if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR;
    if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR;
    if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR;
    
    if (nc_enddef(ncid)) ERR;
   
    /* Write float and double data */
   if (nc_put_var_float(ncid, fvarid, fvals)) ERR;
   if (nc_put_var_double(ncid, dvarid, dvals)) ERR;
   
   if (nc_close(ncid)) ERR;
   
   /* Check it out. */
   
   /* Reopen the file. */
   if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR;
   if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR;
   /* Check the values of the float attributes */
   if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR;
   if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR;
   if (!isnan(att_fvals[0])) ERR;
   if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR;
   if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR;
   if (!isnan(att_fvals[1])) ERR;
   if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR;
   /* Check the values of double attributes */
   if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR;
   if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR;
   if (!isnan(att_dvals[0])) ERR;
   if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR;
   if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR;
   if (!isnan(att_dvals[1])) ERR;
   if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR;
   /* Check values of float data */
   if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR;
   if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR;
   if (!isnan(fvals_in[1])) ERR;
   if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR;
   /* Check values of double data */
   if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR;
   if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR;
   if (!isnan(dvals_in[1])) ERR;
   if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR;

   if (nc_close(ncid)) ERR;
   
   SUMMARIZE_ERR;
   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

   printf("*** SUCCESS writing example file tst_nans.nc!\n");
   return 0;
}
bool
NETCDFFileObject::ReadAttribute(const char *varname, const char *attname,
    TypeEnum *type, int *ndims, int **dims, void **value)
{
    const char *mName = "NETCDFFileObject::ReadAttribute: ";
    int varid, status;
    int natts = 0;
    bool varvalid = false;

    if(varname == 0)
    {
        varid = NC_GLOBAL;
        if((status = nc_inq_natts(GetFileHandle(), &natts)) == NC_NOERR)
            varvalid = natts > 0;
        else
        {
            debug4 << mName << "0: ";
            HandleError(status);
        }
    }
    else
    {
        // Look up the variable name and gets its variable id.
        varvalid = GetVarId(varname, &varid);
    }

    if(varvalid)
    {
        nc_type atttype;
        size_t  attsize;
        if((status = nc_inq_att(GetFileHandle(), varid, attname, &atttype,
                                &attsize)) == NC_NOERR)
        {
            void *val = 0;
            TypeEnum t = NO_TYPE;

            // Try and read the attribute.
            if(atttype == NC_CHAR)
            {
                char *arr = new char[attsize+1];
                status = nc_get_att_text(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                {
                    // Trim trailing spaces.
                    arr[attsize] = '\0';
                    char *c2 = arr + attsize - 1;
                    while(c2 >= arr && *c2 == ' ')
                        *c2-- = '\0';

                    val = (void*)arr;
                }
                t = CHARARRAY_TYPE;
            }
            else if(atttype == NC_BYTE)
            {
                unsigned char *arr = new unsigned char[attsize+1];
                status = nc_get_att_uchar(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = UCHARARRAY_TYPE;
            }
            else if(atttype == NC_SHORT)
            {
                short *arr = new short[attsize];
                status = nc_get_att_short(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = SHORTARRAY_TYPE;
            } 
            else if(atttype == NC_INT)
            {
                int *arr = new int[attsize];
                status = nc_get_att_int(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = INTEGERARRAY_TYPE;
            } 
            else if(atttype == NC_LONG)
            {
                long *arr = new long[attsize];
                status = nc_get_att_long(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = LONGARRAY_TYPE;
            } 
            else if(atttype == NC_FLOAT)
            {
                float *arr = new float[attsize];
                status = nc_get_att_float(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = FLOATARRAY_TYPE;
            } 
            else if(atttype == NC_DOUBLE)
            {
                double *arr = new double[attsize];
                status = nc_get_att_double(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = DOUBLEARRAY_TYPE;
            } 

            if(status == NC_NOERR)
            {
                *type = t;
                *ndims = 1;
                int *d = new int[1];
                d[0] = (int)attsize;
                *dims = d;
                *value = val;
            }
            else
            {
                *type = NO_TYPE;
                *ndims = 0;
                *dims = 0;
                *value = 0;
                debug4 << mName << "3: ";
                HandleError(status);
                varvalid = false;
            }
        }
        else
        {
            varvalid = false;
            debug4 << mName << "4: ";
            HandleError(status);
        }
    }

    return varvalid;
}
Example #19
0
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);

} 
Example #20
0
/*
 * Get the value of a netCDF attribute given its variable ID and name.
 */
static void
c_ncagt(
    int		ncid,		/* netCDF ID */
    int		varid,		/* variable ID */
    const char*	attname,	/* attribute name */
    void*	value,		/* pointer to data values */
    int*	rcode		/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_atttype(ncid, varid, attname, &datatype)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#    	if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_get_att_schar(ncid, varid, attname, 
					   (signed char*)value);
#    	elif NF_INT1_IS_C_SHORT
		status = nc_get_att_short(ncid, varid, attname, 
					   (short*)value);
#    	elif NF_INT1_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#    	elif NF_INT1_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#    	endif
	    break;
	case NC_SHORT:
#    	if NF_INT2_IS_C_SHORT
		status = nc_get_att_short(ncid, varid, attname, 
					   (short*)value);
#    	elif NF_INT2_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#    	elif NF_INT2_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#    	endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#    	if NF_REAL_IS_C_FLOAT
		status = nc_get_att_float(ncid, varid, attname, 
					   (float*)value);
#    	elif NF_REAL_IS_C_DOUBLE
		status = nc_get_att_double(ncid, varid, attname, 
					   (double*)value);
#    	endif
	    break;
	case NC_DOUBLE:
#    	if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_get_att_float(ncid, varid, attname, 
					   (float*)value);
#    	elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_get_att_double(ncid, varid, attname, 
					   (double*)value);
#    	endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCAGT", status, "");
	*rcode = ncerr;
    }
}
Example #21
0
int
main(int argc, char **argv)
{
    (void) signal(SIGFPE, SIG_IGN);

   printf("\n*** Testing netcdf-4 attribute functions.\n");
   printf("*** testing really simple global atts...");
#define NUM_SIMPLE_ATTS 9
   {
      int ncid;
      char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf", 
						      "Gd", "G7", "G8", "G9"};
      char name_in[NC_MAX_NAME];
      int j;

      /* Create a file with some global atts. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      for (j = 0; j < NUM_SIMPLE_ATTS; j++)
	 if (nc_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check the order. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      for (j = 0; j < NUM_SIMPLE_ATTS; j++)
      {
	 if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR;
	 if (strcmp(name_in, name[j])) ERR;
      }

      /* Close up shop. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple global atts...");
   {      
      int ncid;
      nc_type att_type;
      size_t att_len;
      int i;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
      unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
      unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL};
      long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64};


      /* This won't work, because classic files can't create these types. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, 
			    ushort_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, 
			  uint_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, 
			      int64_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, 
			       uint64_out) != NC_ESTRICTNC3) ERR;      
      if (nc_close(ncid)) ERR;

      /* Create a file with a global attribute of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR;
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR;      
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR;      
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR;      
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR;      
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR;      
      if (nc_close(ncid)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      /* Check text. */
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len))
	 ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      /* Check numeric values. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != schar_out[i]) ERR;
      if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uchar_in[i] != uchar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != float_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != double_out[i]) ERR;
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (ushort_in[i] != ushort_out[i]) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uint_in[i] != uint_out[i]) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int64_in[i] != int64_out[i]) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uint64_in[i] != uint64_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing attribute data type conversions...");

   {
      int ncid;
      int i;

      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN];
      unsigned int uint_in[ATT_LEN];
      unsigned long long uint64_in[ATT_LEN];
      long long int64_in[ATT_LEN];

      /* Reopen the file and try different type conversions. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;

      /* No text conversions are allowed, and people who try them shold
       * be locked up, away from decent folk! */
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in) != NC_ECHAR) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in) != NC_ECHAR) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in) != NC_ECHAR) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in) != NC_ECHAR) ERR;
/*   if (nc_get_att_ubyte(ncid, NC_GLOBAL, ATT_TEXT_NAME, uchar_in) != NC_ECHAR) ERR;*/
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_TEXT_NAME, ushort_in) != NC_ECHAR) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint_in) != NC_ECHAR) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_TEXT_NAME, int64_in) != NC_ECHAR) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint64_in) != NC_ECHAR) ERR;

      /* Read all atts (except text) as double. */
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != schar_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != short_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != int_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != float_out[i]) ERR;
      /* Read all atts (except text) as float. */
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != schar_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != short_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != (float)int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != (float)double_out[i]) ERR;
      /* Read all atts (except text) as int. */
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != schar_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != (int)float_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != (int)double_out[i]) ERR;
      /* Read all atts (except text) as short. */
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != schar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)int_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)float_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)double_out[i]) ERR;
      /* Read all atts (except text) as schar. Some range errors will
       * result converting to schar. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)short_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)int_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)float_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)double_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple variable atts...");
   {
      int ncid, varid, dimids[2];
      nc_type att_type;
      size_t att_len;
      int i, v;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};

      /* Create a file with two vars, attaching to each an attribute of
       * each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR;      
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR;      
      if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR;      
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; 
      if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR;           
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR;      
      if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR;      
      if (nc_close(ncid)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      for (v=0; v<2; v++)
      {
	 if (nc_inq_att(ncid, v, ATT_TEXT_NAME, &att_type, &att_len)) ERR;
	 if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
	 if (!(speech_in = malloc(att_len + 1))) ERR;
	 if (nc_get_att_text(ncid, v, ATT_TEXT_NAME, speech_in)) ERR;      
	 if (strcmp(speech, speech_in)) ERR;
	 free(speech_in);
	 if (nc_get_att_schar(ncid, v, ATT_SCHAR_NAME, schar_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (schar_in[i] != schar_out[i]) ERR;
	 if (nc_get_att_short(ncid, v, ATT_SHORT_NAME, short_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (short_in[i] != short_out[i]) ERR;
	 if (nc_get_att_int(ncid, v, ATT_INT_NAME, int_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (int_in[i] != int_out[i]) ERR;
	 if (nc_get_att_float(ncid, v, ATT_FLOAT_NAME, float_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (float_in[i] != float_out[i]) ERR;
	 if (nc_get_att_double(ncid, v, ATT_DOUBLE_NAME, double_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (double_in[i] != double_out[i]) ERR;
      }
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing zero-length attributes...");
   {
      int ncid;

      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/

      /* Create a file with a global attribute of each type of zero length. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR;
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR;
/*   if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR;
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR;
      if (nc_close(ncid)) ERR;
   }

   /* Make sure we can read all these zero-length atts. */
   {
      int ncid;
      signed char schar_in[ATT_LEN];
      short short_in[ATT_LEN];
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN];
      float float_in[ATT_LEN];
      double double_in[ATT_LEN];
      size_t len;
      nc_type xtype;

      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_CHAR) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_BYTE) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_SHORT) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_INT) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_FLOAT) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_DOUBLE) ERR;
      /* Conversions no longer result in range errors, since there's no data. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing zero-length attributes and redef...(this test skipped for HDF5-1.8.0 beta1");
   {
      int ncid;
      signed char schar_in[ATT_LEN];
      short short_in[ATT_LEN];
      int int_in[ATT_LEN];
      float float_in[ATT_LEN];
      double double_in[ATT_LEN];


      /* Create a file with a global attribute of each type of zero length. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR;
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR;
/*   if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR;
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR;
      if (nc_close(ncid)) ERR;

      /* Make sure we can read all these zero-length atts added during a
       * redef. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;
      /* Conversions no longer result in range errors, since there's no data. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

   printf("*** testing attribute deletes and renames...");
   {
      int ncid, varid, dimids[2];
      nc_type att_type;
      size_t att_len;
      char *speech_in;
      char name_in[NC_MAX_NAME + 1];
      int attid_in, natts_in;
      int int_out[ATT_LEN] = {-100000, 128, 100000};

      /* Create a file with a global attribute. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, 
			  speech)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Rename it. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR;
      if (strcmp(name_in, ATT_TEXT_NAME)) ERR;
      if (nc_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2)) ERR;      
      if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR;
      if (strcmp(name_in, ATT_TEXT_NAME2)) ERR;
      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len)) ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in) != NC_ENOTATT) ERR;      
      if (nc_close(ncid)) ERR;

      /* Now delete the att. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2)) ERR;
      if (nc_close(ncid)) ERR;

      /* Now create a file with a variable, which has an att. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and delete it. Make sure it's gone. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and readd the attribute. Enddef and redef,
       * and delete it, then check to make sure it's gone. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR;
      if (nc_inq_varnatts(ncid, 0, &natts_in)) ERR;
      if (natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute create order...");

#define ATT0 "Maturin"
#define ATT1 "Aubery"
   {
      int ncid, varid, dimids[2];
      int attid_in;
      const int number = 42;

      /* Create a file with several global attributes. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Open it and check the order. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in)) ERR;
      if (attid_in != 1) ERR;
      if (nc_close(ncid)) ERR;

      /* Now create a file with a variable, which has two atts. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number)) ERR;
      if (nc_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check the order of the attributes on the var. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, 0, ATT0, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attid(ncid, 0, ATT1, &attid_in)) ERR;
      if (attid_in != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute ordering some more...");

#define VAR_NAME "i"
#define A1_NAME "i"      
#define A2_NAME "f"      
#define A3_NAME "d"      
#define A1_LEN 3
#define A2_LEN 4
#define A3_LEN 5
   {
      int ncid;
      int varid, natts, nvars;
      double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99};
      int varids[1];
      char name_in[NC_MAX_NAME + 1];

      /* Create a file with one var, and attach three atts to it. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid)) ERR;
      if (nc_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue)) ERR;      
      if (nc_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue)) ERR;      
      if (nc_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq_varids(ncid, &nvars, varids)) ERR;
      if (nvars != 1 || varids[0] != 0) ERR;
      if (nc_inq_varnatts(ncid, 0, &natts)) ERR;
      if (natts != 3) ERR;
      if (nc_inq_attname(ncid, 0, 0, name_in)) ERR;
      if (strcmp(name_in, A1_NAME)) ERR;
      if (nc_inq_attname(ncid, 0, 1, name_in)) ERR;
      if (strcmp(name_in, A2_NAME)) ERR;
      if (nc_inq_attname(ncid, 0, 2, name_in)) ERR;
      if (strcmp(name_in, A3_NAME)) ERR;

      /* Close up shop. */
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute ordering even more...");

   /* Test the ordering of atts for each cmode. */
   if (tst_att_ordering(NC_CLOBBER)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_64BIT_OFFSET)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR;

   SUMMARIZE_ERR;
   printf("*** testing attributes and enddef/redef...");

#define ATT_1 "a"
#define ATT_2 "b"
#define ATT_3 "c"
   {
      int ncid, att = 1;

      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL|NC_CLOBBER, &ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att)) ERR;

      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing copy of simple global atts...");
   {      
      int ncid, ncid2;
      nc_type att_type;
      size_t att_len;
      int i;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
      unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
      unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL};
      long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64};

      /* Create a file with a global attribute of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR;
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR;      
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR;      
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR;      
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR;      
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR;      

      /* Create another file and copy all the attributes. */
      if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR;      
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UCHAR_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_USHORT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT64_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT64_NAME, ncid2, NC_GLOBAL)) ERR;

      /* Close both files. */
      if (nc_close(ncid)) ERR;
      if (nc_close(ncid2)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME2, 0, &ncid)) ERR;
      /* Check text. */
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      /* Check numeric values. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != schar_out[i]) ERR;
      if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uchar_in[i] != uchar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != float_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != double_out[i]) ERR;
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (ushort_in[i] != ushort_out[i]) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uint_in[i] != uint_out[i]) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (int64_in[i] != int64_out[i]) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uint64_in[i] != uint64_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, float* data)
{
  return nc_get_att_float(ncid, varid, attrName, data);
}
Example #23
0
str
NCDFattach(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	mvc *m = NULL;
	sql_schema *sch = NULL;
	sql_table *tfiles = NULL, *tdims = NULL, *tvars = NULL, *tvardim = NULL, *tattrs = NULL;
	sql_column *col;
	str msg = MAL_SUCCEED;
	str fname = *(str*)getArgReference(stk, pci, 1);
	char buf[BUFSIZ], *s= buf;
	oid fid, rid = oid_nil;
	sql_trans *tr;

	int ncid;   /* dataset id */
	int ndims, nvars, ngatts, unlimdim;
	int didx, vidx, vndims, vnatts, i, aidx, coord_dim_id = -1;
	int vdims[NC_MAX_VAR_DIMS];

	size_t dlen, alen;
	char dname[NC_MAX_NAME+1], vname[NC_MAX_NAME+1], aname[NC_MAX_NAME +1], 
	  abuf[80], *aval;
	char **dims = NULL;
	nc_type vtype, atype; /* == int */

	int retval, avalint;
	float avalfl;
	double avaldbl;

	msg = getSQLContext(cntxt, mb, &m, NULL);
	if (msg)
        return msg;

	tr = m->session->tr;
	sch = mvc_bind_schema(m, "sys");
	if ( !sch )
        return createException(MAL, "netcdf.attach", "Cannot get schema sys\n");

	tfiles = mvc_bind_table(m, sch, "netcdf_files");
	tdims = mvc_bind_table(m, sch, "netcdf_dims");
	tvars = mvc_bind_table(m, sch, "netcdf_vars");
	tvardim = mvc_bind_table(m, sch, "netcdf_vardim");
	tattrs = mvc_bind_table(m, sch, "netcdf_attrs");

	if (tfiles == NULL || tdims == NULL || tvars == NULL || 
	    tvardim == NULL || tattrs == NULL)
        return createException(MAL, "netcdf.attach", "Catalog table missing\n");

	/* check if the file is already attached */
	col = mvc_bind_column(m, tfiles, "location");
	rid = table_funcs.column_find_row(m->session->tr, col, fname, NULL);
	if (rid != oid_nil) 
	    return createException(SQL, "netcdf.attach", "File %s is already attached\n", fname);

	/* Open NetCDF file  */
	if ((retval = nc_open(fname, NC_NOWRITE, &ncid)))
        return createException(MAL, "netcdf.test", "Cannot open NetCDF \
file %s: %s", fname, nc_strerror(retval));

	if ((retval = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdim)))
        return createException(MAL, "netcdf.test", "Cannot read NetCDF \
header: %s", nc_strerror(retval));

	/* Insert row into netcdf_files table */
	col = mvc_bind_column(m, tfiles, "file_id");
	fid = store_funcs.count_col(tr, col, 1) + 1;

	snprintf(buf, BUFSIZ, INSFILE, (int)fid, fname);
	if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	        != MAL_SUCCEED )
	    goto finish;

	/* Read dimensions from NetCDF header and insert a row for each one into netcdf_dims table */

	dims = (char **)GDKzalloc(sizeof(char *) * ndims);
	for (didx = 0; didx < ndims; didx++){
	    if ((retval = nc_inq_dim(ncid, didx, dname, &dlen)))
	        return createException(MAL, "netcdf.attach", "Cannot read dimension %d : %s", didx, nc_strerror(retval));

	    snprintf(buf, BUFSIZ, INSDIM, didx, (int)fid, dname, (int)dlen);
	    if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
    	 != MAL_SUCCEED )
	        goto finish;

	    dims[didx] = GDKstrdup(dname);
	}

	/* Read variables and attributes from the header and insert rows in netcdf_vars, netcdf_vardims, and netcdf_attrs tables */
	for (vidx = 0; vidx < nvars; vidx++){
	    if ( (retval = nc_inq_var(ncid, vidx, vname, &vtype, &vndims, vdims, &vnatts)))
	        return createException(MAL, "netcdf.attach", 
			     "Cannot read variable %d : %s", 
			     vidx, nc_strerror(retval));

    	/* Check if this is coordinate variable */
        if ( (vndims == 1) && ( strcmp(vname, dims[vdims[0]]) == 0 ))
	        coord_dim_id = vdims[0];
        else coord_dim_id = -1;

	    snprintf(buf, BUFSIZ, INSVAR, vidx, (int)fid, vname, prim_type_name(vtype), vndims, coord_dim_id);
	    if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	        != MAL_SUCCEED )
            goto finish;

	    if ( coord_dim_id < 0 ){
	        for (i = 0; i < vndims; i++){
                snprintf(buf, BUFSIZ, INSVARDIM, vidx, vdims[i], (int)fid, i);
                if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
            	   != MAL_SUCCEED )
                	goto finish;
	        }
	    }

    	if ( vnatts > 0 ) { /* fill in netcdf_attrs table */

            for (aidx = 0; aidx < vnatts; aidx++){
                if ((retval = nc_inq_attname(ncid,vidx,aidx,aname)))
                    return createException(MAL, "netcdf.attach",
                        "Cannot read attribute %d of variable %d: %s",
                        aidx, vidx, nc_strerror(retval));

	            if ((retval = nc_inq_att(ncid,vidx,aname,&atype,&alen)))
                    return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s type and length: %s",
	                    aname, nc_strerror(retval));


        	switch ( atype ) {
        	case NC_CHAR:
                aval = (char *) GDKzalloc(alen + 1);
                if ((retval = nc_get_att_text(ncid,vidx,aname,aval)))
                    return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
		fix_quote(aval, alen);
                aval[alen] = '\0';
                snprintf(buf, BUFSIZ, INSATTR, vname, aname, "string", aval, (int)fid, "root");
                GDKfree(aval);
            break;

        	case NC_INT:
	            if ((retval = nc_get_att_int(ncid,vidx,aname,&avalint)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
                snprintf(abuf,80,"%d",avalint);
                snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;
	
        	case NC_FLOAT:
	            if ((retval = nc_get_att_float(ncid,vidx,aname,&avalfl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
	            snprintf(abuf,80,"%7.2f",avalfl);
	            snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;

	        case NC_DOUBLE:
	            if ((retval = nc_get_att_double(ncid,vidx,aname,&avaldbl)))
        	        return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
    	        snprintf(abuf,80,"%7.2e",avaldbl);
	            snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;

        	default: continue; /* next attribute */
	        }

		printf("statement: '%s'\n", s);
        	if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	            != MAL_SUCCEED )
                goto finish;

	        } /* attr loop */

	    }
	} /* var loop */

	/* Extract global attributes */

	for (aidx = 0; aidx < ngatts; aidx++){
	    if ((retval = nc_inq_attname(ncid,NC_GLOBAL,aidx,aname)))
	        return createException(MAL, "netcdf.attach",
                "Cannot read global attribute %d: %s",
                aidx, nc_strerror(retval));

	    if ((retval = nc_inq_att(ncid,NC_GLOBAL,aname,&atype,&alen)))
	        return createException(MAL, "netcdf.attach",
                "Cannot read global attribute %s type and length: %s",
                aname, nc_strerror(retval));
    	switch ( atype ) {
	        case NC_CHAR:
	            aval = (char *) GDKzalloc(alen + 1);
	            if ((retval = nc_get_att_text(ncid,NC_GLOBAL,aname,aval)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s value: %s",
    	                aname, nc_strerror(retval));
		    fix_quote(aval, alen);
	            aval[alen] = '\0';
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, "string", aval, (int)fid, "root");
	            GDKfree(aval);
	            break;

            case NC_INT:
	            if ((retval = nc_get_att_int(ncid,NC_GLOBAL,aname,&avalint)))
	                return createException(MAL, "netcdf.attach",
			    	    "Cannot read global attribute %s of type %s : %s",
	                    aname, prim_type_name(atype), nc_strerror(retval));
    	        snprintf(abuf,80,"%d",avalint);
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

    	    case NC_FLOAT:
	            if ((retval = nc_get_att_float(ncid,NC_GLOBAL,aname,&avalfl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s of type %s: %s",
	                    aname, prim_type_name(atype), nc_strerror(retval));
    	        snprintf(abuf,80,"%7.2f",avalfl);
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

            case NC_DOUBLE:
    	        if ((retval = nc_get_att_double(ncid,NC_GLOBAL,aname,&avaldbl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s value: %s",
	                    aname, nc_strerror(retval));
	            snprintf(abuf,80,"%7.2e",avaldbl);
    	        snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

            default: continue; /* next attribute */
        }

	printf("global: '%s'\n", s);
        if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	          != MAL_SUCCEED )
	        goto finish;

    } /* global attr loop */


 finish:
    nc_close(ncid);

    if (dims != NULL ){
        for (didx = 0; didx < ndims; didx++)
            GDKfree(dims[didx]);
        GDKfree(dims);
    }

	return msg;
}
Example #24
0
int ex_open_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version,
                int run_version)
{
  int     exoid;
  int     status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t  att_len  = 0;
  int     old_fill;
  int     file_wordsize;
  int     dim_str_name;
  int     int64_status = 0;
  int     nc_mode      = 0;

  char errmsg[MAX_ERR_LENGTH];

  EX_FUNC_ENTER();

  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr,
            "EXODUS: Warning: This code was compiled with exodus "
            "version %d.%02d,\n          but was linked with exodus "
            "library version %d.%02d\n          This is probably an "
            "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE");
    ex_err(__func__, errmsg, EX_BADFILEMODE);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* The EX_READ mode is the default if EX_WRITE is not specified... */
  if (!(mode & EX_WRITE)) { /* READ ONLY */
    nc_mode = NC_NOWRITE | NC_SHARE;

#if NC_HAS_DISKLESS
    if (mode & EX_DISKLESS) {
      nc_mode |= NC_DISKLESS;
    }
#endif

    if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      /* It is possible that the user is trying to open a netcdf4
         file, but the netcdf4 capabilities aren't available in the
         netcdf linked to this library. Note that we can't just use a
         compile-time define since we could be using a shareable
         netcdf library, so the netcdf4 capabilities aren't known
         until runtime...

         Later versions of netcdf-4.X have a function that can be
         queried to determine whether the library being used was
         compiled with --enable-netcdf4, but not everyone is using that
         version yet, so we may have to do some guessing...

         At this time, query the beginning of the file and see if it
         is an HDF-5 file and if it is assume that the open failure
         is due to the netcdf library not enabling netcdf4 features unless
         we have the define that shows it is enabled, then assume other error...
      */
      int type = 0;
      ex_check_file_type(path, &type);

      if (type == 5) {
#if NC_HAS_HDF5
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the netcdf-4 "
                "file:\n\t'%s'\n\t failed. The netcdf library supports "
                "netcdf-4 so there must be a filesystem or some other "
                "issue \n",
                path);
#else
        /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined,
           then we either don't have hdf5 support in this netcdf version,
           OR this is an older netcdf version that doesn't provide that define.

           In either case, we don't have enough information, so we
           assume that the netcdf doesn't have netcdf4 capabilities
           enabled.  Tell the user...
        */
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the netcdf-4 "
                "file:\n\t'%s'\n\t. Either the netcdf library does not "
                "support netcdf-4 or there is a filesystem or some "
                "other issue \n",
                path);

#endif
      }
      else if (type == 4) {
#if defined(NC_64BIT_DATA)
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the CDF5 "
                "file:\n\t'%s'\n\t failed. The netcdf library supports "
                "CDF5-type files so there must be a filesystem or some other "
                "issue \n",
                path);
#else
        /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined,
           then we either don't have cdf5 support in this netcdf version,
           OR this is an older netcdf version that doesn't provide that define.

           In either case, we don't have enough information, so we
           assume that the netcdf doesn't have cdf5 capabilities
           enabled.  Tell the user...
        */
        fprintf(stderr,
                "EXODUS: ERROR: Attempting to open the CDF5 "
                "file:\n\t'%s'\n\t. Either the netcdf library does not "
                "support CDF5 or there is a filesystem or some "
                "other issue \n",
                path);

#endif
      }
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s read only", path);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }
  else { /* (mode & EX_WRITE) READ/WRITE */
    nc_mode = NC_WRITE | NC_SHARE;
#if NC_HAS_DISKLESS
    if (mode & EX_DISKLESS) {
      nc_mode |= NC_DISKLESS;
    }
#endif
    if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) {
      /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s write only", path);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* turn off automatic filling of netCDF variables */
    if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
    stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
    if (stat_att != NC_NOERR || stat_dim != NC_NOERR) {
      if ((status = nc_redef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }

      if (stat_att != NC_NOERR) {
        int max_so_far = 32;
        nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
      }

      /* If the DIM_STR_NAME variable does not exist on the database, we need to
       * add it now. */
      if (stat_dim != NC_NOERR) {
        /* Not found; set to default value of 32+1. */
        int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
        if ((status = nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name)) != NC_NOERR) {
          snprintf(errmsg, MAX_ERR_LENGTH,
                   "ERROR: failed to define string name dimension in file id %d", exoid);
          ex_err(__func__, errmsg, status);
          EX_FUNC_LEAVE(EX_FATAL);
        }
      }
      if ((status = nc_enddef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
    }
  }

  /* determine version of EXODUS file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d",
             *version, exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) {
    /* try old (prior to db version 2.02) attribute name */
    if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) !=
        NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d",
               exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  /* See if int64 status attribute exists and if so, what data is stored as
   * int64
   * Older files don't have the attribute, so it is not an error if it is
   * missing
   */
  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }

  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: There is an existing file already using the file "
             "id %d which was also assigned to file %s.\n\tWas "
             "nc_close() called instead of ex_close() on an open Exodus "
             "file?\n",
             exoid, path);
    ex_err(__func__, errmsg, EX_BADFILEID);
    nc_close(exoid);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 0, 0, 0) != EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to initialize conversion routines in file id %d", exoid);
    ex_err(__func__, errmsg, EX_LASTERR);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  EX_FUNC_LEAVE(exoid);
}
Example #25
0
int ex_open_par_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version,
                    MPI_Comm comm, MPI_Info info, int run_version)
{
  int     exoid;
  int     status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t  att_len  = 0;
  int     nc_mode  = 0;
  int     old_fill;
  int     file_wordsize;
  int     dim_str_name;
  int     int64_status = 0;
  int     is_hdf5      = 0;
  int     is_pnetcdf   = 0;
  int     in_redef     = 0;

  char errmsg[MAX_ERR_LENGTH];

  EX_FUNC_ENTER();

  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval); /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr,
            "EXODUS: Warning: This code was compiled with exodus "
            "version %d.%02d,\n          but was linked with exodus "
            "library version %d.%02d\n          This is probably an "
            "error in the build process of this code.\n",
            run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE");
    ex_err(__func__, errmsg, EX_BADFILEMODE);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (mode & EX_WRITE) {
    nc_mode = (NC_WRITE | NC_MPIIO);
  }
  else {
    nc_mode = (NC_NOWRITE | NC_SHARE | NC_MPIIO);
  }
  if ((status = nc_open_par(path, nc_mode, comm, info, &exoid)) != NC_NOERR) {
    /* It is possible that the user is trying to open a netcdf4
       file, but the netcdf4 capabilities aren't available in the
       netcdf linked to this library. Note that we can't just use a
       compile-time define since we could be using a shareable
       netcdf library, so the netcdf4 capabilities aren't known
       until runtime...

       Later versions of netcdf-4.X have a function that can be
       queried to determine whether the library being used was
       compiled with --enable-netcdf4, but not everyone is using that
       version yet, so we may have to do some guessing...

       At this time, query the beginning of the file and see if it
       is an HDF-5 file and if it is assume that the open failure
       is due to the netcdf library not enabling netcdf4 features unless
       we have the define that shows it is enabled, then assume other error...
    */
    int type = 0;
    ex_check_file_type(path, &type);

    if (type == 5) {
#if NC_HAS_HDF5
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the netcdf-4 "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "netcdf-4 so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined,
         then we either don't have hdf5 support in this netcdf version,
         OR this is an older netcdf version that doesn't provide that define.

         In either case, we don't have enough information, so we
         assume that the netcdf doesn't have netcdf4 capabilities
         enabled.  Tell the user...
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the netcdf-4 "
              "file:\n\t'%s'\n\tEither the netcdf library does not "
              "support netcdf-4 or there is a filesystem or some "
              "other issue \n",
              path);
#endif
    }
    else if (type == 4) {
#if defined(NC_64BIT_DATA)
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the CDF5 "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "CDF5-type files so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined,
         then we either don't have cdf5 support in this netcdf version,
         OR this is an older netcdf version that doesn't provide that define.

         In either case, we don't have enough information, so we
         assume that the netcdf doesn't have cdf5 capabilities
         enabled.  Tell the user...
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the CDF5 "
              "file:\n\t'%s'\n\tEither the netcdf library does not "
              "support CDF5 or there is a filesystem or some "
              "other issue \n",
              path);

#endif
    }
    else if (type == 1 || type == 2) {
#if NC_HAS_PNETCDF
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the classic NetCDF "
              "file:\n\t'%s'\n\t failed. The netcdf library supports "
              "PNetCDF files as required for parallel readinf of this "
              "file type, so there must be a filesystem or some other "
              "issue \n",
              path);
#else
      /* This is an normal NetCDF format file, for parallel reading, the PNetCDF
         library is required but that is not compiled into this version.
      */
      fprintf(stderr,
              "EXODUS: ERROR: Attempting to open the NetCDF "
              "file:\n\t'%s'\n\tThe NetCDF library was not "
              "built with PNetCDF support as required for parallel access to this file.\n",
              path);

#endif
    }

    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s of type %d read only", path, type);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* File opened correctly */
  int type = 0;
  ex_check_file_type(path, &type);
  if (type == 5) {
    is_hdf5 = 1;
  }
  else if (type == 1 || type == 2 || type == 4) {
    is_pnetcdf = 1;
  }

  if (mode & EX_WRITE) { /* Appending */
    /* turn off automatic filling of netCDF variables */
    if (is_pnetcdf) {
      if ((status = nc_redef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      in_redef = 1;
    }

    if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
    stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
    if (stat_att != NC_NOERR || stat_dim != NC_NOERR) {
      if (!in_redef) {
        if ((status = nc_redef(exoid)) != NC_NOERR) {
          snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode",
                   exoid);
          ex_err(__func__, errmsg, status);
          EX_FUNC_LEAVE(EX_FATAL);
        }
        in_redef = 1;
      }
      if (stat_att != NC_NOERR) {
        int max_so_far = 32;
        nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
      }

      /* If the DIM_STR_NAME variable does not exist on the database, we need to
       * add it now. */
      if (stat_dim != NC_NOERR) {
        /* Not found; set to default value of 32+1. */
        int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
        nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name);
      }
    }

    if (in_redef) {
      if ((status = nc_enddef(exoid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      in_redef = 0;
    }

    /* If this is a parallel execution and we are appending, then we
     * need to set the parallel access method for all transient variables to NC_COLLECTIVE since
     * they will be being extended.
     */
    int ndims;    /* number of dimensions */
    int nvars;    /* number of variables */
    int ngatts;   /* number of global attributes */
    int recdimid; /* id of unlimited dimension */

    int varid;

    /* Determine number of variables on the database... */
    nc_inq(exoid, &ndims, &nvars, &ngatts, &recdimid);

    for (varid = 0; varid < nvars; varid++) {
      struct ncvar var;
      nc_inq_var(exoid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts);

      if ((strcmp(var.name, VAR_GLO_VAR) == 0) || (strncmp(var.name, "vals_elset_var", 14) == 0) ||
          (strncmp(var.name, "vals_sset_var", 13) == 0) ||
          (strncmp(var.name, "vals_fset_var", 13) == 0) ||
          (strncmp(var.name, "vals_eset_var", 13) == 0) ||
          (strncmp(var.name, "vals_nset_var", 13) == 0) ||
          (strncmp(var.name, "vals_nod_var", 12) == 0) ||
          (strncmp(var.name, "vals_edge_var", 13) == 0) ||
          (strncmp(var.name, "vals_face_var", 13) == 0) ||
          (strncmp(var.name, "vals_elem_var", 13) == 0) ||
          (strcmp(var.name, VAR_WHOLE_TIME) == 0)) {
        nc_var_par_access(exoid, varid, NC_COLLECTIVE);
      }
    }
  } /* End of (mode & EX_WRITE) */

  /* determine version of EXODUS file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d",
             exoid);
    ex_err(__func__, errmsg, status);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d",
             *version, exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) !=
      NC_NOERR) { /* try old (prior to db version 2.02) attribute name */
    if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) !=
        NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d",
               exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }
  }

  /* See if int64 status attribute exists and if so, what data is stored as
   * int64
   * Older files don't have the attribute, so it is not an error if it is
   * missing
   */
  if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }

  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);

  /* Verify that there is not an existing file_item struct for this
     exoid This could happen (and has) when application calls
     ex_open(), but then closes file using nc_close() and then reopens
     file.  NetCDF will possibly reuse the exoid which results in
     internal corruption in exodus data structures since exodus does
     not know that file was closed and possibly new file opened for
     this exoid
  */
  if (ex_find_file_item(exoid) != NULL) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: There is an existing file already using the file "
             "id %d which was also assigned to file %s.\n\tWas "
             "nc_close() called instead of ex_close() on an open Exodus "
             "file?\n",
             exoid, path);
    ex_err(__func__, errmsg, EX_BADFILEID);
    nc_close(exoid);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 1, is_hdf5, is_pnetcdf) !=
      EX_NOERR) {
    snprintf(errmsg, MAX_ERR_LENGTH,
             "ERROR: failed to initialize conversion routines in file id %d", exoid);
    ex_err(__func__, errmsg, EX_LASTERR);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  EX_FUNC_LEAVE(exoid);
}
Example #26
0
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;
}
Example #27
0
struct ncvar * new_ncvar(const char *filename, const char *varname) {
  struct ncvar *v = NULL;
  int varid;			/* variable id */
  int dimid;			/* dimension id */
  float range[2];		/* min and max */
  int ncstat;
  
  v = calloc(1, sizeof(struct ncvar));
  
  /* open file */
  ncstat = nc_open(filename, NC_NOWRITE, &v->ncid);
  check_ncstat(ncstat, filename);

  /* get lat/lon/time sizes */
  ncstat = nc_inq_dimid(v->ncid, "lat", &dimid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_inq_dimlen(v->ncid, dimid, &v->nlat); 
  check_ncstat(ncstat, NULL);

  ncstat = nc_inq_dimid(v->ncid, "lon", &dimid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_inq_dimlen(v->ncid, dimid, &v->nlon); 
  check_ncstat(ncstat, NULL);

  ncstat = nc_inq_dimid(v->ncid, "time", &dimid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_inq_dimlen(v->ncid, dimid, &v->N); 
  check_ncstat(ncstat, NULL);

  /* get mins and maxes, calculate stepsizes */
  ncstat = nc_inq_varid (v->ncid, "lat", &varid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_get_att_float(v->ncid, varid, "actual_range", range);
  check_ncstat(ncstat, NULL);
  v->minlat = range[0]; v->maxlat = range[1];
  v->latstep = (v->maxlat - v->minlat) / (v->nlat -1.0);
  
  ncstat = nc_inq_varid (v->ncid, "lon", &varid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_get_att_float(v->ncid, varid, "actual_range", range);
  check_ncstat(ncstat, NULL);
  v->minlon = range[0]; v->maxlon = range[1];
  v->lonstep = (v->maxlon - v->minlon) / (v->nlon -1.0);
  
  ncstat = nc_inq_varid (v->ncid, "time", &varid);
  check_ncstat(ncstat, NULL);
  ncstat = nc_get_att_float(v->ncid, varid, "actual_range", range);
  check_ncstat(ncstat, NULL);
  v->mintime = range[0]; v->maxtime = range[1];

  /* get varid */
  ncstat = nc_inq_varid (v->ncid, varname, &v->varid);
  check_ncstat(ncstat, NULL);

  /* get var unpacking info */
  ncstat = nc_get_att_float(v->ncid, v->varid, "scale_factor", &v->scale);
  check_ncstat(ncstat, NULL);
  ncstat = nc_get_att_float(v->ncid, v->varid, "add_offset", &v->offset); 
  check_ncstat(ncstat, NULL);

  /* get nodata val */
  ncstat = nc_get_att_short(v->ncid, v->varid, "missing_value", &v->nodata); 
  check_ncstat(ncstat, NULL);

  /* record filename for debugging */
  v->filename = strdup(filename);
  
  return v;
} /* new_ncvar */
Example #28
0
int
main(int argc, char **argv)
{
    int ncid, dimid, fvarid, dvarid;
    float fvals[NVALS], fvals_in[NVALS];
    double dvals[NVALS], dvals_in[NVALS];


    float fnan = NC_FNAN;//(NC_INFINITE-NC_INFINITE);//0.f/0.f;
    double dnan = NC_DNAN;//(NC_INFINITE-NC_INFINITE);//0.0/0.0;
    float fpinf = NC_FPINF;//NC_INFINITE;//1.0f/0.0f;
    float fninf = -fpinf;
    double dpinf = NC_DPINF;//NC_INFINITE;//1.0/0.0;
    double dninf = -dpinf;
    nc_type att_type;
    size_t att_len;
    float att_fvals[NVALS];
    double att_dvals[NVALS];

    printf("\n*** Testing NaN\n");
    printf("*** creating NaN test file %s...", FILE8_NAME);
    if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR;

    if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR;

    if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, &dimid, &fvarid)) ERR;
    if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, &dimid, &dvarid)) ERR;

    fvals[0] = fninf;
    fvals[1] = fnan;
    fvals[2] = fpinf;
    dvals[0] = dninf;
    dvals[1] = dnan;
    dvals[2] = dpinf;

    /* Create float and double attributes */
    if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR;
    if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR;
    if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR;
    if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR;

    if (nc_enddef(ncid)) ERR;

    /* Write float and double data */
   if (nc_put_var_float(ncid, fvarid, fvals)) ERR;
   if (nc_put_var_double(ncid, dvarid, dvals)) ERR;

   if (nc_close(ncid)) ERR;

   /* Check it out. */

   /* Reopen the file. */
   if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR;
   if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR;
   /* Check the values of the float attributes */
   if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR;
   if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR;
   if (!isnan(att_fvals[0])) ERR;
   if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR;
   if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR;
   if (!isnan(att_fvals[1])) ERR;
   if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR;
   /* Check the values of double attributes */
   if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR;
   if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR;
   if (!isnan(att_dvals[0])) ERR;
   if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR;
   if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR;
   if (!isnan(att_dvals[1])) ERR;
   if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR;
   /* Check values of float data */
   if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR;
   if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR;
   if (!isnan(fvals_in[1])) ERR;
   if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR;
   /* Check values of double data */
   if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR;
   if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR;
   if (!isnan(dvals_in[1])) ERR;
   if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR;

   if (nc_close(ncid)) ERR;

   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #29
0
void get_grid_params(e *E){

    int      t,i,j,k;

    int	     temp_id;
    int      salt_id;
    int      status = 0;
    float    scale = 1.0;
    float    offset = 0.0;

    // open the mom4 temperature file and read the dimensions info
   if ((E->retval = nc_open(E->temperature_file_name, NC_NOWRITE, &E->ncid)))
		fail("couldn't open temperature file\n");	

    get_dimension(E, "xt_ocean", &E->xt_ocean);
    get_dimension(E, "yt_ocean", &E->yt_ocean);
    get_dimension(E, "st_ocean", &E->st_ocean);
    get_dimension(E, "Time", &E->time);

    E->T = malloc4d_double(E->time+1, E->st_ocean, E->yt_ocean, E->xt_ocean); 
    get_field(E,"temp", &E->T[0][0][0][0]);

    E->lon = malloc(E->xt_ocean*sizeof(double));
    E->lat = malloc(E->yt_ocean*sizeof(double));
    E->depth = malloc(E->st_ocean*sizeof(double));
    E->times = malloc(E->time*sizeof(double));

    get_field(E, "xt_ocean", &E->lon[0]);
    get_field(E, "yt_ocean", &E->lat[0]);
    get_field(E, "st_ocean", &E->depth[0]);
    get_field(E, "Time", &E->times[0]);   

 
    // read in the _FillValue
    nc_inq_varid (E->ncid, "temp", &temp_id);
    nc_get_att_float(E->ncid, temp_id, "_FillValue", &E->fillValue_temp);
    //printf("fillValue = %f\n", E->fillValue);
    // read in the scale and offset
    status = nc_get_att_float(E->ncid, temp_id, "scale_factor", &scale);
    if(status != NC_NOERR) scale = 1.0;
    status = nc_get_att_float(E->ncid, temp_id, "add_offset", &offset);
    if(status != NC_NOERR) offset = 0.0;

    //printf("scale = %f\noffset = %f\n", scale, offset);	
    // apply scale and offset to fillvalue
    if(status == NC_NOERR) E->fillValue_temp = E->fillValue_temp*scale + offset;
 
    // unpack the data
    for(t=0;t<E->time;t++){
        for(i=0;i<E->st_ocean;i++){
            for(j=0;j<E->yt_ocean;j++){
                for(k=0;k<E->xt_ocean;k++){
                    E->T[t][i][j][k] = E->T[t][i][j][k]*scale + offset;
                }
            }
         }
     }

    nc_close(E->ncid);
    


    // get salinity
    if ((E->retval = nc_open(E->salinity_file_name, NC_NOWRITE, &E->ncid)))
		fail("couldn't open salinity file\n");	
    
    E->S = malloc4d_double(E->time+1, E->st_ocean, E->yt_ocean, E->xt_ocean); 
    get_field(E,"salt", &E->S[0][0][0][0]);

    // malloc room for the sound speed variable
    E->c = malloc4d_double(E->time+1, E->st_ocean, E->yt_ocean, E->xt_ocean);

    // read in scale factor and offsets for temp and salinity
    // read in _FillValue for temp and salinity
    // read in st_ocean (metres)


    // read in the _FillValue
    nc_inq_varid (E->ncid, "salt", &salt_id);
    nc_get_att_float(E->ncid, salt_id, "_FillValue", &E->fillValue_salt);
    //printf("fillValue = %f\n", E->fillValue);
    // read in the scale and offset
    status = nc_get_att_float(E->ncid, salt_id, "scale_factor", &scale);
    if(status != NC_NOERR) scale = 1.0;
    status = nc_get_att_float(E->ncid, salt_id, "add_offset", &offset);
    if(status != NC_NOERR) offset = 0.0;
    //printf("scale = %f\noffset = %f\n", scale, offset);
    
    // apply scale and offset to fillvalue
    if(status == NC_NOERR) E->fillValue_salt = E->fillValue_salt*scale + offset;
    nc_close(E->ncid);
    
    
    // unpack the data
    for(t=0;t<E->time;t++){
        for(i=0;i<E->st_ocean;i++){
            for(j=0;j<E->yt_ocean;j++){
                for(k=0;k<E->xt_ocean;k++){
                    E->S[t][i][j][k] = E->S[t][i][j][k]*scale + offset;
                }
            }
         }
     }

    nc_close(E->ncid);

}