NetCDF table

From oldwiki.scinet.utoronto.ca
Jump to navigation Jump to search

Storing tables in NetCDF4

Writting a table using Python

The following example shows how to store a table of 10 records with 8 members :

name ADCcount grid_i grid_j pressure energy idnumber pressure2
16-character String Unsigned short integer 32-bit integer 32-bit integer float (single-precision) double (double-precision) Signed 64-bit integer 2-dim table of float (2*3)

The script has been run on gpc with the following modules :

module load gcc/4.8.1 hdf5/187-v18-serial-gcc netcdf/4.1.3_hdf5_serial-gcc intel/14.0.0 python/2.7.2
from netCDF4 import Dataset
from netCDF4 import chartostring, stringtoarr
import numpy

f = Dataset('particles.nc','w',format='NETCDF4')

size = 10

Particle = numpy.dtype([('name', 'S1', 16),                       # 16-character String                                                
                        ('ADCcount',numpy.uint16),                # Unsigned short integer                                             
                        ('grid_i',numpy.int32),                   # 32-bit integer                                                     
                        ('grid_j',numpy.int32),                   # 32-bit integer                                                     
                        ('pressure',numpy.float32),               # float  (single-precision)                                          
                        ('energy',numpy.float64),                 # double (double-precision)                                          
                        ('idnumber',numpy.int64),                 # Signed 64-bit integer                                              
                        ('pressure2' , numpy.float32 , (2,3) )    # array of floats (single-precision) table 2 lines * 3 columns       
                        ])

Particle_t = f.createCompoundType(Particle,'Particle')

f.createDimension('NRecords',None)
v = f.createVariable('Data',Particle_t,'NRecords')
data = numpy.empty(size,Particle)

for i in xrange(10):
    data['name'][i] = stringtoarr('Particle: %6d' % (i),16)
    data['ADCcount'][i] = (i * 256) % (1 << 16)
    data['grid_i'][i] = i
    data['grid_j'][i] = 10 - i
    data['pressure'][i] = float(i*i)
    data['energy'][i] = float(data['pressure'][i] ** 4)
    data['idnumber'][i] = i * (2 ** 34)
    data['pressure2'][i] = [
        [0.5+float(i),1.5+float(i),2.5+float(i)],
        [-1.5+float(i),-2.5+float(i),-3.5+float(i)]]
#Fill data in File                                                                                                                     
v[:] = data

f.close()

Reading the table with a C++ code

The code has been compiled and tested on GPC with the following modules :

module load gcc/4.8.1 hdf5/187-v18-serial-gcc netcdf/4.1.3_hdf5_serial-gcc intel/14.0.0 python/2.7.2
gcc -I$SCINET_NETCDF_INC Test.cpp -o Test -lnetcdf_c++

Test.cpp :

#include <iostream>
#include <netcdfcpp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

using namespace std;

#define FILE_NAME "particles.nc"
#define DIM_LEN 10 //number of records in file 
int main(void)
{
  typedef struct Particle
  {
    char   name[16];
    unsigned short int    ADCcount;
    int grid_i;
    int grid_j;
    float pressure;
    double energy ;
    long  idnumber;
    float pressure2[2][3];
  } Particle;
  Particle data_in[DIM_LEN];
  for (int i=0; i<DIM_LEN; i++){
    data_in[i].ADCcount=0;
    data_in[i].grid_i=0;
    data_in[i].grid_j=0;
    data_in[i].pressure=0.;
    data_in[i].energy=0.;
    for (int j=0; j<2; j++){
      for (int k=0; k<3; k++){
        data_in[i].pressure2[j][k]=0.;
      }
    }
  }
  int ncid, typeidd, varid;
  int dimid;
  int dimids[] = {0}, fieldid;

  nc_def_dim(ncid, "NRecords", DIM_LEN, &dimid);
  nc_def_var(ncid, "Data", typeidd, 1, dimids, &varid);

  //Open the NetCDF file :
  if (nc_open(FILE_NAME, NC_WRITE, &ncid)) cout<<"ERROR"<<endl;
  //Read the data and fill the variable data_in :
  if (nc_get_var(ncid, varid, data_in)) cout<<"ERROR"<<endl;

  for (int i=0; i<DIM_LEN; i++){
    std::cout<<"ADCcount = "<<data_in[i].ADCcount
             <<" ,idnumber = "<<data_in[i].idnumber
             <<" ,grid_i = "<<data_in[i].grid_i
             <<" ,grid_j = "<<data_in[i].grid_j
             <<" ,pressure = "<<data_in[i].pressure
             <<" ,energy = "<<data_in[i].energy
             <<" ,name = "<<data_in[i].name
             <<std::endl;
    for(int j=0;j<2;j++){
      std::cout<<data_in[i].pressure2[j][0]<<" "<<data_in[i].pressure2[j][1]<<" "<<data_in[i].pressure2[j][2]<<std::endl;
    }
  }
cout << "*** SUCCESS reading example file "<<FILE_NAME<<"!" << endl;
  return 0;
}