Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wcsv_ntuple is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_wcsv_ntuple
0005 #define tools_wcsv_ntuple
0006 
0007 // A simple ntuple class to write at the csv format.
0008 // (csv = comma separated value).
0009 // Each add_row() write a row at the csv format.
0010 
0011 #include "vmanip"
0012 #include <ostream>
0013 
0014 #include "scast"
0015 #include "ntuple_booking"
0016 #include "sout"
0017 
0018 namespace tools {
0019 namespace wcsv {
0020 
0021 class ntuple {
0022 public:
0023   static const std::string& s_class() {
0024     static const std::string s_v("tools::wcsv::ntuple");
0025     return s_v;
0026   }
0027 public:
0028   class icol {
0029   public:
0030     virtual ~icol(){}
0031   public:
0032     virtual void* cast(cid) const = 0;
0033     virtual cid id_cls() const = 0;
0034   public:
0035     virtual void add() = 0;
0036     virtual const std::string& name() const = 0;
0037   };
0038 
0039 public:
0040   template <class T>
0041   class column_ref : public virtual icol {
0042   public:
0043     static cid id_class() {
0044       static const T s_v = T(); //do that for T = std::string.
0045       return _cid(s_v)+10000;
0046     }
0047     virtual void* cast(cid a_class) const {
0048       if(void* p = cmp_cast<column_ref>(this,a_class)) {return p;}
0049       else return 0;
0050     }
0051     virtual cid id_cls() const {return id_class();}
0052   public: //icol
0053     virtual void add() {m_writer << m_ref;}
0054     virtual const std::string& name() const {return m_name;}
0055   public:
0056     column_ref(std::ostream& a_writer,const std::string& a_name,const T& a_ref)
0057     :m_writer(a_writer)
0058     ,m_name(a_name)
0059     ,m_ref(a_ref)
0060     {}
0061     virtual ~column_ref(){}
0062   protected:
0063     column_ref(const column_ref& a_from)
0064     :icol(a_from)
0065     ,m_writer(a_from.m_writer)
0066     ,m_name(a_from.m_name)
0067     ,m_ref(a_from.m_ref)
0068     {}
0069     column_ref& operator=(const column_ref& a_from){
0070       m_name = a_from.m_name;
0071       return *this;
0072     }
0073   protected:
0074     std::ostream& m_writer;
0075     std::string m_name;
0076     const T& m_ref;
0077   };
0078 
0079   template <class T>
0080   class column : public column_ref<T> {
0081     typedef column_ref<T> parent;
0082   public:
0083     static cid id_class() {
0084       static const T s_v = T(); //do that for T = std::string.
0085       return _cid(s_v);
0086     }
0087     virtual void* cast(cid a_class) const {
0088       if(void* p = cmp_cast<column>(this,a_class)) {return p;}
0089       else return 0;
0090     }
0091     virtual cid id_cls() const {return id_class();}
0092   public: //icol
0093     virtual void add() {parent::add();m_tmp = m_def;}
0094   public:
0095     column(std::ostream& a_writer,const std::string& a_name,const T& a_def)
0096     :parent(a_writer,a_name,m_tmp)
0097     ,m_def(a_def)
0098     ,m_tmp(a_def)
0099     {}
0100     virtual ~column(){}
0101   protected:
0102     column(const column& a_from)
0103     :icol(a_from)
0104     ,parent(a_from)
0105     ,m_def(a_from.m_def)
0106     ,m_tmp(a_from.m_tmp)
0107     {}
0108     column& operator=(const column& a_from){
0109       parent::operator=(a_from);
0110       m_def = a_from.m_def;
0111       m_tmp = a_from.m_tmp;
0112       return *this;
0113     }
0114   public:
0115     bool fill(const T& a_value) {m_tmp = a_value;return true;}
0116   protected:
0117     T m_def;
0118     T m_tmp;
0119   };
0120 
0121   template <class T>
0122   class std_vector_column : public virtual icol {
0123   public:
0124     static cid id_class() {return _cid_std_vector<T>();}
0125     virtual void* cast(cid a_class) const {
0126       if(void* p = cmp_cast<std_vector_column>(this,a_class)) {return p;}
0127       else return 0;
0128     }
0129     virtual cid id_cls() const {return id_class();}
0130   public: //icol
0131     virtual void add() {
0132       if(m_ref.empty()) {
0133       } else {
0134         typedef typename std::vector<T>::const_iterator it_t;
0135         for(it_t it=m_ref.begin();it!=m_ref.end();++it) {
0136           if(it!=m_ref.begin()) m_writer << m_vec_sep;
0137           m_writer << *it;
0138         }
0139       }
0140     }
0141     virtual const std::string& name() const {return m_name;}
0142   public:
0143     std_vector_column(std::ostream& a_writer,const std::string& a_name,const std::vector<T>& a_ref,char a_vec_sep)
0144     :m_writer(a_writer)
0145     ,m_name(a_name)
0146     ,m_ref(a_ref)
0147     ,m_vec_sep(a_vec_sep)
0148     {}
0149     virtual ~std_vector_column(){}
0150   protected:
0151     std_vector_column(const std_vector_column& a_from)
0152     :icol(a_from)
0153     ,m_writer(a_from.m_writer)
0154     ,m_name(a_from.m_name)
0155     ,m_ref(a_from.m_ref)
0156     ,m_vec_sep(a_from.m_vec_sep)
0157     {}
0158     std_vector_column& operator=(const std_vector_column& a_from){
0159       m_name = a_from.m_name;
0160       m_vec_sep = a_from.m_vec_sep;
0161       return *this;
0162     }
0163   protected:
0164     std::ostream& m_writer;
0165     std::string m_name;
0166     const std::vector<T>& m_ref;
0167     char m_vec_sep;
0168   };
0169 
0170 public:
0171   ntuple(std::ostream& a_writer,char a_sep = ',',char a_vec_sep = ';')
0172   :m_writer(a_writer)
0173   ,m_sep(a_sep)
0174   ,m_vec_sep(a_vec_sep)
0175   {}
0176 
0177   ntuple(std::ostream& a_writer,
0178          std::ostream& a_out, //for errors.
0179          const ntuple_booking& a_bkg,
0180          char a_sep = ',',char a_vec_sep = ';')
0181   :m_writer(a_writer)
0182   ,m_sep(a_sep)
0183   ,m_vec_sep(a_vec_sep)
0184   ,m_title(a_bkg.title())
0185   {
0186     const std::vector<column_booking>& cols = a_bkg.columns();
0187     std::vector<column_booking>::const_iterator it;
0188     for(it=cols.begin();it!=cols.end();++it){
0189 
0190 #define TOOLS_WCSV_NTUPLE_CREATE_COL(a__type) \
0191       if((*it).cls_id()==_cid(a__type())) {\
0192         a__type* user = (a__type*)(*it).user_obj();\
0193         if(user) {\
0194           if(!create_column_ref<a__type>((*it).name(),*user)) {\
0195             a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column_ref(" << (*it).name() << ") failed." << std::endl;\
0196             safe_clear<icol>(m_cols);\
0197             return;\
0198           }\
0199         } else {\
0200           if(!create_column<a__type>((*it).name())) {\
0201             a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
0202             safe_clear<icol>(m_cols);\
0203             return;\
0204           }\
0205         }\
0206       }
0207 
0208 #define TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(a__type) \
0209       if((*it).cls_id()==_cid_std_vector<a__type>()) {\
0210         std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
0211         if(vec) {\
0212           if(!create_column<a__type>((*it).name(),*vec)) {\
0213             a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
0214             safe_clear<icol>(m_cols);\
0215             return;\
0216           }\
0217         } else {\
0218           a_out << "tools::wcsv_ntuple :"\
0219                 << " for std::vector column " << sout((*it).name())\
0220                 << ", the user vector pointer is null."\
0221                 << std::endl;\
0222           safe_clear<icol>(m_cols);\
0223           return;\
0224         }\
0225       }
0226 
0227            TOOLS_WCSV_NTUPLE_CREATE_COL(char)
0228       else TOOLS_WCSV_NTUPLE_CREATE_COL(short)
0229       else TOOLS_WCSV_NTUPLE_CREATE_COL(int)
0230       else TOOLS_WCSV_NTUPLE_CREATE_COL(int64)
0231 
0232       else TOOLS_WCSV_NTUPLE_CREATE_COL(float)
0233       else TOOLS_WCSV_NTUPLE_CREATE_COL(double)
0234 
0235       else TOOLS_WCSV_NTUPLE_CREATE_COL(byte)
0236       else TOOLS_WCSV_NTUPLE_CREATE_COL(ushort)
0237       else TOOLS_WCSV_NTUPLE_CREATE_COL(uint32)
0238       else TOOLS_WCSV_NTUPLE_CREATE_COL(uint64)
0239 
0240       else TOOLS_WCSV_NTUPLE_CREATE_COL(bool)
0241       else TOOLS_WCSV_NTUPLE_CREATE_COL(std::string)
0242 
0243       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(char)
0244       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(short)
0245       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int)
0246       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int64)
0247 
0248       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(float)
0249       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(double)
0250 
0251       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uchar)
0252       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(ushort)
0253       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint32)
0254       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint64)
0255 
0256       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(std::string)
0257       else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(bool)
0258 
0259 #undef TOOLS_WCSV_NTUPLE_CREATE_VEC_COL
0260 #undef TOOLS_WCSV_NTUPLE_CREATE_COL
0261 
0262       else {
0263         a_out << "tools::wcsv::ntuple :"
0264               << " for column " << sout((*it).name())
0265               << ", type with cid " << (*it).cls_id() << " not yet handled."
0266               << std::endl;
0267         //throw
0268         safe_clear<icol>(m_cols);
0269         return;
0270       }
0271     }
0272   }
0273 
0274   virtual ~ntuple() {
0275     safe_clear<icol>(m_cols);
0276   }
0277 protected:
0278   ntuple(const ntuple& a_from)
0279   :m_writer(a_from.m_writer)
0280   ,m_sep(a_from.m_sep)
0281   ,m_vec_sep(a_from.m_vec_sep)
0282   ,m_title(a_from.m_title)
0283   {}
0284   ntuple& operator=(const ntuple& a_from){
0285     m_sep = a_from.m_sep;
0286     m_vec_sep = a_from.m_vec_sep;
0287     m_title = a_from.m_title;
0288     return *this;
0289   }
0290 public:
0291   void write_hippo_header() {
0292     m_writer << m_title << std::endl;
0293     std::vector<icol*>::const_iterator it;
0294     for(it=m_cols.begin();it!=m_cols.end();++it){
0295       if(it!=m_cols.begin()) m_writer << '\t';
0296       m_writer << (*it)->name();
0297     }
0298     m_writer << std::endl;
0299   }
0300 
0301   bool write_commented_header(std::ostream& a_out) {
0302     // commented header similar to the histo case.
0303     m_writer << "#class " << s_class() << std::endl;
0304     m_writer << "#title " << m_title << std::endl;
0305     m_writer << "#separator " << (unsigned int)m_sep << std::endl;
0306     m_writer << "#vector_separator " << (unsigned int)m_vec_sep << std::endl;
0307     bool status = true;
0308    {for(unsigned int count=0;count<m_cols.size();count++) {
0309        icol* _col = m_cols[count];
0310        std::string sid;
0311        if(!cid2s(_col->id_cls(),sid)) {
0312          a_out << "tools::wcsv::ntuple::write_commented_header :"
0313                << " unknown column type id " << _col->id_cls() << std::endl;
0314          status = false; //but we continue.
0315        } else {
0316          m_writer << "#column " << sid << " " << _col->name() << std::endl;
0317        }
0318     }}
0319     return status;
0320   }
0321 
0322   template <class T>
0323   column_ref<T>* create_column_ref(const std::string& a_name,const T& a_ref) {
0324     if(find_named<icol>(m_cols,a_name)) return 0;
0325     column_ref<T>* col = new column_ref<T>(m_writer,a_name,a_ref);
0326     if(!col) return 0;
0327     m_cols.push_back(col);
0328     return col;
0329   }
0330 
0331   template <class T>
0332   column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0333     if(find_named<icol>(m_cols,a_name)) return 0;
0334     column<T>* col = new column<T>(m_writer,a_name,a_def);
0335     if(!col) return 0;
0336     m_cols.push_back(col);
0337     return col;
0338   }
0339 
0340   template <class T>
0341   std_vector_column<T>* create_column(const std::string& a_name,const std::vector<T>& a_ref) {
0342     //NOTE : to optimize, we do not handle a default std::vector value logic.
0343     if(find_named<icol>(m_cols,a_name)) return 0;
0344     std_vector_column<T>* col = new std_vector_column<T>(m_writer,a_name,a_ref,m_vec_sep);
0345     if(!col) return 0;
0346     m_cols.push_back(col);
0347     return col;
0348   }
0349 
0350   template <class T>
0351   column_ref<T>* find_column_ref(const std::string& a_name) {
0352     icol* col = find_named<icol>(m_cols,a_name);
0353     if(!col) return 0;
0354     return id_cast<icol, column_ref<T> >(*col);
0355   }
0356 
0357   template <class T>
0358   column<T>* find_column(const std::string& a_name) {
0359     icol* col = find_named<icol>(m_cols,a_name);
0360     if(!col) return 0;
0361     return id_cast<icol, column<T> >(*col);
0362   }
0363 
0364   bool add_row() {
0365     if(m_cols.empty()) return false;
0366     std::vector<icol*>::iterator it;
0367     it=m_cols.begin();
0368     (*it)->add();
0369     it++;
0370     for(;it!=m_cols.end();++it) {
0371       m_writer << m_sep;
0372       (*it)->add();
0373     }
0374     m_writer << std::endl;
0375     return true;
0376   }
0377 
0378   const std::vector<icol*>& columns() const {return m_cols;}
0379 
0380   void set_title(const std::string& a_value) {m_title = a_value;}
0381   const std::string& title() const {return m_title;}
0382 protected:
0383   std::ostream& m_writer;
0384   char m_sep;
0385   char m_vec_sep;
0386   std::string m_title;
0387   std::vector<icol*> m_cols;
0388 };
0389 
0390 }}
0391 
0392 #endif