Go to the documentation of this file.
19 #include <fmt/format.h>
20 #include <nlohmann/json.hpp>
22 #include <type_traits>
29 template <
typename Tuple,
typename Seq>
31 template <
typename Tuple,
size_t... I>
32 struct SubTuple<Tuple,
std::index_sequence<I...>> {
35 template <
typename Tuple,
unsigned int N>
36 using SubTuple_t =
typename SubTuple<Tuple, std::make_index_sequence<N>>
::type;
39 template <
typename T,
unsigned int ND,
typename = std::make_
integer_sequence<
unsigned int, ND>>
41 template <
typename T,
unsigned int ND,
unsigned int... S>
42 struct make_tuple<T, ND,
std::integer_sequence<unsigned int, S...>> {
43 template <
unsigned int>
47 template <
typename T,
unsigned int ND>
51 template <
typename AxisTupleType>
52 struct AxisToArithmetic;
53 template <
typename... Axis>
54 struct AxisToArithmetic<
std::tuple<Axis...>> {
57 template <
typename AxisTupleType>
59 template <
typename ProfArithmetic,
typename AxisTupleType>
70 fmt::format(
"Histogram title \'{}\' has whitespace at front or back -- please remove", sv ),
80 template <
typename Arithmetic>
90 template <
typename Arithmetic>
92 return v.first *
v.second;
100 template <
typename Arithmetic>
102 return v.first *
v.first *
v.second;
111 template <
typename Arithmetic, atomicity Atomicity>
117 using InternalType = std::conditional_t<isAtomic, AtomicType, OutputType>;
120 return {
v.first.load( std::memory_order_relaxed ),
v.second.load( std::memory_order_relaxed ) };
127 return {
v.first.exchange( newv.first ),
v.second.exchange( newv.second ) };
129 return { std::exchange(
v.first, newv.first ), std::exchange(
v.second, newv.second ) };
139 a.second += b.second;
149 template <atomicity Atomicity,
typename Arithmetic>
151 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, std::pair<unsigned long, Arithmetic>, Atomicity, Identity,
152 ExtractWeight, WeightedAdder<Arithmetic, Atomicity>> {
156 using Base::operator+=;
159 *
this += { 1ul, weight };
172 template <atomicity Atomicity,
typename Arithmetic>
174 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedProduct> {
185 template <atomicity Atomicity,
typename Arithmetic =
double>
187 :
GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedSquare> {
198 template <atomicity Atomicity,
typename Arithmetic>
207 template <atomicity Atomicity,
typename Arithmetic>
217 template <
typename Arithmetic>
233 :
Axis( (unsigned int)def.bins(), def.lowEdge(), def.highEdge(), def.
title() ){};
236 unsigned int index( Arithmetic value )
const {
240 if constexpr ( std::is_integral_v<Arithmetic> ) {
245 return idx < 0 ? 0 : ( (
unsigned int)idx >
numBins() ?
numBins() + 1 : (
unsigned int)idx );
252 <<
"\"" << axis.
m_title <<
"\", (";
253 for (
auto const& label : axis.
m_labels ) { o <<
"\"" << label <<
"\", "; }
306 template <
typename Arithmetic>
311 {
"title", axis.
title() } };
330 template <
typename Arithmetic,
unsigned int NIndex>
334 template <
unsigned int NIndex,
typename... Elements>
339 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
341 return computeIndexInternal<0,
std::tuple<AxisType...>>( axis );
343 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
345 return computeTotNBinsInternal<0,
std::tuple<AxisType...>>( axis );
348 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
350 return inAcceptanceInternal<0,
std::tuple<AxisType...>>( axis );
354 template <
int N,
class Tuple>
357 auto const& axis = std::get<N>( allAxis );
358 unsigned int localIndex = axis.index( std::get<N>( *
this ) );
359 if constexpr (
N + 1 == NIndex )
362 return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis );
364 template <
int N,
class Tuple>
366 auto const& axis = std::get<N>( allAxis );
367 unsigned int localNBins = axis.numBins() + 2;
368 if constexpr (
N + 1 == NIndex )
371 return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis );
373 template <
int N,
class Tuple>
375 auto const& axis = std::get<N>( allAxis );
376 bool localAnswer = axis.inAcceptance( std::get<N>( *
this ) );
377 if constexpr (
N + 1 == NIndex )
380 return localAnswer || inAcceptanceInternal<N + 1, Tuple>( allAxis );
389 template <
typename ArithmeticTuple,
unsigned int NIndex,
typename WArithmetic>
393 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
395 return this->first.computeIndex( axis );
397 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
402 template <
class... AxisType,
typename =
typename std::enable_if_t<(
sizeof...( AxisType ) == NIndex )>>
404 return this->first.inAcceptance( axis );
453 template <
atomicity Atomicity,
typename InputType,
typename Arithmetic,
454 template <atomicity Ato,
typename Arith>
typename BaseAccumulatorT,
typename AxisTupleType>
456 template <atomicity,
typename,
typename,
template <atomicity,
typename>
typename,
typename>
469 template <atomicity ato>
484 template <atomicity ato>
492 [[nodiscard]]
auto operator[](
typename InputType::ValueType
v ) {
496 template <
unsigned int N>
498 return std::get<N>(
m_axis );
520 std::tuple_element_t<0, AxisTupleType>
const&
_getAxis(
size_t i,
523 fmt::format(
"Retrieving axis {} in Histogram of dimension {}", i, std::tuple_size_v<AxisTupleType> ) );
525 template <
size_t N,
typename = std::enable_if_t<std::tuple_size_v<AxisTupleType> != N>>
527 if ( i ==
N )
return std::get<N>(
m_axis );
544 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
554 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
565 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
576 template <atomicity Atomicity,
typename Arithmetic,
typename ND,
typename AxisTupleType>
639 template <
unsigned int ND,
atomicity Atomicity,
typename Arithmetic,
const char* Type,
640 template <atomicity,
typename,
typename,
typename>
typename Accumulator,
typename AxisTupleType>
642 template <
unsigned int ND,
atomicity Atomicity,
typename Arithmetic,
const char* Type,
643 template <atomicity,
typename,
typename,
typename>
typename Accumulator,
typename... AxisTypes>
645 :
public BufferableCounter<Atomicity, Accumulator, Arithmetic, std::integral_constant<unsigned int, ND>,
646 std::tuple<AxisTypes...>> {
651 using AccumulatorType = Accumulator<Atomicity, Arithmetic, NumberDimensions, AxisTupleType>;
657 template <
typename OWNER>
659 :
Parent( owner,
name, *this, axis ), m_title( title ) {
663 template <
typename OWNER>
667 template <
typename stream>
669 o << ND <<
"D Histogram with config ";
670 std::apply( [&o](
auto&&...
args ) { ( ( o <<
args <<
"\n" ), ... ); }, this->axis() );
674 return printImpl( o, tableFormat );
683 bins.
reserve( this->totNBins() );
684 unsigned long totNEntries{ 0 };
685 for (
unsigned int i = 0; i < this->totNBins(); i++ ) {
687 totNEntries += this->nEntries( i );
691 {
"title", m_title },
693 {
"empty", totNEntries == 0 },
694 {
"nEntries", totNEntries },
695 {
"axis", this->axis() },
713 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
719 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
725 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
731 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