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