source: XIOS/dev/branch_yushan_merged/src/io/netCdfInterface.cpp @ 1138

Last change on this file since 1138 was 1138, checked in by yushan, 7 years ago

test_remap back to work. No thread for now

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