Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/waxml/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_waxml_ntuple
0005 #define tools_waxml_ntuple
0006 
0007 // A ntuple class to write at the aida tuple format.
0008 // Each add_row() write a row at the aida tuple format.
0009 
0010 #include "../vmanip"
0011 #include "../sout"
0012 #include "../srep"
0013 #include "../tos"
0014 #include "../forit"
0015 
0016 #include <ostream>
0017 
0018 // for sub_ntuple :
0019 #include "../scast"
0020 #include <sstream>
0021 
0022 #include "../ntuple_booking"
0023 
0024 namespace tools {
0025 namespace waxml {
0026 
0027 class ntuple {
0028 protected:
0029 
0030   class iobj {
0031   public:
0032     virtual ~iobj(){}
0033   public:
0034     virtual void* cast(cid) const = 0;
0035     virtual cid id_cls() const = 0;
0036   public:
0037     virtual const std::string& name() const = 0;
0038     virtual const std::string& aida_type() const = 0;
0039   };
0040 
0041   class leaf : public virtual iobj {
0042   public:
0043     static cid id_class() {return 100;}
0044   public: //iobj
0045     virtual void* cast(cid a_class) const {
0046       if(void* p = cmp_cast<leaf>(this,a_class)) {return p;}
0047       return 0;
0048     }
0049     virtual cid id_cls() const {return id_class();}
0050   public:
0051     virtual const std::string& s_def() const = 0;
0052     virtual void s_value(std::string&) const = 0;
0053   public:
0054     leaf(){}
0055     virtual ~leaf(){}
0056     leaf(const leaf& a_from):iobj(a_from){}
0057     leaf& operator=(const leaf&){return *this;}
0058   };
0059 
0060   static const std::string& s_aida_type(int) {
0061     static const std::string s_v("int");
0062     return s_v;
0063   }
0064   static const std::string& s_aida_type(float) {
0065     static const std::string s_v("float");
0066     return s_v;
0067   }
0068   static const std::string& s_aida_type(double) {
0069     static const std::string s_v("double");
0070     return s_v;
0071   }
0072   static const std::string& s_aida_type(const std::string&) {
0073     static const std::string s_v("string");
0074     return s_v;
0075   }
0076 
0077   static const std::string& s_aida_type_ituple() {
0078     static const std::string s_v("ITuple");
0079     return s_v;
0080   }
0081 
0082 public:
0083   template <class T>
0084   class column : public leaf {
0085   public:
0086     static cid id_class() {return 200+_cid(T());}
0087   public: //iobj
0088     virtual void* cast(cid a_class) const {
0089       if(void* p = cmp_cast< column<T> >(this,a_class)) {return p;}
0090       return leaf::cast(a_class);
0091     }
0092     virtual cid id_cls() const {return id_class();}
0093   public:
0094     virtual const std::string& name() const {return m_name;}
0095     virtual const std::string& aida_type() const {return s_aida_type(T());}
0096   public: //leaf
0097     virtual const std::string& s_def() const {return m_def;}
0098     virtual void s_value(std::string& a_s) const {a_s = tos(m_tmp);}
0099   public:
0100     column(const std::string& a_name,const T& a_def)
0101     :m_name(a_name),m_def(tos(a_def)),m_tmp(a_def)
0102     {}
0103     virtual ~column(){}
0104   protected:
0105     column(const column& a_from)
0106     :leaf(a_from)
0107     ,m_name(a_from.m_name)
0108     ,m_def(a_from.m_def)
0109     ,m_tmp(a_from.m_tmp)
0110     {}
0111     column& operator=(const column& a_from){
0112       m_name = a_from.m_name;
0113       m_def = a_from.m_def;
0114       m_tmp = a_from.m_tmp;
0115       return *this;
0116     }
0117   public:
0118     bool fill(const T& a_value) {m_tmp = a_value;return true;}
0119   protected:
0120     std::string m_name;
0121     std::string m_def;
0122     T m_tmp;
0123   };
0124 
0125 
0126   class sub_ntuple : public virtual iobj {
0127   public:
0128     static cid id_class() {return 300;}
0129   public: //iobj
0130     virtual void* cast(cid a_class) const {
0131       if(void* p = cmp_cast<sub_ntuple>(this,a_class)) {return p;}
0132       return 0;
0133     }
0134     virtual cid id_cls() const {return id_class();}
0135   public:
0136     virtual const std::string& name() const {return m_name;}
0137     virtual const std::string& aida_type() const {return s_aida_type_ituple();}
0138   public:
0139     sub_ntuple(const std::string& a_name,const std::string& a_spaces)
0140     :m_name(a_name),m_spaces(a_spaces){}
0141     virtual ~sub_ntuple(){}
0142   protected:
0143     sub_ntuple(const sub_ntuple& a_from)
0144     :iobj(a_from),m_name(a_from.m_name){}
0145     sub_ntuple& operator=(const sub_ntuple&){return *this;}
0146   public:
0147     template <class T>
0148     column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0149       if(find_named<iobj>(m_cols,a_name)) return 0;
0150       column<T>* col = new column<T>(a_name,a_def);
0151       if(!col) return 0;
0152       m_cols.push_back(col);
0153       return col;
0154     }
0155 
0156     sub_ntuple* create_sub_ntuple(const std::string& a_name){
0157       if(find_named<iobj>(m_cols,a_name)) return 0;
0158       std::string spaces;
0159       for(unsigned int i=0;i<4;i++) spaces += " ";
0160       sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
0161       if(!col) return 0;
0162       m_cols.push_back(col);
0163       return col;
0164     }
0165 
0166 
0167     const std::vector<iobj*>& columns() const {return m_cols;}
0168 
0169     std::string booking(bool a_xml_esc) const {
0170       std::string _s;
0171       get_booking(m_cols,a_xml_esc,_s);
0172       return _s;
0173     }
0174     void reset() {m_tmp.clear();}
0175     const std::string& value() const {return m_tmp;}
0176 
0177     bool add_row() {
0178       if(m_cols.empty()) return false;
0179       std::ostringstream sout;
0180       sout << m_spaces << "<row>" << std::endl;
0181       tools_vforcit(iobj*,m_cols,it) {
0182         if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))) {
0183           sout << m_spaces << "  <entryITuple>" << std::endl;
0184           sout << sub->value();
0185           sout << m_spaces << "  </entryITuple>" << std::endl;
0186           sub->reset();
0187         } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0188           std::string _sv;
0189           lf->s_value(_sv);
0190           sout << m_spaces << "  <entry"
0191                << " value=\"" << _sv
0192                << "\"/>" << std::endl;
0193         }
0194       }
0195       sout << m_spaces << "</row>" << std::endl;
0196 
0197       m_tmp += sout.str();
0198 
0199       return true;
0200     }
0201   protected:
0202     std::string m_name;
0203     std::string m_spaces;
0204     std::vector<iobj*> m_cols;
0205     std::string m_tmp;
0206   };
0207 
0208   template <class T>
0209   class std_vector_column : public leaf {
0210   public:
0211     static cid id_class() {return 200+_cid_std_vector<T>();}
0212   public: //iobj
0213     virtual void* cast(cid a_class) const {
0214       if(void* p = cmp_cast<std_vector_column>(this,a_class)) {return p;}
0215       return leaf::cast(a_class);
0216     }
0217     virtual cid id_cls() const {return id_class();}
0218   public:
0219     virtual const std::string& name() const {return m_name;}
0220     virtual const std::string& aida_type() const {return s_aida_type(T());}
0221   public: //leaf
0222     virtual const std::string& s_def() const {return m_def;} //not used.
0223     virtual void s_value(std::string& a_s) const {
0224       std::ostringstream sout;
0225       sout << m_spaces << "<entryITuple>" << std::endl;
0226       typedef typename std::vector<T>::const_iterator it_t;
0227       for(it_t it=m_user_vec.begin();it!=m_user_vec.end();++it) {
0228         sout << m_spaces << "  <row><entry" << " value=\"" << tos(*it) << "\"/></row>" << std::endl;
0229       }
0230       sout << m_spaces << "</entryITuple>" << std::endl;
0231       a_s = sout.str();
0232     }
0233   public:
0234     std_vector_column(const std::string& a_name,std::vector<T>& a_user_vec,const std::string& a_spaces)
0235     :m_name(a_name)
0236     ,m_user_vec(a_user_vec)
0237     ,m_spaces(a_spaces)
0238     {}
0239     virtual ~std_vector_column(){}
0240   protected:
0241     std_vector_column(const std_vector_column& a_from)
0242     :leaf(a_from)
0243     ,m_name(a_from.m_name)
0244     ,m_user_vec(a_from.m_user_vec)
0245     ,m_spaces(a_from.m_spaces)
0246     {}
0247     std_vector_column& operator=(const std_vector_column& a_from){
0248       m_name = a_from.m_name;
0249       m_spaces = a_from.m_spaces;
0250       return *this;
0251     }
0252   protected:
0253     std::string m_name;
0254     std::string m_def; //not used;
0255     std::vector<T>& m_user_vec;
0256     std::string m_spaces;
0257   };
0258 
0259   static leaf* is_std_vector_column(iobj& a_obj) {
0260     //200+20+id(basic type) ?
0261     int _id = (int)a_obj.id_cls()-220;
0262     if((_id<=0)||(_id>=20)) return 0;
0263     return id_cast<iobj,leaf>(a_obj);
0264   }
0265 
0266 public:
0267   ntuple(std::ostream& a_writer,unsigned int a_spaces = 0)
0268   :m_writer(a_writer){
0269     for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
0270   }
0271   ntuple(std::ostream& a_writer,
0272          std::ostream& a_out,
0273          const ntuple_booking& a_bkg,
0274          unsigned int a_spaces = 0)
0275   :m_writer(a_writer){
0276     for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
0277 
0278     const std::vector<column_booking>& cols = a_bkg.columns();
0279     tools_vforcit(column_booking,cols,it){
0280 
0281       if((*it).cls_id()==_cid(int(0))) {
0282         create_column<int>((*it).name());
0283       } else if((*it).cls_id()==_cid(float(0))) {
0284         create_column<float>((*it).name());
0285       } else if((*it).cls_id()==_cid(double(0))) {
0286         create_column<double>((*it).name());
0287       } else if((*it).cls_id()==_cid(std::string())) {
0288         create_column<std::string>((*it).name());
0289 
0290       } else if((*it).cls_id()==_cid_std_vector<int>()) {
0291         std::vector<int>* vec = (std::vector<int>*)(*it).user_obj();
0292         if(vec) {
0293           create_column<int>((*it).name(),*vec);
0294         } else {
0295           a_out << "tools::waxml::ntuple :"
0296                 << " for std::vector column " << sout((*it).name())
0297                 << ", the user vector pointer is null."
0298                 << std::endl;
0299           safe_clear<iobj>(m_cols);
0300           return;
0301         }
0302       } else if((*it).cls_id()==_cid_std_vector<float>()) {
0303         std::vector<float>* vec = (std::vector<float>*)(*it).user_obj();
0304         if(vec) {
0305           create_column<float>((*it).name(),*vec);
0306         } else {
0307           a_out << "tools::waxml::ntuple :"
0308                 << " for std::vector column " << sout((*it).name())
0309                 << ", the user vector pointer is null."
0310                 << std::endl;
0311           safe_clear<iobj>(m_cols);
0312           return;
0313         }
0314       } else if((*it).cls_id()==_cid_std_vector<double>()) {
0315         std::vector<double>* vec = (std::vector<double>*)(*it).user_obj();
0316         if(vec) {
0317           create_column<double>((*it).name(),*vec);
0318         } else {
0319           a_out << "tools::waxml::ntuple :"
0320                 << " for std::vector column " << sout((*it).name())
0321                 << ", the user vector pointer is null."
0322                 << std::endl;
0323           safe_clear<iobj>(m_cols);
0324           return;
0325         }
0326 
0327       } else if((*it).cls_id()==_cid_std_vector<std::string>()) {
0328         std::vector<std::string>* vec = (std::vector<std::string>*)(*it).user_obj();
0329         if(vec) {
0330           create_column<std::string>((*it).name(),*vec);
0331         } else {
0332           a_out << "tools::waxml::ntuple :"
0333                 << " for std::vector column " << sout((*it).name())
0334                 << ", the user vector pointer is null."
0335                 << std::endl;
0336           safe_clear<iobj>(m_cols);
0337           return;
0338         }
0339 
0340       } else {
0341         a_out << "tools::waxml::ntuple :"
0342               << " for column " << sout((*it).name())
0343               << ", type with cid " << (*it).cls_id() << " not yet handled."
0344               << std::endl;
0345         //throw
0346         safe_clear<iobj>(m_cols);
0347         return;
0348       }
0349     }
0350   }
0351   virtual ~ntuple() {
0352     safe_clear<iobj>(m_cols);
0353   }
0354 protected:
0355   ntuple(const ntuple& a_from)
0356   :m_writer(a_from.m_writer)
0357   ,m_spaces(a_from.m_spaces)
0358   {}
0359   ntuple& operator=(const ntuple& a_from){
0360     m_spaces = a_from.m_spaces;
0361     return *this;
0362   }
0363 public:
0364   const std::vector<iobj*>& columns() const {return m_cols;}
0365 
0366   template <class T>
0367   column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0368     if(find_named<iobj>(m_cols,a_name)) return 0;
0369     column<T>* col = new column<T>(a_name,a_def);
0370     if(!col) return 0;
0371     m_cols.push_back(col);
0372     return col;
0373   }
0374 
0375   template <class T>
0376   std_vector_column<T>* create_column(const std::string& a_name,std::vector<T>& a_user_vec) {
0377     if(find_named<iobj>(m_cols,a_name)) return 0;
0378     std::string spaces;
0379     for(unsigned int i=0;i<8;i++) spaces += " ";
0380     std_vector_column<T>* col = new std_vector_column<T>(a_name,a_user_vec,m_spaces+spaces);
0381     if(!col) return 0;
0382     m_cols.push_back(col);
0383     return col;
0384   }
0385 
0386   template <class T>
0387   column<T>* find_column(const std::string& a_name) {
0388     iobj* col = find_named<iobj>(m_cols,a_name);
0389     if(!col) return 0;
0390     return id_cast<iobj, column<T> >(*col);
0391   }
0392 
0393   sub_ntuple* create_sub_ntuple(const std::string& a_name){
0394     if(find_named<iobj>(m_cols,a_name)) return 0;
0395     std::string spaces;
0396     for(unsigned int i=0;i<10;i++) spaces += " ";
0397     sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
0398     if(!col) return 0;
0399     m_cols.push_back(col);
0400     return col;
0401   }
0402 
0403   void write_header(const std::string& a_path,const std::string& a_name,const std::string& a_title){
0404 
0405     // <tuple> :
0406     m_writer << m_spaces << "  <tuple"
0407              << " path=" << sout(to_xml(a_path))
0408              << " name=" << sout(to_xml(a_name))
0409              << " title=" << sout(to_xml(a_title))
0410              << ">" << std::endl;
0411 
0412     // <columns> :
0413     m_writer << m_spaces << "    <columns>" << std::endl;
0414 
0415     tools_vforcit(iobj*,m_cols,it) {
0416       if(leaf* vlf = is_std_vector_column(*(*it))) {
0417         m_writer << m_spaces << "      <column"
0418                  << " name=" << sout(to_xml((*it)->name()))
0419                  << " type=" << sout("ITuple")
0420                  << " booking=\"{" << vlf->aida_type() << " " << to_xml((*it)->name())
0421                  << "}\""
0422                  << "/>" << std::endl;
0423       } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0424         m_writer << m_spaces << "      <column"
0425                  << " name=" << sout(to_xml((*it)->name()))
0426                  << " type=" << sout("ITuple")
0427                  << " booking=" << sout(sub->booking(true))
0428                  << "/>" << std::endl;
0429       } else if(/*leaf* lf =*/ id_cast<iobj,leaf>(*(*it))){
0430         m_writer << m_spaces << "      <column"
0431                  << " name=" << sout(to_xml((*it)->name()))
0432                  << " type=" << sout((*it)->aida_type())
0433                  << "/>" << std::endl;
0434       }
0435     }
0436 
0437     m_writer << m_spaces << "    </columns>" << std::endl;
0438 
0439     // rows :
0440     m_writer << m_spaces << "    <rows>" << std::endl;
0441   }
0442 
0443   bool add_row() {
0444     if(m_cols.empty()) return false;
0445     m_writer << m_spaces << "      <row>" << std::endl;
0446     tools_vforcit(iobj*,m_cols,it) {
0447       if(leaf* vlf = is_std_vector_column(*(*it))) {
0448         std::string _sv;
0449         vlf->s_value(_sv);
0450         m_writer << _sv;
0451       } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0452         m_writer << m_spaces << "        <entryITuple>" << std::endl;
0453         m_writer << sub->value();
0454         m_writer << m_spaces << "        </entryITuple>" << std::endl;
0455         sub->reset();
0456       } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0457         std::string _sv;
0458         lf->s_value(_sv);
0459         m_writer << m_spaces << "        <entry"
0460                  << " value=" << sout(_sv)
0461                  << "/>" << std::endl;
0462       }
0463     }
0464     m_writer << m_spaces << "      </row>" << std::endl;
0465     return true;
0466   }
0467 
0468   void write_trailer() {
0469     m_writer << m_spaces << "    </rows>" << std::endl;
0470     m_writer << m_spaces << "  </tuple>" << std::endl;
0471   }
0472 
0473   std::string booking(bool a_xml_esc) const {
0474     std::string _s;
0475     get_booking(m_cols,a_xml_esc,_s);
0476     return _s;
0477   }
0478 
0479 protected:
0480   static void get_booking(const std::vector<iobj*>& a_cols,bool a_xml_esc,
0481                           std::string& a_string) {
0482     a_string += "{"; //we need the + because of the tuple in tuple.
0483 
0484     tools_vforcit(iobj*,a_cols,it) {
0485       if(it!=a_cols.begin()) a_string += ",";
0486 
0487       std::string sname = (*it)->name();
0488       if(a_xml_esc) sname = to_xml(sname);
0489 
0490       if(leaf* vlf = is_std_vector_column(*(*it))) {
0491         a_string += "ITuple " + (*it)->name() + " = {" + vlf->aida_type() + " " + sname + "}";
0492 
0493       } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0494         a_string += (*it)->aida_type() + " " + sname + " = ";
0495 
0496         get_booking(sub->columns(),a_xml_esc,a_string);
0497       } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0498         a_string += (*it)->aida_type() + " " + sname + " = " + lf->s_def();
0499       }
0500     }
0501     a_string += "}";
0502   }
0503 
0504 protected:
0505   std::ostream& m_writer;
0506   std::string m_spaces;
0507   std::vector<iobj*> m_cols;
0508 };
0509 
0510 }}
0511 
0512 #endif