Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef toolx_hdf5_ntuple 5 #define toolx_hdf5_ntuple 6 7 #include "store" 8 9 #include <tools/vfind> 10 #include <tools/vmanip> 11 #include <tools/ntuple_binding> 12 #include <tools/ntuple_booking> 13 #include <tools/sout> 14 #include <tools/scast> 15 #include <tools/forit> 16 #include <tools/stype> 17 #include <tools/mnmx> 18 #include <tools/vdata> 19 20 #ifdef TOOLS_MEM 21 #include <tools/mem> 22 #include <tools/stype> 23 #endif 24 25 namespace toolx { 26 namespace hdf5 { 27 28 class ntuple : public store { 29 public: 30 class icol { 31 public: 32 virtual ~icol(){} 33 public: 34 virtual void* cast(tools::cid) const = 0; 35 virtual tools::cid id_cls() const = 0; 36 public: 37 virtual bool set_basket_size(size_t a_size) = 0; 38 virtual bool add() = 0; 39 virtual bool fetch_entry() = 0; 40 virtual const std::string& name() const = 0; 41 virtual void reset() = 0; 42 }; 43 public: 44 45 46 template <class T> 47 class column_ref : public virtual icol { 48 #ifdef TOOLS_MEM 49 static const std::string& s_class() { 50 static const std::string s_v("toolx::hdf5::ntuple::column_ref<"+tools::stype(T())+">"); 51 return s_v; 52 } 53 #endif 54 public: 55 static tools::cid id_class() { 56 static const T s_v = T(); //do that for T = std::string. 57 return tools::_cid(s_v)+10000; 58 } 59 virtual void* cast(tools::cid a_class) const { 60 if(void* p = tools::cmp_cast<column_ref>(this,a_class)) {return p;} 61 else return 0; 62 } 63 virtual tools::cid id_cls() const {return id_class();} 64 public: //icol 65 virtual bool add() { //write. 66 if(!m_write) return false; 67 if(m_basket_pos>=m_basket_size) { 68 if(!m_branch.write_page<T>(m_basket_size,m_basket)) { 69 m_store.out() << "toolx::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl; 70 m_basket_pos = 0; 71 return false; 72 } 73 m_basket_pos = 0; 74 if(m_want_new_basket_size) { 75 delete [] m_basket; 76 m_basket = new T[m_want_new_basket_size]; 77 m_basket_pos = 0; 78 m_basket_size = m_want_new_basket_size; 79 m_want_new_basket_size = 0; 80 } 81 } 82 m_basket[m_basket_pos] = m_ref; 83 m_basket_pos++; 84 return true; 85 } 86 virtual bool fetch_entry() { //read. 87 if(m_write) return false; 88 if(m_basket_pos>=m_basket_end) { //we need more data. 89 if(m_branch.pos()>=m_branch.entries()) { 90 m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl; 91 m_basket_pos = 0; 92 m_basket_end = 0; 93 return false; 94 } 95 if(m_want_new_basket_size) { 96 delete [] m_basket; 97 m_basket = new T[m_want_new_basket_size]; 98 m_basket_pos = 0; 99 m_basket_size = m_want_new_basket_size; 100 m_want_new_basket_size = 0; 101 } 102 tools::uint64 remain = m_branch.entries()-m_branch.pos(); 103 size_t n = tools::mn<size_t>((size_t)remain,m_basket_size); 104 if(!m_branch.read_page<T>(n,m_basket)) { 105 m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl; 106 m_basket_pos = 0; 107 m_basket_end = 0; 108 return false; 109 } 110 m_basket_pos = 0; 111 m_basket_end = n; 112 } 113 m_ref = m_basket[m_basket_pos]; 114 m_basket_pos++; 115 return true; 116 } 117 virtual void reset() {m_branch.reset_pos();} 118 virtual const std::string& name() const {return m_name;} 119 virtual bool set_basket_size(size_t a_size) { 120 if(!a_size) return false; 121 m_want_new_basket_size = a_size; 122 return true; 123 } 124 public: 125 column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref) 126 :m_store(a_store) 127 ,m_branch(a_pages) 128 ,m_write(a_write) 129 ,m_name(a_name) 130 ,m_ref(a_ref) 131 ,m_basket_size(a_basket_size?a_basket_size:32000) 132 ,m_basket_pos(0) 133 ,m_basket_end(0) //read. 134 ,m_basket(0) 135 ,m_want_new_basket_size(0) 136 { 137 #ifdef TOOLS_MEM 138 tools::mem::increment(s_class().c_str()); 139 #endif 140 m_basket = new T[m_basket_size]; 141 if(m_write) { 142 } else { //read. 143 tools::uint64 _entries = m_branch.entries(); 144 size_t n = tools::mn<size_t>((size_t)_entries,m_basket_size); 145 if(_entries) { 146 if(!m_branch.read_page<T>(n,m_basket)) { 147 m_store.out() << "toolx::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl; 148 m_basket_pos = 0; 149 m_basket_end = 0; 150 return; 151 } 152 } 153 m_basket_pos = 0; 154 m_basket_end = n; 155 } 156 } 157 virtual ~column_ref(){ 158 if(m_write && m_basket_pos) { 159 if(!m_branch.write_page<T>(m_basket_pos,m_basket)) { 160 m_store.out() << "toolx::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl; 161 } 162 } 163 delete [] m_basket; 164 #ifdef TOOLS_MEM 165 tools::mem::decrement(s_class().c_str()); 166 #endif 167 } 168 protected: 169 column_ref(const column_ref& a_from) 170 :icol(a_from) 171 ,m_store(a_from.m_store) 172 ,m_branch(a_from.m_branch) 173 ,m_write(a_from.m_write) 174 ,m_name(a_from.m_name) 175 ,m_ref(a_from.m_ref) 176 ,m_basket_size(a_from.m_basket_size) 177 ,m_basket_pos(0) 178 ,m_basket_end(0) 179 ,m_basket(0) 180 ,m_want_new_basket_size(0) 181 {} 182 column_ref& operator=(const column_ref& a_from){ 183 if(&a_from==this) return *this; 184 m_name = a_from.m_name; 185 m_basket_size = a_from.m_basket_size; 186 m_basket_pos = 0; 187 m_basket_end = 0; 188 m_want_new_basket_size = 0; 189 return *this; 190 } 191 protected: 192 store& m_store; 193 pages& m_branch; 194 bool m_write; 195 std::string m_name; 196 T& m_ref; 197 size_t m_basket_size; 198 size_t m_basket_pos; 199 size_t m_basket_end; 200 T* m_basket; 201 size_t m_want_new_basket_size; 202 }; 203 204 template <class T> 205 class column : public column_ref<T> { 206 typedef column_ref<T> parent; 207 #ifdef TOOLS_MEM 208 static const std::string& s_class() { 209 static const std::string s_v("toolx::hdf5::ntuple::column<"+tools::stype(T())+">"); 210 return s_v; 211 } 212 #endif 213 public: 214 static tools::cid id_class() { 215 static const T s_v = T(); //do that for T = std::string. 216 return tools::_cid(s_v); 217 } 218 virtual void* cast(tools::cid a_class) const { 219 if(void* p = tools::cmp_cast<column>(this,a_class)) {return p;} 220 else return 0; 221 } 222 virtual tools::cid id_cls() const {return id_class();} 223 public: 224 column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) 225 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) 226 ,m_tmp(T()) 227 { 228 #ifdef TOOLS_MEM 229 tools::mem::increment(s_class().c_str()); 230 #endif 231 } 232 virtual ~column(){ 233 #ifdef TOOLS_MEM 234 tools::mem::decrement(s_class().c_str()); 235 #endif 236 } 237 protected: 238 column(const column& a_from) 239 :icol(a_from) 240 ,parent(a_from) 241 ,m_tmp(a_from.m_tmp) 242 {} 243 column& operator=(const column& a_from){ 244 if(&a_from==this) return *this; 245 parent::operator=(a_from); 246 m_tmp = a_from.m_tmp; 247 return *this; 248 } 249 public: 250 bool fill(const T& a_value) {m_tmp = a_value;return true;} //write. 251 bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read. 252 protected: 253 T m_tmp; 254 }; 255 256 TOOLS_CLASS_STRING_VALUE(vector_char,vector<char>) 257 TOOLS_CLASS_STRING_VALUE(vector_short,vector<short>) 258 TOOLS_CLASS_STRING_VALUE(vector_int,vector<int>) 259 TOOLS_CLASS_STRING_VALUE(vector_float,vector<float>) 260 TOOLS_CLASS_STRING_VALUE(vector_double,vector<double>) 261 262 TOOLS_CLASS_STRING_VALUE(string,string) 263 264 TOOLS_CLASS_STRING_VALUE(vector_int64,vector<tools::int64>) 265 TOOLS_CLASS_STRING_VALUE(vector_uchar,vector<tools::uchar>) 266 TOOLS_CLASS_STRING_VALUE(vector_ushort,vector<tools::ushort>) 267 TOOLS_CLASS_STRING_VALUE(vector_uint32,vector<tools::uint32>) 268 TOOLS_CLASS_STRING_VALUE(vector_uint64,vector<tools::uint64>) 269 270 TOOLS_CLASS_STRING_VALUE(vector_string,vector<std::string>) 271 272 template <class T> 273 class std_vector_column_ref : public virtual icol { 274 #ifdef TOOLS_MEM 275 static const std::string& s_class() { 276 static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_ref<"+tools::stype(T())+">"); 277 return s_v; 278 } 279 #endif 280 public: 281 static tools::cid id_class() {return tools::_cid_std_vector<T>()+10000;} 282 virtual void* cast(tools::cid a_class) const { 283 if(void* p = tools::cmp_cast<std_vector_column_ref>(this,a_class)) {return p;} 284 else return 0; 285 } 286 virtual tools::cid id_cls() const {return id_class();} 287 public: //icol 288 virtual bool add() { //write. 289 if(!m_write) return false; 290 const T* _data = tools::vec_data(m_ref); 291 return m_branch.write_vlen<T>(m_ref.size(),_data); 292 } 293 virtual bool fetch_entry() { //read. 294 if(m_write) return false; 295 size_t n; 296 T* _data; 297 if(!m_branch.read_vlen<T>(n,_data)) { 298 m_store.out() << "toolx::hdf5::ntuple::std_vector_column_ref:fetch_entry : read_page() failed." << std::endl; 299 return false; 300 } 301 m_ref.resize(n); 302 T* dpos = _data; 303 T* pos = tools::vec_data(m_ref); 304 for(size_t index=0;index<n;index++,pos++,dpos++) *pos = *dpos; 305 delete [] _data; 306 return true; 307 } 308 virtual void reset() {m_branch.reset_pos();} 309 virtual const std::string& name() const {return m_name;} 310 virtual bool set_basket_size(size_t) {return true;} 311 public: 312 std_vector_column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name, 313 size_t /*a_basket_size*/, 314 std::vector<T>& a_ref) 315 :m_store(a_store) 316 ,m_branch(a_pages) 317 ,m_write(a_write) 318 ,m_name(a_name) 319 ,m_ref(a_ref) 320 { 321 #ifdef TOOLS_MEM 322 tools::mem::increment(s_class().c_str()); 323 #endif 324 } 325 virtual ~std_vector_column_ref(){ 326 #ifdef TOOLS_MEM 327 tools::mem::decrement(s_class().c_str()); 328 #endif 329 } 330 protected: 331 std_vector_column_ref(const std_vector_column_ref& a_from) 332 :icol(a_from) 333 ,m_store(a_from.m_store) 334 ,m_branch(a_from.m_branch) 335 ,m_write(a_from.m_write) 336 ,m_name(a_from.m_name) 337 ,m_ref(a_from.m_ref) 338 {} 339 std_vector_column_ref& operator=(const std_vector_column_ref& a_from){ 340 if(&a_from==this) return *this; 341 m_name = a_from.m_name; 342 return *this; 343 } 344 protected: 345 store& m_store; 346 pages& m_branch; 347 bool m_write; 348 std::string m_name; 349 std::vector<T>& m_ref; 350 }; 351 352 template <class T> 353 class std_vector_column : public std_vector_column_ref<T> { 354 typedef std_vector_column_ref<T> parent; 355 #ifdef TOOLS_MEM 356 static const std::string& s_class() { 357 static const std::string s_v("toolx::hdf5::ntuple::std_vector_column<"+tools::stype(T())+">"); 358 return s_v; 359 } 360 #endif 361 public: 362 static tools::cid id_class() {return tools::_cid_std_vector<T>();} 363 virtual void* cast(tools::cid a_class) const { 364 if(void* p = tools::cmp_cast<std_vector_column>(this,a_class)) {return p;} 365 else return 0; 366 } 367 virtual tools::cid id_cls() const {return id_class();} 368 public: 369 std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) 370 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) 371 {} 372 virtual ~std_vector_column(){} 373 protected: 374 std_vector_column(const std_vector_column& a_from) 375 :icol(a_from) 376 ,parent(a_from) 377 {} 378 std_vector_column& operator=(const std_vector_column& a_from){ 379 parent::operator=(a_from); 380 return *this; 381 } 382 public: 383 const std::vector<T>& data() const {return m_tmp;} 384 protected: 385 std::vector<T> m_tmp; 386 }; 387 388 class column_string_ref : public virtual icol { 389 #ifdef TOOLS_MEM 390 TOOLS_SCLASS(toolx::hdf5::ntuple::column_string_ref) 391 #endif 392 public: 393 static tools::cid id_class() { 394 static const std::string s_v; 395 return tools::_cid(s_v)+10000; 396 } 397 virtual void* cast(tools::cid a_class) const { 398 if(void* p = tools::cmp_cast<column_string_ref>(this,a_class)) {return p;} 399 else return 0; 400 } 401 virtual tools::cid id_cls() const {return id_class();} 402 public: //icol 403 virtual bool add() { //write. 404 if(!m_write) return false; 405 return m_branch.write_string(m_ref); 406 } 407 virtual bool fetch_entry() { //read. 408 if(m_write) return false; 409 if(!m_branch.read_string(m_ref)) { 410 m_store.out() << "toolx::hdf5::ntuple::column_string_ref:fetch_entry : read_page() failed." << std::endl; 411 return false; 412 } 413 return true; 414 } 415 virtual void reset() {m_branch.reset_pos();} 416 virtual const std::string& name() const {return m_name;} 417 virtual bool set_basket_size(size_t) {return true;} 418 public: 419 column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name, 420 size_t /*a_basket_size*/, 421 std::string& a_ref) 422 :m_store(a_store) 423 ,m_branch(a_pages) 424 ,m_write(a_write) 425 ,m_name(a_name) 426 ,m_ref(a_ref) 427 { 428 #ifdef TOOLS_MEM 429 tools::mem::increment(s_class().c_str()); 430 #endif 431 } 432 virtual ~column_string_ref(){ 433 #ifdef TOOLS_MEM 434 tools::mem::decrement(s_class().c_str()); 435 #endif 436 } 437 protected: 438 column_string_ref(const column_string_ref& a_from) 439 :icol(a_from) 440 ,m_store(a_from.m_store) 441 ,m_branch(a_from.m_branch) 442 ,m_write(a_from.m_write) 443 ,m_name(a_from.m_name) 444 ,m_ref(a_from.m_ref) 445 {} 446 column_string_ref& operator=(const column_string_ref& a_from){ 447 if(&a_from==this) return *this; 448 m_name = a_from.m_name; 449 return *this; 450 } 451 protected: 452 store& m_store; 453 pages& m_branch; 454 bool m_write; 455 std::string m_name; 456 std::string& m_ref; 457 }; 458 459 class column_string : public column_string_ref { 460 typedef column_string_ref parent; 461 #ifdef TOOLS_MEM 462 TOOLS_SCLASS(toolx::hdf5::ntuple::column_string) 463 #endif 464 public: 465 static tools::cid id_class() { 466 static const std::string s_v; 467 return tools::_cid(s_v); 468 } 469 virtual void* cast(tools::cid a_class) const { 470 if(void* p = tools::cmp_cast<column_string>(this,a_class)) {return p;} 471 else return 0; 472 } 473 virtual tools::cid id_cls() const {return id_class();} 474 public: 475 column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size) 476 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) 477 { 478 #ifdef TOOLS_MEM 479 tools::mem::increment(s_class().c_str()); 480 #endif 481 } 482 virtual ~column_string(){ 483 #ifdef TOOLS_MEM 484 tools::mem::decrement(s_class().c_str()); 485 #endif 486 } 487 protected: 488 column_string(const column_string& a_from) 489 :icol(a_from) 490 ,parent(a_from) 491 {} 492 column_string& operator=(const column_string& a_from){ 493 if(&a_from==this) return *this; 494 parent::operator=(a_from); 495 return *this; 496 } 497 public: 498 bool fill(const std::string& a_value) {m_tmp = a_value;return true;} 499 bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;} 500 protected: 501 std::string m_tmp; 502 }; 503 504 505 506 class std_vector_column_string_ref : public virtual icol { 507 #ifdef TOOLS_MEM 508 static const std::string& s_class() { 509 static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_string_ref"); 510 return s_v; 511 } 512 #endif 513 public: 514 static tools::cid id_class() {return tools::_cid_std_vector<std::string>()+10000;} 515 virtual void* cast(tools::cid a_class) const { 516 if(void* p = tools::cmp_cast<std_vector_column_string_ref>(this,a_class)) {return p;} 517 else return 0; 518 } 519 virtual tools::cid id_cls() const {return id_class();} 520 public: //icol 521 virtual bool add() { //write. 522 if(!m_write) return false; 523 size_t _size = 0; 524 {tools_vforcit(std::string,m_ref,it) { 525 _size += (*it).size(); 526 _size++; 527 }} 528 char* _data = _size?new char[_size]:0; 529 {char* pos = _data; 530 tools_vforcit(std::string,m_ref,it) { 531 ::memcpy(pos,(*it).c_str(),(*it).size()); 532 pos += (*it).size(); 533 *pos = 0; 534 pos++; 535 }} 536 return m_branch.write_vlen<char>(_size,_data); 537 } 538 virtual bool fetch_entry() { //read. 539 if(m_write) return false; 540 size_t n; 541 char* _data; 542 if(!m_branch.read_vlen<char>(n,_data)) { 543 m_store.out() << "toolx::hdf5::ntuple::std_vector_column_string_ref:fetch_entry : read_page() failed." << std::endl; 544 return false; 545 } 546 m_ref.clear(); 547 {char* pos = _data; 548 char* begin = _data; 549 for(size_t ichar=0;ichar<n;ichar++,pos++) { 550 if(*pos==0) { 551 m_ref.push_back(begin); 552 begin = pos+1; 553 } 554 }} 555 delete [] _data; 556 return true; 557 } 558 virtual void reset() {m_branch.reset_pos();} 559 virtual const std::string& name() const {return m_name;} 560 virtual bool set_basket_size(size_t) {return true;} 561 public: 562 std_vector_column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name, 563 size_t /*a_basket_size*/, 564 std::vector<std::string>& a_ref) 565 :m_store(a_store) 566 ,m_branch(a_pages) 567 ,m_write(a_write) 568 ,m_name(a_name) 569 ,m_ref(a_ref) 570 { 571 #ifdef TOOLS_MEM 572 tools::mem::increment(s_class().c_str()); 573 #endif 574 } 575 virtual ~std_vector_column_string_ref(){ 576 #ifdef TOOLS_MEM 577 tools::mem::decrement(s_class().c_str()); 578 #endif 579 } 580 protected: 581 std_vector_column_string_ref(const std_vector_column_string_ref& a_from) 582 :icol(a_from) 583 ,m_store(a_from.m_store) 584 ,m_branch(a_from.m_branch) 585 ,m_write(a_from.m_write) 586 ,m_name(a_from.m_name) 587 ,m_ref(a_from.m_ref) 588 {} 589 std_vector_column_string_ref& operator=(const std_vector_column_string_ref& a_from){ 590 if(&a_from==this) return *this; 591 m_name = a_from.m_name; 592 return *this; 593 } 594 protected: 595 store& m_store; 596 pages& m_branch; 597 bool m_write; 598 std::string m_name; 599 std::vector<std::string>& m_ref; 600 }; 601 602 class std_vector_column_string : public std_vector_column_string_ref { 603 typedef std_vector_column_string_ref parent; 604 #ifdef TOOLS_MEM 605 static const std::string& s_class() { 606 static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_string"); 607 return s_v; 608 } 609 #endif 610 public: 611 static tools::cid id_class() {return tools::_cid_std_vector<std::string>();} 612 virtual void* cast(tools::cid a_class) const { 613 if(void* p = tools::cmp_cast<std_vector_column_string>(this,a_class)) {return p;} 614 else return 0; 615 } 616 virtual tools::cid id_cls() const {return id_class();} 617 public: 618 std_vector_column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) 619 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) 620 {} 621 virtual ~std_vector_column_string(){} 622 protected: 623 std_vector_column_string(const std_vector_column_string& a_from) 624 :icol(a_from) 625 ,parent(a_from) 626 {} 627 std_vector_column_string& operator=(const std_vector_column_string& a_from){ 628 parent::operator=(a_from); 629 return *this; 630 } 631 public: 632 //bool get_entry(std::vector<T>& a_v) const { 633 // a_v = m_tmp; 634 // return true; 635 //} 636 const std::vector<std::string>& data() const {return m_tmp;} 637 protected: 638 std::vector<std::string> m_tmp; 639 }; 640 641 public: 642 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name, 643 unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/) 644 :store(a_out,a_group,a_name,true,a_compress) //true=write 645 {} 646 647 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name) 648 :store(a_out,a_group,a_name,false,0) //false=read 649 { 650 tools_vforcit(pages*,m_pagess,it){ 651 652 #define TOOLX_HDF5_NTUPLE_READ_CREATE_COL(a__type) \ 653 if((*it)->form()==tools::stype(a__type())) {\ 654 column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\ 655 if(!col) {tools::safe_clear<icol>(m_cols);return;}\ 656 m_cols.push_back(col);\ 657 } 658 659 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \ 660 if((*it)->form()==s_vector_##a__vec_type()) {\ 661 std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\ 662 if(!col) {tools::safe_clear<icol>(m_cols);return;}\ 663 m_cols.push_back(col);\ 664 } 665 666 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING \ 667 if((*it)->form()==s_vector_string()) {\ 668 std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\ 669 if(!col) {tools::safe_clear<icol>(m_cols);return;}\ 670 m_cols.push_back(col);\ 671 } 672 673 TOOLX_HDF5_NTUPLE_READ_CREATE_COL(char) 674 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(short) 675 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(int) 676 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::int64) 677 678 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(float) 679 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(double) 680 681 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::byte) 682 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort) 683 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32) 684 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64) 685 686 //else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(bool) //use byte=uchar. 687 688 else 689 if((*it)->form()==s_string()) { 690 column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0); 691 if(!col) {tools::safe_clear<icol>(m_cols);return;} 692 m_cols.push_back(col); 693 } 694 695 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char) 696 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short) 697 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int) 698 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64) 699 700 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float) 701 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double) 702 703 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar) 704 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort) 705 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32) 706 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64) 707 708 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING 709 // else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(bool) //use byte=uchar. 710 711 else { 712 m_out << "toolx::hdf5::ntuple::ntuple(read) :" 713 << " for column " << tools::sout((*it)->name()) 714 << ", type " << tools::sout((*it)->form()) << " not yet handled." 715 << std::endl; 716 //throw 717 tools::safe_clear<icol>(m_cols); 718 return; 719 } 720 } 721 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL 722 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_COL 723 } 724 725 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd) 726 :store(a_out,a_group,a_name,false,0) //false=read 727 { 728 if(!initialize(a_out,a_bd)) {} 729 } 730 731 ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg, 732 unsigned int a_compress,size_t a_basket_size/* = 32000*/) 733 :store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write 734 ,m_title(a_bkg.title()) 735 { 736 const std::vector<tools::column_booking>& cols = a_bkg.columns(); 737 tools_vforcit(tools::column_booking,cols,it){ 738 739 #define TOOLX_HDF5_NTUPLE_CREATE_COL(a__type) \ 740 if((*it).cls_id()==tools::_cid(a__type())) {\ 741 a__type* user = (a__type*)(*it).user_obj();\ 742 if(user) {\ 743 if(!create_column_ref<a__type>((*it).name(),a_basket_size,*user)) {\ 744 m_out << "toolx::hdf5::ntuple :"\ 745 << " can't create column_ref " << tools::sout((*it).name()) << "."\ 746 << std::endl;\ 747 tools::safe_clear<icol>(m_cols);\ 748 return;\ 749 }\ 750 } else {\ 751 if(!create_column<a__type>((*it).name(),a_basket_size)) {\ 752 m_out << "toolx::hdf5::ntuple :"\ 753 << " can't create column " << tools::sout((*it).name()) << "."\ 754 << std::endl;\ 755 tools::safe_clear<icol>(m_cols);\ 756 return;\ 757 }\ 758 }\ 759 } 760 761 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \ 762 if((*it).cls_id()==tools::_cid_std_vector<a__type>()) {\ 763 std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\ 764 if(!vec) {\ 765 m_out << "toolx::hdf5::ntuple :"\ 766 << " for std::vector column " << tools::sout((*it).name())\ 767 << ", the user vector pointer is null."\ 768 << std::endl;\ 769 tools::safe_clear<icol>(m_cols);\ 770 return;\ 771 }\ 772 if(!create_std_column_ref<a__type>((*it).name(),a_basket_size,*vec)) {\ 773 m_out << "toolx::hdf5::ntuple :"\ 774 << " can't create std::vector column " << tools::sout((*it).name()) << "."\ 775 << std::endl;\ 776 tools::safe_clear<icol>(m_cols);\ 777 return;\ 778 }\ 779 } 780 781 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING \ 782 if((*it).cls_id()==tools::_cid_std_vector<std::string>()) {\ 783 std::vector<std::string>* vec = (std::vector<std::string>*)(*it).user_obj();\ 784 if(!vec) {\ 785 m_out << "toolx::hdf5::ntuple :"\ 786 << " for std::vector column " << tools::sout((*it).name())\ 787 << ", the user vector pointer is null."\ 788 << std::endl;\ 789 tools::safe_clear<icol>(m_cols);\ 790 return;\ 791 }\ 792 if(!create_std_column_string_ref((*it).name(),a_basket_size,*vec)) {\ 793 m_out << "toolx::hdf5::ntuple :"\ 794 << " can't create std::vector column " << tools::sout((*it).name()) << "."\ 795 << std::endl;\ 796 tools::safe_clear<icol>(m_cols);\ 797 return;\ 798 }\ 799 } 800 801 TOOLX_HDF5_NTUPLE_CREATE_COL(char) 802 else TOOLX_HDF5_NTUPLE_CREATE_COL(short) 803 else TOOLX_HDF5_NTUPLE_CREATE_COL(int) 804 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::int64) 805 806 else TOOLX_HDF5_NTUPLE_CREATE_COL(float) 807 else TOOLX_HDF5_NTUPLE_CREATE_COL(double) 808 809 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::byte) 810 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::ushort) 811 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint32) 812 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint64) 813 814 //else TOOLX_HDF5_NTUPLE_CREATE_COL(bool) //use byte=uchar. 815 816 else if((*it).cls_id()==tools::_cid(std::string())) { 817 if(!create_column_string((*it).name(),a_basket_size)) { 818 m_out << "toolx::hdf5::ntuple :" 819 << " can't create string column " << tools::sout((*it).name()) << "." 820 << std::endl; 821 tools::safe_clear<icol>(m_cols); 822 return; 823 } 824 825 } else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(char) 826 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(short) 827 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(int) 828 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64) 829 830 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(float) 831 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(double) 832 833 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar) 834 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort) 835 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32) 836 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64) 837 838 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING 839 // else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(std::string) 840 // else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(bool) //use byte=uchar. 841 842 else { 843 m_out << "toolx::hdf5::ntuple :" 844 << " for column " << tools::sout((*it).name()) 845 << ", type with cid " << (*it).cls_id() << " not yet handled." 846 << std::endl; 847 tools::safe_clear<icol>(m_cols); 848 return; 849 } 850 } 851 #undef TOOLX_HDF5_NTUPLE_CREATE_COL 852 #undef TOOLX_HDF5_NTUPLE_CREATE_VEC_COL 853 854 } 855 856 virtual ~ntuple() { 857 tools::safe_clear<icol>(m_cols); 858 } 859 protected: 860 ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){} 861 ntuple& operator=(const ntuple&){return *this;} 862 public: 863 bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) { 864 tools::safe_clear<icol>(m_cols); 865 {tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();} 866 867 tools_vforcit(pages*,m_pagess,it) { 868 869 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \ 870 if((*it)->form()==tools::stype(a__type())) {\ 871 a__type* user_var = a_bd.find_variable<a__type>((*it)->name());\ 872 if(user_var) {\ 873 column_ref<a__type>* col = new column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\ 874 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 875 m_cols.push_back(col);\ 876 } else {\ 877 column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\ 878 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 879 m_cols.push_back(col);\ 880 }\ 881 } 882 883 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \ 884 if((*it)->form()==s_vector_##a__vec_type()) {\ 885 std::vector<a__type>* user_var = a_bd.find_variable< std::vector<a__type> >((*it)->name());\ 886 if(user_var) {\ 887 std_vector_column_ref<a__type>* col = \ 888 new std_vector_column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\ 889 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 890 m_cols.push_back(col);\ 891 } else {\ 892 std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\ 893 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 894 m_cols.push_back(col);\ 895 }\ 896 } 897 898 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING \ 899 if((*it)->form()==s_vector_string()) {\ 900 std::vector<std::string>* user_var = a_bd.find_variable< std::vector<std::string> >((*it)->name());\ 901 if(user_var) {\ 902 std_vector_column_string_ref* col = \ 903 new std_vector_column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\ 904 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 905 m_cols.push_back(col);\ 906 } else {\ 907 std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\ 908 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\ 909 m_cols.push_back(col);\ 910 }\ 911 } 912 913 TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char) 914 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short) 915 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int) 916 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64) 917 918 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float) 919 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double) 920 921 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte) 922 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort) 923 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32) 924 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64) 925 926 //else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(bool) //use byte=uchar. 927 928 else 929 if((*it)->form()==s_string()) { 930 std::string* user_var = a_bd.find_variable<std::string>((*it)->name()); 931 if(user_var) { 932 column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var); 933 if(!col) {tools::safe_clear<icol>(m_cols);return false;} 934 m_cols.push_back(col); 935 } else { 936 column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0); 937 if(!col) {tools::safe_clear<icol>(m_cols);return false;} 938 m_cols.push_back(col); 939 } 940 } 941 942 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char) 943 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short) 944 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int) 945 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64) 946 947 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float) 948 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double) 949 950 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar) 951 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort) 952 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32) 953 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64) 954 955 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING 956 957 // else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(bool) //use byte=uchar. 958 959 else { 960 a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :" 961 << " for column " << tools::sout((*it)->name()) 962 << ", type " << tools::sout((*it)->form()) << " not yet handled." 963 << std::endl; 964 tools::safe_clear<icol>(m_cols); 965 return false; 966 } 967 } 968 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL 969 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL 970 return true; 971 } 972 973 const std::string& title() const {return m_title;} 974 975 const std::vector<icol*>& columns() const {return m_cols;} 976 std::vector<icol*>& columns() {return m_cols;} 977 978 template <class T> 979 column_ref<T>* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_ref) { 980 if(tools::find_named<icol>(m_cols,a_name)) return 0; 981 pages* _pages = create_pages(a_name,tools::stype(T())); 982 if(!_pages) return 0; 983 column_ref<T>* col = new column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref); 984 if(!col) return 0; 985 m_cols.push_back(col); 986 return col; 987 } 988 989 template <class T> 990 column<T>* create_column(const std::string& a_name,size_t a_basket_size) { 991 if(tools::find_named<icol>(m_cols,a_name)) return 0; 992 pages* _pages = create_pages(a_name,tools::stype(T())); 993 if(!_pages) return 0; 994 column<T>* col = new column<T>(*this,*_pages,true,a_name,a_basket_size); 995 if(!col) return 0; 996 m_cols.push_back(col); 997 return col; 998 } 999 1000 column_string* create_column_string(const std::string& a_name,size_t a_basket_size) { 1001 if(tools::find_named<icol>(m_cols,a_name)) return 0; 1002 pages* _pages = create_pages(a_name,s_string()); 1003 if(!_pages) return 0; 1004 column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size); 1005 if(!col) return 0; 1006 m_cols.push_back(col); 1007 return col; 1008 } 1009 1010 template <class T> 1011 std_vector_column_ref<T>* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector<T>& a_ref) { 1012 //NOTE : to optimize, we do not handle a default std::vector value logic. 1013 if(tools::find_named<icol>(m_cols,a_name)) return 0; 1014 pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">"); 1015 if(!_pages) return 0; 1016 std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref); 1017 if(!col) return 0; 1018 m_cols.push_back(col); 1019 return col; 1020 } 1021 1022 std_vector_column_string_ref* create_std_column_string_ref(const std::string& a_name,size_t a_basket_size,std::vector<std::string>& a_ref) { 1023 //NOTE : to optimize, we do not handle a default std::vector value logic. 1024 if(tools::find_named<icol>(m_cols,a_name)) return 0; 1025 pages* _pages = create_pages(a_name,"vector<std::string>"); 1026 if(!_pages) return 0; 1027 std_vector_column_string_ref* col = new std_vector_column_string_ref(*this,*_pages,true,a_name,a_basket_size,a_ref); 1028 if(!col) return 0; 1029 m_cols.push_back(col); 1030 return col; 1031 } 1032 1033 template <class T> 1034 column_ref<T>* find_column_ref(const std::string& a_name) { 1035 icol* col = tools::find_named<icol>(m_cols,a_name); 1036 if(!col) return 0; 1037 return tools::id_cast<icol, column_ref<T> >(*col); 1038 } 1039 template <class T> 1040 column<T>* find_column(const std::string& a_name) { 1041 icol* col = tools::find_named<icol>(m_cols,a_name); 1042 if(!col) return 0; 1043 return tools::id_cast<icol, column<T> >(*col); 1044 } 1045 1046 template <class T> 1047 std_vector_column_ref<T>* find_std_vector_column_ref(const std::string& a_name) { 1048 icol* col = tools::find_named<icol>(m_cols,a_name); 1049 if(!col) return 0; 1050 return tools::id_cast<icol, std_vector_column_ref<T> >(*col); 1051 } 1052 template <class T> 1053 std_vector_column<T>* find_std_vector_column(const std::string& a_name) { 1054 icol* col = tools::find_named<icol>(m_cols,a_name); 1055 if(!col) return 0; 1056 return tools::id_cast<icol, std_vector_column<T> >(*col); 1057 } 1058 1059 std_vector_column_string_ref* find_std_vector_column_string_ref(const std::string& a_name) { 1060 icol* col = tools::find_named<icol>(m_cols,a_name); 1061 if(!col) return 0; 1062 return tools::id_cast<icol, std_vector_column_string_ref >(*col); 1063 } 1064 std_vector_column_string* find_std_vector_column_string(const std::string& a_name) { 1065 icol* col = tools::find_named<icol>(m_cols,a_name); 1066 if(!col) return 0; 1067 return tools::id_cast<icol, std_vector_column_string >(*col); 1068 } 1069 1070 column_string* find_column_string(const std::string& a_name) { 1071 icol* col = tools::find_named<icol>(m_cols,a_name); 1072 if(!col) return 0; 1073 return tools::id_cast<icol, column_string >(*col); 1074 } 1075 1076 bool add_row() { //write. 1077 if(m_cols.empty()) return false; 1078 bool status = true; 1079 tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;} 1080 //tools::uint32 n; 1081 //bool status = store::fill(n); 1082 //tools_vforit(icol*,m_cols,it) (*it)->set_def(); 1083 return status; 1084 } 1085 1086 bool get_row() { //read. 1087 bool status = true; 1088 tools_vforcit(icol*,m_cols,it) { 1089 if(!(*it)->fetch_entry()) status = false; 1090 } 1091 return status; 1092 } 1093 1094 bool set_basket_size(size_t a_size) { 1095 tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;} 1096 return true; 1097 } 1098 1099 void reset() { //read. 1100 tools_vforit(icol*,m_cols,it) (*it)->reset(); 1101 } 1102 1103 protected: 1104 std::string m_title; 1105 std::vector<icol*> m_cols; 1106 }; 1107 1108 }} 1109 1110 1111 #endif