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