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