The Gaudi Framework  master (34daa81a)
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 m_ratio = ( m_maxValue == m_minValue ) ? Arithmetic{} : nBins / ( m_maxValue - m_minValue );
316 }
317 };
318
320 template <typename Arithmetic>
321 void to_json( nlohmann::json& j, const Axis<Arithmetic>& axis ) {
322 j = nlohmann::json{ { "nBins", axis.numBins() },
323 { "minValue", axis.minValue() },
324 { "maxValue", axis.maxValue() },
325 { "title", axis.title() } };
326 if ( !axis.labels().empty() ) { j["labels"] = axis.labels(); }
327 }
328
344 template <typename Arithmetic, unsigned int NIndex>
345 struct HistoInputType : HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex> {
346 using HistoInputType<make_tuple_t<Arithmetic, NIndex>, NIndex>::HistoInputType;
347 };
348 template <unsigned int NIndex, typename... Elements>
349 struct HistoInputType<std::tuple<Elements...>, NIndex> : std::tuple<Elements...> {
350 using InternalType = std::tuple<Elements...>;
352 using std::tuple<Elements...>::tuple;
353 template <class... AxisType>
354 requires( sizeof...( AxisType ) == NIndex )
355 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
356 return computeIndexInternal<0, std::tuple<AxisType...>>( axis );
357 }
358 template <class... AxisType>
359 requires( sizeof...( AxisType ) == NIndex )
360 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
361 return computeTotNBinsInternal<0, std::tuple<AxisType...>>( axis );
362 }
363 auto forInternalCounter() const { return 1ul; }
364 template <class... AxisType>
365 requires( sizeof...( AxisType ) == NIndex )
366 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
367 return inAcceptanceInternal<0, std::tuple<AxisType...>>( axis );
368 }
369
370 private:
371 template <int N, class Tuple>
372 unsigned int computeIndexInternal( Tuple const& allAxis ) const {
373 // compute global index. Bins are stored in a column first manner
374 auto const& axis = std::get<N>( allAxis );
375 unsigned int localIndex = axis.index( std::get<N>( *this ) );
376 if constexpr ( N + 1 == NIndex )
377 return localIndex;
378 else
379 return localIndex + ( axis.numBins() + 2 ) * computeIndexInternal<N + 1, Tuple>( allAxis );
380 }
381 template <int N, class Tuple>
382 static unsigned int computeTotNBinsInternal( Tuple const& allAxis ) {
383 auto const& axis = std::get<N>( allAxis );
384 unsigned int localNBins = axis.numBins() + 2;
385 if constexpr ( N + 1 == NIndex )
386 return localNBins;
387 else
388 return localNBins * computeTotNBinsInternal<N + 1, Tuple>( allAxis );
389 }
390 template <int N, class Tuple>
391 bool inAcceptanceInternal( Tuple const& allAxis ) const {
392 auto const& axis = std::get<N>( allAxis );
393 bool localAnswer = axis.inAcceptance( std::get<N>( *this ) );
394 if constexpr ( N + 1 == NIndex )
395 return localAnswer;
396 else
397 return localAnswer || inAcceptanceInternal<N + 1, Tuple>( allAxis );
398 }
399 };
400
406 template <typename ArithmeticTuple, unsigned int NIndex, typename WArithmetic>
407 struct WeightedHistoInputType : std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic> {
409 using std::pair<HistoInputType<ArithmeticTuple, NIndex>, WArithmetic>::pair;
410 template <class... AxisType>
411 requires( sizeof...( AxisType ) == NIndex )
412 unsigned int computeIndex( std::tuple<AxisType...> const& axis ) const {
413 return this->first.computeIndex( axis );
414 }
415 template <class... AxisType>
416 requires( sizeof...( AxisType ) == NIndex )
417 static unsigned int computeTotNBins( std::tuple<AxisType...> const& axis ) {
419 }
420 auto forInternalCounter() const { return std::pair( this->first.forInternalCounter(), this->second ); }
421 template <class... AxisType>
422 requires( sizeof...( AxisType ) == NIndex )
423 bool inAcceptance( std::tuple<AxisType...> const& axis ) const {
424 return this->first.inAcceptance( axis );
425 }
426 };
427
473 template <atomicity Atomicity, typename InputType, typename Arithmetic,
474 template <atomicity Ato, typename Arith> typename BaseAccumulatorT, typename AxisTupleType>
476 template <atomicity, typename, typename, template <atomicity, typename> typename, typename>
478
479 public:
480 using ND = std::integral_constant<unsigned int, std::tuple_size_v<AxisTupleType>>;
481 using BaseAccumulator = BaseAccumulatorT<Atomicity, Arithmetic>;
482 using AxisTupleArithmeticType = typename InputType::ValueType;
484 : m_axis{ axis }
485 , m_totNBins{ InputType::computeTotNBins( m_axis ) }
487 reset();
488 }
489 template <atomicity ato>
496 [[deprecated( "Use `++h1[x]`, `++h2[{x,y}]`, etc. instead." )]] HistogramingAccumulatorInternal&
497 operator+=( InputType v ) {
498 accumulator( v.computeIndex( m_axis ) ) += v.forInternalCounter();
499 return *this;
500 }
501 void reset() {
502 for ( unsigned int index = 0; index < m_totNBins; index++ ) { accumulator( index ).reset(); }
503 }
504 template <atomicity ato>
507 assert( m_totNBins == other.m_totNBins );
508 for ( unsigned int index = 0; index < m_totNBins; index++ ) {
509 accumulator( index ).mergeAndReset( other.accumulator( index ) );
510 }
511 }
512 [[nodiscard]] auto operator[]( typename InputType::ValueType v ) {
514 }
515
516 template <unsigned int N>
517 auto& axis() const {
518 return std::get<N>( m_axis );
519 }
520 auto& axis() const { return m_axis; }
521 auto binValue( unsigned int i ) const { return accumulator( i ).value(); }
522 auto nEntries( unsigned int i ) const { return accumulator( i ).nEntries(); }
523 auto totNBins() const { return m_totNBins; }
524
525 // FIXME These methods are there for backwrad compatibility with previous implementation
526 // where all Axis had to be of type Axis<...> and were stored in an array
527 // Newer code should call axis<N>().foo for whatever foo is defined in that axis type
528 auto nBins( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).numBins(); }
529 auto minValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).minValue(); }
530 auto maxValue( unsigned int i ) const { return _getAxis( i, std::integral_constant<size_t, 0>() ).maxValue(); }
531
532 private:
533 BaseAccumulator& accumulator( unsigned int index ) const {
534 assert( index < m_totNBins );
535 assert( m_value.get() );
536 return m_value[index];
537 }
538
539 // FIXME Only used for backward compatibility. should be dropped at some stage
540 // Can only work if all axis have same type, which is no more the case
541 std::tuple_element_t<0, AxisTupleType> const& _getAxis( size_t i,
542 typename std::tuple_size<AxisTupleType>::type ) const {
543 throw std::logic_error(
544 std::format( "Retrieving axis {} in Histogram of dimension {}", i, std::tuple_size_v<AxisTupleType> ) );
545 }
546 template <size_t N>
547 requires( std::tuple_size_v<AxisTupleType> != N )
548 auto& _getAxis( size_t i, std::integral_constant<size_t, N> ) const {
549 if ( i == N ) return std::get<N>( m_axis );
550 return _getAxis( i, std::integral_constant<size_t, N + 1>() );
551 }
552
554 AxisTupleType m_axis;
556 unsigned int m_totNBins{};
558 std::unique_ptr<BaseAccumulator[]> m_value;
559 };
560
566 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
569 unsigned long, IntegralAccumulator, AxisTupleType>;
570
576 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
580 Arithmetic, WeightedCountAccumulator, AxisTupleType>;
581
587 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
591 Arithmetic, SigmaAccumulator, AxisTupleType>;
592
598 template <atomicity Atomicity, typename Arithmetic, typename ND, typename AxisTupleType>
601 Arithmetic, WeightedSigmaAccumulator, AxisTupleType>;
602
661 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
662 template <atomicity, typename, typename, typename> typename Accumulator, typename AxisTupleType>
664 template <unsigned int ND, atomicity Atomicity, typename Arithmetic, const char* Type,
665 template <atomicity, typename, typename, typename> typename Accumulator, typename... AxisTypes>
666 class HistogramingCounterBase<ND, Atomicity, Arithmetic, Type, Accumulator, std::tuple<AxisTypes...>>
667 : public BufferableCounter<Atomicity, Accumulator, Arithmetic, std::integral_constant<unsigned int, ND>,
668 std::tuple<AxisTypes...>> {
669 public:
670 using AxisTupleType = std::tuple<AxisTypes...>;
671 using NumberDimensions = std::integral_constant<unsigned int, ND>;
673 using AccumulatorType = Accumulator<Atomicity, Arithmetic, NumberDimensions, AxisTupleType>;
674 using AxisTupleArithmeticType = typename AccumulatorType::AxisTupleArithmeticType;
676 using AxisArithmeticType = typename std::tuple_element<0, AxisTupleType>::type::ArithmeticType;
677 inline static const std::string typeString{ std::string{ Type } + ':' + typeid( Arithmetic ).name() };
679 template <typename OWNER>
680 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTupleType axis )
681 : Parent( owner, name, *this, axis ), m_title( title ) {
683 }
684
685 template <typename OWNER>
686 HistogramingCounterBase( OWNER* owner, std::string const& name, std::string const& title, AxisTypes... allAxis )
687 : HistogramingCounterBase( owner, name, title, std::make_tuple( allAxis... ) ) {}
688 using Parent::print;
689 template <typename stream>
690 stream& printImpl( stream& o, bool /*tableFormat*/ ) const {
691 o << ND << "D Histogram with config ";
692 std::apply( [&o]( auto&&... args ) { ( ( o << args << "\n" ), ... ); }, this->axis() );
693 return o;
694 }
695 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
696 return printImpl( o, tableFormat );
697 }
698 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
699 friend void reset( HistogramingCounterBase& c ) { c.reset(); }
700 friend void mergeAndReset( HistogramingCounterBase& h, HistogramingCounterBase& o ) { h.mergeAndReset( o ); }
701 friend void to_json( nlohmann::json& j, HistogramingCounterBase const& h ) { h.to_json( j ); }
702 virtual void to_json( nlohmann::json& j ) const {
703 // get all bin values and compute total nbEntries
704 std::vector<typename AccumulatorType::BaseAccumulator::OutputType> bins;
705 bins.reserve( this->totNBins() );
706 unsigned long totNEntries{ 0 };
707 for ( unsigned int i = 0; i < this->totNBins(); i++ ) {
708 bins.push_back( this->binValue( i ) );
709 totNEntries += this->nEntries( i );
710 }
711 // build json
712 j = { { "type", std::string( Type ) + ":" + typeid( Arithmetic ).name() },
713 { "title", m_title },
714 { "dimension", ND },
715 { "empty", totNEntries == 0 },
716 { "nEntries", totNEntries },
717 { "axis", this->axis() },
718 { "bins", bins } };
719 }
720 std::string const& title() const { return m_title; }
721
722 protected:
723 std::string const m_title;
724 };
725
726 namespace naming {
727 inline constexpr char histogramString[] = "histogram:Histogram";
728 inline constexpr char weightedHistogramString[] = "histogram:WeightedHistogram";
729 inline constexpr char profilehistogramString[] = "histogram:ProfileHistogram";
730 inline constexpr char weightedProfilehistogramString[] = "histogram:WeightedProfileHistogram";
731 } // namespace naming
732
734 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
735 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
737 HistogramingAccumulator, AxisTupleType>;
738
740 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
741 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
743 WeightedHistogramingAccumulator, AxisTupleType>;
744
746 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
747 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
749 ProfileHistogramingAccumulator, AxisTupleType>;
750
752 template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double,
753 typename AxisTupleType = make_tuple_t<Axis<Arithmetic>, ND>>
757
758} // 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.