Read NetCDF dimensions. More...
#include <io.h>
Go to the source code of this file.
Functions | |
int | read_netcdf_dims_3d (double **lon, double **lat, double **timeval, char **cal_type, char **time_units, int *nlon, int *nlat, int *ntime, info_struct *info, char *coords, char *gridname, char *lonname, char *latname, char *dimxname, char *dimyname, char *timename, char *filename) |
Read dimensions in a NetCDF file for 3D variables. |
Read NetCDF dimensions.
Definition in file read_netcdf_dims_3d.c.
int read_netcdf_dims_3d | ( | double ** | lon, | |
double ** | lat, | |||
double ** | timeval, | |||
char ** | cal_type, | |||
char ** | time_units, | |||
int * | nlon, | |||
int * | nlat, | |||
int * | ntime, | |||
info_struct * | info, | |||
char * | coords, | |||
char * | gridname, | |||
char * | lonname, | |||
char * | latname, | |||
char * | dimxname, | |||
char * | dimyname, | |||
char * | timename, | |||
char * | filename | |||
) |
Read dimensions in a NetCDF file for 3D variables.
[out] | lon | Longitude field |
[out] | lat | Latitude field |
[out] | timeval | Time field |
[out] | cal_type | Calendar type (udunits) |
[out] | time_units | Time units (udunits) |
[out] | nlon | Longitude dimension |
[out] | nlat | Latitude dimension |
[out] | ntime | Time dimension |
[out] | info | Information structure for global NetCDF attributes |
[in] | coords | Coordinates arrangement of latitude and longitude data: either 1D or 2D |
[in] | gridname | Projection grid name |
[in] | lonname | Longitude dimension name |
[in] | latname | Latitude dimension name |
[in] | dimxname | X Dimension name |
[in] | dimyname | Y Dimension name |
[in] | timename | Time dimension name |
[in] | filename | Input NetCDF filename |
1D dimensions lat & lon
1D dimensions x and y with 2D lat & lon related variables
1D dimensions x and y with 2D lat & lon related variables
Read dimensions variables
Definition at line 66 of file read_netcdf_dims_3d.c.
References alloc_error(), info_struct::contact_email, info_struct::contact_name, info_struct::country, info_struct::creator_email, info_struct::creator_name, info_struct::creator_url, info_struct::description, info_struct::downscaling_forcing, FALSE, get_attribute_str(), handle_netcdf_error(), info_struct::institution, info_struct::institution_model, info_struct::keywords, info_struct::member, info_struct::model, info_struct::other_contact_email, info_struct::other_contact_name, info_struct::processor, info_struct::scenario, info_struct::scenario_co2, info_struct::summary, info_struct::summary_french, info_struct::timestep, info_struct::title, info_struct::title_french, TRUE, and info_struct::version.
Referenced by read_field_subdomain_period(), and read_large_scale_fields().
00068 { 00091 int istat; /* Diagnostic status */ 00092 int fixtime = FALSE; /* If we fixed time or not */ 00093 00094 size_t dimval; /* Variable used to retrieve dimension length */ 00095 00096 int ncinid; /* NetCDF input file handle ID */ 00097 int latinid; /* Latitude variable ID */ 00098 int loninid; /* Longitude variable ID */ 00099 int timeinid; /* Time variable ID */ 00100 nc_type vartype; /* Type of the variable (NC_FLOAT, NC_DOUBLE, etc.) */ 00101 int varndims; /* Number of dimensions of variable */ 00102 int vardimids[NC_MAX_VAR_DIMS]; /* Variable dimension ids */ 00103 int timediminid; /* Time dimension ID */ 00104 int londiminid; /* Longitude dimension ID */ 00105 int latdiminid; /* Latitude dimension ID */ 00106 00107 size_t start[3]; /* Start position to read */ 00108 size_t count[3]; /* Number of elements to read */ 00109 00110 double *tmpd = NULL; /* Temporary buffer to read variable from NetCDF file */ 00111 00112 int i; /* Loop counter */ 00113 int j; /* Loop counter */ 00114 int t; /* Time loop counter */ 00115 int ndims; /* Number of dimensions of latitude and longitude variables, 1 or 2 for 1D and 2D respectively */ 00116 00117 /* Read data in NetCDF file */ 00118 00119 /* Open NetCDF file for reading */ 00120 printf("%s: Reading info from NetCDF input file %s\n", __FILE__, filename); 00121 istat = nc_open(filename, NC_NOWRITE, &ncinid); /* open for reading */ 00122 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00123 00124 /* Get dimensions ID */ 00125 istat = nc_inq_dimid(ncinid, timename, &timediminid); /* get ID for time dimension */ 00126 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00127 istat = nc_inq_dimlen(ncinid, timediminid, &dimval); /* get time length */ 00128 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00129 *ntime = (int) dimval; 00130 00131 if ( !strcmp(coords, "1D") ) { 00133 ndims = 1; 00134 00135 /* Get dimensions length */ 00136 istat = nc_inq_dimid(ncinid, dimyname, &latdiminid); /* get ID for lat dimension */ 00137 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00138 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */ 00139 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00140 *nlat = (int) dimval; 00141 00142 istat = nc_inq_dimid(ncinid, dimxname, &londiminid); /* get ID for lon dimension */ 00143 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00144 istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */ 00145 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00146 *nlon = (int) dimval; 00147 } 00148 else if ( !strcmp(coords, "2D") && !strcmp(gridname, "Latitude_Longitude") ) { 00150 ndims = 2; 00151 00152 /* Get dimensions length */ 00153 istat = nc_inq_dimid(ncinid, dimyname, &latdiminid); /* get ID for lat dimension */ 00154 if (istat != NC_NOERR) { 00155 (void) fprintf(stderr, "%s: Dimension name %s.\n", __FILE__, dimyname); 00156 handle_netcdf_error(istat, __FILE__, __LINE__); 00157 } 00158 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */ 00159 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00160 *nlat = (int) dimval; 00161 00162 istat = nc_inq_dimid(ncinid, dimxname, &londiminid); /* get ID for lon dimension */ 00163 if (istat != NC_NOERR) { 00164 (void) fprintf(stderr, "%s: Dimension name %s.\n", __FILE__, dimxname); 00165 handle_netcdf_error(istat, __FILE__, __LINE__); 00166 } 00167 istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */ 00168 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00169 *nlon = (int) dimval; 00170 } 00171 else { 00173 ndims = 2; 00174 00175 /* Get dimensions length */ 00176 istat = nc_inq_dimid(ncinid, "y", &latdiminid); /* get ID for lat dimension */ 00177 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00178 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */ 00179 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00180 *nlat = (int) dimval; 00181 00182 istat = nc_inq_dimid(ncinid, "x", &londiminid); /* get ID for lon dimension */ 00183 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00184 istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */ 00185 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00186 *nlon = (int) dimval; 00187 } 00188 00189 /* Get time dimension ID */ 00190 istat = nc_inq_varid(ncinid, timename, &timeinid); /* get ID for time variable */ 00191 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00192 /* Get time dimensions and type */ 00193 istat = nc_inq_var(ncinid, timeinid, (char *) NULL, &vartype, &varndims, vardimids, (int *) NULL); /* get variable information */ 00194 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00195 if (varndims != 1) { 00196 (void) fprintf(stderr, "Error NetCDF type and/or dimensions %d != 1.\n", varndims); 00197 istat = ncclose(ncinid); 00198 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00199 return -1; 00200 } 00201 00202 /* Get dimension ID */ 00203 istat = nc_inq_varid(ncinid, latname, &latinid); /* get ID for lat variable */ 00204 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00205 /* Get lat dimensions and type */ 00206 istat = nc_inq_var(ncinid, latinid, (char *) NULL, &vartype, &varndims, vardimids, (int *) NULL); /* get variable information */ 00207 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00208 if (varndims != ndims) { 00209 (void) fprintf(stderr, "Error NetCDF type and/or dimensions %d != %d.\n", varndims, ndims); 00210 istat = ncclose(ncinid); 00211 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00212 return -1; 00213 } 00214 00215 /* Get dimension ID */ 00216 istat = nc_inq_varid(ncinid, lonname, &loninid); /* get ID for lon variable */ 00217 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00218 /* Get lat dimensions and type */ 00219 istat = nc_inq_var(ncinid, loninid, (char *) NULL, &vartype, &varndims, vardimids, (int *) NULL); /* get variable information */ 00220 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00221 if (varndims != ndims) { 00222 (void) fprintf(stderr, "Error NetCDF type and/or dimensions %d != %d.\n", varndims, ndims); 00223 istat = ncclose(ncinid); 00224 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00225 return -1; 00226 } 00227 00228 /* Get time units attributes */ 00229 (void) get_attribute_str(time_units, ncinid, timeinid, "units"); 00230 (void) get_attribute_str(cal_type, ncinid, timeinid, "calendar"); 00231 if ( (*cal_type)[0] == '\0' ) { 00232 (void) free(*cal_type); 00233 (*cal_type) = strdup("standard"); 00234 } 00235 00236 /* Get global attributes */ 00237 if (info->title == NULL) { 00238 (void) get_attribute_str(&(info->title), ncinid, NC_GLOBAL, "title"); 00239 (void) get_attribute_str(&(info->title_french), ncinid, NC_GLOBAL, "title_french"); 00240 (void) get_attribute_str(&(info->summary), ncinid, NC_GLOBAL, "summary"); 00241 (void) get_attribute_str(&(info->summary_french), ncinid, NC_GLOBAL, "summary_french"); 00242 (void) get_attribute_str(&(info->keywords), ncinid, NC_GLOBAL, "keywords"); 00243 (void) get_attribute_str(&(info->processor), ncinid, NC_GLOBAL, "processor"); 00244 (void) get_attribute_str(&(info->description), ncinid, NC_GLOBAL, "description"); 00245 (void) get_attribute_str(&(info->institution), ncinid, NC_GLOBAL, "institution"); 00246 (void) get_attribute_str(&(info->creator_email), ncinid, NC_GLOBAL, "creator_email"); 00247 (void) get_attribute_str(&(info->creator_url), ncinid, NC_GLOBAL, "creator_url"); 00248 (void) get_attribute_str(&(info->creator_name), ncinid, NC_GLOBAL, "creator_name"); 00249 (void) get_attribute_str(&(info->version), ncinid, NC_GLOBAL, "version"); 00250 (void) get_attribute_str(&(info->scenario), ncinid, NC_GLOBAL, "scenario"); 00251 (void) get_attribute_str(&(info->scenario_co2), ncinid, NC_GLOBAL, "scenario_co2"); 00252 (void) get_attribute_str(&(info->model), ncinid, NC_GLOBAL, "model"); 00253 (void) get_attribute_str(&(info->institution_model), ncinid, NC_GLOBAL, "institution_model"); 00254 (void) get_attribute_str(&(info->country), ncinid, NC_GLOBAL, "country"); 00255 (void) get_attribute_str(&(info->member), ncinid, NC_GLOBAL, "member"); 00256 (void) get_attribute_str(&(info->downscaling_forcing), ncinid, NC_GLOBAL, "downscaling_forcing"); 00257 (void) get_attribute_str(&(info->timestep), ncinid, NC_GLOBAL, "timestep"); 00258 (void) get_attribute_str(&(info->contact_email), ncinid, NC_GLOBAL, "contact_email"); 00259 (void) get_attribute_str(&(info->contact_name), ncinid, NC_GLOBAL, "contact_name"); 00260 (void) get_attribute_str(&(info->other_contact_email), ncinid, NC_GLOBAL, "other_contact_email"); 00261 (void) get_attribute_str(&(info->other_contact_name), ncinid, NC_GLOBAL, "other_contact_name"); 00262 } 00263 00265 if ( !strcmp(coords, "1D") ) { 00266 /* Allocate memory and set start and count */ 00267 start[0] = 0; 00268 start[1] = 0; 00269 start[2] = 0; 00270 count[0] = (size_t) (*nlat); 00271 count[1] = 0; 00272 count[2] = 0; 00273 (*lat) = (double *) malloc((*nlat) * (*nlon) * sizeof(double)); 00274 if ((*lat) == NULL) alloc_error(__FILE__, __LINE__); 00275 tmpd = (double *) malloc((*nlat) * sizeof(double)); 00276 if (tmpd == NULL) alloc_error(__FILE__, __LINE__); 00277 00278 /* Read values from netCDF variable */ 00279 istat = nc_get_vara_double(ncinid, latinid, start, count, tmpd); 00280 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00281 for (j=0; j<(*nlat); j++) 00282 for (i=0; i<(*nlon); i++) 00283 (*lat)[i+j*(*nlon)] = tmpd[j]; 00284 00285 /* Allocate memory and set start and count */ 00286 start[0] = 0; 00287 start[1] = 0; 00288 start[2] = 0; 00289 count[0] = (size_t) (*nlon); 00290 count[1] = 0; 00291 count[2] = 0; 00292 (*lon) = (double *) malloc((*nlat) * (*nlon) * sizeof(double)); 00293 if ((*lon) == NULL) alloc_error(__FILE__, __LINE__); 00294 tmpd = (double *) realloc(tmpd, (*nlon) * sizeof(double)); 00295 if (tmpd == NULL) alloc_error(__FILE__, __LINE__); 00296 00297 /* Read values from netCDF variable */ 00298 istat = nc_get_vara_double(ncinid, loninid, start, count, tmpd); 00299 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00300 for (j=0; j<(*nlat); j++) 00301 for (i=0; i<(*nlon); i++) 00302 (*lon)[i+j*(*nlon)] = tmpd[i]; 00303 00304 (void) free(tmpd); 00305 00306 } 00307 else { 00308 /* Allocate memory and set start and count */ 00309 start[0] = 0; 00310 start[1] = 0; 00311 start[2] = 0; 00312 count[0] = (size_t) (*nlat); 00313 count[1] = (size_t) (*nlon); 00314 count[2] = 0; 00315 (*lat) = (double *) malloc((*nlat) * (*nlon) * sizeof(double)); 00316 if ((*lat) == NULL) alloc_error(__FILE__, __LINE__); 00317 00318 /* Read values from netCDF variable */ 00319 istat = nc_get_vara_double(ncinid, latinid, start, count, (*lat)); 00320 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00321 00322 /* Allocate memory and set start and count */ 00323 start[0] = 0; 00324 start[1] = 0; 00325 start[2] = 0; 00326 count[0] = (size_t) (*nlat); 00327 count[1] = (size_t) (*nlon); 00328 count[2] = 0; 00329 (*lon) = (double *) malloc((*nlat) * (*nlon) * sizeof(double)); 00330 if ((*lon) == NULL) alloc_error(__FILE__, __LINE__); 00331 00332 /* Read values from netCDF variable */ 00333 istat = nc_get_vara_double(ncinid, loninid, start, count, (*lon)); 00334 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00335 } 00336 00337 /* Allocate memory and set start and count */ 00338 start[0] = 0; 00339 count[0] = (size_t) (*ntime); 00340 (*timeval) = malloc((*ntime) * sizeof(double)); 00341 if ((*timeval) == NULL) alloc_error(__FILE__, __LINE__); 00342 00343 /* Read values from netCDF variable */ 00344 istat = nc_get_vara_double(ncinid, timeinid, start, count, (*timeval)); 00345 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00346 00347 /* Check values of time variable because many times they are all zero. In that case assume a 1 increment and a start at zero. */ 00348 for (t=0; t<(*ntime); t++) 00349 if ((*timeval)[t] != 0.0) 00350 break; 00351 if (t == (*ntime)) { 00352 fprintf(stderr, "\n%s: IMPORTANT WARNING: Time variable values all zero!!! Fixing time variable to index value, STARTING at 0...\n\n", __FILE__); 00353 fixtime = TRUE; 00354 for (t=0; t<(*ntime); t++) 00355 (*timeval)[t] = (double) t; 00356 } 00357 00358 /* Close NetCDF file */ 00359 istat = ncclose(ncinid); 00360 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00361 00362 if (fixtime == FALSE) 00363 /* Success status */ 00364 return 0; 00365 else 00366 return 1; 00367 }