File indexing completed on 2025-04-26 09:01:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013 #include <Gaudi/Accumulators/StaticHistogram.h>
0014
0015 namespace Gaudi::Accumulators {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 template <typename HistogramType,
0039 typename Seq =
0040 std::make_integer_sequence<unsigned int, std::tuple_size_v<typename HistogramType::AxisTupleType>>>
0041 class HistogramWrapperInternal;
0042 template <typename HistogramType, unsigned int... ND>
0043 class HistogramWrapperInternal<HistogramType, std::integer_sequence<unsigned int, ND...>> {
0044 public:
0045 using AxisTupleType = typename HistogramType::AxisTupleType;
0046 using AxisArithmeticType = typename HistogramType::AxisArithmeticType;
0047 template <unsigned int I>
0048 using AxisType = std::tuple_element_t<I, AxisTupleType>;
0049
0050
0051 template <typename OWNER>
0052 HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title = "",
0053 typename HistogramType::AxisTupleType axis = {}, bool doNotInitialize = false )
0054 : m_name{ name }, m_title{ title }, m_axis{ axis } {
0055
0056 owner->declareProperty( titlePropertyName(), m_title, fmt::format( "Title of histogram {}", name ) )
0057 ->template setOwnerType<OWNER>();
0058 ( owner
0059 ->declareProperty( axisPropertyName<ND>(), std::get<ND>( m_axis ),
0060 fmt::format( "Axis {} of histogram {}", ND, name ) )
0061 ->template setOwnerType<OWNER>(),
0062 ... );
0063
0064 if ( !doNotInitialize ) {
0065 if ( owner->FSMState() >= Gaudi::StateMachine::INITIALIZED ) {
0066
0067
0068 createHistogram( *owner );
0069 } else {
0070 owner->registerCallBack( StateMachine::INITIALIZE, [this, owner]() { createHistogram( *owner ); } );
0071 }
0072 }
0073 }
0074
0075
0076 template <typename OWNER>
0077 HistogramWrapperInternal( OWNER const* owner, std::string const& name, std::string const& title = "",
0078 typename HistogramType::AxisTupleType axis = {} )
0079 : m_name{ name }, m_title{ title }, m_axis{ axis } {
0080 createHistogram( *owner );
0081 }
0082
0083 template <typename OWNER>
0084 HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title, AxisType<ND>... allAxis )
0085 : HistogramWrapperInternal( owner, name, title, std::make_tuple( allAxis... ) ) {}
0086
0087
0088 [[nodiscard]] auto operator[]( typename HistogramType::AxisTupleArithmeticType&& v ) {
0089 if ( !m_histo ) {
0090 throw std::logic_error( fmt::format( "Histogram {} is used before being initialized", m_name ) );
0091 }
0092 return m_histo.value()[std::forward<typename HistogramType::AxisTupleArithmeticType>( v )];
0093 }
0094
0095
0096 template <typename OWNER>
0097 void createHistogram( OWNER& owner ) {
0098 m_histo.emplace( &owner, m_name, m_title, m_axis );
0099 }
0100
0101 friend void to_json( nlohmann::json& j, HistogramWrapperInternal const& h ) {
0102 if ( !h.m_histo ) {
0103 throw std::logic_error( fmt::format( "Histogram {} is converted to json before being initialized", h.m_name ) );
0104 }
0105 j = h.m_histo.value();
0106 }
0107
0108
0109 void setTitle( std::string const& title ) {
0110 if ( m_histo )
0111 throw std::logic_error(
0112 fmt::format( "Cannot modify title of histogram {} after it has been initialized", m_name ) );
0113 m_title = title;
0114 }
0115 template <unsigned int N>
0116 void setAxis( std::tuple_element_t<N, typename HistogramType::AxisTupleType> const& axis ) {
0117 if ( m_histo )
0118 throw std::logic_error(
0119 fmt::format( "Cannot modify axis {} of histogram {} after it has been initialized", N, m_name ) );
0120 std::get<N>( m_axis ) = axis;
0121 }
0122
0123 void reset() { m_histo.reset(); }
0124
0125
0126 auto buffer() {
0127 if ( !m_histo )
0128 throw std::logic_error( fmt::format( "`buffer()` called on histogram {} before being initialized", m_name ) );
0129 return m_histo->buffer();
0130 }
0131
0132 private:
0133 std::string basePropertyName() const {
0134
0135
0136 std::string name = m_name;
0137 std::replace_if(
0138 begin( name ), end( name ), []( auto& c ) { return !std::isalnum( c ); }, '_' );
0139 return name;
0140 }
0141 std::string titlePropertyName() const { return fmt::format( "{}_Title", basePropertyName() ); }
0142 template <unsigned int N>
0143 std::string axisPropertyName() const {
0144 return fmt::format( "{}_Axis{}", basePropertyName(), N );
0145 }
0146
0147
0148 std::string m_name{};
0149 std::string m_title{};
0150 typename HistogramType::AxisTupleType m_axis{};
0151 std::optional<HistogramType> m_histo{};
0152 };
0153
0154 template <typename HistogramType>
0155 using HistogramWrapper = HistogramWrapperInternal<HistogramType>;
0156
0157 }