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_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