inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/ntu/aida
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_ntu_aida
00005 #define inlib_ntu_aida
00006 
00007 // an in memory ntuple able to have "sub ntuple" on a column.
00008 
00009 #include "base"
00010 
00011 #include "../tos"
00012 #include "../sto"
00013 #include "../columns"
00014 #include "../stype"
00015 
00016 namespace inlib {
00017 namespace ntu {
00018 
00019 class aida_base_col : public base_col {
00020 public:
00021   static const std::string& s_class() {
00022     static const std::string s_v("inlib::ntu::aida_base_col");
00023     return s_v;
00024   }
00025   virtual void* cast(const std::string& a_class) const {
00026     if(void* p = cmp_cast<aida_base_col>(this,a_class)) {return p;}
00027     else return base_col::cast(a_class);
00028   }
00029 public:
00030   virtual std::string aida_type() const = 0;
00031   virtual bool s_default_value(std::string&) const = 0;
00032   virtual bool s_value(std::string&) const = 0;
00033   virtual bool s_fill(std::string&) = 0;
00034 public:
00035   aida_base_col(std::ostream& a_out,const std::string& a_name)
00036   : base_col(a_out,a_name){}
00037 public:
00038   virtual ~aida_base_col(){}
00039 public:
00040   aida_base_col(const aida_base_col& a_from)
00041   : base_col(a_from)
00042   {}
00043   aida_base_col& operator=(const aida_base_col& a_from){
00044     base_col::operator=(a_from);
00045     return *this;
00046   }
00047 };
00048 
00049 template <class T>
00050 class aida_col : public aida_base_col {
00051 public:
00052   static const std::string& s_class() {
00053     static const std::string s_v("inlib::ntu::aida_col<"+stype(T())+">");
00054     return s_v;
00055   }
00056   virtual void* cast(const std::string& a_class) const {
00057     if(void* p = cmp_cast< aida_col<T> >(this,a_class)) {return p;}
00058     else return aida_base_col::cast(a_class);
00059   }
00060 public:
00061   virtual base_col* copy() const {return new aida_col(*this);}
00062   virtual bool add() {m_data.push_back(m_tmp);m_tmp = m_default;return true;}
00063   virtual bool reset() {
00064     m_data.clear();
00065     m_index = 0;
00066     m_tmp = m_default;
00067     return true;
00068   }
00069   virtual uint64 num_elems() const {return m_data.size();}
00070 public:
00071   virtual std::string aida_type() const {return s_aida_type(T());}
00072   virtual bool s_default_value(std::string& a_s) const {
00073     a_s = tos(m_default);
00074     return true;
00075   }
00076   virtual bool s_value(std::string& a_s) const {
00077     a_s = tos(m_data[m_index]);
00078     return true;
00079   }
00080 
00081   // for exlib/raxml/tuple :
00082   virtual bool s_fill(std::string& a_s) {
00083     if(!to<T>(a_s,m_tmp)) {
00084       m_out << s_class() << "::fill :"
00085             << " can't convert " << sout(a_s) << "."
00086             << std::endl;
00087       return false;
00088     }
00089     return true;
00090   }
00091 public:
00092   aida_col(std::ostream& a_out,const std::string& a_name,const T& a_def)
00093   : aida_base_col(a_out,a_name)
00094   ,m_default(a_def)
00095   ,m_tmp(a_def){}
00096 public:
00097   virtual ~aida_col(){}
00098 public:
00099   aida_col(const aida_col& a_from)
00100   : aida_base_col(a_from)
00101   ,m_data(a_from.m_data)
00102   ,m_default(a_from.m_default)
00103   ,m_tmp(a_from.m_tmp)
00104   {}
00105   aida_col& operator=(const aida_col& a_from){
00106     aida_base_col::operator=(a_from);
00107     m_data = a_from.m_data;
00108     m_default = a_from.m_default;
00109     m_tmp = a_from.m_tmp;
00110     return *this;
00111   }
00112 public:
00113   bool fill(const T& a_value) {m_tmp = a_value;return true;}
00114   bool get_entry(T& a_v) const {
00115     if(m_index>=m_data.size()) {
00116       m_out << s_class() << "::get_entry :"
00117             << " bad index " << m_index
00118             << ". Vec size is " << m_data.size() << "."
00119             << "."
00120             << std::endl;
00121       a_v = T();
00122       return false;
00123     }
00124     a_v = m_data[m_index];
00125     return true;
00126   }
00127 protected:
00128   std::vector<T> m_data;
00129   T m_default;
00130   T m_tmp;
00131 };
00132 
00133 class aida : public base_ntu {
00134 public:
00135   static const std::string& s_class() {
00136     static const std::string s_v("inlib::ntu::aida");
00137     return s_v;
00138   }
00139   virtual void* cast(const std::string& a_class) const {
00140     if(void* p = cmp_cast<aida>(this,a_class)) {return p;}
00141     else return base_ntu::cast(a_class);
00142   }
00143 public:
00144   aida(std::ostream& a_out,const std::string& a_title)
00145   : base_ntu(a_out,a_title)
00146   {}
00147   virtual ~aida() {}
00148 public:
00149   aida(const aida& a_from): base_ntu(a_from){}
00150   aida& operator=(const aida& a_from){
00151     base_ntu::operator=(a_from);
00152     return *this;
00153   }
00154 public:
00155   template <class T>
00156   aida_col<T>* create_col(const std::string& a_name,
00157                                  const T& a_def = T()) {
00158     if(find_named<base_col>(m_cols,a_name)) {
00159       m_out << s_class() << "::create_col :"
00160             << " a column with name " << sout(a_name) << " already exists."
00161             << std::endl;
00162       return 0;
00163     }
00164     aida_col<T>* col = new aida_col<T>(m_out,a_name,a_def);
00165     if(!col) {
00166       m_out << s_class() << "::create_col :"
00167             << " can't create aida_col<T> " << sout(a_name) << "."
00168             << std::endl;
00169       return 0;
00170     }    
00171     m_cols.push_back(col);
00172     return col;
00173   }
00174 
00175   template <class T>
00176   aida_col<T>* find_column(const std::string& a_name){
00177     base_col* col = find_named<base_col>(m_cols,a_name);
00178     if(!col) return 0;
00179     return inlib::cast<base_col, aida_col<T> >(*col);
00180   }
00181 };
00182 
00186 
00187 class aida_col_ntu : public base_col {
00188 public:
00189   static const std::string& s_class() {
00190     static const std::string s_v("inlib::ntu::aida_col_ntu");
00191     return s_v;
00192   }
00193   virtual void* cast(const std::string& a_class) const {
00194     if(void* p = cmp_cast<aida_col_ntu>(this,a_class)) {return p;}
00195     else return base_col::cast(a_class);
00196   }
00197 public:
00198   virtual base_col* copy() const {return new aida_col_ntu(*this);}
00199   virtual bool add() {m_data.push_back(m_tmp);m_tmp.reset();return true;}
00200   virtual bool reset() {m_data.clear();m_index = 0;return true;}
00201   virtual uint64 num_elems() const {return m_data.size();}
00202 public:
00203   base_ntu* get_entry() {
00204     if(m_index>=m_data.size()) {
00205       m_out << s_class() << "::get_entry :"
00206             << " bad index " << m_index
00207             << ". Vec size is " << m_data.size() << "."
00208             << "."
00209             << std::endl;
00210       return 0;
00211     }
00212     return &(m_data[m_index]);
00213   }
00214 
00215   virtual base_ntu* get_to_fill() {return &m_tmp;}
00216 public:
00217   aida_col_ntu(std::ostream& a_out,const std::string& a_name)
00218   : base_col(a_out,a_name)
00219   ,m_tmp(a_out,"tmp")
00220   {}
00221 public:
00222   virtual ~aida_col_ntu(){}
00223 public:
00224   aida_col_ntu(const aida_col_ntu& a_from)
00225   : base_col(a_from)
00226   ,m_data(a_from.m_data)
00227 
00228   ,m_tmp(a_from.m_tmp)
00229   {}
00230   aida_col_ntu& operator=(const aida_col_ntu& a_from){
00231     base_col::operator=(a_from);
00232     m_data = a_from.m_data;
00233 
00234     m_tmp = a_from.m_tmp;
00235     return *this;
00236   }
00237 protected:
00238   std::vector<aida> m_data;
00239   aida m_tmp;
00240 };
00241 
00242 inline bool create_cols_from_vals(aida& a_ntu,
00243                                   const std::vector<value>& a_vars,
00244                                   bool a_verbose = false){
00245   std::vector<value>::const_iterator it;
00246   for(it=a_vars.begin();it!=a_vars.end();++it) {
00247       if((*it).type()==value::VOID_STAR) {
00248         if(a_verbose){
00249           a_ntu.out() << "inlib::ntu::create_cols_from_vals :"
00250                       << " ITuple : " << (*it).label() << " : begin "
00251                       << std::endl;
00252         }
00253         std::vector<value>* vars = 
00254           (std::vector<value>*)(*it).get_void_star();
00255 
00256         aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),(*it).label());
00257         // create sub columns on the the "fillable" of col_ntu :
00258         base_ntu* sub_base_ntu = col_ntu->get_to_fill();
00259         if(!sub_base_ntu) return false;
00260         aida* sub_aida = inlib::cast<base_ntu,aida>(*sub_base_ntu);
00261         if(!sub_aida) return false;
00262 
00263         if(!create_cols_from_vals(*sub_aida,*vars,a_verbose)) {
00264           delete col_ntu;
00265           return false;
00266         }
00267 
00268         a_ntu.add_column(col_ntu);
00269 
00270     } else {
00271         if(a_verbose){
00272           std::string stype;        
00273           (*it).s_type(stype);
00274           std::string sval;        
00275           (*it).tos(sval);
00276           a_ntu.out() << "inlib::ntu::create_cols_from_vals :"
00277                       << " " << stype << " : " 
00278                       << (*it).label() << " : " 
00279                       << sval
00280                       << std::endl;
00281         }
00282 
00283         //   char,short,int,float,double
00284         //   byte,boolean,string,long(for int64)
00285         //   double[]
00286 
00287         base_col* col = 0;
00288         if((*it).type()==value::CHAR) {
00289           col = a_ntu.create_col<char>((*it).label(),(*it).get_char());
00290         } else if((*it).type()==value::SHORT) {
00291           col = a_ntu.create_col<short>((*it).label(),(*it).get_short());
00292         } else if((*it).type()==value::INT) {
00293           col = a_ntu.create_col<int>((*it).label(),(*it).get_int());
00294         } else if((*it).type()==value::INT64) {
00295           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
00296         } else if((*it).type()==value::FLOAT) {
00297           col = a_ntu.create_col<float>((*it).label(),(*it).get_float());
00298         } else if((*it).type()==value::DOUBLE) {
00299           col = a_ntu.create_col<double>((*it).label(),(*it).get_double());
00300 
00301         } else if((*it).type()==value::UNSIGNED_CHAR) {
00302           col = a_ntu.create_col<unsigned char>
00303                   ((*it).label(),(*it).get_unsigned_char());
00304         } else if((*it).type()==value::UNSIGNED_SHORT) {
00305           col = a_ntu.create_col<unsigned short>
00306                   ((*it).label(),(*it).get_unsigned_short());
00307         } else if((*it).type()==value::UNSIGNED_INT) {
00308           col = a_ntu.create_col<unsigned int>
00309                   ((*it).label(),(*it).get_unsigned_int());
00310         } else if((*it).type()==value::UNSIGNED_INT64) {
00311           col = a_ntu.create_col<uint64>
00312                   ((*it).label(),(*it).get_unsigned_int64());
00313 
00314         } else if((*it).type()==value::BOOL) {
00315           col = a_ntu.create_col<bool>((*it).label(),(*it).get_bool());
00316         } else if((*it).type()==value::STRING) {
00317           col = a_ntu.create_col<std::string>
00318                   ((*it).label(),(*it).get_string());
00319         } else if((*it).type()==value::INT64) {
00320           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
00321         }
00322 
00323         if(!col) {
00324           std::string stype;        
00325           (*it).s_type(stype);
00326           std::string sval;        
00327           (*it).tos(sval);
00328           a_ntu.out() << "inlib::ntu::create_cols_from_vals :"
00329                       << " failed for " << stype << " : " 
00330                       << (*it).label() << " : " 
00331                       << sval
00332                       << std::endl;
00333           return false;
00334         }
00335       }
00336   }
00337   return true;
00338 }
00339 
00340 // for raxml :
00341 inline bool create_col(aida& a_ntu,
00342                        const std::string& a_type,
00343                        const std::string& a_name,
00344                        const std::string& a_s, //def or booking.
00345                        bool a_is_ntu){
00346   if(a_type==s_aida_type((char)0)) {
00347     char v;
00348     if(!to<char>(a_s,v)) {
00349       a_ntu.out() << "inlib::ntu::create_col :" 
00350                   << " can't convert def " << sout(a_s)
00351                   << " to a " << a_type
00352                   << std::endl;
00353       return false;
00354     }
00355     if(!a_ntu.create_col<char>(a_name,v)) {
00356       a_ntu.out() << "inlib::ntu::create_col :" 
00357                   << " can't create column of type " << sout(a_type)
00358                   << std::endl;
00359       return false;
00360     }
00361 
00362   } else if(a_type==s_aida_type((short)0)) {
00363     short v;
00364     if(!to<short>(a_s,v)) {
00365       a_ntu.out() << "inlib::ntu::create_col :" 
00366                   << " can't convert def " << sout(a_s)
00367                   << " to a " << a_type
00368                   << std::endl;
00369       return false;
00370     }
00371     if(!a_ntu.create_col<short>(a_name,v)) {
00372       a_ntu.out() << "inlib::ntu::create_col :" 
00373                   << " can't create column of type " << sout(a_type)
00374                   << std::endl;
00375       return false;
00376     }
00377 
00378   } else if(a_type==s_aida_type((int)0)) {
00379     int v;
00380     if(!to<int>(a_s,v)) {
00381       a_ntu.out() << "inlib::ntu::create_col :" 
00382                   << " can't convert def " << sout(a_s)
00383                   << " to a " << a_type
00384                   << std::endl;
00385       return false;
00386     }
00387     if(!a_ntu.create_col<int>(a_name,v)) {
00388       a_ntu.out() << "inlib::ntu::create_col :" 
00389                   << " can't create column of type " << sout(a_type)
00390                   << std::endl;
00391       return false;
00392     }
00393 
00394   } else if(a_type==s_aida_type((int64)0)) {
00395     int64 v;
00396     if(!to<int64>(a_s,v)) {
00397       a_ntu.out() << "inlib::ntu::create_col :" 
00398                   << " can't convert def " << sout(a_s)
00399                   << " to a " << a_type
00400                   << std::endl;
00401       return false;
00402     }
00403     if(!a_ntu.create_col<int64>(a_name,v)) {
00404       a_ntu.out() << "inlib::ntu::create_col :" 
00405                   << " can't create column of type " << sout(a_type)
00406                   << std::endl;
00407       return false;
00408     }
00409 
00410   } else if(a_type==s_aida_type((float)0)) {
00411     float v;
00412     if(!to<float>(a_s,v)) {
00413       a_ntu.out() << "inlib::ntu::create_col :" 
00414                   << " can't convert def " << sout(a_s)
00415                   << " to a " << a_type
00416                   << std::endl;
00417       return false;
00418     }
00419     if(!a_ntu.create_col<float>(a_name,v)) {
00420       a_ntu.out() << "inlib::ntu::create_col :" 
00421                   << " can't create column of type " << sout(a_type)
00422                   << std::endl;
00423       return false;
00424     }
00425 
00426 
00427   } else if(a_type==s_aida_type((double)0)) {
00428     double v;
00429     if(!to<double>(a_s,v)) {
00430       a_ntu.out() << "inlib::ntu::create_col :" 
00431                   << " can't convert def " << sout(a_s)
00432                   << " to a " << a_type
00433                   << std::endl;
00434       return false;
00435     }
00436     if(!a_ntu.create_col<double>(a_name,v)) {
00437       a_ntu.out() << "inlib::ntu::create_col :" 
00438                   << " can't create column of type " << sout(a_type)
00439                   << std::endl;
00440       return false;
00441     }
00442 
00443   } else if(a_type==s_aida_type((unsigned char)0)) {
00444     unsigned char v;
00445     if(!to<unsigned char>(a_s,v)) {
00446       a_ntu.out() << "inlib::ntu::create_col :" 
00447                   << " can't convert def " << sout(a_s)
00448                   << " to a " << a_type
00449                   << std::endl;
00450       return false;
00451     }
00452     if(!a_ntu.create_col<unsigned char>(a_name,v)) {
00453       a_ntu.out() << "inlib::ntu::create_col :" 
00454                   << " can't create column of type " << sout(a_type)
00455                   << std::endl;
00456       return false;
00457     }
00458 
00459   } else if(a_type==s_aida_type((unsigned short)0)) {
00460     unsigned short v;
00461     if(!to<unsigned short>(a_s,v)) {
00462       a_ntu.out() << "inlib::ntu::create_col :" 
00463                   << " can't convert def " << sout(a_s)
00464                   << " to a " << a_type
00465                   << std::endl;
00466       return false;
00467     }
00468     if(!a_ntu.create_col<unsigned short>(a_name,v)) {
00469       a_ntu.out() << "inlib::ntu::create_col :" 
00470                   << " can't create column of type " << sout(a_type)
00471                   << std::endl;
00472       return false;
00473     }
00474 
00475   } else if(a_type==s_aida_type((unsigned int)0)) {
00476     unsigned int v;
00477     if(!to<unsigned int>(a_s,v)) {
00478       a_ntu.out() << "inlib::ntu::create_col :" 
00479                   << " can't convert def " << sout(a_s)
00480                   << " to a " << a_type
00481                   << std::endl;
00482       return false;
00483     }
00484     if(!a_ntu.create_col<unsigned int>(a_name,v)) {
00485       a_ntu.out() << "inlib::ntu::create_col :" 
00486                   << " can't create column of type " << sout(a_type)
00487                   << std::endl;
00488       return false;
00489     }
00490 
00491   } else if(a_type==s_aida_type((uint64)0)) {
00492     uint64 v;
00493     if(!to<uint64>(a_s,v)) {
00494       a_ntu.out() << "inlib::ntu::create_col :" 
00495                   << " can't convert def " << sout(a_s)
00496                   << " to a " << a_type
00497                   << std::endl;
00498       return false;
00499     }
00500     if(!a_ntu.create_col<uint64>(a_name,v)) {
00501       a_ntu.out() << "inlib::ntu::create_col :" 
00502                   << " can't create column of type " << sout(a_type)
00503                   << std::endl;
00504       return false;
00505     }
00506 
00509   } else if(a_type==s_aida_type((bool)true)) {
00510     bool v;
00511     if(!to(a_s,v)) {
00512       a_ntu.out() << "inlib::ntu::create_col :" 
00513                   << " can't convert def " << sout(a_s)
00514                   << " to a " << a_type
00515                   << std::endl;
00516       return false;
00517     }
00518     if(!a_ntu.create_col<bool>(a_name,v)) {
00519       a_ntu.out() << "inlib::ntu::create_col :" 
00520                   << " can't create column of type " << sout(a_type)
00521                   << std::endl;
00522       return false;
00523     }
00524 
00525   } else if(a_type==s_aida_type(std::string())) {
00526     if(!a_ntu.create_col<std::string>(a_name,a_s)) {
00527       a_ntu.out() << "inlib::ntu::create_col :" 
00528                   << " can't create column of type " << sout(a_type)
00529                   << std::endl;
00530       return false;
00531     }
00532 
00533   } else if(a_type==s_aida_type((int64)0)) {
00534     int64 v;
00535     if(!to<int64>(a_s,v)) {
00536       a_ntu.out() << "inlib::ntu::create_col :" 
00537                   << " can't convert def " << sout(a_s)
00538                   << " to a " << a_type
00539                   << std::endl;
00540       return false;
00541     }
00542     if(!a_ntu.create_col<int64>(a_name,v)) {
00543       a_ntu.out() << "inlib::ntu::create_col :" 
00544                   << " can't create column of type " << sout(a_type)
00545                   << std::endl;
00546       return false;
00547     }
00548 
00549   } else if(a_type==s_aida_type_ituple()) {
00550     // we expect a booking string on a_s.
00551 
00552     if(!a_is_ntu) {
00553       a_ntu.out() << "inlib::ntu::create_col :" 
00554                   << " mismatch a_is_ntu/a_type."
00555                   << std::endl;
00556       return false;
00557     }
00558     if(a_s.empty()) {
00559       a_ntu.out() << "inlib::ntu::create_col :" 
00560                   << " empty booking string."
00561                   << std::endl;
00562       return false;
00563     }
00564 
00565     columns::finder f(a_ntu.out(),a_s);
00566     if(!f.find_variables()) {
00567       a_ntu.out() << "inlib::ntu::create_col :" 
00568             << " find_variables() failed for " << sout(a_s) << "."
00569             << std::endl;
00570       return false;
00571     }
00572 
00573     aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),a_name);
00574     //create columns on the fillable.
00575     base_ntu* sub_base_ntu = col_ntu->get_to_fill();
00576     if(!sub_base_ntu) {delete col_ntu;return false;}
00577     aida* sub_aida = inlib::cast<base_ntu,aida>(*sub_base_ntu);
00578     if(!sub_aida) {delete col_ntu;return false;}
00579 
00580     std::vector<value> vars = f.result();
00581     if(!create_cols_from_vals(*sub_aida,vars)) {
00582       columns::delete_columns(vars);
00583       delete col_ntu;
00584       return false;
00585     }
00586     columns::delete_columns(vars);
00587     a_ntu.add_column(col_ntu);
00588 
00589     //FIXME : double[]
00590 
00591   } else {
00592     a_ntu.out() << "inlib::ntu::create_col :" 
00593                 << " col type " << sout(a_type)
00594                 << " not yet handled."
00595                 << std::endl;
00596     return false;
00597   }
00598 
00599   return true;
00600 }
00601 
00602 // for waxml :
00603 inline bool create_cols_from_string(aida& a_ntu,
00604                                     const std::string& a_booking,
00605                                     bool a_verbose = false){
00606   a_ntu.clear();
00607   if(a_booking.empty()) {
00608     a_ntu.out() << "inlib::ntu::create_cols_from_string :"
00609                 << " empty booking string."
00610                 << std::endl;
00611     return false;
00612   }
00613 
00614   columns::finder f(a_ntu.out(),a_booking);
00615   if(!f.find_variables()) {
00616     a_ntu.out() << "inlib::ntu::create_cols_from_string :"
00617           << " find_variables() failed."
00618           << std::endl;
00619     return false;
00620   }
00621   std::vector<value> vars = f.result();
00622   if(a_verbose) columns::dump_columns(a_ntu.out(),vars);
00623 
00624   if(!create_cols_from_vals(a_ntu,vars)) {
00625     columns::delete_columns(vars);
00626     a_ntu.clear();
00627     return false;
00628   }
00629   columns::delete_columns(vars);
00630   return true;
00631 }
00632 
00633 inline aida_col_ntu* find_col_ntu(aida& a_ntu,const std::string& a_name){
00634   base_col* col = find_named<base_col>(a_ntu.cols(),a_name);
00635   if(!col) return 0;
00636   return inlib::cast<base_col, aida_col_ntu >(*col);
00637 }
00638 
00639 template <class T>
00640 class base_looper {
00641 public:
00642   static const std::string& s_class() {
00643     static const std::string s_v("inlib::ntu::base_looper<"+stype(T())+">");
00644     return s_v;
00645   }
00646 protected:
00647   virtual bool action(const T& a_value) = 0; //return false to stop processing.
00648 public:
00649   base_looper(base_ntu& a_ntu,const base_col& a_col)
00650   :m_ntu(a_ntu),m_col(a_col){
00651 #ifdef INLIB_MEM
00652     mem::increment(s_class().c_str());
00653 #endif
00654   }
00655   virtual ~base_looper(){
00656 #ifdef INLIB_MEM
00657     mem::decrement(s_class().c_str());
00658 #endif
00659   }
00660 public:
00661   base_looper(const base_looper& a_from)
00662   :m_ntu(a_from.m_ntu),m_col(a_from.m_col){
00663 #ifdef INLIB_MEM
00664     mem::increment(s_class().c_str());
00665 #endif
00666   }
00667   base_looper& operator=(const base_looper& a_from){return *this;}
00668 public:
00669   bool process() {
00670     std::vector<unsigned int> is;
00671     bool found = false;
00672     if(!find_is(m_ntu,&m_col,is,found)) {
00673       m_ntu.out() << s_class() << "::process :"
00674                   << " find_is failed."
00675                   << std::endl;
00676       return false;
00677     }
00678     if(!found) {
00679       m_ntu.out() << s_class() << "::process :"
00680                   << " find_is : col not found."
00681                   << std::endl;
00682       return false;
00683     }
00684     if(is.empty()) {
00685       m_ntu.out() << s_class() << "::process :"
00686                   << " is vec empty."
00687                   << std::endl;
00688       return false;
00689     }
00690 
00691   //{m_ntu.out() << "debug : sz " << is.size() << std::endl;
00692   // std::vector<unsigned int>::const_iterator it;
00693   // for(it=is.begin();it!=is.end();++it){
00694   //   m_ntu.out() << "  " << *it << std::endl;       
00695   //}}
00696 
00697     bool stop = false;
00698     if(!_looper(m_ntu,is,0,stop)) {
00699       m_ntu.out() << s_class() << "::process :"
00700                   << " _looper failed."
00701                   << std::endl;
00702       return false;
00703     }
00704     return true;
00705   }
00706 protected:
00707   static bool find_is(const base_ntu& a_ntu,const base_col* a_col,
00708                              std::vector<unsigned int>& a_is,
00709                              bool& a_found){
00710     // search the indices to reach the sub leaf a_col from the main a_ntu.    
00711     // Note : it is assumed that a_is is empty and a_found = false before
00712     //        calling with function.
00713   
00714     const std::vector<base_col*>& cols = a_ntu.cols();
00715     std::vector<base_col*>::const_iterator it;
00716   
00717     // look if a_col is a leaf col of a_ntu :
00718    {unsigned int index = 0;
00719     for(it=cols.begin();it!=cols.end();++it,index++) {
00720       if(*it==a_col) {
00721         a_is.push_back(index); //leaf index is the last one in a_is.
00722         a_found = true;
00723         return true;
00724       }
00725     }}
00726   
00727     // go down sub ntu :
00728    {unsigned int index = 0;
00729     for(it=cols.begin();it!=cols.end();++it,index++) {
00730       aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(*it));
00731       if(!col) continue;
00732       base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
00733       if(!sub) {a_is.clear();return false;}
00734       a_is.push_back(index);
00735       if(!find_is(*sub,a_col,a_is,a_found)) {a_is.clear();return false;}
00736       if(a_found) return true;
00737       a_is.pop_back();
00738     }}
00739     return true;
00740   }  
00741 protected:
00742   bool _looper(base_ntu& a_sub,
00743                       const std::vector<unsigned int>& a_is,
00744                       unsigned int a_depth,
00745                       bool& a_stop) {
00746     if(a_depth>=a_is.size()) return false;
00747 
00748     unsigned int coli = a_is[a_depth];  
00749     const std::vector<base_col*>& cols = a_sub.cols();
00750     if(coli>=cols.size()) return false;
00751 
00752     if(a_depth==(a_is.size()-1)) { //we reach the leaf.
00753       aida_col<T>* col = cast<base_col, aida_col<T> >(*(cols[coli]));
00754       if(!col) return false;
00755       a_sub.start();
00756       while(a_sub.next()) {
00757         T v;
00758         if(!col->get_entry(v)) return false;
00759         if(!action(v)) {a_stop = true;break;}
00760       }
00761     } else {
00762       aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(cols[coli]));
00763       if(!col) return false;
00764       a_sub.start();
00765       while(a_sub.next()) {
00766         base_ntu* ntu = col->get_entry(); //not const.
00767         if(!ntu) return false;
00768         ntu->start();
00769         while(ntu->next()) {
00770           if(!_looper(*ntu,a_is,a_depth+1,a_stop)) return false;
00771           if(a_stop) break;
00772         }
00773       }
00774     }
00775     return true;
00776   }
00777 protected:
00778   base_ntu& m_ntu;
00779   const base_col& m_col;
00780 };
00781 
00782 }}
00783 
00784 #include "../mnmx"
00785 
00786 namespace inlib {
00787 namespace ntu {
00788 
00789 template <class T>
00790 class stat_looper : public base_looper<T> {
00791 protected:
00792   virtual bool action(const T& a_v) {
00793     if(m_first) {
00794       m_mn = a_v;
00795       m_mx = a_v;
00796       m_S = a_v;
00797       m_S2 = a_v*a_v;
00798 
00799       m_first = false;
00800     } else {
00801       m_mn = inlib::mn<T>(m_mn,a_v);
00802       m_mx = inlib::mx<T>(m_mx,a_v);
00803       m_S += a_v;
00804       m_S2 += a_v*a_v;
00805     }
00806     m_counter++;
00807     return true; //continue looping.
00808   }
00809 public:
00810   stat_looper(base_ntu& a_ntu,const base_col& a_col)
00811   : base_looper<T>(a_ntu,a_col)
00812   ,m_first(true)
00813   ,m_mn(T())
00814   ,m_mx(T())
00815   ,m_S(T())
00816   ,m_S2(T())
00817   ,m_counter(0)
00818   {}
00819   virtual ~stat_looper(){}
00820 public:
00821   stat_looper(const stat_looper& a_from)
00822   : base_looper<T>(a_from)
00823   ,m_first(true)
00824   ,m_mn(T())
00825   ,m_mx(T())
00826   ,m_S(T())
00827   ,m_S2(T())
00828   ,m_counter(0)
00829   {}
00830   stat_looper& operator=(const stat_looper& a_from){
00831     base_looper<T>::operator=(a_from);
00832     m_first = true;
00833     m_mn = T();
00834     m_mx = T();
00835     m_S = T();
00836     m_S2 = T();
00837     m_counter = 0;
00838     return *this;
00839   }  
00840 public:
00841   bool process() {
00842     m_counter = 0;
00843     if(!base_looper<T>::process()) {
00844       m_mn = T();
00845       m_mx = T();
00846       m_S = T();
00847       m_S2 = T();
00848       m_counter = 0;
00849       return false;
00850     }
00851     return true;
00852   }
00853   T mn() const {return m_mn;}
00854   T mx() const {return m_mx;}
00855   T S() const {return m_S;}
00856   T S2() const {return m_S2;}
00857   uint64 counter() const {return m_counter;}
00858 protected:
00859   bool m_first;
00860   T m_mn;
00861   T m_mx;
00862   T m_S;
00863   T m_S2;
00864   uint64 m_counter;
00865 };
00866 
00867 inline base_col* find_leaf_column(const base_ntu& a_ntu,
00868                               const std::string& a_name){
00869   const std::vector<base_col*>& cols = a_ntu.cols();
00870   std::vector<base_col*>::const_iterator it;  
00871   for(it=cols.begin();it!=cols.end();++it) {
00872     aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(*it));
00873     if(col) {
00874       base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
00875       if(!sub) return 0;
00876       base_col* fcol = find_leaf_column(*sub,a_name);
00877       if(fcol) return fcol;      
00878     } else {
00879       if((*it)->name()==a_name) return *it;
00880     }
00881   }
00882   return 0;
00883 }  
00884 
00885 }}
00886 
00887 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines