Back to home page

EIC code displayed by LXR

 
 

    


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