Index: /XIOS/trunk/src/input/inetcdf4.cpp
===================================================================
--- /XIOS/trunk/src/input/inetcdf4.cpp	(revision 598)
+++ /XIOS/trunk/src/input/inetcdf4.cpp	(revision 599)
@@ -1,3 +1,4 @@
 #include "inetcdf4.hpp"
+#include "netCdfInterface.hpp"
 
 #include <boost/algorithm/string.hpp>
@@ -5,784 +6,809 @@
 namespace xios
 {
-      /// ////////////////////// DÃ©finitions ////////////////////// ///
-      CINetCDF4::CINetCDF4(const StdString & filename)
-      {
-         CheckError(nc_open(filename.c_str(), NC_NOWRITE, &this->ncidp));
-      }
-
-      CINetCDF4::~CINetCDF4(void)
-      {
-          CheckError(nc_close(this->ncidp));
-      }
-
-      ///--------------------------------------------------------------
-
-      void CINetCDF4::CheckError(int status)
-      {
-         if (status != NC_NOERR)
-         {
-            StdString errormsg (nc_strerror(status)); // fuite mÃ©moire ici ?
-            ERROR("CINetCDF4::CheckError(int status)",
-                  << "[ status = " << status << " ] " << errormsg);
-         }
-      }
-
-      //---------------------------------------------------------------
-
-      int CINetCDF4::getGroup(const CVarPath * const path)
-      {
-         int retvalue = this->ncidp;
-         if (path == NULL) return (retvalue);
-         CVarPath::const_iterator it = path->begin(), end = path->end();
-         
-         for (; it != end; it++)
-         {
-            const StdString & groupid = *it;
-            CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
-         }       
-            
-         return (retvalue);
-      }
-
-      int CINetCDF4::getVariable(const StdString & varname,
-                                 const CVarPath * const path)
-      {
-         int varid = 0;
-         int grpid = this->getGroup(path);
-         CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
-         return (varid);
-      }
-
-      int CINetCDF4::getDimension(const StdString & dimname,
-                                  const CVarPath  * const path)
-      {
-         int dimid = 0;
-         int grpid = this->getGroup(path);
-         CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
-         return (dimid);
-      }
-
-      std::pair<nc_type, StdSize> CINetCDF4::getAttribute
-                                 (const StdString & attname,
-                                  const StdString * const var,
-                                  const CVarPath  * const path)
-      {
-         std::pair<nc_type, StdSize> retvalue;
-         int grpid = this->getGroup(path);
-         int varid = (var != NULL)
-                   ? this->getVariable(*var, path) : NC_GLOBAL;
-         CheckError(nc_inq_att(grpid, varid, attname.c_str(),
-                              &retvalue.first, &retvalue.second));
-         return (retvalue);
-      }
-
-      int CINetCDF4::getUnlimitedDimension(const CVarPath  * const path)
-      {
-         int dimid = 0;
-         int grpid = this->getGroup(path);
-         CheckError(nc_inq_unlimdim (grpid, &dimid));
-         return (dimid);
-      }
-
-      StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath  * const path)
-      {
-         char full_name_in[NC_MAX_NAME +1];
-         int grpid = this->getGroup(path);
-         int dimid = this->getUnlimitedDimension(path);
-         CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
-
-         StdString dimname(full_name_in);
-         return (dimname);
-      }
-
-      //---------------------------------------------------------------
-      StdSize CINetCDF4::getNbVertex(const StdString & name,
-                                     const CVarPath  * const path)
-      {
-
-         if (this->isRectilinear(name, path) ||
-             this->isCurvilinear(name, path))
-         {
-            if (this->is3Dim(name, path)) return (8);
-            else return (4);
-         }
-         if (this->isUnstructured(name, path))
-         {
-            StdString bound = this->getBoundsId
-                     (this->getCoordinatesIdList(name, path).back(), path);
-            StdString dim = this->getDimensionsList(&bound, path).back();
-            return (this->getDimensions(&bound, path)[dim]);
-         }
-         return ((size_t)(-1));
-      }
-
-      //---------------------------------------------------------------
-
-      std::list<StdString> CINetCDF4::getGroups(const CVarPath * const path)
-      {
-         StdSize strlen = 0;
-         char full_name_in[NC_MAX_NAME +1];
-         int nbgroup = 0, *groupid = NULL;
-         int grpid = this->getGroup(path);
-         std::list<StdString> retvalue;
-
-         CheckError(nc_inq_grps(grpid, &nbgroup, NULL));
-         groupid = new int[nbgroup]();
-         CheckError(nc_inq_grps(grpid, NULL, groupid));
-
-         for (int i = 0; i < nbgroup; i++)
-         {
-            CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in));
-            StdString groupname(full_name_in, strlen);
-            retvalue.push_back(groupname);
-         }
-
-         delete [] groupid;
-         return (retvalue);
-      }
-
-      std::list<StdString> CINetCDF4::getVariables(const CVarPath * const path)
-      {
-         char full_name_in[NC_MAX_NAME +1];
-         int nbvar = 0, *varid = NULL;
-         int grpid = this->getGroup(path);
-         std::list<StdString> retvalue;
-
-         CheckError(nc_inq_varids(grpid, &nbvar, NULL));
-         varid = new int[nbvar]();
-         CheckError(nc_inq_varids(grpid, NULL, varid));
-
-         for (int i = 0; i < nbvar; i++)
-         {
-            CheckError(nc_inq_varname(grpid, varid[i], full_name_in));
-            StdString varname(full_name_in);
-            retvalue.push_back(varname);
-         }
-
-         delete [] varid;
-         return (retvalue);
-      }
-
-      StdSize CINetCDF4::getNbOfTimestep(const CVarPath * const path)
-      {
-         return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]);
-      }
-
-      std::set<StdString> CINetCDF4::getBoundVariables(const CVarPath * const path)
-      {
-         std::set<StdString> retvalue;         
-         std::list<StdString> variables = this->getVariables(path);
-         std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
-         for (; it != end; it++)
-         {
-            const StdString & var = *it;
-            if (this->hasBounds(var, path))
-               retvalue.insert(retvalue.end(), this->getBoundsId(var, path));
-         }
-         return (retvalue);
-      }
-
-      std::set<StdString> CINetCDF4::getCoordVariables(const CVarPath * const path)
-      {
-         std::set<StdString> retvalue;
-         std::list<StdString> variables = this->getVariables(path);
-         std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
-         for (; it != end; it++)
-         {
-            const StdString & var = *it;
-            std::list<StdString> coords = this->getCoordinatesIdList(var, path);
-            std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-            for (; it != end; it++)
-            {
-               const StdString & coord = *it;
-               if (this->hasVariable(coord, path))
-                  retvalue.insert(retvalue.end(), coord);
-            }
-         }
-         return (retvalue);
-      }
-
-      std::list<StdString> CINetCDF4::getDimensionsList
-                  (const StdString * const var, const CVarPath  * const path)
-      {
-         char full_name_in[NC_MAX_NAME +1];
-         int nbdim = 0, *dimid = NULL;
-         int grpid = this->getGroup(path);
-         int varid = (var != NULL)
-                   ? this->getVariable(*var, path) : NC_GLOBAL;
-         std::list<StdString> retvalue;
-
-         if (var != NULL)
-         {
-            CheckError(nc_inq_varndims(grpid, varid, &nbdim));
-            dimid = new int[nbdim]();
-            CheckError(nc_inq_vardimid(grpid, varid, dimid));
-         }
-         else
-         {
-            CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
-            dimid = new int[nbdim]();
-            CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
-         }
-
-         for (int i = 0; i < nbdim; i++)
-         {
-            CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
-            StdString dimname(full_name_in);
-            retvalue.push_back(dimname);
-         }
-         delete [] dimid;
-
-         return (retvalue);
-      }
-
-      std::map<StdString, StdSize> CINetCDF4::getDimensions
-                  (const StdString * const var, const CVarPath  * const path)
-      {
-         StdSize size = 0;
-         char full_name_in[NC_MAX_NAME +1];
-         int nbdim = 0, *dimid = NULL;
-         int grpid = this->getGroup(path);
-         int varid = (var != NULL)
-                   ? this->getVariable(*var, path) : NC_GLOBAL;
-         std::map<StdString, StdSize> retvalue;
-
-         if (var != NULL)
-         {
-            CheckError(nc_inq_varndims(grpid, varid, &nbdim));
-            dimid = new int[nbdim]();
-            CheckError(nc_inq_vardimid(grpid, varid, dimid));
-         }
-         else
-         {
-            CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
-            dimid = new int[nbdim]();
-            CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
-         }
-
-         for (int i = 0; i < nbdim; i++)
-         {
-            CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
-            CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
-
-            StdString dimname(full_name_in);
-            retvalue.insert(retvalue.end(), std::make_pair(dimname, size));
-         }
-         delete [] dimid;
-
-         return (retvalue);
-      }
-
-      std::list<StdString> CINetCDF4::getAttributes
-               (const StdString * const var, const CVarPath  * const path )
-      {
-         int nbatt = 0;
-         char full_name_in[NC_MAX_NAME +1];
-         std::list<StdString> retvalue;
-         int grpid = this->getGroup(path);
-         int varid = (var != NULL)
-                   ? this->getVariable(*var, path) : NC_GLOBAL;
-
-         if (var != NULL)
-            CheckError(nc_inq_varnatts (grpid, varid, &nbatt));
-         else
-            CheckError(nc_inq_natts(grpid, &nbatt));
-
-         for (int i = 0; i < nbatt; i++)
-         {
-            CheckError(nc_inq_attname(grpid, varid, i, full_name_in));
-            StdString attname(full_name_in);
-            retvalue.push_back(attname);
-         }
-         return (retvalue);
-      }
-
-      int CINetCDF4::getAttributeId(const StdString & name,
-                                    const StdString * const var,
-                                    const CVarPath  * const path)
-      {
-         int retvalue = 0;
-         std::list<StdString> atts = this->getAttributes(var, path);
-         std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
-         for (; it != end; it++)
-         {
-            const StdString & attname = *it;
-            if (attname.compare(name) == 0)
-               return (retvalue);
-            retvalue++;
-         }
-         return (-1);
-      }
-
-      //---------------------------------------------------------------
-
-      bool CINetCDF4::hasMissingValue(const StdString & name,
-                                      const CVarPath  * const path)
-      {
-         return (this->hasAttribute("missing_value", &name, path) ||
-                 this->hasAttribute("_FillValue", &name, path));
-      }
-
-      bool CINetCDF4::hasAttribute(const StdString & name,
-                                   const StdString * const var ,
-                                   const CVarPath  * const path)
-      {
-         std::list<StdString> atts = this->getAttributes(var, path);
-         std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
-         for (; it != end; it++)
-         {
-            const StdString & attname = *it;
-            if (attname.compare(name) == 0) return (true);
-         }
-         return (false);
-      }
-
-      bool CINetCDF4::hasVariable(const StdString & name,
-                                  const CVarPath  * const path)
-      {
-         std::list<StdString> variables = this->getVariables(path);
-         std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
-         for (; it != end; it++)
-         {
-            const StdString & varname = *it;
-            if (varname.compare(name) == 0) return (true);
-         }
-         return (false);
-      }
-
-      bool CINetCDF4::hasCoordinates(const StdString & name,
-                                     const CVarPath  * const path)
-      {
-         return (this->hasAttribute("coordinates", &name, path));
-      }
-
-      bool CINetCDF4::hasBounds(const StdString & name,
-                                const CVarPath  * const path)
-      {
-         return (this->hasAttribute("bounds", &name, path));
-      }
-
-      bool CINetCDF4::hasTemporalDim(const CVarPath  * const path)
-      {
-         return (this->getUnlimitedDimension(path) != -1);
-      }
-
-      //---------------------------------------------------------------
-
-#define GET_ATTRIBUTE_VALUE(type, func_ext, type_enum)                     \
-      template <>                                                          \
-         std::vector<type> CINetCDF4::getAttributeValue                    \
-            (const StdString & name, const StdString * const var,          \
-                                     const CVarPath  * const path)         \
-      {                                                                    \
-         int grpid = this->getGroup(path);                                 \
-         int varid = (var != NULL)                                         \
-                   ? this->getVariable(*var, path) : NC_GLOBAL;            \
-         std::pair<nc_type , StdSize> attinfos =                           \
-                     this->getAttribute(name, var, path);                  \
-         std::vector<type> retvalue(attinfos.second);                      \
-         if (attinfos.first != type_enum)                                  \
-            ERROR("CINetCDF4::getAttributeValue<double>(name, var, path",  \
-                  << "[ name : "          << name                          \
-                  << ", type requested :" << attinfos.first                \
-                  << ", type stored : "   << type_enum      << "]"         \
-                  << " Invalid type !");                                   \
-         CheckError(nc_get_att_##func_ext                                  \
-                        (grpid, varid, name.c_str(), &(retvalue[0])));     \
-         return (retvalue);                                                \
-      }
-
-      GET_ATTRIBUTE_VALUE(double, double, NC_DOUBLE)
-      GET_ATTRIBUTE_VALUE(float , float , NC_FLOAT)
-      GET_ATTRIBUTE_VALUE(int   , int   , NC_INT)
-      GET_ATTRIBUTE_VALUE(char  , text  , NC_CHAR)
-
-      template <>
-         StdString CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path)
-      {
-         std::vector<char> chart = this->getAttributeValue
-                        <std::vector<char> >(name, var, path);
-         StdString retvalue(&(chart[0]), chart.size());
-         return (retvalue);
-      }
-
-      template <>
-         int CINetCDF4::getMissingValue(const StdString & name,
-                                        const CVarPath  * const path)
-      {
-         if (this->hasAttribute("missing_value", &name, path))
-            return (this->getAttributeValue<std::vector<int> >("missing_value", &name, path)[0]);
-         if (this->hasAttribute("_FillValue", &name, path))
-            return (this->getAttributeValue<std::vector<int> >("_FillValue", &name, path)[0]);
-         return (0);
-      }
-
-      template <>
-         double CINetCDF4::getMissingValue(const StdString & name,
-                                           const CVarPath  * const path)
-      {
-         if (this->hasAttribute("missing_value", &name, path))
-            return (this->getAttributeValue<std::vector<double> >("missing_value", &name, path)[0]);
-         if (this->hasAttribute("_FillValue", &name, path))
-            return (this->getAttributeValue<std::vector<double> >("_FillValue", &name, path)[0]);
-         return (0);
-      }
-
-      template <>
-         float CINetCDF4::getMissingValue(const StdString & name,
-                                          const CVarPath  * const path)
-      {
-         if (this->hasAttribute("missing_value", &name, path))
-            return (this->getAttributeValue<std::vector<float> >("missing_value", &name, path)[0]);
-         if (this->hasAttribute("_FillValue", &name, path))
-            return (this->getAttributeValue<std::vector<float> >("_FillValue", &name, path)[0]);
-         return (0);
-      }
-      
-      //---------------------------------------------------------------
-      
-      std::list<StdString> CINetCDF4::getCoordinatesIdList
-         (const StdString & name, const CVarPath  * const path)
-      {
-         std::list<StdString> retvalue;
-         StdString value = this->getCoordinatesId(name, path);
-         
-         boost::split(retvalue, value, boost::is_any_of(" "));
-         
-         std::list<StdString>::iterator it = retvalue.begin(), end = retvalue.end();
-         for (; it != end; it++)
-         {
-            StdString & coord = *it;
-            coord.assign(coord.data());
-         }
-         return (retvalue);
-      }
-
-      StdString CINetCDF4::getCoordinatesId
-         (const StdString & name, const CVarPath  * const path)
-      {
-         StdString retvalue;
-         if (this->hasAttribute("coordinates", &name, path))
-         {
-            return (this->getAttributeValue<StdString>("coordinates", &name, path));
-         }
-         else
-         {
-            std::list<StdString> dims = this->getDimensionsList(&name, path);
-            std::list<StdString>::const_iterator it = dims.begin(), end = dims.end();
-            for (; it != end; it++)
-            {
-               const StdString & value = *it;               
-               retvalue.append(value).push_back(' ');
-            }
-            retvalue.erase (retvalue.end()-1) ;
-         }
-
-         return (retvalue);
-      }
-
-      StdString CINetCDF4::getBoundsId(const StdString & name,
-                                       const CVarPath  * const path)
-      {
-         StdString retvalue;
-         if (this->hasAttribute("bounds", &name, path))
-            return (this->getAttributeValue<StdString>("bounds", &name, path));
-         return (retvalue);
-      }
-
-      //---------------------------------------------------------------
-
-      bool CINetCDF4::isBound(const StdString & name,
-                              const CVarPath  * const path)
-      {
-         std::set<StdString> bounds = this->getBoundVariables(path);
-         return (bounds.find(name) != bounds.end());
-      }
-
-      bool CINetCDF4::isCoordinate(const StdString & name,
-                                   const CVarPath  * const path)
-      {
-         std::set<StdString> coords = this->getCoordVariables(path);
-         return (coords.find(name) != coords.end());
-      }
-
-      bool CINetCDF4::isRectilinear(const StdString & name, const CVarPath  * const path)
-      {
-         std::list<StdString> coords = this->getCoordinatesIdList(name, path);
-         std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-         for (; it != end; it++)
-         {
-            const StdString & coord = *it;
-            if (this->hasVariable(coord, path) && !this->isTemporal(coord, path))
-            {
-               std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
-               if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end()))
-                  continue;
-               else
-                  return (false);
-            }
-         }
-         return (true);
-      }
-
-      bool CINetCDF4::isCurvilinear(const StdString & name, const CVarPath  * const path)
-      {
-         if (this->isRectilinear(name, path) ||
-            !this->hasCoordinates(name, path))
-            return (false);
-
-         std::list<StdString> coords = this->getCoordinatesIdList(name, path);
-         std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-         for (; it != end; it++)
-         {
-            const StdString & coord = *it;
-            if (this->hasVariable(coord, path))
-            {
-               std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
-               if (dimvar.size() != 2) return (false);
-            }
-            else return (false);
-         }
-         return (true);
-      }
-
-      bool CINetCDF4::isUnstructured(const StdString & name, const CVarPath  * const path)
-      {
-         if (this->isRectilinear(name, path)    ||
-             this->isCurvilinear(name, path)    ||
-             !this->hasCoordinates(name, path))
-             return (false);
-
-         StdString dimname = this->getDimensionsList(&name, path).back();
-
-         std::list<StdString> coords = this->getCoordinatesIdList(name, path);
-         std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-         for (; it != end; it++)
-         {
-            const StdString & coord = *it;
-            if (this->hasVariable(coord, path))
-            {
-               std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
-               if ((dimvar.size() == 1) &&
-                   (dimvar.find(dimname) != dimvar.end()))
-                  continue;
-               else
-                  return (false);
-            }
-            else return (false);
-         }
-
-         return (true);
-      }
-
-      bool CINetCDF4::isUnknown(const StdString & name, const CVarPath * const path)
-      {
-         return !(this->isRectilinear(name, path) ||
-                  this->isCurvilinear(name, path) ||
-                  this->isUnstructured(name, path));
-      }
-
-      bool CINetCDF4::isTemporal(const StdString & name, const CVarPath  * const path)
-      {
-         if (!this->hasTemporalDim(path)) return (false);
-         std::map<StdString, StdSize> dims = this->getDimensions(&name, path);
-         if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end())
-            return (true);
-         return (false);
-      }
-
-      bool CINetCDF4::is3Dim(const StdString & name, const CVarPath  * const path)
-      {
-         int i = 0;
-         std::list<StdString> coords = this->getCoordinatesIdList(name, path);
-         std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-         for (; it != end; it++)
-         {
-            const StdString & coord = *it;
-            if (this->hasVariable(coord, path))
-            {
-               if (this->isTemporal(coord, path))
-                  continue;
-               i++;
-            }
-            else
-            {
-               if (coord.compare(this->getUnlimitedDimensionName()) == 0)
-                  continue;
-               i++;
-            }
-         }
-         return (i == 3);
-      }
-
-      bool CINetCDF4::isCellGrid(const StdString & name, const CVarPath  * const path)
-      {
-         if (this->isCoordinate(name, path))
-         {
-            return (this->hasBounds(name, path));
-         }
-         else
-         {
-            std::list<StdString> coords = this->getCoordinatesIdList(name, path);
-            std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
-            for (; it != end; it++)
-            {
-               const StdString & coord = *it;
-               if (this->hasVariable(coord, path))
-               {
-                  if (this->isTemporal(coord, path))
-                     continue;
-                  if (this->isCellGrid(coord, path))
-                     continue;
-                  return (false);
-               }
-               else
-               {
-                  if (coord.compare(this->getUnlimitedDimensionName()) == 0)
-                     continue;
-                  return (false);
-               }
-            }
-         }
-
-         return (true);
-      }
-
-      //---------------------------------------------------------------
-
-      std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti,
-                                                       bool _isCurvi,    bool _isUnstr,
-                                                       bool _isCellData, bool _isTemporal,
-                                                       const CVarPath * const path)
-      {
-         std::list<StdString> retvalue;
-         std::list<StdString> allvars  = this->getVariables(path);
-         std::set<StdString> allcoords = this->getCoordVariables(path);
-
-         std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end();
-         for (; it != end; it++)
-         {
-            const StdString & var = *it;
-            if (this->isCoordinate(var, path)) continue;
-
-            if (!_isRecti && this->isRectilinear(var, path) ) continue;
-            if (!_isCurvi && this->isCurvilinear(var, path) ) continue;
-            if (!_isUnstr && this->isUnstructured(var, path)) continue;
-
-            if (!_isTemporal && this->isTemporal(var, path)) continue;
-            if (!_is3D       && this->is3Dim(var, path)    ) continue;
-            if (!_isCellData && this->isCellGrid(var, path)) continue;
-
-            if (this->isUnknown(var, path)) continue;
-
-            retvalue.push_back(var);
-         }
-         return (retvalue);
-      }
-
-      //---------------------------------------------------------------
-
-      void CINetCDF4::getDataInfo(const StdString & var, const CVarPath  * const path, StdSize record,
-                                  std::vector<StdSize> & start, std::vector<StdSize> & count,
-                                  StdSize & array_size)
-      {
-         std::list<StdString> dimlist        = this->getDimensionsList(&var, path);
-         std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path);
-         std::list<StdString>::iterator it   = dimlist.begin();
-         if (this->isTemporal(var, path))
-         {
-            if (record != UNLIMITED_DIM)
-               start.push_back(record);
-            else
-               start.push_back(0);
-            count.push_back(1);
-            it++;
-         }
-         for (; it != dimlist.end(); it++)
-         {
-            start.push_back(0);
-            count.push_back(dimmap[*it]);
-            array_size *= dimmap[*it];
-         }
-      }
-
-      template <>
-         void CINetCDF4::getData(CArray<int, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record)
-      {
-
-         std::vector<StdSize> start, count;
-         int grpid = this->getGroup(path);
-         int varid = this->getVariable(var, path);
-         StdSize array_size = 1;
-         this->getDataInfo(var, path, record, start, count, array_size);
-         data.resize(array_size);
-         CheckError(nc_get_vara_int (grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
-      }
-
-      template <>
-         void CINetCDF4::getData(CArray<double, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record)
-      {
-         std::vector<StdSize> start, count;
-         int grpid = this->getGroup(path);
-         int varid = this->getVariable(var, path);
-         StdSize array_size = 1;
-         this->getDataInfo(var, path, record, start, count, array_size);
-         data.resize(array_size);
-         CheckError(nc_get_vara_double (grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
-      }
-
-      template <>
-         void CINetCDF4::getData(CArray<float, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record)
-      {
-         std::vector<StdSize> start, count;
-         int grpid = this->getGroup(path);
-         int varid = this->getVariable(var, path);
-         StdSize array_size = 1;
-         this->getDataInfo(var, path, record, start, count, array_size);
-         data.resize(array_size);
-         CheckError(nc_get_vara_float (grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
-      }
-
-      //---------------------------------------------------------------
-      StdString CINetCDF4::getLonCoordName(const StdString & varname,
-                                           const CVarPath  * const path)
-      {
-         std::list<StdString> clist =
-            this->getCoordinatesIdList(varname, path);
-         if (this->hasCoordinates(varname, path))
-            return (*clist.begin());
-         else
-            return (*clist.rbegin());
-      }
-
-      StdString CINetCDF4::getLatCoordName(const StdString & varname,
-                                           const CVarPath  * const path)
-      {
-         std::list<StdString> clist =
-            this->getCoordinatesIdList(varname, path);
-         if (this->hasCoordinates(varname, path))
-            return (*(++clist.begin()));
-         else
-            return (*(++clist.rbegin()));
-      }
-
-      StdString CINetCDF4::getVertCoordName(const StdString & varname,
-                                            const CVarPath  * const path)
-      {
-         if (!this->is3Dim(varname, path)) return ("");
-         std::list<StdString> clist =
-            this->getCoordinatesIdList(varname, path);
-         if (this->hasCoordinates(varname, path))
-            return (*(++(++clist.begin())));
-         else
-            return (*(++(++clist.rbegin())));
-      }
-
-      ///--------------------------------------------------------------
-
+  CINetCDF4::CINetCDF4(const StdString& filename, const MPI_Comm* comm /*= NULL*/, bool multifile /*= true*/)
+    : mpi(comm != NULL && !multifile)
+  {
+    if (comm != NULL)
+    {
+      if (!multifile) CNetCdfInterface::openPar(filename, NC_NOWRITE, *comm, MPI_INFO_NULL, this->ncidp);
+      else CNetCdfInterface::open(filename, NC_NOWRITE, this->ncidp);
+    }
+      else CNetCdfInterface::open(filename, NC_NOWRITE, this->ncidp);
+  }
+
+  CINetCDF4::~CINetCDF4(void)
+  { /* Nothing to do */ }
+
+  ///--------------------------------------------------------------
+
+  void CINetCDF4::CheckError(int status)
+  {
+    if (status != NC_NOERR)
+    {
+      StdString errormsg(nc_strerror(status)); // fuite mÃ©moire ici ?
+      ERROR("CINetCDF4::CheckError(int status)",
+            << "[ status = " << status << " ] " << errormsg);
+    }
+  }
+
+  //---------------------------------------------------------------
+
+  void CINetCDF4::close(void)
+  {
+    CheckError(nc_close(this->ncidp));
+  }
+
+  //---------------------------------------------------------------
+
+  int CINetCDF4::getGroup(const CVarPath* const path)
+  {
+    int retvalue = this->ncidp;
+    if (path == NULL) return retvalue;
+    CVarPath::const_iterator it = path->begin(), end = path->end();
+
+    for (; it != end; it++)
+    {
+      const StdString& groupid = *it;
+      CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
+    }
+
+    return retvalue;
+  }
+
+  int CINetCDF4::getVariable(const StdString& varname,
+                             const CVarPath* const path)
+  {
+    int varid = 0;
+    int grpid = this->getGroup(path);
+    CheckError(nc_inq_varid(grpid, varname.c_str(), &varid));
+    return varid;
+  }
+
+  int CINetCDF4::getDimension(const StdString& dimname,
+                              const CVarPath* const path)
+  {
+    int dimid = 0;
+    int grpid = this->getGroup(path);
+    CheckError(nc_inq_dimid(grpid, dimname.c_str(), &dimid));
+    return dimid;
+  }
+
+  std::pair<nc_type, StdSize> CINetCDF4::getAttribute(const StdString& attname,
+                                                      const StdString* const var,
+                                                      const CVarPath* const path)
+  {
+    std::pair<nc_type, StdSize> retvalue;
+    int grpid = this->getGroup(path);
+    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
+    CheckError(nc_inq_att(grpid, varid, attname.c_str(),
+                          &retvalue.first, &retvalue.second));
+    return retvalue;
+  }
+
+  int CINetCDF4::getUnlimitedDimension(const CVarPath* const path)
+  {
+    int dimid = 0;
+    int grpid = this->getGroup(path);
+    CheckError(nc_inq_unlimdim(grpid, &dimid));
+    return dimid;
+  }
+
+  StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath* const path)
+  {
+    char full_name_in[NC_MAX_NAME +1];
+    int grpid = this->getGroup(path);
+    int dimid = this->getUnlimitedDimension(path);
+    CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
+
+    StdString dimname(full_name_in);
+    return dimname;
+  }
+
+  //---------------------------------------------------------------
+  StdSize CINetCDF4::getNbVertex(const StdString& name,
+                                 const CVarPath* const path)
+  {
+
+    if (this->isRectilinear(name, path) ||
+       this->isCurvilinear(name, path))
+    {
+      if (this->is3Dim(name, path)) return 8;
+      else return 4;
+    }
+    if (this->isUnstructured(name, path))
+    {
+      StdString bound = this->getBoundsId
+            (this->getCoordinatesIdList(name, path).back(), path);
+      StdString dim = this->getDimensionsList(&bound, path).back();
+      return (this->getDimensions(&bound, path)[dim]);
+    }
+    return size_t(-1);
+  }
+
+  //---------------------------------------------------------------
+
+  std::list<StdString> CINetCDF4::getGroups(const CVarPath* const path)
+  {
+    StdSize strlen = 0;
+    char full_name_in[NC_MAX_NAME +1];
+    int nbgroup = 0, *groupid = NULL;
+    int grpid = this->getGroup(path);
+    std::list<StdString> retvalue;
+
+    CheckError(nc_inq_grps(grpid, &nbgroup, NULL));
+    groupid = new int[nbgroup]();
+    CheckError(nc_inq_grps(grpid, NULL, groupid));
+
+    for (int i = 0; i < nbgroup; i++)
+    {
+      CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in));
+      StdString groupname(full_name_in, strlen);
+      retvalue.push_back(groupname);
+    }
+
+    delete [] groupid;
+    return retvalue;
+  }
+
+  std::list<StdString> CINetCDF4::getVariables(const CVarPath* const path)
+  {
+    char full_name_in[NC_MAX_NAME +1];
+    int nbvar = 0, *varid = NULL;
+    int grpid = this->getGroup(path);
+    std::list<StdString> retvalue;
+
+    CheckError(nc_inq_varids(grpid, &nbvar, NULL));
+    varid = new int[nbvar]();
+    CheckError(nc_inq_varids(grpid, NULL, varid));
+
+    for (int i = 0; i < nbvar; i++)
+    {
+      CheckError(nc_inq_varname(grpid, varid[i], full_name_in));
+      StdString varname(full_name_in);
+      retvalue.push_back(varname);
+    }
+
+    delete [] varid;
+    return retvalue;
+  }
+
+  StdSize CINetCDF4::getNbOfTimestep(const CVarPath* const path)
+  {
+    return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]);
+  }
+
+  std::set<StdString> CINetCDF4::getBoundVariables(const CVarPath* const path)
+  {
+    std::set<StdString> retvalue;
+    std::list<StdString> variables = this->getVariables(path);
+    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
+    for (; it != end; it++)
+    {
+      const StdString& var = *it;
+      if (this->hasBounds(var, path))
+        retvalue.insert(retvalue.end(), this->getBoundsId(var, path));
+    }
+    return retvalue;
+  }
+
+  std::set<StdString> CINetCDF4::getCoordVariables(const CVarPath* const path)
+  {
+    std::set<StdString> retvalue;
+    std::list<StdString> variables = this->getVariables(path);
+    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
+    for (; it != end; it++)
+    {
+      const StdString& var = *it;
+      std::list<StdString> coords = this->getCoordinatesIdList(var, path);
+      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+      for (; it != end; it++)
+      {
+        const StdString& coord = *it;
+        if (this->hasVariable(coord, path))
+          retvalue.insert(retvalue.end(), coord);
+      }
+    }
+    return retvalue;
+  }
+
+  std::list<StdString> CINetCDF4::getDimensionsList(const StdString* const var, const CVarPath* const path)
+  {
+    char full_name_in[NC_MAX_NAME +1];
+    int nbdim = 0, *dimid = NULL;
+    int grpid = this->getGroup(path);
+    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
+    std::list<StdString> retvalue;
+
+    if (var != NULL)
+    {
+      CheckError(nc_inq_varndims(grpid, varid, &nbdim));
+      dimid = new int[nbdim]();
+      CheckError(nc_inq_vardimid(grpid, varid, dimid));
+    }
+    else
+    {
+      CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
+      dimid = new int[nbdim]();
+      CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
+    }
+
+    for (int i = 0; i < nbdim; i++)
+    {
+      CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
+      StdString dimname(full_name_in);
+      retvalue.push_back(dimname);
+    }
+    delete [] dimid;
+
+    return retvalue;
+  }
+
+  std::map<StdString, StdSize> CINetCDF4::getDimensions(const StdString* const var, const CVarPath* const path)
+  {
+    StdSize size = 0;
+    char full_name_in[NC_MAX_NAME + 1];
+    int nbdim = 0, *dimid = NULL;
+    int grpid = this->getGroup(path);
+    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
+    std::map<StdString, StdSize> retvalue;
+
+    if (var != NULL)
+    {
+      CheckError(nc_inq_varndims(grpid, varid, &nbdim));
+      dimid = new int[nbdim]();
+      CheckError(nc_inq_vardimid(grpid, varid, dimid));
+    }
+    else
+    {
+      CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
+      dimid = new int[nbdim]();
+      CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
+    }
+
+    for (int i = 0; i < nbdim; i++)
+    {
+      CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
+      CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
+
+      StdString dimname(full_name_in);
+      retvalue.insert(retvalue.end(), std::make_pair(dimname, size));
+    }
+    delete [] dimid;
+
+    return retvalue;
+  }
+
+  std::list<StdString> CINetCDF4::getAttributes(const StdString* const var, const CVarPath* const path )
+  {
+    int nbatt = 0;
+    char full_name_in[NC_MAX_NAME +1];
+    std::list<StdString> retvalue;
+    int grpid = this->getGroup(path);
+    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
+
+    if (var != NULL)
+      CheckError(nc_inq_varnatts(grpid, varid, &nbatt));
+    else
+      CheckError(nc_inq_natts(grpid, &nbatt));
+
+    for (int i = 0; i < nbatt; i++)
+    {
+      CheckError(nc_inq_attname(grpid, varid, i, full_name_in));
+      StdString attname(full_name_in);
+      retvalue.push_back(attname);
+    }
+    return retvalue;
+  }
+
+  int CINetCDF4::getAttributeId(const StdString& name,
+                                const StdString* const var,
+                                const CVarPath* const path)
+  {
+    int retvalue = 0;
+    std::list<StdString> atts = this->getAttributes(var, path);
+    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
+    for (; it != end; it++)
+    {
+      const StdString& attname = *it;
+      if (attname.compare(name) == 0)
+        return retvalue;
+      retvalue++;
+    }
+    return -1;
+  }
+
+  //---------------------------------------------------------------
+
+  bool CINetCDF4::hasMissingValue(const StdString& name,
+                                  const CVarPath* const path)
+  {
+    return (this->hasAttribute("missing_value", &name, path) ||
+          this->hasAttribute("_FillValue", &name, path));
+  }
+
+  bool CINetCDF4::hasAttribute(const StdString& name,
+                               const StdString* const var ,
+                               const CVarPath* const path)
+  {
+    std::list<StdString> atts = this->getAttributes(var, path);
+    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
+    for (; it != end; it++)
+    {
+      const StdString& attname = *it;
+      if (attname.compare(name) == 0) return true;
+    }
+    return false;
+  }
+
+  bool CINetCDF4::hasVariable(const StdString& name,
+                              const CVarPath* const path)
+  {
+    std::list<StdString> variables = this->getVariables(path);
+    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
+    for (; it != end; it++)
+    {
+      const StdString& varname = *it;
+      if (varname.compare(name) == 0) return true;
+    }
+    return false;
+  }
+
+  bool CINetCDF4::hasCoordinates(const StdString& name,
+                                 const CVarPath* const path)
+  {
+    return (this->hasAttribute("coordinates", &name, path));
+  }
+
+  bool CINetCDF4::hasBounds(const StdString& name,
+                            const CVarPath* const path)
+  {
+    return (this->hasAttribute("bounds", &name, path));
+  }
+
+  bool CINetCDF4::hasTemporalDim(const CVarPath* const path)
+  {
+    return (this->getUnlimitedDimension(path) != -1);
+  }
+
+  //---------------------------------------------------------------
+
+#define GET_ATTRIBUTE_VALUE(type, func_ext, type_enum)                              \
+  template <>                                                                       \
+  std::vector<type> CINetCDF4::getAttributeValue(const StdString& name,             \
+                                                 const StdString* const var,        \
+                                                 const CVarPath* const path)        \
+  {                                                                                 \
+    int grpid = this->getGroup(path);                                               \
+    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;          \
+    std::pair<nc_type , StdSize> attinfos = this->getAttribute(name, var, path);    \
+    std::vector<type> retvalue(attinfos.second);                                    \
+    if (attinfos.first != type_enum)                                                \
+      ERROR("CINetCDF4::getAttributeValue<double>(name, var, path",                 \
+            << "[ name : " << name                                                  \
+            << ", type requested :" << attinfos.first                               \
+            << ", type stored : " << type_enum << "]"                               \
+            << " Invalid type !");                                                  \
+    CheckError(nc_get_att_##func_ext(grpid, varid, name.c_str(), &(retvalue[0])));  \
+    return retvalue;                                                                \
+  }
+
+  GET_ATTRIBUTE_VALUE(double, double, NC_DOUBLE)
+  GET_ATTRIBUTE_VALUE(float,  float,  NC_FLOAT)
+  GET_ATTRIBUTE_VALUE(int,    int ,   NC_INT)
+  GET_ATTRIBUTE_VALUE(char,   text,   NC_CHAR)
+
+  template <>
+  StdString CINetCDF4::getAttributeValue(const StdString& name,
+                                         const StdString* const var,
+                                         const CVarPath* const path)
+  {
+    std::vector<char> chart = this->getAttributeValue<std::vector<char> >(name, var, path);
+    StdString retvalue(&(chart[0]), chart.size());
+    return retvalue;
+  }
+
+  template <>
+  int CINetCDF4::getMissingValue(const StdString& name,
+                                 const CVarPath* const path)
+  {
+    if (this->hasAttribute("missing_value", &name, path))
+      return (this->getAttributeValue<std::vector<int> >("missing_value", &name, path)[0]);
+    if (this->hasAttribute("_FillValue", &name, path))
+      return (this->getAttributeValue<std::vector<int> >("_FillValue", &name, path)[0]);
+    return 0;
+  }
+
+  template <>
+  double CINetCDF4::getMissingValue(const StdString& name,
+                                    const CVarPath* const path)
+  {
+    if (this->hasAttribute("missing_value", &name, path))
+      return (this->getAttributeValue<std::vector<double> >("missing_value", &name, path)[0]);
+    if (this->hasAttribute("_FillValue", &name, path))
+      return (this->getAttributeValue<std::vector<double> >("_FillValue", &name, path)[0]);
+    return 0;
+  }
+
+  template <>
+  float CINetCDF4::getMissingValue(const StdString& name,
+                                   const CVarPath* const path)
+  {
+    if (this->hasAttribute("missing_value", &name, path))
+      return (this->getAttributeValue<std::vector<float> >("missing_value", &name, path)[0]);
+    if (this->hasAttribute("_FillValue", &name, path))
+      return (this->getAttributeValue<std::vector<float> >("_FillValue", &name, path)[0]);
+    return 0;
+  }
+
+  //---------------------------------------------------------------
+
+  std::list<StdString> CINetCDF4::getCoordinatesIdList(const StdString& name, const CVarPath* const path)
+  {
+    std::list<StdString> retvalue;
+    StdString value = this->getCoordinatesId(name, path);
+
+    boost::split(retvalue, value, boost::is_any_of(" "));
+
+    std::list<StdString>::iterator it = retvalue.begin(), end = retvalue.end();
+    for (; it != end; it++)
+    {
+      StdString& coord = *it;
+      coord.assign(coord.data());
+    }
+    return retvalue;
+  }
+
+  StdString CINetCDF4::getCoordinatesId(const StdString& name, const CVarPath* const path)
+  {
+    StdString retvalue;
+    if (this->hasAttribute("coordinates", &name, path))
+    {
+      return (this->getAttributeValue<StdString>("coordinates", &name, path));
+    }
+    else
+    {
+      std::list<StdString> dims = this->getDimensionsList(&name, path);
+      std::list<StdString>::const_iterator it = dims.begin(), end = dims.end();
+      for (; it != end; it++)
+      {
+        const StdString& value = *it;
+        retvalue.append(value).push_back(' ');
+      }
+      retvalue.erase(retvalue.end() - 1) ;
+    }
+
+    return retvalue;
+  }
+
+  StdString CINetCDF4::getBoundsId(const StdString& name,
+                                   const CVarPath* const path)
+  {
+    StdString retvalue;
+    if (this->hasAttribute("bounds", &name, path))
+      return (this->getAttributeValue<StdString>("bounds", &name, path));
+    return retvalue;
+  }
+
+  //---------------------------------------------------------------
+
+  bool CINetCDF4::isBound(const StdString& name,
+                          const CVarPath* const path)
+  {
+    std::set<StdString> bounds = this->getBoundVariables(path);
+    return (bounds.find(name) != bounds.end());
+  }
+
+  bool CINetCDF4::isCoordinate(const StdString& name,
+                               const CVarPath* const path)
+  {
+    std::set<StdString> coords = this->getCoordVariables(path);
+    return (coords.find(name) != coords.end());
+  }
+
+  bool CINetCDF4::isRectilinear(const StdString& name, const CVarPath* const path)
+  {
+    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
+    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+    for (; it != end; it++)
+    {
+      const StdString& coord = *it;
+      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path))
+      {
+        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
+        if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end()))
+          continue;
+        else
+          return false;
+      }
+    }
+    return true;
+  }
+
+  bool CINetCDF4::isCurvilinear(const StdString& name, const CVarPath* const path)
+  {
+    if (this->isRectilinear(name, path) || !this->hasCoordinates(name, path))
+      return false;
+
+    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
+    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+    for (; it != end; it++)
+    {
+      const StdString& coord = *it;
+      if (this->hasVariable(coord, path))
+      {
+        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
+        if (dimvar.size() != 2) return false;
+      }
+      else return false;
+    }
+    return true;
+  }
+
+  bool CINetCDF4::isUnstructured(const StdString& name, const CVarPath* const path)
+  {
+    if (this->isRectilinear(name, path) ||
+        this->isCurvilinear(name, path) ||
+        !this->hasCoordinates(name, path))
+       return false;
+
+    StdString dimname = this->getDimensionsList(&name, path).back();
+
+    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
+    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+    for (; it != end; it++)
+    {
+      const StdString& coord = *it;
+      if (this->hasVariable(coord, path))
+      {
+        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
+        if ((dimvar.size() == 1) &&
+            (dimvar.find(dimname) != dimvar.end()))
+          continue;
+        else
+          return false;
+      }
+      else return false;
+    }
+
+    return true;
+  }
+
+  bool CINetCDF4::isUnknown(const StdString& name, const CVarPath* const path)
+  {
+    return !(this->isRectilinear(name, path) || this->isCurvilinear(name, path) || this->isUnstructured(name, path));
+  }
+
+  bool CINetCDF4::isTemporal(const StdString& name, const CVarPath* const path)
+  {
+    if (!this->hasTemporalDim(path)) return false;
+    std::map<StdString, StdSize> dims = this->getDimensions(&name, path);
+    if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end())
+      return true;
+    return false;
+  }
+
+  bool CINetCDF4::is3Dim(const StdString& name, const CVarPath* const path)
+  {
+    int i = 0;
+    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
+    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+    for (; it != end; it++)
+    {
+      const StdString& coord = *it;
+      if (this->hasVariable(coord, path))
+      {
+        if (this->isTemporal(coord, path))
+          continue;
+        i++;
+      }
+      else
+      {
+        if (coord.compare(this->getUnlimitedDimensionName()) == 0)
+          continue;
+        i++;
+      }
+    }
+    return (i == 3);
+  }
+
+  bool CINetCDF4::isCellGrid(const StdString& name, const CVarPath* const path)
+  {
+    if (this->isCoordinate(name, path))
+    {
+      return (this->hasBounds(name, path));
+    }
+    else
+    {
+      std::list<StdString> coords = this->getCoordinatesIdList(name, path);
+      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
+      for (; it != end; it++)
+      {
+        const StdString& coord = *it;
+        if (this->hasVariable(coord, path))
+        {
+          if (this->isTemporal(coord, path))
+            continue;
+          if (this->isCellGrid(coord, path))
+            continue;
+          return false;
+        }
+        else
+        {
+          if (coord.compare(this->getUnlimitedDimensionName()) == 0)
+            continue;
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  //---------------------------------------------------------------
+
+  std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti,
+                                                   bool _isCurvi,    bool _isUnstr,
+                                                   bool _isCellData, bool _isTemporal,
+                                                   const CVarPath* const path)
+  {
+    std::list<StdString> retvalue;
+    std::list<StdString> allvars  = this->getVariables(path);
+    std::set<StdString> allcoords = this->getCoordVariables(path);
+
+    std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end();
+    for (; it != end; it++)
+    {
+      const StdString& var = *it;
+      if (this->isCoordinate(var, path)) continue;
+
+      if (!_isRecti && this->isRectilinear(var, path))  continue;
+      if (!_isCurvi && this->isCurvilinear(var, path))  continue;
+      if (!_isUnstr && this->isUnstructured(var, path)) continue;
+
+      if (!_isTemporal && this->isTemporal(var, path)) continue;
+      if (!_is3D       && this->is3Dim(var, path))     continue;
+      if (!_isCellData && this->isCellGrid(var, path)) continue;
+
+      if (this->isUnknown(var, path)) continue;
+
+      retvalue.push_back(var);
+    }
+    return retvalue;
+  }
+
+  //---------------------------------------------------------------
+
+  void CINetCDF4::getDataInfo(const StdString& var, const CVarPath* const path, StdSize record,
+                              std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size,
+                              const std::vector<StdSize>* start /*= NULL*/, const std::vector<StdSize>* count /*= NULL*/)
+  {
+    std::list<StdString> dimlist = this->getDimensionsList(&var, path);
+    std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path);
+    std::list<StdString>::iterator it = dimlist.begin();
+    if (this->isTemporal(var, path))
+    {
+      if (record != UNLIMITED_DIM)
+        sstart.push_back(record);
+      else
+        sstart.push_back(0);
+      scount.push_back(1);
+      it++;
+    }
+    for (int i = 0; it != dimlist.end(); it++, i++)
+    {
+      if (start && count)
+      {
+        sstart.push_back((*start)[i]);
+        scount.push_back((*count)[i]);
+        array_size *= (*count)[i];
+      }
+      else
+      {
+        sstart.push_back(0);
+        scount.push_back(dimmap[*it]);
+        array_size *= dimmap[*it];
+      }
+    }
+  }
+
+  template <>
+  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record)
+  {
+
+    std::vector<StdSize> start, count;
+    int grpid = this->getGroup(path);
+    int varid = this->getVariable(var, path);
+    StdSize array_size = 1;
+    this->getDataInfo(var, path, record, start, count, array_size);
+    data.resize(array_size);
+    CheckError(nc_get_vara_int(grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
+  }
+
+  template <>
+  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record)
+  {
+    std::vector<StdSize> start, count;
+    int grpid = this->getGroup(path);
+    int varid = this->getVariable(var, path);
+    StdSize array_size = 1;
+    this->getDataInfo(var, path, record, start, count, array_size);
+    data.resize(array_size);
+    CheckError(nc_get_vara_double(grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
+  }
+
+  template <>
+  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record)
+  {
+    std::vector<StdSize> start, count;
+    int grpid = this->getGroup(path);
+    int varid = this->getVariable(var, path);
+    StdSize array_size = 1;
+    this->getDataInfo(var, path, record, start, count, array_size);
+    data.resize(array_size);
+    CheckError(nc_get_vara_float(grpid, varid, &(start[0]), &(count[0]), data.dataFirst()));
+  }
+
+  template <>
+  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
+                          bool collective, StdSize record,
+                          const std::vector<StdSize>* start /*= NULL*/,
+                          const std::vector<StdSize>* count /*= NULL*/)
+  {
+    int varid = this->getVariable(var);
+
+    if (this->mpi && collective)
+      CNetCdfInterface::varParAccess(ncidp, varid, NC_COLLECTIVE);
+    if (this->mpi && !collective)
+      CNetCdfInterface::varParAccess(ncidp, varid, NC_INDEPENDENT);
+
+    std::vector<StdSize> sstart, scount;
+    StdSize array_size = 1;
+    this->getDataInfo(var, NULL, record, sstart, scount, array_size, start, count);
+
+    if (data.numElements() != array_size)
+    {
+      ERROR("CONetCDF4::getData(...)",
+            << "[ Array size = " << data.numElements()
+            << ", Data size = "  << array_size
+            << " ] Invalid array size");
+    }
+
+    CheckError(nc_get_vara_double(ncidp, varid, &(sstart[0]), &(scount[0]), data.dataFirst()));
+  }
+
+  //---------------------------------------------------------------
+
+  StdString CINetCDF4::getLonCoordName(const StdString& varname,
+                                       const CVarPath* const path)
+  {
+    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
+    if (this->hasCoordinates(varname, path))
+      return (*clist.begin());
+    else
+      return (*clist.rbegin());
+  }
+
+  StdString CINetCDF4::getLatCoordName(const StdString& varname,
+                                       const CVarPath* const path)
+  {
+    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
+    if (this->hasCoordinates(varname, path))
+      return (*(++clist.begin()));
+    else
+      return (*(++clist.rbegin()));
+  }
+
+  StdString CINetCDF4::getVertCoordName(const StdString& varname,
+                                        const CVarPath* const path)
+  {
+    if (!this->is3Dim(varname, path)) return "";
+    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
+    if (this->hasCoordinates(varname, path))
+      return (*(++(++clist.begin())));
+    else
+      return (*(++(++clist.rbegin())));
+  }
 } // namespace xios
Index: /XIOS/trunk/src/input/inetcdf4.hpp
===================================================================
--- /XIOS/trunk/src/input/inetcdf4.hpp	(revision 598)
+++ /XIOS/trunk/src/input/inetcdf4.hpp	(revision 599)
@@ -11,224 +11,201 @@
 
 #ifndef UNLIMITED_DIM
-   #define UNLIMITED_DIM (size_t)(-1)
-#endif  //UNLIMITED_DIM
+#define UNLIMITED_DIM (size_t)(-1)
+#endif  // UNLIMITED_DIM
 
 namespace xios
 {
-      /// ////////////////////// DÃ©clarations ////////////////////// ///
-      typedef std::vector<StdString> CVarPath;
-
-      class CINetCDF4
-      {
-         public :
-
-            /// Constructeurs ///
-            CINetCDF4(void);                             // Not implemented.
-            CINetCDF4(const StdString & filename);
-            CINetCDF4(const CINetCDF4 & inetcdf4);       // Not implemented.
-            CINetCDF4(const CINetCDF4 * const inetcdf4); // Not implemented.
-
-         //-------------------------------------------------------------
-
-            /// Accesseurs ///
-            StdSize getNbOfTimestep(const CVarPath  * const path = NULL);
-
-            StdString getUnlimitedDimensionName(const CVarPath  * const path = NULL);
-
-            StdString getCoordinatesId(const StdString & name,
-                                       const CVarPath  * const path = NULL);
-
-            StdString getBoundsId(const StdString & name,
-                                  const CVarPath  * const path = NULL);
-
-            StdString getLonCoordName(const StdString & varname,
-                                      const CVarPath  * const path = NULL);
-            StdString getLatCoordName(const StdString & varname,
-                                       const CVarPath  * const path = NULL);
-            StdString getVertCoordName(const StdString & varname,
-                                       const CVarPath  * const path = NULL);
-
-            std::set<StdString> getCoordVariables(const CVarPath * const path = NULL);
-            std::set<StdString> getBoundVariables(const CVarPath * const path = NULL);
-
-            std::list<StdString> getGroups   (const CVarPath * const path = NULL);
-            std::list<StdString> getVariables(const CVarPath * const path = NULL);
-
-            std::list<StdString> getDataVariables(bool _is3D       = true,
-                                                  bool _isRecti    = true,
-                                                  bool _isCurvi    = true,
-                                                  bool _isUnstr    = true,
-                                                  bool _isCellData = true,
-                                                  bool _isTemporal = true,
-                                                  const CVarPath * const path = NULL);
-
-            std::list<StdString> getAttributes
-                                (const StdString * const var  = NULL,
-                                 const CVarPath  * const path = NULL);
-
-            std::list<StdString> getDimensionsList
-                                (const StdString * const var  = NULL,
-                                 const CVarPath  * const path = NULL);
-
-            std::list<StdString> getCoordinatesIdList(const StdString & name,
-                                                      const CVarPath  * const path = NULL);
-
-            std::map<StdString, StdSize> getDimensions (const StdString * const var  = NULL,
-                                 			const CVarPath  * const path = NULL);
-
-            StdSize getNbVertex(const StdString & name,
-                                const CVarPath  * const path = NULL);
-         //-------------------------------------------------------------
-
-            template <class T>
-               T getMissingValue(const StdString & name,
-                                 const CVarPath  * const path = NULL);
-
-            template <class T>
-               T getAttributeValue(const StdString & name,
-                                   const StdString * const var  = NULL,
-                                   const CVarPath  * const path = NULL);
-
-            template <class T>
-               void getData(CArray<T, 1>& data,
-                            const StdString & var,
-                            const CVarPath  * const path = NULL,
-                            StdSize record   = UNLIMITED_DIM);
-
-         //-------------------------------------------------------------
-
-            /// Tests ///
-            bool hasMissingValue(const StdString & name,
-                                 const CVarPath  * const path = NULL);
-
-            bool hasAttribute(const StdString & name,
-                              const StdString * const var  = NULL,
-                              const CVarPath  * const path = NULL);
-
-            bool hasVariable(const StdString & name,
-                             const CVarPath  * const path = NULL);
-
-            bool hasCoordinates(const StdString & name,
-                                const CVarPath  * const path = NULL);
-
-            bool hasTemporalDim(const CVarPath  * const path = NULL);
-
-            bool hasBounds(const StdString & name,
-                           const CVarPath  * const path = NULL);
-
-         //-------------------------------------------------------------
-
-            bool isBound(const StdString & name,
-                         const CVarPath  * const path = NULL);
-            bool isCoordinate(const StdString & name,
-                              const CVarPath  * const path = NULL);
-            bool isRectilinear(const StdString & name,
-                               const CVarPath  * const path = NULL);
-            bool isCurvilinear(const StdString & name,
-                               const CVarPath  * const path = NULL);
-            bool isUnknown(const StdString & name,
-                               const CVarPath  * const path = NULL);
-            bool isUnstructured(const StdString & name,
-                                const CVarPath  * const path = NULL);
-
-            bool isTemporal(const StdString & name,
-                            const CVarPath  * const path = NULL);
-            bool is3Dim(const StdString & name,
-                        const CVarPath  * const path = NULL);
-            bool isCellGrid(const StdString & name,
-                            const CVarPath  * const path = NULL);
-
-         //-------------------------------------------------------------
-
-            /// Destructeur ///
-            virtual ~CINetCDF4(void);
-
-         protected :
-
-         //-------------------------------------------------------------
-
-            /// Accesseurs ///
-            int getGroup   (const CVarPath * const path = NULL);
-            int getVariable(const StdString & varname,
-                            const CVarPath * const path = NULL);
-            int getDimension(const StdString & dimname,
-                             const CVarPath  * const path = NULL);
-            int getUnlimitedDimension(const CVarPath  * const path = NULL);
-            int getAttributeId(const StdString & name,
-                               const StdString * const var  = NULL,
-                               const CVarPath  * const path = NULL);
-
-            std::pair<nc_type , StdSize> getAttribute(const StdString & attname,
-                                                      const StdString * const var  = NULL,
-                                                      const CVarPath  * const path = NULL);
-
-         //-------------------------------------------------------------
-
-            void getDataInfo(const StdString & var, const CVarPath  * const path, StdSize record,
-                             std::vector<StdSize> & start, std::vector<StdSize> & count,
-                             StdSize & array_size);
-
-         private :
-
-            /// VÃ©rification des erreurs NetCDF ///
-            static void CheckError(int status);
-
-            int ncidp; // Identifiant de fichier netcdf.
-
-      }; // class CINetCDF4
-
-      ///--------------------------------------------------------------
-      template <>
-         StdString CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path);
-
-      template <>
-         std::vector<double> CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path);
-
-      template <>
-         std::vector<float> CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path);
-
-      template <>
-         std::vector<int>  CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path);
-
-      template <>
-         std::vector<char>  CINetCDF4::getAttributeValue
-            (const StdString & name, const StdString * const var,
-                                     const CVarPath  * const path);
-
-      //---------------------------------------------------------------
-      template <>
-         int CINetCDF4::getMissingValue
-            (const StdString & name, const CVarPath  * const path);
-
-      template <>
-         double CINetCDF4::getMissingValue
-            (const StdString & name, const CVarPath  * const path);
-
-      template <>
-         float CINetCDF4::getMissingValue
-            (const StdString & name, const CVarPath  * const path);
-
-      //---------------------------------------------------------------
-      template <>
-         void CINetCDF4::getData(CArray<int, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record);
-
-      template <>
-         void CINetCDF4::getData(CArray<double, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record);
-
-      template <>
-         void CINetCDF4::getData(CArray<float, 1>& data, const StdString & var,
-                                 const CVarPath  * const path, StdSize record);
-      ///--------------------------------------------------------------
-
+  typedef std::vector<StdString> CVarPath;
+
+  class CINetCDF4
+  {
+    public:
+      /// Constructors ///
+      CINetCDF4(const StdString& filename, const MPI_Comm* comm = NULL, bool multifile = true);
+      CINetCDF4(const CINetCDF4& inetcdf4);       // Not implemented.
+      CINetCDF4(const CINetCDF4* const inetcdf4); // Not implemented.
+
+      //-------------------------------------------------------------
+
+      /// Destructor ///
+      virtual ~CINetCDF4(void);
+
+      //-------------------------------------------------------------
+
+      void close(void);
+
+      //-------------------------------------------------------------
+
+      /// Getters ///
+      StdSize getNbOfTimestep(const CVarPath* const path = NULL);
+
+      StdString getUnlimitedDimensionName(const CVarPath* const path = NULL);
+
+      StdString getCoordinatesId(const StdString& name, const CVarPath* const path = NULL);
+
+      StdString getBoundsId(const StdString& name, const CVarPath* const path = NULL);
+
+      StdString getLonCoordName(const StdString& varname, const CVarPath* const path = NULL);
+      StdString getLatCoordName(const StdString& varname, const CVarPath* const path = NULL);
+      StdString getVertCoordName(const StdString& varname, const CVarPath* const path = NULL);
+
+      std::set<StdString> getCoordVariables(const CVarPath* const path = NULL);
+      std::set<StdString> getBoundVariables(const CVarPath* const path = NULL);
+
+      std::list<StdString> getGroups   (const CVarPath* const path = NULL);
+      std::list<StdString> getVariables(const CVarPath* const path = NULL);
+
+      std::list<StdString> getDataVariables(bool _is3D       = true,
+                                            bool _isRecti    = true,
+                                            bool _isCurvi    = true,
+                                            bool _isUnstr    = true,
+                                            bool _isCellData = true,
+                                            bool _isTemporal = true,
+                                            const CVarPath* const path = NULL);
+
+      std::list<StdString> getAttributes(const StdString* const var  = NULL,
+                                         const CVarPath* const path = NULL);
+
+      std::list<StdString> getDimensionsList(const StdString* const var  = NULL,
+                                             const CVarPath* const path = NULL);
+
+      std::list<StdString> getCoordinatesIdList(const StdString& name,
+                                                const CVarPath* const path = NULL);
+
+      std::map<StdString, StdSize> getDimensions(const StdString* const var  = NULL,
+                                                 const CVarPath* const path = NULL);
+
+      StdSize getNbVertex(const StdString& name, const CVarPath* const path = NULL);
+
+      //-------------------------------------------------------------
+
+      template <class T>
+      T getMissingValue(const StdString& name, const CVarPath* const path = NULL);
+
+      template <class T>
+      T getAttributeValue(const StdString& name,
+                          const StdString* const var  = NULL,
+                          const CVarPath* const path = NULL);
+
+      template <class T>
+      void getData(CArray<T, 1>& data,
+                   const StdString& var,
+                   const CVarPath* const path = NULL,
+                   StdSize record = UNLIMITED_DIM);
+
+      template <class T>
+      void getData(CArray<T, 1>& data, const StdString& var,
+                   bool collective, StdSize record,
+                   const std::vector<StdSize>* start = NULL,
+                   const std::vector<StdSize>* count = NULL);
+
+      //-------------------------------------------------------------
+
+      /// Tests ///
+      bool hasMissingValue(const StdString& name, const CVarPath* const path = NULL);
+
+      bool hasAttribute(const StdString& name, const StdString* const var  = NULL, const CVarPath* const path = NULL);
+
+      bool hasVariable(const StdString& name, const CVarPath* const path = NULL);
+
+      bool hasCoordinates(const StdString& name, const CVarPath* const path = NULL);
+
+      bool hasTemporalDim(const CVarPath* const path = NULL);
+
+      bool hasBounds(const StdString& name, const CVarPath* const path = NULL);
+
+      //-------------------------------------------------------------
+
+      bool isBound(const StdString& name, const CVarPath* const path = NULL);
+      bool isCoordinate(const StdString& name, const CVarPath* const path = NULL);
+      bool isRectilinear(const StdString& name, const CVarPath* const path = NULL);
+      bool isCurvilinear(const StdString& name, const CVarPath* const path = NULL);
+      bool isUnknown(const StdString& name, const CVarPath* const path = NULL);
+      bool isUnstructured(const StdString& name, const CVarPath* const path = NULL);
+
+      bool isTemporal(const StdString& name, const CVarPath* const path = NULL);
+      bool is3Dim(const StdString& name, const CVarPath* const path = NULL);
+      bool isCellGrid(const StdString& name, const CVarPath* const path = NULL);
+
+    protected:
+      /// Getters ///
+      int getGroup   (const CVarPath* const path = NULL);
+      int getVariable(const StdString& varname, const CVarPath* const path = NULL);
+      int getDimension(const StdString& dimname, const CVarPath* const path = NULL);
+      int getUnlimitedDimension(const CVarPath* const path = NULL);
+      int getAttributeId(const StdString& name,
+                         const StdString* const var = NULL,
+                         const CVarPath* const path = NULL);
+
+      std::pair<nc_type , StdSize> getAttribute(const StdString& attname,
+                                                const StdString* const var  = NULL,
+                                                const CVarPath* const path = NULL);
+
+      //-------------------------------------------------------------
+
+      void getDataInfo(const StdString& var, const CVarPath* const path, StdSize record,
+                       std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size,
+                       const std::vector<StdSize>* start = NULL, const std::vector<StdSize>* count = NULL);
+
+    private:
+      /// VÃ©rification des erreurs NetCDF ///
+      static void CheckError(int status);
+
+      int ncidp; // Identifiant de fichier netcdf.
+      bool mpi; //< Whether parallel file access is used
+  }; // class CINetCDF4
+
+  ///--------------------------------------------------------------
+
+  template <>
+  StdString CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var,
+                                         const CVarPath* const path);
+
+  template <>
+  std::vector<double> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var,
+                                                   const CVarPath* const path);
+
+  template <>
+  std::vector<float> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var,
+                                                  const CVarPath* const path);
+
+  template <>
+  std::vector<int> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var,
+                                                const CVarPath* const path);
+
+  template <>
+  std::vector<char> CINetCDF4::getAttributeValue(const StdString& name, const StdString* const var,
+                                                 const CVarPath* const path);
+
+  //---------------------------------------------------------------
+
+  template <>
+  int CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
+
+  template <>
+  double CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
+
+  template <>
+  float CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
+
+  //---------------------------------------------------------------
+
+  template <>
+  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record);
+
+  template <>
+  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record);
+
+  template <>
+  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var,
+                          const CVarPath* const path, StdSize record);
+
+  template <>
+  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
+                          bool collective, StdSize record,
+                          const std::vector<StdSize>* start /*= NULL*/,
+                          const std::vector<StdSize>* count /*= NULL*/);
 } // namespace xios
 
