00001
00002
00003
00004
00005
00006 #include <map>
00007 #include <memory>
00008
00009
00010
00011 #include "AIDA/IHistogram1D.h"
00012 #include "AIDA/IHistogram2D.h"
00013 #include "AIDA/IHistogram3D.h"
00014
00015
00016
00017 #include "boost/bind.hpp"
00018
00019
00020
00021 #include "TH1D.h"
00022 #include "TH2D.h"
00023 #include "TH1F.h"
00024 #include "TH2F.h"
00025 #include "TH3D.h"
00026 #include "TAxis.h"
00027
00028
00029
00030 #include "GaudiKernel/ParsersFactory.h"
00031
00032
00033
00034 #include "GaudiUtils/Aida2ROOT.h"
00035 #include "GaudiUtils/HistoParsers.h"
00036 #include "GaudiUtils/HistoXML.h"
00037
00038
00039
00040 #include "H1.h"
00041
00042 namespace Gaudi
00043 {
00044
00045 namespace Parsers
00046 {
00047
00053 template<typename Iterator, typename Skipper>
00054 class EdgeGrammar : public qi::grammar<Iterator, Edges(), qi::locals<char>,
00055 Skipper>
00056 {
00057
00058 public:
00059
00060 typedef Edges ResultT;
00061
00062 public:
00063
00064 EdgeGrammar(): EdgeGrammar::base_type(result) {
00065 inner =
00066 ( ( qi::lit("edges") | "'edges'" | "\"edges\"" )
00067 >> ":" >> edges[qi::_val *= qi::_1] )
00068 | inner_pairs[qi::_val = qi::_1];
00069 inner_pairs =
00070 ((( qi::lit("nbins") | "'nbins'" | "\"nbins\"")
00071 >> ":" >> nbins [ qi::_val /= qi::_1 ])
00072 |
00073 (( qi::lit("low") | "'low'" | "\"low\"" )
00074 >> ":" >> low [qi::_val -= qi::_1])
00075 |
00076 (( qi::lit("high") | "'high'" | "\"high\"" )
00077 >> ":" >> high [qi::_val += qi::_1])) % ',';
00078
00079 begin = enc::char_('[')[qi::_val=']']
00080 | enc::char_('{')[qi::_val='}']
00081 | enc::char_('(')[qi::_val=')'];
00082 end = enc::char_(qi::_r1);
00083 result = begin[qi::_a = qi::_1]
00084 >> inner[qi::_val = qi::_1]
00085 >> end(qi::_a);
00086 }
00087 VectorGrammar<Iterator, std::vector<double>, Skipper> edges ;
00088 RealGrammar<Iterator, double, Skipper> low, high;
00089 IntGrammar<Iterator, unsigned int, Skipper> nbins ;
00090 qi::rule<Iterator, Edges(), qi::locals<char>, Skipper> result;
00091 qi::rule<Iterator, Edges(), Skipper> inner, inner_pairs;
00092 qi::rule<Iterator, char()> begin;
00093 qi::rule<Iterator, void(char)> end;
00094
00095 } ;
00096 REGISTER_GRAMMAR(Edges, EdgeGrammar);
00097
00098 template<typename Iterator, typename Skipper>
00099 class H1Grammar : public qi::grammar<Iterator, H1(), qi::locals<char>,
00100 Skipper>
00101 {
00102
00103 public:
00104
00105 typedef H1 ResultT;
00106
00107 public:
00108
00109 H1Grammar(): H1Grammar::base_type(result) {
00110 inner =
00111 (((qi::lit("name") | "'name'" | "\"name\"" )
00112 >> ":" >> name[qi::_val *= qi::_1 ])
00113 |
00114 (( qi::lit("title") | "'title'" | "\"title\"" )
00115 >> ":" >> title [ qi::_val /= qi::_1 ])
00116 |
00117 (( qi::lit("X") | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':'
00118 >> edges [ qi::_val &= qi::_1 ])
00119 |
00120 (( qi::lit("nbins") | "'nbins'" | "\"nbins\"" )
00121 >> ":" >> nbins [qi::_val |= qi::_1])
00122 |
00123 (( qi::lit("low") | "'low'" | "\"low\"" )
00124 >> ":" >> low [qi::_val -= qi::_1])
00125 |
00126 (( qi::lit("high") | "'high'" | "\"high\"" )
00127 >> ":" >> high [qi::_val ^= qi::_1])
00128 |
00129 (( qi::lit("bins") | "'bins'" | "\"bins\"" )
00130 >> ':' >> bins [qi::_val += qi::_1])) % ',';
00131
00132 begin = enc::char_('[')[qi::_val=']']
00133 | enc::char_('{')[qi::_val='}']
00134 | enc::char_('(')[qi::_val=')'];
00135 end = enc::char_(qi::_r1);
00136 result = (begin[qi::_a = qi::_1]
00137 >> inner[qi::_val = qi::_1]
00138 >> end(qi::_a)) | inner;
00139
00140 }
00141
00142 StringGrammar<Iterator, Skipper> name, title;
00143 EdgeGrammar<Iterator, Skipper> edges;
00144 RealGrammar<Iterator, double, Skipper> low, high;
00145 IntGrammar<Iterator, unsigned int, Skipper> nbins ;
00146
00147 VectorGrammar<Iterator, std::vector<std::pair<double, double> >,
00148 Skipper> bins ;
00149 qi::rule<Iterator, H1(), qi::locals<char>, Skipper> result;
00150 qi::rule<Iterator, H1(), Skipper> inner;
00151 qi::rule<Iterator, char()> begin;
00152 qi::rule<Iterator, void(char)> end;
00153
00154 };
00155 REGISTER_GRAMMAR(H1, H1Grammar);
00156
00157 template<typename Iterator, typename Skipper>
00158 class H2Grammar : public qi::grammar<Iterator, H2(), qi::locals<char>,
00159 Skipper>
00160 {
00161
00162 public:
00163
00164 typedef H2 ResultT;
00165
00166 public:
00167
00168 H2Grammar(): H2Grammar::base_type(result) {
00169 inner =
00170 ((( qi::lit("name") | "'name'" | "\"name\"" )
00171 >> ":" >> name [qi::_val *= qi::_1])
00172 |
00173 (( qi::lit("title") | "'title'" | "\"title\"" )
00174 >> ":" >> title [qi::_val /= qi::_1])
00175 |
00176 (( qi::lit("X") | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':'
00177 >> edges [qi::_val &= qi::_1 ])
00178 |
00179 (( qi::lit("Y") | "'Y'" | "\"Y\"" | "y" | "'y'" | "\"y\"" ) >> ':'
00180 >> edges [qi::_val |= qi::_1 ])
00181 |
00182 (( qi::lit("bins") | "'bins'" | "\"bins\"" )
00183 >> ':' >> bins [ qi::_val += qi::_1 ])) % ',';
00184
00185 begin = enc::char_('[')[qi::_val=']']
00186 | enc::char_('{')[qi::_val='}']
00187 | enc::char_('(')[qi::_val=')'];
00188 end = enc::char_(qi::_r1);
00189 result = (begin[qi::_a = qi::_1]
00190 >> inner[qi::_val = qi::_1]
00191 >> end(qi::_a)) | inner[qi::_val = qi::_1];
00192 }
00193
00194 StringGrammar<Iterator, Skipper> name, title;
00195 EdgeGrammar<Iterator, Skipper> edges ;
00196 VectorGrammar<Iterator, std::vector<std::pair<double, double> >,
00197 Skipper> bins ;
00198 qi::rule<Iterator, H2(), qi::locals<char>, Skipper> result;
00199 qi::rule<Iterator, H2(), Skipper> inner;
00200 qi::rule<Iterator, char()> begin;
00201 qi::rule<Iterator, void(char)> end;
00202
00203
00204 };
00205 REGISTER_GRAMMAR(H2, H2Grammar);
00206
00207 }
00208
00209 }
00210
00211 namespace
00212 {
00213
00215 StatusCode _parse ( H1& h1 , const std::string& input ) {
00216
00217 StatusCode sc = Gaudi::Parsers::parse_(h1, input);
00218 if ( sc.isFailure () ){ return sc ; }
00219 return h1.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE ;
00220 }
00221
00223 StatusCode _parse ( H2& h2 , const std::string& input) {
00224
00225 StatusCode sc = Gaudi::Parsers::parse_(h2, input);
00226 if ( sc.isFailure () ){ return sc ; }
00227 return h2.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE ;
00228 }
00229
00230 template <class HISTO1>
00231 std::auto_ptr<HISTO1>
00232 _parse_1D ( const std::string& input , std::string& name )
00233 {
00234
00235 typedef std::auto_ptr<HISTO1> H1P ;
00236
00237
00238
00239 H1 h1 ;
00240 StatusCode sc = _parse ( h1 , input ) ;
00241 if ( sc.isFailure() || !h1.ok() ) { return H1P() ; }
00242
00243
00244
00245 H1P histo
00246 ( h1.m_edges.edges.empty() ?
00247 new HISTO1 ( "" ,
00248 h1.m_title.c_str() ,
00249 h1.m_edges.nbins ,
00250 h1.m_edges.low ,
00251 h1.m_edges.high ) :
00252 new HISTO1 ( "" ,
00253 h1.m_title .c_str() ,
00254 h1.m_edges.edges.size() -1 ,
00255 &h1.m_edges.edges.front() ) ) ;
00256
00257
00258 for ( unsigned int ibin = 0 ; ibin < h1.m_bins.size() ; ++ibin )
00259 {
00260 histo -> SetBinContent ( ibin , h1.m_bins[ibin].first ) ;
00261 histo -> SetBinError ( ibin , h1.m_bins[ibin].second ) ;
00262 }
00263
00264 name = h1.m_name ;
00265
00266 return histo ;
00267 }
00268
00269 template <class HISTO2>
00270 std::auto_ptr<HISTO2> _parse_2D ( const std::string& input , std::string& name )
00271 {
00272
00273 typedef std::auto_ptr<HISTO2> H2P ;
00274
00275
00276 H2 h2 ;
00277 StatusCode sc = _parse ( h2 , input ) ;
00278 if ( sc.isFailure() || !h2.ok() ) { return H2P() ; }
00279
00280
00281
00282 H2P histo
00283 ( h2.m_xedges.edges.empty() &&
00284 h2.m_yedges.edges.empty() ?
00285 new HISTO2 ( "" ,
00286 h2.m_title.c_str() ,
00287 h2.m_xedges.nbins ,
00288 h2.m_xedges.low ,
00289 h2.m_xedges.high ,
00290 h2.m_yedges.nbins ,
00291 h2.m_yedges.low ,
00292 h2.m_yedges.high ) :
00293 h2.m_xedges.edges.empty() && !h2.m_xedges.edges.empty() ?
00294 new HISTO2 ( "" ,
00295 h2.m_title.c_str() ,
00296 h2.m_xedges.nbins ,
00297 h2.m_xedges.low ,
00298 h2.m_xedges.high ,
00299 h2.m_yedges.nBins() ,
00300 &h2.m_yedges.edges.front() ) :
00301 !h2.m_xedges.edges.empty() && h2.m_xedges.edges.empty() ?
00302 new HISTO2 ( "" ,
00303 h2.m_title.c_str() ,
00304 h2.m_xedges.nBins() ,
00305 &h2.m_xedges.edges.front() ,
00306 h2.m_yedges.nbins ,
00307 h2.m_yedges.low ,
00308 h2.m_yedges.high ) :
00309 new HISTO2 ( "" ,
00310 h2.m_title.c_str() ,
00311 h2.m_xedges.nBins() ,
00312 &h2.m_xedges.edges.front() ,
00313 h2.m_yedges.nBins() ,
00314 &h2.m_yedges.edges.front() ) ) ;
00315
00316 int ibin = 0 ;
00317 const int xBins = h2.m_xedges.nBins() ;
00318 const int yBins = h2.m_yedges.nBins() ;
00319
00320 for ( int jBin = yBins + 1 ; jBin >= 0 ; --jBin )
00321 {
00322 for ( int iBin = 0 ; iBin <= xBins + 1 ; ++iBin )
00323 {
00324 histo -> SetBinContent ( iBin , jBin , h2.m_bins[ibin].first ) ;
00325 histo -> SetBinError ( iBin , jBin , h2.m_bins[ibin].second ) ;
00326 ++ibin ;
00327 }
00328 }
00329
00330 name = h2.m_name ;
00331
00332 return histo ;
00333 }
00334
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 StatusCode Gaudi::Parsers::parse
00344 ( TH1D& result , const std::string& input )
00345 {
00346
00347 std::string name ;
00348
00349 std::auto_ptr<TH1D> h1 = _parse_1D<TH1D> ( input , name ) ;
00350 if ( 0 != h1.get() )
00351 {
00352 result.Reset() ;
00353 h1->Copy ( result ) ;
00354 result.SetName ( name.c_str () ) ;
00355 return StatusCode::SUCCESS ;
00356 }
00357
00358
00359 if ( std::string::npos != input.find('<') )
00360 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00361
00362 return StatusCode::FAILURE ;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 StatusCode Gaudi::Parsers::parse
00372 ( TH1F& result , const std::string& input )
00373 {
00374
00375 std::string name ;
00376
00377 std::auto_ptr<TH1F> h1 = _parse_1D<TH1F> ( input , name ) ;
00378 if ( 0 != h1.get() )
00379 {
00380 result.Reset() ;
00381 h1->Copy ( result ) ;
00382 result.SetName ( name.c_str () ) ;
00383 return StatusCode::SUCCESS ;
00384 }
00385
00386
00387 if ( std::string::npos != input.find('<') )
00388 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00389
00390 return StatusCode::FAILURE ;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 StatusCode Gaudi::Parsers::parse
00400 ( TH2D& result , const std::string& input )
00401 {
00402
00403 std::string name ;
00404 std::auto_ptr<TH2D> h2 = _parse_2D<TH2D> ( input , name ) ;
00405 if ( 0 != h2.get() )
00406 {
00407 result.Reset() ;
00408 h2->Copy ( result ) ;
00409 result.SetName ( name.c_str () ) ;
00410 return StatusCode::SUCCESS ;
00411 }
00412
00413
00414 if ( std::string::npos != input.find('<') )
00415 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00416
00417 return StatusCode::FAILURE ;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 StatusCode Gaudi::Parsers::parse
00427 ( TH2F& result , const std::string& input )
00428 {
00429
00430 std::string name ;
00431 std::auto_ptr<TH2F> h2 = _parse_2D<TH2F> ( input , name ) ;
00432 if ( 0 != h2.get() )
00433 {
00434 result.Reset() ;
00435 h2->Copy ( result ) ;
00436 result.SetName ( name.c_str () ) ;
00437 return StatusCode::SUCCESS ;
00438 }
00439
00440
00441 if ( std::string::npos != input.find('<') )
00442 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00443
00444 return StatusCode::FAILURE ;
00445 }
00446
00447
00448
00449
00450
00451
00452
00453 StatusCode Gaudi::Parsers::parse
00454 ( TH1D*& result , const std::string& input )
00455 {
00456 if ( 0 != result ) { return parse ( *result , input ) ; }
00457
00458
00459 std::string name ;
00460 std::auto_ptr<TH1D> h1 = _parse_1D<TH1D> ( input , name ) ;
00461 if ( 0 != h1.get() )
00462 {
00463 result = h1.release() ;
00464 result->SetName ( name.c_str() ) ;
00465 return StatusCode::SUCCESS ;
00466 }
00467
00468
00469 if ( std::string::npos != input.find('<') )
00470 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00471
00472 return StatusCode::FAILURE ;
00473 }
00474
00475
00476
00477
00478
00479
00480
00481 StatusCode Gaudi::Parsers::parse
00482 ( TH2D*& result , const std::string& input )
00483 {
00484 if ( 0 != result ) { return parse ( *result , input ) ; }
00485
00486
00487 std::string name ;
00488 std::auto_ptr<TH2D> h2 = _parse_2D<TH2D> ( input , name ) ;
00489 if ( 0 != h2.get() )
00490 {
00491 result = h2.release() ;
00492 result->SetName ( name.c_str() ) ;
00493 return StatusCode::SUCCESS ;
00494 }
00495
00496
00497 if ( std::string::npos != input.find('<') )
00498 { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00499
00500 return StatusCode::FAILURE ;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509 StatusCode Gaudi::Parsers::parse
00510 ( AIDA::IHistogram1D& result , const std::string& input )
00511 {
00512
00513 TH1D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
00514 if ( 0 == root ) { return StatusCode::FAILURE ; }
00515
00516 return parse ( *root , input ) ;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525 StatusCode Gaudi::Parsers::parse
00526 ( AIDA::IHistogram2D& result , const std::string& input )
00527 {
00528
00529 TH2D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
00530 if ( 0 == root ) { return StatusCode::FAILURE ; }
00531
00532 return parse ( *root , input ) ;
00533 }
00534
00535
00536