Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

HistoParsers.cpp

Go to the documentation of this file.
00001 // =============================================================================
00002 // Include files
00003 // =============================================================================
00004 // STD & STL
00005 // =============================================================================
00006 #include <map>
00007 #include <memory>
00008 // =============================================================================
00009 // AIDA
00010 // ============================================================================
00011 #include "AIDA/IHistogram1D.h"
00012 #include "AIDA/IHistogram2D.h"
00013 #include "AIDA/IHistogram3D.h"
00014 // ============================================================================
00015 // Boost
00016 // ============================================================================
00017 #include "boost/bind.hpp"
00018 // ============================================================================
00019 // ROOT
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 // GaudiKernel
00029 // ============================================================================
00030 #include "GaudiKernel/ParsersFactory.h"
00031 // ============================================================================
00032 // local
00033 // ============================================================================
00034 #include "GaudiUtils/Aida2ROOT.h"
00035 #include "GaudiUtils/HistoParsers.h"
00036 #include "GaudiUtils/HistoXML.h"
00037 // ============================================================================
00038 // Local
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   } //                                          end of namespace Gaudi::Parsers
00208   // ==========================================================================
00209 } //                                                     end of namespace Gaudi
00210 // ============================================================================
00211 namespace
00212 {
00213   // ==========================================================================
00215   StatusCode _parse ( H1& h1 , const std::string& input ) {
00216     // check the parsing
00217     StatusCode sc  = Gaudi::Parsers::parse_(h1, input);
00218     if ( sc.isFailure () ){ return sc ; }                  // RETURN
00219     return h1.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE ;
00220   }
00221   // ==========================================================================
00223   StatusCode _parse ( H2& h2 , const std::string& input) {
00224     // check the parsing
00225     StatusCode sc  = Gaudi::Parsers::parse_(h2, input);
00226     if ( sc.isFailure () ){ return sc ; }                  // RETURN
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     // 1) parse the custom format
00238     //
00239     H1        h1 ;
00240     StatusCode sc = _parse ( h1 , input ) ;
00241     if ( sc.isFailure() || !h1.ok() ) { return H1P() ; }   // RETURN
00242     //
00243     // 2) create the histogram
00244     //
00245     H1P histo
00246       ( h1.m_edges.edges.empty() ?          // FIXED binning?
00247         new HISTO1 ( "" , //h1.m_name.c_str   ()         ,           // NAME
00248                      h1.m_title.c_str() ,           // TITLE
00249                      h1.m_edges.nbins   ,           // #bins
00250                      h1.m_edges.low     ,           // low edge
00251                      h1.m_edges.high    ) :         // high  edge
00252         new HISTO1 ( "" , // h1.m_name .c_str ()          ,     // NAME
00253                      h1.m_title .c_str()  ,            // TITLE
00254                      h1.m_edges.edges.size() -1  ,     // #bins
00255                      &h1.m_edges.edges.front()   ) ) ; // vector of edges
00256 
00257     // fill the histogram
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     // 1) parse the custom format
00275     //
00276     H2        h2 ;
00277     StatusCode sc = _parse ( h2 , input ) ;
00278     if ( sc.isFailure() || !h2.ok() ) { return H2P() ; }   // RETURN
00279     //
00280     // 2) create the histogram
00281     //
00282     H2P histo
00283       ( h2.m_xedges.edges.empty() &&
00284         h2.m_yedges.edges.empty()     ?            // FIXED binning?
00285         new HISTO2 ( "" , //h1.m_name.c_str   ()         ,           // NAME
00286                      h2.m_title.c_str() ,            // TITLE
00287                      h2.m_xedges.nbins   ,           // #bins
00288                      h2.m_xedges.low     ,           // low edge
00289                      h2.m_xedges.high    ,           // high edge
00290                      h2.m_yedges.nbins   ,           // #bins
00291                      h2.m_yedges.low     ,           // low edge
00292                      h2.m_yedges.high    ) :
00293         h2.m_xedges.edges.empty() && !h2.m_xedges.edges.empty() ?
00294         new HISTO2 ( "" , //h1.m_name.c_str   ()         ,           // NAME
00295                      h2.m_title.c_str() ,            // TITLE
00296                      h2.m_xedges.nbins   ,           // #bins
00297                      h2.m_xedges.low     ,           // low edge
00298                      h2.m_xedges.high    ,           // high edge
00299                      h2.m_yedges.nBins() ,           // #bins
00300                      &h2.m_yedges.edges.front() ) : // vector of edges
00301         !h2.m_xedges.edges.empty() && h2.m_xedges.edges.empty() ?
00302         new HISTO2 ( "" , //h1.m_name.c_str   ()         ,           // NAME
00303                      h2.m_title.c_str() ,            // TITLE
00304                      h2.m_xedges.nBins() ,           // #bins
00305                      &h2.m_xedges.edges.front() ,    // vector of edges
00306                      h2.m_yedges.nbins   ,           // #bins
00307                      h2.m_yedges.low     ,           // low edge
00308                      h2.m_yedges.high    )        :         // high edge
00309         new HISTO2 ( "" , //h1.m_name.c_str   ()         ,           // NAME
00310                      h2.m_title.c_str() ,            // TITLE
00311                      h2.m_xedges.nBins() ,           // #bins
00312                      &h2.m_xedges.edges.front() ,    // vector of edges
00313                      h2.m_yedges.nBins() ,           // #bins
00314                      &h2.m_yedges.edges.front() ) ) ; // vector of edges
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 } //                                                 end of anonymous namespace
00336 // ============================================================================
00337 /*  parse ROOT histogram from text representation
00338  *  @param result (OUTPUT) the histogram
00339  *  @param input  (INPUT)  the input to be parsed
00340  *  @return status code
00341  */
00342 // ============================================================================
00343 StatusCode Gaudi::Parsers::parse
00344 ( TH1D& result , const std::string& input )
00345 {
00346   // 1) check the parsing
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 )  ;                            // ASSIGN
00354     result.SetName ( name.c_str () ) ;
00355     return StatusCode::SUCCESS ;                           // RETURN
00356   }
00357   //
00358   // XML-like text?
00359   if ( std::string::npos != input.find('<') )
00360   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00361   //
00362   return StatusCode::FAILURE ;
00363 }
00364 // ============================================================================
00365 /*  parse ROOT histogram from text representation
00366  *  @param result (OUTPUT) the histogram
00367  *  @param input  (INPUT)  the input to be parsed
00368  *  @return status code
00369  */
00370 // ============================================================================
00371 StatusCode Gaudi::Parsers::parse
00372 ( TH1F& result , const std::string& input )
00373 {
00374   // 1) check the parsing
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 )  ;                            // ASSIGN
00382     result.SetName ( name.c_str () ) ;
00383     return StatusCode::SUCCESS ;                           // RETURN
00384   }
00385   //
00386   // XML-like text?
00387   if ( std::string::npos != input.find('<') )
00388   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00389   //
00390   return StatusCode::FAILURE ;
00391 }
00392 // ============================================================================
00393 /*  parse ROOT histogram from text representation
00394  *  @param result (OUTPUT) the histogram
00395  *  @param input  (INPUT)  the input to be parsed
00396  *  @return status code
00397  */
00398 // ============================================================================
00399 StatusCode Gaudi::Parsers::parse
00400 ( TH2D& result , const std::string& input )
00401 {
00402   // 1) check the parsing
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 )  ;                            // ASSIGN
00409     result.SetName ( name.c_str () ) ;
00410     return StatusCode::SUCCESS ;                           // RETURN
00411   }
00412   //
00413   // XML-like text?
00414   if ( std::string::npos != input.find('<') )
00415   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00416   //
00417   return StatusCode::FAILURE ;
00418 }
00419 // ============================================================================
00420 /*  parse ROOT histogram from text representation
00421  *  @param result (OUTPUT) the histogram
00422  *  @param input  (INPUT)  the input to be parsed
00423  *  @return status code
00424  */
00425 // ============================================================================
00426 StatusCode Gaudi::Parsers::parse
00427 ( TH2F& result , const std::string& input )
00428 {
00429   // 1) check the parsing
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 )  ;                            // ASSIGN
00436     result.SetName ( name.c_str () ) ;
00437     return StatusCode::SUCCESS ;                           // RETURN
00438   }
00439   //
00440   // XML-like text?
00441   if ( std::string::npos != input.find('<') )
00442   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00443   //
00444   return StatusCode::FAILURE ;
00445 }
00446 // ============================================================================
00447 /*  parse ROOT histogram from text representation
00448  *  @param result (OUTPUT) the histogram
00449  *  @param input  (INPUT)  the input to be parsed
00450  *  @return status code
00451  */
00452 // ============================================================================
00453 StatusCode Gaudi::Parsers::parse
00454 ( TH1D*& result , const std::string& input )
00455 {
00456   if ( 0 != result ) { return parse ( *result , input ) ; } // RETURN
00457 
00458   // 1) check the parsing
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 ;                           // RETURN
00466   }
00467   //
00468   // XML-like text?
00469   if ( std::string::npos != input.find('<') )
00470   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00471   //
00472   return StatusCode::FAILURE ;
00473 }
00474 // ============================================================================
00475 /*  parse ROOT histogram from text representation
00476  *  @param result (OUTPUT) the histogram
00477  *  @param input  (INPUT)  the input to be parsed
00478  *  @return status code
00479  */
00480 // ============================================================================
00481 StatusCode Gaudi::Parsers::parse
00482 ( TH2D*& result , const std::string& input )
00483 {
00484   if ( 0 != result ) { return parse ( *result , input ) ; } // RETURN
00485 
00486   // 1) check the parsing
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 ;                           // RETURN
00494   }
00495   //
00496   // XML-like text?
00497   if ( std::string::npos != input.find('<') )
00498   { return Gaudi::Utils::Histos::fromXml ( result , input ) ; }
00499   //
00500   return StatusCode::FAILURE ;
00501 }
00502 // ============================================================================
00503 /*  parse AIDA histogram from text representation
00504  *  @param result (OUTPUT) the histogram
00505  *  @param input  (INPUT)  the input to be parsed
00506  *  @return status code
00507  */
00508 // ============================================================================
00509 StatusCode Gaudi::Parsers::parse
00510 ( AIDA::IHistogram1D& result , const std::string& input )
00511 {
00512   // 1) convert to ROOT
00513   TH1D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
00514   if ( 0 == root ) { return StatusCode::FAILURE ; }
00515   // 2) read ROOT histogram
00516   return parse ( *root , input ) ;
00517 }
00518 // ============================================================================
00519 /*  parse AIDA histogram from text representation
00520  *  @param result (OUTPUT) the histogram
00521  *  @param input  (INPUT)  the input to be parsed
00522  *  @return status code
00523  */
00524 // ============================================================================
00525 StatusCode Gaudi::Parsers::parse
00526 ( AIDA::IHistogram2D& result , const std::string& input )
00527 {
00528   // 1) convert to ROOT
00529   TH2D* root = Gaudi::Utils::Aida2ROOT::aida2root ( &result ) ;
00530   if ( 0 == root ) { return StatusCode::FAILURE ; }
00531   // 2) read ROOT histogram
00532   return parse ( *root , input ) ;
00533 }
00534 // ============================================================================
00535 // The END
00536 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:37 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004