read_netcdf_var_2d.c File Reference

Read a NetCDF variable. More...

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

Go to the source code of this file.

Functions

int read_netcdf_var_2d (double **buf, info_field_struct *info_field, proj_struct *proj, char *filename, char *varname, char *dimxname, char *dimyname, int *nlon, int *nlat, int outinfo)
 Read a 2D variable in a NetCDF file, and return information in info_field_struct structure and proj_struct.

Detailed Description

Read a NetCDF variable.

Definition in file read_netcdf_var_2d.c.


Function Documentation

int read_netcdf_var_2d ( double **  buf,
info_field_struct info_field,
proj_struct proj,
char *  filename,
char *  varname,
char *  dimxname,
char *  dimyname,
int *  nlon,
int *  nlat,
int  outinfo 
)

Read a 2D variable in a NetCDF file, and return information in info_field_struct structure and proj_struct.

Parameters:
[out] buf 2D 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
[out] nlon Longitude dimension length
[out] nlat Latitude dimension length
[in] outinfo TRUE if we want information output, FALSE if not
Returns:
Status.

Read data variable

Definition at line 67 of file read_netcdf_var_2d.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 output_downscaled_analog(), read_learning_fields(), read_learning_obs_eof(), read_learning_rea_eof(), and read_mask().

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


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1