Warning, /include/Geant4/toolx/hdf5/ntuple is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef toolx_hdf5_ntuple
0005 #define toolx_hdf5_ntuple
0006
0007 #include "store"
0008
0009 #include <tools/vmanip>
0010 #include <tools/ntuple_binding>
0011 #include <tools/ntuple_booking>
0012 #include <tools/sout>
0013 #include <tools/scast>
0014 #include <tools/forit>
0015 #include <tools/stype>
0016 #include <tools/mnmx>
0017
0018 namespace toolx {
0019 namespace hdf5 {
0020
0021 class ntuple : public store {
0022 public:
0023 class icol {
0024 public:
0025 virtual ~icol(){}
0026 public:
0027 virtual void* cast(tools::cid) const = 0;
0028 virtual tools::cid id_cls() const = 0;
0029 public:
0030 virtual bool set_basket_size(size_t a_size) = 0;
0031 virtual bool add() = 0;
0032 virtual bool fetch_entry() = 0;
0033 virtual const std::string& name() const = 0;
0034 virtual void reset() = 0;
0035 };
0036 public:
0037
0038
0039 template <class T>
0040 class column_ref : public virtual icol {
0041 public:
0042 static tools::cid id_class() {
0043 static const T s_v = T(); //do that for T = std::string.
0044 return tools::_cid(s_v)+10000;
0045 }
0046 virtual void* cast(tools::cid a_class) const {
0047 if(void* p = tools::cmp_cast<column_ref>(this,a_class)) {return p;}
0048 else return 0;
0049 }
0050 virtual tools::cid id_cls() const {return id_class();}
0051 public: //icol
0052 virtual bool add() { //write.
0053 if(!m_write) return false;
0054 if(m_basket_pos>=m_basket_size) {
0055 if(!m_branch.write_page<T>(m_basket_size,m_basket)) {
0056 m_store.out() << "toolx::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl;
0057 m_basket_pos = 0;
0058 return false;
0059 }
0060 m_basket_pos = 0;
0061 if(m_want_new_basket_size) {
0062 delete [] m_basket;
0063 m_basket = new T[m_want_new_basket_size];
0064 m_basket_pos = 0;
0065 m_basket_size = m_want_new_basket_size;
0066 m_want_new_basket_size = 0;
0067 }
0068 }
0069 m_basket[m_basket_pos] = m_ref;
0070 m_basket_pos++;
0071 return true;
0072 }
0073 virtual bool fetch_entry() { //read.
0074 if(m_write) return false;
0075 if(m_basket_pos>=m_basket_end) { //we need more data.
0076 if(m_branch.pos()>=m_branch.entries()) {
0077 m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl;
0078 m_basket_pos = 0;
0079 m_basket_end = 0;
0080 return false;
0081 }
0082 if(m_want_new_basket_size) {
0083 delete [] m_basket;
0084 m_basket = new T[m_want_new_basket_size];
0085 m_basket_pos = 0;
0086 m_basket_size = m_want_new_basket_size;
0087 m_want_new_basket_size = 0;
0088 }
0089 tools::uint64 remain = m_branch.entries()-m_branch.pos();
0090 size_t n = tools::min_of<size_t>((size_t)remain,m_basket_size);
0091 if(!m_branch.read_page<T>(n,m_basket)) {
0092 m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl;
0093 m_basket_pos = 0;
0094 m_basket_end = 0;
0095 return false;
0096 }
0097 m_basket_pos = 0;
0098 m_basket_end = n;
0099 }
0100 m_ref = m_basket[m_basket_pos];
0101 m_basket_pos++;
0102 return true;
0103 }
0104 virtual void reset() {m_branch.reset_pos();}
0105 virtual const std::string& name() const {return m_name;}
0106 virtual bool set_basket_size(size_t a_size) {
0107 if(!a_size) return false;
0108 m_want_new_basket_size = a_size;
0109 return true;
0110 }
0111 public:
0112 column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref)
0113 :m_store(a_store)
0114 ,m_branch(a_pages)
0115 ,m_write(a_write)
0116 ,m_name(a_name)
0117 ,m_ref(a_ref)
0118 ,m_basket_size(a_basket_size?a_basket_size:32000)
0119 ,m_basket_pos(0)
0120 ,m_basket_end(0) //read.
0121 ,m_basket(0)
0122 ,m_want_new_basket_size(0)
0123 {
0124 m_basket = new T[m_basket_size];
0125 if(m_write) {
0126 } else { //read.
0127 tools::uint64 _entries = m_branch.entries();
0128 size_t n = tools::min_of<size_t>((size_t)_entries,m_basket_size);
0129 if(_entries) {
0130 if(!m_branch.read_page<T>(n,m_basket)) {
0131 m_store.out() << "toolx::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl;
0132 m_basket_pos = 0;
0133 m_basket_end = 0;
0134 return;
0135 }
0136 }
0137 m_basket_pos = 0;
0138 m_basket_end = n;
0139 }
0140 }
0141 virtual ~column_ref(){
0142 if(m_write && m_basket_pos) {
0143 if(!m_branch.write_page<T>(m_basket_pos,m_basket)) {
0144 m_store.out() << "toolx::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl;
0145 }
0146 }
0147 delete [] m_basket;
0148 }
0149 protected:
0150 column_ref(const column_ref& a_from)
0151 :icol(a_from)
0152 ,m_store(a_from.m_store)
0153 ,m_branch(a_from.m_branch)
0154 ,m_write(a_from.m_write)
0155 ,m_name(a_from.m_name)
0156 ,m_ref(a_from.m_ref)
0157 ,m_basket_size(a_from.m_basket_size)
0158 ,m_basket_pos(0)
0159 ,m_basket_end(0)
0160 ,m_basket(0)
0161 ,m_want_new_basket_size(0)
0162 {}
0163 column_ref& operator=(const column_ref& a_from){
0164 if(&a_from==this) return *this;
0165 m_name = a_from.m_name;
0166 m_basket_size = a_from.m_basket_size;
0167 m_basket_pos = 0;
0168 m_basket_end = 0;
0169 m_want_new_basket_size = 0;
0170 return *this;
0171 }
0172 protected:
0173 store& m_store;
0174 pages& m_branch;
0175 bool m_write;
0176 std::string m_name;
0177 T& m_ref;
0178 size_t m_basket_size;
0179 size_t m_basket_pos;
0180 size_t m_basket_end;
0181 T* m_basket;
0182 size_t m_want_new_basket_size;
0183 };
0184
0185 template <class T>
0186 class column : public column_ref<T> {
0187 typedef column_ref<T> parent;
0188 public:
0189 static tools::cid id_class() {
0190 static const T s_v = T(); //do that for T = std::string.
0191 return tools::_cid(s_v);
0192 }
0193 virtual void* cast(tools::cid a_class) const {
0194 if(void* p = tools::cmp_cast<column>(this,a_class)) {return p;}
0195 else return 0;
0196 }
0197 virtual tools::cid id_cls() const {return id_class();}
0198 public:
0199 column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
0200 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
0201 ,m_tmp(T())
0202 {
0203 }
0204 virtual ~column(){
0205 }
0206 protected:
0207 column(const column& a_from)
0208 :icol(a_from)
0209 ,parent(a_from)
0210 ,m_tmp(a_from.m_tmp)
0211 {}
0212 column& operator=(const column& a_from){
0213 if(&a_from==this) return *this;
0214 parent::operator=(a_from);
0215 m_tmp = a_from.m_tmp;
0216 return *this;
0217 }
0218 public:
0219 bool fill(const T& a_value) {m_tmp = a_value;return true;} //write.
0220 bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read.
0221 protected:
0222 T m_tmp;
0223 };
0224
0225 TOOLS_CLASS_STRING_VALUE(vector_char,vector<char>)
0226 TOOLS_CLASS_STRING_VALUE(vector_short,vector<short>)
0227 TOOLS_CLASS_STRING_VALUE(vector_int,vector<int>)
0228 TOOLS_CLASS_STRING_VALUE(vector_float,vector<float>)
0229 TOOLS_CLASS_STRING_VALUE(vector_double,vector<double>)
0230
0231 TOOLS_CLASS_STRING_VALUE(string,string)
0232
0233 TOOLS_CLASS_STRING_VALUE(vector_int64,vector<tools::int64>)
0234 TOOLS_CLASS_STRING_VALUE(vector_uchar,vector<tools::uchar>)
0235 TOOLS_CLASS_STRING_VALUE(vector_ushort,vector<tools::ushort>)
0236 TOOLS_CLASS_STRING_VALUE(vector_uint32,vector<tools::uint32>)
0237 TOOLS_CLASS_STRING_VALUE(vector_uint64,vector<tools::uint64>)
0238
0239 TOOLS_CLASS_STRING_VALUE(vector_string,vector<std::string>)
0240
0241 template <class T>
0242 class std_vector_column_ref : public virtual icol {
0243 public:
0244 static tools::cid id_class() {return tools::_cid_std_vector<T>()+10000;}
0245 virtual void* cast(tools::cid a_class) const {
0246 if(void* p = tools::cmp_cast<std_vector_column_ref>(this,a_class)) {return p;}
0247 else return 0;
0248 }
0249 virtual tools::cid id_cls() const {return id_class();}
0250 public: //icol
0251 virtual bool add() { //write.
0252 if(!m_write) return false;
0253 const T* _data = m_ref.data();
0254 return m_branch.write_vlen<T>(m_ref.size(),_data);
0255 }
0256 virtual bool fetch_entry() { //read.
0257 if(m_write) return false;
0258 size_t n;
0259 T* _data;
0260 if(!m_branch.read_vlen<T>(n,_data)) {
0261 m_store.out() << "toolx::hdf5::ntuple::std_vector_column_ref:fetch_entry : read_page() failed." << std::endl;
0262 return false;
0263 }
0264 m_ref.resize(n);
0265 T* dpos = _data;
0266 T* pos = m_ref.data();
0267 for(size_t index=0;index<n;index++,pos++,dpos++) *pos = *dpos;
0268 delete [] _data;
0269 return true;
0270 }
0271 virtual void reset() {m_branch.reset_pos();}
0272 virtual const std::string& name() const {return m_name;}
0273 virtual bool set_basket_size(size_t) {return true;}
0274 public:
0275 std_vector_column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
0276 size_t /*a_basket_size*/,
0277 std::vector<T>& a_ref)
0278 :m_store(a_store)
0279 ,m_branch(a_pages)
0280 ,m_write(a_write)
0281 ,m_name(a_name)
0282 ,m_ref(a_ref)
0283 {
0284 }
0285 virtual ~std_vector_column_ref(){
0286 }
0287 protected:
0288 std_vector_column_ref(const std_vector_column_ref& a_from)
0289 :icol(a_from)
0290 ,m_store(a_from.m_store)
0291 ,m_branch(a_from.m_branch)
0292 ,m_write(a_from.m_write)
0293 ,m_name(a_from.m_name)
0294 ,m_ref(a_from.m_ref)
0295 {}
0296 std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
0297 if(&a_from==this) return *this;
0298 m_name = a_from.m_name;
0299 return *this;
0300 }
0301 protected:
0302 store& m_store;
0303 pages& m_branch;
0304 bool m_write;
0305 std::string m_name;
0306 std::vector<T>& m_ref;
0307 };
0308
0309 template <class T>
0310 class std_vector_column : public std_vector_column_ref<T> {
0311 typedef std_vector_column_ref<T> parent;
0312 public:
0313 static tools::cid id_class() {return tools::_cid_std_vector<T>();}
0314 virtual void* cast(tools::cid a_class) const {
0315 if(void* p = tools::cmp_cast<std_vector_column>(this,a_class)) {return p;}
0316 else return 0;
0317 }
0318 virtual tools::cid id_cls() const {return id_class();}
0319 public:
0320 std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
0321 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
0322 {}
0323 virtual ~std_vector_column(){}
0324 protected:
0325 std_vector_column(const std_vector_column& a_from)
0326 :icol(a_from)
0327 ,parent(a_from)
0328 {}
0329 std_vector_column& operator=(const std_vector_column& a_from){
0330 parent::operator=(a_from);
0331 return *this;
0332 }
0333 public:
0334 const std::vector<T>& data() const {return m_tmp;}
0335 protected:
0336 std::vector<T> m_tmp;
0337 };
0338
0339 class column_string_ref : public virtual icol {
0340 public:
0341 static tools::cid id_class() {
0342 static const std::string s_v;
0343 return tools::_cid(s_v)+10000;
0344 }
0345 virtual void* cast(tools::cid a_class) const {
0346 if(void* p = tools::cmp_cast<column_string_ref>(this,a_class)) {return p;}
0347 else return 0;
0348 }
0349 virtual tools::cid id_cls() const {return id_class();}
0350 public: //icol
0351 virtual bool add() { //write.
0352 if(!m_write) return false;
0353 return m_branch.write_string(m_ref);
0354 }
0355 virtual bool fetch_entry() { //read.
0356 if(m_write) return false;
0357 if(!m_branch.read_string(m_ref)) {
0358 m_store.out() << "toolx::hdf5::ntuple::column_string_ref:fetch_entry : read_page() failed." << std::endl;
0359 return false;
0360 }
0361 return true;
0362 }
0363 virtual void reset() {m_branch.reset_pos();}
0364 virtual const std::string& name() const {return m_name;}
0365 virtual bool set_basket_size(size_t) {return true;}
0366 public:
0367 column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
0368 size_t /*a_basket_size*/,
0369 std::string& a_ref)
0370 :m_store(a_store)
0371 ,m_branch(a_pages)
0372 ,m_write(a_write)
0373 ,m_name(a_name)
0374 ,m_ref(a_ref)
0375 {
0376 }
0377 virtual ~column_string_ref(){
0378 }
0379 protected:
0380 column_string_ref(const column_string_ref& a_from)
0381 :icol(a_from)
0382 ,m_store(a_from.m_store)
0383 ,m_branch(a_from.m_branch)
0384 ,m_write(a_from.m_write)
0385 ,m_name(a_from.m_name)
0386 ,m_ref(a_from.m_ref)
0387 {}
0388 column_string_ref& operator=(const column_string_ref& a_from){
0389 if(&a_from==this) return *this;
0390 m_name = a_from.m_name;
0391 return *this;
0392 }
0393 protected:
0394 store& m_store;
0395 pages& m_branch;
0396 bool m_write;
0397 std::string m_name;
0398 std::string& m_ref;
0399 };
0400
0401 class column_string : public column_string_ref {
0402 typedef column_string_ref parent;
0403 public:
0404 static tools::cid id_class() {
0405 static const std::string s_v;
0406 return tools::_cid(s_v);
0407 }
0408 virtual void* cast(tools::cid a_class) const {
0409 if(void* p = tools::cmp_cast<column_string>(this,a_class)) {return p;}
0410 else return 0;
0411 }
0412 virtual tools::cid id_cls() const {return id_class();}
0413 public:
0414 column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size)
0415 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
0416 {
0417 }
0418 virtual ~column_string(){
0419 }
0420 protected:
0421 column_string(const column_string& a_from)
0422 :icol(a_from)
0423 ,parent(a_from)
0424 {}
0425 column_string& operator=(const column_string& a_from){
0426 if(&a_from==this) return *this;
0427 parent::operator=(a_from);
0428 return *this;
0429 }
0430 public:
0431 bool fill(const std::string& a_value) {m_tmp = a_value;return true;}
0432 bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;}
0433 protected:
0434 std::string m_tmp;
0435 };
0436
0437
0438
0439 class std_vector_column_string_ref : public virtual icol {
0440 public:
0441 static tools::cid id_class() {return tools::_cid_std_vector<std::string>()+10000;}
0442 virtual void* cast(tools::cid a_class) const {
0443 if(void* p = tools::cmp_cast<std_vector_column_string_ref>(this,a_class)) {return p;}
0444 else return 0;
0445 }
0446 virtual tools::cid id_cls() const {return id_class();}
0447 public: //icol
0448 virtual bool add() { //write.
0449 if(!m_write) return false;
0450 size_t _size = 0;
0451 {tools_vforcit(std::string,m_ref,it) {
0452 _size += (*it).size();
0453 _size++;
0454 }}
0455 char* _data = _size?new char[_size]:0;
0456 {char* pos = _data;
0457 tools_vforcit(std::string,m_ref,it) {
0458 ::memcpy(pos,(*it).c_str(),(*it).size());
0459 pos += (*it).size();
0460 *pos = 0;
0461 pos++;
0462 }}
0463 return m_branch.write_vlen<char>(_size,_data);
0464 }
0465 virtual bool fetch_entry() { //read.
0466 if(m_write) return false;
0467 size_t n;
0468 char* _data;
0469 if(!m_branch.read_vlen<char>(n,_data)) {
0470 m_store.out() << "toolx::hdf5::ntuple::std_vector_column_string_ref:fetch_entry : read_page() failed." << std::endl;
0471 return false;
0472 }
0473 m_ref.clear();
0474 {char* pos = _data;
0475 char* begin = _data;
0476 for(size_t ichar=0;ichar<n;ichar++,pos++) {
0477 if(*pos==0) {
0478 m_ref.push_back(begin);
0479 begin = pos+1;
0480 }
0481 }}
0482 delete [] _data;
0483 return true;
0484 }
0485 virtual void reset() {m_branch.reset_pos();}
0486 virtual const std::string& name() const {return m_name;}
0487 virtual bool set_basket_size(size_t) {return true;}
0488 public:
0489 std_vector_column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
0490 size_t /*a_basket_size*/,
0491 std::vector<std::string>& a_ref)
0492 :m_store(a_store)
0493 ,m_branch(a_pages)
0494 ,m_write(a_write)
0495 ,m_name(a_name)
0496 ,m_ref(a_ref)
0497 {
0498 }
0499 virtual ~std_vector_column_string_ref(){
0500 }
0501 protected:
0502 std_vector_column_string_ref(const std_vector_column_string_ref& a_from)
0503 :icol(a_from)
0504 ,m_store(a_from.m_store)
0505 ,m_branch(a_from.m_branch)
0506 ,m_write(a_from.m_write)
0507 ,m_name(a_from.m_name)
0508 ,m_ref(a_from.m_ref)
0509 {}
0510 std_vector_column_string_ref& operator=(const std_vector_column_string_ref& a_from){
0511 if(&a_from==this) return *this;
0512 m_name = a_from.m_name;
0513 return *this;
0514 }
0515 protected:
0516 store& m_store;
0517 pages& m_branch;
0518 bool m_write;
0519 std::string m_name;
0520 std::vector<std::string>& m_ref;
0521 };
0522
0523 class std_vector_column_string : public std_vector_column_string_ref {
0524 typedef std_vector_column_string_ref parent;
0525 public:
0526 static tools::cid id_class() {return tools::_cid_std_vector<std::string>();}
0527 virtual void* cast(tools::cid a_class) const {
0528 if(void* p = tools::cmp_cast<std_vector_column_string>(this,a_class)) {return p;}
0529 else return 0;
0530 }
0531 virtual tools::cid id_cls() const {return id_class();}
0532 public:
0533 std_vector_column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
0534 :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
0535 {}
0536 virtual ~std_vector_column_string(){}
0537 protected:
0538 std_vector_column_string(const std_vector_column_string& a_from)
0539 :icol(a_from)
0540 ,parent(a_from)
0541 {}
0542 std_vector_column_string& operator=(const std_vector_column_string& a_from){
0543 parent::operator=(a_from);
0544 return *this;
0545 }
0546 public:
0547 const std::vector<std::string>& data() const {return m_tmp;}
0548 protected:
0549 std::vector<std::string> m_tmp;
0550 };
0551
0552 public:
0553 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,
0554 unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/)
0555 :store(a_out,a_group,a_name,true,a_compress) //true=write
0556 {}
0557
0558 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name)
0559 :store(a_out,a_group,a_name,false,0) //false=read
0560 {
0561 tools_vforcit(pages*,m_pagess,it){
0562
0563 #define TOOLX_HDF5_NTUPLE_READ_CREATE_COL(a__type) \
0564 if((*it)->form()==tools::stype(a__type())) {\
0565 column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
0566 if(!col) {tools::safe_clear<icol>(m_cols);return;}\
0567 m_cols.push_back(col);\
0568 }
0569
0570 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \
0571 if((*it)->form()==s_vector_##a__vec_type()) {\
0572 std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
0573 if(!col) {tools::safe_clear<icol>(m_cols);return;}\
0574 m_cols.push_back(col);\
0575 }
0576
0577 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING \
0578 if((*it)->form()==s_vector_string()) {\
0579 std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\
0580 if(!col) {tools::safe_clear<icol>(m_cols);return;}\
0581 m_cols.push_back(col);\
0582 }
0583
0584 TOOLX_HDF5_NTUPLE_READ_CREATE_COL(char)
0585 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(short)
0586 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(int)
0587 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::int64)
0588
0589 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(float)
0590 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(double)
0591
0592 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::byte)
0593 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort)
0594 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32)
0595 else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64)
0596
0597 else
0598 if((*it)->form()==s_string()) {
0599 column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
0600 if(!col) {tools::safe_clear<icol>(m_cols);return;}
0601 m_cols.push_back(col);
0602 }
0603
0604 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char)
0605 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short)
0606 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int)
0607 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64)
0608
0609 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float)
0610 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double)
0611
0612 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar)
0613 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort)
0614 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32)
0615 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64)
0616
0617 else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING
0618
0619 else {
0620 m_out << "toolx::hdf5::ntuple::ntuple(read) :"
0621 << " for column " << tools::sout((*it)->name())
0622 << ", type " << tools::sout((*it)->form()) << " not yet handled."
0623 << std::endl;
0624 //throw
0625 tools::safe_clear<icol>(m_cols);
0626 return;
0627 }
0628 }
0629 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL
0630 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_COL
0631 }
0632
0633 ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd)
0634 :store(a_out,a_group,a_name,false,0) //false=read
0635 {
0636 if(!initialize(a_out,a_bd)) {}
0637 }
0638
0639 ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg,
0640 unsigned int a_compress,size_t a_basket_size/* = 32000*/)
0641 :store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write
0642 ,m_title(a_bkg.title())
0643 {
0644 const std::vector<tools::column_booking>& cols = a_bkg.columns();
0645 tools_vforcit(tools::column_booking,cols,it){
0646
0647 #define TOOLX_HDF5_NTUPLE_CREATE_COL(a__type) \
0648 if((*it).cls_id()==tools::_cid(a__type())) {\
0649 a__type* user = (a__type*)(*it).user_obj();\
0650 if(user) {\
0651 if(!create_column_ref<a__type>((*it).name(),a_basket_size,*user)) {\
0652 m_out << "toolx::hdf5::ntuple :"\
0653 << " can't create column_ref " << tools::sout((*it).name()) << "."\
0654 << std::endl;\
0655 tools::safe_clear<icol>(m_cols);\
0656 return;\
0657 }\
0658 } else {\
0659 if(!create_column<a__type>((*it).name(),a_basket_size)) {\
0660 m_out << "toolx::hdf5::ntuple :"\
0661 << " can't create column " << tools::sout((*it).name()) << "."\
0662 << std::endl;\
0663 tools::safe_clear<icol>(m_cols);\
0664 return;\
0665 }\
0666 }\
0667 }
0668
0669 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \
0670 if((*it).cls_id()==tools::_cid_std_vector<a__type>()) {\
0671 std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
0672 if(!vec) {\
0673 m_out << "toolx::hdf5::ntuple :"\
0674 << " for std::vector column " << tools::sout((*it).name())\
0675 << ", the user vector pointer is null."\
0676 << std::endl;\
0677 tools::safe_clear<icol>(m_cols);\
0678 return;\
0679 }\
0680 if(!create_std_column_ref<a__type>((*it).name(),a_basket_size,*vec)) {\
0681 m_out << "toolx::hdf5::ntuple :"\
0682 << " can't create std::vector column " << tools::sout((*it).name()) << "."\
0683 << std::endl;\
0684 tools::safe_clear<icol>(m_cols);\
0685 return;\
0686 }\
0687 }
0688
0689 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING \
0690 if((*it).cls_id()==tools::_cid_std_vector<std::string>()) {\
0691 std::vector<std::string>* vec = (std::vector<std::string>*)(*it).user_obj();\
0692 if(!vec) {\
0693 m_out << "toolx::hdf5::ntuple :"\
0694 << " for std::vector column " << tools::sout((*it).name())\
0695 << ", the user vector pointer is null."\
0696 << std::endl;\
0697 tools::safe_clear<icol>(m_cols);\
0698 return;\
0699 }\
0700 if(!create_std_column_string_ref((*it).name(),a_basket_size,*vec)) {\
0701 m_out << "toolx::hdf5::ntuple :"\
0702 << " can't create std::vector column " << tools::sout((*it).name()) << "."\
0703 << std::endl;\
0704 tools::safe_clear<icol>(m_cols);\
0705 return;\
0706 }\
0707 }
0708
0709 TOOLX_HDF5_NTUPLE_CREATE_COL(char)
0710 else TOOLX_HDF5_NTUPLE_CREATE_COL(short)
0711 else TOOLX_HDF5_NTUPLE_CREATE_COL(int)
0712 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::int64)
0713
0714 else TOOLX_HDF5_NTUPLE_CREATE_COL(float)
0715 else TOOLX_HDF5_NTUPLE_CREATE_COL(double)
0716
0717 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::byte)
0718 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::ushort)
0719 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint32)
0720 else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint64)
0721
0722 else if((*it).cls_id()==tools::_cid(std::string())) {
0723 if(!create_column_string((*it).name(),a_basket_size)) {
0724 m_out << "toolx::hdf5::ntuple :"
0725 << " can't create string column " << tools::sout((*it).name()) << "."
0726 << std::endl;
0727 tools::safe_clear<icol>(m_cols);
0728 return;
0729 }
0730
0731 } else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(char)
0732 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(short)
0733 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(int)
0734 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64)
0735
0736 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(float)
0737 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(double)
0738
0739 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar)
0740 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort)
0741 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32)
0742 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64)
0743
0744 else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING
0745
0746 else {
0747 m_out << "toolx::hdf5::ntuple :"
0748 << " for column " << tools::sout((*it).name())
0749 << ", type with cid " << (*it).cls_id() << " not yet handled."
0750 << std::endl;
0751 tools::safe_clear<icol>(m_cols);
0752 return;
0753 }
0754 }
0755 #undef TOOLX_HDF5_NTUPLE_CREATE_COL
0756 #undef TOOLX_HDF5_NTUPLE_CREATE_VEC_COL
0757
0758 }
0759
0760 virtual ~ntuple() {
0761 tools::safe_clear<icol>(m_cols);
0762 }
0763 protected:
0764 ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){}
0765 ntuple& operator=(const ntuple&){return *this;}
0766 public:
0767 bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) {
0768 tools::safe_clear<icol>(m_cols);
0769 {tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();}
0770
0771 tools_vforcit(pages*,m_pagess,it) {
0772
0773 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \
0774 if((*it)->form()==tools::stype(a__type())) {\
0775 a__type* user_var = a_bd.find_variable<a__type>((*it)->name());\
0776 if(user_var) {\
0777 column_ref<a__type>* col = new column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
0778 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0779 m_cols.push_back(col);\
0780 } else {\
0781 column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
0782 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0783 m_cols.push_back(col);\
0784 }\
0785 }
0786
0787 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \
0788 if((*it)->form()==s_vector_##a__vec_type()) {\
0789 std::vector<a__type>* user_var = a_bd.find_variable< std::vector<a__type> >((*it)->name());\
0790 if(user_var) {\
0791 std_vector_column_ref<a__type>* col = \
0792 new std_vector_column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
0793 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0794 m_cols.push_back(col);\
0795 } else {\
0796 std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
0797 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0798 m_cols.push_back(col);\
0799 }\
0800 }
0801
0802 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING \
0803 if((*it)->form()==s_vector_string()) {\
0804 std::vector<std::string>* user_var = a_bd.find_variable< std::vector<std::string> >((*it)->name());\
0805 if(user_var) {\
0806 std_vector_column_string_ref* col = \
0807 new std_vector_column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\
0808 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0809 m_cols.push_back(col);\
0810 } else {\
0811 std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\
0812 if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
0813 m_cols.push_back(col);\
0814 }\
0815 }
0816
0817 TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char)
0818 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short)
0819 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int)
0820 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64)
0821
0822 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float)
0823 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double)
0824
0825 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte)
0826 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort)
0827 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32)
0828 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64)
0829
0830 else
0831 if((*it)->form()==s_string()) {
0832 std::string* user_var = a_bd.find_variable<std::string>((*it)->name());
0833 if(user_var) {
0834 column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);
0835 if(!col) {tools::safe_clear<icol>(m_cols);return false;}
0836 m_cols.push_back(col);
0837 } else {
0838 column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
0839 if(!col) {tools::safe_clear<icol>(m_cols);return false;}
0840 m_cols.push_back(col);
0841 }
0842 }
0843
0844 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char)
0845 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short)
0846 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int)
0847 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64)
0848
0849 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float)
0850 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double)
0851
0852 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar)
0853 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort)
0854 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32)
0855 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64)
0856
0857 else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING
0858
0859 else {
0860 a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
0861 << " for column " << tools::sout((*it)->name())
0862 << ", type " << tools::sout((*it)->form()) << " not yet handled."
0863 << std::endl;
0864 tools::safe_clear<icol>(m_cols);
0865 return false;
0866 }
0867 }
0868 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL
0869 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL
0870
0871 size_t num = m_cols.size();
0872 if(!num) {
0873 a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
0874 << " zero columns."
0875 << std::endl;
0876 return false;
0877 }
0878
0879 {tools_vforcit(tools::column_binding,a_bd.columns(),it) {
0880 if(!tools::find_named<icol>(m_cols,(*it).name())) {
0881 a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
0882 << " error : for column binding with name " << tools::sout((*it).name()) << ", no ntuple column found."
0883 << std::endl;
0884 tools::safe_clear<icol>(m_cols);
0885 return false;
0886 }
0887 }}
0888
0889 return true;
0890 }
0891
0892 const std::string& title() const {return m_title;}
0893
0894 const std::vector<icol*>& columns() const {return m_cols;}
0895 std::vector<icol*>& columns() {return m_cols;}
0896
0897 template <class T>
0898 column_ref<T>* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_ref) {
0899 if(tools::find_named<icol>(m_cols,a_name)) return 0;
0900 pages* _pages = create_pages(a_name,tools::stype(T()));
0901 if(!_pages) return 0;
0902 column_ref<T>* col = new column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref);
0903 if(!col) return 0;
0904 m_cols.push_back(col);
0905 return col;
0906 }
0907
0908 template <class T>
0909 column<T>* create_column(const std::string& a_name,size_t a_basket_size) {
0910 if(tools::find_named<icol>(m_cols,a_name)) return 0;
0911 pages* _pages = create_pages(a_name,tools::stype(T()));
0912 if(!_pages) return 0;
0913 column<T>* col = new column<T>(*this,*_pages,true,a_name,a_basket_size);
0914 if(!col) return 0;
0915 m_cols.push_back(col);
0916 return col;
0917 }
0918
0919 column_string* create_column_string(const std::string& a_name,size_t a_basket_size) {
0920 if(tools::find_named<icol>(m_cols,a_name)) return 0;
0921 pages* _pages = create_pages(a_name,s_string());
0922 if(!_pages) return 0;
0923 column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size);
0924 if(!col) return 0;
0925 m_cols.push_back(col);
0926 return col;
0927 }
0928
0929 template <class T>
0930 std_vector_column_ref<T>* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector<T>& a_ref) {
0931 //NOTE : to optimize, we do not handle a default std::vector value logic.
0932 if(tools::find_named<icol>(m_cols,a_name)) return 0;
0933 pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">");
0934 if(!_pages) return 0;
0935 std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref);
0936 if(!col) return 0;
0937 m_cols.push_back(col);
0938 return col;
0939 }
0940
0941 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) {
0942 //NOTE : to optimize, we do not handle a default std::vector value logic.
0943 if(tools::find_named<icol>(m_cols,a_name)) return 0;
0944 pages* _pages = create_pages(a_name,"vector<std::string>");
0945 if(!_pages) return 0;
0946 std_vector_column_string_ref* col = new std_vector_column_string_ref(*this,*_pages,true,a_name,a_basket_size,a_ref);
0947 if(!col) return 0;
0948 m_cols.push_back(col);
0949 return col;
0950 }
0951
0952 template <class T>
0953 column_ref<T>* find_column_ref(const std::string& a_name) {
0954 icol* col = tools::find_named<icol>(m_cols,a_name);
0955 if(!col) return 0;
0956 return tools::id_cast<icol, column_ref<T> >(*col);
0957 }
0958 template <class T>
0959 column<T>* find_column(const std::string& a_name) {
0960 icol* col = tools::find_named<icol>(m_cols,a_name);
0961 if(!col) return 0;
0962 return tools::id_cast<icol, column<T> >(*col);
0963 }
0964
0965 template <class T>
0966 std_vector_column_ref<T>* find_std_vector_column_ref(const std::string& a_name) {
0967 icol* col = tools::find_named<icol>(m_cols,a_name);
0968 if(!col) return 0;
0969 return tools::id_cast<icol, std_vector_column_ref<T> >(*col);
0970 }
0971 template <class T>
0972 std_vector_column<T>* find_std_vector_column(const std::string& a_name) {
0973 icol* col = tools::find_named<icol>(m_cols,a_name);
0974 if(!col) return 0;
0975 return tools::id_cast<icol, std_vector_column<T> >(*col);
0976 }
0977
0978 std_vector_column_string_ref* find_std_vector_column_string_ref(const std::string& a_name) {
0979 icol* col = tools::find_named<icol>(m_cols,a_name);
0980 if(!col) return 0;
0981 return tools::id_cast<icol, std_vector_column_string_ref >(*col);
0982 }
0983 std_vector_column_string* find_std_vector_column_string(const std::string& a_name) {
0984 icol* col = tools::find_named<icol>(m_cols,a_name);
0985 if(!col) return 0;
0986 return tools::id_cast<icol, std_vector_column_string >(*col);
0987 }
0988
0989 column_string* find_column_string(const std::string& a_name) {
0990 icol* col = tools::find_named<icol>(m_cols,a_name);
0991 if(!col) return 0;
0992 return tools::id_cast<icol, column_string >(*col);
0993 }
0994
0995 bool add_row() { //write.
0996 if(m_cols.empty()) return false;
0997 bool status = true;
0998 tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;}
0999 return status;
1000 }
1001
1002 bool get_row() { //read.
1003 bool status = true;
1004 tools_vforcit(icol*,m_cols,it) {
1005 if(!(*it)->fetch_entry()) status = false;
1006 }
1007 return status;
1008 }
1009
1010 bool set_basket_size(size_t a_size) {
1011 tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;}
1012 return true;
1013 }
1014
1015 void reset() { //read.
1016 tools_vforit(icol*,m_cols,it) (*it)->reset();
1017 }
1018
1019 protected:
1020 std::string m_title;
1021 std::vector<icol*> m_cols;
1022 };
1023
1024 }}
1025
1026
1027 #endif