Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wcsv_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 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_wcsv_ntuple
  5 #define tools_wcsv_ntuple
  6 
  7 // A simple ntuple class to write at the csv format.
  8 // (csv = comma separated value).
  9 // Each add_row() write a row at the csv format.
 10 
 11 #include "vfind"
 12 #include "vmanip"
 13 #include <ostream>
 14 
 15 #include "scast"
 16 #include "ntuple_booking"
 17 #include "sout"
 18 //#include "srep"
 19 
 20 namespace tools {
 21 namespace wcsv {
 22 
 23 class ntuple {
 24 public:
 25   static const std::string& s_class() {
 26     static const std::string s_v("tools::wcsv::ntuple");
 27     return s_v;
 28   }
 29 public:
 30   class icol {
 31   public:
 32     virtual ~icol(){}
 33   public:
 34     virtual void* cast(cid) const = 0;
 35     virtual cid id_cls() const = 0;
 36   public:
 37     virtual void add() = 0;
 38     virtual const std::string& name() const = 0;
 39   };
 40 
 41 public:
 42   template <class T>
 43   class column_ref : public virtual icol {
 44   public:
 45     static cid id_class() {
 46       static const T s_v = T(); //do that for T = std::string.
 47       return _cid(s_v)+10000;
 48     }
 49     virtual void* cast(cid a_class) const {
 50       if(void* p = cmp_cast<column_ref>(this,a_class)) {return p;}
 51       else return 0;
 52     }
 53     virtual cid id_cls() const {return id_class();}
 54   public: //icol
 55     virtual void add() {m_writer << m_ref;}
 56     virtual const std::string& name() const {return m_name;}
 57   public:
 58     column_ref(std::ostream& a_writer,const std::string& a_name,const T& a_ref)
 59     :m_writer(a_writer)
 60     ,m_name(a_name)
 61     ,m_ref(a_ref)
 62     {}
 63     virtual ~column_ref(){}
 64   protected:
 65     column_ref(const column_ref& a_from)
 66     :icol(a_from)
 67     ,m_writer(a_from.m_writer)
 68     ,m_name(a_from.m_name)
 69     ,m_ref(a_from.m_ref)
 70     {}
 71     column_ref& operator=(const column_ref& a_from){
 72       m_name = a_from.m_name;
 73       return *this;
 74     }
 75   protected:
 76     std::ostream& m_writer;
 77     std::string m_name;
 78     const T& m_ref;
 79   };
 80 
 81   template <class T>
 82   class column : public column_ref<T> {
 83     typedef column_ref<T> parent;
 84   public:
 85     static cid id_class() {
 86       static const T s_v = T(); //do that for T = std::string.
 87       return _cid(s_v);
 88     }
 89     virtual void* cast(cid a_class) const {
 90       if(void* p = cmp_cast<column>(this,a_class)) {return p;}
 91       else return 0;
 92     }
 93     virtual cid id_cls() const {return id_class();}
 94   public: //icol
 95     virtual void add() {parent::add();m_tmp = m_def;}
 96   public:
 97     column(std::ostream& a_writer,const std::string& a_name,const T& a_def)
 98     :parent(a_writer,a_name,m_tmp)
 99     ,m_def(a_def)
100     ,m_tmp(a_def)
101     {}
102     virtual ~column(){}
103   protected:
104     column(const column& a_from)
105     :icol(a_from)
106     ,parent(a_from)
107     ,m_def(a_from.m_def)
108     ,m_tmp(a_from.m_tmp)
109     {}
110     column& operator=(const column& a_from){
111       parent::operator=(a_from);
112       m_def = a_from.m_def;
113       m_tmp = a_from.m_tmp;
114       return *this;
115     }
116   public:
117     bool fill(const T& a_value) {m_tmp = a_value;return true;}
118   protected:
119     T m_def;
120     T m_tmp;
121   };
122 
123 /*
124   template <class T>
125   static void escape(T&,const std::string&){}
126   static void escape(std::string& a_s,const std::string& a_sep){
127     replace(a_s,a_sep,"\\"+a_sep); //if changing here, change rcsv_ntuple/_vec_read() too.
128   }
129 */
130 
131   template <class T>
132   class std_vector_column : public virtual icol {
133   public:
134     static cid id_class() {return _cid_std_vector<T>();}
135     virtual void* cast(cid a_class) const {
136       if(void* p = cmp_cast<std_vector_column>(this,a_class)) {return p;}
137       else return 0;
138     }
139     virtual cid id_cls() const {return id_class();}
140   public: //icol
141     virtual void add() {
142       if(m_ref.empty()) {
143         //m_writer << "none";
144       } else {
145         //std::string sep;sep+=m_vec_sep;
146         //T value;
147         typedef typename std::vector<T>::const_iterator it_t;
148         for(it_t it=m_ref.begin();it!=m_ref.end();++it) {
149           if(it!=m_ref.begin()) m_writer << m_vec_sep;
150           m_writer << *it;
151           //value = *it;escape(value,sep);
152           //m_writer << value;
153         }
154       }
155     }
156     virtual const std::string& name() const {return m_name;}
157   public:
158     std_vector_column(std::ostream& a_writer,const std::string& a_name,const std::vector<T>& a_ref,char a_vec_sep)
159     :m_writer(a_writer)
160     ,m_name(a_name)
161     ,m_ref(a_ref)
162     ,m_vec_sep(a_vec_sep)
163     {}
164     virtual ~std_vector_column(){}
165   protected:
166     std_vector_column(const std_vector_column& a_from)
167     :icol(a_from)
168     ,m_writer(a_from.m_writer)
169     ,m_name(a_from.m_name)
170     ,m_ref(a_from.m_ref)
171     ,m_vec_sep(a_from.m_vec_sep)
172     {}
173     std_vector_column& operator=(const std_vector_column& a_from){
174       m_name = a_from.m_name;
175       m_vec_sep = a_from.m_vec_sep;
176       return *this;
177     }
178   protected:
179     std::ostream& m_writer;
180     std::string m_name;
181     const std::vector<T>& m_ref;
182     char m_vec_sep;
183   };
184 
185 public:
186   ntuple(std::ostream& a_writer,char a_sep = ',',char a_vec_sep = ';')
187   :m_writer(a_writer)
188   ,m_sep(a_sep)
189   ,m_vec_sep(a_vec_sep)
190   {}
191 
192   ntuple(std::ostream& a_writer,
193          std::ostream& a_out, //for errors.
194          const ntuple_booking& a_bkg,
195          char a_sep = ',',char a_vec_sep = ';')
196   :m_writer(a_writer)
197   ,m_sep(a_sep)
198   ,m_vec_sep(a_vec_sep)
199   ,m_title(a_bkg.title())
200   {
201     const std::vector<column_booking>& cols = a_bkg.columns();
202     std::vector<column_booking>::const_iterator it;
203     for(it=cols.begin();it!=cols.end();++it){
204 
205 #define TOOLS_WCSV_NTUPLE_CREATE_COL(a__type) \
206       if((*it).cls_id()==_cid(a__type())) {\
207         a__type* user = (a__type*)(*it).user_obj();\
208         if(user) {\
209           if(!create_column_ref<a__type>((*it).name(),*user)) {\
210       a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column_ref(" << (*it).name() << ") failed." << std::endl;\
211       safe_clear<icol>(m_cols);\
212       return;\
213     }\
214         } else {\
215           if(!create_column<a__type>((*it).name())) {\
216       a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
217       safe_clear<icol>(m_cols);\
218       return;\
219     }\
220   }\
221       }
222 
223 #define TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(a__type) \
224       if((*it).cls_id()==_cid_std_vector<a__type>()) {\
225         std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
226         if(vec) {\
227           if(!create_column<a__type>((*it).name(),*vec)) {\
228       a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
229       safe_clear<icol>(m_cols);\
230       return;\
231     }\
232         } else {\
233           a_out << "tools::wcsv_ntuple :"\
234                 << " for std::vector column " << sout((*it).name())\
235                 << ", the user vector pointer is null."\
236                 << std::endl;\
237           safe_clear<icol>(m_cols);\
238           return;\
239         }\
240       }
241 
242            TOOLS_WCSV_NTUPLE_CREATE_COL(char)
243       else TOOLS_WCSV_NTUPLE_CREATE_COL(short)
244       else TOOLS_WCSV_NTUPLE_CREATE_COL(int)
245       else TOOLS_WCSV_NTUPLE_CREATE_COL(int64)
246 
247       else TOOLS_WCSV_NTUPLE_CREATE_COL(float)
248       else TOOLS_WCSV_NTUPLE_CREATE_COL(double)
249 
250       else TOOLS_WCSV_NTUPLE_CREATE_COL(byte)
251       else TOOLS_WCSV_NTUPLE_CREATE_COL(ushort)
252       else TOOLS_WCSV_NTUPLE_CREATE_COL(uint32)
253       else TOOLS_WCSV_NTUPLE_CREATE_COL(uint64)
254 
255       else TOOLS_WCSV_NTUPLE_CREATE_COL(bool)
256       else TOOLS_WCSV_NTUPLE_CREATE_COL(std::string)
257 
258       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(char)
259       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(short)
260       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int)
261       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int64)
262 
263       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(float)
264       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(double)
265 
266       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uchar)
267       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(ushort)
268       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint32)
269       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint64)
270 
271       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(std::string)
272       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(bool)
273 
274 #undef TOOLS_WCSV_NTUPLE_CREATE_VEC_COL
275 #undef TOOLS_WCSV_NTUPLE_CREATE_COL
276 
277       else {
278         a_out << "tools::wcsv::ntuple :"
279               << " for column " << sout((*it).name())
280               << ", type with cid " << (*it).cls_id() << " not yet handled."
281               << std::endl;
282         //throw
283         safe_clear<icol>(m_cols);
284         return;
285       }
286     }
287   }
288 
289   virtual ~ntuple() {
290     safe_clear<icol>(m_cols);
291   }
292 protected:
293   ntuple(const ntuple& a_from)
294   :m_writer(a_from.m_writer)
295   ,m_sep(a_from.m_sep)
296   ,m_vec_sep(a_from.m_vec_sep)
297   ,m_title(a_from.m_title)
298   {}
299   ntuple& operator=(const ntuple& a_from){
300     m_sep = a_from.m_sep;
301     m_vec_sep = a_from.m_vec_sep;
302     m_title = a_from.m_title;
303     return *this;
304   }
305 public:
306   void write_hippo_header() {
307     m_writer << m_title << std::endl;
308     std::vector<icol*>::const_iterator it;
309     for(it=m_cols.begin();it!=m_cols.end();++it){
310       if(it!=m_cols.begin()) m_writer << '\t';
311       m_writer << (*it)->name();
312     }
313     m_writer << std::endl;
314   }
315 
316   bool write_commented_header(std::ostream& a_out) {
317     // commented header similar to the histo case.
318     m_writer << "#class " << s_class() << std::endl;
319     m_writer << "#title " << m_title << std::endl;
320     m_writer << "#separator " << (unsigned int)m_sep << std::endl;
321     m_writer << "#vector_separator " << (unsigned int)m_vec_sep << std::endl;
322     bool status = true;
323    {for(unsigned int count=0;count<m_cols.size();count++) {
324        icol* _col = m_cols[count];
325        std::string sid;
326        if(!cid2s(_col->id_cls(),sid)) {
327          a_out << "tools::wcsv::ntuple::write_commented_header :"
328                << " unknown column type id " << _col->id_cls() << std::endl;
329          status = false; //but we continue.
330        } else {
331          m_writer << "#column " << sid << " " << _col->name() << std::endl;
332        }
333     }}
334     return status;
335   }
336 
337   template <class T>
338   column_ref<T>* create_column_ref(const std::string& a_name,const T& a_ref) {
339     if(find_named<icol>(m_cols,a_name)) return 0;
340     column_ref<T>* col = new column_ref<T>(m_writer,a_name,a_ref);
341     if(!col) return 0;
342     m_cols.push_back(col);
343     return col;
344   }
345 
346   template <class T>
347   column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
348     if(find_named<icol>(m_cols,a_name)) return 0;
349     column<T>* col = new column<T>(m_writer,a_name,a_def);
350     if(!col) return 0;
351     m_cols.push_back(col);
352     return col;
353   }
354 
355   template <class T>
356   std_vector_column<T>* create_column(const std::string& a_name,const std::vector<T>& a_ref) {
357     //NOTE : to optimize, we do not handle a default std::vector value logic.
358     if(find_named<icol>(m_cols,a_name)) return 0;
359     std_vector_column<T>* col = new std_vector_column<T>(m_writer,a_name,a_ref,m_vec_sep);
360     if(!col) return 0;
361     m_cols.push_back(col);
362     return col;
363   }
364 
365   template <class T>
366   column_ref<T>* find_column_ref(const std::string& a_name) {
367     icol* col = find_named<icol>(m_cols,a_name);
368     if(!col) return 0;
369     return id_cast<icol, column_ref<T> >(*col);
370   }
371 
372   template <class T>
373   column<T>* find_column(const std::string& a_name) {
374     icol* col = find_named<icol>(m_cols,a_name);
375     if(!col) return 0;
376     return id_cast<icol, column<T> >(*col);
377   }
378 
379   bool add_row() {
380     if(m_cols.empty()) return false;
381     std::vector<icol*>::iterator it;
382     it=m_cols.begin();
383     (*it)->add();
384     it++;
385     for(;it!=m_cols.end();++it) {
386       m_writer << m_sep;
387       (*it)->add();
388     }
389     m_writer << std::endl;
390     return true;
391   }
392 
393   const std::vector<icol*>& columns() const {return m_cols;}
394 
395   void set_title(const std::string& a_value) {m_title = a_value;}
396   const std::string& title() const {return m_title;}
397 protected:
398   std::ostream& m_writer;
399   char m_sep;
400   char m_vec_sep;
401   std::string m_title;
402   std::vector<icol*> m_cols;
403 };
404 
405 }}
406 
407 #endif