read_netcdf_latlon.c

Go to the documentation of this file.
00001 /* ***************************************************** */
00002 /* read_netcdf_latlon Read NetCDF lat and lon dimensions.*/
00003 /* read_netcdf_latlon.c                                  */
00004 /* ***************************************************** */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00006 /* ***************************************************** */
00007 /* Date of creation: nov 2008                            */
00008 /* Last date of modification: nov 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_latlon(double **lon, double **lat, int *nlon, int *nlat, char *dimcoords, char *coords, char *gridname,
00067                    char *lonname, char *latname, char *dimxname, char *dimyname, char *filename) {
00085   int istat; /* Diagnostic status */
00086 
00087   size_t dimval; /* Variable used to retrieve dimension length */
00088 
00089   int ncinid; /* NetCDF input file handle ID */
00090   int latinid; /* Latitude variable ID */
00091   int loninid; /* Longitude variable ID */
00092   nc_type vartype; /* Type of the variable (NC_FLOAT, NC_DOUBLE, etc.) */
00093   int varndims; /* Number of dimensions of variable */
00094   int vardimids[NC_MAX_VAR_DIMS]; /* Variable dimension ids */
00095   int londiminid; /* Longitude dimension ID */
00096   int latdiminid; /* Latitude dimension ID */
00097 
00098   size_t start[3]; /* Start position to read */
00099   size_t count[3]; /* Number of elements to read */
00100 
00101   double *tmpd = NULL; /* Temporary buffer to read variable from NetCDF file */
00102 
00103   int i; /* Loop counter */
00104   int j; /* Loop counter */
00105   int ndims; /* Number of dimensions of latitude and longitude variables, 1 or 2 for 1D and 2D respectively */
00106   int ndims_xy; /* Number of dimensions of X and Y dimensions, 1 or 2 for 1D and 2D respectively */
00107   int npts; /* Number of points for list of latitude + longitude points */
00108 
00109   /* Read data in NetCDF file */
00110 
00111   /* Open NetCDF file for reading */
00112   printf("%s: Reading info from NetCDF input file %s\n", __FILE__, filename);
00113   istat = nc_open(filename, NC_NOWRITE, &ncinid);  /* open for reading */
00114   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00115 
00116   if ( !strcmp(coords, "1D") )
00118     ndims = 1;
00119   else if ( !strcmp(coords, "2D") )
00121     ndims = 2;
00122   else
00124     ndims = 2;
00125   
00126   if ( !strcmp(dimcoords, "1D") ) {
00128     ndims_xy = 1;
00129 
00130     /* Get dimensions length */
00131     istat = nc_inq_dimid(ncinid, dimyname, &latdiminid);  /* get ID for Y dimension */
00132     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00133     istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */
00134     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00135     *nlat = (int) dimval;
00136     
00137     istat = nc_inq_dimid(ncinid, dimxname, &londiminid);  /* get ID for X dimension */
00138     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00139     istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */
00140     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00141     *nlon = (int) dimval;
00142   }
00143   else if ( !strcmp(dimcoords, "2D") && !strcmp(gridname, "Latitude_Longitude") ) {
00145     ndims_xy = 2;
00146 
00147     /* Get dimensions length */
00148     istat = nc_inq_dimid(ncinid, dimyname, &latdiminid);  /* get ID for Y dimension */
00149     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00150     istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */
00151     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00152     *nlat = (int) dimval;
00153     
00154     istat = nc_inq_dimid(ncinid, dimxname, &londiminid);  /* get ID for X dimension */
00155     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00156     istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */
00157     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00158     *nlon = (int) dimval;
00159   }
00160   else {
00162     ndims_xy = 2;
00163 
00164     /* Get dimensions length */
00165     istat = nc_inq_dimid(ncinid, "y", &latdiminid);  /* get ID for lat dimension */
00166     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00167     istat = nc_inq_dimlen(ncinid, latdiminid, &dimval); /* get lat length */
00168     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00169     *nlat = (int) dimval;
00170     
00171     istat = nc_inq_dimid(ncinid, "x", &londiminid);  /* get ID for lon dimension */
00172     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00173     istat = nc_inq_dimlen(ncinid, londiminid, &dimval); /* get lon length */
00174     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00175     *nlon = (int) dimval;
00176   }
00177   
00178   /* Get dimension ID */
00179   istat = nc_inq_varid(ncinid, latname, &latinid);  /* get ID for lat variable */
00180   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00181   /* Get lat dimensions and type */
00182   istat = nc_inq_var(ncinid, latinid, (char *) NULL, &vartype, &varndims, vardimids, (int *) NULL); /* get variable information */
00183   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);  
00184   if (varndims != ndims) {
00185     (void) fprintf(stderr, "Error NetCDF type and/or dimensions %d != %d.\n", varndims, ndims);
00186     istat = ncclose(ncinid);
00187     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00188     return -1;
00189   }
00190 
00191   /* Get dimension ID */
00192   istat = nc_inq_varid(ncinid, lonname, &loninid);  /* get ID for lon variable */
00193   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00194   /* Get lat dimensions and type */
00195   istat = nc_inq_var(ncinid, loninid, (char *) NULL, &vartype, &varndims, vardimids, (int *) NULL); /* get variable information */
00196   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);  
00197   if (varndims != ndims) {
00198     (void) fprintf(stderr, "Error NetCDF type and/or dimensions %d != %d.\n", varndims, ndims);
00199     istat = ncclose(ncinid);
00200     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00201     return -1;
00202   }
00203 
00205   if ( !strcmp(gridname, "list") ) {
00206     /* 1D list of lat + lon points */
00207     npts = *nlon;
00208     *nlat = 0;
00209     /* Allocate memory and set start and count */
00210     start[0] = 0;
00211     start[1] = 0;
00212     start[2] = 0;
00213     count[0] = (size_t) npts;
00214     count[1] = 0;
00215     count[2] = 0;
00216     (*lat) = (double *) malloc(npts * sizeof(double));
00217     if ((*lat) == NULL) alloc_error(__FILE__, __LINE__);
00218     
00219     /* Read values from netCDF variable */
00220     istat = nc_get_vara_double(ncinid, latinid, start, count, (*lat));
00221     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00222     
00223     /* Allocate memory and set start and count */
00224     start[0] = 0;
00225     start[1] = 0;
00226     start[2] = 0;
00227     count[0] = (size_t) npts;
00228     count[1] = 0;
00229     count[2] = 0;
00230     (*lon) = (double *) malloc(npts * sizeof(double));
00231     if ((*lon) == NULL) alloc_error(__FILE__, __LINE__);
00232     
00233     /* Read values from netCDF variable */
00234     istat = nc_get_vara_double(ncinid, loninid, start, count, (*lon));
00235     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00236   }
00237   else if ( !strcmp(coords, "1D") ) {
00238     /* Allocate memory and set start and count */
00239     start[0] = 0;
00240     start[1] = 0;
00241     start[2] = 0;
00242     count[0] = (size_t) (*nlat);
00243     count[1] = 0;
00244     count[2] = 0;
00245     (*lat) = (double *) malloc((*nlat) * (*nlon) * sizeof(double));
00246     if ((*lat) == NULL) alloc_error(__FILE__, __LINE__);
00247     tmpd = (double *) malloc((*nlat) * sizeof(double));
00248     if (tmpd == NULL) alloc_error(__FILE__, __LINE__);
00249     
00250     /* Read values from netCDF variable */
00251     istat = nc_get_vara_double(ncinid, latinid, start, count, tmpd);
00252     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00253     for (j=0; j<(*nlat); j++)
00254       for (i=0; i<(*nlon); i++)
00255         (*lat)[i+j*(*nlon)] = tmpd[j];
00256     
00257     /* Allocate memory and set start and count */
00258     start[0] = 0;
00259     start[1] = 0;
00260     start[2] = 0;
00261     count[0] = (size_t) (*nlon);
00262     count[1] = 0;
00263     count[2] = 0;
00264     (*lon) = (double *) malloc((*nlat) * (*nlon) * sizeof(double));
00265     if ((*lon) == NULL) alloc_error(__FILE__, __LINE__);
00266     tmpd = (double *) realloc(tmpd, (*nlon) * sizeof(double));
00267     if (tmpd == NULL) alloc_error(__FILE__, __LINE__);
00268     
00269     /* Read values from netCDF variable */
00270     istat = nc_get_vara_double(ncinid, loninid, start, count, tmpd);
00271     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00272     for (j=0; j<(*nlat); j++)
00273       for (i=0; i<(*nlon); i++)
00274         (*lon)[i+j*(*nlon)] = tmpd[i];
00275 
00276     (void) free(tmpd);
00277     
00278   }
00279   else {  
00280     /* Allocate memory and set start and count */
00281     start[0] = 0;
00282     start[1] = 0;
00283     start[2] = 0;
00284     count[0] = (size_t) (*nlat);
00285     count[1] = (size_t) (*nlon);
00286     count[2] = 0;
00287     (*lat) = (double *) malloc((*nlat) * (*nlon) * sizeof(double));
00288     if ((*lat) == NULL) alloc_error(__FILE__, __LINE__);
00289     
00290     /* Read values from netCDF variable */
00291     istat = nc_get_vara_double(ncinid, latinid, start, count, (*lat));
00292     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00293     
00294     /* Allocate memory and set start and count */
00295     start[0] = 0;
00296     start[1] = 0;
00297     start[2] = 0;
00298     count[0] = (size_t) (*nlat);
00299     count[1] = (size_t) (*nlon);
00300     count[2] = 0;
00301     (*lon) = (double *) malloc((*nlat) * (*nlon) * sizeof(double));
00302     if ((*lon) == NULL) alloc_error(__FILE__, __LINE__);
00303     
00304     /* Read values from netCDF variable */
00305     istat = nc_get_vara_double(ncinid, loninid, start, count, (*lon));
00306     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00307   }
00308 
00309   istat = ncclose(ncinid);
00310   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00311 
00312   /* Success status */
00313   return 0;
00314 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1