From 9512d7fc4edc79fae3522564433b451e1b12cc44 Mon Sep 17 00:00:00 2001 From: Maarten van Veghel <mvegh@nikhef.nl> Date: Wed, 23 Jun 2021 10:56:33 +0200 Subject: [PATCH 1/3] th3 support --- GaudiUtils/include/GaudiUtils/Histo2String.h | 78 ++++++++ GaudiUtils/include/GaudiUtils/HistoParsers.h | 31 +++ GaudiUtils/src/Lib/H1.h | 58 ++++++ GaudiUtils/src/Lib/Histo2String.cpp | 193 +++++++++++++++++++ GaudiUtils/src/Lib/HistoParsers.cpp | 180 +++++++++++++++++ 5 files changed, 540 insertions(+) diff --git a/GaudiUtils/include/GaudiUtils/Histo2String.h b/GaudiUtils/include/GaudiUtils/Histo2String.h index b860bc1ad4..5d3560bd56 100644 --- a/GaudiUtils/include/GaudiUtils/Histo2String.h +++ b/GaudiUtils/include/GaudiUtils/Histo2String.h @@ -31,14 +31,17 @@ namespace AIDA { class IHistogram1D; class IHistogram2D; + class IHistogram3D; } // namespace AIDA // ============================================================================ // ROOT // ============================================================================ class TH1D; // ROOT class TH2D; // ROOT +class TH3D; // ROOT class TH1F; // ROOT class TH2F; // ROOT +class TH3F; // ROOT // ============================================================================ namespace Gaudi { // =========================================================================== @@ -64,6 +67,16 @@ namespace Gaudi { */ GAUDI_API std::ostream& toStream( const TH2D& histo, std::ostream& stream, const bool asXML = false ); // ========================================================================= + /** stream the ROOT histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + * @return the updated stream + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::ostream& toStream( const TH3D& histo, std::ostream& stream, const bool asXML = false ); + // ========================================================================= /** stream the ROOT histogram into output stream * @param histo (INPUT) the histogram to be streamed * @param stream (OUTPUT) the stream @@ -84,6 +97,16 @@ namespace Gaudi { */ GAUDI_API std::ostream& toStream( const TH2F& histo, std::ostream& stream, const bool asXML = false ); // ======================================================================== + /** stream the AIDA histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + * @return the updated stream + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::ostream& toStream( const TH3F& histo, std::ostream& stream, const bool asXML = false ); + // ======================================================================== /** stream the AIDA histogram into output stream * @param histo (INPUT) the histogram to be streamed * @param stream (OUTPUT) the stream @@ -104,6 +127,16 @@ namespace Gaudi { */ GAUDI_API std::ostream& toStream( const AIDA::IHistogram2D& histo, std::ostream& stream, const bool asXML = false ); // ======================================================================== + /** stream the AIDA histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + * @return the updated stream + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::ostream& toStream( const AIDA::IHistogram3D& histo, std::ostream& stream, const bool asXML = false ); + // ======================================================================== /** convert the histogram into the string * @param histo (INPUT) the histogram to be streamed * @param asXML (INPUT) use XML-format @@ -122,6 +155,15 @@ namespace Gaudi { */ GAUDI_API std::string toString( const TH2D& histo, const bool asXML = false ); // ======================================================================== + /** convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::string toString( const TH3D& histo, const bool asXML = false ); + // ======================================================================== /** convert the histogram into the string * @param histo (INPUT) the histogram to be streamed * @param asXML (INPUT) use XML-format @@ -140,6 +182,15 @@ namespace Gaudi { */ GAUDI_API std::string toString( const TH2F& histo, const bool asXML = false ); // ======================================================================== + /** convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::string toString( const TH3F& histo, const bool asXML = false ); + // ======================================================================== /** convert the histogram into the string * @param histo (INPUT) the histogram to be streamed * @param asXML (INPUT) use XML-format @@ -158,6 +209,15 @@ namespace Gaudi { */ GAUDI_API std::string toString( const AIDA::IHistogram2D& histo, const bool asXML = false ); // ======================================================================== + /** convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::string toString( const AIDA::IHistogram3D& histo, const bool asXML = false ); + // ======================================================================== /** convert the histogram into the string * @param histo (INPUT) the histogram to be streamed * @param asXML (INPUT) use XML-format @@ -212,6 +272,24 @@ namespace Gaudi { */ GAUDI_API std::string toString( TH2D* histo ); // ======================================================================== + /** convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::string toString( const TH3D* histo ); + // ======================================================================== + /** convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ + GAUDI_API std::string toString( TH3D* histo ); + // ======================================================================== } // namespace Utils // ========================================================================== } // end of namespace Gaudi diff --git a/GaudiUtils/include/GaudiUtils/HistoParsers.h b/GaudiUtils/include/GaudiUtils/HistoParsers.h index e2e831ec68..b920994403 100644 --- a/GaudiUtils/include/GaudiUtils/HistoParsers.h +++ b/GaudiUtils/include/GaudiUtils/HistoParsers.h @@ -24,14 +24,17 @@ namespace AIDA { class IHistogram1D; // AIDA class IHistogram2D; // AIDA + class IHistogram3D; } // namespace AIDA // ============================================================================= // ROOT // ============================================================================= class TH1D; // ROOT class TH2D; // ROOT +class TH3D; // ROOT class TH1F; // ROOT class TH2F; // ROOT +class TH3F; // ROOT // ============================================================================= namespace Gaudi { // =========================================================================== @@ -51,6 +54,13 @@ namespace Gaudi { */ GAUDI_API StatusCode parse( TH2D& result, const std::string& input ); // ========================================================================= + /** parse ROOT histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ + GAUDI_API StatusCode parse( TH3D& result, const std::string& input ); + // ========================================================================= /** parse ROOT histogram from text representation * @param result (OUTPUT) the histogram * @param input (INPUT) the input to be parsed @@ -65,6 +75,13 @@ namespace Gaudi { */ GAUDI_API StatusCode parse( TH2F& result, const std::string& input ); // ========================================================================= + /** parse AIDA histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ + GAUDI_API StatusCode parse( TH3F& result, const std::string& input ); + // ========================================================================= /** parse AIDA histogram from text representation * @param result (OUTPUT) the histogram * @param input (INPUT) the input to be parsed @@ -79,6 +96,13 @@ namespace Gaudi { */ GAUDI_API StatusCode parse( AIDA::IHistogram2D& result, const std::string& input ); // ========================================================================= + /** parse AIDA histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ + GAUDI_API StatusCode parse( AIDA::IHistogram3D& result, const std::string& input ); + // ========================================================================= /** parse ROOT histogram from text representation * @param result (OUTPUT) the histogram * @param input (INPUT) the input to be parsed @@ -93,6 +117,13 @@ namespace Gaudi { */ GAUDI_API StatusCode parse( TH2D*& result, const std::string& input ); // ========================================================================= + /** parse ROOT histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ + GAUDI_API StatusCode parse( TH3D*& result, const std::string& input ); + // ========================================================================= } // namespace Parsers // =========================================================================== } // end of namespace Gaudi diff --git a/GaudiUtils/src/Lib/H1.h b/GaudiUtils/src/Lib/H1.h index 6f89720d66..aacfcfc3cc 100644 --- a/GaudiUtils/src/Lib/H1.h +++ b/GaudiUtils/src/Lib/H1.h @@ -168,6 +168,64 @@ namespace { Bins m_bins; }; // ========================================================================== + /** @struct H3 + * the trivial representation of the 3D-histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-10-21 + */ + struct H3 final { + // + void setName( std::string value ) { m_name = std::move( value ); } + void setTitle( std::string value ) { m_title = std::move( value ); } + void setXEdges( Edges value ) { m_xedges = std::move( value ); } + void setYEdges( Edges value ) { m_yedges = std::move( value ); } + void setZEdges( Edges value ) { m_zedges = std::move( value ); } + void setBins( Bins value ) { m_bins = std::move( value ); } + // + H3& operator*=( std::string value ) { + setName( std::move( value ) ); + return *this; + } + H3& operator/=( std::string value ) { + setTitle( std::move( value ) ); + return *this; + } + H3& operator&=( Edges value ) { + setXEdges( std::move( value ) ); + return *this; + } + H3& operator|=( Edges value ) { + setYEdges( std::move( value ) ); + return *this; + } + H3& operator-=( Edges value ) { + setZEdges( std::move( value ) ); + return *this; + } + H3& operator+=( Bins value ) { + setBins( std::move( value ) ); + return *this; + } + // + bool ok() const { + if ( m_bins.empty() ) { return false; } + if ( !m_xedges.ok() ) { return false; } + if ( !m_yedges.ok() ) { return false; } + if ( !m_zedges.ok() ) { return false; } + if ( m_bins.size() != ( m_xedges.nBins() + 2 ) * ( m_yedges.nBins() + 2 ) * ( m_zedges.nBins() + 2 ) ) { return false; } + return true; + } + // + // + std::string m_name; + std::string m_title; + Edges m_xedges; + Edges m_yedges; + Edges m_zedges; + Bins m_bins; + }; + + // ========================================================================== } // end of anonymous namespace // ============================================================================ // The END diff --git a/GaudiUtils/src/Lib/Histo2String.cpp b/GaudiUtils/src/Lib/Histo2String.cpp index 5f42ebe2e0..b8250b0485 100644 --- a/GaudiUtils/src/Lib/Histo2String.cpp +++ b/GaudiUtils/src/Lib/Histo2String.cpp @@ -17,11 +17,14 @@ #include "TH1F.h" #include "TH2D.h" #include "TH2F.h" +#include "TH3D.h" +#include "TH3F.h" // ============================================================================ // AIDA // ============================================================================ #include "AIDA/IHistogram1D.h" #include "AIDA/IHistogram2D.h" +#include "AIDA/IHistogram3D.h" // ============================================================================ // GaudiKernel // ============================================================================ @@ -156,6 +159,101 @@ namespace { return stream; } // ========================================================================== + template <class HISTO> + std::ostream& _toStream_3D_( const HISTO& histo, std::ostream& stream, const bool asXML ) { + if ( asXML ) { return Gaudi::Utils::Histos::toXml( histo, stream ); } + // + stream << "{ "; + // + stream << "'name' : "; + Gaudi::Utils::toStream( std::string( histo.GetName() ), stream ) << " , "; + stream << "'title' : "; + Gaudi::Utils::toStream( std::string( histo.GetTitle() ), stream ) << " , "; + // + const TAxis* xaxis = histo.GetXaxis(); + const int xBins = xaxis->GetNbins(); + // + stream << std::endl << "'X' : { "; + if ( xaxis->IsVariableBinSize() ) { + const TArrayD* xbins = xaxis->GetXbins(); + const unsigned int xsize = xbins->GetSize(); + std::vector<double> edges; + for ( unsigned int iBin = 0; iBin < xsize; ++iBin ) { edges.push_back( xbins->At( iBin ) ); } + // the edges + stream << "'edges' : "; + Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl; + } else { + stream << "'nbins' : "; + Gaudi::Utils::toStream( xBins, stream ) << " , "; + stream << "'low' : "; + Gaudi::Utils::toStream( xaxis->GetXmin(), stream ) << " , "; + stream << "'high' : "; + Gaudi::Utils::toStream( xaxis->GetXmax(), stream ) << " }, " << std::endl; + } + // + const TAxis* yaxis = histo.GetYaxis(); + const int yBins = yaxis->GetNbins(); + // + stream << std::endl << "'Y' : { "; + if ( yaxis->IsVariableBinSize() ) { + const TArrayD* ybins = yaxis->GetXbins(); + const unsigned int ysize = ybins->GetSize(); + std::vector<double> edges; + for ( unsigned int iBin = 0; iBin < ysize; ++iBin ) { edges.push_back( ybins->At( iBin ) ); } + // the edges + stream << " 'edges' : "; + Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl; + } else { + stream << "'nbins' : "; + Gaudi::Utils::toStream( yBins, stream ) << " , "; + stream << "'low' : "; + Gaudi::Utils::toStream( yaxis->GetXmin(), stream ) << " , "; + stream << "'high' : "; + Gaudi::Utils::toStream( yaxis->GetXmax(), stream ) << " }, " << std::endl; + } + // + const TAxis* zaxis = histo.GetZaxis(); + const int zBins = zaxis->GetNbins(); + // + stream << std::endl << "'Y' : { "; + if ( zaxis->IsVariableBinSize() ) { + const TArrayD* zbins = zaxis->GetXbins(); + const unsigned int zsize = zbins->GetSize(); + std::vector<double> edges; + for ( unsigned int iBin = 0; iBin < zsize; ++iBin ) { edges.push_back( zbins->At( iBin ) ); } + // the edges + stream << " 'edges' : "; + Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl; + } else { + stream << "'nbins' : "; + Gaudi::Utils::toStream( zBins, stream ) << " , "; + stream << "'low' : "; + Gaudi::Utils::toStream( zaxis->GetXmin(), stream ) << " , "; + stream << "'high' : "; + Gaudi::Utils::toStream( zaxis->GetXmax(), stream ) << " }, " << std::endl; + } + // + // finally: the content + stream << "'bins' : " << std::endl << " [ "; + for ( int kBin = 0; kBin <= zBins + 1; ++kBin ) { + for ( int jBin = yBins + 1; jBin >= 0; --jBin ) { + if ( yBins + 1 != jBin ) { stream << std::endl; } + for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) { + // + Gaudi::Utils::toStream( std::make_pair( histo.GetBinContent( iBin, jBin, kBin ), histo.GetBinError( iBin, jBin, kBin ) ), + stream ); + // + if ( xBins + 1 != iBin || 0 != jBin || 0 != kBin ) { stream << " , "; } + } + } + } + stream << " ]"; + // + stream << " }"; + // + return stream; + } + // ========================================================================== } // end of anonymous namespace // ============================================================================ /* stream the ROOT histogram into output stream @@ -198,6 +296,26 @@ std::ostream& Gaudi::Utils::toStream( const TH2F& histo, std::ostream& stream, c return _toStream_2D_( histo, stream, asXML ); } // ============================================================================ +/* stream the ROOT histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + */ +// ============================================================================ +std::ostream& Gaudi::Utils::toStream( const TH3D& histo, std::ostream& stream, const bool asXML ) { + return _toStream_3D_( histo, stream, asXML ); +} +// ============================================================================ +/* stream the ROOT histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + */ +// ============================================================================ +std::ostream& Gaudi::Utils::toStream( const TH3F& histo, std::ostream& stream, const bool asXML ) { + return _toStream_3D_( histo, stream, asXML ); +} +// ============================================================================ /* stream the AIDA histogram into output stream * @param histo (INPUT) the histogram to be streamed * @param stream (OUTPUT) the stream @@ -220,6 +338,19 @@ std::ostream& Gaudi::Utils::toStream( const AIDA::IHistogram2D& histo, std::ostr auto root = Gaudi::Utils::Aida2ROOT::aida2root( &histo ); return root ? toStream( *root, stream, asXML ) : stream; } +// ============================================================================ +/* stream the AIDA histogram into output stream + * @param histo (INPUT) the histogram to be streamed + * @param stream (OUTPUT) the stream + * @param asXML (INPUT) use XML-format + */ +// ============================================================================ +std::ostream& Gaudi::Utils::toStream( const AIDA::IHistogram3D& histo, std::ostream& stream, const bool asXML ) { + // + auto root = Gaudi::Utils::Aida2ROOT::aida2root( &histo ); + return root ? toStream( *root, stream, asXML ) : stream; +} + // ============================================================================ /* convert the histogram into the string * @param histo (INPUT) the histogram to be streamed @@ -285,6 +416,34 @@ std::string Gaudi::Utils::toString( const TH2F& histo, const bool asXML ) { * @date 2009-09-26 */ // ============================================================================ +std::string Gaudi::Utils::toString( const TH3D& histo, const bool asXML ) { + std::ostringstream o; + toStream( histo, o, asXML ); + return o.str(); +} +// ============================================================================ +/* convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ +// ============================================================================ +std::string Gaudi::Utils::toString( const TH3F& histo, const bool asXML ) { + std::ostringstream o; + toStream( histo, o, asXML ); + return o.str(); +} +// ============================================================================ +/* convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ +// ============================================================================ std::string Gaudi::Utils::toString( const AIDA::IHistogram1D& histo, const bool asXML ) { std::ostringstream o; toStream( histo, o, asXML ); @@ -305,6 +464,20 @@ std::string Gaudi::Utils::toString( const AIDA::IHistogram2D& histo, const bool return o.str(); } // ============================================================================= +/* convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ +// ============================================================================ +std::string Gaudi::Utils::toString( const AIDA::IHistogram3D& histo, const bool asXML ) { + std::ostringstream o; + toStream( histo, o, asXML ); + return o.str(); +} +// ============================================================================= /* convert the histogram into the string * @param histo (INPUT) the histogram to be streamed * @param asXML (INPUT) use XML-format @@ -365,5 +538,25 @@ std::string Gaudi::Utils::toString( TH1D* histo ) { return histo ? toString( *hi // ============================================================================= std::string Gaudi::Utils::toString( TH2D* histo ) { return histo ? toString( *histo ) : "{}"; } // ============================================================================ +/* convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ +// ============================================================================= +std::string Gaudi::Utils::toString( const TH3D* histo ) { return histo ? toString( *histo ) : "{}"; } +// ============================================================================ +/* convert the histogram into the string + * @param histo (INPUT) the histogram to be streamed + * @param asXML (INPUT) use XML-format + * @return the string representation of the histogram + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-26 + */ +// ============================================================================= +std::string Gaudi::Utils::toString( TH3D* histo ) { return histo ? toString( *histo ) : "{}"; } +// ============================================================================ // The END // ============================================================================ diff --git a/GaudiUtils/src/Lib/HistoParsers.cpp b/GaudiUtils/src/Lib/HistoParsers.cpp index 7642a149c1..add4382e3b 100644 --- a/GaudiUtils/src/Lib/HistoParsers.cpp +++ b/GaudiUtils/src/Lib/HistoParsers.cpp @@ -161,6 +161,42 @@ namespace Gaudi { }; REGISTER_GRAMMAR( H2, H2Grammar ); // ======================================================================== + template <typename Iterator, typename Skipper> + class H3Grammar : public qi::grammar<Iterator, H3(), qi::locals<char>, Skipper> { + // ====================================================================== + public: + // ====================================================================== + typedef H3 ResultT; + // ====================================================================== + public: + // ====================================================================== + H3Grammar() : H3Grammar::base_type( result ) { + inner = ( ( ( qi::lit( "name" ) | "'name'" | "\"name\"" ) >> ":" >> name[qi::_val *= qi::_1] ) | + ( ( qi::lit( "title" ) | "'title'" | "\"title\"" ) >> ":" >> title[qi::_val /= qi::_1] ) | + ( ( qi::lit( "X" ) | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':' >> edges[qi::_val &= qi::_1] ) | + ( ( qi::lit( "Y" ) | "'Y'" | "\"Y\"" | "y" | "'y'" | "\"y\"" ) >> ':' >> edges[qi::_val |= qi::_1] ) | + ( ( qi::lit( "Z" ) | "'Z'" | "\"Z\"" | "z" | "'z'" | "\"z\"" ) >> ':' >> edges[qi::_val -= qi::_1] ) | + ( ( qi::lit( "bins" ) | "'bins'" | "\"bins\"" ) >> ':' >> bins[qi::_val += qi::_1] ) ) % + ','; + + begin = + enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'] | enc::char_( '(' )[qi::_val = ')']; + end = enc::char_( qi::_r1 ); + result = ( begin[qi::_a = qi::_1] >> inner[qi::_val = qi::_1] >> end( qi::_a ) ) | inner[qi::_val = qi::_1]; + } + + StringGrammar<Iterator, Skipper> name, title; + EdgeGrammar<Iterator, Skipper> edges; + VectorGrammar<Iterator, std::vector<std::pair<double, double>>, Skipper> bins; + qi::rule<Iterator, H3(), qi::locals<char>, Skipper> result; + qi::rule<Iterator, H3(), Skipper> inner; + qi::rule<Iterator, char()> begin; + qi::rule<Iterator, void( char )> end; + + // ====================================================================== + }; + REGISTER_GRAMMAR( H3, H3Grammar ); + // ======================================================================== } // namespace Parsers // ========================================================================== } // end of namespace Gaudi @@ -183,6 +219,14 @@ namespace { return h2.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE; } // ========================================================================== + /// parse the histogram + StatusCode _parse( H3& h3, const std::string& input ) { + // check the parsing + StatusCode sc = Gaudi::Parsers::parse_( h3, input ); + if ( sc.isFailure() ) { return sc; } // RETURN + return h3.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE; + } + // ========================================================================== template <class HISTO1> std::unique_ptr<HISTO1> _parse_1D( const std::string& input, std::string& name ) { // @@ -283,6 +327,61 @@ namespace { return histo; } // ========================================================================== + template <class HISTO3> + std::unique_ptr<HISTO3> _parse_3D( const std::string& input, std::string& name ) { + // + typedef std::unique_ptr<HISTO3> H3P; + // 1) parse the custom format + // + H3 h3; + StatusCode sc = _parse( h3, input ); + if ( sc.isFailure() || !h3.ok() ) { return H3P(); } // RETURN + // + // 2) create the histogram + // + H3P histo( h3.m_xedges.edges.empty() || h3.m_yedges.edges.empty() || h3.m_zedges.edges.empty() + ? // FIXED binning? + new HISTO3( "", // h3.m_name.c_str () , // NAME + h3.m_title.c_str(), // TITLE + h3.m_xedges.nbins, // #bins + h3.m_xedges.low, // low edge + h3.m_xedges.high, // high edge + h3.m_yedges.nbins, // #bins + h3.m_yedges.low, // low edge + h3.m_yedges.high, // high edge + h3.m_zedges.nbins, // #bins + h3.m_zedges.low, // low edge + h3.m_zedges.high ) + : // high edge + new HISTO3( "", // h3.m_name.c_str () , // NAME + h3.m_title.c_str(), // TITLE + h3.m_xedges.nBins(), // #bins + &h3.m_xedges.edges.front(), // vector of edges + h3.m_yedges.nBins(), // #bins + &h3.m_yedges.edges.front(), + h3.m_zedges.nBins(), + &h3.m_zedges.edges.front() ) ); // vector of edges + + int ibin = 0; + const int xBins = h3.m_xedges.nBins(); + const int yBins = h3.m_yedges.nBins(); + const int zBins = h3.m_yedges.nBins(); + + for ( int kBin = 0; kBin <= zBins + 1; ++kBin ) { + for ( int jBin = yBins + 1; jBin >= 0; --jBin ) { + for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) { + histo->SetBinContent( iBin, jBin, kBin, h3.m_bins[ibin].first ); + histo->SetBinError( iBin, jBin, kBin, h3.m_bins[ibin].second ); + ++ibin; + } + } + } + // + name = h3.m_name; + // + return histo; + } + // ========================================================================== } // end of anonymous namespace // ============================================================================ /* parse ROOT histogram from text representation @@ -382,6 +481,51 @@ StatusCode Gaudi::Parsers::parse( TH2F& result, const std::string& input ) { * @return status code */ // ============================================================================ +StatusCode Gaudi::Parsers::parse( TH3D& result, const std::string& input ) { + // 1) check the parsing + std::string name; + auto h3 = _parse_3D<TH3D>( input, name ); + if ( h3 ) { + result.Reset(); + h3->Copy( result ); // ASSIGN + result.SetName( name.c_str() ); + return StatusCode::SUCCESS; // RETURN + } + // + // XML-like text? + return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input ) + : StatusCode::FAILURE; +} +// ============================================================================ +/* parse ROOT histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ +// ============================================================================ +StatusCode Gaudi::Parsers::parse( TH3F& result, const std::string& input ) { + // 1) check the parsing + std::string name; + auto h3 = _parse_3D<TH3F>( input, name ); + if ( h3 ) { + result.Reset(); + h3->Copy( result ); // ASSIGN + result.SetName( name.c_str() ); + return StatusCode::SUCCESS; // RETURN + } + // + // XML-like text? + if ( std::string::npos != input.find( '<' ) ) { return Gaudi::Utils::Histos::fromXml( result, input ); } + // + return StatusCode::FAILURE; +} +// ============================================================================ +/* parse ROOT histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ +// ============================================================================ StatusCode Gaudi::Parsers::parse( TH1D*& result, const std::string& input ) { if ( result ) { return parse( *result, input ); } // RETURN @@ -422,6 +566,29 @@ StatusCode Gaudi::Parsers::parse( TH2D*& result, const std::string& input ) { : StatusCode::FAILURE; } // ============================================================================ +/* parse ROOT histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ +// ============================================================================ +StatusCode Gaudi::Parsers::parse( TH3D*& result, const std::string& input ) { + if ( result ) { return parse( *result, input ); } // RETURN + + // 1) check the parsing + std::string name; + auto h3 = _parse_3D<TH3D>( input, name ); + if ( h3 ) { + result = h3.release(); + result->SetName( name.c_str() ); + return StatusCode::SUCCESS; // RETURN + } + // + // XML-like text? + return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input ) + : StatusCode::FAILURE; +} +// ============================================================================ /* parse AIDA histogram from text representation * @param result (OUTPUT) the histogram * @param input (INPUT) the input to be parsed @@ -448,5 +615,18 @@ StatusCode Gaudi::Parsers::parse( AIDA::IHistogram2D& result, const std::string& return root ? parse( *root, input ) : StatusCode::FAILURE; } // ============================================================================ +/* parse AIDA histogram from text representation + * @param result (OUTPUT) the histogram + * @param input (INPUT) the input to be parsed + * @return status code + */ +// ============================================================================ +StatusCode Gaudi::Parsers::parse( AIDA::IHistogram3D& result, const std::string& input ) { + // 1) convert to ROOT + auto root = Gaudi::Utils::Aida2ROOT::aida2root( &result ); + // 2) read ROOT histogram + return root ? parse( *root, input ) : StatusCode::FAILURE; +} +// ============================================================================ // The END // ============================================================================ -- GitLab From dd1d43abfcb533d75b7c92815931d721a035f14b Mon Sep 17 00:00:00 2001 From: Maarten van Veghel <mvegh@nikhef.nl> Date: Thu, 24 Jun 2021 00:48:02 +0200 Subject: [PATCH 2/3] string syntax fix --- GaudiUtils/include/GaudiUtils/HistoParsers.h | 2 +- GaudiUtils/src/Lib/Histo2String.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GaudiUtils/include/GaudiUtils/HistoParsers.h b/GaudiUtils/include/GaudiUtils/HistoParsers.h index b920994403..a470c7f92a 100644 --- a/GaudiUtils/include/GaudiUtils/HistoParsers.h +++ b/GaudiUtils/include/GaudiUtils/HistoParsers.h @@ -24,7 +24,7 @@ namespace AIDA { class IHistogram1D; // AIDA class IHistogram2D; // AIDA - class IHistogram3D; + class IHistogram3D; // AIDA } // namespace AIDA // ============================================================================= // ROOT diff --git a/GaudiUtils/src/Lib/Histo2String.cpp b/GaudiUtils/src/Lib/Histo2String.cpp index b8250b0485..50ca2ee663 100644 --- a/GaudiUtils/src/Lib/Histo2String.cpp +++ b/GaudiUtils/src/Lib/Histo2String.cpp @@ -215,7 +215,7 @@ namespace { const TAxis* zaxis = histo.GetZaxis(); const int zBins = zaxis->GetNbins(); // - stream << std::endl << "'Y' : { "; + stream << std::endl << "'Z' : { "; if ( zaxis->IsVariableBinSize() ) { const TArrayD* zbins = zaxis->GetXbins(); const unsigned int zsize = zbins->GetSize(); @@ -243,7 +243,7 @@ namespace { Gaudi::Utils::toStream( std::make_pair( histo.GetBinContent( iBin, jBin, kBin ), histo.GetBinError( iBin, jBin, kBin ) ), stream ); // - if ( xBins + 1 != iBin || 0 != jBin || 0 != kBin ) { stream << " , "; } + if ( !( ( ( xBins + 1 ) == iBin ) && ( 0 == jBin ) && ( ( zBins + 1 ) == kBin ) ) ) { stream << " , "; } } } } -- GitLab From a78290d3d258ea632addd64906e875cfc8a305d6 Mon Sep 17 00:00:00 2001 From: Gitlab CI <noreply@cern.ch> Date: Wed, 23 Jun 2021 22:52:15 +0000 Subject: [PATCH 3/3] Fixed formatting patch generated by https://gitlab.cern.ch/lhcb/Gaudi/-/jobs/14708672 --- GaudiUtils/src/Lib/H1.h | 4 +++- GaudiUtils/src/Lib/Histo2String.cpp | 5 +++-- GaudiUtils/src/Lib/HistoParsers.cpp | 20 +++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/GaudiUtils/src/Lib/H1.h b/GaudiUtils/src/Lib/H1.h index aacfcfc3cc..1356af992c 100644 --- a/GaudiUtils/src/Lib/H1.h +++ b/GaudiUtils/src/Lib/H1.h @@ -212,7 +212,9 @@ namespace { if ( !m_xedges.ok() ) { return false; } if ( !m_yedges.ok() ) { return false; } if ( !m_zedges.ok() ) { return false; } - if ( m_bins.size() != ( m_xedges.nBins() + 2 ) * ( m_yedges.nBins() + 2 ) * ( m_zedges.nBins() + 2 ) ) { return false; } + if ( m_bins.size() != ( m_xedges.nBins() + 2 ) * ( m_yedges.nBins() + 2 ) * ( m_zedges.nBins() + 2 ) ) { + return false; + } return true; } // diff --git a/GaudiUtils/src/Lib/Histo2String.cpp b/GaudiUtils/src/Lib/Histo2String.cpp index 50ca2ee663..8e8af0d393 100644 --- a/GaudiUtils/src/Lib/Histo2String.cpp +++ b/GaudiUtils/src/Lib/Histo2String.cpp @@ -240,8 +240,9 @@ namespace { if ( yBins + 1 != jBin ) { stream << std::endl; } for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) { // - Gaudi::Utils::toStream( std::make_pair( histo.GetBinContent( iBin, jBin, kBin ), histo.GetBinError( iBin, jBin, kBin ) ), - stream ); + Gaudi::Utils::toStream( + std::make_pair( histo.GetBinContent( iBin, jBin, kBin ), histo.GetBinError( iBin, jBin, kBin ) ), + stream ); // if ( !( ( ( xBins + 1 ) == iBin ) && ( 0 == jBin ) && ( ( zBins + 1 ) == kBin ) ) ) { stream << " , "; } } diff --git a/GaudiUtils/src/Lib/HistoParsers.cpp b/GaudiUtils/src/Lib/HistoParsers.cpp index add4382e3b..73d105c0a9 100644 --- a/GaudiUtils/src/Lib/HistoParsers.cpp +++ b/GaudiUtils/src/Lib/HistoParsers.cpp @@ -339,8 +339,7 @@ namespace { // // 2) create the histogram // - H3P histo( h3.m_xedges.edges.empty() || h3.m_yedges.edges.empty() || h3.m_zedges.edges.empty() - ? // FIXED binning? + H3P histo( h3.m_xedges.edges.empty() || h3.m_yedges.edges.empty() || h3.m_zedges.edges.empty() ? // FIXED binning? new HISTO3( "", // h3.m_name.c_str () , // NAME h3.m_title.c_str(), // TITLE h3.m_xedges.nbins, // #bins @@ -352,15 +351,14 @@ namespace { h3.m_zedges.nbins, // #bins h3.m_zedges.low, // low edge h3.m_zedges.high ) - : // high edge - new HISTO3( "", // h3.m_name.c_str () , // NAME - h3.m_title.c_str(), // TITLE - h3.m_xedges.nBins(), // #bins - &h3.m_xedges.edges.front(), // vector of edges - h3.m_yedges.nBins(), // #bins - &h3.m_yedges.edges.front(), - h3.m_zedges.nBins(), - &h3.m_zedges.edges.front() ) ); // vector of edges + : // high edge + new HISTO3( "", // h3.m_name.c_str () , // NAME + h3.m_title.c_str(), // TITLE + h3.m_xedges.nBins(), // #bins + &h3.m_xedges.edges.front(), // vector of edges + h3.m_yedges.nBins(), // #bins + &h3.m_yedges.edges.front(), h3.m_zedges.nBins(), + &h3.m_zedges.edges.front() ) ); // vector of edges int ibin = 0; const int xBins = h3.m_xedges.nBins(); -- GitLab