remove_clim.c File Reference

Remove climatologies. More...

#include <dsclim.h>
Include dependency graph for remove_clim.c:

Go to the source code of this file.

Functions

int remove_clim (data_struct *data)
 Remove climatologies.

Detailed Description

Remove climatologies.

Definition in file remove_clim.c.


Function Documentation

int remove_clim ( data_struct data  ) 

Remove climatologies.

Parameters:
[in] data MASTER data structure.
Returns:
Status.

Definition at line 66 of file remove_clim.c.

References alloc_error(), conf_struct::cal_type, clim_info_struct::clim_filein_ls, clim_info_struct::clim_fileout_ls, conf_struct::clim_filter_type, conf_struct::clim_filter_width, field_data_struct::clim_info, clim_info_struct::clim_nomvar_ls, clim_info_struct::clim_provided, clim_info_struct::clim_remove, clim_info_struct::clim_save, conf_struct::compression, conf_struct::compression_level, data_struct::conf, info_struct::contact_email, info_struct::contact_name, info_field_struct::coordinates, proj_struct::coords, info_struct::country, create_netcdf(), info_struct::creator_email, info_struct::creator_name, info_struct::creator_url, field_struct::data, field_data_struct::dimxname, field_data_struct::dimyname, info_struct::downscaling_forcing, proj_struct::false_easting, proj_struct::false_northing, data_struct::field, field_data_struct::field_ls, info_field_struct::fillvalue, conf_struct::format, get_calendar_ts(), info_field_struct::grid_mapping, proj_struct::grid_mapping_name, info_field_struct::height, data_struct::info, field_data_struct::info, info_struct::institution, info_struct::institution_model, proj_struct::lat0, field_struct::lat_ls, proj_struct::latin1, proj_struct::latin2, field_data_struct::latname, proj_struct::latpole, field_struct::lon_ls, proj_struct::lonc, info_field_struct::long_name, field_data_struct::lonname, proj_struct::lonpole, info_struct::member, info_struct::model, field_struct::n_ls, proj_struct::name, NCAT, field_struct::nlat_ls, field_struct::nlon_ls, field_struct::ntime_ls, info_struct::other_contact_email, info_struct::other_contact_name, field_struct::proj, read_netcdf_var_3d(), remove_seasonal_cycle(), info_struct::scenario, info_struct::scenario_co2, info_struct::software, field_struct::time_ls, conf_struct::time_units, field_data_struct::timename, TRUE, info_field_struct::units, info_struct::version, write_netcdf_dims_3d(), and write_netcdf_var_3d().

Referenced by wt_downscaling().

00066                                {
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