Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_aida_ntuple 5 #define tools_aida_ntuple 6 7 // An in memory ntuple able to have "sub ntupl 8 // It is used in ioda to read ntuples in XML/A 9 10 #ifdef TOOLS_MEM 11 #include "mem" 12 #endif 13 14 #include "vmanip" 15 #include "vfind" 16 #include "typedefs" 17 #include "scast" 18 #include "forit" 19 #include "ntuple_binding" 20 #include "mnmx" 21 22 #include <string> 23 #include <vector> 24 #include <ostream> 25 26 namespace tools { 27 namespace aida { 28 29 class base_col { 30 public: 31 static const std::string& s_class() { 32 static const std::string s_v("tools::aida: 33 return s_v; 34 } 35 virtual void* cast(const std::string& a_clas 36 if(void* p = cmp_cast<base_col>(this,a_cla 37 return 0; 38 } 39 public: 40 virtual base_col* copy() const = 0; 41 virtual uint64 num_elems() const = 0; 42 virtual bool add() = 0; 43 virtual bool reset() = 0; 44 //binded column reading API : 45 virtual bool fetch_entry() const = 0; 46 virtual void set_user_variable(void*) = 0; 47 protected: 48 base_col(std::ostream& a_out,const std::stri 49 :m_out(a_out) 50 ,m_name(a_name),m_index(0){ 51 #ifdef TOOLS_MEM 52 mem::increment(s_class().c_str()); 53 #endif 54 } 55 public: 56 virtual ~base_col(){ 57 #ifdef TOOLS_MEM 58 mem::decrement(s_class().c_str()); 59 #endif 60 } 61 protected: 62 base_col(const base_col& a_from) 63 :m_out(a_from.m_out) 64 ,m_name(a_from.m_name) 65 ,m_index(a_from.m_index){ 66 #ifdef TOOLS_MEM 67 mem::increment(s_class().c_str()); 68 #endif 69 } 70 base_col& operator=(const base_col& a_from){ 71 m_name = a_from.m_name; 72 m_index = a_from.m_index; 73 return *this; 74 } 75 public: 76 const std::string& name() const {return m_na 77 78 void set_index(uint64 a_index){m_index = a_i 79 protected: 80 std::ostream& m_out; 81 std::string m_name; 82 uint64 m_index; 83 }; 84 85 class base_ntu { 86 public: 87 static const std::string& s_class() { 88 static const std::string s_v("tools::aida: 89 return s_v; 90 } 91 virtual void* cast(const std::string& a_clas 92 if(void* p = cmp_cast<base_ntu>(this,a_cla 93 return 0; 94 } 95 protected: 96 base_ntu(std::ostream& a_out,const std::stri 97 :m_out(a_out),m_title(a_title),m_index(-1){ 98 #ifdef TOOLS_MEM 99 mem::increment(s_class().c_str()); 100 #endif 101 } 102 virtual ~base_ntu() { 103 clear(); 104 #ifdef TOOLS_MEM 105 mem::decrement(s_class().c_str()); 106 #endif 107 } 108 protected: 109 base_ntu(const base_ntu& a_from) 110 :m_out(a_from.m_out) 111 ,m_title(a_from.m_title),m_index(a_from.m_in 112 { 113 #ifdef TOOLS_MEM 114 mem::increment(s_class().c_str()); 115 #endif 116 tools_vforcit(base_col*,a_from.m_cols,it) 117 base_col* column = (*it)->copy(); 118 if(!column) { 119 m_out << s_class() << "::cstor :" 120 << " can't copy column." 121 << std::endl; 122 safe_clear<base_col>(m_cols); 123 m_index = -1; 124 return; //throw 125 } 126 m_cols.push_back(column); 127 } 128 } 129 base_ntu& operator=(const base_ntu& a_from){ 130 if(&a_from==this) return *this; 131 132 safe_clear<base_col>(m_cols); 133 m_index = a_from.m_index; 134 135 m_title = a_from.m_title; 136 tools_vforcit(base_col*,a_from.m_cols,it) 137 base_col* column = (*it)->copy(); 138 if(!column) { 139 m_out << s_class() << "::operator=() : 140 << " can't copy column." 141 << std::endl; 142 safe_clear<base_col>(m_cols); 143 m_index = -1; 144 return *this; 145 } 146 m_cols.push_back(column); 147 } 148 149 return *this; 150 } 151 public: 152 std::ostream& out() const {return m_out;} 153 const std::vector<base_col*>& columns() cons 154 size_t number_of_columns() const {return m_c 155 156 #ifdef tools_aida_ntuple 157 const std::vector<base_col*>& cols() const { 158 #endif 159 160 void column_names(std::vector<std::string>& 161 a_names.clear(); 162 tools_vforcit(base_col*,m_cols,it) a_names 163 } 164 165 const std::string& title() const {return m_t 166 void set_title(const std::string& a_title) { 167 168 uint64 rows() const { 169 if(m_cols.empty()) return 0; 170 return m_cols.front()->num_elems(); 171 } 172 bool number_of_entries(uint64& a_value) cons 173 if(m_cols.empty()) {a_value = 0;return fal 174 a_value = m_cols.front()->num_elems(); 175 return true; 176 } 177 178 void clear() { //must not be confused with r 179 safe_clear<base_col>(m_cols); 180 m_index = -1; 181 } 182 183 bool reset() { //clear data in columns (but 184 bool status = true; 185 tools_vforit(base_col*,m_cols,it) { 186 if(!(*it)->reset()) status = false; 187 } 188 m_index = -1; 189 return status; 190 } 191 192 // reading : 193 void start() {m_index = -1;set_columns_index 194 bool next() { 195 // a tuple loop is of the form : 196 // tuple.start(); 197 // while(tuple.next()) { 198 // ... 199 // double v; 200 // if(!col->get_entry(v)) {} 201 // ... 202 // } 203 if((m_index+1)>=(int64)rows()) return fals 204 m_index++; 205 set_columns_index(m_index); 206 return true; 207 } 208 int64 row_index() const {return m_index;} 209 210 // filling : 211 bool add_row() { 212 bool status = true; 213 tools_vforit(base_col*,m_cols,it) { 214 if(!(*it)->add()) status = false; 215 } 216 return status; 217 } 218 public: 219 base_col* find_column(const std::string& a_n 220 return find_named<base_col>(m_cols,a_name) 221 } 222 223 void add_column(base_col* a_col) { //we take 224 m_cols.push_back(a_col); 225 } 226 227 protected: 228 void set_columns_index(uint64 a_index) { 229 tools_vforit(base_col*,m_cols,it) { 230 (*it)->set_index(a_index); 231 } 232 } 233 protected: 234 std::ostream& m_out; 235 std::string m_title; 236 int64 m_index; 237 std::vector<base_col*> m_cols; 238 }; 239 240 }} 241 242 #include "tos" 243 #include "sto" 244 #include "columns" 245 #include "stype" 246 247 namespace tools { 248 namespace aida { 249 250 //inline const std::string& s_aida_type(char) 251 // static const std::string s_v("char"); 252 // return s_v; 253 //} 254 inline const std::string& s_aida_type(short) { 255 static const std::string s_v("short"); 256 return s_v; 257 } 258 inline const std::string& s_aida_type(int) { 259 static const std::string s_v("int"); 260 return s_v; 261 } 262 inline const std::string& s_aida_type(float) { 263 static const std::string s_v("float"); 264 return s_v; 265 } 266 inline const std::string& s_aida_type(double) 267 static const std::string s_v("double"); 268 return s_v; 269 } 270 271 ///////////////////////////////////////// 272 ///////////////////////////////////////// 273 //inline const std::string& s_aida_type(unsign 274 // static const std::string s_v("byte"); 275 // return s_v; 276 //} 277 278 inline const std::string& s_aida_type(bool) { 279 static const std::string s_v("boolean"); 280 return s_v; 281 } 282 inline const std::string& s_aida_type(const st 283 static const std::string s_v("string"); 284 return s_v; 285 } 286 inline const std::string& s_aida_type(int64) { 287 static const std::string s_v("long"); 288 return s_v; 289 } 290 /* 291 inline const std::string& s_aida_type(const st 292 static const std::string s_v("double[]"); 293 return s_v; 294 } 295 */ 296 inline const std::string& s_aida_type_ituple() 297 static const std::string s_v("ITuple"); 298 return s_v; 299 } 300 301 ///////////////////////////////////////// 302 /// not AIDA ! ////////////////////////// 303 ///////////////////////////////////////// 304 inline const std::string& s_aida_type(unsigned 305 static const std::string s_v("ushort"); 306 return s_v; 307 } 308 inline const std::string& s_aida_type(unsigned 309 static const std::string s_v("uint"); 310 return s_v; 311 } 312 inline const std::string& s_aida_type(uint64) 313 static const std::string s_v("ulong"); 314 return s_v; 315 } 316 317 class aida_base_col : public base_col { 318 public: 319 static const std::string& s_class() { 320 static const std::string s_v("tools::aida: 321 return s_v; 322 } 323 virtual void* cast(const std::string& a_clas 324 if(void* p = cmp_cast<aida_base_col>(this, 325 return base_col::cast(a_class); 326 } 327 public: 328 virtual const std::string& aida_type() const 329 virtual bool s_default_value(std::string&) c 330 virtual bool s_value(std::string&) const = 0 331 virtual bool s_fill(const std::string&) = 0; 332 public: 333 aida_base_col(std::ostream& a_out,const std: 334 :base_col(a_out,a_name){} 335 public: 336 virtual ~aida_base_col(){} 337 public: 338 aida_base_col(const aida_base_col& a_from) 339 :base_col(a_from) 340 {} 341 aida_base_col& operator=(const aida_base_col 342 base_col::operator=(a_from); 343 return *this; 344 } 345 }; 346 347 inline bool s__fill(const std::string& a_s,std 348 a_v = a_s; 349 return true; 350 } 351 inline bool s__fill(const std::string& a_s,cha 352 //for exlib/cbk/aida_ntu 353 if(a_s.empty()) return false; 354 a_v = a_s[0]; 355 return true; 356 } 357 inline bool s__fill(const std::string& a_s,uns 358 //for exlib/cbk/aida_ntu 359 if(a_s.empty()) return false; 360 a_v = a_s[0]; 361 return true; 362 } 363 inline bool s__fill(const std::string& a_s,boo 364 return to(a_s,a_v); 365 } 366 inline bool s__fill(const std::string& a_s,sho 367 return to<short>(a_s,a_v); 368 } 369 inline bool s__fill(const std::string& a_s,uns 370 return to<unsigned short>(a_s,a_v); 371 } 372 inline bool s__fill(const std::string& a_s,int 373 return to<int>(a_s,a_v); 374 } 375 inline bool s__fill(const std::string& a_s,uns 376 return to<unsigned int>(a_s,a_v); 377 } 378 inline bool s__fill(const std::string& a_s,int 379 return to<int64>(a_s,a_v); 380 } 381 inline bool s__fill(const std::string& a_s,uin 382 return to<uint64>(a_s,a_v); 383 } 384 inline bool s__fill(const std::string& a_s,flo 385 return to<float>(a_s,a_v); 386 } 387 inline bool s__fill(const std::string& a_s,dou 388 return to<double>(a_s,a_v); 389 } 390 391 template <class T> 392 class aida_col : public aida_base_col { 393 public: 394 typedef T entry_t; 395 public: 396 static const std::string& s_class() { 397 static const std::string s_v("tools::aida: 398 return s_v; 399 } 400 virtual void* cast(const std::string& a_clas 401 if(void* p = cmp_cast< aida_col<T> >(this, 402 return aida_base_col::cast(a_class); 403 } 404 public: 405 virtual base_col* copy() const {return new a 406 virtual bool add() {m_data.push_back(m_tmp); 407 virtual bool reset() { 408 m_data.clear(); 409 m_index = 0; 410 m_tmp = m_default; 411 return true; 412 } 413 virtual uint64 num_elems() const {return m_d 414 public: 415 virtual const std::string& aida_type() const 416 virtual bool s_default_value(std::string& a_ 417 a_s = tos(m_default); 418 return true; 419 } 420 virtual bool s_value(std::string& a_s) const 421 typedef typename std::vector<T>::size_type 422 a_s = tos(m_data[sz_t(m_index)]); 423 return true; 424 } 425 426 // for exlib/raxml/tuple : 427 virtual bool s_fill(const std::string& a_s) 428 //if(!to<T>(a_s,m_tmp)) { 429 if(!s__fill(a_s,m_tmp)) { 430 m_out << s_class() << "::fill :" 431 << " can't convert " << sout(a_s) 432 << std::endl; 433 return false; 434 } 435 return true; 436 } 437 438 virtual void set_user_variable(void* a_user_ 439 public: 440 aida_col(std::ostream& a_out,const std::stri 441 :aida_base_col(a_out,a_name) 442 ,m_default(a_def) 443 ,m_tmp(a_def) 444 ,m_user_var(0) //not owner 445 {} 446 public: 447 virtual ~aida_col(){} 448 public: 449 aida_col(const aida_col& a_from) 450 :aida_base_col(a_from) 451 ,m_data(a_from.m_data) 452 ,m_default(a_from.m_default) 453 ,m_tmp(a_from.m_tmp) 454 ,m_user_var(a_from.m_user_var) 455 {} 456 aida_col& operator=(const aida_col& a_from){ 457 aida_base_col::operator=(a_from); 458 if(&a_from==this) return *this; 459 m_data = a_from.m_data; 460 m_default = a_from.m_default; 461 m_tmp = a_from.m_tmp; 462 m_user_var = a_from.m_user_var; 463 return *this; 464 } 465 public: 466 bool fill(const T& a_value) {m_tmp = a_value 467 bool get_entry(T& a_v) const { 468 if(m_index>=m_data.size()) { 469 m_out << s_class() << "::get_entry :" 470 << " bad index " << m_index 471 << ". Vec size is " << m_data.size 472 << "." 473 << std::endl; 474 a_v = T(); 475 return false; 476 } 477 typedef typename std::vector<T>::size_type 478 a_v = m_data[sz_t(m_index)]; 479 return true; 480 } 481 virtual bool fetch_entry() const { 482 //NOTE : it is ok to have a NULL m_user_va 483 if(m_index>=m_data.size()) { 484 m_out << s_class() << "::get_entry :" 485 << " bad index " << m_index 486 << ". Vec size is " << m_data.size 487 << "." 488 << std::endl; 489 if(m_user_var) *m_user_var = T(); 490 return false; 491 } 492 typedef typename std::vector<T>::size_type 493 if(m_user_var) *m_user_var = m_data[sz_t(m 494 return true; 495 } 496 protected: 497 std::vector<T> m_data; 498 T m_default; 499 T m_tmp; 500 T* m_user_var; 501 }; 502 503 class ntuple : public base_ntu { 504 public: 505 static cid id_class() {return 2000;} //for n 506 public: 507 static const std::string& s_class() { 508 static const std::string s_v("tools::aida: 509 return s_v; 510 } 511 virtual void* cast(const std::string& a_clas 512 if(void* p = cmp_cast<ntuple>(this,a_class 513 return base_ntu::cast(a_class); 514 } 515 virtual const std::string& s_cls() const {re 516 public: 517 ntuple(std::ostream& a_out,const std::string 518 :base_ntu(a_out,a_title) 519 {} 520 virtual ~ntuple() {} 521 public: 522 ntuple(const ntuple& a_from): base_ntu(a_fro 523 ntuple& operator=(const ntuple& a_from){ 524 base_ntu::operator=(a_from); 525 return *this; 526 } 527 public: 528 template <class T> 529 aida_col<T>* create_col(const std::string& a 530 if(find_named<base_col>(m_cols,a_name)) { 531 m_out << s_class() << "::create_col :" 532 << " a column with name " << sout( 533 << std::endl; 534 return 0; 535 } 536 aida_col<T>* col = new aida_col<T>(m_out,a 537 if(!col) { 538 m_out << s_class() << "::create_col :" 539 << " can't create aida_col<T> " << 540 << std::endl; 541 return 0; 542 } 543 m_cols.push_back(col); 544 return col; 545 } 546 547 template <class T> 548 aida_col<T>* find_column(const std::string& 549 base_col* col = find_named<base_col>(m_col 550 if(!col) return 0; 551 return safe_cast<base_col, aida_col<T> >(* 552 } 553 554 template <class T> 555 bool find_column(const std::string& a_name,a 556 base_col* col = a_case_sensitive ? find_na 557 if(!col) {a_col = 0;return false;} 558 a_col = safe_cast<base_col, aida_col<T> >( 559 return a_col?true:false; 560 } 561 562 aida_base_col* find_aida_base_column(const s 563 base_col* col = a_case_sensitive ? find_na 564 if(!col) return 0; 565 return safe_cast<base_col,aida_base_col>(* 566 } 567 568 bool get_row() const { 569 bool status = true; 570 tools_vforcit(base_col*,m_cols,it) { 571 if(!(*it)->fetch_entry()) status = false 572 } 573 return status; 574 } 575 576 bool set_binding(std::ostream& a_out,const n 577 tools_vforcit(column_binding,a_bd.columns( 578 bool found = false; 579 tools_vforcit(base_col*,m_cols,itc) { 580 if((*itc)->name()==(*itb).name()) { 581 (*itc)->set_user_variable((*itb).use 582 found = true; 583 } 584 } 585 if(!found) { 586 a_out << "tools::aida::ntuple :" 587 << " binding name " << sout((*it 588 << std::endl; 589 return false; 590 } 591 } 592 return true; 593 } 594 595 template <class T> 596 bool column_min(unsigned int a_col,T& a_valu 597 a_value = T(); 598 if(m_cols.empty()) return false; 599 if(a_col>=m_cols.size()) return false; 600 base_col* _base_col = m_cols[a_col]; 601 aida_col<T>* _col = safe_cast<base_col, ai 602 if(!_col) return false; 603 start(); 604 uint64 _rows = rows(); 605 T v; 606 {for(uint64 row=0;row<_rows;row++) { 607 if(!next()) {a_value = T();return false; 608 if(!_col->get_entry(v)) {} 609 if(!row) { 610 a_value = v; 611 } else { 612 a_value = mn<T>(a_value,v); 613 } 614 }} 615 return true; 616 } 617 618 template <class T> 619 bool column_max(unsigned int a_col,T& a_valu 620 a_value = T(); 621 if(m_cols.empty()) return false; 622 if(a_col>=m_cols.size()) return false; 623 base_col* _base_col = m_cols[a_col]; 624 aida_col<T>* _col = safe_cast<base_col, ai 625 if(!_col) return false; 626 start(); 627 uint64 _rows = rows(); 628 T v; 629 {for(uint64 row=0;row<_rows;row++) { 630 if(!next()) {a_value = T();return false; 631 if(!_col->get_entry(v)) {} 632 if(!row) { 633 a_value = v; 634 } else { 635 a_value = mx<T>(a_value,v); 636 } 637 }} 638 return true; 639 } 640 641 }; 642 643 ////////////////////////////////////////////// 644 /// some special column that can't be done wit 645 ////////////////////////////////////////////// 646 647 class aida_col_ntu : public base_col { 648 public: 649 static const std::string& s_class() { 650 static const std::string s_v("tools::aida: 651 return s_v; 652 } 653 virtual void* cast(const std::string& a_clas 654 if(void* p = cmp_cast<aida_col_ntu>(this,a 655 return base_col::cast(a_class); 656 } 657 public: 658 virtual base_col* copy() const {return new a 659 virtual bool add() {m_data.push_back(m_tmp); 660 virtual bool reset() {m_data.clear();m_index 661 virtual uint64 num_elems() const {return m_d 662 public: 663 base_ntu* get_entry() { 664 if(m_index>=m_data.size()) { 665 m_out << s_class() << "::get_entry :" 666 << " bad index " << m_index 667 << ". Vec size is " << m_data.size 668 << "." 669 << std::endl; 670 return 0; 671 } 672 typedef std::vector<ntuple>::size_type sz_ 673 return &(m_data[sz_t(m_index)]); 674 } 675 676 virtual void set_user_variable(void* a_user_ 677 virtual bool fetch_entry() const { 678 if(m_index>=m_data.size()) { 679 m_out << s_class() << "::fetch_entry :" 680 << " bad index " << m_index 681 << ". Vec size is " << m_data.size 682 << "." 683 << std::endl; 684 if(m_user_var) *m_user_var = ntuple(m_ou 685 return false; 686 } 687 typedef std::vector<ntuple>::size_type sz_ 688 if(m_user_var) *m_user_var = m_data[sz_t(m 689 return true; 690 } 691 692 virtual base_ntu* get_to_fill() {return &m_t 693 public: 694 aida_col_ntu(std::ostream& a_out,const std:: 695 :base_col(a_out,a_name) 696 ,m_tmp(a_out,"tmp") 697 ,m_user_var(0) //not owner 698 {} 699 public: 700 virtual ~aida_col_ntu(){} 701 public: 702 aida_col_ntu(const aida_col_ntu& a_from) 703 :base_col(a_from) 704 ,m_data(a_from.m_data) 705 706 ,m_tmp(a_from.m_tmp) 707 ,m_user_var(a_from.m_user_var) 708 {} 709 aida_col_ntu& operator=(const aida_col_ntu& 710 base_col::operator=(a_from); 711 if(&a_from==this) return *this; 712 m_data = a_from.m_data; 713 714 m_tmp = a_from.m_tmp; 715 m_user_var = a_from.m_user_var; 716 return *this; 717 } 718 protected: 719 std::vector<ntuple> m_data; 720 ntuple m_tmp; 721 ntuple* m_user_var; 722 }; 723 724 inline bool create_cols_from_vals(ntuple& a_nt 725 const std::v 726 bool a_verbo 727 tools_vforcit(value,a_vars,it) { 728 if((*it).type()==value::VOID_STAR) { 729 if(a_verbose){ 730 a_ntu.out() << "tools::aida::create_ 731 << " ITuple : " << (*it) 732 << std::endl; 733 } 734 std::vector<value>* vars = (std::vecto 735 736 aida_col_ntu* col_ntu = new aida_col_n 737 // create sub columns on the "fillable 738 base_ntu* sub_base_ntu = col_ntu->get_ 739 if(!sub_base_ntu) { 740 delete col_ntu; 741 return false; 742 } 743 ntuple* sub_aida = safe_cast<base_ntu, 744 if(!sub_aida) { 745 delete col_ntu; 746 return false; 747 } 748 749 if(!create_cols_from_vals(*sub_aida,*v 750 delete col_ntu; 751 return false; 752 } 753 754 a_ntu.add_column(col_ntu); 755 756 } else { 757 if(a_verbose){ 758 std::string stype; 759 (*it).s_type(stype); 760 std::string sval; 761 (*it).tos(sval); 762 a_ntu.out() << "tools::aida::create_ 763 << " " << stype << " : " 764 << (*it).label() << " : 765 << sval 766 << std::endl; 767 } 768 769 // char,short,int,float,double 770 // byte,boolean,string,long(for int6 771 // double[] 772 773 base_col* col = 0; 774 /*if((*it).type()==value::CHAR) { 775 col = a_ntu.create_col<char>((*it).l 776 } else*/ if((*it).type()==value::SHORT 777 col = a_ntu.create_col<short>((*it). 778 } else if((*it).type()==value::INT) { 779 col = a_ntu.create_col<int>((*it).la 780 } else if((*it).type()==value::INT64) 781 col = a_ntu.create_col<int64>((*it). 782 } else if((*it).type()==value::FLOAT) 783 col = a_ntu.create_col<float>((*it). 784 } else if((*it).type()==value::DOUBLE) 785 col = a_ntu.create_col<double>((*it) 786 787 //} else if((*it).type()==value::UNSIG 788 // col = a_ntu.create_col<unsigned ch 789 } else if((*it).type()==value::UNSIGNE 790 col = a_ntu.create_col<unsigned shor 791 } else if((*it).type()==value::UNSIGNE 792 col = a_ntu.create_col<unsigned int> 793 } else if((*it).type()==value::UNSIGNE 794 col = a_ntu.create_col<uint64>((*it) 795 796 } else if((*it).type()==value::BOOL) { 797 col = a_ntu.create_col<bool>((*it).l 798 } else if((*it).type()==value::STRING) 799 col = a_ntu.create_col<std::string>( 800 } else if((*it).type()==value::INT64) 801 col = a_ntu.create_col<int64>((*it). 802 } 803 804 if(!col) { 805 std::string stype; 806 (*it).s_type(stype); 807 std::string sval; 808 (*it).tos(sval); 809 a_ntu.out() << "tools::aida::create_ 810 << " failed for " << sty 811 << (*it).label() << " : 812 << sval 813 << std::endl; 814 return false; 815 } 816 } 817 } 818 return true; 819 } 820 821 // for raxml : 822 inline bool create_col(ntuple& a_ntu, 823 const std::string& a_ty 824 const std::string& a_na 825 const std::string& a_s, 826 bool a_is_ntu){ 827 /* 828 if(a_type==s_aida_type((char)0)) { 829 char v = 0; 830 if(a_s.size()&&!to<char>(a_s,v)) { 831 a_ntu.out() << "tools::aida::create_col 832 << " can't convert def " << 833 << " to a " << a_type 834 << std::endl; 835 return false; 836 } 837 if(!a_ntu.create_col<char>(a_name,v)) { 838 a_ntu.out() << "tools::aida::create_col 839 << " can't create column of 840 << std::endl; 841 return false; 842 } 843 844 } else*/ if(a_type==s_aida_type((short)0)) { 845 short v = 0; 846 if(a_s.size()&&!to<short>(a_s,v)) { 847 a_ntu.out() << "tools::aida::create_col 848 << " can't convert def " << 849 << " to a " << a_type 850 << std::endl; 851 return false; 852 } 853 if(!a_ntu.create_col<short>(a_name,v)) { 854 a_ntu.out() << "tools::aida::create_col 855 << " can't create column of 856 << std::endl; 857 return false; 858 } 859 860 } else if(a_type==s_aida_type((int)0)) { 861 int v = 0; 862 if(a_s.size()&&!to<int>(a_s,v)) { 863 a_ntu.out() << "tools::aida::create_col 864 << " can't convert def " << 865 << " to a " << a_type 866 << std::endl; 867 return false; 868 } 869 if(!a_ntu.create_col<int>(a_name,v)) { 870 a_ntu.out() << "tools::aida::create_col 871 << " can't create column of 872 << std::endl; 873 return false; 874 } 875 876 } else if(a_type==s_aida_type((int64)0)) { 877 int64 v = 0; 878 if(a_s.size()&&!to<int64>(a_s,v)) { 879 a_ntu.out() << "tools::aida::create_col 880 << " can't convert def " << 881 << " to a " << a_type 882 << std::endl; 883 return false; 884 } 885 if(!a_ntu.create_col<int64>(a_name,v)) { 886 a_ntu.out() << "tools::aida::create_col 887 << " can't create column of 888 << std::endl; 889 return false; 890 } 891 892 } else if(a_type==s_aida_type((float)0)) { 893 float v = 0; 894 if(a_s.size()&&!to<float>(a_s,v)) { 895 a_ntu.out() << "tools::aida::create_col 896 << " can't convert def " << 897 << " to a " << a_type 898 << std::endl; 899 return false; 900 } 901 if(!a_ntu.create_col<float>(a_name,v)) { 902 a_ntu.out() << "tools::aida::create_col 903 << " can't create column of 904 << std::endl; 905 return false; 906 } 907 908 909 } else if(a_type==s_aida_type((double)0)) { 910 double v = 0; 911 if(a_s.size()&&!to<double>(a_s,v)) { 912 a_ntu.out() << "tools::aida::create_col 913 << " can't convert def " << 914 << " to a " << a_type 915 << std::endl; 916 return false; 917 } 918 if(!a_ntu.create_col<double>(a_name,v)) { 919 a_ntu.out() << "tools::aida::create_col 920 << " can't create column of 921 << std::endl; 922 return false; 923 } 924 925 /* } else if(a_type==s_aida_type((unsigned ch 926 unsigned int v = 0; 927 if(a_s.size()&&!to<unsigned int>(a_s,v)) { 928 a_ntu.out() << "tools::aida::create_col 929 << " can't convert def " << 930 << " to a " << a_type 931 << std::endl; 932 return false; 933 } 934 if(v>=256) { 935 a_ntu.out() << "tools::aida::create_col 936 << " can't convert def " << 937 << " to byte." 938 << std::endl; 939 return false; 940 } 941 if(!a_ntu.create_col<unsigned char>(a_name 942 a_ntu.out() << "tools::aida::create_col 943 << " can't create column of 944 << std::endl; 945 return false; 946 } 947 */ 948 } else if(a_type==s_aida_type((unsigned shor 949 unsigned short v = 0; 950 if(a_s.size()&&!to<unsigned short>(a_s,v)) 951 a_ntu.out() << "tools::aida::create_col 952 << " can't convert def " << 953 << " to a " << a_type 954 << std::endl; 955 return false; 956 } 957 if(!a_ntu.create_col<unsigned short>(a_nam 958 a_ntu.out() << "tools::aida::create_col 959 << " can't create column of 960 << std::endl; 961 return false; 962 } 963 964 } else if(a_type==s_aida_type((unsigned int) 965 unsigned int v = 0; 966 if(a_s.size()&&!to<unsigned int>(a_s,v)) { 967 a_ntu.out() << "tools::aida::create_col 968 << " can't convert def " << 969 << " to a " << a_type 970 << std::endl; 971 return false; 972 } 973 if(!a_ntu.create_col<unsigned int>(a_name, 974 a_ntu.out() << "tools::aida::create_col 975 << " can't create column of 976 << std::endl; 977 return false; 978 } 979 980 } else if(a_type==s_aida_type((uint64)0)) { 981 uint64 v = 0; 982 if(a_s.size()&&!to<uint64>(a_s,v)) { 983 a_ntu.out() << "tools::aida::create_col 984 << " can't convert def " << 985 << " to a " << a_type 986 << std::endl; 987 return false; 988 } 989 if(!a_ntu.create_col<uint64>(a_name,v)) { 990 a_ntu.out() << "tools::aida::create_col 991 << " can't create column of 992 << std::endl; 993 return false; 994 } 995 996 ///////////////////////////////////////// 997 ///////////////////////////////////////// 998 } else if(a_type==s_aida_type((bool)true)) { 999 bool v = false; 1000 if(a_s.size()&&!to(a_s,v)) { 1001 a_ntu.out() << "tools::aida::create_col 1002 << " can't convert def " << 1003 << " to a " << a_type 1004 << std::endl; 1005 return false; 1006 } 1007 if(!a_ntu.create_col<bool>(a_name,v)) { 1008 a_ntu.out() << "tools::aida::create_col 1009 << " can't create column of 1010 << std::endl; 1011 return false; 1012 } 1013 1014 } else if(a_type==s_aida_type(std::string() 1015 if(!a_ntu.create_col<std::string>(a_name, 1016 a_ntu.out() << "tools::aida::create_col 1017 << " can't create column of 1018 << std::endl; 1019 return false; 1020 } 1021 1022 } else if(a_type==s_aida_type((int64)0)) { 1023 int64 v = 0; 1024 if(a_s.size()&&!to<int64>(a_s,v)) { 1025 a_ntu.out() << "tools::aida::create_col 1026 << " can't convert def " << 1027 << " to a " << a_type 1028 << std::endl; 1029 return false; 1030 } 1031 if(!a_ntu.create_col<int64>(a_name,v)) { 1032 a_ntu.out() << "tools::aida::create_col 1033 << " can't create column of 1034 << std::endl; 1035 return false; 1036 } 1037 1038 } else if(a_type==s_aida_type_ituple()) { 1039 // we expect a booking string on a_s. 1040 1041 if(!a_is_ntu) { 1042 a_ntu.out() << "tools::aida::create_col 1043 << " mismatch a_is_ntu/a_ty 1044 << std::endl; 1045 return false; 1046 } 1047 if(a_s.empty()) { 1048 a_ntu.out() << "tools::aida::create_col 1049 << " empty booking string." 1050 << std::endl; 1051 return false; 1052 } 1053 1054 columns::finder f(a_ntu.out(),a_s); 1055 if(!f.find_variables()) { 1056 a_ntu.out() << "tools::aida::create_col 1057 << " find_variables() failed for 1058 << std::endl; 1059 return false; 1060 } 1061 1062 aida_col_ntu* col_ntu = new aida_col_ntu( 1063 //create columns on the fillable. 1064 base_ntu* sub_base_ntu = col_ntu->get_to_ 1065 if(!sub_base_ntu) {delete col_ntu;return 1066 ntuple* sub_aida = safe_cast<base_ntu,ntu 1067 if(!sub_aida) {delete col_ntu;return fals 1068 1069 std::vector<value> vars;f.result(vars); 1070 if(!create_cols_from_vals(*sub_aida,vars) 1071 columns::delete_columns(vars); 1072 delete col_ntu; 1073 return false; 1074 } 1075 columns::delete_columns(vars); 1076 a_ntu.add_column(col_ntu); 1077 1078 //FIXME : double[] 1079 1080 } else { 1081 a_ntu.out() << "tools::aida::create_col : 1082 << " col type " << sout(a_typ 1083 << " not yet handled." 1084 << std::endl; 1085 return false; 1086 } 1087 1088 return true; 1089 } 1090 1091 // for waxml : 1092 inline bool create_cols_from_string(ntuple& a 1093 const std 1094 bool a_ve 1095 a_ntu.clear(); 1096 if(a_booking.empty()) { 1097 a_ntu.out() << "tools::aida::create_cols_ 1098 << " empty booking string." 1099 << std::endl; 1100 return false; 1101 } 1102 1103 columns::finder f(a_ntu.out(),a_booking); 1104 if(!f.find_variables()) { 1105 a_ntu.out() << "tools::aida::create_cols_ 1106 << " find_variables() failed." 1107 << std::endl; 1108 return false; 1109 } 1110 std::vector<value> vars;f.result(vars); 1111 if(a_verbose) columns::dump_columns(a_ntu.o 1112 1113 if(!create_cols_from_vals(a_ntu,vars)) { 1114 columns::delete_columns(vars); 1115 a_ntu.clear(); 1116 return false; 1117 } 1118 columns::delete_columns(vars); 1119 return true; 1120 } 1121 1122 inline aida_col_ntu* find_col_ntu(ntuple& a_n 1123 base_col* col = find_named<base_col>(a_ntu. 1124 if(!col) return 0; 1125 return safe_cast<base_col, aida_col_ntu >(* 1126 } 1127 1128 template <class T> 1129 class base_looper { 1130 public: 1131 static const std::string& s_class() { 1132 static const std::string s_v("tools::aida 1133 return s_v; 1134 } 1135 protected: 1136 virtual bool action(const T& a_value) = 0; 1137 public: 1138 base_looper(base_ntu& a_ntu,const base_col& 1139 :m_ntu(a_ntu),m_col(a_col){ 1140 #ifdef TOOLS_MEM 1141 mem::increment(s_class().c_str()); 1142 #endif 1143 } 1144 virtual ~base_looper(){ 1145 #ifdef TOOLS_MEM 1146 mem::decrement(s_class().c_str()); 1147 #endif 1148 } 1149 public: 1150 base_looper(const base_looper& a_from) 1151 :m_ntu(a_from.m_ntu),m_col(a_from.m_col){ 1152 #ifdef TOOLS_MEM 1153 mem::increment(s_class().c_str()); 1154 #endif 1155 } 1156 base_looper& operator=(const base_looper&){ 1157 public: 1158 bool process() { 1159 std::vector<unsigned int> is; 1160 bool found = false; 1161 if(!find_is(m_ntu,&m_col,is,found)) { 1162 m_ntu.out() << s_class() << "::process 1163 << " find_is failed." 1164 << std::endl; 1165 return false; 1166 } 1167 if(!found) { 1168 m_ntu.out() << s_class() << "::process 1169 << " find_is : col not foun 1170 << std::endl; 1171 return false; 1172 } 1173 if(is.empty()) { 1174 m_ntu.out() << s_class() << "::process 1175 << " is vec empty." 1176 << std::endl; 1177 return false; 1178 } 1179 1180 bool stop = false; 1181 if(!_looper(m_ntu,is,0,stop)) { 1182 m_ntu.out() << s_class() << "::process 1183 << " _looper failed." 1184 << std::endl; 1185 return false; 1186 } 1187 return true; 1188 } 1189 protected: 1190 static bool find_is(const base_ntu& a_ntu,c 1191 std::vector<unsi 1192 bool& a_found){ 1193 // search the indices to reach the sub le 1194 // Note : it is assumed that a_is is empt 1195 // calling with function. 1196 1197 const std::vector<base_col*>& cols = a_nt 1198 1199 // look if a_col is a leaf col of a_ntu : 1200 {unsigned int index = 0; 1201 tools_vforcit(base_col*,cols,it) { 1202 if(*it==a_col) { 1203 a_is.push_back(index); //leaf index i 1204 a_found = true; 1205 return true; 1206 } 1207 index++; 1208 }} 1209 1210 // go down sub ntu : 1211 {unsigned int index = 0; 1212 tools_vforcit(base_col*,cols,it) { 1213 aida_col_ntu* col = safe_cast<base_col, 1214 if(col) { 1215 base_ntu* sub = col->get_to_fill(); / 1216 if(!sub) {a_is.clear();return false;} 1217 a_is.push_back(index); 1218 if(!find_is(*sub,a_col,a_is,a_found)) 1219 if(a_found) return true; 1220 a_is.pop_back(); 1221 } 1222 index++; 1223 }} 1224 return true; 1225 } 1226 protected: 1227 bool _looper(base_ntu& a_sub, 1228 const std::vector<unsig 1229 unsigned int a_depth, 1230 bool& a_stop) { 1231 if(a_depth>=a_is.size()) return false; 1232 1233 unsigned int coli = a_is[a_depth]; 1234 const std::vector<base_col*>& cols = a_su 1235 if(coli>=cols.size()) return false; 1236 1237 if(a_depth==(a_is.size()-1)) { //we reach 1238 aida_col<T>* col = safe_cast<base_col, 1239 if(!col) return false; 1240 a_sub.start(); 1241 while(a_sub.next()) { 1242 T v; 1243 if(!col->get_entry(v)) return false; 1244 if(!action(v)) {a_stop = true;break;} 1245 } 1246 } else { 1247 aida_col_ntu* col = safe_cast<base_col, 1248 if(!col) return false; 1249 a_sub.start(); 1250 while(a_sub.next()) { 1251 base_ntu* ntu = col->get_entry(); //n 1252 if(!ntu) return false; 1253 ntu->start(); 1254 while(ntu->next()) { 1255 if(!_looper(*ntu,a_is,a_depth+1,a_s 1256 if(a_stop) break; 1257 } 1258 } 1259 } 1260 return true; 1261 } 1262 protected: 1263 base_ntu& m_ntu; 1264 const base_col& m_col; 1265 }; 1266 1267 }} 1268 1269 #include "mnmx" 1270 1271 namespace tools { 1272 namespace aida { 1273 1274 template <class T> 1275 class stat_looper : public base_looper<T> { 1276 protected: 1277 virtual bool action(const T& a_v) { 1278 if(m_first) { 1279 m_mn = a_v; 1280 m_mx = a_v; 1281 m_S = a_v; 1282 m_S2 = a_v*a_v; 1283 1284 m_first = false; 1285 } else { 1286 m_mn = min_of<T>(m_mn,a_v); 1287 m_mx = max_of<T>(m_mx,a_v); 1288 m_S += a_v; 1289 m_S2 += a_v*a_v; 1290 } 1291 m_counter++; 1292 return true; //continue looping. 1293 } 1294 public: 1295 stat_looper(base_ntu& a_ntu,const base_col& 1296 :base_looper<T>(a_ntu,a_col) 1297 ,m_first(true) 1298 ,m_mn(T()) 1299 ,m_mx(T()) 1300 ,m_S(T()) 1301 ,m_S2(T()) 1302 ,m_counter(0) 1303 {} 1304 virtual ~stat_looper(){} 1305 public: 1306 stat_looper(const stat_looper& a_from) 1307 :base_looper<T>(a_from) 1308 ,m_first(true) 1309 ,m_mn(T()) 1310 ,m_mx(T()) 1311 ,m_S(T()) 1312 ,m_S2(T()) 1313 ,m_counter(0) 1314 {} 1315 stat_looper& operator=(const stat_looper& a 1316 base_looper<T>::operator=(a_from); 1317 if(&a_from==this) return *this; 1318 m_first = true; 1319 m_mn = T(); 1320 m_mx = T(); 1321 m_S = T(); 1322 m_S2 = T(); 1323 m_counter = 0; 1324 return *this; 1325 } 1326 public: 1327 bool process() { 1328 m_counter = 0; 1329 if(!base_looper<T>::process()) { 1330 m_mn = T(); 1331 m_mx = T(); 1332 m_S = T(); 1333 m_S2 = T(); 1334 m_counter = 0; 1335 return false; 1336 } 1337 return true; 1338 } 1339 T mn() const {return m_mn;} 1340 T mx() const {return m_mx;} 1341 T S() const {return m_S;} 1342 T S2() const {return m_S2;} 1343 uint64 counter() const {return m_counter;} 1344 protected: 1345 bool m_first; 1346 T m_mn; 1347 T m_mx; 1348 T m_S; 1349 T m_S2; 1350 uint64 m_counter; 1351 }; 1352 1353 template <class T> 1354 inline bool column_infos(base_ntu& a_ntu, 1355 base_col& a_col, 1356 T& a_mn,T& a_mx,T& a 1357 uint64& a_count){ 1358 stat_looper<T> lpr(a_ntu,a_col); 1359 bool status = lpr.process(); 1360 a_mn = lpr.mn(); 1361 a_mx = lpr.mx(); 1362 a_S = lpr.S(); 1363 a_S2 = lpr.S2(); 1364 a_count = lpr.counter(); 1365 if(!status) return false; 1366 if(!a_count) return false; 1367 return true; 1368 } 1369 1370 inline base_col* find_leaf_column(const base_ 1371 const std::vector<base_col*>& cols = a_ntu. 1372 tools_vforcit(base_col*,cols,it) { 1373 aida_col_ntu* col = safe_cast<base_col,ai 1374 if(col) { 1375 base_ntu* sub = col->get_to_fill(); //i 1376 if(!sub) return 0; 1377 base_col* fcol = find_leaf_column(*sub, 1378 if(fcol) return fcol; 1379 } else { 1380 if((*it)->name()==a_name) return *it; 1381 } 1382 } 1383 return 0; 1384 } 1385 1386 template <class T> 1387 inline bool to_vector(base_ntu& a_ntu,std::ve 1388 a_vec.clear(); 1389 const std::vector<base_col*>& cols = a_ntu. 1390 if(cols.empty()) return false; 1391 if(a_col>=cols.size()) return false; 1392 base_col* _base_col = cols[a_col]; 1393 aida_col<T>* _col = safe_cast<base_col, aid 1394 if(!_col) return false; 1395 a_ntu.start(); 1396 uint64 _rows = a_ntu.rows(); 1397 a_vec.resize(_rows); 1398 T v; 1399 {for(uint64 row=0;row<_rows;row++) { 1400 if(!a_ntu.next()) {a_vec.clear();return f 1401 if(!_col->get_entry(v)) {} 1402 a_vec[row] = v; 1403 }} 1404 return true; 1405 } 1406 1407 template <class T> 1408 inline bool column_min(ntuple& a_ntu,unsigned 1409 return a_ntu.column_min(a_col,a_value); 1410 } 1411 1412 template <class T> 1413 inline bool column_max(ntuple& a_ntu,unsigned 1414 return a_ntu.column_max(a_col,a_value); 1415 } 1416 1417 }} 1418 1419 #endif