Index: /XIOS/trunk/src/input/nc4_data_input.cpp
===================================================================
--- /XIOS/trunk/src/input/nc4_data_input.cpp	(revision 598)
+++ /XIOS/trunk/src/input/nc4_data_input.cpp	(revision 599)
@@ -1,12 +1,90 @@
 #include "nc4_data_input.hpp"
+
+#include "context.hpp"
+#include "context_server.hpp"
 
 namespace xios
 {
-      /// ////////////////////// DÃ©finitions ////////////////////// ///
-      CNc4DataInput::CNc4DataInput(void)
-      { /* ne rien faire de plus */ }
+  CNc4DataInput::CNc4DataInput(const StdString& filename, MPI_Comm comm_file, bool multifile, bool isCollective /*= true*/)
+    : SuperClass()
+    , SuperClassWriter(filename, &comm_file, multifile)
+    , comm_file(comm_file)
+    , filename(filename)
+    , isCollective(isCollective)
+  {
+    SuperClass::type = multifile ? MULTI_FILE : ONE_FILE;
+  }
 
-      CNc4DataInput::~CNc4DataInput(void)
-      { /* ne rien faire de plus */ }
+  CNc4DataInput::~CNc4DataInput(void)
+  { /* Nothing more to do */ }
 
+  StdSize CNc4DataInput::getFieldNbRecords_(CField* field)
+  {
+    StdString fieldId = !field->name.isEmpty() ? field->name.getValue() : field->getBaseFieldReference()->getId();
+
+    if (SuperClassWriter::isTemporal(fieldId))
+    {
+      return SuperClassWriter::getDimensions(&fieldId)[SuperClassWriter::getUnlimitedDimensionName()];
+    }
+
+    return 1;
+  }
+
+  void CNc4DataInput::readFieldData_(CField* field)
+  {
+    CContext* context = CContext::getCurrent();
+    CContextServer* server = context->server;
+
+    CGrid* grid = field->grid;
+
+    if (!grid->doGridHaveDataToWrite())
+      if (SuperClass::type==MULTI_FILE || !isCollective) return;
+
+    StdString fieldId = !field->name.isEmpty() ? field->name.getValue() : field->getBaseFieldReference()->getId();
+
+    CArray<double,1> fieldData(grid->getWrittenDataSize());
+    if (!field->default_value.isEmpty()) fieldData = field->default_value;
+
+    switch (SuperClass::type)
+    {
+      case MULTI_FILE:
+        SuperClassWriter::getData(fieldData, fieldId, isCollective, field->getNStep() - 1);
+        break;
+      case ONE_FILE:
+      {
+        std::vector<int> nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
+        std::vector<int> nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
+        std::vector<int> nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
+
+        int ssize = nZoomBeginGlobal.size();
+
+        std::vector<StdSize> start(ssize);
+        std::vector<StdSize> count(ssize);
+
+        for (int i = 0; i < ssize; ++i)
+        {
+          start[i] = nZoomBeginServer[ssize - i - 1] - nZoomBeginGlobal[ssize - i - 1];
+          count[i] = nZoomSizeServer[ssize - i - 1];
+        }
+
+        SuperClassWriter::getData(fieldData, fieldId, isCollective, field->getNStep() - 1, &start, &count);
+        break;
+      }
+    }
+
+    field->inputField(fieldData);
+
+    if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
+    {
+      double scaleFactor = 1.0, addOffset = 0.0;
+      if (!field->scale_factor.isEmpty()) scaleFactor = field->scale_factor;
+      if (!field->add_offset.isEmpty()) addOffset = field->add_offset;
+      field->invertScaleFactorAddOffset(scaleFactor, addOffset);
+    }
+  }
+
+  void CNc4DataInput::closeFile_(void)
+  {
+    SuperClassWriter::close();
+  }
 } // namespace xios
