find_the_days.c

00001 /* ***************************************************** */
00002 /* Find analog days given cluster, supplemental          */
00003 /* large-scale field, and precipitation distances.       */
00004 /* find_the_days.c                                       */
00005 /* ***************************************************** */
00006 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00007 /* ***************************************************** */
00012 /* LICENSE BEGIN
00013 
00014 Copyright Cerfacs (Christian Page) (2015)
00015 
00016 christian.page@cerfacs.fr
00017 
00018 This software is a computer program whose purpose is to downscale climate
00019 scenarios using a statistical methodology based on weather regimes.
00020 
00021 This software is governed by the CeCILL license under French law and
00022 abiding by the rules of distribution of free software. You can use, 
00023 modify and/ or redistribute the software under the terms of the CeCILL
00024 license as circulated by CEA, CNRS and INRIA at the following URL
00025 "http://www.cecill.info". 
00026 
00027 As a counterpart to the access to the source code and rights to copy,
00028 modify and redistribute granted by the license, users are provided only
00029 with a limited warranty and the software's author, the holder of the
00030 economic rights, and the successive licensors have only limited
00031 liability. 
00032 
00033 In this respect, the user's attention is drawn to the risks associated
00034 with loading, using, modifying and/or developing or reproducing the
00035 software by the user in light of its specific status of free software,
00036 that may mean that it is complicated to manipulate, and that also
00037 therefore means that it is reserved for developers and experienced
00038 professionals having in-depth computer knowledge. Users are therefore
00039 encouraged to load and test the software's suitability as regards their
00040 requirements in conditions enabling the security of their systems and/or 
00041 data to be ensured and, more generally, to use and operate it in the 
00042 same conditions as regards security. 
00043 
00044 The fact that you are presently reading this means that you have had
00045 knowledge of the CeCILL license and that you accept its terms.
00046 
00047 LICENSE END */
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 #include <dsclim.h>
00056 
00058 int
00059 find_the_days(analog_day_struct analog_days, double *precip_index, double *precip_index_learn,
00060               double *sup_field_index, double *sup_field_index_learn, double *sup_field, double *sup_field_learn, short int *mask,
00061               int *class_clusters, int *class_clusters_learn, int *year, int *month, int *day,
00062               int *year_learn, int *month_learn, int *day_learn, char *time_units,
00063               int ntime, int ntime_learn, int *months, int nmonths, int ndays, int ndayschoices, int npts, int shuffle, int sup,
00064               int sup_choice, int sup_cov, int use_downscaled_year, int only_wt, int nlon, int nlat, int sup_nlon, int sup_nlat) {
00102   int *buf_sub_i = NULL; /* Temporary buffer for time index of subperiod */
00103   int *buf_learn_sub_i = NULL; /* Temporary buffer for time index of learning subperiod */
00104   int ntime_sub; /* Number of times in subperiod */
00105   int ntime_learn_sub; /* Number of times in learning subperiod */
00106 
00107   unsigned long int *random_num = NULL; /* Random number for shuffle */
00108 
00109   const gsl_rng_type *T = NULL; /* Random number generator type for shuffle */
00110   gsl_rng *rng = NULL; /* Random number generator for shuffle */
00111 
00112   int cur_dayofy; /* Current day of year being downscaled */
00113   int learn_dayofy; /* Learning day of year being processed */
00114   int diff_day_learn; /* Difference in terms of day of year between downscaled day of year and learning one */
00115 
00116   double max_metric = 0.0; /* Maximum metric value. The metric is the value used to compare days
00117                               (cluster distance, index distance, etc.) */
00118   double max_metric_sup = 0.0; /* Maximum metric value for secondary large-scale field metric. */
00119   double min_metric = 0.0; /* Minimum metric */
00120 
00121   double precip_diff; /* Squared sum of regressed precipitation difference (between downscaled and learning day) over all points. */
00122   double diff_precip_pt; /* Regressed precipitation difference (between downscaled and learning day) for 1 point. */
00123   double sup_diff; /* Secondary large-scale field difference (between downscaled and learning day) */
00124 
00125   double varstd; /* Standard deviation of precipitation index metric */
00126   double varmean; /* Mean of precipitation index metric */
00127   double varstd_sup; /* Standard deviation of secondary large-scale field metric */
00128   double varmean_sup; /* Mean of secondary large-scale field metric */
00129 
00130   double *metric = NULL; /* Precipitation index metric buffer */
00131   double *metric_norm = NULL; /* Normalized precipitation index metric buffer */
00132   double *metric_sup = NULL; /* Secondary large-scale field metric */
00133   double *metric_sup_norm = NULL; /* Normalized secondary large-scale field metric */
00134   size_t *metric_index = NULL; /* Metric sorted index of ndayschoices days */
00135   size_t *random_index = NULL; /* Shuffled metric index of ndayschoices days */
00136   int min_metric_index; /* Index of minimum metric */
00137   int max_metric_index; /* Index of maximum metric */
00138   int *clust_diff = NULL; /* Cluster number differences between cluster of learning day and cluster of day being downscaled */
00139 
00140   int ntime_days; /* Number of days in learning period within the +-ndays of downscaled day of year */
00141   int *ntime_days_learn = NULL; /* Time index of the learning subperiod corresponding to all valid days within the +-ndays of downscaled day of year */
00142 
00143   int ii; /* Loop counter */
00144   int t; /* Time loop counter */
00145   int tt; /* Time loop counter */
00146   int tl; /* Time loop counter */
00147   int pts; /* Regression points loop counter */
00148   int ndays_year; /* Number of days in a year */
00149 
00150   ut_system *unitSystem = NULL; /* Unit System (udunits) */
00151   ut_unit *dataunits = NULL; /* udunits variable */
00152   int istat; /* Return status of functions */
00153   double timei; /* udunits Time value */
00154 
00155   /* Initialize udunits */
00156   ut_set_error_message_handler(ut_ignore);
00157   unitSystem = ut_read_xml(NULL);
00158   ut_set_error_message_handler(ut_write_to_stderr);
00159   dataunits = ut_parse(unitSystem, time_units, UT_ASCII);
00160 
00161   /* Initialize random number generator if needed */
00162   if (shuffle == TRUE) {
00163     T = gsl_rng_default;
00164     rng = gsl_rng_alloc(T);
00165     (void) gsl_rng_set(rng, time(NULL));
00166     /* Allocate memory */
00167     random_num = (unsigned long int *) malloc(ndayschoices * sizeof(unsigned long int));
00168     if (random_num == NULL) alloc_error(__FILE__, __LINE__);
00169     random_index = (size_t *) malloc(ndayschoices * sizeof(size_t));
00170     if (random_index == NULL) alloc_error(__FILE__, __LINE__);
00171   }
00172 
00173   /* Allocate memory for metric index */
00174   metric_index = (size_t *) malloc(ndayschoices * sizeof(size_t));
00175   if (metric_index == NULL) alloc_error(__FILE__, __LINE__);
00176 
00177   /* Select correct months for the current season in the time vectors of the downscaled and learning period */
00178   ntime_sub = 0;
00179   for (t=0; t<ntime; t++)
00180     for (tt=0; tt<nmonths; tt++)
00181       if (month[t] == months[tt]) {
00182         buf_sub_i = (int *) realloc(buf_sub_i, (ntime_sub+1) * sizeof(int));
00183         if (buf_sub_i == NULL) alloc_error(__FILE__, __LINE__);
00184         buf_sub_i[ntime_sub++] = t;
00185       }
00186 
00187   ntime_learn_sub = 0;
00188   for (t=0; t<ntime_learn; t++)
00189     for (tt=0; tt<nmonths; tt++)
00190       if (month_learn[t] == months[tt]) {
00191         buf_learn_sub_i = (int *) realloc(buf_learn_sub_i, (ntime_learn_sub+1) * sizeof(int));
00192         if (buf_learn_sub_i == NULL) alloc_error(__FILE__, __LINE__);
00193         buf_learn_sub_i[ntime_learn_sub++] = t;
00194       }
00195 
00196   /* Process each downscaled day */
00197   for (t=0; t<ntime_sub; t++) {
00198     
00199 #if DEBUG > 7
00200     printf("%d %d %d %d\n",t,year[buf_sub_i[t]],month[buf_sub_i[t]],day[buf_sub_i[t]]);
00201 #endif
00202 
00203     /* Compute the current downscaled day of year being processed */
00204     cur_dayofy = dayofclimyear(day[buf_sub_i[t]], month[buf_sub_i[t]]);
00205     if (is_leap_year(year[buf_sub_i[t]]))
00206       ndays_year = 366;
00207     else
00208       ndays_year = 365;
00209 
00210     /* Initializing */
00211     ntime_days = 0;
00212     max_metric = -9999999.9;
00213     max_metric_sup = -9999999.9;
00214 
00215     /* Search analog days in learning period */
00216     for (tl=0; tl<ntime_learn_sub; tl++) {
00217 
00218       /* If use_downscaled_year != 1, check that we don't search the analog day in the downscaled year. */
00219       if (use_downscaled_year != 0 || (use_downscaled_year == 0 && year_learn[buf_learn_sub_i[tl]] != year[buf_sub_i[t]])) {
00220 
00221         /* Compute the learning period day of year and compute the difference with the current processed day of year */
00222         learn_dayofy = dayofclimyear(day_learn[buf_learn_sub_i[tl]], month_learn[buf_learn_sub_i[tl]]);
00223         diff_day_learn = (int) fminl( (float) abs(cur_dayofy - learn_dayofy), (float) abs(cur_dayofy - learn_dayofy + ndays_year) );
00224 
00225         /* We are within the day of year range */
00226         if (diff_day_learn <= ndays) {
00227         
00228           /* Allocate memory */
00229           metric = (double *) realloc(metric, (ntime_days+1) * sizeof(double));
00230           if (metric == NULL) alloc_error(__FILE__, __LINE__);
00231           metric_norm = (double *) realloc(metric_norm, (ntime_days+1) * sizeof(double));
00232           if (metric_norm == NULL) alloc_error(__FILE__, __LINE__);
00233 
00234           /* Compute precipitation index difference and precipitation index metric */
00235           precip_diff = 0.0;
00236           for (pts=0; pts<npts; pts++) {
00237             diff_precip_pt = precip_index[pts+t*npts] - precip_index_learn[pts+tl*npts];
00238             precip_diff += (diff_precip_pt*diff_precip_pt);
00239             /*
00240               if (t == 4595 && year_learn[buf_learn_sub_i[tl]] == 2005 && month_learn[buf_learn_sub_i[tl]] == 5 && day_learn[buf_learn_sub_i[tl]] == 29) {
00241               printf("%d %d %lf %lf %lf %lf\n",t,pts,precip_diff,diff_precip_pt,precip_index[pts+t*npts],precip_index_learn[pts+tl*npts]);
00242               }
00243             */
00244             /*          if (t == 4595)
00245                         printf("%d %d %lf %lf %lf %lf\n",t,pts,precip_diff,diff_precip_pt,precip_index[pts+t*npts],precip_index_learn[pts+tl*npts]);*/
00246             
00247           }
00248           metric[ntime_days] = sqrt(precip_diff);
00249           //        if (t == (ntime_sub-1))
00250           //          printf("metric before max %d %lf\n",ntime_days,metric[ntime_days]);
00251         
00252           /* Store the maximum metric value and its index */
00253           if (metric[ntime_days] > max_metric) {
00254             //          if (t == (ntime_sub-1))
00255             //            printf("%d %lf %lf\n",ntime_days,max_metric,metric[ntime_days]);
00256             max_metric = metric[ntime_days];
00257             max_metric_index = ntime_days;
00258           }
00259 
00260           /* If we want to also use the secondary large-scale fields in the first selection of days */
00261           if (sup_choice == TRUE || sup == TRUE) {
00262             /* Allocate memory */
00263             metric_sup = (double *) realloc(metric_sup, (ntime_days+1) * sizeof(double));
00264             if (metric_sup == NULL) alloc_error(__FILE__, __LINE__);
00265             metric_sup_norm = (double *) realloc(metric_sup_norm, (ntime_days+1) * sizeof(double));
00266             if (metric_sup_norm == NULL) alloc_error(__FILE__, __LINE__);
00267 
00268             if (sup_cov != TRUE) {
00269               /* Compute supplemental field index difference */
00270               sup_diff = sup_field_index[t] - sup_field_index_learn[buf_learn_sub_i[tl]];
00271               metric_sup[ntime_days] = sqrt(sup_diff * sup_diff);
00272             }
00273             else {
00274               /* Compute covariance of supplemental field */
00275               if (nlon != sup_nlon || nlat != sup_nlat) {
00276                 (void) fprintf(stderr, "%s: Dimensions of downscaled large-scale secondary field (nlat=%d nlon=%d) are not the same as the learning field (nlat=%d nlon=%d. Cannot proceed...\n", __FILE__, nlat, nlon, sup_nlat, sup_nlon);
00277                 return -1;
00278               }
00279               (void) covariance_fields_spatial(&sup_diff, sup_field, sup_field_learn, mask, t, tl, sup_nlon, sup_nlat);
00280               metric_sup[ntime_days] = sqrt(sup_diff * sup_diff);
00281             }
00282             /* Store the maximum value and its index */
00283             if (metric_sup[ntime_days] > max_metric_sup)
00284               max_metric_sup = metric_sup[ntime_days];
00285           
00286             //            if (t >= (ntime_sub-5))
00287             // if (year_learn[buf_learn_sub_i[tl]] == 2005 && month_learn[buf_learn_sub_i[tl]] == 5 && day_learn[buf_learn_sub_i[tl]] == 29) {
00288             //            printf("%d %lf %lf %lf %lf %lf %lf\n",ntime_days,max_metric_sup,metric_sup[ntime_days],sup_field_index[t],sup_field_index_learn[buf_learn_sub_i[tl]],metric[ntime_days],precip_diff);
00289             //  }
00290           
00291           }
00292 
00293           /* Compute cluster difference */
00294           clust_diff = (int *) realloc(clust_diff, (ntime_days+1) * sizeof(int));
00295           if (clust_diff == NULL) alloc_error(__FILE__, __LINE__);
00296 
00297           clust_diff[ntime_days] = class_clusters_learn[tl] - class_clusters[t];
00298 
00299           /* Store the index in the time vector of the selected day */
00300           ntime_days_learn = (int *) realloc(ntime_days_learn, (ntime_days+1) * sizeof(int));
00301           if (ntime_days_learn == NULL) alloc_error(__FILE__, __LINE__);
00302 
00303           ntime_days_learn[ntime_days] = buf_learn_sub_i[tl];
00304 
00305           /*        
00306                     if (t == (ntime_sub-1)) {
00307                     printf("!clust %d %d %d %d %d %d day=%d\n",year_learn[buf_learn_sub_i[tl]], month_learn[buf_learn_sub_i[tl]], day_learn[buf_learn_sub_i[tl]], clust_diff[ntime_days], class_clusters_learn[tl], class_clusters[t],t);
00308                     if (year_learn[buf_learn_sub_i[tl]] == 1986 && month_learn[buf_learn_sub_i[tl]] == 5 && day_learn[buf_learn_sub_i[tl]] == 25)
00309                     for (pts=0; pts<npts; pts++)
00310                     printf("!!! %d %d %d %d %d %lf %lf %lf %lf %lf\n",pts,ntime_days,year_learn[buf_learn_sub_i[tl]], month_learn[buf_learn_sub_i[tl]], day_learn[buf_learn_sub_i[tl]], (precip_index[pts+t*npts] - precip_index_learn[pts+tl*npts]), (precip_index[pts+t*npts] - precip_index_learn[pts+tl*npts])*(precip_index[pts+t*npts] - precip_index_learn[pts+tl*npts]), metric[ntime_days], precip_index[pts+t*npts],precip_index_learn[pts+tl*npts]);
00311                     }
00312           */
00313 
00314           /* Count days within day of year range */
00315           ntime_days++;
00316         }
00317       }
00318     }
00319 
00320     /* If at least one day was in range */
00321     if (ntime_days > 0) {
00322 
00323       if (only_wt != 0)
00324         /* Put the maximum value when cluster number is not the same */
00325         /* Parse each days within range */
00326         for (tl=0; tl<ntime_days; tl++) {
00327           if (clust_diff[tl] != 0) {
00328             metric[tl] = max_metric;
00329             if (sup_choice == TRUE || sup == TRUE)
00330             metric_sup[tl] = max_metric_sup;
00331           }
00332         }
00333       
00334       /*
00335         for (tl=0; tl<ntime_days; tl++)
00336         if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29) {
00337         if (clust_diff[tl] == 0)
00338         printf("after max metric %lf max_metric=%lf %d\n",metric[tl],max_metric,max_metric_index);
00339         }
00340       */
00341       
00343       /* Compute the standard deviation */
00344       varmean = gsl_stats_mean(metric, 1, (size_t) ntime_days);
00345       varstd = gsl_stats_sd_m(metric, 1, (size_t) ntime_days, varmean);
00346       if (sup_choice == TRUE) {
00347         /* Do the same if needed for secondary large-scale field */
00348         varmean_sup = gsl_stats_mean(metric_sup, 1, (size_t) ntime_days);
00349         varstd_sup = gsl_stats_sd_m(metric_sup, 1, (size_t) ntime_days, varmean_sup);
00350         /* Apply normalization and sum the two metrics if we use the secondary large-scale field in the first selection */
00351         /* and also in the second and final selection */
00352         if (sup_choice == TRUE) {
00353           /* Process each days within range */
00354           for (tl=0; tl<ntime_days; tl++) {
00355             /*
00356               if (tl == 0)
00357               printf("std mean %lf %lf\n",varstd,varmean);
00358               if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29) {
00359               if (clust_diff[tl] == 0)
00360               printf("after norm metric %lf ",metric[tl]);
00361               }
00362             */
00363             metric_sup_norm[tl] = (metric_sup[tl] - varmean_sup) / varstd_sup;
00364             metric_norm[tl] = ((metric[tl] - varmean) / varstd) + metric_sup_norm[tl];
00365 
00366             /*
00367             if (t >= (ntime_sub-5))
00368               printf("!! %d %lf %lf %lf\n",tl,metric_norm[tl],varmean,varstd);
00369               if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29)
00370               if (clust_diff[tl] == 0)
00371               printf("%lf\n",metric[tl]);
00372             */
00373           }
00374         }
00375         else
00376           for (tl=0; tl<ntime_days; tl++)
00377             metric_norm[tl] = (metric[tl] - varmean) / varstd;
00378       }
00379       else
00380         for (tl=0; tl<ntime_days; tl++)
00381           metric_norm[tl] = (metric[tl] - varmean) / varstd;
00382 
00383       /* Sort the vector, retrieve the sorted indexes and select only the first ndayschoices ones */
00384       //      printf("%d %d\n",ntime_days,ndayschoices);
00385       (void) gsl_sort_smallest_index(metric_index, (size_t) ndayschoices, metric_norm, 1, (size_t) ntime_days);
00386       
00387       if (shuffle == TRUE) {
00388         /* Shuffle the vector of indexes and choose the first one. This select a random day for the second and final selection */
00389         for (ii=0; ii<ndayschoices; ii++)
00390           random_num[ii] = gsl_rng_uniform_int(rng, 100);
00391         (void) gsl_sort_ulong_index(random_index, random_num, 1, (size_t) ndayschoices);
00392         
00393         min_metric = metric_norm[metric_index[random_index[0]]];
00394         min_metric_index = metric_index[random_index[0]];
00395 
00396         /* Save analog day time index in the learning period */
00397         analog_days.tindex[t] = ntime_days_learn[metric_index[random_index[0]]];
00398         analog_days.year[t] = year_learn[analog_days.tindex[t]];
00399         analog_days.month[t] = month_learn[analog_days.tindex[t]];
00400         analog_days.day[t] = day_learn[analog_days.tindex[t]];
00401         analog_days.tindex_all[t] = buf_learn_sub_i[analog_days.tindex[t]];
00402         istat = utInvCalendar2(analog_days.year[t], analog_days.month[t], analog_days.day[t], 0, 0, 0.0, dataunits, &timei);
00403         analog_days.time[t] = (int) timei;
00404 
00405         /* Save date of day being downscaled */
00406         analog_days.year_s[t] = year[buf_sub_i[t]];
00407         analog_days.month_s[t] = month[buf_sub_i[t]];
00408         analog_days.day_s[t] = day[buf_sub_i[t]];
00409         analog_days.tindex_s_all[t] = buf_sub_i[t];
00410 
00411         /* Save all analog days in special time structure */
00412         analog_days.analog_dayschoice[t] = (tstruct *) malloc(ndayschoices * sizeof(tstruct));
00413         if (analog_days.analog_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00414         analog_days.metric_norm[t] = (float *) malloc(ndayschoices * sizeof(float));
00415         if (analog_days.metric_norm[t] == NULL) alloc_error(__FILE__, __LINE__);
00416         analog_days.tindex_dayschoice[t] = (int *) malloc(ndayschoices * sizeof(int));
00417         if (analog_days.tindex_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00418         for (ii=0; ii<ndayschoices; ii++) {
00419           analog_days.metric_norm[t][ii] = metric_norm[metric_index[ii]];
00420           analog_days.tindex_dayschoice[t][ii] = ntime_days_learn[metric_index[ii]];
00421           analog_days.analog_dayschoice[t][ii].year = year_learn[ntime_days_learn[metric_index[ii]]];
00422           analog_days.analog_dayschoice[t][ii].month = month_learn[ntime_days_learn[metric_index[ii]]];
00423           analog_days.analog_dayschoice[t][ii].day = day_learn[ntime_days_learn[metric_index[ii]]];
00424           analog_days.analog_dayschoice[t][ii].hour = 0;
00425           analog_days.analog_dayschoice[t][ii].min = 0;
00426           analog_days.analog_dayschoice[t][ii].sec = 0;
00427         }
00428       }
00429       else {
00430         /* Don't shuffle. Instead choose the one having the smallest metric for the best match */
00431 
00432         min_metric = 99999999.9;
00433         min_metric_index = -1;
00434         if (sup == TRUE) {
00435           /* If we use the secondary large-scale field for this final selection */
00436           for (ii=0; ii<ndayschoices; ii++) {
00437             if (metric_sup[metric_index[ii]] < min_metric) {
00438               min_metric_index = metric_index[ii];
00439               min_metric = metric_sup[metric_index[ii]];
00440             }
00441             
00442             /*            if (t >= (ntime_sub-5)) {
00443               printf("!!! %d %d %d %d %lf\n",ii,t,tl,(int)metric_index[ii],metric_norm[metric_index[ii]]);
00444               printf("SUP %d %d %lf %lf %lf %d ",ii,ndayschoices,metric_sup[metric_index[ii]],metric_norm[metric_index[ii]]*2.0,min_metric,(int)metric_index[ii]);
00445               printf("%d %d %d\n",year_learn[ntime_days_learn[metric_index[ii]]],month_learn[ntime_days_learn[metric_index[ii]]],day_learn[ntime_days_learn[metric_index[ii]]]);
00446               printf("%d %d\n",sup,sup_choice);
00447               }*/
00448             
00449           }
00450         }
00451         else {
00452           /* We rather use the main large-scale field (precipitation) as the metric for the final selection */
00453           for (ii=0; ii<ndayschoices; ii++) {
00454             //            if (t == (ntime_sub-1)) {
00455             //              printf("%d %d %lf %lf\n",ii,ndayschoices,metric[metric_index[ii]],min_metric);
00456             //              printf("%d %d %d\n",year_learn[ntime_days_learn[metric_index[ii]]],month_learn[ntime_days_learn[metric_index[ii]]],day_learn[ntime_days_learn[metric_index[ii]]]);
00457             //            }
00458             if (metric_norm[metric_index[ii]] < min_metric) {
00459               min_metric_index = metric_index[ii];
00460               min_metric = metric_norm[metric_index[ii]];
00461             }
00462           }
00463         }
00464 
00465         /* Save analog day time index in the learning period */
00466         analog_days.tindex[t] = ntime_days_learn[min_metric_index];
00467         analog_days.year[t] = year_learn[analog_days.tindex[t]];
00468         analog_days.month[t] = month_learn[analog_days.tindex[t]];
00469         analog_days.day[t] = day_learn[analog_days.tindex[t]];
00470         analog_days.tindex_all[t] = buf_learn_sub_i[analog_days.tindex[t]];
00471         istat = utInvCalendar2(analog_days.year[t], analog_days.month[t], analog_days.day[t], 0, 0, 0.0, dataunits, &timei);
00472         analog_days.time[t] = (int) timei;
00473 
00474         /* Save date of day being downscaled */
00475         analog_days.year_s[t] = year[buf_sub_i[t]];
00476         analog_days.month_s[t] = month[buf_sub_i[t]];
00477         analog_days.day_s[t] = day[buf_sub_i[t]];
00478         analog_days.tindex_s_all[t] = buf_sub_i[t];
00479 
00480         /* Save all analog days in special time structure */
00481         analog_days.analog_dayschoice[t] = (tstruct *) malloc(ndayschoices * sizeof(tstruct));
00482         if (analog_days.analog_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00483         analog_days.metric_norm[t] = (float *) malloc(ndayschoices * sizeof(float));
00484         if (analog_days.metric_norm[t] == NULL) alloc_error(__FILE__, __LINE__);
00485         analog_days.tindex_dayschoice[t] = (int *) malloc(ndayschoices * sizeof(int));
00486         if (analog_days.tindex_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00487         for (ii=0; ii<ndayschoices; ii++) {
00488           analog_days.metric_norm[t][ii] = metric_norm[metric_index[ii]];
00489           analog_days.tindex_dayschoice[t][ii] = ntime_days_learn[metric_index[ii]];
00490           analog_days.analog_dayschoice[t][ii].year = year_learn[ntime_days_learn[metric_index[ii]]];
00491           analog_days.analog_dayschoice[t][ii].month = month_learn[ntime_days_learn[metric_index[ii]]];
00492           analog_days.analog_dayschoice[t][ii].day = day_learn[ntime_days_learn[metric_index[ii]]];
00493           analog_days.analog_dayschoice[t][ii].hour = 0;
00494           analog_days.analog_dayschoice[t][ii].min = 0;
00495           analog_days.analog_dayschoice[t][ii].sec = 0;
00496         }
00497       }
00498       
00499       /* Free memory */
00500       (void) free(metric);
00501       (void) free(metric_norm);
00502       metric = NULL;
00503       metric_norm = NULL;
00504       if (sup_choice == TRUE || sup == TRUE) {
00505         (void) free(metric_sup);
00506         metric_sup = NULL;
00507         (void) free(metric_sup_norm);
00508         metric_sup_norm = NULL;
00509       }
00510       (void) free(clust_diff);
00511       clust_diff = NULL;
00512       (void) free(ntime_days_learn);
00513       ntime_days_learn = NULL;
00514     }
00515         if (year[buf_sub_i[t]] == 1999 && month[buf_sub_i[t]] == 5)
00516           if (month[buf_sub_i[t]] == 3 || month[buf_sub_i[t]] == 4 || month[buf_sub_i[t]] == 5)
00517             printf("Time downscaled %d: %d %d %d. Analog day: %d %d %d %lf\n", t, year[buf_sub_i[t]], month[buf_sub_i[t]], day[buf_sub_i[t]], year_learn[analog_days.tindex[t]], month_learn[analog_days.tindex[t]], day_learn[analog_days.tindex[t]], min_metric);
00518         
00519   }
00520 
00521   /* Free memory */
00522   if (shuffle == TRUE) {
00523     (void) gsl_rng_free(rng);
00524     (void) free(random_num);
00525     (void) free(random_index);
00526   }
00527   (void) free(metric_index);
00528 
00529   (void) free(buf_sub_i);
00530   (void) free(buf_learn_sub_i);
00531 
00532   (void) ut_free(dataunits);
00533   (void) ut_free_system(unitSystem);  
00534       
00535   return 0;
00536 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1