.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "NetCDF 3pm" .TH NetCDF 3pm "2020-11-19" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" PDL::NetCDF \- Object\-oriented interface between NetCDF files and PDL objects. .PP Perl extension to allow interface to NetCDF portable binary gridded files via PDL objects. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& use PDL; \& use PDL::NetCDF; \& use PDL::Char; \& \& my $ncobj = PDL::NetCDF\->new ("test.nc", {REVERSE_DIMS => 1}); # New file \& my $pdl = pdl [[1, 2, 3], [4, 5, 6]]; \& \& # Specify variable name to put PDL in, plus names of the dimensions. Dimension \& # lengths are taken from the PDL, in this case, dim1 = 2 and dim2 = 3. \& $ncobj\->put (\*(Aqvar1\*(Aq, [\*(Aqdim1\*(Aq, \*(Aqdim2\*(Aq], $pdl); \& # or for netcdf4 files \& # $ncobj\->put (\*(Aqvar1\*(Aq, [\*(Aqdim1\*(Aq, \*(Aqdim2\*(Aq], $pdl, {DEFLATE => 9}); \& \& # get the deflate level (for any fileformat) \& my ($deflate, $shuffle) = $ncobj\->getDeflateShuffle(\*(Aqvar1\*(Aq); \& \& # $pdlout = [[1, 2, 3], [4, 5, 6]] \& my $pdlout = $ncobj\->get (\*(Aqvar1\*(Aq); \& \& # Store textual NetCDF arrays using perl strings: (This is a bit primitive, but works) \& my $str = "Station1 Station2 Station3 "; \& $obj\->puttext(\*(Aqtextvar\*(Aq, [\*(Aqn_station\*(Aq, \*(Aqn_string\*(Aq], [3,10], $str); \& my $outstr = $obj\->gettext(\*(Aqtextvar\*(Aq); \& # $outstr = "Station1 Station2 Station3 " \& \& \& # Now textual NetCDF arrays can be stored with PDL::Char style PDLs. This is much \& # more natural and flexible than the above method. \& $str = PDL::Char\->new ([\*(AqStation1\*(Aq, \*(AqStation2\*(Aq, \*(AqStation3\*(Aq]); \& $obj\->put (\*(Aqstations\*(Aq, [\*(Aqdim_station\*(Aq, \*(Aqdim_charlen\*(Aq], $str); \& $outstr = $obj\->get(\*(Aqstations\*(Aq); \& print $outstr; \& # Prints: [\*(AqStation1\*(Aq, \*(AqStation2\*(Aq, \*(AqStation3\*(Aq] \& # For more info on PDL::Char variables see PDL::Char(3), or perldoc PDL::Char \& \& # $dim1size = 2 \& my $dim1size = $ncobj\->dimsize(\*(Aqdim1\*(Aq); \& \& # A slice of the netCDF variable. \& # [0,0] is the starting point, [1,2] is the count. \& # $slice = [1,2] \& my $slice = $ncobj\->get (\*(Aqvar1\*(Aq, [0,0], [1,2]); \& \& # Attach a double attribute of size 3 to var1 \& $ncobj\->putatt (double([1,2,3]), \*(Aqdouble_attribute\*(Aq, \*(Aqvar1\*(Aq); \& \& # $attr1 = [1,2,3] \& my $attr1 = $ncobj\->getatt (\*(Aqdouble_attribute\*(Aq, \*(Aqvar1\*(Aq); \& \& # $type = PDL::double \& my $type = $ncobj\->getvariabletype(\*(Aqvar1\*(Aq); \& \& # Write a textual, global attribute. \*(Aqattr_name\*(Aq is the attribute name. \& $ncobj\->putatt (\*(AqThe text of the global attribute\*(Aq, \*(Aqattr_name\*(Aq); \& \& # $attr2 = \*(AqThe text of the global attribute\*(Aq \& my $attr2 = $ncobj\->getatt (\*(Aqattr_name\*(Aq); \& \& # Close the netCDF file. The file is also automatically closed in a DESTROY block \& # when it passes out of scope. This just makes is explicit. \& $ncobj\->close; .Ve .PP For (much) more information on NetCDF, see .PP http://www.unidata.ucar.edu/packages/netcdf/index.html .PP Also see the test file, test.pl in this distribution for some working examples. .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is the \s-1PDL\s0 interface to the Unidata NetCDF library. It uses the netCDF version 3 library to make a subset of netCDF functionality available to \s-1PDL\s0 users in a clean, object-oriented interface. .PP Another NetCDF perl interface, which allows access to the entire range of netCDF functionality (but in a non-object-oriented style which uses perl arrays instead of PDLs) is available through Unidata at http://www.unidata.ucar.edu/packages/netcdf/index.html). .PP The NetCDF standard allows N\-dimensional binary data to be efficiently stored, annotated and exchanged between many platforms. .PP When one creates a new netCDF object, this object is associated with one netCDF file. .SH "FUNCTIONS" .IX Header "FUNCTIONS" .SS "isNetcdf4" .IX Subsection "isNetcdf4" Check if compiled against netcdf4 .PP Arguments: none .PP .Vb 3 \& if (PDL::NetCDF::isNetcdf4) { \& # open netcdf4 file \& } .Ve .SS "defaultFormat" .IX Subsection "defaultFormat" Get or change the default format when creating a netcdf-file. This can be overwritten by the \s-1NC_FORMAT\s0 option for new. Possible values are: PDL::NetCDF::NC_FORMAT_CLASSIC, PDL::NetCDF::NC_FORMAT_64BIT, PDL::NetCDF::NC_FORMAT_NETCDF4, PDL::NetCDF::NC_FORMAT_NETCDF4_CLASSIC .PP .Vb 4 \& Arguments: \& 1) new format (constant) \& Return: \& old format as one of the NC_FORMAT_* constants .Ve .SS "new" .IX Subsection "new" Create an object representing a netCDF file. .PP .Vb 10 \& Arguments: \& 1) The name of the file. \& 2) optional: A hashref containing options. Currently defined are: \& TEMPLATE: \& An existing netCDF object for a file with \& identical layout. This allows one to read in many similar netCDF \& files without incurring the overhead of reading in all variable \& and dimension names and IDs each time. Caution: Undefined \& weirdness may occur if you pass the netCDF object from a dissimilar \& file! \& MODE: \& use sysopen file\-opening arguments, O_RDONLY, O_RDWR, O_CREAT, O_EXCL \& when used, this will overwrite the \*(Aq>file.nc\*(Aq type of opening \& see L for usage of O_RDONLY... \& REVERSE_DIMS: \& this will turn the order of the dimension\-names of \& netcdf\-files. Even with this option the \*(Aqput\*(Aq function will write \& variables in FORTRAN order (as before) and will reverse the \& dimension names so they fit this order. With this option, the \& \*(Aqputslice\*(Aq function will write variables in the same way as \*(Aqput\*(Aq. \& You should use this option if your planning to work with other \& netcdf\-programs (ncview, NCL) or if you are planning to combine \& putslice and slice. You should _not_ use this option, if you need \& compatibility to older versions of PDL::NetCDF. \& NC_FORMAT: \& set the file format for a new netcdf file, see defaultFormat() \& SLOW_CHAR_FETCH: \& If this option is set, then a \*(Aqget\*(Aq into a PDL::Char will be done \& one string at a time instead of all text data at once. This \& is necessary if there are NULLs (hex 0) values embedded in the string \& arrays. This takes longer, but gives the correct results. If \& the fetch of a string array yields only the first element, try setting \& this option. .Ve .PP Example: .PP .Vb 6 \& my $nc = PDL::NetCDF\->new ("file1.nc", {REVERSE_DIMS => 1}); \& ... \& foreach my $ncfile (@a_bunch_of_similar_format_netcdf_files) { \& $nc = PDL::NetCDF\->new("file2.nc", {TEMPLATE => $nc}); # These calls to \*(Aqnew\*(Aq are *much* faster \& ... \& } \& \& # opening using MODE \& use Fcntl; # define O_CREAT... \& # opening a completely new file (deleting if it exists!) \& my $newnc = PDL::NetCDF\->new ("file2.nc", {MODE => O_CREAT|O_RDWR, \& REVERSE_DIMS => 1, NC_FORMAT => PDL::NetCDF::NC_FORMAT_NETCDF4}); \& # opening existing file for reading and writing \& $nc = PDL::NetCDF\->new ("file2.nc", {MODE => O_RDWR} \& REVERSE_DIMS => 1}); \& # opening existing file for reading only \& $nc = PDL::NetCDF\->new ("file2.nc", {MODE => O_RDONLY, \& REVERSE_DIMS => 1}); .Ve .PP If this file exists and you want to write to it, prepend the name with the '>' character: \*(L">name.nc\*(R" .PP Returns: The netCDF object. Barfs if there is an error. .SS "getFormat" .IX Subsection "getFormat" Get the format of a netcdf file .PP Arguments: none .PP Returns: @ integer equal to one of the PDL::NetCDF::NC_FORMAT_* constants. .SS "put" .IX Subsection "put" Put a \s-1PDL\s0 matrix to a netCDF variable. .PP Arguments: .PP 1) The name of the variable to create .PP 2) A reference to a list of dimension names for this variable .PP 3) The \s-1PDL\s0 to put. It must have the same number of dimensions as specified in the dimension name list. .PP 4) Optional options hashref: {\s-1SHUFFLE\s0 => 1, \s-1DEFLATE\s0 => 7, \s-1COMPRESS\s0 => 0} .PP Returns: None. .PP .Vb 1 \& my $pdl = pdl [[1, 2, 3], [4, 5, 6]]; \& \& # Specify variable name to put PDL in, plus names of the dimensions. Dimension \& # lengths are taken from the PDL, in this case, dim1 = 2 and dim2 = 3. \& $ncobj\->put (\*(Aqvar1\*(Aq, [\*(Aqdim1\*(Aq, \*(Aqdim2\*(Aq], $pdl); \& \& # Now textual NetCDF arrays can be stored with PDL::Char style PDLs. \& $str = PDL::Char\->new ([\*(AqStation1\*(Aq, \*(AqStation2\*(Aq, \*(AqStation3\*(Aq]); \& $obj\->put (\*(Aqstations\*(Aq, [\*(Aqdim_station\*(Aq, \*(Aqdim_charlen\*(Aq], $str); \& $outstr = $obj\->get(\*(Aqstations\*(Aq); \& print $outstr; \& # Prints: [\*(AqStation1\*(Aq, \*(AqStation2\*(Aq, \*(AqStation3\*(Aq] \& # For more info on PDL::Char variables see PDL::Char(3), or perldoc PDL::Char .Ve .SS "putslice" .IX Subsection "putslice" Put a \s-1PDL\s0 matrix to a slice of a NetCDF variable .PP Arguments: .PP 1) The name of the variable to create .PP 2) A reference to a list of dimension names for this variable .PP 3) A reference to a list of dimensions for this variable .PP 4) A reference to a list which specifies the N dimensional starting point of the slice. .PP 5) A reference to a list which specifies the N dimensional count of the slice. .PP 6) The \s-1PDL\s0 to put. It must conform to the size specified by the 4th and 5th arguments. The 2nd and 3rd argument are optional if the variable is already defined in the netcdf object. .PP 7) Optional options: {\s-1DEFLATE\s0 => 7, \s-1SHUFFLE\s0 => 0/1} will use gzip compression (level 7) on that variable and shuffle will not/will use the shuffle filter. These options are only valid for netcdf4 files. If you are unsure, test with ($nc\->getFormat >= PDL::NetCDF::NC_FORMAT::NC_FORMAT_NETCDF4) .PP Returns: None. .PP .Vb 1 \& my $pdl = pdl [[1, 2, 3], [4, 5, 6]]; \& \& # Specify variable name to put PDL in, plus names of the dimensions. Dimension \& # lengths are taken from the PDL, in this case, dim1 = 2 and dim2 = 3. \& $ncobj\->putslice (\*(Aqvar1\*(Aq, [\*(Aqdim1\*(Aq, \*(Aqdim2\*(Aq, \*(Aqdim3\*(Aq], [2,3,3], [0,0,0], [2,3,1], $pdl); \& $ncobj\->putslice (\*(Aqvar1\*(Aq, [], [], [0,0,2], [2,3,1], $pdl); \& \& my $pdl2 = $ncobj\->get(\*(Aqvar1\*(Aq); \& \& print $pdl2; \& \& [ \& [ \& [ 1 9.96921e+36 1] \& [ 2 9.96921e+36 2] \& [ 3 9.96921e+36 3] \& ] \& [ \& [ 4 9.96921e+36 4] \& [ 5 9.96921e+36 5] \& [ 6 9.96921e+36 6] \& ] \&] \& \& note that the netcdf missing value (not 0) is filled in. .Ve .SS "sync" .IX Subsection "sync" Synchronize the data to the disk. Use this if you want to read the file from another process without closing the file. This makes only sense after put, puttext, putslice, putatt operations .PP Returns: nothing. Barfs on error. .PP .Vb 1 \& $ncobj\->sync .Ve .SS "get" .IX Subsection "get" Get a \s-1PDL\s0 matrix from a netCDF variable. .PP Arguments: .PP 1) The name of the netCDF variable to fetch. If this is the only argument, then the entire variable will be returned. .PP To fetch a slice of the netCDF variable, optional 2nd and 3rd arguments must be specified: .PP 2) A pdl which specifies the N dimensional starting point of the slice. .PP 3) A pdl which specifies the N dimensional count of the slice. .PP Also, an options hashref may be passed. The only option currently is '\s-1NOCOMPRESS\s0' which tells PDL::NetCDF to *not* try to uncompress an compressed variable. See the \s-1COMPRESS\s0 option on 'put' and 'putslice' for more info. .PP Returns: The \s-1PDL\s0 representing the netCDF variable. Barfs on error. .PP .Vb 3 \& # A slice of the netCDF variable. \& # [0,0] is the starting point, [1,2] is the count. \& my $slice = $ncobj\->get (\*(Aqvar1\*(Aq, [0,0], [1,2], {NOCOMPRESS => 1}); \& \& # If var1 contains this: [[1, 2, 3], [4, 5, 6]] \& # Then $slice contains: [1,2] (Size \*(Aq1\*(Aq dimensions are eliminated). .Ve .SS "putatt" .IX Subsection "putatt" putatt \*(-- Attach a numerical or textual attribute to a NetCDF variable or the entire file. .PP Arguments: .PP 1) The attribute. Either: A one dimensional \s-1PDL\s0 (perhaps contining only one number) or a string. .PP 2) The name to give the attribute in the netCDF file. Many attribute names have pre-defined meanings. See the netCDF documentation for more details. .PP 3) Optionally, you may specify the name of the pre-defined netCDF variable to associate this attribute with. If this is left off, the attribute is a global one, pertaining to the entire netCDF file. .PP Returns: Nothing. Barfs on error. .PP .Vb 2 \& # Attach a double attribute of size 3 to var1 \& $ncobj\->putatt (double([1,2,3]), \*(Aqdouble_attribute\*(Aq, \*(Aqvar1\*(Aq); \& \& # Write a textual, global attribute. \*(Aqattr_name\*(Aq is the attribute name. \& $ncobj\->putatt (\*(AqThe text of the global attribute\*(Aq, \*(Aqattr_name\*(Aq); .Ve .SS "getatt" .IX Subsection "getatt" Get an attribute from a netCDF object. .PP Arguments: .PP 1) The name of the attribute (a text string). .PP 2) The name of the variable this attribute is attached to. If this argument is not specified, this function returns a global attribute of the input name. .PP .Vb 2 \& # Get a global attribute \& my $attr2 = $ncobj\->getatt (\*(Aqattr_name\*(Aq); \& \& # Get an attribute associated with the variable \*(Aqvar1\*(Aq \& my $attr1 = $ncobj\->getatt (\*(Aqdouble_attribute\*(Aq, \*(Aqvar1\*(Aq); .Ve .SS "getDeflateShuffle" .IX Subsection "getDeflateShuffle" Get the deflate level and the shuffle flag for a variable. .PP Can be called on all files, although only netcdf4 files support shuffle and deflate. .PP Arguments: .PP 1) The name of the variable. .PP Returns: .PP ($deflate, \f(CW$shuffle\fR) .PP .Vb 1 \& my ($deflate, $shuffle) = $nc\->getDeflateShuffle(\*(AqvarName\*(Aq); .Ve .SS "getvariabletype" .IX Subsection "getvariabletype" Get a type of a variable from a netCDF object. .PP Arguments: .PP 1) The name of the variable. .PP Returns: PDL::type or undef, when variable not defined .PP .Vb 2 \& # Get a type \& my $type = $ncobj\->getvariabletype (\*(Aqvar1\*(Aq); .Ve .SS "puttext" .IX Subsection "puttext" Put a perl text string into a multi-dimensional NetCDF array. .PP Arguments: .PP 1) The name of the variable to be created (a text string). .PP 2) A reference to a perl list of dimension names to use in creating this NetCDF array. .PP 3) A reference to a perl list of dimension lengths. .PP 4) A perl string to put into the netCDF array. If the NetCDF array is 3 x 10, then the string must have 30 charactars. .PP 5) Optional nc4 options: {\s-1DEFLATE\s0 => 7, \s-1SHUFFLE\s0 => 0} .PP .Vb 2 \& my $str = "Station1 Station2 Station3 "; \& $obj\->puttext(\*(Aqtextvar\*(Aq, [\*(Aqn_station\*(Aq, \*(Aqn_string\*(Aq], [3,10], $str); .Ve .SS "gettext" .IX Subsection "gettext" Get a multi-dimensional NetCDF array into a perl string. .PP Arguments: .PP 1) The name of the NetCDF variable. .PP .Vb 1 \& my $outstr = $obj\->gettext(\*(Aqtextvar\*(Aq); .Ve .SS "dimsize" .IX Subsection "dimsize" Get the size of a dimension from a netCDF object. .PP Arguments: .PP 1) The name of the dimension. .PP Returns: The size of the dimension. .PP .Vb 1 \& my $dim1size = $ncobj\->dimsize(\*(Aqdim1\*(Aq); .Ve .SS "close" .IX Subsection "close" Close a NetCDF object, writing out the file. .PP Arguments: None .PP Returns: Nothing .PP This closing of the netCDF file can be done explicitly though the \&'close' method. Alternatively, a \s-1DESTROY\s0 block does an automatic close whenever the netCDF object passes out of scope. .PP .Vb 1 \& $ncobj\->close(); .Ve .SS "getdimensionnames ([$varname])" .IX Subsection "getdimensionnames ([$varname])" Get all the dimension names from an open NetCDF object. If a variable name is specified, just return dimension names for *that* variable. .PP Arguments: none .PP Returns: An array reference of dimension names .PP .Vb 4 \& my $varlist = $ncobj\->getdimensionnames(); \& foreach(@$varlist){ \& print "Found dim $_\en"; \& } .Ve .SS "getattributenames" .IX Subsection "getattributenames" Get the attribute names for a given variable from an open NetCDF object. .PP Arguments: Optional variable name, with no arguments it will return the objects global netcdf attributes. .PP Returns: An array reference of attribute names .PP .Vb 1 \& my $attlist = $ncobj\->getattributenames(\*(Aqvar1\*(Aq); .Ve .SS "getvariablenames" .IX Subsection "getvariablenames" Get all the variable names for an open NetCDF object. .PP Arguments: none. .PP Returns: An array reference of variable names .PP .Vb 1 \& my $varlist = $ncobj\->getvariablenames(); .Ve .SS "setrec" .IX Subsection "setrec" Set up a 'record' of several 1D netCDF variables with the same dimension. Once this is set up, quick reading/writing of one element from all variables can be put/get from/to a perl list. .PP Arguments: .PP .Vb 1 \& 1) The names of all the netCDF variables to group into a record .Ve .PP Returns: A record name to use in future putrec/getrec calls .PP .Vb 1 \& my $rec = $ncobj\->setrec(\*(Aqvar1\*(Aq, \*(Aqvar2\*(Aq, \*(Aqvar3\*(Aq); .Ve .SS "getrec" .IX Subsection "getrec" Gets a 'record' (one value from each of several 1D netCDF variables) previously set up using 'setrec'. These values are returned in a perl list. .PP Arguments: .PP .Vb 2 \& 1) The name of the record set up in \*(Aqsetrec\*(Aq. \& 2) The index to fetch. .Ve .PP Returns: A perl list of all values. Note that these variables can be of different types: float, double, integer, string. .PP .Vb 1 \& my @rec = $ncobj\->getrec($rec, 5); .Ve .SS "putrec" .IX Subsection "putrec" Puts a 'record' (one value from each of several 1D netCDF variables) previously set up using 'setrec'. These values are supplied as a perl list reference. .PP Arguments: .PP .Vb 3 \& 1) The name of the record set up in \*(Aqsetrec\*(Aq. \& 2) The index to set. \& 3) A perl list ref containing the values. .Ve .PP Returns: None. .PP .Vb 1 \& $ncobj\->putrec($rec, 5, \e@values); .Ve .SH "WRITING NetCDF-FILES EFFICIENTLY" .IX Header "WRITING NetCDF-FILES EFFICIENTLY" Writing several variables to NetCDF-files can take a long time. When a new variable is attached by \f(CW\*(C`put\*(C'\fR to a file, the attribute header has to be written. This might force the internal netcdf-library to restructure the complete file, and thus might take very much IO-resources. By pre-defining the dimensions, attributes, and variables, much time can be saved. Essentially the rule of thumb is to define and write the data in the order it will be laid out in the file. Talking PDL::NetCDF, this means the following: .IP "Open the netcdf file" 4 .IX Item "Open the netcdf file" .Vb 2 \& my $nc = new PDL::NetCDF(\*(Aqtest.nc\*(Aq, {MODE => O_CREAT|O_RDWR, \& REVERSE_DIMS => 1}); .Ve .IP "Write the global attributes" 4 .IX Item "Write the global attributes" .Vb 1 \& $nc\->putatt (double([1,2,3]), \*(Aqdouble_attribute\*(Aq); .Ve .IP "Define all variables, make use of the \s-1NC_UNLIMITED\s0 dimension" 4 .IX Item "Define all variables, make use of the NC_UNLIMITED dimension" .Vb 8 \& # here it is possible to choose float/double/short/long \& $pdl_init = long ([]); \& for (my $i=0; $i<$it; $i++) { \& my $out2 = $nc\->putslice("VAR$i", \& [\*(Aqx\*(Aq,\*(Aqy\*(Aq,\*(Aqz\*(Aq,\*(Aqt\*(Aq], \& [150,100,20,PDL::NetCDF::NC_UNLIMITED()], \& [0,0,0,0],[1,0,0,0],$pdl_init); \& } .Ve .IP "Write the variable-attributes" 4 .IX Item "Write the variable-attributes" .Vb 1 \& $nc\->putatt ("var\-attr", \*(Aqattribute\*(Aq, \*(AqVAR0\*(Aq); .Ve .IP "Write data with putslice" 4 .IX Item "Write data with putslice" .Vb 1 \& $nc\->putslice("VAR5",[],[],[0,0,0,0],[$datapdl\->dims],$datapdl); .Ve .SH "AUTHOR" .IX Header "AUTHOR" Doug Hunt, dhunt\e@ucar.edu. .SS "\s-1CONTRIBUTORS\s0" .IX Subsection "CONTRIBUTORS" Heiko Klein, heiko.klein\e@met.no Edward Baudrez, Royal Meteorological Institute of Belgium, edward.baudrez\e@meteo.be .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBperl\fR\|(1), \s-1\fBPDL\s0\fR\|(1), \fBnetcdf\fR\|(3).