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