XMLIOSERVER 0.4
Serveur d'Entrées/Sorties parallèles
|
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