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