read_netcdf_var_3d.c File Reference

Read a NetCDF variable. More...

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

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.

Detailed Description

Read a NetCDF variable.

Definition in file read_netcdf_var_3d.c.


Function Documentation

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.

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

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 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1