Index: /XIOS/trunk/src/input/nc4_data_input.hpp
===================================================================
--- /XIOS/trunk/src/input/nc4_data_input.hpp	(revision 598)
+++ /XIOS/trunk/src/input/nc4_data_input.hpp	(revision 599)
@@ -4,24 +4,41 @@
 /// XIOS headers ///
 #include "xios_spl.hpp"
+#include "data_input.hpp"
 #include "inetcdf4.hpp"
 
 namespace xios
 {
-      /// ////////////////////// DÃ©clarations ////////////////////// ///
+  class CNc4DataInput
+    : protected CINetCDF4
+    , public virtual CDataInput
+  {
+  public:
+    /// Type definitions ///
+    typedef CINetCDF4  SuperClassWriter;
+    typedef CDataInput SuperClass;
 
-      class CNc4DataInput
-      {
-         public :
+    /// Constructors ///
+    CNc4DataInput(const StdString& filename, MPI_Comm comm_file, bool multifile, bool isCollective = true);
+    CNc4DataInput(const CNc4DataInput& dataInput);       // Not implemented.
+    CNc4DataInput(const CNc4DataInput* const dataInput); // Not implemented.
 
-            /// Constructeurs ///
-            CNc4DataInput(void);
-            CNc4DataInput(const CNc4DataInput & datainput);       // Not implemented.
-            CNc4DataInput(const CNc4DataInput * const datainput); // Not implemented.
+    /// Destructor ///
+    virtual ~CNc4DataInput(void);
 
-            /// Destructeur ///
-            virtual ~CNc4DataInput(void);
+    /// Getters ///
+    const StdString& getFileName(void) const;
 
-      }; // class CNc4DataInput
+  protected:
+    // Read methods
+    virtual StdSize getFieldNbRecords_(CField* field);
+    virtual void readFieldData_(CField* field);
+    virtual void closeFile_(void);
 
+  private:
+    /// Private attributes ///
+    MPI_Comm comm_file;
+    const StdString filename;
+    bool isCollective;
+  }; // class CNc4DataInput
 } // namespace xios
 
