1 #ifndef GAUDIKERNEL_COUNTERS_H 2 #define GAUDIKERNEL_COUNTERS_H 1 129 #include "boost/algorithm/string/predicate.hpp" 130 #include "boost/format.hpp" 133 #include <initializer_list> 138 #include <type_traits> 145 namespace Accumulators {
157 template <
unsigned long N>
159 template <
typename U>
169 template <
typename U>
170 constexpr decltype(
auto )
operator()( U&& v )
const noexcept {
171 return std::forward<U>( v );
179 template <
typename U>
180 constexpr decltype(
auto )
operator()( U&& v )
const noexcept {
188 template <
typename T,
typename =
int>
190 template <
typename T>
191 using has_fetch_add =
typename Gaudi::cpp17::is_detected<has_fetch_add_, T>::value_t;
196 template <
typename Arithmetic,
typename Result =
double>
197 using fp_result_type = std::conditional_t<std::is_integral<Arithmetic>::value, Result, Arithmetic>;
202 template <
typename Arithmetic, atomicity Atomicity>
208 template <
typename Arithmetic>
219 template <
typename Arithmetic>
224 return v.load( std::memory_order_relaxed );
233 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
239 template <
typename Arithmetic>
250 template <
typename Arithmetic>
256 if ( DefaultValue() == b )
return;
259 a.fetch_add( b, std::memory_order_relaxed );
262 while ( !a.compare_exchange_weak( current, current + b ) )
272 template <
typename Arithmetic, atomicity Atomicity,
typename Compare, Arithmetic ( *Initial )()>
278 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
284 if ( Compare{}( b, a ) ) a = b;
291 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
298 while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
307 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
314 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
338 template <
typename A,
typename B, atomicity C,
typename D,
typename E,
typename F>
342 using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
344 ValueHandler::merge( m_value, InputTransform{}( by ) );
350 m_value = ValueHandler::getValue( other.
m_value );
353 OutputType value()
const {
return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
355 template <atomicity ato,
typename VH>
357 auto otherValue = VH::exchange( other.m_value, VH::DefaultValue() );
358 ValueHandler::merge( m_value, otherValue );
373 template <
typename Arithmetic, atomicity Atomicity,
template <
typename, atomicity>
class... Bases>
385 template <atomicity Ato>
388 ( Bases<Arithmetic, Atomicity>::mergeAndReset(
static_cast<Bases<Arithmetic, Ato>&&
>( other ) ), 0 )...};
392 void reset(
const std::tuple<
typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
394 [
this](
const auto&... i ) {
405 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
407 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
408 Arithmetic
max()
const {
return this->value(); }
415 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
417 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
418 Arithmetic
min()
const {
return this->value(); }
425 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
427 unsigned long nEntries()
const {
return this->value(); }
434 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
436 Arithmetic
sum()
const {
return this->value(); }
443 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
445 Arithmetic
sum2()
const {
return this->value(); };
458 template <
typename Arithmetic, atomicity Atomicity>
473 template <
typename Arithmetic, atomicity Atomicity>
483 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
485 unsigned long nEntries()
const {
return this->nTrueEntries() + this->nFalseEntries(); };
487 template <
typename Result = fp_result_type<Arithmetic>>
490 if ( 1 > nbEntries )
return Result{-1};
491 return static_cast<Result
>( this->nTrueEntries() ) / nbEntries;
493 auto eff()
const {
return efficiency(); }
495 template <
typename Result = fp_result_type<Arithmetic>>
502 if ( 1 > nbEntries )
return Result{-1};
503 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
505 auto effErr()
const {
return efficiencyErr(); }
512 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
515 template <
typename Result = fp_result_type<Arithmetic>>
518 Result sum = this->sum();
519 return (
n > 0 ) ?
static_cast<Result
>( sum /
n ) : Result{};
527 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
530 template <
typename Result = fp_result_type<Arithmetic>>
533 Result sum = this->sum();
534 return (
n > 0 ) ?
static_cast<Result
>( ( this->sum2() - sum * ( sum /
n ) ) /
n ) : Result{};
537 template <
typename Result = fp_result_type<Arithmetic>>
540 Result sum = this->sum();
541 return (
n > 1 ) ?
static_cast<Result
>( ( this->sum2() - sum * ( sum /
n ) ) / (
n - 1 ) ) : Result{};
544 template <
typename Result = fp_result_type<Arithmetic>>
550 Result v = biased_sample_variance();
551 return ( Result{0} > v ) ? Result{} :
static_cast<Result
>(
sqrt( v ) );
553 [[
deprecated(
"The name 'rms' has changed to standard_deviation" )]] Arithmetic
rms()
const {
554 return standard_deviation();
557 template <
typename Result = fp_result_type<Arithmetic>>
560 if ( 0 ==
n )
return Result{};
565 Result v = biased_sample_variance();
566 return ( Result{0} > v ) ? Result{} :
static_cast<Result
>(
sqrt( v /
n ) );
574 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
583 template <
typename Arithmetic,
template <
typename Int, atomicity Ato>
class ContainedAccumulator>
584 class Buffer :
public ContainedAccumulator<Arithmetic, atomicity::none> {
585 using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
586 using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
594 void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *
this ) ); }
607 template <
class OWNER>
609 o->declareCounter( tag, *
this );
614 template <
typename stream>
616 s <<
boost::format{
" | %|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
617 return print( s,
true );
646 template <
typename Arithmetic, atomicity Atomicity,
template <
typename Int, atomicity Ato>
class Accumulator>
656 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
660 ( *this ) += Arithmetic{};
670 template <
typename stream>
671 stream&
printImpl( stream& o,
bool tableFormat )
const {
673 auto fmt = ( tableFormat ?
"|%|10d| |" :
"#=%|-7lu|" );
679 return printImpl( o, tableFormat );
692 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
698 template <
typename stream>
699 stream&
printImpl( stream& o,
bool tableFormat )
const {
700 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |" :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
705 return printImpl( o, tableFormat );
714 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
721 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
727 template <
typename stream>
728 stream&
printImpl( stream& o,
bool tableFormat )
const {
729 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |" 730 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
735 return printImpl( o, tableFormat );
748 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
753 template <
typename stream>
754 stream&
printImpl( stream& o,
bool tableFormat )
const {
756 ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" 757 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
759 this->
min() % this->
max();
763 return printImpl( o, tableFormat );
773 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
778 template <
typename stream>
779 stream&
printImpl( stream& o,
bool tableFormat )
const {
780 auto fmt = ( tableFormat ?
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |" 781 :
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
782 return o <<
boost::format{fmt} % this->
nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
783 ( this->efficiencyErr() * 100 );
787 return printImpl( o, tableFormat );
791 template <
typename stream>
794 o <<
boost::format{
" |*%|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
795 return print( o,
true );
799 return printImpl( o, tag );
810 template <
typename Counter,
typename Container,
typename Fun>
812 auto b = counter.
buffer();
813 for (
const auto& elem : container ) b += f( elem );
826 Gaudi::Accumulators::StatAccumulator,
827 Gaudi::Accumulators::BinomialAccumulator> {
834 using AccParent::reset;
837 template <
class OWNER>
839 o->declareCounter( tag, *
this );
841 StatEntity(
const unsigned long entries,
const double flag,
const double flag2,
const double minFlag,
842 const double maxFlag ) {
847 void reset() { AccParent::reset(); }
853 ( *this ) += ( -by );
876 std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
887 unsigned long add(
const double v ) {
893 double Sum()
const {
return sum(); }
896 double rms()
const {
return standard_deviation(); }
897 double Rms()
const {
return standard_deviation(); }
898 double RMS()
const {
return standard_deviation(); }
899 double Eff()
const {
return eff(); }
903 double flag()
const {
return sum(); }
904 double flag2()
const {
return sum2(); }
906 double flagRMS()
const {
return standard_deviation(); }
911 using boost::algorithm::icontains;
912 return icontains( name,
"eff" ) || icontains( name,
"acc" ) || icontains( name,
"filt" ) ||
913 icontains( name,
"fltr" ) || icontains( name,
"pass" );
915 template <
typename stream>
919 return o << fmt.str();
922 return printFormattedImpl( o, format );
926 template <
typename stream>
929 if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() && sum() <=
nEntries() &&
930 ( 0 ==
min() || 1 ==
min() ) && ( 0 ==
max() || 1 ==
max() ) ) {
933 if ( name.
empty() ) {
934 constexpr
auto fmt =
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
936 ( efficiencyErr() * 100 );
938 auto fmt =
" |*" + fmtHead +
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
940 ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
943 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
945 ( efficiencyErr() * 100 );
950 if ( name.
empty() ) {
951 constexpr
auto fmt =
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
955 auto fmt =
" | " + fmtHead +
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
960 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
967 return printImpl( o, tableFormat, name, flag, fmtHead );
971 return printImpl( o, tableFormat, name, flag, fmtHead );
974 return print( o,
true, tag,
true );
977 return print( o,
true, tag,
true );
981 return print( o, tableFormat, emptyName,
true );
985 return print( o, tableFormat, emptyName,
true );
996 #endif // GAUDIKERNEL_COUNTERS_H constexpr unsigned long operator()(U &&) const noexcept
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
virtual std::ostream & print(std::ostream &o, const std::string &tag) const override
prints the counter to a stream in table format, with the given tag
std::string toString() const
auto biased_sample_variance() const
static void merge(InternalType &a, Arithmetic b) noexcept
Definition of the MsgStream class used to transmit messages.
stream & printImpl(stream &o, const std::string &tag) const
static void merge(InternalType &a, Arithmetic b) noexcept
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
unsigned long nEntries() const
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
PrintableCounter()=default
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
decltype(std::atomic< T >{}.fetch_add(0)) has_fetch_add_
type_traits for checking the presence of fetch_add in std::atomic<T>
std::ostream & fillStream(std::ostream &o) const
unsigned long nEntries() const
unsigned long nFalseEntries() const
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
An empty ancester of all counters that provides a buffer method that returns a buffer on itself...
unsigned long nTrueEntries() const
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
atomicity
Defines atomicity of the accumulators.
A counter aiming at computing average and sum2 / variance / standard deviation.
typename Gaudi::cpp17::is_detected< has_fetch_add_, T >::value_t has_fetch_add
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
An Adder ValueHandler operator(a, b) means a += b.
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
A counter aiming at computing sum and average.
struct deprecated("use MergingTransformer instead")]] ListTransformer
virtual std::ostream & print(std::ostream &o, const std::string &tag) const
prints the counter to a stream in table format, with the given tag
An functor always returning the value N.
An empty ancester of all counters that knows how to print themselves.
double flagMeanErr() const
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
stream & printImpl(stream &o, bool tableFormat, const std::string &name, bool flag, std::string const &fmtHead) const
bool operator<(const StatEntity &se) const
StatEntity operator++(int)
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
std::decay_t< std::result_of_t< Identity(unsigned long)>> OutputType
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
static constexpr OutputType getValue(const InternalType &v) noexcept
static constexpr OutputType DefaultValue()
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
PropertyMgr & operator=(const PropertyMgr &)=delete
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
MsgStream & fillStream(MsgStream &o) const
StatEntity & operator++()
static constexpr OutputType DefaultValue()
PrintableCounter(OWNER *o, const std::string &tag)
GenericAccumulator operator+=(const InputType by)
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
std::conditional_t< std::is_integral< Arithmetic >::value, Result, Arithmetic > fp_result_type
type_trait for the result type of a floating point operation on the type Arithmetic ...
virtual bool toBePrinted() const
hint whether we should print that counter or not.
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
auto efficiencyErr() const
unsigned int operator()(bool v) const
AccumulatorSet & operator+=(const InputType by)
StatEntity & operator-=(double by)
StatEntity(OWNER *o, const std::string &tag)
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Buffer< Arithmetic, Accumulator > buffer()
virtual std::ostream & print(std::ostream &o, const std::string &tag) const override
prints the counter to a stream in table format, with the given tag
std::ostream & print(std::ostream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
auto standard_deviation() const
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override
GenericAccumulator & operator=(const GenericAccumulator &other)
std::string toString() const
get a string representation
A counter aiming at computing average and sum2 / variance / standard deviation.
auto unbiased_sample_variance() const
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
stream & printFormattedImpl(stream &o, const std::string &format) const
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
StatEntity & operator+=(StatEntity by)
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
stream & printImpl(stream &o, bool tableFormat) const
stream & printImpl(stream &o, bool tableFormat) const
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
stream & printImpl(stream &s, const std::string &tag) const
StatEntity & operator--()
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
A counter dealing with binomial data.
static bool effCounter(const std::string &name)
MsgStream & printFormatted(MsgStream &o, const std::string &format) const
ValueHandler::InternalType m_value
stream & printImpl(stream &o, bool tableFormat) const
static constexpr OutputType DefaultValue()
helper functor for the TrueAccumulator
helper functor for the FalseAccumulator
stream & printImpl(stream &o, bool tableFormat) const
unsigned long addFlag(const double v)
Base type for all functors used as ValuesHandler.
class MergingTransformer< Out(const vector_of_const_< In > void
GenericAccumulator(const GenericAccumulator &other)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
A basic counter counting input values.
MsgStream & print(MsgStream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
static constexpr OutputType DefaultValue()
stream & printImpl(stream &o, bool tableFormat) const
std::ostream & operator<<(std::ostream &s, const PrintableCounter &counter)
external printout operator to a stream type
static void merge(InternalType &a, Arithmetic b) noexcept
static void merge(InternalType &a, Arithmetic b) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
static constexpr OutputType getValue(const InternalType &v) noexcept
backward compatible StatEntity class.
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
StatEntity operator--(int)
StatEntity & operator+=(double by)
ContainedAccumulator< Arithmetic, atomicity::none > base_type
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b...
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
unsigned int operator()(bool v) const
Generic Accumulator, templated by.
Header file for std:chrono::duration-based Counters.
void operator=(double by)
virtual MsgStream & print(MsgStream &o, const std::string &tag) const
unsigned long add(const double v)
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override