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