Index: trunk/SophyaLib/NTools/NTools.o.list
===================================================================
--- trunk/SophyaLib/NTools/NTools.o.list	(revision 717)
+++ trunk/SophyaLib/NTools/NTools.o.list	(revision 718)
@@ -45,2 +45,3 @@
 tvector.o
 utils.o
+xntuple.o
Index: trunk/SophyaLib/NTools/dvlist.cc
===================================================================
--- trunk/SophyaLib/NTools/dvlist.cc	(revision 717)
+++ trunk/SophyaLib/NTools/dvlist.cc	(revision 718)
@@ -27,5 +27,5 @@
 //	en particulier destinés à être inclus dans d'autres objets 
 //	PPersist plus complexes. La classe DVList gère des 
-//	variables de type entier ("int_4"), réél double précision ("double")
+//	variables de type entier ("int_8"), réél double précision ("r_8")
 //	et de type chaine de caracteres ("string, char*", maxi 30 caracteres ).
 //	Une classe intermédiaire (*MuTyV*) est utilisée pour représenter une 
@@ -117,14 +117,14 @@
 for(it = dvl.mvlist.begin(); it != dvl.mvlist.end(); it++)
   {
-  switch ((*it).second.typ) 
+  switch ((*it).second.elval.typ) 
     {
     case 'I' :
-      SetI((*it).first, (*it).second.mtv.iv);
+      SetI((*it).first, (*it).second.elval.mtv.iv);
       break;
     case 'D' : 
-      SetD((*it).first, (*it).second.mtv.dv);
+      SetD((*it).first, (*it).second.elval.mtv.dv);
       break;
     case 'S' : 
-      SetS((*it).first, (*it).second.mtv.strv);
+      SetS((*it).first, (*it).second.elval.mtv.strv);
       break;
     default :
@@ -138,28 +138,30 @@
 
 //++
-// int_4   GetI(string const& key, int_4  def=-1)
-// double  GetD(string const& key, double def=-9.e19)
+// int_8   GetI(string const& key, int_8  def=-1)
+// r_8     GetD(string const& key, r_8 def=-9.e19)
 // string  GetS(string const& key, char* def="")
 //	Retourne la valeur de la variable de nom "key" et de type entier, réél, 
 //	chaine de caracteres.
 //	Si la variable n'existe pas, la valeur par défaut "def" est renvoyée.
-//--
-
-/* --Methode-- */
-int_4       DVList::GetI(string const& key, int_4 def)
+// string  GetComment(string const& key)
+//	Retourne le commentaire associé à la variable de nom "key".
+//--
+
+/* --Methode-- */
+int_8       DVList::GetI(string const& key, int_8 def)
 {
 ValList::iterator it = mvlist.find(key);
 if (it == mvlist.end())  return(def);
-if ( (*it).second.typ != 'I') return(def);
-return((*it).second.mtv.iv);
-}
-
-/* --Methode-- */
-double      DVList::GetD(string const& key, double def)
+if ( (*it).second.elval.typ != 'I') return(def);
+return((*it).second.elval.mtv.iv);
+}
+
+/* --Methode-- */
+r_8      DVList::GetD(string const& key, r_8 def)
 {
 ValList::iterator it = mvlist.find(key);
 if (it == mvlist.end())  return(def);
-if ( (*it).second.typ != 'D') return(def);
-return((*it).second.mtv.dv);
+if ( (*it).second.elval.typ != 'D') return(def);
+return((*it).second.elval.mtv.dv);
 }
 
@@ -169,28 +171,42 @@
 ValList::iterator it = mvlist.find(key);
 if (it == mvlist.end())  return(def);
-if ( (*it).second.typ != 'S') return(def);
-return((*it).second.mtv.strv);
-}
-
-//++
-// void  SetI(string const& key, int_4  val)
-// void  SetD(string const& key, double val)
+if ( (*it).second.elval.typ != 'S') return(def);
+return((*it).second.elval.mtv.strv);
+}
+
+/* --Methode-- */
+string      DVList::GetComment(string const& key)
+{
+ValList::iterator it = mvlist.find(key);
+if (it == mvlist.end())  return("");
+return((*it).second.elcomm);
+}
+
+//++
+// void  SetI(string const& key, int_8  val)
+// void  SetD(string const& key, r_8 val)
 // void  SetS(string const& key, char*  val)
 // void  SetS(string const& key, string val)
 //	Crée la variable de nom "key", de type entier, double, string et 
 //	lui attribue la valeur "val". Si une variable du même nom existe, 
-//	sa valeur et eventuellement son type sont modifiés.  
-//--
-
-/* --Methode-- */
-void        DVList::SetI(string const& key, int_4 val)
-{
-Get(key) = (int_4)val;
-}
-
-/* --Methode-- */
-void        DVList::SetD(string const& key, double val)
-{
-Get(key) = (double)val;
+//	sa valeur et eventuellement son type sont modifiés.  Les noms de
+//	variables ne doivent pas contenir de caractères spéciaux, 
+//	en particulier pas de CR/LF.
+// void  SetComment(string const& key, string const& comm)
+//	Modifie le commentaire associé à la variable de nom "key", si
+//	celle-ci existe. Le texte du commentaire ne doit pas contenir
+//	de caractères spéciaux, et en particulier pas de CR/LF. 
+//--
+
+/* --Methode-- */
+void        DVList::SetI(string const& key, int_8 val)
+{
+Get(key) = (int_8)val;
+}
+
+/* --Methode-- */
+void        DVList::SetD(string const& key, r_8 val)
+{
+Get(key) = (r_8)val;
 }
 
@@ -209,4 +225,11 @@
 }
 
+/* --Methode-- */
+void        DVList::SetComment(string const& key, string const& comm)
+{
+ValList::iterator it = mvlist.find(key);
+if (it == mvlist.end())  return;
+(*it).second.elcomm = comm;
+}
 
 //++
@@ -228,8 +251,9 @@
 if ( (l < 1) || (key.find_first_of(" ") < l) )  return(ddvdum);
 ValList::iterator it = mvlist.find(key);
-if (it == mvlist.end()) mvlist[key] = (int_4) 0;  // $CHECK$ EA. Ambigu si pas de cast...
+dvlElement xxx = {(int_8)0 , ""};
+if (it == mvlist.end()) mvlist[key] = xxx;  
 it = mvlist.find(key);
 if (it == mvlist.end()) return(ddvdum); 
-else return((*it).second);
+else return((*it).second.elval);
 }
 
