The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
StaticHistogram.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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 idx = std::floor( ( value - m_minValue ) * m_ratio ) + 1;
255 }
256 return idx < 0 ? 0 : ( (unsigned int)idx > numBins() ? numBins() + 1 : (unsigned int)idx );
257 }
258
259 friend std::ostream& operator<<( std::ostream& o, Axis const& axis ) {
260 // Note that we print python code here, as the generic toStream implementation uses this
261 // operator to generate python code.
262 o << "(" << axis.numBins() << ", " << axis.minValue() << ", " << axis.maxValue() << ", "
263 << "\"" << axis.m_title << "\", (";
264 for ( auto const& label : axis.m_labels ) { o << "\"" << label << "\", "; }
265 return o << "))";
266 }
267
269 bool inAcceptance( Arithmetic value ) const { return value >= m_minValue && value <= m_maxValue; }
270
271 // accessors
272 unsigned int numBins() const { return nBins; }
273 void setNumBins( unsigned int n ) {
274 nBins = n;
276 }
277 Arithmetic minValue() const { return m_minValue; }
278 void setMinValue( Arithmetic v ) {
279 m_minValue = v;
281 }
282 Arithmetic maxValue() const { return m_maxValue; }
283 void setMaxValue( Arithmetic v ) {
284 m_maxValue = v;
286 }
287 std::string const& title() const { return m_title; }
288 void setTitle( std::string const& t ) { m_title = t; }
289 std::vector<std::string> const& labels() const { return m_labels; }
290
291 private:
293 std::string m_title;
294
295 public:
298 unsigned int nBins;
299
300 private:
307 Arithmetic m_ratio;
309 std::vector<std::string> m_labels;
310
312 m_ratio = ( m_maxValue == m_minValue ) ? Arithmetic{} : nBins / ( m_maxValue - m_minValue );
313 }
314 };
315
317 template <typename Arithmetic>
318 void to_json( nlohmann::json& j, const Axis<Arithmetic>& axis ) {
319 j = nlohmann::json{ { "nBins", axis.numBins() },
320 { "minValue", axis.minValue() },
321 { "maxValue", axis.maxValue() },
322 { "title", axis.title() } };
323 if ( !axis.labels().empty() ) { j["labels"] = axis.labels(); }
324 }
325
341 template <typename Arithmetic, unsigned int NIndex>
342 struct HistoInputType : HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex> {
343 using HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex>::HistoInputType;
344 };
345 template <unsigned int NIndex, typename... Elements>
346 struct HistoInputType<std::tuple<Elements...>, NIndex> : std::tuple<Elements...> {
347 using InternalType = std::tuple<Elements...>;
349 using std::tuple<Elements...>::tuple;
350 template <class... AxisType>
351 requires( sizeof...( AxisType ) == NIndex )
352 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
353 return computeIndexInternal<0, std::tuple<AxisType...>>( axis );
354 }
355 template <class... AxisType>
356 requires( sizeof...( AxisType ) == NIndex )
357 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
358 return computeTotNBinsInternal<0, std::tuple<AxisType...>>( axis );
359 }
360 auto forInternalCounter() const { return 1ul; }
361 template <class... AxisType>
362 requires( sizeof...( AxisType ) == NIndex )
363 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
364 return inAcceptanceInternal<0, std::tuple<AxisType...>>( axis );
365 }
366
367 private:
368 template <int N, class Tuple>
369 unsigned int computeIndexInternal( Tuple const& allAxis ) const {
370 // compute global index. Bins are stored in a column first manner
371 auto const& axis = std::get<N>( allAxis );
372 unsigned int localIndex = axis.index( std::get<N>( *this ) );
373 if constexpr ( N + 1 == NIndex )
374 return localIndex;
375 else
376 return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis );
377 }
378 template <int N, class Tuple>
379 static unsigned int computeTotNBinsInternal( Tuple const& allAxis ) {
380 auto const& axis = std::get<N>( allAxis );
381 unsigned int localNBins = axis.numBins() + 2;
382 if constexpr ( N + 1 == NIndex )
383 return localNBins;
384 else
385 return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis );
386 }
387 template <int N, class Tuple>
388 bool inAcceptanceInternal( Tuple const& allAxis ) const {
389 auto const& axis = std::get<N>( allAxis );
390 bool localAnswer = axis.inAcceptance( std::get<N>( *this ) );
391 if constexpr ( N + 1 == NIndex )
392 return localAnswer;
393 else
394 return localAnswer || inAcceptanceInternal<N + 1, Tuple>( allAxis );
395 }
396 };
397
403 template <typename ArithmeticTuple, unsigned int NIndex, typename WArithmetic>
404 struct WeightedHistoInputType : std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic> {
406 using std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic>::pair;
407 template <class... AxisType>
408 requires( sizeof...( AxisType ) == NIndex )
409 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
410 return this->first.computeIndex( axis );
411 }
412 template <class... AxisType>
413 requires( sizeof...( AxisType ) == NIndex )
414 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
416 }
417 auto forInternalCounter() const { return std::pair( this->first.forInternalCounter(), this->second ); }
418 template <class... AxisType>
419 requires( sizeof...( AxisType ) == NIndex )
420 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
421 return this->first.inAcceptance( axis );
422 }
423 };
424
470 template <atomicity Atomicity, typename InputType, typename Arithmetic,
471 template <atomicity Ato, typename Arith> typename BaseAccumulatorT, typename AxisTupleType>
473 template <atomicity, typename, typename, template <atomicity, typename> typename, typename>
475
476 public:
477 using ND = std::integral_constant<unsigned int, std::tuple_size_v<AxisTupleType>>;
478 using BaseAccumulator = BaseAccumulatorT<Atomicity, Arithmetic>;
479 using AxisTupleArithmeticType = typename InputType::ValueType;
481 : m_axis{ axis }
482 , m_totNBins{ InputType::computeTotNBins( m_axis ) }
484 reset();
485 }
486 template <atomicity ato>
493 [[deprecated( "Use `++h1[x]`, `++h2[{x,y}]`, etc. instead." )]] HistogramingAccumulatorInternal&
494 operator+=( InputType v ) {
495 accumulator( v.computeIndex( m_axis ) ) += v.forInternalCounter();
496 return *this;
497 }
498 void reset() {
499 for ( unsigned int index = 0; index < m_totNBins; index++ ) { accumulator( index ).reset(); }
500 }
501 template <atomicity ato>
504 assert( m_totNBins == other.m_totNBins );
505 for ( unsigned int index = 0; index < m_totNBins; index++ ) {
506 accumulator( index ).mergeAndReset( other.accumulator( index ) );
507 }
508 }
509 [[nodiscard]] auto operator[]( typename InputType::ValueType v ) {
511 }
512
513 template <unsigned int N>
514 auto& axis() const {
515 return std::get<N>( m_axis );
516 }
517 auto& axis() const { return m_axis; }
518 auto binValue( unsigned int i ) const { return accumulator( i ).value(); }
519 auto nEntries( unsigned int i ) const { return accumulator( i ).nEntries(); }
520 auto totNBins() const { return m_totNBins; }
521
522 // FIXME These methods are there for backwrad compatibility with previous implementation
523 // where all Axis had to be of type Axis<...> and were stored in an array
524 // Newer code should call axis<N>().foo for whatever foo is defined in that axis type
525 auto nBins( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).numBins(); }
526 auto minValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).minValue(); }
527 auto maxValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).maxValue(); }
528
529 private:
530 BaseAccumulator& accumulator( unsigned int index ) const {
531 assert( index < m_totNBins );
532 assert( m_value.get() );
533 return m_value[index];
534 }
535
536 // FIXME Only used for backward compatibility. should be dropped at some stage
537 // Can only work if all axis have same type, which is no more the case
538 std::tuple_element_t<0, AxisTupleType> const& _getAxis( size_t i,
539 typename std::tuple_size<AxisTupleType>::type ) const {
540 throw std::logic_error(
541 std::format( "Retrieving axis {} in Histogram of dimension {}", i, std::tuple_size_v<AxisTupleType> ) );
542 }
543 template <size_t N>
544 requires( std::tuple_size_v<AxisTupleType> != N )
545 auto& _getAxis( size_t i, std::integral_constant<size_t, N> ) const {
546 if ( i == N ) return std::get<N>( m_axis );
547 return _getAxis( i, std::integral_constant<size_t, N + 1>() );
548 }
549
551 AxisTupleType m_axis;
553 unsigned int m_totNBins{};
555 std::unique_ptr<BaseAccumulator[]> m_value;
556 };
557
563 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
566 unsigned long, IntegralAccumulator, AxisTupleType>;
567
573 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
577 Arithmetic, WeightedCountAccumulator, AxisTupleType>;
578
584 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
588 Arithmetic, SigmaAccumulator, AxisTupleType>;
589
595 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
598 Arithmetic, WeightedSigmaAccumulator, AxisTupleType>;
599
658 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
659 template <atomicity, typename, typename, typename> typename Accumulator, typename AxisTupleType>
661 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
662 template <atomicity, typename, typename, typename> typename Accumulator, typename... AxisTypes>
663 class HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, std::tuple<AxisTypes...>>
664 : public BufferableCounter<Atomicity, Accumulator, Arithmetic, std::integral_constant<unsigned int, ND>,
665 std::tuple<AxisTypes...>> {
666 public:
667 using AxisTupleType = std::tuple<AxisTypes...>;
668 using NumberDimensions = std::integral_constant<unsigned int, ND>;
670 using AccumulatorType = Accumulator<Atomicity, Arithmetic, NumberDimensions, AxisTupleType>;
671 using AxisTupleArithmeticType = typename AccumulatorType::AxisTupleArithmeticType;
673 using AxisArithmeticType = typename std::tuple_element<0, AxisTupleType>::type::ArithmeticType;
674 inline static const std::string typeString{ std::string{ Type } + ':' + typeid( Arithmetic ).name() };
676 template <typename OWNER>
677 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTupleType axis )
678 : Parent( owner, name, *this, axis ), m_title( title ) {
680 }
681
682 template <typename OWNER>
683 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTypes... allAxis )
684 : HistogramingCounterBase( owner, name, title, std::make_tuple( allAxis... ) ) {}
685 using Parent::print;
686 template <typename stream>
687 stream& printImpl( stream& o, bool /*tableFormat*/ ) const {
688 o << ND << "D Histogram with config ";
689 std::apply( [&o]( auto&&... args ) { ( ( o << args << "\n" ), ... ); }, this->axis() );
690 return o;
691 }
692 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
693 return printImpl( o, tableFormat );
694 }
695 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
696 friend void reset( HistogramingCounterBase& c ) { c.reset(); }
697 friend void mergeAndReset( HistogramingCounterBase& h, HistogramingCounterBase& o ) { h.mergeAndReset( o ); }
698 friend void to_json( nlohmann::json& j, HistogramingCounterBase const& h ) { h.to_json( j ); }
699 virtual void to_json( nlohmann::json& j ) const {
700 // get all bin values and compute total nbEntries
701 std::vector<typename AccumulatorType::BaseAccumulator::OutputType> bins;
702 bins.reserve( this->totNBins() );
703 unsigned long totNEntries{ 0 };
704 for ( unsigned int i = 0; i < this->totNBins(); i++ ) {
705 bins.push_back( this->binValue( i ) );
706 totNEntries += this->nEntries( i );
707 }
708 // build json
709 j = { { "type", std::string( Type ) + ":" + typeid( Arithmetic ).name() },
710 { "title", m_title },
711 { "dimension", ND },
712 { "empty", totNEntries == 0 },
713 { "nEntries", totNEntries },
714 { "axis", this->axis() },
715 { "bins", bins } };
716 }
717 std::string const& title() const { return m_title; }
718
719 protected:
720 std::string const m_title;
721 };
722
723 namespace naming {
724 inline constexpr char histogramString[] = "histogram:Histogram";
725 inline constexpr char weightedHistogramString[] = "histogram:WeightedHistogram";
726 inline constexpr char profilehistogramString[] = "histogram:ProfileHistogram";
727 inline constexpr char weightedProfilehistogramString[] = "histogram:WeightedProfileHistogram";
728 } // namespace naming
729
731 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
732 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
734 HistogramingAccumulator, AxisTupleType>;
735
737 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
738 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
740 WeightedHistogramingAccumulator, AxisTupleType>;
741
743 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
744 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
746 ProfileHistogramingAccumulator, AxisTupleType>;
747
749 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
750 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
754
755} // 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)
A base counter dealing with Histograms.
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
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.
HistogramingAccumulatorInternal< Atomicity, HistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value >, Arithmetic, SigmaAccumulator, AxisTupleType > ProfileHistogramingAccumulator
Class implementing a profile histogram accumulator.
HistogramingAccumulatorInternal< Atomicity, HistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value >, unsigned long, IntegralAccumulator, AxisTupleType > HistogramingAccumulator
Class implementing a regular histogram accumulator.
void to_json(nlohmann::json &j, const Axis< Arithmetic > &axis)
automatic conversion of the Axis type to json
SigmaAccumulatorBase< Atomicity, Arithmetic, WeightedAveragingAccumulator, WeightedSquareAccumulator > WeightedSigmaAccumulator
WeightedSigmaAccumulator.
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< ProfileAxisToArithmetic_t< Arithmetic, AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedSigmaAccumulator, AxisTupleType > WeightedProfileHistogramingAccumulator
Class implementing a weighted profile histogram accumulator.
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::profilehistogramString, ProfileHistogramingAccumulator, AxisTupleType > StaticProfileHistogram
profile static histograming counter. See HistogramingCounterBase for details
AveragingAccumulatorBase< Atomicity, Arithmetic, WeightedCountAccumulator, WeightedSumAccumulator > WeightedAveragingAccumulator
WeightedAveragingAccumulator.
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.
void fetch_add(AtomicType &atVar, Arithmetic value)
generic fetch_add, also dealing with atomic types with no fetch_add member method
SigmaAccumulatorBase< Atomicity, Arithmetic, AveragingAccumulator, SquareAccumulator > SigmaAccumulator
SigmaAccumulator.
HistogramingAccumulatorInternal< Atomicity, WeightedHistoInputType< AxisToArithmetic_t< AxisTupleType >, ND::value, Arithmetic >, Arithmetic, WeightedCountAccumulator, AxisTupleType > WeightedHistogramingAccumulator
Class implementing a weighted histogram accumulator.
HistogramingCounterBase< ND, Atomicity, Arithmetic, naming::weightedHistogramString, WeightedHistogramingAccumulator, AxisTupleType > StaticWeightedHistogram
standard static histograming counter with weight. See HistogramingCounterBase for details
STL namespace.
A functor to extract weight, take a pair (valueTuple, weight) as input.
small class used as InputType for regular Histograms basically a tuple of the given values,...
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
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.