XMLIOSERVER 0.4
Serveur d'Entrées/Sorties parallèles
inetcdf4_adv.cpp
Aller à la documentation de ce fichier.
00001 /* ************************************************************************** *
00002  *      Copyright © IPSL/LSCE, XMLIOServer, Avril 2010 - Octobre 2011         *
00003  * ************************************************************************** */
00004 
00013 #ifndef __XIOS_NO_EXTERN
00014 
00015 // Boost headers
00016 #include <boost/algorithm/string.hpp>
00017 
00018 #endif // __XIOS_NO_EXTERN
00019 
00020 // XMLIOServer headers
00021 #include "inetcdf4_adv.hpp"
00022 #include "inetcdf4_adv_impl.hpp"
00023 
00024 
00025 // /////////////////////////////// Définitions ////////////////////////////// //
00026 
00027 namespace xmlioserver {
00028 namespace io {
00029     
00030    CINetCDF4Adv::CINetCDF4Adv(const std::string & filename)
00031         : CINetCDF4(filename)
00032    { /* Ne rien faire de plus */ }
00033 
00034    CINetCDF4Adv::~CINetCDF4Adv(void)
00035    { /* Ne rien faire de plus */ }
00036    
00037    bool CINetCDF4Adv::hasAttribute(const std::string & name,
00038                                    const std::string * const _varname)
00039    {
00040       std::vector<std::string > atts = this->getAttributes(_varname);
00041       std::vector<std::string >::const_iterator it = atts.begin(), end = atts.end();
00042       for (; it != end; it++)
00043       {
00044          const std::string  & attname = *it;
00045          if (attname.compare(name) == 0) return (true);
00046       }
00047       return (false);
00048    }
00049    
00050    bool CINetCDF4Adv::hasVariable    (const std::string & _varname)
00051    {
00052        return (SuperClass::varExist(_varname));
00053    }
00054    
00055    bool CINetCDF4Adv::hasMissingValue(const std::string & _varname)
00056    {
00057       return (this->hasAttribute("missing_value", &_varname) ||
00058               this->hasAttribute("_FillValue", &_varname));
00059    }
00060    
00061    bool CINetCDF4Adv::hasCoordinates (const std::string & _varname)
00062    {
00063       return (this->hasAttribute("coordinates", &_varname));
00064    }
00065    
00066    bool CINetCDF4Adv::hasBounds      (const std::string & _varname)
00067    {
00068       return (this->hasAttribute("bounds", &_varname));
00069    }
00070 
00071    bool CINetCDF4Adv::hasTemporalDim(void)
00072    {
00073       return (this->getUnlimitedDimension() != -1);
00074    }
00075 
00076    bool CINetCDF4Adv::isBound(const std::string & _varname)
00077    {
00078       std::set<std::string> bounds = this->getBoundVariables();
00079       return (bounds.find(_varname) != bounds.end());
00080    }
00081    
00082    bool CINetCDF4Adv::isCoordinate(const std::string & _varname)
00083    {
00084       std::set<std::string> coords = this->getCoordVariables();
00085       return (coords.find(_varname) != coords.end());
00086    }
00087    
00088    bool CINetCDF4Adv::isRectilinear(const std::string & _varname)
00089    {
00090       std::vector<std::string> coords = this->getCoordinatesIdList(_varname);
00091       std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00092       for (; it != end; it++)
00093       {
00094          const std::string & coord = *it;
00095          if (this->hasVariable(coord) && !this->isTemporal(coord))
00096          {
00097             std::map<std::string, std::size_t> dimvar = this->getDimensions(&coord);
00098             if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end()))
00099                continue;
00100             else
00101                return (false);
00102          }
00103       }
00104       return (true);
00105    }
00106    
00107    bool CINetCDF4Adv::isCurvilinear(const std::string & _varname)
00108    {
00109       if (this->isRectilinear(_varname) ||
00110          !this->hasCoordinates(_varname))
00111          return (false);
00112 
00113       std::vector<std::string> coords = this->getCoordinatesIdList(_varname);
00114       std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00115       for (; it != end; it++)
00116       {
00117          const std::string & coord = *it;
00118          if (this->hasVariable(coord))
00119          {
00120             std::map<std::string, std::size_t> dimvar = this->getDimensions(&coord);
00121             if (dimvar.size() != 2) return (false);
00122          }
00123          else return (false);
00124       }
00125       return (true);
00126    }
00127    
00128    bool CINetCDF4Adv::isUnknown(const std::string & _varname)
00129    {
00130       return !(this->isRectilinear(_varname) ||
00131                this->isCurvilinear(_varname) ||
00132                this->isUnstructured(_varname));
00133    }
00134    
00135    bool CINetCDF4Adv::isUnstructured(const std::string & _varname)
00136    {
00137       if (this->isRectilinear(_varname)    ||
00138           this->isCurvilinear(_varname)    ||
00139          !this->hasCoordinates(_varname))
00140           return (false);
00141 
00142       std::string dimname = this->getDimensionsIdList(&_varname).back();
00143 
00144       std::vector<std::string> coords = this->getCoordinatesIdList(_varname);
00145       std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00146       for (; it != end; it++)
00147       {
00148          const std::string & coord = *it;
00149          if (this->hasVariable(coord))
00150          {
00151             std::map<std::string, std::size_t> dimvar = this->getDimensions(&coord);
00152             if ((dimvar.size() == 1) &&
00153                 (dimvar.find(dimname) != dimvar.end()))
00154                continue;
00155             else
00156                return (false);
00157          }
00158             else return (false);
00159       }
00160 
00161       return (true);
00162    }
00163    
00164    bool CINetCDF4Adv::isTemporal(const std::string & _varname)
00165    {
00166       if (!this->hasTemporalDim()) return (false);
00167       std::map<std::string, std::size_t> dims = this->getDimensions(&_varname);
00168       if (dims.find(this->getUnlimitedDimensionName()) != dims.end())
00169          return (true);
00170       return (false);
00171    }
00172    
00173    bool CINetCDF4Adv::is3Dim(const std::string & _varname)
00174    {
00175       int i = 0;
00176       std::vector<std::string> coords = this->getCoordinatesIdList(_varname);
00177       std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00178       for (; it != end; it++)
00179       {
00180          const std::string & coord = *it;
00181          if (this->hasVariable(coord))
00182          {
00183             if (this->isTemporal(coord))
00184                continue;
00185             i++;
00186          }
00187          else
00188          {
00189             if (coord.compare(this->getUnlimitedDimensionName()) == 0)
00190                continue;
00191             i++;
00192          }
00193       }
00194       return (i == 3);
00195    }
00196    
00197    bool CINetCDF4Adv::isCellGrid(const std::string & _varname)
00198    {
00199       if (this->isCoordinate(_varname))
00200       {
00201          return (this->hasBounds(_varname));
00202       }
00203       else
00204       {
00205          std::vector<std::string> coords = this->getCoordinatesIdList(_varname);
00206          std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00207          for (; it != end; it++)
00208          {
00209             const std::string & coord = *it;
00210             if (this->hasVariable(coord))
00211             {
00212                if (this->isTemporal(coord))
00213                   continue;
00214                if (this->isCellGrid(coord))
00215                   continue;
00216                return (false);
00217             }
00218             else
00219             {
00220                if (coord.compare(this->getUnlimitedDimensionName()) == 0)
00221                   continue;
00222                return (false);
00223             }
00224          }
00225       }
00226 
00227       return (true);
00228    }
00229    
00230    std::size_t CINetCDF4Adv::getNbVertex(const std::string & _varname)
00231    {
00232       if (this->isRectilinear(_varname) ||
00233           this->isCurvilinear(_varname))
00234       {
00235          if (this->is3Dim(_varname)) return (8);
00236          else return (4);
00237       }
00238       if (this->isUnstructured(_varname))
00239       {
00240          std::string bound = this->getBoundsId
00241                   (this->getCoordinatesIdList(_varname).back());
00242          std::string dim = this->getDimensionsIdList(&bound).back();
00243          return (this->getDimensions(&bound)[dim]);
00244       }
00245       return ((size_t)(-1));
00246    }
00247              
00248    std::set<std::string> CINetCDF4Adv::getCoordVariables(void)
00249    {
00250       std::set<std::string> retvalue;
00251       std::vector<std::string> variables = this->getVariables();
00252       std::vector<std::string>::const_iterator it = variables.begin(), end = variables.end();
00253       for (; it != end; it++)
00254       {
00255          const std::string & var = *it;
00256          std::vector<std::string> coords = this->getCoordinatesIdList(var);
00257          std::vector<std::string>::const_iterator it = coords.begin(), end = coords.end();
00258          for (; it != end; it++)
00259          {
00260             const std::string & coord = *it;
00261             if (this->hasVariable(coord))
00262                retvalue.insert(retvalue.end(), coord);
00263          }
00264       }
00265       return (retvalue);
00266    }
00267    
00268    std::set<std::string> CINetCDF4Adv::getBoundVariables(void)
00269    {
00270       std::set<std::string> retvalue;         
00271       std::vector<std::string> variables = this->getVariables();
00272       std::vector<std::string>::const_iterator it = variables.begin(), end = variables.end();
00273       for (; it != end; it++)
00274       {
00275          const std::string & var = *it;
00276          if (this->hasBounds(var))
00277             retvalue.insert(retvalue.end(), this->getBoundsId(var));
00278       }
00279       return (retvalue);
00280    }
00281             
00282    std::string CINetCDF4Adv::getCoordinatesId(const std::string & _varname)
00283    {
00284          std::string retvalue;
00285          if (this->hasAttribute("coordinates", &_varname))
00286          {
00287             this->readAttribute("coordinates", retvalue, &_varname);
00288             return (retvalue);
00289          }
00290          else
00291          {
00292             std::vector<std::string> dims = this->getDimensionsIdList(&_varname);
00293             std::vector<std::string>::const_iterator it = dims.begin(), end = dims.end();
00294             for (; it != end; it++)
00295             {
00296                const std::string & value = *it;               
00297                retvalue.append(value).push_back(' ');
00298             }
00299             retvalue.erase (retvalue.end()-1) ;
00300          }
00301 
00302          return (retvalue);
00303    }
00304    
00305    std::string CINetCDF4Adv::getBoundsId (const std::string & _varname)
00306    {
00307       std::string retvalue;
00308       if (this->hasAttribute("bounds", &_varname))
00309             this->readAttribute("bounds", retvalue, &_varname);
00310 
00311       return (retvalue);
00312    }
00313            
00314             
00315    std::vector<std::string> CINetCDF4Adv::getCoordinatesIdList(const std::string & _varname)
00316    {
00317       std::vector<std::string> retvalue;
00318       std::string value = this->getCoordinatesId(_varname);
00319          
00320       boost::split(retvalue, value, boost::is_any_of(" "));
00321          
00322       std::vector<std::string>::iterator it = retvalue.begin(), end = retvalue.end();
00323       for (; it != end; it++)
00324       {
00325          std::string & coord = *it;
00326          coord.assign(coord.data());
00327       }
00328       return (retvalue);
00329    }
00330    
00331    std::vector<std::string> CINetCDF4Adv::getDataVariables
00332         (bool _is3D, bool _isRecti, bool _isCurvi, bool _isUnstr, bool _isCellData, bool _isTemporal)
00333    {
00334       std::vector<std::string> retvalue;
00335       std::vector<std::string> allvars  = this->getVariables();
00336 
00337       std::vector<std::string>::const_iterator it = allvars.begin(), end = allvars.end();
00338       for (; it != end; it++)
00339       {
00340          const std::string & var = *it;
00341          if (this->isCoordinate(var)) continue;
00342 
00343          if (!_isRecti && this->isRectilinear(var) ) continue;
00344          if (!_isCurvi && this->isCurvilinear(var) ) continue;
00345          if (!_isUnstr && this->isUnstructured(var)) continue;
00346 
00347          if (!_isTemporal && this->isTemporal(var)) continue;
00348          if (!_is3D       && this->is3Dim(var)    ) continue;
00349          if (!_isCellData && this->isCellGrid(var)) continue;
00350 
00351          if (this->isUnknown(var)) continue;
00352 
00353          retvalue.push_back(var);
00354       }
00355       return (retvalue);
00356     }
00357    
00358     std::string CINetCDF4Adv::getLonCoordName (const std::string & _varname)
00359     {
00360        std::vector<std::string> clist = this->getCoordinatesIdList(_varname);
00361        std::vector<std::string>::const_iterator it = clist.begin(), end = clist.end();
00362        if (this->hasCoordinates(_varname))
00363        {
00364           for (; it != end; it++)
00365           {
00366               const std::string & var = *it;
00367               if (this->hasVariable(var) && this->hasAttribute("axis", &var))
00368               {
00369                   std::string axis_name;
00370                   this->readAttribute("axis", axis_name, &var);
00371                   if (axis_name.compare("X") == 0)
00372                       return (var);
00373               }
00374           }
00375           return (*clist.begin());
00376        }
00377        else
00378           return (*clist.rbegin());
00379     }
00380             
00381     std::string CINetCDF4Adv::getLatCoordName (const std::string & _varname)
00382     {
00383        std::vector<std::string> clist = this->getCoordinatesIdList(_varname);
00384        std::vector<std::string>::const_iterator it = clist.begin(), end = clist.end();
00385        if (this->hasCoordinates(_varname))
00386        {
00387           for (; it != end; it++)
00388           {
00389               const std::string & var = *it;
00390               if (this->hasVariable(var) && this->hasAttribute("axis", &var))
00391               {
00392                   std::string axis_name;
00393                   this->readAttribute("axis", axis_name, &var);
00394                   if (axis_name.compare("Y") == 0)
00395                       return (var);
00396               }
00397           }
00398           return (*(++clist.begin()));
00399        }
00400        else
00401           return (*(++clist.rbegin()));
00402     }
00403             
00404     std::string CINetCDF4Adv::getVertCoordName(const std::string & _varname)
00405     {
00406        if (!this->is3Dim(_varname)) return (std::string());
00407        std::vector<std::string> clist = this->getCoordinatesIdList(_varname);
00408        std::vector<std::string>::const_iterator it = clist.begin(), end = clist.end();
00409        if (this->hasCoordinates(_varname))
00410        {
00411           for (; it != end; it++)
00412           {
00413               const std::string & var = *it;
00414               if (this->hasVariable(var) && this->hasAttribute("axis", &var))
00415               {
00416                   std::string axis_name;
00417                   this->readAttribute("axis", axis_name, &var);
00418                   if (axis_name.compare("Z") == 0)
00419                       return (var);
00420               }
00421           }
00422           return (*(++(++clist.begin())));
00423        }
00424        else
00425           return (*(++(++clist.rbegin())));
00426     }
00427     
00428    std::string CINetCDF4Adv::getTimeCoordName(const std::string & _varname)
00429    {
00430       if (!this->isTemporal(_varname)) return (std::string());
00431        std::vector<std::string> clist = this->getCoordinatesIdList(_varname);
00432        std::vector<std::string>::const_iterator it = clist.begin(), end = clist.end();
00433        if (this->hasCoordinates(_varname))
00434        {
00435           for (; it != end; it++)
00436           {
00437               const std::string & var = *it;
00438               if (this->hasVariable(var) && this->hasAttribute("standard_name", &var))
00439               {
00440                   std::string time_name;
00441                   this->readAttribute("standard_name", time_name, &var);
00442                   if (time_name.compare("time") == 0)
00443                       return (var);
00444               }
00445           }
00446           return (this->getUnlimitedDimensionName());
00447        }
00448        else
00449           return (*(clist.begin()));
00450    }
00451    
00452    
00453 } // namespace io
00454 } // namespace xmlioserver
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Définition de type Énumérations Valeurs énumérées Amis Macros