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

Re: 19991115: CHARs in NetCDF/Perl (part II)



Steve,

I didn't think your example was what you really wanted to do, so I
modified it.  I would suggest downloading the Unidata decoders package and
take a look at the NetCDF perl decoders. This is not the easiest code to
understand but the decoders are the best examples available. The one with
reading and writing is the Upperair decoder. ua2nc. There isn't any real
documentation available for this package. I guess it's more learn by the
seat of your pants :) I usually make cdl files for the templates nc files
because ncgen works great and one doesn't have to do any coding for
dimensions, etc.  I'm attaching a cdl (sd.cdl) and sd.pl ( your modified
perl script).  I hard coded the location of ncgen and some other vars that
you might want to look at before running sd.pl  I added my example after
yours in the file.

Robb...





On Mon, 15 Nov 1999, Unidata Support wrote:

> 
> ------- Forwarded Message
> 
> >To: address@hidden
> >cc: address@hidden (Steve Diggs),
> >cc: address@hidden
> >From: Steve Diggs <address@hidden>
> >Subject: CHARs in NetCDF/Perl (part II)
> >Organization: .
> >Keywords: 199911160037.RAA03698
> 
> Robb,
> 
> I have written yet another Perl script to encode some dummy data into a
> NetCDF file.  I think that this is what you're talking about, but I'm not
> sure.  My questions have much more to do with explicit examples of how to
> put CHAR data *into* NetCDF files, than to extract data from them.  Please
> let me know if this is correct.  Also, are there explicit official docs
> that talk about this feature of NetCDF/Perl?
> 
> Thanks,
> -sd
> --
> --------------------------------------------------------------------
> Steve Diggs                                   Voice: (858)534-1108
> Scripps Institution of Oceanography           FAX  : (858)534-7383
> WOCE Hydrographic Program Office/STS          EMAIL: address@hidden
> 9500 Gilman Drive                             WWW  : whpo.ucsd.edu
> La Jolla, CA 92093-0214
> --------------------------------------------------------------------
> 
> ------------------>
> 
> #!/usr/local/bin/perl
> 
> # Example program to encode variable length strings into a NetCDF file.
> # S. Diggs (address@hidden) 1999.11.15
> 
> use diagnostics;
> use strict;
> use NetCDF;
> 
> # null padded strings
> my @atmospheric_conditions = (  "cloudy\0", "sunny\0",
>                                 "fog\0",
>                                 "rain\0" );
> 
> my @count_ac = ($#atmospheric_conditions);
> 
> print STDOUT "dimensions of array are @count_ac\n";
> 
> #
> my $ncid  = NetCDF::create("string_example.nc", NetCDF::WRITE);
> my $dimid = NetCDF::dimdef($ncid, 'string_dimension', NetCDF::UNLIMITED);
> #
> NetCDF::attput($ncid, NetCDF::GLOBAL, "STRING_EXAMPLE", NetCDF::CHAR,
>                       "This is an example of string encoding");
> 
> my $varid_ac   = NetCDF::vardef($ncid, 'ATM_COND', NetCDF::CHAR, $dimid);
> ;
> 
> # leaving define mode
> NetCDF::endef($ncid);
> 
> print STDERR "Leaving define mode....\n";
> 
> #put data into netcdf file
> 
> my $i=0;
> my @start = (0);
> my @new_count = (0);  
> 
> foreach my $element (@atmospheric_conditions) {
> 
>       @new_count = (length($element));
>       print STDERR " Variable $i length = @new_count\n\t",
>                       "starting at @start\n\n";
>       NetCDF::varput($ncid, $varid_ac, \@start, \@new_count, 
>               \$element);
>       $i++;
>       #bump the new starting point by adding the old ending point
>       # to where we are now
>       @start = (($new_count[0] + $start[0]));
> }
> 
> NetCDF::close($ncid);
> #done!
> 
>         
> 
> 
> ------- End of Forwarded Message
> 

===============================================================================
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

# Example program to encode variable length strings into a NetCDF file.
# S. Diggs (address@hidden) 1999.11.15

use diagnostics;
#use strict;
use NetCDF;

unlink( "string_example.nc" );

# strings
my @atmospheric_conditions = (  "cloudy", "sunny",
                                "fog",
                                "rain" );

my @count_ac = ($#atmospheric_conditions);

print STDOUT "dimensions of array are @count_ac\n";

#
my $ncid  = NetCDF::create("string_example.nc", NetCDF::WRITE);
#my $dimid = NetCDF::dimdef($ncid, 'recNum', NetCDF::UNLIMITED);
$string_dimension = 80;
my $sD = NetCDF::dimdef($ncid, 'string_dimension', $string_dimension);
#
NetCDF::attput($ncid, NetCDF::GLOBAL, "STRING_EXAMPLE", NetCDF::CHAR,
                        "This is an example of string encoding");

my $varid_ac   = NetCDF::vardef($ncid, 'ATM_COND', NetCDF::CHAR, $sD);
;

# leaving define mode
NetCDF::endef($ncid);

#NetCDF::close($ncid);

#exit(0);

print STDERR "Leaving define mode....\n";

#put data into netcdf file

my $i=0;
my @start = (0);
my @new_count = (80);   
$S80 = "\0" x $string_dimension ;

foreach my $element (@atmospheric_conditions)   {

        #@new_count = (length($element));
        #print STDERR " Variable $i length = @new_count\n\t",
        #               "starting at @start\n\n";
        $element = padstr( $element, $string_dimension);
        NetCDF::varput($ncid, $varid_ac, \@start, \@new_count, 
                \$element);
        $i++;
        #bump the new starting point by adding the old ending point
        # to where we are now
        #@start = (($new_count[0] + $start[0]));
        last;
}

NetCDF::close($ncid);
#done!

# code to demonstrate UNLIMITED records

$cdlfile = "sd.cdl" ;
$ncfile = "sd.nc" ;
$ncgen = "/upc/netcdf/bin/ncgen" ;
system( "$ncgen -o $ncfile $cdlfile" ) ;
$ncid = NetCDF::open( "$ncfile", WRITE ) ; 
$S80 = "\0" x $string_dimension ;
$ii = 0;

foreach my $element (@atmospheric_conditions)   {

        $element = padstr( $element, $string_dimension);
        @dataref = ( \$element );
        #$results = NetCDF::recput($ncid, $ii, [@dataref]);
        $results = NetCDF::recput($ncid, $ii, [(\$element)]);
        print "$results\n" if( $results );
        $ii++;
}

@dataref = ( \$S80 );

for( $record = 0; $record <= 3; $record++ ) {
        $results = NetCDF::recget( $ncid, $record,  \@dataref );
        print "$results\n" if( $results );
        $ac = ${$dataref[ 0 ]} ;
        print "record = $record , $ac\n" ;
}
NetCDF::close($ncid);
        
# pad str to correct length
sub padstr
{
( $str, $len ) = @_ ;

my( $size, $i ) ;

$size = length( $str ) ;

for( $i = $size; $i < $len; $i++ ) {
        $str .= "\0" ;
        #print "$str,\n" ;
}
if( $size > $len ) {
        print STDOUT "String length is over $len chars long:\n $str\n" ;
        $str = substr( $str, 0, $len ) ;
        #exit 0 ;
}
return $str ;
}
netcdf string_example {
dimensions:
        recNum = UNLIMITED ; // (0 currently)
        string_dimension = 80 ;
variables:
        char ATM_COND(recNum, string_dimension) ;

// global attributes:
                :STRING_EXAMPLE = "This is an example of string encoding" ;
}