read_large_scale_fields.c File Reference

Read large-scale fields data from input files. Currently only NetCDF is implemented. More...

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

Go to the source code of this file.

Functions

int read_large_scale_fields (data_struct *data)
 Read large-scale fields data from input files.

Detailed Description

Read large-scale fields data from input files. Currently only NetCDF is implemented.

Definition in file read_large_scale_fields.c.


Function Documentation

int read_large_scale_fields ( data_struct data  ) 

Read large-scale fields data from input files.

Currently only NetCDF is implemented.

Parameters:
[in] data MASTER data structure.
Returns:
Status.

Definition at line 67 of file read_large_scale_fields.c.

References alloc_error(), conf_struct::cal_type, change_date_origin(), compute_time_info(), data_struct::conf, proj_struct::coords, field_struct::data, data_to_gregorian_cal_d(), field_data_struct::dimxname, field_data_struct::dimyname, extract_subdomain(), data_struct::field, field_data_struct::field_ls, FIELD_LS, field_data_struct::filename_ls, conf_struct::fixtime, field_data_struct::info, data_struct::info, field_struct::lat_ls, conf_struct::latitude_max, conf_struct::latitude_min, field_data_struct::latname, field_struct::lon_ls, conf_struct::longitude_max, conf_struct::longitude_min, field_data_struct::lonname, field_struct::n_ls, proj_struct::name, NCAT, field_struct::nlat_ls, field_struct::nlon_ls, field_data_struct::nomvar_ls, field_struct::ntime_ls, field_struct::proj, read_netcdf_dims_3d(), read_netcdf_var_3d(), SEC_FIELD_LS, conf_struct::secondary_latitude_max, conf_struct::secondary_latitude_min, conf_struct::secondary_longitude_max, conf_struct::secondary_longitude_min, field_struct::time_ls, field_struct::time_s, conf_struct::time_units, field_data_struct::timename, TRUE, conf_struct::year_begin_ctrl, and conf_struct::year_begin_other.

Referenced by wt_downscaling().

