Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wroot/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 tools_wroot_ntuple
0005 #define tools_wroot_ntuple
0006 
0007 // An ntuple class to write at the CERN-ROOT format.
0008 // It inherits wroot::tree and each column is mapped
0009 // on a (wroot::branch,wroot::leaf). Each add_row() does a tree::fill().
0010 
0011 #include "tree"
0012 #include "icol"
0013 
0014 #include "../vmanip"
0015 #include "../ntuple_booking"
0016 #include "../sout"
0017 #include "../scast"
0018 #include "../forit"
0019 
0020 // for mpi :
0021 #include "mpi_create_basket"
0022 
0023 namespace tools {
0024 namespace wroot {
0025 
0026 class ntuple : public tree {
0027 public:
0028 
0029 #include "columns.icc"
0030 
0031 public:
0032   ntuple(idir& a_dir,const std::string& a_name,const std::string& a_title,bool a_row_wise = false)
0033   :tree(a_dir,a_name,a_title),m_row_wise(a_row_wise),m_row_wise_branch(0)
0034   {
0035     if(m_row_wise) m_row_wise_branch = create_branch("row_wise_branch");
0036   }
0037 
0038   ntuple(idir& a_dir,const ntuple_booking& a_bkg,bool a_row_wise = false)
0039   :tree(a_dir,a_bkg.name(),a_bkg.title()),m_row_wise(a_row_wise),m_row_wise_branch(0)
0040   {
0041     if(m_row_wise) m_row_wise_branch = create_branch("row_wise_branch");
0042 
0043     const std::vector<column_booking>& cols = a_bkg.columns();
0044     tools_vforcit(column_booking,cols,it){
0045 
0046 #define TOOLS_WROOT_NTUPLE_CREATE_COL(a__type) \
0047       if((*it).cls_id()==_cid(a__type())) {\
0048         a__type* user = (a__type*)(*it).user_obj();\
0049         if(user) {\
0050           if(!create_column_ref<a__type>((*it).name(),*user)) {\
0051             m_out << "tools::wroot::ntuple : create_column_ref(" << (*it).name() << ") failed." << std::endl;\
0052             safe_clear<icol>(m_cols);\
0053             safe_clear<branch>(m_branches);\
0054             return;\
0055           }\
0056         } else {\
0057           if(!create_column<a__type>((*it).name())) {\
0058             m_out << "tools::wroot::ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
0059             safe_clear<icol>(m_cols);\
0060             safe_clear<branch>(m_branches);\
0061             return;\
0062           }\
0063         }\
0064       }
0065 
0066 #define TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(a__type) \
0067       if((*it).cls_id()==_cid_std_vector<a__type>()) {\
0068         std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
0069         if(vec) {\
0070           if(!create_column_vector_ref<a__type>((*it).name(),*vec)) {\
0071             m_out << "tools::wroot::ntuple : create_column_vector_ref(" << (*it).name() << ") failed." << std::endl;\
0072             safe_clear<icol>(m_cols);\
0073             safe_clear<branch>(m_branches);\
0074             return;\
0075           }\
0076         } else {\
0077           if(!create_column_vector<a__type>((*it).name())) {\
0078             m_out << "tools::wroot::ntuple : create_column_vector(" << (*it).name() << ") failed." << std::endl;\
0079             safe_clear<icol>(m_cols);\
0080             safe_clear<branch>(m_branches);\
0081             return;\
0082           }\
0083         }\
0084       }
0085 
0086       //below types are in sync with rroot/ntuple.
0087 
0088            TOOLS_WROOT_NTUPLE_CREATE_COL(char)
0089       else TOOLS_WROOT_NTUPLE_CREATE_COL(short)
0090       else TOOLS_WROOT_NTUPLE_CREATE_COL(int)
0091       else TOOLS_WROOT_NTUPLE_CREATE_COL(float)
0092       else TOOLS_WROOT_NTUPLE_CREATE_COL(double)
0093 
0094       else if((*it).cls_id()==_cid(std::string())) {
0095         std::string* user = (std::string*)(*it).user_obj();
0096         if(user) {
0097           if(!create_column_string_ref((*it).name(),*user)) {
0098             m_out << "tools::wroot::ntuple : create_column_string_ref(" << (*it).name() << ") failed." << std::endl;
0099             safe_clear<icol>(m_cols);
0100             safe_clear<branch>(m_branches);
0101             return;
0102           }
0103         } else {
0104           if(!create_column_string((*it).name())) {
0105             m_out << "tools::wroot::ntuple : create_column_string(" << (*it).name() << ") failed." << std::endl;
0106             safe_clear<icol>(m_cols);
0107             safe_clear<branch>(m_branches);
0108             return;
0109           }
0110         }
0111       }
0112 
0113       else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(char)
0114       else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(short)
0115       else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(int)
0116       else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(float)
0117       else TOOLS_WROOT_NTUPLE_CREATE_VEC_COL(double)
0118 
0119       else if((*it).cls_id()==_cid_std_vector<std::string>()) {\
0120         std::vector<std::string>* user = (std::vector<std::string>*)(*it).user_obj();
0121         char sep = '\n';
0122         if(user) {
0123           if(!create_column_vector_string_ref((*it).name(),*user,sep)) {
0124             m_out << "tools::wroot::ntuple : create_column_vector_string_ref(" << (*it).name() << ") failed." << std::endl;
0125             safe_clear<icol>(m_cols);
0126             safe_clear<branch>(m_branches);
0127             return;
0128           }
0129         } else {
0130           if(!create_column_vector_string((*it).name(),std::vector<std::string>(),sep)) {
0131             m_out << "tools::wroot::ntuple : create_column_vector_string(" << (*it).name() << ") failed." << std::endl;
0132             safe_clear<icol>(m_cols);
0133             safe_clear<branch>(m_branches);
0134             return;
0135           }
0136         }
0137       }
0138 
0139       // no leaf_store_class() defined for the other types.
0140 
0141       else {
0142         m_out << "tools::wroot::ntuple :"
0143               << " for column " << sout((*it).name())
0144               << ", type with cid " << (*it).cls_id() << " not yet handled."
0145               << std::endl;
0146         //throw
0147         safe_clear<icol>(m_cols);
0148         safe_clear<branch>(m_branches);
0149         return;
0150       }
0151     }
0152 #undef TOOLS_WROOT_NTUPLE_CREATE_VEC_COL
0153 #undef TOOLS_WROOT_NTUPLE_CREATE_COL
0154 
0155   }
0156 
0157   virtual ~ntuple() {
0158     safe_clear<icol>(m_cols);
0159   }
0160 protected:
0161   ntuple(const ntuple& a_from):iobject(a_from),itree(a_from),tree(a_from),m_row_wise(a_from.m_row_wise){}
0162   ntuple& operator=(const ntuple&){return *this;}
0163 public:
0164   const std::vector<icol*>& columns() const {return m_cols;}
0165   std::vector<icol*>& columns() {return m_cols;}
0166 
0167   template <class T>
0168   column_ref<T>* create_column_ref(const std::string& a_name,const T& a_ref) {
0169     if(find_named<icol>(m_cols,a_name)) return 0;
0170     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0171     if(!_branch) return 0;
0172     column_ref<T>* col = new column_ref<T>(*_branch,a_name,a_ref);
0173     if(!col) return 0;
0174     m_cols.push_back(col);
0175     return col;
0176   }
0177 
0178   template <class T>
0179   column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0180     if(find_named<icol>(m_cols,a_name)) return 0;
0181     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0182     if(!_branch) return 0;
0183     column<T>* col = new column<T>(*_branch,a_name,a_def);
0184     if(!col) return 0;
0185     m_cols.push_back(col);
0186     return col;
0187   }
0188 
0189   column_string_ref* create_column_string_ref(const std::string& a_name,const std::string& a_ref) {
0190     if(find_named<icol>(m_cols,a_name)) return 0;
0191     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0192     if(!_branch) return 0;
0193     column_string_ref* col = new column_string_ref(*_branch,a_name,a_ref);
0194     if(!col) return 0;
0195     m_cols.push_back(col);
0196     return col;
0197   }
0198 
0199   column_string* create_column_string(const std::string& a_name,const std::string& a_def = std::string()) {
0200     if(find_named<icol>(m_cols,a_name)) return 0;
0201     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0202     if(!_branch) return 0;
0203     column_string* col = new column_string(*_branch,a_name,a_def);
0204     if(!col) return 0;
0205     m_cols.push_back(col);
0206     return col;
0207   }
0208 
0209   column_vector_string_ref* create_column_vector_string_ref(const std::string& a_name,
0210                                                             const std::vector<std::string>& a_ref,char a_sep) {
0211     if(find_named<icol>(m_cols,a_name)) return 0;
0212     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0213     if(!_branch) return 0;
0214     column_vector_string_ref* col = new column_vector_string_ref(*_branch,a_name,a_ref,a_sep);
0215     if(!col) return 0;
0216     m_cols.push_back(col);
0217     return col;
0218   }
0219 
0220   column_vector_string* create_column_vector_string(const std::string& a_name,
0221                                                     const std::vector<std::string>& a_def,char a_sep) {
0222     if(find_named<icol>(m_cols,a_name)) return 0;
0223     branch* _branch = m_row_wise?m_row_wise_branch:create_branch(a_name);
0224     if(!_branch) return 0;
0225     column_vector_string* col = new column_vector_string(*_branch,a_name,a_def,a_sep);
0226     if(!col) return 0;
0227     m_cols.push_back(col);
0228     return col;
0229   }
0230 
0231   template <class T>
0232   std_vector_column_ref<T>* create_column_vector_ref(const std::string& a_name,const std::vector<T>& a_ref) {
0233     if(find_named<icol>(m_cols,a_name)) return 0;
0234     branch* _branch = m_row_wise?m_row_wise_branch:create_std_vector_be_ref<T>(a_name,a_ref);
0235     if(!_branch) return 0;
0236     std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*_branch,a_name,a_ref);
0237     if(!col) return 0;
0238     m_cols.push_back(col);
0239     return col;
0240   }
0241 
0242   template <class T>
0243   std_vector_column<T>* create_column_vector(const std::string& a_name,const std::vector<T>& a_def = std::vector<T>()) {
0244     if(find_named<icol>(m_cols,a_name)) return 0;
0245     if(m_row_wise) {
0246       branch* _branch = m_row_wise_branch;
0247       std_vector_column<T>* col = new std_vector_column<T>(*_branch,a_name,a_def);
0248       if(!col) return 0;
0249       m_cols.push_back(col);
0250       return col;
0251     } else {
0252       std_vector_be_pointer<T>* _branch = create_std_vector_be_pointer<T>(a_name,0);
0253       if(!_branch) return 0;
0254       std_vector_column<T>* col = new std_vector_column<T>(*_branch,a_name,a_def);
0255       if(!col) return 0;
0256       _branch->set_pointer(&(col->variable()));
0257       m_cols.push_back(col);
0258       return col;
0259     }
0260   }
0261 
0262   template <class T>
0263   column_ref<T>* find_column_ref(const std::string& a_name) {
0264     icol* col = find_named<icol>(m_cols,a_name);
0265     if(!col) return 0;
0266     return id_cast<icol, column_ref<T> >(*col);
0267   }
0268 
0269   template <class T>
0270   column<T>* find_column(const std::string& a_name) {
0271     icol* col = find_named<icol>(m_cols,a_name);
0272     if(!col) return 0;
0273     return id_cast<icol, column<T> >(*col);
0274   }
0275 
0276   column_string_ref* find_column_string_ref(const std::string& a_name) {
0277     icol* col = find_named<icol>(m_cols,a_name);
0278     if(!col) return 0;
0279     return id_cast<icol, column_string_ref >(*col);
0280   }
0281 
0282   column_string* find_column_string(const std::string& a_name) {
0283     icol* col = find_named<icol>(m_cols,a_name);
0284     if(!col) return 0;
0285     return id_cast<icol, column_string >(*col);
0286   }
0287 
0288   template <class T>
0289   std_vector_column_ref<T>* find_column_vector_ref(const std::string& a_name) {
0290     icol* col = find_named<icol>(m_cols,a_name);
0291     if(!col) return 0;
0292     return id_cast<icol, std_vector_column_ref<T> >(*col);
0293   }
0294 
0295   template <class T>
0296   std_vector_column<T>* find_column_vector(const std::string& a_name) {
0297     icol* col = find_named<icol>(m_cols,a_name);
0298     if(!col) return 0;
0299     return id_cast<icol, std_vector_column<T> >(*col);
0300   }
0301 
0302   column_vector_string_ref* find_column_vector_string_ref(const std::string& a_name) {
0303     icol* col = find_named<icol>(m_cols,a_name);
0304     if(!col) return 0;
0305     return id_cast<icol, column_vector_string_ref >(*col);
0306   }
0307 
0308   column_vector_string* find_column_vector_string(const std::string& a_name) {
0309     icol* col = find_named<icol>(m_cols,a_name);
0310     if(!col) return 0;
0311     return id_cast<icol, column_vector_string >(*col);
0312   }
0313 
0314   void print_columns(std::ostream& a_out) {
0315     a_out << "for ntuple named " << sout(m_name) << ", number of columns " << m_cols.size() << " :" << std::endl;
0316     tools_vforit(icol*,m_cols,it) {
0317       a_out << " " << (*it)->name() << std::endl;
0318     }
0319   }
0320 
0321   bool add_row() {
0322     if(m_cols.empty()) return false;
0323     tools_vforit(icol*,m_cols,it) (*it)->add();
0324     uint32 n;
0325     bool status = tree::fill(n);
0326     tools_vforit(icol*,m_cols,it) (*it)->set_def();
0327     return status;
0328   }
0329 
0330   void set_basket_size(uint32 a_size) {
0331     if(m_row_wise) {
0332       if(m_row_wise_branch) m_row_wise_branch->set_basket_size(a_size);
0333     } else {
0334       tools_vforit(icol*,m_cols,it) (*it)->set_basket_size(a_size);
0335     }
0336   }
0337 
0338   ///////////////////////////////////////////////////////////////////////////
0339   /// for parallelization : /////////////////////////////////////////////////
0340   ///////////////////////////////////////////////////////////////////////////
0341   branch* get_row_wise_branch() const {return m_row_wise_branch;}
0342   void get_branches(std::vector<branch*>& a_vec) const {
0343     a_vec.clear();
0344     tools_vforcit(icol*,m_cols,it) a_vec.push_back(&((*it)->get_branch()));
0345   }
0346 
0347   bool merge_number_of_entries() {
0348     m_entries = 0; //it should be zero!
0349     m_tot_bytes = 0;
0350     m_zip_bytes = 0;
0351     bool status = true;
0352     tools_vforit(icol*,m_cols,it) {
0353       if(it==m_cols.begin()) {
0354         m_entries = (*it)->get_branch().entries();
0355       } else if(m_entries!=(*it)->get_branch().entries()) {
0356         m_out << "tools::wroot::ntuple::merge_number_of_entries :"
0357               << " branches do not have same number of entries."
0358               << std::endl;
0359         status = false;
0360       }
0361       m_tot_bytes += (*it)->get_branch().tot_bytes();
0362       m_zip_bytes += (*it)->get_branch().zip_bytes();
0363     }
0364     return status;
0365   }
0366 
0367   bool mpi_add_basket(impi& a_impi) {
0368     uint32 icol; //not used if row_wise.
0369     if(!a_impi.unpack(icol)) {
0370       m_out << "tools::wroot::ntuple::mpi_add_basket : unpack(icol) failed."<< std::endl;
0371       return false;
0372     }
0373 
0374     if(m_row_wise) {
0375       if(!m_row_wise_branch) return false;
0376 
0377       basket* basket = mpi_create_basket(m_out,a_impi,
0378                                          m_dir.file().byte_swap(),m_dir.seek_directory(),
0379                                          m_row_wise_branch->basket_size());
0380       if(!basket) {
0381         m_out << "tools::wroot::ntuple::mpi_add_basket : mpi_create_basket() failed."<< std::endl;
0382         return false;
0383       }
0384 
0385       uint32 add_bytes,nout;
0386       if(!m_row_wise_branch->add_basket(m_dir.file(),*basket,add_bytes,nout)) {
0387         m_out << "tools::wroot::ntuple::mpi_add_basket : row wise : branch.add_basket() failed."<< std::endl;
0388         delete basket;
0389         return false;
0390       }
0391 
0392       delete basket;
0393       m_row_wise_branch->set_tot_bytes(m_row_wise_branch->tot_bytes()+add_bytes);
0394       m_row_wise_branch->set_zip_bytes(m_row_wise_branch->zip_bytes()+nout);
0395 
0396     } else {
0397       if(icol>=m_cols.size()) {
0398         m_out << "tools::wroot::ntuple::mpi_add_basket : column index "  << icol << " >= " << m_cols.size() << std::endl;
0399         return false;
0400       }
0401 
0402       branch& _branch = m_cols[icol]->get_branch();
0403 
0404       basket* basket = mpi_create_basket(m_out,a_impi,
0405                                          m_dir.file().byte_swap(),m_dir.seek_directory(),
0406                                          _branch.basket_size());
0407       if(!basket) {
0408         m_out << "tools::wroot::ntuple::mpi_add_basket : mpi_create_basket() failed."<< std::endl;
0409         return false;
0410       }
0411 
0412       uint32 add_bytes,nout;
0413       if(!_branch.add_basket(m_dir.file(),*basket,add_bytes,nout)) {
0414         m_out << "tools::wroot::ntuple::mpi_add_basket : column wise : branch.add_basket() failed."<< std::endl;
0415         delete basket;
0416         return false;
0417       }
0418 
0419       delete basket;
0420       _branch.set_tot_bytes(_branch.tot_bytes()+add_bytes);
0421       _branch.set_zip_bytes(_branch.zip_bytes()+nout);
0422     }
0423     return true;
0424   }
0425 
0426   bool mpi_add_baskets(impi& a_impi) { //column_wise && row_mode only.
0427     uint32 _icol = 0;
0428     tools_vforcit(icol*,m_cols,it) {
0429       uint32 icol;
0430       if(!a_impi.unpack(icol)) {
0431         m_out << "tools::wroot::ntuple::mpi_add_baskets : unpack(icol) failed."<< std::endl;
0432         return false;
0433       }
0434       if(icol!=_icol) {
0435         m_out << "tools::wroot::ntuple::mpi_add_basket : received column index "  << icol << ", whilst " << _icol << " expected." << std::endl;
0436         return false;
0437       }
0438       branch& _branch = m_cols[icol]->get_branch();
0439       basket* basket = mpi_create_basket(m_out,a_impi,
0440                                          m_dir.file().byte_swap(),m_dir.seek_directory(),
0441                                          _branch.basket_size());
0442       if(!basket) {
0443         m_out << "tools::wroot::ntuple::mpi_add_basket : mpi_create_basket() failed."<< std::endl;
0444         return false;
0445       }
0446 
0447       uint32 add_bytes,nout;
0448       if(!_branch.add_basket(m_dir.file(),*basket,add_bytes,nout)) {
0449         m_out << "tools::wroot::ntuple::mpi_add_basket : column wise : branch.add_basket() failed."<< std::endl;
0450         delete basket;
0451         return false;
0452       }
0453 
0454       delete basket;
0455       _branch.set_tot_bytes(_branch.tot_bytes()+add_bytes);
0456       _branch.set_zip_bytes(_branch.zip_bytes()+nout);
0457 
0458       _icol++;
0459     }
0460     return true;
0461   }
0462 
0463   bool mpi_end_fill(impi& a_impi) {
0464 
0465 #define TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(a__type) \
0466           {leaf_ref<a__type>* _mleaf_ = _mleaf?id_cast<base_leaf, leaf_ref<a__type> >(*_mleaf):0;\
0467             if(_mleaf_) {\
0468               uint32 _len;\
0469               if(!a_impi.unpack(_len)) return false;\
0470               a__type _mx;\
0471               if(!a_impi.unpack(_mx)) return false;\
0472               _mleaf_->set_length(max_of(_len,_mleaf_->length()));\
0473               _mleaf_->set_max(max_of(_mx,_mleaf_->get_max()));\
0474               set_done = true;\
0475             }}
0476 
0477 #define TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(a__type) \
0478           {leaf_std_vector_ref<a__type>* _mleaf_ = _mleaf?id_cast<base_leaf, leaf_std_vector_ref<a__type> >(*_mleaf):0;\
0479             if(_mleaf_) {\
0480               uint32 _len;\
0481               if(!a_impi.unpack(_len)) return false;\
0482               a__type _mx;\
0483               if(!a_impi.unpack(_mx)) return false;\
0484               _mleaf_->set_length(max_of(_len,_mleaf_->length()));\
0485               _mleaf_->set_max(max_of(_mx,_mleaf_->get_max()));\
0486               set_done = true;\
0487             }}
0488 
0489 #define TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LENGTH_MAX \
0490            {leaf_string_ref* _mleaf_ = _mleaf?id_cast<base_leaf,leaf_string_ref>(*_mleaf):0;\
0491             if(_mleaf_) {\
0492               uint32 _len;\
0493               if(!a_impi.unpack(_len)) return false;\
0494               int _mx;\
0495               if(!a_impi.unpack(_mx)) return false;\
0496               _mleaf_->set_length(max_of(_len,_mleaf_->length()));\
0497               _mleaf_->set_max(max_of(_mx,_mleaf_->get_max()));\
0498               set_done = true;\
0499             }}
0500 
0501     if(m_row_wise) {
0502       if(!m_row_wise_branch) return false;
0503 
0504       tools_vforcit(base_leaf*,m_row_wise_branch->leaves(),mit) {
0505         base_leaf* _mleaf = *mit;
0506 
0507         bool set_done = false;
0508 
0509         TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(char)
0510         TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(short)
0511         TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(int)
0512         TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(float)
0513         TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX(double)
0514 
0515         TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(char)
0516         TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(short)
0517         TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(int)
0518         TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(float)
0519         TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX(double)
0520 
0521         TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LENGTH_MAX
0522 
0523         if(!set_done) {
0524           m_out << "tools::wroot::ntuple::mpi_end_fill :"
0525                 << " leaf " << _mleaf->name() << " with cid " << _mleaf->id_cls() << " not treated." << std::endl;
0526           return false;
0527         }
0528       }
0529 
0530     } else { // column wise :
0531       tools_vforcit(wroot::icol*,m_cols,it) {
0532         base_leaf* _mleaf = (*it)->get_leaf();
0533 
0534         bool set_done = false;
0535         TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LENGTH_MAX
0536 
0537         if(!set_done) {
0538           uint32 _len;
0539           if(!a_impi.unpack(_len)) return false;
0540           int _mx;
0541           if(!a_impi.unpack(_mx)) return false;
0542         }
0543       }
0544     }
0545 
0546 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_LENGTH_MAX
0547 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_STD_VECTOR_LENGTH_MAX
0548 #undef TOOLS_WROOT_NTUPLE_SET_LEAF_STRING_LENGTH_MAX
0549 
0550     return true;
0551   }
0552 
0553 protected:
0554   std::vector<icol*> m_cols;
0555   bool m_row_wise;
0556   branch* m_row_wise_branch; //used if row_wise.
0557 };
0558 
0559 }}
0560 
0561 #endif