The Gaudi Framework  master (37c0b60a)
HistogramWrapper.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #pragma once
12 
14 
15 namespace Gaudi::Accumulators {
16 
38  template <typename HistogramType,
39  typename Seq =
40  std::make_integer_sequence<unsigned int, std::tuple_size_v<typename HistogramType::AxisTupleType>>>
42  template <typename HistogramType, unsigned int... ND>
43  class HistogramWrapperInternal<HistogramType, std::integer_sequence<unsigned int, ND...>> {
44  public:
45  using AxisTupleType = typename HistogramType::AxisTupleType;
46  using AxisArithmeticType = typename HistogramType::AxisArithmeticType;
47  using BufferType = typename HistogramType::BufferType;
48  template <unsigned int I>
49  using AxisType = std::tuple_element_t<I, AxisTupleType>;
50 
52  template <typename OWNER>
53  HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title = "",
54  typename HistogramType::AxisTupleType axis = {}, bool doNotInitialize = false )
55  : m_name{ name }, m_title{ title }, m_axis{ axis } {
56  // Create associated properties
57  owner->declareProperty( titlePropertyName(), m_title, fmt::format( "Title of histogram {}", name ) )
58  ->template setOwnerType<OWNER>();
59  ( owner
60  ->declareProperty( axisPropertyName<ND>(), std::get<ND>( m_axis ),
61  fmt::format( "Axis {} of histogram {}", ND, name ) )
62  ->template setOwnerType<OWNER>(),
63  ... );
64  // register creation of the Histogram at initialization time
65  if ( !doNotInitialize ) {
66  if ( owner->FSMState() >= Gaudi::StateMachine::INITIALIZED ) {
67  // if the owner is already initialized (e.g. the histogram is being created during `start()`)
68  // it is too late to register the callback
69  createHistogram( *owner );
70  } else {
71  owner->registerCallBack( StateMachine::INITIALIZE, [this, owner]() { createHistogram( *owner ); } );
72  }
73  }
74  }
77  template <typename OWNER>
78  HistogramWrapperInternal( OWNER const* owner, std::string const& name, std::string const& title = "",
79  typename HistogramType::AxisTupleType axis = {} )
80  : m_name{ name }, m_title{ title }, m_axis{ axis } {
81  createHistogram( *owner );
82  }
84  template <typename OWNER>
85  HistogramWrapperInternal( OWNER* owner, std::string const& name, std::string const& title, AxisType<ND>... allAxis )
86  : HistogramWrapperInternal( owner, name, title, std::make_tuple( allAxis... ) ) {}
87 
89  [[nodiscard]] auto operator[]( typename HistogramType::AxisTupleArithmeticType v ) {
90  if ( !m_histo ) {
91  throw std::logic_error( fmt::format( "Histogram {} is used before being initialized", m_name ) );
92  }
93  return m_histo.value()[v];
94  }
95 
97  template <typename OWNER>
98  void createHistogram( OWNER& owner ) {
99  m_histo.emplace( &owner, m_name, m_title, m_axis );
100  }
101 
103  if ( !h.m_histo ) {
104  throw std::logic_error( fmt::format( "Histogram {} is converted to json before being initialized", h.m_name ) );
105  }
106  j = h.m_histo.value();
107  }
108 
109  // set directly some properties, only if histogram was not yet created
110  void setTitle( std::string const& title ) {
111  if ( m_histo )
112  throw std::logic_error(
113  fmt::format( "Cannot modify title of histogram {} after it has been initialized", m_name ) );
114  m_title = title;
115  }
116  template <unsigned int N>
117  void setAxis( std::tuple_element_t<N, typename HistogramType::AxisTupleType> const& axis ) {
118  if ( m_histo )
119  throw std::logic_error(
120  fmt::format( "Cannot modify axis {} of histogram {} after it has been initialized", N, m_name ) );
121  std::get<N>( m_axis ) = axis;
122  }
123 
124  template <unsigned int N>
125  auto& axis() const {
126  if ( !m_histo )
127  throw std::logic_error(
128  fmt::format( "Cannot get axis {} of histogram {} before it has been initialized", N, m_name ) );
129  return m_histo->template axis<N>();
130  }
131 
132  auto& axis() const {
133  if ( !m_histo )
134  throw std::logic_error(
135  fmt::format( "Cannot get axis of histogram {} before it has been initialized", m_name ) );
136  return m_histo->axis();
137  }
138 
139  void reset() { m_histo.reset(); }
140 
141  // wrapping some methods of the underlyoing histogram
142  auto buffer() {
143  if ( !m_histo )
144  throw std::logic_error( fmt::format( "`buffer()` called on histogram {} before being initialized", m_name ) );
145  return m_histo->buffer();
146  }
147 
148  private:
150  // properties are used as identifiers in python and thus cannot anything alse than _, letters and numbers
151  // we thus replace anything else with '_' in the property names
152  std::string name = m_name;
154  begin( name ), end( name ), []( auto& c ) { return !std::isalnum( c ); }, '_' );
155  return name;
156  }
157  std::string titlePropertyName() const { return fmt::format( "{}_Title", basePropertyName() ); }
158  template <unsigned int N>
160  return fmt::format( "{}_Axis{}", basePropertyName(), N );
161  }
162 
163  // Members of the custom histogrem
164  std::string m_name{};
165  std::string m_title{};
166  typename HistogramType::AxisTupleType m_axis{};
167  std::optional<HistogramType> m_histo{};
168  };
169 
170  template <typename HistogramType>
172 
173 } // namespace Gaudi::Accumulators
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::to_json
friend void to_json(nlohmann::json &j, HistogramWrapperInternal const &h)
Definition: HistogramWrapper.h:102
std::string
STL class.
IOTest.N
N
Definition: IOTest.py:112
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::titlePropertyName
std::string titlePropertyName() const
Definition: HistogramWrapper.h:157
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::AxisTupleType
typename HistogramType::AxisTupleType AxisTupleType
Definition: HistogramWrapper.h:45
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:86
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::HistogramWrapperInternal
HistogramWrapperInternal(OWNER *owner, std::string const &name, std::string const &title, AxisType< ND >... allAxis)
constructor with more natural syntax for axis
Definition: HistogramWrapper.h:85
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::HistogramWrapperInternal
HistogramWrapperInternal(OWNER *owner, std::string const &name, std::string const &title="", typename HistogramType::AxisTupleType axis={}, bool doNotInitialize=false)
constructor, only creates a set of Properties
Definition: HistogramWrapper.h:53
std::isalnum
T isalnum(T... args)
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::axis
auto & axis() const
Definition: HistogramWrapper.h:132
gaudirun.c
c
Definition: gaudirun.py:525
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::setTitle
void setTitle(std::string const &title)
Definition: HistogramWrapper.h:110
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::axis
auto & axis() const
Definition: HistogramWrapper.h:125
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::BufferType
typename HistogramType::BufferType BufferType
Definition: HistogramWrapper.h:47
std::replace_if
T replace_if(T... args)
Gaudi::StateMachine::INITIALIZE
@ INITIALIZE
Definition: StateMachine.h:35
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:136
ProduceConsume.j
j
Definition: ProduceConsume.py:104
AlgSequencer.h
h
Definition: AlgSequencer.py:31
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::reset
void reset()
Definition: HistogramWrapper.h:139
std::logic_error
STL class.
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::HistogramWrapperInternal
HistogramWrapperInternal(OWNER const *owner, std::string const &name, std::string const &title="", typename HistogramType::AxisTupleType axis={})
constructor with const owner (i.e.
Definition: HistogramWrapper.h:78
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::basePropertyName
std::string basePropertyName() const
Definition: HistogramWrapper.h:149
Gaudi::Accumulators
Definition: CounterArray.h:18
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::Accumulators::HistogramWrapperInternal
A Wrapper of a static Histogram base class using Properties to define title and axis.
Definition: HistogramWrapper.h:41
std
STL namespace.
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::setAxis
void setAxis(std::tuple_element_t< N, typename HistogramType::AxisTupleType > const &axis)
Definition: HistogramWrapper.h:117
Gaudi::StateMachine::INITIALIZED
@ INITIALIZED
Definition: StateMachine.h:25
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::createHistogram
void createHistogram(OWNER &owner)
creation of the internal histogram, from the properties
Definition: HistogramWrapper.h:98
Properties.v
v
Definition: Properties.py:122
IOTest.end
end
Definition: IOTest.py:125
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::AxisType
std::tuple_element_t< I, AxisTupleType > AxisType
Definition: HistogramWrapper.h:49
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::buffer
auto buffer()
Definition: HistogramWrapper.h:142
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::operator[]
auto operator[](typename HistogramType::AxisTupleArithmeticType v)
override of operator[] with extra checking that initialization happened
Definition: HistogramWrapper.h:89
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::axisPropertyName
std::string axisPropertyName() const
Definition: HistogramWrapper.h:159
StaticHistogram.h
Gaudi::Accumulators::HistogramWrapperInternal< HistogramType, std::integer_sequence< unsigned int, ND... > >::AxisArithmeticType
typename HistogramType::AxisArithmeticType AxisArithmeticType
Definition: HistogramWrapper.h:46