inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/aida_ntuple
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_aida_ntuple
00005 #define inlib_aida_ntuple
00006 
00007 // An in memory ntuple able to have "sub ntuple" on a column.
00008 // It is used in ioda to read ntuples in XML/AIDA files.
00009 
00010 #ifdef INLIB_MEM
00011 #include "mem"
00012 #endif
00013 
00014 #include "vmanip"
00015 #include "vfind"
00016 #include "typedefs"
00017 #include "scast"
00018 
00019 #include <string>
00020 #include <vector>
00021 #include <ostream>
00022 
00023 namespace inlib {
00024 namespace aida {
00025 
00026 class base_col {
00027 public:
00028   static const std::string& s_class() {
00029     static const std::string s_v("inlib::aida::base_col");
00030     return s_v;
00031   }
00032   virtual void* cast(const std::string& a_class) const {
00033     if(void* p = cmp_cast<base_col>(this,a_class)) {return p;}
00034     else return 0;
00035   }
00036 public:
00037   virtual base_col* copy() const = 0;
00038   virtual uint64 num_elems() const = 0;
00039   virtual bool add() = 0;
00040   virtual bool reset() = 0;
00041 protected:
00042   base_col(std::ostream& a_out,const std::string& a_name)
00043   :m_out(a_out)
00044   ,m_name(a_name),m_index(0){
00045 #ifdef INLIB_MEM
00046     mem::increment(s_class().c_str());
00047 #endif
00048   }
00049 public:
00050   virtual ~base_col(){
00051 #ifdef INLIB_MEM
00052     mem::decrement(s_class().c_str());
00053 #endif
00054   }
00055 protected:
00056   base_col(const base_col& a_from)
00057   :m_out(a_from.m_out)
00058   ,m_name(a_from.m_name)
00059   ,m_index(a_from.m_index){
00060 #ifdef INLIB_MEM
00061     mem::increment(s_class().c_str());
00062 #endif
00063   }
00064   base_col& operator=(const base_col& a_from){
00065     m_name = a_from.m_name;
00066     m_index = a_from.m_index;
00067     return *this;
00068   }
00069 public:
00070   std::string name() {return m_name;}
00071   const std::string& name() const {return m_name;}
00072 
00073   void set_index(uint64 a_index){m_index = a_index;}
00074 protected:
00075   std::ostream& m_out;
00076   std::string m_name;
00077   uint64 m_index;
00078 };
00079 
00080 class base_ntu {
00081 public:
00082   static const std::string& s_class() {
00083     static const std::string s_v("inlib::aida::base_ntu");
00084     return s_v;
00085   }
00086   virtual void* cast(const std::string& a_class) const {
00087     if(void* p = cmp_cast<base_ntu>(this,a_class)) {return p;}
00088     else return 0;
00089   }
00090 protected:
00091 #ifdef ANDROID_NDK
00092   base_ntu():m_out(std::cout),m_index(-1){} //Android : for inlib STL.
00093 #endif
00094   base_ntu(std::ostream& a_out,const std::string& a_title)
00095   :m_out(a_out),m_title(a_title),m_index(-1){
00096 #ifdef INLIB_MEM
00097     mem::increment(s_class().c_str());
00098 #endif
00099   }
00100   virtual ~base_ntu() {
00101     clear();
00102 #ifdef INLIB_MEM
00103     mem::decrement(s_class().c_str());
00104 #endif
00105   }
00106 protected:
00107   base_ntu(const base_ntu& a_from)
00108   :m_out(a_from.m_out)
00109   ,m_title(a_from.m_title),m_index(a_from.m_index)
00110   {
00111 #ifdef INLIB_MEM
00112     mem::increment(s_class().c_str());
00113 #endif
00114     std::vector<base_col*>::const_iterator it;
00115     for(it=a_from.m_cols.begin();it!=a_from.m_cols.end();++it) {
00116       base_col* column = (*it)->copy();
00117       if(!column) {
00118         m_out << s_class() << "::cstor :"
00119               << " can't copy column."
00120               << std::endl;
00121         inlib::clear<base_col>(m_cols);
00122         m_index = -1;
00123         return; //throw
00124       }
00125       m_cols.push_back(column);
00126     }
00127   }
00128   base_ntu& operator=(const base_ntu& a_from){
00129     inlib::clear<base_col>(m_cols);
00130     m_index = a_from.m_index;
00131 
00132     m_title = a_from.m_title;
00133     std::vector<base_col*>::const_iterator it;
00134     for(it=a_from.m_cols.begin();it!=a_from.m_cols.end();++it) {
00135       base_col* column = (*it)->copy();
00136       if(!column) {
00137         m_out << s_class() << "::operator=() :"
00138               << " can't copy column."
00139               << std::endl;
00140         inlib::clear<base_col>(m_cols);
00141         m_index = -1;
00142         return *this;
00143       }
00144       m_cols.push_back(column);
00145     }
00146 
00147     return *this;
00148   }
00149 public:
00150   std::ostream& out() {return m_out;}
00151   const std::vector<base_col*>& cols() const {return m_cols;}
00152 
00153   std::string title() {return m_title;}
00154   const std::string& title() const {return m_title;}
00155   void set_title(const std::string& a_title) {m_title = a_title;}
00156 
00157   uint64 rows() const {
00158     if(m_cols.empty()) return 0;
00159     return m_cols.front()->num_elems();
00160   }
00161 
00162   void clear() { //must not be confused with reset().
00163     inlib::clear<base_col>(m_cols);
00164     m_index = -1;
00165   }
00166 
00167   bool reset() { //clear data in columns (but not the column set)
00168     bool status = true;
00169     std::vector<base_col*>::iterator it;
00170     for(it=m_cols.begin();it!=m_cols.end();++it) {
00171       if(!(*it)->reset()) status = false;
00172     }
00173     m_index = -1;
00174     return status;
00175   }
00176 
00177   // reading :
00178   void start() {m_index = -1;set_columns_index(0);}
00179   bool next() { 
00180     // a tuple loop is of the form :
00181     //  tuple.start();
00182     //  while(tuple.next()) {
00183     //    ...
00184     //    double v;
00185     //    if(!col->get_entry(v)) {}
00186     //    ...
00187     //  }
00188     if((m_index+1)>=(int64)rows()) return false;
00189     m_index++;
00190     set_columns_index(m_index);
00191     return true;
00192   }
00193   int64 row_index() const {return m_index;}
00194 
00195   // filling :
00196   bool add_row() {
00197     bool status = true;
00198     std::vector<base_col*>::iterator it;
00199     for(it=m_cols.begin();it!=m_cols.end();++it) {
00200       if(!(*it)->add()) status = false;
00201     }
00202     return status;
00203   }
00204 
00205 public:
00206   base_col* find_column(const std::string& a_name){
00207     return find_named<base_col>(m_cols,a_name);
00208   }
00209 
00210   void add_column(base_col* a_col) { //we take ownership.
00211     m_cols.push_back(a_col);
00212   }
00213 protected:
00214   void set_columns_index(uint64 a_index) {
00215     std::vector<base_col*>::iterator it;
00216     for(it=m_cols.begin();it!=m_cols.end();++it) {
00217       (*it)->set_index(a_index);
00218     }
00219   }
00220 protected:
00221   std::ostream& m_out;
00222   std::string m_title;
00223   int64 m_index;
00224   std::vector<base_col*> m_cols;
00225 };
00226 
00227 }}
00228 
00229 #include "tos"
00230 #include "sto"
00231 #include "columns"
00232 #include "stype"
00233 
00234 namespace inlib {
00235 namespace aida {
00236 
00237 //inline const std::string& s_aida_type(char) {
00238 //  static const std::string s_v("char");
00239 //  return s_v;
00240 //}
00241 inline const std::string& s_aida_type(short) {
00242   static const std::string s_v("short");
00243   return s_v;
00244 }
00245 inline const std::string& s_aida_type(int) {
00246   static const std::string s_v("int");
00247   return s_v;
00248 }
00249 inline const std::string& s_aida_type(float) {
00250   static const std::string s_v("float");
00251   return s_v;
00252 }
00253 inline const std::string& s_aida_type(double) {
00254   static const std::string s_v("double");
00255   return s_v;
00256 }
00257 
00260 //inline const std::string& s_aida_type(unsigned char) {
00261 //  static const std::string s_v("byte");
00262 //  return s_v;
00263 //}
00264 
00265 inline const std::string& s_aida_type(bool) {
00266   static const std::string s_v("boolean");
00267   return s_v;
00268 }
00269 inline const std::string& s_aida_type(const std::string&) {
00270   static const std::string s_v("string");
00271   return s_v;
00272 }
00273 inline const std::string& s_aida_type(int64) {
00274   static const std::string s_v("long");
00275   return s_v;
00276 }
00277 inline const std::string& s_aida_type(const std::vector<double>&) {
00278   static const std::string s_v("double[]");
00279   return s_v;
00280 }
00281 
00282 inline const std::string& s_aida_type_ituple() {
00283   static const std::string s_v("ITuple");
00284   return s_v;
00285 }
00286 
00290 inline const std::string& s_aida_type(unsigned short) {
00291   static const std::string s_v("ushort");
00292   return s_v;
00293 }
00294 inline const std::string& s_aida_type(unsigned int) {
00295   static const std::string s_v("uint");
00296   return s_v;
00297 }
00298 inline const std::string& s_aida_type(uint64) {
00299   static const std::string s_v("ulong");
00300   return s_v;
00301 }
00302 
00303 class aida_base_col : public base_col {
00304 public:
00305   static const std::string& s_class() {
00306     static const std::string s_v("inlib::aida::aida_base_col");
00307     return s_v;
00308   }
00309   virtual void* cast(const std::string& a_class) const {
00310     if(void* p = cmp_cast<aida_base_col>(this,a_class)) {return p;}
00311     else return base_col::cast(a_class);
00312   }
00313 public:
00314   virtual std::string aida_type() const = 0;
00315   virtual bool s_default_value(std::string&) const = 0;
00316   virtual bool s_value(std::string&) const = 0;
00317   virtual bool s_fill(const std::string&) = 0;
00318 public:
00319   aida_base_col(std::ostream& a_out,const std::string& a_name)
00320   : base_col(a_out,a_name){}
00321 public:
00322   virtual ~aida_base_col(){}
00323 public:
00324   aida_base_col(const aida_base_col& a_from)
00325   : base_col(a_from)
00326   {}
00327   aida_base_col& operator=(const aida_base_col& a_from){
00328     base_col::operator=(a_from);
00329     return *this;
00330   }
00331 };
00332 
00333 inline bool s__fill(const std::string& a_s,std::string& a_v) {
00334   a_v = a_s;
00335   return true;
00336 }
00337 inline bool s__fill(const std::string& a_s,char& a_v) {
00338   //for exlib/cbk/aida_ntu
00339   if(a_s.empty()) return false;
00340   a_v = a_s[0];
00341   return true;
00342 }
00343 inline bool s__fill(const std::string& a_s,unsigned char& a_v) {
00344   //for exlib/cbk/aida_ntu
00345   if(a_s.empty()) return false;
00346   a_v = a_s[0];
00347   return true;
00348 }
00349 inline bool s__fill(const std::string& a_s,bool& a_v) {
00350   return to(a_s,a_v);
00351 }
00352 inline bool s__fill(const std::string& a_s,short& a_v) {
00353   return to<short>(a_s,a_v);
00354 }
00355 inline bool s__fill(const std::string& a_s,unsigned short& a_v) {
00356   return to<unsigned short>(a_s,a_v);
00357 }
00358 inline bool s__fill(const std::string& a_s,int& a_v) {
00359   return to<int>(a_s,a_v);
00360 }
00361 inline bool s__fill(const std::string& a_s,unsigned int& a_v) {
00362   return to<unsigned int>(a_s,a_v);
00363 }
00364 inline bool s__fill(const std::string& a_s,int64& a_v) {
00365   return to<int64>(a_s,a_v);
00366 }
00367 inline bool s__fill(const std::string& a_s,uint64& a_v) {
00368   return to<uint64>(a_s,a_v);
00369 }
00370 inline bool s__fill(const std::string& a_s,float& a_v) {
00371   return to<float>(a_s,a_v);
00372 }
00373 inline bool s__fill(const std::string& a_s,double& a_v) {
00374   return to<double>(a_s,a_v);
00375 }
00376 
00377 template <class T>
00378 class aida_col : public aida_base_col {
00379 public:
00380   static const std::string& s_class() {
00381     static const std::string s_v("inlib::aida::aida_col<"+stype(T())+">");
00382     return s_v;
00383   }
00384   virtual void* cast(const std::string& a_class) const {
00385     if(void* p = cmp_cast< aida_col<T> >(this,a_class)) {return p;}
00386     else return aida_base_col::cast(a_class);
00387   }
00388 public:
00389   virtual base_col* copy() const {return new aida_col(*this);}
00390   virtual bool add() {m_data.push_back(m_tmp);m_tmp = m_default;return true;}
00391   virtual bool reset() {
00392     m_data.clear();
00393     m_index = 0;
00394     m_tmp = m_default;
00395     return true;
00396   }
00397   virtual uint64 num_elems() const {return m_data.size();}
00398 public:
00399   virtual std::string aida_type() const {return s_aida_type(T());}
00400   virtual bool s_default_value(std::string& a_s) const {
00401     a_s = tos(m_default);
00402     return true;
00403   }
00404   virtual bool s_value(std::string& a_s) const {
00405     typedef typename std::vector<T>::size_type sz_t;
00406     a_s = tos(m_data[sz_t(m_index)]);
00407     return true;
00408   }
00409 
00410   // for exlib/raxml/tuple :
00411   virtual bool s_fill(const std::string& a_s) {
00412     //if(!to<T>(a_s,m_tmp)) {
00413     if(!s__fill(a_s,m_tmp)) {
00414       m_out << s_class() << "::fill :"
00415             << " can't convert " << sout(a_s) << "."
00416             << std::endl;
00417       return false;
00418     }
00419     return true;
00420   }
00421 public:
00422   aida_col(std::ostream& a_out,const std::string& a_name,const T& a_def)
00423   : aida_base_col(a_out,a_name)
00424   ,m_default(a_def)
00425   ,m_tmp(a_def){}
00426 public:
00427   virtual ~aida_col(){}
00428 public:
00429   aida_col(const aida_col& a_from)
00430   : aida_base_col(a_from)
00431   ,m_data(a_from.m_data)
00432   ,m_default(a_from.m_default)
00433   ,m_tmp(a_from.m_tmp)
00434   {}
00435   aida_col& operator=(const aida_col& a_from){
00436     aida_base_col::operator=(a_from);
00437     m_data = a_from.m_data;
00438     m_default = a_from.m_default;
00439     m_tmp = a_from.m_tmp;
00440     return *this;
00441   }
00442 public:
00443   bool fill(const T& a_value) {m_tmp = a_value;return true;}
00444   bool get_entry(T& a_v) const {
00445     if(m_index>=m_data.size()) {
00446       m_out << s_class() << "::get_entry :"
00447             << " bad index " << m_index
00448             << ". Vec size is " << m_data.size() << "."
00449             << "."
00450             << std::endl;
00451       a_v = T();
00452       return false;
00453     }
00454     typedef typename std::vector<T>::size_type sz_t;
00455     a_v = m_data[sz_t(m_index)];
00456     return true;
00457   }
00458 protected:
00459   std::vector<T> m_data;
00460   T m_default;
00461   T m_tmp;
00462 };
00463 
00464 class ntuple : public base_ntu {
00465 public:
00466   static const std::string& s_class() {
00467     static const std::string s_v("inlib::aida::ntuple");
00468     return s_v;
00469   }
00470   virtual void* cast(const std::string& a_class) const {
00471     if(void* p = cmp_cast<ntuple>(this,a_class)) {return p;}
00472     else return base_ntu::cast(a_class);
00473   }
00474 public:
00475 #ifdef ANDROID_NDK
00476   ntuple(){} //Android : for inlib STL.
00477 #endif
00478   ntuple(std::ostream& a_out,const std::string& a_title)
00479   : base_ntu(a_out,a_title)
00480   {}
00481   virtual ~ntuple() {}
00482 public:
00483   ntuple(const ntuple& a_from): base_ntu(a_from){}
00484   ntuple& operator=(const ntuple& a_from){
00485     base_ntu::operator=(a_from);
00486     return *this;
00487   }
00488 public:
00489   template <class T>
00490   aida_col<T>* create_col(const std::string& a_name,
00491                                  const T& a_def = T()) {
00492     if(find_named<base_col>(m_cols,a_name)) {
00493       m_out << s_class() << "::create_col :"
00494             << " a column with name " << sout(a_name) << " already exists."
00495             << std::endl;
00496       return 0;
00497     }
00498     aida_col<T>* col = new aida_col<T>(m_out,a_name,a_def);
00499     if(!col) {
00500       m_out << s_class() << "::create_col :"
00501             << " can't create aida_col<T> " << sout(a_name) << "."
00502             << std::endl;
00503       return 0;
00504     }    
00505     m_cols.push_back(col);
00506     return col;
00507   }
00508 
00509   template <class T>
00510   aida_col<T>* find_column(const std::string& a_name){
00511     base_col* col = find_named<base_col>(m_cols,a_name);
00512     if(!col) return 0;
00513     return inlib::cast<base_col, aida_col<T> >(*col);
00514   }
00515 };
00516 
00520 
00521 class aida_col_ntu : public base_col {
00522 public:
00523   static const std::string& s_class() {
00524     static const std::string s_v("inlib::aida::aida_col_ntu");
00525     return s_v;
00526   }
00527   virtual void* cast(const std::string& a_class) const {
00528     if(void* p = cmp_cast<aida_col_ntu>(this,a_class)) {return p;}
00529     else return base_col::cast(a_class);
00530   }
00531 public:
00532   virtual base_col* copy() const {return new aida_col_ntu(*this);}
00533   virtual bool add() {m_data.push_back(m_tmp);m_tmp.reset();return true;}
00534   virtual bool reset() {m_data.clear();m_index = 0;return true;}
00535   virtual uint64 num_elems() const {return m_data.size();}
00536 public:
00537   base_ntu* get_entry() {
00538     if(m_index>=m_data.size()) {
00539       m_out << s_class() << "::get_entry :"
00540             << " bad index " << m_index
00541             << ". Vec size is " << m_data.size() << "."
00542             << "."
00543             << std::endl;
00544       return 0;
00545     }
00546     typedef std::vector<ntuple>::size_type sz_t;
00547     return &(m_data[sz_t(m_index)]);
00548   }
00549 
00550   virtual base_ntu* get_to_fill() {return &m_tmp;}
00551 public:
00552   aida_col_ntu(std::ostream& a_out,const std::string& a_name)
00553   : base_col(a_out,a_name)
00554   ,m_tmp(a_out,"tmp")
00555   {}
00556 public:
00557   virtual ~aida_col_ntu(){}
00558 public:
00559   aida_col_ntu(const aida_col_ntu& a_from)
00560   : base_col(a_from)
00561   ,m_data(a_from.m_data)
00562 
00563   ,m_tmp(a_from.m_tmp)
00564   {}
00565   aida_col_ntu& operator=(const aida_col_ntu& a_from){
00566     base_col::operator=(a_from);
00567     m_data = a_from.m_data;
00568 
00569     m_tmp = a_from.m_tmp;
00570     return *this;
00571   }
00572 protected:
00573   std::vector<ntuple> m_data;
00574   ntuple m_tmp;
00575 };
00576 
00577 inline bool create_cols_from_vals(ntuple& a_ntu,
00578                                   const std::vector<value>& a_vars,
00579                                   bool a_verbose = false){
00580   std::vector<value>::const_iterator it;
00581   for(it=a_vars.begin();it!=a_vars.end();++it) {
00582       if((*it).type()==value::VOID_STAR) {
00583         if(a_verbose){
00584           a_ntu.out() << "inlib::aida::create_cols_from_vals :"
00585                       << " ITuple : " << (*it).label() << " : begin "
00586                       << std::endl;
00587         }
00588         std::vector<value>* vars = 
00589           (std::vector<value>*)(*it).get_void_star();
00590 
00591         aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),(*it).label());
00592         // create sub columns on the the "fillable" of col_ntu :
00593         base_ntu* sub_base_ntu = col_ntu->get_to_fill();
00594         if(!sub_base_ntu) return false;
00595         ntuple* sub_aida =
00596           inlib::cast<base_ntu,ntuple>(*sub_base_ntu);
00597         if(!sub_aida) return false;
00598 
00599         if(!create_cols_from_vals(*sub_aida,*vars,a_verbose)) {
00600           delete col_ntu;
00601           return false;
00602         }
00603 
00604         a_ntu.add_column(col_ntu);
00605 
00606     } else {
00607         if(a_verbose){
00608           std::string stype;        
00609           (*it).s_type(stype);
00610           std::string sval;        
00611           (*it).tos(sval);
00612           a_ntu.out() << "inlib::aida::create_cols_from_vals :"
00613                       << " " << stype << " : " 
00614                       << (*it).label() << " : " 
00615                       << sval
00616                       << std::endl;
00617         }
00618 
00619         //   char,short,int,float,double
00620         //   byte,boolean,string,long(for int64)
00621         //   double[]
00622 
00623         base_col* col = 0;
00624       /*if((*it).type()==value::CHAR) {
00625           col = a_ntu.create_col<char>((*it).label(),(*it).get_char());
00626         } else*/ if((*it).type()==value::SHORT) {
00627           col = a_ntu.create_col<short>((*it).label(),(*it).get_short());
00628         } else if((*it).type()==value::INT) {
00629           col = a_ntu.create_col<int>((*it).label(),(*it).get_int());
00630         } else if((*it).type()==value::INT64) {
00631           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
00632         } else if((*it).type()==value::FLOAT) {
00633           col = a_ntu.create_col<float>((*it).label(),(*it).get_float());
00634         } else if((*it).type()==value::DOUBLE) {
00635           col = a_ntu.create_col<double>((*it).label(),(*it).get_double());
00636 
00637         //} else if((*it).type()==value::UNSIGNED_CHAR) {
00638         //  col = a_ntu.create_col<unsigned char>
00639         //          ((*it).label(),(*it).get_unsigned_char());
00640         } else if((*it).type()==value::UNSIGNED_SHORT) {
00641           col = a_ntu.create_col<unsigned short>
00642                   ((*it).label(),(*it).get_unsigned_short());
00643         } else if((*it).type()==value::UNSIGNED_INT) {
00644           col = a_ntu.create_col<unsigned int>
00645                   ((*it).label(),(*it).get_unsigned_int());
00646         } else if((*it).type()==value::UNSIGNED_INT64) {
00647           col = a_ntu.create_col<uint64>
00648                   ((*it).label(),(*it).get_unsigned_int64());
00649 
00650         } else if((*it).type()==value::BOOL) {
00651           col = a_ntu.create_col<bool>((*it).label(),(*it).get_bool());
00652         } else if((*it).type()==value::STRING) {
00653           col = a_ntu.create_col<std::string>
00654                   ((*it).label(),(*it).get_string());
00655         } else if((*it).type()==value::INT64) {
00656           col = a_ntu.create_col<int64>((*it).label(),(*it).get_int64());
00657         }
00658 
00659         if(!col) {
00660           std::string stype;        
00661           (*it).s_type(stype);
00662           std::string sval;        
00663           (*it).tos(sval);
00664           a_ntu.out() << "inlib::aida::create_cols_from_vals :"
00665                       << " failed for " << stype << " : " 
00666                       << (*it).label() << " : " 
00667                       << sval
00668                       << std::endl;
00669           return false;
00670         }
00671       }
00672   }
00673   return true;
00674 }
00675 
00676 // for raxml :
00677 inline bool create_col(ntuple& a_ntu,
00678                        const std::string& a_type,
00679                        const std::string& a_name,
00680                        const std::string& a_s, //def or booking.
00681                        bool a_is_ntu){
00682 /*
00683   if(a_type==s_aida_type((char)0)) {
00684     char v;
00685     if(!to<char>(a_s,v)) {
00686       a_ntu.out() << "inlib::aida::create_col :" 
00687                   << " can't convert def " << sout(a_s)
00688                   << " to a " << a_type
00689                   << std::endl;
00690       return false;
00691     }
00692     if(!a_ntu.create_col<char>(a_name,v)) {
00693       a_ntu.out() << "inlib::aida::create_col :" 
00694                   << " can't create column of type " << sout(a_type)
00695                   << std::endl;
00696       return false;
00697     }
00698 
00699   } else*/ if(a_type==s_aida_type((short)0)) {
00700     short v;
00701     if(!to<short>(a_s,v)) {
00702       a_ntu.out() << "inlib::aida::create_col :" 
00703                   << " can't convert def " << sout(a_s)
00704                   << " to a " << a_type
00705                   << std::endl;
00706       return false;
00707     }
00708     if(!a_ntu.create_col<short>(a_name,v)) {
00709       a_ntu.out() << "inlib::aida::create_col :" 
00710                   << " can't create column of type " << sout(a_type)
00711                   << std::endl;
00712       return false;
00713     }
00714 
00715   } else if(a_type==s_aida_type((int)0)) {
00716     int v;
00717     if(!to<int>(a_s,v)) {
00718       a_ntu.out() << "inlib::aida::create_col :" 
00719                   << " can't convert def " << sout(a_s)
00720                   << " to a " << a_type
00721                   << std::endl;
00722       return false;
00723     }
00724     if(!a_ntu.create_col<int>(a_name,v)) {
00725       a_ntu.out() << "inlib::aida::create_col :" 
00726                   << " can't create column of type " << sout(a_type)
00727                   << std::endl;
00728       return false;
00729     }
00730 
00731   } else if(a_type==s_aida_type((int64)0)) {
00732     int64 v;
00733     if(!to<int64>(a_s,v)) {
00734       a_ntu.out() << "inlib::aida::create_col :" 
00735                   << " can't convert def " << sout(a_s)
00736                   << " to a " << a_type
00737                   << std::endl;
00738       return false;
00739     }
00740     if(!a_ntu.create_col<int64>(a_name,v)) {
00741       a_ntu.out() << "inlib::aida::create_col :" 
00742                   << " can't create column of type " << sout(a_type)
00743                   << std::endl;
00744       return false;
00745     }
00746 
00747   } else if(a_type==s_aida_type((float)0)) {
00748     float v;
00749     if(!to<float>(a_s,v)) {
00750       a_ntu.out() << "inlib::aida::create_col :" 
00751                   << " can't convert def " << sout(a_s)
00752                   << " to a " << a_type
00753                   << std::endl;
00754       return false;
00755     }
00756     if(!a_ntu.create_col<float>(a_name,v)) {
00757       a_ntu.out() << "inlib::aida::create_col :" 
00758                   << " can't create column of type " << sout(a_type)
00759                   << std::endl;
00760       return false;
00761     }
00762 
00763 
00764   } else if(a_type==s_aida_type((double)0)) {
00765     double v;
00766     if(!to<double>(a_s,v)) {
00767       a_ntu.out() << "inlib::aida::create_col :" 
00768                   << " can't convert def " << sout(a_s)
00769                   << " to a " << a_type
00770                   << std::endl;
00771       return false;
00772     }
00773     if(!a_ntu.create_col<double>(a_name,v)) {
00774       a_ntu.out() << "inlib::aida::create_col :" 
00775                   << " can't create column of type " << sout(a_type)
00776                   << std::endl;
00777       return false;
00778     }
00779 
00780 /*  } else if(a_type==s_aida_type((unsigned char)0)) { //byte
00781     unsigned int v;
00782     if(!to<unsigned int>(a_s,v)) {
00783       a_ntu.out() << "inlib::aida::create_col :" 
00784                   << " can't convert def " << sout(a_s)
00785                   << " to a " << a_type
00786                   << std::endl;
00787       return false;
00788     }    
00789     if(v>=256) {
00790       a_ntu.out() << "inlib::aida::create_col :" 
00791                   << " can't convert def " << sout(a_s)
00792                   << " to byte."
00793                   << std::endl;
00794       return false;
00795     }
00796     if(!a_ntu.create_col<unsigned char>(a_name,v)) {
00797       a_ntu.out() << "inlib::aida::create_col :" 
00798                   << " can't create column of type " << sout(a_type)
00799                   << std::endl;
00800       return false;
00801     }
00802 */
00803   } else if(a_type==s_aida_type((unsigned short)0)) {
00804     unsigned short v;
00805     if(!to<unsigned short>(a_s,v)) {
00806       a_ntu.out() << "inlib::aida::create_col :" 
00807                   << " can't convert def " << sout(a_s)
00808                   << " to a " << a_type
00809                   << std::endl;
00810       return false;
00811     }
00812     if(!a_ntu.create_col<unsigned short>(a_name,v)) {
00813       a_ntu.out() << "inlib::aida::create_col :" 
00814                   << " can't create column of type " << sout(a_type)
00815                   << std::endl;
00816       return false;
00817     }
00818 
00819   } else if(a_type==s_aida_type((unsigned int)0)) {
00820     unsigned int v;
00821     if(!to<unsigned int>(a_s,v)) {
00822       a_ntu.out() << "inlib::aida::create_col :" 
00823                   << " can't convert def " << sout(a_s)
00824                   << " to a " << a_type
00825                   << std::endl;
00826       return false;
00827     }
00828     if(!a_ntu.create_col<unsigned int>(a_name,v)) {
00829       a_ntu.out() << "inlib::aida::create_col :" 
00830                   << " can't create column of type " << sout(a_type)
00831                   << std::endl;
00832       return false;
00833     }
00834 
00835   } else if(a_type==s_aida_type((uint64)0)) {
00836     uint64 v;
00837     if(!to<uint64>(a_s,v)) {
00838       a_ntu.out() << "inlib::aida::create_col :" 
00839                   << " can't convert def " << sout(a_s)
00840                   << " to a " << a_type
00841                   << std::endl;
00842       return false;
00843     }
00844     if(!a_ntu.create_col<uint64>(a_name,v)) {
00845       a_ntu.out() << "inlib::aida::create_col :" 
00846                   << " can't create column of type " << sout(a_type)
00847                   << std::endl;
00848       return false;
00849     }
00850 
00853   } else if(a_type==s_aida_type((bool)true)) {
00854     bool v;
00855     if(!to(a_s,v)) {
00856       a_ntu.out() << "inlib::aida::create_col :" 
00857                   << " can't convert def " << sout(a_s)
00858                   << " to a " << a_type
00859                   << std::endl;
00860       return false;
00861     }
00862     if(!a_ntu.create_col<bool>(a_name,v)) {
00863       a_ntu.out() << "inlib::aida::create_col :" 
00864                   << " can't create column of type " << sout(a_type)
00865                   << std::endl;
00866       return false;
00867     }
00868 
00869   } else if(a_type==s_aida_type(std::string())) {
00870     if(!a_ntu.create_col<std::string>(a_name,a_s)) {
00871       a_ntu.out() << "inlib::aida::create_col :" 
00872                   << " can't create column of type " << sout(a_type)
00873                   << std::endl;
00874       return false;
00875     }
00876 
00877   } else if(a_type==s_aida_type((int64)0)) {
00878     int64 v;
00879     if(!to<int64>(a_s,v)) {
00880       a_ntu.out() << "inlib::aida::create_col :" 
00881                   << " can't convert def " << sout(a_s)
00882                   << " to a " << a_type
00883                   << std::endl;
00884       return false;
00885     }
00886     if(!a_ntu.create_col<int64>(a_name,v)) {
00887       a_ntu.out() << "inlib::aida::create_col :" 
00888                   << " can't create column of type " << sout(a_type)
00889                   << std::endl;
00890       return false;
00891     }
00892 
00893   } else if(a_type==s_aida_type_ituple()) {
00894     // we expect a booking string on a_s.
00895 
00896     if(!a_is_ntu) {
00897       a_ntu.out() << "inlib::aida::create_col :" 
00898                   << " mismatch a_is_ntu/a_type."
00899                   << std::endl;
00900       return false;
00901     }
00902     if(a_s.empty()) {
00903       a_ntu.out() << "inlib::aida::create_col :" 
00904                   << " empty booking string."
00905                   << std::endl;
00906       return false;
00907     }
00908 
00909     columns::finder f(a_ntu.out(),a_s);
00910     if(!f.find_variables()) {
00911       a_ntu.out() << "inlib::aida::create_col :" 
00912             << " find_variables() failed for " << sout(a_s) << "."
00913             << std::endl;
00914       return false;
00915     }
00916 
00917     aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),a_name);
00918     //create columns on the fillable.
00919     base_ntu* sub_base_ntu = col_ntu->get_to_fill();
00920     if(!sub_base_ntu) {delete col_ntu;return false;}
00921     ntuple* sub_aida = inlib::cast<base_ntu,ntuple>(*sub_base_ntu);
00922     if(!sub_aida) {delete col_ntu;return false;}
00923 
00924     std::vector<value> vars = f.result();
00925     if(!create_cols_from_vals(*sub_aida,vars)) {
00926       columns::delete_columns(vars);
00927       delete col_ntu;
00928       return false;
00929     }
00930     columns::delete_columns(vars);
00931     a_ntu.add_column(col_ntu);
00932 
00933     //FIXME : double[]
00934 
00935   } else {
00936     a_ntu.out() << "inlib::aida::create_col :" 
00937                 << " col type " << sout(a_type)
00938                 << " not yet handled."
00939                 << std::endl;
00940     return false;
00941   }
00942 
00943   return true;
00944 }
00945 
00946 // for waxml :
00947 inline bool create_cols_from_string(ntuple& a_ntu,
00948                                     const std::string& a_booking,
00949                                     bool a_verbose = false){
00950   a_ntu.clear();
00951   if(a_booking.empty()) {
00952     a_ntu.out() << "inlib::aida::create_cols_from_string :"
00953                 << " empty booking string."
00954                 << std::endl;
00955     return false;
00956   }
00957 
00958   columns::finder f(a_ntu.out(),a_booking);
00959   if(!f.find_variables()) {
00960     a_ntu.out() << "inlib::aida::create_cols_from_string :"
00961           << " find_variables() failed."
00962           << std::endl;
00963     return false;
00964   }
00965   std::vector<value> vars = f.result();
00966   if(a_verbose) columns::dump_columns(a_ntu.out(),vars);
00967 
00968   if(!create_cols_from_vals(a_ntu,vars)) {
00969     columns::delete_columns(vars);
00970     a_ntu.clear();
00971     return false;
00972   }
00973   columns::delete_columns(vars);
00974   return true;
00975 }
00976 
00977 inline aida_col_ntu* find_col_ntu(ntuple& a_ntu,
00978                                   const std::string& a_name){
00979   base_col* col = find_named<base_col>(a_ntu.cols(),a_name);
00980   if(!col) return 0;
00981   return inlib::cast<base_col, aida_col_ntu >(*col);
00982 }
00983 
00984 template <class T>
00985 class base_looper {
00986 public:
00987   static const std::string& s_class() {
00988     static const std::string s_v("inlib::aida::base_looper<"+stype(T())+">");
00989     return s_v;
00990   }
00991 protected:
00992   virtual bool action(const T& a_value) = 0; //return false to stop processing.
00993 public:
00994   base_looper(base_ntu& a_ntu,const base_col& a_col)
00995   :m_ntu(a_ntu),m_col(a_col){
00996 #ifdef INLIB_MEM
00997     mem::increment(s_class().c_str());
00998 #endif
00999   }
01000   virtual ~base_looper(){
01001 #ifdef INLIB_MEM
01002     mem::decrement(s_class().c_str());
01003 #endif
01004   }
01005 public:
01006   base_looper(const base_looper& a_from)
01007   :m_ntu(a_from.m_ntu),m_col(a_from.m_col){
01008 #ifdef INLIB_MEM
01009     mem::increment(s_class().c_str());
01010 #endif
01011   }
01012   base_looper& operator=(const base_looper& a_from){return *this;}
01013 public:
01014   bool process() {
01015     std::vector<unsigned int> is;
01016     bool found = false;
01017     if(!find_is(m_ntu,&m_col,is,found)) {
01018       m_ntu.out() << s_class() << "::process :"
01019                   << " find_is failed."
01020                   << std::endl;
01021       return false;
01022     }
01023     if(!found) {
01024       m_ntu.out() << s_class() << "::process :"
01025                   << " find_is : col not found."
01026                   << std::endl;
01027       return false;
01028     }
01029     if(is.empty()) {
01030       m_ntu.out() << s_class() << "::process :"
01031                   << " is vec empty."
01032                   << std::endl;
01033       return false;
01034     }
01035 
01036   //{m_ntu.out() << "debug : sz " << is.size() << std::endl;
01037   // std::vector<unsigned int>::const_iterator it;
01038   // for(it=is.begin();it!=is.end();++it){
01039   //   m_ntu.out() << "  " << *it << std::endl;       
01040   //}}
01041 
01042     bool stop = false;
01043     if(!_looper(m_ntu,is,0,stop)) {
01044       m_ntu.out() << s_class() << "::process :"
01045                   << " _looper failed."
01046                   << std::endl;
01047       return false;
01048     }
01049     return true;
01050   }
01051 protected:
01052   static bool find_is(const base_ntu& a_ntu,const base_col* a_col,
01053                              std::vector<unsigned int>& a_is,
01054                              bool& a_found){
01055     // search the indices to reach the sub leaf a_col from the main a_ntu.    
01056     // Note : it is assumed that a_is is empty and a_found = false before
01057     //        calling with function.
01058   
01059     const std::vector<base_col*>& cols = a_ntu.cols();
01060     std::vector<base_col*>::const_iterator it;
01061   
01062     // look if a_col is a leaf col of a_ntu :
01063    {unsigned int index = 0;
01064     for(it=cols.begin();it!=cols.end();++it,index++) {
01065       if(*it==a_col) {
01066         a_is.push_back(index); //leaf index is the last one in a_is.
01067         a_found = true;
01068         return true;
01069       }
01070     }}
01071   
01072     // go down sub ntu :
01073    {unsigned int index = 0;
01074     for(it=cols.begin();it!=cols.end();++it,index++) {
01075       aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(*it));
01076       if(!col) continue;
01077       base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
01078       if(!sub) {a_is.clear();return false;}
01079       a_is.push_back(index);
01080       if(!find_is(*sub,a_col,a_is,a_found)) {a_is.clear();return false;}
01081       if(a_found) return true;
01082       a_is.pop_back();
01083     }}
01084     return true;
01085   }  
01086 protected:
01087   bool _looper(base_ntu& a_sub,
01088                       const std::vector<unsigned int>& a_is,
01089                       unsigned int a_depth,
01090                       bool& a_stop) {
01091     if(a_depth>=a_is.size()) return false;
01092 
01093     unsigned int coli = a_is[a_depth];  
01094     const std::vector<base_col*>& cols = a_sub.cols();
01095     if(coli>=cols.size()) return false;
01096 
01097     if(a_depth==(a_is.size()-1)) { //we reach the leaf.
01098       aida_col<T>* col = cast<base_col, aida_col<T> >(*(cols[coli]));
01099       if(!col) return false;
01100       a_sub.start();
01101       while(a_sub.next()) {
01102         T v;
01103         if(!col->get_entry(v)) return false;
01104         if(!action(v)) {a_stop = true;break;}
01105       }
01106     } else {
01107       aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(cols[coli]));
01108       if(!col) return false;
01109       a_sub.start();
01110       while(a_sub.next()) {
01111         base_ntu* ntu = col->get_entry(); //not const.
01112         if(!ntu) return false;
01113         ntu->start();
01114         while(ntu->next()) {
01115           if(!_looper(*ntu,a_is,a_depth+1,a_stop)) return false;
01116           if(a_stop) break;
01117         }
01118       }
01119     }
01120     return true;
01121   }
01122 protected:
01123   base_ntu& m_ntu;
01124   const base_col& m_col;
01125 };
01126 
01127 }}
01128 
01129 #include "mnmx"
01130 
01131 namespace inlib {
01132 namespace aida {
01133 
01134 template <class T>
01135 class stat_looper : public base_looper<T> {
01136 protected:
01137   virtual bool action(const T& a_v) {
01138     if(m_first) {
01139       m_mn = a_v;
01140       m_mx = a_v;
01141       m_S = a_v;
01142       m_S2 = a_v*a_v;
01143 
01144       m_first = false;
01145     } else {
01146       m_mn = inlib::mn<T>(m_mn,a_v);
01147       m_mx = inlib::mx<T>(m_mx,a_v);
01148       m_S += a_v;
01149       m_S2 += a_v*a_v;
01150     }
01151     m_counter++;
01152     return true; //continue looping.
01153   }
01154 public:
01155   stat_looper(base_ntu& a_ntu,const base_col& a_col)
01156   : base_looper<T>(a_ntu,a_col)
01157   ,m_first(true)
01158   ,m_mn(T())
01159   ,m_mx(T())
01160   ,m_S(T())
01161   ,m_S2(T())
01162   ,m_counter(0)
01163   {}
01164   virtual ~stat_looper(){}
01165 public:
01166   stat_looper(const stat_looper& a_from)
01167   : base_looper<T>(a_from)
01168   ,m_first(true)
01169   ,m_mn(T())
01170   ,m_mx(T())
01171   ,m_S(T())
01172   ,m_S2(T())
01173   ,m_counter(0)
01174   {}
01175   stat_looper& operator=(const stat_looper& a_from){
01176     base_looper<T>::operator=(a_from);
01177     m_first = true;
01178     m_mn = T();
01179     m_mx = T();
01180     m_S = T();
01181     m_S2 = T();
01182     m_counter = 0;
01183     return *this;
01184   }  
01185 public:
01186   bool process() {
01187     m_counter = 0;
01188     if(!base_looper<T>::process()) {
01189       m_mn = T();
01190       m_mx = T();
01191       m_S = T();
01192       m_S2 = T();
01193       m_counter = 0;
01194       return false;
01195     }
01196     return true;
01197   }
01198   T mn() const {return m_mn;}
01199   T mx() const {return m_mx;}
01200   T S() const {return m_S;}
01201   T S2() const {return m_S2;}
01202   uint64 counter() const {return m_counter;}
01203 protected:
01204   bool m_first;
01205   T m_mn;
01206   T m_mx;
01207   T m_S;
01208   T m_S2;
01209   uint64 m_counter;
01210 };
01211 
01212 template <class T>
01213 inline bool column_infos(inlib::aida::base_ntu& a_ntu,
01214                          inlib::aida::base_col& a_col,
01215                          T& a_mn,T& a_mx,T& a_S,T& a_S2,
01216                          inlib::uint64& a_count){
01217   inlib::aida::stat_looper<T> lpr(a_ntu,a_col);
01218   bool status = lpr.process();
01219   a_mn = lpr.mn();
01220   a_mx = lpr.mx();
01221   a_S = lpr.S();
01222   a_S2 = lpr.S2();
01223   a_count = lpr.counter();
01224   if(!status) return false;
01225   if(!a_count) return false;
01226   return true;
01227 }
01228 
01229 inline base_col* find_leaf_column(const base_ntu& a_ntu,
01230                               const std::string& a_name){
01231   const std::vector<base_col*>& cols = a_ntu.cols();
01232   std::vector<base_col*>::const_iterator it;  
01233   for(it=cols.begin();it!=cols.end();++it) {
01234     aida_col_ntu* col = cast<base_col,aida_col_ntu>(*(*it));
01235     if(col) {
01236       base_ntu* sub = col->get_to_fill(); //it holds the "sub" cols schema.
01237       if(!sub) return 0;
01238       base_col* fcol = find_leaf_column(*sub,a_name);
01239       if(fcol) return fcol;      
01240     } else {
01241       if((*it)->name()==a_name) return *it;
01242     }
01243   }
01244   return 0;
01245 }  
01246 
01247 }}
01248 
01249 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines