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 10.2.p3)


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