test_proj_eof.c

Go to the documentation of this file.
00001 /* ********************************************************* */
00002 /* test_proj_eof Test EOF projection function.               */
00003 /* test_proj_eof.c                                           */
00004 /* ********************************************************* */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.        */
00006 /* ********************************************************* */
00011 /* LICENSE BEGIN
00012 
00013 Copyright Cerfacs (Christian Page) (2015)
00014 
00015 christian.page@cerfacs.fr
00016 
00017 This software is a computer program whose purpose is to downscale climate
00018 scenarios using a statistical methodology based on weather regimes.
00019 
00020 This software is governed by the CeCILL license under French law and
00021 abiding by the rules of distribution of free software. You can use, 
00022 modify and/ or redistribute the software under the terms of the CeCILL
00023 license as circulated by CEA, CNRS and INRIA at the following URL
00024 "http://www.cecill.info". 
00025 
00026 As a counterpart to the access to the source code and rights to copy,
00027 modify and redistribute granted by the license, users are provided only
00028 with a limited warranty and the software's author, the holder of the
00029 economic rights, and the successive licensors have only limited
00030 liability. 
00031 
00032 In this respect, the user's attention is drawn to the risks associated
00033 with loading, using, modifying and/or developing or reproducing the
00034 software by the user in light of its specific status of free software,
00035 that may mean that it is complicated to manipulate, and that also
00036 therefore means that it is reserved for developers and experienced
00037 professionals having in-depth computer knowledge. Users are therefore
00038 encouraged to load and test the software's suitability as regards their
00039 requirements in conditions enabling the security of their systems and/or 
00040 data to be ensured and, more generally, to use and operate it in the 
00041 same conditions as regards security. 
00042 
00043 The fact that you are presently reading this means that you have had
00044 knowledge of the CeCILL license and that you accept its terms.
00045 
00046 LICENSE END */
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 /* C standard includes */
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 #include <clim.h>
00099 #include <filter.h>
00100 #include <pceof.h>
00101 
00103 void show_usage(char *pgm);
00104 void handle_netcdf_error(int status, int lineno);
00105 
00107 int main(int argc, char **argv)
00108 {
00116   int nlat;
00117   int nlon;
00118   int nlat_sub;
00119   int nlon_sub;
00120   int ntime;
00121   int nlat_eof;
00122   int nlon_eof;
00123   int neof;
00124 
00125   size_t dimval;
00126 
00127   char *filein = NULL;
00128   char *filein_eof = NULL;
00129   char *fileout = NULL;
00130 
00131   int istat, ncinid, ncinid_eof, ncoutid;
00132   int varinid, timeinid, timediminid, loninid, londiminid, latinid, latdiminid;
00133   int varinid_eof, varinid_sing, loninid_eof, londiminid_eof, latinid_eof, latdiminid_eof, eofdiminid_eof;
00134   int varoutid, timeoutid, timedimoutid, eofdimoutid;
00135   nc_type vartype_main;
00136   nc_type vartype_time;
00137   int varndims;
00138   int vardimids[NC_MAX_VAR_DIMS];    /* dimension ids */
00139 
00140   size_t start[3];
00141   size_t count[3];
00142 
00143   size_t t_len;
00144   char *time_units = NULL;
00145   char *cal_type = NULL;
00146 
00147   char attname[1000];
00148   int natts;
00149   double fillvalue;
00150   double fillvalue_eof;
00151   double scale = 1.0;
00152   float valf;
00153 
00154   double *psl = NULL;
00155   double *psl_eof = NULL;
00156   double *psl_sub = NULL;
00157   double *psl_eof_sub = NULL;
00158   double *psl_sing = NULL;
00159   double *lon_sub = NULL;
00160   double *lat_sub = NULL;
00161   double *timein = NULL;
00162   tstruct *timein_ts;
00163   double *lat = NULL;
00164   double *lon = NULL;
00165   double *lat_eof = NULL;
00166   double *lon_eof = NULL;
00167 
00168   double *psl_proj = NULL;
00169   double *psl_clim = NULL;
00170   double *psl_noclim = NULL;
00171 
00172   int clim_filter_width;
00173   char clim_filter_type[500];
00174   int clim_provided;
00175 
00176   double minlon = -360.0;
00177   double maxlon = 360.0;
00178   double minlat = -90.0;
00179   double maxlat = 90.0;
00180 
00181   double curlon;
00182   double curlat;
00183 
00184   int i;
00185   int j;
00186   int t;
00187   int ii;
00188   int jj;
00189 
00190   /* Print BEGIN banner */
00191   (void) banner(basename(argv[0]), "1.0", "BEGIN");
00192 
00193   /* Get command-line arguments and set appropriate variables */
00194   for (i=1; i<argc; i++) {
00195     if ( !strcmp(argv[i], "-h") ) {
00196       (void) show_usage(basename(argv[0]));
00197       (void) banner(basename(argv[0]), "OK", "END");
00198       return 0;
00199     }
00200     else if ( !strcmp(argv[i], "-i") ) {
00201       filein = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00202       if (filein == NULL) alloc_error(__FILE__, __LINE__);
00203       (void) strcpy(filein, argv[i]);
00204     }
00205     else if ( !strcmp(argv[i], "-i_eof") ) {
00206       filein_eof = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00207       if (filein_eof == NULL) alloc_error(__FILE__, __LINE__);
00208       (void) strcpy(filein_eof, argv[i]);
00209     }
00210     else if ( !strcmp(argv[i], "-o") ) {
00211       fileout = (char *) malloc((strlen(argv[++i])+1) * sizeof(char));
00212       if (fileout == NULL) alloc_error(__FILE__, __LINE__);
00213       (void) strcpy(fileout, argv[i]);
00214     }
00215     else if ( !strcmp(argv[i], "-scale") )
00216       (void) sscanf(argv[++i], "%lf", &scale);
00217     else {
00218       (void) fprintf(stderr, "%s:: Wrong arg %s.\n\n", basename(argv[0]), argv[i]);
00219       (void) show_usage(basename(argv[0]));
00220       (void) banner(basename(argv[0]), "ABORT", "END");
00221       (void) abort();
00222     }
00223   }
00224 
00225   /* Read data in NetCDF file */
00226   printf("%s: Reading info from input file %s.\n", __FILE__, filein);
00227   istat = nc_open(filein, NC_NOWRITE, &ncinid);  /* open for reading */
00228   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00229 
00230   istat = nc_inq_dimid(ncinid, "time", &timediminid);  /* get ID for time dimension */
00231   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00232   istat = nc_inq_dimlen(ncinid, timediminid, &dimval); /* get time length */
00233   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00234   ntime = (int) dimval;
00235 
00236   istat = nc_inq_dimid(ncinid, "lat", &latdiminid);  /* get ID for lat dimension */
00237   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00238   istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */
00239   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00240   nlat = (int) dimval;
00241 
00242   istat = nc_inq_dimid(ncinid, "lon", &londiminid);  /* get ID for lon dimension */
00243   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00244   istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */
00245   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00246   nlon = (int) dimval;
00247   
00248   istat = nc_inq_varid(ncinid, "time", &timeinid);  /* get ID for time variable */
00249   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00250   istat = nc_inq_varid(ncinid, "lat", &latinid);  /* get ID for lat variable */
00251   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00252   istat = nc_inq_varid(ncinid, "lon", &loninid);  /* get ID for lon variable */
00253   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00254 
00255   istat = nc_inq_varid(ncinid, "psl", &varinid); /* get psl variable ID */
00256   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00257 
00259   /* Allocate memory and set start and count */
00260   start[0] = 0;
00261   start[1] = 0;
00262   start[2] = 0;
00263   count[0] = (size_t) nlat;
00264   count[1] = (size_t) nlon;
00265   count[2] = 0;
00266   lat = (double *) malloc(nlat * nlon * sizeof(double));
00267   if (lat == NULL) alloc_error(__FILE__, __LINE__);
00268 
00269   /* Read values from netCDF variable */
00270   istat = nc_get_vara_double(ncinid, latinid, start, count, lat);
00271   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00272 
00273   /* Allocate memory and set start and count */
00274   start[0] = 0;
00275   start[1] = 0;
00276   start[2] = 0;
00277   count[0] = (size_t) nlat;
00278   count[1] = (size_t) nlon;
00279   count[2] = 0;
00280   lon = (double *) malloc(nlat * nlon * sizeof(double));
00281   if (lon == NULL) alloc_error(__FILE__, __LINE__);
00282 
00283   /* Read values from netCDF variable */
00284   istat = nc_get_vara_double(ncinid, loninid, start, count, lon);
00285   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00286   
00287   /* Get time dimensions and type */
00288   istat = nc_inq_var(ncinid, timeinid, (char *) NULL, &vartype_time, &varndims, vardimids, (int *) NULL); /* get variable information */
00289   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00290   
00291   if (varndims != 1) {
00292     (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00293     (void) banner(basename(argv[0]), "ABORT", "END");
00294     (void) abort();
00295   }
00296 
00297   /* Allocate memory and set start and count */
00298   start[0] = 0;
00299   count[0] = (size_t) ntime;
00300   timein = malloc(ntime * sizeof(double));
00301   if (timein == NULL) alloc_error(__FILE__, __LINE__);
00302 
00303   /* Read values from netCDF variable */
00304   istat = nc_get_vara_double(ncinid, timeinid, start, count, timein);
00305   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00306 
00307   /* Check values of time variable because many times they are all zero. In that case assume a 1 increment and a start at zero. */
00308   for (t=0; t<ntime; t++)
00309     if (timein[t] != 0.0)
00310       break;
00311   if (t == ntime) {
00312     fprintf(stderr, "WARNING: Time variable values all zero!!! Fixing time variable to index value...\n");
00313     for (t=0; t<ntime; t++)
00314       timein[t] = (double) t;
00315   }
00316 
00319   /* Get variable information */
00320   istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00321   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00322 
00323   if (varndims != 3) {
00324     (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00325     (void) banner(basename(argv[0]), "ABORT", "END");
00326     (void) abort();
00327   }
00328 
00329   /* Allocate memory and set start and count */
00330   start[0] = 0;
00331   start[1] = 0;
00332   start[2] = 0;
00333   count[0] = (size_t) ntime;
00334   count[1] = (size_t) nlat;
00335   count[2] = (size_t) nlon;
00336   /* Allocate memory */
00337   psl = (double *) calloc(nlat*nlon*ntime, sizeof(double));
00338   if (psl == NULL) alloc_error(__FILE__, __LINE__);
00339 
00340   /* Read values from netCDF variable */
00341   printf("%s: Reading data from input file %s.\n", __FILE__, filein);
00342   istat = nc_get_vara_double(ncinid, varinid, start, count, psl);
00343   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00344 
00345   /* Get time units attribute length */
00346   istat = nc_inq_attlen(ncinid, timeinid, "units", &t_len);
00347   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00348   /* Allocate required space before retrieving values */
00349   time_units = (char *) malloc(t_len + 1);
00350   if (time_units == NULL) alloc_error(__FILE__, __LINE__);
00351   /* Get time units attribute value */
00352   istat = nc_get_att_text(ncinid, timeinid, "units", time_units);
00353   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00354   time_units[t_len] = '\0'; /* null terminate */
00355 
00356   /* Get calendar type attribute length */
00357   istat = nc_inq_attlen(ncinid, timeinid, "calendar", &t_len);
00358   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00359   /* Allocate required space before retrieving values */
00360   cal_type = (char *) malloc(t_len + 1);
00361   if (cal_type == NULL) alloc_error(__FILE__, __LINE__);
00362   /* Get calendar type attribute value */
00363   istat = nc_get_att_text(ncinid, timeinid, "calendar", cal_type);
00364   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00365   cal_type[t_len] = '\0'; /* null terminate */
00366 
00367 
00368 
00369 
00370   /* Read data in NetCDF file */
00371   printf("%s: Reading info from input file %s.\n", __FILE__, filein_eof);
00372   istat = nc_open(filein_eof, NC_NOWRITE, &ncinid_eof);  /* open for reading */
00373   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00374 
00375   istat = nc_inq_dimid(ncinid_eof, "lat", &latdiminid_eof);  /* get ID for lat dimension */
00376   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00377   istat = nc_inq_dimlen(ncinid_eof, latdiminid_eof, &dimval); /* get lat length */
00378   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00379   nlat_eof = (int) dimval;
00380 
00381   istat = nc_inq_dimid(ncinid_eof, "lon", &londiminid_eof);  /* get ID for lon dimension */
00382   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00383   istat = nc_inq_dimlen(ncinid_eof, londiminid_eof, &dimval); /* get lon length */
00384   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00385   nlon_eof = (int) dimval;
00386   
00387   istat = nc_inq_dimid(ncinid_eof, "eof", &eofdiminid_eof);  /* get ID for pc dimension */
00388   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00389   istat = nc_inq_dimlen(ncinid_eof, eofdiminid_eof, &dimval); /* get pc length */
00390   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00391   neof = (int) dimval;
00392   
00393   istat = nc_inq_varid(ncinid_eof, "lat", &latinid_eof);  /* get ID for lat variable */
00394   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00395   istat = nc_inq_varid(ncinid_eof, "lon", &loninid_eof);  /* get ID for lon variable */
00396   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00397 
00398   istat = nc_inq_varid(ncinid_eof, "psl_eof", &varinid_eof); /* get psl variable ID */
00399   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00400   istat = nc_inq_varid(ncinid_eof, "psl_sing", &varinid_sing); /* get psl variable ID */
00401   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00402 
00404   /* Allocate memory and set start and count */
00405   start[0] = 0;
00406   count[0] = (size_t) nlat_eof;
00407   count[1] = 0;
00408   count[2] = 0;
00409   lat_eof = (double *) malloc(nlat_eof * sizeof(double));
00410   if (lat_eof == NULL) alloc_error(__FILE__, __LINE__);
00411 
00412   /* Read values from netCDF variable */
00413   istat = nc_get_vara_double(ncinid_eof, latinid_eof, start, count, lat_eof);
00414   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00415 
00416   /* Allocate memory and set start and count */
00417   start[0] = 0;
00418   count[0] = (size_t) nlon_eof;
00419   count[1] = 0;
00420   count[2] = 0;
00421   lon_eof = (double *) malloc(nlon_eof * sizeof(double));
00422   if (lon_eof == NULL) alloc_error(__FILE__, __LINE__);
00423 
00424   /* Read values from netCDF variable */
00425   istat = nc_get_vara_double(ncinid_eof, loninid_eof, start, count, lon_eof);
00426   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00427 
00430   /* Get variable information */
00431   istat = nc_inq_var(ncinid_eof, varinid_eof, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00432   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00433 
00434   if (varndims != 3) {
00435     (void) fprintf(stderr, "Error NetCDF type and/or dimensions.\n");
00436     (void) banner(basename(argv[0]), "ABORT", "END");
00437     (void) abort();
00438   }
00439 
00440   (void) strcpy(attname, "missing_value");
00441   if (vartype_main == NC_FLOAT) {
00442     istat = nc_get_att_float(ncinid_eof, varinid_eof, attname, &valf);
00443     if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00444     fillvalue_eof = (double) valf;
00445   }
00446   else if (vartype_main == NC_DOUBLE) {
00447     istat = nc_get_att_double(ncinid_eof, varinid_eof, attname, &fillvalue_eof);
00448     if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00449   }
00450 
00451   /* Allocate memory and set start and count */
00452   start[0] = 0;
00453   start[1] = 0;
00454   start[2] = 0;
00455   count[0] = (size_t) neof;
00456   count[1] = (size_t) nlat_eof;
00457   count[2] = (size_t) nlon_eof;
00458   /* Allocate memory */
00459   psl_eof = (double *) calloc(nlat_eof*nlon_eof*neof, sizeof(double));
00460   if (psl_eof == NULL) alloc_error(__FILE__, __LINE__);
00461 
00462   /* Read values from netCDF variable */
00463   printf("%s: Reading data from input file %s.\n", __FILE__, filein_eof);
00464   istat = nc_get_vara_double(ncinid_eof, varinid_eof, start, count, psl_eof);
00465   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00466 
00467   /* Allocate memory and set start and count */
00468   start[0] = 0;
00469   start[1] = 0;
00470   start[2] = 0;
00471   count[0] = (size_t) neof;
00472   count[1] = 0;
00473   count[2] = 0;
00474   /* Allocate memory */
00475   psl_sing = (double *) calloc(neof, sizeof(double));
00476   if (psl_sing == NULL) alloc_error(__FILE__, __LINE__);
00477 
00478   /* Read values from netCDF variable */
00479   istat = nc_get_vara_double(ncinid_eof, varinid_sing, start, count, psl_sing);
00480   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00481 
00482 
00483 
00485   istat = nc_create(fileout, NC_CLOBBER, &ncoutid);
00486   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00487 
00488   /* Set dimensions */
00489   istat = nc_def_dim(ncoutid, "time", NC_UNLIMITED, &timedimoutid);
00490   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00491   istat = nc_def_dim(ncoutid, "eof", neof, &eofdimoutid);
00492   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00493 
00494   /* Define dimensions variables */
00495   vardimids[0] = timedimoutid;
00496   istat = nc_def_var(ncoutid, "time", NC_DOUBLE, 1, vardimids, &timeoutid);
00497   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00498 
00499   /* Define main output variable */
00500   vardimids[0] = timedimoutid;
00501   vardimids[1] = eofdimoutid;
00502   istat = nc_def_var(ncoutid, "psl_proj", vartype_main, 2, vardimids, &varoutid);
00503   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00504 
00505   /* Copy time attributes */
00506   istat = nc_inq_varnatts(ncinid, timeinid, &natts);
00507   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00508   for (i=0; i<natts; i++) {
00509     istat = nc_inq_attname(ncinid, timeinid, i, attname);
00510     if (istat == NC_NOERR) {
00511       printf("Time attribute: %s\n", attname);
00512       istat = nc_copy_att(ncinid, timeinid, attname, ncoutid, timeoutid);
00513       if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00514     }
00515     else
00516       (void) handle_netcdf_error(istat, __LINE__);
00517   }
00518 
00519   /* Copy main variable attributes */
00520   fillvalue = 999999.9999;
00521   istat = nc_inq_varnatts(ncinid, varinid, &natts);
00522   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00523   for (i=0; i<natts; i++) {
00524     istat = nc_inq_attname(ncinid, varinid, i, attname);
00525     if (istat == NC_NOERR) {
00526       printf("Main variable attribute: %s\n", attname);
00527       if ( !strcmp(attname, "_FillValue") || !strcmp(attname, "missing_value") ) {
00528         if (vartype_main == NC_FLOAT) {
00529           istat = nc_get_att_float(ncinid, varinid, attname, &valf);
00530           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00531           fillvalue = (double) valf;
00532           istat = nc_put_att_double(ncoutid, varoutid, attname, NC_DOUBLE, 1, &fillvalue);
00533           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00534         }
00535         else if (vartype_main == NC_DOUBLE) {
00536           istat = nc_get_att_double(ncinid, varinid, attname, &fillvalue);
00537           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00538           istat = nc_put_att_double(ncoutid, varoutid, attname, NC_DOUBLE, 1, &fillvalue);
00539           if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00540         }
00541         else {
00542           (void) fprintf(stderr, "Error NetCDF variable type for main variable.\n");
00543           (void) banner(basename(argv[0]), "ABORT", "END");
00544           (void) abort();
00545         }
00546       }
00547       else {
00548         istat = nc_copy_att(ncinid, varinid, attname, ncoutid, varoutid);
00549         if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00550       }
00551     }
00552     else
00553       (void) handle_netcdf_error(istat, __LINE__);
00554   }
00555   if (fillvalue == 999999.9999) {
00556     (void) strcpy(attname, "missing_value");
00557     istat = nc_put_att_double(ncoutid, varoutid, attname, NC_DOUBLE, 1, &fillvalue);
00558     if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00559   }
00560 
00561   /* End definition mode */
00562   istat = nc_enddef(ncoutid);
00563   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00564 
00567   clim_filter_width = 60;
00568   (void) strcpy(clim_filter_type, "hanning");
00569   clim_provided = 0;
00570 
00571   psl_proj = (double *) calloc(ntime * neof, sizeof(double));
00572   if (psl_proj == NULL) alloc_error(__FILE__, __LINE__);
00573   timein_ts = (tstruct *) malloc(ntime * sizeof(tstruct));
00574   if (timein_ts == NULL) alloc_error(__FILE__, __LINE__);
00575   printf("NLON=%d %d\n",nlon,ntime);
00576   (void) get_calendar_ts(timein_ts, time_units, timein, ntime);
00577   printf("NLON=%d\n",nlon);
00578 
00579   /* Compute subdomain and apply to arrays */
00580   /*  blon=where(lone ge 345 or lone le 20)
00581       blat=where(late ge 35 and late le 60) */
00582   minlon = -10.0;
00583   maxlon = 17.5;
00584   minlat = 35.0;
00585   maxlat = 57.5;
00586   nlon_sub = nlat_sub = 0;
00587   for (i=0; i<nlat_eof; i++)
00588     if (lat_eof[i] >= minlat && lat_eof[i] <= maxlat)
00589       nlat_sub++;
00590   for (i=0; i<nlon_eof; i++) {
00591     if (lon_eof[i] > 180.0)
00592       curlon = lon_eof[i] - 360.0;
00593     else
00594       curlon = lon_eof[i];
00595     if (curlon >= minlon && curlon <= maxlon)
00596       nlon_sub++;
00597   }
00598 
00599   psl_sub = (double *) malloc(nlon_sub*nlat_sub*ntime * sizeof(double));
00600   if (psl_sub == NULL) alloc_error(__FILE__, __LINE__);
00601   psl_eof_sub = (double *) malloc(nlon_sub*nlat_sub*neof * sizeof(double));
00602   if (psl_eof_sub == NULL) alloc_error(__FILE__, __LINE__);
00603   psl_clim = (double *) calloc(nlat_sub*nlon_sub*31*12, sizeof(double));
00604   if (psl_clim == NULL) alloc_error(__FILE__, __LINE__);
00605   psl_noclim = (double *) calloc(nlat_sub*nlon_sub*ntime, sizeof(double));
00606   if (psl_noclim == NULL) alloc_error(__FILE__, __LINE__);
00607 
00608   lon_sub = (double *) malloc(nlon_sub*nlat_sub * sizeof(double));
00609   if (lon_sub == NULL) alloc_error(__FILE__, __LINE__);
00610   lat_sub = (double *) malloc(nlon_sub*nlat_sub * sizeof(double));
00611   if (lat_sub == NULL) alloc_error(__FILE__, __LINE__);
00612 
00613   ii = 0;
00614   jj = 0;
00615   for (j=0; j<nlat; j++) {
00616     if (ii > 0)
00617       jj++;
00618     ii = 0;
00619     printf("j=%d %d %d\n",j,nlon,nlat);
00620     for (i=0; i<nlon; i++) {
00621       printf("i=%d\n",i);
00622       if (lon_eof[i] > 180.0)
00623         curlon = lon_eof[i] - 360.0;
00624       else
00625         curlon = lon_eof[i];
00626       curlat = lat_eof[j];
00627       if (curlon >= minlon && curlon <= maxlon && curlat >= minlat && curlat <= maxlat) {
00628         lon_sub[ii+jj*nlon_sub] = lon[i+j*nlon];
00629         lat_sub[ii+jj*nlon_sub] = lat[i+j*nlon];
00630         for (t=0; t<ntime; t++)
00631           psl_sub[ii+jj*nlon_sub+t*nlon_sub*nlat_sub] = psl[i+j*nlon+t*nlon*nlat];
00632         for (t=0; t<neof; t++)
00633           psl_eof_sub[ii+jj*nlon_sub+t*nlon_sub*nlat_sub] = psl_eof[i+j*nlon+t*nlon*nlat];  
00634         ii++;
00635       }
00636     }
00637   }
00638 
00639   (void) remove_seasonal_cycle(psl_noclim, psl_clim, psl_sub, timein_ts, fillvalue, clim_filter_width, clim_filter_type,
00640                                clim_provided, nlon_sub, nlat_sub, ntime);
00641   (void) project_field_eof(psl_proj, psl_noclim, psl_eof_sub, psl_sing, fillvalue_eof, lon_sub, lat_sub,
00642                            scale, nlon_sub, nlat_sub, ntime, neof);
00643 
00644   (void) fprintf(stderr, "Input/output time units: %s\n", time_units);
00645 
00646   /* Write dimensions variables to NetCDF output file */
00647   start[0] = 0;
00648   count[0] = (size_t) ntime;
00649   count[1] = 0;
00650   count[2] = 0;
00651   istat = nc_put_vara_double(ncoutid, timeoutid, start, count, timein);
00652   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00653 
00654   /* Write variable to NetCDF output file */
00655   start[0] = 0;
00656   start[1] = 0;
00657   start[2] = 0;
00658   count[0] = (size_t) ntime;
00659   count[1] = (size_t) neof;
00660   count[2] = 0;
00661   printf("%s: Writing data to output file %s.\n", __FILE__, fileout);
00662   istat = nc_put_vara_double(ncoutid, varoutid, start, count, psl_proj);
00663   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00664 
00666   /* Close the intput netCDF file. */
00667   istat = ncclose(ncinid);
00668   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00669 
00670   /* Close the output netCDF file. */
00671   istat = ncclose(ncoutid);
00672   if (istat != NC_NOERR) handle_netcdf_error(istat, __LINE__);
00673 
00674   (void) free(psl);
00675   (void) free(psl_proj);
00676   (void) free(psl_sing);
00677   (void) free(psl_eof);
00678   (void) free(psl_clim);
00679   (void) free(psl_noclim);
00680   (void) free(psl_sub);
00681   (void) free(psl_eof_sub);
00682   (void) free(lon_sub);
00683   (void) free(lat_sub);
00684   (void) free(lon);
00685   (void) free(lat);
00686   (void) free(lon_eof);
00687   (void) free(lat_eof);
00688   (void) free(timein);
00689   (void) free(cal_type);
00690   (void) free(time_units);
00691   (void) free(filein);
00692   (void) free(filein_eof);
00693   (void) free(fileout);
00694   (void) free(timein_ts);
00695 
00696   /* Print END banner */
00697   (void) banner(basename(argv[0]), "OK", "END");
00698 
00699   return 0;
00700 }
00701 
00702 
00706 void show_usage(char *pgm) {
00711   (void) fprintf(stderr, "%s: usage:\n", pgm);
00712   (void) fprintf(stderr, "-i: input NetCDF file\n");
00713   (void) fprintf(stderr, "-o: output NetCDF file\n");
00714   (void) fprintf(stderr, "-h: help\n");
00715 
00716 }
00717 
00718 /* Handle error */
00719 void handle_netcdf_error(int status, int lineno)
00720 {
00721   if (status != NC_NOERR) {
00722     fprintf(stderr, "Line: %d Error %d: %s\n", lineno, status, nc_strerror(status));
00723     exit(-1);
00724   }
00725 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1