00001
00002
00003
00004
00005
00006
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifdef HAVE_CONFIG_H
00055 #include <config.h>
00056 #endif
00057
00059 #define _GNU_SOURCE
00060
00061
00062 #ifdef HAVE_SYS_TYPES_H
00063 #include <sys/types.h>
00064 #endif
00065 #ifdef HAVE_SYS_STAT_H
00066 #include <sys/stat.h>
00067 #endif
00068 #ifdef HAVE_FCNTL_H
00069 #include <fcntl.h>
00070 #endif
00071 #ifdef HAVE_UNSTD_H
00072 #include <unistd.h>
00073 #endif
00074 #ifdef HAVE_STDIO_H
00075 #include <stdio.h>
00076 #endif
00077 #ifdef HAVE_STRING_H
00078 #include <string.h>
00079 #endif
00080 #ifdef HAVE_STDLIB_H
00081 #include <stdlib.h>
00082 #endif
00083 #ifdef HAVE_MATH_H
00084 #include <math.h>
00085 #endif
00086 #ifdef HAVE_TIME_H
00087 #include <time.h>
00088 #endif
00089 #ifdef HAVE_LIBGEN_H
00090 #include <libgen.h>
00091 #endif
00092
00093 #include <zlib.h>
00094 #include <hdf5.h>
00095 #include <netcdf.h>
00096
00097 #include <utils.h>
00098
00100 void show_usage(char *pgm);
00101 void handle_netcdf_error(int status, int lineno);
00102
00104 int main(int argc, char **argv)
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];
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
00155 (void) banner(basename(argv[0]), "1.0", "BEGIN");
00156
00157
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
00183 istat = nc_open(filein, NC_NOWRITE, &ncinid);
00184 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00185
00186 istat = nc_inq_dimid(ncinid, "time", &timediminid);
00187 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00188 istat = nc_inq_dimlen(ncinid, timediminid, &dimval);
00189 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00190 ntime = (int) dimval;
00191
00192 istat = nc_inq_dimid(ncinid, "lat", &latdiminid);
00193 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00194 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval);
00195 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00196 nlat = (int) dimval;
00197
00198 istat = nc_inq_dimid(ncinid, "lon", &londiminid);
00199 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00200 istat = nc_inq_dimlen(ncinid, londiminid, &dimval);
00201 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00202 nlon = (int) dimval;
00203
00204 istat = nc_inq_varid(ncinid, "time", &timeinid);
00205 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00206 istat = nc_inq_varid(ncinid, "lat", &latinid);
00207 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00208 istat = nc_inq_varid(ncinid, "lon", &loninid);
00209 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00210
00211 istat = nc_inq_varid(ncinid, "psl", &varinid);
00212 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00213
00215
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
00222 istat = nc_get_vara_double(ncinid, latinid, start, count, lat);
00223 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00224
00225
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
00232 istat = nc_get_vara_double(ncinid, loninid, start, count, lon);
00233 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00234
00235
00236 istat = nc_inq_var(ncinid, timeinid, (char *) NULL, &vartype_time, &varndims, vardimids, (int *) NULL);
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
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
00252 istat = nc_get_vara_double(ncinid, timeinid, start, count, timein);
00253 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00254
00257
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
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
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
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
00292 istat = nc_inq_attlen(ncinid, timeinid, "units", &t_len);
00293 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00294
00295 time_units = (char *) malloc(t_len + 1);
00296 if (time_units == NULL) alloc_error(__FILE__, __LINE__);
00297
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';
00301
00302
00303 istat = nc_inq_attlen(ncinid, timeinid, "calendar", &t_len);
00304 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00305
00306 cal_type = (char *) malloc(t_len + 1);
00307 if (cal_type == NULL) alloc_error(__FILE__, __LINE__);
00308
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';
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
00331 istat = nc_create(fileout, NC_CLOBBER, &ncoutid);
00332 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00333
00334
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
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
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
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
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
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
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
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
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
00443 istat = nc_enddef(ncoutid);
00444 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00445
00446
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
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
00478 istat = ncclose(ncinid);
00479 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00480
00481
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
00500 (void) banner(basename(argv[0]), "OK", "END");
00501
00502 return 0;
00503 }
00504
00505
00509 void show_usage(char *pgm) {
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 }
00520
00521
00522 void handle_netcdf_error(int status, int lineno)
00523 {
00524 if (status != NC_NOERR) {
00525 fprintf(stderr, "Line: %d Error %d: %s\n", lineno, status, nc_strerror(status));
00526 exit(-1);
00527 }
00528 }