testcalendar.c File Reference

Test calendar conversion functions. More...

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <libgen.h>
#include <zlib.h>
#include <hdf5.h>
#include <netcdf.h>
#include <utils.h>
Include dependency graph for testcalendar.c:

Go to the source code of this file.

Defines

#define _GNU_SOURCE
 GNU extensions.

Functions

void show_usage (char *pgm)
 C prototypes.
void handle_netcdf_error (int status, int lineno)
int main (int argc, char **argv)
 Main program.

Detailed Description

Test calendar conversion functions.

Definition in file testcalendar.c.


Define Documentation

#define _GNU_SOURCE

GNU extensions.

Definition at line 59 of file testcalendar.c.


Function Documentation

int main ( int  argc,
char **  argv 
)

Main program.

Parameters:
[in] argc Number of command-line arguments.
[in] argv Vector of command-line argument strings.
Returns:
Status.

Read dimensions variables

Read data variable

Adjust calendar

Write data to NetCDF file

Close NetCDF files

Definition at line 104 of file testcalendar.c.

References alloc_error(), banner(), data_to_gregorian_cal_d(), data_to_gregorian_cal_f(), handle_netcdf_error(), and show_usage().

00105 {
00113   int nlat;
00114   int nlon;
00115   int ntime;
00116 
00117   size_t dimval;
00118   int i;
00119 
00120   char *filein = NULL;
00121   char *fileout = NULL;
00122 
00123   int istat, ncinid, ncoutid;
00124   int varinid, timeinid, timediminid, loninid, londiminid, latinid, latdiminid;
00125   int varoutid, timeoutid, timedimoutid, lonoutid, londimoutid, latoutid, latdimoutid;
00126   nc_type vartype_main;
00127   nc_type vartype_time;
00128   int varndims;
00129   int vardimids[NC_MAX_VAR_DIMS];    /* dimension ids */
00130 
00131   size_t start[3];
00132   size_t count[3];
00133 
00134   size_t t_len;
00135   char *time_units = NULL;
00136   char *cal_type = NULL;
00137   char cal_type_out[500];
00138 
00139   char attname[1000];
00140   int natts;
00141   float fillvaluef;
00142   double fillvalued;
00143 
00144   void *psl = NULL;
00145   double *timein = NULL;
00146   double *lat = NULL;
00147   double *lon = NULL;
00148 
00149   double *psloutd = NULL;
00150   float *psloutf = NULL;
00151   double *outtimeval = NULL;
00152   int ntimeout;
00153 
00154   /* Print BEGIN banner */
00155   (void) banner(basename(argv[0]), "1.0", "BEGIN");
00156 
00157   /* Get command-line arguments and set appropriate variables */
00158   for (i=1; i<argc; i++) {
00159     if ( !strcmp(argv[i], "-h") ) {
00160       (void) show_usage(basename(argv[0]));
00161       (void) banner(basename(argv[0]), "OK", "END");
00162       return 0;
00163     }
00164     else if ( !strcmp(argv[i], "-i") ) {
00165       filein = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00166       if (filein == NULL) alloc_error(__FILE__, __LINE__);
00167       (void) strcpy(filein, argv[i]);
00168     }
00169     else if ( !strcmp(argv[i], "-o") ) {
00170       fileout = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00171       if (fileout == NULL) alloc_error(__FILE__, __LINE__);
00172       (void) strcpy(fileout, argv[i]);
00173     }
00174     else {
00175       (void) fprintf(stderr, "%s:: Wrong arg %s.\n\n", basename(argv[0]), argv[i]);
00176       (void) show_usage(basename(argv[0]));
00177       (void) banner(basename(argv[0]), "ABORT", "END");
00178       (void) abort();
00179     }
00180   }
00181 
00182   /* Read data in NetCDF file */
00183   istat = nc_open(filein, NC_NOWRITE, &ncinid);  /* open for reading */
00184   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00185 
00186   istat = nc_inq_dimid(ncinid, "time", &timediminid);  /* get ID for time dimension */
00187   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00188   istat = nc_inq_dimlen(ncinid, timediminid, &dimval); /* get time length */
00189   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00190   ntime = (int) dimval;
00191 
00192   istat = nc_inq_dimid(ncinid, "lat", &latdiminid);  /* get ID for lat dimension */
00193   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00194   istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */
00195   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00196   nlat = (int) dimval;
00197 
00198   istat = nc_inq_dimid(ncinid, "lon", &londiminid);  /* get ID for lon dimension */
00199   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00200   istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */
00201   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00202   nlon = (int) dimval;
00203   
00204   istat = nc_inq_varid(ncinid, "time", &timeinid);  /* get ID for time variable */
00205   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00206   istat = nc_inq_varid(ncinid, "lat", &latinid);  /* get ID for lat variable */
00207   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00208   istat = nc_inq_varid(ncinid, "lon", &loninid);  /* get ID for lon variable */
00209   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00210 
00211   istat = nc_inq_varid(ncinid, "psl", &varinid); /* get psl variable ID */
00212   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00213 
00215   /* Allocate memory and set start and count */
00216   start[0] = 0;
00217   count[0] = (size_t) nlat;
00218   lat = (double *) malloc(nlat * sizeof(double));
00219   if (lat == NULL) alloc_error(__FILE__, __LINE__);
00220 
00221   /* Read values from netCDF variable */
00222   istat = nc_get_vara_double(ncinid, latinid, start, count, lat);
00223   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00224 
00225   /* Allocate memory and set start and count */
00226   start[0] = 0;
00227   count[0] = (size_t) nlon;
00228   lon = (double *) malloc(nlon * sizeof(double));
00229   if (lon == NULL) alloc_error(__FILE__, __LINE__);
00230 
00231   /* Read values from netCDF variable */
00232   istat = nc_get_vara_double(ncinid, loninid, start, count, lon);
00233   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00234   
00235   /* Get time dimensions and type */
00236   istat = nc_inq_var(ncinid, timeinid, (char *) NULL, &vartype_time, &varndims, vardimids, (int *) NULL); /* get variable information */
00237   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00238   
00239   if (varndims != 1) {
00240     (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00241     (void) banner(basename(argv[0]), "ABORT", "END");
00242     (void) abort();
00243   }
00244 
00245   /* Allocate memory and set start and count */
00246   start[0] = 0;
00247   count[0] = (size_t) ntime;
00248   timein = malloc(ntime * sizeof(double));
00249   if (timein == NULL) alloc_error(__FILE__, __LINE__);
00250 
00251   /* Read values from netCDF variable */
00252   istat = nc_get_vara_double(ncinid, timeinid, start, count, timein);
00253   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00254   
00257   /* Get variable information */
00258   istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00259   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00260 
00261   if (varndims != 3) {
00262     (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00263     (void) banner(basename(argv[0]), "ABORT", "END");
00264     (void) abort();
00265   }
00266 
00267   /* Allocate memory and set start and count */
00268   start[0] = 0;
00269   start[1] = 0;
00270   start[2] = 0;
00271   count[0] = (size_t) ntime;
00272   count[1] = (size_t) nlat;
00273   count[2] = (size_t) nlon;
00274   /* Allocate memory */
00275   if (vartype_main == NC_DOUBLE)
00276     psl = calloc(nlat*nlon*ntime, sizeof(double));
00277   else if (vartype_main == NC_FLOAT)
00278     psl = calloc(nlat*nlon*ntime, sizeof(float));
00279   else {
00280     (void) fprintf(stderr, "Error NetCDF variable type for main variable.\n");
00281     (void) banner(basename(argv[0]), "ABORT", "END");
00282     (void) abort();
00283   }    
00284   if (psl == NULL) alloc_error(__FILE__, __LINE__);
00285 
00286   /* Read values from netCDF variable */
00287   printf("%s: Reading data from input file %s.\n", __FILE__, filein);
00288   istat = nc_get_vara(ncinid, varinid, start, count, psl);
00289   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00290 
00291   /* Get time units attribute length */
00292   istat = nc_inq_attlen(ncinid, timeinid, "units", &t_len);
00293   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00294   /* Allocate required space before retrieving values */
00295   time_units = (char *) malloc(t_len + 1);
00296   if (time_units == NULL) alloc_error(__FILE__, __LINE__);
00297   /* Get time units attribute value */
00298   istat = nc_get_att_text(ncinid, timeinid, "units", time_units);
00299   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00300   time_units[t_len] = '\0'; /* null terminate */
00301 
00302   /* Get calendar type attribute length */
00303   istat = nc_inq_attlen(ncinid, timeinid, "calendar", &t_len);
00304   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00305   /* Allocate required space before retrieving values */
00306   cal_type = (char *) malloc(t_len + 1);
00307   if (cal_type == NULL) alloc_error(__FILE__, __LINE__);
00308   /* Get calendar type attribute value */
00309   istat = nc_get_att_text(ncinid, timeinid, "calendar", cal_type);
00310   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00311   cal_type[t_len] = '\0'; /* null terminate */
00312 
00314   outtimeval = NULL;
00315   if (vartype_main == NC_FLOAT) {
00316     psloutf = NULL;
00317     (void) data_to_gregorian_cal_f(&psloutf, &outtimeval, &ntimeout, psl, timein, time_units, "days since 1900-01-01 00:00:00",
00318                                    "noleap", nlon, nlat, ntime);
00319   }
00320   else {
00321     psloutd = NULL;
00322     (void) data_to_gregorian_cal_d(&psloutd, &outtimeval, &ntimeout, psl, timein, time_units, "days since 1900-01-01 00:00:00",
00323                                    "noleap", nlon, nlat, ntime);
00324   }
00325 
00326   (void) fprintf(stderr, "Input time units: %s\n", time_units);
00327   (void) fprintf(stderr, "Output time units: days since 1900-01-01 00:00:00\n");
00328 
00330   /* Create and open output file */
00331   istat = nc_create(fileout, NC_CLOBBER, &ncoutid);
00332   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00333 
00334   /* Set dimensions */
00335   istat = nc_def_dim(ncoutid, "time", NC_UNLIMITED, &timedimoutid);
00336   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00337   istat = nc_def_dim(ncoutid, "lat", nlat, &latdimoutid);
00338   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00339   istat = nc_def_dim(ncoutid, "lon", nlon, &londimoutid);
00340   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00341 
00342   /* Define dimensions variables */
00343   vardimids[0] = latdimoutid;
00344   istat = nc_def_var(ncoutid, "lat", NC_DOUBLE, 1, vardimids, &latoutid);
00345   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00346   vardimids[0] = londimoutid;
00347   istat = nc_def_var(ncoutid, "lon", NC_DOUBLE, 1, vardimids, &lonoutid);
00348   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00349   vardimids[0] = timedimoutid;
00350   istat = nc_def_var(ncoutid, "time", NC_DOUBLE, 1, vardimids, &timeoutid);
00351   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00352 
00353   /* Define main output variable */
00354   vardimids[0] = timedimoutid;
00355   vardimids[1] = latdimoutid;
00356   vardimids[2] = londimoutid;
00357   istat = nc_def_var(ncoutid, "psl", vartype_main, 3, vardimids, &varoutid);
00358   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00359 
00360   /* Copy lat attributes */
00361   istat = nc_inq_varnatts(ncinid, latinid, &natts);
00362   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00363   for (i=0; i<natts; i++) {
00364     istat = nc_inq_attname(ncinid, latinid, i, attname);
00365     if (istat == NC_NOERR) {
00366       istat = nc_copy_att(ncinid, latinid, attname, ncoutid, latoutid);
00367       if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00368     }
00369     else
00370       (void) handle_netcdf_error(istat, __LINE__);
00371   }
00372 
00373   /* Copy lon attributes */
00374   istat = nc_inq_varnatts(ncinid, loninid, &natts);
00375   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00376   for (i=0; i<natts; i++) {
00377     istat = nc_inq_attname(ncinid, loninid, i, attname);
00378     if (istat == NC_NOERR) {
00379       istat = nc_copy_att(ncinid, loninid, attname, ncoutid, lonoutid);
00380       if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00381     }
00382     else
00383       (void) handle_netcdf_error(istat, __LINE__);
00384   }
00385 
00386   /* Copy time attributes */
00387   istat = nc_inq_varnatts(ncinid, timeinid, &natts);
00388   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00389   for (i=0; i<natts; i++) {
00390     istat = nc_inq_attname(ncinid, timeinid, i, attname);
00391     if (istat == NC_NOERR) {
00392       printf("Time attribute: %s\n", attname);
00393       if ( !strcmp(attname, "calendar") ) {
00394         /* Change calendar type to standard */
00395         (void) strcat(cal_type_out, "standard");
00396         istat = nc_put_att_text(ncoutid, timeoutid, "calendar", strlen(cal_type_out), cal_type_out);
00397       }
00398       else
00399         /* Other time attributes */
00400         istat = nc_copy_att(ncinid, timeinid, attname, ncoutid, timeoutid);
00401       if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00402     }
00403     else
00404       (void) handle_netcdf_error(istat, __LINE__);
00405   }
00406 
00407   /* Copy main variable attributes */
00408   istat = nc_inq_varnatts(ncinid, varinid, &natts);
00409   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00410   for (i=0; i<natts; i++) {
00411     istat = nc_inq_attname(ncinid, varinid, i, attname);
00412     if (istat == NC_NOERR) {
00413       printf("Main variable attribute: %s\n", attname);
00414       if ( !strcmp(attname, "_FillValue") || !strcmp(attname, "missing_value") ) {
00415         if (vartype_main == NC_FLOAT) {
00416           istat = nc_get_att_float(ncinid, varoutid, attname, &fillvaluef);
00417           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00418           istat = nc_put_att_float(ncoutid, varoutid, attname, NC_FLOAT, 1, &fillvaluef);
00419           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00420         }
00421         else if (vartype_main == NC_DOUBLE) {
00422           istat = nc_get_att_double(ncinid, varoutid, attname, &fillvalued);
00423           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00424           istat = nc_put_att_double(ncoutid, varoutid, attname, NC_DOUBLE, 1, &fillvalued);
00425           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00426         }
00427         else {
00428           (void) fprintf(stderr, "Error NetCDF variable type for main variable.\n");
00429           (void) banner(basename(argv[0]), "ABORT", "END");
00430           (void) abort();
00431         }
00432       }
00433       else {
00434         istat = nc_copy_att(ncinid, varinid, attname, ncoutid, varoutid);
00435         if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00436       }
00437     }
00438     else
00439       (void) handle_netcdf_error(istat, __LINE__);
00440   }
00441 
00442   /* End definition mode */
00443   istat = nc_enddef(ncoutid);
00444   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00445 
00446   /* Write dimensions variables to NetCDF output file */
00447   start[0] = 0;
00448   count[0] = (size_t) nlat;
00449   count[1] = 0;
00450   count[2] = 0;
00451   istat = nc_put_vara_double(ncoutid, latoutid, start, count, lat);
00452   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00453   count[0] = (size_t) nlon;
00454   istat = nc_put_vara_double(ncoutid, lonoutid, start, count, lon);
00455   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00456   count[0] = (size_t) ntimeout;
00457   istat = nc_put_vara_double(ncoutid, timeoutid, start, count, outtimeval);
00458   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00459   for (i=0; i<ntimeout; i++)
00460     printf("Output Time Dimension values. index=%d time=%lf\n",i,outtimeval[i]);
00461 
00462   /* Write variable to NetCDF output file */
00463   start[0] = 0;
00464   start[1] = 0;
00465   start[2] = 0;
00466   count[0] = (size_t) ntimeout;
00467   count[1] = (size_t) nlat;
00468   count[2] = (size_t) nlon;
00469   printf("%s: Writing data to output file %s.\n", __FILE__, fileout);
00470   if (vartype_main == NC_FLOAT)
00471     istat = nc_put_vara_float(ncoutid, varoutid, start, count, psloutf);
00472   else
00473     istat = nc_put_vara_double(ncoutid, varoutid, start, count, psloutd);
00474   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00475 
00477   /* Close the intput netCDF file. */
00478   istat = ncclose(ncinid);
00479   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00480 
00481   /* Close the output netCDF file. */
00482   istat = ncclose(ncoutid);
00483   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00484 
00485   (void) free(psl);
00486   if (vartype_main == NC_FLOAT)
00487     (void) free(psloutf);
00488   else
00489     (void) free(psloutd);
00490   (void) free(outtimeval);
00491   (void) free(lon);
00492   (void) free(lat);
00493   (void) free(timein);
00494   (void) free(cal_type);
00495   (void) free(time_units);
00496   (void) free(filein);
00497   (void) free(fileout);
00498 
00499   /* Print END banner */
00500   (void) banner(basename(argv[0]), "OK", "END");
00501 
00502   return 0;
00503 }

void show_usage ( char *  pgm  ) 

C prototypes.

Local Subroutines.

Show usage for program command-line arguments.

Parameters:
[in] pgm Program name.

Definition at line 509 of file testcalendar.c.

00509                            {
00514   (void) fprintf(stderr, "%s: usage:\n", pgm);
00515   (void) fprintf(stderr, "-i: input NetCDF file\n");
00516   (void) fprintf(stderr, "-o: output NetCDF file\n");
00517   (void) fprintf(stderr, "-h: help\n");
00518 
00519 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1