Index: /XIOS/trunk/src/node/field.cpp
===================================================================
--- /XIOS/trunk/src/node/field.cpp	(revision 598)
+++ /XIOS/trunk/src/node/field.cpp	(revision 599)
@@ -23,5 +23,5 @@
       , grid(), file()
       , freq_operation(), freq_write()
-      , nstep(0)
+      , nstep(0), nstepMax(0), isEOF(false)
       , last_Write(), last_operation()
       , foperation(), hasInstantData(false), hasExpression(false)
@@ -36,5 +36,5 @@
       , grid(), file()
       , freq_operation(), freq_write()
-      , nstep(0)
+      , nstep(0), nstepMax(0), isEOF(false)
       , last_Write(), last_operation()
       , foperation(), hasInstantData(false), hasExpression(false)
@@ -267,5 +267,5 @@
     if (!getRelFile()->allDomainEmpty)
     {
-      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) //      if (! grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file)
+      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
       {
         getRelFile()->checkFile();
@@ -329,10 +329,5 @@
     std::list<CMessage> msgs;
 
-    // TODO: Read the data from the file
-    if (data_srv.empty())
-    {
-      for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
-        data_srv.insert( pair<int, CArray<double,1>* >(it->first, new CArray<double,1>(it->second->numElements())));
-    }
+    bool hasData = readField();
 
     map<int, CArray<double,1>* >::iterator it;
@@ -341,10 +336,42 @@
       msgs.push_back(CMessage());
       CMessage& msg = msgs.back();
-      msg << getId() << getNStep() << *it->second;
+      msg << getId();
+      if (hasData)
+        msg << getNStep() - 1 << *it->second;
+      else
+        msg << SIZE_MAX;
       event.push(it->first, grid->nbSenders[it->first], msg);
     }
     client->sendEvent(event);
