Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_wroot_ntuple 5 #define tools_wroot_ntuple 6 7 // An ntuple class to write at the CERN-ROOT f 8 // It inherits wroot::tree and each column is 9 // on a (wroot::branch,wroot::leaf). Each add_ 10 11 #include "tree" 12 #include "icol" 13 14 #include "../vfind" 15 #include "../vmanip" 16 #include "../ntuple_booking" 17 #include "../sout" 18 #include "../scast" 19 #include "../forit" 20 21 // for mpi : 22 #include "mpi_create_basket" 23 24 #ifdef TOOLS_MEM 25 #include "../mem" 26 #endif 27 28 namespace tools { 29 namespace wroot { 30 31 class ntuple : public tree { 32 public: 33 //typedef wroot::icol icol; //for backward com 34 public: 35 36 #include "columns.icc" 37 38 public: 39 ntuple(idir& a_dir,const std::string& a_name 40 :tree(a_dir,a_name,a_title),m_row_wise(a_row 41 { 42 if(m_row_wise) m_row_wise_branch = create_ 43 } 44 45 ntuple(idir& a_dir,const ntuple_booking& a_b 46 :tree(a_dir,a_bkg.name(),a_bkg.title()),m_ro 47 { 48 if(m_row_wise) m_row_wise_branch = create_ 49 50 const std::vector<column_booking>& cols = 51 tools_vforcit(column_booking,cols,it){ 52 53 #define TOOLS_WROOT_NTUPLE_CREATE_COL(a__type) 54 if((*it).cls_id()==_cid(a__type())) {\ 55 a__type* user = (a__type*)(*it).user_o 56 if(user) {\ 57 if(!create_column_ref<a__type>((*it) 58 m_out << "tools::wroot::ntuple : create_ 59 safe_clear<icol>(m_cols);\ 60 safe_clear<branch>(m_branches);\ 61 return;\ 62 }\ 63 } else {\ 64 if(!create_column<a__type>((*it).nam 65 m_out << "tools::wroot::ntuple : create_ 66 safe_clear<icol>(m_cols);\ 67 safe_clear<branch>(m_branches);\ 68 return;\ 69 }\ 70 }\ 71 } 72 73 #define TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(a__t 74 if((*it).cls_id()==_cid_std_vector<a__ty 75 std::vector<a__type>* vec = (std::vect 76 if(vec) {\ 77 if(!create_column_vector_ref<a__type 78 m_out << "tools::wroot::ntuple : c 79 safe_clear<icol>(m_cols);\ 80 safe_clear<branch>(m_branches);\ 81 return;\ 82 }\ 83 } else {\ 84 if(!create_column_vector<a__type>((* 85 m_out << "tools::wroot::ntuple : c 86 safe_clear<icol>(m_cols);\ 87 safe_clear<branch>(m_branches);\ 88 return;\ 89 }\ 90 }\ 91 } 92 93 //below types are in sync with rroot/ntu 94 95 TOOLS_WROOT_NTUPLE_CREATE_COL(char) 96 else TOOLS_WROOT_NTUPLE_CREATE_COL(short 97 else TOOLS_WROOT_NTUPLE_CREATE_COL(int) 98 else TOOLS_WROOT_NTUPLE_CREATE_COL(float 99 else TOOLS_WROOT_NTUPLE_CREATE_COL(doubl 100 101 else if((*it).cls_id()==_cid(std::string 102 std::string* user = (std::string*)(*it 103 if(user) { 104 if(!create_column_string_ref((*it).n 105 m_out << "tools::wroot::ntuple : create_ 106 safe_clear<icol>(m_cols); 107 safe_clear<branch>(m_branches); 108 return; 109 } 110 } else { 111 if(!create_column_string((*it).name( 112 m_out << "tools::wroot::ntuple : create_ 113 safe_clear<icol>(m_cols); 114 safe_clear<branch>(m_branches); 115 return; 116 } 117 } 118 } 119 120 else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(c 121 else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(s 122 else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(i 123 else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(f 124 else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(d 125 126 else if((*it).cls_id()==_cid_std_vector< 127 std::vector<std::string>* user = (std: 128 char sep = '\n'; 129 if(user) { 130 if(!create_column_vector_string_ref( 131 m_out << "tools::wroot::ntuple : create_ 132 safe_clear<icol>(m_cols); 133 safe_clear<branch>(m_branches); 134 return; 135 } 136 } else { 137 if(!create_column_vector_string((*it 138 m_out << "tools::wroot::ntuple : create_ 139 safe_clear<icol>(m_cols); 140 safe_clear<branch>(m_branches); 141 return; 142 } 143 } 144 } 145 146 // no leaf_store_class() defined for the 147 148 else { 149 m_out << "tools::wroot::ntuple :" 150 << " for column " << sout((*it). 151 << ", type with cid " << (*it).c 152 << std::endl; 153 //throw 154 safe_clear<icol>(m_cols); 155 safe_clear<branch>(m_branches); 156 return; 157 } 158 } 159 #undef TOOLS_WROOT_NTUPLE_CREATE_VEC_COL 160 #undef TOOLS_WROOT_NTUPLE_CREATE_COL 161 162 } 163 164 virtual ~ntuple() { 165 safe_clear<icol>(m_cols); 166 } 167 protected: 168 ntuple(const ntuple& a_from):iobject(a_from) 169 ntuple& operator=(const ntuple&){return *thi 170 public: 171 const std::vector<icol*>& columns() const {r 172 std::vector<icol*>& columns() {return m_cols 173 174 template <class T> 175 column_ref<T>* create_column_ref(const std:: 176 if(find_named<icol>(m_cols,a_name)) return 177 branch* _branch = m_row_wise?m_row_wise_br 178 if(!_branch) return 0; 179 column_ref<T>* col = new column_ref<T>(*_b 180 if(!col) return 0; 181 m_cols.push_back(col); 182 return col; 183 } 184 185 template <class T> 186 column<T>* create_column(const std::string& 187 if(find_named<icol>(m_cols,a_name)) return 188 branch* _branch = m_row_wise?m_row_wise_br 189 if(!_branch) return 0; 190 column<T>* col = new column<T>(*_branch,a_ 191 if(!col) return 0; 192 m_cols.push_back(col); 193 return col; 194 } 195 196 column_string_ref* create_column_string_ref( 197 if(find_named<icol>(m_cols,a_name)) return 198 branch* _branch = m_row_wise?m_row_wise_br 199 if(!_branch) return 0; 200 column_string_ref* col = new column_string 201 if(!col) return 0; 202 m_cols.push_back(col); 203 return col; 204 } 205 206 column_string* create_column_string(const st 207 if(find_named<icol>(m_cols,a_name)) return 208 branch* _branch = m_row_wise?m_row_wise_br 209 if(!_branch) return 0; 210 column_string* col = new column_string(*_b 211 if(!col) return 0; 212 m_cols.push_back(col); 213 return col; 214 } 215 216 column_vector_string_ref* create_column_vect 217 218 if(find_named<icol>(m_cols,a_name)) return 219 branch* _branch = m_row_wise?m_row_wise_br 220 if(!_branch) return 0; 221 column_vector_string_ref* col = new column 222 if(!col) return 0; 223 m_cols.push_back(col); 224 return col; 225 } 226 227 column_vector_string* create_column_vector_s 228 229 if(find_named<icol>(m_cols,a_name)) return 230 branch* _branch = m_row_wise?m_row_wise_br 231 if(!_branch) return 0; 232 column_vector_string* col = new column_vec 233 if(!col) return 0; 234 m_cols.push_back(col); 235 return col; 236 } 237 238 template <class T> 239 std_vector_column_ref<T>* create_column_vect 240 if(find_named<icol>(m_cols,a_name)) return 241 branch* _branch = m_row_wise?m_row_wise_br 242 if(!_branch) return 0; 243 std_vector_column_ref<T>* col = new std_ve 244 if(!col) return 0; 245 m_cols.push_back(col); 246 return col; 247 } 248 249 template <class T> 250 std_vector_column<T>* create_column_vector(c 251 if(find_named<icol>(m_cols,a_name)) return 252 if(m_row_wise) { 253 branch* _branch = m_row_wise_branch; 254 std_vector_column<T>* col = new std_vect 255 if(!col) return 0; 256 m_cols.push_back(col); 257 return col; 258 } else { 259 std_vector_be_pointer<T>* _branch = crea 260 if(!_branch) return 0; 261 std_vector_column<T>* col = new std_vect 262 if(!col) return 0; 263 _branch->set_pointer(&(col->variable())) 264 m_cols.push_back(col); 265 return col; 266 } 267 } 268 269 template <class T> 270 column_ref<T>* find_column_ref(const std::st 271 icol* col = find_named<icol>(m_cols,a_name 272 if(!col) return 0; 273 return id_cast<icol, column_ref<T> >(*col) 274 } 275 276 template <class T> 277 column<T>* find_column(const std::string& a_ 278 icol* col = find_named<icol>(m_cols,a_name 279 if(!col) return 0; 280 return id_cast<icol, column<T> >(*col); 281 } 282 283 column_string_ref* find_column_string_ref(co 284 icol* col = find_named<icol>(m_cols,a_name 285 if(!col) return 0; 286 return id_cast<icol, column_string_ref >(* 287 } 288 289 column_string* find_column_string(const std: 290 icol* col = find_named<icol>(m_cols,a_name 291 if(!col) return 0; 292 return id_cast<icol, column_string >(*col) 293 } 294 295 template <class T> 296 std_vector_column_ref<T>* find_column_vector 297 icol* col = find_named<icol>(m_cols,a_name 298 if(!col) return 0; 299 return id_cast<icol, std_vector_column_ref 300 } 301 302 template <class T> 303 std_vector_column<T>* find_column_vector(con 304 icol* col = find_named<icol>(m_cols,a_name 305 if(!col) return 0; 306 return id_cast<icol, std_vector_column<T> 307 } 308 309 column_vector_string_ref* find_column_vector 310 icol* col = find_named<icol>(m_cols,a_name 311 if(!col) return 0; 312 return id_cast<icol, column_vector_string_ 313 } 314 315 column_vector_string* find_column_vector_str 316 icol* col = find_named<icol>(m_cols,a_name 317 if(!col) return 0; 318 return id_cast<icol, column_vector_string 319 } 320 321 void print_columns(std::ostream& a_out) { 322 a_out << "for ntuple named " << sout(m_nam 323 tools_vforit(icol*,m_cols,it) { 324 a_out << " " << (*it)->name() << std::en 325 } 326 } 327 328 bool add_row() { 329 if(m_cols.empty()) return false; 330 tools_vforit(icol*,m_cols,it) (*it)->add() 331 uint32 n; 332 bool status = tree::fill(n); 333 tools_vforit(icol*,m_cols,it) (*it)->set_d 334 return status; 335 } 336 337 void set_basket_size(uint32 a_size) { 338 if(m_row_wise) { 339 if(m_row_wise_branch) m_row_wise_branch- 340 } else { 341 tools_vforit(icol*,m_cols,it) (*it)->set 342 } 343 } 344 345 //////////////////////////////////////////// 346 /// for parallelization : ////////////////// 347 //////////////////////////////////////////// 348 branch* get_row_wise_branch() const {return 349 void get_branches(std::vector<branch*>& a_ve 350 a_vec.clear(); 351 tools_vforcit(icol*,m_cols,it) a_vec.push_ 352 } 353 354 bool merge_number_of_entries() { 355 m_entries = 0; //it should be zero! 356 m_tot_bytes = 0; 357 m_zip_bytes = 0; 358 bool status = true; 359 tools_vforit(icol*,m_cols,it) { 360 if(it==m_cols.begin()) { 361 m_entries = (*it)->get_branch().entrie 362 } else if(m_entries!=(*it)->get_branch() 363 m_out << "tools::wroot::ntuple::merge_ 364 << " branches do not have same n 365 << std::endl; 366 status = false; 367 } 368 m_tot_bytes += (*it)->get_branch().tot_b 369 m_zip_bytes += (*it)->get_branch().zip_b 370 } 371 return status; 372 } 373 374 bool mpi_add_basket(impi& a_impi) { 375 uint32 icol; //not used if row_wise. 376 if(!a_impi.unpack(icol)) { 377 m_out << "tools::wroot::ntuple::mpi_add_ 378 return false; 379 } 380 381 if(m_row_wise) { 382 if(!m_row_wise_branch) return false; 383 384 basket* basket = mpi_create_basket(m_out 385 m_dir 386 m_row 387 if(!basket) { 388 m_out << "tools::wroot::ntuple::mpi_ad 389 return false; 390 } 391 392 uint32 add_bytes,nout; 393 if(!m_row_wise_branch->add_basket(m_dir. 394 m_out << "tools::wroot::ntuple::mpi_ad 395 delete basket; 396 return false; 397 } 398 399 delete basket; 400 m_row_wise_branch->set_tot_bytes(m_row_w 401 m_row_wise_branch->set_zip_bytes(m_row_w 402 403 } else { 404 if(icol>=m_cols.size()) { 405 m_out << "tools::wroot::ntuple::mpi_ad 406 return false; 407 } 408 409 branch& _branch = m_cols[icol]->get_bran 410 411 basket* basket = mpi_create_basket(m_out 412 m_dir 413 _bran 414 if(!basket) { 415 m_out << "tools::wroot::ntuple::mpi_ad 416 return false; 417 } 418 419 uint32 add_bytes,nout; 420 if(!_branch.add_basket(m_dir.file(),*bas 421 m_out << "tools::wroot::ntuple::mpi_ad 422 delete basket; 423 return false; 424 } 425 426 delete basket; 427 _branch.set_tot_bytes(_branch.tot_bytes( 428 _branch.set_zip_bytes(_branch.zip_bytes( 429 } 430 return true; 431 } 432 433 bool mpi_add_baskets(impi& a_impi) { //colum 434 uint32 _icol = 0; 435 tools_vforcit(icol*,m_cols,it) { 436 uint32 icol; 437 if(!a_impi.unpack(icol)) { 438 m_out << "tools::wroot::ntuple::mpi_ad 439 return false; 440 } 441 if(icol!=_icol) { 442 m_out << "tools::wroot::ntuple::mpi_ad 443 return false; 444 } 445 branch& _branch = m_cols[icol]->get_bran 446 basket* basket = mpi_create_basket(m_out 447 m_dir 448 _bran 449 if(!basket) { 450 m_out << "tools::wroot::ntuple::mpi_ad 451 return false; 452 } 453 454 uint32 add_bytes,nout; 455 if(!_branch.add_basket(m_dir.file(),*bas 456 m_out << "tools::wroot::ntuple::mpi_ad 457 delete basket; 458 return false; 459 } 460 461 delete basket; 462 _branch.set_tot_bytes(_branch.tot_bytes( 463 _branch.set_zip_bytes(_branch.zip_bytes( 464 465 _icol++; 466 } 467 return true; 468 } 469 470 bool mpi_end_fill(impi& a_impi) { 471 472 #define TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 473 {leaf_ref<a__type>* _mleaf_ = _mleaf 474 if(_mleaf_) {\ 475 uint32 _len;\ 476 if(!a_impi.unpack(_len)) return 477 a__type _mx;\ 478 if(!a_impi.unpack(_mx)) return f 479 _mleaf_->set_length(mx(_len,_mle 480 _mleaf_->set_max(mx(_mx,_mleaf_- 481 set_done = true;\ 482 }} 483 484 #define TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 485 {leaf_std_vector_ref<a__type>* _mlea 486 if(_mleaf_) {\ 487 uint32 _len;\ 488 if(!a_impi.unpack(_len)) return 489 a__type _mx;\ 490 if(!a_impi.unpack(_mx)) return f 491 _mleaf_->set_length(mx(_len,_mle 492 _mleaf_->set_max(mx(_mx,_mleaf_- 493 set_done = true;\ 494 }} 495 496 #define TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LEN 497 {leaf_string_ref* _mleaf_ = _mleaf? 498 if(_mleaf_) {\ 499 uint32 _len;\ 500 if(!a_impi.unpack(_len)) return 501 int _mx;\ 502 if(!a_impi.unpack(_mx)) return f 503 _mleaf_->set_length(mx(_len,_mle 504 _mleaf_->set_max(mx(_mx,_mleaf_- 505 set_done = true;\ 506 }} 507 508 if(m_row_wise) { 509 if(!m_row_wise_branch) return false; 510 511 tools_vforcit(base_leaf*,m_row_wise_bran 512 base_leaf* _mleaf = *mit; 513 514 bool set_done = false; 515 516 TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 517 TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 518 TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 519 TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 520 TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 521 522 TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 523 TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 524 TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 525 TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 526 TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR 527 528 TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LEN 529 530 if(!set_done) { 531 m_out << "tools::wroot::ntuple::mpi_ 532 << " leaf " << _mleaf->name() 533 return false; 534 } 535 } 536 537 } else { // column wise : 538 tools_vforcit(wroot::icol*,m_cols,it) { 539 base_leaf* _mleaf = (*it)->get_leaf(); 540 541 bool set_done = false; 542 TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LEN 543 544 if(!set_done) { 545 uint32 _len; 546 if(!a_impi.unpack(_len)) return fals 547 int _mx; 548 if(!a_impi.unpack(_mx)) return false 549 } 550 } 551 } 552 553 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX 554 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_ 555 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LENG 556 557 return true; 558 } 559 560 protected: 561 std::vector<icol*> m_cols; 562 bool m_row_wise; 563 branch* m_row_wise_branch; //used if row_wis 564 }; 565 566 }} 567 568 #endif