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

Re: NetCDF library problems



On Wed, 30 Jun 2004, Jason Thaxter wrote:

> One quick question, as I'm wrapping up...
>
> There are two ways I can see to get the values for a variable: one is via
> recget, which is mostly what I use.
>
> Another one is via varget. It *looks* as if I should be able to get the whole
> (possibly 2-dimensional) array with varget.  And for variables that are
> dimensions, I can. e.g., in the attached file, I can get the contents of lat,
> lon, depth, and time. But at the first real "data" variable, current_u, I get:
>
> ncvarget: ncid 3; varid 4: Index exceeds dimension bound
>

Jason,

A problem appeared for me on the varget until i changed the start
and count syntax from \($i, 0, 0, 0) to [ $i, 0, 0, 0 ]. Then everything
started working correctly, ie

NetCDF::varget
            ( $ncid, $current_u_id, [ $i, 0, 0, 0 ], [ 1, 30, 1, 1 ], \@data ) ;

Also, one could:

            @start = ( $i, 0, 0, 0 ) ;
            @count = ( 1, 30, 1, 1 ) ;
            NetCDF::varget
            ( $ncid, $current_u_id, \@start, \@count, \@data ) ;

This looks like a bug in the perl interpreter.

A test script is attached to this message.

Some netCDF documentation is include about varget and a url to all the
netCDF documentation.  The parameters are the same for the netcdf-perl
invocations. Also all the values matched the dump from the test2.nc file
for current_u variable.

Robb...




The varget documentation:

The members of the nc_get_vara_ type family of functions read an array of
values from a netCDF variable of an open netCDF dataset. The array is
specified by giving a corner and a vector of edge lengths. The values are
read into consecutive locations with the last dimension varying fastest.
The netCDF dataset must be in data mode.



Usage

int nc_get_vara_text  (int ncid, int varid, const size_t start[],
                       const size_t count[] char *tp);
int nc_get_vara_uchar (int ncid, int varid, const size_t start[],
                       const size_t count[] unsigned char *up);
int nc_get_vara_schar (int ncid, int varid, const size_t start[],
                       const size_t count[] signed char *cp);
int nc_get_vara_short (int ncid, int varid, const size_t start[],
                       const size_t count[] short *sp);
int nc_get_vara_int   (int ncid, int varid, const size_t start[],
                       const size_t count[] int *ip);
int nc_get_vara_long  (int ncid, int varid, const size_t start[],
                       const size_t count[] long *lp);
int nc_get_vara_float (int ncid, int varid, const size_t start[],
                       const size_t count[] float *fp);
int nc_get_vara_double(int ncid, int varid, const size_t start[],
                       const size_t count[] double *dp);

ncid


NetCDF ID, from a previous call to nc_open or nc_create.

varid


Variable ID.

start


A vector of size_t integers specifying the index in the variable where the
first of the data values will be read. The indices are relative to 0, so
for example, the first data value of a variable would have index (0, 0,
... , 0). The length of start must be the same as the number of dimensions
of the specified variable. The elements of start correspond, in order, to
the variable's dimensions. Hence, if the variable is a record variable,
the first index would correspond to the starting record number for reading
the data values.

count


A vector of size_t integers specifying the edge lengths along each
dimension of the block of data values to be read. To read a single value,
for example, specify count as (1, 1, ... , 1). The length of count is the
number of dimensions of the specified variable. The elements of count
correspond, in order, to the variable's dimensions. Hence, if the variable
is a record variable, the first element of count corresponds to a count of
the number of records to read.

tp, up, cp, sp, ip, lp, fp, or, dp


Pointer to the location into which the data value is read. If the type of
data value differs from the netCDF variable type, type conversion will
occur. See Section 3.3 "Type Conversion," page 20, for details.





http://my.unidata.ucar.edu/content/software/netcdf/guidec/guidec-12.html#HEADING12-0



