Go to the documentation of this file.
20 #include <fmt/format.h>
21 #include <nlohmann/json.hpp>
23 #include <type_traits>
30 template <
typename Tuple,
typename Seq>
32 template <
typename Tuple,
size_t... I>
33 struct SubTuple<Tuple,
std::index_sequence<I...>> {
36 template <
typename Tuple,
unsigned int N>
37 using SubTuple_t =
typename SubTuple<Tuple, std::make_index_sequence<N>>
::type;
40 template <
typename T,
unsigned int ND,
typename = std::make_
integer_sequence<
unsigned int, ND>>
42 template <
typename T,
unsigned int ND,
unsigned int... S>
43 struct make_tuple<T, ND,
std::integer_sequence<unsigned int, S...>> {
44 template <
unsigned int>
48 template <
typename T,
unsigned int ND>
52 template <
typename AxisTupleType>
53 struct AxisToArithmetic;
54 template <
typename... Axis>
55 struct AxisToArithmetic<
std::tuple<Axis...>> {
58 template <
typename AxisTupleType>
60 template <
typename ProfArithmetic,
typename AxisTupleType>
71 fmt::format(
"Histogram title \'{}\' has whitespace at front or back -- please remove", sv ),
81 template <
typename Arithmetic>
91 template <
typename Arithmetic>
93 return v.first *
v.second;
101 template <
typename Arithmetic>
103 return v.first *
v.first *
v.second;
111 template <
typename Arithmetic>
122 template <
typename Arithmetic, atomicity Atomicity>
128 using InternalType = std::conditional_t<isAtomic, AtomicType, OutputType>;
131 return {
v.first.load( std::memory_order_relaxed ),
v.second.load( std::memory_order_relaxed ) };
138 return {
v.first.exchange( newv.first ),
v.second.exchange( newv.second ) };
140 return { std::exchange(
v.first, newv.first ), std::exchange(
v.second, newv.second ) };
150 a.second += b.second;
160 template <atomicity Atomicity,
typename Arithmetic>
162 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, std::pair<unsigned long, Arithmetic>, Atomicity,
163 WeightedProfileTransform, ExtractWeight, WeightedAdder<Arithmetic, Atomicity>> {
167 using Base::operator+=;
170 *
this += { 1ul, weight };
183 template <atomicity Atomicity,
typename Arithmetic>
185 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedProduct> {
196 template <atomicity Atomicity,
typename Arithmetic =
double>
198 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedSquare> {
209 template <atomicity Atomicity,
typename Arithmetic>
218 template <atomicity Atomicity,
typename Arithmetic>
228 template <
typename Arithmetic>
244 :
Axis( (unsigned int)def.bins(), def.lowEdge(), def.highEdge(), def.
title() ) {}
247 unsigned int index( Arithmetic value )
const {
251 if constexpr ( std::is_integral_v<Arithmetic> ) {
256 return idx < 0 ? 0 : ( (
unsigned int)idx >
numBins() ?
numBins() + 1 : (
unsigned int)idx );
263 <<
"\"" << axis.
m_title <<
"\", (";
264 for (
auto const& label : axis.
m_labels ) { o <<
"\"" << label <<
"\", "; }
317 template <
typename Arithmetic>
322 {
"title", axis.
title() } };
341 template <
typename Arithmetic,
unsigned int NIndex>
345 template <
unsigned int NIndex,
typename... Elements>
350 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
352 return computeIndexInternal<0,
std::tuple<AxisType...>>( axis );
354 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
356 return computeTotNBinsInternal<0,
std::tuple<AxisType...>>( axis );
359 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
361 return inAcceptanceInternal<0,
std::tuple<AxisType...>>( axis );
365 template <
int N,
class Tuple>
368 auto const& axis = std::get<N>( allAxis );
369 unsigned int localIndex = axis.index( std::get<N>( *
this ) );
370 if constexpr (
N + 1 == NIndex )
373 return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis );
375 template <
int N,
class Tuple>
377 auto const& axis = std::get<N>( allAxis );
378 unsigned int localNBins = axis.numBins() + 2;
379 if constexpr (
N + 1 == NIndex )
382 return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis );
384 template <
int N,
class Tuple>
386 auto const& axis = std::get<N>( allAxis );
387 bool localAnswer = axis.inAcceptance( std::get<N>( *
this ) );
388 if constexpr (
N + 1 == NIndex )
391 return localAnswer || inAcceptanceInternal<N + 1, Tuple>( allAxis );
400 template <
typename ArithmeticTuple,
unsigned int NIndex,
typename WArithmetic>
404 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
406 return this->first.computeIndex( axis );
408 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
413 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
415 return this->first.inAcceptance( axis );
464 template <
atomicity Atomicity,
typename InputType,
typename Arithmetic,
465 template <atomicity Ato,
typename Arith>
typename BaseAccumulatorT,
typename AxisTupleType>
467 template <atomicity,
typename,
typename,
template <atomicity,
typename>
typename,
typename>
480 template <atomicity ato>
495 template <atomicity ato>
503 [[nodiscard]]
auto operator[](
typename InputType::ValueType
v ) {
507 template <
unsigned int N>
509 return std::get<N>(
m_axis );
532 std::tuple_element_t<0, AxisTupleType>
const&
_getAxis(
size_t i,
535 fmt::format(
"Retrieving axis {} in Histogram of dimension {}", i, std::tuple_size_v<AxisTupleType> ) );
537 template <
size_t N,
typename = std::enable_if_t<std::tuple_size_v<AxisTupleType> != N>>
539 if ( i ==
N )
return std::get<N>(
m_axis );
556 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
566 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
577 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
588 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
651 template <
unsigned int ND,
atomicity Atomicity,
typename Arithmetic,
const char* Type,
652 template <atomicity,
typename,
typename,
typename>
typename Accumulator,
typename AxisTupleType>
654 template <
unsigned int ND,
atomicity Atomicity,
typename Arithmetic,
const char* Type,
655 template <atomicity,
typename,
typename,
typename>
typename Accumulator,
typename... AxisTypes>
657 :
public BufferableCounter<Atomicity, Accumulator, Arithmetic, std::integral_constant<unsigned int, ND>,
658 std::tuple<AxisTypes...>> {
663 using AccumulatorType = Accumulator<Atomicity, Arithmetic, NumberDimensions, AxisTupleType>;
669 template <
typename OWNER>
671 :
Parent( owner,
name, *this, axis ), m_title( title ) {
675 template <
typename OWNER>
679 template <
typename stream>
681 o << ND <<
"D Histogram with config ";
682 std::apply( [&o](
auto&&...
args ) { ( ( o <<
args <<
"\n" ), ... ); }, this->axis() );
686 return printImpl( o, tableFormat );
695 bins.
reserve( this->totNBins() );
696 unsigned long totNEntries{ 0 };
697 for (
unsigned int i = 0; i < this->totNBins(); i++ ) {
699 totNEntries += this->nEntries( i );
703 {
"title", m_title },
705 {
"empty", totNEntries == 0 },
706 {
"nEntries", totNEntries },
707 {
"axis", this->axis() },
725 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
731 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
737 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
743 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
auto operator[](typename InputType::ValueType v)
friend std::ostream & operator<<(std::ostream &o, Axis const &axis)
WeightedSquareAccumulator.
Arithmetic m_minValue
min and max values on this axis
unsigned int index(Arithmetic value) const
returns the bin number for a given value, ranging from 0 (underflow) to nBins+1 (overflow)
void requireValidTitle(std::string_view sv)
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedSigmaAccumulator, AxisTupleType > WeightedProfileHistogramingAccumulator
Class implementing a weighted profile histogram accumulator.
stream & printImpl(stream &o, bool) const
auto maxValue(unsigned int i) const
auto minValue(unsigned int i) const
Axis(unsigned int nBins=0, Arithmetic minValue=Arithmetic{}, Arithmetic maxValue=Arithmetic{}, std::string title={}, std::vector< std::string > labels={})
A base counter dealing with Histograms.
Arithmetic ArithmeticType
std::string const & title() const
std::conditional_t< isAtomic, AtomicType, OutputType > InternalType
constexpr char weightedHistogramString[]
unsigned int m_totNBins
total number of bins in this histogram, under and overflow included
Arithmetic sumOfWeights() const
HistogramingCounterBase(OWNER *owner, std::string const &name, std::string const &title, AxisTupleType axis)
This constructor takes the axis as a tuple.
HistogramingAccumulatorInternal(AxisTupleType axis)
virtual void to_json(nlohmann::json &j) const
Accumulator< Atomicity, Arithmetic, NumberDimensions, AxisTupleType > AccumulatorType
void setMaxValue(Arithmetic v)
AxisTupleType m_axis
set of Axis of this Histogram
SigmaAccumulatorBase< Atomicity, Arithmetic, WeightedAveragingAccumulator, WeightedSquareAccumulator > WeightedSigmaAccumulator
WeightedSigmaAccumulator.
constexpr char weightedProfilehistogramString[]
Axis(Gaudi::Histo1DDef const &def)
unsigned long nEntries() const
AveragingAccumulatorBase.
unsigned int numBins() const
HistogramingAccumulatorInternal< Atomicity, HistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value >, Arithmetic, SigmaAccumulator, AxisTupleType > ProfileHistogramingAccumulator
Class implementing a profile histogram accumulator.
constexpr char profilehistogramString[]
static constexpr OutputType DefaultValue()
std::vector< std::string > m_labels
labels for the bins
SigmaAccumulatorBase< Atomicity, Arithmetic, AveragingAccumulator, SquareAccumulator > SigmaAccumulator
SigmaAccumulator.
std::string const m_title
static constexpr OutputType getValue(const InternalType &v) noexcept
void setNumBins(unsigned int n)
std::vector< std::string > const labels() const
unsigned int nBins
number of bins for this Axis FIXME : should be private and called m_nBins but will break backward com...
std::string const & title() const
typename std::tuple_element< 0, AxisTupleType >::type::ArithmeticType AxisArithmeticType
for backward compatibility with previous implementation, should not be used FIXME
auto binValue(unsigned int i) const
friend class GenericAccumulator
friend void mergeAndReset(HistogramingCounterBase &h, HistogramingCounterBase &o)
std::unique_ptr< BaseAccumulator[]> m_value
Histogram content.
static RegularType exchange(InternalType &v, RegularType newv) noexcept
An Adder ValueHandler, taking weight into account and computing a count plus the sum of the weights I...
bool inAcceptance(Arithmetic value) const
says whether the given value is within the range of the axis
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
void setTitle(std::string const &t)
Generic Accumulator, templated by.
std::tuple_element_t< 0, AxisTupleType > const & _getAxis(size_t i, typename std::tuple_size< AxisTupleType >::type) const
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
void to_json(nlohmann::json &j, const Axis< Arithmetic > &axis)
automatic conversion of the Axis type to json
BaseAccumulatorT< Atomicity, Arithmetic > BaseAccumulator
A Product functor, take a pair (value, weight) as input.
An empty ancester of all counters that provides a buffer method that returns a buffer on itself Also ...
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Internal Accumulator class dealing with Histograming.
static constexpr bool isAtomic
friend void reset(HistogramingCounterBase &c)
auto nEntries(unsigned int i) const
Arithmetic maxValue() const
std::pair< unsigned long, Arithmetic > RegularType
A WeightedSquare functor, take a pair (value, weight) as input.
HistogramingAccumulatorInternal(construct_empty_t, const HistogramingAccumulatorInternal< ato, InputType, Arithmetic, BaseAccumulatorT, AxisTupleType > &other)
std::string m_title
title of this axis
friend class HistogramingAccumulatorInternal
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedCountAccumulator, AxisTupleType > WeightedHistogramingAccumulator
Class implementing a weighted histogram accumulator.
atomicity
Defines atomicity of the accumulators.
void fetch_add(AtomicType &atVar, Arithmetic value)
generic fetch_add, also dealing with atomic types with no fetch_add member method
Arithmetic minValue() const
constant used to disambiguate construction of an empty Accumulator versus the copy constructor.
WeightedCountAccumulator.
void setMinValue(Arithmetic v)
constexpr static const auto FAILURE
friend void to_json(nlohmann::json &j, HistogramingCounterBase const &h)
HistogramingAccumulatorInternal< Atomicity, HistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value >, unsigned long, IntegralAccumulator, AxisTupleType > HistogramingAccumulator
Class implementing a regular histogram accumulator.
BaseAccumulator & accumulator(unsigned int index) const
HistogramingAccumulatorInternal & operator+=(InputType v)
constexpr char histogramString[]
Arithmetic m_ratio
precomputed ratio to convert a value into bin number equal to nBins/(maxValue-minValue).
WeightedCountAccumulator operator+=(const Arithmetic weight)
overload of operator+= to be able to only give weight and no value
typename AccumulatorType::AxisTupleArithmeticType AxisTupleArithmeticType
Definition of a default type of Histogram Axis It contains number of bins, min and max value plus a t...
void mergeAndReset(HistogramingAccumulatorInternal< ato, InputType, Arithmetic, BaseAccumulatorT, AxisTupleType > &other)
auto & _getAxis(size_t i, std::integral_constant< size_t, N >) const
HistogramingCounterBase(OWNER *owner, std::string const &name, std::string const &title, AxisTypes... allAxis)
This constructor takes the axis one by one, when ND >= 2. If ND = 1, the other one can be used.
typename InputType::ValueType AxisTupleArithmeticType
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
static void merge(InternalType &a, RegularType b) noexcept
auto nBins(unsigned int i) const