read_netcdf_var_1d.c

Go to the documentation of this file.
00001 /* ***************************************************** */
00002 /* read_netcdf_var_1d Read a 1D NetCDF variable.         */
00003 /* read_netcdf_var_1d.c                                  */
00004 /* ***************************************************** */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00006 /* ***************************************************** */
00007 /* Date of creation: sep 2008                            */
00008 /* Last date of modification: sep 2008                   */
00009 /* ***************************************************** */
00010 /* Original version: 1.0                                 */
00011 /* Current revision:                                     */
00012 /* ***************************************************** */
00013 /* Revisions                                             */
00014 /* ***************************************************** */
00019 /* LICENSE BEGIN
00020 
00021 Copyright Cerfacs (Christian Page) (2015)
00022 
00023 christian.page@cerfacs.fr
00024 
00025 This software is a computer program whose purpose is to downscale climate
00026 scenarios using a statistical methodology based on weather regimes.
00027 
00028 This software is governed by the CeCILL license under French law and
00029 abiding by the rules of distribution of free software. You can use, 
00030 modify and/ or redistribute the software under the terms of the CeCILL
00031 license as circulated by CEA, CNRS and INRIA at the following URL
00032 "http://www.cecill.info". 
00033 
00034 As a counterpart to the access to the source code and rights to copy,
00035 modify and redistribute granted by the license, users are provided only
00036 with a limited warranty and the software's author, the holder of the
00037 economic rights, and the successive licensors have only limited
00038 liability. 
00039 
00040 In this respect, the user's attention is drawn to the risks associated
00041 with loading, using, modifying and/or developing or reproducing the
00042 software by the user in light of its specific status of free software,
00043 that may mean that it is complicated to manipulate, and that also
00044 therefore means that it is reserved for developers and experienced
00045 professionals having in-depth computer knowledge. Users are therefore
00046 encouraged to load and test the software's suitability as regards their
00047 requirements in conditions enabling the security of their systems and/or 
00048 data to be ensured and, more generally, to use and operate it in the 
00049 same conditions as regards security. 
00050 
00051 The fact that you are presently reading this means that you have had
00052 knowledge of the CeCILL license and that you accept its terms.
00053 
00054 LICENSE END */
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 #include <io.h>
00063 
00065 int
00066 read_netcdf_var_1d(double **buf, info_field_struct *info_field, char *filename, char *varname,
00067                    char *dimname, int *ndim, int outinfo) {
00080   int istat; /* Diagnostic status */
00081 
00082   size_t dimval; /* Variable used to retrieve dimension length */
00083 
00084   int ncinid; /* NetCDF input file handle ID */
00085   int varinid; /* NetCDF variable ID */
00086   int diminid; /* NetCDF dimension ID */
00087   nc_type vartype_main; /* Type of the variable (NC_FLOAT, NC_DOUBLE, etc.) */
00088   int varndims; /* Number of dimensions of variable */
00089   int vardimids[NC_MAX_VAR_DIMS]; /* Variable dimension ids */
00090 
00091   size_t start[3]; /* Start position to read */
00092   size_t count[3]; /* Number of elements to read */
00093 
00094   float valf; /* Variable used to retrieve fillvalue */
00095   char *tmpstr = NULL; /* Temporary string */
00096   size_t t_len; /* Length of string attribute */
00097 
00098   /* Allocate memory */
00099   tmpstr = (char *) malloc(MAXPATH * sizeof(char));
00100   if (tmpstr == NULL) alloc_error(__FILE__, __LINE__);
00101 
00102   /* Read data in NetCDF file */
00103 
00104   /* Open NetCDF file for reading */
00105   if (outinfo == TRUE)
00106     printf("%s: Opening for reading NetCDF input file %s\n", __FILE__, filename);
00107   istat = nc_open(filename, NC_NOWRITE, &ncinid);  /* open for reading */
00108   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00109 
00110   if (outinfo == TRUE)
00111     printf("%s: READ %s %s\n", __FILE__, varname, filename);
00112 
00113   /* Get dimension length */
00114   istat = nc_inq_dimid(ncinid, dimname, &diminid);  /* get ID for dimension */
00115   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00116   istat = nc_inq_dimlen(ncinid, diminid, &dimval); /* get dimension length */
00117   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00118   *ndim = (int) dimval;
00119 
00120   /* Get main variable ID */
00121   istat = nc_inq_varid(ncinid, varname, &varinid); /* get main variable ID */
00122   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00123 
00126   /* Get variable information */
00127   istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00128   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00129 
00130   /* Verify that variable is really 1D */
00131   if (varndims != 1) {
00132     (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions.\n", __FILE__);
00133     (void) free(tmpstr);
00134     istat = ncclose(ncinid);
00135     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00136     return -1;
00137   }
00138 
00139   /* If info_field si not NULL, get some information about the read variable */
00140   if (info_field != NULL) {
00141     /* Get missing value */
00142     if (vartype_main == NC_FLOAT) {
00143       istat = nc_get_att_float(ncinid, varinid, "missing_value", &valf);
00144       if (istat != NC_NOERR)
00145         info_field->fillvalue = -9999.0;
00146       else
00147         info_field->fillvalue = (double) valf;
00148     }
00149     else if (vartype_main == NC_DOUBLE) {
00150       istat = nc_get_att_double(ncinid, varinid, "missing_value", &(info_field->fillvalue));
00151       if (istat != NC_NOERR)
00152         info_field->fillvalue = -9999.0;
00153     }
00154 
00155     /* Get units */
00156     istat = nc_inq_attlen(ncinid, varinid, "units", &t_len);
00157     if (istat == NC_NOERR) {
00158       handle_netcdf_error(istat, __FILE__, __LINE__);
00159       istat = nc_get_att_text(ncinid, varinid, "units", tmpstr);
00160       if (istat == NC_NOERR) {
00161         if (tmpstr[t_len-1] != '\0')
00162           tmpstr[t_len] = '\0';
00163         info_field->units = strdup(tmpstr);
00164       }
00165       else
00166         info_field->units = strdup("unknown");
00167     }
00168     else
00169       info_field->units = strdup("unknown");
00170 
00171     /* Get height */
00172     istat = nc_inq_attlen(ncinid, varinid, "height", &t_len);
00173     if (istat == NC_NOERR) {
00174       handle_netcdf_error(istat, __FILE__, __LINE__);
00175       istat = nc_get_att_text(ncinid, varinid, "height", tmpstr);
00176       if (istat == NC_NOERR) {
00177         if (tmpstr[t_len-1] != '\0')
00178           tmpstr[t_len] = '\0';
00179         info_field->height = strdup(tmpstr);
00180       }
00181       else
00182         info_field->height = strdup("unknown");
00183     }
00184     else
00185       info_field->height = strdup("unknown");
00186 
00187     /* Get long name */
00188     istat = nc_inq_attlen(ncinid, varinid, "long_name", &t_len);
00189     if (istat == NC_NOERR) {
00190       handle_netcdf_error(istat, __FILE__, __LINE__);
00191       istat = nc_get_att_text(ncinid, varinid, "long_name", tmpstr);
00192       if (istat == NC_NOERR) {
00193         if (tmpstr[t_len-1] != '\0')
00194           tmpstr[t_len] = '\0';
00195         info_field->long_name = strdup(tmpstr);
00196       }
00197       else
00198         info_field->long_name = strdup(varname);
00199     }
00200     else
00201       info_field->long_name = strdup(varname);
00202   }
00203 
00204   /* Allocate memory and set start and count */
00205   start[0] = 0;
00206   start[1] = 0;
00207   start[2] = 0;
00208   count[0] = (size_t) *ndim;
00209   count[1] = 0;
00210   count[2] = 0;
00211   /* Allocate memory */
00212   (*buf) = (double *) malloc((*ndim) * sizeof(double));
00213   if ((*buf) == NULL) alloc_error(__FILE__, __LINE__);
00214 
00215   /* Read values from netCDF variable */
00216   istat = nc_get_vara_double(ncinid, varinid, start, count, *buf);
00217   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00218 
00219   /* Close the input netCDF file. */
00220   istat = ncclose(ncinid);
00221   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00222 
00223   /* Free memory */
00224   (void) free(tmpstr);
00225 
00226   /* Success status */
00227   return 0;
00228 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1