Back to home page

EIC code displayed by LXR

 
 

    


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