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

Re: 971110: Netcdf-3.3.1 gives 4 byte ncShort?



>From: "Carolyn L. Harris" <address@hidden>
>Subject: Netcdf-3.3.1 gives 4 byte ncShort?
>Organization: UCSD
>Keywords: 199711102126.OAA00321 netCDF 3.3 ncShort
>
>
> Hi,
>
> I'm using the C++ interface to NetCDF version 3.3.1 on a DEC Alpha and
> a Sun Solaris machine.  On both machines, I find that a ncShort takes
> 4 bytes of storage instead of 2.  Yet the documentation I read (e.g.,
> http://www.unidata.ucar.edu/cgi-bin/mfs/04/guide_9.html?161#mfs)
> says that ncShort should be 16 bits, or 2 bytes.
>
> Included below is a test program which creates a NetCDF file
> containing 20 ncShorts.  My resulting datafile is 80 bytes long.  Am I
> doing something stupid to end up with 80 bytes instead of 40?
> I'd really like to have 2 byte integer storage.
>
> Thanks,
> Lyn Harris
>
> ************************************************************************
> Lyn Harris                                      address@hidden
> SIO/UCSD Mail Code 0230                         address@hidden
> 9500 Gilman Drive                           fax (619) 534-0704
> La Jolla, CA 92093-0230                   voice (619) 534-5996
>                                          http://chowder.ucsd.edu/~lyn
> ************************************************************************
>
> // CC a.cc -I/usr/local/include -L/usr/local/lib -lnetcdf_c++ -lnetcdf
> // cxx a.cc -I/usr/local/include -L/usr/local/lib -lnetcdf_c++ -lnetcdf
>
> #include <stdio.h>
> #include <stdlib.h>
> #include "netcdf.hh"
>
> NcFile *ncfile;
>
> int main()
> {
>   int t0[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
>
>     NcFile ofile = NcFile("jnk.nc", NcFile::Replace);
>     ncfile = &ofile;
>     if (!ncfile->is_valid()){
>       cerr << "invalid ofile\n";
>       return(1);
>     }
>
>     NcDim* tdim = ncfile->add_dim("time");
>     NcVar* tvar = ncfile->add_var("time", ncShort, tdim);
>
>     tvar->put(t0, 10);
>     tvar->set_cur(10);
>     tvar->put(t0, 10);
>
>     ncfile->~NcFile();
> }
>
> //.................................................................
> //.................................................................

Lyn:

It appears that you have a couple of misunderstandings.

First off, the example program above creates an _empty_ netcdf
file. The calls to tvar->put() fail because the type of t0
does not match the nc_type of tvar. Although the netcdf-3 C interface
performs conversions automatically, the C++ interface method you
are using does not. (The C++ interface is still layered on the old C
interface.) If you had checked the return of tvar->put(),
you would have noticed this.

        if(!tvar->put(t0, 10))
                cerr << "put failed\n";

You can fix the problem easily in your example by declaring t0
to be of type 'short'.

The second misunderstanding is that the netcdf file will be of size
exactly n * size_of_external_short. You are forgetting about the header.
In general, it's hard for you to know exactly how big the header will be.
(See Appendix A of the documentation.)
For your example, the header is 80 bytes (the size of the empty file
you created). As you put data, the size of your file will grow as
size = 80 + (n + 1) * 2; where n is the number of shorts you write.

By the way, you don't need to explictly call the destructor, it gets
called automatically when ofile goes out of scope. As a matter of style,
you may wish to call close explictly.

-glenn

====== Corrected example ====
#include <stdio.h>
#include <stdlib.h>
#include "netcdf.hh"

NcFile *ncfile;

int main()
{
  int t0[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    NcFile ofile = NcFile("jnk.nc", NcFile::Replace);
    ncfile = &ofile;
    if (!ncfile->is_valid()){
      cerr << "invalid ofile\n";
      return(1);
    }

    NcDim* tdim = ncfile->add_dim("time");
    NcVar* tvar = ncfile->add_var("time", ncShort, tdim);

    if(!tvar->put(t0, 10))
        cerr << "put failed\n";
    if(!tvar->set_cur(10))
        cerr << "set_cur failed\n";
    if(!tvar->put(t0, 10))
        cerr << "2nd put failed\n";

    ncfile->close();
}