Exemplo n.º 1
0
/* 
 * Put a single character into an open netCDF file.
 */
static void
c_ncvp1c(
    int			ncid,	/* netCDF ID */
    int	 		varid,	/* variable ID */
    const size_t*	indices,/* multidim index of data to be written */
    const char*		value,	/* pointer to data value to be written */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	status = datatype != NC_CHAR
		    ? NC_ECHAR
		    : nc_put_var1_text(ncid, varid, indices, value);
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVP1C", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 2
0
/*
 * Get a single character data value from a variable of an open
 * netCDF file.
 */
static void
c_ncvg1c(
    int			ncid,	/* netCDF ID */
    int	 		varid,	/* variable ID */
    const size_t*	indices,/* multidim index of data to be read */
    char*		value,	/* pointer to data value to be read */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = nc_get_var1_text(ncid, varid, indices, value);
	    break;
	default:
	    status = NC_ECHAR;
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVG1C", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 3
0
/* Get attributes which define missing data information. If the
 * attributes are not there, then provide the valid data anyway, based
 * on netCDF defaults. */
int 
nccf_inq_var_missing(int ncid, int varid, void *fill_value, 
		     void *valid_min, void *valid_max)
{
   nc_type xtype;
   int ret;

   if ((ret = nc_inq_vartype(ncid, varid, &xtype)))
      return ret;

   /* Does the user want the fill value?*/
   if (fill_value)
   {
      /* Get the value of the _FillValue att, if it is there. */
      ret = nc_get_att(ncid, varid, CF_FILL_VALUE, fill_value);
      if (ret == NC_ENOTATT)
      {
	 /* No _FillValue att, so find the default fill value for this
	  * type. */
	 if ((ret = nccf_get_default_missing(xtype, fill_value, NULL, NULL)))
	    return ret;
      }
      else if (ret != NC_NOERR)
	 return ret;
   }

   /* Does the user want the fill value?*/
   if (valid_min)
   {
      /* Get the value of the valid_min, if it is there. */
      ret = nc_get_att(ncid, varid, CF_VALID_MIN, valid_min);
      if (ret == NC_ENOTATT)
      {
	 /* No _FillValue att, so find the default fill value for this
	  * type. */
	 if ((ret = nccf_get_default_missing(xtype, NULL, valid_min, NULL)))
	    return ret;
      }
      else if (ret != NC_NOERR)
	 return ret;
   }

   /* Does the user want the fill value?*/
   if (valid_max)
   {
      /* Get the value of the _FillValue att, if it is there. */
      ret = nc_get_att(ncid, varid, CF_VALID_MAX, valid_max);
      if (ret == NC_ENOTATT)
      {
	 /* No _FillValue att, so find the default fill value for this
	  * type. */
	 if ((ret = nccf_get_default_missing(xtype, NULL, NULL, valid_max)))
	    return ret;
      }
      else if (ret != NC_NOERR)
	 return ret;
   }

   return NC_NOERR;
}
Exemplo n.º 4
0
/* Return size of chunk in bytes for a variable varid in a group igrp, or 0 if
 * layout is contiguous */
static int
inq_var_chunksize(int igrp, int varid, size_t* chunksizep) {
    int stat = NC_NOERR;
    int ndims;
    size_t *chunksizes;
    int dim;
    int contig = 1;
    nc_type vartype;
    size_t value_size;
    size_t prod;

    NC_CHECK(nc_inq_vartype(igrp, varid, &vartype));
    /* from type, get size in memory needed for each value */
    NC_CHECK(nc_inq_type(igrp, vartype, NULL, &value_size));
    prod = value_size;
    NC_CHECK(nc_inq_varndims(igrp, varid, &ndims));
    chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));
    if(ndims > 0) {
	NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, NULL));
    }
    if(contig == 1) {
	*chunksizep = 0;
    } else {
	NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunksizes));
	for(dim = 0; dim < ndims; dim++) {
	    prod *= chunksizes[dim];
	}
	*chunksizep = prod;
    }
    free(chunksizes);
    return stat;
}
Exemplo n.º 5
0
NcType NcVar::type( void ) const
{
    nc_type typ;
    NcError::set_err(
		     nc_inq_vartype(the_file->id(), the_id, &typ)
		     );
    return (NcType) typ;
}
Exemplo n.º 6
0
/* Initialize iteration for a variable.  Just a wrapper for
 * nc_blkio_init() that makes the netCDF calls needed to initialize
 * lower-level iterator. */
int
nc_get_iter(int ncid,
	     int varid,
	     size_t bufsize,   /* size in bytes of memory buffer */
	     nciter_t **iterpp /* returned opaque iteration state */)
{
    int stat = NC_NOERR;
    nciter_t *iterp;
    nc_type vartype;
    size_t value_size = 0;      /* size in bytes of each variable element */
    int ndims;		    /* number of dimensions for variable */
    int *dimids;
    long long nvalues = 1;
    int dim;
    int chunked = 0;

    /* Caller should free this by calling nc_free_iter(iterp) */
    iterp = (nciter_t *) emalloc(sizeof(nciter_t));
    memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */

    NC_CHECK(nc_inq_varndims(ncid, varid, &ndims));

    dimids = (int *) emalloc((ndims + 1) * sizeof(int));

    iterp->dimsizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));
    iterp->chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t));

    NC_CHECK(nc_inq_vardimid (ncid, varid, dimids));
    for(dim = 0; dim < ndims; dim++) {
	size_t len;
	NC_CHECK(nc_inq_dimlen(ncid, dimids[dim], &len));
	nvalues *= len;
	iterp->dimsizes[dim] = len;
    }
    NC_CHECK(nc_inq_vartype(ncid, varid, &vartype));
    NC_CHECK(inq_value_size(ncid, vartype, &value_size));
#ifdef USE_NETCDF4
    {
	int contig = 1;
	if(ndims > 0) {
	    NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, NULL));
	}
	if(contig == 0) {	/* chunked */
	    NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, iterp->chunksizes));
	    chunked = 1;
	}
    }
#endif	/* USE_NETCDF4 */
    NC_CHECK(nc_blkio_init(bufsize, value_size, ndims, chunked, iterp));
    iterp->to_get = 0;
    free(dimids);
    *iterpp = iterp;
    return stat;
}
Exemplo n.º 7
0
/**@{*/
int
nc_get_vara(int ncid, int varid, const size_t *startp,
	    const size_t *countp, void *ip)
{
   NC* ncp = NULL;
   nc_type xtype = NC_NAT;
   int stat = NC_check_id(ncid, &ncp);
   if(stat != NC_NOERR) return stat;
   stat = nc_inq_vartype(ncid, varid, &xtype);
   if(stat != NC_NOERR) return stat;
   return NC_get_vara(ncid, varid, startp, countp, ip, xtype);
}
Exemplo n.º 8
0
/**@{*/
int
nc_put_vara(int ncid, int varid, const size_t *startp,
	    const size_t *countp, const void *op)
{
   NC* ncp;
   int stat = NC_check_id(ncid, &ncp);
   nc_type xtype;
   if(stat != NC_NOERR) return stat;
   stat = nc_inq_vartype(ncid, varid, &xtype);
   if(stat != NC_NOERR) return stat;
   return NC_put_vara(ncid, varid, startp, countp, op, xtype);
}
Exemplo n.º 9
0
Arquivo: ncdf.c Projeto: cran/ncdf
/* byte_style is 1 for signed, 2 for unsigned
 */
