Remove climatologies. More...
#include <dsclim.h>
Go to the source code of this file.
Functions | |
int | remove_clim (data_struct *data) |
Remove climatologies. |
Remove climatologies.
Definition in file remove_clim.c.
int remove_clim | ( | data_struct * | data | ) |
Remove climatologies.
[in] | data | MASTER data structure. |
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 }