Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/rroot/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_rroot_ntuple
0005 #define tools_rroot_ntuple
0006 
0007 // to have same API than rcsv::ntuple.
0008 
0009 #include "../rntuple"
0010 
0011 #include "tree"
0012 #include "leaf"
0013 #include "stl_vector"
0014 
0015 #include "../cids"
0016 #include "../vfind"
0017 #include "../vmanip"
0018 #include "../ntuple_binding"
0019 #include "../get_lines"
0020 
0021 #ifdef TOOLS_MEM
0022 #include "../mem"
0023 #endif
0024 
0025 namespace tools {
0026 namespace rroot {
0027 
0028 class ntuple : public virtual read::intuple {
0029   typedef read::intuple parent;
0030 public:
0031   static const std::string& s_class() {
0032     static const std::string s_v("tools::rroot::ntuple");
0033     return s_v;
0034   }
0035   virtual const std::string& s_cls() const {return s_class();}
0036 public: //intuple
0037   virtual void start() {m_index = -1;}
0038   virtual bool next() {
0039     m_index++;
0040     if((uint64)m_index>=m_tree.entries()) return false;
0041     return true;
0042   }
0043   virtual read::icol* find_icol(const std::string& a_name){
0044     return find_named<read::icol>(m_cols,a_name);
0045   }
0046   virtual const std::vector<read::icol*>& columns() const {return m_cols;}
0047   virtual const std::string& title() const {return m_tree.title();}
0048   virtual bool number_of_entries(uint64 & a_value) const {a_value = m_tree.entries();return true;}
0049 public:
0050 
0051   template <class T,class LEAF>
0052   class column_ref : public virtual read::icolumn<T> {
0053     typedef read::icolumn<T> parent;
0054   public:
0055     static cid id_class() {return 200+_cid(T())+10000;}
0056   public: //icol
0057     virtual void* cast(cid a_class) const {
0058       if(void* p = cmp_cast<column_ref>(this,a_class)) return p;
0059       return parent::cast(a_class);
0060     }
0061     virtual cid id_cls() const {return id_class();}
0062   public: //icol
0063     virtual const std::string& name() const {return m_leaf.name();}
0064   public: //icolumn<T>
0065     virtual bool fetch_entry() const {return _fetch_entry();}
0066     virtual bool get_entry(T& a_v) const {
0067       if(!_fetch_entry()) {a_v = T();return false;}
0068       a_v = m_ref;
0069       return true;
0070     }
0071   public:
0072     column_ref(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index,T& a_ref)
0073     :m_file(a_file)
0074     ,m_branch(a_branch)
0075     ,m_leaf(a_leaf)
0076     ,m_index(a_index) //WARNING : we keep the ref !
0077     ,m_ref(a_ref)
0078     {}
0079     virtual ~column_ref(){}
0080   protected:
0081     column_ref(const column_ref& a_from)
0082     :read::icol(a_from)
0083     ,parent(a_from)
0084     ,m_file(a_from.m_file)
0085     ,m_branch(a_from.m_branch)
0086     ,m_leaf(a_from.m_leaf)
0087     ,m_index(a_from.m_index)
0088     ,m_ref(a_from.m_ref)
0089     {}
0090     column_ref& operator=(const column_ref& a_from){
0091       if(&a_from==this) return *this;
0092       return *this;
0093     }
0094   protected:
0095     //typedef typename LEAF::value_t value_t;
0096     bool _fetch_entry() const {
0097       unsigned int n;
0098       if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;}
0099       if(!m_leaf.num_elem()) {m_ref = T();return true;} //it is ok. It may be a vector from a row_wise ntuple column.
0100       typename LEAF::value_t _tmp;
0101       if(!m_leaf.value(0,_tmp)) return false;
0102       m_ref = T(_tmp);
0103       return true;
0104     }
0105   protected:
0106     ifile& m_file;
0107     branch& m_branch;
0108     LEAF& m_leaf;
0109     int64& m_index; //WARNING : a ref.
0110     T& m_ref;
0111     //value_t m_tmp;
0112   };
0113 
0114   template <class T,class LEAF>
0115   class column : public column_ref<T,LEAF> {
0116     typedef column_ref<T,LEAF> parent;
0117   public:
0118     static cid id_class() {return 200+_cid(T());}
0119   public: //icol
0120     virtual void* cast(cid a_class) const {
0121       if(void* p = cmp_cast<column>(this,a_class)) return p;
0122       return parent::cast(a_class);
0123     }
0124     virtual cid id_cls() const {return id_class();}
0125   public:
0126     column(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index)
0127     :parent(a_file,a_branch,a_leaf,a_index,m_value)
0128     ,m_value(T())
0129     {}
0130     virtual ~column(){}
0131   protected:
0132     column(const column& a_from)
0133     :read::icol(a_from)
0134     ,read::icolumn<T>(a_from)
0135     ,parent(a_from)
0136     ,m_value(a_from.m_value)
0137     {}
0138     column& operator=(const column& a_from){
0139       if(&a_from==this) return *this;
0140       m_value = a_from.m_value;
0141       return *this;
0142     }
0143   public:
0144     const T& get_value() const {return m_value;}
0145   protected:
0146     T m_value;
0147   };
0148 
0149   class column_string_ref : public virtual read::icol {
0150     typedef read::icol parent;
0151   public:
0152     static cid id_class() {
0153       static const std::string s_v;
0154       return _cid(s_v)+10000;
0155     }
0156   public: //icol
0157     virtual void* cast(cid a_class) const {
0158       if(void* p = cmp_cast<column_string_ref>(this,a_class)) return p;
0159       return 0;
0160     }
0161     virtual cid id_cls() const {return id_class();}
0162     virtual const std::string& name() const {return m_leaf.name();}
0163   public:
0164     virtual bool fetch_entry() const {return _fetch_entry();}
0165   public:
0166     column_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,std::string& a_ref)
0167     :m_file(a_file)
0168     ,m_branch(a_branch)
0169     ,m_leaf(a_leaf)
0170     ,m_index(a_index) //WARNING : we keep the ref !
0171     ,m_ref(a_ref)
0172     {}
0173     virtual ~column_string_ref(){}
0174   protected:
0175     column_string_ref(const column_string_ref& a_from)
0176     :parent(a_from)
0177     ,m_file(a_from.m_file)
0178     ,m_branch(a_from.m_branch)
0179     ,m_leaf(a_from.m_leaf)
0180     ,m_index(a_from.m_index)
0181     ,m_ref(a_from.m_ref)
0182     {}
0183     column_string_ref& operator=(const column_string_ref& a_from){
0184       if(&a_from==this) return *this;
0185       return *this;
0186     }
0187   public:
0188     bool get_entry(std::string& a_v) const {
0189       if(!_fetch_entry()) {a_v.clear();return false;}
0190       a_v = m_ref;
0191       return true;
0192     }
0193   protected:
0194     bool _fetch_entry() const {
0195       unsigned int n;
0196       if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;}
0197       const char* _cs = m_leaf.value();
0198       if(!_cs) {m_ref.clear();return false;}
0199       m_ref = _cs;
0200       return true;
0201     }
0202   protected:
0203     ifile& m_file;
0204     branch& m_branch;
0205     leaf_string& m_leaf;
0206     int64& m_index; //WARNING : a ref.
0207     std::string& m_ref;
0208   };
0209 
0210   class column_string : public column_string_ref {
0211     typedef column_string_ref parent;
0212   public:
0213     static cid id_class() {
0214       static const std::string s_v;
0215       return _cid(s_v);
0216     }
0217   public: //icol
0218     virtual void* cast(cid a_class) const {
0219       if(void* p = cmp_cast<column_string>(this,a_class)) return p;
0220       return parent::cast(a_class);
0221     }
0222     virtual cid id_cls() const {return id_class();}
0223     virtual const std::string& name() const {return m_leaf.name();}
0224   public:
0225     column_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index)
0226     :parent(a_file,a_branch,a_leaf,a_index,m_value)
0227     {}
0228     virtual ~column_string(){}
0229   protected:
0230     column_string(const column_string& a_from)
0231     :read::icol(a_from)
0232     ,parent(a_from)
0233     ,m_value(a_from.m_value)
0234     {}
0235     column_string& operator=(const column_string& a_from){
0236       if(&a_from==this) return *this;
0237       m_value = a_from.m_value;
0238       return *this;
0239     }
0240   public:
0241     const std::string& get_value() const {return m_value;}
0242   protected:
0243     std::string m_value;
0244   };
0245 
0246   class column_vector_string_ref : public column_string_ref {
0247     typedef column_string_ref parent;
0248   public:
0249     static cid id_class() {return _cid_std_vector<std::string>()+10000;}
0250   public: //icol
0251     virtual void* cast(cid a_class) const {
0252       if(void* p = cmp_cast<column_vector_string_ref>(this,a_class)) return p;
0253       return parent::cast(a_class);
0254     }
0255     virtual cid id_cls() const {return id_class();}
0256     virtual const std::string& name() const {return m_leaf.name();}
0257   public:
0258     virtual bool fetch_entry() const {return _fetch_entry();}
0259   public:
0260     column_vector_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,
0261                              std::vector<std::string>& a_ref,char a_sep)
0262     :parent(a_file,a_branch,a_leaf,a_index,m_value)
0263     ,m_ref(a_ref)
0264     ,m_sep(a_sep)
0265     {}
0266     virtual ~column_vector_string_ref(){}
0267   protected:
0268     column_vector_string_ref(const column_vector_string_ref& a_from)
0269     :read::icol(a_from)
0270     ,parent(a_from)
0271     ,m_ref(a_from.m_ref)
0272     ,m_sep(a_from.m_sep)
0273     {}
0274     column_vector_string_ref& operator=(const column_vector_string_ref& a_from){
0275       if(&a_from==this) return *this;
0276       m_sep = a_from.m_sep;
0277       return *this;
0278     }
0279   public:
0280     bool get_entry(std::vector<std::string>& a_v) const {
0281       if(!_fetch_entry()) {a_v.clear();return false;}
0282       a_v = m_ref;
0283       return true;
0284     }
0285   protected:
0286     bool _fetch_entry() const {
0287       if(!parent::_fetch_entry()) return false;
0288       get_lines(m_value,m_ref);
0289       return true;
0290     }
0291   protected:
0292     std::vector<std::string>& m_ref;
0293     char m_sep;
0294     std::string m_value;
0295   };
0296 
0297   class column_vector_string : public column_vector_string_ref {
0298     typedef column_vector_string_ref parent;
0299   public:
0300     static cid id_class() {return _cid_std_vector<std::string>();}
0301   public: //icol
0302     virtual void* cast(cid a_class) const {
0303       if(void* p = cmp_cast<column_vector_string>(this,a_class)) return p;
0304       return parent::cast(a_class);
0305     }
0306     virtual cid id_cls() const {return id_class();}
0307     virtual const std::string& name() const {return m_leaf.name();}
0308   public:
0309     column_vector_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,char a_sep)
0310     :parent(a_file,a_branch,a_leaf,a_index,m_value,a_sep)
0311     {}
0312     virtual ~column_vector_string(){}
0313   protected:
0314     column_vector_string(const column_vector_string& a_from)
0315     :read::icol(a_from)
0316     ,parent(a_from)
0317     ,m_value(a_from.m_value)
0318     {}
0319     column_vector_string& operator=(const column_vector_string& a_from){
0320       if(&a_from==this) return *this;
0321       m_value = a_from.m_value;
0322       return *this;
0323     }
0324   public:
0325     const std::vector<std::string>& get_value() const {return m_value;}
0326   protected:
0327     std::vector<std::string> m_value;
0328   };
0329 
0330   // to read row_wise columns with vector of basic types :
0331   template <class T>
0332   class std_vector_column_ref : public virtual read::icolumn<T> {
0333     typedef read::icolumn<T> parent;
0334   public:
0335     static cid id_class() {return 200+_cid(T())+10000;}
0336   public: //icol
0337     virtual void* cast(cid a_class) const {
0338       if(void* p = cmp_cast<std_vector_column_ref>(this,a_class)) return p;
0339       return parent::cast(a_class);
0340     }
0341     virtual cid id_cls() const {return id_class();}
0342   public: //icol
0343     virtual const std::string& name() const {return m_leaf.name();}
0344   public: //icolumn<T>
0345     virtual bool fetch_entry() const {return _fetch_entry();}
0346     virtual bool get_entry(T& a_v) const {
0347       if(!_fetch_entry()) {a_v = T();return false;}
0348       if(m_ref.empty()) {a_v = T();return false;}
0349       a_v = m_ref[0];
0350       return true;
0351     }
0352   public:
0353     std_vector_column_ref(ifile& a_file,branch& a_branch,leaf<T>& a_leaf,int64& a_index,std::vector<T>& a_ref)
0354     :m_file(a_file)
0355     ,m_branch(a_branch)
0356     ,m_leaf(a_leaf)
0357     ,m_index(a_index) //WARNING : we keep the ref !
0358     ,m_ref(a_ref)
0359     {}
0360     virtual ~std_vector_column_ref(){}
0361   protected:
0362     std_vector_column_ref(const std_vector_column_ref& a_from)
0363     :read::icol(a_from)
0364     ,parent(a_from)
0365     ,m_file(a_from.m_file)
0366     ,m_branch(a_from.m_branch)
0367     ,m_leaf(a_from.m_leaf)
0368     ,m_index(a_from.m_index)
0369     ,m_ref(a_from.m_ref)
0370     {}
0371     std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
0372       if(&a_from==this) return *this;
0373       return *this;
0374     }
0375   protected:
0376     bool _fetch_entry() const {
0377       unsigned int n;
0378       if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;}
0379       m_leaf.value(m_ref);
0380       return true;
0381     }
0382   protected:
0383     ifile& m_file;
0384     branch& m_branch;
0385     leaf<T>& m_leaf;
0386     int64& m_index; //WARNING : a ref.
0387     std::vector<T>& m_ref;
0388   };
0389 
0390   // to read column_wise columns with vector of basic types :
0391   template <class RT,class T>
0392   class column_element_ref : public virtual read::icolumn<T> {
0393     typedef read::icolumn<T> parent;
0394   public:
0395     static cid id_class() {return 300+_cid(T())+10000;}
0396   public: //icol
0397     virtual void* cast(cid a_class) const {
0398       if(void* p = cmp_cast<column_element_ref>(this,a_class)) return p;
0399       return parent::cast(a_class);
0400     }
0401     virtual cid id_cls() const {return id_class();}
0402   public: //icol
0403     virtual const std::string& name() const {return m_leaf.name();}
0404   public: //icolumn<T>
0405     virtual bool fetch_entry() const {return _fetch_entry();}
0406     virtual bool get_entry(T& a_v) const {
0407       if(!_fetch_entry()) {a_v = T();return false;}
0408       a_v = m_ref;
0409       return true;
0410     }
0411   public:
0412     column_element_ref(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index,T& a_ref)
0413     :m_file(a_file)
0414     ,m_be(a_branch)
0415     ,m_leaf(a_leaf)
0416     ,m_index(a_index) //WARNING : we keep the ref !
0417     ,m_ref(a_ref)
0418     {}
0419     virtual ~column_element_ref(){}
0420   protected:
0421     column_element_ref(const column_element_ref& a_from)
0422     :read::icol(a_from),parent(a_from)
0423     ,m_file(a_from.m_file)
0424     ,m_be(a_from.m_be)
0425     ,m_leaf(a_from.m_leaf)
0426     ,m_index(a_from.m_index)
0427     ,m_ref(a_from.m_ref)
0428     {}
0429     column_element_ref& operator=(const column_element_ref& a_from){
0430       if(&a_from==this) return *this;
0431       return *this;
0432     }
0433   protected:
0434     bool _fetch_entry() const {
0435       unsigned int n;
0436       if(!m_be.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;}
0437       iro* obj = m_be.object(); //Not owner.
0438       if(!obj)  {m_ref = T();return false;}
0439       RT* v = id_cast<iro,RT>(*obj);
0440       if(!v)  {m_ref = T();return false;}
0441       m_ref = *v; //it assumes a T::operator=(RT)
0442       return true;
0443     }
0444   protected:
0445     ifile& m_file;
0446     branch_element& m_be;
0447     leaf_element& m_leaf;
0448     int64& m_index; //WARNING : a ref.
0449     T& m_ref;
0450   };
0451 
0452   template <class RT,class T>
0453   class column_element : public column_element_ref<RT,T> {
0454     typedef column_element_ref<RT,T> parent;
0455   public:
0456     static cid id_class() {return 300+_cid(T());}
0457   public: //icol
0458     virtual void* cast(cid a_class) const {
0459       if(void* p = cmp_cast<column_element>(this,a_class)) return p;
0460       return parent::cast(a_class);
0461     }
0462     virtual cid id_cls() const {return id_class();}
0463   public:
0464     column_element(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index)
0465     :parent(a_file,a_branch,a_leaf,a_index,m_value)
0466     ,m_value(T())
0467     {}
0468     virtual ~column_element(){}
0469   protected:
0470     column_element(const column_element& a_from)
0471     :read::icol(a_from)
0472     ,read::icolumn<T>(a_from)
0473     ,parent(a_from)
0474     ,m_value(a_from.m_value)
0475     {}
0476     column_element& operator=(const column_element& a_from){
0477       if(&a_from==this) return *this;
0478       m_value = a_from.m_value;
0479       return *this;
0480     }
0481   public:
0482     const T& get_value() const {return m_value;}
0483   protected:
0484     T m_value;
0485   };
0486 
0487 public:
0488   ntuple(tree& a_tree):m_tree(a_tree),m_index(-1){
0489 #ifdef TOOLS_MEM
0490     mem::increment(s_class().c_str());
0491 #endif
0492   }
0493   virtual ~ntuple() {
0494     safe_clear<read::icol>(m_cols);
0495 #ifdef TOOLS_MEM
0496     mem::decrement(s_class().c_str());
0497 #endif
0498   }
0499 protected:
0500   ntuple(const ntuple& a_from)
0501   :parent(a_from),m_tree(a_from.m_tree){
0502 #ifdef TOOLS_MEM
0503     mem::increment(s_class().c_str());
0504 #endif
0505   }
0506   ntuple& operator=(const ntuple&){return *this;}
0507 public:
0508   bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding(),bool a_enforce_double = false) {
0509     safe_clear<read::icol>(m_cols);
0510 
0511     std::vector<base_leaf*> leaves;
0512     m_tree.find_leaves(leaves);
0513     tools_vforcit(base_leaf*,leaves,it) {
0514       base_leaf* bl = (*it);
0515       if(find_named<read::icol>(m_cols,bl->name())) {
0516         a_out << "tools::rroot::ntuple::initialize :"
0517               << " column with name " << sout(bl->name())
0518               << " already exists."
0519               << std::endl;
0520         safe_clear<read::icol>(m_cols);
0521         return false;
0522       }
0523       branch* _branch = m_tree.find_leaf_branch(*bl);
0524       if(!_branch) {
0525         a_out << "tools::rroot::ntuple::initialize :"
0526               << " can't find branch of leaf " << sout(bl->name()) << "."
0527               << std::endl;
0528         safe_clear<read::icol>(m_cols);
0529         return false;
0530       }
0531 
0532       //a_out << "tools::rroot::ntuple::initialize :"
0533       //      << " branch " << _branch->name()
0534       //      << ", entries " << _branch->entry_number() << "."
0535       //      << std::endl;
0536 
0537 #define TOOLS_RROOT_NTUPLE_CREATE_COL(a__type) \
0538       if(leaf<a__type>* lf_##a__type = safe_cast<base_leaf, leaf<a__type> >(*bl) ){\
0539         cid user_cid;void* user_obj;\
0540         a_bd.find_user_obj(bl->name(),user_cid,user_obj);\
0541         typedef leaf<a__type> leaf_t;\
0542         if(!user_obj) {\
0543           if(a_enforce_double) {\
0544             column<double,leaf_t>* col = new column<double,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\
0545             m_cols.push_back(col);\
0546           } else {\
0547             column<a__type,leaf_t>* col = new column<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\
0548             m_cols.push_back(col);\
0549           }\
0550         } else {\
0551           const base_leaf* lfc = bl->leaf_count();\
0552           if(lfc) {\
0553             /*::printf("debug : ntuple : create col leaf count : %s\n",bl->name().c_str());*/\
0554             if(user_cid!=_cid_std_vector<a__type>()) {\
0555               a_out << "tools::rroot::ntuple::initialize :"\
0556                     << " for leaf with name " << sout(bl->name())\
0557                     << ", user variable type is not a std::vector of " << #a__type << "."\
0558                     << std::endl;\
0559               safe_clear<read::icol>(m_cols);\
0560               return false;\
0561             }\
0562             std::vector<a__type>* user_var = (std::vector<a__type>*)user_obj;\
0563             std_vector_column_ref<a__type>* col = new std_vector_column_ref<a__type>\
0564               (m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\
0565             m_cols.push_back(col);\
0566           } else {\
0567             /*::printf("debug : ntuple : create col : %s\n",bl->name().c_str());*/\
0568             if(user_cid!=_cid(a__type())) {\
0569               a_out << "tools::rroot::ntuple::initialize :"\
0570                     << " for leaf with name " << sout(bl->name())\
0571                     << ", user variable type is not a " << #a__type << "."\
0572                     << std::endl;\
0573               safe_clear<read::icol>(m_cols);\
0574               return false;\
0575             }\
0576             a__type* user_var = (a__type*)user_obj;\
0577             column_ref<a__type,leaf_t>* col =\
0578               new column_ref<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\
0579             m_cols.push_back(col);\
0580           }\
0581         }\
0582       }
0583 
0584       //below types are in sync with wroot/ntuple.
0585 
0586            TOOLS_RROOT_NTUPLE_CREATE_COL(char)
0587       else TOOLS_RROOT_NTUPLE_CREATE_COL(short)
0588       else TOOLS_RROOT_NTUPLE_CREATE_COL(int)
0589       else TOOLS_RROOT_NTUPLE_CREATE_COL(float)
0590       else TOOLS_RROOT_NTUPLE_CREATE_COL(double)
0591 
0592       else if(leaf_string* ls = safe_cast<base_leaf, leaf_string >(*bl) ){
0593         char sep = '\n';
0594         cid user_cid;void* user_obj;
0595         if(!a_bd.find_user_obj(bl->name(),user_cid,user_obj)) {
0596           column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep);
0597           m_cols.push_back(col);
0598         } else if(user_cid==_cid_std_vector<std::string>()) {
0599           std::vector<std::string>* user_var = (std::vector<std::string>*)user_obj;
0600           if(user_var) {
0601             column_vector_string_ref* col = new column_vector_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var,sep);
0602             m_cols.push_back(col);
0603           } else {
0604             column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep);
0605             m_cols.push_back(col);
0606           }
0607         } else if(user_cid==_cid(std::string())) {
0608           std::string* user_var = (std::string*)user_obj;
0609           if(user_var) {
0610             column_string_ref* col = new column_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var);
0611             m_cols.push_back(col);
0612           } else {
0613             column_string* col = new column_string(m_tree.file(),*_branch,*ls,m_index);
0614             m_cols.push_back(col);
0615           }
0616         } else {
0617           a_out << "tools::rroot::ntuple::initialize :"
0618                 << " for leaf with name " << sout(ls->name())
0619                 << ", user variable type is not a std::string or a std::vector<std::string>."
0620                 << ". It's class id is " << user_cid << "."
0621                 << std::endl;
0622           safe_clear<read::icol>(m_cols);
0623           return false;
0624         }
0625 
0626       } else if(leaf_element* le = safe_cast<base_leaf,leaf_element>(*bl) ){
0627 
0628         branch_element* be = safe_cast<branch,branch_element>(*_branch);
0629         if(!be) {
0630           a_out << "tools::rroot::ntuple::initialize : branch is not a branch_element." << std::endl;
0631           safe_clear<read::icol>(m_cols);
0632           return false;
0633         }
0634 
0635 #define TOOLS_RROOT_NTUPLE_CREATE_VEC_COL(a__name,a__type) \
0636         if(be->class_name()==a__name) {\
0637           /*::printf("debug : ntuple : create vec col : %s\n",bl->name().c_str());*/\
0638           typedef a__type el_t;\
0639           std::vector<el_t>* user_var = a_bd.find_vector_variable<el_t>(bl->name());\
0640           if(user_var) {\
0641             typedef column_element_ref< stl_vector<el_t> , std::vector<el_t> > ce_t;\
0642             ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index,*user_var);\
0643             m_cols.push_back(col);\
0644           } else {\
0645             typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;\
0646             ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index);\
0647             m_cols.push_back(col);\
0648           }\
0649         }
0650 
0651              TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<char>",char)
0652         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<short>",short)
0653       //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned short>",unsigned short)
0654       //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned int>",unsigned int)
0655         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<int>",int)
0656         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<float>",float)
0657         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<double>",double)
0658 
0659       //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<string>",std::string)
0660       //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned long>",uint64) //beurk
0661 
0662         // WARNING : take care of the space in "> >".
0663         /* VisualC++ : the below does not compile.
0664         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned short> >",std::vector<unsigned short>)
0665         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<short> >",std::vector<short>)
0666         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned int> >",std::vector<unsigned int>)
0667         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<int> >",std::vector<short>)
0668         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<float> >",std::vector<float>)
0669         else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<double> >",std::vector<double>)
0670         */
0671 
0672         else {
0673           a_out << "tools::rroot::ntuple::initialize :"
0674                 << " WARNING : leaf element"
0675                 << " with name " << sout(bl->name())
0676                 << ",title " << sout(bl->title())
0677                 << " br_elem class name " << be->class_name() << "."
0678                 << " entries " << be->entry_number() << "."
0679                 << std::endl;
0680         }
0681 
0682       } else {
0683         a_out << "tools::rroot::ntuple::initialize :"
0684               << " WARNING : column type not yet handled for leaf"
0685               << " with name " << sout(bl->name())
0686               << " and title " << sout(bl->title()) << "."
0687               << " s_cls() is " << sout(bl->s_cls()) << "."
0688               << " Not fatal."
0689               << std::endl;
0690       }
0691 
0692     }
0693 
0694 #undef TOOLS_RROOT_NTUPLE_CREATE_VEC_COL
0695 #undef TOOLS_RROOT_NTUPLE_CREATE_COL
0696 
0697     size_t num = m_cols.size();
0698     if(!num) {
0699       a_out << "tools::rroot::ntuple::initialize :"
0700             << " zero columns."
0701             << std::endl;
0702       return false;
0703     }
0704 
0705    {tools_vforcit(column_binding,a_bd.columns(),it) {
0706       if(!find_named<read::icol>(m_cols,(*it).name())) {
0707         a_out << "tools::rroot::ntuple::initialize :"
0708               << " warning : for column binding with name " << sout((*it).name()) << ", no ntuple column found."
0709               << std::endl;
0710       }
0711     }}
0712 
0713     //a_out << "tools::rroot::ntuple::initialize :"
0714     //      << " number of columns " << num << "."
0715     //      << std::endl;
0716 
0717     return true;
0718   }
0719 
0720   bool get_row() const {
0721     bool status = true;
0722     tools_vforcit(read::icol*,m_cols,it) {
0723       if(!(*it)->fetch_entry()) {
0724         m_tree.out() << "tools::rroot::ntuple::get_row : fetch_entry() failed for leaf " << (*it)->name() << std::endl;
0725         status = false;
0726       }
0727     }
0728     return status;
0729   }
0730 protected:
0731   tree& m_tree;
0732   std::vector<read::icol*> m_cols;
0733   int64 m_index;
0734 };
0735 
0736 // for gopaw :
0737 
0738 class fac_tree_holder {
0739 public:
0740   fac_tree_holder(ifac* a_fac,tree* a_tree):m_fac(a_fac),m_tree(a_tree){}  //own a_fac,a_tree.
0741   virtual ~fac_tree_holder() {delete m_tree;delete m_fac;}
0742 protected:
0743   fac_tree_holder(const fac_tree_holder&){}
0744   fac_tree_holder& operator=(const fac_tree_holder&){return *this;}
0745 protected:
0746   ifac* m_fac;
0747   tree* m_tree;
0748 };
0749 
0750 class fac_tree_ntuple : public fac_tree_holder, public ntuple { //fac_tree_holder must be first.
0751   typedef ntuple parent;
0752 public:
0753   static const std::string& s_class() {
0754     static const std::string s_v("tools::rroot::fac_tree_ntuple");
0755     return s_v;
0756   }
0757   virtual const std::string& s_cls() const {return s_class();}
0758 public:
0759   fac_tree_ntuple(ifac* a_fac,tree* a_tree) //own these.
0760   :fac_tree_holder(a_fac,a_tree)
0761   ,parent(*a_tree)  //deleted first.
0762   {}
0763   virtual ~fac_tree_ntuple() {}
0764 protected:
0765   fac_tree_ntuple(const fac_tree_ntuple& a_from):read::intuple(a_from),fac_tree_holder(a_from),parent(a_from){}
0766   fac_tree_ntuple& operator=(const fac_tree_ntuple&){return *this;}
0767 };
0768 
0769 }}
0770 
0771 #endif