void R_nc_get_vara_int( int *ncid, int *varid, int *start, 
	int *count, int *byte_style, int *data, int *retval )
{
	int	i, err, ndims;
	size_t	s_start[MAX_NC_DIMS], s_count[MAX_NC_DIMS], tot_size, k;
	char	vn[2048];
	nc_type	nct;

	err = nc_inq_varndims(*ncid, *varid, &ndims );
	if( err != NC_NOERR ) 
		REprintf( "Error in R_nc_get_vara_int while getting ndims: %s\n", 
			nc_strerror(*retval) );

	tot_size = 1L;
	for( i=0; i<ndims; i++ ) {
		s_start[i] = (size_t)start[i];
		s_count[i] = (size_t)count[i];
		tot_size *= s_count[i];
		}
		
	*retval = nc_get_vara_int(*ncid, *varid, s_start, s_count, data );
	if( *retval != NC_NOERR ) {
		nc_inq_varname( *ncid, *varid, vn );
		REprintf( "Error in R_nc_get_vara_int: %s\n", 
			nc_strerror(*retval) );
		REprintf( "Var: %s  Ndims: %d   Start: ", vn, ndims );
		for( i=0; i<ndims; i++ ) {
			REprintf( "%u", (unsigned int)s_start[i] );
			if( i < ndims-1 )
				REprintf( "," );
			}
		REprintf( "Count: " );
		for( i=0; i<ndims; i++ ) {
			REprintf( "%u", (unsigned int)s_count[i] );
			if( i < ndims-1 )
				REprintf( "," );
			}
		}

	*retval = nc_inq_vartype( *ncid, *varid, &nct );
	if( nct == NC_BYTE ) {
		/* netcdf library for reading from byte to int, as we do here,
		 * is SIGNED.  So, if user requests signed, we don't have to
		 * do anything; only adjust if user asks for unsigned.
		 */
		if( *byte_style == 2 ) {	/* unsigned */
			for( k=0L; k<tot_size; k++ ) {
				if( data[k] < 0 )
					data[k] += 256;
				}
			}
		}
}
Exemplo n.º 10
0
Arquivo: ncdf.c Projeto: cran/ncdf
void R_nc_inq_vartype( int *ncid, int *varid, int *precint, int *retval )
{
	nc_type nct;

	*retval = nc_inq_vartype( *ncid, *varid, &nct );

	if( *retval != NC_NOERR ) 
		REprintf( "Error in R_nc_inq_var: %s\n", 
			nc_strerror(*retval) );

	*precint = R_nc_nctype_to_Rtypecode(nct);
}
Exemplo n.º 11
0
/*
 * Write a hypercube of character values into an open netCDF file.
 */
static void
c_ncvptc(
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    const char*		value,	/* block of data values to be written */
    int			lenstr,	/* declared length of the data argument */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	if (datatype != NC_CHAR)
	    status = NC_ECHAR;
	else
	{
	    int	rank;

	    status = nc_inq_varndims(ncid, varid, &rank);
	    if (status == 0)
	    {
		if (dimprod(count, rank) > (size_t)lenstr)
		    status = NC_ESTS;
		else
		    status = nc_put_vara_text(ncid, varid, start, count, value);
	    }
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVPTC", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 12
0
Arquivo: mpp_io.c Projeto: djibi2/AM3
/********************************************************************
  nc_type mpp_get_var_type(int fid, int vid)
  get var type
********************************************************************/
nc_type mpp_get_var_type(int fid, int vid)
{
  char errmsg[512];
  
  nc_type vartype;
  int status;

  if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_ndim): invalid fid number, fid should be "
				    "a nonnegative integer that less than nfiles");
  if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_get_var_ndim): invalid vid number, vid should be "
				    "a nonnegative integer that less than nvar");
  
  status = nc_inq_vartype(files[fid].ncid, files[fid].var[vid].fldid, &vartype);
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_var_type): Error in getting type of var %s from file %s",
	    files[fid].var[vid].name, files[fid].name );
    netcdf_error(errmsg, status);
  }

  return vartype;
}
Exemplo n.º 13
0
/*
 * Read a hypercube of character values from a netCDF variable.
 */
static void
c_ncvgtc(
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    char*		value,	/* block of data values to be read */
    int			lenstr,	/* declared length of the data argument */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	if (datatype != NC_CHAR)
	    status = NC_ECHAR;
	else if ((status = nc_get_vara_text(ncid, varid, start, count, value))
		 == 0)
	{
	    int	rank;

	    if ((status = nc_inq_varndims(ncid, varid, &rank)) == 0)
	    {
		size_t	total = dimprod(count, rank);

		(void) memset(value+total, ' ', lenstr - total);
	    }
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVGTC", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 14
0
/*
 * Read a generalized hypercube of character values from a netCDF variable 
 * of an open netCDF file.
 */
static void
c_ncvggc(
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    const ptrdiff_t*	strides,/* netCDF variable access strides */
    const ptrdiff_t*	imap,	/* memory values access basis vector */
    char*		value,	/* block of data values to be written */
    int*		rcode	/* returned error code */
)
{
    int		status;
    int		rank;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0 &&
	(status = nc_inq_varndims(ncid, varid, &rank)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = nc_get_varm_text(ncid, varid, start, count,
				       strides, imap,
				       value);
	    break;
	default:
	    status = NC_ECHAR;
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVGGC", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 15
0
Arquivo: v2i.c Projeto: stcorp/harp
/*
 * Computes record size (in bytes) of the record variable with a specified
 * variable id.  Returns size as 0 if not a record variable.
 */
static int
ncrecsize(int ncid, int varid, size_t *recsizep)
{
    int status;
    int recdimid;
    nc_type type;
    int ndims;
    int dimids[MAX_NC_DIMS];
    int id;
    size_t size;

    *recsizep = 0;
    status = nc_inq_unlimdim(ncid, &recdimid); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_vartype(ncid, varid, &type); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_varndims(ncid, varid, &ndims); 
    if(status != NC_NOERR)
	return status;
    status = nc_inq_vardimid(ncid, varid, dimids); 
    if(status != NC_NOERR)
	return status;
    if (ndims == 0 || dimids[0] != recdimid) {
	return NC_NOERR;
    }
    size = nctypelen(type);
    for (id = 1; id < ndims; id++) {
	size_t len;
	status = nc_inq_dimlen(ncid, dimids[id], &len);
	if(status != NC_NOERR)
		return status;
	size *= len;
    }
    *recsizep = size;
    return NC_NOERR;
}
Exemplo n.º 16
0
/* Set attributes to define missing data information. */
int 
nccf_def_var_missing(int ncid, int varid, const void *fill_value, 
		     const void *valid_min, const void *valid_max)
{
   nc_type xtype;
   int ret;

   /* User must provide either both or neither of valid_min and
    * valid_max. */
   if ((valid_min && !valid_max) || 
       (!valid_min && valid_max))
      return CF_EMINMAX;

   /* Get the variable type. */
   if ((ret = nc_inq_vartype(ncid, varid, &xtype)))
      return ret;

   /* Write a fill value if the user provided one. */
   if (fill_value)
      if ((ret = nc_put_att(ncid, varid, CF_FILL_VALUE, 
			    xtype, 1, fill_value)))
	 return ret;

   /* Write a valid_min if the user provided one. */
   if (valid_min)
      if ((ret = nc_put_att(ncid, varid, CF_VALID_MIN, 
			    xtype, 1, valid_min)))
	 return ret;

   /* Write a valid_max value if the user provided one. */
   if (valid_max)
      if ((ret = nc_put_att(ncid, varid, CF_VALID_MAX, 
			    xtype, 1, valid_max)))
	 return ret;
      
   return NC_NOERR;
}
Exemplo n.º 17
0
static NFvarType _NCgridVariableType(NFio_p io, NFvarHandle varHandle) {
    int status;
    NCgridVariable_p gridVariable = (NCgridVariable_p) varHandle;
    nc_type vartype;

    if ((status = nc_inq_vartype(((NCgrid_p) (io->PluginData))->NCid, gridVariable->VarIDs[0], &vartype)) != NC_NOERR) {
        CMmsgPrint(CMmsgAppError, "Variable type inquery error in %s:%d!\n", __FILE__, __LINE__);
        return (NFvarTypeVoid);
    }
    switch (vartype) {
        default:
            return (NFvarTypeVoid);
        case NC_CHAR:
            return (NFvarTypeByte);
        case NC_SHORT:
        case NC_INT:
            return (NFvarTypeShort);
        case NC_FLOAT:
            return (NFvarTypeFloat);
        case NC_DOUBLE:
            return (NFvarTypeDouble);
    }
    return (NFvarTypeVoid);
}
Exemplo n.º 18
0
Arquivo: mpp_io.c Projeto: djibi2/AM3
/*********************************************************************
  int mpp_get_varid(int fid, const char *varname)
  get the id of the varname from file with fid, the id will be the index
  in files[fid].var.
*********************************************************************/
int mpp_get_varid(int fid, const char *varname)
{
  int status, fldid, vid, n;
  char errmsg[512];
  
  /* First look through existing variables to see
     if the fldid of varname is already retrieved. */
  if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_varid): invalid id number, id should be "
				    "a nonnegative integer that less than nfiles");
  
  for(n=0; n<files[fid].nvar; n++) {
    if( !strcmp(files[fid].var[n].name, varname) ) return n;
  }

  vid = files[fid].nvar;
  files[fid].nvar++;
  if(files[fid].nvar > MAXVAR ) mpp_error("mpp_io(mpp_get_varid): nvar is larger than MAXVAR, increase MAXVAR");
  
  status =  nc_inq_varid(files[fid].ncid, varname, &fldid);
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_varid): error in get field_id of variable %s from file %s", varname, files[fid].name);
    netcdf_error(errmsg, status);
  }

  status = nc_inq_vartype(files[fid].ncid, fldid, &(files[fid].var[vid].type));
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_varid): Error in getting type of of field %s in file %s ",
	    files[fid].var[vid].name, files[fid].name );
    netcdf_error(errmsg, status);
  }
  
  files[fid].var[vid].fldid = fldid;
  strcpy(files[fid].var[vid].name, varname);
  return vid;

};/* mpp_get_varid */
Exemplo n.º 19
0
/*
 * Write a generalized hypercube of numeric values into a netCDF variable of 
 * an open netCDF file.
 */
