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