00067                                            {
00074   int istat; /* Diagnostic status */
00075   int i; /* Loop counter */
00076   int t; /* Time loop counter */
00077   int cat; /* Field category loop counter */
00078   double *buf = NULL; /* Temporary data buffer */
00079   double *time_ls = NULL; /* Temporary time information buffer */
00080   double *lat = NULL; /* Temporary latitude buffer for main large-scale fields */
00081   double *lon = NULL; /* Temporary longitude buffer for main large-scale fields */
00082   char **cal_type; /* Calendar type (udunits) */
00083   char **time_units; /* Time units (udunits) */
00084   double longitude_min; /* Domain bounding box minimum longitude */
00085   double longitude_max; /* Domain bounding box maximum longitude */
00086   double latitude_min; /* Domain bounding box minimum latitude */
00087   double latitude_max; /* Domain bounding box maximum latitude */
00088   int ntime; /* Number of times dimension */
00089   int nlon; /* Longitude dimension for main large-scale fields */
00090   int nlat; /* Latitude dimension for main large-scale fields */
00091   int ntime_file; /* Number of times dimension in input file */
00092   int nlon_file; /* Longitude dimension for main large-scale fields in input file */
00093   int nlat_file; /* Latitude dimension for main large-scale fields in input file */
00094   
00095   int year_begin; /* When fixing time units, year to use as start date. */
00096 
00097   cal_type = (char **) malloc(NCAT * sizeof(char *));
00098   if (cal_type == NULL) alloc_error(__FILE__, __LINE__);
00099   time_units = (char **) malloc(NCAT * sizeof(char *));
00100   if (time_units == NULL) alloc_error(__FILE__, __LINE__);
00101 
00102   /* Loop over all large-scale field categories */
00103   for (cat=0; cat<NCAT; cat++) {
00104 
00105     cal_type[cat] = NULL;
00106     time_units[cat] = NULL;
00107 
00108     /* Select proper domain given large-scale field category */
00109     if (cat == 0 || cat == 1) {
00110       longitude_min = data->conf->longitude_min;
00111       longitude_max = data->conf->longitude_max;
00112       latitude_min = data->conf->latitude_min;
00113       latitude_max = data->conf->latitude_max;
00114     }
00115     else {
00116       longitude_min = data->conf->secondary_longitude_min;
00117       longitude_max = data->conf->secondary_longitude_max;
00118       latitude_min = data->conf->secondary_latitude_min;
00119       latitude_max = data->conf->secondary_latitude_max;
00120     }
00121 
00122     /* Free memory for loop and set pointers to NULL for realloc */
00123     if (data->field[cat].time_ls != NULL) {
00124       (void) free(data->field[cat].time_ls);
00125       data->field[cat].time_ls = NULL;
00126     }
00127     if (data->field[cat].lat_ls != NULL) {
00128       (void) free(data->field[cat].lat_ls);
00129       data->field[cat].lat_ls = NULL;
00130     }
00131     if (data->field[cat].lon_ls != NULL)  {
00132       (void) free(data->field[cat].lon_ls);
00133       data->field[cat].lon_ls = NULL;
00134     }
00135 
00136     /* Loop over large-scale fields */
00137     for (i=0; i<data->field[cat].n_ls; i++) {
00138       /* Retrieve dimensions if time buffer is not already set for this field category */
00139       if (data->field[cat].time_ls == NULL) {
00140         istat = read_netcdf_dims_3d(&lon, &lat, &time_ls, &(cal_type[cat]), &(time_units[cat]), &nlon, &nlat, &ntime,
00141                                     data->info, data->field[cat].proj[i].coords, data->field[cat].proj[i].name,
00142                                     data->field[cat].data[i].lonname, data->field[cat].data[i].latname,
00143                                     data->field[cat].data[i].dimxname, data->field[cat].data[i].dimyname,
00144                                     data->field[cat].data[i].timename,
00145                                     data->field[cat].data[i].filename_ls);
00146         if (istat < 0) {
00147           /* In case of failure */
00148           (void) free(lon);
00149           (void) free(lat);
00150           (void) free(time_ls);
00151           (void) free(time_units[cat]);
00152           (void) free(cal_type[cat]);
00153           return istat;
00154         }
00155         /* Adjust time units if we want to fix time (set in the configuration file) */
00156         if (data->conf->fixtime == TRUE) {
00157           if (cat == FIELD_LS || cat == SEC_FIELD_LS)
00158             year_begin = data->conf->year_begin_other;
00159           else
00160             year_begin = data->conf->year_begin_ctrl;
00161           if (istat != 1) {
00162             (void) fprintf(stderr, "\n%s: IMPORTANT WARNING: Time variable values all zero!!! Fixing time variable to index value, STARTING at 0...\n\n", __FILE__);
00163             for (t=0; t<ntime; t++)
00164               time_ls[t] = (double) t;
00165           }
00166           (void) fprintf(stdout, "%s: Fixing time units using start date %d-01-01 12:00:00.\n", __FILE__, year_begin);
00167           time_units[cat] = realloc(time_units[cat], 500 * sizeof(char));
00168           if (time_units[cat] == NULL) alloc_error(__FILE__, __LINE__);
00169           /* days since 1950-01-01 12:00:00 */
00170           (void) sprintf(time_units[cat], "days since %d-01-01 12:00:00", year_begin);
00171         }
00172       }
00173 
00174       /* For standard calendar data */
00175       if ( !strcmp(cal_type[cat], "gregorian") || !strcmp(cal_type[cat], "standard") ) {
00176         
00177         /* Read data */
00178         istat = read_netcdf_var_3d(&buf, data->field[cat].data[i].info, &(data->field[cat].proj[i]),
00179                                    data->field[cat].data[i].filename_ls,
00180                                    data->field[cat].data[i].nomvar_ls,
00181                                    data->field[cat].data[i].dimxname, data->field[cat].data[i].dimyname, data->field[cat].data[i].timename,
00182                                    &nlon_file, &nlat_file, &ntime_file, TRUE);
00183         if (nlon != nlon_file || nlat != nlat_file || ntime != ntime_file) {
00184           (void) fprintf(stderr, "%s: Problems in dimensions! nlat=%d nlat_file=%d nlon=%d nlon_file=%d ntime=%d ntime_file=%d\n",
00185                          __FILE__, nlat, nlat_file, nlon, nlon_file, ntime, ntime_file);
00186           istat = -1;
00187         }
00188         if (istat != 0) {
00189           /* In case of failure */
00190           (void) free(buf);
00191           (void) free(lon);
00192           (void) free(lat);
00193           (void) free(time_ls);
00194           (void) free(time_units[cat]);
00195           (void) free(cal_type[cat]);
00196           return istat;
00197         }
00198         
00199         /* Extract subdomain of spatial fields */
00200         if (data->field[cat].lon_ls != NULL) {
00201           (void) free(data->field[cat].lon_ls);
00202           data->field[cat].lon_ls = NULL;
00203         }
00204         if (data->field[cat].lat_ls != NULL) {
00205           (void) free(data->field[cat].lat_ls);
00206           data->field[cat].lat_ls = NULL;
00207         }
00208         if (data->field[cat].data[i].field_ls != NULL) {
00209           (void) free(data->field[cat].data[i].field_ls);
00210           data->field[cat].data[i].field_ls = NULL;
00211         }
00212 
00213         /* Extraction of subdomain */
00214         (void) extract_subdomain(&(data->field[cat].data[i].field_ls), &(data->field[cat].lon_ls), &(data->field[cat].lat_ls),
00215                                  &(data->field[cat].nlon_ls), &(data->field[cat].nlat_ls), buf, lon, lat,
00216                                  longitude_min, longitude_max, latitude_min, latitude_max, nlon, nlat, ntime);
00217         (void) free(buf);
00218 
00219         /* Save number of times dimension */
00220         data->field[cat].ntime_ls = ntime;
00221 
00222         /* If time info not already retrieved for this category, get time information and generate time structure */
00223         if (data->field[cat].time_ls == NULL) {
00224           data->field[cat].time_ls = (double *) malloc(data->field[cat].ntime_ls * sizeof(double));
00225           if (data->field[cat].time_ls == NULL) alloc_error(__FILE__, __LINE__);
00226           if ( strcmp(time_units[cat], data->conf->time_units) )
00227             (void) change_date_origin(data->field[cat].time_ls, data->conf->time_units, time_ls, time_units[cat], ntime);
00228           else
00229             for (t=0; t<data->field[cat].ntime_ls; t++)
00230               data->field[cat].time_ls[t] = time_ls[t];
00231           istat = compute_time_info(data->field[cat].time_s, data->field[cat].time_ls, data->conf->time_units, data->conf->cal_type,
00232                                     data->field[cat].ntime_ls);
00233         }
00234       }
00235       else {
00236         /* Non-standard calendar type */
00237 
00238         double *dummy = NULL;
00239 
00240         /* Free memory if previously allocated */
00241         if (data->field[cat].lon_ls != NULL) {
00242           (void) free(data->field[cat].lon_ls);
00243           data->field[cat].lon_ls = NULL;
00244         }
00245         if (data->field[cat].lat_ls != NULL) {
00246           (void) free(data->field[cat].lat_ls);
00247           data->field[cat].lat_ls = NULL;
00248         }
00249         if (data->field[cat].data[i].field_ls != NULL) {
00250           (void) free(data->field[cat].data[i].field_ls);
00251           data->field[cat].data[i].field_ls = NULL;
00252         }
00253         /* Read data and fix calendar */
00254         istat = read_netcdf_var_3d(&(data->field[cat].data[i].field_ls), data->field[cat].data[i].info,
00255                                    &(data->field[cat].proj[i]), data->field[cat].data[i].filename_ls,
00256                                    data->field[cat].data[i].nomvar_ls,
00257                                    data->field[cat].data[i].dimxname, data->field[cat].data[i].dimyname, data->field[cat].data[i].timename,
00258                                    &nlon_file, &nlat_file, &ntime_file, TRUE);
00259         if (nlon != nlon_file || nlat != nlat_file || ntime != ntime_file) {
00260           (void) fprintf(stderr, "%s: Problems in dimensions! nlat=%d nlat_file=%d nlon=%d nlon_file=%d ntime=%d ntime_file=%d\n",
00261                          __FILE__, nlat, nlat_file, nlon, nlon_file, ntime, ntime_file);
00262           istat = -1;
00263         }
00264         if (istat != 0) {
00265           /* In case of failure */
00266           (void) free(lon);
00267           (void) free(lat);
00268           (void) free(time_ls);
00269           (void) free(time_units[cat]);
00270           (void) free(cal_type[cat]);
00271           return istat;
00272         }
00273 
00274         /* Extract subdomain of spatial fields */
00275         (void) extract_subdomain(&buf, &(data->field[cat].lon_ls), &(data->field[cat].lat_ls),
00276                                  &(data->field[cat].nlon_ls), &(data->field[cat].nlat_ls), data->field[cat].data[i].field_ls, lon, lat,
00277                                  longitude_min, longitude_max, latitude_min, latitude_max, nlon, nlat, ntime);
00278         (void) free(data->field[cat].data[i].field_ls);
00279 
00280         /* Adjust calendar to standard calendar */
00281         istat = data_to_gregorian_cal_d(&(data->field[cat].data[i].field_ls), &dummy, &(data->field[cat].ntime_ls),
00282                                         buf, time_ls, time_units[cat], data->conf->time_units,
00283                                         cal_type[cat], data->field[cat].nlon_ls, data->field[cat].nlat_ls, ntime);
00284         if (istat < 0) {
00285           /* In case of failure */
00286           (void) free(lon);
00287           (void) free(lat);
00288           (void) free(time_ls);
00289           (void) free(time_units[cat]);
00290           (void) free(cal_type[cat]);
00291           (void) free(buf);
00292           (void) free(data->field[cat].lon_ls);
00293           (void) free(data->field[cat].lat_ls);
00294           (void) free(data->field[cat].data[i].field_ls);
00295           return istat;
00296         }
00297         if (data->field[cat].time_ls == NULL) {
00298           data->field[cat].time_ls = (double *) malloc(data->field[cat].ntime_ls * sizeof(double));
00299           if (data->field[cat].time_ls == NULL) alloc_error(__FILE__, __LINE__);
00300           for (t=0; t<data->field[cat].ntime_ls; t++)
00301             data->field[cat].time_ls[t] = dummy[t];
00302           istat = compute_time_info(data->field[cat].time_s, data->field[cat].time_ls, data->conf->time_units, data->conf->cal_type,
00303                                     data->field[cat].ntime_ls);
00304         }
00305         (void) free(dummy);
00306         (void) free(buf);
00307       }
00308     }
00309     /* Free memory */
00310     if (lat != NULL) {
00311       (void) free(lat);
00312       lat = NULL;
00313     }
00314     if (lon != NULL) {
00315       (void) free(lon);
00316       lon = NULL;
00317     }
00318     if (time_ls != NULL) {
00319       (void) free(time_ls);
00320       time_ls = NULL;
00321     }
00322     if (time_units[cat] != NULL) {
00323       (void) free(time_units[cat]);
00324       time_units[cat] = NULL;
00325     }
00326     if (cal_type[cat] != NULL) {
00327       (void) free(cal_type[cat]);
00328       cal_type[cat] = NULL;
00329     }
00330   }
00331 
00332   (void) free(time_units);
00333   (void) free(cal_type);
00334 
00335   /* Diagnostic status */
00336   return 0;
00337 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1