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