get_time_info.c File Reference

Get time NetCDF info. More...

#include <io.h>
Include dependency graph for get_time_info.c:

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.

Detailed Description

Get time NetCDF info.

Definition in file get_time_info.c.


Function Documentation

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.

Parameters:
[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
Returns:
Status.

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 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1