Changeset 782 for XIOS/trunk/src/io


Ignore:
Timestamp:
11/12/15 16:33:03 (8 years ago)
Author:
mhnguyen
Message:

Reading attributes of curvilinear grid from file

+) Correct some minor bugs detecting type of grid
+) Use constant string for attributes conforming to CF convention
+) Add part of code to read attributes of curvilinear grid

Test
+) On Curie
+) test_remap passes

Location:
XIOS/trunk/src/io
Files:
3 added
5 edited

Legend:

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

    r736 r782  
    11#include "inetcdf4.hpp" 
    22#include "netCdfInterface.hpp" 
     3#include "netCdf_cf_constant.hpp" 
    34 
    45#include <boost/algorithm/string.hpp> 
     
    302303    { 
    303304      const StdString& attname = *it; 
    304       if (attname.compare(name) == 0) 
     305      if (attname.compare(0, name.size(), name) == 0) 
    305306        return retvalue; 
    306307      retvalue++; 
     
    326327    { 
    327328      const StdString& attname = *it; 
    328       if (attname.compare(name) == 0) return true; 
     329      if (attname.compare(0, name.size(), name) == 0) return true; 
    329330    } 
    330331    return false; 
     
    339340    { 
    340341      const StdString& varname = *it; 
    341       if (varname.compare(name) == 0) return true; 
     342      if (varname.compare(0, name.size(), name) == 0) return true; 
    342343    } 
    343344    return false; 
     
    347348                                 const CVarPath* const path) 
    348349  { 
    349     return this->hasAttribute("coordinates", &name, path); 
     350    return this->hasAttribute(CCFKeywords::XIOS_CF_coordinates, &name, path); 
    350351  } 
    351352 
     
    353354                            const CVarPath* const path) 
    354355  { 
    355     return this->hasAttribute("bounds", &name, path); 
     356    return this->hasAttribute(CCFKeywords::XIOS_CF_bounds, &name, path); 
    356357  } 
    357358 
     
    441442  { 
    442443    StdString retvalue; 
    443     if (this->hasAttribute("coordinates", &name, path)) 
    444     { 
    445       return this->getAttributeValue("coordinates", &name, path); 
     444    if (this->hasAttribute(CCFKeywords::XIOS_CF_coordinates, &name, path)) 
     445    { 
     446      return this->getAttributeValue(CCFKeywords::XIOS_CF_coordinates, &name, path); 
    446447    } 
    447448    else 
     
    464465  { 
    465466    StdString retvalue; 
    466     if (this->hasAttribute("bounds", &name, path)) 
    467       retvalue = this->getAttributeValue("bounds", &name, path); 
     467    if (this->hasAttribute(CCFKeywords::XIOS_CF_bounds, &name, path)) 
     468      retvalue = this->getAttributeValue(CCFKeywords::XIOS_CF_bounds, &name, path); 
    468469    return retvalue; 
    469470  } 
     
    509510      return false; 
    510511 
     512    bool isCurVi = true; 
     513    unsigned int nbLonLat = 0; 
    511514    std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    512515    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     
    514517    { 
    515518      const StdString& coord = *it; 
    516       if (this->hasVariable(coord, path)) 
     519      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path)) 
    517520      { 
    518521        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
    519         if (dimvar.size() != 2) return false; 
    520       } 
    521       else return false; 
    522     } 
    523     return true; 
     522        if (2 == dimvar.size()) ++nbLonLat; 
     523      } 
     524    } 
     525    if (2 != nbLonLat) isCurVi = false; 
     526 
     527    return isCurVi; 
    524528  } 
    525529 
     
    538542    { 
    539543      const StdString& coord = *it; 
    540       if (this->hasVariable(coord, path)) 
     544      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path)) 
    541545      { 
    542546        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
     
    581585      else 
    582586      { 
    583         if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
     587        StdString unlimitedDimName = this->getUnlimitedDimensionName(); 
     588        if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0) 
    584589          continue; 
    585590        i++; 
     
    612617        else 
    613618        { 
    614           if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
     619          StdString unlimitedDimName = this->getUnlimitedDimensionName(); 
     620          if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0) 
    615621            continue; 
    616622          return false; 
     
    712718                          const CVarPath* const path, StdSize record); 
    713719 
    714   template <> 
    715   void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var, 
    716                           bool collective, StdSize record, 
    717                           const std::vector<StdSize>* start /*= NULL*/, 
    718                           const std::vector<StdSize>* count /*= NULL*/) 
    719   { 
    720     int varid = this->getVariable(var); 
    721  
    722     if (this->mpi && collective) 
    723       CNetCdfInterface::varParAccess(ncidp, varid, NC_COLLECTIVE); 
    724     else if (this->mpi && !collective) 
    725       CNetCdfInterface::varParAccess(ncidp, varid, NC_INDEPENDENT); 
    726  
    727     std::vector<StdSize> sstart, scount; 
    728     StdSize array_size = 1; 
    729     this->getDataInfo(var, NULL, record, sstart, scount, array_size, start, count); 
    730  
    731     if (data.numElements() != array_size) 
    732     { 
    733       ERROR("CONetCDF4::getData(...)", 
    734             << "[ Array size = " << data.numElements() 
    735             << ", Data size = "  << array_size 
    736             << " ] Invalid array size"); 
    737     } 
    738  
    739     CNetCdfInterface::getVaraType(ncidp, varid, &sstart[0], &scount[0], data.dataFirst()); 
    740   } 
    741  
    742720  //--------------------------------------------------------------- 
    743721 
     
    745723                                       const CVarPath* const path) 
    746724  { 
     725    std::list<StdString>::const_iterator itbList, itList, iteList; 
    747726    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
    748     if (this->hasCoordinates(varname, path)) 
    749       return *clist.begin(); 
    750     else 
    751       return *clist.rbegin(); 
     727    itbList = clist.begin(); iteList = clist.end(); 
     728    for (itList = itbList; itList != iteList; ++itList) 
     729    { 
     730      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path)) 
     731      { 
     732        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path); 
     733        if (CCFConvention::XIOS_CF_Longitude_units.end() != CCFConvention::XIOS_CF_Longitude_units.find(unit)) 
     734          return *itList; 
     735      } 
     736    } 
    752737  } 
    753738 
     
    755740                                       const CVarPath* const path) 
    756741  { 
     742    std::list<StdString>::const_iterator itbList, itList, iteList; 
    757743    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
    758     if (this->hasCoordinates(varname, path)) 
    759       return *(++clist.begin()); 
    760     else 
    761       return *(++clist.rbegin()); 
     744    itbList = clist.begin(); iteList = clist.end(); 
     745    for (itList = itbList; itList != iteList; ++itList) 
     746    { 
     747      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path)) 
     748      { 
     749        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path); 
     750        if (CCFConvention::XIOS_CF_Latitude_units.end() != CCFConvention::XIOS_CF_Latitude_units.find(unit)) 
     751          return *itList; 
     752      } 
     753    } 
    762754  } 
    763755 
  • XIOS/trunk/src/io/inetcdf4.hpp

    r686 r782  
    9898                   StdSize record = UNLIMITED_DIM); 
    9999 
    100       template <class T> 
    101       void getData(CArray<T, 1>& data, const StdString& var, 
     100      template <class T, int Ndim> 
     101      void getData(CArray<T, Ndim>& data, const StdString& var, 
    102102                   bool collective, StdSize record, 
    103103                   const std::vector<StdSize>* start = NULL, 
  • XIOS/trunk/src/io/nc4_data_input.cpp

    r777 r782  
    202202    \param [in] dimSizeMap Dimensions and and their corresponding names and size read from file 
    203203    \param [in] emelentPosition position of domain in grid 
     204    \param [in] fieldId id (or name) associated with the grid 
    204205  */ 
    205206  void CNc4DataInput::readDomainAttributeValueFromFile(CDomain* domain, std::map<StdString, StdSize>& dimSizeMap, 
     
    227228    else if (this->isCurvilinear(fieldId)) 
    228229    { 
    229  
     230      int ni = domain->ni; 
     231      int nj = domain->nj; 
     232      std::vector<StdSize> nBeginLatLon(2), nSizeLatLon(2); 
     233      nBeginLatLon[0] = domain->jbegin.getValue(); nBeginLatLon[1] = domain->ibegin.getValue(); 
     234      nSizeLatLon[0]  = nj; nSizeLatLon[1] = ni; 
     235 
     236      StdString latName = this->getLatCoordName(fieldId); 
     237      domain->latvalue_2d.resize(ni,nj); 
     238      readFieldVariableValue(domain->latvalue_2d, latName, nBeginLatLon, nSizeLatLon); 
     239      StdString lonName = this->getLonCoordName(fieldId); 
     240      domain->lonvalue_2d.resize(ni,nj); 
     241      readFieldVariableValue(domain->lonvalue_2d, lonName, nBeginLatLon, nSizeLatLon); 
     242 
     243      StdString boundsLatName = this->getBoundsId(latName); 
     244      if (0 == boundsLatName.compare("")) 
     245         ERROR("CNc4DataInput::readDomainAttributeValueFromFile(...)", 
     246              << "Field '" << fieldId << std::endl 
     247              << "Trying to read attributes from curvilinear grid." 
     248              << "Latitude variable " << latName << " does not have bounds."); 
     249      StdString boundsLonName = this->getBoundsId(lonName); 
     250      if (0 == boundsLonName.compare("")) 
     251         ERROR("CNc4DataInput::readDomainAttributeValueFromFile(...)", 
     252              << "Field '" << fieldId << std::endl 
     253              << "Trying to read attributes from curvilinear grid." 
     254              << "Longitude variable " << lonName << " does not have bounds."); 
     255 
     256      domain->nvertex.setValue(4); 
     257      std::vector<StdSize> nBeginBndsLatLon(3), nSizeBndsLatLon(3); 
     258      nBeginBndsLatLon[0] = domain->jbegin.getValue(); nSizeBndsLatLon[0] = nj; 
     259      nBeginBndsLatLon[1] = domain->ibegin.getValue(); nSizeBndsLatLon[1] = ni; 
     260      nBeginBndsLatLon[2] = 0; nSizeBndsLatLon[2] = 4; 
     261 
     262      domain->bounds_lat_2d.resize(4,ni,nj); 
     263      readFieldVariableValue(domain->bounds_lat_2d, boundsLatName, nBeginBndsLatLon, nSizeBndsLatLon); 
     264      domain->bounds_lon_2d.resize(4,ni,nj); 
     265      readFieldVariableValue(domain->bounds_lon_2d, boundsLonName, nBeginBndsLatLon, nSizeBndsLatLon); 
    230266    } 
    231267    else if (this->isUnstructured(fieldId)) 
     
    236272 
    237273  /*! 
    238     Read attributes of a domain from a file 
     274    Read attribute value of a domain from a file 
    239275    \param [in] domain domain whose attributes are read from the file 
    240276    \param [in] dimSizeMap Dimensions and and their corresponding names and size read from file 
    241277    \param [in] emelentPosition position of domain in grid 
     278    \param [in] fieldId id (or name) associated with the grid 
    242279  */ 
    243280  void CNc4DataInput::readDomainAttributesFromFile(CDomain* domain, std::map<StdString, StdSize>& dimSizeMap, 
     
    251288    itMapNi = itMapNj; ++itMapNi; 
    252289 
    253     if (this->isRectilinear(fieldId)) 
     290    if (this->isRectilinear(fieldId) || this->isCurvilinear(fieldId)) 
    254291    { 
    255292      domain->nj_glo.setValue(itMapNj->second); 
    256293      domain->ni_glo.setValue((itMapNi)->second); 
    257     } 
    258     else if (this->isCurvilinear(fieldId)) 
    259     { 
    260  
    261294    } 
    262295    else if (this->isUnstructured(fieldId)) 
     
    271304    \param [in] dimSizeMap Dimensions and and their corresponding names and size read from file 
    272305    \param [in] emelentPosition position of axis in grid 
     306    \param [in] fieldId id (or name) associated with the grid 
    273307  */ 
    274308  void CNc4DataInput::readAxisAttributesFromFile(CAxis* axis, std::map<StdString, StdSize>& dimSizeMap, 
     
    282316 
    283317  /*! 
    284     Read attributes of an axis from a file 
     318    Read attribute value of an axis from a file 
    285319    \param [in] axis axis whose attributes are read from the file 
    286320    \param [in] dimSizeMap Dimensions and and their corresponding names and size read from file 
    287321    \param [in] emelentPosition position of axis in grid 
     322    \param [in] fieldId id (or name) associated with the grid 
    288323  */ 
    289324  void CNc4DataInput::readAxisAttributeValueFromFile(CAxis* axis, std::map<StdString, StdSize>& dimSizeMap, 
     
    306341  } 
    307342 
    308   void CNc4DataInput::readFieldVariableValue(CArray<double,1>& var, const StdString& varId, 
    309                                              const std::vector<StdSize>& nBegin, 
    310                                              const std::vector<StdSize>& nSize, 
    311                                              bool forceIndependent) 
    312   { 
    313     if (SuperClass::type==MULTI_FILE || !isCollective) return; 
    314  
    315     bool openCollective = isCollective; 
    316     if (forceIndependent) openCollective = !isCollective; 
    317     switch (SuperClass::type) 
    318     { 
    319       case MULTI_FILE: 
    320         SuperClassWriter::getData(var, varId, openCollective, 0); 
    321         break; 
    322       case ONE_FILE: 
    323       { 
    324         SuperClassWriter::getData(var, varId, openCollective, 0, &nBegin, &nSize); 
    325         break; 
    326       } 
    327     } 
    328   } 
    329  
    330343  void CNc4DataInput::closeFile_(void) 
    331344  { 
  • XIOS/trunk/src/io/nc4_data_input.hpp

    r775 r782  
    5050                                        int elementPosition, const StdString& fieldId); 
    5151 
    52     void readFieldVariableValue(CArray<double,1>& var, const StdString& varId, 
     52    template <typename T, int Ndim> 
     53    void readFieldVariableValue(CArray<T, Ndim>& var, const StdString& varId, 
    5354                                const std::vector<StdSize>& nBegin, 
    5455                                const std::vector<StdSize>& nSize, 
     
    6566    bool isCollective; 
    6667  }; // class CNc4DataInput 
     68 
     69template <typename T, int Ndim> 
     70void CNc4DataInput::readFieldVariableValue(CArray<T,Ndim>& var, const StdString& varId, 
     71                                           const std::vector<StdSize>& nBegin, 
     72                                           const std::vector<StdSize>& nSize, 
     73                                           bool forceIndependent) 
     74{ 
     75  if (SuperClass::type==MULTI_FILE || !isCollective) return; 
     76 
     77  bool openCollective = isCollective; 
     78  if (forceIndependent) openCollective = !isCollective; 
     79  switch (SuperClass::type) 
     80  { 
     81    case MULTI_FILE: 
     82      ERROR("CINetCDF4::readFieldVariableValue(...)", 
     83            << "Only support attributes reading with one_file mode"); 
     84      break; 
     85    case ONE_FILE: 
     86    { 
     87      SuperClassWriter::getData(var, varId, openCollective, 0, &nBegin, &nSize); 
     88      break; 
     89    } 
     90  } 
     91} 
    6792} // namespace xios 
    6893 
  • XIOS/trunk/src/io/netCdfInterface.cpp

    r686 r782  
    603603int CNetCdfInterface::inqAttName(int ncid, int varid, int attnum, StdString& name) 
    604604{ 
    605   char attName[NC_MAX_NAME + 1]; 
    606   int status = nc_inq_attname(ncid, varid, attnum, attName); 
     605  std::vector<char> attName(NC_MAX_NAME + 1,' '); 
     606  int status = nc_inq_attname(ncid, varid, attnum, &attName[0]); 
    607607  if (NC_NOERR != status) 
    608608  { 
     
    616616    throw CNetCdfException(e); 
    617617  } 
     618 
     619  int nameSize = 0; 
     620  while ((nameSize < NC_MAX_NAME) && (' ' != attName[nameSize] )) ++nameSize; 
     621  name.resize(nameSize); 
     622//  for (int idx = 0; idx < nameSize; ++idx) name.at(idx) = attName[idx]; 
     623  std::copy(&attName[0], &attName[nameSize-1], name.begin()); 
    618624 
    619625  return status; 
Note: See TracChangeset for help on using the changeset viewer.