Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/rcsv_ntuple

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/rcsv_ntuple (Version 11.3.0) and /externals/g4tools/include/tools/rcsv_ntuple (Version 11.1.3)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef tools_rcsv_ntuple                           4 #ifndef tools_rcsv_ntuple
  5 #define tools_rcsv_ntuple                           5 #define tools_rcsv_ntuple
  6                                                     6 
  7 // A simple ntuple class to read at the csv fo      7 // A simple ntuple class to read at the csv format.
  8 // (csv = comma separated value).                   8 // (csv = comma separated value).
  9                                                     9 
 10 // This reader can be use to read file at the      10 // This reader can be use to read file at the hippodraw format
 11 // which is :                                      11 // which is :
 12 // - one header line for the ntuple title.         12 // - one header line for the ntuple title.
 13 // - one csv line for column names.                13 // - one csv line for column names.
 14 // - data at csv format.                           14 // - data at csv format.
 15                                                    15 
 16 #include "rntuple"                                 16 #include "rntuple"
 17                                                    17 
 18 #include <istream>                                 18 #include <istream>
 19 #include <sstream>                                 19 #include <sstream>
 20                                                    20 
 21 #include "vfind"                                   21 #include "vfind"
 22 #include "vmanip"                                  22 #include "vmanip"
 23 #include "words"                                   23 #include "words"
 24 #include "snums"                                   24 #include "snums"
 25 #include "sto"                                     25 #include "sto"
 26 #include "s2time"                                  26 #include "s2time"
 27 #include "chars"                                   27 #include "chars"
 28 #include "strip"                                   28 #include "strip"
 29 #include "cids"                                    29 #include "cids"
 30 #include "ntuple_binding"                          30 #include "ntuple_binding"
 31 #include "sout"                                    31 #include "sout"
 32 #include "num2s"                                   32 #include "num2s"
 33 //#include "srep"                                  33 //#include "srep"
 34                                                    34 
 35 #ifdef TOOLS_MEM                                   35 #ifdef TOOLS_MEM
 36 #include "mem"                                     36 #include "mem"
 37 #endif                                             37 #endif
 38                                                    38 
 39 #include <utility>                             << 
 40                                                << 
 41 namespace tools {                                  39 namespace tools {
 42 namespace rcsv {                                   40 namespace rcsv {
 43                                                    41 
 44 class ntuple : public virtual read::intuple {      42 class ntuple : public virtual read::intuple {
 45   typedef read::intuple parent;                    43   typedef read::intuple parent;
 46 public: //read::intuple                            44 public: //read::intuple
 47   virtual void start() {                           45   virtual void start() {
 48     m_reader.clear();                              46     m_reader.clear();
 49     m_reader.seekg(0,std::ios::beg);               47     m_reader.seekg(0,std::ios::beg);
 50     if(m_hippo) {                                  48     if(m_hippo) {
 51       skip_line(m_reader,m_sz);                    49       skip_line(m_reader,m_sz);
 52       skip_line(m_reader,m_sz);                    50       skip_line(m_reader,m_sz);
 53     }                                              51     }
 54   }                                                52   }
 55   virtual bool next() {                            53   virtual bool next() {
 56     if(!m_sep) return false; //not inited.         54     if(!m_sep) return false; //not inited.
 57     if(m_reader.tellg()>=m_sz) return false;       55     if(m_reader.tellg()>=m_sz) return false;
 58     // first time we are at bol but else we ar     56     // first time we are at bol but else we are at eol.
 59     char c;                                        57     char c;
 60     m_reader.get(c);                               58     m_reader.get(c);
 61     if(c==LF()){                                   59     if(c==LF()){
 62       if(m_reader.tellg()>=m_sz) {                 60       if(m_reader.tellg()>=m_sz) {
 63         //eof. Tell caller to stop looping on      61         //eof. Tell caller to stop looping on ntuple rows.
 64         return false;                              62         return false;
 65       }                                            63       }
 66       //eol. Next char read is going to be at      64       //eol. Next char read is going to be at bol.
 67     } else {                                       65     } else {
 68       m_reader.putback(c);                         66       m_reader.putback(c);
 69       //bol                                        67       //bol
 70     }                                              68     }
 71     // ready for a new row :                       69     // ready for a new row :
 72                                                    70 
 73     while(skip_comment(m_reader,m_sz)){}           71     while(skip_comment(m_reader,m_sz)){}
 74     if(m_reader.tellg()>=m_sz) return false;       72     if(m_reader.tellg()>=m_sz) return false;
 75                                                    73 
 76     return _read_line();                           74     return _read_line();
 77   }                                                75   }
 78                                                    76 
 79   virtual read::icol* find_icol(const std::str     77   virtual read::icol* find_icol(const std::string& a_name){
 80     return find_named<read::icol>(m_cols,a_nam     78     return find_named<read::icol>(m_cols,a_name);
 81   }                                                79   }
 82                                                    80 
 83   virtual const std::vector<read::icol*>& colu     81   virtual const std::vector<read::icol*>& columns() const {return m_cols;}
 84                                                    82 
 85   virtual const std::string& title() const {re     83   virtual const std::string& title() const {return m_title;}
 86                                                    84 
 87   virtual bool number_of_entries(tools::uint64     85   virtual bool number_of_entries(tools::uint64 & a_value) const {
 88     if(!m_sep) {a_value = 0;return false;} //n     86     if(!m_sep) {a_value = 0;return false;} //not inited.
 89     ntuple& self = const_cast<ntuple&>(*this);     87     ntuple& self = const_cast<ntuple&>(*this);
 90     if(m_rows==(-1)) {                             88     if(m_rows==(-1)) {
 91       self.m_rows = 0;                             89       self.m_rows = 0;
 92       self.start();                                90       self.start();
 93       while(self.next()) {self.m_rows++;}          91       while(self.next()) {self.m_rows++;}
 94     }                                              92     }
 95     a_value = (uint64)m_rows;                      93     a_value = (uint64)m_rows;
 96     return true;                                   94     return true;
 97   }                                                95   }
 98 public:                                            96 public:
 99   template <class T>                               97   template <class T>
100   class column : public virtual read::icolumn<     98   class column : public virtual read::icolumn<T> {
101     typedef read::icolumn<T> parent;               99     typedef read::icolumn<T> parent;
102   public:                                         100   public:
103     static cid id_class() {                       101     static cid id_class() {
104       static const T s_v = T(); //do that for     102       static const T s_v = T(); //do that for T = std::string.
105       return 200+_cid(s_v);                       103       return 200+_cid(s_v);
106     }                                             104     }
107   public: //icol                                  105   public: //icol
108     virtual void* cast(cid a_class) const {       106     virtual void* cast(cid a_class) const {
109       if(void* p = cmp_cast<column>(this,a_cla    107       if(void* p = cmp_cast<column>(this,a_class)) {return p;}
110       return parent::cast(a_class);               108       return parent::cast(a_class);
111     }                                             109     }
112     virtual cid id_cls() const {return id_clas    110     virtual cid id_cls() const {return id_class();}
113   public: //icol                                  111   public: //icol
114     virtual const std::string& name() const {r    112     virtual const std::string& name() const {return m_name;}
115     virtual bool fetch_entry() const {            113     virtual bool fetch_entry() const {
116       if(m_user_var) *m_user_var = m_tmp;         114       if(m_user_var) *m_user_var = m_tmp;
117       return true;                                115       return true;
118     }                                             116     }
119   public: //icolumn<T>                            117   public: //icolumn<T>
120     virtual bool get_entry(T& a_v) const {        118     virtual bool get_entry(T& a_v) const {
121       a_v = m_tmp;                                119       a_v = m_tmp;
122       return true;                                120       return true;
123     }                                             121     }
124   public:                                         122   public:
125     column(const std::string& a_name,T* a_user    123     column(const std::string& a_name,T* a_user_var = 0)
126     :m_name(a_name)                               124     :m_name(a_name)
127     ,m_tmp(T())                                   125     ,m_tmp(T())
128     ,m_user_var(a_user_var) //not owner           126     ,m_user_var(a_user_var) //not owner
129     {}                                            127     {}
130     virtual ~column(){}                           128     virtual ~column(){}
131   protected:                                      129   protected:
132     column(const column& a_from)                  130     column(const column& a_from)
133     :read::icol(a_from)                           131     :read::icol(a_from)
134     ,parent(a_from)                               132     ,parent(a_from)
135     ,m_name(a_from.m_name)                        133     ,m_name(a_from.m_name)
136     ,m_tmp(a_from.m_tmp)                          134     ,m_tmp(a_from.m_tmp)
137     ,m_user_var(a_from.m_user_var)                135     ,m_user_var(a_from.m_user_var)
138     {}                                            136     {}
139     column& operator=(const column& a_from){      137     column& operator=(const column& a_from){
140       m_name = a_from.m_name;                     138       m_name = a_from.m_name;
141       m_tmp = a_from.m_tmp;                       139       m_tmp = a_from.m_tmp;
142       m_user_var = a_from.m_user_var;             140       m_user_var = a_from.m_user_var;
143       return *this;                               141       return *this;
144     }                                             142     }
145   public:                                         143   public:
146     // should be used in ntuple _read_line onl    144     // should be used in ntuple _read_line only :
147     void set_value(const T& a_v){m_tmp = a_v;}    145     void set_value(const T& a_v){m_tmp = a_v;}
148   protected:                                      146   protected:
149     std::string m_name;                           147     std::string m_name;
150     T m_tmp;                                      148     T m_tmp;
151     T* m_user_var;                                149     T* m_user_var;
152   };                                              150   };
153                                                   151 
154 #ifdef TOOLS_MEM                                  152 #ifdef TOOLS_MEM
155 public:                                           153 public:
156   static const std::string& s_class() {           154   static const std::string& s_class() {
157     static const std::string s_v("tools::rcsv:    155     static const std::string s_v("tools::rcsv::ntuple");
158     return s_v;                                   156     return s_v;
159   }                                               157   }
160 #endif                                            158 #endif
161 public:                                           159 public:
162   ntuple(std::istream& a_reader)                  160   ntuple(std::istream& a_reader)
163   :m_reader(a_reader)                             161   :m_reader(a_reader)
164   ,m_title()                                      162   ,m_title()
165   ,m_sep(0)                                       163   ,m_sep(0)
166   ,m_vec_sep(';')                                 164   ,m_vec_sep(';')
167   ,m_sz(0)                                        165   ,m_sz(0)
168   ,m_rows(-1)                                     166   ,m_rows(-1)
169   ,m_hippo(false)                                 167   ,m_hippo(false)
170   {                                               168   {
171 #ifdef TOOLS_MEM                                  169 #ifdef TOOLS_MEM
172     mem::increment(s_class().c_str());            170     mem::increment(s_class().c_str());
173 #endif                                            171 #endif
174   }                                               172   }
175   virtual ~ntuple() {                             173   virtual ~ntuple() {
176     safe_clear<read::icol>(m_cols);               174     safe_clear<read::icol>(m_cols);
177 #ifdef TOOLS_MEM                                  175 #ifdef TOOLS_MEM
178     mem::decrement(s_class().c_str());            176     mem::decrement(s_class().c_str());
179 #endif                                            177 #endif
180   }                                               178   }
181 protected:                                        179 protected:
182   ntuple(const ntuple& a_from)                    180   ntuple(const ntuple& a_from)
183   :parent(a_from)                                 181   :parent(a_from)
184   ,m_reader(a_from.m_reader)                      182   ,m_reader(a_from.m_reader)
185   ,m_title(a_from.m_title)                        183   ,m_title(a_from.m_title)
186   ,m_sep(a_from.m_sep)                            184   ,m_sep(a_from.m_sep)
187   ,m_vec_sep(a_from.m_vec_sep)                    185   ,m_vec_sep(a_from.m_vec_sep)
188   ,m_sz(a_from.m_sz)                              186   ,m_sz(a_from.m_sz)
189   ,m_rows(-1)                                     187   ,m_rows(-1)
190   ,m_hippo(a_from.m_hippo)                        188   ,m_hippo(a_from.m_hippo)
191   {                                               189   {
192 #ifdef TOOLS_MEM                                  190 #ifdef TOOLS_MEM
193     mem::increment(s_class().c_str());            191     mem::increment(s_class().c_str());
194 #endif                                            192 #endif
195   }                                               193   }
196   ntuple& operator=(const ntuple& a_from){        194   ntuple& operator=(const ntuple& a_from){
197     m_title = a_from.m_title;                     195     m_title = a_from.m_title;
198     m_sep = a_from.m_sep;                         196     m_sep = a_from.m_sep;
199     m_vec_sep = a_from.m_vec_sep;                 197     m_vec_sep = a_from.m_vec_sep;
200     m_hippo = a_from.m_hippo;                     198     m_hippo = a_from.m_hippo;
201     m_rows = a_from.m_rows;                       199     m_rows = a_from.m_rows;
202     return *this;                                 200     return *this;
203   }                                               201   }
204 public:                                           202 public:
205   void set_vec_sep(char a_c) {m_vec_sep = a_c;    203   void set_vec_sep(char a_c) {m_vec_sep = a_c;}
206   void set_sep(char a_c) {m_sep = a_c;}           204   void set_sep(char a_c) {m_sep = a_c;}
207   void set_hippo(bool a_hippo) {m_hippo = a_hi    205   void set_hippo(bool a_hippo) {m_hippo = a_hippo;}
208                                                   206 
209   std::istream& istrm() {return m_reader;}        207   std::istream& istrm() {return m_reader;}
210                                                   208 
211 /* use file::is_hippo for that.                   209 /* use file::is_hippo for that.
212   static bool is_hippo(std::ostream& a_out,std    210   static bool is_hippo(std::ostream& a_out,std::istream& a_reader) {
213     // analyse two first data line.               211     // analyse two first data line.
214                                                   212 
215     a_reader.clear();                             213     a_reader.clear();
216     a_reader.seekg(0,std::ios::end);              214     a_reader.seekg(0,std::ios::end);
217     std::streampos sz = a_reader.tellg();         215     std::streampos sz = a_reader.tellg();
218     a_reader.seekg(0,std::ios::beg);              216     a_reader.seekg(0,std::ios::beg);
219     if(!sz) {                                     217     if(!sz) {
220       a_out << "tools::rcsv::ntuple::is_hippo     218       a_out << "tools::rcsv::ntuple::is_hippo :"
221             << " stream is empty."                219             << " stream is empty."
222             << std::endl;                         220             << std::endl;
223       return false;                               221       return false;
224     } //file empty.                               222     } //file empty.
225                                                   223 
226     std::string _title;                           224     std::string _title;
227     if(!read_line(a_reader,sz,_title)) return     225     if(!read_line(a_reader,sz,_title)) return false;
228     std::string _s;                               226     std::string _s;
229     if(!read_line(a_reader,sz,_s)) return fals    227     if(!read_line(a_reader,sz,_s)) return false;
230     if(_s.find('\t')==std::string::npos) retur    228     if(_s.find('\t')==std::string::npos) return false;
231                                                   229 
232     //std::vector<std::string> labels;            230     //std::vector<std::string> labels;
233     //words(s,"\t",false,labels);                 231     //words(s,"\t",false,labels);
234     //return labels.size()?true:false;            232     //return labels.size()?true:false;
235                                                   233 
236     return true;                                  234     return true;
237   }                                               235   }
238 */                                                236 */
239   static bool find_sep(std::ostream& a_out,       237   static bool find_sep(std::ostream& a_out,
240                        std::istream& a_reader,    238                        std::istream& a_reader,bool a_hippo,
241                        bool a_verbose,            239                        bool a_verbose,
242                        char& a_sep){              240                        char& a_sep){
243     // analyse first data line to find the cha    241     // analyse first data line to find the char separator.
244                                                   242 
245     a_reader.clear();                             243     a_reader.clear();
246     a_reader.seekg(0,std::ios::end);              244     a_reader.seekg(0,std::ios::end);
247     std::streampos sz = a_reader.tellg();         245     std::streampos sz = a_reader.tellg();
248     a_reader.seekg(0,std::ios::beg);              246     a_reader.seekg(0,std::ios::beg);
249     if(!sz) {                                     247     if(!sz) {
250       a_out << "tools::rcsv::ntuple::find_sep     248       a_out << "tools::rcsv::ntuple::find_sep :"
251             << " stream is empty."                249             << " stream is empty."
252             << std::endl;                         250             << std::endl;
253       a_sep = 0;                                  251       a_sep = 0;
254       return false;                               252       return false;
255     } //file empty.                               253     } //file empty.
256     if(a_verbose) a_out << "file size " << sz     254     if(a_verbose) a_out << "file size " << sz << std::endl;
257                                                   255 
258     if(a_hippo) { //skip first two lines :        256     if(a_hippo) { //skip first two lines :
259       if(!skip_line(a_reader,sz)) {a_sep = 0;r    257       if(!skip_line(a_reader,sz)) {a_sep = 0;return false;}
260       if(!skip_line(a_reader,sz)) {a_sep = 0;r    258       if(!skip_line(a_reader,sz)) {a_sep = 0;return false;}
261     } else {                                      259     } else {
262       while(skip_comment(a_reader,sz)){}          260       while(skip_comment(a_reader,sz)){}
263     }                                             261     }
264     if(a_reader.tellg()>=sz) {a_sep=0;return f    262     if(a_reader.tellg()>=sz) {a_sep=0;return false;} //no data line.
265                                                   263 
266     // get first data line :                      264     // get first data line :
267     std::string sfirst;                           265     std::string sfirst;
268    {char c;                                       266    {char c;
269     while(true) {                                 267     while(true) {
270       if(a_reader.tellg()>=sz) break;             268       if(a_reader.tellg()>=sz) break;
271       a_reader.get(c);                            269       a_reader.get(c);
272       if((c==CR())||(c==LF())) break;             270       if((c==CR())||(c==LF())) break;
273       sfirst += c;                                271       sfirst += c;
274     }}                                            272     }}
275     if(sfirst.empty()) {                          273     if(sfirst.empty()) {
276       a_out << "tools::rcsv::ntuple::find_set     274       a_out << "tools::rcsv::ntuple::find_set :"
277             << " first datat line is empty."      275             << " first datat line is empty."
278             << std::endl;                         276             << std::endl;
279       a_sep = 0;                                  277       a_sep = 0;
280       return false;                               278       return false;
281     }                                             279     }
282     if(a_verbose) a_out << "first data line \"    280     if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl;
283                                                   281 
284     //guess sep from first data line :            282     //guess sep from first data line :
285     std::istringstream strm(sfirst.c_str());      283     std::istringstream strm(sfirst.c_str());
286     double d;                                     284     double d;
287     strm >> d;                                    285     strm >> d;
288     std::streampos pos = strm.tellg();            286     std::streampos pos = strm.tellg();
289     if(pos==std::streampos(-1)) {                 287     if(pos==std::streampos(-1)) {
290       a_out << "tools::rcsv::ntuple::find_sep     288       a_out << "tools::rcsv::ntuple::find_sep :"
291             << " first line does not start wit    289             << " first line does not start with a number."
292             << std::endl;                         290             << std::endl;
293       a_sep = 0;                                  291       a_sep = 0;
294       return false;                               292       return false;
295     } //not a number.                             293     } //not a number.
296     if(a_verbose) a_out << "first number " <<     294     if(a_verbose) a_out << "first number " << d
297                         << " ending at pos " <    295                         << " ending at pos " << pos << std::endl;
298     if(pos>=(std::streampos)sfirst.size()) {      296     if(pos>=(std::streampos)sfirst.size()) {
299       a_out << "tools::rcsv::ntuple::find_sep     297       a_out << "tools::rcsv::ntuple::find_sep :"
300             << " no separator found in first l    298             << " no separator found in first line."
301             << " pos " << pos                     299             << " pos " << pos
302             << " sfirst.size() " << sfirst.siz    300             << " sfirst.size() " << sfirst.size()
303             << std::endl;                         301             << std::endl;
304       a_sep = 0;                                  302       a_sep = 0;
305       return false;                               303       return false;
306     } //no sep.                                   304     } //no sep.
307                                                   305 
308     strm.get(a_sep);                              306     strm.get(a_sep);
309                                                   307 
310     return true;                                  308     return true;
311   }                                               309   }
312                                                   310 
313 public:                                           311 public:
314   bool initialize(std::ostream& a_out,            312   bool initialize(std::ostream& a_out,
315                   char a_sep = 0, //guessed       313                   char a_sep = 0, //guessed
316                   const std::string& a_suffix     314                   const std::string& a_suffix = "x", //col suffix
317                   bool a_verbose = false) {       315                   bool a_verbose = false) {
318     safe_clear<read::icol>(m_cols);               316     safe_clear<read::icol>(m_cols);
319     m_sep = 0;                                    317     m_sep = 0;
320     m_sz = 0;                                     318     m_sz = 0;
321     m_rows = -1;                                  319     m_rows = -1;
322                                                   320 
323     if(a_suffix.empty()) {                        321     if(a_suffix.empty()) {
324       a_out << "tools::rcsv::ntuple::initializ    322       a_out << "tools::rcsv::ntuple::initialize : expect a column suffix." << std::endl;
325       return false;                               323       return false;
326     }                                             324     }
327                                                   325 
328     m_reader.clear();                             326     m_reader.clear();
329     m_reader.seekg(0,std::ios::end);              327     m_reader.seekg(0,std::ios::end);
330     m_sz = m_reader.tellg();                      328     m_sz = m_reader.tellg();
331     m_reader.seekg(0,std::ios::beg);              329     m_reader.seekg(0,std::ios::beg);
332     if(!m_sz) {                                   330     if(!m_sz) {
333       a_out << "tools::rcsv::ntuple::initializ    331       a_out << "tools::rcsv::ntuple::initialize :"
334             << " stream is empty."                332             << " stream is empty."
335             << std::endl;                         333             << std::endl;
336       return false; //file empty.                 334       return false; //file empty.
337     }                                             335     }
338     if(a_verbose) a_out << "file size " << m_s    336     if(a_verbose) a_out << "file size " << m_sz << std::endl;
339                                                   337 
340     std::vector<std::string> labels;              338     std::vector<std::string> labels;
341     if(m_hippo) { //skip first two lines :        339     if(m_hippo) { //skip first two lines :
342       std::string _title;                         340       std::string _title;
343       if(!read_line(m_reader,m_sz,_title)) {      341       if(!read_line(m_reader,m_sz,_title)) {
344         a_out << "tools::rcsv::ntuple::initial    342         a_out << "tools::rcsv::ntuple::initialize : read_line() failed." << std::endl;
345         m_sz = 0;                                 343         m_sz = 0;
346         m_rows = -1;                              344         m_rows = -1;
347         return false;                             345         return false;
348       }                                           346       }
349       std::string _s;                             347       std::string _s;
350       if(!read_line(m_reader,m_sz,_s)) {          348       if(!read_line(m_reader,m_sz,_s)) {
351         a_out << "tools::rcsv::ntuple::initial    349         a_out << "tools::rcsv::ntuple::initialize : (2) read_line() failed." << std::endl;
352         m_sz = 0;                                 350         m_sz = 0;
353         m_rows = -1;                              351         m_rows = -1;
354   return false;                                   352   return false;
355       }                                           353       }
356       words(_s,"\t",false,labels); //false for    354       words(_s,"\t",false,labels); //false for glast.tnt that has a trailing \t.
357     } else {                                      355     } else {
358       while(skip_comment(m_reader,m_sz)){}        356       while(skip_comment(m_reader,m_sz)){}
359     }                                             357     }
360     if(m_reader.tellg()>=m_sz) {                  358     if(m_reader.tellg()>=m_sz) {
361       a_out << "tools::rcsv::ntuple::initializ    359       a_out << "tools::rcsv::ntuple::initialize : tellg() >= sz." << std::endl;
362       m_sz = 0;                                   360       m_sz = 0;
363       m_rows = -1;                                361       m_rows = -1;
364       return false;                               362       return false;
365     }                                             363     }
366                                                   364 
367     // get first data line :                      365     // get first data line :
368     std::string sfirst;                           366     std::string sfirst;
369   {{char c;                                       367   {{char c;
370     while(true) {                                 368     while(true) {
371       if(m_reader.tellg()>=m_sz) break;           369       if(m_reader.tellg()>=m_sz) break;
372       m_reader.get(c);                            370       m_reader.get(c);
373       if((c==CR())||(c==LF())) break;             371       if((c==CR())||(c==LF())) break;
374       sfirst += c;                                372       sfirst += c;
375     }}                                            373     }}
376     if(sfirst.empty()) {                          374     if(sfirst.empty()) {
377       a_out << "tools::rcsv::ntuple::initializ    375       a_out << "tools::rcsv::ntuple::initialize :"
378             << " first datat line is empty."      376             << " first datat line is empty."
379             << std::endl;                         377             << std::endl;
380       m_sz = 0;                                   378       m_sz = 0;
381       m_rows = -1;                                379       m_rows = -1;
382       return false;                               380       return false;
383     }}                                            381     }}
384     if(a_verbose) a_out << "first data line \"    382     if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl;
385                                                   383 
386     if(a_sep) {                                   384     if(a_sep) {
387       m_sep = a_sep;                              385       m_sep = a_sep;
388     } else {                                      386     } else {
389       //guess sep from first data line :          387       //guess sep from first data line :
390       std::istringstream strm(sfirst.c_str());    388       std::istringstream strm(sfirst.c_str());
391       double d;                                   389       double d;
392       strm >> d;                                  390       strm >> d;
393       std::streampos pos = strm.tellg();          391       std::streampos pos = strm.tellg();
394       if(pos==std::streampos(-1)) {               392       if(pos==std::streampos(-1)) {
395         a_out << "tools::rcsv::ntuple::initial    393         a_out << "tools::rcsv::ntuple::initialize :"
396               << " first line does not start w    394               << " first line does not start with a number."
397               << std::endl;                       395               << std::endl;
398         m_sz = 0;                                 396         m_sz = 0;
399         m_rows = -1;                              397         m_rows = -1;
400         return false;                             398         return false;
401       }                                           399       }
402       if(a_verbose) a_out << "first number " <    400       if(a_verbose) a_out << "first number " << d << " ending at pos " << pos << std::endl;
403       if(pos>=(std::streampos)sfirst.size()) {    401       if(pos>=(std::streampos)sfirst.size()) {
404         a_out << "tools::rcsv::ntuple::initial    402         a_out << "tools::rcsv::ntuple::initialize :"
405               << " no separator found in first    403               << " no separator found in first line."
406               << std::endl;                       404               << std::endl;
407         m_sz = 0;                                 405         m_sz = 0;
408         m_rows = -1;                              406         m_rows = -1;
409         return false;                             407         return false;
410       }                                           408       }
411       strm.get(m_sep);                            409       strm.get(m_sep);
412     }                                             410     }
413     if(a_verbose) a_out << "sep " << (int)m_se    411     if(a_verbose) a_out << "sep " << (int)m_sep << std::endl;
414                                                   412 
415     // in case sep is ' ', there is an ambigui    413     // in case sep is ' ', there is an ambiguity with some leading
416     // space in front of first number.            414     // space in front of first number.
417     if(m_sep==' ') strip(sfirst,leading,' ');     415     if(m_sep==' ') strip(sfirst,leading,' ');
418                                                   416 
419     std::vector<std::string> ws;                  417     std::vector<std::string> ws;
420    {std::string sep;                              418    {std::string sep;
421     sep += m_sep;                                 419     sep += m_sep;
422     words(sfirst,sep,m_hippo?false:true,ws);}     420     words(sfirst,sep,m_hippo?false:true,ws);}
423                                                   421 
424     // look if words are numbers :                422     // look if words are numbers :
425     if(a_verbose) a_out << "words " << ws.size    423     if(a_verbose) a_out << "words " << ws.size() << std::endl;
426     unsigned int index = 0;                       424     unsigned int index = 0;
427     std::vector<std::string>::iterator it;        425     std::vector<std::string>::iterator it;
428     for(it=ws.begin();it!=ws.end();++it,index+    426     for(it=ws.begin();it!=ws.end();++it,index++) {
429       if(a_verbose) a_out << "word " << sout(*    427       if(a_verbose) a_out << "word " << sout(*it) << "" << std::endl;
430 /* with glast.tnt there is trailing \t that wi    428 /* with glast.tnt there is trailing \t that will induce an extra empty column.
431       if((*it).empty()) {                         429       if((*it).empty()) {
432         // do not accept :                        430         // do not accept :
433         //   <num><sep><num><sep><sep><num>...    431         //   <num><sep><num><sep><sep><num>...
434         // but accept a trailing <sep> (glast.    432         // but accept a trailing <sep> (glast.tnt) :
435         //   <num><sep><num>....<sep><num><sep    433         //   <num><sep><num>....<sep><num><sep>
436         if(index==(ws.size()-1)) {                434         if(index==(ws.size()-1)) {
437           break;                                  435           break;
438         } else {                                  436         } else {
439           a_out << "tools::rcsv::ntuple::initi    437           a_out << "tools::rcsv::ntuple::initialize :"
440                 << " empty word."                 438                 << " empty word."
441                 << std::endl;                     439                 << std::endl;
442           safe_clear<read::icol>(m_cols);         440           safe_clear<read::icol>(m_cols);
443           m_sep = 0;                              441           m_sep = 0;
444           m_sz = 0;                               442           m_sz = 0;
445           m_rows = -1;                            443           m_rows = -1;
446           return false;                           444           return false;
447         }                                         445         }
448       }                                           446       }
449 */                                                447 */
450       std::string name = a_suffix;                448       std::string name = a_suffix;
451       if(!numas<uint64>(m_cols.size(),name)){}    449       if(!numas<uint64>(m_cols.size(),name)){}
452       if(m_hippo) {                               450       if(m_hippo) {
453         if(index>=labels.size()) {                451         if(index>=labels.size()) {
454           a_out << "tools::rcsv::ntuple::initi    452           a_out << "tools::rcsv::ntuple::initialize :"
455                 << " warning : not enough labe    453                 << " warning : not enough labels."
456                 << std::endl;                     454                 << std::endl;
457         } else {                                  455         } else {
458           name = labels[index];                   456           name = labels[index];
459         }                                         457         }
460       }                                           458       }
461       double d;                                   459       double d;
462       if(to<double>(*it,d)) {                     460       if(to<double>(*it,d)) {
463         if(a_verbose) a_out << "number " << d     461         if(a_verbose) a_out << "number " << d << std::endl;
464         create_column<double>(name);              462         create_column<double>(name);
465       } else {                                    463       } else {
466         time_t time;                              464         time_t time;
467         if(s2time(*it,time)) {                    465         if(s2time(*it,time)) {
468           create_column<csv_time>(name);          466           create_column<csv_time>(name);
469         } else {                                  467         } else {
470           std::vector<double> v;                  468           std::vector<double> v;
471           std::string vec_sep;vec_sep += m_vec    469           std::string vec_sep;vec_sep += m_vec_sep;
472           if(snums<double>(*it,vec_sep,v)&&v.s    470           if(snums<double>(*it,vec_sep,v)&&v.size()) {
473             create_column< std::vector<double>    471             create_column< std::vector<double> >(name);
474           } else {                                472           } else {
475             create_column<std::string>(name);     473             create_column<std::string>(name);
476           }                                       474           }
477         }                                         475         }
478       }                                           476       }
479     }                                             477     }
480     size_t num = m_cols.size();                   478     size_t num = m_cols.size();
481     if(!num) {                                    479     if(!num) {
482       a_out << "tools::rcsv::ntuple::initializ    480       a_out << "tools::rcsv::ntuple::initialize :"
483             << " zero columns."                   481             << " zero columns."
484             << std::endl;                         482             << std::endl;
485       m_sep = 0;                                  483       m_sep = 0;
486       m_sz = 0;                                   484       m_sz = 0;
487       m_rows = -1;                                485       m_rows = -1;
488       return false;                               486       return false;
489     }                                             487     }
490                                                   488 
491     return true;                                  489     return true;
492   }                                               490   }
493                                                   491 
494   static const std::string& s_cid(cid a_id) {     492   static const std::string& s_cid(cid a_id) {
495                                                   493 
496 #define TOOLS_RCSV_NTUPLE_IF_CID(a__name,a__ty    494 #define TOOLS_RCSV_NTUPLE_IF_CID(a__name,a__type) \
497     if(a_id==column<a__type>::id_class()) {\      495     if(a_id==column<a__type>::id_class()) {\
498       static const std::string s_v(#a__name);\    496       static const std::string s_v(#a__name);\
499       return s_v;\                                497       return s_v;\
500     }                                             498     }
501                                                   499 
502 #define TOOLS_RCSV_NTUPLE_IF_VEC_CID(a__name,a    500 #define TOOLS_RCSV_NTUPLE_IF_VEC_CID(a__name,a__type) \
503     if(a_id==column< std::vector<a__type> >::i    501     if(a_id==column< std::vector<a__type> >::id_class()) {\
504       static const std::string s_v(#a__name+st    502       static const std::string s_v(#a__name+std::string("[]"));\
505       return s_v;\                                503       return s_v;\
506     }                                             504     }
507                                                   505 
508          TOOLS_RCSV_NTUPLE_IF_CID(char,char)      506          TOOLS_RCSV_NTUPLE_IF_CID(char,char)
509     else TOOLS_RCSV_NTUPLE_IF_CID(short,short)    507     else TOOLS_RCSV_NTUPLE_IF_CID(short,short)
510     else TOOLS_RCSV_NTUPLE_IF_CID(int,int)        508     else TOOLS_RCSV_NTUPLE_IF_CID(int,int)
511     else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64)    509     else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64)
512                                                   510 
513     else TOOLS_RCSV_NTUPLE_IF_CID(float,float)    511     else TOOLS_RCSV_NTUPLE_IF_CID(float,float)
514     else TOOLS_RCSV_NTUPLE_IF_CID(double,doubl    512     else TOOLS_RCSV_NTUPLE_IF_CID(double,double)
515                                                   513 
516     else TOOLS_RCSV_NTUPLE_IF_CID(uchar,uchar)    514     else TOOLS_RCSV_NTUPLE_IF_CID(uchar,uchar)
517     else TOOLS_RCSV_NTUPLE_IF_CID(ushort,ushor    515     else TOOLS_RCSV_NTUPLE_IF_CID(ushort,ushort)
518     else TOOLS_RCSV_NTUPLE_IF_CID(uint,uint32)    516     else TOOLS_RCSV_NTUPLE_IF_CID(uint,uint32)   //WARNING
519     else TOOLS_RCSV_NTUPLE_IF_CID(uint64,uint6    517     else TOOLS_RCSV_NTUPLE_IF_CID(uint64,uint64)
520                                                   518 
521     else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool)      519     else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool)
522     else if(a_id==column<std::string>::id_clas    520     else if(a_id==column<std::string>::id_class()) {
523       static const std::string s_v("string");     521       static const std::string s_v("string");
524       return s_v;                                 522       return s_v;
525     }                                             523     }
526                                                   524 
527     else if(a_id==column<csv_time>::id_class()    525     else if(a_id==column<csv_time>::id_class()) {
528       static const std::string s_v("time");       526       static const std::string s_v("time");
529       return s_v;                                 527       return s_v;
530     }                                             528     }
531                                                   529 
532     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(char,cha    530     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(char,char)
533     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(short,sh    531     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(short,short)
534     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int,int)    532     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int,int)
535     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,in    533     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,int64)
536                                                   534 
537     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(float,fl    535     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(float,float)
538     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(double,d    536     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(double,double)
539                                                   537 
540     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uchar,uc    538     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uchar,uchar)
541     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(ushort,u    539     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(ushort,ushort)
542     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint,uin    540     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint,uint32)   //WARNING
543     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint64,u    541     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint64,uint64)
544                                                   542 
545     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,boo    543     else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,bool)
546     else if(a_id==column< std::vector<std::str    544     else if(a_id==column< std::vector<std::string> >::id_class()) {
547       static const std::string s_v("string[]")    545       static const std::string s_v("string[]");
548       return s_v;                                 546       return s_v;
549     }                                             547     }
550                                                   548 
551 #undef TOOLS_RCSV_NTUPLE_IF_CID                   549 #undef TOOLS_RCSV_NTUPLE_IF_CID
552 #undef TOOLS_RCSV_NTUPLE_IF_VEC_CID               550 #undef TOOLS_RCSV_NTUPLE_IF_VEC_CID
553                                                   551 
554     else {                                        552     else {
555       static const std::string s_v("unknown");    553       static const std::string s_v("unknown");
556       return s_v;                                 554       return s_v;
557     }                                             555     }
558   }                                               556   }
559                                                   557 
560   void dump_columns(std::ostream& a_out) const    558   void dump_columns(std::ostream& a_out) const {
561     if((m_sep>=32)&&(m_sep<=126)) { //printabl    559     if((m_sep>=32)&&(m_sep<=126)) { //printable
562       a_out << "separator is '" << m_sep << "'    560       a_out << "separator is '" << m_sep << "'" << std::endl;
563     } else {                                      561     } else {
564       a_out << "separator is " << (unsigned in    562       a_out << "separator is " << (unsigned int)m_sep << std::endl;
565     }                                             563     }
566     a_out << "number of columns " << m_cols.si    564     a_out << "number of columns " << m_cols.size() << std::endl;
567     std::vector<read::icol*>::const_iterator i    565     std::vector<read::icol*>::const_iterator it;
568     for(it=m_cols.begin();it!=m_cols.end();++i    566     for(it=m_cols.begin();it!=m_cols.end();++it) {
569       a_out << sout((*it)->name())                567       a_out << sout((*it)->name())
570             << " " << s_cid((*it)->id_cls())      568             << " " << s_cid((*it)->id_cls())
571             << std::endl;                         569             << std::endl;
572     }                                             570     }
573   }                                               571   }
574 public:                                           572 public:
575   typedef std::pair<std::string,std::string> c    573   typedef std::pair<std::string,std::string> col_desc;
576                                                   574 
577   bool initialize(std::ostream& a_out,const nt    575   bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
578     // it assumes a "commented header".           576     // it assumes a "commented header".
579                                                   577 
580     safe_clear<read::icol>(m_cols);               578     safe_clear<read::icol>(m_cols);
581     m_sep = 0;                                    579     m_sep = 0;
582     m_sz = 0;                                     580     m_sz = 0;
583     m_rows = -1;                                  581     m_rows = -1;
584     m_hippo = false;                              582     m_hippo = false;
585                                                   583 
586     m_reader.clear();                             584     m_reader.clear();
587     m_reader.seekg(0,std::ios::end);              585     m_reader.seekg(0,std::ios::end);
588     m_sz = m_reader.tellg();                      586     m_sz = m_reader.tellg();
589     m_reader.seekg(0,std::ios::beg);              587     m_reader.seekg(0,std::ios::beg);
590     if(!m_sz) {                                   588     if(!m_sz) {
591       a_out << "tools::rcsv::ntuple::initializ    589       a_out << "tools::rcsv::ntuple::initialize(booking) :"
592             << " stream is empty."                590             << " stream is empty."
593             << std::endl;                         591             << std::endl;
594       return false; //file empty.                 592       return false; //file empty.
595     }                                             593     }
596     //if(a_verbose) a_out << "file size " << m    594     //if(a_verbose) a_out << "file size " << m_sz << std::endl;
597                                                   595 
598     std::string _title;                           596     std::string _title;
599     char _sep,_vec_sep;                           597     char _sep,_vec_sep;
600     std::vector<col_desc> _cols;                  598     std::vector<col_desc> _cols;
601     if(!read_commented_header(a_out,m_reader,_    599     if(!read_commented_header(a_out,m_reader,_title,_sep,_vec_sep,_cols)) return false;
602                                                   600 
603     m_sep = _sep;                                 601     m_sep = _sep;
604     m_title = std::move(_title);               << 602     m_title = _title;
605                                                   603 
606     tools_vforcit(col_desc,_cols,it) {            604     tools_vforcit(col_desc,_cols,it) {
607       const std::string& type = (*it).first;      605       const std::string& type = (*it).first;
608       const std::string& name = (*it).second;     606       const std::string& name = (*it).second;
609                                                   607 
610 #define TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(a__na    608 #define TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(a__name,a__type) \
611       if(type==(std::string(#a__name)+"[]")) {    609       if(type==(std::string(#a__name)+"[]")) {\
612         create_column< std::vector<a__type> >(    610         create_column< std::vector<a__type> >(name,a_bd.find_variable< std::vector<a__type> >(name));\
613       }                                           611       }
614                                                   612 
615       // see cid2s() for string types.            613       // see cid2s() for string types.
616                                                   614 
617            if(type=="char")   create_column<ch    615            if(type=="char")   create_column<char>(name,a_bd.find_variable<char>(name));
618       else if(type=="short")  create_column<sh    616       else if(type=="short")  create_column<short>(name,a_bd.find_variable<short>(name));
619       else if(type=="int")    create_column<in    617       else if(type=="int")    create_column<int>(name,a_bd.find_variable<int>(name));
620       else if(type=="float")  create_column<fl    618       else if(type=="float")  create_column<float>(name,a_bd.find_variable<float>(name));
621       else if(type=="double") create_column<do    619       else if(type=="double") create_column<double>(name,a_bd.find_variable<double>(name));
622       else if(type=="string") create_column<st    620       else if(type=="string") create_column<std::string>(name,a_bd.find_variable<std::string>(name));
623                                                   621 
624       else if(type=="uchar")  create_column<un    622       else if(type=="uchar")  create_column<unsigned char>(name,a_bd.find_variable<unsigned char>(name));
625       else if(type=="ushort") create_column<un    623       else if(type=="ushort") create_column<unsigned short>(name,a_bd.find_variable<unsigned short>(name));
626       else if(type=="uint")   create_column<ui    624       else if(type=="uint")   create_column<uint32>(name,a_bd.find_variable<uint32>(name)); //WARNING
627       else if(type=="bool")   create_column<bo    625       else if(type=="bool")   create_column<bool>(name,a_bd.find_variable<bool>(name));
628       else if(type=="int64")  create_column<in    626       else if(type=="int64")  create_column<int64>(name,a_bd.find_variable<int64>(name));
629       else if(type=="uint64") create_column<ui    627       else if(type=="uint64") create_column<uint64>(name,a_bd.find_variable<uint64>(name));
630                                                   628 
631       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ch    629       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(char,char)
632       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(sh    630       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(short,short)
633       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(in    631       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(int,int)
634       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(fl    632       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(float,float)
635       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(do    633       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(double,double)
636                                                   634 
637       else if(type=="string[]") create_column<    635       else if(type=="string[]") create_column< std::vector<std::string> >(name,a_bd.find_variable< std::vector<std::string> >(name));
638                                                   636 
639       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uc    637       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uchar,uchar)
640       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(us    638       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ushort,ushort)
641       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ui    639       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uint,uint32)   //WARNING
642       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(bo    640       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(bool,bool)
643       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(in    641       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(int64,int64)
644       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ui    642       else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uint64,uint64)
645                                                   643 
646       else {                                      644       else {
647         a_out << "tools::rcsv::ntuple::initial    645         a_out << "tools::rcsv::ntuple::initialize(booking) :"
648               << " unhandled column type " <<     646               << " unhandled column type " << sout(type)
649               << std::endl;                       647               << std::endl;
650         safe_clear<read::icol>(m_cols);           648         safe_clear<read::icol>(m_cols);
651         m_sep = 0;                                649         m_sep = 0;
652         m_sz = 0;                                 650         m_sz = 0;
653         m_rows = -1;                              651         m_rows = -1;
654         m_hippo = false;                          652         m_hippo = false;
655         return false;                             653         return false;
656       }                                           654       }
657                                                   655 
658 #undef TOOLS_RCSV_NTUPLE_CREATE_VEC_COL           656 #undef TOOLS_RCSV_NTUPLE_CREATE_VEC_COL
659                                                   657 
660     }                                             658     }
661                                                   659 
662     size_t num = m_cols.size();                   660     size_t num = m_cols.size();
663     if(!num) {                                    661     if(!num) {
664       a_out << "tools::rcsv::ntuple::initializ    662       a_out << "tools::rcsv::ntuple::initialize(booking) :"
665             << " zero columns."                   663             << " zero columns."
666             << std::endl;                         664             << std::endl;
667       return false;                               665       return false;
668     }                                             666     }
669                                                   667 
670     //a_out << "tools::rroot::ntuple::initiali    668     //a_out << "tools::rroot::ntuple::initialize :"
671     //      << " number of columns " << num <<    669     //      << " number of columns " << num << "."
672     //      << std::endl;                         670     //      << std::endl;
673                                                   671 
674     return true;                                  672     return true;
675   }                                               673   }
676                                                   674 
677   bool initialize_from_commented_header(std::o    675   bool initialize_from_commented_header(std::ostream& a_out) { // it assumes a "commented header".
678     std::string _title;                           676     std::string _title;
679     char _sep,_vec_sep;                           677     char _sep,_vec_sep;
680     std::vector<col_desc> _cols;                  678     std::vector<col_desc> _cols;
681     if(!read_commented_header(a_out,m_reader,_    679     if(!read_commented_header(a_out,m_reader,_title,_sep,_vec_sep,_cols)) return false;
682     ntuple_binding nbd;                           680     ntuple_binding nbd;
683    {tools_vforcit(col_desc,_cols,it) nbd.add_c    681    {tools_vforcit(col_desc,_cols,it) nbd.add_column_no_var((*it).second);} //user_var is 0.
684     return initialize(a_out,nbd);                 682     return initialize(a_out,nbd);
685   }                                               683   }
686                                                   684 
687   bool get_row() const {                          685   bool get_row() const {
688     bool status = true;                           686     bool status = true;
689     tools_vforcit(read::icol*,m_cols,it) {        687     tools_vforcit(read::icol*,m_cols,it) {
690       if(!(*it)->fetch_entry()) status = false    688       if(!(*it)->fetch_entry()) status = false;
691     }                                             689     }
692     return status;                                690     return status;
693   }                                               691   }
694                                                   692 
695 protected:                                        693 protected:
696   bool read_commented_header(std::ostream& a_o    694   bool read_commented_header(std::ostream& a_out,std::istream& a_reader,
697                              std::string& a_ti    695                              std::string& a_title,char& a_sep,char& a_vec_sep,std::vector<col_desc>& a_cols) {
698     // analyse first lines starting with '#'.     696     // analyse first lines starting with '#'.
699     a_title.clear();                              697     a_title.clear();
700     a_sep = 0;                                    698     a_sep = 0;
701     a_cols.clear();                               699     a_cols.clear();
702                                                   700 
703     a_reader.clear();                             701     a_reader.clear();
704     a_reader.seekg(0,std::ios::end);              702     a_reader.seekg(0,std::ios::end);
705     std::streampos sz = a_reader.tellg();         703     std::streampos sz = a_reader.tellg();
706     a_reader.seekg(0,std::ios::beg);              704     a_reader.seekg(0,std::ios::beg);
707     if(!sz) {                                     705     if(!sz) {
708       a_out << "tools::rcsv::ntuple::read_comm    706       a_out << "tools::rcsv::ntuple::read_commented_header :"
709             << " stream is empty."                707             << " stream is empty."
710             << std::endl;                         708             << std::endl;
711       return false;                               709       return false;
712     } //file empty.                               710     } //file empty.
713                                                   711 
714                                                   712 
715     std::string _class;                           713     std::string _class;
716                                                   714 
717     while(true) {                                 715     while(true) {
718       if(a_reader.tellg()>=sz) break;             716       if(a_reader.tellg()>=sz) break;
719       //we should be at bol :                     717       //we should be at bol :
720       char c;                                     718       char c;
721       a_reader.get(c);                            719       a_reader.get(c);
722       a_reader.putback(c);                        720       a_reader.putback(c);
723       if(c!='#') break; //finished, probably a    721       if(c!='#') break; //finished, probably a data line now.
724       std::string line;                           722       std::string line;
725       if(!read_line(a_reader,sz,line)) break;     723       if(!read_line(a_reader,sz,line)) break; //or return false ?
726                                                   724 
727       std::vector<std::string> _words;            725       std::vector<std::string> _words;
728       words(line," ",false,_words);               726       words(line," ",false,_words);
729       if(!_words.size()) {                        727       if(!_words.size()) {
730         a_out << "tools::rcsv::ntuple::read_co    728         a_out << "tools::rcsv::ntuple::read_commented_header :"
731               << " syntax error : empty header    729               << " syntax error : empty header line."
732               << std::endl;                       730               << std::endl;
733         return false;                             731         return false;
734       }                                           732       }
735       if((_words[0]=="#class")) {                 733       if((_words[0]=="#class")) {
736         if(_words.size()!=2) {                    734         if(_words.size()!=2) {
737           a_out << "tools::rcsv::ntuple::read_    735           a_out << "tools::rcsv::ntuple::read_commented_header :"
738                 << " syntax error in " << sout    736                 << " syntax error in " << sout(line)
739                 << std::endl;                     737                 << std::endl;
740           return false;                           738           return false;
741         }                                         739         }
742         _class = _words[1];                       740         _class = _words[1];
743       } else if(_words[0]=="#title") {            741       } else if(_words[0]=="#title") {
744         if(_words.size()<1) {                     742         if(_words.size()<1) {
745           a_out << "tools::rcsv::ntuple::read_    743           a_out << "tools::rcsv::ntuple::read_commented_header :"
746                 << " syntax error in " << sout    744                 << " syntax error in " << sout(line)
747                 << std::endl;                     745                 << std::endl;
748           return false;                           746           return false;
749         }                                         747         }
750         if(_words.size()==1)  {                   748         if(_words.size()==1)  {
751           a_title.clear();                        749           a_title.clear();
752         } else {                                  750         } else {
753           std::string::size_type pos = line.fi    751           std::string::size_type pos = line.find(_words[0]);
754           pos += _words[0].size()+1;              752           pos += _words[0].size()+1;
755           a_title = line.substr(pos,line.size(    753           a_title = line.substr(pos,line.size()-pos);
756         }                                         754         }
757       } else if((_words[0]=="#separator")) {      755       } else if((_words[0]=="#separator")) {
758         if(_words.size()!=2) {                    756         if(_words.size()!=2) {
759           a_out << "tools::rcsv::ntuple::read_    757           a_out << "tools::rcsv::ntuple::read_commented_header :"
760                 << " syntax error in " << sout    758                 << " syntax error in " << sout(line)
761                 << std::endl;                     759                 << std::endl;
762           return false;                           760           return false;
763         }                                         761         }
764         unsigned int uisep;                       762         unsigned int uisep;
765         if(!to(_words[1],uisep)) {                763         if(!to(_words[1],uisep)) {
766           a_out << "tools::rcsv::ntuple::read_    764           a_out << "tools::rcsv::ntuple::read_commented_header :"
767                 << " syntax error in " << sout    765                 << " syntax error in " << sout(line)
768                 << std::endl;                     766                 << std::endl;
769           return false;                           767           return false;
770         }                                         768         }
771         a_sep = (char)uisep;                      769         a_sep = (char)uisep;
772       } else if((_words[0]=="#vector_separator    770       } else if((_words[0]=="#vector_separator")) {
773         if(_words.size()!=2) {                    771         if(_words.size()!=2) {
774           a_out << "tools::rcsv::ntuple::read_    772           a_out << "tools::rcsv::ntuple::read_commented_header :"
775                 << " syntax error in " << sout    773                 << " syntax error in " << sout(line)
776                 << std::endl;                     774                 << std::endl;
777           return false;                           775           return false;
778         }                                         776         }
779         unsigned int uisep;                       777         unsigned int uisep;
780         if(!to(_words[1],uisep)) {                778         if(!to(_words[1],uisep)) {
781           a_out << "tools::rcsv::ntuple::read_    779           a_out << "tools::rcsv::ntuple::read_commented_header :"
782                 << " syntax error in " << sout    780                 << " syntax error in " << sout(line)
783                 << std::endl;                     781                 << std::endl;
784           return false;                           782           return false;
785         }                                         783         }
786         a_vec_sep = (char)uisep;                  784         a_vec_sep = (char)uisep;
787       } else if((_words[0]=="#column")) {         785       } else if((_words[0]=="#column")) {
788         if(_words.size()<2) {                     786         if(_words.size()<2) {
789           a_out << "tools::rcsv::ntuple::read_    787           a_out << "tools::rcsv::ntuple::read_commented_header :"
790                 << " syntax error in " << sout    788                 << " syntax error in " << sout(line)
791                 << std::endl;                     789                 << std::endl;
792           return false;                           790           return false;
793         }                                         791         }
794         std::string stype = _words[1];            792         std::string stype = _words[1];
795         std::string label;                        793         std::string label;
796         if(_words.size()==2) {                    794         if(_words.size()==2) {
797           label.clear();                          795           label.clear();
798         } else {                                  796         } else {
799           std::string::size_type pos = line.fi    797           std::string::size_type pos = line.find(_words[1]);
800           pos += _words[1].size()+1;              798           pos += _words[1].size()+1;
801           label = line.substr(pos,line.size()-    799           label = line.substr(pos,line.size()-pos);
802         }                                         800         }
803         //a_out << "column " << stype << " " <    801         //a_out << "column " << stype << " " << sout(label) << std::endl;
804         a_cols.push_back(col_desc(stype,label)    802         a_cols.push_back(col_desc(stype,label));
805       } else {                                    803       } else {
806         a_out << "tools::rcsv::ntuple::read_co    804         a_out << "tools::rcsv::ntuple::read_commented_header :"
807               << " syntax error in " << sout(l    805               << " syntax error in " << sout(line)
808               << ", unknown keyword " << sout(    806               << ", unknown keyword " << sout(_words[0])
809               << std::endl;                       807               << std::endl;
810         //return false;                           808         //return false;
811       }                                           809       }
812     }                                             810     }
813                                                   811 
814 /*                                                812 /*
815     a_out << "class " << _class << std::endl;     813     a_out << "class " << _class << std::endl;
816     a_out << "title " << _title << std::endl;     814     a_out << "title " << _title << std::endl;
817     a_out << "separator " << _separator << std    815     a_out << "separator " << _separator << std::endl;
818 */                                                816 */
819                                                   817 
820     return true;                                  818     return true;
821   }                                               819   }
822                                                   820 
823 protected:                                        821 protected:
824   template <class T>                              822   template <class T>
825   column<T>* create_column(const std::string&     823   column<T>* create_column(const std::string& a_name,T* a_user_var = 0){
826     if(find_named<read::icol>(m_cols,a_name))     824     if(find_named<read::icol>(m_cols,a_name)) return 0;
827     column<T>* col = new column<T>(a_name,a_us    825     column<T>* col = new column<T>(a_name,a_user_var);
828     if(!col) return 0;                            826     if(!col) return 0;
829     m_cols.push_back(col);                        827     m_cols.push_back(col);
830     return col;                                   828     return col;
831   }                                               829   }
832                                                   830 
833 protected:                                        831 protected:
834   static bool read_line(std::istream& a_reader    832   static bool read_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
835     a_s.clear();                                  833     a_s.clear();
836     char c;                                       834     char c;
837     while(true) {                                 835     while(true) {
838       if(a_reader.tellg()>=a_sz) {a_s.clear();    836       if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
839       a_reader.get(c);                            837       a_reader.get(c);
840       if(c==CR()) continue;                       838       if(c==CR()) continue;
841       if(c==LF()) break; //eol.                   839       if(c==LF()) break; //eol.
842       a_s += c;                                   840       a_s += c;
843     }                                             841     }
844     return true;                                  842     return true;
845   }                                               843   }
846                                                   844 
847   static bool skip_line(std::istream& a_reader    845   static bool skip_line(std::istream& a_reader,std::streampos a_sz){
848     char c;                                       846     char c;
849     while(true) {                                 847     while(true) {
850       if(a_reader.tellg()>=a_sz) return false;    848       if(a_reader.tellg()>=a_sz) return false;
851       a_reader.get(c);                            849       a_reader.get(c);
852       if(c==LF()) break;                          850       if(c==LF()) break;
853     }                                             851     }
854     return true;                                  852     return true;
855   }                                               853   }
856                                                   854 
857   static bool skip_comment(std::istream& a_rea    855   static bool skip_comment(std::istream& a_reader,std::streampos a_sz){
858     //ret true = we had a commented line, fals    856     //ret true = we had a commented line, false : a data line or nothing.
859     if(a_reader.tellg()>=a_sz) return false;      857     if(a_reader.tellg()>=a_sz) return false;
860     //we should be at bol :                       858     //we should be at bol :
861     char c;                                       859     char c;
862     a_reader.get(c);                              860     a_reader.get(c);
863     if(c=='#') {                                  861     if(c=='#') {
864       return skip_line(a_reader,a_sz);            862       return skip_line(a_reader,a_sz);
865       //eol. Next char should be bol.             863       //eol. Next char should be bol.
866     } else {                                      864     } else {
867       a_reader.putback(c);                        865       a_reader.putback(c);
868       return false;                               866       return false;
869     }                                             867     }
870   }                                               868   }
871                                                   869 
872   template <class T>                              870   template <class T>
873   static bool _read(std::istream& a_reader,std    871   static bool _read(std::istream& a_reader,std::streampos,char,T& a_v) {
874     a_reader >> a_v;                              872     a_reader >> a_v;
875     if(a_reader.tellg()==std::streampos(-1)) {    873     if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;}
876     //std::cout << "debug : _read(double) " <<    874     //std::cout << "debug : _read(double) " << a_v << std::endl;
877     return true;                                  875     return true;
878   }                                               876   }
879   static bool _read_time(std::istream& a_reade    877   static bool _read_time(std::istream& a_reader,std::streampos a_sz,char a_sep,time_t& a_v) {
880     std::string _s;                               878     std::string _s;
881     char c;                                       879     char c;
882     while(true){                                  880     while(true){
883       if(a_reader.tellg()>=a_sz) break;           881       if(a_reader.tellg()>=a_sz) break;
884       a_reader.get(c);                            882       a_reader.get(c);
885       if((c==a_sep)||(c==CR())||(c==LF())) {      883       if((c==a_sep)||(c==CR())||(c==LF())) {
886         a_reader.putback(c);                      884         a_reader.putback(c);
887         break;                                    885         break;
888       }                                           886       }
889       _s += c;                                    887       _s += c;
890     }                                             888     }
891     if(!s2time(_s,a_v)) return false;             889     if(!s2time(_s,a_v)) return false;
892     return true;                                  890     return true;
893   }                                               891   }
894   static bool _read(std::istream& a_reader,std    892   static bool _read(std::istream& a_reader,std::streampos a_sz,char a_sep,std::string& a_v) {
895     a_v.clear();                                  893     a_v.clear();
896     char c;                                       894     char c;
897     while(true){                                  895     while(true){
898       if(a_reader.tellg()>=a_sz) break;           896       if(a_reader.tellg()>=a_sz) break;
899       a_reader.get(c);                            897       a_reader.get(c);
900       if((c==a_sep)||(c==CR())||(c==LF())) {      898       if((c==a_sep)||(c==CR())||(c==LF())) {
901         a_reader.putback(c);                      899         a_reader.putback(c);
902         break;                                    900         break;
903       }                                           901       }
904       a_v += c;                                   902       a_v += c;
905     }                                             903     }
906     return true;                                  904     return true;
907   }                                               905   }
908                                                   906 
909   static bool _vec_read(std::istream& a_reader    907   static bool _vec_read(std::istream& a_reader,std::streampos a_sz,
910                         std::istringstream&,st    908                         std::istringstream&,std::vector<std::string>&,
911                         char a_sep,const std::    909                         char a_sep,const std::string& a_vec_sep,
912                         std::vector<std::strin    910                         std::vector<std::string>& a_v) {
913     std::string _s;                               911     std::string _s;
914     if(!_read(a_reader,a_sz,a_sep,_s)) return     912     if(!_read(a_reader,a_sz,a_sep,_s)) return false;
915     //replace(_s,"\\"+a_vec_sep,"@@");            913     //replace(_s,"\\"+a_vec_sep,"@@");
916     words(_s,a_vec_sep,true,a_v);                 914     words(_s,a_vec_sep,true,a_v);
917     //tools_vforit(std::string,a_v,it) replace    915     //tools_vforit(std::string,a_v,it) replace(*it,"@@",a_vec_sep);
918     return true;                                  916     return true;
919   }                                               917   }
920                                                   918 
921   template <class T>                              919   template <class T>
922   static bool _vec_read(std::istream& a_reader    920   static bool _vec_read(std::istream& a_reader,std::streampos a_sz,
923                         std::istringstream& a_    921                         std::istringstream& a_iss,std::vector<std::string>& a_tmp,
924                         char a_sep,const std::    922                         char a_sep,const std::string& a_vec_sep,
925                         std::vector<T>& a_v) {    923                         std::vector<T>& a_v) {
926     std::string _s;                               924     std::string _s;
927     if(!_read(a_reader,a_sz,a_sep,_s)) return     925     if(!_read(a_reader,a_sz,a_sep,_s)) return false;
928     if(!snums<T>(_s,a_iss,a_tmp,a_vec_sep,a_v)    926     if(!snums<T>(_s,a_iss,a_tmp,a_vec_sep,a_v)) return false;
929     return true;                                  927     return true;
930   }                                               928   }
931                                                   929 
932 protected:                                        930 protected:
933   bool _read_line() {                             931   bool _read_line() {
934     // have to loop on all columns !              932     // have to loop on all columns !
935     typedef read::icol icol_t;                    933     typedef read::icol icol_t;
936                                                   934 
937     typedef ntuple::column<char> col_char;        935     typedef ntuple::column<char> col_char;
938     typedef ntuple::column<short> col_short;      936     typedef ntuple::column<short> col_short;
939     typedef ntuple::column<int> col_int;          937     typedef ntuple::column<int> col_int;
940     typedef ntuple::column<float> col_float;      938     typedef ntuple::column<float> col_float;
941     typedef ntuple::column<double> col_double;    939     typedef ntuple::column<double> col_double;
942     typedef std::string string_t;                 940     typedef std::string string_t;
943     typedef ntuple::column<string_t> col_strin    941     typedef ntuple::column<string_t> col_string_t;
944                                                   942 
945     typedef ntuple::column<uchar> col_uchar;      943     typedef ntuple::column<uchar> col_uchar;
946     typedef ntuple::column<ushort> col_ushort;    944     typedef ntuple::column<ushort> col_ushort;
947     typedef ntuple::column<uint32> col_uint32;    945     typedef ntuple::column<uint32> col_uint32;
948     typedef ntuple::column<bool> col_bool;        946     typedef ntuple::column<bool> col_bool;
949     typedef ntuple::column<int64> col_int64;      947     typedef ntuple::column<int64> col_int64;
950     typedef ntuple::column<uint64> col_uint64;    948     typedef ntuple::column<uint64> col_uint64;
951                                                   949 
952     typedef ntuple::column<csv_time> col_time;    950     typedef ntuple::column<csv_time> col_time;
953                                                   951 
954     typedef ntuple::column< std::vector<char>     952     typedef ntuple::column< std::vector<char> > col_vec_char;
955     typedef ntuple::column< std::vector<short>    953     typedef ntuple::column< std::vector<short> > col_vec_short;
956     typedef ntuple::column< std::vector<int32>    954     typedef ntuple::column< std::vector<int32> > col_vec_int;
957     typedef ntuple::column< std::vector<float>    955     typedef ntuple::column< std::vector<float> > col_vec_float;
958     typedef ntuple::column< std::vector<double    956     typedef ntuple::column< std::vector<double> > col_vec_double;
959     typedef ntuple::column< std::vector<std::s    957     typedef ntuple::column< std::vector<std::string> > col_vec_string_t;
960                                                   958 
961     typedef ntuple::column< std::vector<uchar>    959     typedef ntuple::column< std::vector<uchar> > col_vec_uchar;
962     typedef ntuple::column< std::vector<ushort    960     typedef ntuple::column< std::vector<ushort> > col_vec_ushort;
963     typedef ntuple::column< std::vector<uint32    961     typedef ntuple::column< std::vector<uint32> > col_vec_uint32;
964     typedef ntuple::column< std::vector<bool>     962     typedef ntuple::column< std::vector<bool> > col_vec_bool;
965     typedef ntuple::column< std::vector<int64>    963     typedef ntuple::column< std::vector<int64> > col_vec_int64;
966     typedef ntuple::column< std::vector<uint64    964     typedef ntuple::column< std::vector<uint64> > col_vec_uint64;
967                                                   965 
968     std::string vec_sep;vec_sep += m_vec_sep;     966     std::string vec_sep;vec_sep += m_vec_sep;
969     std::istringstream iss;                       967     std::istringstream iss;
970     std::vector<std::string> tmp;                 968     std::vector<std::string> tmp;
971                                                   969 
972     size_t index = 0;                             970     size_t index = 0;
973     size_t num = m_cols.size();                   971     size_t num = m_cols.size();
974     std::vector<icol_t*>::const_iterator it;      972     std::vector<icol_t*>::const_iterator it;
975     for(it=m_cols.begin();it!=m_cols.end();++i    973     for(it=m_cols.begin();it!=m_cols.end();++it,index++) {
976                                                   974 
977 #define TOOLS_RCSV_NTUPLE_IF_COL(a__type) \       975 #define TOOLS_RCSV_NTUPLE_IF_COL(a__type) \
978       if(col_##a__type* _col_##a__type = id_ca    976       if(col_##a__type* _col_##a__type = id_cast<icol_t,col_##a__type>(*(*it))) {\
979         a__type v;\                               977         a__type v;\
980         if(!_read(m_reader,m_sz,m_sep,v)) retu    978         if(!_read(m_reader,m_sz,m_sep,v)) return false;\
981         _col_##a__type->set_value(v);\            979         _col_##a__type->set_value(v);\
982       }                                           980       }
983                                                   981 
984 #define TOOLS_RCSV_NTUPLE_IF_VEC_COL(a__type)     982 #define TOOLS_RCSV_NTUPLE_IF_VEC_COL(a__type) \
985       if(col_vec_##a__type* _col_vec_##a__type    983       if(col_vec_##a__type* _col_vec_##a__type = id_cast<icol_t,col_vec_##a__type>(*(*it))) {\
986         std::vector<a__type> v;\                  984         std::vector<a__type> v;\
987         if(!_vec_read(m_reader,m_sz,iss,tmp,m_    985         if(!_vec_read(m_reader,m_sz,iss,tmp,m_sep,vec_sep,v)) return false;\
988         _col_vec_##a__type->set_value(v);\        986         _col_vec_##a__type->set_value(v);\
989       }                                           987       }
990                                                   988 
991            TOOLS_RCSV_NTUPLE_IF_COL(char)         989            TOOLS_RCSV_NTUPLE_IF_COL(char)
992       else TOOLS_RCSV_NTUPLE_IF_COL(short)        990       else TOOLS_RCSV_NTUPLE_IF_COL(short)
993       else TOOLS_RCSV_NTUPLE_IF_COL(int)          991       else TOOLS_RCSV_NTUPLE_IF_COL(int)
994       else TOOLS_RCSV_NTUPLE_IF_COL(float)        992       else TOOLS_RCSV_NTUPLE_IF_COL(float)
995       else TOOLS_RCSV_NTUPLE_IF_COL(double)       993       else TOOLS_RCSV_NTUPLE_IF_COL(double)
996       else TOOLS_RCSV_NTUPLE_IF_COL(string_t)     994       else TOOLS_RCSV_NTUPLE_IF_COL(string_t)
997                                                   995 
998       else TOOLS_RCSV_NTUPLE_IF_COL(uchar)        996       else TOOLS_RCSV_NTUPLE_IF_COL(uchar)
999       else TOOLS_RCSV_NTUPLE_IF_COL(ushort)       997       else TOOLS_RCSV_NTUPLE_IF_COL(ushort)
1000       else TOOLS_RCSV_NTUPLE_IF_COL(uint32)      998       else TOOLS_RCSV_NTUPLE_IF_COL(uint32)
1001       else TOOLS_RCSV_NTUPLE_IF_COL(bool)        999       else TOOLS_RCSV_NTUPLE_IF_COL(bool)
1002       else TOOLS_RCSV_NTUPLE_IF_COL(int64)       1000       else TOOLS_RCSV_NTUPLE_IF_COL(int64)
1003       else TOOLS_RCSV_NTUPLE_IF_COL(uint64)      1001       else TOOLS_RCSV_NTUPLE_IF_COL(uint64)
1004                                                  1002 
1005       else if(col_time* _col_time = id_cast<i    1003       else if(col_time* _col_time = id_cast<icol_t,col_time>(*(*it))) {
1006         time_t v;                                1004         time_t v;
1007         if(!_read_time(m_reader,m_sz,m_sep,v)    1005         if(!_read_time(m_reader,m_sz,m_sep,v)) return false;
1008         csv_time ct;ct.m_l = long(v);            1006         csv_time ct;ct.m_l = long(v);
1009         _col_time->set_value(ct);                1007         _col_time->set_value(ct);
1010       }                                          1008       }
1011                                                  1009 
1012       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(char)    1010       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(char)
1013       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(short    1011       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(short)
1014       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int)     1012       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int)
1015       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(float    1013       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(float)
1016       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(doubl    1014       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(double)
1017       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(strin    1015       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(string_t)
1018                                                  1016 
1019       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uchar    1017       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uchar)
1020       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(ushor    1018       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(ushort)
1021       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint3    1019       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint32)
1022       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(bool)    1020       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(bool)
1023       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int64    1021       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int64)
1024       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint6    1022       else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint64)
1025                                                  1023 
1026 #undef TOOLS_RCSV_NTUPLE_IF_COL                  1024 #undef TOOLS_RCSV_NTUPLE_IF_COL
1027 #undef TOOLS_RCSV_NTUPLE_IF_VEC_COL              1025 #undef TOOLS_RCSV_NTUPLE_IF_VEC_COL
1028                                                  1026 
1029       else {                                     1027       else {
1030         //std::cout << "column cast failed."     1028         //std::cout << "column cast failed." << std::endl;
1031         return false;                            1029         return false;
1032       }                                          1030       }
1033                                                  1031 
1034       if(index==(num-1)) { //read up to LF()     1032       if(index==(num-1)) { //read up to LF()
1035         char c;                                  1033         char c;
1036         while(true){                             1034         while(true){
1037           if(m_reader.tellg()>=m_sz) break;      1035           if(m_reader.tellg()>=m_sz) break;
1038           m_reader.get(c);                       1036           m_reader.get(c);
1039           if(c==LF()) break;                     1037           if(c==LF()) break;
1040         }                                        1038         }
1041       } else { //read sep :                      1039       } else { //read sep :
1042         char sep;                                1040         char sep;
1043         m_reader.get(sep);                       1041         m_reader.get(sep);
1044       }                                          1042       }
1045     }                                            1043     }
1046     return true;                                 1044     return true;
1047   }                                              1045   }
1048 protected:                                       1046 protected:
1049   std::istream& m_reader;                        1047   std::istream& m_reader;
1050   std::string m_title;                           1048   std::string m_title;
1051   char m_sep;                                    1049   char m_sep;
1052   char m_vec_sep;                                1050   char m_vec_sep;
1053   std::vector<read::icol*> m_cols;               1051   std::vector<read::icol*> m_cols;
1054   std::streampos m_sz;                           1052   std::streampos m_sz;
1055   int m_rows; //to optimize number_of_entries    1053   int m_rows; //to optimize number_of_entries().
1056   bool m_hippo;                                  1054   bool m_hippo;
1057 };                                               1055 };
1058                                                  1056 
1059 }}                                               1057 }}
1060                                                  1058 
1061                                                  1059 
1062 #include <fstream>                               1060 #include <fstream>
1063                                                  1061 
1064 namespace tools {                                1062 namespace tools {
1065 namespace rcsv {                                 1063 namespace rcsv {
1066                                                  1064 
1067 class fntuple : public ntuple {                  1065 class fntuple : public ntuple {
1068   typedef ntuple parent;                         1066   typedef ntuple parent;
1069 public:                                          1067 public:
1070   static const std::string& s_class() {          1068   static const std::string& s_class() {
1071     static const std::string s_v("tools::rcsv    1069     static const std::string s_v("tools::rcsv::fntuple");
1072     return s_v;                                  1070     return s_v;
1073   }                                              1071   }
1074 public:                                          1072 public:
1075   fntuple(const std::string& a_file)             1073   fntuple(const std::string& a_file)
1076   :parent(m_freader)                             1074   :parent(m_freader)
1077   ,m_file(a_file)                                1075   ,m_file(a_file)
1078   {}                                             1076   {}
1079   virtual ~fntuple() {m_freader.close();}        1077   virtual ~fntuple() {m_freader.close();}
1080 protected:                                       1078 protected:
1081   fntuple(const fntuple& a_from)                 1079   fntuple(const fntuple& a_from)
1082   :read::intuple(a_from)                         1080   :read::intuple(a_from)
1083   ,parent(a_from)                                1081   ,parent(a_from)
1084   ,m_file(a_from.m_file)                         1082   ,m_file(a_from.m_file)
1085   {}                                             1083   {}
1086   fntuple& operator=(const fntuple& a_from){     1084   fntuple& operator=(const fntuple& a_from){
1087     parent::operator=(a_from);                   1085     parent::operator=(a_from);
1088     m_file = a_from.m_file;                      1086     m_file = a_from.m_file;
1089     return *this;                                1087     return *this;
1090   }                                              1088   }
1091 public:                                          1089 public:
1092   bool open(){                                   1090   bool open(){
1093     m_freader.open(m_file.c_str());              1091     m_freader.open(m_file.c_str());
1094     return m_freader.fail()?false:true;          1092     return m_freader.fail()?false:true;
1095   }                                              1093   }
1096   bool initialize(std::ostream& a_out,           1094   bool initialize(std::ostream& a_out,
1097                   char a_sep = 0, //guessed      1095                   char a_sep = 0, //guessed
1098                   const std::string& a_suffix    1096                   const std::string& a_suffix = "x", //col suffix
1099                   bool a_verbose = false) {      1097                   bool a_verbose = false) {
1100     if(!m_freader.is_open()) {                   1098     if(!m_freader.is_open()) {
1101       m_freader.open(m_file.c_str());            1099       m_freader.open(m_file.c_str());
1102       if(m_freader.fail()) {                     1100       if(m_freader.fail()) {
1103         a_out << "tools::rcsv::fntuple::initi    1101         a_out << "tools::rcsv::fntuple::initialize :"
1104               << " can't open " << m_file <<     1102               << " can't open " << m_file << "."
1105               << std::endl;                      1103               << std::endl;
1106         return false;                            1104         return false;
1107       }                                          1105       }
1108     }                                            1106     }
1109     return parent::initialize(a_out,a_sep,a_s    1107     return parent::initialize(a_out,a_sep,a_suffix,a_verbose);
1110   }                                              1108   }
1111 protected:                                       1109 protected:
1112   std::string m_file;                            1110   std::string m_file;
1113   std::ifstream m_freader;                       1111   std::ifstream m_freader;
1114 };                                               1112 };
1115                                                  1113 
1116 }}                                               1114 }}
1117                                                  1115 
1118 #endif                                           1116 #endif