Recipe: C program to read data from downloaded file

From GEOS-5
Revision as of 13:30, 30 October 2014 by Pchakrab (talk | contribs) (See Also)
Jump to navigation Jump to search

Back to G5NR Data Access Guide.

Problem

We want to read a downloaded data file using C.

Solution

For the purpose of this example, we assume that the file c1440_NR.inst01hr_3d_T_Cv.20060918_0900z.nc4 has already been downloaded from the ftp server. For more information about file naming conventions, and how to download a file from the ftp server, please follow the links in the #See Also section. Here we use the NetCDF-4 library to read the downloaded file (since NetCDF-4 uses HDF-5 as the underlying data format, HDF-5 library can also be used directly). First, we ensure that out NetCDF-4 library has been built with HDF5 support. If the query

> nc-config --has-hdf5

returns "yes", we have a compatible NetCDF-4 library. Here nc-config is a utility bundled with NetCDF-4 package.

Code

#include<stdio.h>
#include<stdlib.h>
#include<netcdf.h>  // for reading NR files

/* Handle errors by printing an error message and exiting with a
 * non-zero status. */
#define ERRCODE 2
#define ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);}

int main(void){

  // file name
  char* T_file = NULL;

  // store temperature data in T
  float *T = NULL;

  // miscellaneous
  int rc, ctr;
  int im, jm, lm;
  int ncid, varid;

  // file name and dimensions
  T_file = "c1440_NR.inst01hr_3d_T_Cv.20060918_0900z.nc4";

  // netCDF ID for the file and data variable
  im = 720; // lon
  jm = 361; // lat
  lm = 72;  // lev

  // open file and get var id
  if (rc = nc_open(T_file, NC_NOWRITE, &ncid)) ERR(rc);
  if (rc = nc_inq_varid(ncid, "T", &varid)) ERR(rc);

  // read global temperature data
  int asyz = 1*lm*jm*im;
  T = malloc(asyz*sizeof(float));
  size_t start[4] = {0, 0, 0, 0};
  size_t count[4] = {1, lm, jm, im}; // 1 time step, 3D (lev, lat, lon) array
  printf("Reading T..."); fflush(stdout);
  if (rc = nc_get_vara_float(ncid, varid, start, count, T)) ERR(rc);
  printf("done.\n"); fflush(stdout);

  // min/max of T
  float minval, maxval;
  minval = 1.0e15;
  maxval = -1.0e15;
  for (ctr=0; ctr<asyz; ctr++){
    if (T[ctr]<minval){
      minval = T[ctr];
    }
    if (T[ctr]>maxval){
      maxval = T[ctr];
    }
  }
  printf("min(T): %f\n", minval);
  printf("max(T): %f\n", maxval);

  // free memory
  free(T);

  return 0;
}

Compile and link

We use the utility nc-config (included in the NetCDF-4 installation) to identify the linking rules.

For a typical NetCDF-4 installation, the above code, g5nr_reader_global.c can be compiled and linked to to the NetCDF-f library via

gcc -o g5nr_reader_global.x `nc-config --cflags` g5nr_reader_global.c `nc-config --libs`

creating the executable g5nr_reader_global.x

NOTE:

  1. We can use our favorite C compiler instead of gcc
  2. If the NetCDF-4 library was built with parallel I/O support, we will need to use <mpicc> to link, even if our code does not use the MPI library.

Run

Running the executable

> ./g5nr_reader_global.x

produces the output

Reading T...done.
min(T): 180.366745
max(T): 315.651245

Discussions

See Also

  1. File Spec: File:G5NR-Ganymed-7km FileSpec-ON6-V1.0.pdf
  2. Recipe: Retrieve (global) data from FTP server
  3. Recipe: C program as OPeNDAP client

No Warranty

Copyright