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