read_obs_period.c

Go to the documentation of this file.
00001 /* ***************************************************** */
00002 /* Read observation data for a given period              */
00003 /* read_obs_period.c                                     */
00004 /* ***************************************************** */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00006 /* ***************************************************** */
00011 /* LICENSE BEGIN
00012 
00013 Copyright Cerfacs (Christian Page) (2015)
00014 
00015 christian.page@cerfacs.fr
00016 
00017 This software is a computer program whose purpose is to downscale climate
00018 scenarios using a statistical methodology based on weather regimes.
00019 
00020 This software is governed by the CeCILL license under French law and
00021 abiding by the rules of distribution of free software. You can use, 
00022 modify and/ or redistribute the software under the terms of the CeCILL
00023 license as circulated by CEA, CNRS and INRIA at the following URL
00024 "http://www.cecill.info". 
00025 
00026 As a counterpart to the access to the source code and rights to copy,
00027 modify and redistribute granted by the license, users are provided only
00028 with a limited warranty and the software's author, the holder of the
00029 economic rights, and the successive licensors have only limited
00030 liability. 
00031 
00032 In this respect, the user's attention is drawn to the risks associated
00033 with loading, using, modifying and/or developing or reproducing the
00034 software by the user in light of its specific status of free software,
00035 that may mean that it is complicated to manipulate, and that also
00036 therefore means that it is reserved for developers and experienced
00037 professionals having in-depth computer knowledge. Users are therefore
00038 encouraged to load and test the software's suitability as regards their
00039 requirements in conditions enabling the security of their systems and/or 
00040 data to be ensured and, more generally, to use and operate it in the 
00041 same conditions as regards security. 
00042 
00043 The fact that you are presently reading this means that you have had
00044 knowledge of the CeCILL license and that you accept its terms.
00045 
00046 LICENSE END */
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 #include <dsclim.h>
00055 
00057 int
00058 read_obs_period(double **buffer, double **lon, double **lat, double *missing_value, data_struct *data, char *varname,
00059                 int *year, int *month, int *day, int *nlon, int *nlat, int ntime) {
00078   double *buf = NULL; /* Temporary buffer */
00079   char *infile = NULL; /* Input filename */
00080   int year1 = 0; /* First year of data input file */
00081   int year2 = 0; /* End year of data input file */
00082   double *timeval = NULL; /* Temporary time information buffer */
00083   char *cal_type = NULL; /* Calendar type (udunits) */
00084   char *time_units = NULL; /* Time units (udunits) */
00085   int ntime_obs; /* Number of times dimension in observation database */
00086   int found = FALSE; /* Used to tag if we found a specific date */
00087   time_vect_struct *time_s = NULL; /* Time structure for observation database */
00088 
00089   info_field_struct *info = NULL; /* Temporary field information structure */
00090   proj_struct *proj = NULL; /* Temporary field projection structure */
00091 
00092   int tmpi; /* Temporay integer value */
00093   char *format = NULL; /* Temporay format string */
00094 
00095   int t; /* Time loop counter */
00096   int tl; /* Time loop counter */
00097   int var; /* Variable ID */
00098   int istat; /* Diagnostic status */
00099   int i;
00100   int j;
00101 
00102   int ntime_file;
00103 
00104   char *prev_infile = NULL;
00105 
00106   /* Search variable */
00107   var = find_str_value(varname, data->conf->obs_var->netcdfname, data->conf->obs_var->nobs_var);
00108   if (var == -1) return -2;
00109 
00110   infile = (char *) malloc(MAXPATH * sizeof(char));
00111   if (infile == NULL) alloc_error(__FILE__, __LINE__);
00112   prev_infile = (char *) malloc(MAXPATH * sizeof(char));
00113   if (prev_infile == NULL) alloc_error(__FILE__, __LINE__);
00114   (void) strcpy(prev_infile, "");
00115   format = (char *) malloc(MAXPATH * sizeof(char));
00116   if (format == NULL) alloc_error(__FILE__, __LINE__);
00117 
00118   info = (info_field_struct *) malloc(sizeof(info_field_struct));
00119   if (info == NULL) alloc_error(__FILE__, __LINE__);
00120   proj = (proj_struct *) malloc(sizeof(proj_struct));
00121   if (proj == NULL) alloc_error(__FILE__, __LINE__);
00122 
00123   *lat = NULL;
00124   *lon = NULL;
00125 
00126   if (data->conf->obs_var->proj->name != NULL)
00127     (void) free(data->conf->obs_var->proj->name);
00128   data->conf->obs_var->proj->name = NULL;
00129   proj->name = NULL;
00130   if (data->conf->obs_var->proj->grid_mapping_name != NULL)
00131     (void) free(data->conf->obs_var->proj->grid_mapping_name);
00132   data->conf->obs_var->proj->grid_mapping_name = NULL;
00133   proj->grid_mapping_name = NULL;
00134 
00135   /* Loop over time */
00136   for (t=0; t<ntime; t++) {
00137     
00138     /* Create input filename for reading data */
00139     (void) strcpy(format, "%s/%s/");
00140     (void) strcat(format, data->conf->obs_var->template);
00141     if (data->conf->obs_var->month_begin != 1) {
00142       /* Months in observation files *does not* begin in January: must have 2 years in filename */
00143       if (month[t] < data->conf->obs_var->month_begin)
00144         year1 = year[t] - 1;
00145       else
00146         year1 = year[t];
00147       year2 = year1 + 1;
00148       if (data->conf->obs_var->year_digits == 4)
00149         (void) sprintf(infile, format, data->conf->obs_var->path, data->conf->obs_var->frequency,
00150                        data->conf->obs_var->acronym[var], year1, year2);
00151       else {
00152         tmpi = year1 / 100;
00153         year1 = year1 - (tmpi*100);
00154         tmpi = year2 / 100;
00155         year2 = year2 - (tmpi*100);
00156         (void) sprintf(infile, format, data->conf->obs_var->path, data->conf->obs_var->frequency,
00157                        data->conf->obs_var->acronym[var], year1, year2);
00158       }
00159     }
00160     else {
00161       /* Months in observation files begins in January: must have 1 year in filename */
00162       if (data->conf->obs_var->year_digits == 4) {
00163         year1 = year[t];
00164         (void) sprintf(infile, format, data->conf->obs_var->path, data->conf->obs_var->frequency,
00165                        data->conf->obs_var->acronym[var], year1);
00166       }
00167       else {
00168         tmpi = year1 / 100;
00169         year1 = year1 - (tmpi*100);
00170         (void) sprintf(infile, format, data->conf->obs_var->path, data->conf->obs_var->frequency,
00171                        data->conf->obs_var->acronym[var], year1);
00172       }
00173     }
00174     
00175     /* Get time information for this input file if needed */
00176     if ( strcmp(prev_infile, infile) ) {
00177       (void) printf("%s: Reading observation data %s from %s\n", __FILE__, varname, infile);
00178       if (time_s != NULL) {
00179         (void) free(time_s->year);
00180         (void) free(time_s->month);
00181         (void) free(time_s->day);
00182         (void) free(time_s->hour);
00183         (void) free(time_s->minutes);
00184         (void) free(time_s->seconds);
00185         
00186         (void) free(time_s);
00187         (void) free(cal_type);
00188         (void) free(time_units);
00189         (void) free(timeval);
00190       }
00191       
00192       time_s = (time_vect_struct *) malloc(sizeof(time_vect_struct));
00193       if (time_s == NULL) alloc_error(__FILE__, __LINE__);
00194       
00195       istat = get_time_info(time_s, &timeval, &time_units, &cal_type, &ntime_obs, infile, data->conf->obs_var->timename, FALSE);
00196       if (istat < 0) {
00197         (void) free(time_s);
00198         (void) free(infile);
00199         (void) free(prev_infile);
00200         (void) free(format);
00201         (void) free(info);
00202         (void) free(proj);
00203         return -1;
00204       }
00205     }
00206     
00207     /* Find date in observation database */
00208     found = FALSE;
00209     tl = 0;
00210     while (tl<ntime_obs && found == FALSE) {
00211       if (year[t] == time_s->year[tl] && month[t] == time_s->month[tl] && day[t] == time_s->day[tl])
00212         found = TRUE;
00213       tl++;
00214     }
00215     
00216     if (found == TRUE) {
00217       
00218       tl--;
00219           
00220       /* Read data */
00221       istat = read_netcdf_var_3d_2d(&buf, info, proj, infile, data->conf->obs_var->acronym[var],
00222                                     data->conf->obs_var->dimxname, data->conf->obs_var->dimyname, data->conf->obs_var->timename,
00223                                     tl, nlon, nlat, &ntime_file, FALSE);
00224       *missing_value = info->fillvalue;
00225 
00226       if (data->conf->obs_var->proj->name == NULL) {
00227         /* Retrieve observation grid parameters if not done already */
00228         data->conf->obs_var->proj->name = strdup(proj->name);
00229         data->conf->obs_var->proj->grid_mapping_name = strdup(proj->grid_mapping_name);
00230         data->conf->obs_var->proj->latin1 = proj->latin1;
00231         data->conf->obs_var->proj->latin2 = proj->latin2;
00232         data->conf->obs_var->proj->lonc = proj->lonc;
00233         data->conf->obs_var->proj->lat0 = proj->lat0;
00234         data->conf->obs_var->proj->false_easting = proj->false_easting;
00235         data->conf->obs_var->proj->false_northing = proj->false_northing;
00236       }
00237 
00238       if ( (*lat) == NULL && (*lon) == NULL ) {
00239         /* Get latitude and longitude coordinates information */
00240         istat = read_netcdf_latlon(lon, lat, nlon, nlat, data->conf->obs_var->dimcoords, data->conf->obs_var->proj->coords,
00241                                    data->conf->obs_var->proj->name, data->conf->obs_var->lonname,
00242                                    data->conf->obs_var->latname, data->conf->obs_var->dimxname,
00243                                    data->conf->obs_var->dimyname, infile);
00244             
00245         /* Allocate buffer memory given dimensions */
00246         *buffer = (double *) malloc((*nlon)*(*nlat)*ntime * sizeof(double));
00247         if ( (*buffer) == NULL) alloc_error(__FILE__, __LINE__);
00248       }
00249 
00250       /* Transfer data */
00251       for (j=0; j<(*nlat); j++)
00252         for (i=0; i<(*nlon); i++)
00253           if (buf[i+j*(*nlon)] != (*missing_value))
00254             (*buffer)[i+j*(*nlon)+t*(*nlon)*(*nlat)] = (buf[i+j*(*nlon)] * data->conf->obs_var->factor[var]) +
00255               data->conf->obs_var->delta[var];
00256           else
00257             (*buffer)[i+j*(*nlon)+t*(*nlon)*(*nlat)] = (*missing_value);
00258                     
00259       /* Free allocated memory */
00260       (void) free(proj->name);
00261       (void) free(proj->grid_mapping_name);
00262           
00263       (void) free(info->grid_mapping);
00264       (void) free(info->units);
00265       (void) free(info->height);
00266       (void) free(info->coordinates);
00267       (void) free(info->long_name);
00268 
00269       (void) free(buf);
00270     }
00271     else {
00272       (void) fprintf(stderr, "%s: Fatal error in algorithm: date not found: %d %d %d %d!!\n", __FILE__, t, year[t],month[t],day[t]);
00273           
00274       /* Fatal error */
00275       (void) free(infile);
00276       (void) free(format);
00277           
00278       (void) free(info);
00279       (void) free(proj);
00280           
00281       if (time_s != NULL) {
00282         (void) free(time_s->year);
00283         (void) free(time_s->month);
00284         (void) free(time_s->day);
00285         (void) free(time_s->hour);
00286         (void) free(time_s->minutes);
00287         (void) free(time_s->seconds);
00288           
00289         (void) free(time_s);
00290         (void) free(cal_type);
00291         (void) free(time_units);
00292         (void) free(timeval);
00293       }
00294           
00295       return -1;
00296     }
00297     (void) strcpy(prev_infile, infile);
00298   }
00299 
00300   /* Free allocated memory */
00301   if (time_s != NULL) {
00302     (void) free(time_s->year);
00303     (void) free(time_s->month);
00304     (void) free(time_s->day);
00305     (void) free(time_s->hour);
00306     (void) free(time_s->minutes);
00307     (void) free(time_s->seconds);
00308 
00309     (void) free(time_s);
00310     (void) free(cal_type);
00311     (void) free(time_units);
00312     (void) free(timeval);
00313   }
00314 
00315   (void) free(info);
00316   (void) free(proj);
00317           
00318   (void) free(infile);
00319   (void) free(prev_infile);
00320   (void) free(format);
00321   
00322   /* Success diagnostic */
00323   return 0;
00324 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1