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

Last change on this file since 606 was 606, checked in by rlacroix, 6 years ago

Support NetCDF4 compression.

Only available for non-parallel output so either if only one server is used or if the multiple file mode is enabled).

  • 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: 25.6 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
13namespace xios
14{
15/*!
16This 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*/
22int 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/*!
41This 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*/
49int 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/*!
68This 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*/
74int 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/*!
94This 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*/
102int 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/*!
121This function closes a netcdf file, given its id
122\param [in] ncId id of the opening netcdf file
123\return Status code
124*/
125int 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/*!
143This 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*/
147int 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/*!
165This 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*/
169int 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/*!
188This 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*/
194int 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/*!
214This 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*/
220int 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/*!
239This 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*/
245int 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/*!
264This 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*/
269int 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/*!
288This 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*/
294int 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/*!
314This 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*/
320int 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/*!
339This 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*/
345int 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/*!
364This 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*/
370int 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/*!
389This 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*/
396int 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/*!
416This 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*/
422int 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/*!
441This 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*/
447int 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/*!
467This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode,
468return 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*/
477int 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/*!
499This function makes a request to netcdf with a ncid, to set the chunking size of a variable,
500given 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*/
507int 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/*!
527This function sets the compression level to the specified variable
528\param [in] ncid Groud id (or file id)
529\param [in] varId Id of the variable
530\param [in] compressionLevel The compression level from 0 to 9 (0 disables the compression, 9 is the higher compression)
531\return Status code
532*/
533int CNetCdfInterface::defVarDeflate(int ncid, int varId, int compressionLevel)
534{
535  int status = nc_def_var_deflate(ncid, varId, false, (compressionLevel > 0), compressionLevel);
536  if (NC_NOERR != status)
537  {
538    StdString errormsg(nc_strerror(status));
539    StdStringStream sstr;
540
541    sstr << "Error in calling function " << "nc_def_var_deflate(ncid, varId, false, (compressionLevel > 0), compressionLevel)" << std::endl;
542    sstr << errormsg << std::endl;
543    sstr << "Unable to set the compression level of the variable with id: " << varId
544         << " and compression level: " << compressionLevel << std::endl;
545    StdString e = sstr.str();
546    throw CNetCdfException(e);
547  }
548
549  return status;
550}
551
552/*!
553Set or unset the fill mode for a NetCDF file specified by its file id.
554\param [in] ncid File id
555\param [in] fill Define whether the fill mode should be enabled or not
556\return Status code
557*/
558int CNetCdfInterface::setFill(int ncid, bool fill)
559{
560  int old_fill_mode;
561  int status = nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode);
562  if (NC_NOERR != status)
563  {
564    StdString errormsg(nc_strerror(status));
565    StdStringStream sstr;
566
567    sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode)" << std::endl;
568    sstr << errormsg << std::endl;
569    sstr << "Unable to set the fill mode to : " << (fill ? "NC_FILL" : "NC_NOFILL") << std::endl;
570    StdString e = sstr.str();
571    throw CNetCdfException(e);
572  }
573
574  return status;
575}
576
577/*!
578This function makes a request to netcdf with a ncid, to set the fill parameters for a variable,
579given variable id and type of fill
580\param [in] ncid Id groupd(or File Id)
581\param [in] varId Id of the variable
582\param [in] noFill turn on/off nofill mode on a variable
583\param [in/out] fillValue
584\return Status code
585*/
586int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue)
587{
588  int status = nc_def_var_fill(ncid, varId, noFill, fillValue);
589  if (NC_NOERR != status)
590  {
591    StdString errormsg(nc_strerror(status));
592    StdStringStream sstr;
593
594    sstr << "Error in calling function " << "nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl;
595    sstr << errormsg << std::endl;
596    sstr << "Unable to set fill parameters of the variable with id : " << varId
597      << " and fill option " << noFill << std::endl;
598    StdString e = sstr.str();
599    throw CNetCdfException(e);
600  }
601
602  return status;
603}
604
605/*!
606This function makes a request to netcdf with a ncid, to change the way read/write operations are performed
607collectively or independently on the variable.
608\param [in] ncid Id groupd(or File Id)
609\param [in] varId Id of the variable
610\param [in] noFill turn on/off nofill mode on a variable
611\param [in/out] fillValue
612\return Status code
613*/
614int CNetCdfInterface::varParAccess(int ncid, int varId, int access)
615{
616  int status = nc_var_par_access(ncid, varId, access);
617  if (NC_NOERR != status)
618  {
619    StdString errormsg(nc_strerror(status));
620    StdStringStream sstr;
621
622    sstr << "Error in calling function " << "nc_var_par_access(ncid, varId, access)" << std::endl;
623    sstr << errormsg << std::endl;
624    sstr << "Unable to change read/write option of the variable with id : " << varId << std::endl;
625    StdString e = sstr.str();
626    throw CNetCdfException(e);
627  }
628
629  return status;
630}
631
632/*!
633This function makes a synchronisation of the disk copy of a netCDF dataset.
634\param [in] ncid Id groupd(or File Id)
635\return Status code
636*/
637int CNetCdfInterface::sync(int ncid)
638{
639  int status = nc_sync(ncid);
640  if (NC_NOERR != status)
641  {
642    StdString errormsg(nc_strerror(status));
643    StdStringStream sstr;
644
645    sstr << "Error in calling function " << "nc_sync(ncid)" << std::endl;
646    sstr << errormsg << std::endl;
647    sstr << "Unable to make a synchronization of a netCDF file with id : " << ncid << std::endl;
648    StdString e = sstr.str();
649    throw CNetCdfException(e);
650  }
651
652  return status;
653}
654
655/*!
656This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute,
657given its name, type, number of values provided for attribute
658\param [in] ncid Id of groupd(or File Id)
659\param [in] varId Id of the variable
660\param [in] attrName Name of the attribute
661\param [in] xtypes One of the set of predefined netCDF data types
662\param [in] numVal Number of values
663\param [in] op Array of values provided for attribute
664\return Status code
665*/
666int CNetCdfInterface::putAtt(int ncid, int varId, const StdString& attrName, nc_type xtype,
667                            StdSize numVal, const void* op)
668{
669  int status = nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op);
670  if (NC_NOERR != status)
671  {
672    StdString errormsg(nc_strerror(status));
673    StdStringStream sstr;
674
675    sstr << "Error in calling function " << "nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op)" << std::endl;
676    sstr << errormsg << std::endl;
677    sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId
678         << " with number of attribute  " << numVal
679         << " with type " << xtype << std::endl;
680    StdString e = sstr.str();
681    throw CNetCdfException(e);
682  }
683
684  return status;
685}
686
687 // Some specilization of putAttributeType
688template<>
689int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
690                                 StdSize numVal, const double* op)
691{
692  return (nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, op));
693}
694
695template<>
696int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
697                                   StdSize numVal, const float* op)
698{
699  return (nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, op));
700}
701
702template<>
703int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
704                                   StdSize numVal, const int* op)
705{
706  return (nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, op));
707}
708
709template<>
710int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
711                                   StdSize numVal, const long* op)
712{
713  return (nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, op));
714}
715
716template<>
717int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
718                                   StdSize numVal, const short* op)
719{
720  return (nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, op));
721}
722
723
724// Some specilization of putVariableType
725template<>
726int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* op)
727{
728  return (nc_put_vara_double(ncid, varid, start, count, op));
729}
730
731template<>
732int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* op)
733{
734  return (nc_put_vara_float(ncid, varid, start, count, op));
735}
736
737template<>
738int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* op)
739{
740  return (nc_put_vara_int(ncid, varid, start, count, op));
741}
742
743 /*!
744 This function verifies an existence of a variable by using its name.
745 Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either
746 \param [in] ncid Id of groupd(or File Id)
747 \param [in] attrName Name of the variable
748 \return Existence of variable
749 */
750bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName)
751{
752   int varId = 0;
753   return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId)));
754}
755
756StdString CNetCdfInterface::openMode2String(int oMode)
757{
758  StdString modeMes;
759  switch (oMode)
760  {
761  case NC_NOWRITE:
762    modeMes = StdString("NC_NOWRITE : Opening netCDF file with read-only access with buffering and caching access");
763    break;
764  case NC_SHARE:
765    modeMes = StdString("NC_SHARE : Several processes can read the file concurrently");
766    break;
767  case NC_WRITE:
768    modeMes = StdString("NC_WRITE : NetCDF file is readable and writable");
769    break;
770  default:
771    modeMes = StdString("In the composed opening mode");
772    break;
773  }
774  return modeMes;
775}
776
777StdString CNetCdfInterface::creationMode2String(int cMode)
778{
779  StdString modeMes;
780  switch (cMode)
781  {
782  case NC_NOCLOBBER:
783    modeMes = StdString("NC_NOCLOBBER : Not overwrite an exisiting netCDF file ");
784    break;
785  case NC_SHARE:
786    modeMes = StdString("NC_SHARE : Several processes can read from and write into the file concurrently");
787    break;
788  case NC_64BIT_OFFSET:
789    modeMes = StdString("NC_64BIT_OFFSET : NetCDF file is 64-bit offset");
790    break;
791  case NC_NETCDF4:
792    modeMes = StdString("NC_NETCDF4 : NetCDF file is HDF5/NetCDF-4");
793    break;
794  case NC_CLASSIC_MODEL:
795    modeMes = StdString("NC_CLASSIC_MODEL : NetCDF file is classical model");
796    break;
797  default:
798    modeMes = StdString("In the composed creation mode");
799    break;
800  }
801  return modeMes;
802}
803
804}
Note: See TracBrowser for help on using the repository browser.