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