static void
c_ncvptg (
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    const ptrdiff_t*	strides,/* netCDF variable access strides */
    const ptrdiff_t*	imap,	/* memory values access mapping vector */
    const void*		value,	/* block of data values to be written */
    int*		rcode	/* returned error code */
)
{
    int		status;
    int		rank;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0 &&
	(status = nc_inq_varndims(ncid, varid, &rank)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#	    if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_put_varm_schar(ncid, varid, start, count,
					   strides, imap,
					   (const signed char*)value);
#	    elif NF_INT1_IS_C_SHORT
		status = nc_put_varm_short(ncid, varid, start, count,
					   strides, imap,
					   (const short*)value);
#	    elif NF_INT1_IS_C_INT
		status = nc_put_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (const int*)value);
#	    elif NF_INT1_IS_C_LONG
		status = nc_put_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (const long*)value);
#	    endif
	    break;
	case NC_SHORT:
#	    if NF_INT2_IS_C_SHORT
		status = nc_put_varm_short(ncid, varid, start, count,
					   strides, imap,
					   (const short*)value);
#	    elif NF_INT2_IS_C_INT
		status = nc_put_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (const int*)value);
#	    elif NF_INT2_IS_C_LONG
		status = nc_put_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (const long*)value);
#	    endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_put_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (const int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_put_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (const long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#	    if NF_REAL_IS_C_FLOAT
		status = nc_put_varm_float(ncid, varid, start, count,
					   strides, imap,
					   (const float*)value);
#	    elif NF_REAL_IS_C_DOUBLE
		status = nc_put_varm_double(ncid, varid, start, count,
					   strides, imap,
					   (const double*)value);
#	    endif
	    break;
	case NC_DOUBLE:
#	    if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_put_varm_float(ncid, varid, start, count,
					   strides, imap,
					   (const float*)value);
#	    elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_put_varm_double(ncid, varid, start, count,
					   strides, imap,
					   (const double*)value);
#	    endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVPTG", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 20
0
/*
 * Put a single numeric data value into a variable of an open netCDF.
 */
static void
c_ncvpt1 (
    int			ncid,	/* netCDF ID */
    int	 		varid,	/* variable ID */
    const size_t*	indices,/* multidim index of data to be written */
    const void*		value,	/* pointer to data value to be written */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#	    if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_put_var1_schar(ncid, varid, indices,
					   (const signed char*)value);
#	    elif NF_INT1_IS_C_SHORT
		status = nc_put_var1_short(ncid, varid, indices,
					   (const short*)value);
#	    elif NF_INT1_IS_C_INT
		status = nc_put_var1_int(ncid, varid, indices,
					   (const int*)value);
#	    elif NF_INT1_IS_C_LONG
		status = nc_put_var1_long(ncid, varid, indices,
					   (const long*)value);
#	    endif
	    break;
	case NC_SHORT:
#	    if NF_INT2_IS_C_SHORT
		status = nc_put_var1_short(ncid, varid, indices,
					   (const short*)value);
#	    elif NF_INT2_IS_C_INT
		status = nc_put_var1_int(ncid, varid, indices,
					   (const int*)value);
#	    elif NF_INT2_IS_C_LONG
		status = nc_put_var1_long(ncid, varid, indices,
					   (const long*)value);
