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> 146 namespace Accumulators {
154 template <
unsigned long N>
156 template <
typename U>
166 template <
typename U>
167 constexpr decltype(
auto )
operator()( U&& v )
const noexcept {
168 return std::forward<U>( v );
176 template <
typename U>
177 constexpr decltype(
auto )
operator()( U&& v )
const noexcept {
185 template <
typename T,
typename =
int>
187 template <
typename T>
188 using has_fetch_add =
typename Gaudi::cpp17::is_detected<has_fetch_add_, T>::value_t;
193 template <
typename Arithmetic,
typename Result =
double>
194 using fp_result_type = std::conditional_t<std::is_integral<Arithmetic>::value, Result, Arithmetic>;
199 template <
typename Arithmetic, atomicity Atomicity>
205 template <
typename Arithmetic>
216 template <
typename Arithmetic>
221 return v.load( std::memory_order_relaxed );
230 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
236 template <
typename Arithmetic>
247 template <
typename Arithmetic>
252 #if __cplusplus > 201402L 253 static void merge(
InternalType& a, Arithmetic b ) noexcept {
254 if ( DefaultValue() == b )
return;
257 a.
fetch_add( b, std::memory_order_relaxed );
267 template <
typename T>
269 auto current = a.
load( std::memory_order_relaxed );
273 template <
typename T>
275 a.
fetch_add( b, std::memory_order_relaxed );
280 if ( DefaultValue() == b )
return;
290 template <
typename Arithmetic, atomicity Atomicity,
typename Compare, Arithmetic ( *Initial )()>
296 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
302 if ( Compare{}( b, a ) ) a = b;
309 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
316 while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
325 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
332 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
356 template <
typename A,
typename B, atomicity C,
typename D,
typename E,
typename F>
360 using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
362 ValueHandler::merge( m_value, InputTransform{}( by ) );
368 m_value = ValueHandler::getValue( other.
m_value );
371 OutputType value()
const {
return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
373 template <atomicity ato,
typename VH>
375 auto otherValue = VH::exchange( other.m_value, VH::DefaultValue() );
376 ValueHandler::merge( m_value, otherValue );
391 template <
typename Arithmetic, atomicity Atomicity,
template <
typename, atomicity>
class... Bases>
403 template <atomicity Ato>
406 ( Bases<Arithmetic, Atomicity>::mergeAndReset(
static_cast<Bases<Arithmetic, Ato>&&
>( other ) ), 0 )...};
410 void reset(
const std::tuple<
typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
412 [
this](
const auto&... i ) {
423 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
425 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
426 Arithmetic
max()
const {
return this->value(); }
433 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
435 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
436 Arithmetic
min()
const {
return this->value(); }
443 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
445 unsigned long nEntries()
const {
return this->value(); }
452 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
454 Arithmetic
sum()
const {
return this->value(); }
461 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
463 Arithmetic
sum2()
const {
return this->value(); };
476 template <
typename Arithmetic, atomicity Atomicity>
491 template <
typename Arithmetic, atomicity Atomicity>
501 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
503 unsigned long nEntries()
const {
return this->nTrueEntries() + this->nFalseEntries(); };
505 template <
typename Result = fp_result_type<Arithmetic>>
508 if ( 1 > nbEntries )
return Result{-1};
509 return static_cast<Result
>( this->nTrueEntries() ) / nbEntries;
511 auto eff()
const {
return efficiency(); }
513 template <
typename Result = fp_result_type<Arithmetic>>
519 if ( 1 > nbEntries )
return Result{-1};
520 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
522 auto effErr()
const {
return efficiencyErr(); }
529 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
532 template <
typename Result = fp_result_type<Arithmetic>>
535 return (
n > 0 ) ?
static_cast<Result
>( this->
sum() ) /
n : Result{};
543 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
546 template <
typename Result = fp_result_type<Arithmetic>>
550 return (
n > 0 ) ? ( this->sum2() - sum * ( sum /
n ) ) /
n : Result{};
553 template <
typename Result = fp_result_type<Arithmetic>>
557 return (
n > 1 ) ? ( this->sum2() - sum * ( sum /
n ) ) / (
n - 1 ) : Result{};
560 template <
typename Result = fp_result_type<Arithmetic>>
565 Result v = biased_sample_variance();
566 return ( 0 > v ) ? Result{} : sqrt( v );
568 [[
deprecated(
"The name 'rms' has changed to standard_deviation" )]] Arithmetic
rms()
const {
569 return standard_deviation();
572 template <
typename Result = fp_result_type<Arithmetic>>
575 if ( 0 ==
n )
return Result{};
579 Result v = biased_sample_variance();
580 return ( 0 > v ) ? Result{} : sqrt( v /
n );
588 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
597 template <
typename Arithmetic,
template <
typename Int, atomicity Ato>
class ContainedAccumulator>
598 class Buffer :
public ContainedAccumulator<Arithmetic, atomicity::none> {
599 using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
600 using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
608 void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *
this ) ); }
621 template <
class OWNER>
623 o->declareCounter( tag, *
this );
628 template <
typename stream>
630 s <<
boost::format{
" | %|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
631 return print( s,
true );
660 template <
typename Arithmetic, atomicity Atomicity,
template <
typename Int, atomicity Ato>
class Accumulator>
670 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
674 ( *this ) += Arithmetic{};
684 template <
typename stream>
685 stream&
printImpl( stream& o,
bool tableFormat )
const {
687 auto fmt = ( tableFormat ?
"|%|10d| |" :
"#=%|-7lu|" );
693 return printImpl( o, tableFormat );
706 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
712 template <
typename stream>
713 stream&
printImpl( stream& o,
bool tableFormat )
const {
714 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |" :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
719 return printImpl( o, tableFormat );
728 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
735 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
741 template <
typename stream>
742 stream&
printImpl( stream& o,
bool tableFormat )
const {
743 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |" 744 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
749 return printImpl( o, tableFormat );
762 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
767 template <
typename stream>
768 stream&
printImpl( stream& o,
bool tableFormat )
const {
770 ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" 771 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
773 this->
min() % this->
max();
777 return printImpl( o, tableFormat );
787 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
792 template <
typename stream>
793 stream&
printImpl( stream& o,
bool tableFormat )
const {
794 auto fmt = ( tableFormat ?
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |" 795 :
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
796 return o <<
boost::format{fmt} % this->
nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
797 ( this->efficiencyErr() * 100 );
801 return printImpl( o, tableFormat );
805 template <
typename stream>
808 o <<
boost::format{
" |*%|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
809 return print( o,
true );
813 return printImpl( o, tag );
823 template <
typename Counter,
typename Container,
typename Fun>
825 auto b = counter.
buffer();
826 for (
const auto& elem : container ) b += f( elem );
839 Gaudi::Accumulators::StatAccumulator,
840 Gaudi::Accumulators::BinomialAccumulator> {
847 using AccParent::reset;
850 template <
class OWNER>
852 o->declareCounter( tag, *
this );
854 StatEntity(
const unsigned long entries,
const double flag,
const double flag2,
const double minFlag,
855 const double maxFlag ) {
860 void reset() { AccParent::reset(); }
866 ( *this ) += ( -by );
889 std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
900 unsigned long add(
const double v ) {
909 double rms()
const {
return standard_deviation(); }
910 double Rms()
const {
return standard_deviation(); }
911 double RMS()
const {
return standard_deviation(); }
912 double Eff()
const {
return eff(); }
917 double flag2()
const {
return sum2(); }
919 double flagRMS()
const {
return standard_deviation(); }
924 using boost::algorithm::icontains;
925 return icontains( name,
"eff" ) || icontains( name,
"acc" ) || icontains( name,
"filt" ) ||
926 icontains( name,
"fltr" ) || icontains( name,
"pass" );
928 template <
typename stream>
932 return o << fmt.str();
935 return printFormattedImpl( o, format );
939 template <
typename stream>
942 if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() &&
sum() <=
nEntries() &&
943 ( 0 ==
min() || 1 ==
min() ) && ( 0 ==
max() || 1 ==
max() ) ) {
946 if ( name.
empty() ) {
947 constexpr
auto fmt =
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
949 ( efficiencyErr() * 100 );
951 auto fmt =
" |*" + fmtHead +
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
953 ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
956 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
958 ( efficiencyErr() * 100 );
963 if ( name.
empty() ) {
964 constexpr
auto fmt =
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
968 auto fmt =
" | " + fmtHead +
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
973 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
980 return printImpl( o, tableFormat, name, flag, fmtHead );
984 return printImpl( o, tableFormat, name, flag, fmtHead );
987 return print( o,
true, tag,
true );
990 return print( o,
true, tag,
true );
994 return print( o, tableFormat, emptyName,
true );
998 return print( o, tableFormat, emptyName,
true );
1009 #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
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...
double sum(double x, double y, double z)
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
class MergingTransformer< Out(const vector_of_const_< In > void
decltype(auto) constexpr apply(F &&f, Tuple &&t) noexcept(noexcept( detail::apply_impl(std::forward< F >(f), std::forward< Tuple >(t), std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple >>::value >{})))
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
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)
static void add(InternalType &a, T b, std::true_type)
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 ...
static void add(InternalType &a, T b, std::false_type)
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)
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
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
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.
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
T compare_exchange_weak(T...args)
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.
Helper functions to set/get the application return code.
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