Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_rroot_ntuple 5 #define tools_rroot_ntuple 6 7 // to have same API than rcsv::ntuple. 8 9 #include "../rntuple" 10 11 #include "tree" 12 #include "leaf" 13 #include "stl_vector" 14 15 #include "../cids" 16 #include "../vfind" 17 #include "../vmanip" 18 #include "../ntuple_binding" 19 #include "../get_lines" 20 21 #ifdef TOOLS_MEM 22 #include "../mem" 23 #endif 24 25 namespace tools { 26 namespace rroot { 27 28 class ntuple : public virtual read::intuple { 29 typedef read::intuple parent; 30 public: 31 static const std::string& s_class() { 32 static const std::string s_v("tools::rroot::ntuple"); 33 return s_v; 34 } 35 virtual const std::string& s_cls() const {return s_class();} 36 public: //intuple 37 virtual void start() {m_index = -1;} 38 virtual bool next() { 39 m_index++; 40 if((uint64)m_index>=m_tree.entries()) return false; 41 return true; 42 } 43 virtual read::icol* find_icol(const std::string& a_name){ 44 return find_named<read::icol>(m_cols,a_name); 45 } 46 virtual const std::vector<read::icol*>& columns() const {return m_cols;} 47 virtual const std::string& title() const {return m_tree.title();} 48 virtual bool number_of_entries(uint64 & a_value) const {a_value = m_tree.entries();return true;} 49 public: 50 51 template <class T,class LEAF> 52 class column_ref : public virtual read::icolumn<T> { 53 typedef read::icolumn<T> parent; 54 public: 55 static cid id_class() {return 200+_cid(T())+10000;} 56 public: //icol 57 virtual void* cast(cid a_class) const { 58 if(void* p = cmp_cast<column_ref>(this,a_class)) return p; 59 return parent::cast(a_class); 60 } 61 virtual cid id_cls() const {return id_class();} 62 public: //icol 63 virtual const std::string& name() const {return m_leaf.name();} 64 public: //icolumn<T> 65 virtual bool fetch_entry() const {return _fetch_entry();} 66 virtual bool get_entry(T& a_v) const { 67 if(!_fetch_entry()) {a_v = T();return false;} 68 a_v = m_ref; 69 return true; 70 } 71 public: 72 column_ref(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index,T& a_ref) 73 :m_file(a_file) 74 ,m_branch(a_branch) 75 ,m_leaf(a_leaf) 76 ,m_index(a_index) //WARNING : we keep the ref ! 77 ,m_ref(a_ref) 78 {} 79 virtual ~column_ref(){} 80 protected: 81 column_ref(const column_ref& a_from) 82 :read::icol(a_from) 83 ,parent(a_from) 84 ,m_file(a_from.m_file) 85 ,m_branch(a_from.m_branch) 86 ,m_leaf(a_from.m_leaf) 87 ,m_index(a_from.m_index) 88 ,m_ref(a_from.m_ref) 89 {} 90 column_ref& operator=(const column_ref& a_from){ 91 if(&a_from==this) return *this; 92 return *this; 93 } 94 protected: 95 //typedef typename LEAF::value_t value_t; 96 bool _fetch_entry() const { 97 unsigned int n; 98 if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;} 99 if(!m_leaf.num_elem()) {m_ref = T();return true;} //it is ok. It may be a vector from a row_wise ntuple column. 100 typename LEAF::value_t _tmp; 101 if(!m_leaf.value(0,_tmp)) return false; 102 m_ref = T(_tmp); 103 return true; 104 } 105 protected: 106 ifile& m_file; 107 branch& m_branch; 108 LEAF& m_leaf; 109 int64& m_index; //WARNING : a ref. 110 T& m_ref; 111 //value_t m_tmp; 112 }; 113 114 template <class T,class LEAF> 115 class column : public column_ref<T,LEAF> { 116 typedef column_ref<T,LEAF> parent; 117 public: 118 static cid id_class() {return 200+_cid(T());} 119 public: //icol 120 virtual void* cast(cid a_class) const { 121 if(void* p = cmp_cast<column>(this,a_class)) return p; 122 return parent::cast(a_class); 123 } 124 virtual cid id_cls() const {return id_class();} 125 public: 126 column(ifile& a_file,branch& a_branch,LEAF& a_leaf,int64& a_index) 127 :parent(a_file,a_branch,a_leaf,a_index,m_value) 128 ,m_value(T()) 129 {} 130 virtual ~column(){} 131 protected: 132 column(const column& a_from) 133 :read::icol(a_from) 134 ,read::icolumn<T>(a_from) 135 ,parent(a_from) 136 ,m_value(a_from.m_value) 137 {} 138 column& operator=(const column& a_from){ 139 if(&a_from==this) return *this; 140 m_value = a_from.m_value; 141 return *this; 142 } 143 public: 144 const T& get_value() const {return m_value;} 145 protected: 146 T m_value; 147 }; 148 149 class column_string_ref : public virtual read::icol { 150 typedef read::icol parent; 151 public: 152 static cid id_class() { 153 static const std::string s_v; 154 return _cid(s_v)+10000; 155 } 156 public: //icol 157 virtual void* cast(cid a_class) const { 158 if(void* p = cmp_cast<column_string_ref>(this,a_class)) return p; 159 return 0; 160 } 161 virtual cid id_cls() const {return id_class();} 162 virtual const std::string& name() const {return m_leaf.name();} 163 public: 164 virtual bool fetch_entry() const {return _fetch_entry();} 165 public: 166 column_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,std::string& a_ref) 167 :m_file(a_file) 168 ,m_branch(a_branch) 169 ,m_leaf(a_leaf) 170 ,m_index(a_index) //WARNING : we keep the ref ! 171 ,m_ref(a_ref) 172 {} 173 virtual ~column_string_ref(){} 174 protected: 175 column_string_ref(const column_string_ref& a_from) 176 :parent(a_from) 177 ,m_file(a_from.m_file) 178 ,m_branch(a_from.m_branch) 179 ,m_leaf(a_from.m_leaf) 180 ,m_index(a_from.m_index) 181 ,m_ref(a_from.m_ref) 182 {} 183 column_string_ref& operator=(const column_string_ref& a_from){ 184 if(&a_from==this) return *this; 185 return *this; 186 } 187 public: 188 bool get_entry(std::string& a_v) const { 189 if(!_fetch_entry()) {a_v.clear();return false;} 190 a_v = m_ref; 191 return true; 192 } 193 protected: 194 bool _fetch_entry() const { 195 unsigned int n; 196 if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;} 197 const char* _cs = m_leaf.value(); 198 if(!_cs) {m_ref.clear();return false;} 199 m_ref = _cs; 200 return true; 201 } 202 protected: 203 ifile& m_file; 204 branch& m_branch; 205 leaf_string& m_leaf; 206 int64& m_index; //WARNING : a ref. 207 std::string& m_ref; 208 }; 209 210 class column_string : public column_string_ref { 211 typedef column_string_ref parent; 212 public: 213 static cid id_class() { 214 static const std::string s_v; 215 return _cid(s_v); 216 } 217 public: //icol 218 virtual void* cast(cid a_class) const { 219 if(void* p = cmp_cast<column_string>(this,a_class)) return p; 220 return parent::cast(a_class); 221 } 222 virtual cid id_cls() const {return id_class();} 223 virtual const std::string& name() const {return m_leaf.name();} 224 public: 225 column_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index) 226 :parent(a_file,a_branch,a_leaf,a_index,m_value) 227 {} 228 virtual ~column_string(){} 229 protected: 230 column_string(const column_string& a_from) 231 :read::icol(a_from) 232 ,parent(a_from) 233 ,m_value(a_from.m_value) 234 {} 235 column_string& operator=(const column_string& a_from){ 236 if(&a_from==this) return *this; 237 m_value = a_from.m_value; 238 return *this; 239 } 240 public: 241 const std::string& get_value() const {return m_value;} 242 protected: 243 std::string m_value; 244 }; 245 246 class column_vector_string_ref : public column_string_ref { 247 typedef column_string_ref parent; 248 public: 249 static cid id_class() {return _cid_std_vector<std::string>()+10000;} 250 public: //icol 251 virtual void* cast(cid a_class) const { 252 if(void* p = cmp_cast<column_vector_string_ref>(this,a_class)) return p; 253 return parent::cast(a_class); 254 } 255 virtual cid id_cls() const {return id_class();} 256 virtual const std::string& name() const {return m_leaf.name();} 257 public: 258 virtual bool fetch_entry() const {return _fetch_entry();} 259 public: 260 column_vector_string_ref(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index, 261 std::vector<std::string>& a_ref,char a_sep) 262 :parent(a_file,a_branch,a_leaf,a_index,m_value) 263 ,m_ref(a_ref) 264 ,m_sep(a_sep) 265 {} 266 virtual ~column_vector_string_ref(){} 267 protected: 268 column_vector_string_ref(const column_vector_string_ref& a_from) 269 :read::icol(a_from) 270 ,parent(a_from) 271 ,m_ref(a_from.m_ref) 272 ,m_sep(a_from.m_sep) 273 {} 274 column_vector_string_ref& operator=(const column_vector_string_ref& a_from){ 275 if(&a_from==this) return *this; 276 m_sep = a_from.m_sep; 277 return *this; 278 } 279 public: 280 bool get_entry(std::vector<std::string>& a_v) const { 281 if(!_fetch_entry()) {a_v.clear();return false;} 282 a_v = m_ref; 283 return true; 284 } 285 protected: 286 bool _fetch_entry() const { 287 if(!parent::_fetch_entry()) return false; 288 get_lines(m_value,m_ref); 289 return true; 290 } 291 protected: 292 std::vector<std::string>& m_ref; 293 char m_sep; 294 std::string m_value; 295 }; 296 297 class column_vector_string : public column_vector_string_ref { 298 typedef column_vector_string_ref parent; 299 public: 300 static cid id_class() {return _cid_std_vector<std::string>();} 301 public: //icol 302 virtual void* cast(cid a_class) const { 303 if(void* p = cmp_cast<column_vector_string>(this,a_class)) return p; 304 return parent::cast(a_class); 305 } 306 virtual cid id_cls() const {return id_class();} 307 virtual const std::string& name() const {return m_leaf.name();} 308 public: 309 column_vector_string(ifile& a_file,branch& a_branch,leaf_string& a_leaf,int64& a_index,char a_sep) 310 :parent(a_file,a_branch,a_leaf,a_index,m_value,a_sep) 311 {} 312 virtual ~column_vector_string(){} 313 protected: 314 column_vector_string(const column_vector_string& a_from) 315 :read::icol(a_from) 316 ,parent(a_from) 317 ,m_value(a_from.m_value) 318 {} 319 column_vector_string& operator=(const column_vector_string& a_from){ 320 if(&a_from==this) return *this; 321 m_value = a_from.m_value; 322 return *this; 323 } 324 public: 325 const std::vector<std::string>& get_value() const {return m_value;} 326 protected: 327 std::vector<std::string> m_value; 328 }; 329 330 // to read row_wise columns with vector of basic types : 331 template <class T> 332 class std_vector_column_ref : public virtual read::icolumn<T> { 333 typedef read::icolumn<T> parent; 334 public: 335 static cid id_class() {return 200+_cid(T())+10000;} 336 public: //icol 337 virtual void* cast(cid a_class) const { 338 if(void* p = cmp_cast<std_vector_column_ref>(this,a_class)) return p; 339 return parent::cast(a_class); 340 } 341 virtual cid id_cls() const {return id_class();} 342 public: //icol 343 virtual const std::string& name() const {return m_leaf.name();} 344 public: //icolumn<T> 345 virtual bool fetch_entry() const {return _fetch_entry();} 346 virtual bool get_entry(T& a_v) const { 347 if(!_fetch_entry()) {a_v = T();return false;} 348 if(m_ref.empty()) {a_v = T();return false;} 349 a_v = m_ref[0]; 350 return true; 351 } 352 public: 353 std_vector_column_ref(ifile& a_file,branch& a_branch,leaf<T>& a_leaf,int64& a_index,std::vector<T>& a_ref) 354 :m_file(a_file) 355 ,m_branch(a_branch) 356 ,m_leaf(a_leaf) 357 ,m_index(a_index) //WARNING : we keep the ref ! 358 ,m_ref(a_ref) 359 {} 360 virtual ~std_vector_column_ref(){} 361 protected: 362 std_vector_column_ref(const std_vector_column_ref& a_from) 363 :read::icol(a_from) 364 ,parent(a_from) 365 ,m_file(a_from.m_file) 366 ,m_branch(a_from.m_branch) 367 ,m_leaf(a_from.m_leaf) 368 ,m_index(a_from.m_index) 369 ,m_ref(a_from.m_ref) 370 {} 371 std_vector_column_ref& operator=(const std_vector_column_ref& a_from){ 372 if(&a_from==this) return *this; 373 return *this; 374 } 375 protected: 376 bool _fetch_entry() const { 377 unsigned int n; 378 if(!m_branch.find_entry(m_file,uint32(m_index),n)) {m_ref.clear();return false;} 379 m_leaf.value(m_ref); 380 return true; 381 } 382 protected: 383 ifile& m_file; 384 branch& m_branch; 385 leaf<T>& m_leaf; 386 int64& m_index; //WARNING : a ref. 387 std::vector<T>& m_ref; 388 }; 389 390 // to read column_wise columns with vector of basic types : 391 template <class RT,class T> 392 class column_element_ref : public virtual read::icolumn<T> { 393 typedef read::icolumn<T> parent; 394 public: 395 static cid id_class() {return 300+_cid(T())+10000;} 396 public: //icol 397 virtual void* cast(cid a_class) const { 398 if(void* p = cmp_cast<column_element_ref>(this,a_class)) return p; 399 return parent::cast(a_class); 400 } 401 virtual cid id_cls() const {return id_class();} 402 public: //icol 403 virtual const std::string& name() const {return m_leaf.name();} 404 public: //icolumn<T> 405 virtual bool fetch_entry() const {return _fetch_entry();} 406 virtual bool get_entry(T& a_v) const { 407 if(!_fetch_entry()) {a_v = T();return false;} 408 a_v = m_ref; 409 return true; 410 } 411 public: 412 column_element_ref(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index,T& a_ref) 413 :m_file(a_file) 414 ,m_be(a_branch) 415 ,m_leaf(a_leaf) 416 ,m_index(a_index) //WARNING : we keep the ref ! 417 ,m_ref(a_ref) 418 {} 419 virtual ~column_element_ref(){} 420 protected: 421 column_element_ref(const column_element_ref& a_from) 422 :read::icol(a_from),parent(a_from) 423 ,m_file(a_from.m_file) 424 ,m_be(a_from.m_be) 425 ,m_leaf(a_from.m_leaf) 426 ,m_index(a_from.m_index) 427 ,m_ref(a_from.m_ref) 428 {} 429 column_element_ref& operator=(const column_element_ref& a_from){ 430 if(&a_from==this) return *this; 431 return *this; 432 } 433 protected: 434 bool _fetch_entry() const { 435 unsigned int n; 436 if(!m_be.find_entry(m_file,uint32(m_index),n)) {m_ref = T();return false;} 437 iro* obj = m_be.object(); //Not owner. 438 if(!obj) {m_ref = T();return false;} 439 RT* v = id_cast<iro,RT>(*obj); 440 if(!v) {m_ref = T();return false;} 441 m_ref = *v; //it assumes a T::operator=(RT) 442 return true; 443 } 444 protected: 445 ifile& m_file; 446 branch_element& m_be; 447 leaf_element& m_leaf; 448 int64& m_index; //WARNING : a ref. 449 T& m_ref; 450 }; 451 452 template <class RT,class T> 453 class column_element : public column_element_ref<RT,T> { 454 typedef column_element_ref<RT,T> parent; 455 public: 456 static cid id_class() {return 300+_cid(T());} 457 public: //icol 458 virtual void* cast(cid a_class) const { 459 if(void* p = cmp_cast<column_element>(this,a_class)) return p; 460 return parent::cast(a_class); 461 } 462 virtual cid id_cls() const {return id_class();} 463 public: 464 column_element(ifile& a_file,branch_element& a_branch,leaf_element& a_leaf,int64& a_index) 465 :parent(a_file,a_branch,a_leaf,a_index,m_value) 466 ,m_value(T()) 467 {} 468 virtual ~column_element(){} 469 protected: 470 column_element(const column_element& a_from) 471 :read::icol(a_from) 472 ,read::icolumn<T>(a_from) 473 ,parent(a_from) 474 ,m_value(a_from.m_value) 475 {} 476 column_element& operator=(const column_element& a_from){ 477 if(&a_from==this) return *this; 478 m_value = a_from.m_value; 479 return *this; 480 } 481 public: 482 const T& get_value() const {return m_value;} 483 protected: 484 T m_value; 485 }; 486 487 public: 488 ntuple(tree& a_tree):m_tree(a_tree),m_index(-1){ 489 #ifdef TOOLS_MEM 490 mem::increment(s_class().c_str()); 491 #endif 492 } 493 virtual ~ntuple() { 494 safe_clear<read::icol>(m_cols); 495 #ifdef TOOLS_MEM 496 mem::decrement(s_class().c_str()); 497 #endif 498 } 499 protected: 500 ntuple(const ntuple& a_from) 501 :parent(a_from),m_tree(a_from.m_tree){ 502 #ifdef TOOLS_MEM 503 mem::increment(s_class().c_str()); 504 #endif 505 } 506 ntuple& operator=(const ntuple&){return *this;} 507 public: 508 bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding(),bool a_enforce_double = false) { 509 safe_clear<read::icol>(m_cols); 510 511 std::vector<base_leaf*> leaves; 512 m_tree.find_leaves(leaves); 513 tools_vforcit(base_leaf*,leaves,it) { 514 base_leaf* bl = (*it); 515 if(find_named<read::icol>(m_cols,bl->name())) { 516 a_out << "tools::rroot::ntuple::initialize :" 517 << " column with name " << sout(bl->name()) 518 << " already exists." 519 << std::endl; 520 safe_clear<read::icol>(m_cols); 521 return false; 522 } 523 branch* _branch = m_tree.find_leaf_branch(*bl); 524 if(!_branch) { 525 a_out << "tools::rroot::ntuple::initialize :" 526 << " can't find branch of leaf " << sout(bl->name()) << "." 527 << std::endl; 528 safe_clear<read::icol>(m_cols); 529 return false; 530 } 531 532 //a_out << "tools::rroot::ntuple::initialize :" 533 // << " branch " << _branch->name() 534 // << ", entries " << _branch->entry_number() << "." 535 // << std::endl; 536 537 #define TOOLS_RROOT_NTUPLE_CREATE_COL(a__type) \ 538 if(leaf<a__type>* lf_##a__type = safe_cast<base_leaf, leaf<a__type> >(*bl) ){\ 539 cid user_cid;void* user_obj;\ 540 a_bd.find_user_obj(bl->name(),user_cid,user_obj);\ 541 typedef leaf<a__type> leaf_t;\ 542 if(!user_obj) {\ 543 if(a_enforce_double) {\ 544 column<double,leaf_t>* col = new column<double,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\ 545 m_cols.push_back(col);\ 546 } else {\ 547 column<a__type,leaf_t>* col = new column<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index);\ 548 m_cols.push_back(col);\ 549 }\ 550 } else {\ 551 const base_leaf* lfc = bl->leaf_count();\ 552 if(lfc) {\ 553 /*::printf("debug : ntuple : create col leaf count : %s\n",bl->name().c_str());*/\ 554 if(user_cid!=_cid_std_vector<a__type>()) {\ 555 a_out << "tools::rroot::ntuple::initialize :"\ 556 << " for leaf with name " << sout(bl->name())\ 557 << ", user variable type is not a std::vector of " << #a__type << "."\ 558 << std::endl;\ 559 safe_clear<read::icol>(m_cols);\ 560 return false;\ 561 }\ 562 std::vector<a__type>* user_var = (std::vector<a__type>*)user_obj;\ 563 std_vector_column_ref<a__type>* col = new std_vector_column_ref<a__type>\ 564 (m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\ 565 m_cols.push_back(col);\ 566 } else {\ 567 /*::printf("debug : ntuple : create col : %s\n",bl->name().c_str());*/\ 568 if(user_cid!=_cid(a__type())) {\ 569 a_out << "tools::rroot::ntuple::initialize :"\ 570 << " for leaf with name " << sout(bl->name())\ 571 << ", user variable type is not a " << #a__type << "."\ 572 << std::endl;\ 573 safe_clear<read::icol>(m_cols);\ 574 return false;\ 575 }\ 576 a__type* user_var = (a__type*)user_obj;\ 577 column_ref<a__type,leaf_t>* col =\ 578 new column_ref<a__type,leaf_t>(m_tree.file(),*_branch,*lf_##a__type,m_index,*user_var);\ 579 m_cols.push_back(col);\ 580 }\ 581 }\ 582 } 583 584 //below types are in sync with wroot/ntuple. 585 586 TOOLS_RROOT_NTUPLE_CREATE_COL(char) 587 else TOOLS_RROOT_NTUPLE_CREATE_COL(short) 588 else TOOLS_RROOT_NTUPLE_CREATE_COL(int) 589 else TOOLS_RROOT_NTUPLE_CREATE_COL(float) 590 else TOOLS_RROOT_NTUPLE_CREATE_COL(double) 591 592 else if(leaf_string* ls = safe_cast<base_leaf, leaf_string >(*bl) ){ 593 char sep = '\n'; 594 cid user_cid;void* user_obj; 595 if(!a_bd.find_user_obj(bl->name(),user_cid,user_obj)) { 596 column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep); 597 m_cols.push_back(col); 598 } else if(user_cid==_cid_std_vector<std::string>()) { 599 std::vector<std::string>* user_var = (std::vector<std::string>*)user_obj; 600 if(user_var) { 601 column_vector_string_ref* col = new column_vector_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var,sep); 602 m_cols.push_back(col); 603 } else { 604 column_vector_string* col = new column_vector_string(m_tree.file(),*_branch,*ls,m_index,sep); 605 m_cols.push_back(col); 606 } 607 } else if(user_cid==_cid(std::string())) { 608 std::string* user_var = (std::string*)user_obj; 609 if(user_var) { 610 column_string_ref* col = new column_string_ref(m_tree.file(),*_branch,*ls,m_index,*user_var); 611 m_cols.push_back(col); 612 } else { 613 column_string* col = new column_string(m_tree.file(),*_branch,*ls,m_index); 614 m_cols.push_back(col); 615 } 616 } else { 617 a_out << "tools::rroot::ntuple::initialize :" 618 << " for leaf with name " << sout(ls->name()) 619 << ", user variable type is not a std::string or a std::vector<std::string>." 620 << ". It's class id is " << user_cid << "." 621 << std::endl; 622 safe_clear<read::icol>(m_cols); 623 return false; 624 } 625 626 } else if(leaf_element* le = safe_cast<base_leaf,leaf_element>(*bl) ){ 627 628 branch_element* be = safe_cast<branch,branch_element>(*_branch); 629 if(!be) { 630 a_out << "tools::rroot::ntuple::initialize : branch is not a branch_element." << std::endl; 631 safe_clear<read::icol>(m_cols); 632 return false; 633 } 634 635 #define TOOLS_RROOT_NTUPLE_CREATE_VEC_COL(a__name,a__type) \ 636 if(be->class_name()==a__name) {\ 637 /*::printf("debug : ntuple : create vec col : %s\n",bl->name().c_str());*/\ 638 typedef a__type el_t;\ 639 std::vector<el_t>* user_var = a_bd.find_vector_variable<el_t>(bl->name());\ 640 if(user_var) {\ 641 typedef column_element_ref< stl_vector<el_t> , std::vector<el_t> > ce_t;\ 642 ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index,*user_var);\ 643 m_cols.push_back(col);\ 644 } else {\ 645 typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;\ 646 ce_t* col = new ce_t(m_tree.file(),*be,*le,m_index);\ 647 m_cols.push_back(col);\ 648 }\ 649 } 650 651 TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<char>",char) 652 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<short>",short) 653 //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned short>",unsigned short) 654 //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned int>",unsigned int) 655 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<int>",int) 656 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<float>",float) 657 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<double>",double) 658 659 //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<string>",std::string) 660 //else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<unsigned long>",uint64) //beurk 661 662 // WARNING : take care of the space in "> >". 663 /* VisualC++ : the below does not compile. 664 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned short> >",std::vector<unsigned short>) 665 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<short> >",std::vector<short>) 666 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<unsigned int> >",std::vector<unsigned int>) 667 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<int> >",std::vector<short>) 668 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<float> >",std::vector<float>) 669 else TOOLS_RROOT_NTUPLE_CREATE_VEC_COL("vector<vector<double> >",std::vector<double>) 670 */ 671 672 else { 673 a_out << "tools::rroot::ntuple::initialize :" 674 << " WARNING : leaf element" 675 << " with name " << sout(bl->name()) 676 << ",title " << sout(bl->title()) 677 << " br_elem class name " << be->class_name() << "." 678 << " entries " << be->entry_number() << "." 679 << std::endl; 680 } 681 682 } else { 683 a_out << "tools::rroot::ntuple::initialize :" 684 << " WARNING : column type not yet handled for leaf" 685 << " with name " << sout(bl->name()) 686 << " and title " << sout(bl->title()) << "." 687 << " s_cls() is " << sout(bl->s_cls()) << "." 688 << " Not fatal." 689 << std::endl; 690 } 691 692 } 693 694 #undef TOOLS_RROOT_NTUPLE_CREATE_VEC_COL 695 #undef TOOLS_RROOT_NTUPLE_CREATE_COL 696 697 size_t num = m_cols.size(); 698 if(!num) { 699 a_out << "tools::rroot::ntuple::initialize :" 700 << " zero columns." 701 << std::endl; 702 return false; 703 } 704 705 {tools_vforcit(column_binding,a_bd.columns(),it) { 706 if(!find_named<read::icol>(m_cols,(*it).name())) { 707 a_out << "tools::rroot::ntuple::initialize :" 708 << " warning : for column binding with name " << sout((*it).name()) << ", no ntuple column found." 709 << std::endl; 710 } 711 }} 712 713 //a_out << "tools::rroot::ntuple::initialize :" 714 // << " number of columns " << num << "." 715 // << std::endl; 716 717 return true; 718 } 719 720 bool get_row() const { 721 bool status = true; 722 tools_vforcit(read::icol*,m_cols,it) { 723 if(!(*it)->fetch_entry()) { 724 m_tree.out() << "tools::rroot::ntuple::get_row : fetch_entry() failed for leaf " << (*it)->name() << std::endl; 725 status = false; 726 } 727 } 728 return status; 729 } 730 protected: 731 tree& m_tree; 732 std::vector<read::icol*> m_cols; 733 int64 m_index; 734 }; 735 736 // for gopaw : 737 738 class fac_tree_holder { 739 public: 740 fac_tree_holder(ifac* a_fac,tree* a_tree):m_fac(a_fac),m_tree(a_tree){} //own a_fac,a_tree. 741 virtual ~fac_tree_holder() {delete m_tree;delete m_fac;} 742 protected: 743 fac_tree_holder(const fac_tree_holder&){} 744 fac_tree_holder& operator=(const fac_tree_holder&){return *this;} 745 protected: 746 ifac* m_fac; 747 tree* m_tree; 748 }; 749 750 class fac_tree_ntuple : public fac_tree_holder, public ntuple { //fac_tree_holder must be first. 751 typedef ntuple parent; 752 public: 753 static const std::string& s_class() { 754 static const std::string s_v("tools::rroot::fac_tree_ntuple"); 755 return s_v; 756 } 757 virtual const std::string& s_cls() const {return s_class();} 758 public: 759 fac_tree_ntuple(ifac* a_fac,tree* a_tree) //own these. 760 :fac_tree_holder(a_fac,a_tree) 761 ,parent(*a_tree) //deleted first. 762 {} 763 virtual ~fac_tree_ntuple() {} 764 protected: 765 fac_tree_ntuple(const fac_tree_ntuple& a_from):read::intuple(a_from),fac_tree_holder(a_from),parent(a_from){} 766 fac_tree_ntuple& operator=(const fac_tree_ntuple&){return *this;} 767 }; 768 769 }} 770 771 #endif