File indexing completed on 2025-09-17 08:57:31
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 using BufferType = typename HistogramType::BufferType;
0048 template <unsigned int I>
0049 using AxisType = std::tuple_element_t<I, AxisTupleType>;
0050
0051
0052 template <typename OWNER>
0053 HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title = "",
0054 typename HistogramType::AxisTupleType axis = {}, bool doNotInitialize = false )
0055 : m_name{ name }, m_title{ title }, m_axis{ axis } {
0056
0057 owner->declareProperty( titlePropertyName(), m_title, fmt::format( "Title of histogram {}", name ) )
0058 ->template setOwnerType<OWNER>();
0059 ( owner
0060 ->declareProperty( axisPropertyName<ND>(), std::get<ND>( m_axis ),
0061 fmt::format( "Axis {} of histogram {}", ND, name ) )
0062 ->template setOwnerType<OWNER>(),
0063 ... );
0064
0065 if ( !doNotInitialize ) {
0066 if ( owner->FSMState() >= Gaudi::StateMachine::INITIALIZED ) {
0067
0068
0069 createHistogram( *owner );
0070 } else {
0071 owner->registerCallBack( StateMachine::INITIALIZE, [this, owner]() { createHistogram( *owner ); } );
0072 }
0073 }
0074 }
0075
0076
0077 template <typename OWNER>
0078 HistogramWrapperInternal( OWNER const* owner, std::string const& name, std::string const& title = "",
0079 typename HistogramType::AxisTupleType axis = {} )
0080 : m_name{ name }, m_title{ title }, m_axis{ axis } {
0081 createHistogram( *owner );
0082 }
0083
0084 template <typename OWNER>
0085 HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title, AxisType<ND>... allAxis )
0086 : HistogramWrapperInternal( owner, name, title, std::make_tuple( allAxis... ) ) {}
0087
0088
0089 [[nodiscard]] auto operator[]( typename HistogramType::AxisTupleArithmeticType v ) {
0090 if ( !m_histo ) {
0091 throw std::logic_error( fmt::format( "Histogram {} is used before being initialized", m_name ) );
0092 }
0093 return m_histo.value()[v];
0094 }
0095
0096
0097 template <typename OWNER>
0098 void createHistogram( OWNER& owner ) {
0099 m_histo.emplace( &owner, m_name, m_title, m_axis );
0100 }
0101
0102 friend void to_json( nlohmann::json& j, HistogramWrapperInternal const& h ) {
0103 if ( !h.m_histo ) {
0104 throw std::logic_error( fmt::format( "Histogram {} is converted to json before being initialized", h.m_name ) );
0105 }
0106 j = h.m_histo.value();
0107 }
0108
0109
0110 void setTitle( std::string const& title ) {
0111 if ( m_histo )
0112 throw std::logic_error(
0113 fmt::format( "Cannot modify title of histogram {} after it has been initialized", m_name ) );
0114 m_title = title;
0115 }
0116 template <unsigned int N>
0117 void setAxis( std::tuple_element_t<N, typename HistogramType::AxisTupleType> const& axis ) {
0118 if ( m_histo )
0119 throw std::logic_error(
0120 fmt::format( "Cannot modify axis {} of histogram {} after it has been initialized", N, m_name ) );
0121 std::get<N>( m_axis ) = axis;
0122 }
0123
0124 template <unsigned int N>
0125 auto& axis() const {
0126 if ( !m_histo )
0127 throw std::logic_error(
0128 fmt::format( "Cannot get axis {} of histogram {} before it has been initialized", N, m_name ) );
0129 return m_histo->template axis<N>();
0130 }
0131
0132 auto& axis() const {
0133 if ( !m_histo )
0134 throw std::logic_error(
0135 fmt::format( "Cannot get axis of histogram {} before it has been initialized", m_name ) );
0136 return m_histo->axis();
0137 }
0138
0139 void reset() { m_histo.reset(); }
0140
0141
0142 auto buffer() {
0143 if ( !m_histo )
0144 throw std::logic_error( fmt::format( "`buffer()` called on histogram {} before being initialized", m_name ) );
0145 return m_histo->buffer();
0146 }
0147
0148 private:
0149 std::string basePropertyName() const {
0150
0151
0152 std::string name = m_name;
0153 std::replace_if(
0154 begin( name ), end( name ), []( auto& c ) { return !std::isalnum( c ); }, '_' );
0155 return name;
0156 }
0157 std::string titlePropertyName() const { return fmt::format( "{}_Title", basePropertyName() ); }
0158 template <unsigned int N>
0159 std::string axisPropertyName() const {
0160 return fmt::format( "{}_Axis{}", basePropertyName(), N );
0161 }
0162
0163
0164 std::string m_name{};
0165 std::string m_title{};
0166 typename HistogramType::AxisTupleType m_axis{};
0167 std::optional<HistogramType> m_histo{};
0168 };
0169
0170 template <typename HistogramType>
0171 using HistogramWrapper = HistogramWrapperInternal<HistogramType>;
0172
0173 }