netcdf-c/libdispatch/dvarget.c

1816 lines
50 KiB
C
Raw Normal View History

/*! \file
Functions for getting data from variables.
Copyright 2011 University Corporation for Atmospheric
Research/Unidata. See \ref copyright file for more info.
2014-07-10 06:45:13 +08:00
*/
#include "ncdispatch.h"
/*!
\internal
2014-07-10 06:45:13 +08:00
*/
struct GETodometer {
int rank;
size_t index[NC_MAX_VAR_DIMS];
size_t start[NC_MAX_VAR_DIMS];
size_t edges[NC_MAX_VAR_DIMS];
ptrdiff_t stride[NC_MAX_VAR_DIMS];
size_t stop[NC_MAX_VAR_DIMS];
};
2014-07-10 06:45:13 +08:00
2017-12-05 03:21:14 +08:00
/**
* @internal Initialize odometer.
*
* @param odom Pointer to odometer.
* @param rank
2018-04-24 06:38:08 +08:00
* @param start Start indices.
2017-12-05 03:21:14 +08:00
* @param edges Counts.
* @param stride Strides.
*
2014-07-10 06:45:13 +08:00
*/
static void
2017-12-05 03:21:14 +08:00
odom_init(struct GETodometer* odom, int rank, const size_t* start,
const size_t* edges, const ptrdiff_t* stride)
{
int i;
memset(odom,0,sizeof(struct GETodometer));
odom->rank = rank;
assert(odom->rank <= NC_MAX_VAR_DIMS);
for(i=0;i<odom->rank;i++) {
odom->start[i] = (start != NULL ? start[i] : 0);
odom->edges[i] = (edges != NULL ? edges[i] : 1);
odom->stride[i] = (stride != NULL ? stride[i] : 1);
odom->stop[i] = odom->start[i] + (odom->edges[i]*((size_t)odom->stride[i]));
odom->index[i] = odom->start[i];
2014-07-10 06:45:13 +08:00
}
}
2017-12-05 03:21:14 +08:00
/**
* @internal Return true if there is more.
*
* @param odom Pointer to odometer.
*
* @return True if there is more, 0 otherwise.
2014-07-10 06:45:13 +08:00
*/
static int
odom_more(struct GETodometer* odom)
{
return (odom->index[0] < odom->stop[0]);
}
2017-12-05 03:21:14 +08:00
/**
* @internal Move odometer.
*
* @param odom Pointer to odometer.
*
* @return 0 or 1
2014-07-10 06:45:13 +08:00
*/
static int
odom_next(struct GETodometer* odom)
{
int i;
if(odom->rank == 0) return 0;
for(i=odom->rank-1;i>=0;i--) {
odom->index[i] += (size_t)odom->stride[i];
if(odom->index[i] < odom->stop[i]) break;
if(i == 0) return 0; /* leave the 0th entry if it overflows*/
odom->index[i] = odom->start[i]; /* reset this position*/
}
return 1;
}
2018-08-14 22:01:54 +08:00
/**
* @internal Check the start, count, and stride parameters for gets
* and puts, and handle NULLs.
*
* @param ncid The file ID.
* @param varid The variable ID.
* @param start Pointer to pointer to start array. If *start is NULL
* NC_EINVALCOORDS will be returned for non-scalar variable.
* @param count Pointer to pointer to count array. If *count is NULL,
* an array of the correct size will be allocated, and filled with
* counts that represent the full extent of the variable. In this
* case, the memory must be freed by the caller.
* @param stride Pointer to pointer to stride array. If NULL, stide is
* ignored. If *stride is NULL an array of the correct size will be
* allocated, and filled with ones. In this case, the memory must be
* freed by the caller.
*
* @return ::NC_NOERR No error.
* @return ::NC_EBADID Bad ncid.
* @return ::NC_ENOTVAR Variable not found.
* @return ::NC_ENOMEM Out of memory.
* @return ::NC_EINVALCOORS Missing start array.
* @author Ed Hartnett
*/
int
NC_check_nulls(int ncid, int varid, size_t **start, size_t **count,
ptrdiff_t **stride)
{
int varndims;
int stat;
if ((stat = nc_inq_varndims(ncid, varid, &varndims)))
return stat;
/* For non-scalar vars, start is required. */
if (!*start && varndims)
return NC_EINVALCOORDS;
/* If count is NULL, assume full extent of var. */
if (!*count)
{
if (!(*count = malloc(varndims * sizeof(size_t))))
return NC_ENOMEM;
if ((stat = NC_getshape(ncid, varid, varndims, *count)))
return stat;
}
/* If stride is NULL, do nothing, if *stride is NULL use all 1s. */
if (stride && !*stride)
{
int i;
if (!(*stride = malloc(varndims * sizeof(size_t))))
return NC_ENOMEM;
for (i = 0; i < varndims; i++)
*stride[i] = 1;
}
return NC_NOERR;
}
2011-07-15 06:21:46 +08:00
/** \internal
2014-07-10 06:45:13 +08:00
\ingroup variables
*/
int
NC_get_vara(int ncid, int varid,
const size_t *start, const size_t *edges,
void *value, nc_type memtype)
{
NC* ncp;
2018-08-14 22:01:54 +08:00
size_t *my_start = (size_t *)start, *my_count = (size_t *)edges;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2018-08-14 22:01:54 +08:00
if(start == NULL || edges == NULL) {
stat = NC_check_nulls(ncid, varid, &my_start, &my_count, NULL);
if(stat != NC_NOERR) return stat;
2018-08-13 23:15:50 +08:00
}
2018-08-14 22:01:54 +08:00
stat = ncp->dispatch->get_vara(ncid,varid,my_start,my_count,value,memtype);
if(edges == NULL) free(my_count);
return stat;
}
2017-11-14 21:48:38 +08:00
/**
Get data for a variable.
\param ncid NetCDF or group ID.
\param varid Variable ID
\param value Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\param memtype the NC type of the data after it is read into
memory. Data are converted from the variable's type to the memtype as
they are read.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_EEDGE Start+count exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
\internal
2017-11-14 21:48:38 +08:00
\author Dennis Heimbigner
*/
static int
NC_get_var(int ncid, int varid, void *value, nc_type memtype)
{
int ndims;
size_t shape[NC_MAX_VAR_DIMS];
int stat = nc_inq_varndims(ncid,varid, &ndims);
if(stat) return stat;
stat = NC_getshape(ncid,varid, ndims, shape);
if(stat) return stat;
2011-07-15 06:21:46 +08:00
return NC_get_vara(ncid, varid, NC_coord_zero, shape, value, memtype);
}
/** \internal
2014-07-10 06:45:13 +08:00
\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)
{
/* Rebuilt get_vars code to simplify and avoid use of get_varm */
2014-07-10 06:45:13 +08:00
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;
size_t nels;
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;
2014-07-10 06:45:13 +08:00
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 */
2014-07-10 06:45:13 +08:00
status = nc_inq_varndims(ncid, varid, &rank);
if(status != NC_NOERR) return status;
2018-08-13 23:15:50 +08:00
/* Start array is always required for non-scalar vars. */
if(rank > 0 && start == NULL)
return NC_EINVALCOORDS;
/* Get variable dimension sizes */
isrecvar = NC_is_recvar(ncid,varid,&numrecs);
2014-07-10 06:45:13 +08:00
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 */
nels = 1;
for(i=0;i<rank;i++) {
size_t dimlen;
mystart[i] = (start == NULL ? 0 : start[i]);
/* illegal value checks */
dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
/* mystart is unsigned, never < 0 */
#ifdef RELAX_COORD_BOUND
if (mystart[i] > dimlen) return NC_EINVALCOORDS;
#else
if (mystart[i] >= dimlen) return NC_EINVALCOORDS;
#endif
if(edges == NULL) {
if(i == 0 && isrecvar)
myedges[i] = numrecs - start[i];
else
myedges[i] = varshape[i] - mystart[i];
} else
myedges[i] = edges[i];
#ifdef RELAX_COORD_BOUND
if (mystart[i] == dimlen && myedges[i] > 0) return NC_EINVALCOORDS;
#endif
/* myedges is unsigned, never < 0 */
if(mystart[i] + myedges[i] > dimlen)
return NC_EEDGE;
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;
2014-07-10 06:45:13 +08:00
if(mystride[i] != 1) simplestride = 0;
if(myedges[i] == 0)
nels = 0;
}
if(nels == 0)
return NC_NOERR; /* cannot read anything */
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;
}
/** \internal
2014-07-10 06:45:13 +08:00
\ingroup variables
*/
static int
2014-07-10 06:45:13 +08:00
NC_get_var1(int ncid, int varid, const size_t *coord, void* value,
nc_type memtype)
{
2011-07-15 06:21:46 +08:00
return NC_get_vara(ncid, varid, coord, NC_coord_one, value, memtype);
}
/** \internal
2014-07-10 06:45:13 +08:00
\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)
{
2012-03-17 06:29:09 +08:00
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;
*/
2014-07-10 06:45:13 +08:00
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;
2014-07-10 06:45:13 +08:00
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;
2014-07-10 06:45:13 +08:00
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);
2014-07-10 06:45:13 +08:00
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;
}
2014-07-10 06:45:13 +08:00
/* 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;
/*
* Check start, edges
*/
for (idim = maxidim; idim >= 0; --idim)
{
size_t dimlen =
idim == 0 && isrecvar
? numrecs
: varshape[idim];
mystart[idim] = start != NULL
? start[idim]
: 0;
#ifdef RELAX_COORD_BOUND
if (mystart[idim] > dimlen)
#else
if (mystart[idim] >= dimlen)
#endif
{
status = NC_EINVALCOORDS;
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
#ifdef RELAX_COORD_BOUND
if (mystart[idim] == dimlen && myedges[idim] > 0)
{
status = NC_EINVALCOORDS;
goto done;
}
#endif
if (mystart[idim] + myedges[idim] > dimlen)
{
status = NC_EEDGE;
goto done;
}
}
/*
* Initialize I/O parameters.
*/
for (idim = maxidim; idim >= 0; --idim)
{
if (edges != NULL && edges[idim] == 0)
{
status = NC_NOERR; /* read/write no data */
goto done;
}
mystride[idim] = stride != NULL
? stride[idim]
: 1;
2015-08-16 06:26:35 +08:00
/* 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
2014-07-10 06:45:13 +08:00
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]);
}
/* Lower body */
/*
2014-07-10 06:45:13 +08:00
* 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];
}
2014-07-10 06:45:13 +08:00
/*
* 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;
}
2018-08-14 20:44:11 +08:00
/**
2017-11-14 21:48:38 +08:00
Called by externally visible nc_get_vars_xxx routines.
\param ncid NetCDF or group ID.
\param varid Variable ID
2018-08-14 18:17:34 +08:00
\param start start indices. Required for non-scalar vars.
2017-11-14 21:48:38 +08:00
\param edges count indices.
\param stride data strides.
\param value Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\param memtype the NC type of the data after it is read into
memory. Data are converted from the variable's type to the memtype as
they are read.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_EEDGE Start+count exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
\internal
2018-08-14 18:44:26 +08:00
\author Dennis Heimbigner, Ed Hartnett
2017-11-14 21:48:38 +08:00
*/
static int
2014-07-10 06:45:13 +08:00
NC_get_vars(int ncid, int varid, const size_t *start,
const size_t *edges, const ptrdiff_t *stride, void *value,
nc_type memtype)
{
NC* ncp;
2018-08-14 20:28:28 +08:00
size_t *my_start = (size_t *)start, *my_count = (size_t *)edges;
ptrdiff_t *my_stride = (ptrdiff_t *)stride;
int stat;
2018-08-14 20:28:28 +08:00
stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2018-08-14 18:17:34 +08:00
2018-08-14 20:28:28 +08:00
if(start == NULL || edges == NULL || stride == NULL) {
stat = NC_check_nulls(ncid, varid, &my_start, &my_count, &my_stride);
2018-08-14 18:17:34 +08:00
if(stat != NC_NOERR) return stat;
}
2018-08-14 20:28:28 +08:00
stat = ncp->dispatch->get_vars(ncid,varid,my_start,my_count,my_stride,
value,memtype);
if(edges == NULL) free(my_count);
if(stride == NULL) free(my_stride);
return stat;
/* if(start == NULL || edges == NULL) { */
/* stat = nc_inq_varndims(ncid, varid, &varndims); */
/* if(stat != NC_NOERR) return stat; */
/* if(start == NULL && varndims > 0) return NC_EINVALCOORDS; */
/* } */
/* if(edges == NULL) { */
/* size_t shape[NC_MAX_VAR_DIMS]; */
/* stat = NC_getshape(ncid, varid, varndims, shape); */
/* if(stat != NC_NOERR) return stat; */
/* return ncp->dispatch->get_vars(ncid, varid, start, shape, stride, */
/* value, memtype); */
/* } else */
/* return ncp->dispatch->get_vars(ncid,varid,start,edges,stride,value,memtype); */
}
2017-11-14 21:48:38 +08:00
/**
Called by externally visible nc_get_varm_xxx routines. Note that the
varm routines are deprecated. Use the vars routines instead for new
code.
\param ncid NetCDF or group ID.
\param varid Variable ID
\param start start indices.
\param edges count indices.
\param stride data strides.
\param map mapping of dimensions.
\param value Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\param memtype the NC type of the data after it is read into
memory. Data are converted from the variable's type to the memtype as
they are read.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_EEDGE Start+count exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
\ingroup variables
\internal
2018-08-14 18:44:26 +08:00
\author Dennis Heimbigner, Ed Hartnett
*/
static int
2014-07-10 06:45:13 +08:00
NC_get_varm(int ncid, int varid, const size_t *start,
const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t* map,
void *value, nc_type memtype)
{
NC* ncp;
int rank;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
/* Non-scalar vars require start array. */
if(start == NULL) {
stat = nc_inq_varndims(ncid, varid, &rank);
if(stat != NC_NOERR) return stat;
if(rank > 0) return NC_EINVALCOORDS;
}
return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,map,value,memtype);
}
/** \name Reading Data from Variables
Functions to read data from variables. */
/*! \{ */ /* All these functions are part of this named group... */
/** \ingroup variables
2014-07-10 06:45:13 +08:00
Read an array of values from a variable.
The array to be read is specified by giving a corner and a vector of
2014-07-10 06:45:13 +08:00
edge lengths to \ref specify_hyperslab.
The data values are read into consecutive locations with the last
dimension varying fastest. The netCDF dataset must be in data mode
(for netCDF-4/HDF5 files, the switch to data mode will happen
automatically, unless the classic model is used).
The nc_get_vara() function will read a variable of any type,
including user defined type. For this function, the type of the data
in memory must match the type of the variable - no data conversion is
done.
Other nc_get_vara_ functions will convert data to the desired output
type as needed.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
2014-07-10 06:45:13 +08:00
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID
\param startp Start vector with one element for each dimension to \ref
specify_hyperslab.
\param countp Count vector with one element for each dimension to \ref
specify_hyperslab.
\param ip Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_EEDGE Start+count exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
\section nc_get_vara_double_example Example
Here is an example using nc_get_vara_double() to read all the values of
the variable named rh from an existing netCDF dataset named
foo.nc. For simplicity in this example, we assume that we know that rh
is dimensioned with time, lat, and lon, and that there are three time
values, five lat values, and ten lon values.
\code
#include <netcdf.h>
...
#define TIMES 3
#define LATS 5
#define LONS 10
2014-07-10 06:45:13 +08:00
int status;
int ncid;
int rh_id;
static size_t start[] = {0, 0, 0};
static size_t count[] = {TIMES, LATS, LONS};
2014-07-10 06:45:13 +08:00
double rh_vals[TIMES*LATS*LONS];
...
status = nc_open("foo.nc", NC_NOWRITE, &ncid);
if (status != NC_NOERR) handle_error(status);
...
status = nc_inq_varid (ncid, "rh", &rh_id);
if (status != NC_NOERR) handle_error(status);
...
status = nc_get_vara_double(ncid, rh_id, start, count, rh_vals);
if (status != NC_NOERR) handle_error(status);
\endcode
2018-08-14 18:44:26 +08:00
\author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
*/
/**@{*/
int
2014-07-10 06:45:13 +08:00
nc_get_vara(int ncid, int varid, const size_t *startp,
const size_t *countp, void *ip)
{
2012-03-17 06:29:09 +08:00
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);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vara_text(int ncid, int varid, const size_t *startp,
const size_t *countp, char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vara(ncid, varid, startp, countp,
(void *)ip, NC_CHAR);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vara_schar(int ncid, int varid, const size_t *startp,
const size_t *countp, signed char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vara(ncid, varid, startp, countp,
(void *)ip, NC_BYTE);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vara_uchar(int ncid, int varid, const size_t *startp,
const size_t *countp, unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vara(ncid, varid, startp, countp,
(void *)ip, T_uchar);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vara_short(int ncid, int varid, const size_t *startp,
const size_t *countp, short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vara(ncid, varid, startp, countp,
(void *)ip, NC_SHORT);
}
int
nc_get_vara_int(int ncid, int varid,
const size_t *startp, const size_t *countp, int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_INT);
}
int
nc_get_vara_long(int ncid, int varid,
const size_t *startp, const size_t *countp, long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_long);
}
int
nc_get_vara_float(int ncid, int varid,
const size_t *startp, const size_t *countp, float *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_float);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vara_double(int ncid, int varid, const size_t *startp,
const size_t *countp, double *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_double);
}
int
nc_get_vara_ubyte(int ncid, int varid,
const size_t *startp, const size_t *countp, unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ubyte);
}
int
nc_get_vara_ushort(int ncid, int varid,
const size_t *startp, const size_t *countp, unsigned short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ushort);
}
int
nc_get_vara_uint(int ncid, int varid,
const size_t *startp, const size_t *countp, unsigned int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_uint);
}
int
nc_get_vara_longlong(int ncid, int varid,
const size_t *startp, const size_t *countp, long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_longlong);
}
int
nc_get_vara_ulonglong(int ncid, int varid,
const size_t *startp, const size_t *countp, unsigned long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_UINT64);
}
#ifdef USE_NETCDF4
int
nc_get_vara_string(int ncid, int varid,
const size_t *startp, const size_t *countp, char* *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_STRING);
}
#endif /*USE_NETCDF4*/
/**@}*/
/** \ingroup variables
2014-07-10 06:45:13 +08:00
Read a single datum from a variable.
Inputs are the netCDF ID, the variable ID, a multidimensional index
that specifies which value to get, and the address of a location into
which the data value will be read. The value is converted from the
external data type of the variable, if necessary.
The nc_get_var1() function will read a variable of any type, including
user defined type. For this function, the type of the data in memory
must match the type of the variable - no data conversion is done.
Other nc_get_var1_ functions will convert data to the desired output
type as needed.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
2014-07-10 06:45:13 +08:00
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
\param varid Variable ID
\param indexp Index vector with one element for each dimension.
\param ip Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
2018-08-14 18:44:26 +08:00
\author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
*/
/** \{ */
int
nc_get_var1(int ncid, int varid, const size_t *indexp, void *ip)
{
return NC_get_var1(ncid, varid, indexp, ip, NC_NAT);
}
int
nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_CHAR);
}
int
nc_get_var1_schar(int ncid, int varid, const size_t *indexp, signed char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_BYTE);
}
int
nc_get_var1_uchar(int ncid, int varid, const size_t *indexp, unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE);
}
int
nc_get_var1_short(int ncid, int varid, const size_t *indexp, short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_SHORT);
}
int
nc_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_long(int ncid, int varid, const size_t *indexp,
long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, longtype);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_float(int ncid, int varid, const size_t *indexp,
float *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_FLOAT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_double(int ncid, int varid, const size_t *indexp,
double *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_DOUBLE);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp,
unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_ushort(int ncid, int varid, const size_t *indexp,
unsigned short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_USHORT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_uint(int ncid, int varid, const size_t *indexp,
unsigned int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2013-02-12 02:04:03 +08:00
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UINT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_longlong(int ncid, int varid, const size_t *indexp,
long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT64);
}
int
2014-07-10 06:45:13 +08:00
nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp,
unsigned long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UINT64);
}
#ifdef USE_NETCDF4
int
nc_get_var1_string(int ncid, int varid, const size_t *indexp, char* *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_STRING);
}
#endif /*USE_NETCDF4*/
/** \} */
2011-07-12 23:37:24 +08:00
/** \ingroup variables
2014-07-10 06:45:13 +08:00
Read an entire variable in one call.
2011-07-12 23:37:24 +08:00
This function will read all the values from a netCDF variable of an
open netCDF dataset.
This is the simplest interface to use for reading the value of a
scalar variable or when all the values of a multidimensional variable
can be read at once. The values are read into consecutive locations
with the last dimension varying fastest. The netCDF dataset must be in
data mode.
Take care when using this function with record variables (variables
that use the ::NC_UNLIMITED dimension). If you try to read all the
values of a record variable into an array but there are more records
in the file than you assume, more data will be read than you expect,
which may cause a segmentation violation. To avoid such problems, it
is better to use the nc_get_vara interfaces for variables that use the
::NC_UNLIMITED dimension.
The functions for types ubyte, ushort, uint, longlong, ulonglong, and
string are only available for netCDF-4/HDF5 files.
The nc_get_var() function will read a variable of any type, including
user defined type. For this function, the type of the data in memory
must match the type of the variable - no data conversion is done.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
2014-07-10 06:45:13 +08:00
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
2011-07-12 23:37:24 +08:00
\param varid Variable ID
\param ip Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
2018-08-14 18:44:26 +08:00
\author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
2011-07-12 23:37:24 +08:00
*/
/** \{ */
int
nc_get_var(int ncid, int varid, void *ip)
{
return NC_get_var(ncid, varid, ip, NC_NAT);
}
int
nc_get_var_text(int ncid, int varid, char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid, varid, (void *)ip, NC_CHAR);
}
int
nc_get_var_schar(int ncid, int varid, signed char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid, varid, (void *)ip, NC_BYTE);
}
int
nc_get_var_uchar(int ncid, int varid, unsigned char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE);
}
int
nc_get_var_short(int ncid, int varid, short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid, varid, (void *)ip, NC_SHORT);
}
int
nc_get_var_int(int ncid, int varid, int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_INT);
}
int
nc_get_var_long(int ncid, int varid, long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, longtype);
}
int
nc_get_var_float(int ncid, int varid, float *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_FLOAT);
}
int
nc_get_var_double(int ncid, int varid, double *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_DOUBLE);
}
int
nc_get_var_ubyte(int ncid, int varid, unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE);
}
int
nc_get_var_ushort(int ncid, int varid, unsigned short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_USHORT);
}
int
nc_get_var_uint(int ncid, int varid, unsigned int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_UINT);
}
int
nc_get_var_longlong(int ncid, int varid, long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip, NC_INT64);
}
int
nc_get_var_ulonglong(int ncid, int varid, unsigned long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip,NC_UINT64);
}
#ifdef USE_NETCDF4
int
nc_get_var_string(int ncid, int varid, char* *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_var(ncid,varid, (void *)ip,NC_STRING);
}
#endif /*USE_NETCDF4*/
2011-07-12 23:37:24 +08:00
/** \} */
/** \ingroup variables
2014-07-10 06:45:13 +08:00
Read a strided array from a variable.
2011-07-12 23:37:24 +08:00
This function reads a subsampled (strided) array section of values
from a netCDF variable of an open netCDF dataset. The subsampled array
section is specified by giving a corner, a vector of edge lengths, and
a stride vector. The values are read with the last dimension of the
netCDF variable varying fastest. The netCDF dataset must be in data
mode.
The nc_get_vars() function will read a variable of any type, including
user defined type. For this function, the type of the data in memory
must match the type of the variable - no data conversion is done.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
2014-07-10 06:45:13 +08:00
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
2011-07-12 23:37:24 +08:00
\param varid Variable ID
\param startp Start vector with one element for each dimension to \ref
specify_hyperslab.
\param countp Count vector with one element for each dimension to \ref
specify_hyperslab.
2011-07-12 23:37:24 +08:00
\param stridep Stride vector with one element for each dimension to
\ref specify_hyperslab.
\param ip Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
2018-08-14 18:44:26 +08:00
\author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
2011-07-12 23:37:24 +08:00
*/
/** \{ */
int
nc_get_vars(int ncid, int varid, const size_t * startp,
const size_t * countp, const ptrdiff_t * stridep,
void *ip)
2011-07-12 23:37:24 +08:00
{
NC* ncp;
2012-03-17 06:29:09 +08:00
int stat = NC_NOERR;
2011-07-12 23:37:24 +08:00
if ((stat = NC_check_id(ncid, &ncp)))
return stat;
return NC_get_vars(ncid, varid, startp, countp, stridep,
2011-07-12 23:37:24 +08:00
ip, NC_NAT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_text(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, NC_CHAR);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_schar(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
signed char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, NC_BYTE);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_uchar(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, T_uchar);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_short(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t *stridep,
short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
2011-07-12 23:37:24 +08:00
(void *)ip, NC_SHORT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_int(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, NC_INT);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_long(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, T_long);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_float(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
float *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, T_float);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_double(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
double *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, T_double);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_ubyte(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
unsigned char *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid, startp, countp, stridep,
(void *)ip, T_ubyte);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_ushort(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
unsigned short *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp,countp, stridep,
(void *)ip, T_ushort);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_uint(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
unsigned int *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid,varid,startp, countp, stridep,
(void *)ip, T_uint);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_longlong(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid, varid, startp, countp, stridep,
(void *)ip, T_longlong);
}
int
2014-07-10 06:45:13 +08:00
nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp,
2011-07-12 23:37:24 +08:00
const size_t *countp, const ptrdiff_t * stridep,
unsigned long long *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_vars(ncid, varid, startp, countp, stridep,
(void *)ip, NC_UINT64);
}
#ifdef USE_NETCDF4
int
2011-07-12 23:37:24 +08:00
nc_get_vars_string(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t * stridep,
char* *ip)
{
NC* ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2014-07-10 06:45:13 +08:00
return NC_get_vars(ncid, varid, startp, countp, stridep,
2011-07-12 23:37:24 +08:00
(void *)ip, NC_STRING);
}
#endif /*USE_NETCDF4*/
2011-07-12 23:37:24 +08:00
/** \} */
/** \ingroup variables
2014-07-10 06:45:13 +08:00
Read a mapped array from a variable.
2011-07-12 23:37:24 +08:00
The nc_get_varm_ type family of functions reads a mapped array section
of values from a netCDF variable of an open netCDF dataset. The mapped
array section is specified by giving a corner, a vector of edge
lengths, a stride vector, and an index mapping vector. The index
mapping vector is a vector of integers that specifies the mapping
between the dimensions of a netCDF variable and the in-memory
structure of the internal data array. No assumptions are made about
the ordering or length of the dimensions of the data array. The netCDF
dataset must be in data mode.
The functions for types ubyte, ushort, uint, longlong, ulonglong, and
string are only available for netCDF-4/HDF5 files.
The nc_get_varm() function will only read a variable of an
atomic type; it will not read user defined types. For this
function, the type of the data in memory must match the type
of the variable - no data conversion is done.
2011-07-12 23:37:24 +08:00
2014-10-13 02:38:41 +08:00
@deprecated Use of this family of functions is discouraged,
although it will continue to be supported.
The reason is the complexity of the
algorithm makes its use difficult for users to properly use.
\param ncid NetCDF or group ID, from a previous call to nc_open(),
2014-07-10 06:45:13 +08:00
nc_create(), nc_def_grp(), or associated inquiry functions such as
nc_inq_ncid().
2011-07-12 23:37:24 +08:00
\param varid Variable ID
2011-07-12 23:37:24 +08:00
\param startp Start vector with one element for each dimension to \ref
specify_hyperslab.
\param countp Count vector with one element for each dimension to \ref
specify_hyperslab.
\param stridep Stride vector with one element for each dimension to
\ref specify_hyperslab.
\param imapp Mapping vector with one element for each dimension to
\ref specify_hyperslab.
\param ip Pointer where the data will be copied. Memory must be
allocated by the user before this function is called.
\returns ::NC_NOERR No error.
\returns ::NC_ENOTVAR Variable not found.
\returns ::NC_EINVALCOORDS Index exceeds dimension bound.
\returns ::NC_ERANGE One or more of the values are out of range.
\returns ::NC_EINDEFINE Operation not allowed in define mode.
\returns ::NC_EBADID Bad ncid.
2018-08-14 18:44:26 +08:00
\author Glenn Davis, Russ Rew, Ed Hartnett, Dennis Heimbigner, Ward Fisher
2011-07-12 23:37:24 +08:00
*/
/** \{ */
int
2011-07-12 23:37:24 +08:00
nc_get_varm(int ncid, int varid, const size_t * startp,
const size_t * countp, const ptrdiff_t * stridep,
const ptrdiff_t * imapp, void *ip)
{
NC* ncp;
2012-03-17 06:29:09 +08:00
int stat = NC_NOERR;
2011-07-12 23:37:24 +08:00
if ((stat = NC_check_id(ncid, &ncp)))
return stat;
return NC_get_varm(ncid, varid, startp, countp, stridep, imapp, ip, NC_NAT);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_schar(int ncid, int varid,
const size_t *startp, const size_t *countp,
2014-07-10 06:45:13 +08:00
const ptrdiff_t *stridep,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *imapp, signed char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp,
stridep, imapp, (void *)ip, NC_BYTE);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_uchar(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
unsigned char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_uchar);
}
int
2014-07-10 06:45:13 +08:00
nc_get_varm_short(int ncid, int varid, const size_t *startp,
const size_t *countp, const ptrdiff_t *stridep,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *imapp, short *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_SHORT);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_int(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
int *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_INT);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_long(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
long *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_long);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_float(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
float *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_float);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_double(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
double *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_double);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_ubyte(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
unsigned char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid,varid,startp,countp,stridep,
imapp, (void *)ip, T_ubyte);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_ushort(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
unsigned short *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp, stridep,
imapp, (void *)ip, T_ushort);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_uint(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
unsigned int *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp,
stridep, imapp, (void *)ip, T_uint);
}
int
2014-07-10 06:45:13 +08:00
nc_get_varm_longlong(int ncid, int varid, const size_t *startp,
const size_t *countp, const ptrdiff_t *stridep,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *imapp, long long *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
(void *)ip, T_longlong);
}
int
2011-07-12 23:37:24 +08:00
nc_get_varm_ulonglong(int ncid, int varid,
const size_t *startp, const size_t *countp,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *stridep, const ptrdiff_t *imapp,
unsigned long long *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
(void *)ip, NC_UINT64);
}
int
2014-07-10 06:45:13 +08:00
nc_get_varm_text(int ncid, int varid, const size_t *startp,
const size_t *countp, const ptrdiff_t *stridep,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *imapp, char *ip)
{
2011-07-12 23:37:24 +08:00
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
2011-07-12 23:37:24 +08:00
return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
(void *)ip, NC_CHAR);
}
2011-07-12 23:37:24 +08:00
#ifdef USE_NETCDF4
int
2014-07-10 06:45:13 +08:00
nc_get_varm_string(int ncid, int varid, const size_t *startp,
const size_t *countp, const ptrdiff_t *stridep,
2011-07-12 23:37:24 +08:00
const ptrdiff_t *imapp, char **ip)
{
NC *ncp;
int stat = NC_check_id(ncid, &ncp);
if(stat != NC_NOERR) return stat;
return NC_get_varm(ncid, varid, startp, countp, stridep, imapp,
(void *)ip, NC_STRING);
}
/** \} */
#endif /*USE_NETCDF4*/
2011-07-12 23:37:24 +08:00
/*! \} */ /* End of named group... */