> I'm not giving a dimension bound; if I were, I'd expect this function to be
> called ncdimget... Am I missing something? Since the script I'm writing apes
> the output of ncdump, I thought I might get somewhere by going through the
> ncdump code, but in fact it calls some function vardata, which appears to step
> through the binary chunks of data on its own, as opposed to using an interface
> into the library such as varget.
>
> Obviously there's something fundamental about NetCDF that I'm not getting
> here, but the nice thing about intefaces is that you usually don't have to
> understand the whole thing. Time to dive in, I guess.
>
> Anyway, if you consider this a blind alley, I can show that via
> NetCDF::recget, I can extract our data, but the variable made of bytes arrays
> comes back with zilch. I can just strip my little demo down to that example
> and send it on...
>
> Thanks,
> Jason
>
> --
> ----------------------------------------------
> Jason Thaxter
> GoMOOS, P.O. Box 4919, Portland, ME 04112-4919
> Office Location: 1 Canal Plaza, 7th Floor
> Office: 207.773.0423
> Fax:    207.773.8672
> Email:  address@hidden
> ------------www.gomoos.org--------------------
>

===============================================================================
Robb Kambic                                Unidata Program Center
Software Engineer III                      Univ. Corp for Atmospheric Research
address@hidden             WWW: http://www.unidata.ucar.edu/
===============================================================================
#! /usr/local/bin/perl
#
use NetCDF ;
#
$ncfile = "test2.nc" ;

# open or create ncfiles
if( -e $ncfile ) {
        $ncid = NetCDF::open( "$ncfile", WRITE ) ;
        return 0 if( $ncid == -1 ) ;
        $time_id = NetCDF::dimid( $ncid, "time" ) ;
        $name_id =  "xxxxxxxx"  ;
        $recnum =  -1  ;
        # get current value of recnum
        NetCDF::diminq( $ncid, $time_id, $name_id, $recnum ) ;

        # get current_u var data to fill in RECNUM array
        $depth_id = NetCDF::varid( $ncid, "depth" ) ;
        print "depth_id=$depth_id\n\n" ;

        $F = -99999 ;
        @data = (   $F, $F, $F, $F, $F, $F, $F, $F, $F, $F,
                        $F, $F, $F, $F, $F, $F, $F, $F, $F, $F,
                        $F, $F, $F, $F, $F, $F, $F, $F, $F, $F) ;
        NetCDF::varget( $ncid, $depth_id, [ 0 ], [ 30 ], \@data ) ;
        for( $j = 0; $j < 30; $j++ ) {
                print "$data[ $j ] " ;
         }
         print "\n\n" ;


        $time_id = NetCDF::varid( $ncid, "time" ) ;
        print "time_id=$time_id\n\n" ;

        $F = -99999 ;
        for ($i = 0 ; $i < $recnum ; $i++ ) {
            @data = ( $F ) ;
            NetCDF::varget( $ncid, $time_id, [ $i ], [ 1 ], \@data ) ;
            print "$data[ 0 ] " ;
        }
        print "\n\n" ;


        undef( @data ) ;

        $current_u_id = NetCDF::varid( $ncid, "current_u" ) ;
        print "current_u_id=$current_u_id\n\n" ;

        #@dimids = () ;
        #$ndims = 4 ;
        #$natts = 8 ;
        #$name = "XXXXXXXXX" ;
        #NetCDF::varinq($ncid, $current_u_id, $name, NetCDF::FLOAT, $ndims, 
\@dimids, $natts) ;

        #print "dimids=@dimids\n" ;


        $F = -99999 ;
        for ($i = 0 ; $i < $recnum ; $i++ ) {
            @data = (   $F, $F, $F, $F, $F, $F, $F, $F, $F, $F,
                        $F, $F, $F, $F, $F, $F, $F, $F, $F, $F,
                        $F, $F, $F, $F, $F, $F, $F, $F, $F, $F) ;
            @start = ( $i, 0, 0, 0 ) ;
            @count = ( 1, 30, 1, 1 ) ;
            NetCDF::varget
            ( $ncid, $current_u_id, \@start, \@count, \@data ) ;
            #( $ncid, $current_u_id, [ $i, 0, 0, 0 ], [ 1, 30, 1, 1 ], \@data ) 
;
            for( $j = 0; $j < 30; $j++ ) {
                print "$data[ $j ] " ;
            }
            print "\n\n\n" ;
        }
}