remove_clim.c

Go to the documentation of this file.
00001 /* ***************************************************** */
00002 /* remove_clim Remove climatology.                       */
00003 /* remove_clim.c                                         */
00004 /* ***************************************************** */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00006 /* ***************************************************** */
00007 /* Date of creation: oct 2008                            */
00008 /* Last date of modification: oct 2008                   */
00009 /* ***************************************************** */
00010 /* Original version: 1.0                                 */
00011 /* Current revision:                                     */
00012 /* ***************************************************** */
00013 /* Revisions                                             */
00014 /* ***************************************************** */
00019 /* LICENSE BEGIN
00020 
00021 Copyright Cerfacs (Christian Page) (2015)
00022 
00023 christian.page@cerfacs.fr
00024 
00025 This software is a computer program whose purpose is to downscale climate
00026 scenarios using a statistical methodology based on weather regimes.
00027 
00028 This software is governed by the CeCILL license under French law and
00029 abiding by the rules of distribution of free software. You can use, 
00030 modify and/ or redistribute the software under the terms of the CeCILL
00031 license as circulated by CEA, CNRS and INRIA at the following URL
00032 "http://www.cecill.info". 
00033 
00034 As a counterpart to the access to the source code and rights to copy,
00035 modify and redistribute granted by the license, users are provided only
00036 with a limited warranty and the software's author, the holder of the
00037 economic rights, and the successive licensors have only limited
00038 liability. 
00039 
00040 In this respect, the user's attention is drawn to the risks associated
00041 with loading, using, modifying and/or developing or reproducing the
00042 software by the user in light of its specific status of free software,
00043 that may mean that it is complicated to manipulate, and that also
00044 therefore means that it is reserved for developers and experienced
00045 professionals having in-depth computer knowledge. Users are therefore
00046 encouraged to load and test the software's suitability as regards their
00047 requirements in conditions enabling the security of their systems and/or 
00048 data to be ensured and, more generally, to use and operate it in the 
00049 same conditions as regards security. 
00050 
00051 The fact that you are presently reading this means that you have had
00052 knowledge of the CeCILL license and that you accept its terms.
00053 
00054 LICENSE END */
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 #include <dsclim.h>
00063 
00065 int
00066 remove_clim(data_struct *data) {
00073   double *bufnoclim = NULL; /* Temporary buffer for field with climatology removed */
00074   double **clim = NULL; /* Climatology buffer */
00075   tstruct *timein_ts = NULL; /* Time info for input field */
00076   int ntime_clim; /* Number of times for input field */
00077   int nlon_file; /* Longitude dimension for input field */
00078   int nlat_file; /* Latitude dimension for input field */
00079   int ntime_file; /* Time dimension for input field */
00080 
00081   double fillvalue; /* Missing value */
00082 
00083   int istat = 0; /* Diagnostic status */
00084   int i; /* Loop counter */
00085   int j; /* Loop counter */
00086   int cat; /* Loop counter for field category */
00087   int ii; /* Loop counter */
00088   info_field_struct clim_info_field; /* Information structure for climatology field */
00089   double *timeclim = NULL; /* Time info for climatology field */
00090 
00091   /* Remove seasonal cycle:
00092      - Fix calendar and generate a gregorian calendar
00093      - Compute climatology including Feb 29th
00094      - Filter climatology
00095      - Optionally save climatology in file */
00096 
00097   /* Climatological year is 366 days */
00098   ntime_clim = 366;
00099 
00100   /* Time variable for climatological year: day timestep */
00101   timeclim = (double *) malloc(ntime_clim * sizeof(double));
00102   if (timeclim == NULL) alloc_error(__FILE__, __LINE__);
00103   for (j=0; j<ntime_clim; j++)
00104     timeclim[j] = (double) (j+1);
00105 
00106   /* Climatology variable */
00107   clim = (double **) malloc(NCAT * sizeof(double *));
00108   if (clim == NULL) alloc_error(__FILE__, __LINE__);
00109   for (cat=0; cat<NCAT; cat++)
00110     clim[cat] = NULL;
00111 
00112   /* Loop over all control-run large-scale field categories to process */
00113   /* Always remove climatology from the control run and apply to corresponding fields for other downscaled runs */
00114   for (cat=1; cat<NCAT; cat=cat+2) {
00115 
00116     /* Loop over all large-scale fields */
00117     for (i=0; i<data->field[cat].n_ls; i++) {
00118 
00119       /* Allocate memory for field with climatology removed */
00120       bufnoclim = (double *) malloc(data->field[cat].nlon_ls * data->field[cat].nlat_ls * data->field[cat].ntime_ls * sizeof(double));
00121       if (bufnoclim == NULL) alloc_error(__FILE__, __LINE__);
00122 
00123       /* Allocate memory for temporary time structure */
00124       timein_ts = (tstruct *) malloc(data->field[cat].ntime_ls * sizeof(tstruct));
00125       if (timein_ts == NULL) alloc_error(__FILE__, __LINE__);
00126       /* Get time info and calendar units */
00127       istat = get_calendar_ts(timein_ts, data->conf->time_units, data->field[cat].time_ls, data->field[cat].ntime_ls);
00128       if (istat < 0) {
00129         (void) free(timein_ts);
00130         (void) free(bufnoclim);
00131         (void) free(timeclim);
00132         return -1;
00133       }
00134 
00135       /* If we need to remove climatology for that field */
00136       if (data->field[cat].data[i].clim_info->clim_remove == TRUE) {
00137         /* If climatology field is already provided */
00138         if (data->field[cat].data[i].clim_info->clim_provided == TRUE) {
00139           /* Read climatology from NetCDF file */
00140           istat = read_netcdf_var_3d(&(clim[cat]), &clim_info_field, (proj_struct *) NULL,
00141                                      data->field[cat].data[i].clim_info->clim_filein_ls,
00142                                      data->field[cat].data[i].clim_info->clim_nomvar_ls,
00143                                      data->field[cat].data[i].dimxname, data->field[cat].data[i].dimyname,
00144                                      data->field[cat].data[i].timename,
00145                                      &nlon_file, &nlat_file, &ntime_file, TRUE);
00146           if (data->field[cat].nlon_ls != nlon_file || data->field[cat].nlat_ls != nlat_file || ntime_clim != ntime_file) {
00147             (void) fprintf(stderr, "%s: Problems in dimensions! nlat=%d nlat_file=%d nlon=%d nlon_file=%d ntime=%d ntime_file=%d\n",
00148                            __FILE__, data->field[cat].nlat_ls, nlat_file, data->field[cat].nlon_ls, nlon_file, ntime_clim, ntime_file);
00149             istat = -1;
00150           }
00151           if (istat != 0) {
00152             /* In case of error in reading data */
00153             (void) free(bufnoclim);
00154             (void) free(timein_ts);
00155             (void) free(timeclim);
00156             if (clim[cat] != NULL) (void) free(clim[cat]);
00157             return istat;
00158           }
00159           /* Get missing value */
00160           fillvalue = clim_info_field.fillvalue;
00161           /* Free memory */
00162           (void) free(clim_info_field.height);
00163           (void) free(clim_info_field.coordinates);
00164           (void) free(clim_info_field.grid_mapping);
00165           (void) free(clim_info_field.units);
00166           (void) free(clim_info_field.long_name);
00167         }
00168         else {
00169           /* Climatology is not provided: must calculate */
00170           if (clim[cat] == NULL) {
00171             /* Allocate memory if not already */
00172             clim[cat] = (double *) malloc(data->field[cat].nlon_ls * data->field[cat].nlat_ls * ntime_clim * sizeof(double));
00173             if (clim[cat] == NULL) alloc_error(__FILE__, __LINE__);
00174           }
00175           /* Get missing value */
00176           fillvalue = data->field[cat].data[i].info->fillvalue;
00177         }
00178       
00179         /* Remove seasonal cycle by calculating filtered climatology and substracting from field values */
00180         (void) remove_seasonal_cycle(bufnoclim, clim[cat], data->field[cat].data[i].field_ls, timein_ts,
00181                                      data->field[cat].data[i].info->fillvalue,
00182                                      data->conf->clim_filter_width, data->conf->clim_filter_type,
00183                                      data->field[cat].data[i].clim_info->clim_provided,
00184                                      data->field[cat].nlon_ls, data->field[cat].nlat_ls, data->field[cat].ntime_ls);
00185       
00186         /* If we want to save climatology in NetCDF output file for further use */
00187         if (data->field[cat].data[i].clim_info->clim_save == TRUE) {
00188           istat = create_netcdf("Computed climatology", "Climatologie calculee", "Computed climatology", "Climatologie calculee",
00189                                 "climatologie,climatology", "C language", data->info->software,
00190                                 "Computed climatology", data->info->institution,
00191                                 data->info->creator_email, data->info->creator_url, data->info->creator_name,
00192                                 data->info->version, data->info->scenario, data->info->scenario_co2, data->info->model,
00193                                 data->info->institution_model, data->info->country, data->info->member,
00194                                 data->info->downscaling_forcing, data->info->contact_email, data->info->contact_name,
00195                                 data->info->other_contact_email, data->info->other_contact_name,
00196                                 data->field[cat].data[i].clim_info->clim_fileout_ls, TRUE, data->conf->format, data->conf->compression);
00197           if (istat != 0) {
00198             /* In case of failure */
00199             (void) free(bufnoclim);
00200             (void) free(timein_ts);
00201             (void) free(timeclim);
00202             if (clim[cat] != NULL) (void) free(clim[cat]);
00203             return istat;
00204           }
00205           /* Write dimensions of climatology field in NetCDF output file */
00206           istat = write_netcdf_dims_3d(data->field[cat].lon_ls, data->field[cat].lat_ls, (double *) NULL, (double *) NULL,
00207                                        (double *) NULL, timeclim, data->conf->cal_type,
00208                                        data->conf->time_units, data->field[cat].nlon_ls, data->field[cat].nlat_ls, ntime_clim,
00209                                        "daily", data->field[cat].proj[i].name, data->field[cat].proj[i].coords,
00210                                        data->field[cat].proj[i].grid_mapping_name, data->field[cat].proj[i].latin1,
00211                                        data->field[cat].proj[i].latin2, data->field[cat].proj[i].lonc, data->field[cat].proj[i].lat0,
00212                                        data->field[cat].proj[i].false_easting, data->field[cat].proj[i].false_northing,
00213                                        data->field[cat].proj[i].lonpole, data->field[cat].proj[i].latpole,
00214                                        data->field[cat].data[i].lonname, data->field[cat].data[i].latname,
00215                                        data->field[cat].data[i].timename,
00216                                        data->field[cat].data[i].clim_info->clim_fileout_ls, TRUE);
00217           if (istat != 0) {
00218             /* In case of failure */
00219             (void) free(bufnoclim);
00220             (void) free(timein_ts);
00221             (void) free(timeclim);
00222             if (clim[cat] != NULL) (void) free(clim[cat]);
00223             return istat;
00224           }
00225         
00226           /* Write climatology field in NetCDF output file */
00227           istat = write_netcdf_var_3d(clim[cat], fillvalue, data->field[cat].data[i].clim_info->clim_fileout_ls,
00228                                       data->field[cat].data[i].clim_info->clim_nomvar_ls, data->field[cat].proj[i].name,
00229                                       data->field[cat].data[i].lonname, data->field[cat].data[i].latname,
00230                                       data->field[cat].data[i].timename,
00231                                       data->conf->format, data->conf->compression_level,
00232                                       data->field[cat].nlon_ls, data->field[cat].nlat_ls, ntime_clim, TRUE);
00233           if (istat != 0) {
00234             /* In case of failure */
00235             (void) free(bufnoclim);
00236             (void) free(timein_ts);
00237             (void) free(timeclim);
00238             if (clim[cat] != NULL) (void) free(clim[cat]);
00239             return istat;
00240           }
00241         }
00242 
00243         /* Copy field with climatology removed to proper variable in data structure */
00244         for (ii=0; ii<(data->field[cat].nlon_ls * data->field[cat].nlat_ls * data->field[cat].ntime_ls); ii++)
00245           data->field[cat].data[i].field_ls[ii] = bufnoclim[ii];
00246       }
00247       /* Free memory */
00248       (void) free(bufnoclim);
00249       (void) free(timein_ts);
00250     }
00251   }
00252 
00253   /* Loop over all non-control-run large-scale field categories to process */
00254   /* Always remove climatology calculated with the control run and apply to corresponding fields for other downscaled runs */
00255   for (cat=0; cat<NCAT; cat=cat+2) {
00256 
00257     /* Loop over all large-scale fields */
00258     for (i=0; i<data->field[cat].n_ls; i++) {
00259 
00260       /* Allocate memory for field with climatology removed */
00261       bufnoclim = (double *) malloc(data->field[cat].nlon_ls * data->field[cat].nlat_ls * data->field[cat].ntime_ls * sizeof(double));
00262       if (bufnoclim == NULL) alloc_error(__FILE__, __LINE__);
00263 
00264       /* Allocate memory for temporary time structure */
00265       timein_ts = (tstruct *) malloc(data->field[cat].ntime_ls * sizeof(tstruct));
00266       if (timein_ts == NULL) alloc_error(__FILE__, __LINE__);
00267       /* Get time info and calendar units */
00268       istat = get_calendar_ts(timein_ts, data->conf->time_units, data->field[cat].time_ls, data->field[cat].ntime_ls);
00269       if (istat < 0) {
00270         (void) free(timein_ts);
00271         (void) free(bufnoclim);
00272         (void) free(timeclim);
00273         return -1;
00274       }
00275 
00276       /* If we need to remove climatology for that field */
00277       if (data->field[cat].data[i].clim_info->clim_remove == TRUE) {
00278         /* If climatology field is already provided */
00279         if (data->field[cat].data[i].clim_info->clim_provided == TRUE) {
00280           /* Read climatology from NetCDF file */
00281           istat = read_netcdf_var_3d(&(clim[cat]), &clim_info_field, (proj_struct *) NULL,
00282                                      data->field[cat].data[i].clim_info->clim_filein_ls,
00283                                      data->field[cat].data[i].clim_info->clim_nomvar_ls,
00284                                      data->field[cat].data[i].dimxname, data->field[cat].data[i].dimyname,
00285                                      data->field[cat].data[i].timename,
00286                                      &nlon_file, &nlat_file, &ntime_file, TRUE);
00287           if (data->field[cat].nlon_ls != nlon_file || data->field[cat].nlat_ls != nlat_file || ntime_clim != ntime_file) {
00288             (void) fprintf(stderr, "%s: Problems in dimensions! nlat=%d nlat_file=%d nlon=%d nlon_file=%d ntime=%d ntime_file=%d\n",
00289                            __FILE__, data->field[cat].nlat_ls, nlat_file, data->field[cat].nlon_ls, nlon_file, ntime_clim, ntime_file);
00290             istat = -1;
00291           }
00292           if (istat != 0) {
00293             /* In case of error in reading data */
00294             (void) free(bufnoclim);
00295             (void) free(timein_ts);
00296             (void) free(timeclim);
00297             if (clim[cat] != NULL) (void) free(clim[cat]);
00298             return istat;
00299           }
00300           /* Get missing value */
00301           fillvalue = clim_info_field.fillvalue;
00302           /* Free memory */
00303           (void) free(clim_info_field.height);
00304           (void) free(clim_info_field.coordinates);
00305           (void) free(clim_info_field.grid_mapping);
00306           (void) free(clim_info_field.units);
00307           (void) free(clim_info_field.long_name);
00308         }
00309         else {
00310           /* Climatology is not provided: must use the one calculated with control-run data */
00311           /* Get missing value */
00312           fillvalue = data->field[cat].data[i].info->fillvalue;
00313         }
00314       
00315         /* Remove seasonal cycle by substracting control-run climatology from field values (not the clim[cat+1] */
00316         (void) remove_seasonal_cycle(bufnoclim, clim[cat+1], data->field[cat].data[i].field_ls, timein_ts,
00317                                      data->field[cat].data[i].info->fillvalue,
00318                                      data->conf->clim_filter_width, data->conf->clim_filter_type,
00319                                      TRUE,
00320                                      data->field[cat].nlon_ls, data->field[cat].nlat_ls, data->field[cat].ntime_ls);
00321       
00322         /* If we want to save climatology in NetCDF output file for further use */
00323         if (data->field[cat].data[i].clim_info->clim_save == TRUE) {
00324           istat = create_netcdf("Computed climatology", "Climatologie calculee", "Computed climatology", "Climatologie calculee",
00325                                 "climatologie,climatology", "C language", data->info->software,
00326                                 "Computed climatology", data->info->institution,
00327                                 data->info->creator_email, data->info->creator_url, data->info->creator_name,
00328                                 data->info->version, data->info->scenario, data->info->scenario_co2, data->info->model,
00329                                 data->info->institution_model, data->info->country, data->info->member,
00330                                 data->info->downscaling_forcing, data->info->contact_email, data->info->contact_name,
00331                                 data->info->other_contact_email, data->info->other_contact_name,
00332                                 data->field[cat].data[i].clim_info->clim_fileout_ls, TRUE, data->conf->format, data->conf->compression);
00333           if (istat != 0) {
00334             /* In case of failure */
00335             (void) free(bufnoclim);
00336             (void) free(timein_ts);
00337             (void) free(timeclim);
00338             if (clim[cat+1] != NULL) (void) free(clim[cat+1]);
00339             return istat;
00340           }
00341           /* Write dimensions of climatology field in NetCDF output file */
00342           istat = write_netcdf_dims_3d(data->field[cat].lon_ls, data->field[cat].lat_ls, (double *) NULL, (double *) NULL,
00343                                        (double *) NULL, timeclim, data->conf->cal_type,
00344                                        data->conf->time_units, data->field[cat].nlon_ls, data->field[cat].nlat_ls, ntime_clim,
00345                                        "daily", data->field[cat].proj[i].name, data->field[cat].proj[i].coords,
00346                                        data->field[cat].proj[i].grid_mapping_name, data->field[cat].proj[i].latin1,
00347                                        data->field[cat].proj[i].latin2, data->field[cat].proj[i].lonc, data->field[cat].proj[i].lat0,
00348                                        data->field[cat].proj[i].false_easting, data->field[cat].proj[i].false_northing,
00349                                        data->field[cat].proj[i].lonpole, data->field[cat].proj[i].latpole,
00350                                        data->field[cat].data[i].lonname, data->field[cat].data[i].latname,
00351                                        data->field[cat].data[i].timename,
00352                                        data->field[cat].data[i].clim_info->clim_fileout_ls, TRUE);
00353           if (istat != 0) {
00354             /* In case of failure */
00355             (void) free(bufnoclim);
00356             (void) free(timein_ts);
00357             (void) free(timeclim);
00358             if (clim[cat+1] != NULL) (void) free(clim[cat+1]);
00359             return istat;
00360           }
00361         
00362           /* Write climatology field in NetCDF output file */
00363           istat = write_netcdf_var_3d(clim[cat+1], fillvalue, data->field[cat].data[i].clim_info->clim_fileout_ls,
00364                                       data->field[cat].data[i].clim_info->clim_nomvar_ls, data->field[cat].proj[i].name,
00365                                       data->field[cat].data[i].lonname, data->field[cat].data[i].latname,
00366                                       data->field[cat].data[i].timename,
00367                                       data->conf->format, data->conf->compression_level,
00368                                       data->field[cat].nlon_ls, data->field[cat].nlat_ls, ntime_clim, TRUE);
00369           if (istat != 0) {
00370             /* In case of failure */
00371             (void) free(bufnoclim);
00372             (void) free(timein_ts);
00373             (void) free(timeclim);
00374             if (clim[cat+1] != NULL) (void) free(clim[cat+1]);
00375             return istat;
00376           }
00377         }
00378 
00379         /* Copy field with climatology removed to proper variable in data structure */
00380         for (ii=0; ii<(data->field[cat].nlon_ls * data->field[cat].nlat_ls * data->field[cat].ntime_ls); ii++)
00381           data->field[cat].data[i].field_ls[ii] = bufnoclim[ii];
00382       }
00383       /* Free memory */
00384       (void) free(bufnoclim);
00385       (void) free(timein_ts);
00386     }
00387   }
00388 
00389   /* Free memory */
00390   (void) free(timeclim);
00391   for (cat=0; cat<NCAT; cat++)
00392     if (clim[cat] != NULL) (void) free(clim[cat]);
00393   (void) free(clim);
00394 
00395   /* Success status */
00396   return 0;
00397 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1