Read analog day data and write it for downscaled period. More...
#include <dsclim.h>
Go to the source code of this file.
Functions | |
int | output_downscaled_analog (analog_day_struct analog_days, double *delta, int output_month_begin, char *output_path, char *config, char *time_units, char *cal_type, double deltat, int file_format, int file_compression, int file_compression_level, int debug, info_struct *info, var_struct *obs_var, period_struct *period, double *time_ls, int ntime) |
Read analog day data and write it for downscaled period. |
Read analog day data and write it for downscaled period.
Definition in file output_downscaled_analog.c.
int output_downscaled_analog | ( | analog_day_struct | analog_days, | |
double * | delta, | |||
int | output_month_begin, | |||
char * | output_path, | |||
char * | config, | |||
char * | time_units, | |||
char * | cal_type, | |||
double | deltat, | |||
int | file_format, | |||
int | file_compression, | |||
int | file_compression_level, | |||
int | debug, | |||
info_struct * | info, | |||
var_struct * | obs_var, | |||
period_struct * | period, | |||
double * | time_ls, | |||
int | ntime | |||
) |
Read analog day data and write it for downscaled period.
[in] | analog_days | Analog days time indexes and dates with corresponding dates being downscaled. |
[in] | delta | Temperature difference to apply to analog day data |
[in] | output_month_begin | First month for yearly file output |
[in] | output_path | Output path directory |
[in] | config | Whole configuration text |
[in] | time_units | Output base time units |
[in] | cal_type | Output calendar-type |
[in] | deltat | Absolute difference of large-scale temperature threshold to apply as a correction |
[in] | file_format | File format version for NetCDF |
[in] | file_compression | Compression flag for NetCDF-4 file format |
[in] | file_compression_level | Compression level for NetCDF-4 file format |
[in] | debug | Debugging supplemental info (TRUE or FALSE) |
[in] | info | General meta-data information structure for NetCDF output file |
[in] | obs_var | Input/output observation variables data structure |
[in] | period | Period structure for downscaling output |
[in] | time_ls | Time values |
[in] | ntime | Number of times dimension |
Add algorithm configuration
Retrieve temperature change and apply to analog day temperature and other variables
Definition at line 59 of file output_downscaled_analog.c.
References var_struct::acronym, alloc_error(), alt_to_press(), var_struct::altitude, var_struct::altitudename, calc_etp_mf(), 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, analog_day_struct::day, time_vect_struct::day, period_struct::day_begin, period_struct::day_end, analog_day_struct::day_s, var_struct::delta, info_struct::description, var_struct::dimcoords, var_struct::dimxname, var_struct::dimyname, info_struct::downscaling_forcing, var_struct::factor, FALSE, proj_struct::false_easting, proj_struct::false_northing, info_field_struct::fillvalue, find_str_value(), var_struct::frequency, get_time_info(), info_field_struct::grid_mapping, proj_struct::grid_mapping_name, handle_netcdf_error(), info_field_struct::height, var_struct::height, time_vect_struct::hour, info_struct::institution, info_struct::institution_model, K_TKELVIN, info_struct::keywords, proj_struct::lat0, proj_struct::latin1, proj_struct::latin2, var_struct::latname, proj_struct::latpole, proj_struct::lonc, info_field_struct::long_name, var_struct::lonname, proj_struct::lonpole, MAXPATH, info_struct::member, time_vect_struct::minutes, info_struct::model, time_vect_struct::month, analog_day_struct::month, var_struct::month_begin, period_struct::month_begin, period_struct::month_end, analog_day_struct::month_s, var_struct::name, proj_struct::name, var_struct::netcdfname, var_struct::nobs_var, info_struct::other_contact_email, info_struct::other_contact_name, var_struct::output, var_struct::path, var_struct::post, info_struct::processor, var_struct::proj, read_netcdf_latlon(), read_netcdf_var_2d(), read_netcdf_var_3d_2d(), read_netcdf_xy(), info_struct::scenario, info_struct::scenario_co2, time_vect_struct::seconds, info_struct::software, spechum_to_hr(), info_struct::summary, info_struct::summary_french, var_struct::template, var_struct::timename, info_struct::timestep, info_struct::title, info_struct::title_french, TRUE, info_field_struct::units, var_struct::units, info_struct::version, write_netcdf_dims_3d(), write_netcdf_var_3d_2d(), time_vect_struct::year, analog_day_struct::year, period_struct::year_begin, var_struct::year_digits, period_struct::year_end, and analog_day_struct::year_s.
Referenced by wt_downscaling().
00064 { 00085 char **infile = NULL; /* Input filename */ 00086 char *infile_alt = NULL; /* Input filename for optional altitudes */ 00087 char **outfile = NULL; /* Output filename */ 00088 char ***outfiles = NULL; /* Output filelist */ 00089 int year1 = 0; /* First year of data input file */ 00090 int year2 = 0; /* End year of data input file */ 00091 double **buf = NULL; /* Temporary data buffer */ 00092 double **bufsave = NULL; /* Temporary data buffer for averaging hourly data */ 00093 double *buftmp = NULL; /* Temporary buffer for mean temperature */ 00094 double *alt = NULL; /* Altitudes of observation points (optional) */ 00095 double *pmsl = NULL; /* Standard Pressure of observation points (optional) */ 00096 double *timeval = NULL; /* Temporary time information buffer */ 00097 double *lat = NULL; /* Temporary latitude buffer */ 00098 double *lon = NULL; /* Temporary longitude buffer */ 00099 double *y = NULL; /* Temporary Y buffer */ 00100 double *x = NULL; /* Temporary X buffer */ 00101 char *cal_type_tmp = NULL; /* Input observations calendar type (udunits) */ 00102 char *time_units_tmp = NULL; /* Input observations time units (udunits) */ 00103 double ctimeval[1]; /* Dummy time info */ 00104 int ntime_file; /* Number of times dimension */ 00105 int ntime_obs; /* Number of times dimension in observation database */ 00106 int nlon; /* Longitude dimension */ 00107 int nlat; /* Latitude dimension */ 00108 int *noutf = NULL; /* Number of files in filelist */ 00109 int found = FALSE; /* Used to tag if we found a specific date */ 00110 int *found_file = NULL; /* Used to tag if we found a specific filename in the filelist */ 00111 int output_month_end; /* Ending month for observation database */ 00112 time_vect_struct *time_s = NULL; /* Time structure for observation database */ 00113 00114 info_field_struct **info_tmp = NULL; /* Temporary field information structure */ 00115 proj_struct *proj_tmp = NULL; /* Temporary field projection structure */ 00116 00117 int tmpi; /* Temporay integer value */ 00118 double curtas; /* Current temperature value */ 00119 double newcurtas; /* New current temperature value */ 00120 char *format = NULL; /* Temporay format string */ 00121 00122 int varid_tas; /* Variable index ID */ 00123 int varid_tasmax; /* Variable index ID */ 00124 int varid_tasmin; /* Variable index ID */ 00125 int varid_prsn; /* Variable index ID */ 00126 int varid_prr; /* Variable index ID */ 00127 int varid_rlds; /* Variable index ID */ 00128 int varid_rsds; /* Variable index ID */ 00129 int varid_hur; /* Variable index ID */ 00130 int varid_hus; /* Variable index ID */ 00131 int varid_husmin; /* Variable index ID */ 00132 int varid_husmax; /* Variable index ID */ 00133 int varid_etp; /* Variable index ID */ 00134 int varid_uvas; /* Variable index ID */ 00135 int varid_prtot; /* Variable index ID */ 00136 00137 int configstrdimid; /* Variable dimension ID for configuration */ 00138 int configstroutid; /* Variable ID for configuration */ 00139 size_t start[1]; /* Start element when writing */ 00140 size_t count[1]; /* Count of elements to write */ 00141 00142 int t; /* Time loop counter */ 00143 int tl; /* Time loop counter */ 00144 int var; /* Variable counter */ 00145 int vare; /* Variable counter */ 00146 int istat; /* Diagnostic status */ 00147 int f; /* Loop counter for files */ 00148 int i; /* Loop counter */ 00149 int j; /* Loop counter */ 00150 00151 double curtime; 00152 00153 int ncoutid; 00154 ut_system *unitSystem = NULL; /* Unit System (udunits) */ 00155 ut_unit *dataunits = NULL; /* udunits variable */ 00156 00157 double period_begin; 00158 double period_end; 00159 00160 int year; 00161 int month; 00162 int day; 00163 int hour; 00164 int minutes; 00165 double seconds; 00166 00167 int yy; 00168 int mm; 00169 int dd; 00170 int hh; 00171 00172 int minh; 00173 int maxh; 00174 00175 char *tmpstr = NULL; 00176 short int tas_correction = TRUE; 00177 00178 /* J F M A M J J A S O N D */ 00179 static int days_per_month_reg_year[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 00180 00181 infile = (char **) malloc(obs_var->nobs_var * sizeof(char *)); 00182 if (infile == NULL) alloc_error(__FILE__, __LINE__); 00183 outfile = (char **) malloc(obs_var->nobs_var * sizeof(char *)); 00184 if (outfile == NULL) alloc_error(__FILE__, __LINE__); 00185 outfiles = (char ***) malloc(obs_var->nobs_var * sizeof(char **)); 00186 if (outfiles == NULL) alloc_error(__FILE__, __LINE__); 00187 buf = (double **) malloc(obs_var->nobs_var * sizeof(double *)); 00188 if (buf == NULL) alloc_error(__FILE__, __LINE__); 00189 for (i=0; i<obs_var->nobs_var; i++) 00190 buf[i] = NULL; 00191 if ( !strcmp(info->timestep, "daily") && !strcmp(obs_var->frequency, "hourly") ) { 00192 bufsave = (double **) malloc(obs_var->nobs_var * sizeof(double *)); 00193 if (bufsave == NULL) alloc_error(__FILE__, __LINE__); 00194 } 00195 found_file = (int *) malloc(obs_var->nobs_var * sizeof(int)); 00196 if (found_file == NULL) alloc_error(__FILE__, __LINE__); 00197 noutf = (int *) malloc(obs_var->nobs_var * sizeof(int)); 00198 if (noutf == NULL) alloc_error(__FILE__, __LINE__); 00199 info_tmp = (info_field_struct **) malloc(obs_var->nobs_var * sizeof(info_field_struct *)); 00200 if (info_tmp == NULL) alloc_error(__FILE__, __LINE__); 00201 00202 found = FALSE; 00203 for (var=0; var<obs_var->nobs_var; var++) { 00204 infile[var] = (char *) malloc(MAXPATH * sizeof(char)); 00205 if (infile[var] == NULL) alloc_error(__FILE__, __LINE__); 00206 outfile[var] = (char *) malloc(MAXPATH * sizeof(char)); 00207 if (outfile[var] == NULL) alloc_error(__FILE__, __LINE__); 00208 found_file[var] = FALSE; 00209 } 00210 format = (char *) malloc(MAXPATH * sizeof(char)); 00211 if (format == NULL) alloc_error(__FILE__, __LINE__); 00212 00213 if (output_month_begin == 1) 00214 output_month_end = 12; 00215 else 00216 output_month_end = output_month_begin - 1; 00217 00218 if (obs_var->proj->name != NULL) 00219 (void) free(obs_var->proj->name); 00220 obs_var->proj->name = NULL; 00221 00222 /* Initialize udunits */ 00223 ut_set_error_message_handler(ut_ignore); 00224 unitSystem = ut_read_xml(NULL); 00225 ut_set_error_message_handler(ut_write_to_stderr); 00226 dataunits = ut_parse(unitSystem, time_units, UT_ASCII); 00227 00228 /* Read altitudes if available, and compute pressure using standard atmosphere */ 00229 if ( strcmp(obs_var->altitude, "") ) { 00230 infile_alt = (char *) malloc(MAXPATH * sizeof(char)); 00231 if (infile_alt == NULL) alloc_error(__FILE__, __LINE__); 00232 (void) sprintf(infile_alt, "%s/%s", obs_var->path, obs_var->altitude); 00233 istat = read_netcdf_var_2d(&alt, (info_field_struct *) NULL, (proj_struct *) NULL, infile_alt, obs_var->altitudename, 00234 obs_var->dimxname, obs_var->dimyname, &nlon, &nlat, FALSE); 00235 if (istat < 0) 00236 (void) fprintf(stderr, "%s: WARNING: Cannot read observation altitude field in file %s.\n", __FILE__, infile_alt); 00237 else { 00238 pmsl = (double *) malloc(nlon*nlat*sizeof(double)); 00239 if (pmsl == NULL) alloc_error(__FILE__, __LINE__); 00240 (void) alt_to_press(pmsl, alt, nlon, nlat); 00241 } 00242 (void) free(infile_alt); 00243 } 00244 00245 /* Compute time limits for writing */ 00246 if (period->year_begin != -1) { 00247 (void) printf("%s: Downscaling output from %02d/%02d/%04d to %02d/%02d/%04d inclusively.\n", __FILE__, 00248 period->month_begin, period->day_begin, period->year_begin, 00249 period->month_end, period->day_end, period->year_end); 00250 istat = utInvCalendar2(period->year_begin, period->month_begin, period->day_begin, 0, 0, 0.0, dataunits, &period_begin); 00251 istat = utInvCalendar2(period->year_end, period->month_end, period->day_end, 23, 59, 0.0, dataunits, &period_end); 00252 } 00253 else { 00254 istat = utCalendar2(time_ls[0], dataunits, &year, &month, &day, &hour, &minutes, &seconds); 00255 (void) printf("%s: Downscaling whole period: %02d/%02d/%04d", __FILE__, month, day, year); 00256 istat = utCalendar2(time_ls[ntime-1], dataunits, &year, &month, &day, &hour, &minutes, &seconds); 00257 (void) printf(" to %02d/%02d/%04d inclusively.\n", month, day, year); 00258 period_begin = time_ls[0]; 00259 period_end = time_ls[ntime-1]; 00260 } 00261 00262 /* Process each downscaled day */ 00263 for (var=0; var<obs_var->nobs_var; var++) { 00264 noutf[var] = 0; 00265 outfiles[var] = NULL; 00266 } 00267 for (t=0; t<ntime; t++) { 00268 00269 /* Check if we want to write data for this date */ 00270 if (time_ls[t] >= period_begin && time_ls[t] <= period_end) { 00271 00272 /* Create output filename for writing data */ 00273 if (analog_days.month_s[t] < output_month_begin) 00274 year1 = analog_days.year_s[t] - 1; 00275 else 00276 year1 = analog_days.year_s[t]; 00277 if (output_month_begin != 1) 00278 year2 = year1 + 1; 00279 else 00280 year2 = year1; 00281 /* Process each variable and create output filenames, and output files if necessary */ 00282 for (var=0; var<obs_var->nobs_var; var++) { 00283 /* Example: evapn_1d_19790801_19800731.nc */ 00284 (void) sprintf(outfile[var], "%s/%s_1d_%04d%02d%02d_%04d%02d%02d.nc", output_path, obs_var->netcdfname[var], 00285 year1, output_month_begin, 1, 00286 year2, output_month_end, days_per_month_reg_year[output_month_end-1]); 00287 /* Check if output file has already been created */ 00288 found_file[var] = FALSE; 00289 f = 0; 00290 while (f < noutf[var] && found_file[var] == FALSE) { 00291 if ( !strcmp(outfiles[var][f], outfile[var]) ) { 00292 found_file[var] = TRUE; 00293 break; 00294 } 00295 f++; 00296 } 00297 if (found_file[var] == FALSE) { 00298 00299 if ( !strcmp(obs_var->output[var], "yes") ) { 00300 00301 /* File was not created already by this algorithm run */ 00302 outfiles[var] = (char **) realloc(outfiles[var], (noutf[var]+1) * sizeof(char *)); 00303 if (outfiles[var] == NULL) alloc_error(__FILE__, __LINE__); 00304 outfiles[var][noutf[var]++] = strdup(outfile[var]); 00305 00306 /* Verify if file exists and if we can write into it */ 00307 istat = nc_open(outfile[var], NC_WRITE, &ncoutid); 00308 00309 if (istat != NC_NOERR) { 00310 /* File does not exists */ 00311 00312 /* Create output file */ 00313 istat = create_netcdf(info->title, info->title_french, info->summary, info->summary_french, 00314 info->keywords, info->processor, info->software, 00315 info->description, info->institution, 00316 info->creator_email, info->creator_url, info->creator_name, 00317 info->version, info->scenario, info->scenario_co2, info->model, 00318 info->institution_model, info->country, info->member, 00319 info->downscaling_forcing, info->contact_email, info->contact_name, 00320 info->other_contact_email, info->other_contact_name, 00321 outfile[var], TRUE, file_format, file_compression); 00322 if (istat != 0) { 00323 /* In case of failure */ 00324 (void) free(outfile[var]); 00325 for (f=0; f<noutf[var]; f++) 00326 (void) free(outfiles[var][f]); 00327 if (noutf[var] > 0) 00328 (void) free(outfiles[var]); 00329 if (pmsl != NULL) (void) free(pmsl); 00330 if (alt != NULL) (void) free(alt); 00331 (void) ut_free(dataunits); 00332 (void) ut_free_system(unitSystem); 00333 return istat; 00334 } 00335 00338 istat = nc_open(outfile[var], NC_WRITE, &ncoutid); /* open NetCDF file */ 00339 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00340 00341 /* Go into redefine mode */ 00342 istat = nc_redef(ncoutid); 00343 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00344 00345 /* Define configuration */ 00346 istat = nc_def_dim(ncoutid, "configstr", strlen(config)+1, &configstrdimid); 00347 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00348 istat = nc_def_var(ncoutid, "dsclim_configuration", NC_CHAR, 1, &configstrdimid, &configstroutid); 00349 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00350 00351 /* Update also time_coverage_end and time_coverage_start global attribute */ 00352 tmpstr = (char *) malloc(MAXPATH * sizeof(char)); 00353 if (tmpstr == NULL) alloc_error(__FILE__, __LINE__); 00354 hour=0; 00355 minutes=0; 00356 seconds=0; 00357 (void) sprintf(tmpstr, "%04d-%02d-%02dT%02d:%02d:%02dZ", year1, output_month_begin, 1, hour, minutes, (int) seconds); 00358 istat = nc_put_att_text(ncoutid, NC_GLOBAL, "time_coverage_start", strlen(tmpstr), tmpstr); 00359 hour=23; 00360 minutes=59; 00361 seconds=59; 00362 (void) sprintf(tmpstr, "%04d-%02d-%02dT%02d:%02d:%02dZ", year2, output_month_end, days_per_month_reg_year[output_month_end-1], 00363 hour, minutes, (int) seconds); 00364 istat = nc_put_att_text(ncoutid, NC_GLOBAL, "time_coverage_end", strlen(tmpstr), tmpstr); 00365 (void) free(tmpstr); 00366 00367 /* End definition mode */ 00368 istat = nc_enddef(ncoutid); 00369 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00370 00371 /* Write configuration */ 00372 start[0] = 0; 00373 count[0] = strlen(config) + 1; 00374 istat = nc_put_vara_text(ncoutid, configstroutid, start, count, config); 00375 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00376 } 00377 else 00378 found_file[var] = TRUE; 00379 00380 /* Close the output netCDF file. */ 00381 istat = ncclose(ncoutid); 00382 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00383 } 00384 } 00385 } 00386 00387 /* Create input filename for reading data */ 00388 (void) strcpy(format, "%s/%s/"); 00389 (void) strcat(format, obs_var->template); 00390 if (obs_var->month_begin != 1) { 00391 /* Months in observation files *does not* begin in January: must have 2 years in filename */ 00392 if (analog_days.month[t] < obs_var->month_begin) 00393 year1 = analog_days.year[t] - 1; 00394 else 00395 year1 = analog_days.year[t]; 00396 year2 = year1 + 1; 00397 if (obs_var->year_digits == 4) 00398 /* Process each variable and create input filenames */ 00399 for (var=0; var<obs_var->nobs_var; var++) 00400 (void) sprintf(infile[var], format, obs_var->path, obs_var->frequency, 00401 obs_var->acronym[var], year1, year2); 00402 else { 00403 tmpi = year1 / 100; 00404 year1 = year1 - (tmpi*100); 00405 tmpi = year2 / 100; 00406 year2 = year2 - (tmpi*100); 00407 /* Process each variable and create input filenames */ 00408 for (var=0; var<obs_var->nobs_var; var++) 00409 (void) sprintf(infile[var], format, obs_var->path, obs_var->frequency, 00410 obs_var->acronym[var], year1, year2); 00411 } 00412 } 00413 else { 00414 /* Months in observation files begins in January: must have 1 year in filename */ 00415 year1 = analog_days.year[t]; 00416 if (obs_var->year_digits == 4) 00417 /* Process each variable and create input filenames */ 00418 for (var=0; var<obs_var->nobs_var; var++) 00419 (void) sprintf(infile[var], format, obs_var->path, obs_var->frequency, 00420 obs_var->acronym[var], year1); 00421 else { 00422 tmpi = year1 / 100; 00423 year1 = year1 - (tmpi*100); 00424 /* Process each variable and create input filenames */ 00425 for (var=0; var<obs_var->nobs_var; var++) 00426 (void) sprintf(infile[var], format, obs_var->path, obs_var->frequency, 00427 obs_var->acronym[var], year1); 00428 } 00429 } 00430 00431 /* Get time information for first input observation file and assume all files are alike */ 00432 time_s = (time_vect_struct *) malloc(sizeof(time_vect_struct)); 00433 if (time_s == NULL) alloc_error(__FILE__, __LINE__); 00434 istat = get_time_info(time_s, &timeval, &time_units_tmp, &cal_type_tmp, &ntime_obs, infile[0], obs_var->timename, FALSE); 00435 (void) free(cal_type_tmp); 00436 (void) free(time_units_tmp); 00437 (void) free(timeval); 00438 if (istat < 0) { 00439 for (var=0; var<obs_var->nobs_var; var++) { 00440 (void) free(outfile[var]); 00441 for (f=0; f<noutf[var]; f++) { 00442 (void) free(outfiles[var][f]); 00443 } 00444 if (noutf[var] > 0) { 00445 (void) free(outfiles[var]); 00446 } 00447 } 00448 (void) free(time_s); 00449 if (pmsl != NULL) (void) free(pmsl); 00450 if (alt != NULL) (void) free(alt); 00451 (void) ut_free(dataunits); 00452 (void) ut_free_system(unitSystem); 00453 return istat; 00454 } 00455 00456 /* Find date in observation database */ 00457 #if DEBUG > 7 00458 (void) printf("Processing %d %d %d %d\n",t,analog_days.year_s[t],analog_days.month_s[t],analog_days.day_s[t]); 00459 #endif 00460 00461 if ( !strcmp(obs_var->frequency, "hourly") ) { 00462 /* For hourly frequency data, find hours from 0 to 23 */ 00463 minh = 0; 00464 maxh = 23; 00465 } 00466 else { 00467 /* For daily data, only read data for one day */ 00468 minh = 0; 00469 maxh = 0; 00470 } 00471 00472 /* Loop over hours if needed */ 00473 for (hour=minh; hour<=maxh; hour++) { 00474 found = FALSE; 00475 tl = 0; 00476 00477 if ( !strcmp(obs_var->frequency, "hourly") ) { 00478 while (tl<ntime_obs && found == FALSE) { 00479 #if DEBUG > 7 00480 (void) printf("%d %d %d %d %d\n",tl,time_s->year[tl],time_s->month[tl],time_s->day[tl],time_s->hour[tl]); 00481 #endif 00482 if (analog_days.year[t] == time_s->year[tl] && analog_days.month[t] == time_s->month[tl] && 00483 analog_days.day[t] == time_s->day[tl] && hour == time_s->hour[tl]) { 00484 found = TRUE; 00485 #if DEBUG > 7 00486 (void) printf("Found analog %d %d %d %d\n",tl,analog_days.year[t],analog_days.month[t],analog_days.day[t]); 00487 #endif 00488 } 00489 tl++; 00490 } 00491 } 00492 else { 00493 while (tl<ntime_obs && found == FALSE) { 00494 #if DEBUG > 7 00495 (void) printf("%d %d %d %d\n",tl,time_s->year[tl],time_s->month[tl],time_s->day[tl]); 00496 #endif 00497 if (analog_days.year[t] == time_s->year[tl] && analog_days.month[t] == time_s->month[tl] && 00498 analog_days.day[t] == time_s->day[tl]) { 00499 found = TRUE; 00500 #if DEBUG > 7 00501 (void) printf("Found analog %d %d %d %d\n",tl,analog_days.year[t],analog_days.month[t],analog_days.day[t]); 00502 #endif 00503 } 00504 tl++; 00505 } 00506 } 00507 00508 if (found == TRUE) { 00509 00510 tl--; 00511 00512 proj_tmp = (proj_struct *) malloc(sizeof(proj_struct)); 00513 if (proj_tmp == NULL) alloc_error(__FILE__, __LINE__); 00514 proj_tmp->name = NULL; 00515 proj_tmp->grid_mapping_name = NULL; 00516 00517 /* Process each variable and read data */ 00518 for (var=0; var<obs_var->nobs_var; var++) { 00519 info_tmp[var] = (info_field_struct *) malloc(sizeof(info_field_struct)); 00520 if (info_tmp[var] == NULL) alloc_error(__FILE__, __LINE__); 00521 /* Don't read variables which will be calculated : read only variables already available in datafiles */ 00522 if ( !strcmp(obs_var->post[var], "no") ) { 00523 if (proj_tmp->name != NULL) { 00524 (void) free(proj_tmp->name); 00525 proj_tmp->name = NULL; 00526 } 00527 if (proj_tmp->grid_mapping_name != NULL) { 00528 (void) free(proj_tmp->grid_mapping_name); 00529 proj_tmp->grid_mapping_name = NULL; 00530 } 00531 istat = read_netcdf_var_3d_2d(&(buf[var]), info_tmp[var], proj_tmp, infile[var], obs_var->acronym[var], 00532 obs_var->dimxname, obs_var->dimyname, obs_var->timename, 00533 tl, &nlon, &nlat, &ntime_file, debug); 00534 /* Apply factor and delta */ 00535 for (j=0; j<nlat; j++) 00536 for (i=0; i<nlon; i++) 00537 buf[var][i+j*nlon] = (buf[var][i+j*nlon] * obs_var->factor[var]) + obs_var->delta[var]; 00538 /* Overwrite units and height if it was specified in configuration file. In that case, the value is not unknown. */ 00539 if ( strcmp(obs_var->units[var], "unknown")) { 00540 (void) free(info_tmp[var]->units); 00541 info_tmp[var]->units = strdup(obs_var->units[var]); 00542 } 00543 if ( strcmp(obs_var->height[var], "unknown")) { 00544 (void) free(info_tmp[var]->height); 00545 info_tmp[var]->height = strdup(obs_var->height[var]); 00546 } 00547 } 00548 else { 00549 /* For post-processing variables, must fill in the info field structure info_tmp. 00550 The projection structure proj_tmp used is the one of the previous variable, 00551 because the first variable in the list is enforced to be a non post-processing variable 00552 when loading the configuration file. */ 00553 info_tmp[var]->fillvalue = info_tmp[0]->fillvalue; 00554 info_tmp[var]->coordinates = strdup(info_tmp[0]->coordinates); 00555 info_tmp[var]->grid_mapping = strdup(info_tmp[0]->grid_mapping); 00556 info_tmp[var]->units = strdup(obs_var->units[var]); 00557 info_tmp[var]->height = strdup(obs_var->height[var]); 00558 info_tmp[var]->long_name = strdup(obs_var->name[var]); 00559 } 00560 } 00561 00562 if (obs_var->proj->name == NULL) { 00563 /* Retrieve observation grid parameters if not done already */ 00564 obs_var->proj->name = strdup(proj_tmp->name); 00565 obs_var->proj->grid_mapping_name = strdup(proj_tmp->grid_mapping_name); 00566 obs_var->proj->latin1 = proj_tmp->latin1; 00567 obs_var->proj->latin2 = proj_tmp->latin2; 00568 obs_var->proj->lonc = proj_tmp->lonc; 00569 obs_var->proj->lat0 = proj_tmp->lat0; 00570 obs_var->proj->false_easting = proj_tmp->false_easting; 00571 obs_var->proj->false_northing = proj_tmp->false_northing; 00572 00573 /* Get latitude and longitude coordinates information from first file */ 00574 istat = read_netcdf_latlon(&lon, &lat, &nlon, &nlat, obs_var->dimcoords, obs_var->proj->coords, 00575 obs_var->proj->name, obs_var->lonname, 00576 obs_var->latname, obs_var->dimxname, 00577 obs_var->dimyname, infile[0]); 00578 if ( !strcmp(obs_var->proj->name, "list") ) 00579 /* List of lat + lon points only : keep only X dimension */ 00580 nlat = 0; 00581 else 00582 /* Read coordinates information */ 00583 istat = read_netcdf_xy(&x, &y, &nlon, &nlat, obs_var->dimxname, obs_var->dimyname, 00584 obs_var->dimxname, obs_var->dimyname, infile[0]); 00585 } 00586 00587 /*** Apply modifications to data ***/ 00590 /* Find known variable IDs for correction or calculation */ 00591 varid_tas = find_str_value("tas", obs_var->netcdfname, obs_var->nobs_var); 00592 varid_tasmin = find_str_value("tasmin", obs_var->netcdfname, obs_var->nobs_var); 00593 varid_tasmax = find_str_value("tasmax", obs_var->netcdfname, obs_var->nobs_var); 00594 varid_prsn = find_str_value("prsn", obs_var->netcdfname, obs_var->nobs_var); 00595 varid_prr = find_str_value("prr", obs_var->netcdfname, obs_var->nobs_var); 00596 varid_rlds = find_str_value("rlds", obs_var->netcdfname, obs_var->nobs_var); 00597 varid_rsds = find_str_value("rsds", obs_var->netcdfname, obs_var->nobs_var); 00598 varid_hus = find_str_value("hus", obs_var->netcdfname, obs_var->nobs_var); 00599 varid_husmin = find_str_value("husmin", obs_var->netcdfname, obs_var->nobs_var); 00600 varid_husmax = find_str_value("husmax", obs_var->netcdfname, obs_var->nobs_var); 00601 varid_uvas = find_str_value("uvas", obs_var->netcdfname, obs_var->nobs_var); 00602 varid_hur = find_str_value("hur", obs_var->netcdfname, obs_var->nobs_var); 00603 varid_etp = find_str_value("evapn", obs_var->netcdfname, obs_var->nobs_var); 00604 varid_prtot = find_str_value("prtot", obs_var->netcdfname, obs_var->nobs_var); 00605 00606 tas_correction = TRUE; 00607 00608 if ( (varid_tasmax >= 0 || varid_tasmin >= 0 || varid_husmin >= 0 || varid_husmax >= 0) && !strcmp(obs_var->frequency, "hourly")) { 00609 (void) fprintf(stderr, "%s: WARNING: Cannot mix min and/or max observation variables with hourly data! Min and/or max variables will be ignored! \n", __FILE__); 00610 varid_tasmin = -1; 00611 varid_tasmax = -1; 00612 varid_husmin = -1; 00613 varid_husmax = -1; 00614 } 00615 00616 if ( !strcmp(obs_var->frequency, "daily") ) { 00617 if (varid_tas < 0 && ( varid_tasmin < 0 || varid_tasmax < 0 ) ) 00618 tas_correction = FALSE; 00619 } 00620 else { 00621 if (varid_tas < 0) 00622 tas_correction = FALSE; 00623 } 00624 00625 // (void) fprintf(stderr, "%s: WARNING: No temperature correction can be done to precipitation partition or infra-red radiation required temperature variables are not available! It needs at least either average daily or hourly temperature, or, with daily data, min and max temperatures.\n", __FILE__); 00626 00627 /* Correct average temperature and related variables (precipitation partition, infra-red radiation) */ 00628 if (varid_tas >= 0 && tas_correction == TRUE) { 00629 if (fabs(delta[t]) >= deltat) 00630 for (j=0; j<nlat; j++) 00631 for (i=0; i<nlon; i++) 00632 00633 if (buf[varid_tas][i+j*nlon] != info_tmp[varid_tas]->fillvalue) { 00634 00635 /* Save non-corrected temperature */ 00636 curtas = buf[varid_tas][i+j*nlon]; 00637 /* Compute new temperature */ 00638 buf[varid_tas][i+j*nlon] += delta[t]; 00639 00640 /* Compute new rain/snow partition, if needed */ 00641 if (varid_prsn != -1 && varid_prr != -1) 00642 if (buf[varid_prsn][i+j*nlon] != info_tmp[varid_prsn]->fillvalue && 00643 buf[varid_prr][i+j*nlon] != info_tmp[varid_prr]->fillvalue) 00644 if ( buf[varid_tas][i+j*nlon] >= (K_TKELVIN + 1.5) ) { 00645 buf[varid_prr][i+j*nlon] += buf[varid_prsn][i+j*nlon]; 00646 buf[varid_prsn][i+j*nlon] = 0.0; 00647 } 00648 00649 /* Compute new infra-red radiation, if needed */ 00650 if (varid_rlds != -1) 00651 if (buf[varid_rlds][i+j*nlon] != info_tmp[varid_rlds]->fillvalue) 00652 buf[varid_rlds][i+j*nlon] += (4.0 * delta[t] / curtas ) * buf[varid_rlds][i+j*nlon]; 00653 00654 } 00655 } 00656 00657 /* Correct min and max temperatures and related variables when having daily data */ 00658 if (varid_tasmax >= 0 && varid_tasmin >= 0 && tas_correction == TRUE && !strcmp(obs_var->frequency, "daily")) { 00659 if (fabs(delta[t]) >= deltat) 00660 for (j=0; j<nlat; j++) 00661 for (i=0; i<nlon; i++) 00662 00663 if (buf[varid_tasmax][i+j*nlon] != info_tmp[varid_tasmax]->fillvalue) { 00664 00665 /* Save non-corrected mean temperature */ 00666 curtas = (buf[varid_tasmax][i+j*nlon] + buf[varid_tasmin][i+j*nlon]) / 2.0; 00667 /* Compute new temperature */ 00668 buf[varid_tasmax][i+j*nlon] += delta[t]; 00669 buf[varid_tasmin][i+j*nlon] += delta[t]; 00670 /* New averaged temperature */ 00671 newcurtas = (buf[varid_tasmax][i+j*nlon] + buf[varid_tasmin][i+j*nlon]) / 2.0; 00672 00673 /* Do not perform correction twice! */ 00674 if (varid_tas < 0) { 00675 /* Compute new rain/snow partition, if needed */ 00676 if (varid_prsn != -1 && varid_prr != -1) 00677 if (buf[varid_prsn][i+j*nlon] != info_tmp[varid_prsn]->fillvalue && 00678 buf[varid_prr][i+j*nlon] != info_tmp[varid_prr]->fillvalue) 00679 if ( newcurtas >= (K_TKELVIN + 1.5) ) { 00680 buf[varid_prr][i+j*nlon] += buf[varid_prsn][i+j*nlon]; 00681 buf[varid_prsn][i+j*nlon] = 0.0; 00682 } 00683 00684 /* Compute new infra-red radiation, if needed */ 00685 if (varid_rlds != -1) 00686 if (buf[varid_rlds][i+j*nlon] != info_tmp[varid_rlds]->fillvalue) 00687 buf[varid_rlds][i+j*nlon] += (4.0 * delta[t] / curtas ) * buf[varid_rlds][i+j*nlon]; 00688 } 00689 } 00690 } 00691 00692 /* Calculate only known post-processed variables */ 00693 00694 if (varid_hur >= 0) { 00695 /* Relative humidity */ 00696 if ( !strcmp(obs_var->post[varid_hur], "yes") ) { 00697 if ( varid_hus >= 0 && (varid_tas >= 0 || (varid_tasmax >= 0 && varid_tasmin >= 0 )) && pmsl != NULL ) { 00698 /* Calculate relative humidity from temperature and specific humidity */ 00699 buf[varid_hur] = (double *) malloc(nlat*nlon * sizeof(double)); 00700 if (buf[varid_hur] == NULL) alloc_error(__FILE__, __LINE__); 00701 if (varid_tas >= 0) 00702 info_tmp[varid_hur]->fillvalue = info_tmp[varid_tas]->fillvalue; 00703 else if (varid_tasmax >= 0) 00704 info_tmp[varid_hur]->fillvalue = info_tmp[varid_tasmax]->fillvalue; 00705 else 00706 info_tmp[varid_hur]->fillvalue = -9999.0; 00707 /* Create mean temperature temporary matrix when having only min and max temperature */ 00708 if (varid_tas < 0) { 00709 buftmp = (double *) malloc(nlat*nlon* sizeof(double)); 00710 if (buftmp == NULL) alloc_error(__FILE__, __LINE__); 00711 info_tmp[varid_tas]->fillvalue = info_tmp[varid_tasmax]->fillvalue; 00712 for (i=0; i<(nlon*nlat); i++) 00713 if ((buf[varid_tasmax][i] != info_tmp[varid_tasmax]->fillvalue) && 00714 (buf[varid_tasmin][i] != info_tmp[varid_tasmin]->fillvalue)) 00715 buftmp[i] = (buf[varid_tasmax][i] + buf[varid_tasmin][i]) / 2.0; 00716 else 00717 buftmp[i] = info_tmp[varid_tas]->fillvalue; 00718 } 00719 else 00720 buftmp = buf[varid_tas]; 00721 (void) spechum_to_hr(buf[varid_hur], buftmp, buf[varid_hus], pmsl, info_tmp[varid_hur]->fillvalue, nlon, nlat); 00722 if (varid_tas < 0) 00723 (void) free(buftmp); 00724 } 00725 else { 00726 (void) fprintf(stderr, "%s: WARNING: Cannot calculate Relative Humidity because needed variables are not available: Specific Humidity; Averaged temperature or Min/Max temperature, Standard Pressure from altitude.\n", __FILE__); 00727 buf[varid_hur] = NULL; 00728 } 00729 } 00730 } 00731 00732 if (varid_prsn >= 0 && varid_prr >= 0 && varid_prtot >= 0) { 00733 /* Total precipitation */ 00734 if ( !strcmp(obs_var->post[varid_prtot], "yes") ) { 00735 /* Calculate total precipitation from liquid and solid precipitation */ 00736 buf[varid_prtot] = (double *) malloc(nlat*nlon * sizeof(double)); 00737 if (buf[varid_prtot] == NULL) alloc_error(__FILE__, __LINE__); 00738 info_tmp[varid_prtot]->fillvalue = info_tmp[varid_prr]->fillvalue; 00739 for (i=0; i<(nlon*nlat); i++) { 00740 if ( (buf[varid_prr][i] != info_tmp[varid_prr]->fillvalue) && (buf[varid_prsn][i] != info_tmp[varid_prsn]->fillvalue)) 00741 buf[varid_prtot][i] = buf[varid_prr][i] + buf[varid_prsn][i]; 00742 else 00743 buf[varid_prtot][i] = info_tmp[varid_prtot]->fillvalue; 00744 } 00745 } 00746 else { 00747 (void) fprintf(stderr, "%s: WARNING: Cannot calculate Total Precipitation because needed variables are not available: Liquid and Solid Precipitation.\n", __FILE__); 00748 buf[varid_prtot] = NULL; 00749 } 00750 } 00751 00752 if (varid_etp >= 0) { 00753 /* ETP */ 00754 if ( !strcmp(obs_var->post[varid_etp], "yes") ) { 00755 if ( varid_hus >= 0 && (varid_tas >= 0 || (varid_tasmax >= 0 && varid_tasmin >= 0 )) && varid_rsds >= 0 && varid_rlds >= 0 && 00756 varid_uvas >= 0 && pmsl != NULL ) { 00757 /* Calculate ETP */ 00758 buf[varid_etp] = (double *) malloc(nlat*nlon * sizeof(double)); 00759 if (buf[varid_etp] == NULL) alloc_error(__FILE__, __LINE__); 00760 if (varid_tas >= 0) 00761 info_tmp[varid_etp]->fillvalue = info_tmp[varid_tas]->fillvalue; 00762 else if (varid_tasmax >= 0) 00763 info_tmp[varid_etp]->fillvalue = info_tmp[varid_tasmax]->fillvalue; 00764 else 00765 info_tmp[varid_etp]->fillvalue = -9999.0; 00766 /* Create mean temperature temporary matrix when having only min and max temperature */ 00767 if (varid_tas < 0) { 00768 buftmp = (double *) malloc(nlat*nlon* sizeof(double)); 00769 if (buftmp == NULL) alloc_error(__FILE__, __LINE__); 00770 for (i=0; i<(nlon*nlat); i++) { 00771 if ((buf[varid_tasmax][i] != info_tmp[varid_tasmax]->fillvalue) && 00772 (buf[varid_tasmin][i] != info_tmp[varid_tasmin]->fillvalue)) 00773 buftmp[i] = (buf[varid_tasmax][i] + buf[varid_tasmin][i]) / 2.0; 00774 else 00775 buftmp[i] = info_tmp[varid_tasmax]->fillvalue; 00776 } 00777 } 00778 else 00779 buftmp = buf[varid_tas]; 00780 (void) calc_etp_mf(buf[varid_etp], buftmp, buf[varid_hus], buf[varid_rsds], buf[varid_rlds], buf[varid_uvas], 00781 pmsl, info_tmp[varid_etp]->fillvalue, nlon, nlat); 00782 if (varid_tas < 0) 00783 (void) free(buftmp); 00784 } 00785 else { 00786 (void) fprintf(stderr, "%s: WARNING: Cannot calculate ETP because needed variables are not available: Specific Humidity; Averaged Temperature or Min/Max Temperature; Short and Long Wave Radiation; Wind Module, Standard Pressure from altitude.\n", __FILE__); 00787 buf[varid_etp] = NULL; 00788 } 00789 } 00790 } 00791 00792 /* Process each variable for writing */ 00793 for (var=0; var<obs_var->nobs_var; var++) { 00794 if ( !strcmp(obs_var->output[var], "yes") ) { 00795 /* Write dimensions of field in newly-created NetCDF output file */ 00796 if (found_file[var] == FALSE && hour == minh && buf[var] != NULL) { 00797 /* We just created output file: we need to write dimensions */ 00798 ctimeval[0] = time_ls[t]; 00799 istat = write_netcdf_dims_3d(lon, lat, x, y, alt, ctimeval, cal_type, 00800 time_units, nlon, nlat, 0, 00801 info->timestep, obs_var->proj->name, obs_var->proj->coords, 00802 obs_var->proj->grid_mapping_name, obs_var->proj->latin1, 00803 obs_var->proj->latin2, obs_var->proj->lonc, obs_var->proj->lat0, 00804 obs_var->proj->false_easting, obs_var->proj->false_northing, 00805 obs_var->proj->lonpole, obs_var->proj->latpole, 00806 obs_var->lonname, obs_var->latname, obs_var->timename, 00807 outfile[var], debug); 00808 if (istat != 0) { 00809 /* In case of failure */ 00810 (void) free(time_s->year); 00811 (void) free(time_s->month); 00812 (void) free(time_s->day); 00813 (void) free(time_s->hour); 00814 (void) free(time_s->minutes); 00815 (void) free(time_s->seconds); 00816 00817 (void) free(time_s); 00818 00819 (void) free(infile[var]); 00820 (void) free(outfile[var]); 00821 (void) free(info_tmp[var]->grid_mapping); 00822 (void) free(info_tmp[var]->units); 00823 (void) free(info_tmp[var]->height); 00824 (void) free(info_tmp[var]->coordinates); 00825 (void) free(info_tmp[var]->long_name); 00826 (void) free(info_tmp[var]); 00827 (void) free(proj_tmp->name); 00828 (void) free(proj_tmp->grid_mapping_name); 00829 (void) free(proj_tmp); 00830 for (f=0; f<noutf[var]; f++) 00831 (void) free(outfiles[var][f]); 00832 if (noutf[var] > 0) 00833 (void) free(outfiles[var]); 00834 (void) free(outfiles); 00835 if (pmsl != NULL) (void) free(pmsl); 00836 if (alt != NULL) (void) free(alt); 00837 (void) ut_free(dataunits); 00838 (void) ut_free_system(unitSystem); 00839 return istat; 00840 } 00841 } 00842 } 00843 } 00844 00845 /* Compute time if output timestep is hourly and not daily */ 00846 if ( !strcmp(info->timestep, "hourly") ) { 00847 istat = utCalendar2(time_ls[t], dataunits, &yy, &mm, &dd, &hh, &minutes, &seconds); 00848 istat = utInvCalendar2(yy, mm, dd, hour, 0, 0.0, dataunits, &curtime); 00849 } 00850 else 00851 curtime = time_ls[t]; 00852 00853 /* Process each variable */ 00854 for (var=0; var<obs_var->nobs_var; var++) { 00855 if (buf[var] != NULL && !strcmp(obs_var->output[var], "yes")) { 00856 if ( !strcmp(info->timestep, obs_var->frequency) ) { 00857 /* Output and input data are at same frequency */ 00858 if (found_file[var] == FALSE && hour == minh) 00859 (void) fprintf(stderr, "%s: Writing data to %s\n", __FILE__, outfile[var]); 00860 /* Write data */ 00861 istat = write_netcdf_var_3d_2d(buf[var], &curtime, info_tmp[var]->fillvalue, outfile[var], obs_var->netcdfname[var], 00862 info_tmp[var]->long_name, info_tmp[var]->units, info_tmp[var]->height, proj_tmp->name, 00863 obs_var->dimxname, obs_var->dimyname, obs_var->timename, 00864 0, !(found_file[var]), file_format, file_compression_level, 00865 nlon, nlat, ntime_file, debug); 00866 found_file[var] = TRUE; 00867 } 00868 else if ( !strcmp(info->timestep, "daily") && !strcmp(obs_var->frequency, "hourly") ) { 00869 if (hour == maxh) { 00870 /* Last hour of day */ 00871 for (i=0; i<nlon*nlat; i++) 00872 /* Average data */ 00873 buf[var][i] = (bufsave[var][i] + buf[var][i]) / 24.0; 00874 /* Free memory */ 00875 (void) free(bufsave[var]); 00876 bufsave[var] = NULL; 00877 if (found_file[var] == FALSE && hour == minh) 00878 (void) fprintf(stderr, "%s: Writing data to %s\n",__FILE__, outfile[var]); 00879 /* Write data */ 00880 istat = write_netcdf_var_3d_2d(buf[var], &curtime, info_tmp[var]->fillvalue, outfile[var], obs_var->netcdfname[var], 00881 info_tmp[var]->long_name, info_tmp[var]->units, info_tmp[var]->height, proj_tmp->name, 00882 obs_var->dimxname, obs_var->dimyname, obs_var->timename, 00883 0, !(found_file[var]), file_format, file_compression_level, 00884 nlon, nlat, ntime_file, debug); 00885 found_file[var] = TRUE; 00886 } 00887 else { 00888 /* Allocate memory if first hour accumulating */ 00889 if (bufsave[var] == NULL) { 00890 bufsave[var] = (double *) calloc(nlat*nlon, sizeof(double)); 00891 if (bufsave[var] == NULL) alloc_error(__FILE__, __LINE__); 00892 } 00893 /* Accumulate data to compute average when input data is hourly and output is daily */ 00894 for (i=0; i<nlon*nlat; i++) 00895 bufsave[var][i] += buf[var][i]; 00896 } 00897 } 00898 else { 00899 (void) fprintf(stderr, "%s: Fatal error in configuration of output timestep and observation variables frequency! Output timestep = %s Observation variables frequency = %s\n", __FILE__, info->timestep, obs_var->frequency); 00900 00901 /* Fatal error */ 00902 if (buf[var] != NULL) (void) free(buf[var]); 00903 (void) free(info_tmp[var]->grid_mapping); 00904 (void) free(info_tmp[var]->units); 00905 (void) free(info_tmp[var]->height); 00906 (void) free(info_tmp[var]->coordinates); 00907 (void) free(info_tmp[var]->long_name); 00908 (void) free(info_tmp[var]); 00909 00910 for (vare=0; vare<=var; vare++) { 00911 for (f=0; f<noutf[vare]; f++) 00912 (void) free(outfiles[vare][f]); 00913 if (noutf[vare] > 0) 00914 (void) free(outfiles[vare]); 00915 (void) free(infile[vare]); 00916 (void) free(outfile[vare]); 00917 } 00918 (void) free(outfiles); 00919 (void) free(noutf); 00920 (void) free(found_file); 00921 (void) free(info_tmp); 00922 (void) free(buf); 00923 00924 (void) free(lat); 00925 (void) free(lon); 00926 00927 (void) free(x); 00928 (void) free(y); 00929 00930 (void) free(format); 00931 00932 (void) free(proj_tmp->name); 00933 (void) free(proj_tmp->grid_mapping_name); 00934 (void) free(proj_tmp); 00935 00936 (void) free(time_s->year); 00937 (void) free(time_s->month); 00938 (void) free(time_s->day); 00939 (void) free(time_s->hour); 00940 (void) free(time_s->minutes); 00941 (void) free(time_s->seconds); 00942 00943 (void) free(time_s); 00944 00945 if (alt != NULL) (void) free(alt); 00946 00947 (void) ut_free(dataunits); 00948 (void) ut_free_system(unitSystem); 00949 00950 return -3; 00951 } 00952 } 00953 00954 /* Free allocated memory */ 00955 if (buf[var] != NULL) (void) free(buf[var]); 00956 (void) free(info_tmp[var]->grid_mapping); 00957 (void) free(info_tmp[var]->units); 00958 (void) free(info_tmp[var]->height); 00959 (void) free(info_tmp[var]->coordinates); 00960 (void) free(info_tmp[var]->long_name); 00961 (void) free(info_tmp[var]); 00962 } 00963 00964 /* Free allocated memory */ 00965 (void) free(proj_tmp->name); 00966 (void) free(proj_tmp->grid_mapping_name); 00967 (void) free(proj_tmp); 00968 } 00969 else { 00970 //output_downscaled_analog.c: Fatal error in algorithm: analog date 3276 2000 12 31 19 not found in database!! 00971 //output_downscaled_analog.c: Writing data to /home/globc/page/downscaling_v2/data/results/scratch2010/hourly/arpege/arpege_ref/uvas_1d_19820101_19821231.nc 00972 //output_downscaled_analog.c: Fatal error in algorithm: analog date 12050 2000 12 31 19 not found in database!! 00973 if ( !strcmp(obs_var->frequency, "hourly") ) { 00974 (void) fprintf(stderr, "%s: Fatal error in algorithm: analog date %d %d %d %d %d not found in database!!\n", __FILE__, t, 00975 analog_days.year[t],analog_days.month[t],analog_days.day[t],hour); 00976 minh = 0; 00977 maxh = 23; 00978 for (hour=minh; hour<=maxh; hour++) { 00979 found = FALSE; 00980 tl = 0; 00981 while (tl<ntime_obs && found == FALSE) { 00982 (void) printf("%d %d %d %d %d\n",tl,time_s->year[tl],time_s->month[tl],time_s->day[tl],time_s->hour[tl]); 00983 if (analog_days.year[t] == time_s->year[tl] && analog_days.month[t] == time_s->month[tl] && 00984 analog_days.day[t] == time_s->day[tl] && hour == time_s->hour[tl]) { 00985 found = TRUE; 00986 (void) printf("Found analog %d %d %d %d\n",tl,analog_days.year[t],analog_days.month[t],analog_days.day[t]); 00987 } 00988 tl++; 00989 } 00990 } 00991 } 00992 else 00993 (void) fprintf(stderr, "%s: Fatal error in algorithm: analog date %d %d %d %d not found in database!!\n", __FILE__, t, 00994 analog_days.year[t],analog_days.month[t],analog_days.day[t]); 00995 /* Fatal error */ 00996 for (var=0; var<obs_var->nobs_var; var++) { 00997 for (f=0; f<noutf[var]; f++) 00998 (void) free(outfiles[var][f]); 00999 if (noutf[var] > 0) 01000 (void) free(outfiles[var]); 01001 (void) free(infile[var]); 01002 (void) free(outfile[var]); 01003 } 01004 (void) free(outfiles); 01005 (void) free(noutf); 01006 (void) free(found_file); 01007 (void) free(info_tmp); 01008 (void) free(buf); 01009 01010 (void) free(lat); 01011 (void) free(lon); 01012 01013 (void) free(x); 01014 (void) free(y); 01015 01016 (void) free(format); 01017 01018 (void) free(proj_tmp->name); 01019 (void) free(proj_tmp->grid_mapping_name); 01020 (void) free(proj_tmp); 01021 01022 (void) free(time_s->year); 01023 (void) free(time_s->month); 01024 (void) free(time_s->day); 01025 (void) free(time_s->hour); 01026 (void) free(time_s->minutes); 01027 (void) free(time_s->seconds); 01028 01029 (void) free(time_s); 01030 01031 if (alt != NULL) (void) free(alt); 01032 01033 (void) ut_free(dataunits); 01034 (void) ut_free_system(unitSystem); 01035 01036 return -1; 01037 } 01038 } 01039 (void) free(time_s->year); 01040 (void) free(time_s->month); 01041 (void) free(time_s->day); 01042 (void) free(time_s->hour); 01043 (void) free(time_s->minutes); 01044 (void) free(time_s->seconds); 01045 01046 (void) free(time_s); 01047 } 01048 } 01049 01050 /* Free allocated memory */ 01051 for (var=0; var<obs_var->nobs_var; var++) { 01052 for (f=0; f<noutf[var]; f++) 01053 (void) free(outfiles[var][f]); 01054 if (noutf[var] > 0) 01055 (void) free(outfiles[var]); 01056 (void) free(infile[var]); 01057 (void) free(outfile[var]); 01058 } 01059 (void) free(outfiles); 01060 (void) free(noutf); 01061 (void) free(found_file); 01062 (void) free(info_tmp); 01063 (void) free(buf); 01064 01065 (void) free(x); 01066 (void) free(y); 01067 01068 (void) free(lat); 01069 (void) free(lon); 01070 01071 if (pmsl != NULL) (void) free(pmsl); 01072 if (alt != NULL) (void) free(alt); 01073 01074 (void) free(infile); 01075 (void) free(outfile); 01076 (void) free(format); 01077 01078 (void) ut_free(dataunits); 01079 (void) ut_free_system(unitSystem); 01080 01081 /* Success diagnostic */ 01082 return 0; 01083 }