All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HistoParsers.cpp
Go to the documentation of this file.
1 // =============================================================================
2 // Include files
3 // =============================================================================
4 // STD & STL
5 // =============================================================================
6 #include <map>
7 #include <memory>
8 // =============================================================================
9 // AIDA
10 // ============================================================================
11 #include "AIDA/IHistogram1D.h"
12 #include "AIDA/IHistogram2D.h"
13 #include "AIDA/IHistogram3D.h"
14 // ============================================================================
15 // Boost
16 // ============================================================================
17 #include "boost/bind.hpp"
18 // ============================================================================
19 // ROOT
20 // ============================================================================
21 #include "TH1D.h"
22 #include "TH2D.h"
23 #include "TH1F.h"
24 #include "TH2F.h"
25 #include "TH3D.h"
26 #include "TAxis.h"
27 // ============================================================================
28 // GaudiKernel
29 // ============================================================================
31 // ============================================================================
32 // local
33 // ============================================================================
34 #include "GaudiUtils/Aida2ROOT.h"
36 #include "GaudiUtils/HistoXML.h"
37 // ============================================================================
38 // Local
39 // ============================================================================
40 #include "H1.h"
41 // ============================================================================
42 namespace Gaudi
43 {
44  // ==========================================================================
45  namespace Parsers
46  {
47  // ========================================================================
53  template<typename Iterator, typename Skipper>
54  class EdgeGrammar : public qi::grammar<Iterator, Edges(), qi::locals<char>,
55  Skipper>
56  {
57  // ======================================================================
58  public:
59  // ======================================================================
60  typedef Edges ResultT;
61  // ======================================================================
62  public:
63  // ======================================================================
64  EdgeGrammar(): EdgeGrammar::base_type(result) {
65  inner =
66  ( ( qi::lit("edges") | "'edges'" | "\"edges\"" )
67  >> ":" >> edges[qi::_val *= qi::_1] )
68  | inner_pairs[qi::_val = qi::_1];
69  inner_pairs =
70  ((( qi::lit("nbins") | "'nbins'" | "\"nbins\"")
71  >> ":" >> nbins [ qi::_val /= qi::_1 ])
72  |
73  (( qi::lit("low") | "'low'" | "\"low\"" )
74  >> ":" >> low [qi::_val -= qi::_1])
75  |
76  (( qi::lit("high") | "'high'" | "\"high\"" )
77  >> ":" >> high [qi::_val += qi::_1])) % ',';
78 
79  begin = enc::char_('[')[qi::_val=']']
80  | enc::char_('{')[qi::_val='}']
81  | enc::char_('(')[qi::_val=')'];
82  end = enc::char_(qi::_r1);
83  result = begin[qi::_a = qi::_1]
84  >> inner[qi::_val = qi::_1]
85  >> end(qi::_a) ;
86  }
90  qi::rule<Iterator, Edges(), qi::locals<char>, Skipper> result;
91  qi::rule<Iterator, Edges(), Skipper> inner, inner_pairs;
92  qi::rule<Iterator, char()> begin;
93  qi::rule<Iterator, void(char)> end;
94  // ======================================================================
95  } ;
97  // ========================================================================
98  template<typename Iterator, typename Skipper>
99  class H1Grammar : public qi::grammar<Iterator, H1(), qi::locals<char>,
100  Skipper>
101  {
102  // ======================================================================
103  public:
104  // ======================================================================
105  typedef H1 ResultT;
106  // ======================================================================
107  public:
108  // ======================================================================
109  H1Grammar(): H1Grammar::base_type(result) {
110  inner =
111  (((qi::lit("name") | "'name'" | "\"name\"" )
112  >> ":" >> name[qi::_val *= qi::_1 ])
113  |
114  (( qi::lit("title") | "'title'" | "\"title\"" )
115  >> ":" >> title [ qi::_val /= qi::_1 ])
116  |
117  ( -(( qi::lit("X") | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':' )
118  >> edges [ qi::_val &= qi::_1 ])
119  |
120  (( qi::lit("nbins") | "'nbins'" | "\"nbins\"" )
121  >> ":" >> nbins [qi::_val |= qi::_1])
122  |
123  (( qi::lit("low") | "'low'" | "\"low\"" )
124  >> ":" >> low [qi::_val -= qi::_1])
125  |
126  (( qi::lit("high") | "'high'" | "\"high\"" )
127  >> ":" >> high [qi::_val ^= qi::_1])
128  |
129  (( qi::lit("bins") | "'bins'" | "\"bins\"" )
130  >> ':' >> bins [qi::_val += qi::_1])) % ',';
131 
132  begin = enc::char_('[')[qi::_val=']']
133  | enc::char_('{')[qi::_val='}']
134  | enc::char_('(')[qi::_val=')'];
135  end = enc::char_(qi::_r1);
136  result = (begin[qi::_a = qi::_1]
137  >> inner[qi::_val = qi::_1]
138  >> end(qi::_a)) | inner;
139 
140  }
141 
146 
149  qi::rule<Iterator, H1(), qi::locals<char>, Skipper> result;
150  qi::rule<Iterator, H1(), Skipper> inner;
151  qi::rule<Iterator, char()> begin;
152  qi::rule<Iterator, void(char)> end;
153 
154  };
156  // ========================================================================
157  template<typename Iterator, typename Skipper>
158  class H2Grammar : public qi::grammar<Iterator, H2(), qi::locals<char>,
159  Skipper>
160  {
161  // ======================================================================
162  public:
163  // ======================================================================
164  typedef H2 ResultT;
165  // ======================================================================
166  public:
167  // ======================================================================
168  H2Grammar(): H2Grammar::base_type(result) {
169  inner =
170  ((( qi::lit("name") | "'name'" | "\"name\"" )
171  >> ":" >> name [qi::_val *= qi::_1])
172  |
173  (( qi::lit("title") | "'title'" | "\"title\"" )
174  >> ":" >> title [qi::_val /= qi::_1])
175  |
176  (( qi::lit("X") | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':'
177  >> edges [qi::_val &= qi::_1 ])
178  |
179  (( qi::lit("Y") | "'Y'" | "\"Y\"" | "y" | "'y'" | "\"y\"" ) >> ':'
180  >> edges [qi::_val |= qi::_1 ])
181  |
182  (( qi::lit("bins") | "'bins'" | "\"bins\"" )
183  >> ':' >> bins [ qi::_val += qi::_1 ])) % ',';
184 
185  begin = enc::char_('[')[qi::_val=']']
186  | enc::char_('{')[qi::_val='}']
187  | enc::char_('(')[qi::_val=')'];
188  end = enc::char_(qi::_r1);
189  result = (begin[qi::_a = qi::_1]
190  >> inner[qi::_val = qi::_1]
191  >> end(qi::_a)) | inner[qi::_val = qi::_1];
192  }
193 
198  qi::rule<Iterator, H2(), qi::locals<char>, Skipper> result;
199  qi::rule<Iterator, H2(), Skipper> inner;
200  qi::rule<Iterator, char()> begin;
201  qi::rule<Iterator, void(char)> end;
202 
203  // ======================================================================
204  };
206  // ========================================================================
207  } // end of namespace Gaudi::Parsers
208  // ==========================================================================
209 } // end of namespace Gaudi
210 // ============================================================================
211 namespace
212 {
213  // ==========================================================================
215  StatusCode _parse ( H1& h1 , const std::string& input ) {
216  // check the parsing
217  StatusCode sc = Gaudi::Parsers::parse_(h1, input);
218  if ( sc.isFailure () ){ return sc ; } // RETURN
219  return h1.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE ;
220  }
221  // ==========================================================================
223  StatusCode _parse ( H2& h2 , const std::string& input) {
224  // check the parsing
225  StatusCode sc = Gaudi::Parsers::parse_(h2, input);
226  if ( sc.isFailure () ){ return sc ; } // RETURN
227  return h2.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE ;
228  }
229  // ==========================================================================
230  template <class HISTO1>
231  std::auto_ptr<HISTO1>
232  _parse_1D ( const std::string& input , std::string& name )
233  {
234  //
235  typedef std::auto_ptr<HISTO1> H1P ;
236  // ==========================================================================
237  // 1) parse the custom format
238  //
239  H1 h1 ;
240  StatusCode sc = _parse ( h1 , input ) ;
241  if ( sc.isFailure() || !h1.ok() ) { return H1P() ; } // RETURN
242  //
243  // 2) create the histogram
244  //
245  H1P histo
246  ( h1.m_edges.edges.empty() ? // FIXED binning?
247  new HISTO1 ( "" , //h1.m_name.c_str () , // NAME
248  h1.m_title.c_str() , // TITLE
249  h1.m_edges.nbins , // #bins
250  h1.m_edges.low , // low edge
251  h1.m_edges.high ) : // high edge
252  new HISTO1 ( "" , // h1.m_name .c_str () , // NAME
253  h1.m_title .c_str() , // TITLE
254  h1.m_edges.edges.size() -1 , // #bins
255  &h1.m_edges.edges.front() ) ) ; // vector of edges
256 
257  // fill the histogram
258  for ( unsigned int ibin = 0 ; ibin < h1.m_bins.size() ; ++ibin )
259  {
260  histo -> SetBinContent ( ibin , h1.m_bins[ibin].first ) ;
261  histo -> SetBinError ( ibin , h1.m_bins[ibin].second ) ;
262  }
263  //
264  name = h1.m_name ;
265  //
266  return histo ;
267  }
268  // ==========================================================================
269  template <class HISTO2>
270  std::auto_ptr<HISTO2> _parse_2D ( const std::string& input , std::string& name )
271  {
272  //
273  typedef std::auto_ptr<HISTO2> H2P ;
274  // 1) parse the custom format
275  //
276  H2 h2 ;
277  StatusCode sc = _parse ( h2 , input ) ;
278  if ( sc.isFailure() || !h2.ok() ) { return H2P() ; } // RETURN
279  //
280  // 2) create the histogram
281  //
282  H2P histo
283  ( h2.m_xedges.edges.empty() &&
284  h2.m_yedges.edges.empty() ? // FIXED binning?
285  new HISTO2 ( "" , //h1.m_name.c_str () , // NAME
286  h2.m_title.c_str() , // TITLE
287  h2.m_xedges.nbins , // #bins
288  h2.m_xedges.low , // low edge
289  h2.m_xedges.high , // high edge
290  h2.m_yedges.nbins , // #bins
291  h2.m_yedges.low , // low edge
292  h2.m_yedges.high ) :
293  h2.m_xedges.edges.empty() && !h2.m_xedges.edges.empty() ?
294  new HISTO2 ( "" , //h1.m_name.c_str () , // NAME
295  h2.m_title.c_str() , // TITLE
296  h2.m_xedges.nbins , // #bins
297  h2.m_xedges.low , // low edge
298  h2.m_xedges.high , // high edge
299  h2.m_yedges.nBins() , // #bins
300  &h2.m_yedges.edges.front() ) : // vector of edges
301  !h2.m_xedges.edges.empty() && h2.m_xedges.edges.empty() ?
302  new HISTO2 ( "" , //h1.m_name.c_str () , // NAME
303  h2.m_title.c_str() , // TITLE
304  h2.m_xedges.nBins() , // #bins
305  &h2.m_xedges.edges.front() , // vector of edges
306  h2.m_yedges.nbins , // #bins
307  h2.m_yedges.low , // low edge
308  h2.m_yedges.high ) : // high edge
309  new HISTO2 ( "" , //h1.m_name.c_str () , // NAME
310  h2.m_title.c_str() , // TITLE
311  h2.m_xedges.nBins() , // #bins
312  &h2.m_xedges.edges.front() , // vector of edges
313  h2.m_yedges.nBins() , // #bins
314  &h2.m_yedges.edges.front() ) ) ; // vector of edges
315 
316  int ibin = 0 ;
317  const int xBins = h2.m_xedges.nBins() ;
318  const int yBins = h2.m_yedges.nBins() ;
319 
320  for ( int jBin = yBins + 1 ; jBin >= 0 ; --jBin )
321  {
322  for ( int iBin = 0 ; iBin <= xBins + 1 ; ++iBin )
323  {
324  histo -> SetBinContent ( iBin , jBin , h2.m_bins[ibin].first ) ;
325  histo -> SetBinError ( iBin , jBin , h2.m_bins[ibin].second ) ;
326  ++ibin ;
327  }
328  }
329  //
330  name = h2.m_name ;
331  //
332  return histo ;
333  }
334  // ==========================================================================
335 } // end of anonymous namespace
336 // ============================================================================
337 /* parse ROOT histogram from text representation
338  * @param result (OUTPUT) the histogram
339  * @param input (INPUT) the input to be parsed
340  * @return status code
341  */
342 // ============================================================================
344 ( TH1D& result , const std::string& input )
345 {
346  // 1) check the parsing
347  std::string name ;
348  //
349  std::auto_ptr<TH1D> h1 = _parse_1D<TH1D> ( input , name ) ;
350  if ( 0 != h1.get() )
351  {
352  result.Reset() ;
353  h1->Copy ( result ) ; // ASSIGN
354  result.SetName ( name.c_str () ) ;
355  return StatusCode::SUCCESS ; // RETURN
356  }
357  //
358  // XML-like text?
359  if ( std::string::npos != input.find('<') )
360  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
361  //
362  return StatusCode::FAILURE ;
363 }
364 // ============================================================================
365 /* parse ROOT histogram from text representation
366  * @param result (OUTPUT) the histogram
367  * @param input (INPUT) the input to be parsed
368  * @return status code
369  */
370 // ============================================================================
372 ( TH1F& result , const std::string& input )
373 {
374  // 1) check the parsing
375  std::string name ;
376  //
377  std::auto_ptr<TH1F> h1 = _parse_1D<TH1F> ( input , name ) ;
378  if ( 0 != h1.get() )
379  {
380  result.Reset() ;
381  h1->Copy ( result ) ; // ASSIGN
382  result.SetName ( name.c_str () ) ;
383  return StatusCode::SUCCESS ; // RETURN
384  }
385  //
386  // XML-like text?
387  if ( std::string::npos != input.find('<') )
388  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
389  //
390  return StatusCode::FAILURE ;
391 }
392 // ============================================================================
393 /* parse ROOT histogram from text representation
394  * @param result (OUTPUT) the histogram
395  * @param input (INPUT) the input to be parsed
396  * @return status code
397  */
398 // ============================================================================
400 ( TH2D& result , const std::string& input )
401 {
402  // 1) check the parsing
403  std::string name ;
404  std::auto_ptr<TH2D> h2 = _parse_2D<TH2D> ( input , name ) ;
405  if ( 0 != h2.get() )
406  {
407  result.Reset() ;
408  h2->Copy ( result ) ; // ASSIGN
409  result.SetName ( name.c_str () ) ;
410  return StatusCode::SUCCESS ; // RETURN
411  }
412  //
413  // XML-like text?
414  if ( std::string::npos != input.find('<') )
415  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
416  //
417  return StatusCode::FAILURE ;
418 }
419 // ============================================================================
420 /* parse ROOT histogram from text representation
421  * @param result (OUTPUT) the histogram
422  * @param input (INPUT) the input to be parsed
423  * @return status code
424  */
425 // ============================================================================
427 ( TH2F& result , const std::string& input )
428 {
429  // 1) check the parsing
430  std::string name ;
431  std::auto_ptr<TH2F> h2 = _parse_2D<TH2F> ( input , name ) ;
432  if ( 0 != h2.get() )
433  {
434  result.Reset() ;
435  h2->Copy ( result ) ; // ASSIGN
436  result.SetName ( name.c_str () ) ;
437  return StatusCode::SUCCESS ; // RETURN
438  }
439  //
440  // XML-like text?
441  if ( std::string::npos != input.find('<') )
442  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
443  //
444  return StatusCode::FAILURE ;
445 }
446 // ============================================================================
447 /* parse ROOT histogram from text representation
448  * @param result (OUTPUT) the histogram
449  * @param input (INPUT) the input to be parsed
450  * @return status code
451  */
452 // ============================================================================
454 ( TH1D*& result , const std::string& input )
455 {
456  if ( 0 != result ) { return parse ( *result , input ) ; } // RETURN
457 
458  // 1) check the parsing
459  std::string name ;
460  std::auto_ptr<TH1D> h1 = _parse_1D<TH1D> ( input , name ) ;
461  if ( 0 != h1.get() )
462  {
463  result = h1.release() ;
464  result->SetName ( name.c_str() ) ;
465  return StatusCode::SUCCESS ; // RETURN
466  }
467  //
468  // XML-like text?
469  if ( std::string::npos != input.find('<') )
470  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
471  //
472  return StatusCode::FAILURE ;
473 }
474 // ============================================================================
475 /* parse ROOT histogram from text representation
476  * @param result (OUTPUT) the histogram
477  * @param input (INPUT) the input to be parsed
478  * @return status code
479  */
480 // ============================================================================
482 ( TH2D*& result , const std::string& input )
483 {
484  if ( 0 != result ) { return parse ( *result , input ) ; } // RETURN
485 
486  // 1) check the parsing
487  std::string name ;
488  std::auto_ptr<TH2D> h2 = _parse_2D<TH2D> ( input , name ) ;
489  if ( 0 != h2.get() )
490  {
491  result = h2.release() ;
492  result->SetName ( name.c_str() ) ;
493  return StatusCode::SUCCESS ; // RETURN
494  }
495  //
496  // XML-like text?
497  if ( std::string::npos != input.find('<') )
498  { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
499  //
500  return StatusCode::FAILURE ;
501 }
502 // ============================================================================
503 /* parse AIDA histogram from text representation
504  * @param result (OUTPUT) the histogram
505  * @param input (INPUT) the input to be parsed
506  * @return status code
507  */
508 // ============================================================================
510 ( AIDA::IHistogram1D& result , const std::string& input )
511 {
512  // 1) convert to ROOT
513  TH1D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
514  if ( 0 == root ) { return StatusCode::FAILURE ; }
515  // 2) read ROOT histogram
516  return parse ( *root , input ) ;
517 }
518 // ============================================================================
519 /* parse AIDA histogram from text representation
520  * @param result (OUTPUT) the histogram
521  * @param input (INPUT) the input to be parsed
522  * @return status code
523  */
524 // ============================================================================
526 ( AIDA::IHistogram2D& result , const std::string& input )
527 {
528  // 1) convert to ROOT
529  TH2D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
530  if ( 0 == root ) { return StatusCode::FAILURE ; }
531  // 2) read ROOT histogram
532  return parse ( *root , input ) ;
533 }
534 // ============================================================================
535 // The END
536 // ============================================================================
EdgeGrammar< Iterator, Skipper > edges
IntGrammar< Iterator, unsigned int, Skipper > nbins
RealGrammar< Iterator, double, Skipper > low
qi::rule< Iterator, char()> begin
qi::rule< Iterator, void(char)> end
GAUDI_API StatusCode fromXml(TH1D &result, const std::string &input)
parse the histogram from standard ROOT XML
Definition: HistoXML.cpp:297
StatusCode parse_(ResultT &result, const std::string &input)
qi::rule< Iterator, H2(), Skipper > inner
REGISTER_GRAMMAR(std::string, StringGrammar)
qi::rule< Iterator, char()> begin
qi::rule< Iterator, H1(), qi::locals< char >, Skipper > result
RealGrammar< Iterator, double, Skipper > low
qi::rule< Iterator, Edges(), qi::locals< char >, Skipper > result
RealGrammar< Iterator, double, Skipper > high
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
VectorGrammar< Iterator, std::vector< double >, Skipper > edges
std::vector< double > Edges
Definition: GaudiPI.h:19
qi::rule< Iterator, Edges(), Skipper > inner_pairs
The valid represenation of string values are:
Definition: Grammar.h:55
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:85
StringGrammar< Iterator, Skipper > title
StringGrammar< Iterator, Skipper > name
StringGrammar< Iterator, Skipper > title
StringGrammar< Iterator, Skipper > name
tuple h2
Definition: Test.py:42
VectorGrammar< Iterator, std::vector< std::pair< double, double > >, Skipper > bins
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
qi::rule< Iterator, Edges(), Skipper > inner
qi::rule< Iterator, H2(), qi::locals< char >, Skipper > result
static TH1D * aida2root(AIDA::IHistogram1D *aida)
get the underlying pointer for 1D-histogram
Definition: Aida2ROOT.cpp:55
qi::rule< Iterator, H1(), Skipper > inner
The valid represenation of vector are:
Definition: Grammars.h:424
Skipping spaces and comments.
Definition: Grammar.h:45
tuple root
Definition: IOTest.py:42
qi::rule< Iterator, void(char)> end
qi::rule< Iterator, void(char)> end
This is a number of static methods for bootstrapping the Gaudi framework.
Definition: Bootstrap.h:14
VectorGrammar< Iterator, std::vector< std::pair< double, double > >, Skipper > bins
EdgeGrammar< Iterator, Skipper > edges
RealGrammar< Iterator, double, Skipper > high
IntGrammar< Iterator, unsigned int, Skipper > nbins
qi::rule< Iterator, char()> begin