-
-    incrementNStep();
+  }
+
+  bool CField::readField(void)
+  {
+    if (!getRelFile()->allDomainEmpty)
+    {
+      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
+      {
+        if (data_srv.empty())
+        {
+          for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
+            data_srv.insert(pair<int, CArray<double,1>*>(it->first, new CArray<double,1>(it->second->numElements())));
+        }
+
+        getRelFile()->checkFile();
+        this->incrementNStep();
+
+        if (!nstepMax)
+        {
+          nstepMax = getRelFile()->getDataInput()->getFieldNbRecords(CField::get(this));
+        }
+
+        if (getNStep() > nstepMax)
+          return false;
+
+        getRelFile()->getDataInput()->readFieldData(CField::get(this));
+      }
+    }
+
+    return true;
   }
 
@@ -373,22 +400,32 @@
     {
       int rank = ranks[i];
-      CArray<int,1>& index = *grid->storeIndex_toSrv[rank];
-      CArray<double,1> data_tmp(index.numElements());
-      *buffers[i] >> record >> data_tmp;
-
-      for (int n = 0; n < data_tmp.numElements(); n++)
-        instantData(index(n)) = data_tmp(n);
-    }
-
-    for (list< pair<CField*, int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it)
-      it->first->setSlot(it->second);
-
-    if (!hasExpression) // Should be always true ?
-    {
-      const std::vector<CField*>& refField = getAllReference();
-      std::vector<CField*>::const_iterator it = refField.begin(), end = refField.end();
-
-      for (; it != end; it++) (*it)->setDataFromExpression(instantData);
-      if (hasFieldOut) updateDataFromExpression(instantData);
+      *buffers[i] >> record;
+      isEOF = (record == SIZE_MAX);
+
+      if (!isEOF)
+      {
+        CArray<int,1>& index = *grid->storeIndex_toSrv[rank];
+        CArray<double,1> data_tmp(index.numElements());
+        *buffers[i] >> data_tmp;
+        for (int n = 0; n < data_tmp.numElements(); n++)
+          instantData(index(n)) = data_tmp(n);
+      }
+      else
+        break;
+    }
+
+    if (!isEOF)
+    {
+      for (list< pair<CField*, int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it)
+        it->first->setSlot(it->second);
+
+      if (!hasExpression) // Should be always true ?
+      {
+        const std::vector<CField*>& refField = getAllReference();
+        std::vector<CField*>::const_iterator it = refField.begin(), end = refField.end();
+
+        for (; it != end; it++) (*it)->setDataFromExpression(instantData);
+        if (hasFieldOut) updateDataFromExpression(instantData);
+      }
     }
 