#	    endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_put_var1_int(ncid, varid, indices,
					   (const int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_put_var1_long(ncid, varid, indices,
					   (const long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#	    if NF_REAL_IS_C_FLOAT
		status = nc_put_var1_float(ncid, varid, indices,
					   (const float*)value);
#	    elif NF_REAL_IS_C_DOUBLE
		status = nc_put_var1_double(ncid, varid, indices,
					   (const double*)value);
#	    endif
	    break;
	case NC_DOUBLE:
#	    if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_put_var1_float(ncid, varid, indices,
					   (const float*)value);
#	    elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_put_var1_double(ncid, varid, indices,
					   (const double*)value);
#	    endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVPT1", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 21
0
/**
 * Convert a Version 2 Fortran IMAP vector into a Version 3 C imap vector.
 */
static ptrdiff_t*
f2c_v2imap(int ncid, int varid, const int* fimap, ptrdiff_t* cimap)
{
    int		rank;
    nc_type	datatype;

    if (nc_inq_vartype(ncid, varid, &datatype) ||
	nc_inq_varndims(ncid, varid, &rank) || rank <= 0)
    {
	return NULL;
    }

    /* else */
    if (fimap[0] == 0)
    {
	/*
	 * Special Fortran version 2 semantics: use external netCDF variable 
	 * structure.
	 */
	int		dimids[NC_MAX_VAR_DIMS];
	int		idim;
	size_t	total;

	if (nc_inq_vardimid(ncid, varid, dimids) != NC_NOERR)
	    return NULL;

	for (total = 1, idim = rank - 1; idim >= 0; --idim)
	{
	    size_t	length;

	    cimap[idim] = total;

	    if (nc_inq_dimlen(ncid, dimids[idim], &length) != NC_NOERR)
		return NULL;

	    total *= length;
	}
    }
    else
    {
	/*
	 * Regular Fortran version 2 semantics: convert byte counts to
	 * element counts.
	 */
	int	idim;
	size_t	size;

	switch (datatype)
	{

	    case NC_CHAR:
		size = sizeof(char);
		break;
	    case NC_BYTE:
#		if NF_INT1_IS_C_SIGNED_CHAR
		    size = sizeof(signed char);
#		elif NF_INT1_IS_C_SHORT
		    size = sizeof(short);
#		elif NF_INT1_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT1_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_SHORT:
#		if NF_INT2_IS_C_SHORT
		    size = sizeof(short);
#		elif NF_INT2_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT2_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_INT:
#		if NF_INT_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_FLOAT:
#		if NF_REAL_IS_C_FLOAT
		    size = sizeof(float);
#		elif NF_REAL_IS_C_DOUBLE
		    size = sizeof(double);
#		endif
		break;
	    case NC_DOUBLE:
#		if NF_DOUBLEPRECISION_IS_C_FLOAT
		    size = sizeof(float);
#		elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		    size = sizeof(double);
#		endif
		break;
	    default:
		return NULL;
	}

	for (idim = 0; idim < rank; ++idim)
	    cimap[idim] = fimap[rank - 1 - idim] / size;
    }

    return cimap;
}
Exemplo n.º 22
0
/*
 * Read a hypercube of numeric values from a netCDF variable of an open
 * netCDF file.
 */
static void
c_ncvgt(
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    void*		value,	/* block of data values to be read */
    int*		rcode	/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#	    if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_get_vara_schar(ncid, varid, start, count,
					   (signed char*)value);
#	    elif NF_INT1_IS_C_SHORT
		status = nc_get_vara_short(ncid, varid, start, count,
					   (short*)value);
#	    elif NF_INT1_IS_C_INT
		status = nc_get_vara_int(ncid, varid, start, count,
					   (int*)value);
#	    elif NF_INT1_IS_C_LONG
		status = nc_get_vara_long(ncid, varid, start, count,
					   (long*)value);
#	    endif
	    break;
	case NC_SHORT:
#	    if NF_INT2_IS_C_SHORT
		status = nc_get_vara_short(ncid, varid, start, count,
					   (short*)value);
#	    elif NF_INT2_IS_C_INT
		status = nc_get_vara_int(ncid, varid, start, count,
					   (int*)value);
#	    elif NF_INT2_IS_C_LONG
		status = nc_get_vara_long(ncid, varid, start, count,
					   (long*)value);
#	    endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_get_vara_int(ncid, varid, start, count,
					   (int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_get_vara_long(ncid, varid, start, count,
					   (long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#	    if NF_REAL_IS_C_FLOAT
		status = nc_get_vara_float(ncid, varid, start, count,
					   (float*)value);
#	    elif NF_REAL_IS_C_DOUBLE
		status = nc_get_vara_double(ncid, varid, start, count,
					   (double*)value);
#	    endif
	    break;
	case NC_DOUBLE:
#	    if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_get_vara_float(ncid, varid, start, count,
					   (float*)value);
#	    elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_get_vara_double(ncid, varid, start, count,
					   (double*)value);
#	    endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVGT", status, "");
	*rcode = ncerr;
    }
}
Exemplo n.º 23
0
int
main(int argc, char **argv)
{
#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif

   int ncid, dimids[3];
   int char_varid, byte_varid, ubyte_varid, short_varid, int_varid, float_varid, double_varid;
   int ushort_varid, uint_varid, int64_varid, uint64_varid;
   int i, j;

   unsigned char ubyte_out[DIM1_LEN][DIM2_LEN] = {{1, 128, 255},{1, 128, 255}};
   signed char byte_in[DIM1_LEN][DIM2_LEN], byte_out[DIM1_LEN][DIM2_LEN] = {{-127, 1, 127},{-127, 1, 127}};
   unsigned short ushort_out[DIM1_LEN][DIM2_LEN] = {{110, 128, 255},{110, 128, 255}};
   short short_in[DIM1_LEN][DIM2_LEN], short_out[DIM1_LEN][DIM2_LEN] = {{-110, -128, 255},{-110, -128, 255}};
   int int_in[DIM1_LEN][DIM2_LEN], int_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   float float_in[DIM1_LEN][DIM2_LEN], float_out[DIM1_LEN][DIM2_LEN] = {{-.1, 9999.99, 100.001},{-.1, 9999.99, 100.001}};
   double double_in[DIM1_LEN][DIM2_LEN], double_out[DIM1_LEN][DIM2_LEN] = {{0.02, .1128, 1090.1},{0.02, .1128, 1090.1}};
   unsigned int uint_in[DIM1_LEN][DIM2_LEN], uint_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   long long int64_in[DIM1_LEN][DIM2_LEN], int64_out[DIM1_LEN][DIM2_LEN] = {{-111, 777, 100},{-111, 777, 100}};
   unsigned long long uint64_in[DIM1_LEN][DIM2_LEN];
   unsigned long long uint64_out[DIM1_LEN][DIM2_LEN] = {{0, 10101, 9999999},{0, 10101, 9999999}};
   char char_out[DIM1_LEN][DIM2_LEN][DIM3_LEN] = {{"lalala", "lololo", "lelele"}, {"lalala", "lololo", "lelele"}};

   /*nc_set_log_level(4);*/

   printf("\n*** Testing netcdf-4 variable functions.\n");

   printf("*** testing netcdf-4 varids inq on netcdf-3 file...");
   {
      int nvars_in, varids_in[2];

      /* Create a netcdf-3 file with one dim and two vars. */
      if (nc_create(FILE_NAME, 0, &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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_varids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing simple variables...");

   {      
      /* Create a file with a variable 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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

#define DEFLATE_LEVEL_4 4

   printf("*** testing simple variables with deflation...");
   {
      /* Create a file with a variable 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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var_deflate(ncid, short_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var_deflate(ncid, int_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var_deflate(ncid, float_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var_deflate(ncid, double_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var_deflate(ncid, ubyte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var_deflate(ncid, ushort_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var_deflate(ncid, int64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;

      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

   }
   SUMMARIZE_ERR;

#define NDIMS4 1
#define NVARS4 1
#define DIM4_NAME "treaty_of_paris_1783"
#define DIM4_LEN 5
#define VAR_NAME4 "John_Adams"
#define DEFLATE_LEVEL 6

   printf("*** testing netcdf-4 simple variable define...");
   {
      int dimids[NDIMS4], dimids_in[NDIMS4];
      int varid, varids_in[NVARS4];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level;

      /* Create a netcdf-4 file with one dim and one var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      if (nc_def_var(ncid, VAR_NAME4, NC_INT64, NDIMS4, dimids, &varid)) ERR;
      if (nc_def_var_deflate(ncid, varid, 0, 1, DEFLATE_LEVEL)) ERR;
      if (varid != 0) ERR;

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NDIMS5 1
#define NVARS5 5
#define DIM5_NAME "treaty_of_paris_1783"
#define DIM5_LEN 5

   printf("*** testing netcdf-4 less simple variable define...");
   {
      int dimids[NDIMS5], dimids_in[NDIMS5];
      int varid[NVARS5], varids_in[NVARS5];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      char var_name[NVARS5][NC_MAX_NAME + 1] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
						"Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
						"Charles_F_Ritchel"};
      int shuffle_in, deflate_in, deflate_level_in;
      int deflate_level[NVARS5];
      int i;

      /* Set up options for this var. */
      for (i = 0; i < NVARS5; i++)
	 deflate_level[i] = i;

      /* Create a netcdf-4 file with one dim and two vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_INT64, NDIMS5, dimids, 
			&varid[i])) ERR;
	 if (varid[i] != i) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 1, 1, deflate_level[i])) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NVARS 5
#define NDIMS 1
#define DIM6_NAME "airship_cross_sectional_area"
#define DIM6_LEN 100
#define TEN_K_M2 10000.0
#define INCREMENT 1000.0

   printf("*** testing more complex netcdf-4 variable defines...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      int varid[NVARS], varids_in[NVARS];
      int ndims, nvars, natts, unlimdimid;
      char var_name[NVARS][50] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
				  "Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
				  "Charles_F_Ritchel"};
      double data[DIM6_LEN];
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in;
      int i;

      /* Create some phoney data. */
      for (i = 1, data[0] = TEN_K_M2; i < DIM6_LEN; i++)
	 data[i] = data[i - 1] + INCREMENT;

      /* Create a netcdf-4 file with one dim and 5 NC_DOUBLE vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM6_NAME, DIM6_LEN, &dimids[0])) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_DOUBLE, NDIMS, dimids,
			&varid[i])) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 0, 1, 0)) ERR;
	 if (nc_def_var_fletcher32(ncid, varid[i], 1)) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || 
	     deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define DIM7_LEN 2
#define DIM7_NAME "dim_7_from_Indiana"
#define VAR7_NAME "var_7_from_Idaho"
#define NDIMS 1

   printf("*** testing fill values...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      size_t index[NDIMS];
      int varid, ndims, natts;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in, no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;
      if (nc_inq_var_fill(ncid, 0, &no_fill, &fill_value_in)) ERR;
      if (no_fill || fill_value_in != NC_FILL_USHORT) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, 0, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, 0, index, &ushort_data_in)) ERR;
      if (ushort_data_in != NC_FILL_USHORT) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing more fill values...");
   {
      int dimids[NDIMS];
      size_t index[NDIMS];
      int varid;
      int no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;
      if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing lots of variables...");
#define DIM_A_NAME "x"
#define DIM_A_LEN 10
#define NUM_VARS 2000
#define MAX_VARNAME 10
   {
      /* This simple test failed on HDF5 1.7.58, but passes just fine
       * on 1.8.0 alpha5... */
      int ncid, dimids[1], i;
      char varname[MAX_VARNAME];
      int varids[NUM_VARS];

      /* Create a file with three dimensions. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_A_NAME, DIM_A_LEN, &dimids[0])) ERR;

      /* Create a large number of variables. */
      for (i = 0; i < NUM_VARS; i++)
      {
	 sprintf(varname, "a_%d", i);
	 if (nc_def_var(ncid, varname, NC_FLOAT, 1, dimids, &varids[i])) ERR;
      }
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define NC3_CLASSIC_FILE "tst_pres_temp_4D_classic.nc"
#define NC3_64BIT_OFFSET_FILE "tst_pres_temp_4D_64bit_offset.nc"
#define NC3_NETCDF4_FILE "tst_pres_temp_4D_netcdf4.nc"
#define NC3_NETCDF4_CLASSIC_FILE "tst_pres_temp_4D_netcdf4_classic.nc"
   printf("*** testing 4D example file in classic format...");
   if (create_4D_example(NC3_CLASSIC_FILE, NC_CLOBBER)) ERR;
   if (check_4D_example(NC3_CLASSIC_FILE, NC_FORMAT_CLASSIC)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in 64-bit offset format...");
   if (create_4D_example(NC3_64BIT_OFFSET_FILE, NC_CLOBBER|NC_64BIT_OFFSET)) ERR;
   if (check_4D_example(NC3_64BIT_OFFSET_FILE, NC_FORMAT_64BIT)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format...");
   if (create_4D_example(NC3_NETCDF4_FILE, NC_CLOBBER|NC_NETCDF4)) ERR;
   if (check_4D_example(NC3_NETCDF4_FILE, NC_FORMAT_NETCDF4)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format with classic model rules...");
   if (create_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR;
   if (check_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_FORMAT_NETCDF4_CLASSIC)) ERR;      
   SUMMARIZE_ERR;

   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

}
Exemplo n.º 24
0
/*! \internal */
int cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int cpy_var_def(): output output-file variable ID
 */
{
  /* Routine to copy the variable metadata from an input netCDF file
   * to an output netCDF file. 
   */

  int status;
  int *dim_in_id;
  int *dim_out_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;

  nc_type var_type;

  /* See if the requested variable is already in the output file. */
  status = nc_inq_varid(out_id, var_nm, &var_out_id);
  if(status == NC_NOERR)
    return var_out_id;

  /* See if the requested variable is in the input file. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);

  /* Get the type of the variable and the number of dimensions. */
  (void)nc_inq_vartype (in_id, var_in_id, &var_type);
  (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim);

  /* Recall:
     1. The dimensions must be defined before the variable.
     2. The variable must be defined before the attributes. */

  /* Allocate space to hold the dimension IDs */
  dim_in_id=malloc(nbr_dim*sizeof(int)); 
  dim_out_id=malloc(nbr_dim*sizeof(int));

  /* Get the dimension IDs */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_in_id);

  /* Get the dimension sizes and names */
  for(idx=0;idx<nbr_dim;idx++){
    char dim_nm[NC_MAX_NAME];
    size_t dim_sz;

    (void)nc_inq_dim(in_id, dim_in_id[idx], dim_nm, &dim_sz);

    /* See if the dimension has already been defined */
    status = nc_inq_dimid(out_id, dim_nm, &dim_out_id[idx]);

    /* If the dimension hasn't been defined, copy it */
    if (status != NC_NOERR) {
      if (dim_in_id[idx] != rec_dim_id) {
        (void)nc_def_dim(out_id, dim_nm, dim_sz, &dim_out_id[idx]);
      } else {
        (void)nc_def_dim(out_id, dim_nm, NC_UNLIMITED, &dim_out_id[idx]);
      } 
    } 
  } 

  /* Define the variable in the output file */

  /* If variable is float or double, define it according to the EXODUS
     file's IO_word_size */

  if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) {
    (void)nc_def_var(out_id, var_nm, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 2);
  } else {
    (void)nc_def_var(out_id, var_nm, var_type,            nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 1);
  }

  /* Free the space holding the dimension IDs */
  (void)free(dim_in_id);
  (void)free(dim_out_id);

  return var_out_id;
} /* end cpy_var_def() */
Exemplo n.º 25
0
/** \internal
\ingroup variables
 */
int
NCDEFAULT_get_varm(int ncid, int varid, const size_t *start,
	    const size_t *edges, const ptrdiff_t *stride,
	    const ptrdiff_t *imapp, void *value0, nc_type memtype)
{
   int status = NC_NOERR;
   nc_type vartype = NC_NAT;
   int varndims,maxidim;
   NC* ncp;
   int memtypelen;
   char* value = (char*)value0;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

/*
  if(NC_indef(ncp)) return NC_EINDEFINE;
*/

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;
   /* Check that this is an atomic type */
   if(vartype > NC_MAX_ATOMIC_TYPE)
	return NC_EMAPTYPE;

   status = nc_inq_varndims(ncid, varid, &varndims);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) {
      memtype = vartype;
   }

   if(memtype == NC_CHAR && vartype != NC_CHAR)
      return NC_ECHAR;
   else if(memtype != NC_CHAR && vartype == NC_CHAR)
      return NC_ECHAR;

   memtypelen = nctypelen(memtype);

   maxidim = (int) varndims - 1;

   if (maxidim < 0)
   {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_get_vara(ncid, varid, start, edge1, value, memtype);
   }

   /*
    * else
    * The variable is an array.
    */
   {
      int idim;
      size_t *mystart = NULL;
      size_t *myedges;
      size_t *iocount;    /* count vector */
      size_t *stop;   /* stop indexes */
      size_t *length; /* edge lengths in bytes */
      ptrdiff_t *mystride;
      ptrdiff_t *mymap;
      size_t varshape[NC_MAX_VAR_DIMS];
      int isrecvar;
      size_t numrecs;

      /* Compute some dimension related values */
      isrecvar = NC_is_recvar(ncid,varid,&numrecs);
      NC_getshape(ncid,varid,varndims,varshape);

      /*
       * Verify stride argument; also see if stride is all ones
       */
      if(stride != NULL) {
	 int stride1 = 1;
	 for (idim = 0; idim <= maxidim; ++idim)
	 {
            if (stride[idim] == 0
		/* cast needed for braindead systems with signed size_t */
                || ((unsigned long) stride[idim] >= X_INT_MAX))
            {
	       return NC_ESTRIDE;
            }
	    if(stride[idim] != 1) stride1 = 0;
	 }
         /* If stride1 is true, and there is no imap
            then call get_vara directly.
         */
         if(stride1 && imapp == NULL) {
	     return NC_get_vara(ncid, varid, start, edges, value, memtype);
	 }
      }

      /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
      /* Allocate space for mystart,mystride,mymap etc.all at once */
      mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t));
      if(mystart == NULL) return NC_ENOMEM;
      myedges = mystart + varndims;
      iocount = myedges + varndims;
      stop = iocount + varndims;
      length = stop + varndims;
      mystride = (ptrdiff_t *)(length + varndims);
      mymap = mystride + varndims;

      /*
       * Initialize I/O parameters.
       */
      for (idim = maxidim; idim >= 0; --idim)
      {
	 mystart[idim] = start != NULL
	    ? start[idim]
	    : 0;

	 if (edges != NULL && edges[idim] == 0)
	 {
	    status = NC_NOERR;    /* read/write no data */
	    goto done;
	 }

#ifdef COMPLEX
	 myedges[idim] = edges != NULL
	    ? edges[idim]
	    : idim == 0 && isrecvar
	    ? numrecs - mystart[idim]
	    : varshape[idim] - mystart[idim];
#else
	 if(edges != NULL)
	    myedges[idim] = edges[idim];
	 else if (idim == 0 && isrecvar)
	    myedges[idim] = numrecs - mystart[idim];
	 else
	    myedges[idim] = varshape[idim] - mystart[idim];
#endif

	 mystride[idim] = stride != NULL
	    ? stride[idim]
	    : 1;

	 /* Remember: in netCDF-2 imapp is byte oriented, not index oriented
	  *           Starting from netCDF-3, imapp is index oriented */
#ifdef COMPLEX
	 mymap[idim] = (imapp != NULL
			? imapp[idim]
			: (idim == maxidim ? 1
			   : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]));
#else
	 if(imapp != NULL)
	    mymap[idim] = imapp[idim];
	 else if (idim == maxidim)
	    mymap[idim] = 1;
	 else
	    mymap[idim] =
	       mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];
#endif
	 iocount[idim] = 1;
	 length[idim] = ((size_t)mymap[idim]) * myedges[idim];
	 stop[idim] = (mystart[idim] + myedges[idim] * (size_t)mystride[idim]);
      }

      /*
       * Check start, edges
       */
      for (idim = maxidim; idim >= 0; --idim)
      {
	 size_t dimlen =
	    idim == 0 && isrecvar
	    ? numrecs
	    : varshape[idim];
	 if (mystart[idim] >= dimlen)
	 {
	    status = NC_EINVALCOORDS;
	    goto done;
	 }

	 if (mystart[idim] + myedges[idim] > dimlen)
	 {
	    status = NC_EEDGE;
	    goto done;
	 }

      }


      /* Lower body */
      /*
       * As an optimization, adjust I/O parameters when the fastest
       * dimension has unity stride both externally and internally.
       * In this case, the user could have called a simpler routine
       * (i.e. ncvar$1()
       */
      if (mystride[maxidim] == 1
	  && mymap[maxidim] == 1)
      {
	 iocount[maxidim] = myedges[maxidim];
	 mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
	 mymap[maxidim] = (ptrdiff_t) length[maxidim];
      }

      /*
       * Perform I/O.  Exit when done.
       */
      for (;;)
      {
	 /* TODO: */
	 int lstatus = NC_get_vara(ncid, varid, mystart, iocount,
				   value, memtype);
	 if (lstatus != NC_NOERR) {
	    if(status == NC_NOERR || lstatus != NC_ERANGE)
	       status = lstatus;
	 }
	 /*
	  * The following code permutes through the variable s
	  * external start-index space and it s internal address
	  * space.  At the UPC, this algorithm is commonly
	  * called "odometer code".
	  */
	 idim = maxidim;
        carry:
	 value += (((int)mymap[idim]) * memtypelen);
	 mystart[idim] += (size_t)mystride[idim];
	 if (mystart[idim] == stop[idim])
	 {
	    size_t l = (length[idim] * (size_t)memtypelen);
	    value -= l;
	    mystart[idim] = start[idim];
	    if (--idim < 0)
	       break; /* normal return */
	    goto carry;
	 }
      } /* I/O loop */
     done:
      free(mystart);
   } /* variable is array */
   return status;
}
Exemplo n.º 26
0
/*! \internal */
int
cpy_var_val(int in_id,int out_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the variable data from an input netCDF file
   * to an output netCDF file. 
   */

  int *dim_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;
  size_t *dim_cnt;
  size_t *dim_sz;
  size_t *dim_srt;
  size_t var_sz=1L;
  nc_type var_type_in, var_type_out;

  void *void_ptr = NULL;

  /* Get the var_id for the requested variable from both files. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);
  (void)nc_inq_varid(out_id,var_nm, &var_out_id);
 
  /* Get the number of dimensions for the variable. */
  (void)nc_inq_vartype( out_id, var_out_id, &var_type_out);
  (void)nc_inq_varndims(out_id, var_out_id, &nbr_dim);

  (void)nc_inq_vartype( in_id,   var_in_id, &var_type_in);
  (void)nc_inq_varndims(in_id,   var_in_id, &nbr_dim);
 
  /* Allocate space to hold the dimension IDs */
  dim_cnt = malloc(nbr_dim*sizeof(size_t));

  dim_id=malloc(nbr_dim*sizeof(int));

  dim_sz=malloc(nbr_dim*sizeof(size_t));

  dim_srt=malloc(nbr_dim*sizeof(size_t));
 
  /* Get the dimension IDs from the input file */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_id);
 
  /* Get the dimension sizes and names from the input file */
  for(idx=0;idx<nbr_dim;idx++){
  /* NB: For the unlimited dimension, ncdiminq() returns the maximum
     value used so far in writing data for that dimension.
     Thus if you read the dimension sizes from the output file, then
     the ncdiminq() returns dim_sz=0 for the unlimited dimension
     until a variable has been written with that dimension. This is
     the reason for always reading the input file for the dimension
     sizes. */

    (void)nc_inq_dimlen(in_id,dim_id[idx],dim_cnt+idx);

    /* Initialize the indicial offset and stride arrays */
    dim_srt[idx]=0L;
    var_sz*=dim_cnt[idx];
  } /* end loop over dim */

  /* Allocate enough space to hold the variable */
  if (var_sz > 0)
      void_ptr=malloc(var_sz * type_size(var_type_in));

  /* Get the variable */

  /* if variable is float or double, convert if necessary */

  if(nbr_dim==0){  /* variable is a scalar */

    if (var_type_in == NC_INT && var_type_out == NC_INT) {
      nc_get_var1_int(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_int(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) {
      nc_get_var1_longlong(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_longlong(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_FLOAT) {
      nc_get_var1_float(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_float(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_DOUBLE) {
      nc_get_var1_double(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_double(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_CHAR) {
      nc_get_var1_text(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_text(out_id, var_out_id, 0L, void_ptr);
    }

    else {
      assert(1==0);
    }
  } else { /* variable is a vector */

    if (var_type_in == NC_INT && var_type_out == NC_INT) {
      (void)nc_get_var_int(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_int(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) {
      (void)nc_get_var_longlong(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_longlong(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_FLOAT) {
      (void)nc_get_var_float(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_float(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_DOUBLE) {
      (void)nc_get_var_double(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_double(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_CHAR) {
      (void)nc_get_var_text(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_text(out_id, var_out_id, void_ptr);
    }

    else {
      assert(1==0);
    }
  } /* end if variable is an array */

  /* Free the space that held the dimension IDs */
  (void)free(dim_cnt);
  (void)free(dim_id);
  (void)free(dim_sz);
  (void)free(dim_srt);

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_var_val() */
Exemplo n.º 27
0
NCtable_t *NCtableOpen(int ncid, char *tablename)
{
	int status, *dimids, dimid, i = 0, j = 0;
	int ndims, nvars;
	size_t nrecords;
	size_t len;
	char varname [NC_MAX_NAME];
	nc_type type;
	NCfield_t *field = (NCfield_t *) NULL;
	NCtable_t *tbl   = (NCtable_t *) NULL;

	if((status = nc_inq_dimid  (ncid,tablename,&dimid)) != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if((status = nc_inq_dimlen (ncid,dimid,&nrecords))  != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if((status = nc_inq_nvars  (ncid,&nvars))           != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if(nc_inq_ndims(ncid,&ndims) != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if ((dimids = (int *) malloc(sizeof(int) * ndims)) == (int *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); return (NCtable_t *) NULL; }

	if ((tbl = (NCtable_t *) malloc(sizeof(NCtable_t))) == (NCtable_t *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); return ((NCtable_t *) NULL); }
	if ((tbl->Name = (char *) malloc (strlen(tablename) + 1)) == (char *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); free (tbl); return ((NCtable_t *) NULL); }
	strcpy(tbl->Name,tablename);
	tbl->NFields  = 0;
	tbl->Fields   = (NCfield_t *) NULL;

	for(i = 0; i < nvars; i++)
	{
		if ((status = nc_inq_vartype(ncid,i,&type)) != NC_NOERR)
		{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		if ((len = _NCtableVarLen(ncid,i,dimid,dimids)) == NCfailed) continue;
		if ((type != NC_CHAR) && (len > 1)) continue;

		if((status = nc_inq_varname(ncid,i,varname)) != NC_NOERR)
		{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }

		if ((tbl->Fields = (NCfield_t *) realloc (tbl->Fields, sizeof (NCfield_t) * (tbl->NFields + 1))) == (NCfield_t *) NULL)
		{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		field = tbl->Fields + tbl->NFields;
		tbl->NFields += 1;
		field->NRecords = nrecords;
		field->Data = (void *) NULL;
		field->Name = (char *) NULL;
		field->Type = type;
		field->Len  = len;

		if ((field->Name = malloc (strlen (varname) + 1)) == (char *) NULL)
		{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		strcpy (field->Name,varname);

		if (nc_get_att_double (ncid,i,NCnameVAScaleFactor,&field->Scale)      != NC_NOERR) field->Scale      = 1.0;
		if (nc_get_att_double (ncid,i,NCnameVAAddOffset,  &field->Offset)     != NC_NOERR) field->Offset     = 0.0;

		switch(field->Type)
		{
			case NC_CHAR:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (char)))   == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_text(ncid,i,(char *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				break;
			case NC_BYTE:
			case NC_SHORT:
			case NC_INT:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (int)))   == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_int(ncid,i,(int *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if (nc_get_att_int    (ncid,i,NCnameVAFillValue,  &field->FillValue.Int)  != NC_NOERR) field->FillValue.Int  = INT_NOVALUE;
				if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal)     != NC_NOERR) field->MissingVal     = FLOAT_NOVALUE;
				break;
			case NC_FLOAT:
			case NC_DOUBLE:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (double))) == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_double(ncid,i,(double *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if (nc_get_att_double (ncid,i,NCnameVAFillValue,  &field->FillValue.Float)  != NC_NOERR) field->FillValue.Float = FLOAT_NOVALUE;
				if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal)       != NC_NOERR) field->MissingVal      = FLOAT_NOVALUE;
				break;
			default:        field->Data = (void *) NULL; break;
		}
		if(GetDebug()) CMmsgPrint (CMmsgUsrError, "Loaded: %s(dimid: %d)\n",field->Name,dimid);
	}

	if(GetDebug())
	{
		CMmsgPrint (CMmsgUsrError, "Dim: %d Name: %s Cols: %d Rows: %d\n",dimid,tbl->Name,tbl->NFields,field->NRecords);
		for(i = 0; i < tbl->NFields; i++)
		{
			field = tbl->Fields + i;
			CMmsgPrint (CMmsgUsrError, "\tField: %d Name: %s ",i,field->Name);
			switch(field->Type)
			{
				case NC_CHAR:
					if(field->Len == 1)
					{
						CMmsgPrint (CMmsgUsrError, "Type: char\n");
						for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %c\n",j,((char *) (field->Data)) [j]);
					}
					else
					{
						CMmsgPrint (CMmsgUsrError, "Type: string\n");
						for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %s\n",j,((char *) (field->Data)) + j * field->Len);
					}
					break;
				case NC_BYTE:
				case NC_SHORT:
				case NC_INT:
					CMmsgPrint (CMmsgUsrError, "Type: int\n");
					for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %i\n",j,((int *)    (field->Data)) [j]);
					break;
				case NC_FLOAT:
				case NC_DOUBLE:
					CMmsgPrint (CMmsgUsrError, "Type: double\n");
					for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %f\n",j,((double *) (field->Data)) [j]);
					break;
				default: break;
			}
		}
	}
	return (tbl);
}
Exemplo n.º 28
0
/*! \internal */
int
cpy_coord_val(int in_id,int out_id,char *var_nm,
              int in_large, int out_large)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the coordinate data from an input netCDF file
   * to an output netCDF file. 
   */

  const char *routine = NULL;
  int temp;
  size_t i;
  size_t spatial_dim, num_nodes;
  size_t start[2], count[2];
  nc_type var_type_in, var_type_out;

  void *void_ptr = NULL;

  /* Handle easiest situation first: in_large matches out_large */
  if (in_large == out_large)
    return cpy_var_val(in_id, out_id, var_nm);
  
  /* At this point, know that in_large != out_large, so will need to
     either copy a vector to multiple scalars or vice-versa.  Also
     will need a couple dimensions, so get them now.*/
  ex_get_dimension(in_id, DIM_NUM_DIM, "dimension", &spatial_dim, &temp, routine);
  ex_get_dimension(in_id, DIM_NUM_NODES, "nodes",   &num_nodes, &temp, routine);

  if (in_large == 0 && out_large == 1) {
    /* output file will have coordx, coordy, coordz (if 3d). */
    /* Get the var_id for the requested variable from both files. */
    int var_in_id, var_out_id[3];
    (void)nc_inq_varid(in_id, VAR_COORD, &var_in_id);

    (void)nc_inq_varid(out_id, VAR_COORD_X, &var_out_id[0]);
    (void)nc_inq_varid(out_id, VAR_COORD_Y, &var_out_id[1]);
    (void)nc_inq_varid(out_id, VAR_COORD_Z, &var_out_id[2]);

    (void)nc_inq_vartype( in_id, var_in_id,     &var_type_in);
    (void)nc_inq_vartype(out_id, var_out_id[0], &var_type_out);

    if (num_nodes > 0)
        void_ptr=malloc(num_nodes * type_size(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;
      if (var_type_in == NC_FLOAT) {
	nc_get_vara_float(in_id, var_in_id,     start, count, void_ptr);
	nc_put_var_float(out_id, var_out_id[i],               void_ptr);
      } else {
	assert(var_type_in == NC_DOUBLE);
	nc_get_vara_double(in_id, var_in_id,    start, count, void_ptr);
	nc_put_var_double(out_id, var_out_id[i],              void_ptr);
      }
    }
  }

  if (in_large == 1 && out_large == 0) {
    /* input file will have coordx, coordy, coordz (if 3d); output has only "coord" */
    int var_in_id[3], var_out_id;
    (void)nc_inq_varid(in_id,  VAR_COORD_X, &var_in_id[0]);
    (void)nc_inq_varid(in_id,  VAR_COORD_Y, &var_in_id[1]);
    (void)nc_inq_varid(in_id,  VAR_COORD_Z, &var_in_id[2]);
    (void)nc_inq_varid(out_id, VAR_COORD,   &var_out_id);
    
    (void)nc_inq_vartype(in_id,  var_in_id[0], &var_type_in);
    (void)nc_inq_vartype(out_id, var_out_id,   &var_type_out);

    if (num_nodes > 0)
        void_ptr=malloc(num_nodes * type_size(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;

      if (var_type_in == NC_FLOAT) {
        nc_get_var_float( in_id,  var_in_id[i],               void_ptr);
        nc_put_vara_float(out_id, var_out_id,   start, count, void_ptr);
      
      } else {
        nc_get_var_double( in_id,  var_in_id[i],               void_ptr);
        nc_put_vara_double(out_id, var_out_id,   start, count, void_ptr);
      }
    }
  }

  /* Free the space that held the variable */
  (void)free(void_ptr);
  return(EX_NOERR);
} /* end cpy_coord_val() */
Exemplo n.º 29
0
Arquivo: ncdf3.c Projeto: cran/ncdf
/***************************************************************************************
 * Given a numeric varid, this reads the data from the file.
 * Does not return on errors.
 */
SEXP R_nc_get_vara_numvarid( SEXP sx_nc, SEXP sx_varid, SEXP sx_start, SEXP sx_count ) 
{
	int 	varid, ncid, ndims, len_start, len_count, i, j, ierr,
		start_arg[MAX_NC_DIMS], count_arg[MAX_NC_DIMS],
		*data_addr_i, missval_i, ndims_cgt1;
	SEXP 	rv_data = R_NilValue /* -Wall */, sx_dim;
	size_t	start[MAX_NC_DIMS], count[MAX_NC_DIMS], varsize[MAX_NC_DIMS], tot_var_size,
		i_szt;
	double	*data_addr_d, missval_d, missval_tol;
	nc_type	vartype;

	/*--------------------------------------------------------------------------- 
	 * On entry, the following are guaranteed to be integers:
	 *	varid
	 *	*start
	 *	*count
	 *
	 * Note that varid, start, and/or count could be a single '-1' if the user
	 * has not specified the start and count to use.
	 * 'sx_nc' is guaranteed to be the full object of class 'ncdf'.
	 *----------------------------------------------------------------------------*/


	varid = INTEGER(sx_varid)[0];
	ncid  = INTEGER(R_ncu_getListElement( sx_nc, "id" ))[0];

	/*-----------------------------------------------------------------------
	 * Copy passed start and count to local vars so we can modify them safely
	 *----------------------------------------------------------------------*/
	len_start = length(sx_start);
	for( i=0; i<len_start; i++ )
		start_arg[i] = INTEGER(sx_start)[i];
	len_count = length(sx_count);
	for( i=0; i<len_count; i++ )
		count_arg[i] = INTEGER(sx_count)[i];
	
	/*-----------------------------------------
	 * Get varid to use, if passed value is -1.
	 *----------------------------------------*/
	if( varid == -1 ) {
		/*----------------------------------------------------
		 * Get how many vars are in this file ... if only one,
		 * use that one.  Otherwise, signal error.
		 *---------------------------------------------------*/
		varid = R_ncu_varid_onlyvar( ncid );
		if( varid == -1 ) 
			error( "Error: no var specified, and the file has more than one valid var!" );
		}
	else
		varid--;	/* go from R to C indexing */
	
	/*--------------------------------------------------------
	 * Get # of dims for this var, as a check to make sure any
	 * passed 'start' and 'count' are correct.
	 *-------------------------------------------------------*/
	ierr = nc_inq_varndims( ncid, varid, &ndims );
	if( ierr != NC_NOERR )
		error( "Internal error in ncdf package, routine R_nc_get_vara_numvarid: failed to get ndims for var!\n" );

	/*------------------------------------------------------
	 * Get our variable's size, and the start & count to use
	 *-----------------------------------------------------*/
	R_ncu_get_varsize( ncid, varid, ndims, varsize );
	R_ncu_calc_start_count( ncid, varid, start_arg, len_start, count_arg, len_count, 
			varsize, ndims, start, count );

	/*------------------------------------------------------------
	 * Allocate space for data, depending on the type of var it is
	 *-----------------------------------------------------------*/
	ierr = nc_inq_vartype( ncid, varid, &vartype );
	if( ierr != NC_NOERR )
		error( "Internal error in ncdf package, routine R_nc_get_vara_numvarid: failed to get type for var!\n" );

	tot_var_size = 1L;
	for( i=0; i<ndims; i++ ) {
		tot_var_size *= count[i];
		}

	switch( vartype ) {
		case NC_CHAR:
			error( "chars not handled yet, use old interface" );
			break;

		case NC_BYTE:
		case NC_SHORT:
		case NC_INT:
			/*---------------
			 * Allocate space
			 *--------------*/
			PROTECT( rv_data = allocVector( INTSXP, tot_var_size ));
			data_addr_i = &(INTEGER(rv_data)[0]);	/* Is this guaranteed to work?  Dunno. */

			/*--------------
			 * Read the data
			 *-------------*/
			ierr        = nc_get_vara_int( ncid, varid, start, count, data_addr_i );
			if( ierr != NC_NOERR )
				error( "Error while trying to read int data from file!" );

			/*---------------------
			 * Handle missing value
			 *--------------------*/
			ierr = nc_get_att_int( ncid, varid, "missing_value", &missval_i );
			if( ierr != NC_NOERR )
				/* No missing value attribute found, use default value */
				missval_i = NC_FILL_INT;
			for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) 
				if( data_addr_i[i_szt] == missval_i )
					data_addr_i[i_szt] = NA_INTEGER;
			break;

		case NC_FLOAT:
		case NC_DOUBLE:
			/*---------------
			 * Allocate space
			 *--------------*/
			PROTECT( rv_data = allocVector( REALSXP, tot_var_size ));
			data_addr_d = &(REAL(rv_data)[0]);	/* Is this guaranteed to work?  Dunno. */

			/*--------------
			 * Read the data
			 *-------------*/
			ierr        = nc_get_vara_double( ncid, varid, start, count, data_addr_d );
			if( ierr != NC_NOERR )
				error( "Error while trying to read real data from file!" );

			/*---------------------
			 * Handle missing value
			 *--------------------*/
			ierr = nc_get_att_double( ncid, varid, "missing_value", &missval_d );
			if( ierr != NC_NOERR )
				/* No missing value attribute found, use default value */
				missval_d = 1.e30;
			missval_tol = 1.e-5*fabs(missval_d);
			for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) 
				if( fabs(data_addr_d[i_szt] - missval_d) < missval_tol )
					data_addr_d[i_szt] = NA_REAL;
			break;

		default:
			error( "unhandled var type when allocating var space in R_nc_get_vara_numvarid");
		}

	/*-----------------------------------------
	 * Set our dims (note: non-degenerate only)
	 *----------------------------------------*/
	ndims_cgt1 = 0;  
	for( i=0; i<ndims; i++ )
		if( count[i] > 1 )
			ndims_cgt1++;
	if( ndims_cgt1 == 0 ) {
		PROTECT( sx_dim = allocVector( INTSXP, 1 ));
		INTEGER(sx_dim)[0] = 1;
		}
	else
		{
		PROTECT( sx_dim = allocVector( INTSXP, ndims_cgt1 ));
		j = 0;
		for( i=0; i<ndims; i++ )
			if( count[i] > 1 ) {
				INTEGER(sx_dim)[ndims_cgt1-j-1] = count[i];
				j++;
				}
		}
	setAttrib( rv_data, R_DimSymbol, sx_dim );

	UNPROTECT(2);
	return(rv_data);
}
Exemplo n.º 30
0
/** \internal
\ingroup variables
 Most dispatch tables will use the default procedures
*/
int
NCDEFAULT_get_vars(int ncid, int varid, const size_t * start,
	    const size_t * edges, const ptrdiff_t * stride,
	    void *value0, nc_type memtype)
{
#ifdef VARS_USES_VARM
   NC* ncp;
   int stat = NC_check_id(ncid, &ncp);

   if(stat != NC_NOERR) return stat;
   return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value0,memtype);
#else
  /* Rebuilt get_vars code to simplify and avoid use of get_varm */

   int status = NC_NOERR;
   int i,simplestride,isrecvar;
   int rank;
   struct GETodometer odom;
   nc_type vartype = NC_NAT;
   NC* ncp;
   int memtypelen;
   size_t vartypelen;
   char* value = (char*)value0;
   size_t numrecs;
   size_t varshape[NC_MAX_VAR_DIMS];
   size_t mystart[NC_MAX_VAR_DIMS];
   size_t myedges[NC_MAX_VAR_DIMS];
   ptrdiff_t mystride[NC_MAX_VAR_DIMS];
   char *memptr = NULL;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) memtype = vartype;

   /* compute the variable type size */
   status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
   if(status != NC_NOERR) return status;

   if(memtype > NC_MAX_ATOMIC_TYPE)
	memtypelen = (int)vartypelen;
    else
	memtypelen = nctypelen(memtype);

   /* Check gross internal/external type compatibility */
   if(vartype != memtype) {
      /* If !atomic, the two types must be the same */
      if(vartype > NC_MAX_ATOMIC_TYPE
         || memtype > NC_MAX_ATOMIC_TYPE)
	 return NC_EBADTYPE;
      /* ok, the types differ but both are atomic */
      if(memtype == NC_CHAR || vartype == NC_CHAR)
	 return NC_ECHAR;
   }

   /* Get the variable rank */
   status = nc_inq_varndims(ncid, varid, &rank);
   if(status != NC_NOERR) return status;

   /* Get variable dimension sizes */
   isrecvar = NC_is_recvar(ncid,varid,&numrecs);
   NC_getshape(ncid,varid,rank,varshape);

   /* Optimize out using various checks */
   if (rank == 0) {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_get_vara(ncid, varid, start, edge1, value, memtype);
   }

   /* Do various checks and fixups on start/edges/stride */
   simplestride = 1; /* assume so */
   for(i=0;i<rank;i++) {
	size_t dimlen;
	mystart[i] = (start == NULL ? 0 : start[i]);
	if(edges == NULL) {
	   if(i == 0 && isrecvar)
  	      myedges[i] = numrecs - start[i];
	   else
	      myedges[i] = varshape[i] - mystart[i];
	} else
	    myedges[i] = edges[i];
	if(myedges[i] == 0)
	    return NC_NOERR; /* cannot read anything */
	mystride[i] = (stride == NULL ? 1 : stride[i]);
	if(mystride[i] <= 0
	   /* cast needed for braindead systems with signed size_t */
           || ((unsigned long) mystride[i] >= X_INT_MAX))
           return NC_ESTRIDE;
  	if(mystride[i] != 1) simplestride = 0;
        /* illegal value checks */
	dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
        /* mystart is unsigned, never < 0 */
	if(mystart[i] >= dimlen)
	  return NC_EINVALCOORDS;
        /* myedges is unsigned, never < 0 */
	if(mystart[i] + myedges[i] > dimlen)
	  return NC_EEDGE;
   }
   if(simplestride) {
      return NC_get_vara(ncid, varid, mystart, myedges, value, memtype);
   }

   /* memptr indicates where to store the next value */
   memptr = value;

   odom_init(&odom,rank,mystart,myedges,mystride);

   /* walk the odometer to extract values */
   while(odom_more(&odom)) {
      int localstatus = NC_NOERR;
      /* Read a single value */
      localstatus = NC_get_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype);
      /* So it turns out that when get_varm is used, all errors are
         delayed and ERANGE will be overwritten by more serious errors.
      */
      if(localstatus != NC_NOERR) {
	    if(status == NC_NOERR || localstatus != NC_ERANGE)
	       status = localstatus;
      }
      memptr += memtypelen;
      odom_next(&odom);
   }
   return status;
#endif
}