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