@@ -437,4 +474,9 @@
    {
       this->nstep = 0;
+   }
+
+   void CField::resetNStepMax(void)
+   {
+      this->nstepMax = 0;
    }
 
@@ -761,4 +803,10 @@
    }
 
+   void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset)
+   {
+     map<int, CArray<double,1>* >::iterator it;
+     for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = *it->second * scaleFactor + addOffset;
+   }
+
    void CField::outputField(CArray<double,3>& fieldOut)
    {
@@ -786,4 +834,31 @@
       {
          grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ;
+      }
+   }
+
+   void CField::inputField(CArray<double,3>& fieldOut)
+   {
+      map<int, CArray<double,1>*>::iterator it;
+      for (it = data_srv.begin(); it != data_srv.end(); it++)
+      {
+        grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
+      }
+   }
+
+   void CField::inputField(CArray<double,2>& fieldOut)
+   {
+      map<int, CArray<double,1>*>::iterator it;
+      for(it = data_srv.begin(); it != data_srv.end(); it++)
+      {
+         grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
+      }
+   }
+
+   void CField::inputField(CArray<double,1>& fieldOut)
+   {
+      map<int, CArray<double,1>*>::iterator it;
+      for (it = data_srv.begin(); it != data_srv.end(); it++)
+      {
+         grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
       }
    }
