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

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

save dev. TO DO : test with xios

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