write_netcdf_var_3d_2d.c

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

Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1