Get time NetCDF info. More...
#include <io.h>
Go to the source code of this file.
Functions | |
int | get_time_info (time_vect_struct *time_s, double **timeval, char **time_units, char **cal_type, int *ntime, char *filename, char *varname, int outinfo) |
Get time information in a NetCDF file. |
Get time NetCDF info.
Definition in file get_time_info.c.
int get_time_info | ( | time_vect_struct * | time_s, | |
double ** | timeval, | |||
char ** | time_units, | |||
char ** | cal_type, | |||
int * | ntime, | |||
char * | filename, | |||
char * | varname, | |||
int | outinfo | |||
) |
Get time information in a NetCDF file.
[out] | time_s | Time information in a time structure |
[out] | timeval | Time field |
[out] | time_units | Time units (udunits) |
[out] | cal_type | Calendar-type (udunits) |
[out] | ntime | Time dimension |
[in] | filename | NetCDF input filename |
[in] | varname | Variable name |
[in] | outinfo | TRUE if we want information output, FALSE if not |
Close NetCDF file
Definition at line 67 of file get_time_info.c.
References alloc_error(), time_vect_struct::day, handle_netcdf_error(), time_vect_struct::hour, time_vect_struct::minutes, time_vect_struct::month, time_vect_struct::seconds, TRUE, and time_vect_struct::year.
Referenced by output_downscaled_analog(), read_learning_fields(), read_learning_obs_eof(), read_learning_rea_eof(), and read_obs_period().
00068 { 00082 int istat; /* Diagnostic status */ 00083 00084 size_t dimval; /* Variable used to retrieve dimension length */ 00085 00086 int ncinid; /* NetCDF input file handle ID */ 00087 int timediminid; /* Time dimension ID */ 00088 int timeinid; /* Time variable ID */ 00089 nc_type vartype_time; /* Type of the time variable (NC_FLOAT, NC_DOUBLE, etc.) */ 00090 00091 int varndims; /* Number of dimensions of variable */ 00092 int vardimids[NC_MAX_VAR_DIMS]; /* Variable dimension ids */ 00093 00094 size_t start[3]; /* Start position to read */ 00095 size_t count[3]; /* Number of elements to read */ 00096 00097 size_t t_len; /* Length of time units attribute string */ 00098 ut_system *unitSystem = NULL; /* Unit System (udunits) */ 00099 ut_unit *dataunits = NULL; /* Data units (udunits) */ 00100 00101 int t; /* Time loop counter */ 00102 00103 /* Read data in NetCDF file */ 00104 00105 /* Open NetCDF file for reading */ 00106 if (outinfo == TRUE) 00107 printf("%s: Opening for reading time information in NetCDF input file %s\n", __FILE__, filename); 00108 istat = nc_open(filename, NC_NOWRITE, &ncinid); /* open for reading */ 00109 if (istat != NC_NOERR) { 00110 (void) fprintf(stderr, "%s: filename = %s\n", __FILE__, filename); 00111 handle_netcdf_error(istat, __FILE__, __LINE__); 00112 } 00113 00114 /* Get dimensions length and ID */ 00115 istat = nc_inq_dimid(ncinid, varname, &timediminid); /* get ID for time dimension */ 00116 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00117 istat = nc_inq_dimlen(ncinid, timediminid, &dimval); /* get time length */ 00118 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00119 *ntime = (int) dimval; 00120 00121 istat = nc_inq_varid(ncinid, varname, &timeinid); /* get ID for time variable */ 00122 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00123 00124 /* Get time dimensions and type */ 00125 istat = nc_inq_var(ncinid, timeinid, (char *) NULL, &vartype_time, &varndims, vardimids, (int *) NULL); /* get variable information */ 00126 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00127 00128 if (varndims != 1) { 00129 (void) fprintf(stderr, "Error NetCDF type and/or dimensions Line %d.\n", __LINE__); 00130 return -1; 00131 } 00132 00133 /* Allocate memory and set start and count */ 00134 start[0] = 0; 00135 count[0] = (size_t) (*ntime); 00136 (*timeval) = malloc((*ntime) * sizeof(double)); 00137 if ((*timeval) == NULL) alloc_error(__FILE__, __LINE__); 00138 00139 /* Read values from netCDF variable */ 00140 istat = nc_get_vara_double(ncinid, timeinid, start, count, *timeval); 00141 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00142 00143 /* Check values of time variable because many times they are all zero. In that case assume a 1 increment and a start at zero. */ 00144 for (t=0; t<(*ntime); t++) 00145 if ((*timeval)[t] != 0.0) 00146 break; 00147 if (t == (*ntime)) { 00148 fprintf(stderr, "WARNING: Time variable values all zero!!! Fixing time variable to index value...\n"); 00149 for (t=0; t<(*ntime); t++) 00150 (*timeval)[t] = (double) t; 00151 } 00152 00153 /* Get time units attribute length */ 00154 istat = nc_inq_attlen(ncinid, timeinid, "units", &t_len); 00155 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00156 /* Allocate required space before retrieving values */ 00157 (*time_units) = (char *) malloc((t_len+1) * sizeof(char)); 00158 if ((*time_units) == NULL) alloc_error(__FILE__, __LINE__); 00159 /* Get time units attribute value */ 00160 istat = nc_get_att_text(ncinid, timeinid, "units", *time_units); 00161 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00162 /* Correct if time units ends incorrectly with Z */ 00163 if ((*time_units)[t_len-2] == 'Z') 00164 (*time_units)[t_len-2] = '\0'; /* null terminate */ 00165 else if ((*time_units)[t_len-1] == 'Z') 00166 (*time_units)[t_len-1] = '\0'; /* null terminate */ 00167 else 00168 (*time_units)[t_len] = '\0'; 00169 00170 /* Get calendar type attribute length */ 00171 istat = nc_inq_attlen(ncinid, timeinid, "calendar", &t_len); 00172 if (istat != NC_NOERR) { 00173 /* If not present, assume standard calendar */ 00174 *cal_type = strdup("gregorian"); 00175 } 00176 else { 00177 /* Allocate required space before retrieving values */ 00178 (*cal_type) = (char *) malloc(t_len + 1); 00179 if ((*cal_type) == NULL) alloc_error(__FILE__, __LINE__); 00180 /* Get calendar type attribute value */ 00181 istat = nc_get_att_text(ncinid, timeinid, "calendar", *cal_type); 00182 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00183 (*cal_type)[t_len] = '\0'; /* null terminate */ 00184 } 00185 00186 /* Compute time info and store into easy time structure */ 00187 time_s->year = (int *) malloc((*ntime) * sizeof(int)); 00188 if (time_s->year == NULL) alloc_error(__FILE__, __LINE__); 00189 time_s->month = (int *) malloc((*ntime) * sizeof(int)); 00190 if (time_s->month == NULL) alloc_error(__FILE__, __LINE__); 00191 time_s->day = (int *) malloc((*ntime) * sizeof(int)); 00192 if (time_s->day == NULL) alloc_error(__FILE__, __LINE__); 00193 time_s->hour = (int *) malloc((*ntime) * sizeof(int)); 00194 if (time_s->hour == NULL) alloc_error(__FILE__, __LINE__); 00195 time_s->minutes = (int *) malloc((*ntime) * sizeof(int)); 00196 if (time_s->minutes == NULL) alloc_error(__FILE__, __LINE__); 00197 time_s->seconds = (double *) malloc((*ntime) * sizeof(double)); 00198 if (time_s->seconds == NULL) alloc_error(__FILE__, __LINE__); 00199 00200 /* Initialize udunits */ 00201 ut_set_error_message_handler(ut_ignore); 00202 unitSystem = ut_read_xml(NULL); 00203 ut_set_error_message_handler(ut_write_to_stderr); 00204 00205 dataunits = ut_parse(unitSystem, (*time_units), UT_ASCII); 00206 for (t=0; t<(*ntime); t++) { 00207 istat = utCalendar2_cal((*timeval)[t], dataunits, &(time_s->year[t]), &(time_s->month[t]), &(time_s->day[t]), 00208 &(time_s->hour[t]), &(time_s->minutes[t]), &(time_s->seconds[t]), *cal_type); 00209 if (istat < 0) { 00210 (void) ut_free(dataunits); 00211 (void) ut_free_system(unitSystem); 00212 return -1; 00213 } 00214 } 00215 00216 (void) ut_free(dataunits); 00217 (void) ut_free_system(unitSystem); 00218 00220 istat = ncclose(ncinid); 00221 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00222 00223 /* Success status */ 00224 return 0; 00225 }