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

[netCDF #DVS-605789]: Getting values of compound attributes



James,

I've written general C code for compound types in ncdump and nccopy,
though for attributes in nccopy I can just use the netCDF-4 library
function nc_copy_att() which does the attribute work.  

But for copying variable metadata and data, I still have to handle the
general case of arbitrarily nested user-defined data types and data
values, so it turns out to be easier not to treat compound types
separately from other user-defined types.  That way you can use the
same code to handle compound types nested within variable-length
types, or variable-length types nested within compound types, or
compound types nested in compound types, etc., with nesting
arbitrarily deep.

I use recursion in both ncdump and nccopy to handle arbitrary user-defined 
types.  I started out trying to explain this in more detail for ncdump, but
soon realized that the use of function pointers to do this in ncdump would
seem kind of pointless for a C++ implementation, which should be able to
use member functions in a more elegant implementation.

The main use of recursion is for vlen and compound types, though the use 
of fixed-size array members of compound types is also involved, because
the base type of an array member can also be another user-defined type.

So the main idea with compound types is to treat them as a bunch of fields
and to handle each field with another call to the function that handles the
compound type, with primitive types at the bottom bottoming out the recursion.

I think to explain it better, I'd need to explain the code in ncdump/vardata.c
and ncdump/dumplib.c for ncdump or the similar coded in ncdump/nccopy.c for 
nccopy.

As far as the new netCDF-4 C++ API goes, I'm afraid I don't know much about it,
as it was contributed by Lynton Appel.  But I'm pretty sure it does handle 
arbitrary user-defined types.

Sorry, this may not be of much help.  We need a better collection of test data
for testing user-defined types and for debugging code that handles them.

--Russ

> On Sep 9, 2011, at 9:13 AM, Unidata netCDF Support wrote:
> 
> > Hi James,
> >
> >> What is the best way to get the values of a compound attribute? Is there
> >> a way to get the values of each field in a compound attribute separately?
> >
> > Values of a compound attribute are accessed atomically.  It's not possible 
> > to
> > read or write member fields separately.  That's a constraint of the 
> > undelying
> > HDF5 library.  This is the C-based netCDF-4 library; I don't know whether 
> > the
> > netCDF-Java library provides access to individual fields, and there's no one
> > here to ask right now.  If your question is about the netCDF-Java API, I'll
> > find out and get back to you, but you might get a faster response to that 
> > from
> > address@hidden.
> 
> OK. I got it - the attributes that is. I assume a similar technique can be 
> used for variables. I'm using code that looks like:
> 
> 
> try {
> vector<unsigned char> values((len + 1) * attr_size);
> 
> int errstat = nc_get_att(ncid, varid, attrname, (void *)&values[0]);
> if (errstat != NC_NOERR)
> throw Error(errstat, string("Could not get the value for attribute '") + 
> attrname + string("'"));
> 
> for (int i = 0; i < nfields; ++i) {
> char field_name[NC_MAX_NAME];
> nc_type field_typeid;
> size_t field_offset;
> // TODO: these are unused... should they be used?
> int field_ndims;
> int field_sizes[MAX_NC_DIMS];
> nc_inq_compound_field(ncid, datatype, i, field_name, &field_offset, 
> &field_typeid, &field_ndims, &field_sizes[0]);
> 
> at->append_attr(field_name, print_type(field_typeid),
> print_attr(field_typeid, 0, &values[field_offset]));
> }
> 
> }
> catch (std::exception &e) {
> cerr << "Caught and exception in append_compound_values: " << e.what() << 
> endl;
> }
> 
> Summary: I read a slug of values using nc_get_att() and then use nfields 
> calls to nc_inq_compound_field() to extract the values from the buffer filled 
> in the nc_get_att() call.
> 
> Question: What will the buffer look like if there's a compound that contains 
> a compound (you can see from the code above that I have not tackled the 
> general case yet)? Will the buffer hold all of the data for the 'flattened' 
> structure or will it have a null in place of the child structure? In either 
> case can I assume that field_typeid will be >= NC_FIRSTUSERTYPEID?
> 
> I have not looked into the C++ api because I have this suspicion that it 
> won't be included on linux machine by default - should I switch to the C++ 
> api (because maybe it provides a way to get values for compounds' fields one 
> by one)?
> 
> Thanks,
> James
> 
> >
> > --Russ
> >
> > Russ Rew                                         UCAR Unidata Program
> > address@hidden                      http://www.unidata.ucar.edu
> >
> >
> >
> > Ticket Details
> > ===================
> > Ticket ID: DVS-605789
> > Department: Support netCDF
> > Priority: Normal
> > Status: Closed
> >
> 
> --
> James Gallagher
> jgallagher at opendap.org
> 406.723.8663
> 
> 

Russ Rew                                         UCAR Unidata Program
address@hidden                      http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: DVS-605789
Department: Support netCDF
Priority: Normal
Status: Closed