The Gaudi Framework  v30r3 (a5ef0a68)
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 "TAxis.h"
18 #include "TH1D.h"
19 #include "TH1F.h"
20 #include "TH2D.h"
21 #include "TH2F.h"
22 #include "TH3D.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>, Skipper>
51  {
52  // ======================================================================
53  public:
54  // ======================================================================
55  typedef Edges ResultT;
56  // ======================================================================
57  public:
58  // ======================================================================
59  EdgeGrammar() : EdgeGrammar::base_type( result )
60  {
61  inner = ( ( qi::lit( "edges" ) | "'edges'" | "\"edges\"" ) >> ":" >> edges[qi::_val *= qi::_1] ) |
62  inner_pairs[qi::_val = qi::_1];
63  inner_pairs = ( ( ( qi::lit( "nbins" ) | "'nbins'" | "\"nbins\"" ) >> ":" >> nbins[qi::_val /= qi::_1] ) |
64  ( ( qi::lit( "low" ) | "'low'" | "\"low\"" ) >> ":" >> low[qi::_val -= qi::_1] ) |
65  ( ( qi::lit( "high" ) | "'high'" | "\"high\"" ) >> ":" >> high[qi::_val += qi::_1] ) ) %
66  ',';
67 
68  begin =
69  enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'] | enc::char_( '(' )[qi::_val = ')'];
70  end = enc::char_( qi::_r1 );
71  result = begin[qi::_a = qi::_1] >> inner[qi::_val = qi::_1] >> end( qi::_a );
72  }
76  qi::rule<Iterator, Edges(), qi::locals<char>, Skipper> result;
77  qi::rule<Iterator, Edges(), Skipper> inner, inner_pairs;
78  qi::rule<Iterator, char()> begin;
79  qi::rule<Iterator, void( char )> end;
80  // ======================================================================
81  };
83  // ========================================================================
84  template <typename Iterator, typename Skipper>
85  class H1Grammar : public qi::grammar<Iterator, H1(), qi::locals<char>, Skipper>
86  {
87  // ======================================================================
88  public:
89  // ======================================================================
90  typedef H1 ResultT;
91  // ======================================================================
92  public:
93  // ======================================================================
94  H1Grammar() : H1Grammar::base_type( result )
95  {
96  inner = ( ( ( qi::lit( "name" ) | "'name'" | "\"name\"" ) >> ":" >> name[qi::_val *= qi::_1] ) |
97  ( ( qi::lit( "title" ) | "'title'" | "\"title\"" ) >> ":" >> title[qi::_val /= qi::_1] ) |
98  ( -( ( qi::lit( "X" ) | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':' ) >>
99  edges[qi::_val &= qi::_1] ) |
100  ( ( qi::lit( "nbins" ) | "'nbins'" | "\"nbins\"" ) >> ":" >> nbins[qi::_val |= qi::_1] ) |
101  ( ( qi::lit( "low" ) | "'low'" | "\"low\"" ) >> ":" >> low[qi::_val -= qi::_1] ) |
102  ( ( qi::lit( "high" ) | "'high'" | "\"high\"" ) >> ":" >> high[qi::_val ^= qi::_1] ) |
103  ( ( qi::lit( "bins" ) | "'bins'" | "\"bins\"" ) >> ':' >> bins[qi::_val += qi::_1] ) ) %
104  ',';
105 
106  begin =
107  enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'] | enc::char_( '(' )[qi::_val = ')'];
108  end = enc::char_( qi::_r1 );
109  result = ( begin[qi::_a = qi::_1] >> inner[qi::_val = qi::_1] >> end( qi::_a ) ) | inner;
110  }
111 
116 
118  qi::rule<Iterator, H1(), qi::locals<char>, Skipper> result;
119  qi::rule<Iterator, H1(), Skipper> inner;
120  qi::rule<Iterator, char()> begin;
121  qi::rule<Iterator, void( char )> end;
122  };
124  // ========================================================================
125  template <typename Iterator, typename Skipper>
126  class H2Grammar : public qi::grammar<Iterator, H2(), qi::locals<char>, Skipper>
127  {
128  // ======================================================================
129  public:
130  // ======================================================================
131  typedef H2 ResultT;
132  // ======================================================================
133  public:
134  // ======================================================================
135  H2Grammar() : H2Grammar::base_type( result )
136  {
137  inner = ( ( ( qi::lit( "name" ) | "'name'" | "\"name\"" ) >> ":" >> name[qi::_val *= qi::_1] ) |
138  ( ( qi::lit( "title" ) | "'title'" | "\"title\"" ) >> ":" >> title[qi::_val /= qi::_1] ) |
139  ( ( qi::lit( "X" ) | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':' >> edges[qi::_val &= qi::_1] ) |
140  ( ( qi::lit( "Y" ) | "'Y'" | "\"Y\"" | "y" | "'y'" | "\"y\"" ) >> ':' >> edges[qi::_val |= qi::_1] ) |
141  ( ( qi::lit( "bins" ) | "'bins'" | "\"bins\"" ) >> ':' >> bins[qi::_val += qi::_1] ) ) %
142  ',';
143 
144  begin =
145  enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'] | enc::char_( '(' )[qi::_val = ')'];
146  end = enc::char_( qi::_r1 );
147  result = ( begin[qi::_a = qi::_1] >> inner[qi::_val = qi::_1] >> end( qi::_a ) ) | inner[qi::_val = qi::_1];
148  }
149 
153  qi::rule<Iterator, H2(), qi::locals<char>, Skipper> result;
154  qi::rule<Iterator, H2(), Skipper> inner;
155  qi::rule<Iterator, char()> begin;
156  qi::rule<Iterator, void( char )> end;
157 
158  // ======================================================================
159  };
161  // ========================================================================
162  } // end of namespace Gaudi::Parsers
163  // ==========================================================================
164 } // end of namespace Gaudi
165 // ============================================================================
166 namespace
167 {
168  // ==========================================================================
170  StatusCode _parse( H1& h1, const std::string& input )
171  {
172  // check the parsing
173  StatusCode sc = Gaudi::Parsers::parse_( h1, input );
174  if ( sc.isFailure() ) {
175  return sc;
176  } // RETURN
177  return h1.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE;
178  }
179  // ==========================================================================
181  StatusCode _parse( H2& h2, const std::string& input )
182  {
183  // check the parsing
184  StatusCode sc = Gaudi::Parsers::parse_( h2, input );
185  if ( sc.isFailure() ) {
186  return sc;
187  } // RETURN
188  return h2.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE;
189  }
190  // ==========================================================================
191  template <class HISTO1>
192  std::unique_ptr<HISTO1> _parse_1D( const std::string& input, std::string& name )
193  {
194  //
195  typedef std::unique_ptr<HISTO1> H1P;
196  // ==========================================================================
197  // 1) parse the custom format
198  //
199  H1 h1;
200  StatusCode sc = _parse( h1, input );
201  if ( sc.isFailure() || !h1.ok() ) {
202  return H1P();
203  } // RETURN
204  //
205  // 2) create the histogram
206  //
207  H1P histo( h1.m_edges.edges.empty() ? // FIXED binning?
208  new HISTO1( "", // h1.m_name.c_str () , // NAME
209  h1.m_title.c_str(), // TITLE
210  h1.m_edges.nbins, // #bins
211  h1.m_edges.low, // low edge
212  h1.m_edges.high )
213  : // high edge
214  new HISTO1( "", // h1.m_name .c_str () , // NAME
215  h1.m_title.c_str(), // TITLE
216  h1.m_edges.edges.size() - 1, // #bins
217  &h1.m_edges.edges.front() ) ); // vector of edges
218 
219  // fill the histogram
220  for ( unsigned int ibin = 0; ibin < h1.m_bins.size(); ++ibin ) {
221  histo->SetBinContent( ibin, h1.m_bins[ibin].first );
222  histo->SetBinError( ibin, h1.m_bins[ibin].second );
223  }
224  //
225  name = h1.m_name;
226  //
227  return histo;
228  }
229  // ==========================================================================
230  template <class HISTO2>
231  std::unique_ptr<HISTO2> _parse_2D( const std::string& input, std::string& name )
232  {
233  //
234  typedef std::unique_ptr<HISTO2> H2P;
235  // 1) parse the custom format
236  //
237  H2 h2;
238  StatusCode sc = _parse( h2, input );
239  if ( sc.isFailure() || !h2.ok() ) {
240  return H2P();
241  } // RETURN
242  //
243  // 2) create the histogram
244  //
245  H2P histo( h2.m_xedges.edges.empty() && h2.m_yedges.edges.empty()
246  ? // FIXED binning?
247  new HISTO2( "", // h1.m_name.c_str () , // NAME
248  h2.m_title.c_str(), // TITLE
249  h2.m_xedges.nbins, // #bins
250  h2.m_xedges.low, // low edge
251  h2.m_xedges.high, // high edge
252  h2.m_yedges.nbins, // #bins
253  h2.m_yedges.low, // low edge
254  h2.m_yedges.high )
255  : h2.m_xedges.edges.empty() && !h2.m_xedges.edges.empty()
256  ? new HISTO2( "", // h1.m_name.c_str () , // NAME
257  h2.m_title.c_str(), // TITLE
258  h2.m_xedges.nbins, // #bins
259  h2.m_xedges.low, // low edge
260  h2.m_xedges.high, // high edge
261  h2.m_yedges.nBins(), // #bins
262  &h2.m_yedges.edges.front() )
263  : // vector of edges
264  !h2.m_xedges.edges.empty() && h2.m_xedges.edges.empty()
265  ? new HISTO2( "", // h1.m_name.c_str () , // NAME
266  h2.m_title.c_str(), // TITLE
267  h2.m_xedges.nBins(), // #bins
268  &h2.m_xedges.edges.front(), // vector of edges
269  h2.m_yedges.nbins, // #bins
270  h2.m_yedges.low, // low edge
271  h2.m_yedges.high )
272  : // high edge
273  new HISTO2( "", // h1.m_name.c_str () , // NAME
274  h2.m_title.c_str(), // TITLE
275  h2.m_xedges.nBins(), // #bins
276  &h2.m_xedges.edges.front(), // vector of edges
277  h2.m_yedges.nBins(), // #bins
278  &h2.m_yedges.edges.front() ) ); // vector of edges
279 
280  int ibin = 0;
281  const int xBins = h2.m_xedges.nBins();
282  const int yBins = h2.m_yedges.nBins();
283 
284  for ( int jBin = yBins + 1; jBin >= 0; --jBin ) {
285  for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) {
286  histo->SetBinContent( iBin, jBin, h2.m_bins[ibin].first );
287  histo->SetBinError( iBin, jBin, h2.m_bins[ibin].second );
288  ++ibin;
289  }
290  }
291  //
292  name = h2.m_name;
293  //
294  return histo;
295  }
296  // ==========================================================================
297 } // end of anonymous namespace
298 // ============================================================================
299 /* parse ROOT histogram from text representation
300  * @param result (OUTPUT) the histogram
301  * @param input (INPUT) the input to be parsed
302  * @return status code
303  */
304 // ============================================================================
306 {
307  // 1) check the parsing
309  //
310  auto h1 = _parse_1D<TH1D>( input, name );
311  if ( h1 ) {
312  result.Reset();
313  h1->Copy( result ); // ASSIGN
314  result.SetName( name.c_str() );
315  return StatusCode::SUCCESS; // RETURN
316  }
317  //
318  // XML-like text?
319  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
321 }
322 // ============================================================================
323 /* parse ROOT histogram from text representation
324  * @param result (OUTPUT) the histogram
325  * @param input (INPUT) the input to be parsed
326  * @return status code
327  */
328 // ============================================================================
330 {
331  // 1) check the parsing
333  //
334  auto h1 = _parse_1D<TH1F>( input, name );
335  if ( h1 ) {
336  result.Reset();
337  h1->Copy( result ); // ASSIGN
338  result.SetName( name.c_str() );
339  return StatusCode::SUCCESS; // RETURN
340  }
341  //
342  // XML-like text?
343  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
345 }
346 // ============================================================================
347 /* parse ROOT histogram from text representation
348  * @param result (OUTPUT) the histogram
349  * @param input (INPUT) the input to be parsed
350  * @return status code
351  */
352 // ============================================================================
354 {
355  // 1) check the parsing
357  auto h2 = _parse_2D<TH2D>( input, name );
358  if ( h2 ) {
359  result.Reset();
360  h2->Copy( result ); // ASSIGN
361  result.SetName( name.c_str() );
362  return StatusCode::SUCCESS; // RETURN
363  }
364  //
365  // XML-like text?
366  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
368 }
369 // ============================================================================
370 /* parse ROOT histogram from text representation
371  * @param result (OUTPUT) the histogram
372  * @param input (INPUT) the input to be parsed
373  * @return status code
374  */
375 // ============================================================================
377 {
378  // 1) check the parsing
380  auto h2 = _parse_2D<TH2F>( input, name );
381  if ( h2 ) {
382  result.Reset();
383  h2->Copy( result ); // ASSIGN
384  result.SetName( name.c_str() );
385  return StatusCode::SUCCESS; // RETURN
386  }
387  //
388  // XML-like text?
389  if ( std::string::npos != input.find( '<' ) ) {
390  return Gaudi::Utils::Histos::fromXml( result, input );
391  }
392  //
393  return StatusCode::FAILURE;
394 }
395 // ============================================================================
396 /* parse ROOT histogram from text representation
397  * @param result (OUTPUT) the histogram
398  * @param input (INPUT) the input to be parsed
399  * @return status code
400  */
401 // ============================================================================
403 {
404  if ( result ) {
405  return parse( *result, input );
406  } // RETURN
407 
408  // 1) check the parsing
410  auto h1 = _parse_1D<TH1D>( input, name );
411  if ( h1 ) {
412  result = h1.release();
413  result->SetName( name.c_str() );
414  return StatusCode::SUCCESS; // RETURN
415  }
416  //
417  // XML-like text?
418  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
420 }
421 // ============================================================================
422 /* parse ROOT histogram from text representation
423  * @param result (OUTPUT) the histogram
424  * @param input (INPUT) the input to be parsed
425  * @return status code
426  */
427 // ============================================================================
429 {
430  if ( result ) {
431  return parse( *result, input );
432  } // RETURN
433 
434  // 1) check the parsing
436  auto h2 = _parse_2D<TH2D>( input, name );
437  if ( h2 ) {
438  result = h2.release();
439  result->SetName( name.c_str() );
440  return StatusCode::SUCCESS; // RETURN
441  }
442  //
443  // XML-like text?
444  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
446 }
447 // ============================================================================
448 /* parse AIDA histogram from text representation
449  * @param result (OUTPUT) the histogram
450  * @param input (INPUT) the input to be parsed
451  * @return status code
452  */
453 // ============================================================================
454 StatusCode Gaudi::Parsers::parse( AIDA::IHistogram1D& result, const std::string& input )
455 {
456  // 1) convert to ROOT
457  auto root = Gaudi::Utils::Aida2ROOT::aida2root( &result );
458  // 2) read ROOT histogram
459  return root ? parse( *root, input ) : StatusCode::FAILURE;
460 }
461 // ============================================================================
462 /* parse AIDA histogram from text representation
463  * @param result (OUTPUT) the histogram
464  * @param input (INPUT) the input to be parsed
465  * @return status code
466  */
467 // ============================================================================
468 StatusCode Gaudi::Parsers::parse( AIDA::IHistogram2D& result, const std::string& input )
469 {
470  // 1) convert to ROOT
471  auto root = Gaudi::Utils::Aida2ROOT::aida2root( &result );
472  // 2) read ROOT histogram
473  return root ? parse( *root, input ) : StatusCode::FAILURE;
474 }
475 // ============================================================================
476 // The END
477 // ============================================================================
EdgeGrammar< Iterator, Skipper > edges
IntGrammar< Iterator, unsigned int, Skipper > nbins
RealGrammar< Iterator, double, Skipper > low
qi::rule< Iterator, char()> begin
constexpr static const auto FAILURE
Definition: StatusCode.h:88
GAUDI_API StatusCode fromXml(TH1D &result, const std::string &input)
parse the histogram from standard ROOT XML
Definition: HistoXML.cpp:202
qi::rule< Iterator, void(char)> end
StatusCode parse_(ResultT &result, const std::string &input)
qi::rule< Iterator, H2(), Skipper > inner
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:18
qi::rule< Iterator, Edges(), Skipper > inner_pairs
bool isFailure() const
Definition: StatusCode.h:139
StringGrammar< Iterator, Skipper > title
STL class.
StringGrammar< Iterator, Skipper > title
qi::rule< Iterator, void(char)> end
VectorGrammar< Iterator, std::vector< std::pair< double, double > >, Skipper > bins
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
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:73
qi::rule< Iterator, H1(), Skipper > inner
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
qi::rule< Iterator, void(char)> end
STL class.
T c_str(T...args)
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
REGISTER_GRAMMAR(GaudiMath::Interpolation::Type, InterpolGrammar)