00001
00002
00003
00004
00005
00006
00007
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
00055 #ifdef HAVE_CONFIG_H
00056 #include <config.h>
00057 #endif
00058
00060 #define _GNU_SOURCE
00061
00062
00063 #ifdef HAVE_SYS_TYPES_H
00064 #include <sys/types.h>
00065 #endif
00066 #ifdef HAVE_SYS_STAT_H
00067 #include <sys/stat.h>
00068 #endif
00069 #ifdef HAVE_FCNTL_H
00070 #include <fcntl.h>
00071 #endif
00072 #ifdef HAVE_UNSTD_H
00073 #include <unistd.h>
00074 #endif
00075 #ifdef HAVE_STDIO_H
00076 #include <stdio.h>
00077 #endif
00078 #ifdef HAVE_STRING_H
00079 #include <string.h>
00080 #endif
00081 #ifdef HAVE_STDLIB_H
00082 #include <stdlib.h>
00083 #endif
00084 #ifdef HAVE_MATH_H
00085 #include <math.h>
00086 #endif
00087 #ifdef HAVE_TIME_H
00088 #include <time.h>
00089 #endif
00090 #ifdef HAVE_LIBGEN_H
00091 #include <libgen.h>
00092 #endif
00093
00094 #include <zlib.h>
00095 #include <hdf5.h>
00096 #include <netcdf.h>
00097
00098 #include <utils.h>
00099 #include <filter.h>
00100
00101 #include <gsl/gsl_statistics.h>
00102
00104 void show_usage(char *pgm);
00105 void handle_netcdf_error(int status, int lineno);
00106
00108 int main(int argc, char **argv)
00109 {
00117 int nlat;
00118 int nlon;
00119 int ntime;
00120
00121 int nlat2;
00122 int nlon2;
00123 int ntime2;
00124
00125 size_t dimval;
00126 int i;
00127
00128 char *filein = NULL;
00129 char *filein2 = NULL;
00130 char *fileout = NULL;
00131 FILE *outptr;
00132
00133 int istat;
00134
00135 int ncinid;
00136 int varinid, timeinid, timediminid, londiminid, latdiminid;
00137 nc_type vartype_main;
00138 int varndims;
00139 int vardimids[NC_MAX_VAR_DIMS];
00140
00141 int ncinid2;
00142 int varinid2, timeinid2, timediminid2, londiminid2, latdiminid2;
00143 nc_type vartype_main2;
00144 int varndims2;
00145 int vardimids2[NC_MAX_VAR_DIMS];
00146
00147 size_t start[3];
00148 size_t count[3];
00149
00150 size_t t_len;
00151 char *time_units = NULL;
00152 size_t t_len2;
00153 char *time_units2 = NULL;
00154
00155 int *year = NULL;
00156 int *month = NULL;
00157 int *day = NULL;
00158 int *hour = NULL;
00159 int *minutes = NULL;
00160 float *seconds = NULL;
00161
00162 int *year2 = NULL;
00163 int *month2 = NULL;
00164 int *day2 = NULL;
00165 int *hour2 = NULL;
00166 int *minutes2 = NULL;
00167 float *seconds2 = NULL;
00168
00169 float *buf = NULL;
00170 float *buf2 = NULL;
00171 double *timein = NULL;
00172 double *timein2 = NULL;
00173
00174 double *invect;
00175 double *invect2;
00176 double *outvect;
00177 double *outvect2;
00178
00179 double correl;
00180 int width[8];
00181 int wd;
00182
00183 int firstt;
00184 int firstt2;
00185 int lastt;
00186 int lastt2;
00187
00188 int t;
00189 int x;
00190 int y;
00191
00192 int byear;
00193 int bmonth;
00194 int bday;
00195 int eyear;
00196 int emonth;
00197 int eday;
00198
00199 char *varname = NULL;
00200 char *varname2 = NULL;
00201
00202 int ntime_sub;
00203 double mean_cor;
00204
00205 double missing_value;
00206 double missing_value2;
00207
00208 int countpt;
00209
00210
00211 (void) banner(basename(argv[0]), "1.0", "BEGIN");
00212
00213
00214 for (i=1; i<argc; i++) {
00215 if ( !strcmp(argv[i], "-h") ) {
00216 (void) show_usage(basename(argv[0]));
00217 (void) banner(basename(argv[0]), "OK", "END");
00218 return 0;
00219 }
00220 else if ( !strcmp(argv[i], "-i") ) {
00221 filein = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00222 if (filein == NULL) alloc_error(__FILE__, __LINE__);
00223 (void) strcpy(filein, argv[i]);
00224 }
00225 else if ( !strcmp(argv[i], "-i2") ) {
00226 filein2 = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00227 if (filein2 == NULL) alloc_error(__FILE__, __LINE__);
00228 (void) strcpy(filein2, argv[i]);
00229 }
00230 else if ( !strcmp(argv[i], "-o") ) {
00231 fileout = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00232 if (fileout == NULL) alloc_error(__FILE__, __LINE__);
00233 (void) strcpy(fileout, argv[i]);
00234 }
00235 else if ( !strcmp(argv[i], "-v1") ) {
00236 varname = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00237 if (varname == NULL) alloc_error(__FILE__, __LINE__);
00238 (void) strcpy(varname, argv[i]);
00239 }
00240 else if ( !strcmp(argv[i], "-v2") ) {
00241 varname2 = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00242 if (varname2 == NULL) alloc_error(__FILE__, __LINE__);
00243 (void) strcpy(varname2, argv[i]);
00244 }
00245 else if ( !strcmp(argv[i], "-byear") ) {
00246 (void) sscanf(argv[++i], "%d", &byear);
00247 }
00248 else if ( !strcmp(argv[i], "-bmonth") ) {
00249 (void) sscanf(argv[++i], "%d", &bmonth);
00250 }
00251 else if ( !strcmp(argv[i], "-bday") ) {
00252 (void) sscanf(argv[++i], "%d", &bday);
00253 }
00254 else if ( !strcmp(argv[i], "-eyear") ) {
00255 (void) sscanf(argv[++i], "%d", &eyear);
00256 }
00257 else if ( !strcmp(argv[i], "-emonth") ) {
00258 (void) sscanf(argv[++i], "%d", &emonth);
00259 }
00260 else if ( !strcmp(argv[i], "-eday") ) {
00261 (void) sscanf(argv[++i], "%d", &eday);
00262 }
00263 else {
00264 (void) fprintf(stderr, "%s:: Wrong arg %s.\n\n", basename(argv[0]), argv[i]);
00265 (void) show_usage(basename(argv[0]));
00266 (void) banner(basename(argv[0]), "ABORT", "END");
00267 (void) abort();
00268 }
00269 }
00270
00273
00274 istat = nc_open(filein, NC_NOWRITE, &ncinid);
00275 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00276
00277 istat = nc_inq_dimid(ncinid, "time", &timediminid);
00278 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00279 istat = nc_inq_dimlen(ncinid, timediminid, &dimval);
00280 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00281 ntime = (int) dimval;
00282
00283 istat = nc_inq_dimid(ncinid, "y", &latdiminid);
00284 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00285 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval);
00286 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00287 nlat = (int) dimval;
00288
00289 istat = nc_inq_dimid(ncinid, "x", &londiminid);
00290 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00291 istat = nc_inq_dimlen(ncinid, londiminid, &dimval);
00292 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00293 nlon = (int) dimval;
00294
00295 istat = nc_inq_varid(ncinid, "time", &timeinid);
00296 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00297
00298 istat = nc_inq_varid(ncinid, varname, &varinid);
00299 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00300
00301
00302 istat = nc_get_att_double(ncinid, varinid, "missing_value", &missing_value);
00303 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00304 printf("Missing value=%lf\n", missing_value);
00305
00306
00307 istat = nc_inq_attlen(ncinid, timeinid, "units", &t_len);
00308 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00309
00310 time_units = (char *) malloc(t_len);
00311 if (time_units == NULL) alloc_error(__FILE__, __LINE__);
00312
00313 istat = nc_get_att_text(ncinid, timeinid, "units", time_units);
00314 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00315 time_units[t_len-2] = '\0';
00316
00317
00318 start[0] = 0;
00319 count[0] = (size_t) ntime;
00320 timein = malloc(ntime * sizeof(double));
00321 if (timein == NULL) alloc_error(__FILE__, __LINE__);
00322
00323
00324 istat = nc_get_vara_double(ncinid, timeinid, start, count, timein);
00325 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00326
00327 year = malloc(ntime * sizeof(int));
00328 if (year == NULL) alloc_error(__FILE__, __LINE__);
00329 month = malloc(ntime * sizeof(int));
00330 if (month == NULL) alloc_error(__FILE__, __LINE__);
00331 day = malloc(ntime * sizeof(int));
00332 if (day == NULL) alloc_error(__FILE__, __LINE__);
00333 hour = malloc(ntime * sizeof(int));
00334 if (hour == NULL) alloc_error(__FILE__, __LINE__);
00335 minutes = malloc(ntime * sizeof(int));
00336 if (minutes == NULL) alloc_error(__FILE__, __LINE__);
00337 seconds = malloc(ntime * sizeof(float));
00338 if (seconds == NULL) alloc_error(__FILE__, __LINE__);
00339 istat = get_calendar(year, month, day, hour, minutes, seconds, time_units, timein, ntime);
00340
00343
00344 istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00345 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00346
00347 if (varndims != 3) {
00348 (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00349 (void) banner(basename(argv[0]), "ABORT", "END");
00350 (void) abort();
00351 }
00352
00353
00354 start[0] = 0;
00355 start[1] = 0;
00356 start[2] = 0;
00357 count[0] = (size_t) ntime;
00358 count[1] = (size_t) nlat;
00359 count[2] = (size_t) nlon;
00360
00361 buf = (float *) calloc(nlat*nlon*ntime, sizeof(float));
00362 if (buf == NULL) alloc_error(__FILE__, __LINE__);
00363
00364
00365 printf("%s: Reading data from input file %s.\n", __FILE__, filein);
00366 istat = nc_get_vara(ncinid, varinid, start, count, buf);
00367 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00368
00370
00371 istat = ncclose(ncinid);
00372 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00373
00376
00377 istat = nc_open(filein2, NC_NOWRITE, &ncinid2);
00378 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00379
00380 istat = nc_inq_dimid(ncinid2, "time", &timediminid2);
00381 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00382 istat = nc_inq_dimlen(ncinid2, timediminid2, &dimval);
00383 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00384 ntime2 = (int) dimval;
00385
00386 istat = nc_inq_dimid(ncinid2, "y", &latdiminid2);
00387 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00388 istat = nc_inq_dimlen(ncinid2, latdiminid2, &dimval);
00389 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00390 nlat2 = (int) dimval;
00391
00392 istat = nc_inq_dimid(ncinid2, "x", &londiminid2);
00393 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00394 istat = nc_inq_dimlen(ncinid2, londiminid2, &dimval);
00395 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00396 nlon2 = (int) dimval;
00397
00398 istat = nc_inq_varid(ncinid2, "time", &timeinid2);
00399 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00400
00401 istat = nc_inq_varid(ncinid2, varname2, &varinid2);
00402 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00403
00404
00405 istat = nc_get_att_double(ncinid2, varinid2, "missing_value", &missing_value2);
00406 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00407
00408
00409 istat = nc_inq_attlen(ncinid2, timeinid2, "units", &t_len2);
00410 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00411
00412 time_units2 = (char *) malloc(t_len2);
00413 if (time_units2 == NULL) alloc_error(__FILE__, __LINE__);
00414
00415 istat = nc_get_att_text(ncinid2, timeinid2, "units", time_units2);
00416 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00417 time_units2[t_len2-2] = '\0';
00418
00419
00420 start[0] = 0;
00421 count[0] = (size_t) ntime2;
00422 timein2 = malloc(ntime2 * sizeof(double));
00423 if (timein2 == NULL) alloc_error(__FILE__, __LINE__);
00424
00425
00426 istat = nc_get_vara_double(ncinid2, timeinid2, start, count, timein2);
00427 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00428
00429 year2 = malloc(ntime2 * sizeof(int));
00430 if (year2 == NULL) alloc_error(__FILE__, __LINE__);
00431 month2 = malloc(ntime2 * sizeof(int));
00432 if (month2 == NULL) alloc_error(__FILE__, __LINE__);
00433 day2 = malloc(ntime2 * sizeof(int));
00434 if (day2 == NULL) alloc_error(__FILE__, __LINE__);
00435 hour2 = malloc(ntime2 * sizeof(int));
00436 if (hour2 == NULL) alloc_error(__FILE__, __LINE__);
00437 minutes2 = malloc(ntime2 * sizeof(int));
00438 if (minutes2 == NULL) alloc_error(__FILE__, __LINE__);
00439 seconds2 = malloc(ntime2 * sizeof(float));
00440 if (seconds2 == NULL) alloc_error(__FILE__, __LINE__);
00441 istat = get_calendar(year2, month2, day2, hour2, minutes2, seconds2, time_units2, timein2, ntime2);
00442
00445
00446 istat = nc_inq_var(ncinid2, varinid2, (char *) NULL, &vartype_main2, &varndims2, vardimids2, (int *) NULL);
00447 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00448
00449 if (varndims2 != 3) {
00450 (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00451 (void) banner(basename(argv[0]), "ABORT", "END");
00452 (void) abort();
00453 }
00454
00455
00456 start[0] = 0;
00457 start[1] = 0;
00458 start[2] = 0;
00459 count[0] = (size_t) ntime2;
00460 count[1] = (size_t) nlat2;
00461 count[2] = (size_t) nlon2;
00462
00463 buf2 = (float *) calloc(nlat2*nlon2*ntime2, sizeof(float));
00464 if (buf2 == NULL) alloc_error(__FILE__, __LINE__);
00465
00466
00467 printf("%s: Reading data from input file %s.\n", __FILE__, filein2);
00468 istat = nc_get_vara(ncinid2, varinid2, start, count, buf2);
00469 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00470
00472
00473 istat = ncclose(ncinid2);
00474 if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00475
00476
00477
00478
00479 outptr = fopen(fileout, "w");
00480 if (outptr == NULL) {
00481 (void) fprintf(stderr, "Cannot open output file : %s.\n", fileout);
00482 (void) abort();
00483 }
00484
00485 invect = malloc(ntime * sizeof(double));
00486 if (invect == NULL) alloc_error(__FILE__, __LINE__);
00487 invect2 = malloc(ntime2 * sizeof(double));
00488 if (invect == NULL) alloc_error(__FILE__, __LINE__);
00489
00490 outvect = malloc(ntime * sizeof(double));
00491 if (outvect == NULL) alloc_error(__FILE__, __LINE__);
00492 outvect2 = malloc(ntime2 * sizeof(double));
00493 if (outvect == NULL) alloc_error(__FILE__, __LINE__);
00494
00495 firstt = -1;
00496 lastt = -1;
00497 for (t=0; t<ntime; t++) {
00498 if (year[t] == byear && month[t] == bmonth && day[t] == bday) {
00499 firstt = t;
00500 t = ntime;
00501 }
00502 }
00503 for (t=0; t<ntime; t++) {
00504 if (year[t] == eyear && month[t] == emonth && day[t] == eday) {
00505 lastt = t;
00506 t = ntime;
00507 }
00508 }
00509 if (firstt == -1 || lastt == -1) {
00510 (void) fprintf(stderr, "Error in searching for time boundaries! %d %d\n", firstt, lastt);
00511 (void) exit(1);
00512 }
00513 ntime_sub = lastt - firstt + 1;
00514
00515 firstt2 = -1;
00516 lastt2 = -1;
00517 for (t=0; t<ntime2; t++) {
00518 if (year2[t] == byear && month2[t] == bmonth && day2[t] == bday) {
00519 firstt2 = t;
00520 t = ntime2;
00521 }
00522 }
00523 for (t=0; t<ntime2; t++) {
00524 if (year2[t] == eyear && month2[t] == emonth && day2[t] == eday) {
00525 lastt2 = t;
00526 t = ntime2;
00527 }
00528 }
00529 if (firstt2 == -1 || lastt2 == -1) {
00530 (void) fprintf(stderr, "Error in searching for time boundaries! %d %d\n", firstt2, lastt2);
00531 (void) exit(1);
00532 }
00533
00534 if (ntime_sub != (lastt2 - firstt2 + 1)) {
00535 (void) fprintf(stderr, "Error: cannot compare time series of different lengths %d vs %d! %d %d %d %d\n", ntime_sub, lastt2 - firstt2 + 1, firstt, lastt, firstt2, lastt2);
00536 (void) exit(1);
00537 }
00538
00539 width[0] = 4;
00540 width[1] = 30;
00541 width[2] = 60;
00542 width[3] = 90;
00543 width[4] = 120;
00544 width[5] = 182;
00545 width[6] = 365;
00546 for (wd=0; wd<7; wd++) {
00547
00548 mean_cor = 0.0;
00549
00550 (void) fprintf(stdout, "Filter width=%d\n", width[wd]);
00551
00552 countpt = 0;
00553 for (y=0; y<nlat; y++)
00554 for (x=0; x<nlon; x++) {
00555
00556 if (buf[x+y*nlon] != missing_value) {
00557
00558 for (t=firstt; t<=lastt; t++) {
00559 invect[t] = buf[x+y*nlon+t*nlat*nlon];
00560 }
00561 for (t=firstt2; t<=lastt2; t++)
00562 invect2[t] = buf2[x+y*nlon2+t*nlat2*nlon2];
00563
00564 filter(outvect, invect, "hanning", width[wd], 1, 1, ntime_sub);
00565
00566
00567 filter(outvect2, invect2, "hanning", width[wd], 1, 1, ntime_sub);
00568 correl = gsl_stats_correlation(outvect, 1, outvect2, 1, ntime_sub);
00569
00570 mean_cor = mean_cor + correl;
00571
00572 countpt++;
00573 }
00574 }
00575
00576 mean_cor = mean_cor / (float) (countpt);
00577 printf("%d %lf %d\n", width[wd], mean_cor, countpt);
00578 (void) fprintf(outptr, "%d %lf\n", width[wd], mean_cor);
00579
00580 }
00581
00582 (void) fclose(outptr);
00583
00584
00585
00586 (void) free(buf);
00587 (void) free(filein);
00588
00589 (void) free(buf2);
00590 (void) free(filein2);
00591
00592 (void) free(fileout);
00593
00594 (void) free(timein);
00595 (void) free(timein2);
00596
00597 (void) free(invect);
00598 (void) free(invect2);
00599
00600 (void) free(outvect);
00601 (void) free(outvect2);
00602
00603 (void) free(year);
00604 (void) free(month);
00605 (void) free(day);
00606 (void) free(hour);
00607 (void) free(minutes);
00608 (void) free(seconds);
00609
00610 (void) free(year2);
00611 (void) free(month2);
00612 (void) free(day2);
00613 (void) free(hour2);
00614 (void) free(minutes2);
00615 (void) free(seconds2);
00616
00617
00618 (void) banner(basename(argv[0]), "OK", "END");
00619
00620 return 0;
00621 }
00622
00623
00627 void show_usage(char *pgm) {
00632 (void) fprintf(stderr, "%s: usage:\n", pgm);
00633 (void) fprintf(stderr, "-i: input NetCDF file\n");
00634 (void) fprintf(stderr, "-o: output NetCDF file\n");
00635 (void) fprintf(stderr, "-h: help\n");
00636
00637 }
00638
00639
00640 void handle_netcdf_error(int status, int lineno)
00641 {
00642 if (status != NC_NOERR) {
00643 fprintf(stderr, "Line: %d Error %d: %s\n", lineno, status, nc_strerror(status));
00644 exit(-1);
00645 }
00646 }