Warning, /include/Geant4/tools/waxml/ntuple is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_waxml_ntuple
0005 #define tools_waxml_ntuple
0006
0007 // A ntuple class to write at the aida tuple format.
0008 // Each add_row() write a row at the aida tuple format.
0009
0010 #include "../vmanip"
0011 #include "../sout"
0012 #include "../srep"
0013 #include "../tos"
0014 #include "../forit"
0015
0016 #include <ostream>
0017
0018 // for sub_ntuple :
0019 #include "../scast"
0020 #include <sstream>
0021
0022 #include "../ntuple_booking"
0023
0024 namespace tools {
0025 namespace waxml {
0026
0027 class ntuple {
0028 protected:
0029
0030 class iobj {
0031 public:
0032 virtual ~iobj(){}
0033 public:
0034 virtual void* cast(cid) const = 0;
0035 virtual cid id_cls() const = 0;
0036 public:
0037 virtual const std::string& name() const = 0;
0038 virtual const std::string& aida_type() const = 0;
0039 };
0040
0041 class leaf : public virtual iobj {
0042 public:
0043 static cid id_class() {return 100;}
0044 public: //iobj
0045 virtual void* cast(cid a_class) const {
0046 if(void* p = cmp_cast<leaf>(this,a_class)) {return p;}
0047 return 0;
0048 }
0049 virtual cid id_cls() const {return id_class();}
0050 public:
0051 virtual const std::string& s_def() const = 0;
0052 virtual void s_value(std::string&) const = 0;
0053 public:
0054 leaf(){}
0055 virtual ~leaf(){}
0056 leaf(const leaf& a_from):iobj(a_from){}
0057 leaf& operator=(const leaf&){return *this;}
0058 };
0059
0060 static const std::string& s_aida_type(int) {
0061 static const std::string s_v("int");
0062 return s_v;
0063 }
0064 static const std::string& s_aida_type(float) {
0065 static const std::string s_v("float");
0066 return s_v;
0067 }
0068 static const std::string& s_aida_type(double) {
0069 static const std::string s_v("double");
0070 return s_v;
0071 }
0072 static const std::string& s_aida_type(const std::string&) {
0073 static const std::string s_v("string");
0074 return s_v;
0075 }
0076
0077 static const std::string& s_aida_type_ituple() {
0078 static const std::string s_v("ITuple");
0079 return s_v;
0080 }
0081
0082 public:
0083 template <class T>
0084 class column : public leaf {
0085 public:
0086 static cid id_class() {return 200+_cid(T());}
0087 public: //iobj
0088 virtual void* cast(cid a_class) const {
0089 if(void* p = cmp_cast< column<T> >(this,a_class)) {return p;}
0090 return leaf::cast(a_class);
0091 }
0092 virtual cid id_cls() const {return id_class();}
0093 public:
0094 virtual const std::string& name() const {return m_name;}
0095 virtual const std::string& aida_type() const {return s_aida_type(T());}
0096 public: //leaf
0097 virtual const std::string& s_def() const {return m_def;}
0098 virtual void s_value(std::string& a_s) const {a_s = tos(m_tmp);}
0099 public:
0100 column(const std::string& a_name,const T& a_def)
0101 :m_name(a_name),m_def(tos(a_def)),m_tmp(a_def)
0102 {}
0103 virtual ~column(){}
0104 protected:
0105 column(const column& a_from)
0106 :leaf(a_from)
0107 ,m_name(a_from.m_name)
0108 ,m_def(a_from.m_def)
0109 ,m_tmp(a_from.m_tmp)
0110 {}
0111 column& operator=(const column& a_from){
0112 m_name = a_from.m_name;
0113 m_def = a_from.m_def;
0114 m_tmp = a_from.m_tmp;
0115 return *this;
0116 }
0117 public:
0118 bool fill(const T& a_value) {m_tmp = a_value;return true;}
0119 protected:
0120 std::string m_name;
0121 std::string m_def;
0122 T m_tmp;
0123 };
0124
0125
0126 class sub_ntuple : public virtual iobj {
0127 public:
0128 static cid id_class() {return 300;}
0129 public: //iobj
0130 virtual void* cast(cid a_class) const {
0131 if(void* p = cmp_cast<sub_ntuple>(this,a_class)) {return p;}
0132 return 0;
0133 }
0134 virtual cid id_cls() const {return id_class();}
0135 public:
0136 virtual const std::string& name() const {return m_name;}
0137 virtual const std::string& aida_type() const {return s_aida_type_ituple();}
0138 public:
0139 sub_ntuple(const std::string& a_name,const std::string& a_spaces)
0140 :m_name(a_name),m_spaces(a_spaces){}
0141 virtual ~sub_ntuple(){}
0142 protected:
0143 sub_ntuple(const sub_ntuple& a_from)
0144 :iobj(a_from),m_name(a_from.m_name){}
0145 sub_ntuple& operator=(const sub_ntuple&){return *this;}
0146 public:
0147 template <class T>
0148 column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0149 if(find_named<iobj>(m_cols,a_name)) return 0;
0150 column<T>* col = new column<T>(a_name,a_def);
0151 if(!col) return 0;
0152 m_cols.push_back(col);
0153 return col;
0154 }
0155
0156 sub_ntuple* create_sub_ntuple(const std::string& a_name){
0157 if(find_named<iobj>(m_cols,a_name)) return 0;
0158 std::string spaces;
0159 for(unsigned int i=0;i<4;i++) spaces += " ";
0160 sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
0161 if(!col) return 0;
0162 m_cols.push_back(col);
0163 return col;
0164 }
0165
0166
0167 const std::vector<iobj*>& columns() const {return m_cols;}
0168
0169 std::string booking(bool a_xml_esc) const {
0170 std::string _s;
0171 get_booking(m_cols,a_xml_esc,_s);
0172 return _s;
0173 }
0174 void reset() {m_tmp.clear();}
0175 const std::string& value() const {return m_tmp;}
0176
0177 bool add_row() {
0178 if(m_cols.empty()) return false;
0179 std::ostringstream sout;
0180 sout << m_spaces << "<row>" << std::endl;
0181 tools_vforcit(iobj*,m_cols,it) {
0182 if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))) {
0183 sout << m_spaces << " <entryITuple>" << std::endl;
0184 sout << sub->value();
0185 sout << m_spaces << " </entryITuple>" << std::endl;
0186 sub->reset();
0187 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0188 std::string _sv;
0189 lf->s_value(_sv);
0190 sout << m_spaces << " <entry"
0191 << " value=\"" << _sv
0192 << "\"/>" << std::endl;
0193 }
0194 }
0195 sout << m_spaces << "</row>" << std::endl;
0196
0197 m_tmp += sout.str();
0198
0199 return true;
0200 }
0201 protected:
0202 std::string m_name;
0203 std::string m_spaces;
0204 std::vector<iobj*> m_cols;
0205 std::string m_tmp;
0206 };
0207
0208 template <class T>
0209 class std_vector_column : public leaf {
0210 public:
0211 static cid id_class() {return 200+_cid_std_vector<T>();}
0212 public: //iobj
0213 virtual void* cast(cid a_class) const {
0214 if(void* p = cmp_cast<std_vector_column>(this,a_class)) {return p;}
0215 return leaf::cast(a_class);
0216 }
0217 virtual cid id_cls() const {return id_class();}
0218 public:
0219 virtual const std::string& name() const {return m_name;}
0220 virtual const std::string& aida_type() const {return s_aida_type(T());}
0221 public: //leaf
0222 virtual const std::string& s_def() const {return m_def;} //not used.
0223 virtual void s_value(std::string& a_s) const {
0224 std::ostringstream sout;
0225 sout << m_spaces << "<entryITuple>" << std::endl;
0226 typedef typename std::vector<T>::const_iterator it_t;
0227 for(it_t it=m_user_vec.begin();it!=m_user_vec.end();++it) {
0228 sout << m_spaces << " <row><entry" << " value=\"" << tos(*it) << "\"/></row>" << std::endl;
0229 }
0230 sout << m_spaces << "</entryITuple>" << std::endl;
0231 a_s = sout.str();
0232 }
0233 public:
0234 std_vector_column(const std::string& a_name,std::vector<T>& a_user_vec,const std::string& a_spaces)
0235 :m_name(a_name)
0236 ,m_user_vec(a_user_vec)
0237 ,m_spaces(a_spaces)
0238 {}
0239 virtual ~std_vector_column(){}
0240 protected:
0241 std_vector_column(const std_vector_column& a_from)
0242 :leaf(a_from)
0243 ,m_name(a_from.m_name)
0244 ,m_user_vec(a_from.m_user_vec)
0245 ,m_spaces(a_from.m_spaces)
0246 {}
0247 std_vector_column& operator=(const std_vector_column& a_from){
0248 m_name = a_from.m_name;
0249 m_spaces = a_from.m_spaces;
0250 return *this;
0251 }
0252 protected:
0253 std::string m_name;
0254 std::string m_def; //not used;
0255 std::vector<T>& m_user_vec;
0256 std::string m_spaces;
0257 };
0258
0259 static leaf* is_std_vector_column(iobj& a_obj) {
0260 //200+20+id(basic type) ?
0261 int _id = (int)a_obj.id_cls()-220;
0262 if((_id<=0)||(_id>=20)) return 0;
0263 return id_cast<iobj,leaf>(a_obj);
0264 }
0265
0266 public:
0267 ntuple(std::ostream& a_writer,unsigned int a_spaces = 0)
0268 :m_writer(a_writer){
0269 for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
0270 }
0271 ntuple(std::ostream& a_writer,
0272 std::ostream& a_out,
0273 const ntuple_booking& a_bkg,
0274 unsigned int a_spaces = 0)
0275 :m_writer(a_writer){
0276 for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
0277
0278 const std::vector<column_booking>& cols = a_bkg.columns();
0279 tools_vforcit(column_booking,cols,it){
0280
0281 if((*it).cls_id()==_cid(int(0))) {
0282 create_column<int>((*it).name());
0283 } else if((*it).cls_id()==_cid(float(0))) {
0284 create_column<float>((*it).name());
0285 } else if((*it).cls_id()==_cid(double(0))) {
0286 create_column<double>((*it).name());
0287 } else if((*it).cls_id()==_cid(std::string())) {
0288 create_column<std::string>((*it).name());
0289
0290 } else if((*it).cls_id()==_cid_std_vector<int>()) {
0291 std::vector<int>* vec = (std::vector<int>*)(*it).user_obj();
0292 if(vec) {
0293 create_column<int>((*it).name(),*vec);
0294 } else {
0295 a_out << "tools::waxml::ntuple :"
0296 << " for std::vector column " << sout((*it).name())
0297 << ", the user vector pointer is null."
0298 << std::endl;
0299 safe_clear<iobj>(m_cols);
0300 return;
0301 }
0302 } else if((*it).cls_id()==_cid_std_vector<float>()) {
0303 std::vector<float>* vec = (std::vector<float>*)(*it).user_obj();
0304 if(vec) {
0305 create_column<float>((*it).name(),*vec);
0306 } else {
0307 a_out << "tools::waxml::ntuple :"
0308 << " for std::vector column " << sout((*it).name())
0309 << ", the user vector pointer is null."
0310 << std::endl;
0311 safe_clear<iobj>(m_cols);
0312 return;
0313 }
0314 } else if((*it).cls_id()==_cid_std_vector<double>()) {
0315 std::vector<double>* vec = (std::vector<double>*)(*it).user_obj();
0316 if(vec) {
0317 create_column<double>((*it).name(),*vec);
0318 } else {
0319 a_out << "tools::waxml::ntuple :"
0320 << " for std::vector column " << sout((*it).name())
0321 << ", the user vector pointer is null."
0322 << std::endl;
0323 safe_clear<iobj>(m_cols);
0324 return;
0325 }
0326
0327 } else if((*it).cls_id()==_cid_std_vector<std::string>()) {
0328 std::vector<std::string>* vec = (std::vector<std::string>*)(*it).user_obj();
0329 if(vec) {
0330 create_column<std::string>((*it).name(),*vec);
0331 } else {
0332 a_out << "tools::waxml::ntuple :"
0333 << " for std::vector column " << sout((*it).name())
0334 << ", the user vector pointer is null."
0335 << std::endl;
0336 safe_clear<iobj>(m_cols);
0337 return;
0338 }
0339
0340 } else {
0341 a_out << "tools::waxml::ntuple :"
0342 << " for column " << sout((*it).name())
0343 << ", type with cid " << (*it).cls_id() << " not yet handled."
0344 << std::endl;
0345 //throw
0346 safe_clear<iobj>(m_cols);
0347 return;
0348 }
0349 }
0350 }
0351 virtual ~ntuple() {
0352 safe_clear<iobj>(m_cols);
0353 }
0354 protected:
0355 ntuple(const ntuple& a_from)
0356 :m_writer(a_from.m_writer)
0357 ,m_spaces(a_from.m_spaces)
0358 {}
0359 ntuple& operator=(const ntuple& a_from){
0360 m_spaces = a_from.m_spaces;
0361 return *this;
0362 }
0363 public:
0364 const std::vector<iobj*>& columns() const {return m_cols;}
0365
0366 template <class T>
0367 column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0368 if(find_named<iobj>(m_cols,a_name)) return 0;
0369 column<T>* col = new column<T>(a_name,a_def);
0370 if(!col) return 0;
0371 m_cols.push_back(col);
0372 return col;
0373 }
0374
0375 template <class T>
0376 std_vector_column<T>* create_column(const std::string& a_name,std::vector<T>& a_user_vec) {
0377 if(find_named<iobj>(m_cols,a_name)) return 0;
0378 std::string spaces;
0379 for(unsigned int i=0;i<8;i++) spaces += " ";
0380 std_vector_column<T>* col = new std_vector_column<T>(a_name,a_user_vec,m_spaces+spaces);
0381 if(!col) return 0;
0382 m_cols.push_back(col);
0383 return col;
0384 }
0385
0386 template <class T>
0387 column<T>* find_column(const std::string& a_name) {
0388 iobj* col = find_named<iobj>(m_cols,a_name);
0389 if(!col) return 0;
0390 return id_cast<iobj, column<T> >(*col);
0391 }
0392
0393 sub_ntuple* create_sub_ntuple(const std::string& a_name){
0394 if(find_named<iobj>(m_cols,a_name)) return 0;
0395 std::string spaces;
0396 for(unsigned int i=0;i<10;i++) spaces += " ";
0397 sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
0398 if(!col) return 0;
0399 m_cols.push_back(col);
0400 return col;
0401 }
0402
0403 void write_header(const std::string& a_path,const std::string& a_name,const std::string& a_title){
0404
0405 // <tuple> :
0406 m_writer << m_spaces << " <tuple"
0407 << " path=" << sout(to_xml(a_path))
0408 << " name=" << sout(to_xml(a_name))
0409 << " title=" << sout(to_xml(a_title))
0410 << ">" << std::endl;
0411
0412 // <columns> :
0413 m_writer << m_spaces << " <columns>" << std::endl;
0414
0415 tools_vforcit(iobj*,m_cols,it) {
0416 if(leaf* vlf = is_std_vector_column(*(*it))) {
0417 m_writer << m_spaces << " <column"
0418 << " name=" << sout(to_xml((*it)->name()))
0419 << " type=" << sout("ITuple")
0420 << " booking=\"{" << vlf->aida_type() << " " << to_xml((*it)->name())
0421 << "}\""
0422 << "/>" << std::endl;
0423 } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0424 m_writer << m_spaces << " <column"
0425 << " name=" << sout(to_xml((*it)->name()))
0426 << " type=" << sout("ITuple")
0427 << " booking=" << sout(sub->booking(true))
0428 << "/>" << std::endl;
0429 } else if(/*leaf* lf =*/ id_cast<iobj,leaf>(*(*it))){
0430 m_writer << m_spaces << " <column"
0431 << " name=" << sout(to_xml((*it)->name()))
0432 << " type=" << sout((*it)->aida_type())
0433 << "/>" << std::endl;
0434 }
0435 }
0436
0437 m_writer << m_spaces << " </columns>" << std::endl;
0438
0439 // rows :
0440 m_writer << m_spaces << " <rows>" << std::endl;
0441 }
0442
0443 bool add_row() {
0444 if(m_cols.empty()) return false;
0445 m_writer << m_spaces << " <row>" << std::endl;
0446 tools_vforcit(iobj*,m_cols,it) {
0447 if(leaf* vlf = is_std_vector_column(*(*it))) {
0448 std::string _sv;
0449 vlf->s_value(_sv);
0450 m_writer << _sv;
0451 } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0452 m_writer << m_spaces << " <entryITuple>" << std::endl;
0453 m_writer << sub->value();
0454 m_writer << m_spaces << " </entryITuple>" << std::endl;
0455 sub->reset();
0456 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0457 std::string _sv;
0458 lf->s_value(_sv);
0459 m_writer << m_spaces << " <entry"
0460 << " value=" << sout(_sv)
0461 << "/>" << std::endl;
0462 }
0463 }
0464 m_writer << m_spaces << " </row>" << std::endl;
0465 return true;
0466 }
0467
0468 void write_trailer() {
0469 m_writer << m_spaces << " </rows>" << std::endl;
0470 m_writer << m_spaces << " </tuple>" << std::endl;
0471 }
0472
0473 std::string booking(bool a_xml_esc) const {
0474 std::string _s;
0475 get_booking(m_cols,a_xml_esc,_s);
0476 return _s;
0477 }
0478
0479 protected:
0480 static void get_booking(const std::vector<iobj*>& a_cols,bool a_xml_esc,
0481 std::string& a_string) {
0482 a_string += "{"; //we need the + because of the tuple in tuple.
0483
0484 tools_vforcit(iobj*,a_cols,it) {
0485 if(it!=a_cols.begin()) a_string += ",";
0486
0487 std::string sname = (*it)->name();
0488 if(a_xml_esc) sname = to_xml(sname);
0489
0490 if(leaf* vlf = is_std_vector_column(*(*it))) {
0491 a_string += "ITuple " + (*it)->name() + " = {" + vlf->aida_type() + " " + sname + "}";
0492
0493 } else if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
0494 a_string += (*it)->aida_type() + " " + sname + " = ";
0495
0496 get_booking(sub->columns(),a_xml_esc,a_string);
0497 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
0498 a_string += (*it)->aida_type() + " " + sname + " = " + lf->s_def();
0499 }
0500 }
0501 a_string += "}";
0502 }
0503
0504 protected:
0505 std::ostream& m_writer;
0506 std::string m_spaces;
0507 std::vector<iobj*> m_cols;
0508 };
0509
0510 }}
0511
0512 #endif