Warning, /include/Geant4/tools/wcsv_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_wcsv_ntuple
0005 #define tools_wcsv_ntuple
0006
0007 // A simple ntuple class to write at the csv format.
0008 // (csv = comma separated value).
0009 // Each add_row() write a row at the csv format.
0010
0011 #include "vfind"
0012 #include "vmanip"
0013 #include <ostream>
0014
0015 #include "scast"
0016 #include "ntuple_booking"
0017 #include "sout"
0018 //#include "srep"
0019
0020 namespace tools {
0021 namespace wcsv {
0022
0023 class ntuple {
0024 public:
0025 static const std::string& s_class() {
0026 static const std::string s_v("tools::wcsv::ntuple");
0027 return s_v;
0028 }
0029 public:
0030 class icol {
0031 public:
0032 virtual ~icol(){}
0033 public:
0034 virtual void* cast(cid) const = 0;
0035 virtual cid id_cls() const = 0;
0036 public:
0037 virtual void add() = 0;
0038 virtual const std::string& name() const = 0;
0039 };
0040
0041 public:
0042 template <class T>
0043 class column_ref : public virtual icol {
0044 public:
0045 static cid id_class() {
0046 static const T s_v = T(); //do that for T = std::string.
0047 return _cid(s_v)+10000;
0048 }
0049 virtual void* cast(cid a_class) const {
0050 if(void* p = cmp_cast<column_ref>(this,a_class)) {return p;}
0051 else return 0;
0052 }
0053 virtual cid id_cls() const {return id_class();}
0054 public: //icol
0055 virtual void add() {m_writer << m_ref;}
0056 virtual const std::string& name() const {return m_name;}
0057 public:
0058 column_ref(std::ostream& a_writer,const std::string& a_name,const T& a_ref)
0059 :m_writer(a_writer)
0060 ,m_name(a_name)
0061 ,m_ref(a_ref)
0062 {}
0063 virtual ~column_ref(){}
0064 protected:
0065 column_ref(const column_ref& a_from)
0066 :icol(a_from)
0067 ,m_writer(a_from.m_writer)
0068 ,m_name(a_from.m_name)
0069 ,m_ref(a_from.m_ref)
0070 {}
0071 column_ref& operator=(const column_ref& a_from){
0072 m_name = a_from.m_name;
0073 return *this;
0074 }
0075 protected:
0076 std::ostream& m_writer;
0077 std::string m_name;
0078 const T& m_ref;
0079 };
0080
0081 template <class T>
0082 class column : public column_ref<T> {
0083 typedef column_ref<T> parent;
0084 public:
0085 static cid id_class() {
0086 static const T s_v = T(); //do that for T = std::string.
0087 return _cid(s_v);
0088 }
0089 virtual void* cast(cid a_class) const {
0090 if(void* p = cmp_cast<column>(this,a_class)) {return p;}
0091 else return 0;
0092 }
0093 virtual cid id_cls() const {return id_class();}
0094 public: //icol
0095 virtual void add() {parent::add();m_tmp = m_def;}
0096 public:
0097 column(std::ostream& a_writer,const std::string& a_name,const T& a_def)
0098 :parent(a_writer,a_name,m_tmp)
0099 ,m_def(a_def)
0100 ,m_tmp(a_def)
0101 {}
0102 virtual ~column(){}
0103 protected:
0104 column(const column& a_from)
0105 :icol(a_from)
0106 ,parent(a_from)
0107 ,m_def(a_from.m_def)
0108 ,m_tmp(a_from.m_tmp)
0109 {}
0110 column& operator=(const column& a_from){
0111 parent::operator=(a_from);
0112 m_def = a_from.m_def;
0113 m_tmp = a_from.m_tmp;
0114 return *this;
0115 }
0116 public:
0117 bool fill(const T& a_value) {m_tmp = a_value;return true;}
0118 protected:
0119 T m_def;
0120 T m_tmp;
0121 };
0122
0123 /*
0124 template <class T>
0125 static void escape(T&,const std::string&){}
0126 static void escape(std::string& a_s,const std::string& a_sep){
0127 replace(a_s,a_sep,"\\"+a_sep); //if changing here, change rcsv_ntuple/_vec_read() too.
0128 }
0129 */
0130
0131 template <class T>
0132 class std_vector_column : public virtual icol {
0133 public:
0134 static cid id_class() {return _cid_std_vector<T>();}
0135 virtual void* cast(cid a_class) const {
0136 if(void* p = cmp_cast<std_vector_column>(this,a_class)) {return p;}
0137 else return 0;
0138 }
0139 virtual cid id_cls() const {return id_class();}
0140 public: //icol
0141 virtual void add() {
0142 if(m_ref.empty()) {
0143 //m_writer << "none";
0144 } else {
0145 //std::string sep;sep+=m_vec_sep;
0146 //T value;
0147 typedef typename std::vector<T>::const_iterator it_t;
0148 for(it_t it=m_ref.begin();it!=m_ref.end();++it) {
0149 if(it!=m_ref.begin()) m_writer << m_vec_sep;
0150 m_writer << *it;
0151 //value = *it;escape(value,sep);
0152 //m_writer << value;
0153 }
0154 }
0155 }
0156 virtual const std::string& name() const {return m_name;}
0157 public:
0158 std_vector_column(std::ostream& a_writer,const std::string& a_name,const std::vector<T>& a_ref,char a_vec_sep)
0159 :m_writer(a_writer)
0160 ,m_name(a_name)
0161 ,m_ref(a_ref)
0162 ,m_vec_sep(a_vec_sep)
0163 {}
0164 virtual ~std_vector_column(){}
0165 protected:
0166 std_vector_column(const std_vector_column& a_from)
0167 :icol(a_from)
0168 ,m_writer(a_from.m_writer)
0169 ,m_name(a_from.m_name)
0170 ,m_ref(a_from.m_ref)
0171 ,m_vec_sep(a_from.m_vec_sep)
0172 {}
0173 std_vector_column& operator=(const std_vector_column& a_from){
0174 m_name = a_from.m_name;
0175 m_vec_sep = a_from.m_vec_sep;
0176 return *this;
0177 }
0178 protected:
0179 std::ostream& m_writer;
0180 std::string m_name;
0181 const std::vector<T>& m_ref;
0182 char m_vec_sep;
0183 };
0184
0185 public:
0186 ntuple(std::ostream& a_writer,char a_sep = ',',char a_vec_sep = ';')
0187 :m_writer(a_writer)
0188 ,m_sep(a_sep)
0189 ,m_vec_sep(a_vec_sep)
0190 {}
0191
0192 ntuple(std::ostream& a_writer,
0193 std::ostream& a_out, //for errors.
0194 const ntuple_booking& a_bkg,
0195 char a_sep = ',',char a_vec_sep = ';')
0196 :m_writer(a_writer)
0197 ,m_sep(a_sep)
0198 ,m_vec_sep(a_vec_sep)
0199 ,m_title(a_bkg.title())
0200 {
0201 const std::vector<column_booking>& cols = a_bkg.columns();
0202 std::vector<column_booking>::const_iterator it;
0203 for(it=cols.begin();it!=cols.end();++it){
0204
0205 #define TOOLS_WCSV_NTUPLE_CREATE_COL(a__type) \
0206 if((*it).cls_id()==_cid(a__type())) {\
0207 a__type* user = (a__type*)(*it).user_obj();\
0208 if(user) {\
0209 if(!create_column_ref<a__type>((*it).name(),*user)) {\
0210 a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column_ref(" << (*it).name() << ") failed." << std::endl;\
0211 safe_clear<icol>(m_cols);\
0212 return;\
0213 }\
0214 } else {\
0215 if(!create_column<a__type>((*it).name())) {\
0216 a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
0217 safe_clear<icol>(m_cols);\
0218 return;\
0219 }\
0220 }\
0221 }
0222
0223 #define TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(a__type) \
0224 if((*it).cls_id()==_cid_std_vector<a__type>()) {\
0225 std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
0226 if(vec) {\
0227 if(!create_column<a__type>((*it).name(),*vec)) {\
0228 a_out << "tools::wcsv_ntuple::wcsv_ntuple : create_column(" << (*it).name() << ") failed." << std::endl;\
0229 safe_clear<icol>(m_cols);\
0230 return;\
0231 }\
0232 } else {\
0233 a_out << "tools::wcsv_ntuple :"\
0234 << " for std::vector column " << sout((*it).name())\
0235 << ", the user vector pointer is null."\
0236 << std::endl;\
0237 safe_clear<icol>(m_cols);\
0238 return;\
0239 }\
0240 }
0241
0242 TOOLS_WCSV_NTUPLE_CREATE_COL(char)
0243 else TOOLS_WCSV_NTUPLE_CREATE_COL(short)
0244 else TOOLS_WCSV_NTUPLE_CREATE_COL(int)
0245 else TOOLS_WCSV_NTUPLE_CREATE_COL(int64)
0246
0247 else TOOLS_WCSV_NTUPLE_CREATE_COL(float)
0248 else TOOLS_WCSV_NTUPLE_CREATE_COL(double)
0249
0250 else TOOLS_WCSV_NTUPLE_CREATE_COL(byte)
0251 else TOOLS_WCSV_NTUPLE_CREATE_COL(ushort)
0252 else TOOLS_WCSV_NTUPLE_CREATE_COL(uint32)
0253 else TOOLS_WCSV_NTUPLE_CREATE_COL(uint64)
0254
0255 else TOOLS_WCSV_NTUPLE_CREATE_COL(bool)
0256 else TOOLS_WCSV_NTUPLE_CREATE_COL(std::string)
0257
0258 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(char)
0259 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(short)
0260 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int)
0261 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(int64)
0262
0263 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(float)
0264 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(double)
0265
0266 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uchar)
0267 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(ushort)
0268 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint32)
0269 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(uint64)
0270
0271 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(std::string)
0272 else TOOLS_WCSV_NTUPLE_CREATE_VEC_COL(bool)
0273
0274 #undef TOOLS_WCSV_NTUPLE_CREATE_VEC_COL
0275 #undef TOOLS_WCSV_NTUPLE_CREATE_COL
0276
0277 else {
0278 a_out << "tools::wcsv::ntuple :"
0279 << " for column " << sout((*it).name())
0280 << ", type with cid " << (*it).cls_id() << " not yet handled."
0281 << std::endl;
0282 //throw
0283 safe_clear<icol>(m_cols);
0284 return;
0285 }
0286 }
0287 }
0288
0289 virtual ~ntuple() {
0290 safe_clear<icol>(m_cols);
0291 }
0292 protected:
0293 ntuple(const ntuple& a_from)
0294 :m_writer(a_from.m_writer)
0295 ,m_sep(a_from.m_sep)
0296 ,m_vec_sep(a_from.m_vec_sep)
0297 ,m_title(a_from.m_title)
0298 {}
0299 ntuple& operator=(const ntuple& a_from){
0300 m_sep = a_from.m_sep;
0301 m_vec_sep = a_from.m_vec_sep;
0302 m_title = a_from.m_title;
0303 return *this;
0304 }
0305 public:
0306 void write_hippo_header() {
0307 m_writer << m_title << std::endl;
0308 std::vector<icol*>::const_iterator it;
0309 for(it=m_cols.begin();it!=m_cols.end();++it){
0310 if(it!=m_cols.begin()) m_writer << '\t';
0311 m_writer << (*it)->name();
0312 }
0313 m_writer << std::endl;
0314 }
0315
0316 bool write_commented_header(std::ostream& a_out) {
0317 // commented header similar to the histo case.
0318 m_writer << "#class " << s_class() << std::endl;
0319 m_writer << "#title " << m_title << std::endl;
0320 m_writer << "#separator " << (unsigned int)m_sep << std::endl;
0321 m_writer << "#vector_separator " << (unsigned int)m_vec_sep << std::endl;
0322 bool status = true;
0323 {for(unsigned int count=0;count<m_cols.size();count++) {
0324 icol* _col = m_cols[count];
0325 std::string sid;
0326 if(!cid2s(_col->id_cls(),sid)) {
0327 a_out << "tools::wcsv::ntuple::write_commented_header :"
0328 << " unknown column type id " << _col->id_cls() << std::endl;
0329 status = false; //but we continue.
0330 } else {
0331 m_writer << "#column " << sid << " " << _col->name() << std::endl;
0332 }
0333 }}
0334 return status;
0335 }
0336
0337 template <class T>
0338 column_ref<T>* create_column_ref(const std::string& a_name,const T& a_ref) {
0339 if(find_named<icol>(m_cols,a_name)) return 0;
0340 column_ref<T>* col = new column_ref<T>(m_writer,a_name,a_ref);
0341 if(!col) return 0;
0342 m_cols.push_back(col);
0343 return col;
0344 }
0345
0346 template <class T>
0347 column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
0348 if(find_named<icol>(m_cols,a_name)) return 0;
0349 column<T>* col = new column<T>(m_writer,a_name,a_def);
0350 if(!col) return 0;
0351 m_cols.push_back(col);
0352 return col;
0353 }
0354
0355 template <class T>
0356 std_vector_column<T>* create_column(const std::string& a_name,const std::vector<T>& a_ref) {
0357 //NOTE : to optimize, we do not handle a default std::vector value logic.
0358 if(find_named<icol>(m_cols,a_name)) return 0;
0359 std_vector_column<T>* col = new std_vector_column<T>(m_writer,a_name,a_ref,m_vec_sep);
0360 if(!col) return 0;
0361 m_cols.push_back(col);
0362 return col;
0363 }
0364
0365 template <class T>
0366 column_ref<T>* find_column_ref(const std::string& a_name) {
0367 icol* col = find_named<icol>(m_cols,a_name);
0368 if(!col) return 0;
0369 return id_cast<icol, column_ref<T> >(*col);
0370 }
0371
0372 template <class T>
0373 column<T>* find_column(const std::string& a_name) {
0374 icol* col = find_named<icol>(m_cols,a_name);
0375 if(!col) return 0;
0376 return id_cast<icol, column<T> >(*col);
0377 }
0378
0379 bool add_row() {
0380 if(m_cols.empty()) return false;
0381 std::vector<icol*>::iterator it;
0382 it=m_cols.begin();
0383 (*it)->add();
0384 it++;
0385 for(;it!=m_cols.end();++it) {
0386 m_writer << m_sep;
0387 (*it)->add();
0388 }
0389 m_writer << std::endl;
0390 return true;
0391 }
0392
0393 const std::vector<icol*>& columns() const {return m_cols;}
0394
0395 void set_title(const std::string& a_value) {m_title = a_value;}
0396 const std::string& title() const {return m_title;}
0397 protected:
0398 std::ostream& m_writer;
0399 char m_sep;
0400 char m_vec_sep;
0401 std::string m_title;
0402 std::vector<icol*> m_cols;
0403 };
0404
0405 }}
0406
0407 #endif