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

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

save modif

  • 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.5 KB
Line 
1/*!
2   \file netCdfInterface.cpp
3   \author Ha NGUYEN
4   \date 08 Oct 2014
5   \since 03 Oct 2014
6
7   \brief Wrapper of netcdf functions.
8 */
9
10#include "netCdfInterface.hpp"
11#include "netCdfException.hpp"
12// 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;
106  #pragma omp critical (_netcdf)
107  status = xios::nc_open_par(fileName.c_str(), oMode, comm, info, &ncId);
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;
352  #pragma omp critical (_netcdf)
353  status = nc_inq_dimlen(ncid, dimId, &dimLen);
354  if (NC_NOERR != status)
355  {
356    StdString errormsg(nc_strerror(status));
357    StdStringStream sstr;
358
359    sstr << "Error when calling function nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl
360         << errormsg << std::endl
361         << "Unable to get dimension length given its id: " << dimId << std::endl;
362    StdString e = sstr.str();
363    throw CNetCdfException(e);
364  }
365
366  return status;
367}
368
369/*!
370This function makes a request to netcdf, returns number of dimensions of a variable, given its id
371\param [in] ncid Groupd id (or File Id)
372\param [in] varId Id of variable
373\param [in/out] ndims number of dimension of the variable
374\return Status code
375*/
376int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims)
377{
378  int status = nc_inq_varndims(ncid, varId, &nDims);
379  if (NC_NOERR != status)
380  {
381    StdString errormsg(nc_strerror(status));
382    StdStringStream sstr;
383
384    sstr << "Error when calling function nc_inq_varndims(ncid, varId, &nDims)" << std::endl
385         << errormsg << std::endl
386         << "Unable to get the number of dimension of variable with Id: " << varId << std::endl;
387    StdString e = sstr.str();
388    throw CNetCdfException(e);
389  }
390
391  return status;
392}
393
394/*!
395This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id
396\param [in] ncid Groupd id (or File Id)
397\param [in] varId Id of variable
398\param [in/out] dimIds list of dimension of the variable
399\return Status code
400*/
401int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds)
402{
403  int status = nc_inq_vardimid(ncid, varId, dimIds);
404  if (NC_NOERR != status)
405  {
406    StdString errormsg(nc_strerror(status));
407    StdStringStream sstr;
408
409    sstr << "Error when calling function nc_inq_vardimid(ncid, varId, dimIds)" << std::endl
410         << errormsg << std::endl
411         << "Unable to get list of dimension id of the variable with id " << varId << std::endl;
412    StdString e = sstr.str();
413    throw CNetCdfException(e);
414  }
415
416  return status;
417}
418
419/*!
420This function makes a request to netcdf, to find all dimension in a group
421\param [in] ncid Groupd id (or File Id)
422\param [in/out] nDims number of list of dimension
423\param [in/out] dimIds list of dimension in a group or any of its parent
424\param [in] includeParents number of parents
425\return Status code
426*/
427int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents)
428{
429  int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents);
430  if (NC_NOERR != status)
431  {
432    StdString errormsg(nc_strerror(status));
433    StdStringStream sstr;
434
435    sstr << "Error when calling function nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl;
436    sstr << errormsg << std::endl;
437    sstr << "Unable to retrieve number of dimension in the group with id: " << ncid << std::endl;
438    sstr << "With number of Parents " << includeParents << std::endl;
439    StdString e = sstr.str();
440    throw CNetCdfException(e);
441  }
442
443  return status;
444}
445
446/*!
447This function queries the full name of a group given its id.
448\param [in] ncid Groupd id (or File Id)
449\param [in/out] grpFullName the full name of the group
450\return Status code
451*/
452int CNetCdfInterface::inqGrpFullName(int ncid, StdString& grpFullName)
453{
454  StdSize strlen = 0;
455  std::vector<char> buff;
456  int status = nc_inq_grpname_full(ncid, &strlen, NULL);
457  if (NC_NOERR == status)
458  {
459    buff.resize(strlen + 1);
460    status = nc_inq_grpname_full(ncid, NULL, &buff[0]);
461  }
462
463  if (NC_NOERR != status)
464  {
465    StdString errormsg(nc_strerror(status));
466    StdStringStream sstr;
467
468    sstr << "Error when calling function nc_inq_grpname_full(ncid, &strlen, &buff[0])" << std::endl
469         << errormsg << std::endl
470         << "Unable to get the full group name given its id: " << ncid << std::endl;
471    StdString e = sstr.str();
472    throw CNetCdfException(e);
473  }
474
475  grpFullName.assign(buff.begin(), buff.end());
476
477  return status;
478}
479
480/*!
481This function queries the list of group ids given a location id.
482\param [in] ncid Groupd id (or File Id)
483\param [in/out] numgrps number of groups
484\param [in/out] ncids list of group ids
485\return Status code
486*/
487int CNetCdfInterface::inqGrpIds(int ncid, int& numgrps, int* ncids)
488{
489  int status = nc_inq_grps(ncid, &numgrps, ncids);
490  if (NC_NOERR != status)
491  {
492    StdString errormsg(nc_strerror(status));
493    StdStringStream sstr;
494
495    sstr << "Error when calling function nc_inq_grps(ncid, &numgrps, ncids)" << std::endl;
496    sstr << errormsg << std::endl;
497    sstr << "Unable to retrieve the list of groups for location id: " << ncid << std::endl;
498    StdString e = sstr.str();
499    throw CNetCdfException(e);
500  }
501
502  return status;
503}
504
505/*!
506This function queries the list of variable ids given a location id.
507\param [in] ncid Groupd id (or File Id)
508\param [in/out] nvars number of variables
509\param [in/out] varids list of variable ids
510\return Status code
511*/
512int CNetCdfInterface::inqVarIds(int ncid, int& nvars, int* varids)
513{
514  int status = nc_inq_varids(ncid, &nvars, varids);
515  if (NC_NOERR != status)
516  {
517    StdString errormsg(nc_strerror(status));
518    StdStringStream sstr;
519
520    sstr << "Error when calling function nc_inq_varids(ncid, &nvars, varids)" << std::endl;
521    sstr << errormsg << std::endl;
522    sstr << "Unable to retrieve the list of variables for location id: " << ncid << std::endl;
523    StdString e = sstr.str();
524    throw CNetCdfException(e);
525  }
526
527  return status;
528}
529
530/*!
531This function queries the type and the size of an attribute given its name and the id of the variable to which it is attached.
532\param [in] ncid Groupd id (or File Id)
533\param [in] varid the id of the variable to which the attribute is attached
534\param [in] name the name of the attribute
535\param [out] type the type of the attribute
536\param [out] len the size of the attribute
537\return Status code
538*/
539int CNetCdfInterface::inqAtt(int ncid, int varid, const StdString& name, nc_type& type, size_t& len)
540{
541  int status = nc_inq_att(ncid, varid, name.c_str(), &type, &len);
542  if (NC_NOERR != status)
543  {
544    StdString errormsg(nc_strerror(status));
545    StdStringStream sstr;
546
547    sstr << "Error when calling function nc_inq_att(ncid, varid, name.c_str(), &type, &len)" << std::endl;
548    sstr << errormsg << std::endl;
549    sstr << "Unable to query the attribute information given its name: " << name << " and its variable id:" << varid << std::endl;
550    StdString e = sstr.str();
551    throw CNetCdfException(e);
552  }
553
554  return status;
555}
556
557/*!
558This function queries the number of global attributes given a location id.
559\param [in] ncid Groupd id (or File Id)
560\param [out] ngatts the number of global attributes
561\return Status code
562*/
563int CNetCdfInterface::inqNAtts(int ncid, int& ngatts)
564{
565  int status = nc_inq_natts(ncid, &ngatts);
566  if (NC_NOERR != status)
567  {
568    StdString errormsg(nc_strerror(status));
569    StdStringStream sstr;
570
571    sstr << "Error when calling function nc_inq_natts(ncid, &ngatts)" << std::endl;
572    sstr << errormsg << std::endl;
573    sstr << "Unable to query the number of global attributes given the location id:" << ncid << std::endl;
574    StdString e = sstr.str();
575    throw CNetCdfException(e);
576  }
577
578  return status;
579}
580
581/*!
582This function queries the number of global attributes given a location id and a variable id.
583\param [in] ncid Groupd id (or File Id)
584\param [in] varid the id of the variable
585\param [out] natts the number of global attributes
586\return Status code
587*/
588int CNetCdfInterface::inqVarNAtts(int ncid, int varid, int& natts)
589{
590  int status = nc_inq_varnatts(ncid, varid, &natts);
591  if (NC_NOERR != status)
592  {
593    StdString errormsg(nc_strerror(status));
594    StdStringStream sstr;
595
596    sstr << "Error when calling function nc_inq_varnatts(ncid, varid, &natts)" << std::endl;
597    sstr << errormsg << std::endl;
598    sstr << "Unable to query the number of attributes given the location id:" << ncid << " and the variable id:" << varid << std::endl;
599    StdString e = sstr.str();
600    throw CNetCdfException(e);
601  }
602
603  return status;
604}
605
606
607//! Query the name of an attribute given a location id, a variable id and the attribute number
608int CNetCdfInterface::inqAttName(int ncid, int varid, int attnum, StdString& name)
609{
610  std::vector<char> attName(NC_MAX_NAME + 1,' ');
611  int status = nc_inq_attname(ncid, varid, attnum, &attName[0]);
612  if (NC_NOERR != status)
613  {
614    StdString errormsg(nc_strerror(status));
615    StdStringStream sstr;
616
617    sstr << "Error when calling function nc_inq_attname(ncid, varid, attnum, attName)" << std::endl;
618    sstr << errormsg << std::endl;
619    sstr << "Unable to query the name: " << name << " of attribute " << attnum << " given the location id:" << ncid << " and the variable id:" << varid << std::endl;
620    StdString e = sstr.str();
621    throw CNetCdfException(e);
622  }
623
624  int nameSize = 0;
625  while ((nameSize < NC_MAX_NAME) && (' ' != attName[nameSize] )) ++nameSize;
626  name.resize(nameSize);
627//  for (int idx = 0; idx < nameSize; ++idx) name.at(idx) = attName[idx];
628  std::copy(&attName[0], &attName[nameSize-1], name.begin());
629
630  return status;
631}
632
633/*!
634This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name
635\param [in] parentNcid Id of parent groupd(or File Id)
636\param [in] grpName Name of the desired group
637\param [in/out] grpId Group id if this group is created sucessfully
638\return Status code
639*/
640int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId)
641{
642  int status = nc_def_grp(parentNcid, grpName.c_str(), &grpId);
643  if (NC_NOERR != status)
644  {
645    StdString errormsg(nc_strerror(status));
646    StdStringStream sstr;
647
648    sstr << "Error when calling function nc_def_grp(parentNcid, grpName.c_str(), &grpId)" << std::endl;
649    sstr << errormsg << std::endl;
650    sstr << "Unable to create group Id, given its name: " << grpName << std::endl;
651    StdString e = sstr.str();
652    throw CNetCdfException(e);
653  }
654
655  return status;
656}
657
658/*!
659This function makes a request to netcdf, add a new dimension to an open netcdf in define mode
660\param [in] ncid Id of groupd(or File Id)
661\param [in] dimName Name of the desired dimension
662\param [in/out] grpId Group id if this group is created sucessfully
663\return Status code
664*/
665int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId)
666{
667  int status = nc_def_dim(ncid, dimName.c_str(), dimLen, &dimId);
668  if (NC_NOERR != status)
669  {
670    StdString errormsg(nc_strerror(status));
671    StdStringStream sstr;
672
673    sstr << "Error when calling function nc_def_dim(ncid, dimName.c_str(), dimLen, &dimId)" << std::endl;
674    sstr << errormsg << std::endl;
675    sstr << "Unable to create dimension with name: " << dimName
676         << " and with length " << dimLen << std::endl;
677    StdString e = sstr.str();
678    throw CNetCdfException(e);
679  }
680
681  return status;
682}
683
684/*!
685This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode,
686return a variable id, given its name, type, the number of dimensions and list of dimension id
687\param [in] ncid Id of groupd(or File Id)
688\param [in] varName Name of the desired dimension
689\param [in] xtypes One of the set of predefined netCDF data types
690\param [in] nDims Number of dimension for the variable
691\param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions
692\param [in/out] varId Variable id if it is added sucessfully
693\return Status code
694*/
695int CNetCdfInterface::defVar(int ncid, const StdString& varName, nc_type xtype,
696                             int nDims, const int dimIds[], int& varId)
697{
698  int status = nc_def_var(ncid, varName.c_str(), xtype, nDims, dimIds, &varId);
699  if (NC_NOERR != status)
700  {
701    StdString errormsg(nc_strerror(status));
702    StdStringStream sstr;
703
704    sstr << "Error when calling function  nc_def_var(ncid, varName.c_str(), xtype, nDims, dimIds, &varId)" << std::endl;
705    sstr << errormsg << std::endl;
706    sstr << "Unable to add a new variable with name: " << varName
707         << " with type " << xtype
708         << " and number of dimension " << nDims << std::endl;
709    StdString e = sstr.str();
710    throw CNetCdfException(e);
711  }
712
713  return status;
714}
715
716/*!
717This function makes a request to netcdf with a ncid, to set the chunking size of a variable,
718given variable id and type of storage
719\param [in] ncid Id groupd(or File Id)
720\param [in] varId Id of the variable
721\param [in] storage Type of storage (It can be: NC_CONTIGUOUS, NC_CHUNKED)
722\param [in/out] chunkSize array list of chunk sizes
723\return Status code
724*/
725int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[])
726{
727  int status = nc_def_var_chunking(ncid, varId, storage, chunkSize);
728  if (NC_NOERR != status)
729  {
730    StdString errormsg(nc_strerror(status));
731    StdStringStream sstr;
732
733    sstr << "Error when calling function nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl;
734    sstr << errormsg << std::endl;
735    sstr << "Unable to set chunk size of the variable with id: " << varId
736      << " and storage type " << storage << std::endl;
737    StdString e = sstr.str();
738    throw CNetCdfException(e);
739  }
740
741  return status;
742}
743
744/*!
745This function sets the compression level to the specified variable
746\param [in] ncid Groud id (or file id)
747\param [in] varId Id of the variable
748\param [in] compressionLevel The compression level from 0 to 9 (0 disables the compression, 9 is the higher compression)
749\return Status code
750*/
751int CNetCdfInterface::defVarDeflate(int ncid, int varId, int compressionLevel)
752{
753 
754  if (compressionLevel == 0) return NC_NOERR ;
755  int status = nc_def_var_deflate(ncid, varId, false, (compressionLevel > 0), compressionLevel);
756  if (NC_NOERR != status)
757  {
758    StdString errormsg(nc_strerror(status));
759    StdStringStream sstr;
760
761    sstr << "Error when calling function nc_def_var_deflate(ncid, varId, false, (compressionLevel > 0), compressionLevel)" << std::endl;
762    sstr << errormsg << std::endl;
763    sstr << "Unable to set the compression level of the variable with id: " << varId
764         << " and compression level: " << compressionLevel << std::endl;
765    StdString e = sstr.str();
766    throw CNetCdfException(e);
767  }
768
769  return status;
770}
771
772/*!
773Set or unset the fill mode for a NetCDF file specified by its file id.
774\param [in] ncid File id
775\param [in] fill Define whether the fill mode should be enabled or not
776\return Status code
777*/
778int CNetCdfInterface::setFill(int ncid, bool fill)
779{
780  int old_fill_mode;
781  int status = nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode);
782  if (NC_NOERR != status)
783  {
784    StdString errormsg(nc_strerror(status));
785    StdStringStream sstr;
786
787    sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode)" << std::endl;
788    sstr << errormsg << std::endl;
789    sstr << "Unable to set the fill mode to: " << (fill ? "NC_FILL": "NC_NOFILL") << std::endl;
790    StdString e = sstr.str();
791    throw CNetCdfException(e);
792  }
793
794  return status;
795}
796
797/*!
798This function makes a request to netcdf with a ncid, to set the fill parameters for a variable,
799given variable id and type of fill
800\param [in] ncid Id groupd(or File Id)
801\param [in] varId Id of the variable
802\param [in] noFill turn on/off nofill mode on a variable
803\param [in/out] fillValue
804\return Status code
805*/
806int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue)
807{
808  int status = nc_def_var_fill(ncid, varId, noFill, fillValue);
809  if (NC_NOERR != status)
810  {
811    StdString errormsg(nc_strerror(status));
812    StdStringStream sstr;
813
814    sstr << "Error when calling function nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl;
815    sstr << errormsg << std::endl;
816    sstr << "Unable to set fill parameters of the variable with id: " << varId
817      << " and fill option " << noFill << std::endl;
818    StdString e = sstr.str();
819    throw CNetCdfException(e);
820  }
821
822  return status;
823}
824
825/*!
826This function makes a request to netcdf with a ncid, to change the way read/write operations are performed
827collectively or independently on the variable.
828\param [in] ncid Id groupd(or File Id)
829\param [in] varId Id of the variable
830\param [in] noFill turn on/off nofill mode on a variable
831\param [in/out] fillValue
832\return Status code
833*/
834int CNetCdfInterface::varParAccess(int ncid, int varId, int access)
835{
836  int status = nc_var_par_access(ncid, varId, access);
837  if (NC_NOERR != status)
838  {
839    StdString errormsg(nc_strerror(status));
840    StdStringStream sstr;
841
842    sstr << "Error when calling function nc_var_par_access(ncid, varId, access)" << std::endl;
843    sstr << errormsg << std::endl;
844    sstr << "Unable to change read/write option of the variable with id: " << varId << std::endl;
845    StdString e = sstr.str();
846    throw CNetCdfException(e);
847  }
848
849  return status;
850}
851
852/*!
853This function makes a synchronisation of the disk copy of a netCDF dataset.
854\param [in] ncid Id groupd(or File Id)
855\return Status code
856*/
857int CNetCdfInterface::sync(int ncid)
858{
859  int status = nc_sync(ncid);
860  if (NC_NOERR != status)
861  {
862    StdString errormsg(nc_strerror(status));
863    StdStringStream sstr;
864
865    sstr << "Error when calling function nc_sync(ncid)" << std::endl;
866    sstr << errormsg << std::endl;
867    sstr << "Unable to make a synchronization of a netCDF file with id: " << ncid << std::endl;
868    StdString e = sstr.str();
869    throw CNetCdfException(e);
870  }
871
872  return status;
873}
874
875// Some specializations of getAttributeType
876template<>
877int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, double* data)
878{
879  return nc_get_att_double(ncid, varid, attrName, data);
880}
881
882template<>
883int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, float* data)
884{
885  return nc_get_att_float(ncid, varid, attrName, data);
886}
887
888template<>
889int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, int* data)
890{
891  return nc_get_att_int(ncid, varid, attrName, data);
892}
893
894template<>
895int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, long* data)
896{
897  return nc_get_att_long(ncid, varid, attrName, data);
898}
899
900template<>
901int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, short* data)
902{
903  return nc_get_att_short(ncid, varid, attrName, data);
904}
905
906template<>
907int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, char* data)
908{
909  return nc_get_att_text(ncid, varid, attrName, data);
910}
911
912// Some specializations of putAttributeType
913template<>
914int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
915                                   StdSize numVal, const double* data)
916{
917  return nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, data);
918}
919
920template<>
921int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
922                                   StdSize numVal, const float* data)
923{
924  return nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, data);
925}
926
927template<>
928int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
929                                   StdSize numVal, const int* data)
930{
931  return nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, data);
932}
933
934template<>
935int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
936                                   StdSize numVal, const long* data)
937{
938  return nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, data);
939}
940
941template<>
942int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
943                                   StdSize numVal, const short* data)
944{
945  return nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, data);
946}
947
948template<>
949int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName,
950                                   StdSize numVal, const char* data)
951{
952  return nc_put_att_text(ncid, varid, attrName, numVal, data);
953}
954
955// Some specializations of getVariableType
956template<>
957int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, double* data)
958{
959  return nc_get_vara_double(ncid, varid, start, count, data);
960}
961
962template<>
963int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, float* data)
964{
965  return nc_get_vara_float(ncid, varid, start, count, data);
966}
967
968template<>
969int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, int* data)
970{
971  return nc_get_vara_int(ncid, varid, start, count, data);
972}
973
974template<>
975int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, char* data)
976{
977  return nc_get_vara_text(ncid, varid, start, count, data);
978}
979
980// Some specializations of putVariableType
981template<>
982int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* data)
983{
984  return nc_put_vara_double(ncid, varid, start, count, data);
985}
986
987template<>
988int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* data)
989{
990  return nc_put_vara_float(ncid, varid, start, count, data);
991}
992
993template<>
994int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* data)
995{
996  return nc_put_vara_int(ncid, varid, start, count, data);
997}
998
999template<>
1000int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const char* data)
1001{
1002  return nc_put_vara_text(ncid, varid, start, count, data);
1003}
1004
1005 /*!
1006 This function verifies an existence of a variable by using its name.
1007 Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either
1008 \param [in] ncid Id of groupd(or File Id)
1009 \param [in] attrName Name of the variable
1010 \return Existence of variable
1011 */
1012bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName)
1013{
1014   int varId = 0;
1015   return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId)));
1016}
1017
1018bool CNetCdfInterface::isDimExisted(int ncId, const StdString& dimName)
1019{
1020   int dimId = 0;
1021   return (NC_NOERR == (nc_inq_dimid(ncId, dimName.c_str(), &dimId)));
1022}
1023
1024StdString CNetCdfInterface::openMode2String(int oMode)
1025{
1026  StdString modeMes;
1027  switch (oMode)
1028  {
1029  case NC_NOWRITE:
1030    modeMes = StdString("NC_NOWRITE: Opening netCDF file with read-only access with buffering and caching access");
1031    break;
1032  case NC_SHARE:
1033    modeMes = StdString("NC_SHARE: Several processes can read the file concurrently");
1034    break;
1035  case NC_WRITE:
1036    modeMes = StdString("NC_WRITE: NetCDF file is readable and writable");
1037    break;
1038  default:
1039    modeMes = StdString("In the composed opening mode");
1040    break;
1041  }
1042  return modeMes;
1043}
1044
1045StdString CNetCdfInterface::creationMode2String(int cMode)
1046{
1047  StdString modeMes;
1048  switch (cMode)
1049  {
1050  case NC_NOCLOBBER:
1051    modeMes = StdString("NC_NOCLOBBER: Not overwrite an exisiting netCDF file ");
1052    break;
1053  case NC_SHARE:
1054    modeMes = StdString("NC_SHARE: Several processes can read from and write into the file concurrently");
1055    break;
1056  case NC_64BIT_OFFSET:
1057    modeMes = StdString("NC_64BIT_OFFSET: NetCDF file is 64-bit offset");
1058    break;
1059  case NC_NETCDF4:
1060    modeMes = StdString("NC_NETCDF4: NetCDF file is HDF5/NetCDF-4");
1061    break;
1062  case NC_CLASSIC_MODEL:
1063    modeMes = StdString("NC_CLASSIC_MODEL: NetCDF file is classical model");
1064    break;
1065  default:
1066    modeMes = StdString("In the composed creation mode");
1067    break;
1068  }
1069  return modeMes;
1070}
1071
1072}
Note: See TracBrowser for help on using the repository browser.