output_downscaled_analog.c File Reference

Read analog day data and write it for downscaled period. More...

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

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.

Detailed Description

Read analog day data and write it for downscaled period.

Definition in file output_downscaled_analog.c.


Function Documentation

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.

Parameters:
[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 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1