inlib
1.2.0
|
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