source: XIOS/dev/branch_openmp/src/io/netCdfInterface.cpp @ 1460

Last change on this file since 1460 was 1460, checked in by yushan, 6 years ago

branch_openmp merged with XIOS_DEV_CMIP6@1459

  • 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: 33.7 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 when 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, MPI_INFO_NULL.mpi_info, &ncId);
52  int status = xios::nc_create_par(fileName.c_str(), cMode, comm, *(static_cast< MPI_Info* >(MPI_INFO_NULL.mpi_info)), &ncId);
53  if (NC_NOERR != status)
54  {
55    StdString errormsg(nc_strerror(status));
56    StdStringStream sstr;
57    sstr << "Error when calling function: nc_create_par(fileName.c_str(), cMode, comm, info, &ncId) " << std::endl
58         << errormsg << std::endl
59         << "Unable to create file on parallel file system, given its name: " << std::endl
60         << "and its creation mode " << creationMode2String(cMode) << std::endl;
61    StdString e = sstr.str();
62    throw CNetCdfException(e);
63  }
64
65  return status;
66}
67
68/*!
69This function opens a netcdf file, given its name and open mode, return its id
70\param [in] fileName Name of the file
71\param [in] oMode open mode
72\param [in/out] ncId id of the opening file
73\return Status code
74*/
75int CNetCdfInterface::open(const StdString& fileName, int oMode, int& ncId)
76{
77  int status = nc_open(fileName.c_str(), oMode, &ncId);
78  if (NC_NOERR != status)
79  {
80    StdString errormsg(nc_strerror(status));
81    StdStringStream sstr;
82    sstr << "Error when calling function: nc_open(fileName.c_str(), oMode, &ncId) "<< std::endl
83         << errormsg << std::endl
84         << "Unable to open file, given its name: " << fileName
85         << "and its open mode " << openMode2String(oMode) << std::endl;
86    StdString e = sstr.str();
87    throw CNetCdfException(e);
88  }
89
90  return status;
91}
92
93
94/*!
95This function opens a new netcdf file on parallel file system
96\param [in] fileName Name of the file
97\param [in] oMode open mode
98\param [in] comm MPI communicator
99\param [in] info MPI information
100\param [in/out] ncId id of the opened file
101\return Status code
102*/
103int CNetCdfInterface::openPar(const StdString& fileName, int oMode, MPI_Comm comm, MPI_Info info, int& ncId)
104{
105  int status;
106  #pragma omp critical (_netcdf)
107  status = xios::nc_open_par(fileName.c_str(), oMode, comm, *(static_cast< MPI_Info* >(MPI_INFO_NULL.mpi_info)), &ncId);
108 
109  if (NC_NOERR != status)
110  {
111    StdString errormsg(nc_strerror(status));
112    StdStringStream sstr;
113    sstr << "Error when calling function nc_open_par(fileName.c_str(), oMode, comm, info, &ncId) " << std::endl
114         << errormsg << std::endl
115         << "Unable to open file on parallel file system, given its name: " << fileName
116         << "and its open mode " << openMode2String(oMode) << std::endl;
117    StdString e = sstr.str();
118    throw CNetCdfException(e);
119  }
120
121  return status;
122}
123
124/*!
125This function closes a netcdf file, given its id
126\param [in] ncId id of the opening netcdf file
127\return Status code
128*/
129int CNetCdfInterface::close(int ncId)
130{
131  int status = NC_NOERR;
132  #pragma omp master
133  {
134    status = nc_close(ncId);
135    if (NC_NOERR != status)
136    {
137      StdString errormsg(nc_strerror(status));
138      StdStringStream sstr;
139      sstr << "Error when calling function nc_close(ncId)" << std::endl
140           << errormsg << std::endl
141           << "Unable to close file, given its id: " << ncId << std::endl;
142      StdString e = sstr.str();
143      throw CNetCdfException(e);
144    }
145  }
146
147  return status;
148}
149
150/*!
151This function put a netcdf file into define mode, given its id
152\param [in] ncId id of the opening netcdf file to be put into define mode
153\return Status code
154*/
155int CNetCdfInterface::reDef(int ncId)
156{
157  int status = nc_redef(ncId);
158  if (NC_NOERR != status)
159  {
160    StdString errormsg(nc_strerror(status));
161    StdStringStream sstr;
162    sstr << "Error when calling function nc_redef(ncId)" << std::endl
163      << errormsg << std::endl
164      << "Unable to put this file into define mode given its id: " << ncId << std::endl;
165    StdString e = sstr.str();
166    throw CNetCdfException(e);
167  }
168
169  return status;
170}
171
172/*!
173This function ends a netcdf file define mode, given its id
174\param [in] ncId id of the opening netcdf file to be put into define mode
175\return Status code
176*/
177int CNetCdfInterface::endDef(int ncId)
178{
179  int status = nc_enddef(ncId);
180  if (NC_NOERR != status)
181  {
182    StdString errormsg(nc_strerror(status));
183    StdStringStream sstr;
184
185    sstr << "Error when calling function nc_enddef(ncId)" << std::endl
186         << errormsg << std::endl
187         << "Unable to end define mode of this file, given its id: " << ncId << std::endl;
188    StdString e = sstr.str();
189    throw CNetCdfException(e);
190  }
191
192  return status;
193}
194
195/*!
196This function makes a request to netcdf with ncid and group name then return ncid of the named group
197\param [in] ncid Groupd id (or File Id)
198\param [in] grpName Name of the desired group (or file)
199\param [in/out] grpId Group id if the group is found
200\return Status code
201*/
202int CNetCdfInterface::inqNcId(int ncid, const StdString& grpName, int& grpId)
203{
204  int status = nc_inq_ncid(ncid, grpName.c_str(), &grpId);
205  if (NC_NOERR != status)
206  {
207    StdString errormsg(nc_strerror(status));
208    StdStringStream sstr;
209
210    sstr << "Error when calling function nc_inq_ncid(ncid, grpName.c_str(), &grpId)" << std::endl
211         << errormsg << std::endl
212         << "Unable to get id of a group (File), given its name: " << grpName << std::endl;
213    StdString e = sstr.str();
214    throw CNetCdfException(e);
215  }
216
217  return status;
218}
219
220
221/*!
222This function makes a request to netcdf with ncid and variable name then return ncid of the named variable
223\param [in] ncid Groupd id (or File Id)
224\param [in] varName Name of the desired variable
225\param [in/out] varId Variable id if this variable is found
226\return Status code
227*/
228int CNetCdfInterface::inqVarId(int ncid, const StdString& varName, int& varId)
229{
230  int status = nc_inq_varid(ncid, varName.c_str(), &varId);
231  if (NC_NOERR != status)
232  {
233    StdString errormsg(nc_strerror(status));
234    StdStringStream sstr;
235
236    sstr << "Error when calling function: nc_inq_varid(ncid, varName.c_str(), &varId)" << std::endl
237         << (errormsg) << std::endl
238         << "Unable to get id of variable with name: " << varName << std::endl;
239    StdString e = sstr.str();
240    throw CNetCdfException(e);
241  }
242
243  return status;
244}
245
246/*!
247This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension
248\param [in] ncid Groupd id (or File Id)
249\param [in] dimName Name of the desired dimension
250\param [in/out] dimId Dimension id if this dimension is found
251\return Status code
252*/
253int CNetCdfInterface::inqDimId(int ncid, const StdString& dimName, int& dimId)
254{
255  int status = nc_inq_dimid(ncid, dimName.c_str(), &dimId);
256  if (NC_NOERR != status)
257  {
258    StdString errormsg(nc_strerror(status));
259    StdStringStream sstr;
260
261    sstr << "Error when calling function nc_inq_dimid(ncid, dimName.c_str(), &dimId)" << std::endl
262         << errormsg << std::endl
263         << "Unable to get id of dimension, given its name: " << dimName << std::endl;
264    StdString e = sstr.str();
265    throw CNetCdfException(e);
266  }
267
268  return status;
269}
270
271/*!
272This function queries the name of a variable given its id.
273\param [in] ncid Groupd id (or File Id)
274\param [in] varId Id of desired variable
275\param [out] varName name of desired variable
276\return Status code
277*/
278int CNetCdfInterface::inqVarName(int ncid, int varId, StdString& varName)
279{
280  char varNameBuff[NC_MAX_NAME + 1];
281  int status = nc_inq_varname(ncid, varId, varNameBuff);
282  if (NC_NOERR != status)
283  {
284    StdString errormsg(nc_strerror(status));
285    StdStringStream sstr;
286
287    sstr << "Error when calling function nc_inq_varname(ncid, varId, varNameBuff)" << std::endl
288         << errormsg << std::endl
289         << "Unable to get variable name: "<< varName << " given its id: " << varId << std::endl;
290    StdString e = sstr.str();
291    throw CNetCdfException(e);
292  }
293  varName = varNameBuff;
294  return status;
295}
296
297/*!
298This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension
299\param [in] ncid Groupd id (or File Id)
300\param [in/out] dimId Dimension id if this dimension is found
301\return Status code
302*/
303int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId)
304{
305  int status = nc_inq_unlimdim(ncid, &dimId);
306  if (NC_NOERR != status)
307  {
308    StdString errormsg(nc_strerror(status));
309    StdStringStream sstr;
310
311    sstr << "Error when calling function nc_inq_dimid" << std::endl
312      << errormsg << std::endl
313      << "Unable to get id of unlimited dimension " << std::endl;
314    StdString e = sstr.str();
315    throw CNetCdfException(e);
316 }
317
318  return status;
319}
320
321/*!
322This function makes a request to netcdf, returns name of a dimension, given its id
323\param [in] ncid Groupd id (or File Id)
324\param [in] dimId Id of desired dimension
325\param [out] dimName Name of desired dimension
326\return Status code
327*/
328int CNetCdfInterface::inqDimName(int ncid, int dimId, StdString& dimName)
329{
330  char fullNameIn[NC_MAX_NAME + 1];
331  int status = nc_inq_dimname(ncid, dimId, fullNameIn);
332  if (NC_NOERR != status)
333  {
334    StdString errormsg(nc_strerror(status));
335    StdStringStream sstr;
336
337    sstr << "Error when calling function nc_inq_dimname(ncid, dimId, fullNameIn)" << std::endl
338         << errormsg << std::endl
339         << "Unable to get dimension name: " << dimName << " given its id: " << dimId << std::endl;
340    StdString e = sstr.str();
341    throw CNetCdfException(e);
342  }
343  dimName = StdString(fullNameIn);
344  return status;
345}
346
347/*!
348This function makes a request to netcdf, returns length of a dimension, given its id
349\param [in] ncid Groupd id (or File Id)
350\param [in] dimId Id of desired dimension
351\param [in/out] dimLen Length of desired dimension
352\return Status code
353*/
354int CNetCdfInterface::inqDimLen(int ncid, int dimId, StdSize& dimLen)
355{
356  int status = nc_inq_dimlen(ncid, dimId, &dimLen);
357  if (NC_NOERR != status)
358  {
359    StdString errormsg(nc_strerror(status));
360    StdStringStream sstr;
361
362    sstr << "Error when calling function nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl
363         << errormsg << std::endl
364         << "Unable to get dimension length given its id: " << dimId << std::endl;
365    StdString e = sstr.str();
366    throw CNetCdfException(e);
367  }
368
369  return status;
370}
371
372/*!
373This function makes a request to netcdf, returns number of dimensions of a variable, given its id
374\param [in] ncid Groupd id (or File Id)
375\param [in] varId Id of variable
376\param [in/out] ndims number of dimension of the variable
377\return Status code
378*/
379int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims)
380{
381  int status = nc_inq_varndims(ncid, varId, &nDims);
382  if (NC_NOERR != status)
383  {
384    StdString errormsg(nc_strerror(status));
385    StdStringStream sstr;
386
387    sstr << "Error when calling function nc_inq_varndims(ncid, varId, &nDims)" << std::endl
388         << errormsg << std::endl
389         << "Unable to get the number of dimension of variable with Id: " << varId << std::endl;
390    StdString e = sstr.str();
391    throw CNetCdfException(e);
392  }
393
394  return status;
395}
396
397/*!
398This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id
399\param [in] ncid Groupd id (or File Id)
400\param [in] varId Id of variable
401\param [in/out] dimIds list of dimension of the variable
402\return Status code
403*/
404int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds)
405{
406  int status = nc_inq_vardimid(ncid, varId, dimIds);
407  if (NC_NOERR != status)
408  {
409    StdString errormsg(nc_strerror(status));
410    StdStringStream sstr;
411
412    sstr << "Error when calling function nc_inq_vardimid(ncid, varId, dimIds)" << std::endl
413         << errormsg << std::endl
414         << "Unable to get list of dimension id of the variable with id " << varId << std::endl;
415    StdString e = sstr.str();
416    throw CNetCdfException(e);
417  }
418
419  return status;
420}
421
422/*!
423This function makes a request to netcdf, to find all dimension in a group
424\param [in] ncid Groupd id (or File Id)
425\param [in/out] nDims number of list of dimension
426\param [in/out] dimIds list of dimension in a group or any of its parent
427\param [in] includeParents number of parents
428\return Status code
429*/
430int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents)
431{
432  int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents);
433  if (NC_NOERR != status)
434  {
435    StdString errormsg(nc_strerror(status));
436    StdStringStream sstr;
437
438    sstr << "Error when calling function nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl;
439    sstr << errormsg << std::endl;
440    sstr << "Unable to retrieve number of dimension in the group with id: " << ncid << std::endl;
441    sstr << "With number of Parents " << includeParents << std::endl;
442    StdString e = sstr.str();
443    throw CNetCdfException(e);
444  }
445
446  return status;
447}
448
449/*!
450This function queries the full name of a group given its id.
451\param [in] ncid Groupd id (or File Id)
452\param [in/out] grpFullName the full name of the group
453\return Status code
454*/
455int CNetCdfInterface::inqGrpFullName(int ncid, StdString& grpFullName)
456{
457  StdSize strlen = 0;
458  std::vector<char> buff;
459  int status = nc_inq_grpname_full(ncid, &strlen, NULL);
460  if (NC_NOERR == status)
461  {
462    buff.resize(strlen + 1);
463    status = nc_inq_grpname_full(ncid, NULL, &buff[0]);
464  }
465
466  if (NC_NOERR != status)
467  {
468    StdString errormsg(nc_strerror(status));
469    StdStringStream sstr;
470
471    sstr << "Error when calling function nc_inq_grpname_full(ncid, &strlen, &buff[0])" << std::endl
472         << errormsg << std::endl
473         << "Unable to get the full group name given its id: " << ncid << std::endl;
474    StdString e = sstr.str();
475    throw CNetCdfException(e);
476  }
477
478  grpFullName.assign(buff.begin(), buff.end());
479
480  return status;
481}
482
483/*!
484This function queries the list of group ids given a location id.
485\param [in] ncid Groupd id (or File Id)
486\param [in/out] numgrps number of groups
487\param [in/out] ncids list of group ids
488\return Status code
489*/
490int CNetCdfInterface::inqGrpIds(int ncid, int& numgrps, int* ncids)
491{
492  int status = nc_inq_grps(ncid, &numgrps, ncids);
493  if (NC_NOERR != status)
494  {
495    StdString errormsg(nc_strerror(status));
496    StdStringStream sstr;
497
498    sstr << "Error when calling function nc_inq_grps(ncid, &numgrps, ncids)" << std::endl;
499    sstr << errormsg << std::endl;
500    sstr << "Unable to retrieve the list of groups for location id: " << ncid << std::endl;
501    StdString e = sstr.str();
502    throw CNetCdfException(e);
503  }
504
505  return status;
506}
507
508/*!
509This function queries the list of variable ids given a location id.
510\param [in] ncid Groupd id (or File Id)
511\param [in/out] nvars number of variables
512\param [in/out] varids list of variable ids
513\return Status code
514*/
515int CNetCdfInterface::inqVarIds(int ncid, int& nvars, int* varids)
516{
517  int status = nc_inq_varids(ncid, &nvars, varids);
518  if (NC_NOERR != status)
519  {
520    StdString errormsg(nc_strerror(status));
521    StdStringStream sstr;
522
523    sstr << "Error when calling function nc_inq_varids(ncid, &nvars, varids)" << std::endl;
524    sstr << errormsg << std::endl;
525    sstr << "Unable to retrieve the list of variables for location id: " << ncid << std::endl;
526    StdString e = sstr.str();
527    throw CNetCdfException(e);
528  }
529
530  return status;
531}
532
533/*!
534This function queries the type and the size of an attribute given its name and the id of the variable to which it is attached.
535\param [in] ncid Groupd id (or File Id)
536\param [in] varid the id of the variable to which the attribute is attached
537\param [in] name the name of the attribute
538\param [out] type the type of the attribute
539\param [out] len the size of the attribute
540\return Status code
541*/
542int CNetCdfInterface::inqAtt(int ncid, int varid, const StdString& name, nc_type& type, size_t& len)
543{
544  int status = nc_inq_att(ncid, varid, name.c_str(), &type, &len);
545  if (NC_NOERR != status)
546  {
547    StdString errormsg(nc_strerror(status));
548    StdStringStream sstr;
549
550    sstr << "Error when calling function nc_inq_att(ncid, varid, name.c_str(), &type, &len)" << std::endl;
551    sstr << errormsg << std::endl;
552    sstr << "Unable to query the attribute information given its name: " << name << " and its variable id:" << varid << std::endl;
553    StdString e = sstr.str();
554    throw CNetCdfException(e);
555  }
556
557  return status;
558}
559
560/*!
561This function queries the number of global attributes given a location id.
562\param [in] ncid Groupd id (or File Id)
563\param [out] ngatts the number of global attributes
564\return Status code
565*/
566int CNetCdfInterface::inqNAtts(int ncid, int& ngatts)
567{
568  int status = nc_inq_natts(ncid, &ngatts);
569  if (NC_NOERR != status)
570  {
571    StdString errormsg(nc_strerror(status));
572    StdStringStream sstr;
573
574    sstr << "Error when calling function nc_inq_natts(ncid, &ngatts)" << std::endl;
575    sstr << errormsg << std::endl;
576    sstr << "Unable to query the number of global attributes given the location id:" << ncid << std::endl;
577    StdString e = sstr.str();
578    throw CNetCdfException(e);
579  }
580
581  return status;
582}
583
584/*!
585This function queries the number of global attributes given a location id and a variable id.
586\param [in] ncid Groupd id (or File Id)
587\param [in] varid the id of the variable
588\param [out] natts the number of global attributes
589\return Status code
590*/
591int CNetCdfInterface::inqVarNAtts(int ncid, int varid, int& natts)
592{
593  int status = nc_inq_varnatts(ncid, varid, &natts);
594  if (NC_NOERR != status)
595  {
596    StdString errormsg(nc_strerror(status));
597    StdStringStream sstr;
598
599    sstr << "Error when calling function nc_inq_varnatts(ncid, varid, &natts)" << std::endl;
600    sstr << errormsg << std::endl;
601    sstr << "Unable to query the number of attributes given the location id:" << ncid << " and the variable id:" << varid << std::endl;
602    StdString e = sstr.str();
603    throw CNetCdfException(e);
604  }
605
606  return status;
607}
608
609
610//! Query the name of an attribute given a location id, a variable id and the attribute number
611int CNetCdfInterface::inqAttName(int ncid, int varid, int attnum, StdString& name)
612{
613  std::vector<char> attName(NC_MAX_NAME + 1,' ');
614  int status = nc_inq_attname(ncid, varid, attnum, &attName[0]);
615  if (NC_NOERR != status)
616  {
617    StdString errormsg(nc_strerror(status));
618    StdStringStream sstr;
619
620    sstr << "Error when calling function nc_inq_attname(ncid, varid, attnum, attName)" << std::endl;
621    sstr << errormsg << std::endl;
622    sstr << "Unable to query the name: " << name << " of attribute " << attnum << " given the location id:" << ncid << " and the variable id:" << varid << std::endl;
623    StdString e = sstr.str();
624    throw CNetCdfException(e);
625  }
626
627  int nameSize = 0;
628  while ((nameSize < NC_MAX_NAME) && (' ' != attName[nameSize] )) ++nameSize;
629  name.resize(nameSize);
630//  for (int idx = 0; idx < nameSize; ++idx) name.at(idx) = attName[idx];
631  std::copy(&attName[0], &attName[nameSize-1], name.begin());
632
633  return status;
634}
635
636/*!
637This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name
638\param [in] parentNcid Id of parent groupd(or File Id)
639\param [in] grpName Name of the desired group
640\param [in/out] grpId Group id if this group is created sucessfully
641\return Status code
642*/
643int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId)
644{
645  int status = nc_def_grp(parentNcid, grpName.c_str(), &grpId);
646  if (NC_NOERR != status)
647  {
648    StdString errormsg(nc_strerror(status));
649    StdStringStream sstr;
650
651    sstr << "Error when calling function nc_def_grp(parentNcid, grpName.c_str(), &grpId)" << std::endl;
652    sstr << errormsg << std::endl;
653    sstr << "Unable to create group Id, given its name: " << grpName << std::endl;
654    StdString e = sstr.str();
655    throw CNetCdfException(e);
656  }
657
658  return status;
659}
660
661/*!
662This function makes a request to netcdf, add a new dimension to an open netcdf in define mode
663\param [in] ncid Id of groupd(or File Id)
664\param [in] dimName Name of the desired dimension
665\param [in/out] grpId Group id if this group is created sucessfully
666\return Status code
667*/
668int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId)
669{
670  int status = nc_def_dim(ncid, dimName.c_str(), dimLen, &dimId);
671  if (NC_NOERR != status)
672  {
673    StdString errormsg(nc_strerror(status));
674    StdStringStream sstr;
675
676    sstr << "Error when calling function nc_def_dim(ncid, dimName.c_str(), dimLen, &dimId)" << std::endl;
677    sstr << errormsg << std::endl;
678    sstr << "Unable to create dimension with name: " << dimName
679         << " and with length " << dimLen << std::endl;
680    StdString e = sstr.str();
681    throw CNetCdfException(e);
682  }
683
684  return status;
685}
686
687/*!
688This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode,
689return a variable id, given its name, type, the number of dimensions and list of dimension id
690\param [in] ncid Id of groupd(or File Id)
691\param [in] varName Name of the desired dimension
692\param [in] xtypes One of the set of predefined netCDF data types
693\param [in] nDims Number of dimension for the variable
694\param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions
695\param [in/out] varId Variable id if it is added sucessfully
696\return Status code
697*/
698int CNetCdfInterface::defVar(int ncid, const StdString& varName, nc_type xtype,
699                             int nDims, const int dimIds[], int& varId)
700{
701  int status = nc_def_var(ncid, varName.c_str(), xtype, nDims, dimIds, &varId);
702  if (NC_NOERR != status)
703  {
704    StdString errormsg(nc_strerror(status));
705    StdStringStream sstr;
706
707    sstr << "Error when calling function  nc_def_var(ncid, varName.c_str(), xtype, nDims, dimIds, &varId)" << std::endl;
708    sstr << errormsg << std::endl;
709    sstr << "Unable to add a new variable with name: " << varName
710         << " with type " << xtype
711         << " and number of dimension " << nDims << std::endl;
712    StdString e = sstr.str();
713    throw CNetCdfException(e);
714  }
715
716  return status;
717}
718
719/*!
720This function makes a request to netcdf with a ncid, to set the chunking size of a variable,
721given variable id and type of storage
722\param [in] ncid Id groupd(or File Id)
723\param [in] varId Id of the variable
724\param [in] storage Type of storage (It can be: NC_CONTIGUOUS, NC_CHUNKED)
725\param [in/out] chunkSize array list of chunk sizes
726\return Status code
727*/
728int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[])
729{
730  int status = nc_def_var_chunking(ncid, varId, storage, chunkSize);
731  if (NC_NOERR != status)
732  {
733    StdString errormsg(nc_strerror(status));
734    StdStringStream sstr;
735
736    sstr << "Error when calling function nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl;
737    sstr << errormsg << std::endl;
738    sstr << "Unable to set chunk size of the variable with id: " << varId
739      << " and storage type " << storage << std::endl;
740    StdString e = sstr.str();
741    throw CNetCdfException(e);
742  }
743
744  return status;
745}
746
747/*!
748This function sets the compression level to the specified variable
749\param [in] ncid Groud id (or file id)
750\param [in] varId Id of the variable
751\param [in] compressionLevel The compression level from 0 to 9 (0 disables the compression, 9 is the higher compression)
752\return Status code
753*/
754int CNetCdfInterface::defVarDeflate(int ncid, int varId, int compressionLevel)
755{
756 
757  if (compressionLevel == 0) return NC_NOERR ;
758  int status = nc_def_var_deflate(ncid, varId, (compressionLevel > 0), (compressionLevel > 0), compressionLevel);
759  if (NC_NOERR != status)
760  {
761    StdString errormsg(nc_strerror(status));
762    StdStringStream sstr;
763
764    sstr << "Error when calling function nc_def_var_deflate(ncid, varId, false, (compressionLevel > 0), compressionLevel)" << std::endl;
765    sstr << errormsg << std::endl;
766    sstr << "Unable to set the compression level of the variable with id: " << varId
767         << " and compression level: " << compressionLevel << std::endl;
768    StdString e = sstr.str();
769    throw CNetCdfException(e);
770  }
771
772  return status;
773}
774
775/*!
776Set or unset the fill mode for a NetCDF file specified by its file id.
777\param [in] ncid File id
778\param [in] fill Define whether the fill mode should be enabled or not
779\return Status code
780*/
781int CNetCdfInterface::setFill(int ncid, bool fill)
782{
783  int old_fill_mode;
784  int status = nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode);
785  if (NC_NOERR != status)
786  {
787    StdString errormsg(nc_strerror(status));
788    StdStringStream sstr;
789
790    sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode)" << std::endl;
791    sstr << errormsg << std::endl;
792    sstr << "Unable to set the fill mode to: " << (fill ? "NC_FILL": "NC_NOFILL") << std::endl;
793    StdString e = sstr.str();
794    throw CNetCdfException(e);
795  }
796
797  return status;
798}
799
800/*!
801This function makes a request to netcdf with a ncid, to set the fill parameters for a variable,
802given variable id and type of fill
803\param [in] ncid Id groupd(or File Id)
804\param [in] varId Id of the variable
805\param [in] noFill turn on/off nofill mode on a variable
806\param [in/out] fillValue
807\return Status code
808*/
809int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue)
810{
811  int status = nc_def_var_fill(ncid, varId, noFill, fillValue);
812  if (NC_NOERR != status)
813  {
814    StdString errormsg(nc_strerror(status));
815    StdStringStream sstr;
816
817    sstr << "Error when calling function nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl;
818    sstr << errormsg << std::endl;
819    sstr << "Unable to set fill parameters of the variable with id: " << varId
820      << " and fill option " << noFill << std::endl;
821    StdString e = sstr.str();
822    throw CNetCdfException(e);
823  }
824
825  return status;
826}
827
828/*!
829This function makes a request to netcdf with a ncid, to change the way read/write operations are performed
830collectively or independently on the variable.
831\param [in] ncid Id groupd(or File Id)
832\param [in] varId Id of the variable
833\param [in] noFill turn on/off nofill mode on a variable
834\param [in/out] fillValue
835\return Status code
836*/
837int CNetCdfInterface::varParAccess(int ncid, int varId, int access)
838{
839  int status = nc_var_par_access(ncid, varId, access);
840  if (NC_NOERR != status)
841  {
842    StdString errormsg(nc_strerror(status));
843    StdStringStream sstr;
844
845    sstr << "Error when calling function nc_var_par_access(ncid, varId, access)" << std::endl;
846    sstr << errormsg << std::endl;
847    sstr << "Unable to change read/write option of the variable with id: " << varId << std::endl;
848    StdString e = sstr.str();
849    throw CNetCdfException(e);
850  }
851
852  return status;
853}
854
855/*!
856This function makes a synchronisation of the disk copy of a netCDF dataset.
857\param [in] ncid Id groupd(or File Id)
858\return Status code
859*/
860int CNetCdfInterface::sync(int ncid)
861{
862  int status = nc_sync(ncid);
863  if (NC_NOERR != status)
864  {
865    StdString errormsg(nc_strerror(status));
866    StdStringStream sstr;
867
868    sstr << "Error when calling function nc_sync(ncid)" << std::endl;
869    sstr << errormsg << std::endl;
870    sstr << "Unable to make a synchronization of a netCDF file with id: " << ncid << std::endl;
871    StdString e = sstr.str();
872    throw CNetCdfException(e);
873  }
874
875  return status;
876}
877
878// Some specializations of getAttributeType
879template<>
880int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, double* data)
881{
882  return nc_get_att_double(ncid, varid, attrName, data);
883}
884
885template<>
886int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, float* data)
887{
888  return nc_get_att_float(ncid, varid, attrName, data);
889}
890
891template<>
892int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, int* data)
893{
894  return nc_get_att_int(ncid, varid, attrName, data);
895}
896
897template<>
898int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, long* data)
899{
900  return nc_get_att_long(ncid, varid, attrName, data);
901}
902
903template<>
904int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, short* data)
905{
906  return nc_get_att_short(ncid, varid, attrName, data);
907}
908
909template<>
910int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, char* data)
911{
912  return nc_get_att_text(ncid, varid, attrName, data);
913}
914
915// Some specializations of putAttributeType
916template<>
917int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
918                                   StdSize numVal, const double* data)
919{
920  return nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, data);
921}
922
923template<>
924int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
925                                   StdSize numVal, const float* data)
926{
927  return nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, data);
928}
929
930template<>
931int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
932                                   StdSize numVal, const int* data)
933{
934  return nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, data);
935}
936
937template<>
938int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
939                                   StdSize numVal, const long* data)
940{
941  return nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, data);
942}
943
944template<>
945int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
946                                   StdSize numVal, const short* data)
947{
948  return nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, data);
949}
950
951template<>
952int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
953                                   StdSize numVal, const char* data)
954{
955  return nc_put_att_text(ncid, varid, attrName, numVal, data);
956}
957
958// Some specializations of getVariableType
959template<>
960int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, double* data)
961{
962  return nc_get_vara_double(ncid, varid, start, count, data);
963}
964
965template<>
966int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, float* data)
967{
968  return nc_get_vara_float(ncid, varid, start, count, data);
969}
970
971template<>
972int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, int* data)
973{
974  return nc_get_vara_int(ncid, varid, start, count, data);
975}
976
977template<>
978int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, char* data)
979{
980  return nc_get_vara_text(ncid, varid, start, count, data);
981}
982
983// Some specializations of putVariableType
984template<>
985int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* data)
986{
987  return nc_put_vara_double(ncid, varid, start, count, data);
988}
989
990template<>
991int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* data)
992{
993  return nc_put_vara_float(ncid, varid, start, count, data);
994}
995
996template<>
997int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* data)
998{
999  return nc_put_vara_int(ncid, varid, start, count, data);
1000}
1001
1002template<>
1003int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const char* data)
1004{
1005  return nc_put_vara_text(ncid, varid, start, count, data);
1006}
1007
1008 /*!
1009 This function verifies an existence of a variable by using its name.
1010 Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either
1011 \param [in] ncid Id of groupd(or File Id)
1012 \param [in] attrName Name of the variable
1013 \return Existence of variable
1014 */
1015bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName)
1016{
1017   int varId = 0;
1018   return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId)));
1019}
1020
1021bool CNetCdfInterface::isDimExisted(int ncId, const StdString& dimName)
1022{
1023   int dimId = 0;
1024   return (NC_NOERR == (nc_inq_dimid(ncId, dimName.c_str(), &dimId)));
1025}
1026
1027StdString CNetCdfInterface::openMode2String(int oMode)
1028{
1029  StdString modeMes;
1030  switch (oMode)
1031  {
1032  case NC_NOWRITE:
1033    modeMes = StdString("NC_NOWRITE: Opening netCDF file with read-only access with buffering and caching access");
1034    break;
1035  case NC_SHARE:
1036    modeMes = StdString("NC_SHARE: Several processes can read the file concurrently");
1037    break;
1038  case NC_WRITE:
1039    modeMes = StdString("NC_WRITE: NetCDF file is readable and writable");
1040    break;
1041  default:
1042    modeMes = StdString("In the composed opening mode");
1043    break;
1044  }
1045  return modeMes;
1046}
1047
1048StdString CNetCdfInterface::creationMode2String(int cMode)
1049{
1050  StdString modeMes;
1051  switch (cMode)
1052  {
1053  case NC_NOCLOBBER:
1054    modeMes = StdString("NC_NOCLOBBER: Not overwrite an exisiting netCDF file ");
1055    break;
1056  case NC_SHARE:
1057    modeMes = StdString("NC_SHARE: Several processes can read from and write into the file concurrently");
1058    break;
1059  case NC_64BIT_OFFSET:
1060    modeMes = StdString("NC_64BIT_OFFSET: NetCDF file is 64-bit offset");
1061    break;
1062  case NC_NETCDF4:
1063    modeMes = StdString("NC_NETCDF4: NetCDF file is HDF5/NetCDF-4");
1064    break;
1065  case NC_CLASSIC_MODEL:
1066    modeMes = StdString("NC_CLASSIC_MODEL: NetCDF file is classical model");
1067    break;
1068  default:
1069    modeMes = StdString("In the composed creation mode");
1070    break;
1071  }
1072  return modeMes;
1073}
1074
1075}
Note: See TracBrowser for help on using the repository browser.