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>
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. |
Test calendar conversion functions.
Definition in file testcalendar.c.
#define _GNU_SOURCE |
GNU extensions.
Definition at line 59 of file testcalendar.c.
int main | ( | int | argc, | |
char ** | argv | |||
) |
Main program.
[in] | argc | Number of command-line arguments. |
[in] | argv | Vector of command-line argument strings. |
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.
[in] | pgm | Program name. |
Definition at line 509 of file testcalendar.c.