Read Learning data from input files. Currently only NetCDF is implemented. More...
#include <dsclim.h>
Go to the source code of this file.
Functions | |
int | read_learning_fields (data_struct *data) |
Read Learning data from input files. |
Read Learning data from input files. Currently only NetCDF is implemented.
Definition in file read_learning_fields.c.
int read_learning_fields | ( | data_struct * | data | ) |
Read Learning data from input files.
Currently only NetCDF is implemented.
[in] | data | MASTER data structure. |
We read as many season times the same variable to have the same values available for each season!
Create whole period time info from separate season info merging
Definition at line 66 of file read_learning_fields.c.
References alloc_error(), learning_data_struct::class_clusters, conf_struct::clustname, data_struct::conf, field_struct::data, learning_struct::data, time_vect_struct::day, field_data_struct::eof_info, conf_struct::eofname, data_struct::field, learning_struct::filename_open_clust_learn, learning_struct::filename_open_learn, learning_struct::filename_open_weight, get_time_info(), time_vect_struct::hour, data_struct::learning, time_vect_struct::minutes, time_vect_struct::month, field_struct::n_ls, season_struct::nclusters, eof_info_struct::neof_ls, learning_struct::nomvar_class_clusters, learning_struct::nomvar_pc_normalized_var, learning_struct::nomvar_precip_index, learning_struct::nomvar_precip_reg, learning_struct::nomvar_precip_reg_cst, learning_struct::nomvar_precip_reg_dist, learning_struct::nomvar_precip_reg_err, learning_struct::nomvar_sup_index, learning_struct::nomvar_sup_index_mean, learning_struct::nomvar_sup_index_var, learning_struct::nomvar_sup_val, learning_struct::nomvar_time, learning_struct::nomvar_weight, reg_struct::npts, season_struct::nreg, conf_struct::nseasons, learning_struct::ntime, learning_data_struct::ntime, learning_struct::pc_normalized_var, learning_data_struct::precip_index, learning_data_struct::precip_reg, learning_data_struct::precip_reg_cst, learning_data_struct::precip_reg_dist, learning_data_struct::precip_reg_err, conf_struct::ptsname, read_netcdf_var_1d(), read_netcdf_var_2d(), read_netcdf_var_3d(), read_netcdf_var_generic_val(), data_struct::reg, conf_struct::season, season_struct::secondary_cov, time_vect_struct::seconds, learning_data_struct::sup_index, learning_data_struct::sup_index_mean, learning_data_struct::sup_index_var, learning_struct::sup_lat, learning_struct::sup_latname, learning_struct::sup_lon, learning_struct::sup_lonname, learning_struct::sup_nlat, learning_struct::sup_nlon, learning_data_struct::sup_val, learning_data_struct::time, learning_struct::time_s, learning_data_struct::time_s, TRUE, learning_data_struct::weight, and time_vect_struct::year.
Referenced by wt_learning().
00066 { 00073 int istat; /* Diagnostic status */ 00074 int i; /* Loop counter */ 00075 int t; /* Loop counter */ 00076 int ii; /* Loop counter */ 00077 char *nomvar = NULL; /* Variable name in NetCDF file */ 00078 char *nomvar_time = NULL; /* Time variable name in NetCDF file */ 00079 char *nomvar_season = NULL; /* Season variable name in NetCDF file */ 00080 char *name = NULL; /* Dimension name in NetCDF file */ 00081 char *cal_type = NULL; /* Calendar type (udunits) */ 00082 char *time_units = NULL; /* Time units (udunits) */ 00083 double *bufd = NULL; /* Temporary buffer */ 00084 double *time_sort = NULL; /* Temporary time info used for time merging */ 00085 size_t *time_index = NULL; /* Temporary time index used for time merging */ 00086 int total_t; /* Total number of times used for time merging */ 00087 int neof; /* EOF dimension */ 00088 int npts; /* Points dimension */ 00089 int nclusters; /* Clusters dimension */ 00090 int neof_file; /* EOF dimension in input file */ 00091 00092 data->learning->sup_lat = data->learning->sup_lon = NULL; 00093 00094 /* Allocate memory for temporary strings */ 00095 nomvar = (char *) malloc(500 * sizeof(char)); 00096 if (nomvar == NULL) alloc_error(__FILE__, __LINE__); 00097 nomvar_time = (char *) malloc(500 * sizeof(char)); 00098 if (nomvar_time == NULL) alloc_error(__FILE__, __LINE__); 00099 nomvar_season = (char *) malloc(500 * sizeof(char)); 00100 if (nomvar_season == NULL) alloc_error(__FILE__, __LINE__); 00101 name = (char *) malloc(500 * sizeof(char)); 00102 if (name == NULL) alloc_error(__FILE__, __LINE__); 00103 00104 /* Initialize season string */ 00105 (void) strcpy(nomvar_season, "season"); 00106 00107 /* Loop over all the seasons */ 00108 for (i=0; i<data->conf->nseasons; i++) { 00109 00110 if (data->conf->season[i].secondary_cov == TRUE && data->learning->sup_lat == NULL) { 00111 /* Read lat variable */ 00112 istat = read_netcdf_var_2d(&(data->learning->sup_lat), (info_field_struct *) NULL, (proj_struct *) NULL, 00113 data->learning->filename_open_learn, 00114 data->learning->sup_latname, data->learning->sup_lonname, data->learning->sup_latname, 00115 &(data->learning->sup_nlon), &(data->learning->sup_nlat), TRUE); 00116 if (istat != 0) { 00117 /* In case of failure */ 00118 (void) free(nomvar); 00119 (void) free(nomvar_time); 00120 (void) free(nomvar_season); 00121 (void) free(name); 00122 return istat; 00123 } 00124 } 00125 if (data->conf->season[i].secondary_cov == TRUE && data->learning->sup_lon == NULL) { 00126 /* Read lon variable */ 00127 istat = read_netcdf_var_2d(&(data->learning->sup_lon), (info_field_struct *) NULL, (proj_struct *) NULL, 00128 data->learning->filename_open_learn, 00129 data->learning->sup_lonname, data->learning->sup_lonname, data->learning->sup_latname, 00130 &(data->learning->sup_nlon), &(data->learning->sup_nlat), TRUE); 00131 if (istat != 0) { 00132 /* In case of failure */ 00133 (void) free(nomvar); 00134 (void) free(nomvar_time); 00135 (void) free(nomvar_season); 00136 (void) free(name); 00137 return istat; 00138 } 00139 } 00140 00141 /* Read time data and info */ 00142 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_time, i+1); 00143 (void) sprintf(nomvar_time, "%s_%d", data->learning->nomvar_time, i+1); 00144 istat = get_time_info(data->learning->data[i].time_s, &(data->learning->data[i].time), &time_units, &cal_type, 00145 &(data->learning->data[i].ntime), 00146 data->learning->filename_open_learn, nomvar_time, TRUE); 00147 (void) free(cal_type); 00148 (void) free(time_units); 00149 if (istat != 0) { 00150 /* In case of failure */ 00151 (void) free(nomvar); 00152 (void) free(nomvar_time); 00153 (void) free(nomvar_season); 00154 (void) free(name); 00155 return istat; 00156 } 00157 00158 /* Read weight data */ 00159 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_weight, i+1); 00160 (void) sprintf(name, "%s_%d", data->conf->clustname, i+1); 00161 istat = read_netcdf_var_2d(&(data->learning->data[i].weight), (info_field_struct *) NULL, (proj_struct *) NULL, 00162 data->learning->filename_open_weight, nomvar, data->conf->eofname, name, 00163 &neof_file, &nclusters, TRUE); 00164 /* Save EOF dimension for control and model large-scale fields */ 00165 if (data->field[0].n_ls > 0) { 00166 if (data->field[0].data[0].eof_info->neof_ls != neof_file) { 00167 (void) fprintf(stderr, "%s: ERROR: Number of EOFs in learning weight datafile (%d) is not equal to number of EOFs specified in XML configuration file for model large-scale fields (%d)!\n", __FILE__, neof_file, data->field[0].data[0].eof_info->neof_ls); 00168 (void) free(nomvar); 00169 (void) free(nomvar_time); 00170 (void) free(nomvar_season); 00171 (void) free(name); 00172 return -1; 00173 } 00174 } 00175 if (data->field[1].n_ls > 0) 00176 if (data->field[1].data[0].eof_info->neof_ls != neof_file) { 00177 (void) fprintf(stderr, "%s: ERROR: Number of EOFs in learning weight datafile (%d) is not equal to number of EOFs specified in XML configuration file for control large-scale fields (%d)!\n", __FILE__, neof_file, data->field[1].data[0].eof_info->neof_ls); 00178 (void) free(nomvar); 00179 (void) free(nomvar_time); 00180 (void) free(nomvar_season); 00181 (void) free(name); 00182 return -1; 00183 } 00184 00185 /* If clusters dimension is not initialized, use retrieved info from input file */ 00186 if (data->conf->season[i].nclusters == -1) 00187 data->conf->season[i].nclusters = nclusters; 00188 /* Else verify that they match */ 00189 else if (data->conf->season[i].nclusters != nclusters) { 00190 (void) fprintf(stderr, "%s: ERROR: Incorrect number of clusters in NetCDF file. Season %d, nclusters=%d vs configuration file %d.\n", 00191 __FILE__, i, nclusters, data->conf->season[i].nclusters); 00192 (void) free(nomvar); 00193 (void) free(nomvar_time); 00194 (void) free(nomvar_season); 00195 (void) free(name); 00196 return -1; 00197 } 00198 if (istat != 0) { 00199 /* In case of failure */ 00200 (void) free(nomvar); 00201 (void) free(nomvar_time); 00202 (void) free(nomvar_season); 00203 (void) free(name); 00204 return istat; 00205 } 00206 00207 /* Read precip_reg data (precipitation regression coefficients) */ 00208 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_precip_reg, i+1); 00209 (void) sprintf(name, "%s_%d", data->conf->clustname, i+1); 00210 istat = read_netcdf_var_2d(&(data->learning->data[i].precip_reg), (info_field_struct *) NULL, (proj_struct *) NULL, 00211 data->learning->filename_open_learn, 00212 nomvar, data->conf->ptsname, name, 00213 &npts, &(data->conf->season[i].nreg), TRUE); 00214 /* Verify that points dimension match configuration value */ 00215 if (npts != data->reg->npts) { 00216 (void) fprintf(stderr, "%s: ERROR: Incorrect number of points in NetCDF file %d vs configuration file %d.\n", 00217 __FILE__, npts, data->reg->npts); 00218 (void) free(nomvar); 00219 (void) free(nomvar_time); 00220 (void) free(nomvar_season); 00221 (void) free(name); 00222 return -1; 00223 } 00224 if (istat != 0) { 00225 /* In case of failure */ 00226 (void) free(nomvar); 00227 (void) free(nomvar_time); 00228 (void) free(nomvar_season); 00229 (void) free(name); 00230 return istat; 00231 } 00232 00233 /* Read precip_reg_cst data (precipitation regression constant) */ 00234 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_precip_reg_cst, i+1); 00235 istat = read_netcdf_var_1d(&(data->learning->data[i].precip_reg_cst), (info_field_struct *) NULL, 00236 data->learning->filename_open_learn, nomvar, data->conf->ptsname, &npts, TRUE); 00237 /* Verify that points dimension match configuration value */ 00238 if (npts != data->reg->npts) { 00239 (void) fprintf(stderr, "%s: ERROR: Incorrect number of points in NetCDF file %d vs configuration file %d.\n", 00240 __FILE__, npts, data->reg->npts); 00241 (void) free(nomvar); 00242 (void) free(nomvar_time); 00243 (void) free(nomvar_season); 00244 (void) free(name); 00245 return -1; 00246 } 00247 if (istat != 0) { 00248 /* In case of failure */ 00249 (void) free(nomvar); 00250 (void) free(nomvar_time); 00251 (void) free(nomvar_season); 00252 (void) free(name); 00253 return istat; 00254 } 00255 00256 /* Read precip_index data (precipitation index for learning period over all regression points) */ 00257 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_precip_index, i+1); 00258 istat = read_netcdf_var_2d(&(data->learning->data[i].precip_index), (info_field_struct *) NULL, (proj_struct *) NULL, 00259 data->learning->filename_open_learn, 00260 nomvar, data->conf->ptsname, nomvar_time, 00261 &npts, &(data->learning->data[i].ntime), TRUE); 00262 /* Verify that points dimension match configuration value */ 00263 if (npts != data->reg->npts) { 00264 (void) fprintf(stderr, "%s: ERROR: Incorrect number of points in NetCDF file %d vs configuration file %d.\n", 00265 __FILE__, npts, data->reg->npts); 00266 (void) free(nomvar); 00267 (void) free(nomvar_time); 00268 (void) free(nomvar_season); 00269 (void) free(name); 00270 return -1; 00271 } 00272 if (istat != 0) { 00273 /* In case of failure */ 00274 (void) free(nomvar); 00275 (void) free(nomvar_time); 00276 (void) free(nomvar_season); 00277 (void) free(name); 00278 return istat; 00279 } 00280 00281 /* Read optional precip_reg_err data (regression residuals for learning period over all regression points) */ 00282 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_precip_reg_err, i+1); 00283 istat = read_netcdf_var_2d(&(data->learning->data[i].precip_reg_err), (info_field_struct *) NULL, (proj_struct *) NULL, 00284 data->learning->filename_open_learn, 00285 nomvar, data->conf->ptsname, nomvar_time, 00286 &npts, &(data->learning->data[i].ntime), TRUE); 00287 if (istat != 0) { 00288 /* In case of failure */ 00289 /* Support the fact that this variable is not in pre-1.5.15 dsclim version output files, so it is optional */ 00290 data->learning->data[i].precip_reg_err = NULL; 00291 (void) fprintf(stderr, "%s: WARNING: Old learning file without precip_reg_err data.\n", __FILE__); 00292 } 00293 else { 00294 /* Verify that points dimension match configuration value */ 00295 if (npts != data->reg->npts) { 00296 (void) fprintf(stderr, "%s: ERROR: Incorrect number of points in NetCDF file %d vs configuration file %d.\n", 00297 __FILE__, npts, data->reg->npts); 00298 (void) free(nomvar); 00299 (void) free(nomvar_time); 00300 (void) free(nomvar_season); 00301 (void) free(name); 00302 return -1; 00303 } 00304 } 00305 00306 /* Read cluster distances data (normalized distances for learning period over all clusters) */ 00307 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_precip_reg_dist, i+1); 00308 (void) sprintf(name, "%s_%d", data->conf->clustname, i+1); 00309 istat = read_netcdf_var_2d(&(data->learning->data[i].precip_reg_dist), (info_field_struct *) NULL, (proj_struct *) NULL, 00310 data->learning->filename_open_learn, 00311 nomvar, name, nomvar_time, 00312 &nclusters, &(data->learning->data[i].ntime), TRUE); 00313 if (istat != 0) { 00314 /* In case of failure */ 00315 /* Support the fact that this variable is not in pre-1.5.15 dsclim version output files, so it is optional */ 00316 data->learning->data[i].precip_reg_dist = NULL; 00317 (void) fprintf(stderr, "%s: WARNING: Old learning file without cluster distances data.\n", __FILE__); 00318 } 00319 else { 00320 /* If clusters dimension is not initialized, use retrieved info from input file */ 00321 if (data->conf->season[i].nclusters == -1) 00322 data->conf->season[i].nclusters = nclusters; 00323 /* Else verify that they match */ 00324 else if (data->conf->season[i].nclusters != nclusters) { 00325 (void) fprintf(stderr, "%s: ERROR: Incorrect number of clusters in NetCDF file. Season %d, nclusters=%d vs configuration file %d.\n", 00326 __FILE__, i, nclusters, data->conf->season[i].nclusters); 00327 (void) free(nomvar); 00328 (void) free(nomvar_time); 00329 (void) free(nomvar_season); 00330 (void) free(name); 00331 return -1; 00332 } 00333 } 00334 00335 /* Read cluster allocation data */ 00336 bufd = NULL; 00337 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_class_clusters, i+1); 00338 istat = read_netcdf_var_1d(&bufd, (info_field_struct *) NULL, 00339 data->learning->filename_open_clust_learn, nomvar, nomvar_time, 00340 &(data->learning->data[i].ntime), TRUE); 00341 if (istat != 0) { 00342 /* In case of failure */ 00343 (void) free(nomvar); 00344 (void) free(nomvar_time); 00345 (void) free(nomvar_season); 00346 (void) free(name); 00347 return istat; 00348 } 00349 /* Transfer data into proper data structure */ 00350 data->learning->data[i].class_clusters = malloc(data->learning->data[i].ntime * sizeof(int)); 00351 if (data->learning->data[i].class_clusters == NULL) alloc_error(__FILE__, __LINE__); 00352 for (ii=0; ii<data->learning->data[i].ntime; ii++) 00353 data->learning->data[i].class_clusters[ii] = bufd[ii]; 00354 (void) free(bufd); 00355 00356 /* Read sup_index data (secondary large-scale field index for learning period) */ 00357 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_sup_index, i+1); 00358 istat = read_netcdf_var_1d(&(data->learning->data[i].sup_index), (info_field_struct *) NULL, 00359 data->learning->filename_open_learn, nomvar, nomvar_time, 00360 &(data->learning->data[i].ntime), TRUE); 00361 if (istat != 0) { 00362 /* In case of failure */ 00363 (void) free(nomvar); 00364 (void) free(nomvar_time); 00365 (void) free(nomvar_season); 00366 (void) free(name); 00367 return istat; 00368 } 00369 00370 if (data->conf->season[i].secondary_cov == TRUE) { 00371 (void) sprintf(nomvar, "%s_%d", data->learning->nomvar_sup_val, i+1); 00372 istat = read_netcdf_var_3d(&(data->learning->data[i].sup_val), (info_field_struct *) NULL, (proj_struct *) NULL, 00373 data->learning->filename_open_learn, 00374 nomvar, data->learning->sup_lonname, data->learning->sup_latname, nomvar_time, 00375 &(data->learning->sup_nlon), &(data->learning->sup_nlat), &(data->learning->data[i].ntime), TRUE); 00376 if (istat != 0) { 00377 /* In case of failure */ 00378 (void) free(nomvar); 00379 (void) free(nomvar_time); 00380 (void) free(nomvar_season); 00381 (void) free(name); 00382 return istat; 00383 } 00384 } 00385 else 00386 data->learning->data[i].sup_val = NULL; 00387 00388 00391 /* Read sup_index_mean data (secondary large-scale field index spatial mean for learning period) */ 00392 istat = read_netcdf_var_generic_val(&(data->learning->data[i].sup_index_mean), (info_field_struct *) NULL, 00393 data->learning->filename_open_learn, data->learning->nomvar_sup_index_mean, i); 00394 if (istat != 0) { 00395 /* In case of failure */ 00396 (void) free(nomvar); 00397 (void) free(nomvar_time); 00398 (void) free(nomvar_season); 00399 (void) free(name); 00400 return istat; 00401 } 00402 00403 /* Read sup_index_var data (secondary large-scale field index spatial variance for learning period) */ 00404 istat = read_netcdf_var_generic_val(&(data->learning->data[i].sup_index_var), (info_field_struct *) NULL, 00405 data->learning->filename_open_learn, data->learning->nomvar_sup_index_var, i); 00406 if (istat != 0) { 00407 /* In case of failure */ 00408 (void) free(nomvar); 00409 (void) free(nomvar_time); 00410 (void) free(nomvar_season); 00411 (void) free(name); 00412 return istat; 00413 } 00414 } 00415 00418 /* Allocate memory and set pointers to NULL for realloc use */ 00419 time_index = (size_t *) malloc(data->conf->nseasons * sizeof(size_t)); 00420 if (time_index == NULL) alloc_error(__FILE__, __LINE__); 00421 data->learning->time_s->year = NULL; 00422 data->learning->time_s->month = NULL; 00423 data->learning->time_s->day = NULL; 00424 data->learning->time_s->hour = NULL; 00425 data->learning->time_s->minutes = NULL; 00426 data->learning->time_s->seconds = NULL; 00427 00428 /* Sort the vector, get the sorted vector indexes */ 00429 time_sort = (double *) malloc(data->conf->nseasons * sizeof(double)); 00430 if (time_sort == NULL) alloc_error(__FILE__, __LINE__); 00431 /* Loop over seasons */ 00432 for (i=0; i<data->conf->nseasons; i++) 00433 time_sort[i] = data->learning->data[i].time[0]; 00434 /* Sorting */ 00435 (void) gsl_sort_index(time_index, time_sort, 1, (size_t) data->conf->nseasons); 00436 (void) free(time_sort); 00437 00438 /* Merge time info */ 00439 total_t = 0; 00440 for (i=0; i<data->conf->nseasons; i++) { 00441 for (t=0; t<data->learning->data[time_index[i]].ntime; t++) { 00442 data->learning->time_s->year = (int *) realloc(data->learning->time_s->year, (total_t+1) * sizeof(int)); 00443 if (data->learning->time_s->year == NULL) alloc_error(__FILE__, __LINE__); 00444 data->learning->time_s->month = (int *) realloc(data->learning->time_s->month, (total_t+1) * sizeof(int)); 00445 if (data->learning->time_s->month == NULL) alloc_error(__FILE__, __LINE__); 00446 data->learning->time_s->day = (int *) realloc(data->learning->time_s->day, (total_t+1) * sizeof(int)); 00447 if (data->learning->time_s->day == NULL) alloc_error(__FILE__, __LINE__); 00448 data->learning->time_s->hour = (int *) realloc(data->learning->time_s->hour, (total_t+1) * sizeof(int)); 00449 if (data->learning->time_s->hour == NULL) alloc_error(__FILE__, __LINE__); 00450 data->learning->time_s->minutes = (int *) realloc(data->learning->time_s->minutes, (total_t+1) * sizeof(int)); 00451 if (data->learning->time_s->minutes == NULL) alloc_error(__FILE__, __LINE__); 00452 data->learning->time_s->seconds = (double *) realloc(data->learning->time_s->seconds, (total_t+1) * sizeof(double)); 00453 if (data->learning->time_s->seconds == NULL) alloc_error(__FILE__, __LINE__); 00454 data->learning->time_s->year[total_t] = data->learning->data[time_index[i]].time_s->year[t]; 00455 data->learning->time_s->month[total_t] = data->learning->data[time_index[i]].time_s->month[t]; 00456 data->learning->time_s->day[total_t] = data->learning->data[time_index[i]].time_s->day[t]; 00457 data->learning->time_s->hour[total_t] = data->learning->data[time_index[i]].time_s->hour[t]; 00458 data->learning->time_s->minutes[total_t] = data->learning->data[time_index[i]].time_s->minutes[t]; 00459 data->learning->time_s->seconds[total_t] = data->learning->data[time_index[i]].time_s->seconds[t]; 00460 total_t++; 00461 } 00462 } 00463 /* Save total number of times */ 00464 data->learning->ntime = total_t; 00465 00466 /* Free temporary vector */ 00467 (void) free(time_index); 00468 00469 /* Read pc_normalized_var data (normalized EOF-projected large-scale field variance for learning period) */ 00470 istat = read_netcdf_var_1d(&(data->learning->pc_normalized_var), (info_field_struct *) NULL, 00471 data->learning->filename_open_learn, data->learning->nomvar_pc_normalized_var, data->conf->eofname, 00472 &neof, TRUE); 00473 if (neof != neof_file) { 00474 /* Verify that EOF dimension match configuration value */ 00475 (void) fprintf(stderr, "%s: ERROR: Number of EOFs in learning weight datafile (%d) is not equal to number of EOFs in learning datafile (%d)!\n", __FILE__, neof, neof_file); 00476 (void) free(nomvar); 00477 (void) free(nomvar_time); 00478 (void) free(nomvar_season); 00479 (void) free(name); 00480 return -1; 00481 } 00482 if (istat != 0) { 00483 /* In case of failure */ 00484 (void) free(nomvar); 00485 (void) free(nomvar_time); 00486 (void) free(nomvar_season); 00487 (void) free(name); 00488 return istat; 00489 } 00490 /* The square-root of variance is stored: convert back to variance */ 00491 for (ii=0; ii<neof; ii++) 00492 data->learning->pc_normalized_var[ii] = data->learning->pc_normalized_var[ii] * data->learning->pc_normalized_var[ii]; 00493 00494 /* Free memory */ 00495 (void) free(nomvar); 00496 (void) free(nomvar_time); 00497 (void) free(nomvar_season); 00498 (void) free(name); 00499 00500 /* Success status */ 00501 return 0; 00502 }