Ignore:
Timestamp:
09/15/15 15:15:57 (9 years ago)
Author:
rlacroix
Message:

Use the NetCDF wrapper for inputs for better error checking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/io/inetcdf4.cpp

    r685 r686  
    2020  { /* Nothing to do */ } 
    2121 
    22   ///-------------------------------------------------------------- 
    23  
    24   void CINetCDF4::CheckError(int status) 
    25   { 
    26     if (status != NC_NOERR) 
    27     { 
    28       StdString errormsg(nc_strerror(status)); // fuite mémoire ici ? 
    29       ERROR("CINetCDF4::CheckError(int status)", 
    30             << "[ status = " << status << " ] " << errormsg); 
    31     } 
    32   } 
    33  
    3422  //--------------------------------------------------------------- 
    3523 
    3624  void CINetCDF4::close(void) 
    3725  { 
    38     CheckError(nc_close(this->ncidp)); 
     26    CNetCdfInterface::close(this->ncidp); 
    3927  } 
    4028 
     
    5038    { 
    5139      const StdString& groupid = *it; 
    52       CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue)); 
     40      CNetCdfInterface::inqNcId(retvalue, groupid, retvalue); 
    5341    } 
    5442 
     
    6149    int varid = 0; 
    6250    int grpid = this->getGroup(path); 
    63     CheckError(nc_inq_varid(grpid, varname.c_str(), &varid)); 
     51    CNetCdfInterface::inqVarId(grpid, varname, varid); 
    6452    return varid; 
    6553  } 
     
    7058    int dimid = 0; 
    7159    int grpid = this->getGroup(path); 
    72     CheckError(nc_inq_dimid(grpid, dimname.c_str(), &dimid)); 
     60    CNetCdfInterface::inqDimId(grpid, dimname, dimid); 
    7361    return dimid; 
    7462  } 
     
    8169    int grpid = this->getGroup(path); 
    8270    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL; 
    83     CheckError(nc_inq_att(grpid, varid, attname.c_str(), 
    84                           &retvalue.first, &retvalue.second)); 
     71    CNetCdfInterface::inqAtt(grpid, varid, attname, retvalue.first, retvalue.second); 
    8572    return retvalue; 
    8673  } 
     
    9077    int dimid = 0; 
    9178    int grpid = this->getGroup(path); 
    92     CheckError(nc_inq_unlimdim(grpid, &dimid)); 
     79    CNetCdfInterface::inqUnLimDim(grpid, dimid); 
    9380    return dimid; 
    9481  } 
     
    9683  StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath* const path) 
    9784  { 
    98     char full_name_in[NC_MAX_NAME +1]; 
    9985    int grpid = this->getGroup(path); 
    10086    int dimid = this->getUnlimitedDimension(path); 
    101     CheckError(nc_inq_dimname(grpid, dimid, full_name_in)); 
    102  
    103     StdString dimname(full_name_in); 
     87 
     88    StdString dimname; 
     89    if (dimid != -1) 
     90      CNetCdfInterface::inqDimName(grpid, dimid, dimname); 
    10491    return dimname; 
    10592  } 
    10693 
    10794  //--------------------------------------------------------------- 
     95 
    10896  StdSize CINetCDF4::getNbVertex(const StdString& name, 
    10997                                 const CVarPath* const path) 
     
    121109            (this->getCoordinatesIdList(name, path).back(), path); 
    122110      StdString dim = this->getDimensionsList(&bound, path).back(); 
    123       return (this->getDimensions(&bound, path)[dim]); 
     111      return this->getDimensions(&bound, path)[dim]; 
    124112    } 
    125113    return size_t(-1); 
     
    130118  std::list<StdString> CINetCDF4::getGroups(const CVarPath* const path) 
    131119  { 
    132     StdSize strlen = 0; 
    133     char full_name_in[NC_MAX_NAME +1]; 
    134120    int nbgroup = 0, *groupid = NULL; 
    135121    int grpid = this->getGroup(path); 
    136122    std::list<StdString> retvalue; 
    137123 
    138     CheckError(nc_inq_grps(grpid, &nbgroup, NULL)); 
     124    CNetCdfInterface::inqGrpIds(grpid, nbgroup, NULL); 
    139125    groupid = new int[nbgroup](); 
    140     CheckError(nc_inq_grps(grpid, NULL, groupid)); 
     126    CNetCdfInterface::inqGrpIds(grpid, nbgroup, groupid); 
    141127 
    142128    for (int i = 0; i < nbgroup; i++) 
    143129    { 
    144       CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in)); 
    145       StdString groupname(full_name_in, strlen); 
    146       retvalue.push_back(groupname); 
     130      StdString fullGrpName; 
     131      CNetCdfInterface::inqGrpFullName(groupid[i], fullGrpName); 
     132      retvalue.push_back(fullGrpName); 
    147133    } 
    148134 
     
    153139  std::list<StdString> CINetCDF4::getVariables(const CVarPath* const path) 
    154140  { 
    155     char full_name_in[NC_MAX_NAME +1]; 
    156141    int nbvar = 0, *varid = NULL; 
    157142    int grpid = this->getGroup(path); 
    158143    std::list<StdString> retvalue; 
    159144 
    160     CheckError(nc_inq_varids(grpid, &nbvar, NULL)); 
     145    CNetCdfInterface::inqVarIds(grpid, nbvar, NULL); 
    161146    varid = new int[nbvar](); 
    162     CheckError(nc_inq_varids(grpid, NULL, varid)); 
     147    CNetCdfInterface::inqVarIds(grpid, nbvar, varid); 
    163148 
    164149    for (int i = 0; i < nbvar; i++) 
    165150    { 
    166       CheckError(nc_inq_varname(grpid, varid[i], full_name_in)); 
    167       StdString varname(full_name_in); 
    168       retvalue.push_back(varname); 
     151      StdString varName; 
     152      CNetCdfInterface::inqVarName(grpid, varid[i], varName); 
     153      retvalue.push_back(varName); 
    169154    } 
    170155 
     
    175160  StdSize CINetCDF4::getNbOfTimestep(const CVarPath* const path) 
    176161  { 
    177     return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]); 
     162    return this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]; 
    178163  } 
    179164 
     
    214199  std::list<StdString> CINetCDF4::getDimensionsList(const StdString* const var, const CVarPath* const path) 
    215200  { 
    216     char full_name_in[NC_MAX_NAME +1]; 
    217201    int nbdim = 0, *dimid = NULL; 
    218202    int grpid = this->getGroup(path); 
     
    222206    if (var != NULL) 
    223207    { 
    224       CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
     208      CNetCdfInterface::inqVarNDims(grpid, varid, nbdim); 
    225209      dimid = new int[nbdim](); 
    226       CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
     210      CNetCdfInterface::inqVarDimId(grpid, varid, dimid); 
    227211    } 
    228212    else 
    229213    { 
    230       CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
     214      CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1); 
    231215      dimid = new int[nbdim](); 
    232       CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
     216      CNetCdfInterface::inqDimIds(grpid, nbdim, dimid, 1); 
    233217    } 
    234218 
    235219    for (int i = 0; i < nbdim; i++) 
    236220    { 
    237       CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); 
    238       StdString dimname(full_name_in); 
     221      std::string dimname; 
     222      CNetCdfInterface::inqDimName(grpid, dimid[i], dimname); 
    239223      retvalue.push_back(dimname); 
    240224    } 
     
    246230  std::map<StdString, StdSize> CINetCDF4::getDimensions(const StdString* const var, const CVarPath* const path) 
    247231  { 
    248     StdSize size = 0; 
    249     char full_name_in[NC_MAX_NAME + 1]; 
    250232    int nbdim = 0, *dimid = NULL; 
    251233    int grpid = this->getGroup(path); 
     
    255237    if (var != NULL) 
    256238    { 
    257       CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
     239      CNetCdfInterface::inqVarNDims(grpid, varid, nbdim); 
    258240      dimid = new int[nbdim](); 
    259       CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
     241      CNetCdfInterface::inqVarDimId(grpid, varid, dimid); 
    260242    } 
    261243    else 
    262244    { 
    263       CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
     245      CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1); 
    264246      dimid = new int[nbdim](); 
    265       CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
     247      CNetCdfInterface::inqDimIds(grpid, nbdim, dimid, 1); 
    266248    } 
    267249 
    268250    for (int i = 0; i < nbdim; i++) 
    269251    { 
    270       CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); 
    271       CheckError(nc_inq_dimlen (grpid, dimid[i], &size)); 
    272  
    273       StdString dimname(full_name_in); 
     252      std::string dimname; 
     253      CNetCdfInterface::inqDimName(grpid, dimid[i], dimname); 
     254      StdSize size = 0; 
     255      CNetCdfInterface::inqDimLen(grpid, dimid[i], size); 
     256 
    274257      retvalue.insert(retvalue.end(), std::make_pair(dimname, size)); 
    275258    } 
     
    279262  } 
    280263 
    281   std::list<StdString> CINetCDF4::getAttributes(const StdString* const var, const CVarPath* const path ) 
     264  std::list<StdString> CINetCDF4::getAttributes(const StdString* const var, const CVarPath* const path) 
    282265  { 
    283266    int nbatt = 0; 
    284     char full_name_in[NC_MAX_NAME +1]; 
    285267    std::list<StdString> retvalue; 
    286268    int grpid = this->getGroup(path); 
     
    288270 
    289271    if (var != NULL) 
    290       CheckError(nc_inq_varnatts(grpid, varid, &nbatt)); 
     272      CNetCdfInterface::inqVarNAtts(grpid, varid, nbatt); 
    291273    else 
    292       CheckError(nc_inq_natts(grpid, &nbatt)); 
     274      CNetCdfInterface::inqNAtts(grpid, nbatt); 
    293275 
    294276    for (int i = 0; i < nbatt; i++) 
    295277    { 
    296       CheckError(nc_inq_attname(grpid, varid, i, full_name_in)); 
    297       StdString attname(full_name_in); 
     278      StdString attname; 
     279      CNetCdfInterface::inqAttName(grpid, varid, i, attname); 
    298280      retvalue.push_back(attname); 
    299281    } 
     
    323305                                  const CVarPath* const path) 
    324306  { 
    325     return (this->hasAttribute("missing_value", &name, path) || 
    326           this->hasAttribute("_FillValue", &name, path)); 
     307    return (this->hasAttribute("missing_value", &name, path) || this->hasAttribute("_FillValue", &name, path)); 
    327308  } 
    328309 
     
    357338                                 const CVarPath* const path) 
    358339  { 
    359     return (this->hasAttribute("coordinates", &name, path)); 
     340    return this->hasAttribute("coordinates", &name, path); 
    360341  } 
    361342 
     
    363344                            const CVarPath* const path) 
    364345  { 
    365     return (this->hasAttribute("bounds", &name, path)); 
     346    return this->hasAttribute("bounds", &name, path); 
    366347  } 
    367348 
     
    373354  //--------------------------------------------------------------- 
    374355 
    375 #define GET_ATTRIBUTE_VALUE(type, func_ext, type_enum)                              \ 
    376   template <>                                                                       \ 
    377   std::vector<type> CINetCDF4::getAttributeValue(const StdString& name,             \ 
    378                                                  const StdString* const var,        \ 
    379                                                  const CVarPath* const path)        \ 
    380   {                                                                                 \ 
    381     int grpid = this->getGroup(path);                                               \ 
    382     int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;          \ 
    383     std::pair<nc_type , StdSize> attinfos = this->getAttribute(name, var, path);    \ 
    384     std::vector<type> retvalue(attinfos.second);                                    \ 
    385     if (attinfos.first != type_enum)                                                \ 
    386       ERROR("CINetCDF4::getAttributeValue<double>(name, var, path",                 \ 
    387             << "[ name : " << name                                                  \ 
    388             << ", type requested :" << attinfos.first                               \ 
    389             << ", type stored : " << type_enum << "]"                               \ 
    390             << " Invalid type !");                                                  \ 
    391     CheckError(nc_get_att_##func_ext(grpid, varid, name.c_str(), &(retvalue[0])));  \ 
    392     return retvalue;                                                                \ 
    393   } 
    394  
    395   GET_ATTRIBUTE_VALUE(double, double, NC_DOUBLE) 
    396   GET_ATTRIBUTE_VALUE(float,  float,  NC_FLOAT) 
    397   GET_ATTRIBUTE_VALUE(int,    int ,   NC_INT) 
    398   GET_ATTRIBUTE_VALUE(char,   text,   NC_CHAR) 
    399  
    400   template <> 
     356  template <class T> 
     357  std::vector<T> CINetCDF4::getAttributeValue(const StdString& name, 
     358                                              const StdString* const var, 
     359                                              const CVarPath* const path) 
     360  { 
     361    int grpid = this->getGroup(path); 
     362    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL; 
     363    std::pair<nc_type , StdSize> attinfos = this->getAttribute(name, var, path); 
     364    std::vector<T> retvalue(attinfos.second); 
     365    nc_type type = CNetCdfInterface::getNcType<T>(); 
     366    if (attinfos.first != type) 
     367      ERROR("CINetCDF4::getAttributeValue<T>(name, var, path)", 
     368            << "[ name : " << name 
     369            << ", type requested :" << attinfos.first 
     370            << ", type stored : " << type << "]" 
     371            << " Invalid type !"); 
     372    CNetCdfInterface::getAttType(grpid, varid, name.c_str(), &retvalue[0]); 
     373    return retvalue; 
     374  } 
     375 
     376  template std::vector<double> CINetCDF4::getAttributeValue(const StdString& name, 
     377                                                            const StdString* const var, 
     378                                                            const CVarPath* const path); 
     379  template std::vector<float> CINetCDF4::getAttributeValue(const StdString& name, 
     380                                                           const StdString* const var, 
     381                                                           const CVarPath* const path); 
     382  template std::vector<int> CINetCDF4::getAttributeValue(const StdString& name, 
     383                                                         const StdString* const var, 
     384                                                         const CVarPath* const path); 
     385  template std::vector<char> CINetCDF4::getAttributeValue(const StdString& name, 
     386                                                          const StdString* const var, 
     387                                                          const CVarPath* const path); 
     388 
    401389  StdString CINetCDF4::getAttributeValue(const StdString& name, 
    402390                                         const StdString* const var, 
    403391                                         const CVarPath* const path) 
    404392  { 
    405     std::vector<char> chart = this->getAttributeValue<std::vector<char> >(name, var, path); 
    406     StdString retvalue(&(chart[0]), chart.size()); 
    407     return retvalue; 
    408   } 
    409  
    410   template <> 
    411   int CINetCDF4::getMissingValue(const StdString& name, 
    412                                  const CVarPath* const path) 
     393    std::vector<char> data = this->getAttributeValue<char>(name, var, path); 
     394 
     395    return StdString(data.begin(), data.end()); 
     396  } 
     397 
     398  template <class T> 
     399  T CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path) 
    413400  { 
    414401    if (this->hasAttribute("missing_value", &name, path)) 
    415       return (this->getAttributeValue<std::vector<int> >("missing_value", &name, path)[0]); 
     402      return this->getAttributeValue<T>("missing_value", &name, path)[0]; 
    416403    if (this->hasAttribute("_FillValue", &name, path)) 
    417       return (this->getAttributeValue<std::vector<int> >("_FillValue", &name, path)[0]); 
     404      return this->getAttributeValue<T>("_FillValue", &name, path)[0]; 
    418405    return 0; 
    419406  } 
    420407 
    421   template <> 
    422   double CINetCDF4::getMissingValue(const StdString& name, 
    423                                     const CVarPath* const path) 
    424   { 
    425     if (this->hasAttribute("missing_value", &name, path)) 
    426       return (this->getAttributeValue<std::vector<double> >("missing_value", &name, path)[0]); 
    427     if (this->hasAttribute("_FillValue", &name, path)) 
    428       return (this->getAttributeValue<std::vector<double> >("_FillValue", &name, path)[0]); 
    429     return 0; 
    430   } 
    431  
    432   template <> 
    433   float CINetCDF4::getMissingValue(const StdString& name, 
    434                                    const CVarPath* const path) 
    435   { 
    436     if (this->hasAttribute("missing_value", &name, path)) 
    437       return (this->getAttributeValue<std::vector<float> >("missing_value", &name, path)[0]); 
    438     if (this->hasAttribute("_FillValue", &name, path)) 
    439       return (this->getAttributeValue<std::vector<float> >("_FillValue", &name, path)[0]); 
    440     return 0; 
    441   } 
     408  template double CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     409  template float CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     410  template int CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     411  template char CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
    442412 
    443413  //--------------------------------------------------------------- 
     
    464434    if (this->hasAttribute("coordinates", &name, path)) 
    465435    { 
    466       return (this->getAttributeValue<StdString>("coordinates", &name, path)); 
     436      return this->getAttributeValue("coordinates", &name, path); 
    467437    } 
    468438    else 
     
    486456    StdString retvalue; 
    487457    if (this->hasAttribute("bounds", &name, path)) 
    488       return (this->getAttributeValue<StdString>("bounds", &name, path)); 
     458      retvalue = this->getAttributeValue("bounds", &name, path); 
    489459    return retvalue; 
    490460  } 
     
    583553    if (!this->hasTemporalDim(path)) return false; 
    584554    std::map<StdString, StdSize> dims = this->getDimensions(&name, path); 
    585     if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end()) 
    586       return true; 
    587     return false; 
     555    return (dims.find(this->getUnlimitedDimensionName(path)) != dims.end()); 
    588556  } 
    589557 
     
    616584    if (this->isCoordinate(name, path)) 
    617585    { 
    618       return (this->hasBounds(name, path)); 
     586      return this->hasBounds(name, path); 
    619587    } 
    620588    else 
     
    712680  } 
    713681 
    714   template <> 
    715   void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var, 
     682  template <class T> 
     683  void CINetCDF4::getData(CArray<T, 1>& data, const StdString& var, 
    716684                          const CVarPath* const path, StdSize record) 
    717685  { 
    718  
    719686    std::vector<StdSize> start, count; 
    720687    int grpid = this->getGroup(path); 
     
    723690    this->getDataInfo(var, path, record, start, count, array_size); 
    724691    data.resize(array_size); 
    725     CheckError(nc_get_vara_int(grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    726   } 
    727  
     692    CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], data.dataFirst()); 
     693  } 
     694 
     695  template <> 
     696  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var, 
     697                          const CVarPath* const path, StdSize record); 
    728698  template <> 
    729699  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var, 
    730                           const CVarPath* const path, StdSize record) 
    731   { 
    732     std::vector<StdSize> start, count; 
    733     int grpid = this->getGroup(path); 
    734     int varid = this->getVariable(var, path); 
    735     StdSize array_size = 1; 
    736     this->getDataInfo(var, path, record, start, count, array_size); 
    737     data.resize(array_size); 
    738     CheckError(nc_get_vara_double(grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    739   } 
    740  
     700                          const CVarPath* const path, StdSize record); 
    741701  template <> 
    742702  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var, 
    743                           const CVarPath* const path, StdSize record) 
    744   { 
    745     std::vector<StdSize> start, count; 
    746     int grpid = this->getGroup(path); 
    747     int varid = this->getVariable(var, path); 
    748     StdSize array_size = 1; 
    749     this->getDataInfo(var, path, record, start, count, array_size); 
    750     data.resize(array_size); 
    751     CheckError(nc_get_vara_float(grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    752   } 
     703                          const CVarPath* const path, StdSize record); 
    753704 
    754705  template <> 
     
    762713    if (this->mpi && collective) 
    763714      CNetCdfInterface::varParAccess(ncidp, varid, NC_COLLECTIVE); 
    764     if (this->mpi && !collective) 
     715    else if (this->mpi && !collective) 
    765716      CNetCdfInterface::varParAccess(ncidp, varid, NC_INDEPENDENT); 
    766717 
     
    777728    } 
    778729 
    779     CheckError(nc_get_vara_double(ncidp, varid, &(sstart[0]), &(scount[0]), data.dataFirst())); 
     730    CNetCdfInterface::getVaraType(ncidp, varid, &sstart[0], &scount[0], data.dataFirst()); 
    780731  } 
    781732 
     
    787738    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
    788739    if (this->hasCoordinates(varname, path)) 
    789       return (*clist.begin()); 
     740      return *clist.begin(); 
    790741    else 
    791       return (*clist.rbegin()); 
     742      return *clist.rbegin(); 
    792743  } 
    793744 
     
    797748    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
    798749    if (this->hasCoordinates(varname, path)) 
    799       return (*(++clist.begin())); 
     750      return *(++clist.begin()); 
    800751    else 
    801       return (*(++clist.rbegin())); 
     752      return *(++clist.rbegin()); 
    802753  } 
    803754 
     
    808759    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
    809760    if (this->hasCoordinates(varname, path)) 
    810       return (*(++(++clist.begin()))); 
     761      return *(++(++clist.begin())); 
    811762    else 
    812       return (*(++(++clist.rbegin()))); 
     763      return *(++(++clist.rbegin())); 
    813764  } 
    814765} // namespace xios 
Note: See TracChangeset for help on using the changeset viewer.