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

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

omp_dev

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