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

Re: 20000512: Help



Oops, forgot to CC: support-netcdf ...

------- Forwarded Message

Date:    Mon, 15 May 2000 08:21:57 -0600
From:    Russ Rew <address@hidden>
To:      address@hidden
cc:      address@hidden
Subject: Re: 20000512: Help 

>To: address@hidden
>cc: address@hidden
>From: address@hidden
>Subject: Help
>Organization: UCAR/Unidata
>Keywords: 200005121304.e4CD41405481, examples

Hi,

> We are evaluating the possibility of using netCDF for our data management.
> We are looking initially to test a simple case. Say a file containing the
> following data in two columns:
> 
> 1    1
> 2    2
> 3    3
> 4    4
> 5    5
> 6    6
> 7    7
> 8    8
> 9    9
> 
> How can we generate the netCDF file that contains the above data? We want
> to import the generated file using a program that can handle the netCDF
> format and check that it produces a straight line when graphed. We
> appreciate your help. Thanks a lot!

There are several ways to do this, since there are netCDF utility
programs such as ncgen that make this easier as well as netCDF
programming interfaces you could use for accomplishing this task in C,
C++, Fortran 77, Fortran 90, Java, perl, Python, MATLAB, or IDL.

 1. Here's an easy way to do it using the "ncgen" program that is built
    and installed as part of the current netCDF source distribution.
    
    First, create a text file containing the CDL version of the netCDF
    data (CDL is a text representation of binary netCDF data), for
    example the following lines of text in a file named "table.cdl":

netcdf table {
dimensions:
        nrows = 9;
variables:
    float x(nrows), y(nrows);
data:
    x = 1, 2, 3, 4, 5, 6, 7, 8, 9;
    y = 1, 2, 3, 4, 5, 6, 7, 8, 9;
}

    Then, run the "ncgen" program using this as input to generate the
    binary netCDF file "table.nc":

     ncgen -b table.cdl

    You can verify that table.nc contains the desired data by running the
    "ncdump" program on it to dump out the data, as follows:
    
     ncdump table.nc

 2. Here's a C program that you could compile, link, and run to
    create a netCDF file like that produced in 1, above.  It includes
    all error checking and is actually also generated by the ncgen
    program, using "ncgen -c table.cdl":

#include <stdio.h>
#include <stdlib.h>
#include <netcdf.h>

void
check_err(const int stat, const int line, const char *file) {
    if (stat != NC_NOERR) {
           (void) fprintf(stderr, "line %d of %s: %s\n", line, file, 
nc_strerror(stat));
        exit(1);
    }
}

int
main() {                        /* create table.nc */

   int  ncid;                   /* netCDF id */

   /* dimension ids */
   int nrows_dim;

   /* dimension lengths */
   size_t nrows_len = 9;

   /* variable ids */
   int x_id;
   int y_id;

   /* rank (number of dimensions) for each variable */
#  define RANK_x 1
#  define RANK_y 1

   /* variable shapes */
   int x_dims[RANK_x];
   int y_dims[RANK_y];

   /* enter define mode */
   int stat = nc_create("table.nc", NC_CLOBBER, &ncid);
   check_err(stat,__LINE__,__FILE__);

   /* define dimensions */
   stat = nc_def_dim(ncid, "nrows", nrows_len, &nrows_dim);
   check_err(stat,__LINE__,__FILE__);

   /* define variables */

   x_dims[0] = nrows_dim;
   stat = nc_def_var(ncid, "x", NC_FLOAT, RANK_x, x_dims, &x_id);
   check_err(stat,__LINE__,__FILE__);

   y_dims[0] = nrows_dim;
   stat = nc_def_var(ncid, "y", NC_FLOAT, RANK_y, y_dims, &y_id);
   check_err(stat,__LINE__,__FILE__);

   /* leave define mode */
   stat = nc_enddef (ncid);
   check_err(stat,__LINE__,__FILE__);

   {                    /* store x */
    static float x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    stat = nc_put_var_float(ncid, x_id, x);
    check_err(stat,__LINE__,__FILE__);
   }

   {                    /* store y */
    static float y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    stat = nc_put_var_float(ncid, y_id, y);
    check_err(stat,__LINE__,__FILE__);
   }
   stat = nc_close(ncid);
   check_err(stat,__LINE__,__FILE__);
   return 0;
}

 3. Similarly, you can generated a Fortran 77 program to do the same
    thing, using "ncgen -f table.cdl".  The C++ interface is somewhat
    simpler:

#include <string.h>
#include "netcdfcpp.h"

#define NUM(array) (sizeof(array)/sizeof(array[0]))

int
main( void )
{
    const char* path = "table.nc";
    NcFile nc (path, NcFile::Replace); // Create and leave in define mode

    // Check if the file was opened
    if (! nc.is_valid()) {
        cerr << "can't create netCDF file " << path << "\n";
        return 0;
    }

    // Create dimensions
    NcDim* nrows = nc.add_dim("nrows", 9);

    // Create variables and their attributes
    NcVar* x = nc.add_var("x", ncFloat, nrows);
    NcVar* y = nc.add_var("y", ncFloat, nrows);

    // Start writing data, implictly leaves define mode
    static float xs[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    x->put(xs, NUM(xs));
    static float ys[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    y->put(ys, NUM(ys));
    
    // close of nc takes place in destructor
}

Similar simple examples could be written in Java, perl, etc.  These
examples don't really demonstrate the strengths of netCDF to represent
multidimensional data, to support text-valued or numeric attributes
that describe the data (for example units, valid range), the use of
the unlimited dimension to permit data to be easily added along one
dimension, and the use of direct access that allows a small subset of
a large dataset to be accessed efficiently.

--Russ

_____________________________________________________________________

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

------- End of Forwarded Message