Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/aida_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_aida_ntuple
0005 #define tools_aida_ntuple
0006 
0007 // An in memory ntuple able to have "sub ntuple" on a column.
0008 // It is used in ioda to read ntuples in XML/AIDA files.
0009 
0010 #ifdef TOOLS_MEM
0011 #include "mem"
0012 #endif
0013 
0014 #include "vmanip"
0015 #include "vfind"
0016 #include "typedefs"
0017 #include "scast"
0018 #include "forit"
0019 #include "ntuple_binding"
0020 #include "mnmx"
0021 
0022 #include <string>
0023 #include <vector>
0024 #include <ostream>
0025 
0026 namespace tools {
0027 namespace aida {
0028 
0029 class base_col {
0030 public:
0031   static const std::string& s_class() {
0032     static const std::string s_v("tools::aida::base_col");
0033     return s_v;
0034   }
0035   virtual void* cast(const std::string& a_class) const {
0036     if(void* p = cmp_cast<base_col>(this,a_class)) {return p;}
0037     return 0;
0038   }
0039 public:
0040   virtual base_col* copy() const = 0;
0041   virtual uint64 num_elems() const = 0;
0042   virtual bool add() = 0;
0043   virtual bool reset() = 0;
0044   //binded column reading API :
0045   virtual bool fetch_entry() const = 0;
0046   virtual void set_user_variable(void*) = 0;
0047 protected:
0048   base_col(std::ostream& a_out,const std::string& a_name)
0049   :m_out(a_out)
0050   ,m_name(a_name),m_index(0){
0051 #ifdef TOOLS_MEM
0052     mem::increment(s_class().c_str());
0053 #endif
0054   }
0055 public:
0056   virtual ~base_col(){
0057 #ifdef TOOLS_MEM
0058     mem::decrement(s_class().c_str());
0059 #endif
0060   }
0061 protected:
0062   base_col(const base_col& a_from)
0063   :m_out(a_from.m_out)
0064   ,m_name(a_from.m_name)
0065   ,m_index(a_from.m_index){
0066 #ifdef TOOLS_MEM
0067     mem::increment(s_class().c_str());
0068 #endif
0069   }
0070   base_col& operator=(const base_col& a_from){
0071     m_name = a_from.m_name;
0072     m_index = a_from.m_index;
0073     return *this;
0074   }
0075 public:
0076   const std::string& name() const {return m_name;}
0077 
0078   void set_index(uint64 a_index){m_index = a_index;}
0079 protected:
0080   std::ostream& m_out;
0081   std::string m_name;
0082   uint64 m_index;
0083 };
0084 
0085 class base_ntu {
0086 public:
0087   static const std::string& s_class() {
0088     static const std::string s_v("tools::aida::base_ntu");
0089     return s_v;
0090   }
0091   virtual void* cast(const std::string& a_class) const {
0092     if(void* p = cmp_cast<base_ntu>(this,a_class)) {return p;}
0093     return 0;
0094   }
0095 protected:
0096   base_ntu(std::ostream& a_out,const std::string& a_title)
0097   :m_out(a_out),m_title(a_title),m_index(-1){
0098 #ifdef TOOLS_MEM
0099     mem::increment(s_class().c_str());
0100 #endif
0101   }
0102   virtual ~base_ntu() {
0103     clear();
0104 #ifdef TOOLS_MEM
0105     mem::decrement(s_class().c_str());
0106 #endif
0107   }
0108 protected:
0109   base_ntu(const base_ntu& a_from)
0110   :m_out(a_from.m_out)
0111   ,m_title(a_from.m_title),m_index(a_from.m_index)
0112   {
0113 #ifdef TOOLS_MEM
0114     mem::increment(s_class().c_str());
0115 #endif
0116     tools_vforcit(base_col*,a_from.m_cols,it) {
0117       base_col* column = (*it)->copy();
0118       if(!column) {
0119         m_out << s_class() << "::cstor :"
0120               << " can't copy column."
0121               << std::endl;
0122         safe_clear<base_col>(m_cols);
0123         m_index = -1;
0124         return; //throw
0125       }
0126       m_cols.push_back(column);
0127     }
0128   }
0129   base_ntu& operator=(const base_ntu& a_from){
0130     if(&a_from==this) return *this;
0131 
0132     safe_clear<base_col>(m_cols);
0133     m_index = a_from.m_index;
0134 
0135     m_title = a_from.m_title;
0136     tools_vforcit(base_col*,a_from.m_cols,it) {
0137       base_col* column = (*it)->copy();
0138       if(!column) {
0139         m_out << s_class() << "::operator=() :"
0140               << " can't copy column."
0141               << std::endl;
0142         safe_clear<base_col>(m_cols);
0143         m_index = -1;
0144         return *this;
0145       }
0146       m_cols.push_back(column);
0147     }
0148 
0149     return *this;
0150   }
0151 public:
0152   std::ostream& out() const {return m_out;}
0153   const std::vector<base_col*>& columns() const {return m_cols;}
0154   size_t number_of_columns() const {return m_cols.size();}
0155 
0156 #ifdef tools_aida_ntuple
0157   const std::vector<base_col*>& cols() const {return m_cols;} //deprecated : use columns().
0158 #endif
0159 
0160   void column_names(std::vector<std::string>& a_names) const {
0161     a_names.clear();
0162     tools_vforcit(base_col*,m_cols,it) a_names.push_back((*it)->name());
0163   }
0164 
0165   const std::string& title() const {return m_title;}
0166   void set_title(const std::string& a_title) {m_title = a_title;}
0167 
0168   uint64 rows() const {
0169     if(m_cols.empty()) return 0;
0170     return m_cols.front()->num_elems();
0171   }
0172   bool number_of_entries(uint64& a_value) const {
0173     if(m_cols.empty()) {a_value = 0;return false;}
0174     a_value = m_cols.front()->num_elems();
0175     return true;
0176   }
0177 
0178   void clear() { //must not be confused with reset().
0179     safe_clear<base_col>(m_cols);
0180     m_index = -1;
0181   }
0182 
0183   bool reset() { //clear data in columns (but not the column set)
0184     bool status = true;
0185     tools_vforit(base_col*,m_cols,it) {
0186       if(!(*it)->reset()) status = false;
0187     }
0188     m_index = -1;
0189     return status;
0190   }
0191 
0192   // reading :
0193   void start() {m_index = -1;set_columns_index(0);}
0194   bool next() {
0195     // a tuple loop is of the form :
0196     //  tuple.start();
0197     //  while(tuple.next()) {
0198     //    ...
0199     //    double v;
0200     //    if(!col->get_entry(v)) {}
0201     //    ...
0202     //  }
0203     if((m_index+1)>=(int64)rows()) return false;
0204     m_index++;
0205     set_columns_index(m_index);
0206     return true;
0207   }
0208   int64 row_index() const {return m_index;}
0209 
0210   // filling :
0211   bool add_row() {
0212     bool status = true;
0213     tools_vforit(base_col*,m_cols,it) {
0214       if(!(*it)->add()) status = false;
0215     }
0216     return status;
0217   }
0218 public:
0219   base_col* find_column(const std::string& a_name){
0220     return find_named<base_col>(m_cols,a_name);
0221   }
0222 
0223   void add_column(base_col* a_col) { //we take ownership.
0224     m_cols.push_back(a_col);
0225   }
0226 
0227 protected:
0228   void set_columns_index(uint64 a_index) {
0229     tools_vforit(base_col*,m_cols,it) {
0230       (*it)->set_index(a_index);
0231     }
0232   }
0233 protected:
0234   std::ostream& m_out;
0235   std::string m_title;
0236   int64 m_index;
0237   std::vector<base_col*> m_cols;
0238 };
0239 
0240 }}
0241 
0242 #include "tos"
0243 #include "sto"
0244 #include "columns"
0245 #include "stype"
0246 
0247 namespace tools {
0248 namespace aida {
0249 
0250 //inline const std::string& s_aida_type(char) {
0251 //  static const std::string s_v("char");
0252 //  return s_v;
0253 //}
0254 inline const std::string& s_aida_type(short) {
0255   static const std::string s_v("short");
0256   return s_v;
0257 }
0258 inline const std::string& s_aida_type(int) {
0259   static const std::string s_v("int");
0260   return s_v;
0261 }
0262 inline const std::string& s_aida_type(float) {
0263   static const std::string s_v("float");
0264   return s_v;
0265 }
0266 inline const std::string& s_aida_type(double) {
0267   static const std::string s_v("double");
0268   return s_v;
0269 }
0270 
0271 /////////////////////////////////////////
0272 /////////////////////////////////////////
0273 //inline const std::string& s_aida_type(unsigned char) {
0274 //  static const std::string s_v("byte");
0275 //  return s_v;
0276 //}
0277 
0278 inline const std::string& s_aida_type(bool) {
0279   static const std::string s_v("boolean");
0280   return s_v;
0281 }
0282 inline const std::string& s_aida_type(const std::string&) {
0283   static const std::string s_v("string");
0284   return s_v;
0285 }
0286 inline const std::string& s_aida_type(int64) {
0287   static const std::string s_v("long");
0288   return s_v;
0289 }
0290 /*
0291 inline const std::string& s_aida_type(const std::vector<double>&) {
0292   static const std::string s_v("double[]");
0293   return s_v;
0294 }
0295 */
0296 inline const std::string& s_aida_type_ituple() {
0297   static const std::string s_v("ITuple");
0298   return s_v;
0299 }
0300 
0301 /////////////////////////////////////////
0302 /// not AIDA ! //////////////////////////
0303 /////////////////////////////////////////
0304 inline const std::string& s_aida_type(unsigned short) {
0305   static const std::string s_v("ushort");
0306   return s_v;
0307 }
0308 inline const std::string& s_aida_type(unsigned int) {
0309   static const std::string s_v("uint");
0310   return s_v;
0311 }
0312 inline const std::string& s_aida_type(uint64) {
0313   static const std::string s_v("ulong");
0314   return s_v;
0315 }
0316 
0317 class aida_base_col : public base_col {
0318 public:
0319   static const std::string& s_class() {
0320     static const std::string s_v("tools::aida::aida_base_col");
0321     return s_v;
0322   }
0323   virtual void* cast(const std::string& a_class) const {
0324     if(void* p = cmp_cast<aida_base_col>(this,a_class)) {return p;}
0325     return base_col::cast(a_class);
0326   }
0327 public:
0328   virtual const std::string& aida_type() const = 0;
0329   virtual bool s_default_value(std::string&) const = 0;
0330   virtual bool s_value(std::string&) const = 0;
0331   virtual bool s_fill(const std::string&) = 0;
0332 public:
0333   aida_base_col(std::ostream& a_out,const std::string& a_name)
0334   :base_col(a_out,a_name){}
0335 public:
0336   virtual ~aida_base_col(){}
0337 public:
0338   aida_base_col(const aida_base_col& a_from)
0339   :base_col(a_from)
0340   {}
0341   aida_base_col& operator=(const aida_base_col& a_from){
0342     base_col::operator=(a_from);
0343     return *this;
0344   }
0345 };
0346 
0347 inline bool s__fill(const std::string& a_s,std::string& a_v) {
0348   a_v = a_s;
0349   return true;
0350 }
0351 inline bool s__fill(const std::string& a_s,char& a_v) {
0352   //for exlib/cbk/aida_ntu
0353   if(a_s.empty()) return false;
0354   a_v = a_s[0];
0355   return true;
0356 }
0357 inline bool s__fill(const std::string& a_s,unsigned char& a_v) {
0358   //for exlib/cbk/aida_ntu
0359   if(a_s.empty()) return false;
0360   a_v = a_s[0];
0361   return true;
0362 }
0363 inline bool s__fill(const std::string& a_s,bool& a_v) {
0364   return to(a_s,a_v);
0365 }
0366 inline bool s__fill(const std::string& a_s,short& a_v) {
0367   return to<short>(a_s,a_v);
0368 }
0369 inline bool s__fill(const std::string& a_s,unsigned short& a_v) {
0370   return to<unsigned short>(a_s,a_v);
0371 }
0372 inline bool s__fill(const std::string& a_s,int& a_v) {
0373   return to<int>(a_s,a_v);
0374 }
0375 inline bool s__fill(const std::string& a_s,unsigned int& a_v) {
0376   return to<unsigned int>(a_s,a_v);
0377 }
0378 inline bool s__fill(const std::string& a_s,int64& a_v) {
0379   return to<int64>(a_s,a_v);
0380 }
0381 inline bool s__fill(const std::string& a_s,uint64& a_v) {
0382   return to<uint64>(a_s,a_v);
0383 }
0384 inline bool s__fill(const std::string& a_s,float& a_v) {
0385   return to<float>(a_s,a_v);
0386 }
0387 inline bool s__fill(const std::string& a_s,double& a_v) {
0388   return to<double>(a_s,a_v);
0389 }
0390 
0391 template <class T>
0392 class aida_col : public aida_base_col {
0393 public:
0394   typedef T entry_t;
0395 public:
0396   static const std::string& s_class() {
0397     static const std::string s_v("tools::aida::aida_col<"+stype(T())+">");
0398     return s_v;
0399   }
0400   virtual void* cast(const std::string& a_class) const {
0401     if(void* p = cmp_cast< aida_col<T> >(this,a_class)) {return p;}
0402     return aida_base_col::cast(a_class);
0403   }
0404 public:
0405   virtual base_col* copy() const {return new aida_col(*this);}
0406   virtual bool add() {m_data.push_back(m_tmp);m_tmp = m_default;return true;}
0407   virtual bool reset() {
0408     m_data.clear();
0409     m_index = 0;
0410     m_tmp = m_default;
0411     return true;
0412   }
0413   virtual uint64 num_elems() const {return m_data.size();}
0414 public:
0415   virtual const std::string& aida_type() const {return s_aida_type(T());}
0416   virtual bool s_default_value(std::string& a_s) const {
0417     a_s = tos(m_default);
0418     return true;
0419   }
0420   virtual bool s_value(std::string& a_s) const {
0421     typedef typename std::vector<T>::size_type sz_t;
0422     a_s = tos(m_data[sz_t(m_index)]);
0423     return true;
0424   }
0425 
0426   // for exlib/raxml/tuple :
0427   virtual bool s_fill(const std::string& a_s) {
0428     //if(!to<T>(a_s,m_tmp)) {
0429     if(!s__fill(a_s,m_tmp)) {
0430       m_out << s_class() << "::fill :"
0431             << " can't convert " << sout(a_s) << "."
0432             << std::endl;
0433       return false;
0434     }
0435     return true;
0436   }
0437 
0438   virtual void set_user_variable(void* a_user_var) {m_user_var = (T*)a_user_var;} //not owner.
0439 public:
0440   aida_col(std::ostream& a_out,const std::string& a_name,const T& a_def)
0441   :aida_base_col(a_out,a_name)
0442   ,m_default(a_def)
0443   ,m_tmp(a_def)
0444   ,m_user_var(0) //not owner
0445   {}
0446 public:
0447   virtual ~aida_col(){}
0448 public:
0449   aida_col(const aida_col& a_from)
0450   :aida_base_col(a_from)
0451   ,m_data(a_from.m_data)
0452   ,m_default(a_from.m_default)
0453   ,m_tmp(a_from.m_tmp)
0454   ,m_user_var(a_from.m_user_var)
0455   {}
0456   aida_col& operator=(const aida_col& a_from){
0457     aida_base_col::operator=(a_from);
0458     if(&a_from==this) return *this;
0459     m_data = a_from.m_data;
0460     m_default = a_from.m_default;
0461     m_tmp = a_from.m_tmp;
0462     m_user_var = a_from.m_user_var;
0463     return *this;
0464   }
0465 public:
0466   bool fill(const T& a_value) {m_tmp = a_value;return true;}
0467   bool get_entry(T& a_v) const {
0468     if(m_index>=m_data.size()) {
0469       m_out << s_class() << "::get_entry :"
0470             << " bad index " << m_index
0471             << ". Vec size is " << m_data.size() << "."
0472             << "."
0473             << std::endl;
0474       a_v = T();
0475       return false;
0476     }
0477     typedef typename std::vector<T>::size_type sz_t;
0478     a_v = m_data[sz_t(m_index)];
0479     return true;
0480   }
0481   virtual bool fetch_entry() const {
0482     //NOTE : it is ok to have a NULL m_user_var.
0483     if(m_index>=m_data.size()) {
0484       m_out << s_class() << "::get_entry :"
0485             << " bad index " << m_index
0486             << ". Vec size is " << m_data.size() << "."
0487             << "."
0488             << std::endl;
0489       if(m_user_var) *m_user_var = T();
0490       return false;
0491     }
0492     typedef typename std::vector<T>::size_type sz_t;
0493     if(m_user_var) *m_user_var = m_data[sz_t(m_index)];
0494     return true;
0495   }
0496 protected:
0497   std::vector<T> m_data;
0498   T m_default;
0499   T m_tmp;
0500   T* m_user_var;
0501 };
0502 
0503 class ntuple : public base_ntu {
0504 public:
0505   static cid id_class() {return 2000;} //for ntuple_binding.
0506 public:
0507   static const std::string& s_class() {
0508     static const std::string s_v("tools::aida::ntuple");
0509     return s_v;
0510   }
0511   virtual void* cast(const std::string& a_class) const {
0512     if(void* p = cmp_cast<ntuple>(this,a_class)) {return p;}
0513     return base_ntu::cast(a_class);
0514   }
0515   virtual const std::string& s_cls() const {return s_class();}
0516 public:
0517   ntuple(std::ostream& a_out,const std::string& a_title)
0518   :base_ntu(a_out,a_title)
0519   {}
0520   virtual ~ntuple() {}
0521 public:
0522   ntuple(const ntuple& a_from): base_ntu(a_from){}
0523   ntuple& operator=(const ntuple& a_from){
0524     base_ntu::operator=(a_from);
0525     return *this;
0526   }
0527 public:
0528   template <class T>
0529   aida_col<T>* create_col(const std::string& a_name,const T& a_def = T()) {
0530     if(find_named<base_col>(m_cols,a_name)) {
0531       m_out << s_class() << "::create_col :"
0532             << " a column with name " << sout(a_name) << " already exists."
0533             << std::endl;
0534       return 0;
0535     }
0536     aida_col<T>* col = new aida_col<T>(m_out,a_name,a_def);
0537     if(!col) {
0538       m_out << s_class() << "::create_col :"
0539             << " can't create aida_col<T> " << sout(a_name) << "."
0540             << std::endl;
0541       return 0;
0542     }
0543     m_cols.push_back(col);
0544     return col;
0545   }
0546 
0547   template <class T>
0548   aida_col<T>* find_column(const std::string& a_name){
0549     base_col* col = find_named<base_col>(m_cols,a_name);
0550     if(!col) return 0;
0551     return safe_cast<base_col, aida_col<T> >(*col);
0552   }
0553 
0554   template <class T>
0555   bool find_column(const std::string& a_name,aida_col<T>*& a_col,bool a_case_sensitive = true) { //for exlib::evaluator.
0556     base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
0557     if(!col) {a_col = 0;return false;}
0558     a_col = safe_cast<base_col, aida_col<T> >(*col);
0559     return a_col?true:false;
0560   }
0561 
0562   aida_base_col* find_aida_base_column(const std::string& a_name,bool a_case_sensitive = true){ //for opaw/panntu.
0563     base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
0564     if(!col) return 0;
0565     return safe_cast<base_col,aida_base_col>(*col);
0566   }
0567 
0568   bool get_row() const {
0569     bool status = true;
0570     tools_vforcit(base_col*,m_cols,it) {
0571       if(!(*it)->fetch_entry()) status = false;
0572     }
0573     return status;
0574   }
0575 
0576   bool set_binding(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
0577     tools_vforcit(column_binding,a_bd.columns(),itb) {
0578       bool found = false;
0579       tools_vforcit(base_col*,m_cols,itc) {
0580         if((*itc)->name()==(*itb).name()) {
0581           (*itc)->set_user_variable((*itb).user_obj());
0582           found = true;
0583         }
0584       }
0585       if(!found) {
0586         a_out << "tools::aida::ntuple :"
0587               << " binding name " << sout((*itb).name()) << " does not match any ntuple column."
0588               << std::endl;
0589         return false;
0590       }
0591     }
0592     return true;
0593   }
0594 
0595   template <class T>
0596   bool column_min(unsigned int a_col,T& a_value) {
0597     a_value = T();
0598     if(m_cols.empty()) return false;
0599     if(a_col>=m_cols.size()) return false;
0600     base_col* _base_col = m_cols[a_col];
0601     aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
0602     if(!_col) return false;
0603     start();
0604     uint64 _rows = rows();
0605     T v;
0606    {for(uint64 row=0;row<_rows;row++) {
0607       if(!next()) {a_value = T();return false;}
0608       if(!_col->get_entry(v)) {}
0609       if(!row) {
0610         a_value = v;
0611       } else {
0612         a_value = mn<T>(a_value,v);
0613       }
0614     }}
0615     return true;
0616   }
0617 
0618   template <class T>
0619   bool column_max(unsigned int a_col,T& a_value) {
0620     a_value = T();
0621     if(m_cols.empty()) return false;
0622     if(a_col>=m_cols.size()) return false;
0623     base_col* _base_col = m_cols[a_col];
0624     aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
0625     if(!_col) return false;
0626     start();
0627     uint64 _rows = rows();
0628     T v;
0629    {for(uint64 row=0;row<_rows;row++) {
0630       if(!next()) {a_value = T();return false;}
0631       if(!_col->get_entry(v)) {}
0632       if(!row) {
0633         a_value = v;
0634       } else {
0635         a_value = mx<T>(a_value,v);
0636       }
0637     }}
0638     return true;
0639   }
0640 
0641 };
0642 
0643 ////////////////////////////////////////////////////////////
0644 /// some special column that can't be done with aida_col<T> ////
0645 ////////////////////////////////////////////////////////////
0646 
0647 class aida_col_ntu : public base_col {
0648 public:
0649   static const std::string& s_class() {
0650     static const std::string s_v("tools::aida::aida_col_ntu");
0651     return s_v;
0652   }
0653   virtual void* cast(const std::string& a_class) const {
0654     if(void* p = cmp_cast<aida_col_ntu>(this,a_class)) {return p;}
0655     return base_col::cast(a_class);
0656   }
0657 public:
0658   virtual base_col* copy() const {return new aida_col_ntu(*this);}
0659   virtual bool add() {m_data.push_back(m_tmp);m_tmp.reset();return true;}
0660   virtual bool reset() {m_data.clear();m_index = 0;return true;}
0661   virtual uint64 num_elems() const {return m_data.size();}
0662 public:
0663   base_ntu* get_entry() {
0664     if(m_index>=m_data.size()) {
0665       m_out << s_class() << "::get_entry :"
0666             << " bad index " << m_index
0667             << ". Vec size is " << m_data.size() << "."
0668             << "."
0669             << std::endl;
0670       return 0;
0671     }
0672     typedef std::vector<ntuple>::size_type sz_t;
0673     return &(m_data[sz_t(m_index)]);
0674   }
0675 
0676   virtual void set_user_variable(void* a_user_var) {m_user_var = (ntuple*)a_user_var;} //not owner.
0677   virtual bool fetch_entry() const {
0678     if(m_index>=m_data.size()) {
0679       m_out << s_class() << "::fetch_entry :"
0680             << " bad index " << m_index
0681             << ". Vec size is " << m_data.size() << "."
0682             << "."
0683             << std::endl;
0684       if(m_user_var) *m_user_var = ntuple(m_out,"");
0685       return false;
0686     }
0687     typedef std::vector<ntuple>::size_type sz_t;
0688     if(m_user_var) *m_user_var = m_data[sz_t(m_index)];
0689     return true;
0690   }
0691 
0692   virtual base_ntu* get_to_fill() {return &m_tmp;}
0693 public:
0694   aida_col_ntu(std::ostream& a_out,const std::string& a_name)
0695   :base_col(a_out,a_name)
0696   ,m_tmp(a_out,"tmp")
0697   ,m_user_var(0) //not owner
0698   {}
0699 public:
0700   virtual ~aida_col_ntu(){}
0701 public:
0702   aida_col_ntu(const aida_col_ntu& a_from)
0703   :base_col(a_from)
0704   ,m_data(a_from.m_data)
0705 
0706   ,m_tmp(a_from.m_tmp)
0707   ,m_user_var(a_from.m_user_var)
0708   {}
0709   aida_col_ntu& operator=(const aida_col_ntu& a_from){
0710     base_col::operator=(a_from);
0711     if(&a_from==this) return *this;
0712     m_data = a_from.m_data;
0713 
0714     m_tmp = a_from.m_tmp;
0715     m_user_var = a_from.m_user_var;
0716     return *this;
0717   }
0718 protected:
0719   std::vector<ntuple> m_data;
0720   ntuple m_tmp;
0721   ntuple* m_user_var;
0722 };
0723 
0724 inline bool create_cols_from_vals(ntuple& a_ntu,
0725                                   const std::vector<value>& a_vars,
0726                                   bool a_verbose = false){
0727   tools_vforcit(value,a_vars,it) {
0728       if((*it).type()==value::VOID_STAR) {
0729         if(a_verbose){
0730           a_ntu.out() << "tools::aida::create_cols_from_vals :"
0731                       << " ITuple : " << (*it).label() << " : begin "
0732                       << std::endl;
0733         }
0734         std::vector<value>* vars = (std::vector<value>*)(*it).get_void_star();
0735 
0736         aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),(*it).label());
0737         // create sub columns on the "fillable" of col_ntu :
0738         base_ntu* sub_base_ntu = col_ntu->get_to_fill();
0739         if(!sub_base_ntu) {
0740           delete col_ntu;
0741           return false;
0742         }
0743         ntuple* sub_aida = safe_cast<base_ntu,ntuple>(*sub_base_ntu);
0744         if(!sub_aida) {
0745           delete col_ntu;
0746           return false;
0747         }
0748 
0749         if(!create_cols_from_vals(*sub_aida,*vars,a_verbose)) {
0750           delete col_ntu;
0751           return false;
0752         }
0753 
0754         a_ntu.add_column(col_ntu);
0755 
0756     } else {
0757         if(a_verbose){
0758           std::string stype;
0759           (*it).s_type(stype);
0760           std::string sval;
0761           (*it).tos(sval);
0762           a_ntu.out() << "tools::aida::create_cols_from_vals :"
0763                       << " " << stype << " : "
0764                       << (*it).label() << " : "
0765                       << sval
0766                       << std::endl;
0767         }
0768 
0769         //   char,short,int,float,double
0770         //   byte,boolean,string,long(for int64)
0771         //   double[]
0772 
0773         base_col* col = 0;
0774       /*if((*it).type()==value::CHAR) {
0775           col = a_ntu.create_col<char>((*it).label(),(*it).get_char());
0776         } else*/ if((*it).type()==value::SHORT) {
0777           col = a_ntu.create_col<short>((*it).label(),(*it).get_short());
0778         } else if((*it).type()==value::INT) {
0779           col = a_ntu.create_col<int>((*it).label(),(*it).get_int());
0780         } else if((*it).type()==value::INT64) {
0781           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
0782         } else if((*it).type()==value::FLOAT) {
0783           col = a_ntu.create_col<float>((*it).label(),(*it).get_float());
0784         } else if((*it).type()==value::DOUBLE) {
0785           col = a_ntu.create_col<double>((*it).label(),(*it).get_double());
0786 
0787         //} else if((*it).type()==value::UNSIGNED_CHAR) {
0788         //  col = a_ntu.create_col<unsigned char>((*it).label(),(*it).get_unsigned_char());
0789         } else if((*it).type()==value::UNSIGNED_SHORT) {
0790           col = a_ntu.create_col<unsigned short>((*it).label(),(*it).get_unsigned_short());
0791         } else if((*it).type()==value::UNSIGNED_INT) {
0792           col = a_ntu.create_col<unsigned int>((*it).label(),(*it).get_unsigned_int());
0793         } else if((*it).type()==value::UNSIGNED_INT64) {
0794           col = a_ntu.create_col<uint64>((*it).label(),(*it).get_unsigned_int64());
0795 
0796         } else if((*it).type()==value::BOOL) {
0797           col = a_ntu.create_col<bool>((*it).label(),(*it).get_bool());
0798         } else if((*it).type()==value::STRING) {
0799           col = a_ntu.create_col<std::string>((*it).label(),(*it).get_string());
0800         } else if((*it).type()==value::INT64) {
0801           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
0802         }
0803 
0804         if(!col) {
0805           std::string stype;
0806           (*it).s_type(stype);
0807           std::string sval;
0808           (*it).tos(sval);
0809           a_ntu.out() << "tools::aida::create_cols_from_vals :"
0810                       << " failed for " << stype << " : "
0811                       << (*it).label() << " : "
0812                       << sval
0813                       << std::endl;
0814           return false;
0815         }
0816       }
0817   }
0818   return true;
0819 }
0820 
0821 // for raxml :
0822 inline bool create_col(ntuple& a_ntu,
0823                        const std::string& a_type,
0824                        const std::string& a_name,
0825                        const std::string& a_s, //def or booking.
0826                        bool a_is_ntu){
0827 /*
0828   if(a_type==s_aida_type((char)0)) {
0829     char v = 0;
0830     if(a_s.size()&&!to<char>(a_s,v)) {
0831       a_ntu.out() << "tools::aida::create_col :"
0832                   << " can't convert def " << sout(a_s)
0833                   << " to a " << a_type
0834                   << std::endl;
0835       return false;
0836     }
0837     if(!a_ntu.create_col<char>(a_name,v)) {
0838       a_ntu.out() << "tools::aida::create_col :"
0839                   << " can't create column of type " << sout(a_type)
0840                   << std::endl;
0841       return false;
0842     }
0843 
0844   } else*/ if(a_type==s_aida_type((short)0)) {
0845     short v = 0;
0846     if(a_s.size()&&!to<short>(a_s,v)) {
0847       a_ntu.out() << "tools::aida::create_col :"
0848                   << " can't convert def " << sout(a_s)
0849                   << " to a " << a_type
0850                   << std::endl;
0851       return false;
0852     }
0853     if(!a_ntu.create_col<short>(a_name,v)) {
0854       a_ntu.out() << "tools::aida::create_col :"
0855                   << " can't create column of type " << sout(a_type)
0856                   << std::endl;
0857       return false;
0858     }
0859 
0860   } else if(a_type==s_aida_type((int)0)) {
0861     int v = 0;
0862     if(a_s.size()&&!to<int>(a_s,v)) {
0863       a_ntu.out() << "tools::aida::create_col :"
0864                   << " can't convert def " << sout(a_s)
0865                   << " to a " << a_type
0866                   << std::endl;
0867       return false;
0868     }
0869     if(!a_ntu.create_col<int>(a_name,v)) {
0870       a_ntu.out() << "tools::aida::create_col :"
0871                   << " can't create column of type " << sout(a_type)
0872                   << std::endl;
0873       return false;
0874     }
0875 
0876   } else if(a_type==s_aida_type((int64)0)) {
0877     int64 v = 0;
0878     if(a_s.size()&&!to<int64>(a_s,v)) {
0879       a_ntu.out() << "tools::aida::create_col :"
0880                   << " can't convert def " << sout(a_s)
0881                   << " to a " << a_type
0882                   << std::endl;
0883       return false;
0884     }
0885     if(!a_ntu.create_col<int64>(a_name,v)) {
0886       a_ntu.out() << "tools::aida::create_col :"
0887                   << " can't create column of type " << sout(a_type)
0888                   << std::endl;
0889       return false;
0890     }
0891 
0892   } else if(a_type==s_aida_type((float)0)) {
0893     float v = 0;
0894     if(a_s.size()&&!to<float>(a_s,v)) {
0895       a_ntu.out() << "tools::aida::create_col :"
0896                   << " can't convert def " << sout(a_s)
0897                   << " to a " << a_type
0898                   << std::endl;
0899       return false;
0900     }
0901     if(!a_ntu.create_col<float>(a_name,v)) {
0902       a_ntu.out() << "tools::aida::create_col :"
0903                   << " can't create column of type " << sout(a_type)
0904                   << std::endl;
0905       return false;
0906     }
0907 
0908 
0909   } else if(a_type==s_aida_type((double)0)) {
0910     double v = 0;
0911     if(a_s.size()&&!to<double>(a_s,v)) {
0912       a_ntu.out() << "tools::aida::create_col :"
0913                   << " can't convert def " << sout(a_s)
0914                   << " to a " << a_type
0915                   << std::endl;
0916       return false;
0917     }
0918     if(!a_ntu.create_col<double>(a_name,v)) {
0919       a_ntu.out() << "tools::aida::create_col :"
0920                   << " can't create column of type " << sout(a_type)
0921                   << std::endl;
0922       return false;
0923     }
0924 
0925 /*  } else if(a_type==s_aida_type((unsigned char)0)) { //byte
0926     unsigned int v = 0;
0927     if(a_s.size()&&!to<unsigned int>(a_s,v)) {
0928       a_ntu.out() << "tools::aida::create_col :"
0929                   << " can't convert def " << sout(a_s)
0930                   << " to a " << a_type
0931                   << std::endl;
0932       return false;
0933     }
0934     if(v>=256) {
0935       a_ntu.out() << "tools::aida::create_col :"
0936                   << " can't convert def " << sout(a_s)
0937                   << " to byte."
0938                   << std::endl;
0939       return false;
0940     }
0941     if(!a_ntu.create_col<unsigned char>(a_name,v)) {
0942       a_ntu.out() << "tools::aida::create_col :"
0943                   << " can't create column of type " << sout(a_type)
0944                   << std::endl;
0945       return false;
0946     }
0947 */
0948   } else if(a_type==s_aida_type((unsigned short)0)) {
0949     unsigned short v = 0;
0950     if(a_s.size()&&!to<unsigned short>(a_s,v)) {
0951       a_ntu.out() << "tools::aida::create_col :"
0952                   << " can't convert def " << sout(a_s)
0953                   << " to a " << a_type
0954                   << std::endl;
0955       return false;
0956     }
0957     if(!a_ntu.create_col<unsigned short>(a_name,v)) {
0958       a_ntu.out() << "tools::aida::create_col :"
0959                   << " can't create column of type " << sout(a_type)
0960                   << std::endl;
0961       return false;
0962     }
0963 
0964   } else if(a_type==s_aida_type((unsigned int)0)) {
0965     unsigned int v = 0;
0966     if(a_s.size()&&!to<unsigned int>(a_s,v)) {
0967       a_ntu.out() << "tools::aida::create_col :"
0968                   << " can't convert def " << sout(a_s)
0969                   << " to a " << a_type
0970                   << std::endl;
0971       return false;
0972     }
0973     if(!a_ntu.create_col<unsigned int>(a_name,v)) {
0974       a_ntu.out() << "tools::aida::create_col :"
0975                   << " can't create column of type " << sout(a_type)
0976                   << std::endl;
0977       return false;
0978     }
0979 
0980   } else if(a_type==s_aida_type((uint64)0)) {
0981     uint64 v = 0;
0982     if(a_s.size()&&!to<uint64>(a_s,v)) {
0983       a_ntu.out() << "tools::aida::create_col :"
0984                   << " can't convert def " << sout(a_s)
0985                   << " to a " << a_type
0986                   << std::endl;
0987       return false;
0988     }
0989     if(!a_ntu.create_col<uint64>(a_name,v)) {
0990       a_ntu.out() << "tools::aida::create_col :"
0991                   << " can't create column of type " << sout(a_type)
0992                   << std::endl;
0993       return false;
0994     }
0995 
0996   /////////////////////////////////////////
0997   /////////////////////////////////////////
0998   } else if(a_type==s_aida_type((bool)true)) {
0999     bool v = false;
1000     if(a_s.size()&&!to(a_s,v)) {
1001       a_ntu.out() << "tools::aida::create_col :"
1002                   << " can't convert def " << sout(a_s)
1003                   << " to a " << a_type
1004                   << std::endl;
1005       return false;
1006     }
1007     if(!a_ntu.create_col<bool>(a_name,v)) {
1008       a_ntu.out() << "tools::aida::create_col :"
1009                   << " can't create column of type " << sout(a_type)
1010                   << std::endl;
1011       return false;
1012     }
1013 
1014   } else if(a_type==s_aida_type(std::string())) {
1015     if(!a_ntu.create_col<std::string>(a_name,a_s)) {
1016       a_ntu.out() << "tools::aida::create_col :"
1017                   << " can't create column of type " << sout(a_type)
1018                   << std::endl;
1019       return false;
1020     }
1021 
1022   } else if(a_type==s_aida_type((int64)0)) {
1023     int64 v = 0;
1024     if(a_s.size()&&!to<int64>(a_s,v)) {
1025       a_ntu.out() << "tools::aida::create_col :"
1026                   << " can't convert def " << sout(a_s)
1027                   << " to a " << a_type
1028                   << std::endl;
1029       return false;
1030     }
1031     if(!a_ntu.create_col<int64>(a_name,v)) {
1032       a_ntu.out() << "tools::aida::create_col :"
1033                   << " can't create column of type " << sout(a_type)
1034                   << std::endl;
1035       return false;
1036     }
1037 
1038   } else if(a_type==s_aida_type_ituple()) {
1039     // we expect a booking string on a_s.
1040 
1041     if(!a_is_ntu) {
1042       a_ntu.out() << "tools::aida::create_col :"
1043                   << " mismatch a_is_ntu/a_type."
1044                   << std::endl;
1045       return false;
1046     }
1047     if(a_s.empty()) {
1048       a_ntu.out() << "tools::aida::create_col :"
1049                   << " empty booking string."
1050                   << std::endl;
1051       return false;
1052     }
1053 
1054     columns::finder f(a_ntu.out(),a_s);
1055     if(!f.find_variables()) {
1056       a_ntu.out() << "tools::aida::create_col :"
1057             << " find_variables() failed for " << sout(a_s) << "."
1058             << std::endl;
1059       return false;
1060     }
1061 
1062     aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),a_name);
1063     //create columns on the fillable.
1064     base_ntu* sub_base_ntu = col_ntu->get_to_fill();
1065     if(!sub_base_ntu) {delete col_ntu;return false;}
1066     ntuple* sub_aida = safe_cast<base_ntu,ntuple>(*sub_base_ntu);
1067     if(!sub_aida) {delete col_ntu;return false;}
1068 
1069     std::vector<value> vars;f.result(vars);
1070     if(!create_cols_from_vals(*sub_aida,vars)) {
1071       columns::delete_columns(vars);
1072       delete col_ntu;
1073       return false;
1074     }
1075     columns::delete_columns(vars);
1076     a_ntu.add_column(col_ntu);
1077 
1078     //FIXME : double[]
1079 
1080   } else {
1081     a_ntu.out() << "tools::aida::create_col :"
1082                 << " col type " << sout(a_type)
1083                 << " not yet handled."
1084                 << std::endl;
1085     return false;
1086   }
1087 
1088   return true;
1089 }
1090 
1091 // for waxml :
1092 inline bool create_cols_from_string(ntuple& a_ntu,
1093                                     const std::string& a_booking,
1094                                     bool a_verbose = false){
1095   a_ntu.clear();
1096   if(a_booking.empty()) {
1097     a_ntu.out() << "tools::aida::create_cols_from_string :"
1098                 << " empty booking string."
1099                 << std::endl;
1100     return false;
1101   }
1102 
1103   columns::finder f(a_ntu.out(),a_booking);
1104   if(!f.find_variables()) {
1105     a_ntu.out() << "tools::aida::create_cols_from_string :"
1106           << " find_variables() failed."
1107           << std::endl;
1108     return false;
1109   }
1110   std::vector<value> vars;f.result(vars);
1111   if(a_verbose) columns::dump_columns(a_ntu.out(),vars);
1112 
1113   if(!create_cols_from_vals(a_ntu,vars)) {
1114     columns::delete_columns(vars);
1115     a_ntu.clear();
1116     return false;
1117   }
1118   columns::delete_columns(vars);
1119   return true;
1120 }
1121 
1122 inline aida_col_ntu* find_col_ntu(ntuple& a_ntu,const std::string& a_name){
1123   base_col* col = find_named<base_col>(a_ntu.columns(),a_name);
1124   if(!col) return 0;
1125   return safe_cast<base_col, aida_col_ntu >(*col);
1126 }
1127 
1128 template <class T>
1129 class base_looper {
1130 public:
1131   static const std::string& s_class() {
1132     static const std::string s_v("tools::aida::base_looper<"+stype(T())+">");
1133     return s_v;
1134   }
1135 protected:
1136   virtual bool action(const T& a_value) = 0; //return false to stop processing.
1137 public:
1138   base_looper(base_ntu& a_ntu,const base_col& a_col)
1139   :m_ntu(a_ntu),m_col(a_col){
1140 #ifdef TOOLS_MEM
1141     mem::increment(s_class().c_str());
1142 #endif
1143   }
1144   virtual ~base_looper(){
1145 #ifdef TOOLS_MEM
1146     mem::decrement(s_class().c_str());
1147 #endif
1148   }
1149 public:
1150   base_looper(const base_looper& a_from)
1151   :m_ntu(a_from.m_ntu),m_col(a_from.m_col){
1152 #ifdef TOOLS_MEM
1153     mem::increment(s_class().c_str());
1154 #endif
1155   }
1156   base_looper& operator=(const base_looper&){return *this;}
1157 public:
1158   bool process() {
1159     std::vector<unsigned int> is;
1160     bool found = false;
1161     if(!find_is(m_ntu,&m_col,is,found)) {
1162       m_ntu.out() << s_class() << "::process :"
1163                   << " find_is failed."
1164                   << std::endl;
1165       return false;
1166     }
1167     if(!found) {
1168       m_ntu.out() << s_class() << "::process :"
1169                   << " find_is : col not found."
1170                   << std::endl;
1171       return false;
1172     }
1173     if(is.empty()) {
1174       m_ntu.out() << s_class() << "::process :"
1175                   << " is vec empty."
1176                   << std::endl;
1177       return false;
1178     }
1179 
1180     bool stop = false;
1181     if(!_looper(m_ntu,is,0,stop)) {
1182       m_ntu.out() << s_class() << "::process :"
1183                   << " _looper failed."
1184                   << std::endl;
1185       return false;
1186     }
1187     return true;
1188   }
1189 protected:
1190   static bool find_is(const base_ntu& a_ntu,const base_col* a_col,
1191                              std::vector<unsigned int>& a_is,
1192                              bool& a_found){
1193     // search the indices to reach the sub leaf a_col from the main a_ntu.
1194     // Note : it is assumed that a_is is empty and a_found = false before
1195     //        calling with function.
1196 
1197     const std::vector<base_col*>& cols = a_ntu.columns();
1198 
1199     // look if a_col is a leaf col of a_ntu :
1200    {unsigned int index = 0;
1201     tools_vforcit(base_col*,cols,it) {
1202       if(*it==a_col) {
1203         a_is.push_back(index); //leaf index is the last one in a_is.
1204         a_found = true;
1205         return true;
1206       }
1207       index++;
1208     }}
1209 
1210     // go down sub ntu :
1211    {unsigned int index = 0;
1212     tools_vforcit(base_col*,cols,it) {
1213       aida_col_ntu* col = safe_cast<base_col,aida_col_ntu>(*(*it));
1214       if(col) {
1215         base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
1216         if(!sub) {a_is.clear();return false;}
1217         a_is.push_back(index);
1218         if(!find_is(*sub,a_col,a_is,a_found)) {a_is.clear();return false;}
1219         if(a_found) return true;
1220         a_is.pop_back();
1221       }
1222       index++;
1223     }}
1224     return true;
1225   }
1226 protected:
1227   bool _looper(base_ntu& a_sub,
1228                       const std::vector<unsigned int>& a_is,
1229                       unsigned int a_depth,
1230                       bool& a_stop) {
1231     if(a_depth>=a_is.size()) return false;
1232 
1233     unsigned int coli = a_is[a_depth];
1234     const std::vector<base_col*>& cols = a_sub.columns();
1235     if(coli>=cols.size()) return false;
1236 
1237     if(a_depth==(a_is.size()-1)) { //we reach the leaf.
1238       aida_col<T>* col = safe_cast<base_col, aida_col<T> >(*(cols[coli]));
1239       if(!col) return false;
1240       a_sub.start();
1241       while(a_sub.next()) {
1242         T v;
1243         if(!col->get_entry(v)) return false;
1244         if(!action(v)) {a_stop = true;break;}
1245       }
1246     } else {
1247       aida_col_ntu* col = safe_cast<base_col,aida_col_ntu>(*(cols[coli]));
1248       if(!col) return false;
1249       a_sub.start();
1250       while(a_sub.next()) {
1251         base_ntu* ntu = col->get_entry(); //not const.
1252         if(!ntu) return false;
1253         ntu->start();
1254         while(ntu->next()) {
1255           if(!_looper(*ntu,a_is,a_depth+1,a_stop)) return false;
1256           if(a_stop) break;
1257         }
1258       }
1259     }
1260     return true;
1261   }
1262 protected:
1263   base_ntu& m_ntu;
1264   const base_col& m_col;
1265 };
1266 
1267 }}
1268 
1269 #include "mnmx"
1270 
1271 namespace tools {
1272 namespace aida {
1273 
1274 template <class T>
1275 class stat_looper : public base_looper<T> {
1276 protected:
1277   virtual bool action(const T& a_v) {
1278     if(m_first) {
1279       m_mn = a_v;
1280       m_mx = a_v;
1281       m_S = a_v;
1282       m_S2 = a_v*a_v;
1283 
1284       m_first = false;
1285     } else {
1286       m_mn = min_of<T>(m_mn,a_v);
1287       m_mx = max_of<T>(m_mx,a_v);
1288       m_S += a_v;
1289       m_S2 += a_v*a_v;
1290     }
1291     m_counter++;
1292     return true; //continue looping.
1293   }
1294 public:
1295   stat_looper(base_ntu& a_ntu,const base_col& a_col)
1296   :base_looper<T>(a_ntu,a_col)
1297   ,m_first(true)
1298   ,m_mn(T())
1299   ,m_mx(T())
1300   ,m_S(T())
1301   ,m_S2(T())
1302   ,m_counter(0)
1303   {}
1304   virtual ~stat_looper(){}
1305 public:
1306   stat_looper(const stat_looper& a_from)
1307   :base_looper<T>(a_from)
1308   ,m_first(true)
1309   ,m_mn(T())
1310   ,m_mx(T())
1311   ,m_S(T())
1312   ,m_S2(T())
1313   ,m_counter(0)
1314   {}
1315   stat_looper& operator=(const stat_looper& a_from){
1316     base_looper<T>::operator=(a_from);
1317     if(&a_from==this) return *this;
1318     m_first = true;
1319     m_mn = T();
1320     m_mx = T();
1321     m_S = T();
1322     m_S2 = T();
1323     m_counter = 0;
1324     return *this;
1325   }
1326 public:
1327   bool process() {
1328     m_counter = 0;
1329     if(!base_looper<T>::process()) {
1330       m_mn = T();
1331       m_mx = T();
1332       m_S = T();
1333       m_S2 = T();
1334       m_counter = 0;
1335       return false;
1336     }
1337     return true;
1338   }
1339   T mn() const {return m_mn;}
1340   T mx() const {return m_mx;}
1341   T S() const {return m_S;}
1342   T S2() const {return m_S2;}
1343   uint64 counter() const {return m_counter;}
1344 protected:
1345   bool m_first;
1346   T m_mn;
1347   T m_mx;
1348   T m_S;
1349   T m_S2;
1350   uint64 m_counter;
1351 };
1352 
1353 template <class T>
1354 inline bool column_infos(base_ntu& a_ntu,
1355                          base_col& a_col,
1356                          T& a_mn,T& a_mx,T& a_S,T& a_S2,
1357                          uint64& a_count){
1358   stat_looper<T> lpr(a_ntu,a_col);
1359   bool status = lpr.process();
1360   a_mn = lpr.mn();
1361   a_mx = lpr.mx();
1362   a_S = lpr.S();
1363   a_S2 = lpr.S2();
1364   a_count = lpr.counter();
1365   if(!status) return false;
1366   if(!a_count) return false;
1367   return true;
1368 }
1369 
1370 inline base_col* find_leaf_column(const base_ntu& a_ntu,const std::string& a_name){
1371   const std::vector<base_col*>& cols = a_ntu.columns();
1372   tools_vforcit(base_col*,cols,it) {
1373     aida_col_ntu* col = safe_cast<base_col,aida_col_ntu>(*(*it));
1374     if(col) {
1375       base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
1376       if(!sub) return 0;
1377       base_col* fcol = find_leaf_column(*sub,a_name);
1378       if(fcol) return fcol;
1379     } else {
1380       if((*it)->name()==a_name) return *it;
1381     }
1382   }
1383   return 0;
1384 }
1385 
1386 template <class T>
1387 inline bool to_vector(base_ntu& a_ntu,std::vector<double>& a_vec,unsigned int a_col = 0) {
1388   a_vec.clear();
1389   const std::vector<base_col*>& cols = a_ntu.columns();
1390   if(cols.empty()) return false;
1391   if(a_col>=cols.size()) return false;
1392   base_col* _base_col = cols[a_col];
1393   aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
1394   if(!_col) return false;
1395   a_ntu.start();
1396   uint64 _rows = a_ntu.rows();
1397   a_vec.resize(_rows);
1398   T v;
1399  {for(uint64 row=0;row<_rows;row++) {
1400     if(!a_ntu.next()) {a_vec.clear();return false;}
1401     if(!_col->get_entry(v)) {}
1402     a_vec[row] = v;
1403   }}
1404   return true;
1405 }
1406 
1407 template <class T>
1408 inline bool column_min(ntuple& a_ntu,unsigned int a_col,T& a_value) {
1409   return a_ntu.column_min(a_col,a_value);
1410 }
1411 
1412 template <class T>
1413 inline bool column_max(ntuple& a_ntu,unsigned int a_col,T& a_value) {
1414   return a_ntu.column_max(a_col,a_value);
1415 }
1416 
1417 }}
1418 
1419 #endif