[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 20000512: Help
- Subject: Re: 20000512: Help
- Date: Mon, 15 May 2000 08:23:16 -0600
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