Index: /XIOS/trunk/src/node/field.hpp
===================================================================
--- /XIOS/trunk/src/node/field.hpp	(revision 598)
+++ /XIOS/trunk/src/node/field.hpp	(revision 599)
@@ -89,4 +89,5 @@
          void incrementNStep(void);
          void resetNStep() ;
+         void resetNStepMax();
 
          template <int N> bool updateData(const CArray<double, N>&   data);
@@ -138,4 +139,5 @@
         static void recvReadDataRequest(CEventServer& event);
         void recvReadDataRequest(void);
+        bool readField(void);
         static void recvReadDataReady(CEventServer& event);
         void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers);
@@ -143,5 +145,9 @@
         void outputField(CArray<double,2>& fieldOut) ;
         void outputField(CArray<double,1>& fieldOut) ;
+        void inputField(CArray<double,3>& fieldOut);
+        void inputField(CArray<double,2>& fieldOut);
+        void inputField(CArray<double,1>& fieldOut);
         void scaleFactorAddOffset(double scaleFactor, double addOffset) ;
+        void invertScaleFactorAddOffset(double scaleFactor, double addOffset);
         void parse(xml::CXMLNode & node) ;
         CArray<double,1>* getInstantData(void)  ;
@@ -176,5 +182,6 @@
          CDuration freq_operation_srv, freq_write_srv;
 
