Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/aida_ntuple

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_aida_ntuple
  5 #define tools_aida_ntuple
  6 
  7 // An in memory ntuple able to have "sub ntuple" on a column.
  8 // It is used in ioda to read ntuples in XML/AIDA files.
  9 
 10 #ifdef TOOLS_MEM
 11 #include "mem"
 12 #endif
 13 
 14 #include "vmanip"
 15 #include "vfind"
 16 #include "typedefs"
 17 #include "scast"
 18 #include "forit"
 19 #include "ntuple_binding"
 20 #include "mnmx"
 21 
 22 #include <string>
 23 #include <vector>
 24 #include <ostream>
 25 
 26 namespace tools {
 27 namespace aida {
 28 
 29 class base_col {
 30 public:
 31   static const std::string& s_class() {
 32     static const std::string s_v("tools::aida::base_col");
 33     return s_v;
 34   }
 35   virtual void* cast(const std::string& a_class) const {
 36     if(void* p = cmp_cast<base_col>(this,a_class)) {return p;}
 37     return 0;
 38   }
 39 public:
 40   virtual base_col* copy() const = 0;
 41   virtual uint64 num_elems() const = 0;
 42   virtual bool add() = 0;
 43   virtual bool reset() = 0;
 44   //binded column reading API :
 45   virtual bool fetch_entry() const = 0;
 46   virtual void set_user_variable(void*) = 0;
 47 protected:
 48   base_col(std::ostream& a_out,const std::string& a_name)
 49   :m_out(a_out)
 50   ,m_name(a_name),m_index(0){
 51 #ifdef TOOLS_MEM
 52     mem::increment(s_class().c_str());
 53 #endif
 54   }
 55 public:
 56   virtual ~base_col(){
 57 #ifdef TOOLS_MEM
 58     mem::decrement(s_class().c_str());
 59 #endif
 60   }
 61 protected:
 62   base_col(const base_col& a_from)
 63   :m_out(a_from.m_out)
 64   ,m_name(a_from.m_name)
 65   ,m_index(a_from.m_index){
 66 #ifdef TOOLS_MEM
 67     mem::increment(s_class().c_str());
 68 #endif
 69   }
 70   base_col& operator=(const base_col& a_from){
 71     m_name = a_from.m_name;
 72     m_index = a_from.m_index;
 73     return *this;
 74   }
 75 public:
 76   const std::string& name() const {return m_name;}
 77 
 78   void set_index(uint64 a_index){m_index = a_index;}
 79 protected:
 80   std::ostream& m_out;
 81   std::string m_name;
 82   uint64 m_index;
 83 };
 84 
 85 class base_ntu {
 86 public:
 87   static const std::string& s_class() {
 88     static const std::string s_v("tools::aida::base_ntu");
 89     return s_v;
 90   }
 91   virtual void* cast(const std::string& a_class) const {
 92     if(void* p = cmp_cast<base_ntu>(this,a_class)) {return p;}
 93     return 0;
 94   }
 95 protected:
 96   base_ntu(std::ostream& a_out,const std::string& a_title)
 97   :m_out(a_out),m_title(a_title),m_index(-1){
 98 #ifdef TOOLS_MEM
 99     mem::increment(s_class().c_str());
100 #endif
101   }
102   virtual ~base_ntu() {
103     clear();
104 #ifdef TOOLS_MEM
105     mem::decrement(s_class().c_str());
106 #endif
107   }
108 protected:
109   base_ntu(const base_ntu& a_from)
110   :m_out(a_from.m_out)
111   ,m_title(a_from.m_title),m_index(a_from.m_index)
112   {
113 #ifdef TOOLS_MEM
114     mem::increment(s_class().c_str());
115 #endif
116     tools_vforcit(base_col*,a_from.m_cols,it) {
117       base_col* column = (*it)->copy();
118       if(!column) {
119         m_out << s_class() << "::cstor :"
120               << " can't copy column."
121               << std::endl;
122         safe_clear<base_col>(m_cols);
123         m_index = -1;
124         return; //throw
125       }
126       m_cols.push_back(column);
127     }
128   }
129   base_ntu& operator=(const base_ntu& a_from){
130     if(&a_from==this) return *this;
131 
132     safe_clear<base_col>(m_cols);
133     m_index = a_from.m_index;
134 
135     m_title = a_from.m_title;
136     tools_vforcit(base_col*,a_from.m_cols,it) {
137       base_col* column = (*it)->copy();
138       if(!column) {
139         m_out << s_class() << "::operator=() :"
140               << " can't copy column."
141               << std::endl;
142         safe_clear<base_col>(m_cols);
143         m_index = -1;
144         return *this;
145       }
146       m_cols.push_back(column);
147     }
148 
149     return *this;
150   }
151 public:
152   std::ostream& out() const {return m_out;}
153   const std::vector<base_col*>& columns() const {return m_cols;}
154   size_t number_of_columns() const {return m_cols.size();}
155 
156 #ifdef tools_aida_ntuple
157   const std::vector<base_col*>& cols() const {return m_cols;} //deprecated : use columns().
158 #endif
159 
160   void column_names(std::vector<std::string>& a_names) const {
161     a_names.clear();
162     tools_vforcit(base_col*,m_cols,it) a_names.push_back((*it)->name());
163   }
164 
165   const std::string& title() const {return m_title;}
166   void set_title(const std::string& a_title) {m_title = a_title;}
167 
168   uint64 rows() const {
169     if(m_cols.empty()) return 0;
170     return m_cols.front()->num_elems();
171   }
172   bool number_of_entries(uint64& a_value) const {
173     if(m_cols.empty()) {a_value = 0;return false;}
174     a_value = m_cols.front()->num_elems();
175     return true;
176   }
177 
178   void clear() { //must not be confused with reset().
179     safe_clear<base_col>(m_cols);
180     m_index = -1;
181   }
182 
183   bool reset() { //clear data in columns (but not the column set)
184     bool status = true;
185     tools_vforit(base_col*,m_cols,it) {
186       if(!(*it)->reset()) status = false;
187     }
188     m_index = -1;
189     return status;
190   }
191 
192   // reading :
193   void start() {m_index = -1;set_columns_index(0);}
194   bool next() {
195     // a tuple loop is of the form :
196     //  tuple.start();
197     //  while(tuple.next()) {
198     //    ...
199     //    double v;
200     //    if(!col->get_entry(v)) {}
201     //    ...
202     //  }
203     if((m_index+1)>=(int64)rows()) return false;
204     m_index++;
205     set_columns_index(m_index);
206     return true;
207   }
208   int64 row_index() const {return m_index;}
209 
210   // filling :
211   bool add_row() {
212     bool status = true;
213     tools_vforit(base_col*,m_cols,it) {
214       if(!(*it)->add()) status = false;
215     }
216     return status;
217   }
218 public:
219   base_col* find_column(const std::string& a_name){
220     return find_named<base_col>(m_cols,a_name);
221   }
222 
223   void add_column(base_col* a_col) { //we take ownership.
224     m_cols.push_back(a_col);
225   }
226 
227 protected:
228   void set_columns_index(uint64 a_index) {
229     tools_vforit(base_col*,m_cols,it) {
230       (*it)->set_index(a_index);
231     }
232   }
233 protected:
234   std::ostream& m_out;
235   std::string m_title;
236   int64 m_index;
237   std::vector<base_col*> m_cols;
238 };
239 
240 }}
241 
242 #include "tos"
243 #include "sto"
244 #include "columns"
245 #include "stype"
246 
247 namespace tools {
248 namespace aida {
249 
250 //inline const std::string& s_aida_type(char) {
251 //  static const std::string s_v("char");
252 //  return s_v;
253 //}
254 inline const std::string& s_aida_type(short) {
255   static const std::string s_v("short");
256   return s_v;
257 }
258 inline const std::string& s_aida_type(int) {
259   static const std::string s_v("int");
260   return s_v;
261 }
262 inline const std::string& s_aida_type(float) {
263   static const std::string s_v("float");
264   return s_v;
265 }
266 inline const std::string& s_aida_type(double) {
267   static const std::string s_v("double");
268   return s_v;
269 }
270 
271 /////////////////////////////////////////
272 /////////////////////////////////////////
273 //inline const std::string& s_aida_type(unsigned char) {
274 //  static const std::string s_v("byte");
275 //  return s_v;
276 //}
277 
278 inline const std::string& s_aida_type(bool) {
279   static const std::string s_v("boolean");
280   return s_v;
281 }
282 inline const std::string& s_aida_type(const std::string&) {
283   static const std::string s_v("string");
284   return s_v;
285 }
286 inline const std::string& s_aida_type(int64) {
287   static const std::string s_v("long");
288   return s_v;
289 }
290 /*
291 inline const std::string& s_aida_type(const std::vector<double>&) {
292   static const std::string s_v("double[]");
293   return s_v;
294 }
295 */
296 inline const std::string& s_aida_type_ituple() {
297   static const std::string s_v("ITuple");
298   return s_v;
299 }
300 
301 /////////////////////////////////////////
302 /// not AIDA ! //////////////////////////
303 /////////////////////////////////////////
304 inline const std::string& s_aida_type(unsigned short) {
305   static const std::string s_v("ushort");
306   return s_v;
307 }
308 inline const std::string& s_aida_type(unsigned int) {
309   static const std::string s_v("uint");
310   return s_v;
311 }
312 inline const std::string& s_aida_type(uint64) {
313   static const std::string s_v("ulong");
314   return s_v;
315 }
316 
317 class aida_base_col : public base_col {
318 public:
319   static const std::string& s_class() {
320     static const std::string s_v("tools::aida::aida_base_col");
321     return s_v;
322   }
323   virtual void* cast(const std::string& a_class) const {
324     if(void* p = cmp_cast<aida_base_col>(this,a_class)) {return p;}
325     return base_col::cast(a_class);
326   }
327 public:
328   virtual const std::string& aida_type() const = 0;
329   virtual bool s_default_value(std::string&) const = 0;
330   virtual bool s_value(std::string&) const = 0;
331   virtual bool s_fill(const std::string&) = 0;
332 public:
333   aida_base_col(std::ostream& a_out,const std::string& a_name)
334   :base_col(a_out,a_name){}
335 public:
336   virtual ~aida_base_col(){}
337 public:
338   aida_base_col(const aida_base_col& a_from)
339   :base_col(a_from)
340   {}
341   aida_base_col& operator=(const aida_base_col& a_from){
342     base_col::operator=(a_from);
343     return *this;
344   }
345 };
346 
347 inline bool s__fill(const std::string& a_s,std::string& a_v) {
348   a_v = a_s;
349   return true;
350 }
351 inline bool s__fill(const std::string& a_s,char& a_v) {
352   //for exlib/cbk/aida_ntu
353   if(a_s.empty()) return false;
354   a_v = a_s[0];
355   return true;
356 }
357 inline bool s__fill(const std::string& a_s,unsigned char& a_v) {
358   //for exlib/cbk/aida_ntu
359   if(a_s.empty()) return false;
360   a_v = a_s[0];
361   return true;
362 }
363 inline bool s__fill(const std::string& a_s,bool& a_v) {
364   return to(a_s,a_v);
365 }
366 inline bool s__fill(const std::string& a_s,short& a_v) {
367   return to<short>(a_s,a_v);
368 }
369 inline bool s__fill(const std::string& a_s,unsigned short& a_v) {
370   return to<unsigned short>(a_s,a_v);
371 }
372 inline bool s__fill(const std::string& a_s,int& a_v) {
373   return to<int>(a_s,a_v);
374 }
375 inline bool s__fill(const std::string& a_s,unsigned int& a_v) {
376   return to<unsigned int>(a_s,a_v);
377 }
378 inline bool s__fill(const std::string& a_s,int64& a_v) {
379   return to<int64>(a_s,a_v);
380 }
381 inline bool s__fill(const std::string& a_s,uint64& a_v) {
382   return to<uint64>(a_s,a_v);
383 }
384 inline bool s__fill(const std::string& a_s,float& a_v) {
385   return to<float>(a_s,a_v);
386 }
387 inline bool s__fill(const std::string& a_s,double& a_v) {
388   return to<double>(a_s,a_v);
389 }
390 
391 template <class T>
392 class aida_col : public aida_base_col {
393 public:
394   typedef T entry_t;
395 public:
396   static const std::string& s_class() {
397     static const std::string s_v("tools::aida::aida_col<"+stype(T())+">");
398     return s_v;
399   }
400   virtual void* cast(const std::string& a_class) const {
401     if(void* p = cmp_cast< aida_col<T> >(this,a_class)) {return p;}
402     return aida_base_col::cast(a_class);
403   }
404 public:
405   virtual base_col* copy() const {return new aida_col(*this);}
406   virtual bool add() {m_data.push_back(m_tmp);m_tmp = m_default;return true;}
407   virtual bool reset() {
408     m_data.clear();
409     m_index = 0;
410     m_tmp = m_default;
411     return true;
412   }
413   virtual uint64 num_elems() const {return m_data.size();}
414 public:
415   virtual const std::string& aida_type() const {return s_aida_type(T());}
416   virtual bool s_default_value(std::string& a_s) const {
417     a_s = tos(m_default);
418     return true;
419   }
420   virtual bool s_value(std::string& a_s) const {
421     typedef typename std::vector<T>::size_type sz_t;
422     a_s = tos(m_data[sz_t(m_index)]);
423     return true;
424   }
425 
426   // for exlib/raxml/tuple :
427   virtual bool s_fill(const std::string& a_s) {
428     //if(!to<T>(a_s,m_tmp)) {
429     if(!s__fill(a_s,m_tmp)) {
430       m_out << s_class() << "::fill :"
431             << " can't convert " << sout(a_s) << "."
432             << std::endl;
433       return false;
434     }
435     return true;
436   }
437 
438   virtual void set_user_variable(void* a_user_var) {m_user_var = (T*)a_user_var;} //not owner.
439 public:
440   aida_col(std::ostream& a_out,const std::string& a_name,const T& a_def)
441   :aida_base_col(a_out,a_name)
442   ,m_default(a_def)
443   ,m_tmp(a_def)
444   ,m_user_var(0) //not owner
445   {}
446 public:
447   virtual ~aida_col(){}
448 public:
449   aida_col(const aida_col& a_from)
450   :aida_base_col(a_from)
451   ,m_data(a_from.m_data)
452   ,m_default(a_from.m_default)
453   ,m_tmp(a_from.m_tmp)
454   ,m_user_var(a_from.m_user_var)
455   {}
456   aida_col& operator=(const aida_col& a_from){
457     aida_base_col::operator=(a_from);
458     if(&a_from==this) return *this;
459     m_data = a_from.m_data;
460     m_default = a_from.m_default;
461     m_tmp = a_from.m_tmp;
462     m_user_var = a_from.m_user_var;
463     return *this;
464   }
465 public:
466   bool fill(const T& a_value) {m_tmp = a_value;return true;}
467   bool get_entry(T& a_v) const {
468     if(m_index>=m_data.size()) {
469       m_out << s_class() << "::get_entry :"
470             << " bad index " << m_index
471             << ". Vec size is " << m_data.size() << "."
472             << "."
473             << std::endl;
474       a_v = T();
475       return false;
476     }
477     typedef typename std::vector<T>::size_type sz_t;
478     a_v = m_data[sz_t(m_index)];
479     return true;
480   }
481   virtual bool fetch_entry() const {
482     //NOTE : it is ok to have a NULL m_user_var.
483     if(m_index>=m_data.size()) {
484       m_out << s_class() << "::get_entry :"
485             << " bad index " << m_index
486             << ". Vec size is " << m_data.size() << "."
487             << "."
488             << std::endl;
489       if(m_user_var) *m_user_var = T();
490       return false;
491     }
492     typedef typename std::vector<T>::size_type sz_t;
493     if(m_user_var) *m_user_var = m_data[sz_t(m_index)];
494     return true;
495   }
496 protected:
497   std::vector<T> m_data;
498   T m_default;
499   T m_tmp;
500   T* m_user_var;
501 };
502 
503 class ntuple : public base_ntu {
504 public:
505   static cid id_class() {return 2000;} //for ntuple_binding.
506 public:
507   static const std::string& s_class() {
508     static const std::string s_v("tools::aida::ntuple");
509     return s_v;
510   }
511   virtual void* cast(const std::string& a_class) const {
512     if(void* p = cmp_cast<ntuple>(this,a_class)) {return p;}
513     return base_ntu::cast(a_class);
514   }
515   virtual const std::string& s_cls() const {return s_class();}
516 public:
517   ntuple(std::ostream& a_out,const std::string& a_title)
518   :base_ntu(a_out,a_title)
519   {}
520   virtual ~ntuple() {}
521 public:
522   ntuple(const ntuple& a_from): base_ntu(a_from){}
523   ntuple& operator=(const ntuple& a_from){
524     base_ntu::operator=(a_from);
525     return *this;
526   }
527 public:
528   template <class T>
529   aida_col<T>* create_col(const std::string& a_name,const T& a_def = T()) {
530     if(find_named<base_col>(m_cols,a_name)) {
531       m_out << s_class() << "::create_col :"
532             << " a column with name " << sout(a_name) << " already exists."
533             << std::endl;
534       return 0;
535     }
536     aida_col<T>* col = new aida_col<T>(m_out,a_name,a_def);
537     if(!col) {
538       m_out << s_class() << "::create_col :"
539             << " can't create aida_col<T> " << sout(a_name) << "."
540             << std::endl;
541       return 0;
542     }
543     m_cols.push_back(col);
544     return col;
545   }
546 
547   template <class T>
548   aida_col<T>* find_column(const std::string& a_name){
549     base_col* col = find_named<base_col>(m_cols,a_name);
550     if(!col) return 0;
551     return safe_cast<base_col, aida_col<T> >(*col);
552   }
553 
554   template <class T>
555   bool find_column(const std::string& a_name,aida_col<T>*& a_col,bool a_case_sensitive = true) { //for exlib::evaluator.
556     base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
557     if(!col) {a_col = 0;return false;}
558     a_col = safe_cast<base_col, aida_col<T> >(*col);
559     return a_col?true:false;
560   }
561 
562   aida_base_col* find_aida_base_column(const std::string& a_name,bool a_case_sensitive = true){ //for opaw/panntu.
563     base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
564     if(!col) return 0;
565     return safe_cast<base_col,aida_base_col>(*col);
566   }
567 
568   bool get_row() const {
569     bool status = true;
570     tools_vforcit(base_col*,m_cols,it) {
571       if(!(*it)->fetch_entry()) status = false;
572     }
573     return status;
574   }
575 
576   bool set_binding(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
577     tools_vforcit(column_binding,a_bd.columns(),itb) {
578       bool found = false;
579       tools_vforcit(base_col*,m_cols,itc) {
580         if((*itc)->name()==(*itb).name()) {
581           (*itc)->set_user_variable((*itb).user_obj());
582           found = true;
583         }
584       }
585       if(!found) {
586         a_out << "tools::aida::ntuple :"
587               << " binding name " << sout((*itb).name()) << " does not match any ntuple column."
588               << std::endl;
589         return false;
590       }
591     }
592     return true;
593   }
594 
595   template <class T>
596   bool column_min(unsigned int a_col,T& a_value) {
597     a_value = T();
598     if(m_cols.empty()) return false;
599     if(a_col>=m_cols.size()) return false;
600     base_col* _base_col = m_cols[a_col];
601     aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
602     if(!_col) return false;
603     start();
604     uint64 _rows = rows();
605     T v;
606    {for(uint64 row=0;row<_rows;row++) {
607       if(!next()) {a_value = T();return false;}
608       if(!_col->get_entry(v)) {}
609       if(!row) {
610         a_value = v;
611       } else {
612         a_value = mn<T>(a_value,v);
613       }
614     }}
615     return true;
616   }
617 
618   template <class T>
619   bool column_max(unsigned int a_col,T& a_value) {
620     a_value = T();
621     if(m_cols.empty()) return false;
622     if(a_col>=m_cols.size()) return false;
623     base_col* _base_col = m_cols[a_col];
624     aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
625     if(!_col) return false;
626     start();
627     uint64 _rows = rows();
628     T v;
629    {for(uint64 row=0;row<_rows;row++) {
630       if(!next()) {a_value = T();return false;}
631       if(!_col->get_entry(v)) {}
632       if(!row) {
633         a_value = v;
634       } else {
635         a_value = mx<T>(a_value,v);
636       }
637     }}
638     return true;
639   }
640 
641 };
642 
643 ////////////////////////////////////////////////////////////
644 /// some special column that can't be done with aida_col<T> ////
645 ////////////////////////////////////////////////////////////
646 
647 class aida_col_ntu : public base_col {
648 public:
649   static const std::string& s_class() {
650     static const std::string s_v("tools::aida::aida_col_ntu");
651     return s_v;
652   }
653   virtual void* cast(const std::string& a_class) const {
654     if(void* p = cmp_cast<aida_col_ntu>(this,a_class)) {return p;}
655     return base_col::cast(a_class);
656   }
657 public:
658   virtual base_col* copy() const {return new aida_col_ntu(*this);}
659   virtual bool add() {m_data.push_back(m_tmp);m_tmp.reset();return true;}
660   virtual bool reset() {m_data.clear();m_index = 0;return true;}
661   virtual uint64 num_elems() const {return m_data.size();}
662 public:
663   base_ntu* get_entry() {
664     if(m_index>=m_data.size()) {
665       m_out << s_class() << "::get_entry :"
666             << " bad index " << m_index
667             << ". Vec size is " << m_data.size() << "."
668             << "."
669             << std::endl;
670       return 0;
671     }
672     typedef std::vector<ntuple>::size_type sz_t;
673     return &(m_data[sz_t(m_index)]);
674   }
675 
676   virtual void set_user_variable(void* a_user_var) {m_user_var = (ntuple*)a_user_var;} //not owner.
677   virtual bool fetch_entry() const {
678     if(m_index>=m_data.size()) {
679       m_out << s_class() << "::fetch_entry :"
680             << " bad index " << m_index
681             << ". Vec size is " << m_data.size() << "."
682             << "."
683             << std::endl;
684       if(m_user_var) *m_user_var = ntuple(m_out,"");
685       return false;
686     }
687     typedef std::vector<ntuple>::size_type sz_t;
688     if(m_user_var) *m_user_var = m_data[sz_t(m_index)];
689     return true;
690   }
691 
692   virtual base_ntu* get_to_fill() {return &m_tmp;}
693 public:
694   aida_col_ntu(std::ostream& a_out,const std::string& a_name)
695   :base_col(a_out,a_name)
696   ,m_tmp(a_out,"tmp")
697   ,m_user_var(0) //not owner
698   {}
699 public:
700   virtual ~aida_col_ntu(){}
701 public:
702   aida_col_ntu(const aida_col_ntu& a_from)
703   :base_col(a_from)
704   ,m_data(a_from.m_data)
705 
706   ,m_tmp(a_from.m_tmp)
707   ,m_user_var(a_from.m_user_var)
708   {}
709   aida_col_ntu& operator=(const aida_col_ntu& a_from){
710     base_col::operator=(a_from);
711     if(&a_from==this) return *this;
712     m_data = a_from.m_data;
713 
714     m_tmp = a_from.m_tmp;
715     m_user_var = a_from.m_user_var;
716     return *this;
717   }
718 protected:
719   std::vector<ntuple> m_data;
720   ntuple m_tmp;
721   ntuple* m_user_var;
722 };
723 
724 inline bool create_cols_from_vals(ntuple& a_ntu,
725                                   const std::vector<value>& a_vars,
726                                   bool a_verbose = false){
727   tools_vforcit(value,a_vars,it) {
728       if((*it).type()==value::VOID_STAR) {
729         if(a_verbose){
730           a_ntu.out() << "tools::aida::create_cols_from_vals :"
731                       << " ITuple : " << (*it).label() << " : begin "
732                       << std::endl;
733         }
734         std::vector<value>* vars = (std::vector<value>*)(*it).get_void_star();
735 
736         aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),(*it).label());
737         // create sub columns on the "fillable" of col_ntu :
738         base_ntu* sub_base_ntu = col_ntu->get_to_fill();
739         if(!sub_base_ntu) {
740           delete col_ntu;
741           return false;
742         }
743         ntuple* sub_aida = safe_cast<base_ntu,ntuple>(*sub_base_ntu);
744         if(!sub_aida) {
745           delete col_ntu;
746           return false;
747         }
748 
749         if(!create_cols_from_vals(*sub_aida,*vars,a_verbose)) {
750           delete col_ntu;
751           return false;
752         }
753 
754         a_ntu.add_column(col_ntu);
755 
756     } else {
757         if(a_verbose){
758           std::string stype;
759           (*it).s_type(stype);
760           std::string sval;
761           (*it).tos(sval);
762           a_ntu.out() << "tools::aida::create_cols_from_vals :"
763                       << " " << stype << " : "
764                       << (*it).label() << " : "
765                       << sval
766                       << std::endl;
767         }
768 
769         //   char,short,int,float,double
770         //   byte,boolean,string,long(for int64)
771         //   double[]
772 
773         base_col* col = 0;
774       /*if((*it).type()==value::CHAR) {
775           col = a_ntu.create_col<char>((*it).label(),(*it).get_char());
776         } else*/ if((*it).type()==value::SHORT) {
777           col = a_ntu.create_col<short>((*it).label(),(*it).get_short());
778         } else if((*it).type()==value::INT) {
779           col = a_ntu.create_col<int>((*it).label(),(*it).get_int());
780         } else if((*it).type()==value::INT64) {
781           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
782         } else if((*it).type()==value::FLOAT) {
783           col = a_ntu.create_col<float>((*it).label(),(*it).get_float());
784         } else if((*it).type()==value::DOUBLE) {
785           col = a_ntu.create_col<double>((*it).label(),(*it).get_double());
786 
787         //} else if((*it).type()==value::UNSIGNED_CHAR) {
788         //  col = a_ntu.create_col<unsigned char>((*it).label(),(*it).get_unsigned_char());
789         } else if((*it).type()==value::UNSIGNED_SHORT) {
790           col = a_ntu.create_col<unsigned short>((*it).label(),(*it).get_unsigned_short());
791         } else if((*it).type()==value::UNSIGNED_INT) {
792           col = a_ntu.create_col<unsigned int>((*it).label(),(*it).get_unsigned_int());
793         } else if((*it).type()==value::UNSIGNED_INT64) {
794           col = a_ntu.create_col<uint64>((*it).label(),(*it).get_unsigned_int64());
795 
796         } else if((*it).type()==value::BOOL) {
797           col = a_ntu.create_col<bool>((*it).label(),(*it).get_bool());
798         } else if((*it).type()==value::STRING) {
799           col = a_ntu.create_col<std::string>((*it).label(),(*it).get_string());
800         } else if((*it).type()==value::INT64) {
801           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
802         }
803 
804         if(!col) {
805           std::string stype;
806           (*it).s_type(stype);
807           std::string sval;
808           (*it).tos(sval);
809           a_ntu.out() << "tools::aida::create_cols_from_vals :"
810                       << " failed for " << stype << " : "
811                       << (*it).label() << " : "
812                       << sval
813                       << std::endl;
814           return false;
815         }
816       }
817   }
818   return true;
819 }
820 
821 // for raxml :
822 inline bool create_col(ntuple& a_ntu,
823                        const std::string& a_type,
824                        const std::string& a_name,
825                        const std::string& a_s, //def or booking.
826                        bool a_is_ntu){
827 /*
828   if(a_type==s_aida_type((char)0)) {
829     char v = 0;
830     if(a_s.size()&&!to<char>(a_s,v)) {
831       a_ntu.out() << "tools::aida::create_col :"
832                   << " can't convert def " << sout(a_s)
833                   << " to a " << a_type
834                   << std::endl;
835       return false;
836     }
837     if(!a_ntu.create_col<char>(a_name,v)) {
838       a_ntu.out() << "tools::aida::create_col :"
839                   << " can't create column of type " << sout(a_type)
840                   << std::endl;
841       return false;
842     }
843 
844   } else*/ if(a_type==s_aida_type((short)0)) {
845     short v = 0;
846     if(a_s.size()&&!to<short>(a_s,v)) {
847       a_ntu.out() << "tools::aida::create_col :"
848                   << " can't convert def " << sout(a_s)
849                   << " to a " << a_type
850                   << std::endl;
851       return false;
852     }
853     if(!a_ntu.create_col<short>(a_name,v)) {
854       a_ntu.out() << "tools::aida::create_col :"
855                   << " can't create column of type " << sout(a_type)
856                   << std::endl;
857       return false;
858     }
859 
860   } else if(a_type==s_aida_type((int)0)) {
861     int v = 0;
862     if(a_s.size()&&!to<int>(a_s,v)) {
863       a_ntu.out() << "tools::aida::create_col :"
864                   << " can't convert def " << sout(a_s)
865                   << " to a " << a_type
866                   << std::endl;
867       return false;
868     }
869     if(!a_ntu.create_col<int>(a_name,v)) {
870       a_ntu.out() << "tools::aida::create_col :"
871                   << " can't create column of type " << sout(a_type)
872                   << std::endl;
873       return false;
874     }
875 
876   } else if(a_type==s_aida_type((int64)0)) {
877     int64 v = 0;
878     if(a_s.size()&&!to<int64>(a_s,v)) {
879       a_ntu.out() << "tools::aida::create_col :"
880                   << " can't convert def " << sout(a_s)
881                   << " to a " << a_type
882                   << std::endl;
883       return false;
884     }
885     if(!a_ntu.create_col<int64>(a_name,v)) {
886       a_ntu.out() << "tools::aida::create_col :"
887                   << " can't create column of type " << sout(a_type)
888                   << std::endl;
889       return false;
890     }
891 
892   } else if(a_type==s_aida_type((float)0)) {
893     float v = 0;
894     if(a_s.size()&&!to<float>(a_s,v)) {
895       a_ntu.out() << "tools::aida::create_col :"
896                   << " can't convert def " << sout(a_s)
897                   << " to a " << a_type
898                   << std::endl;
899       return false;
900     }
901     if(!a_ntu.create_col<float>(a_name,v)) {
902       a_ntu.out() << "tools::aida::create_col :"
903                   << " can't create column of type " << sout(a_type)
904                   << std::endl;
905       return false;
906     }
907 
908 
909   } else if(a_type==s_aida_type((double)0)) {
910     double v = 0;
911     if(a_s.size()&&!to<double>(a_s,v)) {
912       a_ntu.out() << "tools::aida::create_col :"
913                   << " can't convert def " << sout(a_s)
914                   << " to a " << a_type
915                   << std::endl;
916       return false;
917     }
918     if(!a_ntu.create_col<double>(a_name,v)) {
919       a_ntu.out() << "tools::aida::create_col :"
920                   << " can't create column of type " << sout(a_type)
921                   << std::endl;
922       return false;
923     }
924 
925 /*  } else if(a_type==s_aida_type((unsigned char)0)) { //byte
926     unsigned int v = 0;
927     if(a_s.size()&&!to<unsigned int>(a_s,v)) {
928       a_ntu.out() << "tools::aida::create_col :"
929                   << " can't convert def " << sout(a_s)
930                   << " to a " << a_type
931                   << std::endl;
932       return false;
933     }
934     if(v>=256) {
935       a_ntu.out() << "tools::aida::create_col :"
936                   << " can't convert def " << sout(a_s)
937                   << " to byte."
938                   << std::endl;
939       return false;
940     }
941     if(!a_ntu.create_col<unsigned char>(a_name,v)) {
942       a_ntu.out() << "tools::aida::create_col :"
943                   << " can't create column of type " << sout(a_type)
944                   << std::endl;
945       return false;
946     }
947 */
948   } else if(a_type==s_aida_type((unsigned short)0)) {
949     unsigned short v = 0;
950     if(a_s.size()&&!to<unsigned short>(a_s,v)) {
951       a_ntu.out() << "tools::aida::create_col :"
952                   << " can't convert def " << sout(a_s)
953                   << " to a " << a_type
954                   << std::endl;
955       return false;
956     }
957     if(!a_ntu.create_col<unsigned short>(a_name,v)) {
958       a_ntu.out() << "tools::aida::create_col :"
959                   << " can't create column of type " << sout(a_type)
960                   << std::endl;
961       return false;
962     }
963 
964   } else if(a_type==s_aida_type((unsigned int)0)) {
965     unsigned int v = 0;
966     if(a_s.size()&&!to<unsigned int>(a_s,v)) {
967       a_ntu.out() << "tools::aida::create_col :"
968                   << " can't convert def " << sout(a_s)
969                   << " to a " << a_type
970                   << std::endl;
971       return false;
972     }
973     if(!a_ntu.create_col<unsigned int>(a_name,v)) {
974       a_ntu.out() << "tools::aida::create_col :"
975                   << " can't create column of type " << sout(a_type)
976                   << std::endl;
977       return false;
978     }
979 
980   } else if(a_type==s_aida_type((uint64)0)) {
981     uint64 v = 0;
982     if(a_s.size()&&!to<uint64>(a_s,v)) {
983       a_ntu.out() << "tools::aida::create_col :"
984                   << " can't convert def " << sout(a_s)
985                   << " to a " << a_type
986                   << std::endl;
987       return false;
988     }
989     if(!a_ntu.create_col<uint64>(a_name,v)) {
990       a_ntu.out() << "tools::aida::create_col :"
991                   << " can't create column of type " << sout(a_type)
992                   << std::endl;
993       return false;
994     }
995 
996   /////////////////////////////////////////
997   /////////////////////////////////////////
998   } else if(a_type==s_aida_type((bool)true)) {
999     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