The Gaudi Framework  master (53dee381)
Loading...
Searching...
No Matches
StaticHistogram.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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
13#include <Gaudi/Accumulators.h>
14#include <Gaudi/MonitoringHub.h>
16
17#include <array>
18#include <cassert>
19#include <cmath>
20#include <format>
21#include <nlohmann/json.hpp>
22#include <string>
23#include <type_traits>
24#include <utility>
25#include <vector>
26
27namespace {
28 // Helper class creating a "subtuple" type from a tuple type by keeping only
29 // the first N items.
30 template <typename Tuple, typename Seq>
31 struct SubTuple;
32 template <typename Tuple, size_t... I>
33 struct SubTuple<Tuple, std::index_sequence<I...>> {
34 using type = decltype( std::make_tuple( std::get<I>( std::declval<Tuple>() )... ) );
35 };
36 template <typename Tuple, unsigned int N>
37 using SubTuple_t = typename SubTuple<Tuple, std::make_index_sequence<N>>::type;
38
40 template <typename T, unsigned int ND, typename = std::make_integer_sequence<unsigned int, ND>>
41 struct make_tuple;
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>
45 using typeMap = T;
46 using type = std::tuple<typeMap<S>...>;
47 };
48 template <typename T, unsigned int ND>
49 using make_tuple_t = typename make_tuple<T, ND>::type;
50
52 template <typename AxisTupleType>
53 struct AxisToArithmetic;
54 template <typename... Axis>
55 struct AxisToArithmetic<std::tuple<Axis...>> {
56 using type = std::tuple<typename Axis::ArithmeticType...>;
57 };
58 template <typename AxisTupleType>
59 using AxisToArithmetic_t = typename AxisToArithmetic<AxisTupleType>::type;
60 template <typename ProfArithmetic, typename AxisTupleType>
61 using ProfileAxisToArithmetic_t = decltype( std::tuple_cat( std::declval<AxisToArithmetic_t<AxisTupleType>>(),
62 std::declval<std::tuple<ProfArithmetic>>() ) );
63} // namespace
64
65namespace Gaudi::Accumulators {
66
67 namespace details {
68 inline void requireValidTitle( std::string_view sv ) {
69 if ( !sv.empty() && ( std::isspace( sv.back() ) || std::isspace( sv.front() ) ) ) {
70 throw GaudiException(
71 std::format( "Histogram title \'{}\' has whitespace at front or back -- please remove", sv ),
72 "Gaudi::Accumulators", StatusCode::FAILURE );
73 }
74 }
75 } // namespace details
76
81 template <typename Arithmetic>
82 constexpr decltype( auto ) operator()( const std::pair<unsigned long, Arithmetic>& v ) const noexcept {
83 return v.second;
84 }
85 };
86
91 template <typename Arithmetic>
92 constexpr decltype( auto ) operator()( const std::pair<Arithmetic, Arithmetic>& v ) const noexcept {
93 return v.first * v.second;
94 }
95 };
96
101 template <typename Arithmetic>
102 constexpr decltype( auto ) operator()( const std::pair<Arithmetic, Arithmetic>& v ) const noexcept {
103 return v.first * v.first * v.second;
104 }
105 };
106
111 template <typename Arithmetic>
112 constexpr decltype( auto ) operator()( const std::pair<Arithmetic, Arithmetic>& v ) const noexcept {
113 return std::pair<unsigned int, Arithmetic>{ 1ul, v.second };
114 }
115 };
116
122 template <typename Arithmetic, atomicity Atomicity>
124 using RegularType = std::pair<unsigned long, Arithmetic>;
125 using AtomicType = std::pair<std::atomic<unsigned long>, std::atomic<Arithmetic>>;
127 static constexpr bool isAtomic = Atomicity == atomicity::full;
128 using InternalType = std::conditional_t<isAtomic, AtomicType, OutputType>;
129 static constexpr OutputType getValue( const InternalType& v ) noexcept {
130 if constexpr ( isAtomic ) {
131 return { v.first.load( std::memory_order_relaxed ), v.second.load( std::memory_order_relaxed ) };
132 } else {
133 return v;
134 }
135 }
136 static RegularType exchange( InternalType& v, RegularType newv ) noexcept {
137 if constexpr ( isAtomic ) {
138 return { v.first.exchange( newv.first ), v.second.exchange( newv.second ) };
139 } else {
140 return { std::exchange( v.first, newv.first ), std::exchange( v.second, newv.second ) };
141 }
142 }
143 static constexpr OutputType DefaultValue() { return { 0, Arithmetic{} }; }
144 static void merge( InternalType& a, RegularType b ) noexcept {
145 if constexpr ( isAtomic ) {
146 fetch_add( a.first, b.first );
147 fetch_add( a.second, b.second );
148 } else {
149 a.first += b.first;
150 a.second += b.second;
151 }
152 }
153 };
154
160 template <atomicity Atomicity, typename Arithmetic>
162 : GenericAccumulator<std::pair<Arithmetic, Arithmetic>, std::pair<unsigned long, Arithmetic>, Atomicity,
163 WeightedProfileTransform, ExtractWeight, WeightedAdder<Arithmetic, Atomicity>> {
164 using Base = GenericAccumulator<std::pair<Arithmetic, Arithmetic>, std::pair<unsigned long, Arithmetic>, Atomicity,
166 using Base::Base;
167 using Base::operator+=;
169 WeightedCountAccumulator operator+=( const Arithmetic weight ) {
170 *this += { 1ul, weight };
171 return *this;
172 }
173 unsigned long nEntries() const { return this->rawValue().first; }
174 Arithmetic sumOfWeights() const { return this->rawValue().second; }
175 };
176
183 template <atomicity Atomicity, typename Arithmetic>
185 : GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedProduct> {
186 using GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity,
188 Arithmetic sum() const { return this->value(); }
189 };
190
196 template <atomicity Atomicity, typename Arithmetic = double>
198 : GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity, WeightedSquare> {
199 using GenericAccumulator<std::pair<Arithmetic, Arithmetic>, Arithmetic, Atomicity,
201 Arithmetic sum2() const { return this->value(); }
202 };
203
209 template <atomicity Atomicity, typename Arithmetic>
212
218 template <atomicity Atomicity, typename Arithmetic>
221
228 template <typename Arithmetic>
229 class Axis {
230 public:
231 using ArithmeticType = Arithmetic;
232 Axis( unsigned int nBins = 0, Arithmetic minValue = Arithmetic{}, Arithmetic maxValue = Arithmetic{},
233 std::string title = {}, std::vector<std::string> labels = {} )
234 : m_title( std::move( title ) )
235 , nBins( nBins )
238 , m_labels( std::move( labels ) ) {
241 for ( const auto& s : m_labels ) details::requireValidTitle( s );
242 }
243 explicit Axis( Gaudi::Histo1DDef const& def )
244 : Axis( (unsigned int)def.bins(), def.lowEdge(), def.highEdge(), def.title() ) {}
245
247 unsigned int index( Arithmetic value ) const {
248 // In case we use integer as Arithmetic type, we cannot use ratio for computing indices,
249 // as ratios < 1.0 will simply be 0, so we have to pay the division in such a case
250 int idx;
251 if constexpr ( std::is_integral_v<Arithmetic> ) {
252 idx = ( ( value - m_minValue ) * nBins / ( m_maxValue - m_minValue ) ) + 1;
253 } else {
254 auto floatIdx = std::floor( ( value - m_minValue ) * m_ratio ) + 1;
255 // Converting NaN or infinity to int is undefined behaviour
256 if ( !std::isfinite( floatIdx ) ) { return floatIdx > 0 ? numBins() + 1 : 0; }
257 idx = static_cast<int>( floatIdx );
258 }
259 return idx < 0 ? 0 : ( (unsigned int)idx > numBins() ? numBins() + 1 : (unsigned int)idx );
260 }
261
262 friend std::ostream& operator<<( std::ostream& o, Axis const& axis ) {
263 // Note that we print python code here, as the generic toStream implementation uses this
264 // operator to generate python code.
265 o << "(" << axis.numBins() << ", " << axis.minValue() << ", " << axis.maxValue() << ", "
266 << "\"" << axis.m_title << "\", (";
267 for ( auto const& label : axis.m_labels ) { o << "\"" << label << "\", "; }
268 return o << "))";
269 }
270
272 bool inAcceptance( Arithmetic value ) const { return value >= m_minValue && value <= m_maxValue; }
273
274 // accessors
275 unsigned int numBins() const { return nBins; }
276 void setNumBins( unsigned int n ) {
277 nBins = n;
279 }
280 Arithmetic minValue() const { return m_minValue; }
281 void setMinValue( Arithmetic v ) {
282 m_minValue = v;
284 }
285 Arithmetic maxValue() const { return m_maxValue; }
286 void setMaxValue( Arithmetic v ) {
287 m_maxValue = v;
289 }
290 std::string const& title() const { return m_title; }
291 void setTitle( std::string const& t ) { m_title = t; }
292 std::vector<std::string> const& labels() const { return m_labels; }
293
294 private:
296 std::string m_title;
297
298 public:
301 unsigned int nBins;
302
303 private:
310 Arithmetic m_ratio;
312 std::vector<std::string> m_labels;
313
315 if constexpr ( std::is_floating_point_v<Arithmetic> ) {
316 // For floating-point types, use epsilon comparison to avoid -Wfloat_equal warning
317 m_ratio = ( std::abs( m_maxValue - m_minValue ) < std::numeric_limits<Arithmetic>::epsilon() )
318 ? Arithmetic{}
319 : nBins / ( m_maxValue - m_minValue );
320 } else {
321 // For integer types, direct comparison is safe
322 m_ratio = ( m_maxValue == m_minValue ) ? Arithmetic{} : nBins / ( m_maxValue - m_minValue );
323 }
324 }
325 };
326
328 template <typename Arithmetic>
329 void to_json( nlohmann::json& j, const Axis<Arithmetic>& axis ) {
330 j = nlohmann::json{ { "nBins", axis.numBins() },
331 { "minValue", axis.minValue() },
332 { "maxValue", axis.maxValue() },
333 { "title", axis.title() } };
334 if ( !axis.labels().empty() ) { j["labels"] = axis.labels(); }
335 }
336
352 template <typename Arithmetic, unsigned int NIndex>
353 struct HistoInputType : HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex> {
354 using HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex>::HistoInputType;
355 };
356 template <unsigned int NIndex, typename... Elements>
357 struct HistoInputType<std::tuple<Elements...>, NIndex> : std::tuple<Elements...> {
358 using InternalType = std::tuple<Elements...>;
360 using std::tuple<Elements...>::tuple;
361 template <class... AxisType>
362 requires( sizeof...( AxisType ) == NIndex )
363 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
364 return computeIndexInternal<0, std::tuple<AxisType...>>( axis );
365 }
366 template <class... AxisType>
367 requires( sizeof...( AxisType ) == NIndex )
368 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
369 return computeTotNBinsInternal<0, std::tuple<AxisType...>>( axis );
370 }
371 auto forInternalCounter() const { return 1ul; }
372 template <class... AxisType>
373 requires( sizeof...( AxisType ) == NIndex )
374 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
375 return inAcceptanceInternal<0, std::tuple<AxisType...>>( axis );
376 }
377
378 private:
379 template <int N, class Tuple>
380 unsigned int computeIndexInternal( Tuple const& allAxis ) const {
381 // compute global index. Bins are stored in a column first manner
382 auto const& axis = std::get<N>( allAxis );
383 unsigned int localIndex = axis.index( std::get<N>( *this ) );
384 if constexpr ( N + 1 == NIndex )
385 return localIndex;
386 else
387 return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis );
388 }
389 template <int N, class Tuple>
390 static unsigned int computeTotNBinsInternal( Tuple const& allAxis ) {
391 auto const& axis = std::get<N>( allAxis );
392 unsigned int localNBins = axis.numBins() + 2;
393 if constexpr ( N + 1 == NIndex )
394 return localNBins;
395 else
396 return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis );
397 }
398 template <int N, class Tuple>
399 bool inAcceptanceInternal( Tuple const& allAxis ) const {
400 auto const& axis = std::get<N>( allAxis );
401 bool localAnswer = axis.inAcceptance( std::get<N>( *this ) );
402 if constexpr ( N + 1 == NIndex )
403 return localAnswer;
404 else
405 return localAnswer || inAcceptanceInternal<N + 1, Tuple>( allAxis );
406 }
407 };
408
414 template <typename ArithmeticTuple, unsigned int NIndex, typename WArithmetic>
415 struct WeightedHistoInputType : std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic> {
417 using std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic>::pair;
418 template <class... AxisType>
419 requires( sizeof...( AxisType ) == NIndex )
420 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
421 return this->first.computeIndex( axis );
422 }
423 template <class... AxisType>
424 requires( sizeof...( AxisType ) == NIndex )
425 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
427 }
428 auto forInternalCounter() const { return std::pair( this->first.forInternalCounter(), this->second ); }
429 template <class... AxisType>
430 requires( sizeof...( AxisType ) == NIndex )
431 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
432 return this->first.inAcceptance( axis );
433 }
434 };
435
481 template <atomicity Atomicity, typename InputType, typename Arithmetic,
482 template <atomicity Ato, typename Arith> typename BaseAccumulatorT, typename AxisTupleType>
484 template <atomicity, typename, typename, template <atomicity, typename> typename, typename>
486
487 public:
488 using ND = std::integral_constant<unsigned int, std::tuple_size_v<AxisTupleType>>;
489 using BaseAccumulator = BaseAccumulatorT<Atomicity, Arithmetic>;
490 using AxisTupleArithmeticType = typename InputType::ValueType;
492 : m_axis{ axis }
493 , m_totNBins{ InputType::computeTotNBins( m_axis ) }
495 reset();
496 }
497 template <atomicity ato>
504 [[deprecated( "Use `++h1[x]`, `++h2[{x,y}]`, etc. instead." )]] HistogramingAccumulatorInternal&
505 operator+=( InputType v ) {
506 accumulator( v.computeIndex( m_axis ) ) += v.forInternalCounter();
507 return *this;
508 }
509 void reset() {
510 for ( unsigned int index = 0; index < m_totNBins; index++ ) { accumulator( index ).reset(); }
511 }
512 template <atomicity ato>
515 assert( m_totNBins == other.m_totNBins );
516 for ( unsigned int index = 0; index < m_totNBins; index++ ) {
517 accumulator( index ).mergeAndReset( other.accumulator( index ) );
518 }
519 }
520 [[nodiscard]] auto operator[]( typename InputType::ValueType v ) {
522 }
523
524 template <unsigned int N>
525 auto& axis() const {
526 return std::get<N>( m_axis );
527 }
528 auto& axis() const { return m_axis; }
529 auto binValue( unsigned int i ) const { return accumulator( i ).value(); }
530 auto nEntries( unsigned int i ) const { return accumulator( i ).nEntries(); }
531 auto totNBins() const { return m_totNBins; }
532
533 // FIXME These methods are there for backwrad compatibility with previous implementation
534 // where all Axis had to be of type Axis<...> and were stored in an array
535 // Newer code should call axis<N>().foo for whatever foo is defined in that axis type
536 auto nBins( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).numBins(); }
537 auto minValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).minValue(); }
538 auto maxValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).maxValue(); }
539
540 private:
541 BaseAccumulator& accumulator( unsigned int index ) const {
542 assert( index < m_totNBins );
543 assert( m_value.get() );
544 return m_value[index];
545 }
546
547 // FIXME Only used for backward compatibility. should be dropped at some stage
548 // Can only work if all axis have same type, which is no more the case
549 std::tuple_element_t<0, AxisTupleType> const& _getAxis( size_t i,
550 typename std::tuple_size<AxisTupleType>::type ) const {
551 throw std::logic_error(
552 std::format( "Retrieving axis {} in Histogram of dimension {}", i, std::tuple_size_v<AxisTupleType> ) );
553 }
554 template <size_t N>
555 requires( std::tuple_size_v<AxisTupleType> != N )
556 auto& _getAxis( size_t i, std::integral_constant<size_t, N> ) const {
557 if ( i == N ) return std::get<N>( m_axis );
558 return _getAxis( i, std::integral_constant<size_t, N + 1>() );
559 }
560
562 AxisTupleType m_axis;
564 unsigned int m_totNBins{};
566 std::unique_ptr<BaseAccumulator[]> m_value;
567 };
568
574 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
577 unsigned long, IntegralAccumulator, AxisTupleType>;
578
584 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
588 Arithmetic, WeightedCountAccumulator, AxisTupleType>;
589
595 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
599 Arithmetic, SigmaAccumulator, AxisTupleType>;
600
606 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
609 Arithmetic, WeightedSigmaAccumulator, AxisTupleType>;
610
669 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
670 template <atomicity, typename, typename, typename> typename Accumulator, typename AxisTupleType>
672 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
673 template <atomicity, typename, typename, typename> typename Accumulator, typename... AxisTypes>
674 class HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, std::tuple<AxisTypes...>>
675 : public BufferableCounter<Atomicity, Accumulator, Arithmetic, std::integral_constant<unsigned int, ND>,
676 std::tuple<AxisTypes...>> {
677 public:
678 using AxisTupleType = std::tuple<AxisTypes...>;
679 using NumberDimensions = std::integral_constant<unsigned int, ND>;
681 using AccumulatorType = Accumulator<Atomicity, Arithmetic, NumberDimensions, AxisTupleType>;
682 using AxisTupleArithmeticType = typename AccumulatorType::AxisTupleArithmeticType;
684 using AxisArithmeticType = typename std::tuple_element<0, AxisTupleType>::type::ArithmeticType;
685 inline static const std::string typeString{ std::string{ Type } + ':' + typeid( Arithmetic ).name() };
687 template <typename OWNER>
688 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTupleType axis )
689 : Parent( owner, name, *this, axis ), m_title( title ) {
691 }
692
693 template <typename OWNER>
694 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTypes... allAxis )
695 : HistogramingCounterBase( owner, name, title, std::make_tuple( allAxis... ) ) {}
696 using Parent::print;
697 template <typename stream>
698 stream& printImpl( stream& o, bool /*tableFormat*/ ) const {
699 o << ND << "D Histogram with config ";
700 std::apply( [&o]( auto&&... args ) { ( ( o << args << "\n" ), ... ); }, this->axis() );
701 return o;
702 }
703 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
704 return printImpl( o, tableFormat );
705 }
706 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
707 friend void reset( HistogramingCounterBase& c ) { c.reset(); }
708 friend void mergeAndReset( HistogramingCounterBase& h, HistogramingCounterBase& o ) { h.mergeAndReset( o ); }
709 friend void to_json( nlohmann::json& j, HistogramingCounterBase const& h ) { h.to_json( j ); }
710 virtual void to_json( nlohmann::json& j ) const {
711 // get all bin values and compute total nbEntries
712 std::vector<typename AccumulatorType::BaseAccumulator::OutputType> bins;
713 bins.reserve( this->totNBins() );
714 unsigned long totNEntries{ 0 };
715 for ( unsigned int i = 0; i < this->totNBins(); i++ ) {
716 bins.push_back( this->binValue( i ) );
717 totNEntries += this->nEntries( i );
718 }
719 // build json
720 j = { { "type", std::string( Type ) + ":" + typeid( Arithmetic ).name() },
721 { "title", m_title },
722 { "dimension", ND },
723 { "empty", totNEntries == 0 },
724 { "nEntries", totNEntries },
725 { "axis", this->axis() },
726 { "bins", bins } };
727 }
728 std::string const& title() const { return m_title; }
729
730 protected:
731 std::string const m_title;
732 };
733
734 namespace naming {
735 inline constexpr char histogramString[] = "histogram:Histogram";
736 inline constexpr char weightedHistogramString[] = "histogram:WeightedHistogram";
737 inline constexpr char profilehistogramString[] = "histogram:ProfileHistogram";
738 inline constexpr char weightedProfilehistogramString[] = "histogram:WeightedProfileHistogram";
739 } // namespace naming
740
742 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
743 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
745 HistogramingAccumulator, AxisTupleType>;
746
748 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
749 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
751 WeightedHistogramingAccumulator, AxisTupleType>;
752
754 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
755 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
757 ProfileHistogramingAccumulator, AxisTupleType>;
758
760 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
761 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
765
766} // namespace Gaudi::Accumulators
Definition of a default type of Histogram Axis It contains number of bins, min and max value plus a t...
std::string const & title() const
void setMinValue(Arithmetic v)
Arithmetic minValue() const
unsigned int numBins() const
void setMaxValue(Arithmetic v)
Arithmetic m_minValue
min and max values on this axis
std::vector< std::string > m_labels
labels for the bins
Axis(unsigned int nBins=0, Arithmetic minValue=Arithmetic{}, Arithmetic maxValue=Arithmetic{}, std::string title={}, std::vector< std::string > labels={})
std::vector< std::string > const & labels() const
bool inAcceptance(Arithmetic value) const
says whether the given value is within the range of the axis
void setNumBins(unsigned int n)
Arithmetic maxValue() const
friend std::ostream & operator<<(std::ostream &o, Axis const &axis)
Axis(Gaudi::Histo1DDef const &def)
void setTitle(std::string const &t)
std::string m_title
title of this axis
unsigned int nBins
number of bins for this Axis FIXME : should be private and called m_nBins but will break backward com...
unsigned int index(Arithmetic value) const
returns the bin number for a given value, ranging from 0 (underflow) to nBins+1 (overflow)
Arithmetic m_ratio
precomputed ratio to convert a value into bin number equal to nBins/(maxValue-minValue).
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Internal Accumulator class dealing with Histograming.
auto operator[](typename InputType::ValueType v)
std::integral_constant< unsigned int, std::tuple_size_v< AxisTupleType > > ND
void mergeAndReset(HistogramingAccumulatorInternal< ato, InputType, Arithmetic, BaseAccumulatorT, AxisTupleType > &other)
auto & _getAxis(size_t i, std::integral_constant< size_t, N >) const
BaseAccumulator & accumulator(unsigned int index) const
std::tuple_element_t< 0, AxisTupleType > const & _getAxis(size_t i, typename std::tuple_size< AxisTupleType >::type) const
HistogramingAccumulatorInternal & operator+=(InputType v)
BaseAccumulatorT< Atomicity, Arithmetic > BaseAccumulator
HistogramingAccumulatorInternal(construct_empty_t, const HistogramingAccumulatorInternal< ato, InputType, Arithmetic, BaseAccumulatorT, AxisTupleType > &other)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
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 std::tuple_element< 0, AxisTupleType >::type::ArithmeticType AxisArithmeticType
for backward compatibility with previous implementation, should not be used FIXME
HistogramingCounterBase(OWNER *owner, std::string const &name, std::string const &title, AxisTupleType axis)
This constructor takes the axis as a tuple.
BufferableCounter< Atomicity, Accumulator, Arithmetic, NumberDimensions, AxisTupleType > Parent
A base counter dealing with Histograms.
Simple helper class for description of 1D-histogram The class is targeted to act as the primary "hist...
Definition HistoDef.h:30
Define general base for Gaudi exception.
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
constexpr static const auto FAILURE
Definition StatusCode.h:100
void requireValidTitle(std::string_view sv)
constexpr char profilehistogramString[]
constexpr char weightedProfilehistogramString[]
constexpr char weightedHistogramString[]
Efficient counter implementations for Gaudi.
AveragingAccumulatorBase< Atomicity, Arithmetic, WeightedCountAccumulator, WeightedSumAccumulator > WeightedAveragingAccumulator
WeightedAveragingAccumulator.
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedSigmaAccumulator, AxisTupleType > WeightedProfileHistogramingAccumulator
Class implementing a weighted profile histogram accumulator.
void to_json(nlohmann::json &j, const Axis< Arithmetic > &axis)
automatic conversion of the Axis type to json
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedCountAccumulator, AxisTupleType > WeightedHistogramingAccumulator
Class implementing a weighted histogram accumulator.
HistogramingAccumulatorInternal< Atomicity, HistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value >, unsigned long, IntegralAccumulator, AxisTupleType > HistogramingAccumulator
Class implementing a regular histogram accumulator.
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::histogramString, HistogramingAccumulator, AxisTupleType > StaticHistogram
standard static histograming counter. See HistogramingCounterBase for details
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::weightedProfilehistogramString, WeightedProfileHistogramingAccumulator, AxisTupleType > StaticWeightedProfileHistogram
weighted static profile histograming counter. See HistogramingCounterBase for details
atomicity
Defines atomicity of the accumulators.
HistogramingAccumulatorInternal< Atomicity, HistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value >, Arithmetic, SigmaAccumulator, AxisTupleType > ProfileHistogramingAccumulator
Class implementing a profile histogram accumulator.
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::profilehistogramString, ProfileHistogramingAccumulator, AxisTupleType > StaticProfileHistogram
profile static histograming counter. See HistogramingCounterBase for details
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::weightedHistogramString, WeightedHistogramingAccumulator, AxisTupleType > StaticWeightedHistogram
standard static histograming counter with weight. See HistogramingCounterBase for details
void fetch_add(AtomicType &atVar, Arithmetic value)
generic fetch_add, also dealing with atomic types with no fetch_add member method
SigmaAccumulatorBase< Atomicity, Arithmetic, WeightedAveragingAccumulator, WeightedSquareAccumulator > WeightedSigmaAccumulator
WeightedSigmaAccumulator.
SigmaAccumulatorBase< Atomicity, Arithmetic, AveragingAccumulator, SquareAccumulator > SigmaAccumulator
SigmaAccumulator.
STL namespace.
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.
Definition ParticleID.h:191
A functor to extract weight, take a pair (valueTuple, weight) as input.
unsigned int computeIndex(std::tuple< AxisType... > const &axis) const
HistoInputType< SubTuple_t< InternalType, NIndex >, NIndex > ValueType
static unsigned int computeTotNBins(std::tuple< AxisType... > const &axis)
bool inAcceptance(std::tuple< AxisType... > const &axis) const
small class used as InputType for regular Histograms basically a tuple of the given values,...
An Adder ValueHandler, taking weight into account and computing a count plus the sum of the weights I...
std::conditional_t< isAtomic, AtomicType, OutputType > InternalType
static RegularType exchange(InternalType &v, RegularType newv) noexcept
std::pair< std::atomic< unsigned long >, std::atomic< Arithmetic > > AtomicType
static constexpr OutputType DefaultValue()
static constexpr OutputType getValue(const InternalType &v) noexcept
static void merge(InternalType &a, RegularType b) noexcept
std::pair< unsigned long, Arithmetic > RegularType
GenericAccumulator< std::pair< Arithmetic, Arithmetic >, std::pair< unsigned long, Arithmetic >, Atomicity, WeightedProfileTransform, ExtractWeight, WeightedAdder< Arithmetic, Atomicity > > Base
WeightedCountAccumulator operator+=(const Arithmetic weight)
overload of operator+= to be able to only give weight and no value
small class used as InputType for weighted Histograms only a pair of the InnerType and the weight.
unsigned int computeIndex(std::tuple< AxisType... > const &axis) const
static unsigned int computeTotNBins(std::tuple< AxisType... > const &axis)
bool inAcceptance(std::tuple< AxisType... > const &axis) const
typename HistoInputType< ArithmeticTuple, NIndex >::ValueType ValueType
A Product functor, take a pair (value, weight) as input.
An inputTransform for WeightedProfile histograms, keeping weight and replacing value by 1.
A WeightedSquare functor, take a pair (value, weight) as input.
constant used to disambiguate construction of an empty Accumulator versus the copy constructor.