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