source: XIOS/trunk/src/output/netCdfInterface.cpp @ 517

Last change on this file since 517 was 517, checked in by rlacroix, 8 years ago

Add a new attribute to the file definition so that the output format can be controlled.

Currently the supported formats are "netcdf4" and "netcdf4_classic". The "format" attribute is optional. The "netcdf4" format will be used when no format is explicitly defined. Since "netcdf4" is the format which was previously used by XIOS, existing configuration files will not be affected by this change.

If "netcdf4_classic" is used, the output file(s) will be created using the classic NetCDF format. This format can be used with the attribute "type" set to "one_file" if the NetCDF4 library was compiled with Parallel NetCDF support (--enable-pnetcdf).

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 26.5 KB
Line 
1/*!
2   \file netCdfInterface.cpp
3   \author Ha NGUYEN
4   \date 08 Oct 2014
5   \since 03 Oct 2014
6
7   \brief Wrapper of netcdf functions.
8 */
9
10 #include "netCdfInterface.hpp"
11 #include "netCdfException.hpp"
12
13 namespace xios
14 {
15   /*!
16   This function creates a new netcdf file and return its id
17   \param [in] fileName Name of the file
18   \param [in] cMode create mode
19   \param [in/out] ncId id of the created file
20   \return Status code
21   */
22   int CNetCdfInterface::create(const StdString& fileName, int cMode, int& ncId)
23   {
24     int status = nc_create((fileName.c_str()), cMode, &ncId);
25     if (NC_NOERR != status)
26     {
27       StdString errormsg(nc_strerror(status));
28       StdStringStream sstr;
29       sstr << "Error in calling function : nc_create((fileName.c_str()), cMode, &ncId) " << std::endl
30            << errormsg << std::endl
31            << "Unable to create file, given its name : " << fileName
32            << "and its creation mode " << creationMode2String(cMode) << std::endl;
33       StdString e = sstr.str();
34       throw CNetCdfException(e);
35     }
36
37     return status;
38   }
39
40   /*!
41   This function creates a new netcdf file on parallel file system
42   \param [in] fileName Name of the file
43   \param [in] cMode create mode
44   \param [in] comm MPI communicator
45   \param [in] info MPI information
46   \param [in/out] ncId id of the created file
47   \return Status code
48   */
49   int CNetCdfInterface::createPar(const StdString& fileName, int cMode, MPI_Comm comm, MPI_Info info, int& ncId)
50   {
51     int status = xios::nc_create_par((fileName.c_str()), cMode, comm, info, &ncId);
52     if (NC_NOERR != status)
53     {
54       StdString errormsg(nc_strerror(status));
55       StdStringStream sstr;
56       sstr << "Error in calling function : nc_create_par((fileName.c_str()), cMode, comm, info, &ncId) " << std::endl
57            << errormsg << std::endl
58            << "Unable to create file on parallel filesys, given its name : " << std::endl
59            << "and its creation mode " << creationMode2String(cMode) << std::endl;
60       StdString e = sstr.str();
61       throw CNetCdfException(e);
62     }
63
64     return status;
65   }
66
67   /*!
68   This function opens a netcdf file, given its name and open mode, return its id
69   \param [in] fileName Name of the file
70   \param [in] oMode open mode
71   \param [in/out] ncId id of the opening file
72   \return Status code
73   */
74   int CNetCdfInterface::open(const StdString& fileName, int oMode, int& ncId)
75   {
76     int status = nc_open((fileName.c_str()), oMode, &ncId);
77     if (NC_NOERR != status)
78     {
79       StdString errormsg(nc_strerror(status));
80       StdStringStream sstr;
81       sstr << "Error in calling function : nc_open((fileName.c_str()), oMode, &ncId) "<< std::endl
82            << errormsg << std::endl
83            << "Unable to open file, given its name : " << fileName
84            << "and its open mode " << openMode2String(oMode) << std::endl;
85       StdString e = sstr.str();
86       throw CNetCdfException(e);
87     }
88
89     return status;
90   }
91
92
93   /*!
94   This function opens a new netcdf file on parallel file system
95   \param [in] fileName Name of the file
96   \param [in] oMode open mode
97   \param [in] comm MPI communicator
98   \param [in] info MPI information
99   \param [in/out] ncId id of the opened file
100   \return Status code
101   */
102   int CNetCdfInterface::openPar(const StdString& fileName, int oMode, MPI_Comm comm, MPI_Info info, int& ncId)
103   {
104     int status = xios::nc_open_par((fileName.c_str()), oMode, comm, info, &ncId);
105     if (NC_NOERR != status)
106     {
107       StdString errormsg(nc_strerror(status));
108       StdStringStream sstr;
109       sstr << "Error in calling function " << "nc_open_par((fileName.c_str()), oMode, comm, info, &ncId) " << std::endl
110            << errormsg << std::endl
111            << "Unable to open file on parallel filesys, given its name : " << fileName
112            << "and its open mode " << openMode2String(oMode) << std::endl;
113       StdString e = sstr.str();
114       throw CNetCdfException(e);
115     }
116
117     return status;
118   }
119
120   /*!
121   This function closes a netcdf file, given its id
122   \param [in] ncId id of the opening netcdf file
123   \return Status code
124   */
125   int CNetCdfInterface::close(int ncId)
126   {
127     int status = nc_close(ncId);
128     if (NC_NOERR != status)
129     {
130       StdString errormsg(nc_strerror(status));
131       StdStringStream sstr;
132       sstr << "Error in calling function " << "nc_close(ncId)" << std::endl
133            << errormsg << std::endl
134            << "Unable to close file, given its id : " << ncId << std::endl;
135       StdString e = sstr.str();
136       throw CNetCdfException(e);
137     }
138
139     return status;
140   }
141
142   /*!
143   This function put a netcdf file into define mode, given its id
144   \param [in] ncId id of the opening netcdf file to be put into define mode
145   \return Status code
146   */
147   int CNetCdfInterface::reDef(int ncId)
148   {
149     int status = nc_redef(ncId);
150     if (NC_NOERR != status)
151     {
152       StdString errormsg(nc_strerror(status));
153       StdStringStream sstr;
154       sstr << "Error in calling function " << "nc_redef(ncId)" << std::endl
155         << errormsg << std::endl
156         << "Unable to put this file into define mode given its id : " << ncId << std::endl;
157       StdString e = sstr.str();
158       throw CNetCdfException(e);
159     }
160
161     return status;
162   }
163
164   /*!
165   This function ends a netcdf file define mode, given its id
166   \param [in] ncId id of the opening netcdf file to be put into define mode
167   \return Status code
168   */
169   int CNetCdfInterface::endDef(int ncId)
170   {
171     int status = nc_enddef(ncId);
172     if (NC_NOERR != status)
173     {
174       StdString errormsg(nc_strerror(status));
175       StdStringStream sstr;
176
177       sstr << "Error in calling function " << "nc_enddef(ncId)" << std::endl
178            << errormsg << std::endl
179            << "Unable to end define mode of this file, given its id : " << ncId << std::endl;
180       StdString e = sstr.str();
181       throw CNetCdfException(e);
182     }
183
184     return status;
185   }
186
187   /*!
188   This function makes a request to netcdf with ncid and group name then return ncid of the named group
189   \param [in] ncid Groupd id (or File Id)
190   \param [in] grpName Name of the desired group (or file)
191   \param [in/out] grpId Group id if the group is found
192   \return Status code
193   */
194   int CNetCdfInterface::inqNcId(int ncid, const StdString& grpName, int& grpId)
195   {
196     int status = nc_inq_ncid(ncid, (grpName.c_str()), &grpId);
197     if (NC_NOERR != status)
198     {
199       StdString errormsg(nc_strerror(status));
200       StdStringStream sstr;
201
202       sstr << "Error in calling function " << "nc_inq_ncid(ncid, (grpName.c_str()), &grpId)" << std::endl
203            << errormsg << std::endl
204            << "Unable to get id of a group (File), given its name : " << grpName << std::endl;
205       StdString e = sstr.str();
206       throw CNetCdfException(e);
207     }
208
209     return status;
210   }
211
212
213   /*!
214   This function makes a request to netcdf with ncid and variable name then return ncid of the named variable
215   \param [in] ncid Groupd id (or File Id)
216   \param [in] varName Name of the desired variable
217   \param [in/out] varId Variable id if this variable is found
218   \return Status code
219   */
220   int CNetCdfInterface::inqVarId(int ncid,const StdString& varName, int& varId)
221   {
222     int status = nc_inq_varid(ncid, (varName.c_str()), &varId);
223     if (NC_NOERR != status)
224     {
225       StdString errormsg(nc_strerror(status));
226       StdStringStream sstr;
227
228       sstr << "Error in calling function : nc_inq_varid(ncid, (varName.c_str()), &varId)" << std::endl
229            << (errormsg) << std::endl
230            << "Unable to get id of variable with name : " << varName << std::endl;
231       StdString e = sstr.str();
232       throw CNetCdfException(e);
233     }
234
235     return status;
236   }
237
238  /*!
239   This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension
240   \param [in] ncid Groupd id (or File Id)
241   \param [in] dimName Name of the desired dimension
242   \param [in/out] dimId Dimension id if this dimension is found
243   \return Status code
244   */
245   int CNetCdfInterface::inqDimId(int ncid,const StdString& dimName, int& dimId)
246   {
247     int status = nc_inq_dimid(ncid, (dimName.c_str()), &dimId);
248     if (NC_NOERR != status)
249     {
250       StdString errormsg(nc_strerror(status));
251       StdStringStream sstr;
252
253       sstr << "Error in calling function " << "nc_inq_dimid(ncid, (dimName.c_str()), &dimId)" << std::endl
254            << errormsg << std::endl
255            << "Unable to get id of dimension, given its name : " << dimName << std::endl;
256       StdString e = sstr.str();
257       throw CNetCdfException(e);
258     }
259
260     return status;
261   }
262
263  /*!
264   This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension
265   \param [in] ncid Groupd id (or File Id)
266   \param [in/out] dimId Dimension id if this dimension is found
267   \return Status code
268   */
269   int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId)
270   {
271     int status = nc_inq_unlimdim(ncid, &dimId);
272     if (NC_NOERR != status)
273     {
274       StdString errormsg(nc_strerror(status));
275       StdStringStream sstr;
276
277       sstr << "Error in calling function " << "nc_inq_dimid" << std::endl
278         << errormsg << std::endl
279         << "Unable to get id of unlimited dimension " << std::endl;
280       StdString e = sstr.str();
281       throw CNetCdfException(e);
282    }
283
284     return status;
285   }
286
287  /*!
288   This function makes a request to netcdf, returns name of a dimension, given its id
289   \param [in] ncid Groupd id (or File Id)
290   \param [in] dimId Id of desired dimension
291   \param [in/out] dimName Name of desired dimension
292   \return Status code
293   */
294   int CNetCdfInterface::inqDimName(int ncid, int dimId, StdString& dimName)
295   {
296     char fullNameIn[NC_MAX_NAME +1];
297     int status = nc_inq_dimname(ncid, dimId, fullNameIn);
298     if (NC_NOERR != status)
299     {
300       StdString errormsg(nc_strerror(status));
301       StdStringStream sstr;
302
303       sstr << "Error in calling function " << "nc_inq_dimname(ncid, dimId, fullNameIn)" << std::endl
304            << errormsg << std::endl
305            << "Unable to get dimension name from its id : " << dimId << std::endl;
306       StdString e = sstr.str();
307       throw CNetCdfException(e);
308     }
309     dimName = StdString(fullNameIn);
310     return status;
311   }
312
313  /*!
314   This function makes a request to netcdf, returns length of a dimension, given its id
315   \param [in] ncid Groupd id (or File Id)
316   \param [in] dimId Id of desired dimension
317   \param [in/out] dimLen Length of desired dimension
318   \return Status code
319   */
320   int CNetCdfInterface::inqDimLen(int ncid, int dimId, StdSize& dimLen)
321   {
322     int status = nc_inq_dimlen(ncid, dimId, &dimLen);
323     if (NC_NOERR != status)
324     {
325       StdString errormsg(nc_strerror(status));
326       StdStringStream sstr;
327
328       sstr << "Error in calling function " << "nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl
329            << errormsg << std::endl
330            << "Unable to get dimension length from its id: " << dimId << std::endl;
331       StdString e = sstr.str();
332       throw CNetCdfException(e);
333     }
334
335     return status;
336   }
337
338  /*!
339   This function makes a request to netcdf, returns number of dimensions of a variable, given its id
340   \param [in] ncid Groupd id (or File Id)
341   \param [in] varId Id of variable
342   \param [in/out] ndims number of dimension of the variable
343   \return Status code
344   */
345   int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims)
346   {
347     int status = nc_inq_varndims(ncid, varId, &nDims);
348     if (NC_NOERR != status)
349     {
350       StdString errormsg(nc_strerror(status));
351       StdStringStream sstr;
352
353       sstr << "Error in calling function " << "nc_inq_varndims(ncid, varId, &nDims)" << std::endl
354            << errormsg << std::endl
355            << "Unable to get the number of dimension of variable with Id : " << varId << std::endl;
356       StdString e = sstr.str();
357       throw CNetCdfException(e);
358     }
359
360     return status;
361   }
362
363  /*!
364   This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id
365   \param [in] ncid Groupd id (or File Id)
366   \param [in] varId Id of variable
367   \param [in/out] dimIds list of dimension of the variable
368   \return Status code
369   */
370   int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds)
371   {
372     int status = nc_inq_vardimid(ncid, varId, dimIds);
373     if (NC_NOERR != status)
374     {
375       StdString errormsg(nc_strerror(status));
376       StdStringStream sstr;
377
378       sstr << "Error in calling function " << "nc_inq_vardimid(ncid, varId, dimIds)" << std::endl
379            << errormsg << std::endl
380            << "Unable to get list of dimension id of the variable with id " << varId << std::endl;
381       StdString e = sstr.str();
382       throw CNetCdfException(e);
383     }
384
385     return status;
386   }
387
388   /*!
389   This function makes a request to netcdf, to find all dimension in a group
390   \param [in] ncid Groupd id (or File Id)
391   \param [in/out] nDims number of list of dimension
392   \param [in/out] dimIds list of dimension in a group or any of its parent
393   \param [in] includeParents number of parents
394   \return Status code
395   */
396   int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents)
397   {
398     int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents);
399     if (NC_NOERR != status)
400     {
401       StdString errormsg(nc_strerror(status));
402       StdStringStream sstr;
403
404       sstr << "Error in calling function " << "nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl;
405       sstr << errormsg << std::endl;
406       sstr << "Unable to retrieve number of dimension in the group with id : " << ncid << std::endl;
407       sstr << "With number of Parents " << includeParents << std::endl;
408       StdString e = sstr.str();
409       throw CNetCdfException(e);
410     }
411
412     return status;
413   }
414
415   /*!
416   This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name
417   \param [in] parentNcid Id of parent groupd(or File Id)
418   \param [in] grpName Name of the desired group
419   \param [in/out] grpId Group id if this group is created sucessfully
420   \return Status code
421   */
422   int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId)
423   {
424     int status = nc_def_grp(parentNcid, (grpName.c_str()), &grpId);
425     if (NC_NOERR != status)
426     {
427       StdString errormsg(nc_strerror(status));
428       StdStringStream sstr;
429
430       sstr << "Error in calling function " << "nc_def_grp(parentNcid, (grpName.c_str()), &grpId)" << std::endl;
431       sstr << errormsg << std::endl;
432       sstr << "Unable to create group Id, given its name : " << grpName << std::endl;
433       StdString e = sstr.str();
434       throw CNetCdfException(e);
435     }
436
437     return status;
438   }
439
440   /*!
441   This function makes a request to netcdf, add a new dimension to an open netcdf in define mode
442   \param [in] ncid Id of groupd(or File Id)
443   \param [in] dimName Name of the desired dimension
444   \param [in/out] grpId Group id if this group is created sucessfully
445   \return Status code
446   */
447   int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId)
448   {
449     int status = nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId);
450     if (NC_NOERR != status)
451     {
452       StdString errormsg(nc_strerror(status));
453       StdStringStream sstr;
454
455       sstr << "Error in calling function " << "nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId)" << std::endl;
456       sstr << errormsg << std::endl;
457       sstr << "Unable to create dimension with name : " << dimName
458            << " and with length " << dimLen << std::endl;
459       StdString e = sstr.str();
460       throw CNetCdfException(e);
461     }
462
463     return status;
464   }
465
466   /*!
467   This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode,
468   return a variable id, given its name, type, the number of dimensions and list of dimension id
469   \param [in] ncid Id of groupd(or File Id)
470   \param [in] varName Name of the desired dimension
471   \param [in] xtypes One of the set of predefined netCDF data types
472   \param [in] nDims Number of dimension for the variable
473   \param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions
474   \param [in/out] varId Variable id if it is added sucessfully
475   \return Status code
476   */
477   int CNetCdfInterface::defVar(int ncid,const StdString& varName, nc_type xtype,
478                                int nDims, const int dimIds[], int& varId)
479   {
480     int status = nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId);
481     if (NC_NOERR != status)
482     {
483       StdString errormsg(nc_strerror(status));
484       StdStringStream sstr;
485
486       sstr << "Error in calling function " << " nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId)" << std::endl;
487       sstr << errormsg << std::endl;
488       sstr << "Unable to add a new variable with name : " << varName
489            << " with type " << xtype
490            << " and number of dimension " << nDims << std::endl;
491       StdString e = sstr.str();
492       throw CNetCdfException(e);
493     }
494
495     return status;
496   }
497
498   /*!
499   This function makes a request to netcdf with a ncid, to set the chunking size of a variable,
500   given variable id and type of storage
501   \param [in] ncid Id groupd(or File Id)
502   \param [in] varId Id of the variable
503   \param [in] storage Type of storage (It can be : NC_CONTIGUOUS, NC_CHUNKED)
504   \param [in/out] chunkSize array list of chunk sizes
505   \return Status code
506   */
507   int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[])
508   {
509     int status = nc_def_var_chunking(ncid, varId, storage, chunkSize);
510     if (NC_NOERR != status)
511     {
512       StdString errormsg(nc_strerror(status));
513       StdStringStream sstr;
514
515       sstr << "Error in calling function " << "nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl;
516       sstr << errormsg << std::endl;
517       sstr << "Unable to set chunk size of the variable with id : " << varId
518         << " and storage type " << storage << std::endl;
519       StdString e = sstr.str();
520       throw CNetCdfException(e);
521     }
522
523     return status;
524   }
525
526  /*!
527  Set or unset the fill mode for a NetCDF file specified by its file id.
528  \param [in] ncid File id
529  \param [in] fill Define whether the fill mode should be enabled or not
530  \return Status code
531  */
532  int CNetCdfInterface::setFill(int ncid, bool fill)
533  {
534    int old_fill_mode;
535    int status = nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode);
536    if (NC_NOERR != status)
537    {
538      StdString errormsg(nc_strerror(status));
539      StdStringStream sstr;
540
541      sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode)" << std::endl;
542      sstr << errormsg << std::endl;
543      sstr << "Unable to set the fill mode to : " << (fill ? "NC_FILL" : "NC_NOFILL") << std::endl;
544      StdString e = sstr.str();
545      throw CNetCdfException(e);
546    }
547
548    return status;
549  }
550
551   /*!
552   This function makes a request to netcdf with a ncid, to set the fill parameters for a variable,
553   given variable id and type of fill
554   \param [in] ncid Id groupd(or File Id)
555   \param [in] varId Id of the variable
556   \param [in] noFill turn on/off nofill mode on a variable
557   \param [in/out] fillValue
558   \return Status code
559   */
560   int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue)
561   {
562     int status = nc_def_var_fill(ncid, varId, noFill, fillValue);
563     if (NC_NOERR != status)
564     {
565       StdString errormsg(nc_strerror(status));
566       StdStringStream sstr;
567
568       sstr << "Error in calling function " << "nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl;
569       sstr << errormsg << std::endl;
570       sstr << "Unable to set fill parameters of the variable with id : " << varId
571         << " and fill option " << noFill << std::endl;
572       StdString e = sstr.str();
573       throw CNetCdfException(e);
574     }
575
576     return status;
577   }
578
579   /*!
580   This function makes a request to netcdf with a ncid, to change the way read/write operations are performed
581   collectively or independently on the variable.
582   \param [in] ncid Id groupd(or File Id)
583   \param [in] varId Id of the variable
584   \param [in] noFill turn on/off nofill mode on a variable
585   \param [in/out] fillValue
586   \return Status code
587   */
588   int CNetCdfInterface::varParAccess(int ncid, int varId, int access)
589   {
590     int status = nc_var_par_access(ncid, varId, access);
591     if (NC_NOERR != status)
592     {
593       StdString errormsg(nc_strerror(status));
594       StdStringStream sstr;
595
596       sstr << "Error in calling function " << "nc_var_par_access(ncid, varId, access)" << std::endl;
597       sstr << errormsg << std::endl;
598       sstr << "Unable to change read/write option of the variable with id : " << varId << std::endl;
599       StdString e = sstr.str();
600       throw CNetCdfException(e);
601     }
602
603     return status;
604   }
605
606   /*!
607   This function makes a synchronisation of the disk copy of a netCDF dataset.
608   \param [in] ncid Id groupd(or File Id)
609   \return Status code
610   */
611   int CNetCdfInterface::sync(int ncid)
612   {
613     int status = nc_sync(ncid);
614     if (NC_NOERR != status)
615     {
616       StdString errormsg(nc_strerror(status));
617       StdStringStream sstr;
618
619       sstr << "Error in calling function " << "nc_sync(ncid)" << std::endl;
620       sstr << errormsg << std::endl;
621       sstr << "Unable to make a synchronization of a netCDF file with id : " << ncid << std::endl;
622       StdString e = sstr.str();
623       throw CNetCdfException(e);
624     }
625
626     return status;
627   }
628
629   /*!
630   This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute,
631   given its name, type, number of values provided for attribute
632   \param [in] ncid Id of groupd(or File Id)
633   \param [in] varId Id of the variable
634   \param [in] attrName Name of the attribute
635   \param [in] xtypes One of the set of predefined netCDF data types
636   \param [in] numVal Number of values
637   \param [in] op Array of values provided for attribute
638   \return Status code
639   */
640   int CNetCdfInterface::putAtt(int ncid, int varId, const StdString& attrName, nc_type xtype,
641                                StdSize numVal, const void* op)
642   {
643     int status = nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op);
644     if (NC_NOERR != status)
645     {
646       StdString errormsg(nc_strerror(status));
647       StdStringStream sstr;
648
649       sstr << "Error in calling function " << "nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op)" << std::endl;
650       sstr << errormsg << std::endl;
651       sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId
652            << " with number of attribute  " << numVal
653            << " with type " << xtype << std::endl;
654       StdString e = sstr.str();
655       throw CNetCdfException(e);
656     }
657
658     return status;
659   }
660
661   // Some specilization of putAttributeType
662  template<>
663  int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
664                                   StdSize numVal, const double* op)
665  {
666    return (nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, op));
667  }
668
669  template<>
670  int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
671                                     StdSize numVal, const float* op)
672  {
673    return (nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, op));
674  }
675
676  template<>
677  int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
678                                     StdSize numVal, const int* op)
679  {
680    return (nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, op));
681  }
682
683  template<>
684  int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
685                                     StdSize numVal, const long* op)
686  {
687    return (nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, op));
688  }
689
690  template<>
691  int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
692                                     StdSize numVal, const short* op)
693  {
694    return (nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, op));
695  }
696
697
698  // Some specilization of putVariableType
699  template<>
700  int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* op)
701  {
702    return (nc_put_vara_double(ncid, varid, start, count, op));
703  }
704
705  template<>
706  int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* op)
707  {
708    return (nc_put_vara_float(ncid, varid, start, count, op));
709  }
710
711  template<>
712  int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* op)
713  {
714    return (nc_put_vara_int(ncid, varid, start, count, op));
715  }
716
717   /*!
718   This function verifies an existence of a variable by using its name.
719   Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either
720   \param [in] ncid Id of groupd(or File Id)
721   \param [in] attrName Name of the variable
722   \return Existence of variable
723   */
724  bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName)
725  {
726     int varId = 0;
727     return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId)));
728  }
729
730  StdString CNetCdfInterface::openMode2String(int oMode)
731  {
732    StdString modeMes;
733    switch (oMode)
734    {
735    case NC_NOWRITE:
736      modeMes = StdString("NC_NOWRITE : Opening netCDF file with read-only access with buffering and caching access");
737      break;
738    case NC_SHARE:
739      modeMes = StdString("NC_SHARE : Several processes can read the file concurrently");
740      break;
741    case NC_WRITE:
742      modeMes = StdString("NC_WRITE : NetCDF file is readable and writable");
743      break;
744    default:
745      modeMes = StdString("In the composed opening mode");
746      break;
747    return modeMes;
748    }
749  }
750
751  StdString CNetCdfInterface::creationMode2String(int cMode)
752  {
753    StdString modeMes;
754    switch (cMode)
755    {
756    case NC_NOCLOBBER:
757      modeMes = StdString("NC_NOCLOBBER : Not overwrite an exisiting netCDF file ");
758      break;
759    case NC_SHARE:
760      modeMes = StdString("NC_SHARE : Several processes can read from and write into the file concurrently");
761      break;
762    case NC_64BIT_OFFSET:
763      modeMes = StdString("NC_64BIT_OFFSET : NetCDF file is 64-bit offset");
764      break;
765    case NC_NETCDF4:
766      modeMes = StdString("NC_NETCDF4 : NetCDF file is HDF5/NetCDF-4");
767      break;
768    case NC_CLASSIC_MODEL:
769      modeMes = StdString("NC_CLASSIC_MODEL : NetCDF file is classical model");
770      break;
771    default:
772      modeMes = StdString("In the composed creation mode");
773      break;
774    return modeMes;
775    }
776  }
777
778 }
Note: See TracBrowser for help on using the repository browser.