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

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

bug fixed in mpi_comm_split. Key needs to be specifify.

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