@@ -256,18 +280,21 @@
 {
 os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
-os << "Comment: " << comment << "\n";
-char buff[128];
+if (comment.length() > 0)  os << comment << endl;
+char buff[256];
 ValList::const_iterator it;
 for(it = mvlist.begin(); it != mvlist.end(); it++)  {
-  switch ((*it).second.typ) 
+  switch ((*it).second.elval.typ) 
     {
     case 'I' :
-      sprintf(buff, "%s = %d (int) \n", (*it).first.substr(0,64).c_str(), (*it).second.mtv.iv );
+      sprintf(buff, "%s = %d (int) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.mtv.iv, (*it).second.elcomm.substr(0,128).c_str());
       break;
     case 'D' : 
-      sprintf(buff, "%s = %.20g (double) \n", (*it).first.substr(0,64).c_str(), (*it).second.mtv.dv );
+      sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.mtv.dv, (*it).second.elcomm.substr(0,128).c_str());
       break;
     case 'S' : 
-      sprintf(buff, "%s = %s (string) \n", (*it).first.substr(0,64).c_str(), (*it).second.mtv.strv );
+      sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.mtv.strv, (*it).second.elcomm.substr(0,128).c_str());
       break;
     default :
@@ -287,5 +314,5 @@
 //|	mvu = 66.6;        // et double (= 66.6) maintenant ...   
 //|	MuTyV mvi(14);     // On construit une variable entiere = 14
-//|	float x = mvi;     // x vaut 14.0
+//|	r_4 x = mvi;     // x vaut 14.0
 //|	MuTyV mvd(44.4);   // Variable double = 44.4
 //|	int k = mvd;       // k vaut 44  
@@ -305,7 +332,7 @@
 //|	DVList dvlr("dvlist.ppf");
 //|	int k = dvlr["toto"] ;     //  k = 14
-//|	double b = dvlr["titi"] ;  //  b = 25.5
+//|	r_8 b = dvlr["titi"] ;  //  b = 25.5
 //|	string s =  dvlr["tata"] ; //  s = "Bonjour, Ca va ?"
-//|	float c = dvlr["Hello"] ;  //  c = 77.77
+//|	r_4 c = dvlr["Hello"] ;  //  c = 77.77
 //|	int l =  dvlr["Hello"] ;   //  l = 77
 //|	int m =  dvlr["hello"] ;   //  m = 88
@@ -321,8 +348,8 @@
 void        ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
 {
-char buf[320];
+char buf[512];
 
 int lc = dobj->Comment().length();
-if (lc > 319) lc = 319;
+if (lc > 511) lc = 511;
 if (lc > 0) {
   sprintf(buf,"Comment: ( %6d ) ", lc); 
@@ -333,22 +360,26 @@
 DVList::ValList::const_iterator it;
 for(it = dobj->Begin(); it != dobj->End(); it++)  {
-  switch ((*it).second.typ) 
-    {
+  switch ((*it).second.elval.typ) {
     case 'I' :
-      sprintf(buf,"I %s %d", (*it).first.substr(0,64).c_str(), (*it).second.mtv.iv );
+      sprintf(buf,"I %s %d", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.iv );
       s.PutLine(buf); 
       break;
     case 'D' : 
-      sprintf(buf,"D %s %.20g", (*it).first.substr(0,64).c_str(), (*it).second.mtv.dv );
+      sprintf(buf,"D %s %.20g", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.dv );
       s.PutLine(buf); 
       break;
     case 'S' : 
-      sprintf(buf,"S %s %s", (*it).first.substr(0,64).c_str(), (*it).second.mtv.strv );
+      sprintf(buf,"S %s %s", (*it).first.substr(0,64).c_str(), (*it).second.elval.mtv.strv );
       s.PutLine(buf); 
       break;
     default :
       break;
-    }
-  }
+  }
+// Ecriture eventuelle du commentaire associe
+  if ((*it).second.elcomm.length() > 0) {
+    sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
+    s.PutLine(buf); 
+  }
+}
 
 s.PutLine("ZZZZZ--End-of-Varible-List------");
@@ -358,18 +389,18 @@
 void        ObjFileIO<DVList>::ReadSelf(PInPersist& s)
 {
-char buf[320];
-int_4 j,iv;
-double dv;
+char buf[512];
+int_8 j,iv;
+r_8 dv;
 bool ok=true;
 buf[0] = '\0';
 dobj->Clear();
 
-s.GetLine(buf, 319);  // Pour lire les "------- "
+s.GetLine(buf, 511);  // Pour lire les "------- "
 if (buf[0] != '-') {  // Il y a un champ commentaire a lire 
   buf[18] ='\0';
   int lc = atoi(buf+11);
-  if (lc > 319)  { 
+  if (lc > 511)  { 
     cerr << "DVList::ReadSelf() Pb/Bug ??  CommentLength= " << lc << endl;
-    lc = 319;
+    lc = 511;
     }
   s.GetBytes(buf, lc);
@@ -378,22 +409,29 @@
   }
 
+string key="";
 while(ok) {
-  s.GetLine(buf, 319);
-  buf[319] = '\0';
+  s.GetLine(buf, 511);
+  buf[511] = '\0';
   if (strncmp(buf,"ZZZZZ",5) == 0)  { ok=false; break; }
+  if (buf[0] == '#') {
+    dobj->SetComment(key, buf+2);
+    continue;
+  }
   j = posc(buf+2, ' ')+2;
   buf[j] = '\0';
-  switch (buf[0])
-    {
+  switch (buf[0]) {
     case 'I' :
-      iv = (int_4)atol(buf+j+1);
-      dobj->SetI(buf+2, iv);
+      iv = (int_8)atol(buf+j+1);
+      key = buf+2;
+      dobj->SetI(key, iv);
       break;
     case 'D' :
       dv = atof(buf+j+1);
-      dobj->SetD(buf+2, dv);
+      key = buf+2;
+      dobj->SetD(key, dv);
       break;
     case 'S' :
-      dobj->SetS(buf+2, buf+j+1);
+      key = buf+2;
+      dobj->SetS(key, buf+j+1);
       break;
     default :
Index: trunk/SophyaLib/NTools/dvlist.h
===================================================================
--- trunk/SophyaLib/NTools/dvlist.h	(revision 717)
+++ trunk/SophyaLib/NTools/dvlist.h	(revision 718)
@@ -23,6 +23,6 @@
 public:
   union {
-  int_4 iv;
-  double dv;
+  int_8 iv;
+  r_8 dv;
   char strv[31];
   } mtv; 
@@ -32,12 +32,14 @@
 
   inline MuTyV() { typ = 'I'; mtv.iv = 0;  mtv.dv = 0.;  mtv.strv[0] ='\0'; }
-  inline MuTyV(int_4 i) { typ = 'I'; mtv.iv = i; mtv.dv = 0.;  mtv.strv[0] ='\0'; }
-  inline MuTyV(float f) { typ = 'D'; mtv.dv = (double)f;  mtv.iv = 0;  mtv.strv[0] ='\0'; }
-  inline MuTyV(double d) { typ = 'D'; mtv.dv = d; mtv.iv = 0;  mtv.strv[0] ='\0'; }
+  inline MuTyV(int_4 i) { typ = 'I'; mtv.iv = (int_8)i; mtv.dv = 0.;  mtv.strv[0] ='\0'; }
+  inline MuTyV(int_8 i) { typ = 'I'; mtv.iv = i; mtv.dv = 0.;  mtv.strv[0] ='\0'; }
+  inline MuTyV(r_4 f) { typ = 'D'; mtv.dv = (r_8)f;  mtv.iv = 0;  mtv.strv[0] ='\0'; }
+  inline MuTyV(r_8 d) { typ = 'D'; mtv.dv = d; mtv.iv = 0;  mtv.strv[0] ='\0'; }
   inline MuTyV(char const* s)  { typ = 'S'; strncpy(mtv.strv, s, 31); mtv.strv[30] = '\0'; }
   inline MuTyV(string const& s) { typ = 'S'; strncpy(mtv.strv, s.c_str(), 31); mtv.strv[30] = '\0'; }
-  inline int_4  operator= (int_4 v)  { typ = 'I'; mtv.iv = v; return(v); }
-  inline float  operator= (float v)  { typ = 'D'; mtv.dv = (double)v; return(v); }
-  inline double operator= (double v) { typ = 'D'; mtv.dv = v; return(v); }
+  inline int_4  operator= (int_4 v)  { typ = 'I'; mtv.iv = (int_8)v; return(v); }
+  inline int_8  operator= (int_8 v)  { typ = 'I'; mtv.iv = v; return(v); }
+  inline r_4  operator= (r_4 v)  { typ = 'D'; mtv.dv = (r_8)v; return(v); }
+  inline r_8 operator= (r_8 v) { typ = 'D'; mtv.dv = v; return(v); }
   inline char*  operator= (char* s)  { typ = 'S'; strncpy(mtv.strv, s, 31); 
                                        mtv.strv[30] = '\0';  return(s); }
@@ -45,11 +47,14 @@
                                             mtv.strv[30] = '\0'; return(s); }
 
-  inline operator int_4() { if (typ == 'I')  return(mtv.iv);
+  inline operator int_4() { if (typ == 'I')  return((int_4)mtv.iv);
                             else if (typ == 'D') return((int_4)mtv.dv); 
                             else return(atol(mtv.strv)); }
-  inline operator float() { if (typ == 'I')  return((float)mtv.iv);
-                            else if (typ == 'D') return((float)mtv.dv); 
-                            else return((float)atof(mtv.strv)); }
-  inline operator double() { if (typ == 'I')  return((double)mtv.iv);
+  inline operator int_8() { if (typ == 'I')  return((int_8)mtv.iv);
+                            else if (typ == 'D') return((int_8)mtv.dv); 
+                            else return(atol(mtv.strv)); }
+  inline operator r_4() { if (typ == 'I')  return((r_4)mtv.iv);
+                            else if (typ == 'D') return((r_4)mtv.dv); 
+                            else return((r_4)atof(mtv.strv)); }
+  inline operator r_8() { if (typ == 'I')  return((r_8)mtv.iv);
                             else if (typ == 'D') return(mtv.dv); 
                             else return(atof(mtv.strv)); }
@@ -78,12 +83,14 @@
   DVList&           Merge(const DVList&);
 
-  int_4             GetI(string const& key, int_4 def=-1);
-  double            GetD(string const& key, double def=-9.e19);
+  int_8             GetI(string const& key, int_8 def=-1);
+  r_8               GetD(string const& key, r_8 def=-9.e19);
   string            GetS(string const& key, char* def="");
+  string            GetComment(string const& key);
 
-  void              SetI(string const& key, int_4 val);
-  void              SetD(string const& key, double val);
+  void              SetI(string const& key, int_8 val);
+  void              SetD(string const& key, r_8 val);
   void              SetS(string const& key, char const*  val);
   void              SetS(string const& key, string val);
+  void              SetComment(string const& key, string const& comm);
 
   MuTyV&            Get(string const& key);
@@ -95,13 +102,14 @@
   virtual void      Print(ostream& os)  const;
 
-  typedef map<string, MuTyV, less<string> >  ValList; 
+// Chaque element dans un DVList est constitue desormais d'un MuTyV
+// et d'une chaine de caracteres (commentaire) regroupe dans la structure
+// dvlElement. Ces elements sont associes aux noms de variables dans un 
+// map<...> ValList.            Reza 02/2000
+
+  struct dvlElement {MuTyV elval; string elcomm; } ;
+  typedef map<string, dvlElement, less<string> >  ValList; 
   inline ValList::const_iterator Begin() { return(mvlist.begin()); } 
   inline ValList::const_iterator End() { return(mvlist.end()); } 
   
-//  int_4             ClassId() const        { return classId; }
-//  static PPersist*  Create()               { return new DVList;}
-
-//  virtual void      WriteSelf(POutPersist&) const;
-//  virtual void      ReadSelf(PInPersist&);
 
 private:
Index: trunk/SophyaLib/NTools/history_eros
===================================================================
--- trunk/SophyaLib/NTools/history_eros	(revision 717)
+++ trunk/SophyaLib/NTools/history_eros	(revision 718)
@@ -186,4 +186,10 @@
    Repository revision:	1.14	/projects/Eros/CVSEros/CodeCxx/Outils/utils.h,v
    OK                   1.15    KCC std
+-----------> xntuple.cc
+   Repository revision: 1.8     /projects/Eros/CVSEros/CodeCxx/Outils/xntuple.cc,v
+   OK
+-----------> xntuple.h
+   Repository revision: 1.6     /projects/Eros/CVSEros/CodeCxx/Outils/xntuple.h,v
+   OK
 
 NTools from Images++
Index: trunk/SophyaLib/NTools/outilsinit.cc
===================================================================
--- trunk/SophyaLib/NTools/outilsinit.cc	(revision 717)
+++ trunk/SophyaLib/NTools/outilsinit.cc	(revision 718)
@@ -12,4 +12,5 @@
 #include "hisprof.h"
 #include "ntuple.h"
+#include "xntuple.h"
 #include "generaldata.h"
 #include "tmatrix.h"
@@ -42,4 +43,5 @@
 
   PPRegister(ObjFileIO<NTuple>);
+  PPRegister(ObjFileIO<XNTuple>);
   PPRegister(ObjFileIO<GeneralFitData>);
 
@@ -52,6 +54,6 @@
   PPRegister(FIO_TMatrix<r_4>);
   PPRegister(FIO_TMatrix<r_8>);
-  PPRegister(FIO_TMatrix< complex<float> >);
-  PPRegister(FIO_TMatrix< complex<double> >);
+  PPRegister(FIO_TMatrix< complex<r_4> >);
+  PPRegister(FIO_TMatrix< complex<r_8> >);
 
   PPRegister(FIO_TVector<uint_1>);
@@ -63,6 +65,6 @@
   PPRegister(FIO_TVector<r_4>);
   PPRegister(FIO_TVector<r_8>);
-  PPRegister(FIO_TVector< complex<float> >);
-  PPRegister(FIO_TVector< complex<double> >);
+  PPRegister(FIO_TVector< complex<r_4> >);
+  PPRegister(FIO_TVector< complex<r_8> >);
 
 
Index: trunk/SophyaLib/NTools/tmatrix.cc
===================================================================
--- trunk/SophyaLib/NTools/tmatrix.cc	(revision 717)
+++ trunk/SophyaLib/NTools/tmatrix.cc	(revision 718)
@@ -1,3 +1,3 @@
-// $Id: tmatrix.cc,v 1.12 1999-10-25 16:40:03 ansari Exp $
+// $Id: tmatrix.cc,v 1.13 2000-02-06 15:05:43 ansari Exp $
 //                         C.Magneville          04/99
 #include "machdefs.h"
@@ -616,6 +616,6 @@
 #pragma define_template TMatrix<r_4>
 #pragma define_template TMatrix<r_8>
-#pragma define_template TMatrix< complex<float> > 
-#pragma define_template TMatrix< complex<double> > 
+#pragma define_template TMatrix< complex<r_4> > 
+#pragma define_template TMatrix< complex<r_8> > 
 // Instances des delegues FileIO (PPersist)
 #pragma define_template FIO_TMatrix<uint_1>
@@ -628,6 +628,6 @@
 #pragma define_template FIO_TMatrix<r_8>
 #pragma define_template FIO_TMatrix<r_4>
-#pragma define_template FIO_TMatrix< complex<float> >
-#pragma define_template FIO_TMatrix< complex<double> >
+#pragma define_template FIO_TMatrix< complex<r_4> >
+#pragma define_template FIO_TMatrix< complex<r_8> >
 // Instances gestion lignes/colonnes
 #pragma define_template TMatrixRC<uint_1>
@@ -640,6 +640,6 @@
 #pragma define_template TMatrixRC<r_4>
 #pragma define_template TMatrixRC<r_8>
-#pragma define_template TMatrixRC< complex<float> > 
-#pragma define_template TMatrixRC< complex<double> >
+#pragma define_template TMatrixRC< complex<r_4> > 
+#pragma define_template TMatrixRC< complex<r_8> >
 #endif
 
@@ -654,6 +654,6 @@
 template class TMatrix<r_4>;
 template class TMatrix<r_8>;
-template class TMatrix< complex<float> >;
-template class TMatrix< complex<double> >;
+template class TMatrix< complex<r_4> >;
+template class TMatrix< complex<r_8> >;
 // Instances des delegues FileIO (PPersist)
 template class FIO_TMatrix<uint_1>;
@@ -666,6 +666,6 @@
 template class FIO_TMatrix<r_8>;
 template class FIO_TMatrix<r_4>;
-template class FIO_TMatrix< complex<float> >;
-template class FIO_TMatrix< complex<double> >;
+template class FIO_TMatrix< complex<r_4> >;
+template class FIO_TMatrix< complex<r_8> >;
 // Instances gestion lignes/colonnes
 template class TMatrixRC<uint_1>;
@@ -678,5 +678,5 @@
 template class TMatrixRC<r_4>;
 template class TMatrixRC<r_8>;
-template class TMatrixRC< complex<float> >;
-template class TMatrixRC< complex<double> >;
+template class TMatrixRC< complex<r_4> >;
+template class TMatrixRC< complex<r_8> >;
 #endif
Index: trunk/SophyaLib/NTools/tvector.cc
===================================================================
--- trunk/SophyaLib/NTools/tvector.cc	(revision 717)
+++ trunk/SophyaLib/NTools/tvector.cc	(revision 718)
@@ -1,3 +1,3 @@
-// $Id: tvector.cc,v 1.5 1999-10-25 16:40:04 ansari Exp $
+// $Id: tvector.cc,v 1.6 2000-02-06 15:05:43 ansari Exp $
 //                         C.Magneville          04/99
 #include "machdefs.h"
@@ -185,6 +185,6 @@
 #pragma define_template TVector<r_4>
 #pragma define_template TVector<r_8>
-#pragma define_template TVector< complex<float> > 
-#pragma define_template TVector< complex<double> > 
+#pragma define_template TVector< complex<r_4> > 
+#pragma define_template TVector< complex<r_8> > 
 // Instances des delegues FileIO (PPersist)
 #pragma define_template FIO_TVector<uint_1>
@@ -197,6 +197,6 @@
 #pragma define_template FIO_TVector<r_8>
 #pragma define_template FIO_TVector<r_4>
-#pragma define_template FIO_TVector< complex<float> >
-#pragma define_template FIO_TVector< complex<double> >
+#pragma define_template FIO_TVector< complex<r_4> >
+#pragma define_template FIO_TVector< complex<r_8> >
 #endif
 
@@ -211,6 +211,6 @@
 template class TVector<r_4>;
 template class TVector<r_8>;
-template class TVector< complex<float> >;
-template class TVector< complex<double> >;
+template class TVector< complex<r_4> >;
+template class TVector< complex<r_8> >;
 // Instances des delegues FileIO (PPersist)
 template class FIO_TVector<uint_1>;
@@ -223,5 +223,5 @@
 template class FIO_TVector<r_8>;
 template class FIO_TVector<r_4>;
-template class FIO_TVector< complex<float> >;
-template class FIO_TVector< complex<double> >;
+template class FIO_TVector< complex<r_4> >;
+template class FIO_TVector< complex<r_8> >;
 #endif
Index: trunk/SophyaLib/NTools/xntuple.cc
===================================================================
--- trunk/SophyaLib/NTools/xntuple.cc	(revision 718)
+++ trunk/SophyaLib/NTools/xntuple.cc	(revision 718)
@@ -0,0 +1,932 @@
+// -*- C++ -*- 
+// 
+// xntuple.cc 
+// N. Regnault   -      98-99 
+// Extended NTuples 
+// 
+#include <string.h>
+#include "ppersist.h"
+#include "perrors.h"
+#include "xntuple.h"
+
+#define LENNAME 31 
+#define MAXLEN 128
+#define BADVAL -1.e19
+
+//++
+// Class	XNTuple
+// Lib		Outils++ 
+// include	xntuple.h
+//
+//	Classe de ntuples
+//--
+//++
+// Links	Parents
+// PPersist
+// NTupleInterface
+//--
+//++
+// Links	Voir aussi
+// NTuple
+//--
+
+
+char* XNTuple::glob_swp = NULL ; 
+long int  XNTuple::NbNT = 0 ; 
+
+
+NTBlk::NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz) 
+    : sw(0), // pas swappe 
+      swoff(-1), 
+      ddata(NULL), fdata(NULL), 
+      idata(NULL), sdata(NULL)
+{
+    if(ndvar) ddata = new double[ndvar*sz] ; 
+    if(nfvar) fdata = new float[nfvar*sz] ; 
+    if(nivar) idata = new int_4[nivar*sz] ; 
+    if(nsvar) sdata = new char[nsvar*(strsz+1)*sz] ; 
+}
+
+NTBlk::~NTBlk()
+{
+    free() ; 
+}
+
+void NTBlk::free() 
+{
+    if(ddata) delete[] ddata ; ddata = NULL ; 
+    if(fdata) delete[] fdata ; fdata = NULL ; 
+    if(idata) delete[] idata ; idata = NULL ; 
+    if(sdata) delete[] sdata ; sdata = NULL ; 
+}
+
+// 
+// relit bloc ds fichier swap 
+// (seulement si bloc n'est plus en memoire) 
+// 
+void XNTuple::read_blk(NTBlk* blk) const 
+{
+    // deja en memoire ? 
+    if( !blk->sw ) return ;  
+    
+    blk->free() ; 
+    
+    // On va --> blk 
+    fseek(swf, blk->swoff, SEEK_SET) ; 
+    
+    if(mD) { 
+	blk->ddata = new double[mD*mBlkSz] ; 
+	fread(blk->ddata, sizeof(double), mD*mBlkSz, swf) ; 
+    }
+    if(mF) { 
+	blk->fdata = new float[mF*mBlkSz] ; 
+	fread(blk->fdata, sizeof(float), mF*mBlkSz, swf) ; 
+    }
+    if(mI) { 
+	blk->idata = new int_4[mI*mBlkSz] ; 
+	fread(blk->idata, sizeof(int), mI*mBlkSz, swf) ; 
+    }
+    if(mS) { 
+	blk->sdata = new char[mS*(mStrSz+1)*mBlkSz] ; 
+	fread(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ; 
+    }
+}
+
+// 
+// swappe le bloc present en memoire 
+// depuis le + longtemps 
+// 
+void XNTuple::swap() const 
+{
+    // fichier de swap ouvert ? 
+    if(!swf) { 
+	swf_name = new char[swp.length()+64] ; 
+	strncpy(swf_name, swp.c_str(), swp.length()+1) ; 
+	strcat(swf_name, "NTupleXXXXXX") ; 
+	//	swf_name = strdup("NTupleXXXXXX") ; 
+	mktemp(swf_name) ; 
+	swf = fopen(swf_name, "w+") ; 
+	if(!swf) THROW(fileErr) ; 
+    }
+    
+    // bloc a swapper 
+    NTBlk* blk = sw.front() ; 
+    
+    // bloc dans fichiers de swap ? 
+    //    if( blk->swoff > 0 ) 
+    write_blk(blk) ; 
+    blk->free() ; 
+    
+    blk->sw = 1 ; // on marque le bloc swappe 
+    sw.pop_front() ; // on le vire de la liste de swap 
+    mNSwBlk++ ; 
+}
+
+
+// 
+// unswap() 
+// 
+void XNTuple::get_blk(int i) const 
+{
+    if(i<0 || i>=mNBlk) return ; 
+    read_blk(ptr[i]) ; 
+    ptr[i]->sw = 0 ; 
+    sw.push_back(ptr[i]) ; 
+    mNSwBlk-- ; 
+}
+
+
+// 
+// ecrit le bloc en bout de fichier 
+// (seulement si swoff < 0 ) 
+// 
+void XNTuple::write_blk(NTBlk* blk) const 
+{
+    // deja swappe ? 
+    if( blk->swoff >= 0 ) return ; 
+    fseek(swf, (off_t)0, SEEK_END) ; 
+    // position debut du bloc 
+    blk->swoff = ftell(swf) ; 
+    if(blk->ddata) fwrite(blk->ddata, sizeof(double), mD*mBlkSz, swf) ; 
+    if(blk->fdata) fwrite(blk->fdata, sizeof(float),  mF*mBlkSz, swf) ; 
+    if(blk->idata) fwrite(blk->idata, sizeof(int),    mI*mBlkSz, swf) ; 
+    if(blk->sdata) fwrite(blk->sdata, sizeof(char),   mS*mBlkSz*(mStrSz+1), swf) ; 
+}
+
+
+void  XNTuple::add_blk() 
+{
+    // l'ancien bloc en ecriture peut maintenant 
+    // etre swappe (s'il existe) 
+    if(mBlk>=0) sw.push_back(ptr[mBlk]) ; 
+    
+    // si pas de place, on swappe 
+    if( mNBlk+1 >= mMaxBlk ) swap() ; 
+    
+    // nouveau bloc 
+    NTBlk* tmp = new NTBlk(mD, mF, mI, mS, mStrSz, mBlkSz) ; 
+    ptr.push_back(tmp) ; 
+    
+    //    mNBlk++ ; 
+    //    mOff = 0 ; 
+    //    mBlk++ ; 
+}
+
+
+XNTuple::XNTuple()
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+  swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath("/tmp/") ; 
+    swp = glob_swp ; 
+    NbNT++ ; 
+}
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// XNTuple(int ndvar, int nfvar, int nivar, int nsvar, char** vnames, -
+//	   int blk=512, int maxblk=100, int strsz=30)
+//	Constructeur - Création d'un XNTuple de "ndvar" variables de type "double", -
+//                      "nfvar" de type "float", "nivar" de type "int" et "nsvar" de type -
+//                      "char*". 
+//|            * "blk"    = taille blocs de données (en nombre d'entrées) 
+//|            * "maxblk" = nombre max de blocs présents en mémoire (non swappés) 
+//|            * "strsz"  = taille des données de type char* 
+// XNTuple(XNTuple const& nt)
+//	Constructeur de copie.
+// XNTuple(string const& flnm)
+//	Constructeur - lecture à partir d'un fichier PPersist.
+//--
+
+XNTuple::XNTuple(int ndvar, int nfvar, int nivar, int nsvar, 
+		   char** vnames, 
+		   int blk, int maxblk, int strsz)
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(blk), mBlk(-1), mOff(0), 
+      mMaxBlk(maxblk), mStrSz(strsz), 
+      mD(ndvar), mF(nfvar), mI(nivar), mS(nsvar), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(ndvar+nfvar+nivar+nsvar), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath("/tmp/") ; 
+    swp = glob_swp ; 
+    
+    mVarD = new r_8[mNVars] ; 
+    mMin  = new r_8[mD+mF+mI] ; 
+    int i;
+    for(i = 0 ; i < (mD+mF+mI) ; i++) mMin[i] =  9E19 ; 
+    mMax  = new r_8[mD+mF+mI] ; 
+    for(i = 0 ; i < (mD+mF+mI) ; i++) mMax[i] = -9E19 ; 
+    
+    if(mNVars) mNames = new char[mNVars*(LENNAME+1)] ; 
+    memset(mNames, 0, mNVars*(LENNAME+1));
+    for(i = 0 ; i < mNVars ; i++)
+      strncpy(mNames+i*(LENNAME+1), vnames[i], LENNAME);
+
+    NbNT++ ; 
+}
+
+
+
+XNTuple::XNTuple(string const& flnm) 
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath("/tmp/") ; 
+    swp = glob_swp ; 
+    
+    PInPersist s(flnm);
+    ObjFileIO<XNTuple> fiont(this);
+    fiont.Read(s);
+    NbNT++ ; 
+}
+
+
+XNTuple::XNTuple(XNTuple const& nt) 
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL) 
+{
+    if(!glob_swp) SetSwapPath("/tmp/") ; 
+    swp = glob_swp ; 
+    Copy(nt) ; 
+    NbNT++ ; 
+}
+
+
+
+XNTuple::~XNTuple()
+{
+    clean() ; 
+    NbNT-- ; 
+    if(NbNT==0) delete[] glob_swp ; 
+}
+
+
+
+void XNTuple::clean()
+{
+    // On libere tous les blocs 
+    for(int i = 0 ; i < mNBlk ; i++) 
+	if(!ptr[i]->sw) delete ptr[i] ; 
+    ptr.erase(ptr.begin(), ptr.end()) ; 
+    sw.erase(sw.begin(), sw.end()) ; 
+    
+    // on ferme le fichier de swap 
+    if(swf) fclose(swf) ; swf = NULL ; 
+    remove(swf_name) ; 
+    delete swf_name ; swf_name = NULL ; 
+    
+    // tout le monde remis a 0 
+    mNEnt   = 0 ;     mNBlk   = 0 ; 
+    mNSwBlk = 0 ;     mBlkSz  = 0 ;  
+    mBlk    = -1 ;    mOff    = 0 ; 
+    mMaxBlk = 0 ;     mStrSz  = 0 ; 
+    mD      = 0 ;     mF      = 0 ; 
+    mI      = 0 ;     mS      = 0 ; 
+    mNVars  = 0 ; 
+    
+    
+    if(mVarD) { delete[] mVarD ; mVarD = NULL ; } 
+    if(mMin)  { delete[] mMin  ; mMin  = NULL ; } 
+    if(mMax)  { delete[] mMax  ; mMax  = NULL ; } 
+
+    if(mNames) {delete[] mNames ; mNames = NULL ; }
+    if (mInfo) delete mInfo;
+
+}
+
+
+//++
+// Titre	Méthodes
+//--
+//++
+//  void Fill(double* d_data, float* f_data, int* i_data, char** s_data) 
+//	Remplissage d'une ligne dans le NTuple
+//  void Show(ostream& os) const 
+//	Impression de la liste des variables avec min-max sur le flot "oß
+//  void Show() const 
+//	Identique à "Show(cout)"
+//  XNTuple&   operator = (XNTuple const& nt) 
+//	Opérateur égal (=) , copie "nt" dans le premier NTuple
+//--
+void XNTuple::Fill(double* d_data, float* f_data, int* i_data, char** s_data) 
+{
+    // place disponible dans bloc courant ? 
+    if( mOff==mBlkSz || mOff==0 ) {
+	add_blk() ; mOff = 0 ; mNBlk++ ; mBlk++ ; 
+    }
+    
+    if( mD && !ptr[mBlk]->ddata || 
+	mF && !ptr[mBlk]->fdata || 
+	mI && !ptr[mBlk]->idata || 
+	mS && !ptr[mBlk]->sdata )
+	THROW(parmErr) ; 
+    
+    double x ; 
+    // copie variables et update mMin, mMax 
+    if(mD) {
+	memcpy(ptr[mBlk]->ddata+mOff*mD, d_data, mD*sizeof(double)) ; 
+	for(int i = 0 ; i < mD ; i++) {
+	    x = d_data[i] ; 
+	    if(x<mMin[i]) mMin[i] = x ; 
+	    if(x>mMax[i]) mMax[i] = x ; 
+	}
+    }
+    
+    if(mF) {
+	memcpy(ptr[mBlk]->fdata+mOff*mF, f_data, mF*sizeof(float)) ; 
+	for(int i = 0 ; i < mF ; i++) {
+	    x = f_data[i] ; 
+	    if(x<mMin[i+mD]) mMin[i+mD] = x ; 
+	    if(x>mMax[i+mD]) mMax[i+mD] = x ; 
+	}
+    }
+
+    if(mI) {
+	memcpy(ptr[mBlk]->idata+mOff*mI, i_data, mI*sizeof(int)) ; 
+	for(int i = 0 ; i < mI ; i++) {
+	    x = i_data[i] ; 
+	    if(x<mMin[i+mD+mF]) mMin[i+mD+mF] = x ; 
+	    if(x>mMax[i+mD+mF]) mMax[i+mD+mF] = x ; 
+	}
+    }
+    for(int i = 0 ; i < mS ; i++) 
+	memcpy(ptr[mBlk]->sdata+(mOff*mS+i)*(mStrSz+1), 
+	       s_data[i], (strlen(s_data[i])+1)*sizeof(char)) ; 
+    mOff++ ; 
+    mNEnt++ ; 
+}
+
+// 
+// A quel index correspond mon nom ? 
+// 
+int XNTuple::IndexNom(char const* nom) const 
+{
+    int i ; 
+    for(i = 0 ; i < (mD+mF+mI+mS) ; i++)
+	if( !strncmp( mNames+i*(LENNAME+1), nom, LENNAME+1) ) 
+	    return i ; 
+    return -1 ; 
+}
+
+string XNTuple::NomIndex(int k) const 
+{
+    if( k<0 || k>=mNVars ) return "" ; 
+    return mNames + k*(LENNAME+1) ; 
+}
+
+
+// 
+// 
+// 
+double XNTuple::GetDVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<0 || k>=mD ) 
+	THROW(rangeCheckErr) ; 
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    return ptr[blk]->ddata[off*mD+k] ; 
+}
+
+// 
+// 
+// 
+float XNTuple::GetFVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<mD || k>=(mD+mF) ) 
+	THROW(rangeCheckErr) ; 
+    k -= mD ; 
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    return ptr[blk]->fdata[off*mF+k] ; 
+}
+
+// 
+// 
+// 
+int XNTuple::GetIVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<(mD+mF) || k>=(mD+mF+mI) )
+	THROW(rangeCheckErr) ; 
+    k -= (mD+mF) ; 
+
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+
+    return ptr[blk]->idata[off*mI+k] ; 
+}
+
+// 
+// 
+// 
+string  XNTuple::GetSVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<(mD+mF+mI) || k>=(mD+mF+mI+mS) )
+	THROW(rangeCheckErr) ; 
+    k -= (mD+mF+mI) ; 
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    
+    // copie de la chaine 
+    // string ret = strdup(ptr[blk]->sdata + (off*mS+k)*(mStrSz+1)) ; // $CHECK$ EA fuite de memoire
+       // attention, strdup fait un malloc et on ne fait jamais de free...
+       // a quoi sert ce strdup ?????????
+    string ret = ptr[blk]->sdata + (off*mS+k)*(mStrSz+1) ; 
+    //    return ptr[blk]->sdata[k] ; 
+    return ret ; 
+}
+
+
+// 
+// Copie bloc a bloc, avec meme parametres 
+//  
+void XNTuple::Copy(XNTuple const& nt) 
+{
+    clean() ; 
+    // Parametres 
+    mNEnt = nt.mNEnt ; 
+    mBlkSz = nt.mBlkSz ; 
+    mOff = nt.mOff ; 
+    mMaxBlk = nt.mMaxBlk ; 
+    mStrSz = nt.mStrSz ; 
+    mD = nt.mD ; 
+    mF = nt.mF ; 
+    mI = nt.mI ; 
+    mS = nt.mS ; 
+    mNVars = nt.mNVars ; 
+    
+    // noms 
+    if(mNVars) {
+	mNames = new char[mNVars*(LENNAME+1)] ; 
+        mVarD = new double[mNVars];
+	memcpy(mNames, nt.mNames, mNVars*(LENNAME+1)*sizeof(char)) ; 
+    }
+    // MinMax 
+    if(nt.mMin) { 
+	mMin = new double[(mD+mF+mI)] ; 
+	memcpy(mMin, nt.mMin, (mD+mF+mI)*sizeof(double)) ; 
+    }
+    if(nt.mMax) { 
+	mMax = new double[(mD+mF+mI)] ; 
+	memcpy(mMax, nt.mMax, (mD+mF+mI)*sizeof(double)) ; 
+    }
+    
+    //dup blocs 
+    mNBlk = 0 ; 
+    mBlk  = -1 ; 
+    for(int i = 0 ; i < nt.mNBlk ; i++) {
+	add_blk() ; mBlk++ ; mNBlk++ ; 
+	// si nt.ptr[i] swappe, on le relit 
+	if(nt.ptr[i]->sw) nt.read_blk(nt.ptr[i]) ; 
+	if(mD) 
+	    memcpy(ptr[i]->ddata, nt.ptr[i]->ddata, mD*mBlkSz*sizeof(double)) ; 
+	if(mF)
+	    memcpy(ptr[i]->fdata, nt.ptr[i]->fdata, mF*mBlkSz*sizeof(float)) ; 
+	if(mI)
+	    memcpy(ptr[i]->idata, nt.ptr[i]->idata, mF*mBlkSz*sizeof(int)) ; 
+	if(mS)
+	    memcpy(ptr[i]->sdata, nt.ptr[i]->sdata, mS*mBlkSz*sizeof(char)*(mStrSz+1)) ; 
+	if(nt.ptr[i]->sw) nt.ptr[i]->free() ; 
+    }
+
+    // DVList Info block 
+    if(nt.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(nt.mInfo);}
+
+}
+
+//++
+// DVList& Info()
+//	Renvoie une référence sur l'objet DVList Associé
+//--
+
+DVList&  XNTuple::Info()
+{
+  if (mInfo == NULL)  mInfo = new DVList;
+  return(*mInfo);
+}
+
+void XNTuple::Print(int num, int nmax) const 
+{
+    printf("XNTuple::Print() : \n") ; 
+    printf("  Entrees = %d, Blocs  = %d, Bloc Size = %d\n", 
+	   mNEnt, mNBlk, mBlkSz) ; 
+    int i,j;
+    printf("  D_Vars  = %d : ", mD) ; 
+    for(i = 0 ; i < mD ; i++) 
+	printf("%s ", NomIndex(i).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  F_Vars  = %d : ", mF) ; 
+    for(i = 0 ; i < mF ; i++) 
+	printf("%s ", NomIndex(i+mD).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  I_Vars  = %d : ", mI) ; 
+    for(i = 0 ; i < mI ; i++) 
+	printf("%s ", NomIndex(i+mD+mF).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  S_Vars  = %d : ", mS) ; 
+    for(i = 0 ; i < mS ; i++) 
+	printf("%s ", NomIndex(i+mD+mF+mI).c_str() ) ; 
+    printf("\n") ; 
+    
+    for(i = num ; i < num+nmax ; i++) {
+	for(j = 0 ; j < mD ; j++) printf("%f ", GetDVal(i,j)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mF ; j++) printf("%f ", GetFVal(i,j+mD)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mI ; j++) printf("%d ", GetIVal(i,j+mD+mF)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mS ; j++) printf("%s ", GetSVal(i,j+mD+mF+mI).c_str()) ; 
+	printf("\n") ; 
+    }
+}
+
+
+void   XNTuple::Show(ostream& os) const 
+{
+    os << "XNTuple: NVar= " << mNVars << " NEnt= " << mNEnt 
+       << " (BlkSz,NBlk= " << mBlkSz << ", " << mNBlk << ")" 
+       << " (mNSwBlk= " << mNSwBlk << ")" << endl ; 
+    os << "(Sw File= " ; if(swf_name) os << swf_name ; os << ")" << endl ; 
+    
+    char* buff = new char[80] ; 
+    sprintf(buff, "Variables   :  Type         Min         Max  \n") ; 
+    os << buff ; 
+    
+    double min, max ;
+    int i; 
+    for(i = 0 ; i < mD ; i++) {
+	GetMinMax(i, min, max) ; 
+	sprintf(buff, "  %-10s:   D    %12.6g   %12.6g \n", 
+		NomIndex(i).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mF ; i++) {
+	GetMinMax(i+mD, min, max) ; 
+	sprintf(buff, "  %-10s:   F    %12.6g   %12.6g \n", 
+		NomIndex(i+mD).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mI ; i++) {
+	GetMinMax(i+mD+mF, min, max) ; 
+	sprintf(buff, "  %-10s:   I    %12.6g   %12.6g \n", 
+		NomIndex(i+mD+mF).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mS ; i++) {
+	sprintf(buff, "  %-10s:   S      -----        ----- \n", 
+		NomIndex(i+mD+mF+mI).c_str()) ; 
+	os << buff ; 
+    }
+    delete[] buff ; 
+}
+
+int    XNTuple::FillFromASCIIFile(string const& fn, double ddval,  float dfval,
+                                        int dival, const char * dsval)
+//	Remplit le ntuple a partir d'un fichier ASCII.
+//	Renvoie le nombre de lignes ajoutees.
+{
+// a faire
+return(0);
+}
+
+
+void  XNTuple::SetSwapPath(char* p) 
+{
+    if(!glob_swp) glob_swp = new char[MAXLEN+1] ; 
+    strncpy(glob_swp, p, MAXLEN) ; 
+}
+
+// 
+// 
+// Interface NTuple 
+// 
+// 
+uint_4 XNTuple::NbLines() const
+{
+    return(NEntry());
+}
+
+uint_4 XNTuple::NbColumns() const
+{
+    return(NVar());
+}
+
+r_8* XNTuple::GetLineD(int n) const 
+{
+    // memcpy() impossible
+    // il faut faire des GetVal 
+    int i;
+    for(i = 0 ; i < mD ; i++) 
+	mVarD[i] = GetDVal(n, i) ; 
+    for(i = 0 ; i < mF ; i++) 
+	mVarD[i+mD] = (double)GetFVal(n, i+mD) ; 
+    for(i = 0 ; i < mI ; i++) 
+	mVarD[i+mD+mF] = (double)GetIVal(n, i+mD+mF) ; 
+    for(i = 0 ; i < mS ; i++) 
+	mVarD[i+mD+mF+mI] = atof(GetSVal(n, i+mD+mF+mI).c_str()) ; 
+    return mVarD ; 
+}
+
+
+r_8  XNTuple::GetCell(int n, int k) const 
+{
+    if( k<0 || k>=(mD+mF+mI+mS) ) return BADVAL ; 
+    if(k<mD) return GetDVal(n,k) ; 
+    if(k<(mF+mD)) return GetFVal(n,k) ; 
+    if(k<(mF+mD+mI)) return GetIVal(n,k) ; 
+    if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ; 
+    return BADVAL ; 
+}
+
+
+r_8  XNTuple::GetCell(int n, string const& nom) const 
+{
+    int k = IndexNom(nom.c_str()) ; 
+    if(k<0) return BADVAL ; 
+    if(k<mD) return GetDVal(n,k) ; 
+    if(k<(mF+mD)) return GetFVal(n,k) ; 
+    if(k<(mF+mD+mI)) return GetIVal(n,k) ; 
+    if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ; 
+    return BADVAL ; 
+}
+
+string   XNTuple::GetCelltoString(int n, int k) const
+{
+    char buff[32];
+    if(k<0) return (""); 
+    else if(k<mD) 
+      { sprintf(buff, "%g", GetDVal(n,k)); return(buff) ; } 
+    else if(k<(mF+mD)) 
+      { sprintf(buff, "%g", (double)GetFVal(n,k)); return(buff) ; } 
+    else if(k<(mF+mD+mI)) 
+      { sprintf(buff, "%d", GetIVal(n,k)); return(buff) ; } 
+    else if(k<(mD+mF+mI+mS)) 
+      return(GetSVal(n,k).c_str()) ; 
+    return("");
+}
+
+void XNTuple::GetMinMax(int k, double& min, double& max)  const
+{
+    min = 9E19 ; max = -9E19 ; 
+    // variables string non traitees 
+    if( k<0 || k>=(mD+mF+mI) ) return ; 
+    
+    min = mMin[k] ; 
+    max = mMax[k] ; 
+    return ; 
+}
+
+
+void XNTuple::GetMinMax(string const & nom, double& min, double& max)   const
+{
+    GetMinMax(IndexNom(nom.c_str()), min, max) ; 
+}
+
+
+int XNTuple::ColumnIndex(string const& nom) const 
+{
+    return IndexNom(nom.c_str()) ; 
+}
+
+
+string XNTuple::ColumnName(int k) const 
+{
+    return NomIndex(k) ; 
+}
+
+
+string XNTuple::VarList_C(const char* nomx) const 
+{
+    string rets = "" ; 
+    rets += "/* double type variables */ \n";
+    // variables double 
+    int i;
+    for(i = 0 ; i < mD ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i) ; 
+    }
+    if(mD) rets += ";" ; 
+    
+    // variables float 
+    rets += "/* float type variables */ \n";
+    for(i = 0 ; i < mF ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD) ; 
+    }
+    if(mF) rets += ";" ; 
+    
+    // variables int 
+    rets += "/* int type variables */ \n";
+    for(i = 0 ; i < mI ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD+mF) ; 
+    }
+    if(mI) rets += ";" ; 
+    
+    // variables string
+    rets += "/* string type variables */ \n"; 
+    for(i = 0 ; i < mS ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD+mF+mI) ; 
+    }
+    rets += "; \n" ; 
+
+    if(nomx) {
+	char buff[256] ; 
+	for(i = 0 ; i < mNVars ; i++) {
+	    sprintf(buff, "%s=%s[%d]; ", NomIndex(i).c_str(), nomx, i) ; 
+	    rets+=buff ; 
+	    if( (i%3 == 0) && (i>0) ) rets += "\n" ; 
+	}
+    }
+    return rets ; 
+}
+
+
+string XNTuple::LineHeaderToString() const 
+{
+    char buff[32];
+    string rets=" Num    ";
+    for(int i=0; i<mNVars; i++) {
+	sprintf(buff, "%8s ", NomIndex(i).c_str() );
+	rets += buff;
+    }
+    rets += '\n';
+    return(rets);
+
+}
+
+
+string XNTuple::LineToString(int n) const 
+{
+    char buff[32];
+    double* val;
+    val = GetLineD(n);
+    sprintf(buff,"%6d: ",n); 
+    string rets=buff;
+    int i;
+    for(i=0; i<(mD+mF+mI); i++) {
+	sprintf(buff, "%8.3g ", val[i]);
+	rets += buff;
+    }
+    
+    for(i = mD+mF+mI ; i < mNVars ; i++) {
+	sprintf(buff, "%8s ", GetSVal(n,i).c_str() ) ; 
+	rets += buff ; 
+    }
+    
+    rets += '\n';
+    return(rets);
+}
+
+
+void   ObjFileIO<XNTuple>::WriteSelf(POutPersist& ppout) const 
+{
+  if (dobj == NULL)   return;
+//  On ecrit 3 uint_4 .... 
+//  0: Numero de version,  1 : non nul -> has info,  2 : reserve
+  uint_4 itab[3];
+  itab[0] = 1;  // Numero de version a 1
+  itab[1] = itab[2] = 0;
+  if (dobj->mInfo)  itab[1] = 1;
+  ppout.Put(itab,3);
+  if (dobj->mInfo)  if (dobj->mInfo)  ppout << (*(dobj->mInfo));
+
+  // variables internes 
+  ppout.PutI4(dobj->mNEnt) ; 
+  ppout.PutI4(dobj->mNBlk) ; 
+  ppout.PutI4(dobj->mBlkSz) ; 
+  ppout.PutI4(dobj->mBlk) ; 
+  ppout.PutI4(dobj->mOff) ; 
+  ppout.PutI4(dobj->mMaxBlk) ; 
+  ppout.PutI4(dobj->mStrSz) ; 
+  ppout.PutI4(dobj->mD) ; 
+  ppout.PutI4(dobj->mF) ; 
+  ppout.PutI4(dobj->mI) ; 
+  ppout.PutI4(dobj->mS) ; 
+  ppout.PutI4(dobj->mNVars) ; 
+    
+  // Noms 
+  ppout.PutBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; 
+
+  // MinMax 
+  ppout.PutR8s(dobj->mMin, (dobj->mD+dobj->mF+dobj->mI)) ; 
+  ppout.PutR8s(dobj->mMax, (dobj->mD+dobj->mF+dobj->mI)) ; 
+    
+  // Ecriture blocs N'ecrire que si datas existent 
+  for(int i = 0 ; i < dobj->mNBlk ; i++) {
+    // si bloc swappe, on le relit en douce ... 
+    if( dobj->ptr[i]->sw )  dobj->read_blk(dobj->ptr[i]) ; 
+    ppout.PutR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; 
+    ppout.PutR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; 
+    ppout.PutI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; 
+    ppout.PutBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; 
+    if(dobj->ptr[i]->sw) dobj->ptr[i]->free() ; 
+    }
+}
+
+
+void   ObjFileIO<XNTuple>::ReadSelf(PInPersist& ppin) 
+{
+  if (dobj == NULL) dobj = new XNTuple;
+  else    dobj->clean() ; 
+//  On lit 3 uint_4 .... 
+//  0: Numero de version,  1 : non nul -> has info,  2 : reserve
+  uint_4 itab[3];
+  ppin.Get(itab,3);
+  if (itab[1] != 0) { // Lecture eventuelle du DVList Info
+    if (dobj->mInfo == NULL)  dobj->mInfo = new DVList;
+    ppin >> (*(dobj->mInfo));
+  }
+
+  ppin.GetI4(dobj->mNEnt) ; 
+  ppin.GetI4(dobj->mNBlk) ; 
+  ppin.GetI4(dobj->mBlkSz) ; 
+  ppin.GetI4(dobj->mBlk) ; 
+  ppin.GetI4(dobj->mOff) ; 
+  ppin.GetI4(dobj->mMaxBlk) ; 
+  ppin.GetI4(dobj->mStrSz) ; 
+  ppin.GetI4(dobj->mD) ; 
+  ppin.GetI4(dobj->mF) ; 
+  ppin.GetI4(dobj->mI) ; 
+  ppin.GetI4(dobj->mS) ; 
+  ppin.GetI4(dobj->mNVars) ; 
+    
+  // Noms 
+  dobj->mNames = new char[dobj->mNVars*(LENNAME+1)] ;
+  dobj->mVarD = new double[dobj->mNVars]; 
+  ppin.GetBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; 
+
+  // MinMax 
+  dobj->mMin = new r_8[dobj->mD+dobj->mF+dobj->mI] ; 
+  ppin.GetR8s(dobj->mMin, dobj->mD+dobj->mF+dobj->mI) ; 
+  dobj->mMax = new r_8[dobj->mD+dobj->mF+dobj->mI] ; 
+  ppin.GetR8s(dobj->mMax, dobj->mD+dobj->mF+dobj->mI) ; 
+    
+  // lecture Blocs 
+  int nblk = dobj->mNBlk ; 
+  dobj->mBlk = -1 ; dobj->mNBlk = 0 ; 
+  for(int i = 0 ; i < nblk ; i++) {
+    dobj->add_blk() ; dobj->mBlk++ ; dobj->mNBlk++ ; 
+    ppin.GetR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; 
+    ppin.GetR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; 
+    ppin.GetI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; 
+    ppin.GetBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; 
+  } 
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<XNTuple>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<XNTuple>;
+#endif
Index: trunk/SophyaLib/NTools/xntuple.h
===================================================================
--- trunk/SophyaLib/NTools/xntuple.h	(revision 718)
+++ trunk/SophyaLib/NTools/xntuple.h	(revision 718)
@@ -0,0 +1,165 @@
+// -*- C++ -*- 
+// 
+// XNTuple 
+// 
+// N. Regnault 03/98 
+//             07/99 (NTupleInterface)
+// 
+// 
+#ifndef XNTUPLE_H_SEEN
+#define XNTUPLE_H_SEEN
+
+#include "objfio.h"
+
+#include <string.h>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "ntupintf.h"
+#include "ppersist.h"
+#include "dvlist.h"
+
+namespace SOPHYA {
+// 
+// Bloc de donnees 
+// 
+struct NTBlk
+{
+    NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz) ; 
+    ~NTBlk() ; 
+    
+    void free() ;     // ne libere que les zones de donnees 
+
+    int      sw ;     // swappe ? 
+    long int swoff ;  // offset dans fichier de swap 
+    float*   fdata ;  
+    double*  ddata ;  
+    int_4*   idata ;  
+    char*    sdata ;  
+} ; 
+
+
+class XNTuple : public AnyDataObj , public NTupleInterface {
+public:
+  //    enum {classId = ClassId_XNTuple };
+
+    XNTuple() ; 
+    XNTuple(int ndvar, int nfvar, int nivar, int nsvar, 
+	    char** vnames, 
+	    int blk=512, int maxblk=100, int strsz=30) ; 
+    XNTuple(XNTuple const& nt) ; 
+    XNTuple(string const & flnm); 
+    virtual           ~XNTuple();
+    
+    void              Fill(double* d_data, float* f_data, int* i_data, char** sdata);
+    
+    inline int_4      NEntry() const { return mNEnt ; } 
+    inline int_4      NDVar() const  { return mD ; } 
+    inline int_4      NFVar() const  { return mF ; } 
+    inline int_4      NIVar() const  { return mI ; } 
+    inline int_4      NSVar() const  { return mS ; } 
+    inline int_4      NVar() const   { return mNVars ; } 
+    int               IndexNom(char const* nom) const ; 
+    string            NomIndex(int k) const ; 
+    
+    double            GetDVal(int i, int k) const ; 
+    float             GetFVal(int i, int k) const ; 
+    int               GetIVal(int i, int k) const ; 
+    string            GetSVal(int i, int k) const ; 
+    //    MuTyV             GetVal(char const* nom) ; 
+    
+    void              Copy(XNTuple const& nt) ; 
+    inline XNTuple&   operator=(XNTuple const& nt) { Copy(nt) ; return *this ; } 
+    
+    void              Print(int num, int nmax=1) const ;
+    void              Show(ostream& os) const ; 
+    inline void       Show() const { Show(cout) ; } 
+
+    DVList&           Info() ; 
+
+// Remplissage depuis fichier ASCII 
+   int		      FillFromASCIIFile(string const& fn, double ddfval=0., float dfval=0.,
+                                        int dival=0, const char * dsval="");
+        
+    static  void      SetSwapPath(char* p) ; 
+    string&           SwapPath() { return swp ; } 
+    
+// Declaration de l interface NTuple
+    virtual uint_4    NbLines() const ;
+    virtual uint_4    NbColumns() const ;
+    virtual r_8 *     GetLineD(int n) const ;
+    virtual r_8	      GetCell(int n, int k) const ;
+    virtual r_8	      GetCell(int n, string const & nom) const ;
+    virtual string    GetCelltoString(int n, int k) const ;
+    virtual void      GetMinMax(int k, double& min, double& max)   const ; 
+    virtual void      GetMinMax(string const & nom, double& min, double& max)   const ; 
+    virtual int       ColumnIndex(string const & nom)  const ;
+    virtual string    ColumnName(int k) const;
+    virtual string    VarList_C(const char* nomx=NULL) const ;
+    virtual string    LineHeaderToString() const;
+    virtual string    LineToString(int n) const;  
+
+//  Pour la gestion de persistance
+    friend class ObjFileIO<XNTuple> ;
+   
+private:
+    void    clean();    // remet tout a zero 
+    void    swap() const ;    // swappe le + ancien blk en memoire 
+    void    read_blk(NTBlk*) const ;  // relit le bloc 
+    void    write_blk(NTBlk*) const ; // ecrit un bloc 
+    void    get_blk(int i) const ;  // == unswap() 
+    void    add_blk() ; // ajout d'un nouveau bloc 
+    
+    int_4   mNEnt ;   // nb total d'entrees 
+    int_4   mNBlk ;   // nb total de blocs 
+    mutable int_4   mNSwBlk ; // nb blocs swappes 
+    int_4   mBlkSz ;  // taille bloc 
+    int_4   mBlk ;    // bloc courant en ecriture 
+    int_4   mOff ;    // offset dans bloc en ecriture ; pointe sur le premiere case vide 
+    int_4   mMaxBlk ; // nb max de blocs autorises en memoire 
+    int_4   mStrSz ;  // taille des variables char** 
+    int_4   mNVars ;  // mD + mF + mI + mS 
+    int_4   mD, mF, mI, mS ; // nb variables de chaque type 
+    
+    r_8* mVarD, *mMin, *mMax ; 
+    
+    // 
+    // Noms + Prefix --> indiquer le type 
+    // 
+    //    char* mDNames, *mFNames, *mINames, *mSNames ; 
+    char* mNames ; 
+    //    typedef less<string> SCmp ; 
+    //    map<string,int,SCmp> mNames ; 
+    
+    // Donnees 
+    mutable vector<NTBlk*> ptr ; 
+    mutable list<NTBlk*> sw ; // liste --> swap() 
+
+    mutable FILE* swf ; // fichier --> swap 
+    mutable char* swf_name ; 
+    string  swp ; // swap_path 
+
+    DVList* mInfo;        // Infos (variables) attachees au NTuple
+
+    static  char*  glob_swp ; // swap_path global 
+    static  long int NbNT ; 
+}; 
+
+
+inline ostream& operator << (ostream& s, XNTuple const & nt)
+  {  nt.Show(s);  return(s);  }
+
+inline POutPersist& operator << (POutPersist& os, XNTuple & obj)
+{ ObjFileIO<XNTuple> fio(&obj);  fio.Write(os);  return(os); }
+inline PInPersist& operator >> (PInPersist& is, XNTuple & obj)
+{ ObjFileIO<XNTuple> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<XNTuple>
+
+
+} // namespace SOPHYA
+
+#endif
+
