write_netcdf_var_3d.c

Go to the documentation of this file.
00001 /* ***************************************************** */
00002 /* write_netcdf_var_3d Write a 3D NetCDF variable.       */
00003 /* write_netcdf_var_3d.c                                 */
00004 /* ***************************************************** */
00005 /* Author: Christian Page, CERFACS, Toulouse, France.    */
00006 /* ***************************************************** */
00007 /* Date of creation: sep 2008                            */
00008 /* Last date of modification: jan 2010                   */
00009 /* ***************************************************** */
00010 /* Original version: 1.0                                 */
00011 /* Current revision: 1.1                                 */
00012 /* ***************************************************** */
00013 /* Revisions                                             */
00014 /* 1.1 Added compression level                           */
00015 /* ***************************************************** */
00020 /* LICENSE BEGIN
00021 
00022 Copyright Cerfacs (Christian Page) (2015)
00023 
00024 christian.page@cerfacs.fr
00025 
00026 This software is a computer program whose purpose is to downscale climate
00027 scenarios using a statistical methodology based on weather regimes.
00028 
00029 This software is governed by the CeCILL license under French law and
00030 abiding by the rules of distribution of free software. You can use, 
00031 modify and/ or redistribute the software under the terms of the CeCILL
00032 license as circulated by CEA, CNRS and INRIA at the following URL
00033 "http://www.cecill.info". 
00034 
00035 As a counterpart to the access to the source code and rights to copy,
00036 modify and redistribute granted by the license, users are provided only
00037 with a limited warranty and the software's author, the holder of the
00038 economic rights, and the successive licensors have only limited
00039 liability. 
00040 
00041 In this respect, the user's attention is drawn to the risks associated
00042 with loading, using, modifying and/or developing or reproducing the
00043 software by the user in light of its specific status of free software,
00044 that may mean that it is complicated to manipulate, and that also
00045 therefore means that it is reserved for developers and experienced
00046 professionals having in-depth computer knowledge. Users are therefore
00047 encouraged to load and test the software's suitability as regards their
00048 requirements in conditions enabling the security of their systems and/or 
00049 data to be ensured and, more generally, to use and operate it in the 
00050 same conditions as regards security. 
00051 
00052 The fact that you are presently reading this means that you have had
00053 knowledge of the CeCILL license and that you accept its terms.
00054 
00055 LICENSE END */
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 #include <io.h>
00064 
00066 int
00067 write_netcdf_var_3d(double *buf, double fillvalue, char *filename,
00068                     char *varname, char *gridname, char *lonname, char *latname, char *timename,
00069                     int format, int compression_level, int nlon, int nlat, int ntime, int outinfo) {
00089   int istat; /* Diagnostic status */
00090 
00091   size_t dimval; /* Temporary variable used to get values from dimension lengths */
00092 
00093   int ncoutid; /* NetCDF output file handle ID */
00094   int varoutid; /* NetCDF variable output ID */
00095   int timedimoutid; /* NetCDF time dimension output ID */
00096   int londimoutid; /* NetCDF longitude dimension output ID */
00097   int latdimoutid; /* NetCDF latitude dimension output ID */
00098   int vardimids[NC_MAX_VAR_DIMS]; /* NetCDF dimension IDs */
00099   //  size_t chunksize[NC_MAX_VAR_DIMS]; /* Chunksize */
00100   //  size_t cachesize; /* HDF5 cache size */
00101   //  size_t cache_nelems = 2000; /* HDF5 cache number of elements */
00102   //  float cache_preemp;
00103 
00104   int ntime_file; /* Time dimension in NetCDF output file */
00105   int nlat_file; /* Latitude dimension in NetCDF output file */
00106   int nlon_file; /* Longitude dimension in NetCDF output file */
00107 
00108   size_t start[3]; /* Start element when writing */
00109   size_t count[3]; /* Count of elements to write */
00110 
00111   char *attname = NULL; /* Attribute name */
00112   char *tmpstr = NULL; /* Temporary string */
00113 
00114   /* Change directory to output directory for autofs notification */
00115   tmpstr = strdup(filename);
00116   istat = chdir(dirname(tmpstr));
00117   (void) free(tmpstr);
00118 
00119   /* Allocate memory */
00120   attname = (char *) malloc(MAXPATH * sizeof(char));
00121   if (attname == NULL) alloc_error(__FILE__, __LINE__);
00122 
00123   /* Set cache size */
00124   /*   if (format == 4 && compression_level > 0) {
00125     if ( !strcmp(gridname, "list") )
00126       cachesize = (size_t) nlon*sizeof(float)*cache_nelems;
00127     else
00128       cachesize = (size_t) nlat*nlon*sizeof(float)*cache_nelems;
00129     istat = nc_get_chunk_cache(&cachesize, &cache_nelems, &cache_preemp);
00130     cache_preemp = 0.75;
00131     cachesize=128000000;
00132     printf("%d %d %f\n",(int)cachesize,(int)cache_nelems,cache_preemp);
00133     istat = nc_set_chunk_cache(cachesize, cache_nelems, cache_preemp);
00134     if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00135     } */
00136 
00138   istat = nc_open(filename, NC_WRITE, &ncoutid);
00139   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00140   
00141   /* Get dimension lengths */
00142   istat = nc_inq_dimid(ncoutid, timename, &timedimoutid);  /* get ID for time dimension */
00143   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00144   istat = nc_inq_dimlen(ncoutid, timedimoutid, &dimval); /* get time length */
00145   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00146   ntime_file = (int) dimval;
00147 
00148   istat = nc_inq_dimid(ncoutid, latname, &latdimoutid);  /* get ID for lat dimension */
00149   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00150   istat = nc_inq_dimlen(ncoutid, latdimoutid, &dimval); /* get lat length */
00151   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00152   nlat_file = (int) dimval;
00153 
00154   istat = nc_inq_dimid(ncoutid, lonname, &londimoutid);  /* get ID for lon dimension */
00155   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00156   istat = nc_inq_dimlen(ncoutid, londimoutid, &dimval); /* get lon length */
00157   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00158   nlon_file = (int) dimval;
00159 
00160   /* Verify that they match the provided ones in parameters */
00161   if ( !strcmp(gridname, "list") ) {
00162     if ( (ntime_file != ntime) || (nlat_file != nlon) || (nlon_file != nlon) ) {
00163       (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions.\n", __FILE__);
00164       return -1;
00165     }
00166   }
00167   else {
00168     if ( (ntime_file != ntime) || (nlat_file != nlat) || (nlon_file != nlon) ) {
00169       (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions.\n", __FILE__);
00170       return -1;
00171     }
00172   }
00173 
00174   /* Go into NetCDF define mode */
00175   istat = nc_redef(ncoutid);
00176   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00177 
00178   /* Define main output variable */
00179   vardimids[0] = timedimoutid;
00180   if ( !strcmp(gridname, "list") ) {
00181     vardimids[1] = londimoutid;
00182     istat = nc_def_var(ncoutid, varname, NC_FLOAT, 2, vardimids, &varoutid);  
00183   }
00184   else {
00185     vardimids[1] = latdimoutid;
00186     vardimids[2] = londimoutid;
00187     istat = nc_def_var(ncoutid, varname, NC_FLOAT, 3, vardimids, &varoutid);  
00188   }
00189   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00190 
00191 #ifdef NC_NETCDF4
00192     if (format == 4 && compression_level > 0) {
00193       istat = nc_def_var_deflate(ncoutid, varoutid, 0, 1, compression_level);
00194       if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00195       /* Set up chunking */
00196       /*      if ( !strcmp(gridname, "list") ) {
00197         chunksize[0] = (size_t) ntime;
00198         chunksize[1] = (size_t) nlon;
00199         chunksize[2] = (size_t) 0;
00200       }
00201       else {
00202         chunksize[0] = (size_t) ntime;
00203         chunksize[1] = (size_t) nlat;
00204         chunksize[2] = (size_t) nlon;
00205       }
00206       istat = nc_def_var_chunking(ncoutid, varoutid, NC_CHUNKED, chunksize);
00207       if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00208       */
00209     }
00210 #endif
00211 
00212   /* Set main variable attributes */
00213   (void) strcpy(attname, "_FillValue");
00214   istat = nc_put_att_double(ncoutid, varoutid, attname, NC_FLOAT, 1, &fillvalue);
00215   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00216 
00217   (void) strcpy(attname, "missing_value");
00218   istat = nc_put_att_double(ncoutid, varoutid, attname, NC_FLOAT, 1, &fillvalue);
00219   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00220 
00221   tmpstr = (char *) malloc(100 * sizeof(char));
00222   if (tmpstr == NULL) alloc_error(__FILE__, __LINE__);
00223   istat = sprintf(tmpstr, "Climatology of %s", varname);
00224   istat = nc_put_att_text(ncoutid, varoutid, "long_name", strlen(tmpstr), tmpstr);
00225   istat = nc_put_att_text(ncoutid, varoutid, "grid_mapping", strlen(gridname), gridname);
00226   istat = sprintf(tmpstr, "lon lat");
00227   istat = nc_put_att_text(ncoutid, varoutid, "coordinates", strlen(tmpstr), tmpstr);
00228   (void) free(tmpstr);
00229 
00230   /* End definition mode */
00231   istat = nc_enddef(ncoutid);
00232   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00233 
00234   /* Write variable to NetCDF output file */
00235   start[0] = 0;
00236   start[1] = 0;
00237   start[2] = 0;
00238   count[0] = (size_t) ntime;
00239   if ( !strcmp(gridname, "list") ) {
00240     count[1] = (size_t) nlon;
00241     count[2] = 0;
00242   }
00243   else {
00244     count[1] = (size_t) nlat;
00245     count[2] = (size_t) nlon;
00246   }
00247   if (outinfo == TRUE)
00248     printf("%s: WRITE %s %s\n", __FILE__, varname, filename);
00249   istat = nc_put_vara_double(ncoutid, varoutid, start, count, buf);
00250   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00251 
00252   /* Close the output netCDF file. */
00253   istat = ncclose(ncoutid);
00254   if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00255 
00256   /* Free memory */
00257   (void) free(attname);
00258 
00259   /* Diagnostic status */
00260   return 0;
00261 }

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1