Warning, /include/Geant4/tools/rcsv_histo 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_rcsv_histo
0005 #define tools_rcsv_histo
0006
0007 #include "sto"
0008 #include "chars"
0009 #include "words"
0010 #include "forit"
0011 #include "sout"
0012
0013 #include "histo/h1d"
0014 #include "histo/h2d"
0015 #include "histo/h3d"
0016 #include "histo/p1d"
0017 #include "histo/p2d"
0018 //#include "histo/h1df"
0019
0020 #ifdef TOOLS_MEM
0021 #include "mem"
0022 #endif
0023
0024 #include <istream>
0025
0026 namespace tools {
0027 namespace rcsv {
0028
0029 class histo {
0030 #ifdef TOOLS_MEM
0031 public:
0032 static const std::string& s_class() {
0033 static const std::string s_v("tools::rcsv::histo");
0034 return s_v;
0035 }
0036 #endif
0037 public:
0038 histo(std::istream& a_reader)
0039 :m_reader(a_reader)
0040 {
0041 #ifdef TOOLS_MEM
0042 mem::increment(s_class().c_str());
0043 #endif
0044 }
0045 virtual ~histo() {
0046 #ifdef TOOLS_MEM
0047 mem::decrement(s_class().c_str());
0048 #endif
0049 }
0050 protected:
0051 histo(const histo& a_from)
0052 :m_reader(a_from.m_reader)
0053 {
0054 #ifdef TOOLS_MEM
0055 mem::increment(s_class().c_str());
0056 #endif
0057 }
0058 histo& operator=(const histo&){return *this;}
0059 public:
0060 std::istream& istrm() {return m_reader;}
0061 public:
0062 bool read(std::ostream& a_out,std::string& a_class,void*& a_obj,bool a_verbose = false) {
0063 a_class.clear();
0064 a_obj = 0;
0065
0066 std::streampos file_sz = 0;
0067 m_reader.clear();
0068 m_reader.seekg(0,std::ios::end);
0069 file_sz = m_reader.tellg();
0070 m_reader.seekg(0,std::ios::beg);
0071 if(!file_sz) {
0072 a_out << "tools::rcsv::histo::read : stream is empty." << std::endl;
0073 return false;
0074 }
0075 if(a_verbose) a_out << "file size is " << file_sz << std::endl;
0076
0077 tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata; //to be filled correctly.
0078 hdata.m_dimension = 0;
0079 hdata.m_bin_number = 0;
0080
0081 bool is_profile = false;
0082 bool _cut_v = false;
0083 double _min_v = 0;
0084 double _max_v = 0;
0085
0086 // read commented header :
0087 std::string _class;
0088 typedef tools::histo::axis<double,unsigned int> axis_t;
0089 {std::string line;
0090 while(read_header_line(m_reader,file_sz,line)) {
0091 // a_out << "line : " << sout(s) << std::endl;
0092 std::vector<std::string> _words;
0093 words(line," ",false,_words);
0094 if(!_words.size()) {
0095 a_out << "tools::rcsv::histo::read : syntax error : empty header line." << std::endl;
0096 return false;
0097 }
0098 if((_words[0]=="#class")) {
0099 if(_words.size()!=2) {
0100 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0101 return false;
0102 }
0103 _class = _words[1];
0104 } else if(_words[0]=="#title") {
0105 if(_words.size()<1) {
0106 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0107 return false;
0108 }
0109 if(_words.size()==1) {
0110 hdata.m_title.clear();
0111 } else {
0112 std::string::size_type pos = line.find(_words[0]);
0113 pos += _words[0].size()+1;
0114 hdata.m_title = line.substr(pos,line.size()-pos);
0115 }
0116 } else if(_words[0]=="#dimension") {
0117 if(_words.size()!=2) {
0118 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0119 return false;
0120 }
0121 if(!to(_words[1],hdata.m_dimension)) {
0122 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0123 return false;
0124 }
0125 } else if(_words[0]=="#annotation") {
0126 if(_words.size()<2) {
0127 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0128 return false;
0129 }
0130 if(_words.size()==2) {
0131 hdata.m_annotations[_words[1]] = std::string();
0132 } else {
0133 std::string::size_type pos = line.find(_words[1]);
0134 pos += _words[1].size()+1;
0135 hdata.m_annotations[_words[1]] = line.substr(pos,line.size()-pos);
0136 }
0137 } else if(_words[0]=="#axis") {
0138 if(_words.size()<2) {
0139 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0140 return false;
0141 }
0142 if(_words[1]=="fixed") {
0143 if(_words.size()!=5) {
0144 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0145 return false;
0146 }
0147 unsigned int number_of_bins;
0148 if(!to(_words[2],number_of_bins)) {
0149 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0150 return false;
0151 }
0152 double minimum_value;
0153 if(!to(_words[3],minimum_value)) {
0154 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0155 return false;
0156 }
0157 double maximum_value;
0158 if(!to(_words[4],maximum_value)) {
0159 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0160 return false;
0161 }
0162 axis_t axis;
0163 if(!axis.configure(number_of_bins,minimum_value,maximum_value)) {
0164 a_out << "tools::rcsv::histo::read : bad axis values in line " << sout(line) << std::endl;
0165 return false;
0166 }
0167 hdata.m_axes.push_back(axis);
0168 } else if(_words[1]=="edges") {
0169 std::vector<double> edges;
0170 double value;
0171 for(unsigned int index=2;index<_words.size();index++) {
0172 if(!to(_words[index],value)) {
0173 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0174 return false;
0175 }
0176 edges.push_back(value);
0177 }
0178 axis_t axis;
0179 if(!axis.configure(edges)) {
0180 a_out << "tools::rcsv::histo::read : bad axis values in line " << sout(line) << std::endl;
0181 return false;
0182 }
0183 hdata.m_axes.push_back(axis);
0184 } else {
0185 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0186 return false;
0187 }
0188
0189 } else if(_words[0]=="#planes_Sxyw") {
0190 std::vector<double> planes;
0191 double value;
0192 for(unsigned int index=1;index<_words.size();index++) {
0193 if(!to(_words[index],value)) {
0194 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0195 return false;
0196 }
0197 planes.push_back(value);
0198 }
0199 hdata.m_in_range_plane_Sxyw = planes;
0200
0201 } else if(_words[0]=="#bin_number") {
0202 if(_words.size()!=2) {
0203 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0204 return false;
0205 }
0206 if(!to(_words[1],hdata.m_bin_number)) {
0207 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0208 return false;
0209 }
0210 } else if(_words[0]=="#cut_v") {
0211 if(_words.size()!=2) {
0212 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0213 return false;
0214 }
0215 if(!to(_words[1],_cut_v)) {
0216 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0217 return false;
0218 }
0219 is_profile = true;
0220 } else if(_words[0]=="#min_v") {
0221 if(_words.size()!=2) {
0222 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0223 return false;
0224 }
0225 if(!to(_words[1],_min_v)) {
0226 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0227 return false;
0228 }
0229 } else if(_words[0]=="#max_v") {
0230 if(_words.size()!=2) {
0231 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0232 return false;
0233 }
0234 if(!to(_words[1],_max_v)) {
0235 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0236 return false;
0237 }
0238 } else {
0239 a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
0240 return false;
0241 }
0242 }}
0243
0244 if(a_verbose) {
0245 a_out << "class " << _class << std::endl;
0246 a_out << "title " << hdata.m_title << std::endl;
0247 tools_mforcit(std::string,std::string,hdata.m_annotations,it) {
0248 a_out << "annotation " << (*it).first << " " << sout((*it).second) << std::endl;
0249 }
0250 }
0251
0252 if(!hdata.m_dimension) {
0253 a_out << "tools::rcsv::histo::read : null dimension." << std::endl;
0254 return false;
0255 }
0256
0257 // csv labels :
0258 std::vector<std::string> labels;
0259 {std::string line;
0260 if(!read_line(m_reader,file_sz,line)) {
0261 a_out << "tools::rcsv::histo::read :"
0262 << " syntax error in " << sout(line)
0263 << ". Can't read labels."
0264 << std::endl;
0265 return false;
0266 }
0267 if(a_verbose) a_out << "labels " << sout(line) << std::endl;
0268 words(line,",",false,labels);}
0269
0270 unsigned int valn = 3+2*hdata.m_dimension;
0271
0272 if(is_profile) valn += 2;
0273 std::vector<double> _bin_Svw;
0274 std::vector<double> _bin_Sv2w;
0275
0276 if(labels.size()!=valn) {
0277 a_out << "tools::rcsv::histo::read :"
0278 << " bad number of labels " << labels.size() << ". Expected " << valn << "."
0279 << std::endl;
0280 return false;
0281 }
0282
0283 // csv data (bins) :
0284 {std::vector<double> vals;
0285 unsigned int nline = 0;
0286 std::vector<double> bin_Sxw(hdata.m_dimension);
0287 std::vector<double> bin_Sx2w(hdata.m_dimension);
0288 while(read_data_line(m_reader,file_sz,labels.size(),vals)) {
0289 /*
0290 for(unsigned int index=0;index<vals.size();index++) {
0291 a_out << vals[index] << " ";
0292 }
0293 a_out << std::endl;
0294 */
0295 if(vals.size()!=valn) {
0296 a_out << "tools::rcsv::histo::read :"
0297 << " bad number of items in data line " << vals.size() << ". Expected " << valn << "."
0298 << std::endl;
0299 return false;
0300 }
0301 unsigned int ival = 0;
0302 hdata.m_bin_entries.push_back(static_cast<unsigned int>(vals[ival++]));
0303 hdata.m_bin_Sw.push_back(vals[ival++]);
0304 hdata.m_bin_Sw2.push_back(vals[ival++]);
0305 if(is_profile) {
0306 _bin_Svw.push_back(vals[ival++]);
0307 _bin_Sv2w.push_back(vals[ival++]);
0308 }
0309 {for(unsigned int iaxis=0;iaxis<hdata.m_dimension;iaxis++) {
0310 bin_Sxw[iaxis] = vals[ival++];
0311 bin_Sx2w[iaxis] = vals[ival++];
0312 }}
0313 hdata.m_bin_Sxw.push_back(bin_Sxw);
0314 hdata.m_bin_Sx2w.push_back(bin_Sx2w);
0315 nline++;
0316 }
0317 if(nline!=hdata.m_bin_number) {
0318 a_out << "tools::rcsv::histo::read : bad data line number " << nline << ". Expected " << hdata.m_bin_number << "."
0319 << std::endl;
0320 return false;
0321 }}
0322
0323 if(hdata.m_axes.size()!=hdata.m_dimension) {
0324 a_out << "tools::rcsv::histo::read : inconsistent axes data." << std::endl;
0325 return false;
0326 }
0327
0328 hdata.m_axes[0].m_offset = 1;
0329 {for(unsigned int iaxis=1;iaxis<hdata.m_dimension;iaxis++) {
0330 hdata.m_axes[iaxis].m_offset = hdata.m_axes[iaxis-1].m_offset * (hdata.m_axes[iaxis-1].bins()+2);
0331 }}
0332
0333 hdata.update_fast_getters(); //important.
0334
0335 tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata(hdata); //to be filled correctly.
0336 if(is_profile) {
0337 pdata.m_is_profile = true;
0338 pdata.m_bin_Svw = _bin_Svw;
0339 pdata.m_bin_Sv2w = _bin_Sv2w;
0340 pdata.m_cut_v = _cut_v;
0341 pdata.m_min_v = _min_v;
0342 pdata.m_max_v = _max_v;
0343 }
0344
0345 if(_class==tools::histo::h1d::s_class()) {
0346 if(hdata.m_dimension!=1) {
0347 a_out << "tools::rcsv::histo::read :"
0348 << " inconsistent dimension data."
0349 << std::endl;
0350 return false;
0351 }
0352 tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
0353 h->copy_from_data(hdata);
0354 //if(a_verbose) h->hprint(a_out);
0355 if(a_verbose) {
0356 a_out << "h1d : " << h->title()
0357 << ", all entries " << h->all_entries()
0358 << ", entries " << h->entries()
0359 << ", mean " << h->mean() << ", rms " << h->rms()
0360 << std::endl;
0361 }
0362 a_class = _class;
0363 a_obj = h;
0364
0365 } else if(_class==tools::histo::h2d::s_class()) {
0366 if(hdata.m_dimension!=2) {
0367 a_out << "tools::rcsv::histo::read :"
0368 << " inconsistent dimension data."
0369 << std::endl;
0370 return false;
0371 }
0372 tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
0373 h->copy_from_data(hdata);
0374 //if(a_verbose) h->hprint(a_out);
0375 if(a_verbose) {
0376 a_out << "h2d : " << h->title()
0377 << ", all entries " << h->all_entries()
0378 << ", entries " << h->entries()
0379 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0380 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0381 << std::endl;
0382 }
0383 a_class = _class;
0384 a_obj = h;
0385
0386 } else if(_class==tools::histo::h3d::s_class()) {
0387 if(hdata.m_dimension!=3) {
0388 a_out << "tools::rcsv::histo::read :"
0389 << " inconsistent dimension data."
0390 << std::endl;
0391 return false;
0392 }
0393 tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
0394 h->copy_from_data(hdata);
0395 //if(a_verbose) h->hprint(a_out);
0396 if(a_verbose) {
0397 a_out << "h3d : " << h->title()
0398 << ", all entries " << h->all_entries()
0399 << ", entries " << h->entries()
0400 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0401 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0402 << ", mean_z " << h->mean_z() << ", rms_z " << h->rms_z()
0403 << std::endl;
0404 }
0405 a_class = _class;
0406 a_obj = h;
0407
0408 } else if(_class==tools::histo::p1d::s_class()) {
0409 if(hdata.m_dimension!=1) {
0410 a_out << "tools::rcsv::histo::read :"
0411 << " inconsistent dimension data."
0412 << std::endl;
0413 return false;
0414 }
0415 tools::histo::p1d* h = new tools::histo::p1d("",10,0,1);
0416 h->copy_from_data(pdata);
0417 //if(a_verbose) h->hprint(a_out);
0418 if(a_verbose) {
0419 a_out << "p1d : " << h->title()
0420 << ", all entries " << h->all_entries()
0421 << ", entries " << h->entries()
0422 << ", mean " << h->mean() << ", rms " << h->rms()
0423 << std::endl;
0424 }
0425 a_class = _class;
0426 a_obj = h;
0427
0428 } else if(_class==tools::histo::p2d::s_class()) {
0429 if(hdata.m_dimension!=2) {
0430 a_out << "tools::rcsv::histo::read :"
0431 << " inconsistent dimension data."
0432 << std::endl;
0433 return false;
0434 }
0435 tools::histo::p2d* h = new tools::histo::p2d("",10,0,1,10,0,1);
0436 h->copy_from_data(pdata);
0437 //if(a_verbose) h->hprint(a_out);
0438 if(a_verbose) {
0439 a_out << "p2d : " << h->title()
0440 << ", all entries " << h->all_entries()
0441 << ", entries " << h->entries()
0442 << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
0443 << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
0444 << std::endl;
0445 }
0446 a_class = _class;
0447 a_obj = h;
0448
0449 /*
0450 } else if(_class==tools::histo::h1df::s_class()) {
0451 if(hdata.m_dimension!=1) {
0452 a_out << "tools::rcsv::histo::read :"
0453 << " inconsistent dimension data."
0454 << std::endl;
0455 return false;
0456 }
0457 tools::histo::h1df* h = new tools::histo::h1df("",10,0,1);
0458 h->copy_from_data(hdata);
0459 //return h; //give ownership to caller.
0460 if(a_verbose) h->hprint(a_out);
0461 */
0462
0463 } else {
0464 a_out << "tools::rcsv::histo::read : unknown class " << sout(_class) << std::endl;
0465 return false;
0466 }
0467
0468 return true;
0469 }
0470 protected:
0471 static bool read_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
0472 a_s.clear();
0473 char c;
0474 while(true) {
0475 if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
0476 a_reader.get(c);
0477 if(c==CR()) continue;
0478 if(c==LF()) break; //eol.
0479 a_s += c;
0480 }
0481 return true;
0482 }
0483
0484 static bool read_header_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
0485 //we should be at bol.
0486 //ret true = we had a commented line, false : a data line or nothing.
0487 if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
0488 char c;
0489 a_reader.get(c);
0490 a_reader.putback(c);
0491 if(c!='#') {a_s.clear();return false;}
0492 return read_line(a_reader,a_sz,a_s);
0493 }
0494
0495 static bool _read(std::istream& a_reader,double& a_v) {
0496 a_reader >> a_v;
0497 if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;}
0498 //std::cout << "debug : _read(double) " << a_v << std::endl;
0499 return true;
0500 }
0501
0502 static bool read_data_line(std::istream& a_reader,std::streampos a_sz,size_t a_number,std::vector<double>& a_vals) {
0503 a_vals.clear();
0504 for(size_t index=0;index<a_number;index++) {
0505 double v;
0506 if(!_read(a_reader,v)) return false;
0507 a_vals.push_back(v);
0508 if(index==(a_number-1)) { //read up to LF()
0509 char c;
0510 while(true){
0511 if(a_reader.tellg()>=a_sz) break;
0512 a_reader.get(c);
0513 if(c==LF()) break;
0514 }
0515 } else { //read sep :
0516 char sep;
0517 a_reader.get(sep);
0518 }
0519 }
0520 return true;
0521 }
0522 protected:
0523 std::istream& m_reader;
0524 };
0525
0526 }}
0527
0528 #endif