00001
00002
00003
00004
00005
00006
00007
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include <dsclim.h>
00056
00058 int
00059 output_downscaled_analog(analog_day_struct analog_days, double *delta, int output_month_begin, char *output_path,
00060 char *config, char *time_units, char *cal_type,
00061 double deltat, int file_format, int file_compression, int file_compression_level,
00062 int debug,
00063 info_struct *info, var_struct *obs_var, period_struct *period,
00064 double *time_ls, int ntime) {
00085 char **infile = NULL;
00086 char *infile_alt = NULL;
00087 char **outfile = NULL;
00088 char ***outfiles = NULL;
00089 int year1 = 0;
00090 int year2 = 0;
00091 double **buf = NULL;
00092 double **bufsave = NULL;
00093 double *buftmp = NULL;
00094 double *alt = NULL;
00095 double *pmsl = NULL;
00096 double *timeval = NULL;
00097 double *lat = NULL;
00098 double *lon = NULL;
00099 double *y = NULL;
00100 double *x = NULL;
00101 char *cal_type_tmp = NULL;
00102 char *time_units_tmp = NULL;
00103 double ctimeval[1];
00104 int ntime_file;
00105 int ntime_obs;
00106 int nlon;
00107 int nlat;
00108 int *noutf = NULL;
00109 int found = FALSE;
00110 int *found_file = NULL;
00111 int output_month_end;
00112 time_vect_struct *time_s = NULL;
00113
00114 info_field_struct **info_tmp = NULL;
00115 proj_struct *proj_tmp = NULL;
00116
00117 int tmpi;
00118 double curtas;
00119 double newcurtas;
00120 char *format = NULL;
00121
00122 int varid_tas;
00123 int varid_tasmax;
00124 int varid_tasmin;
00125 int varid_prsn;
00126 int varid_prr;
00127 int varid_rlds;
00128 int varid_rsds;
00129 int varid_hur;
00130 int varid_hus;
00131 int varid_husmin;
00132 int varid_husmax;
00133 int varid_etp;
00134 int varid_uvas;
00135 int varid_prtot;
00136
00137 int configstrdimid;
00138 int configstroutid;
00139 size_t start[1];
00140 size_t count[1];
00141
00142 int t;
00143 int tl;
00144 int var;
00145 int vare;
00146 int istat;
00147 int f;
00148 int i;
00149 int j;
00150
00151 double curtime;
00152
00153 int ncoutid;
00154 ut_system *unitSystem = NULL;
00155 ut_unit *dataunits = NULL;
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
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
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
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
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
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
00270 if (time_ls[t] >= period_begin && time_ls[t] <= period_end) {
00271
00272
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
00282 for (var=0; var<obs_var->nobs_var; var++) {
00283
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
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
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
00307 istat = nc_open(outfile[var], NC_WRITE, &ncoutid);
00308
00309 if (istat != NC_NOERR) {
00310
00311
00312
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
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);
00339 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00340
00341
00342 istat = nc_redef(ncoutid);
00343 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00344
00345
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
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
00368 istat = nc_enddef(ncoutid);
00369 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00370
00371
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
00381 istat = ncclose(ncoutid);
00382 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00383 }
00384 }
00385 }
00386
00387
00388 (void) strcpy(format, "%s/%s/");
00389 (void) strcat(format, obs_var->template);
00390 if (obs_var->month_begin != 1) {
00391
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
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
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
00415 year1 = analog_days.year[t];
00416 if (obs_var->year_digits == 4)
00417
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
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
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
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
00463 minh = 0;
00464 maxh = 23;
00465 }
00466 else {
00467
00468 minh = 0;
00469 maxh = 0;
00470 }
00471
00472
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
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
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
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
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
00550
00551
00552
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
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
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
00580 nlat = 0;
00581 else
00582
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
00590
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
00626
00627
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
00636 curtas = buf[varid_tas][i+j*nlon];
00637
00638 buf[varid_tas][i+j*nlon] += delta[t];
00639
00640
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
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
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
00666 curtas = (buf[varid_tasmax][i+j*nlon] + buf[varid_tasmin][i+j*nlon]) / 2.0;
00667
00668 buf[varid_tasmax][i+j*nlon] += delta[t];
00669 buf[varid_tasmin][i+j*nlon] += delta[t];
00670
00671 newcurtas = (buf[varid_tasmax][i+j*nlon] + buf[varid_tasmin][i+j*nlon]) / 2.0;
00672
00673
00674 if (varid_tas < 0) {
00675
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
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
00693
00694 if (varid_hur >= 0) {
00695
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
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
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
00734 if ( !strcmp(obs_var->post[varid_prtot], "yes") ) {
00735
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
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
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
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
00793 for (var=0; var<obs_var->nobs_var; var++) {
00794 if ( !strcmp(obs_var->output[var], "yes") ) {
00795
00796 if (found_file[var] == FALSE && hour == minh && buf[var] != NULL) {
00797
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
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
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
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
00858 if (found_file[var] == FALSE && hour == minh)
00859 (void) fprintf(stderr, "%s: Writing data to %s\n", __FILE__, outfile[var]);
00860
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
00871 for (i=0; i<nlon*nlat; i++)
00872
00873 buf[var][i] = (bufsave[var][i] + buf[var][i]) / 24.0;
00874
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
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
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
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
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
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
00965 (void) free(proj_tmp->name);
00966 (void) free(proj_tmp->grid_mapping_name);
00967 (void) free(proj_tmp);
00968 }
00969 else {
00970
00971
00972
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
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
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
01082 return 0;
01083 }