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

Re: 20010212: variable attributes problems (cont.)



>Date: Mon, 12 Feb 2001 13:55:18 -0500 (EST)
>From: "Edwin R Wolfe Jr." <address@hidden>
>Organization: University of Michigan
>To: Steve Emmerson <address@hidden>
>Subject: Re: 20010212: variable attributes problems (cont.) 
>Keywords: 200102091837.f19IbPL07744

> > > the generated code has
> > > 
> > > iret = nf_put_vara_int(ncid, ms_time_id, ms_time_start, ms_time_count,
> > > ms_time)
> > > 
> > > I was hoping for put_vara_int2, since that's what will be passed to the
> > > writerec routine.  Is there a way to get that to happen?
> > 
> > No, but I'm not sure why you would want that to happen.  If a variable
> > is declared to be of netCDF type "short" corresponding to a 2-byte
> > integer, conversion to that external type will occur from integer data
> > when nf_put_vara_int() is called, 
>
> we are wanting to pass a 2 byte variable to write as a two byte variable,
> and get a conversion error using the put_vara_int() written by ncgen.
> put_vara_int2() gives no error.

So for some data value x that can be held in a 2-byte integer, x is
not preserved by first assigning it to a 4-byte integer and then
assigning that to a 2-byte integer?  This may indicate a bug in
nf_put_vara_int().  Do you have an example of a value that is not
converted correctly?

> >  The advantage of using an INTEGER data type is as Steve pointed
> > out, for portability, since 2-byte integers may not be supported as a
> > valid data type in the Fortran compiler you are using.

> so maybe we should change our thinking to save space and just use ints,
> even when we know a value will never exceed 2 (or sometimes 1) bytes?

No, you are right to use 2-byte ints for values you know will always
be small.  It's just that ncgen generates Fortran code that uses a
call to nf_put_vara_int() for any kind of integer value because it
makes the code generated by ncgen more portable.  ncgen would be much
more complicated if it had to generate different code for different
Fortran platforms depending on things such as whether their Fortran
compiler supported integer*2 and integer*1 declarations or not.  So
ncgen generates code that is as portable as possible, though maybe not
as efficient as possible.

> > I'm not sure what the relevance of the writerecs() is here.  That's
> > just an internal FORTRAN subroutine that ncgen generates to write
> > record variables, and is an implementation detail of ncgen that should
> > probably not be modeled in your own code.  In fact none of the
> > arguments to the writerecs() subroutine are for the data; they are
> > just the netCDF ID and the variable ID.  The data is initialized in an
> > internal DATA statement in writerecs(), which is almost surely not the
> > way you would do it in your code.

> Well, we have a number of data collections defined and are trying to
> minimize the coding effort to support them. It seemed that if we could use
> ncgen to do most of the work for us, that would be great.  I
> change the <program fgennc> statement to <subroutine make_vec()> with a 
> few parameters (filename, clobbermode, ncid return, and any non-unlimited 
> dimension variables). writerecs we modify to accept a single record of a
> structure type defined in a .inc file.  And delete the data statements.  
> The variable ids we put on a common block seen only by make_vec and
> writerec.  The intent is to create a certain type of data file, process
> data to fill in one structure record, and call writerec to write it out,
> process the next record, etc. Ncgen provides the code for doing that (with
> a bit of modification)

As the author of ncgen, I'm just admitting that it was not designed
to generate pretty or efficient code, just code that works on all
platforms netCDF works on.  Feel free to modify ncgen to generate
calls to nf_put_vara_int2() if you want to.  But then you also have to
modify it to declare the data array given to nf_put_vara_int2() as
INTEGER*2, which is not a portable declaration, so the result may not
work on some platforms.

> Unless I misread, it seems netCDF doesn't understand the concept of a
> structure so it seemed, if we wanted to use structure records, we'd either
> need to have each program that wanted to write the same data type have
> separate put_var calls for each element in the structure, or put all that
> code in one place: writerec.
>
> Is there a better scheme we could be using?

Yes, you're right, netCDF doesn't understand the concept of a
structure.  That constraint was dictated by the necessity to have a
Fortran-77 interface able to read the data written by programs in
other languages such as C.  If a C program wrote a structure into a
netCDF file, what would a Fortran-77 program read it into?  It might
be possible to use a named COMMON block as an approximation to a
structure in Fortran-77, but this turns out not to work very well for
nesting structures.  Instead netCDF just supports scalars and
multidimensional array abstractions.  If you need support for
structures, I recommend considering HDF-5
<http://hdf.ncsa.uiuc.edu/HDF5/>, which uses multidimensional arrays
of structs as its basic data abstraction, but it only has a C
interface.

--Russ

_____________________________________________________________________

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