-         StdSize nstep;
+         StdSize nstep, nstepMax;
+         bool isEOF;
          boost::shared_ptr<CDate>    last_Write, last_operation;
          boost::shared_ptr<CDate>    lastlast_Write_srv,last_Write_srv, last_operation_srv;
Index: /XIOS/trunk/src/node/field_impl.hpp
===================================================================
--- /XIOS/trunk/src/node/field_impl.hpp	(revision 598)
+++ /XIOS/trunk/src/node/field_impl.hpp	(revision 599)
@@ -190,4 +190,8 @@
         context->checkBuffersAndListen();
 
+      if (isEOF)
+        ERROR("void CField::getData(CArray<double, N>& _data) const",
+              << "Impossible to access field data, all the records of the field [ id = " << getId() << " ] have been already read.");
+
       grid->outputField(instantData, _data);
     }
Index: /XIOS/trunk/src/node/file.cpp
===================================================================
--- /XIOS/trunk/src/node/file.cpp	(revision 598)
+++ /XIOS/trunk/src/node/file.cpp	(revision 599)
@@ -5,8 +5,8 @@
 #include "group_template.hpp"
 #include "object_factory.hpp"
-#include "data_output.hpp"
 #include "context.hpp"
 #include "context_server.hpp"
 #include "nc4_data_output.hpp"
+#include "nc4_data_input.hpp"
 #include "calendar_util.hpp"
 #include "date.hpp"
@@ -48,12 +48,23 @@
    //----------------------------------------------------------------
    /*!
-   \brief Get data that will be written out.
+   \brief Get data writer object.
    Each enabled file in xml represents a physical netcdf file.
-   This function allows to access to data to be written out into netcdf file
-   \return data written out.
+   This function allows to access the data writer object.
+   \return data writer object.
    */
    boost::shared_ptr<CDataOutput> CFile::getDataOutput(void) const
    {
-      return (data_out);
+      return data_out;
+   }
+
+   /*!
+   \brief Get data reader object.
+   Each enabled file in xml represents a physical netcdf file.
+   This function allows to access the data reader object.
+   \return data reader object.
+   */
+   boost::shared_ptr<CDataInput> CFile::getDataInput(void) const
+   {
+      return data_in;
    }
 
@@ -239,9 +250,15 @@
     void CFile::checkFile(void)
     {
-      if (!isOpen) createHeader() ;
-      checkSync() ;
-      checkSplit() ;
+      if (mode.isEmpty() || mode.getValue() == mode_attr::write)
+      {
+        if (!isOpen) createHeader();
+        checkSync();
+      }
+      else
+      {
+        if (!isOpen) openInReadMode();
+      }
+      checkSplit();
     }
-
 
     /*!
@@ -283,6 +300,13 @@
           *lastSplit = *lastSplit + split_freq.getValue();
           std::vector<CField*>::iterator it, end = this->enabledFields.end();
-          for (it = this->enabledFields.begin() ;it != end; it++)  (*it)->resetNStep() ;
-          createHeader() ;
+          for (it = this->enabledFields.begin(); it != end; it++)
+          {
+            (*it)->resetNStep();
+            (*it)->resetNStepMax();
+          }
+          if (mode.isEmpty() || mode.getValue() == mode_attr::write)
+            createHeader() ;
+          else
+            openInReadMode();
           return true ;
         }
@@ -398,4 +422,78 @@
    }
 
+  /*!
+  \brief Open an existing NetCDF file in read-only mode
+  */
+  void CFile::openInReadMode(void)
+  {
+    CContext* context = CContext::getCurrent();
+    CContextServer* server=context->server;
+
+    if (!allDomainEmpty)
+    {
+      StdString filename = (!name.isEmpty()) ? name.getValue() : getId();
+      StdOStringStream oss;
+      oss << filename;
+      if (!name_suffix.isEmpty()) oss << name_suffix.getValue();
+
+      if (!split_freq.isEmpty())
+      {
+        string splitFormat;
+        if (split_freq_format.isEmpty())
+        {
+          if (split_freq.getValue().second != 0) splitFormat = "%y%mo%d%h%mi%s";
+          else if (split_freq.getValue().minute != 0) splitFormat = "%y%mo%d%h%mi";
+          else if (split_freq.getValue().hour != 0) splitFormat = "%y%mo%d%h";
+          else if (split_freq.getValue().day != 0) splitFormat = "%y%mo%d";
+          else if (split_freq.getValue().month != 0) splitFormat = "%y%mo";
+          else splitFormat = "%y";
+        }
+        else splitFormat=split_freq_format;
+        oss << "_" << lastSplit->getStr(splitFormat)
+        << "-" << (*lastSplit + split_freq.getValue() - 1 * Second).getStr(splitFormat);
+      }
+
+      bool multifile = true;
+      if (!type.isEmpty())
+      {
+        if (type == type_attr::one_file) multifile = false;
+        else if (type == type_attr::multiple_file) multifile = true;
+      }
+  #ifndef USING_NETCDF_PAR
+      if (!multifile)
+      {
+        info(0) << "!!! Warning -> Using non parallel version of netcdf, switching in multiple_file mode for file : " << filename << " ..." << endl;
+        multifile = true;
+      }
+  #endif
+      if (multifile)
+      {
+        int commSize, commRank;
+        MPI_Comm_size(fileComm, &commSize);
+        MPI_Comm_rank(fileComm, &commRank);
+
+        if (server->intraCommSize > 1)
+        {
+          oss << "_" ;
+          int width = 0, n = commSize - 1;
+          while (n != 0) { n = n / 10; width++; }
+          if (!min_digits.isEmpty() && width < min_digits)
+            width = min_digits;
+          oss.width(width);
+          oss.fill('0');
+          oss << right << commRank;
+        }
+      }
+      oss << ".nc";
+
+      bool isCollective = par_access.isEmpty() || par_access == par_access_attr::collective;
+
+      if (isOpen) data_out->closeFile();
+
+      data_in = shared_ptr<CDataInput>(new CNc4DataInput(oss.str(), fileComm, multifile, isCollective));
+      isOpen = true;
+    }
+  }
+
    //! Close file
    void CFile::close(void)
@@ -406,5 +504,8 @@
        if (isOpen)
        {
-         this->data_out->closeFile();
+         if (mode.isEmpty() || mode.getValue() == mode_attr::write)
+          this->data_out->closeFile();
+         else
+          this->data_in->closeFile();
        }
       if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm) ;
Index: /XIOS/trunk/src/node/file.hpp
===================================================================
--- /XIOS/trunk/src/node/file.hpp	(revision 598)
+++ /XIOS/trunk/src/node/file.hpp	(revision 599)
@@ -6,4 +6,5 @@
 #include "field.hpp"
 #include "data_output.hpp"
+#include "data_input.hpp"
 #include "declare_group.hpp"
 #include "date.hpp"
@@ -69,4 +70,5 @@
          /// Accesseurs ///
          boost::shared_ptr<CDataOutput> getDataOutput(void) const;
+         boost::shared_ptr<CDataInput> getDataInput(void) const;
          CFieldGroup* getVirtualFieldGroup(void) const;
          CVariableGroup* getVirtualVariableGroup(void) const;
@@ -94,4 +96,5 @@
 
          void createHeader(void);
+         void openInReadMode(void);
          void close(void) ;
 
@@ -162,4 +165,5 @@
          CVariableGroup* vVariableGroup ;
          boost::shared_ptr<CDataOutput> data_out;
+         boost::shared_ptr<CDataInput> data_in;
          std::vector<CField*> enabledFields;
 
Index: /XIOS/trunk/src/node/grid.cpp
===================================================================
--- /XIOS/trunk/src/node/grid.cpp	(revision 598)
+++ /XIOS/trunk/src/node/grid.cpp	(revision 599)
@@ -507,4 +507,14 @@
    }
 
+   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
+   {
+     CArray<size_t,1>& out_i = *outIndexFromClient[rank];
+     StdSize numElements = stored.numElements();
+     for (StdSize n = 0; n < numElements; ++n)
+     {
+       stored(n) = *(field+out_i(n));
+     }
+   }
+
    //----------------------------------------------------------------
 
Index: /XIOS/trunk/src/node/grid.hpp
===================================================================
--- /XIOS/trunk/src/node/grid.hpp	(revision 598)
+++ /XIOS/trunk/src/node/grid.hpp	(revision 599)
@@ -106,8 +106,6 @@
                                CArray<double, 1>&  storedServer) const;
 
-         void outputField(int rank, const CArray<double,1>& stored,  CArray<double,3>& field)  ;
-         void outputField(int rank, const CArray<double,1>& stored,  CArray<double,2>& field)  ;
-         void outputField(int rank, const CArray<double,1>& stored,  CArray<double,1>& field)  ;
-         void outputField(int rank, const CArray<double,1>& stored,  double* field);
+         void outputField(int rank, const CArray<double,1>& stored, double* field);
+         void inputField(int rank, const double* const field, CArray<double,1>& stored);
 
          virtual void parse(xml::CXMLNode & node);
Index: /XIOS/trunk/src/output/onetcdf4.hpp
===================================================================
--- /XIOS/trunk/src/output/onetcdf4.hpp	(revision 598)
+++ /XIOS/trunk/src/output/onetcdf4.hpp	(revision 599)
@@ -1,4 +1,4 @@
-#ifndef __XIOS_INETCDF4__
-#define __XIOS_INETCDF4__
+#ifndef __XIOS_ONETCDF4__
+#define __XIOS_ONETCDF4__
 
 /// XIOS headers ///
@@ -130,3 +130,3 @@
 } // namespace xios
 
-#endif //__XIOS_INETCDF4__
+#endif //__XIOS_ONETCDF4__
