Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/rcsv_histo

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_rcsv_histo
  5 #define tools_rcsv_histo
  6 
  7 #include "sto"
  8 #include "chars"
  9 #include "words"
 10 #include "forit"
 11 #include "sout"
 12 
 13 #include "histo/h1d"
 14 #include "histo/h2d"
 15 #include "histo/h3d"
 16 #include "histo/p1d"
 17 #include "histo/p2d"
 18 //#include "histo/h1df"
 19 
 20 #ifdef TOOLS_MEM
 21 #include "mem"
 22 #endif
 23 
 24 #include <istream>
 25 #include <utility>
 26 
 27 namespace tools {
 28 namespace rcsv {
 29 
 30 class histo {
 31 #ifdef TOOLS_MEM
 32 public:
 33   static const std::string& s_class() {
 34     static const std::string s_v("tools::rcsv::histo");
 35     return s_v;
 36   }
 37 #endif
 38 public:
 39   histo(std::istream& a_reader)
 40   :m_reader(a_reader)
 41   {
 42 #ifdef TOOLS_MEM
 43     mem::increment(s_class().c_str());
 44 #endif
 45   }
 46   virtual ~histo() {
 47 #ifdef TOOLS_MEM
 48     mem::decrement(s_class().c_str());
 49 #endif
 50   }
 51 protected:
 52   histo(const histo& a_from)
 53   :m_reader(a_from.m_reader)
 54   {
 55 #ifdef TOOLS_MEM
 56     mem::increment(s_class().c_str());
 57 #endif
 58   }
 59   histo& operator=(const histo&){return *this;}
 60 public:
 61   std::istream& istrm() {return m_reader;}
 62 public:
 63   bool read(std::ostream& a_out,std::string& a_class,void*& a_obj,bool a_verbose = false) {
 64     a_class.clear();
 65     a_obj = 0;
 66 
 67     std::streampos file_sz = 0;
 68     m_reader.clear();
 69     m_reader.seekg(0,std::ios::end);
 70     file_sz = m_reader.tellg();
 71     m_reader.seekg(0,std::ios::beg);
 72     if(!file_sz) {
 73       a_out << "tools::rcsv::histo::read : stream is empty." << std::endl;
 74       return false;
 75     }
 76     if(a_verbose) a_out << "file size is " << file_sz << std::endl;
 77 
 78     tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata; //to be filled correctly.
 79     hdata.m_dimension = 0;
 80     hdata.m_bin_number = 0;
 81 
 82     bool is_profile = false;
 83     bool _cut_v = false;
 84     double _min_v = 0;
 85     double _max_v = 0;
 86 
 87     // read commented header :
 88     std::string _class;
 89     typedef tools::histo::axis<double,unsigned int> axis_t;
 90    {std::string line;
 91     while(read_header_line(m_reader,file_sz,line)) {
 92 //      a_out << "line : " << sout(s) << std::endl;
 93       std::vector<std::string> _words;
 94       words(line," ",false,_words);
 95       if(!_words.size()) {
 96         a_out << "tools::rcsv::histo::read : syntax error : empty header line." << std::endl;
 97         return false;
 98       }
 99       if((_words[0]=="#class")) {
100         if(_words.size()!=2) {
101           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
102           return false;
103         }
104         _class = _words[1];
105       } else if(_words[0]=="#title") {
106         if(_words.size()<1) {
107           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
108           return false;
109         }
110         if(_words.size()==1)  {
111           hdata.m_title.clear();
112         } else {
113           std::string::size_type pos = line.find(_words[0]);
114           pos += _words[0].size()+1;
115           hdata.m_title = line.substr(pos,line.size()-pos);
116         }
117       } else if(_words[0]=="#dimension") {
118         if(_words.size()!=2) {
119           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
120           return false;
121         }
122         if(!to(_words[1],hdata.m_dimension)) {
123           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
124           return false;
125         }
126       } else if(_words[0]=="#annotation") {
127         if(_words.size()<2) {
128           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
129           return false;
130         }
131         if(_words.size()==2) {
132           hdata.m_annotations[_words[1]] = std::string();
133         } else {
134           std::string::size_type pos = line.find(_words[1]);
135           pos += _words[1].size()+1;
136           hdata.m_annotations[_words[1]] = line.substr(pos,line.size()-pos);
137         }
138       } else if(_words[0]=="#axis") {
139         if(_words.size()<2) {
140           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
141           return false;
142         }
143         if(_words[1]=="fixed") {
144           if(_words.size()!=5) {
145             a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
146             return false;
147           }
148           unsigned int number_of_bins;
149           if(!to(_words[2],number_of_bins)) {
150             a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
151             return false;
152           }
153           double minimum_value;
154           if(!to(_words[3],minimum_value)) {
155             a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
156             return false;
157           }
158           double maximum_value;
159           if(!to(_words[4],maximum_value)) {
160             a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
161             return false;
162           }
163           axis_t axis;
164           if(!axis.configure(number_of_bins,minimum_value,maximum_value)) {
165             a_out << "tools::rcsv::histo::read : bad axis values in line " << sout(line) << std::endl;
166             return false;
167           }
168           hdata.m_axes.push_back(axis);
169         } else if(_words[1]=="edges") {
170           std::vector<double> edges;
171           double value;
172           for(unsigned int index=2;index<_words.size();index++) {
173             if(!to(_words[index],value)) {
174               a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
175               return false;
176             }
177             edges.push_back(value);
178           }
179           axis_t axis;
180           if(!axis.configure(edges)) {
181             a_out << "tools::rcsv::histo::read : bad axis values in line " << sout(line) << std::endl;
182             return false;
183           }
184           hdata.m_axes.push_back(axis);
185         } else {
186           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
187           return false;
188         }
189 
190       } else if(_words[0]=="#planes_Sxyw") {
191         std::vector<double> planes;
192         double value;
193         for(unsigned int index=1;index<_words.size();index++) {
194           if(!to(_words[index],value)) {
195             a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
196             return false;
197           }
198           planes.push_back(value);
199         }
200         hdata.m_in_range_plane_Sxyw = std::move(planes);
201 
202       } else if(_words[0]=="#bin_number") {
203         if(_words.size()!=2) {
204           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
205           return false;
206         }
207         if(!to(_words[1],hdata.m_bin_number)) {
208           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
209           return false;
210         }
211       } else if(_words[0]=="#cut_v") {
212         if(_words.size()!=2) {
213           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
214           return false;
215         }
216         if(!to(_words[1],_cut_v)) {
217           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
218           return false;
219         }
220         is_profile = true;
221       } else if(_words[0]=="#min_v") {
222         if(_words.size()!=2) {
223           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
224           return false;
225         }
226         if(!to(_words[1],_min_v)) {
227           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
228           return false;
229         }
230       } else if(_words[0]=="#max_v") {
231         if(_words.size()!=2) {
232           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
233           return false;
234         }
235         if(!to(_words[1],_max_v)) {
236           a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
237           return false;
238         }
239       } else {
240         a_out << "tools::rcsv::histo::read : syntax error in " << sout(line) << std::endl;
241         return false;
242       }
243     }}
244 
245     if(a_verbose) {
246       a_out << "class " << _class << std::endl;
247       a_out << "title " << hdata.m_title << std::endl;
248       tools_mforcit(std::string,std::string,hdata.m_annotations,it) {
249          a_out << "annotation " << (*it).first << " " << sout((*it).second) << std::endl;
250       }
251     }
252 
253     if(!hdata.m_dimension) {
254       a_out << "tools::rcsv::histo::read : null dimension." << std::endl;
255       return false;
256     }
257 
258     // csv labels :
259     std::vector<std::string> labels;
260    {std::string line;
261     if(!read_line(m_reader,file_sz,line)) {
262       a_out << "tools::rcsv::histo::read :"
263             << " syntax error in " << sout(line)
264             << ". Can't read labels."
265             << std::endl;
266       return false;
267     }
268     if(a_verbose) a_out << "labels " << sout(line) << std::endl;
269     words(line,",",false,labels);}
270 
271     unsigned int valn = 3+2*hdata.m_dimension;
272 
273     if(is_profile) valn += 2;
274     std::vector<double> _bin_Svw;
275     std::vector<double> _bin_Sv2w;
276 
277     if(labels.size()!=valn) {
278       a_out << "tools::rcsv::histo::read :"
279             << " bad number of labels " << labels.size() << ". Expected " << valn << "."
280             << std::endl;
281       return false;
282     }
283 
284     // csv data (bins) :
285    {std::vector<double> vals;
286     unsigned int nline = 0;
287     std::vector<double> bin_Sxw(hdata.m_dimension);
288     std::vector<double> bin_Sx2w(hdata.m_dimension);
289     while(read_data_line(m_reader,file_sz,labels.size(),vals)) {
290 /*
291       for(unsigned int index=0;index<vals.size();index++) {
292         a_out << vals[index] << " ";
293       }
294       a_out << std::endl;
295 */
296       if(vals.size()!=valn) {
297          a_out << "tools::rcsv::histo::read :"
298                << " bad number of items in data line " << vals.size() << ". Expected " << valn << "."
299                << std::endl;
300          return false;
301       }
302       unsigned int ival = 0;
303       hdata.m_bin_entries.push_back(static_cast<unsigned int>(vals[ival++]));
304       hdata.m_bin_Sw.push_back(vals[ival++]);
305       hdata.m_bin_Sw2.push_back(vals[ival++]);
306       if(is_profile) {
307         _bin_Svw.push_back(vals[ival++]);
308         _bin_Sv2w.push_back(vals[ival++]);
309       }
310      {for(unsigned int iaxis=0;iaxis<hdata.m_dimension;iaxis++) {
311         bin_Sxw[iaxis] = vals[ival++];
312         bin_Sx2w[iaxis] = vals[ival++];
313       }}
314       hdata.m_bin_Sxw.push_back(bin_Sxw);
315       hdata.m_bin_Sx2w.push_back(bin_Sx2w);
316       nline++;
317     }
318     if(nline!=hdata.m_bin_number) {
319       a_out << "tools::rcsv::histo::read : bad data line number " << nline << ". Expected " << hdata.m_bin_number << "."
320             << std::endl;
321       return false;
322     }}
323 
324     if(hdata.m_axes.size()!=hdata.m_dimension) {
325       a_out << "tools::rcsv::histo::read : inconsistent axes data." << std::endl;
326       return false;
327     }
328 
329     hdata.m_axes[0].m_offset = 1;
330    {for(unsigned int iaxis=1;iaxis<hdata.m_dimension;iaxis++) {
331       hdata.m_axes[iaxis].m_offset = hdata.m_axes[iaxis-1].m_offset * (hdata.m_axes[iaxis-1].bins()+2);
332     }}
333 
334     hdata.update_fast_getters(); //important.
335 
336     tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata(hdata); //to be filled correctly.
337     if(is_profile) {
338       pdata.m_is_profile = true;
339       pdata.m_bin_Svw = std::move(_bin_Svw);
340       pdata.m_bin_Sv2w = std::move(_bin_Sv2w);
341       pdata.m_cut_v = _cut_v;
342       pdata.m_min_v = _min_v;
343       pdata.m_max_v = _max_v;
344     }
345 
346     if(_class==tools::histo::h1d::s_class()) {
347       if(hdata.m_dimension!=1) {
348         a_out << "tools::rcsv::histo::read :"
349               << " inconsistent dimension data."
350               << std::endl;
351         return false;
352       }
353       tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
354       h->copy_from_data(hdata);
355       //if(a_verbose) h->hprint(a_out);
356       if(a_verbose) {
357         a_out << "h1d : " << h->title()
358               << ", all entries " << h->all_entries()
359               << ", entries " << h->entries()
360               << ", mean " << h->mean() << ", rms " << h->rms()
361               << std::endl;
362       }
363       a_class = std::move(_class);
364       a_obj = h;
365 
366     } else if(_class==tools::histo::h2d::s_class()) {
367       if(hdata.m_dimension!=2) {
368         a_out << "tools::rcsv::histo::read :"
369               << " inconsistent dimension data."
370               << std::endl;
371         return false;
372       }
373       tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
374       h->copy_from_data(hdata);
375       //if(a_verbose) h->hprint(a_out);
376       if(a_verbose) {
377         a_out << "h2d : " << h->title()
378               << ", all entries " << h->all_entries()
379               << ", entries " << h->entries()
380               << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
381               << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
382               << std::endl;
383       }
384       a_class = std::move(_class);
385       a_obj = h;
386 
387     } else if(_class==tools::histo::h3d::s_class()) {
388       if(hdata.m_dimension!=3) {
389         a_out << "tools::rcsv::histo::read :"
390               << " inconsistent dimension data."
391               << std::endl;
392         return false;
393       }
394       tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
395       h->copy_from_data(hdata);
396       //if(a_verbose) h->hprint(a_out);
397       if(a_verbose) {
398         a_out << "h3d : " << h->title()
399               << ", all entries " << h->all_entries()
400               << ", entries " << h->entries()
401               << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
402               << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
403               << ", mean_z " << h->mean_z() << ", rms_z " << h->rms_z()
404               << std::endl;
405       }
406       a_class = std::move(_class);
407       a_obj = h;
408 
409     } else if(_class==tools::histo::p1d::s_class()) {
410       if(hdata.m_dimension!=1) {
411         a_out << "tools::rcsv::histo::read :"
412               << " inconsistent dimension data."
413               << std::endl;
414         return false;
415       }
416       tools::histo::p1d* h = new tools::histo::p1d("",10,0,1);
417       h->copy_from_data(pdata);
418       //if(a_verbose) h->hprint(a_out);
419       if(a_verbose) {
420         a_out << "p1d : " << h->title()
421               << ", all entries " << h->all_entries()
422               << ", entries " << h->entries()
423               << ", mean " << h->mean() << ", rms " << h->rms()
424               << std::endl;
425       }
426       a_class = std::move(_class);
427       a_obj = h;
428 
429     } else if(_class==tools::histo::p2d::s_class()) {
430       if(hdata.m_dimension!=2) {
431         a_out << "tools::rcsv::histo::read :"
432               << " inconsistent dimension data."
433               << std::endl;
434         return false;
435       }
436       tools::histo::p2d* h = new tools::histo::p2d("",10,0,1,10,0,1);
437       h->copy_from_data(pdata);
438       //if(a_verbose) h->hprint(a_out);
439       if(a_verbose) {
440         a_out << "p2d : " << h->title()
441               << ", all entries " << h->all_entries()
442               << ", entries " << h->entries()
443               << ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
444               << ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
445               << std::endl;
446       }
447       a_class = std::move(_class);
448       a_obj = h;
449 
450 /*
451     } else if(_class==tools::histo::h1df::s_class()) {
452       if(hdata.m_dimension!=1) {
453         a_out << "tools::rcsv::histo::read :"
454               << " inconsistent dimension data."
455               << std::endl;
456         return false;
457       }
458       tools::histo::h1df* h = new tools::histo::h1df("",10,0,1);
459       h->copy_from_data(hdata);
460       //return h; //give ownership to caller.
461       if(a_verbose) h->hprint(a_out);
462 */
463 
464     } else {
465       a_out << "tools::rcsv::histo::read : unknown class " << sout(_class) << std::endl;
466       return false;
467     }
468 
469     return true;
470   }
471 protected:
472   static bool read_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
473     a_s.clear();
474     char c;
475     while(true) {
476       if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
477       a_reader.get(c);
478       if(c==CR()) continue;
479       if(c==LF()) break; //eol.
480       a_s += c;
481     }
482     return true;
483   }
484 
485   static bool read_header_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
486     //we should be at bol.
487     //ret true = we had a commented line, false : a data line or nothing.
488     if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
489     char c;
490     a_reader.get(c);
491     a_reader.putback(c);
492     if(c!='#') {a_s.clear();return false;}
493     return read_line(a_reader,a_sz,a_s);
494   }
495 
496   static bool _read(std::istream& a_reader,double& a_v) {
497     a_reader >> a_v;
498     if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;}
499     //std::cout << "debug : _read(double) " << a_v << std::endl;
500     return true;
501   }
502 
503   static bool read_data_line(std::istream& a_reader,std::streampos a_sz,size_t a_number,std::vector<double>& a_vals) {
504     a_vals.clear();
505     for(size_t index=0;index<a_number;index++) {
506       double v;
507       if(!_read(a_reader,v)) return false;
508       a_vals.push_back(v);
509       if(index==(a_number-1)) { //read up to LF()
510         char c;
511         while(true){
512           if(a_reader.tellg()>=a_sz) break;
513           a_reader.get(c);
514           if(c==LF()) break;
515         }
516       } else { //read sep :
517         char sep;
518         a_reader.get(sep);
519       }
520     }
521     return true;
522   }
523 protected:
524   std::istream& m_reader;
525 };
526 
527 }}
528 
529 #endif