Read a NetCDF variable. More...
#include <io.h>
Go to the source code of this file.
Functions | |
int | read_netcdf_var_3d (double **buf, info_field_struct *info_field, proj_struct *proj, char *filename, char *varname, char *dimxname, char *dimyname, char *timename, int *nlon, int *nlat, int *ntime, int outinfo) |
Read a 3D variable in a NetCDF file, and return information in info_field_struct structure and proj_struct. |
Read a NetCDF variable.
Definition in file read_netcdf_var_3d.c.
int read_netcdf_var_3d | ( | double ** | buf, | |
info_field_struct * | info_field, | |||
proj_struct * | proj, | |||
char * | filename, | |||
char * | varname, | |||
char * | dimxname, | |||
char * | dimyname, | |||
char * | timename, | |||
int * | nlon, | |||
int * | nlat, | |||
int * | ntime, | |||
int | outinfo | |||
) |
Read a 3D variable in a NetCDF file, and return information in info_field_struct structure and proj_struct.
[out] | buf | 3D variable |
[out] | info_field | Information about the output variable |
[out] | proj | Information about the horizontal projection of the output variable |
[in] | filename | NetCDF input filename |
[in] | varname | NetCDF variable name |
[in] | dimxname | Longitude dimension name |
[in] | dimyname | Latitude dimension name |
[in] | timename | Time dimension name |
[out] | nlon | Longitude dimension length |
[out] | nlat | Latitude dimension length |
[out] | ntime | Time dimension length |
[in] | outinfo | TRUE if we want information output, FALSE if not |
Read data variable
Definition at line 67 of file read_netcdf_var_3d.c.
References alloc_error(), info_field_struct::coordinates, proj_struct::false_easting, proj_struct::false_northing, info_field_struct::fillvalue, get_attribute_str(), info_field_struct::grid_mapping, proj_struct::grid_mapping_name, handle_netcdf_error(), info_field_struct::height, proj_struct::lat0, proj_struct::latin1, proj_struct::latin2, proj_struct::latpole, proj_struct::lonc, info_field_struct::long_name, proj_struct::lonpole, MAXPATH, proj_struct::name, TRUE, and info_field_struct::units.
Referenced by read_large_scale_eof(), read_large_scale_fields(), read_learning_fields(), and remove_clim().
00068 { 00086 int istat; /* Diagnostic status */ 00087 00088 size_t dimval; /* Variable used to retrieve dimension length */ 00089 00090 int ncinid; /* NetCDF input file handle ID */ 00091 int varinid; /* NetCDF variable ID */ 00092 int projinid; /* Projection variable ID */ 00093 nc_type vartype_main; /* Type of the variable (NC_FLOAT, NC_DOUBLE, etc.) */ 00094 int varndims; /* Number of dimensions of variable */ 00095 int vardimids[NC_MAX_VAR_DIMS]; /* Variable dimension ids */ 00096 int timediminid; /* Time dimension ID */ 00097 int londiminid; /* Longitude dimension ID */ 00098 int latdiminid; /* Latitude dimension ID */ 00099 00100 size_t start[3]; /* Start position to read */ 00101 size_t count[3]; /* Number of elements to read */ 00102 00103 float valf; /* Variable used to retrieve fillvalue */ 00104 int vali; /* Variable used to retrieve integer values */ 00105 char *tmpstr = NULL; /* Temporary string */ 00106 size_t t_len; /* Length of string attribute */ 00107 00108 float *proj_latin = NULL; /* Parallel latitudes of projection */ 00109 int npts = 0; /* Number of points for 1D variables */ 00110 char *grid_mapping = NULL; 00111 00112 /* Allocate memory */ 00113 tmpstr = (char *) malloc(MAXPATH * sizeof(char)); 00114 if (tmpstr == NULL) alloc_error(__FILE__, __LINE__); 00115 00116 /* Read data in NetCDF file */ 00117 00118 /* Open NetCDF file for reading */ 00119 if (outinfo == TRUE) 00120 printf("%s: Opening for reading 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 if (outinfo == TRUE) 00125 printf("%s: READ %s %s\n", __FILE__, varname, filename); 00126 00127 /* Get dimensions length */ 00128 istat = nc_inq_dimid(ncinid, timename, &timediminid); /* get ID for time dimension */ 00129 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00130 istat = nc_inq_dimlen(ncinid, timediminid, &dimval); /* get time length */ 00131 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00132 *ntime = (int) dimval; 00133 00134 istat = nc_inq_dimid(ncinid, dimyname, &latdiminid); /* get ID for lat dimension */ 00135 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00136 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */ 00137 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00138 *nlat = (int) dimval; 00139 00140 istat = nc_inq_dimid(ncinid, dimxname, &londiminid); /* get ID for lon dimension */ 00141 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00142 istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */ 00143 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00144 *nlon = (int) dimval; 00145 00146 /* Get main variable ID */ 00147 istat = nc_inq_varid(ncinid, varname, &varinid); 00148 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00149 00152 /* Get variable information */ 00153 istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL); 00154 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00155 00156 /* Verify that variable is really 3D or 2D */ 00157 if (varndims != 3 && varndims != 2) { 00158 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d.\n", __FILE__, *nlon, *nlat); 00159 (void) free(tmpstr); 00160 istat = ncclose(ncinid); 00161 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00162 return -1; 00163 } 00164 00165 if (varndims == 2) { 00166 if ((*nlat) != (*nlon)) { 00167 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d.\n", __FILE__, *nlon, *nlat); 00168 (void) free(tmpstr); 00169 istat = ncclose(ncinid); 00170 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00171 return -1; 00172 } 00173 npts = *nlon; 00174 *nlat = 0; 00175 } 00176 00177 /* If info_field si not NULL, get some information about the read variable */ 00178 if (info_field != NULL) { 00179 /* Get missing value */ 00180 if (vartype_main == NC_FLOAT) { 00181 istat = nc_get_att_float(ncinid, varinid, "missing_value", &valf); 00182 if (istat != NC_NOERR) 00183 info_field->fillvalue = -9999.0; 00184 else 00185 info_field->fillvalue = (double) valf; 00186 } 00187 else if (vartype_main == NC_DOUBLE) { 00188 istat = nc_get_att_double(ncinid, varinid, "missing_value", &(info_field->fillvalue)); 00189 if (istat != NC_NOERR) 00190 info_field->fillvalue = -9999.0; 00191 } 00192 00193 /* Get coordinates */ 00194 istat = nc_inq_attlen(ncinid, varinid, "coordinates", &t_len); 00195 if (istat == NC_NOERR) { 00196 istat = nc_get_att_text(ncinid, varinid, "coordinates", tmpstr); 00197 if (istat == NC_NOERR) { 00198 if (tmpstr[t_len-1] != '\0') 00199 tmpstr[t_len] = '\0'; 00200 info_field->coordinates = strdup(tmpstr); 00201 } 00202 else 00203 info_field->coordinates = strdup("lon lat"); 00204 } 00205 else 00206 info_field->coordinates = strdup("lon lat"); 00207 00208 /* Get grid projection */ 00209 istat = nc_inq_attlen(ncinid, varinid, "grid_mapping", &t_len); 00210 if (istat == NC_NOERR) { 00211 handle_netcdf_error(istat, __FILE__, __LINE__); 00212 istat = nc_get_att_text(ncinid, varinid, "grid_mapping", tmpstr); 00213 if (istat == NC_NOERR) { 00214 if (tmpstr[t_len-1] != '\0') 00215 tmpstr[t_len] = '\0'; 00216 info_field->grid_mapping = strdup(tmpstr); 00217 } 00218 else 00219 info_field->grid_mapping = strdup("unknown"); 00220 } 00221 else 00222 info_field->grid_mapping = strdup("unknown"); 00223 00224 /* Get units */ 00225 istat = nc_inq_attlen(ncinid, varinid, "units", &t_len); 00226 if (istat == NC_NOERR) { 00227 handle_netcdf_error(istat, __FILE__, __LINE__); 00228 istat = nc_get_att_text(ncinid, varinid, "units", tmpstr); 00229 if (istat == NC_NOERR) { 00230 if (tmpstr[t_len-1] != '\0') 00231 tmpstr[t_len] = '\0'; 00232 info_field->units = strdup(tmpstr); 00233 } 00234 else 00235 info_field->units = strdup("unknown"); 00236 } 00237 else 00238 info_field->units = strdup("unknown"); 00239 00240 /* Get height */ 00241 istat = nc_inq_attlen(ncinid, varinid, "height", &t_len); 00242 if (istat == NC_NOERR) { 00243 handle_netcdf_error(istat, __FILE__, __LINE__); 00244 istat = nc_get_att_text(ncinid, varinid, "height", tmpstr); 00245 if (istat == NC_NOERR) { 00246 if (tmpstr[t_len-1] != '\0') 00247 tmpstr[t_len] = '\0'; 00248 info_field->height = strdup(tmpstr); 00249 } 00250 else 00251 info_field->height = strdup("unknown"); 00252 } 00253 else 00254 info_field->height = strdup("unknown"); 00255 00256 /* Get long name */ 00257 istat = nc_inq_attlen(ncinid, varinid, "long_name", &t_len); 00258 if (istat == NC_NOERR) { 00259 handle_netcdf_error(istat, __FILE__, __LINE__); 00260 istat = nc_get_att_text(ncinid, varinid, "long_name", tmpstr); 00261 if (istat == NC_NOERR) { 00262 if (tmpstr[t_len-1] != '\0') 00263 tmpstr[t_len] = '\0'; 00264 info_field->long_name = strdup(tmpstr); 00265 } 00266 else 00267 info_field->long_name = strdup(varname); 00268 } 00269 else 00270 info_field->long_name = strdup(varname); 00271 } 00272 00273 /* if proj is not NULL, retrieve informations about the horizontal projection parameters */ 00274 if (proj != NULL) { 00275 if (info_field == NULL) 00276 grid_mapping = strdup("unknown"); 00277 else 00278 grid_mapping = strdup(info_field->grid_mapping); 00279 /* Get projection variable ID */ 00280 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) { 00281 istat = nc_inq_varid(ncinid, grid_mapping, &projinid); /* get projection variable ID */ 00282 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00283 } 00284 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) { 00285 istat = nc_inq_varid(ncinid, grid_mapping, &projinid); /* get projection variable ID */ 00286 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00287 } 00288 if (proj->name != NULL) { 00289 if ( strcmp(grid_mapping, "Lambert_Conformal") && strcmp(grid_mapping, "Latitude_Longitude") && 00290 ( !strcmp(proj->name, "Latitude_Longitude") || !strcmp(proj->name, "Lambert_Conformal") ) ) { 00291 (void) free(grid_mapping); 00292 grid_mapping = strdup(proj->name); 00293 } 00294 else if ( strcmp(grid_mapping, "rotated_latitude_longitude") && !strcmp(proj->name, "rotated_pole") ) { 00295 (void) free(grid_mapping); 00296 grid_mapping = strdup("rotated_latitude_longitude"); 00297 } 00298 } 00299 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) { 00300 /* int Lambert_Conformal ; 00301 Lambert_Conformal:grid_mapping_name = "lambert_conformal_conic" ; 00302 Lambert_Conformal:standard_parallel = 45.89892f, 47.69601f ; 00303 Lambert_Conformal:longitude_of_central_meridian = 2.337229f ; 00304 Lambert_Conformal:latitude_of_projection_origin = 46.8f ; 00305 Lambert_Conformal:false_easting = 600000.f ; 00306 Lambert_Conformal:false_northing = 2200000.f ; 00307 */ 00308 istat = nc_get_var1_int(ncinid, projinid, 0, &vali); 00309 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00310 if (proj->name != NULL) 00311 (void) free(proj->name); 00312 proj->name = strdup(grid_mapping); 00313 if (proj->grid_mapping_name != NULL) 00314 (void) free(proj->grid_mapping_name); 00315 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name"); 00316 00317 proj_latin = (float *) malloc(2 * sizeof(float)); 00318 if (proj_latin == NULL) alloc_error(__FILE__, __LINE__); 00319 istat = nc_get_att_float(ncinid, projinid, "standard_parallel", proj_latin); 00320 proj->latin1 = (double) proj_latin[0]; 00321 proj->latin2 = (double) proj_latin[1]; 00322 (void) free(proj_latin); 00323 00324 istat = nc_get_att_double(ncinid, projinid, "longitude_of_central_meridian", &(proj->lonc)); 00325 istat = nc_get_att_double(ncinid, projinid, "latitude_of_projection_origin", &(proj->lat0)); 00326 istat = nc_get_att_double(ncinid, projinid, "false_easting", &(proj->false_easting)); 00327 istat = nc_get_att_double(ncinid, projinid, "false_northing", &(proj->false_northing)); 00328 00329 } 00330 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) { 00331 /* int rotated_pole ; 00332 rotated_pole:grid_mapping_name = "rotated_latitude_longitude" ; 00333 rotated_pole:grid_north_pole_latitude = 39.25 ; 00334 rotated_pole:grid_north_pole_longitude = -162. ; 00335 */ 00336 istat = nc_get_var1_int(ncinid, projinid, 0, &vali); 00337 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00338 if (proj->name != NULL) 00339 (void) free(proj->name); 00340 proj->name = strdup(grid_mapping); 00341 if (proj->grid_mapping_name != NULL) 00342 (void) free(proj->grid_mapping_name); 00343 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name"); 00344 00345 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_latitude", &(proj->latpole)); 00346 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_longitude", &(proj->lonpole)); 00347 00348 } 00349 else if ( !strcmp(grid_mapping, "Latitude_Longitude") ) { 00350 if (proj->name != NULL) 00351 (void) free(proj->name); 00352 proj->name = strdup(grid_mapping); 00353 if (proj->grid_mapping_name != NULL) 00354 (void) free(proj->grid_mapping_name); 00355 proj->grid_mapping_name = strdup("Latitude_Longitude"); 00356 proj->latin1 = 0.0; 00357 proj->latin2 = 0.0; 00358 proj->lonc = 0.0; 00359 proj->lat0 = 0.0; 00360 proj->false_easting = 0.0; 00361 proj->false_northing = 0.0; 00362 } 00363 else if ( !strcmp(grid_mapping, "list") ) { 00364 if (proj->name != NULL) 00365 (void) free(proj->name); 00366 proj->name = strdup(grid_mapping); 00367 if (proj->grid_mapping_name != NULL) 00368 (void) free(proj->grid_mapping_name); 00369 proj->grid_mapping_name = strdup("list"); 00370 proj->latin1 = 0.0; 00371 proj->latin2 = 0.0; 00372 proj->lonc = 0.0; 00373 proj->lat0 = 0.0; 00374 proj->false_easting = 0.0; 00375 proj->false_northing = 0.0; 00376 } 00377 else { 00378 (void) fprintf(stderr, "%s: WARNING: No projection parameter available for %s.\n", __FILE__, grid_mapping); 00379 (void) fprintf(stderr, "%s: WARNING: Assuming list of longitude and latitude points.\n", __FILE__); 00380 if (proj->name != NULL) 00381 (void) free(proj->name); 00382 proj->name = strdup("list"); 00383 if (proj->grid_mapping_name != NULL) 00384 (void) free(proj->grid_mapping_name); 00385 proj->grid_mapping_name = strdup("list"); 00386 proj->latin1 = 0.0; 00387 proj->latin2 = 0.0; 00388 proj->lonc = 0.0; 00389 proj->lat0 = 0.0; 00390 proj->false_easting = 0.0; 00391 proj->false_northing = 0.0; 00392 } 00393 (void) free(grid_mapping); 00394 } 00395 00396 if (varndims == 3) { 00397 /* Allocate memory and set start and count */ 00398 start[0] = 0; 00399 start[1] = 0; 00400 start[2] = 0; 00401 count[0] = (size_t) *ntime; 00402 count[1] = (size_t) *nlat; 00403 count[2] = (size_t) *nlon; 00404 /* Allocate memory */ 00405 (*buf) = (double *) malloc((*nlat)*(*nlon)*(*ntime) * sizeof(double)); 00406 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__); 00407 } 00408 else if (varndims == 2) { 00409 /* Allocate memory and set start and count */ 00410 start[0] = 0; 00411 start[1] = 0; 00412 start[2] = 0; 00413 count[0] = (size_t) *ntime; 00414 count[1] = (size_t) npts; 00415 count[2] = 0; 00416 /* Allocate memory */ 00417 (*buf) = (double *) malloc(npts*(*ntime) * sizeof(double)); 00418 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__); 00419 } 00420 00421 /* Read values from netCDF variable */ 00422 istat = nc_get_vara_double(ncinid, varinid, start, count, *buf); 00423 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00424 00425 /* Close the input netCDF file. */ 00426 istat = ncclose(ncinid); 00427 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__); 00428 00429 /* Free memory */ 00430 (void) free(tmpstr); 00431 00432 /* Success status */ 00433 return 0; 00434 }