Read large-scale fields data from input files. Currently only NetCDF is implemented. More...
#include <dsclim.h>
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. |
Read large-scale fields data from input files. Currently only NetCDF is implemented.
Definition in file read_large_scale_fields.c.
int read_large_scale_fields | ( | data_struct * | data | ) |
Read large-scale fields data from input files.
Currently only NetCDF is implemented.
[in] | data | MASTER data structure. |
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 }