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         diff_day_learn = (int) fminl( (float) diff_day_learn, (float) abs(cur_dayofy - learn_dayofy - ndays_year) );
00225 
00226         /* We are within the day of year range */
00227         if (diff_day_learn <= ndays) {
00228         
00229           /* Allocate memory */
00230           metric = (double *) realloc(metric, (ntime_days+1) * sizeof(double));
00231           if (metric == NULL) alloc_error(__FILE__, __LINE__);
00232           metric_norm = (double *) realloc(metric_norm, (ntime_days+1) * sizeof(double));
00233           if (metric_norm == NULL) alloc_error(__FILE__, __LINE__);
00234 
00235           /* Compute precipitation index difference and precipitation index metric */
00236           precip_diff = 0.0;
00237           for (pts=0; pts<npts; pts++) {
00238             diff_precip_pt = precip_index[pts+t*npts] - precip_index_learn[pts+tl*npts];
00239             precip_diff += (diff_precip_pt*diff_precip_pt);
00240             /*
00241               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) {
00242               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]);
00243               }
00244             */
00245             /*          if (t == 4595)
00246                         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]);*/
00247             
00248           }
00249           metric[ntime_days] = sqrt(precip_diff);
00250           //        if (t == (ntime_sub-1))
00251           //          printf("metric before max %d %lf\n",ntime_days,metric[ntime_days]);
00252         
00253           /* Store the maximum metric value and its index */
00254           if (metric[ntime_days] > max_metric) {
00255             //          if (t == (ntime_sub-1))
00256             //            printf("%d %lf %lf\n",ntime_days,max_metric,metric[ntime_days]);
00257             max_metric = metric[ntime_days];
00258             max_metric_index = ntime_days;
00259           }
00260 
00261           /* If we want to also use the secondary large-scale fields in the first selection of days */
00262           if (sup_choice == TRUE || sup == TRUE) {
00263             /* Allocate memory */
00264             metric_sup = (double *) realloc(metric_sup, (ntime_days+1) * sizeof(double));
00265             if (metric_sup == NULL) alloc_error(__FILE__, __LINE__);
00266             metric_sup_norm = (double *) realloc(metric_sup_norm, (ntime_days+1) * sizeof(double));
00267             if (metric_sup_norm == NULL) alloc_error(__FILE__, __LINE__);
00268 
00269             if (sup_cov != TRUE) {
00270               /* Compute supplemental field index difference */
00271               sup_diff = sup_field_index[t] - sup_field_index_learn[buf_learn_sub_i[tl]];
00272               metric_sup[ntime_days] = sqrt(sup_diff * sup_diff);
00273             }
00274             else {
00275               /* Compute covariance of supplemental field */
00276               if (nlon != sup_nlon || nlat != sup_nlat) {
00277                 (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);
00278                 return -1;
00279               }
00280               (void) covariance_fields_spatial(&sup_diff, sup_field, sup_field_learn, mask, t, tl, sup_nlon, sup_nlat);
00281               metric_sup[ntime_days] = sqrt(sup_diff * sup_diff);
00282             }
00283             /* Store the maximum value and its index */
00284             if (metric_sup[ntime_days] > max_metric_sup)
00285               max_metric_sup = metric_sup[ntime_days];
00286           
00287             //            if (t >= (ntime_sub-5))
00288             // 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) {
00289             //            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);
00290             //  }
00291           
00292           }
00293 
00294           /* Compute cluster difference */
00295           clust_diff = (int *) realloc(clust_diff, (ntime_days+1) * sizeof(int));
00296           if (clust_diff == NULL) alloc_error(__FILE__, __LINE__);
00297 
00298           clust_diff[ntime_days] = class_clusters_learn[tl] - class_clusters[t];
00299 
00300           /* Store the index in the time vector of the selected day */
00301           ntime_days_learn = (int *) realloc(ntime_days_learn, (ntime_days+1) * sizeof(int));
00302           if (ntime_days_learn == NULL) alloc_error(__FILE__, __LINE__);
00303 
00304           ntime_days_learn[ntime_days] = buf_learn_sub_i[tl];
00305 
00306           /*        
00307                     if (t == (ntime_sub-1)) {
00308                     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);
00309                     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)
00310                     for (pts=0; pts<npts; pts++)
00311                     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]);
00312                     }
00313           */
00314 
00315           /* Count days within day of year range */
00316           ntime_days++;
00317         }
00318       }
00319     }
00320 
00321     /* If at least one day was in range */
00322     if (ntime_days > 0) {
00323 
00324       if (only_wt != 0)
00325         /* Put the maximum value when cluster number is not the same */
00326         /* Parse each days within range */
00327         for (tl=0; tl<ntime_days; tl++) {
00328           if (clust_diff[tl] != 0) {
00329             metric[tl] = max_metric;
00330             if (sup_choice == TRUE || sup == TRUE)
00331             metric_sup[tl] = max_metric_sup;
00332           }
00333         }
00334       
00335       /*
00336         for (tl=0; tl<ntime_days; tl++)
00337         if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29) {
00338         if (clust_diff[tl] == 0)
00339         printf("after max metric %lf max_metric=%lf %d\n",metric[tl],max_metric,max_metric_index);
00340         }
00341       */
00342       
00344       /* Compute the standard deviation */
00345       varmean = gsl_stats_mean(metric, 1, (size_t) ntime_days);
00346       varstd = gsl_stats_sd_m(metric, 1, (size_t) ntime_days, varmean);
00347       if (sup_choice == TRUE) {
00348         /* Do the same if needed for secondary large-scale field */
00349         varmean_sup = gsl_stats_mean(metric_sup, 1, (size_t) ntime_days);
00350         varstd_sup = gsl_stats_sd_m(metric_sup, 1, (size_t) ntime_days, varmean_sup);
00351         /* Apply normalization and sum the two metrics if we use the secondary large-scale field in the first selection */
00352         /* and also in the second and final selection */
00353         if (sup_choice == TRUE) {
00354           /* Process each days within range */
00355           for (tl=0; tl<ntime_days; tl++) {
00356             /*
00357               if (tl == 0)
00358               printf("std mean %lf %lf\n",varstd,varmean);
00359               if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29) {
00360               if (clust_diff[tl] == 0)
00361               printf("after norm metric %lf ",metric[tl]);
00362               }
00363             */
00364             metric_sup_norm[tl] = (metric_sup[tl] - varmean_sup) / varstd_sup;
00365             metric_norm[tl] = ((metric[tl] - varmean) / varstd) + metric_sup_norm[tl];
00366 
00367             /*
00368             if (t >= (ntime_sub-5))
00369               printf("!! %d %lf %lf %lf\n",tl,metric_norm[tl],varmean,varstd);
00370               if (year_learn[ntime_days_learn[tl]] == 2005 && month_learn[ntime_days_learn[tl]] == 5 && day_learn[ntime_days_learn[tl]] == 29)
00371               if (clust_diff[tl] == 0)
00372               printf("%lf\n",metric[tl]);
00373             */
00374           }
00375         }
00376         else
00377           for (tl=0; tl<ntime_days; tl++)
00378             metric_norm[tl] = (metric[tl] - varmean) / varstd;
00379       }
00380       else
00381         for (tl=0; tl<ntime_days; tl++)
00382           metric_norm[tl] = (metric[tl] - varmean) / varstd;
00383 
00384       /* Sort the vector, retrieve the sorted indexes and select only the first ndayschoices ones */
00385       //      printf("%d %d\n",ntime_days,ndayschoices);
00386       (void) gsl_sort_smallest_index(metric_index, (size_t) ndayschoices, metric_norm, 1, (size_t) ntime_days);
00387       
00388       if (shuffle == TRUE) {
00389         /* Shuffle the vector of indexes and choose the first one. This select a random day for the second and final selection */
00390         for (ii=0; ii<ndayschoices; ii++)
00391           random_num[ii] = gsl_rng_uniform_int(rng, 100);
00392         (void) gsl_sort_ulong_index(random_index, random_num, 1, (size_t) ndayschoices);
00393         
00394         min_metric = metric_norm[metric_index[random_index[0]]];
00395         min_metric_index = metric_index[random_index[0]];
00396 
00397         /* Save analog day time index in the learning period */
00398         analog_days.tindex[t] = ntime_days_learn[metric_index[random_index[0]]];
00399         analog_days.year[t] = year_learn[analog_days.tindex[t]];
00400         analog_days.month[t] = month_learn[analog_days.tindex[t]];
00401         analog_days.day[t] = day_learn[analog_days.tindex[t]];
00402         analog_days.tindex_all[t] = buf_learn_sub_i[analog_days.tindex[t]];
00403         istat = utInvCalendar2(analog_days.year[t], analog_days.month[t], analog_days.day[t], 0, 0, 0.0, dataunits, &timei);
00404         analog_days.time[t] = (int) timei;
00405 
00406         /* Save date of day being downscaled */
00407         analog_days.year_s[t] = year[buf_sub_i[t]];
00408         analog_days.month_s[t] = month[buf_sub_i[t]];
00409         analog_days.day_s[t] = day[buf_sub_i[t]];
00410         analog_days.tindex_s_all[t] = buf_sub_i[t];
00411 
00412         /* Save all analog days in special time structure */
00413         analog_days.analog_dayschoice[t] = (tstruct *) malloc(ndayschoices * sizeof(tstruct));
00414         if (analog_days.analog_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00415         analog_days.metric_norm[t] = (float *) malloc(ndayschoices * sizeof(float));
00416         if (analog_days.metric_norm[t] == NULL) alloc_error(__FILE__, __LINE__);
00417         analog_days.tindex_dayschoice[t] = (int *) malloc(ndayschoices * sizeof(int));
00418         if (analog_days.tindex_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00419         for (ii=0; ii<ndayschoices; ii++) {
00420           analog_days.metric_norm[t][ii] = metric_norm[metric_index[ii]];
00421           analog_days.tindex_dayschoice[t][ii] = ntime_days_learn[metric_index[ii]];
00422           analog_days.analog_dayschoice[t][ii].year = year_learn[ntime_days_learn[metric_index[ii]]];
00423           analog_days.analog_dayschoice[t][ii].month = month_learn[ntime_days_learn[metric_index[ii]]];
00424           analog_days.analog_dayschoice[t][ii].day = day_learn[ntime_days_learn[metric_index[ii]]];
00425           analog_days.analog_dayschoice[t][ii].hour = 0;
00426           analog_days.analog_dayschoice[t][ii].min = 0;
00427           analog_days.analog_dayschoice[t][ii].sec = 0;
00428         }
00429       }
00430       else {
00431         /* Don't shuffle. Instead choose the one having the smallest metric for the best match */
00432 
00433         min_metric = 99999999.9;
00434         min_metric_index = -1;
00435         if (sup == TRUE) {
00436           /* If we use the secondary large-scale field for this final selection */
00437           for (ii=0; ii<ndayschoices; ii++) {
00438             if (metric_sup[metric_index[ii]] < min_metric) {
00439               min_metric_index = metric_index[ii];
00440               min_metric = metric_sup[metric_index[ii]];
00441             }
00442             
00443             /*            if (t >= (ntime_sub-5)) {
00444               printf("!!! %d %d %d %d %lf\n",ii,t,tl,(int)metric_index[ii],metric_norm[metric_index[ii]]);
00445               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]);
00446               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]]]);
00447               printf("%d %d\n",sup,sup_choice);
00448               }*/
00449             
00450           }
00451         }
00452         else {
00453           /* We rather use the main large-scale field (precipitation) as the metric for the final selection */
00454           for (ii=0; ii<ndayschoices; ii++) {
00455             //            if (t == (ntime_sub-1)) {
00456             //              printf("%d %d %lf %lf\n",ii,ndayschoices,metric[metric_index[ii]],min_metric);
00457             //              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]]]);
00458             //            }
00459             if (metric_norm[metric_index[ii]] < min_metric) {
00460               min_metric_index = metric_index[ii];
00461               min_metric = metric_norm[metric_index[ii]];
00462             }
00463           }
00464         }
00465 
00466         /* Save analog day time index in the learning period */
00467         analog_days.tindex[t] = ntime_days_learn[min_metric_index];
00468         analog_days.year[t] = year_learn[analog_days.tindex[t]];
00469         analog_days.month[t] = month_learn[analog_days.tindex[t]];
00470         analog_days.day[t] = day_learn[analog_days.tindex[t]];
00471         analog_days.tindex_all[t] = buf_learn_sub_i[analog_days.tindex[t]];
00472         istat = utInvCalendar2(analog_days.year[t], analog_days.month[t], analog_days.day[t], 0, 0, 0.0, dataunits, &timei);
00473         analog_days.time[t] = (int) timei;
00474 
00475         /* Save date of day being downscaled */
00476         analog_days.year_s[t] = year[buf_sub_i[t]];
00477         analog_days.month_s[t] = month[buf_sub_i[t]];
00478         analog_days.day_s[t] = day[buf_sub_i[t]];
00479         analog_days.tindex_s_all[t] = buf_sub_i[t];
00480 
00481         /* Save all analog days in special time structure */
00482         analog_days.analog_dayschoice[t] = (tstruct *) malloc(ndayschoices * sizeof(tstruct));
00483         if (analog_days.analog_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00484         analog_days.metric_norm[t] = (float *) malloc(ndayschoices * sizeof(float));
00485         if (analog_days.metric_norm[t] == NULL) alloc_error(__FILE__, __LINE__);
00486         analog_days.tindex_dayschoice[t] = (int *) malloc(ndayschoices * sizeof(int));
00487         if (analog_days.tindex_dayschoice[t] == NULL) alloc_error(__FILE__, __LINE__);
00488         for (ii=0; ii<ndayschoices; ii++) {
00489           analog_days.metric_norm[t][ii] = metric_norm[metric_index[ii]];
00490           analog_days.tindex_dayschoice[t][ii] = ntime_days_learn[metric_index[ii]];
00491           analog_days.analog_dayschoice[t][ii].year = year_learn[ntime_days_learn[metric_index[ii]]];
00492           analog_days.analog_dayschoice[t][ii].month = month_learn[ntime_days_learn[metric_index[ii]]];
00493           analog_days.analog_dayschoice[t][ii].day = day_learn[ntime_days_learn[metric_index[ii]]];
00494           analog_days.analog_dayschoice[t][ii].hour = 0;
00495           analog_days.analog_dayschoice[t][ii].min = 0;
00496           analog_days.analog_dayschoice[t][ii].sec = 0;
00497         }
00498       }
00499       
00500       /* Free memory */
00501       (void) free(metric);
00502       (void) free(metric_norm);
00503       metric = NULL;
00504       metric_norm = NULL;
00505       if (sup_choice == TRUE || sup == TRUE) {
00506         (void) free(metric_sup);
00507         metric_sup = NULL;
00508         (void) free(metric_sup_norm);
00509         metric_sup_norm = NULL;
00510       }
00511       (void) free(clust_diff);
00512       clust_diff = NULL;
00513       (void) free(ntime_days_learn);
00514       ntime_days_learn = NULL;
00515     }
00516         if (year[buf_sub_i[t]] == 1999 && month[buf_sub_i[t]] == 5)
00517           if (month[buf_sub_i[t]] == 3 || month[buf_sub_i[t]] == 4 || month[buf_sub_i[t]] == 5)
00518             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);
00519         
00520   }
00521 
00522   /* Free memory */
00523   if (shuffle == TRUE) {
00524     (void) gsl_rng_free(rng);
00525     (void) free(random_num);
00526     (void) free(random_index);
00527   }
00528   (void) free(metric_index);
00529 
00530   (void) free(buf_sub_i);
00531   (void) free(buf_learn_sub_i);
00532 
00533   (void) ut_free(dataunits);
00534   (void) ut_free_system(unitSystem);  
00535       
00536   return 0;
00537 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1