Changeset 599


Ignore:
Timestamp:
05/26/15 16:13:48 (9 years ago)
Author:
rlacroix
Message:

Implement reading fields from NetCDF files.

Location:
XIOS/trunk/src
Files:
12 edited

Legend:

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

    r501 r599  
    11#include "inetcdf4.hpp" 
     2#include "netCdfInterface.hpp" 
    23 
    34#include <boost/algorithm/string.hpp> 
     
    56namespace xios 
    67{ 
    7       /// ////////////////////// Définitions ////////////////////// /// 
    8       CINetCDF4::CINetCDF4(const StdString & filename) 
    9       { 
    10          CheckError(nc_open(filename.c_str(), NC_NOWRITE, &this->ncidp)); 
    11       } 
    12  
    13       CINetCDF4::~CINetCDF4(void) 
    14       { 
    15           CheckError(nc_close(this->ncidp)); 
    16       } 
    17  
    18       ///-------------------------------------------------------------- 
    19  
    20       void CINetCDF4::CheckError(int status) 
    21       { 
    22          if (status != NC_NOERR) 
    23          { 
    24             StdString errormsg (nc_strerror(status)); // fuite mémoire ici ? 
    25             ERROR("CINetCDF4::CheckError(int status)", 
    26                   << "[ status = " << status << " ] " << errormsg); 
    27          } 
    28       } 
    29  
    30       //--------------------------------------------------------------- 
    31  
    32       int CINetCDF4::getGroup(const CVarPath * const path) 
    33       { 
    34          int retvalue = this->ncidp; 
    35          if (path == NULL) return (retvalue); 
    36          CVarPath::const_iterator it = path->begin(), end = path->end(); 
    37           
    38          for (; it != end; it++) 
    39          { 
    40             const StdString & groupid = *it; 
    41             CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue)); 
    42          }        
    43              
    44          return (retvalue); 
    45       } 
    46  
    47       int CINetCDF4::getVariable(const StdString & varname, 
    48                                  const CVarPath * const path) 
    49       { 
    50          int varid = 0; 
    51          int grpid = this->getGroup(path); 
    52          CheckError(nc_inq_varid (grpid, varname.c_str(), &varid)); 
    53          return (varid); 
    54       } 
    55  
    56       int CINetCDF4::getDimension(const StdString & dimname, 
    57                                   const CVarPath  * const path) 
    58       { 
    59          int dimid = 0; 
    60          int grpid = this->getGroup(path); 
    61          CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid)); 
    62          return (dimid); 
    63       } 
    64  
    65       std::pair<nc_type, StdSize> CINetCDF4::getAttribute 
    66                                  (const StdString & attname, 
    67                                   const StdString * const var, 
    68                                   const CVarPath  * const path) 
    69       { 
    70          std::pair<nc_type, StdSize> retvalue; 
    71          int grpid = this->getGroup(path); 
    72          int varid = (var != NULL) 
    73                    ? this->getVariable(*var, path) : NC_GLOBAL; 
    74          CheckError(nc_inq_att(grpid, varid, attname.c_str(), 
    75                               &retvalue.first, &retvalue.second)); 
    76          return (retvalue); 
    77       } 
    78  
    79       int CINetCDF4::getUnlimitedDimension(const CVarPath  * const path) 
    80       { 
    81          int dimid = 0; 
    82          int grpid = this->getGroup(path); 
    83          CheckError(nc_inq_unlimdim (grpid, &dimid)); 
    84          return (dimid); 
    85       } 
    86  
    87       StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath  * const path) 
    88       { 
    89          char full_name_in[NC_MAX_NAME +1]; 
    90          int grpid = this->getGroup(path); 
    91          int dimid = this->getUnlimitedDimension(path); 
    92          CheckError(nc_inq_dimname(grpid, dimid, full_name_in)); 
    93  
    94          StdString dimname(full_name_in); 
    95          return (dimname); 
    96       } 
    97  
    98       //--------------------------------------------------------------- 
    99       StdSize CINetCDF4::getNbVertex(const StdString & name, 
    100                                      const CVarPath  * const path) 
    101       { 
    102  
    103          if (this->isRectilinear(name, path) || 
    104              this->isCurvilinear(name, path)) 
    105          { 
    106             if (this->is3Dim(name, path)) return (8); 
    107             else return (4); 
    108          } 
    109          if (this->isUnstructured(name, path)) 
    110          { 
    111             StdString bound = this->getBoundsId 
    112                      (this->getCoordinatesIdList(name, path).back(), path); 
    113             StdString dim = this->getDimensionsList(&bound, path).back(); 
    114             return (this->getDimensions(&bound, path)[dim]); 
    115          } 
    116          return ((size_t)(-1)); 
    117       } 
    118  
    119       //--------------------------------------------------------------- 
    120  
    121       std::list<StdString> CINetCDF4::getGroups(const CVarPath * const path) 
    122       { 
    123          StdSize strlen = 0; 
    124          char full_name_in[NC_MAX_NAME +1]; 
    125          int nbgroup = 0, *groupid = NULL; 
    126          int grpid = this->getGroup(path); 
    127          std::list<StdString> retvalue; 
    128  
    129          CheckError(nc_inq_grps(grpid, &nbgroup, NULL)); 
    130          groupid = new int[nbgroup](); 
    131          CheckError(nc_inq_grps(grpid, NULL, groupid)); 
    132  
    133          for (int i = 0; i < nbgroup; i++) 
    134          { 
    135             CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in)); 
    136             StdString groupname(full_name_in, strlen); 
    137             retvalue.push_back(groupname); 
    138          } 
    139  
    140          delete [] groupid; 
    141          return (retvalue); 
    142       } 
    143  
    144       std::list<StdString> CINetCDF4::getVariables(const CVarPath * const path) 
    145       { 
    146          char full_name_in[NC_MAX_NAME +1]; 
    147          int nbvar = 0, *varid = NULL; 
    148          int grpid = this->getGroup(path); 
    149          std::list<StdString> retvalue; 
    150  
    151          CheckError(nc_inq_varids(grpid, &nbvar, NULL)); 
    152          varid = new int[nbvar](); 
    153          CheckError(nc_inq_varids(grpid, NULL, varid)); 
    154  
    155          for (int i = 0; i < nbvar; i++) 
    156          { 
    157             CheckError(nc_inq_varname(grpid, varid[i], full_name_in)); 
    158             StdString varname(full_name_in); 
    159             retvalue.push_back(varname); 
    160          } 
    161  
    162          delete [] varid; 
    163          return (retvalue); 
    164       } 
    165  
    166       StdSize CINetCDF4::getNbOfTimestep(const CVarPath * const path) 
    167       { 
    168          return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]); 
    169       } 
    170  
    171       std::set<StdString> CINetCDF4::getBoundVariables(const CVarPath * const path) 
    172       { 
    173          std::set<StdString> retvalue;          
    174          std::list<StdString> variables = this->getVariables(path); 
    175          std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
    176          for (; it != end; it++) 
    177          { 
    178             const StdString & var = *it; 
    179             if (this->hasBounds(var, path)) 
    180                retvalue.insert(retvalue.end(), this->getBoundsId(var, path)); 
    181          } 
    182          return (retvalue); 
    183       } 
    184  
    185       std::set<StdString> CINetCDF4::getCoordVariables(const CVarPath * const path) 
    186       { 
    187          std::set<StdString> retvalue; 
    188          std::list<StdString> variables = this->getVariables(path); 
    189          std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
    190          for (; it != end; it++) 
    191          { 
    192             const StdString & var = *it; 
    193             std::list<StdString> coords = this->getCoordinatesIdList(var, path); 
    194             std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    195             for (; it != end; it++) 
    196             { 
    197                const StdString & coord = *it; 
    198                if (this->hasVariable(coord, path)) 
    199                   retvalue.insert(retvalue.end(), coord); 
    200             } 
    201          } 
    202          return (retvalue); 
    203       } 
    204  
    205       std::list<StdString> CINetCDF4::getDimensionsList 
    206                   (const StdString * const var, const CVarPath  * const path) 
    207       { 
    208          char full_name_in[NC_MAX_NAME +1]; 
    209          int nbdim = 0, *dimid = NULL; 
    210          int grpid = this->getGroup(path); 
    211          int varid = (var != NULL) 
    212                    ? this->getVariable(*var, path) : NC_GLOBAL; 
    213          std::list<StdString> retvalue; 
    214  
    215          if (var != NULL) 
    216          { 
    217             CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
    218             dimid = new int[nbdim](); 
    219             CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
    220          } 
    221          else 
    222          { 
    223             CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
    224             dimid = new int[nbdim](); 
    225             CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
    226          } 
    227  
    228          for (int i = 0; i < nbdim; i++) 
    229          { 
    230             CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); 
    231             StdString dimname(full_name_in); 
    232             retvalue.push_back(dimname); 
    233          } 
    234          delete [] dimid; 
    235  
    236          return (retvalue); 
    237       } 
    238  
    239       std::map<StdString, StdSize> CINetCDF4::getDimensions 
    240                   (const StdString * const var, const CVarPath  * const path) 
    241       { 
    242          StdSize size = 0; 
    243          char full_name_in[NC_MAX_NAME +1]; 
    244          int nbdim = 0, *dimid = NULL; 
    245          int grpid = this->getGroup(path); 
    246          int varid = (var != NULL) 
    247                    ? this->getVariable(*var, path) : NC_GLOBAL; 
    248          std::map<StdString, StdSize> retvalue; 
    249  
    250          if (var != NULL) 
    251          { 
    252             CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
    253             dimid = new int[nbdim](); 
    254             CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
    255          } 
    256          else 
    257          { 
    258             CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
    259             dimid = new int[nbdim](); 
    260             CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
    261          } 
    262  
    263          for (int i = 0; i < nbdim; i++) 
    264          { 
    265             CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); 
    266             CheckError(nc_inq_dimlen (grpid, dimid[i], &size)); 
    267  
    268             StdString dimname(full_name_in); 
    269             retvalue.insert(retvalue.end(), std::make_pair(dimname, size)); 
    270          } 
    271          delete [] dimid; 
    272  
    273          return (retvalue); 
    274       } 
    275  
    276       std::list<StdString> CINetCDF4::getAttributes 
    277                (const StdString * const var, const CVarPath  * const path ) 
    278       { 
    279          int nbatt = 0; 
    280          char full_name_in[NC_MAX_NAME +1]; 
    281          std::list<StdString> retvalue; 
    282          int grpid = this->getGroup(path); 
    283          int varid = (var != NULL) 
    284                    ? this->getVariable(*var, path) : NC_GLOBAL; 
    285  
    286          if (var != NULL) 
    287             CheckError(nc_inq_varnatts (grpid, varid, &nbatt)); 
    288          else 
    289             CheckError(nc_inq_natts(grpid, &nbatt)); 
    290  
    291          for (int i = 0; i < nbatt; i++) 
    292          { 
    293             CheckError(nc_inq_attname(grpid, varid, i, full_name_in)); 
    294             StdString attname(full_name_in); 
    295             retvalue.push_back(attname); 
    296          } 
    297          return (retvalue); 
    298       } 
    299  
    300       int CINetCDF4::getAttributeId(const StdString & name, 
    301                                     const StdString * const var, 
    302                                     const CVarPath  * const path) 
    303       { 
    304          int retvalue = 0; 
    305          std::list<StdString> atts = this->getAttributes(var, path); 
    306          std::list<StdString>::const_iterator it = atts.begin(), end = atts.end(); 
    307          for (; it != end; it++) 
    308          { 
    309             const StdString & attname = *it; 
    310             if (attname.compare(name) == 0) 
    311                return (retvalue); 
    312             retvalue++; 
    313          } 
    314          return (-1); 
    315       } 
    316  
    317       //--------------------------------------------------------------- 
    318  
    319       bool CINetCDF4::hasMissingValue(const StdString & name, 
    320                                       const CVarPath  * const path) 
    321       { 
    322          return (this->hasAttribute("missing_value", &name, path) || 
    323                  this->hasAttribute("_FillValue", &name, path)); 
    324       } 
    325  
    326       bool CINetCDF4::hasAttribute(const StdString & name, 
    327                                    const StdString * const var , 
    328                                    const CVarPath  * const path) 
    329       { 
    330          std::list<StdString> atts = this->getAttributes(var, path); 
    331          std::list<StdString>::const_iterator it = atts.begin(), end = atts.end(); 
    332          for (; it != end; it++) 
    333          { 
    334             const StdString & attname = *it; 
    335             if (attname.compare(name) == 0) return (true); 
    336          } 
    337          return (false); 
    338       } 
    339  
    340       bool CINetCDF4::hasVariable(const StdString & name, 
    341                                   const CVarPath  * const path) 
    342       { 
    343          std::list<StdString> variables = this->getVariables(path); 
    344          std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
    345          for (; it != end; it++) 
    346          { 
    347             const StdString & varname = *it; 
    348             if (varname.compare(name) == 0) return (true); 
    349          } 
    350          return (false); 
    351       } 
    352  
    353       bool CINetCDF4::hasCoordinates(const StdString & name, 
    354                                      const CVarPath  * const path) 
    355       { 
    356          return (this->hasAttribute("coordinates", &name, path)); 
    357       } 
    358  
    359       bool CINetCDF4::hasBounds(const StdString & name, 
    360                                 const CVarPath  * const path) 
    361       { 
    362          return (this->hasAttribute("bounds", &name, path)); 
    363       } 
    364  
    365       bool CINetCDF4::hasTemporalDim(const CVarPath  * const path) 
    366       { 
    367          return (this->getUnlimitedDimension(path) != -1); 
    368       } 
    369  
    370       //--------------------------------------------------------------- 
    371  
    372 #define GET_ATTRIBUTE_VALUE(type, func_ext, type_enum)                     \ 
    373       template <>                                                          \ 
    374          std::vector<type> CINetCDF4::getAttributeValue                    \ 
    375             (const StdString & name, const StdString * const var,          \ 
    376                                      const CVarPath  * const path)         \ 
    377       {                                                                    \ 
    378          int grpid = this->getGroup(path);                                 \ 
    379          int varid = (var != NULL)                                         \ 
    380                    ? this->getVariable(*var, path) : NC_GLOBAL;            \ 
    381          std::pair<nc_type , StdSize> attinfos =                           \ 
    382                      this->getAttribute(name, var, path);                  \ 
    383          std::vector<type> retvalue(attinfos.second);                      \ 
    384          if (attinfos.first != type_enum)                                  \ 
    385             ERROR("CINetCDF4::getAttributeValue<double>(name, var, path",  \ 
    386                   << "[ name : "          << name                          \ 
    387                   << ", type requested :" << attinfos.first                \ 
    388                   << ", type stored : "   << type_enum      << "]"         \ 
    389                   << " Invalid type !");                                   \ 
    390          CheckError(nc_get_att_##func_ext                                  \ 
    391                         (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 <> 
    401          StdString CINetCDF4::getAttributeValue 
    402             (const StdString & name, const StdString * const var, 
    403                                      const CVarPath  * const path) 
    404       { 
    405          std::vector<char> chart = this->getAttributeValue 
    406                         <std::vector<char> >(name, var, path); 
    407          StdString retvalue(&(chart[0]), chart.size()); 
    408          return (retvalue); 
    409       } 
    410  
    411       template <> 
    412          int CINetCDF4::getMissingValue(const StdString & name, 
    413                                         const CVarPath  * const path) 
    414       { 
    415          if (this->hasAttribute("missing_value", &name, path)) 
    416             return (this->getAttributeValue<std::vector<int> >("missing_value", &name, path)[0]); 
    417          if (this->hasAttribute("_FillValue", &name, path)) 
    418             return (this->getAttributeValue<std::vector<int> >("_FillValue", &name, path)[0]); 
    419          return (0); 
    420       } 
    421  
    422       template <> 
    423          double CINetCDF4::getMissingValue(const StdString & name, 
    424                                            const CVarPath  * const path) 
    425       { 
    426          if (this->hasAttribute("missing_value", &name, path)) 
    427             return (this->getAttributeValue<std::vector<double> >("missing_value", &name, path)[0]); 
    428          if (this->hasAttribute("_FillValue", &name, path)) 
    429             return (this->getAttributeValue<std::vector<double> >("_FillValue", &name, path)[0]); 
    430          return (0); 
    431       } 
    432  
    433       template <> 
    434          float CINetCDF4::getMissingValue(const StdString & name, 
    435                                           const CVarPath  * const path) 
    436       { 
    437          if (this->hasAttribute("missing_value", &name, path)) 
    438             return (this->getAttributeValue<std::vector<float> >("missing_value", &name, path)[0]); 
    439          if (this->hasAttribute("_FillValue", &name, path)) 
    440             return (this->getAttributeValue<std::vector<float> >("_FillValue", &name, path)[0]); 
    441          return (0); 
    442       } 
    443        
    444       //--------------------------------------------------------------- 
    445        
    446       std::list<StdString> CINetCDF4::getCoordinatesIdList 
    447          (const StdString & name, const CVarPath  * const path) 
    448       { 
    449          std::list<StdString> retvalue; 
    450          StdString value = this->getCoordinatesId(name, path); 
    451           
    452          boost::split(retvalue, value, boost::is_any_of(" ")); 
    453           
    454          std::list<StdString>::iterator it = retvalue.begin(), end = retvalue.end(); 
    455          for (; it != end; it++) 
    456          { 
    457             StdString & coord = *it; 
    458             coord.assign(coord.data()); 
    459          } 
    460          return (retvalue); 
    461       } 
    462  
    463       StdString CINetCDF4::getCoordinatesId 
    464          (const StdString & name, const CVarPath  * const path) 
    465       { 
    466          StdString retvalue; 
    467          if (this->hasAttribute("coordinates", &name, path)) 
    468          { 
    469             return (this->getAttributeValue<StdString>("coordinates", &name, path)); 
    470          } 
    471          else 
    472          { 
    473             std::list<StdString> dims = this->getDimensionsList(&name, path); 
    474             std::list<StdString>::const_iterator it = dims.begin(), end = dims.end(); 
    475             for (; it != end; it++) 
    476             { 
    477                const StdString & value = *it;                
    478                retvalue.append(value).push_back(' '); 
    479             } 
    480             retvalue.erase (retvalue.end()-1) ; 
    481          } 
    482  
    483          return (retvalue); 
    484       } 
    485  
    486       StdString CINetCDF4::getBoundsId(const StdString & name, 
    487                                        const CVarPath  * const path) 
    488       { 
    489          StdString retvalue; 
    490          if (this->hasAttribute("bounds", &name, path)) 
    491             return (this->getAttributeValue<StdString>("bounds", &name, path)); 
    492          return (retvalue); 
    493       } 
    494  
    495       //--------------------------------------------------------------- 
    496  
    497       bool CINetCDF4::isBound(const StdString & name, 
    498                               const CVarPath  * const path) 
    499       { 
    500          std::set<StdString> bounds = this->getBoundVariables(path); 
    501          return (bounds.find(name) != bounds.end()); 
    502       } 
    503  
    504       bool CINetCDF4::isCoordinate(const StdString & name, 
    505                                    const CVarPath  * const path) 
    506       { 
    507          std::set<StdString> coords = this->getCoordVariables(path); 
    508          return (coords.find(name) != coords.end()); 
    509       } 
    510  
    511       bool CINetCDF4::isRectilinear(const StdString & name, const CVarPath  * const path) 
    512       { 
    513          std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    514          std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    515          for (; it != end; it++) 
    516          { 
    517             const StdString & coord = *it; 
    518             if (this->hasVariable(coord, path) && !this->isTemporal(coord, path)) 
    519             { 
    520                std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
    521                if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end())) 
    522                   continue; 
    523                else 
    524                   return (false); 
    525             } 
    526          } 
    527          return (true); 
    528       } 
    529  
    530       bool CINetCDF4::isCurvilinear(const StdString & name, const CVarPath  * const path) 
    531       { 
    532          if (this->isRectilinear(name, path) || 
    533             !this->hasCoordinates(name, path)) 
    534             return (false); 
    535  
    536          std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    537          std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    538          for (; it != end; it++) 
    539          { 
    540             const StdString & coord = *it; 
    541             if (this->hasVariable(coord, path)) 
    542             { 
    543                std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
    544                if (dimvar.size() != 2) return (false); 
    545             } 
    546             else return (false); 
    547          } 
    548          return (true); 
    549       } 
    550  
    551       bool CINetCDF4::isUnstructured(const StdString & name, const CVarPath  * const path) 
    552       { 
    553          if (this->isRectilinear(name, path)    || 
    554              this->isCurvilinear(name, path)    || 
    555              !this->hasCoordinates(name, path)) 
    556              return (false); 
    557  
    558          StdString dimname = this->getDimensionsList(&name, path).back(); 
    559  
    560          std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    561          std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    562          for (; it != end; it++) 
    563          { 
    564             const StdString & coord = *it; 
    565             if (this->hasVariable(coord, path)) 
    566             { 
    567                std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
    568                if ((dimvar.size() == 1) && 
    569                    (dimvar.find(dimname) != dimvar.end())) 
    570                   continue; 
    571                else 
    572                   return (false); 
    573             } 
    574             else return (false); 
    575          } 
    576  
    577          return (true); 
    578       } 
    579  
    580       bool CINetCDF4::isUnknown(const StdString & name, const CVarPath * const path) 
    581       { 
    582          return !(this->isRectilinear(name, path) || 
    583                   this->isCurvilinear(name, path) || 
    584                   this->isUnstructured(name, path)); 
    585       } 
    586  
    587       bool CINetCDF4::isTemporal(const StdString & name, const CVarPath  * const path) 
    588       { 
    589          if (!this->hasTemporalDim(path)) return (false); 
    590          std::map<StdString, StdSize> dims = this->getDimensions(&name, path); 
    591          if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end()) 
    592             return (true); 
    593          return (false); 
    594       } 
    595  
    596       bool CINetCDF4::is3Dim(const StdString & name, const CVarPath  * const path) 
    597       { 
    598          int i = 0; 
    599          std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    600          std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    601          for (; it != end; it++) 
    602          { 
    603             const StdString & coord = *it; 
    604             if (this->hasVariable(coord, path)) 
    605             { 
    606                if (this->isTemporal(coord, path)) 
    607                   continue; 
    608                i++; 
    609             } 
    610             else 
    611             { 
    612                if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
    613                   continue; 
    614                i++; 
    615             } 
    616          } 
    617          return (i == 3); 
    618       } 
    619  
    620       bool CINetCDF4::isCellGrid(const StdString & name, const CVarPath  * const path) 
    621       { 
    622          if (this->isCoordinate(name, path)) 
    623          { 
    624             return (this->hasBounds(name, path)); 
    625          } 
    626          else 
    627          { 
    628             std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
    629             std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
    630             for (; it != end; it++) 
    631             { 
    632                const StdString & coord = *it; 
    633                if (this->hasVariable(coord, path)) 
    634                { 
    635                   if (this->isTemporal(coord, path)) 
    636                      continue; 
    637                   if (this->isCellGrid(coord, path)) 
    638                      continue; 
    639                   return (false); 
    640                } 
    641                else 
    642                { 
    643                   if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
    644                      continue; 
    645                   return (false); 
    646                } 
    647             } 
    648          } 
    649  
    650          return (true); 
    651       } 
    652  
    653       //--------------------------------------------------------------- 
    654  
    655       std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti, 
    656                                                        bool _isCurvi,    bool _isUnstr, 
    657                                                        bool _isCellData, bool _isTemporal, 
    658                                                        const CVarPath * const path) 
    659       { 
    660          std::list<StdString> retvalue; 
    661          std::list<StdString> allvars  = this->getVariables(path); 
    662          std::set<StdString> allcoords = this->getCoordVariables(path); 
    663  
    664          std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end(); 
    665          for (; it != end; it++) 
    666          { 
    667             const StdString & var = *it; 
    668             if (this->isCoordinate(var, path)) continue; 
    669  
    670             if (!_isRecti && this->isRectilinear(var, path) ) continue; 
    671             if (!_isCurvi && this->isCurvilinear(var, path) ) continue; 
    672             if (!_isUnstr && this->isUnstructured(var, path)) continue; 
    673  
    674             if (!_isTemporal && this->isTemporal(var, path)) continue; 
    675             if (!_is3D       && this->is3Dim(var, path)    ) continue; 
    676             if (!_isCellData && this->isCellGrid(var, path)) continue; 
    677  
    678             if (this->isUnknown(var, path)) continue; 
    679  
    680             retvalue.push_back(var); 
    681          } 
    682          return (retvalue); 
    683       } 
    684  
    685       //--------------------------------------------------------------- 
    686  
    687       void CINetCDF4::getDataInfo(const StdString & var, const CVarPath  * const path, StdSize record, 
    688                                   std::vector<StdSize> & start, std::vector<StdSize> & count, 
    689                                   StdSize & array_size) 
    690       { 
    691          std::list<StdString> dimlist        = this->getDimensionsList(&var, path); 
    692          std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path); 
    693          std::list<StdString>::iterator it   = dimlist.begin(); 
    694          if (this->isTemporal(var, path)) 
    695          { 
    696             if (record != UNLIMITED_DIM) 
    697                start.push_back(record); 
    698             else 
    699                start.push_back(0); 
    700             count.push_back(1); 
    701             it++; 
    702          } 
    703          for (; it != dimlist.end(); it++) 
    704          { 
    705             start.push_back(0); 
    706             count.push_back(dimmap[*it]); 
    707             array_size *= dimmap[*it]; 
    708          } 
    709       } 
    710  
    711       template <> 
    712          void CINetCDF4::getData(CArray<int, 1>& data, const StdString & var, 
    713                                  const CVarPath  * const path, StdSize record) 
    714       { 
    715  
    716          std::vector<StdSize> start, count; 
    717          int grpid = this->getGroup(path); 
    718          int varid = this->getVariable(var, path); 
    719          StdSize array_size = 1; 
    720          this->getDataInfo(var, path, record, start, count, array_size); 
    721          data.resize(array_size); 
    722          CheckError(nc_get_vara_int (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    723       } 
    724  
    725       template <> 
    726          void CINetCDF4::getData(CArray<double, 1>& data, const StdString & var, 
    727                                  const CVarPath  * const path, StdSize record) 
    728       { 
    729          std::vector<StdSize> start, count; 
    730          int grpid = this->getGroup(path); 
    731          int varid = this->getVariable(var, path); 
    732          StdSize array_size = 1; 
    733          this->getDataInfo(var, path, record, start, count, array_size); 
    734          data.resize(array_size); 
    735          CheckError(nc_get_vara_double (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    736       } 
    737  
    738       template <> 
    739          void CINetCDF4::getData(CArray<float, 1>& data, const StdString & var, 
    740                                  const CVarPath  * const path, StdSize record) 
    741       { 
    742          std::vector<StdSize> start, count; 
    743          int grpid = this->getGroup(path); 
    744          int varid = this->getVariable(var, path); 
    745          StdSize array_size = 1; 
    746          this->getDataInfo(var, path, record, start, count, array_size); 
    747          data.resize(array_size); 
    748          CheckError(nc_get_vara_float (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
    749       } 
    750  
    751       //--------------------------------------------------------------- 
    752       StdString CINetCDF4::getLonCoordName(const StdString & varname, 
    753                                            const CVarPath  * const path) 
    754       { 
    755          std::list<StdString> clist = 
    756             this->getCoordinatesIdList(varname, path); 
    757          if (this->hasCoordinates(varname, path)) 
    758             return (*clist.begin()); 
    759          else 
    760             return (*clist.rbegin()); 
    761       } 
    762  
    763       StdString CINetCDF4::getLatCoordName(const StdString & varname, 
    764                                            const CVarPath  * const path) 
    765       { 
    766          std::list<StdString> clist = 
    767             this->getCoordinatesIdList(varname, path); 
    768          if (this->hasCoordinates(varname, path)) 
    769             return (*(++clist.begin())); 
    770          else 
    771             return (*(++clist.rbegin())); 
    772       } 
    773  
    774       StdString CINetCDF4::getVertCoordName(const StdString & varname, 
    775                                             const CVarPath  * const path) 
    776       { 
    777          if (!this->is3Dim(varname, path)) return (""); 
    778          std::list<StdString> clist = 
    779             this->getCoordinatesIdList(varname, path); 
    780          if (this->hasCoordinates(varname, path)) 
    781             return (*(++(++clist.begin()))); 
    782          else 
    783             return (*(++(++clist.rbegin()))); 
    784       } 
    785  
    786       ///-------------------------------------------------------------- 
    787  
     8  CINetCDF4::CINetCDF4(const StdString& filename, const MPI_Comm* comm /*= NULL*/, bool multifile /*= true*/) 
     9    : mpi(comm != NULL && !multifile) 
     10  { 
     11    if (comm != NULL) 
     12    { 
     13      if (!multifile) CNetCdfInterface::openPar(filename, NC_NOWRITE, *comm, MPI_INFO_NULL, this->ncidp); 
     14      else CNetCdfInterface::open(filename, NC_NOWRITE, this->ncidp); 
     15    } 
     16      else CNetCdfInterface::open(filename, NC_NOWRITE, this->ncidp); 
     17  } 
     18 
     19  CINetCDF4::~CINetCDF4(void) 
     20  { /* Nothing to do */ } 
     21 
     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 
     34  //--------------------------------------------------------------- 
     35 
     36  void CINetCDF4::close(void) 
     37  { 
     38    CheckError(nc_close(this->ncidp)); 
     39  } 
     40 
     41  //--------------------------------------------------------------- 
     42 
     43  int CINetCDF4::getGroup(const CVarPath* const path) 
     44  { 
     45    int retvalue = this->ncidp; 
     46    if (path == NULL) return retvalue; 
     47    CVarPath::const_iterator it = path->begin(), end = path->end(); 
     48 
     49    for (; it != end; it++) 
     50    { 
     51      const StdString& groupid = *it; 
     52      CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue)); 
     53    } 
     54 
     55    return retvalue; 
     56  } 
     57 
     58  int CINetCDF4::getVariable(const StdString& varname, 
     59                             const CVarPath* const path) 
     60  { 
     61    int varid = 0; 
     62    int grpid = this->getGroup(path); 
     63    CheckError(nc_inq_varid(grpid, varname.c_str(), &varid)); 
     64    return varid; 
     65  } 
     66 
     67  int CINetCDF4::getDimension(const StdString& dimname, 
     68                              const CVarPath* const path) 
     69  { 
     70    int dimid = 0; 
     71    int grpid = this->getGroup(path); 
     72    CheckError(nc_inq_dimid(grpid, dimname.c_str(), &dimid)); 
     73    return dimid; 
     74  } 
     75 
     76  std::pair<nc_type, StdSize> CINetCDF4::getAttribute(const StdString& attname, 
     77                                                      const StdString* const var, 
     78                                                      const CVarPath* const path) 
     79  { 
     80    std::pair<nc_type, StdSize> retvalue; 
     81    int grpid = this->getGroup(path); 
     82    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)); 
     85    return retvalue; 
     86  } 
     87 
     88  int CINetCDF4::getUnlimitedDimension(const CVarPath* const path) 
     89  { 
     90    int dimid = 0; 
     91    int grpid = this->getGroup(path); 
     92    CheckError(nc_inq_unlimdim(grpid, &dimid)); 
     93    return dimid; 
     94  } 
     95 
     96  StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath* const path) 
     97  { 
     98    char full_name_in[NC_MAX_NAME +1]; 
     99    int grpid = this->getGroup(path); 
     100    int dimid = this->getUnlimitedDimension(path); 
     101    CheckError(nc_inq_dimname(grpid, dimid, full_name_in)); 
     102 
     103    StdString dimname(full_name_in); 
     104    return dimname; 
     105  } 
     106 
     107  //--------------------------------------------------------------- 
     108  StdSize CINetCDF4::getNbVertex(const StdString& name, 
     109                                 const CVarPath* const path) 
     110  { 
     111 
     112    if (this->isRectilinear(name, path) || 
     113       this->isCurvilinear(name, path)) 
     114    { 
     115      if (this->is3Dim(name, path)) return 8; 
     116      else return 4; 
     117    } 
     118    if (this->isUnstructured(name, path)) 
     119    { 
     120      StdString bound = this->getBoundsId 
     121            (this->getCoordinatesIdList(name, path).back(), path); 
     122      StdString dim = this->getDimensionsList(&bound, path).back(); 
     123      return (this->getDimensions(&bound, path)[dim]); 
     124    } 
     125    return size_t(-1); 
     126  } 
     127 
     128  //--------------------------------------------------------------- 
     129 
     130  std::list<StdString> CINetCDF4::getGroups(const CVarPath* const path) 
     131  { 
     132    StdSize strlen = 0; 
     133    char full_name_in[NC_MAX_NAME +1]; 
     134    int nbgroup = 0, *groupid = NULL; 
     135    int grpid = this->getGroup(path); 
     136    std::list<StdString> retvalue; 
     137 
     138    CheckError(nc_inq_grps(grpid, &nbgroup, NULL)); 
     139    groupid = new int[nbgroup](); 
     140    CheckError(nc_inq_grps(grpid, NULL, groupid)); 
     141 
     142    for (int i = 0; i < nbgroup; i++) 
     143    { 
     144      CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in)); 
     145      StdString groupname(full_name_in, strlen); 
     146      retvalue.push_back(groupname); 
     147    } 
     148 
     149    delete [] groupid; 
     150    return retvalue; 
     151  } 
     152 
     153  std::list<StdString> CINetCDF4::getVariables(const CVarPath* const path) 
     154  { 
     155    char full_name_in[NC_MAX_NAME +1]; 
     156    int nbvar = 0, *varid = NULL; 
     157    int grpid = this->getGroup(path); 
     158    std::list<StdString> retvalue; 
     159 
     160    CheckError(nc_inq_varids(grpid, &nbvar, NULL)); 
     161    varid = new int[nbvar](); 
     162    CheckError(nc_inq_varids(grpid, NULL, varid)); 
     163 
     164    for (int i = 0; i < nbvar; i++) 
     165    { 
     166      CheckError(nc_inq_varname(grpid, varid[i], full_name_in)); 
     167      StdString varname(full_name_in); 
     168      retvalue.push_back(varname); 
     169    } 
     170 
     171    delete [] varid; 
     172    return retvalue; 
     173  } 
     174 
     175  StdSize CINetCDF4::getNbOfTimestep(const CVarPath* const path) 
     176  { 
     177    return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]); 
     178  } 
     179 
     180  std::set<StdString> CINetCDF4::getBoundVariables(const CVarPath* const path) 
     181  { 
     182    std::set<StdString> retvalue; 
     183    std::list<StdString> variables = this->getVariables(path); 
     184    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
     185    for (; it != end; it++) 
     186    { 
     187      const StdString& var = *it; 
     188      if (this->hasBounds(var, path)) 
     189        retvalue.insert(retvalue.end(), this->getBoundsId(var, path)); 
     190    } 
     191    return retvalue; 
     192  } 
     193 
     194  std::set<StdString> CINetCDF4::getCoordVariables(const CVarPath* const path) 
     195  { 
     196    std::set<StdString> retvalue; 
     197    std::list<StdString> variables = this->getVariables(path); 
     198    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
     199    for (; it != end; it++) 
     200    { 
     201      const StdString& var = *it; 
     202      std::list<StdString> coords = this->getCoordinatesIdList(var, path); 
     203      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     204      for (; it != end; it++) 
     205      { 
     206        const StdString& coord = *it; 
     207        if (this->hasVariable(coord, path)) 
     208          retvalue.insert(retvalue.end(), coord); 
     209      } 
     210    } 
     211    return retvalue; 
     212  } 
     213 
     214  std::list<StdString> CINetCDF4::getDimensionsList(const StdString* const var, const CVarPath* const path) 
     215  { 
     216    char full_name_in[NC_MAX_NAME +1]; 
     217    int nbdim = 0, *dimid = NULL; 
     218    int grpid = this->getGroup(path); 
     219    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL; 
     220    std::list<StdString> retvalue; 
     221 
     222    if (var != NULL) 
     223    { 
     224      CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
     225      dimid = new int[nbdim](); 
     226      CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
     227    } 
     228    else 
     229    { 
     230      CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
     231      dimid = new int[nbdim](); 
     232      CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
     233    } 
     234 
     235    for (int i = 0; i < nbdim; i++) 
     236    { 
     237      CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); 
     238      StdString dimname(full_name_in); 
     239      retvalue.push_back(dimname); 
     240    } 
     241    delete [] dimid; 
     242 
     243    return retvalue; 
     244  } 
     245 
     246  std::map<StdString, StdSize> CINetCDF4::getDimensions(const StdString* const var, const CVarPath* const path) 
     247  { 
     248    StdSize size = 0; 
     249    char full_name_in[NC_MAX_NAME + 1]; 
     250    int nbdim = 0, *dimid = NULL; 
     251    int grpid = this->getGroup(path); 
     252    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL; 
     253    std::map<StdString, StdSize> retvalue; 
     254 
     255    if (var != NULL) 
     256    { 
     257      CheckError(nc_inq_varndims(grpid, varid, &nbdim)); 
     258      dimid = new int[nbdim](); 
     259      CheckError(nc_inq_vardimid(grpid, varid, dimid)); 
     260    } 
     261    else 
     262    { 
     263      CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); 
     264      dimid = new int[nbdim](); 
     265      CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); 
     266    } 
     267 
     268    for (int i = 0; i < nbdim; i++) 
     269    { 
     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); 
     274      retvalue.insert(retvalue.end(), std::make_pair(dimname, size)); 
     275    } 
     276    delete [] dimid; 
     277 
     278    return retvalue; 
     279  } 
     280 
     281  std::list<StdString> CINetCDF4::getAttributes(const StdString* const var, const CVarPath* const path ) 
     282  { 
     283    int nbatt = 0; 
     284    char full_name_in[NC_MAX_NAME +1]; 
     285    std::list<StdString> retvalue; 
     286    int grpid = this->getGroup(path); 
     287    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL; 
     288 
     289    if (var != NULL) 
     290      CheckError(nc_inq_varnatts(grpid, varid, &nbatt)); 
     291    else 
     292      CheckError(nc_inq_natts(grpid, &nbatt)); 
     293 
     294    for (int i = 0; i < nbatt; i++) 
     295    { 
     296      CheckError(nc_inq_attname(grpid, varid, i, full_name_in)); 
     297      StdString attname(full_name_in); 
     298      retvalue.push_back(attname); 
     299    } 
     300    return retvalue; 
     301  } 
     302 
     303  int CINetCDF4::getAttributeId(const StdString& name, 
     304                                const StdString* const var, 
     305                                const CVarPath* const path) 
     306  { 
     307    int retvalue = 0; 
     308    std::list<StdString> atts = this->getAttributes(var, path); 
     309    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end(); 
     310    for (; it != end; it++) 
     311    { 
     312      const StdString& attname = *it; 
     313      if (attname.compare(name) == 0) 
     314        return retvalue; 
     315      retvalue++; 
     316    } 
     317    return -1; 
     318  } 
     319 
     320  //--------------------------------------------------------------- 
     321 
     322  bool CINetCDF4::hasMissingValue(const StdString& name, 
     323                                  const CVarPath* const path) 
     324  { 
     325    return (this->hasAttribute("missing_value", &name, path) || 
     326          this->hasAttribute("_FillValue", &name, path)); 
     327  } 
     328 
     329  bool CINetCDF4::hasAttribute(const StdString& name, 
     330                               const StdString* const var , 
     331                               const CVarPath* const path) 
     332  { 
     333    std::list<StdString> atts = this->getAttributes(var, path); 
     334    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end(); 
     335    for (; it != end; it++) 
     336    { 
     337      const StdString& attname = *it; 
     338      if (attname.compare(name) == 0) return true; 
     339    } 
     340    return false; 
     341  } 
     342 
     343  bool CINetCDF4::hasVariable(const StdString& name, 
     344                              const CVarPath* const path) 
     345  { 
     346    std::list<StdString> variables = this->getVariables(path); 
     347    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end(); 
     348    for (; it != end; it++) 
     349    { 
     350      const StdString& varname = *it; 
     351      if (varname.compare(name) == 0) return true; 
     352    } 
     353    return false; 
     354  } 
     355 
     356  bool CINetCDF4::hasCoordinates(const StdString& name, 
     357                                 const CVarPath* const path) 
     358  { 
     359    return (this->hasAttribute("coordinates", &name, path)); 
     360  } 
     361 
     362  bool CINetCDF4::hasBounds(const StdString& name, 
     363                            const CVarPath* const path) 
     364  { 
     365    return (this->hasAttribute("bounds", &name, path)); 
     366  } 
     367 
     368  bool CINetCDF4::hasTemporalDim(const CVarPath* const path) 
     369  { 
     370    return (this->getUnlimitedDimension(path) != -1); 
     371  } 
     372 
     373  //--------------------------------------------------------------- 
     374 
     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 <> 
     401  StdString CINetCDF4::getAttributeValue(const StdString& name, 
     402                                         const StdString* const var, 
     403                                         const CVarPath* const path) 
     404  { 
     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) 
     413  { 
     414    if (this->hasAttribute("missing_value", &name, path)) 
     415      return (this->getAttributeValue<std::vector<int> >("missing_value", &name, path)[0]); 
     416    if (this->hasAttribute("_FillValue", &name, path)) 
     417      return (this->getAttributeValue<std::vector<int> >("_FillValue", &name, path)[0]); 
     418    return 0; 
     419  } 
     420 
     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  } 
     442 
     443  //--------------------------------------------------------------- 
     444 
     445  std::list<StdString> CINetCDF4::getCoordinatesIdList(const StdString& name, const CVarPath* const path) 
     446  { 
     447    std::list<StdString> retvalue; 
     448    StdString value = this->getCoordinatesId(name, path); 
     449 
     450    boost::split(retvalue, value, boost::is_any_of(" ")); 
     451 
     452    std::list<StdString>::iterator it = retvalue.begin(), end = retvalue.end(); 
     453    for (; it != end; it++) 
     454    { 
     455      StdString& coord = *it; 
     456      coord.assign(coord.data()); 
     457    } 
     458    return retvalue; 
     459  } 
     460 
     461  StdString CINetCDF4::getCoordinatesId(const StdString& name, const CVarPath* const path) 
     462  { 
     463    StdString retvalue; 
     464    if (this->hasAttribute("coordinates", &name, path)) 
     465    { 
     466      return (this->getAttributeValue<StdString>("coordinates", &name, path)); 
     467    } 
     468    else 
     469    { 
     470      std::list<StdString> dims = this->getDimensionsList(&name, path); 
     471      std::list<StdString>::const_iterator it = dims.begin(), end = dims.end(); 
     472      for (; it != end; it++) 
     473      { 
     474        const StdString& value = *it; 
     475        retvalue.append(value).push_back(' '); 
     476      } 
     477      retvalue.erase(retvalue.end() - 1) ; 
     478    } 
     479 
     480    return retvalue; 
     481  } 
     482 
     483  StdString CINetCDF4::getBoundsId(const StdString& name, 
     484                                   const CVarPath* const path) 
     485  { 
     486    StdString retvalue; 
     487    if (this->hasAttribute("bounds", &name, path)) 
     488      return (this->getAttributeValue<StdString>("bounds", &name, path)); 
     489    return retvalue; 
     490  } 
     491 
     492  //--------------------------------------------------------------- 
     493 
     494  bool CINetCDF4::isBound(const StdString& name, 
     495                          const CVarPath* const path) 
     496  { 
     497    std::set<StdString> bounds = this->getBoundVariables(path); 
     498    return (bounds.find(name) != bounds.end()); 
     499  } 
     500 
     501  bool CINetCDF4::isCoordinate(const StdString& name, 
     502                               const CVarPath* const path) 
     503  { 
     504    std::set<StdString> coords = this->getCoordVariables(path); 
     505    return (coords.find(name) != coords.end()); 
     506  } 
     507 
     508  bool CINetCDF4::isRectilinear(const StdString& name, const CVarPath* const path) 
     509  { 
     510    std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
     511    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     512    for (; it != end; it++) 
     513    { 
     514      const StdString& coord = *it; 
     515      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path)) 
     516      { 
     517        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
     518        if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end())) 
     519          continue; 
     520        else 
     521          return false; 
     522      } 
     523    } 
     524    return true; 
     525  } 
     526 
     527  bool CINetCDF4::isCurvilinear(const StdString& name, const CVarPath* const path) 
     528  { 
     529    if (this->isRectilinear(name, path) || !this->hasCoordinates(name, path)) 
     530      return false; 
     531 
     532    std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
     533    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     534    for (; it != end; it++) 
     535    { 
     536      const StdString& coord = *it; 
     537      if (this->hasVariable(coord, path)) 
     538      { 
     539        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
     540        if (dimvar.size() != 2) return false; 
     541      } 
     542      else return false; 
     543    } 
     544    return true; 
     545  } 
     546 
     547  bool CINetCDF4::isUnstructured(const StdString& name, const CVarPath* const path) 
     548  { 
     549    if (this->isRectilinear(name, path) || 
     550        this->isCurvilinear(name, path) || 
     551        !this->hasCoordinates(name, path)) 
     552       return false; 
     553 
     554    StdString dimname = this->getDimensionsList(&name, path).back(); 
     555 
     556    std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
     557    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     558    for (; it != end; it++) 
     559    { 
     560      const StdString& coord = *it; 
     561      if (this->hasVariable(coord, path)) 
     562      { 
     563        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path); 
     564        if ((dimvar.size() == 1) && 
     565            (dimvar.find(dimname) != dimvar.end())) 
     566          continue; 
     567        else 
     568          return false; 
     569      } 
     570      else return false; 
     571    } 
     572 
     573    return true; 
     574  } 
     575 
     576  bool CINetCDF4::isUnknown(const StdString& name, const CVarPath* const path) 
     577  { 
     578    return !(this->isRectilinear(name, path) || this->isCurvilinear(name, path) || this->isUnstructured(name, path)); 
     579  } 
     580 
     581  bool CINetCDF4::isTemporal(const StdString& name, const CVarPath* const path) 
     582  { 
     583    if (!this->hasTemporalDim(path)) return false; 
     584    std::map<StdString, StdSize> dims = this->getDimensions(&name, path); 
     585    if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end()) 
     586      return true; 
     587    return false; 
     588  } 
     589 
     590  bool CINetCDF4::is3Dim(const StdString& name, const CVarPath* const path) 
     591  { 
     592    int i = 0; 
     593    std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
     594    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     595    for (; it != end; it++) 
     596    { 
     597      const StdString& coord = *it; 
     598      if (this->hasVariable(coord, path)) 
     599      { 
     600        if (this->isTemporal(coord, path)) 
     601          continue; 
     602        i++; 
     603      } 
     604      else 
     605      { 
     606        if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
     607          continue; 
     608        i++; 
     609      } 
     610    } 
     611    return (i == 3); 
     612  } 
     613 
     614  bool CINetCDF4::isCellGrid(const StdString& name, const CVarPath* const path) 
     615  { 
     616    if (this->isCoordinate(name, path)) 
     617    { 
     618      return (this->hasBounds(name, path)); 
     619    } 
     620    else 
     621    { 
     622      std::list<StdString> coords = this->getCoordinatesIdList(name, path); 
     623      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end(); 
     624      for (; it != end; it++) 
     625      { 
     626        const StdString& coord = *it; 
     627        if (this->hasVariable(coord, path)) 
     628        { 
     629          if (this->isTemporal(coord, path)) 
     630            continue; 
     631          if (this->isCellGrid(coord, path)) 
     632            continue; 
     633          return false; 
     634        } 
     635        else 
     636        { 
     637          if (coord.compare(this->getUnlimitedDimensionName()) == 0) 
     638            continue; 
     639          return false; 
     640        } 
     641      } 
     642    } 
     643 
     644    return true; 
     645  } 
     646 
     647  //--------------------------------------------------------------- 
     648 
     649  std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti, 
     650                                                   bool _isCurvi,    bool _isUnstr, 
     651                                                   bool _isCellData, bool _isTemporal, 
     652                                                   const CVarPath* const path) 
     653  { 
     654    std::list<StdString> retvalue; 
     655    std::list<StdString> allvars  = this->getVariables(path); 
     656    std::set<StdString> allcoords = this->getCoordVariables(path); 
     657 
     658    std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end(); 
     659    for (; it != end; it++) 
     660    { 
     661      const StdString& var = *it; 
     662      if (this->isCoordinate(var, path)) continue; 
     663 
     664      if (!_isRecti && this->isRectilinear(var, path))  continue; 
     665      if (!_isCurvi && this->isCurvilinear(var, path))  continue; 
     666      if (!_isUnstr && this->isUnstructured(var, path)) continue; 
     667 
     668      if (!_isTemporal && this->isTemporal(var, path)) continue; 
     669      if (!_is3D       && this->is3Dim(var, path))     continue; 
     670      if (!_isCellData && this->isCellGrid(var, path)) continue; 
     671 
     672      if (this->isUnknown(var, path)) continue; 
     673 
     674      retvalue.push_back(var); 
     675    } 
     676    return retvalue; 
     677  } 
     678 
     679  //--------------------------------------------------------------- 
     680 
     681  void CINetCDF4::getDataInfo(const StdString& var, const CVarPath* const path, StdSize record, 
     682                              std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size, 
     683                              const std::vector<StdSize>* start /*= NULL*/, const std::vector<StdSize>* count /*= NULL*/) 
     684  { 
     685    std::list<StdString> dimlist = this->getDimensionsList(&var, path); 
     686    std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path); 
     687    std::list<StdString>::iterator it = dimlist.begin(); 
     688    if (this->isTemporal(var, path)) 
     689    { 
     690      if (record != UNLIMITED_DIM) 
     691        sstart.push_back(record); 
     692      else 
     693        sstart.push_back(0); 
     694      scount.push_back(1); 
     695      it++; 
     696    } 
     697    for (int i = 0; it != dimlist.end(); it++, i++) 
     698    { 
     699      if (start && count) 
     700      { 
     701        sstart.push_back((*start)[i]); 
     702        scount.push_back((*count)[i]); 
     703        array_size *= (*count)[i]; 
     704      } 
     705      else 
     706      { 
     707        sstart.push_back(0); 
     708        scount.push_back(dimmap[*it]); 
     709        array_size *= dimmap[*it]; 
     710      } 
     711    } 
     712  } 
     713 
     714  template <> 
     715  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var, 
     716                          const CVarPath* const path, StdSize record) 
     717  { 
     718 
     719    std::vector<StdSize> start, count; 
     720    int grpid = this->getGroup(path); 
     721    int varid = this->getVariable(var, path); 
     722    StdSize array_size = 1; 
     723    this->getDataInfo(var, path, record, start, count, array_size); 
     724    data.resize(array_size); 
     725    CheckError(nc_get_vara_int(grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); 
     726  } 
     727 
     728  template <> 
     729  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 
     741  template <> 
     742  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  } 
     753 
     754  template <> 
     755  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var, 
     756                          bool collective, StdSize record, 
     757                          const std::vector<StdSize>* start /*= NULL*/, 
     758                          const std::vector<StdSize>* count /*= NULL*/) 
     759  { 
     760    int varid = this->getVariable(var); 
     761 
     762    if (this->mpi && collective) 
     763      CNetCdfInterface::varParAccess(ncidp, varid, NC_COLLECTIVE); 
     764    if (this->mpi && !collective) 
     765      CNetCdfInterface::varParAccess(ncidp, varid, NC_INDEPENDENT); 
     766 
     767    std::vector<StdSize> sstart, scount; 
     768    StdSize array_size = 1; 
     769    this->getDataInfo(var, NULL, record, sstart, scount, array_size, start, count); 
     770 
     771    if (data.numElements() != array_size) 
     772    { 
     773      ERROR("CONetCDF4::getData(...)", 
     774            << "[ Array size = " << data.numElements() 
     775            << ", Data size = "  << array_size 
     776            << " ] Invalid array size"); 
     777    } 
     778 
     779    CheckError(nc_get_vara_double(ncidp, varid, &(sstart[0]), &(scount[0]), data.dataFirst())); 
     780  } 
     781 
     782  //--------------------------------------------------------------- 
     783 
     784  StdString CINetCDF4::getLonCoordName(const StdString& varname, 
     785                                       const CVarPath* const path) 
     786  { 
     787    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
     788    if (this->hasCoordinates(varname, path)) 
     789      return (*clist.begin()); 
     790    else 
     791      return (*clist.rbegin()); 
     792  } 
     793 
     794  StdString CINetCDF4::getLatCoordName(const StdString& varname, 
     795                                       const CVarPath* const path) 
     796  { 
     797    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
     798    if (this->hasCoordinates(varname, path)) 
     799      return (*(++clist.begin())); 
     800    else 
     801      return (*(++clist.rbegin())); 
     802  } 
     803 
     804  StdString CINetCDF4::getVertCoordName(const StdString& varname, 
     805                                        const CVarPath* const path) 
     806  { 
     807    if (!this->is3Dim(varname, path)) return ""; 
     808    std::list<StdString> clist = this->getCoordinatesIdList(varname, path); 
     809    if (this->hasCoordinates(varname, path)) 
     810      return (*(++(++clist.begin()))); 
     811    else 
     812      return (*(++(++clist.rbegin()))); 
     813  } 
    788814} // namespace xios 
  • XIOS/trunk/src/input/inetcdf4.hpp

    r591 r599  
    1111 
    1212#ifndef UNLIMITED_DIM 
    13    #define UNLIMITED_DIM (size_t)(-1) 
    14 #endif  //UNLIMITED_DIM 
     13#define UNLIMITED_DIM (size_t)(-1) 
     14#endif  // UNLIMITED_DIM 
    1515 
    1616namespace xios 
    1717{ 
    18       /// ////////////////////// Déclarations ////////////////////// /// 
    19       typedef std::vector<StdString> CVarPath; 
    20  
    21       class CINetCDF4 
    22       { 
    23          public : 
    24  
    25             /// Constructeurs /// 
    26             CINetCDF4(void);                             // Not implemented. 
    27             CINetCDF4(const StdString & filename); 
    28             CINetCDF4(const CINetCDF4 & inetcdf4);       // Not implemented. 
    29             CINetCDF4(const CINetCDF4 * const inetcdf4); // Not implemented. 
    30  
    31          //------------------------------------------------------------- 
    32  
    33             /// Accesseurs /// 
    34             StdSize getNbOfTimestep(const CVarPath  * const path = NULL); 
    35  
    36             StdString getUnlimitedDimensionName(const CVarPath  * const path = NULL); 
    37  
    38             StdString getCoordinatesId(const StdString & name, 
    39                                        const CVarPath  * const path = NULL); 
    40  
    41             StdString getBoundsId(const StdString & name, 
    42                                   const CVarPath  * const path = NULL); 
    43  
    44             StdString getLonCoordName(const StdString & varname, 
    45                                       const CVarPath  * const path = NULL); 
    46             StdString getLatCoordName(const StdString & varname, 
    47                                        const CVarPath  * const path = NULL); 
    48             StdString getVertCoordName(const StdString & varname, 
    49                                        const CVarPath  * const path = NULL); 
    50  
    51             std::set<StdString> getCoordVariables(const CVarPath * const path = NULL); 
    52             std::set<StdString> getBoundVariables(const CVarPath * const path = NULL); 
    53  
    54             std::list<StdString> getGroups   (const CVarPath * const path = NULL); 
    55             std::list<StdString> getVariables(const CVarPath * const path = NULL); 
    56  
    57             std::list<StdString> getDataVariables(bool _is3D       = true, 
    58                                                   bool _isRecti    = true, 
    59                                                   bool _isCurvi    = true, 
    60                                                   bool _isUnstr    = true, 
    61                                                   bool _isCellData = true, 
    62                                                   bool _isTemporal = true, 
    63                                                   const CVarPath * const path = NULL); 
    64  
    65             std::list<StdString> getAttributes 
    66                                 (const StdString * const var  = NULL, 
    67                                  const CVarPath  * const path = NULL); 
    68  
    69             std::list<StdString> getDimensionsList 
    70                                 (const StdString * const var  = NULL, 
    71                                  const CVarPath  * const path = NULL); 
    72  
    73             std::list<StdString> getCoordinatesIdList(const StdString & name, 
    74                                                       const CVarPath  * const path = NULL); 
    75  
    76             std::map<StdString, StdSize> getDimensions (const StdString * const var  = NULL, 
    77                                                         const CVarPath  * const path = NULL); 
    78  
    79             StdSize getNbVertex(const StdString & name, 
    80                                 const CVarPath  * const path = NULL); 
    81          //------------------------------------------------------------- 
    82  
    83             template <class T> 
    84                T getMissingValue(const StdString & name, 
    85                                  const CVarPath  * const path = NULL); 
    86  
    87             template <class T> 
    88                T getAttributeValue(const StdString & name, 
    89                                    const StdString * const var  = NULL, 
    90                                    const CVarPath  * const path = NULL); 
    91  
    92             template <class T> 
    93                void getData(CArray<T, 1>& data, 
    94                             const StdString & var, 
    95                             const CVarPath  * const path = NULL, 
    96                             StdSize record   = UNLIMITED_DIM); 
    97  
    98          //------------------------------------------------------------- 
    99  
    100             /// Tests /// 
    101             bool hasMissingValue(const StdString & name, 
    102                                  const CVarPath  * const path = NULL); 
    103  
    104             bool hasAttribute(const StdString & name, 
    105                               const StdString * const var  = NULL, 
    106                               const CVarPath  * const path = NULL); 
    107  
    108             bool hasVariable(const StdString & name, 
    109                              const CVarPath  * const path = NULL); 
    110  
    111             bool hasCoordinates(const StdString & name, 
    112                                 const CVarPath  * const path = NULL); 
    113  
    114             bool hasTemporalDim(const CVarPath  * const path = NULL); 
    115  
    116             bool hasBounds(const StdString & name, 
    117                            const CVarPath  * const path = NULL); 
    118  
    119          //------------------------------------------------------------- 
    120  
    121             bool isBound(const StdString & name, 
    122                          const CVarPath  * const path = NULL); 
    123             bool isCoordinate(const StdString & name, 
    124                               const CVarPath  * const path = NULL); 
    125             bool isRectilinear(const StdString & name, 
    126                                const CVarPath  * const path = NULL); 
    127             bool isCurvilinear(const StdString & name, 
    128                                const CVarPath  * const path = NULL); 
    129             bool isUnknown(const StdString & name, 
    130                                const CVarPath  * const path = NULL); 
    131             bool isUnstructured(const StdString & name, 
    132                                 const CVarPath  * const path = NULL); 
    133  
    134             bool isTemporal(const StdString & name, 
    135                             const CVarPath  * const path = NULL); 
    136             bool is3Dim(const StdString & name, 
    137                         const CVarPath  * const path = NULL); 
    138             bool isCellGrid(const StdString & name, 
    139                             const CVarPath  * const path = NULL); 
    140  
    141          //------------------------------------------------------------- 
    142  
    143             /// Destructeur /// 
    144             virtual ~CINetCDF4(void); 
    145  
    146          protected : 
    147  
    148          //------------------------------------------------------------- 
    149  
    150             /// Accesseurs /// 
    151             int getGroup   (const CVarPath * const path = NULL); 
    152             int getVariable(const StdString & varname, 
    153                             const CVarPath * const path = NULL); 
    154             int getDimension(const StdString & dimname, 
    155                              const CVarPath  * const path = NULL); 
    156             int getUnlimitedDimension(const CVarPath  * const path = NULL); 
    157             int getAttributeId(const StdString & name, 
    158                                const StdString * const var  = NULL, 
    159                                const CVarPath  * const path = NULL); 
    160  
    161             std::pair<nc_type , StdSize> getAttribute(const StdString & attname, 
    162                                                       const StdString * const var  = NULL, 
    163                                                       const CVarPath  * const path = NULL); 
    164  
    165          //------------------------------------------------------------- 
    166  
    167             void getDataInfo(const StdString & var, const CVarPath  * const path, StdSize record, 
    168                              std::vector<StdSize> & start, std::vector<StdSize> & count, 
    169                              StdSize & array_size); 
    170  
    171          private : 
    172  
    173             /// Vérification des erreurs NetCDF /// 
    174             static void CheckError(int status); 
    175  
    176             int ncidp; // Identifiant de fichier netcdf. 
    177  
    178       }; // class CINetCDF4 
    179  
    180       ///-------------------------------------------------------------- 
    181       template <> 
    182          StdString CINetCDF4::getAttributeValue 
    183             (const StdString & name, const StdString * const var, 
    184                                      const CVarPath  * const path); 
    185  
    186       template <> 
    187          std::vector<double> CINetCDF4::getAttributeValue 
    188             (const StdString & name, const StdString * const var, 
    189                                      const CVarPath  * const path); 
    190  
    191       template <> 
    192          std::vector<float> CINetCDF4::getAttributeValue 
    193             (const StdString & name, const StdString * const var, 
    194                                      const CVarPath  * const path); 
    195  
    196       template <> 
    197          std::vector<int>  CINetCDF4::getAttributeValue 
    198             (const StdString & name, const StdString * const var, 
    199                                      const CVarPath  * const path); 
    200  
    201       template <> 
    202          std::vector<char>  CINetCDF4::getAttributeValue 
    203             (const StdString & name, const StdString * const var, 
    204                                      const CVarPath  * const path); 
    205  
    206       //--------------------------------------------------------------- 
    207       template <> 
    208          int CINetCDF4::getMissingValue 
    209             (const StdString & name, const CVarPath  * const path); 
    210  
    211       template <> 
    212          double CINetCDF4::getMissingValue 
    213             (const StdString & name, const CVarPath  * const path); 
    214  
    215       template <> 
    216          float CINetCDF4::getMissingValue 
    217             (const StdString & name, const CVarPath  * const path); 
    218  
    219       //--------------------------------------------------------------- 
    220       template <> 
    221          void CINetCDF4::getData(CArray<int, 1>& data, const StdString & var, 
    222                                  const CVarPath  * const path, StdSize record); 
    223  
    224       template <> 
    225          void CINetCDF4::getData(CArray<double, 1>& data, const StdString & var, 
    226                                  const CVarPath  * const path, StdSize record); 
    227  
    228       template <> 
    229          void CINetCDF4::getData(CArray<float, 1>& data, const StdString & var, 
    230                                  const CVarPath  * const path, StdSize record); 
    231       ///-------------------------------------------------------------- 
    232  
     18  typedef std::vector<StdString> CVarPath; 
     19 
     20  class CINetCDF4 
     21  { 
     22    public: 
     23      /// Constructors /// 
     24      CINetCDF4(const StdString& filename, const MPI_Comm* comm = NULL, bool multifile = true); 
     25      CINetCDF4(const CINetCDF4& inetcdf4);       // Not implemented. 
     26      CINetCDF4(const CINetCDF4* const inetcdf4); // Not implemented. 
     27 
     28      //------------------------------------------------------------- 
     29 
     30      /// Destructor /// 
     31      virtual ~CINetCDF4(void); 
     32 
     33      //------------------------------------------------------------- 
     34 
     35      void close(void); 
     36 
     37      //------------------------------------------------------------- 
     38 
     39      /// Getters /// 
     40      StdSize getNbOfTimestep(const CVarPath* const path = NULL); 
     41 
     42      StdString getUnlimitedDimensionName(const CVarPath* const path = NULL); 
     43 
     44      StdString getCoordinatesId(const StdString& name, const CVarPath* const path = NULL); 
     45 
     46      StdString getBoundsId(const StdString& name, const CVarPath* const path = NULL); 
     47 
     48      StdString getLonCoordName(const StdString& varname, const CVarPath* const path = NULL); 
     49      StdString getLatCoordName(const StdString& varname, const CVarPath* const path = NULL); 
     50      StdString getVertCoordName(const StdString& varname, const CVarPath* const path = NULL); 
     51 
     52      std::set<StdString> getCoordVariables(const CVarPath* const path = NULL); 
     53      std::set<StdString> getBoundVariables(const CVarPath* const path = NULL); 
     54 
     55      std::list<StdString> getGroups   (const CVarPath* const path = NULL); 
     56      std::list<StdString> getVariables(const CVarPath* const path = NULL); 
     57 
     58      std::list<StdString> getDataVariables(bool _is3D       = true, 
     59                                            bool _isRecti    = true, 
     60                                            bool _isCurvi    = true, 
     61                                            bool _isUnstr    = true, 
     62                                            bool _isCellData = true, 
     63                                            bool _isTemporal = true, 
     64                                            const CVarPath* const path = NULL); 
     65 
     66      std::list<StdString> getAttributes(const StdString* const var  = NULL, 
     67                                         const CVarPath* const path = NULL); 
     68 
     69      std::list<StdString> getDimensionsList(const StdString* const var  = NULL, 
     70                                             const CVarPath* const path = NULL); 
     71 
     72      std::list<StdString> getCoordinatesIdList(const StdString& name, 
     73                                                const CVarPath* const path = NULL); 
     74 
     75      std::map<StdString, StdSize> getDimensions(const StdString* const var  = NULL, 
     76                                                 const CVarPath* const path = NULL); 
     77 
     78      StdSize getNbVertex(const StdString& name, const CVarPath* const path = NULL); 
     79 
     80      //------------------------------------------------------------- 
     81 
     82      template <class T> 
     83      T getMissingValue(const StdString& name, const CVarPath* const path = NULL); 
     84 
     85      template <class T> 
     86      T getAttributeValue(const StdString& name, 
     87                          const StdString* const var  = NULL, 
     88                          const CVarPath* const path = NULL); 
     89 
     90      template <class T> 
     91      void getData(CArray<T, 1>& data, 
     92                   const StdString& var, 
     93                   const CVarPath* const path = NULL, 
     94                   StdSize record = UNLIMITED_DIM); 
     95 
     96      template <class T> 
     97      void getData(CArray<T, 1>& data, const StdString& var, 
     98                   bool collective, StdSize record, 
     99                   const std::vector<StdSize>* start = NULL, 
     100                   const std::vector<StdSize>* count = NULL); 
     101 
     102      //------------------------------------------------------------- 
     103 
     104      /// Tests /// 
     105      bool hasMissingValue(const StdString& name, const CVarPath* const path = NULL); 
     106 
     107      bool hasAttribute(const StdString& name, const StdString* const var  = NULL, const CVarPath* const path = NULL); 
     108 
     109      bool hasVariable(const StdString& name, const CVarPath* const path = NULL); 
     110 
     111      bool hasCoordinates(const StdString& name, const CVarPath* const path = NULL); 
     112 
     113      bool hasTemporalDim(const CVarPath* const path = NULL); 
     114 
     115      bool hasBounds(const StdString& name, const CVarPath* const path = NULL); 
     116 
     117      //------------------------------------------------------------- 
     118 
     119      bool isBound(const StdString& name, const CVarPath* const path = NULL); 
     120      bool isCoordinate(const StdString& name, const CVarPath* const path = NULL); 
     121      bool isRectilinear(const StdString& name, const CVarPath* const path = NULL); 
     122      bool isCurvilinear(const StdString& name, const CVarPath* const path = NULL); 
     123      bool isUnknown(const StdString& name, const CVarPath* const path = NULL); 
     124      bool isUnstructured(const StdString& name, const CVarPath* const path = NULL); 
     125 
     126      bool isTemporal(const StdString& name, const CVarPath* const path = NULL); 
     127      bool is3Dim(const StdString& name, const CVarPath* const path = NULL); 
     128      bool isCellGrid(const StdString& name, const CVarPath* const path = NULL); 
     129 
     130    protected: 
     131      /// Getters /// 
     132      int getGroup   (const CVarPath* const path = NULL); 
     133      int getVariable(const StdString& varname, const CVarPath* const path = NULL); 
     134      int getDimension(const StdString& dimname, const CVarPath* const path = NULL); 
     135      int getUnlimitedDimension(const CVarPath* const path = NULL); 
     136      int getAttributeId(const StdString& name, 
     137                         const StdString* const var = NULL, 
     138                         const CVarPath* const path = NULL); 
     139 
     140      std::pair<nc_type , StdSize> getAttribute(const StdString& attname, 
     141                                                const StdString* const var  = NULL, 
     142                                                const CVarPath* const path = NULL); 
     143 
     144      //------------------------------------------------------------- 
     145 
     146      void getDataInfo(const StdString& var, const CVarPath* const path, StdSize record, 
     147                       std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size, 
     148                       const std::vector<StdSize>* start = NULL, const std::vector<StdSize>* count = NULL); 
     149 
     150    private: 
     151      /// Vérification des erreurs NetCDF /// 
     152      static void CheckError(int status); 
     153 
     154      int ncidp; // Identifiant de fichier netcdf. 
     155      bool mpi; //< Whether parallel file access is used 
     156  }; // class CINetCDF4 
     157 
     158  ///-------------------------------------------------------------- 
     159 
     160  template <> 
     161  StdString CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var, 
     162                                         const CVarPath* const path); 
     163 
     164  template <> 
     165  std::vector<double> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var, 
     166                                                   const CVarPath* const path); 
     167 
     168  template <> 
     169  std::vector<float> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var, 
     170                                                  const CVarPath* const path); 
     171 
     172  template <> 
     173  std::vector<int> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var, 
     174                                                const CVarPath* const path); 
     175 
     176  template <> 
     177  std::vector<char> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var, 
     178                                                 const CVarPath* const path); 
     179 
     180  //--------------------------------------------------------------- 
     181 
     182  template <> 
     183  int CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     184 
     185  template <> 
     186  double CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     187 
     188  template <> 
     189  float CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path); 
     190 
     191  //--------------------------------------------------------------- 
     192 
     193  template <> 
     194  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var, 
     195                          const CVarPath* const path, StdSize record); 
     196 
     197  template <> 
     198  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var, 
     199                          const CVarPath* const path, StdSize record); 
     200 
     201  template <> 
     202  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var, 
     203                          const CVarPath* const path, StdSize record); 
     204 
     205  template <> 
     206  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var, 
     207                          bool collective, StdSize record, 
     208                          const std::vector<StdSize>* start /*= NULL*/, 
     209                          const std::vector<StdSize>* count /*= NULL*/); 
    233210} // namespace xios 
    234211 
  • XIOS/trunk/src/input/nc4_data_input.cpp

    r501 r599  
    11#include "nc4_data_input.hpp" 
     2 
     3#include "context.hpp" 
     4#include "context_server.hpp" 
    25 
    36namespace xios 
    47{ 
    5       /// ////////////////////// Définitions ////////////////////// /// 
    6       CNc4DataInput::CNc4DataInput(void) 
    7       { /* ne rien faire de plus */ } 
     8  CNc4DataInput::CNc4DataInput(const StdString& filename, MPI_Comm comm_file, bool multifile, bool isCollective /*= true*/) 
     9    : SuperClass() 
     10    , SuperClassWriter(filename, &comm_file, multifile) 
     11    , comm_file(comm_file) 
     12    , filename(filename) 
     13    , isCollective(isCollective) 
     14  { 
     15    SuperClass::type = multifile ? MULTI_FILE : ONE_FILE; 
     16  } 
    817 
    9       CNc4DataInput::~CNc4DataInput(void) 
    10       { /* ne rien faire de plus */ } 
     18  CNc4DataInput::~CNc4DataInput(void) 
     19  { /* Nothing more to do */ } 
    1120 
     21  StdSize CNc4DataInput::getFieldNbRecords_(CField* field) 
     22  { 
     23    StdString fieldId = !field->name.isEmpty() ? field->name.getValue() : field->getBaseFieldReference()->getId(); 
     24 
     25    if (SuperClassWriter::isTemporal(fieldId)) 
     26    { 
     27      return SuperClassWriter::getDimensions(&fieldId)[SuperClassWriter::getUnlimitedDimensionName()]; 
     28    } 
     29 
     30    return 1; 
     31  } 
     32 
     33  void CNc4DataInput::readFieldData_(CField* field) 
     34  { 
     35    CContext* context = CContext::getCurrent(); 
     36    CContextServer* server = context->server; 
     37 
     38    CGrid* grid = field->grid; 
     39 
     40    if (!grid->doGridHaveDataToWrite()) 
     41      if (SuperClass::type==MULTI_FILE || !isCollective) return; 
     42 
     43    StdString fieldId = !field->name.isEmpty() ? field->name.getValue() : field->getBaseFieldReference()->getId(); 
     44 
     45    CArray<double,1> fieldData(grid->getWrittenDataSize()); 
     46    if (!field->default_value.isEmpty()) fieldData = field->default_value; 
     47 
     48    switch (SuperClass::type) 
     49    { 
     50      case MULTI_FILE: 
     51        SuperClassWriter::getData(fieldData, fieldId, isCollective, field->getNStep() - 1); 
     52        break; 
     53      case ONE_FILE: 
     54      { 
     55        std::vector<int> nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal(); 
     56        std::vector<int> nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer(); 
     57        std::vector<int> nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer(); 
     58 
     59        int ssize = nZoomBeginGlobal.size(); 
     60 
     61        std::vector<StdSize> start(ssize); 
     62        std::vector<StdSize> count(ssize); 
     63 
     64        for (int i = 0; i < ssize; ++i) 
     65        { 
     66          start[i] = nZoomBeginServer[ssize - i - 1] - nZoomBeginGlobal[ssize - i - 1]; 
     67          count[i] = nZoomSizeServer[ssize - i - 1]; 
     68        } 
     69 
     70        SuperClassWriter::getData(fieldData, fieldId, isCollective, field->getNStep() - 1, &start, &count); 
     71        break; 
     72      } 
     73    } 
     74 
     75    field->inputField(fieldData); 
     76 
     77    if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty()) 
     78    { 
     79      double scaleFactor = 1.0, addOffset = 0.0; 
     80      if (!field->scale_factor.isEmpty()) scaleFactor = field->scale_factor; 
     81      if (!field->add_offset.isEmpty()) addOffset = field->add_offset; 
     82      field->invertScaleFactorAddOffset(scaleFactor, addOffset); 
     83    } 
     84  } 
     85 
     86  void CNc4DataInput::closeFile_(void) 
     87  { 
     88    SuperClassWriter::close(); 
     89  } 
    1290} // namespace xios 
  • XIOS/trunk/src/input/nc4_data_input.hpp

    r591 r599  
    44/// XIOS headers /// 
    55#include "xios_spl.hpp" 
     6#include "data_input.hpp" 
    67#include "inetcdf4.hpp" 
    78 
    89namespace xios 
    910{ 
    10       /// ////////////////////// Déclarations ////////////////////// /// 
     11  class CNc4DataInput 
     12    : protected CINetCDF4 
     13    , public virtual CDataInput 
     14  { 
     15  public: 
     16    /// Type definitions /// 
     17    typedef CINetCDF4  SuperClassWriter; 
     18    typedef CDataInput SuperClass; 
    1119 
    12       class CNc4DataInput 
    13       { 
    14          public : 
     20    /// Constructors /// 
     21    CNc4DataInput(const StdString& filename, MPI_Comm comm_file, bool multifile, bool isCollective = true); 
     22    CNc4DataInput(const CNc4DataInput& dataInput);       // Not implemented. 
     23    CNc4DataInput(const CNc4DataInput* const dataInput); // Not implemented. 
    1524 
    16             /// Constructeurs /// 
    17             CNc4DataInput(void); 
    18             CNc4DataInput(const CNc4DataInput & datainput);       // Not implemented. 
    19             CNc4DataInput(const CNc4DataInput * const datainput); // Not implemented. 
     25    /// Destructor /// 
     26    virtual ~CNc4DataInput(void); 
    2027 
    21             /// Destructeur /// 
    22             virtual ~CNc4DataInput(void); 
     28    /// Getters /// 
     29    const StdString& getFileName(void) const; 
    2330 
    24       }; // class CNc4DataInput 
     31  protected: 
     32    // Read methods 
     33    virtual StdSize getFieldNbRecords_(CField* field); 
     34    virtual void readFieldData_(CField* field); 
     35    virtual void closeFile_(void); 
    2536 
     37  private: 
     38    /// Private attributes /// 
     39    MPI_Comm comm_file; 
     40    const StdString filename; 
     41    bool isCollective; 
     42  }; // class CNc4DataInput 
    2643} // namespace xios 
    2744 
  • XIOS/trunk/src/node/field.cpp

    r598 r599  
    2323      , grid(), file() 
    2424      , freq_operation(), freq_write() 
    25       , nstep(0) 
     25      , nstep(0), nstepMax(0), isEOF(false) 
    2626      , last_Write(), last_operation() 
    2727      , foperation(), hasInstantData(false), hasExpression(false) 
     
    3636      , grid(), file() 
    3737      , freq_operation(), freq_write() 
    38       , nstep(0) 
     38      , nstep(0), nstepMax(0), isEOF(false) 
    3939      , last_Write(), last_operation() 
    4040      , foperation(), hasInstantData(false), hasExpression(false) 
     
    267267    if (!getRelFile()->allDomainEmpty) 
    268268    { 
    269       if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) //      if (! grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file) 
     269      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) 
    270270      { 
    271271        getRelFile()->checkFile(); 
     
    329329    std::list<CMessage> msgs; 
    330330 
    331     // TODO: Read the data from the file 
    332     if (data_srv.empty()) 
    333     { 
    334       for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it) 
    335         data_srv.insert( pair<int, CArray<double,1>* >(it->first, new CArray<double,1>(it->second->numElements()))); 
    336     } 
     331    bool hasData = readField(); 
    337332 
    338333    map<int, CArray<double,1>* >::iterator it; 
     
    341336      msgs.push_back(CMessage()); 
    342337      CMessage& msg = msgs.back(); 
    343       msg << getId() << getNStep() << *it->second; 
     338      msg << getId(); 
     339      if (hasData) 
     340        msg << getNStep() - 1 << *it->second; 
     341      else 
     342        msg << SIZE_MAX; 
    344343      event.push(it->first, grid->nbSenders[it->first], msg); 
    345344    } 
    346345    client->sendEvent(event); 
    347  
    348     incrementNStep(); 
     346  } 
     347 
     348  bool CField::readField(void) 
     349  { 
     350    if (!getRelFile()->allDomainEmpty) 
     351    { 
     352      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) 
     353      { 
     354        if (data_srv.empty()) 
     355        { 
     356          for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it) 
     357            data_srv.insert(pair<int, CArray<double,1>*>(it->first, new CArray<double,1>(it->second->numElements()))); 
     358        } 
     359 
     360        getRelFile()->checkFile(); 
     361        this->incrementNStep(); 
     362 
     363        if (!nstepMax) 
     364        { 
     365          nstepMax = getRelFile()->getDataInput()->getFieldNbRecords(CField::get(this)); 
     366        } 
     367 
     368        if (getNStep() > nstepMax) 
     369          return false; 
     370 
     371        getRelFile()->getDataInput()->readFieldData(CField::get(this)); 
     372      } 
     373    } 
     374 
     375    return true; 
    349376  } 
    350377 
     
    373400    { 
    374401      int rank = ranks[i]; 
    375       CArray<int,1>& index = *grid->storeIndex_toSrv[rank]; 
    376       CArray<double,1> data_tmp(index.numElements()); 
    377       *buffers[i] >> record >> data_tmp; 
    378  
    379       for (int n = 0; n < data_tmp.numElements(); n++) 
    380         instantData(index(n)) = data_tmp(n); 
    381     } 
    382  
    383     for (list< pair<CField*, int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it) 
    384       it->first->setSlot(it->second); 
    385  
    386     if (!hasExpression) // Should be always true ? 
    387     { 
    388       const std::vector<CField*>& refField = getAllReference(); 
    389       std::vector<CField*>::const_iterator it = refField.begin(), end = refField.end(); 
    390  
    391       for (; it != end; it++) (*it)->setDataFromExpression(instantData); 
    392       if (hasFieldOut) updateDataFromExpression(instantData); 
     402      *buffers[i] >> record; 
     403      isEOF = (record == SIZE_MAX); 
     404 
     405      if (!isEOF) 
     406      { 
     407        CArray<int,1>& index = *grid->storeIndex_toSrv[rank]; 
     408        CArray<double,1> data_tmp(index.numElements()); 
     409        *buffers[i] >> data_tmp; 
     410        for (int n = 0; n < data_tmp.numElements(); n++) 
     411          instantData(index(n)) = data_tmp(n); 
     412      } 
     413      else 
     414        break; 
     415    } 
     416 
     417    if (!isEOF) 
     418    { 
     419      for (list< pair<CField*, int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it) 
     420        it->first->setSlot(it->second); 
     421 
     422      if (!hasExpression) // Should be always true ? 
     423      { 
     424        const std::vector<CField*>& refField = getAllReference(); 
     425        std::vector<CField*>::const_iterator it = refField.begin(), end = refField.end(); 
     426 
     427        for (; it != end; it++) (*it)->setDataFromExpression(instantData); 
     428        if (hasFieldOut) updateDataFromExpression(instantData); 
     429      } 
    393430    } 
    394431 
     
    437474   { 
    438475      this->nstep = 0; 
     476   } 
     477 
     478   void CField::resetNStepMax(void) 
     479   { 
     480      this->nstepMax = 0; 
    439481   } 
    440482 
     
    761803   } 
    762804 
     805   void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset) 
     806   { 
     807     map<int, CArray<double,1>* >::iterator it; 
     808     for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = *it->second * scaleFactor + addOffset; 
     809   } 
     810 
    763811   void CField::outputField(CArray<double,3>& fieldOut) 
    764812   { 
     
    786834      { 
    787835         grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ; 
     836      } 
     837   } 
     838 
     839   void CField::inputField(CArray<double,3>& fieldOut) 
     840   { 
     841      map<int, CArray<double,1>*>::iterator it; 
     842      for (it = data_srv.begin(); it != data_srv.end(); it++) 
     843      { 
     844        grid->inputField(it->first, fieldOut.dataFirst(), *it->second); 
     845      } 
     846   } 
     847 
     848   void CField::inputField(CArray<double,2>& fieldOut) 
     849   { 
     850      map<int, CArray<double,1>*>::iterator it; 
     851      for(it = data_srv.begin(); it != data_srv.end(); it++) 
     852      { 
     853         grid->inputField(it->first, fieldOut.dataFirst(), *it->second); 
     854      } 
     855   } 
     856 
     857   void CField::inputField(CArray<double,1>& fieldOut) 
     858   { 
     859      map<int, CArray<double,1>*>::iterator it; 
     860      for (it = data_srv.begin(); it != data_srv.end(); it++) 
     861      { 
     862         grid->inputField(it->first, fieldOut.dataFirst(), *it->second); 
    788863      } 
    789864   } 
  • XIOS/trunk/src/node/field.hpp

    r598 r599  
    8989         void incrementNStep(void); 
    9090         void resetNStep() ; 
     91         void resetNStepMax(); 
    9192 
    9293         template <int N> bool updateData(const CArray<double, N>&   data); 
     
    138139        static void recvReadDataRequest(CEventServer& event); 
    139140        void recvReadDataRequest(void); 
     141        bool readField(void); 
    140142        static void recvReadDataReady(CEventServer& event); 
    141143        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); 
     
    143145        void outputField(CArray<double,2>& fieldOut) ; 
    144146        void outputField(CArray<double,1>& fieldOut) ; 
     147        void inputField(CArray<double,3>& fieldOut); 
     148        void inputField(CArray<double,2>& fieldOut); 
     149        void inputField(CArray<double,1>& fieldOut); 
    145150        void scaleFactorAddOffset(double scaleFactor, double addOffset) ; 
     151        void invertScaleFactorAddOffset(double scaleFactor, double addOffset); 
    146152        void parse(xml::CXMLNode & node) ; 
    147153        CArray<double,1>* getInstantData(void)  ; 
     
    176182         CDuration freq_operation_srv, freq_write_srv; 
    177183 
    178          StdSize nstep; 
     184         StdSize nstep, nstepMax; 
     185         bool isEOF; 
    179186         boost::shared_ptr<CDate>    last_Write, last_operation; 
    180187         boost::shared_ptr<CDate>    lastlast_Write_srv,last_Write_srv, last_operation_srv; 
  • XIOS/trunk/src/node/field_impl.hpp

    r598 r599  
    190190        context->checkBuffersAndListen(); 
    191191 
     192      if (isEOF) 
     193        ERROR("void CField::getData(CArray<double, N>& _data) const", 
     194              << "Impossible to access field data, all the records of the field [ id = " << getId() << " ] have been already read."); 
     195 
    192196      grid->outputField(instantData, _data); 
    193197    } 
  • XIOS/trunk/src/node/file.cpp

    r598 r599  
    55#include "group_template.hpp" 
    66#include "object_factory.hpp" 
    7 #include "data_output.hpp" 
    87#include "context.hpp" 
    98#include "context_server.hpp" 
    109#include "nc4_data_output.hpp" 
     10#include "nc4_data_input.hpp" 
    1111#include "calendar_util.hpp" 
    1212#include "date.hpp" 
     
    4848   //---------------------------------------------------------------- 
    4949   /*! 
    50    \brief Get data that will be written out. 
     50   \brief Get data writer object. 
    5151   Each enabled file in xml represents a physical netcdf file. 
    52    This function allows to access to data to be written out into netcdf file 
    53    \return data written out. 
     52   This function allows to access the data writer object. 
     53   \return data writer object. 
    5454   */ 
    5555   boost::shared_ptr<CDataOutput> CFile::getDataOutput(void) const 
    5656   { 
    57       return (data_out); 
     57      return data_out; 
     58   } 
     59 
     60   /*! 
     61   \brief Get data reader object. 
     62   Each enabled file in xml represents a physical netcdf file. 
     63   This function allows to access the data reader object. 
     64   \return data reader object. 
     65   */ 
     66   boost::shared_ptr<CDataInput> CFile::getDataInput(void) const 
     67   { 
     68      return data_in; 
    5869   } 
    5970 
     
    239250    void CFile::checkFile(void) 
    240251    { 
    241       if (!isOpen) createHeader() ; 
    242       checkSync() ; 
    243       checkSplit() ; 
     252      if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
     253      { 
     254        if (!isOpen) createHeader(); 
     255        checkSync(); 
     256      } 
     257      else 
     258      { 
     259        if (!isOpen) openInReadMode(); 
     260      } 
     261      checkSplit(); 
    244262    } 
    245  
    246263 
    247264    /*! 
     
    283300          *lastSplit = *lastSplit + split_freq.getValue(); 
    284301          std::vector<CField*>::iterator it, end = this->enabledFields.end(); 
    285           for (it = this->enabledFields.begin() ;it != end; it++)  (*it)->resetNStep() ; 
    286           createHeader() ; 
     302          for (it = this->enabledFields.begin(); it != end; it++) 
     303          { 
     304            (*it)->resetNStep(); 
     305            (*it)->resetNStepMax(); 
     306          } 
     307          if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
     308            createHeader() ; 
     309          else 
     310            openInReadMode(); 
    287311          return true ; 
    288312        } 
     
    398422   } 
    399423 
     424  /*! 
     425  \brief Open an existing NetCDF file in read-only mode 
     426  */ 
     427  void CFile::openInReadMode(void) 
     428  { 
     429    CContext* context = CContext::getCurrent(); 
     430    CContextServer* server=context->server; 
     431 
     432    if (!allDomainEmpty) 
     433    { 
     434      StdString filename = (!name.isEmpty()) ? name.getValue() : getId(); 
     435      StdOStringStream oss; 
     436      oss << filename; 
     437      if (!name_suffix.isEmpty()) oss << name_suffix.getValue(); 
     438 
     439      if (!split_freq.isEmpty()) 
     440      { 
     441        string splitFormat; 
     442        if (split_freq_format.isEmpty()) 
     443        { 
     444          if (split_freq.getValue().second != 0) splitFormat = "%y%mo%d%h%mi%s"; 
     445          else if (split_freq.getValue().minute != 0) splitFormat = "%y%mo%d%h%mi"; 
     446          else if (split_freq.getValue().hour != 0) splitFormat = "%y%mo%d%h"; 
     447          else if (split_freq.getValue().day != 0) splitFormat = "%y%mo%d"; 
     448          else if (split_freq.getValue().month != 0) splitFormat = "%y%mo"; 
     449          else splitFormat = "%y"; 
     450        } 
     451        else splitFormat=split_freq_format; 
     452        oss << "_" << lastSplit->getStr(splitFormat) 
     453        << "-" << (*lastSplit + split_freq.getValue() - 1 * Second).getStr(splitFormat); 
     454      } 
     455 
     456      bool multifile = true; 
     457      if (!type.isEmpty()) 
     458      { 
     459        if (type == type_attr::one_file) multifile = false; 
     460        else if (type == type_attr::multiple_file) multifile = true; 
     461      } 
     462  #ifndef USING_NETCDF_PAR 
     463      if (!multifile) 
     464      { 
     465        info(0) << "!!! Warning -> Using non parallel version of netcdf, switching in multiple_file mode for file : " << filename << " ..." << endl; 
     466        multifile = true; 
     467      } 
     468  #endif 
     469      if (multifile) 
     470      { 
     471        int commSize, commRank; 
     472        MPI_Comm_size(fileComm, &commSize); 
     473        MPI_Comm_rank(fileComm, &commRank); 
     474 
     475        if (server->intraCommSize > 1) 
     476        { 
     477          oss << "_" ; 
     478          int width = 0, n = commSize - 1; 
     479          while (n != 0) { n = n / 10; width++; } 
     480          if (!min_digits.isEmpty() && width < min_digits) 
     481            width = min_digits; 
     482          oss.width(width); 
     483          oss.fill('0'); 
     484          oss << right << commRank; 
     485        } 
     486      } 
     487      oss << ".nc"; 
     488 
     489      bool isCollective = par_access.isEmpty() || par_access == par_access_attr::collective; 
     490 
     491      if (isOpen) data_out->closeFile(); 
     492 
     493      data_in = shared_ptr<CDataInput>(new CNc4DataInput(oss.str(), fileComm, multifile, isCollective)); 
     494      isOpen = true; 
     495    } 
     496  } 
     497 
    400498   //! Close file 
    401499   void CFile::close(void) 
     
    406504       if (isOpen) 
    407505       { 
    408          this->data_out->closeFile(); 
     506         if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
     507          this->data_out->closeFile(); 
     508         else 
     509          this->data_in->closeFile(); 
    409510       } 
    410511      if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm) ; 
  • XIOS/trunk/src/node/file.hpp

    r598 r599  
    66#include "field.hpp" 
    77#include "data_output.hpp" 
     8#include "data_input.hpp" 
    89#include "declare_group.hpp" 
    910#include "date.hpp" 
     
    6970         /// Accesseurs /// 
    7071         boost::shared_ptr<CDataOutput> getDataOutput(void) const; 
     72         boost::shared_ptr<CDataInput> getDataInput(void) const; 
    7173         CFieldGroup* getVirtualFieldGroup(void) const; 
    7274         CVariableGroup* getVirtualVariableGroup(void) const; 
     
    9496 
    9597         void createHeader(void); 
     98         void openInReadMode(void); 
    9699         void close(void) ; 
    97100 
     
    162165         CVariableGroup* vVariableGroup ; 
    163166         boost::shared_ptr<CDataOutput> data_out; 
     167         boost::shared_ptr<CDataInput> data_in; 
    164168         std::vector<CField*> enabledFields; 
    165169 
  • XIOS/trunk/src/node/grid.cpp

    r598 r599  
    507507   } 
    508508 
     509   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored) 
     510   { 
     511     CArray<size_t,1>& out_i = *outIndexFromClient[rank]; 
     512     StdSize numElements = stored.numElements(); 
     513     for (StdSize n = 0; n < numElements; ++n) 
     514     { 
     515       stored(n) = *(field+out_i(n)); 
     516     } 
     517   } 
     518 
    509519   //---------------------------------------------------------------- 
    510520 
  • XIOS/trunk/src/node/grid.hpp

    r598 r599  
    106106                               CArray<double, 1>&  storedServer) const; 
    107107 
    108          void outputField(int rank, const CArray<double,1>& stored,  CArray<double,3>& field)  ; 
    109          void outputField(int rank, const CArray<double,1>& stored,  CArray<double,2>& field)  ; 
    110          void outputField(int rank, const CArray<double,1>& stored,  CArray<double,1>& field)  ; 
    111          void outputField(int rank, const CArray<double,1>& stored,  double* field); 
     108         void outputField(int rank, const CArray<double,1>& stored, double* field); 
     109         void inputField(int rank, const double* const field, CArray<double,1>& stored); 
    112110 
    113111         virtual void parse(xml::CXMLNode & node); 
  • XIOS/trunk/src/output/onetcdf4.hpp

    r591 r599  
    1 #ifndef __XIOS_INETCDF4__ 
    2 #define __XIOS_INETCDF4__ 
     1#ifndef __XIOS_ONETCDF4__ 
     2#define __XIOS_ONETCDF4__ 
    33 
    44/// XIOS headers /// 
     
    130130} // namespace xios 
    131131 
    132 #endif //__XIOS_INETCDF4__ 
     132#endif //__XIOS_ONETCDF4__ 
Note: See TracChangeset for help on using the changeset viewer.