[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: calculating space for ncrecget



> Organization: NCAR/ATD
> Keywords: 199403242316.AA16016

Hi Carol,

> How does one calculate the space required for a call
> to ncrecget() without calling ncrecinq()?  I believe
> I have all the necessary information to do so without
> an extraneous call, I just don't think I'm doing it
> right.

I just noticed that this question may not have gotten answered, since I was
on vacation when it got posted.  In case you're still looking for a way to
do this, I have appended some code from netcdf/nctest/rec.c in the source
distribution that demonstrates how ncrecinq() can be written in terms of
ncinquire(), ncvarinq(), and ncdiminq().  I'm not sure why you would want to
do this when ncrecinq() is available, but let me know if you have any more
questions about this.

__________________________________________________________________________
                      
Russ Rew                                              UCAR Unidata Program
address@hidden                                        P.O. Box 3000
(303)497-8645                                 Boulder, Colorado 80307-3000


#include "netcdf.h"

/*
 * Returns number of record variables in an open netCDF file, and an array of
 * the record variable ids, if the array parameter is non-null.  Returns -1 on
 * error.
 */
static int
numrecvars(ncid, recvarids)
     int ncid;
     int *recvarids;     
{
    int ndims, iv, nvars;
    int nrecvars;
    int recdimid;
    int dimids[MAX_NC_DIMS];

    if (ncinquire(ncid, 0, &nvars, 0, &recdimid) == -1)
      return -1;
    if (recdimid == -1)
      return 0;
    nrecvars = 0;
    for (iv = 0; iv < nvars; iv++) {
        if (ncvarinq(ncid, iv, 0, 0, &ndims, dimids, 0) == -1)
          return -1;
        if (ndims > 0 && dimids[0] == recdimid) {
            if (recvarids)
              recvarids[nrecvars] = iv;
            nrecvars++;
        }
    }
    return nrecvars;
}


/*
 * Returns record size (in bytes) of the record variable with a specified
 * variable id.  Returns 0 if not a record variable.  Returns -1 on error.
 */
static long
ncrecsize(ncid,vid)
     int ncid;
     int vid;
{
    int recdimid;
    nc_type type;
    int ndims;
    int dimids[MAX_NC_DIMS];
    int id;
    long size;

    if (ncinquire(ncid, 0, 0, 0, &recdimid) == -1)
      return -1;
    if (ncvarinq(ncid, vid, 0, &type, &ndims, dimids, 0) == -1)
      return -1;
    if (ndims == 0 || dimids[0] != recdimid)
      return 0;
    size = nctypelen(type);
    for (id = 1; id < ndims; id++) {
        long len;
        (void) ncdiminq(ncid, dimids[id], 0, &len);
        size *= len;
    }
    return size;
}


/*
 * Retrieves the number of record variables, the record variable ids, and the
 * record size of each record variable.  If any pointer to info to be returned
 * is null, the associated information is not returned.  Returns -1 on error.
 * This is the same as the ncrecinq() in the library, except that can handle
 * errors better.
 */
static int
recinq(ncid, nrecvars, recvarids, recsizes)
     int ncid;
     int *nrecvars;
     int *recvarids;
     long *recsizes;
{
    int iv;
    int rvarids[MAX_NC_VARS];
    int nrvars = numrecvars(ncid, rvarids);

    if (nrvars == -1)
      return -1;

    if (nrecvars)
      *nrecvars = nrvars;
    if (recvarids)
      for (iv = 0; iv < nrvars; iv++)
        recvarids[iv] = rvarids[iv];
    if (recsizes)
      for (iv = 0; iv < nrvars; iv++)
        recsizes[iv] = ncrecsize(ncid, rvarids[iv]);
    return 0;
}