Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_waxml_ntuple 5 #define tools_waxml_ntuple 6 7 // A ntuple class to write at the aida tuple f 8 // Each add_row() write a row at the aida tupl 9 10 #include "../vfind" 11 #include "../vmanip" 12 #include "../sout" 13 #include "../srep" 14 #include "../tos" 15 #include "../forit" 16 17 #include <ostream> 18 19 // for sub_ntuple : 20 #include "../scast" 21 #include <sstream> 22 23 #include "../ntuple_booking" 24 25 namespace tools { 26 namespace waxml { 27 28 class ntuple { 29 protected: 30 31 class iobj { 32 public: 33 virtual ~iobj(){} 34 public: 35 virtual void* cast(cid) const = 0; 36 virtual cid id_cls() const = 0; 37 public: 38 virtual const std::string& name() const = 39 virtual const std::string& aida_type() con 40 }; 41 42 class leaf : public virtual iobj { 43 public: 44 static cid id_class() {return 100;} 45 public: //iobj 46 virtual void* cast(cid a_class) const { 47 if(void* p = cmp_cast<leaf>(this,a_class 48 return 0; 49 } 50 virtual cid id_cls() const {return id_clas 51 public: 52 virtual const std::string& s_def() const = 53 virtual void s_value(std::string&) const = 54 public: 55 leaf(){} 56 virtual ~leaf(){} 57 leaf(const leaf& a_from):iobj(a_from){} 58 leaf& operator=(const leaf&){return *this; 59 }; 60 61 static const std::string& s_aida_type(int) { 62 static const std::string s_v("int"); 63 return s_v; 64 } 65 static const std::string& s_aida_type(float) 66 static const std::string s_v("float"); 67 return s_v; 68 } 69 static const std::string& s_aida_type(double 70 static const std::string s_v("double"); 71 return s_v; 72 } 73 static const std::string& s_aida_type(const 74 static const std::string s_v("string"); 75 return s_v; 76 } 77 78 static const std::string& s_aida_type_ituple 79 static const std::string s_v("ITuple"); 80 return s_v; 81 } 82 83 public: 84 template <class T> 85 class column : public leaf { 86 public: 87 static cid id_class() {return 200+_cid(T() 88 public: //iobj 89 virtual void* cast(cid a_class) const { 90 if(void* p = cmp_cast< column<T> >(this, 91 return leaf::cast(a_class); 92 } 93 virtual cid id_cls() const {return id_clas 94 public: 95 virtual const std::string& name() const {r 96 virtual const std::string& aida_type() con 97 public: //leaf 98 virtual const std::string& s_def() const { 99 virtual void s_value(std::string& a_s) con 100 public: 101 column(const std::string& a_name,const T& 102 :m_name(a_name),m_def(tos(a_def)),m_tmp(a_ 103 {} 104 virtual ~column(){} 105 protected: 106 column(const column& a_from) 107 :leaf(a_from) 108 ,m_name(a_from.m_name) 109 ,m_def(a_from.m_def) 110 ,m_tmp(a_from.m_tmp) 111 {} 112 column& operator=(const column& a_from){ 113 m_name = a_from.m_name; 114 m_def = a_from.m_def; 115 m_tmp = a_from.m_tmp; 116 return *this; 117 } 118 public: 119 bool fill(const T& a_value) {m_tmp = a_val 120 protected: 121 std::string m_name; 122 std::string m_def; 123 T m_tmp; 124 }; 125 126 127 class sub_ntuple : public virtual iobj { 128 public: 129 static cid id_class() {return 300;} 130 public: //iobj 131 virtual void* cast(cid a_class) const { 132 if(void* p = cmp_cast<sub_ntuple>(this,a 133 return 0; 134 } 135 virtual cid id_cls() const {return id_clas 136 public: 137 virtual const std::string& name() const {r 138 virtual const std::string& aida_type() con 139 public: 140 sub_ntuple(const std::string& a_name,const 141 :m_name(a_name),m_spaces(a_spaces){} 142 virtual ~sub_ntuple(){} 143 protected: 144 sub_ntuple(const sub_ntuple& a_from) 145 :iobj(a_from),m_name(a_from.m_name){} 146 sub_ntuple& operator=(const sub_ntuple&){r 147 public: 148 template <class T> 149 column<T>* create_column(const std::string 150 if(find_named<iobj>(m_cols,a_name)) retu 151 column<T>* col = new column<T>(a_name,a_ 152 if(!col) return 0; 153 m_cols.push_back(col); 154 return col; 155 } 156 157 sub_ntuple* create_sub_ntuple(const std::s 158 if(find_named<iobj>(m_cols,a_name)) retu 159 std::string spaces; 160 for(unsigned int i=0;i<4;i++) spaces += 161 sub_ntuple* col = new sub_ntuple(a_name, 162 if(!col) return 0; 163 m_cols.push_back(col); 164 return col; 165 } 166 167 168 const std::vector<iobj*>& columns() const 169 170 std::string booking(bool a_xml_esc) const 171 std::string _s; 172 get_booking(m_cols,a_xml_esc,_s); 173 return _s; 174 } 175 void reset() {m_tmp.clear();} 176 const std::string& value() const {return m 177 178 bool add_row() { 179 if(m_cols.empty()) return false; 180 std::ostringstream sout; 181 sout << m_spaces << "<row>" << std::endl 182 tools_vforcit(iobj*,m_cols,it) { 183 if(sub_ntuple* sub = id_cast<iobj,sub_ 184 sout << m_spaces << " <entryITuple> 185 sout << sub->value(); 186 sout << m_spaces << " </entryITuple 187 sub->reset(); 188 } else if(leaf* lf = id_cast<iobj,leaf 189 std::string _sv; 190 lf->s_value(_sv); 191 sout << m_spaces << " <entry" 192 << " value=\"" << _sv 193 << "\"/>" << std::endl; 194 } 195 } 196 sout << m_spaces << "</row>" << std::end 197 198 m_tmp += sout.str(); 199 200 return true; 201 } 202 protected: 203 std::string m_name; 204 std::string m_spaces; 205 std::vector<iobj*> m_cols; 206 std::string m_tmp; 207 }; 208 209 template <class T> 210 class std_vector_column : public leaf { 211 public: 212 static cid id_class() {return 200+_cid_std 213 public: //iobj 214 virtual void* cast(cid a_class) const { 215 if(void* p = cmp_cast<std_vector_column> 216 return leaf::cast(a_class); 217 } 218 virtual cid id_cls() const {return id_clas 219 public: 220 virtual const std::string& name() const {r 221 virtual const std::string& aida_type() con 222 public: //leaf 223 virtual const std::string& s_def() const { 224 virtual void s_value(std::string& a_s) con 225 std::ostringstream sout; 226 sout << m_spaces << "<entryITuple>" << s 227 typedef typename std::vector<T>::const_i 228 for(it_t it=m_user_vec.begin();it!=m_use 229 sout << m_spaces << " <row><entry" << 230 } 231 sout << m_spaces << "</entryITuple>" << 232 a_s = sout.str(); 233 } 234 public: 235 std_vector_column(const std::string& a_nam 236 :m_name(a_name) 237 ,m_user_vec(a_user_vec) 238 ,m_spaces(a_spaces) 239 {} 240 virtual ~std_vector_column(){} 241 protected: 242 std_vector_column(const std_vector_column& 243 :leaf(a_from) 244 ,m_name(a_from.m_name) 245 ,m_user_vec(a_from.m_user_vec) 246 ,m_spaces(a_from.m_spaces) 247 {} 248 std_vector_column& operator=(const std_vec 249 m_name = a_from.m_name; 250 m_spaces = a_from.m_spaces; 251 return *this; 252 } 253 protected: 254 std::string m_name; 255 std::string m_def; //not used; 256 std::vector<T>& m_user_vec; 257 std::string m_spaces; 258 }; 259 260 static leaf* is_std_vector_column(iobj& a_ob 261 //200+20+id(basic type) ? 262 int _id = (int)a_obj.id_cls()-220; 263 if((_id<=0)||(_id>=20)) return 0; 264 return id_cast<iobj,leaf>(a_obj); 265 } 266 267 public: 268 ntuple(std::ostream& a_writer,unsigned int a 269 :m_writer(a_writer){ 270 for(unsigned int i=0;i<a_spaces;i++) m_spa 271 } 272 ntuple(std::ostream& a_writer, 273 std::ostream& a_out, 274 const ntuple_booking& a_bkg, 275 unsigned int a_spaces = 0) 276 :m_writer(a_writer){ 277 for(unsigned int i=0;i<a_spaces;i++) m_spa 278 279 const std::vector<column_booking>& cols = 280 tools_vforcit(column_booking,cols,it){ 281 282 if((*it).cls_id()==_cid(int(0))) { 283 create_column<int>((*it).name()); 284 } else if((*it).cls_id()==_cid(float(0)) 285 create_column<float>((*it).name()); 286 } else if((*it).cls_id()==_cid(double(0) 287 create_column<double>((*it).name()); 288 } else if((*it).cls_id()==_cid(std::stri 289 create_column<std::string>((*it).name( 290 291 } else if((*it).cls_id()==_cid_std_vecto 292 std::vector<int>* vec = (std::vector<i 293 if(vec) { 294 create_column<int>((*it).name(),*vec 295 } else { 296 a_out << "tools::waxml::ntuple :" 297 << " for std::vector column " 298 << ", the user vector pointer 299 << std::endl; 300 safe_clear<iobj>(m_cols); 301 return; 302 } 303 } else if((*it).cls_id()==_cid_std_vecto 304 std::vector<float>* vec = (std::vector 305 if(vec) { 306 create_column<float>((*it).name(),*v 307 } else { 308 a_out << "tools::waxml::ntuple :" 309 << " for std::vector column " 310 << ", the user vector pointer 311 << std::endl; 312 safe_clear<iobj>(m_cols); 313 return; 314 } 315 } else if((*it).cls_id()==_cid_std_vecto 316 std::vector<double>* vec = (std::vecto 317 if(vec) { 318 create_column<double>((*it).name(),* 319 } else { 320 a_out << "tools::waxml::ntuple :" 321 << " for std::vector column " 322 << ", the user vector pointer 323 << std::endl; 324 safe_clear<iobj>(m_cols); 325 return; 326 } 327 328 } else if((*it).cls_id()==_cid_std_vecto 329 std::vector<std::string>* vec = (std:: 330 if(vec) { 331 create_column<std::string>((*it).nam 332 } else { 333 a_out << "tools::waxml::ntuple :" 334 << " for std::vector column " 335 << ", the user vector pointer 336 << std::endl; 337 safe_clear<iobj>(m_cols); 338 return; 339 } 340 341 } else { 342 a_out << "tools::waxml::ntuple :" 343 << " for column " << sout((*it). 344 << ", type with cid " << (*it).c 345 << std::endl; 346 //throw 347 safe_clear<iobj>(m_cols); 348 return; 349 } 350 } 351 } 352 virtual ~ntuple() { 353 safe_clear<iobj>(m_cols); 354 } 355 protected: 356 ntuple(const ntuple& a_from) 357 :m_writer(a_from.m_writer) 358 ,m_spaces(a_from.m_spaces) 359 {} 360 ntuple& operator=(const ntuple& a_from){ 361 m_spaces = a_from.m_spaces; 362 return *this; 363 } 364 public: 365 const std::vector<iobj*>& columns() const {r 366 367 template <class T> 368 column<T>* create_column(const std::string& 369 if(find_named<iobj>(m_cols,a_name)) return 370 column<T>* col = new column<T>(a_name,a_de 371 if(!col) return 0; 372 m_cols.push_back(col); 373 return col; 374 } 375 376 template <class T> 377 std_vector_column<T>* create_column(const st 378 if(find_named<iobj>(m_cols,a_name)) return 379 std::string spaces; 380 for(unsigned int i=0;i<8;i++) spaces += " 381 std_vector_column<T>* col = new std_vector 382 if(!col) return 0; 383 m_cols.push_back(col); 384 return col; 385 } 386 387 template <class T> 388 column<T>* find_column(const std::string& a_ 389 iobj* col = find_named<iobj>(m_cols,a_name 390 if(!col) return 0; 391 return id_cast<iobj, column<T> >(*col); 392 } 393 394 sub_ntuple* create_sub_ntuple(const std::str 395 if(find_named<iobj>(m_cols,a_name)) return 396 std::string spaces; 397 for(unsigned int i=0;i<10;i++) spaces += " 398 sub_ntuple* col = new sub_ntuple(a_name,m_ 399 if(!col) return 0; 400 m_cols.push_back(col); 401 return col; 402 } 403 404 void write_header(const std::string& a_path, 405 406 // <tuple> : 407 m_writer << m_spaces << " <tuple" 408 << " path=" << sout(to_xml(a_path 409 << " name=" << sout(to_xml(a_name 410 << " title=" << sout(to_xml(a_tit 411 << ">" << std::endl; 412 413 // <columns> : 414 m_writer << m_spaces << " <columns>" << 415 416 tools_vforcit(iobj*,m_cols,it) { 417 if(leaf* vlf = is_std_vector_column(*(*i 418 m_writer << m_spaces << " <column 419 << " name=" << sout(to_xml((* 420 << " type=" << sout("ITuple") 421 << " booking=\"{" << vlf->aid 422 << "}\"" 423 << "/>" << std::endl; 424 } else if(sub_ntuple* sub = id_cast<iobj 425 m_writer << m_spaces << " <column 426 << " name=" << sout(to_xml((* 427 << " type=" << sout("ITuple") 428 << " booking=" << sout(sub->b 429 << "/>" << std::endl; 430 } else if(/*leaf* lf =*/ id_cast<iobj,le 431 m_writer << m_spaces << " <column 432 << " name=" << sout(to_xml((* 433 << " type=" << sout((*it)->ai 434 //<< " default=" << sout(lf->s_ 435 << "/>" << std::endl; 436 } 437 } 438 439 m_writer << m_spaces << " </columns>" < 440 441 // rows : 442 m_writer << m_spaces << " <rows>" << st 443 } 444 445 bool add_row() { 446 if(m_cols.empty()) return false; 447 m_writer << m_spaces << " <row>" << s 448 tools_vforcit(iobj*,m_cols,it) { 449 if(leaf* vlf = is_std_vector_column(*(*i 450 std::string _sv; 451 vlf->s_value(_sv); 452 m_writer << _sv; 453 } else if(sub_ntuple* sub = id_cast<iobj 454 m_writer << m_spaces << " <entr 455 m_writer << sub->value(); 456 m_writer << m_spaces << " </ent 457 sub->reset(); 458 } else if(leaf* lf = id_cast<iobj,leaf>( 459 std::string _sv; 460 lf->s_value(_sv); 461 m_writer << m_spaces << " <entr 462 << " value=" << sout(_sv) 463 << "/>" << std::endl; 464 } 465 } 466 m_writer << m_spaces << " </row>" << 467 return true; 468 } 469 470 void write_trailer() { 471 m_writer << m_spaces << " </rows>" << s 472 m_writer << m_spaces << " </tuple>" << st 473 } 474 475 std::string booking(bool a_xml_esc) const { 476 std::string _s; 477 get_booking(m_cols,a_xml_esc,_s); 478 return _s; 479 } 480 481 protected: 482 static void get_booking(const std::vector<io 483 std::string& a_strin 484 a_string += "{"; //we need the + because o 485 486 tools_vforcit(iobj*,a_cols,it) { 487 if(it!=a_cols.begin()) a_string += ","; 488 489 std::string sname = (*it)->name(); 490 if(a_xml_esc) sname = to_xml(sname); 491 492 if(leaf* vlf = is_std_vector_column(*(*i 493 a_string += "ITuple " + (*it)->name() 494 495 } else if(sub_ntuple* sub = id_cast<iobj 496 a_string += (*it)->aida_type() + " " + 497 498 get_booking(sub->columns(),a_xml_esc,a 499 } else if(leaf* lf = id_cast<iobj,leaf>( 500 a_string += (*it)->aida_type() + " " + 501 } 502 } 503 a_string += "}"; 504 } 505 506 protected: 507 std::ostream& m_writer; 508 //std::string m_path; 509 //std::string m_name; 510 //std::string m_title; 511 std::string m_spaces; 512 std::vector<iobj*> m_cols; 513 }; 514 515 }} 516 517 #endif