1 #ifndef GAUDIKERNEL_COUNTERS_H 2 #define GAUDIKERNEL_COUNTERS_H 1 131 #include "boost/algorithm/string/predicate.hpp" 132 #include "boost/format.hpp" 139 #include <type_traits> 158 template <
typename T, T N>
160 template <
typename U>
170 template <
typename U>
171 constexpr decltype(
auto ) operator()( U&& v )
const noexcept {
172 return std::forward<U>( v );
180 template <
typename U>
181 constexpr decltype(
auto ) operator()( U&& v )
const noexcept {
189 template <
typename T,
typename =
int>
191 template <
typename T>
192 inline constexpr
bool has_fetch_add_v = Gaudi::cpp17::is_detected_v<has_fetch_add_, T>;
197 template <
typename Arithmetic,
typename Result =
double>
198 using fp_result_type = std::conditional_t<std::is_integral_v<Arithmetic>, Result, Arithmetic>;
203 template <
typename Arithmetic, atomicity Atomicity>
209 template <
typename Arithmetic>
220 template <
typename Arithmetic>
225 return v.load( std::memory_order_relaxed );
234 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
240 template <
typename Arithmetic>
251 template <
typename Arithmetic>
257 if ( DefaultValue() == b )
return;
258 if constexpr ( has_fetch_add_v<InternalType> ) {
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,
typename, atomicity,
typename,
typename,
typename>
342 using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
348 template <
typename... Args>
357 template <atomicity ato,
typename VH>
374 template <
typename Arithmetic, atomicity Atomicity,
template <
typename, atomicity>
class... Bases>
381 ( Bases<Arithmetic, Atomicity>::operator+=( by ), ... );
385 void reset() { ( Bases<Arithmetic, Atomicity>::reset(), ... ); }
386 template <atomicity Ato>
388 ( Bases<Arithmetic, Atomicity>::mergeAndReset(
static_cast<Bases<Arithmetic, Ato>&&
>( other ) ), ... );
392 void reset(
const std::tuple<
typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
393 std::apply( [
this](
const auto&... i ) { ( this->Bases<Arithmetic, Atomicity>::reset( i ), ... ); }, t );
401 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
403 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
411 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
413 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
421 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
430 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
439 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
454 template <
typename Arithmetic, atomicity Atomicity>
469 template <
typename Arithmetic, atomicity Atomicity>
479 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
481 unsigned long nEntries()
const {
return this->nTrueEntries() + this->nFalseEntries(); };
483 template <
typename Result = fp_result_type<Arithmetic>>
486 if ( 1 > nbEntries )
return Result{-1};
487 return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
491 template <
typename Result = fp_result_type<Arithmetic>>
498 if ( 1 > nbEntries )
return Result{-1};
499 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
508 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
511 template <
typename Result = fp_result_type<Arithmetic>>
514 Result sum = this->sum();
515 return (
n > 0 ) ? static_cast<Result>( sum /
n ) : Result{};
523 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
526 template <
typename Result = fp_result_type<Arithmetic>>
529 Result sum = this->sum();
530 return (
n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum /
n ) ) /
n ) : Result{};
533 template <
typename Result = fp_result_type<Arithmetic>>
536 Result sum = this->sum();
537 return (
n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum /
n ) ) / (
n - 1 ) ) : Result{};
540 template <
typename Result = fp_result_type<Arithmetic>>
547 return ( Result{0} > v ) ? Result{} : static_cast<Result>(
sqrt( v ) );
549 [[deprecated(
"The name 'rms' has changed to standard_deviation" )]] Arithmetic
rms()
const {
553 template <
typename Result = fp_result_type<Arithmetic>>
556 if ( 0 ==
n )
return Result{};
562 return ( Result{0} > v ) ? Result{} : static_cast<Result>(
sqrt( v /
n ) );
570 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
579 template <
typename Arithmetic,
template <
typename Int, atomicity Ato>
class ContainedAccumulator>
580 class Buffer :
public ContainedAccumulator<Arithmetic, atomicity::none> {
581 using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
582 using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
590 void push() {
m_prime.mergeAndReset( static_cast<base_type&&>( *
this ) ); }
603 template <
class OWNER>
605 o->declareCounter( tag, *
this );
610 template <
typename stream>
612 s <<
boost::format{
" | %|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
642 template <
typename Arithmetic, atomicity Atomicity,
template <
typename Int, atomicity Ato>
class Accumulator>
652 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
656 ( *this ) += Arithmetic{};
666 template <
typename stream>
667 stream&
printImpl( stream& o,
bool tableFormat )
const {
669 auto fmt = ( tableFormat ?
"|%|10d| |" :
"#=%|-7lu|" );
687 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
693 template <
typename stream>
694 stream&
printImpl( stream& o,
bool tableFormat )
const {
695 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |" :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
709 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
716 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
722 template <
typename stream>
723 stream&
printImpl( stream& o,
bool tableFormat )
const {
724 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |" 725 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
743 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
748 template <
typename stream>
749 stream&
printImpl( stream& o,
bool tableFormat )
const {
750 auto fmt = ( tableFormat ?
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" 751 :
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
753 this->
min() % this->
max();
767 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
772 template <
typename stream>
773 stream&
printImpl( stream& o,
bool tableFormat )
const {
774 auto fmt = ( tableFormat ?
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |" 775 :
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
785 template <
typename stream>
788 o <<
boost::format{
" |*%|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
789 return print( o,
true );
812 template <atomicity Atomicity>
814 std::conditional_t<Atomicity == atomicity::none, unsigned long, std::atomic<unsigned long>>
count = {0};
820 template <atomicity OtherAtomicity>
828 template <atomicity Atomicity>
837 auto count = ++orig.
count;
843 template <atomicity Atomicity>
850 template <MSG::Level level, atomicity Atomicity = atomicity::full>
853 details::MsgCounter::Logger,
855 details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>> {
856 template <
typename OWNER>
861 details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>>{
862 std::in_place,
this, nMax} {}
867 template <
typename stream>
868 stream&
printImpl( stream& o,
bool tableFormat )
const {
869 return o <<
boost::format{tableFormat ?
"|%|10d| |" :
"#=%|-7lu|"} % this->value();
881 template <
typename Counter,
typename Container,
typename Fun>
884 for (
const auto& elem : container ) b += f( elem );
895 Gaudi::Accumulators::StatAccumulator,
896 Gaudi::Accumulators::BinomialAccumulator> {
903 using AccParent::reset;
906 template <
class OWNER>
908 o->declareCounter( tag, *
this );
910 StatEntity(
const unsigned long entries,
const double flag,
const double flag2,
const double minFlag,
911 const double maxFlag ) {
916 void reset() { AccParent::reset(); }
922 ( *this ) += ( -by );
945 std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
949 this->AccumulatorSet::operator+=( by );
956 unsigned long add(
const double v ) {
962 double Sum()
const {
return sum(); }
965 double rms()
const {
return standard_deviation(); }
966 double Rms()
const {
return standard_deviation(); }
967 double RMS()
const {
return standard_deviation(); }
968 double Eff()
const {
return eff(); }
972 double flag()
const {
return sum(); }
973 double flag2()
const {
return sum2(); }
975 double flagRMS()
const {
return standard_deviation(); }
980 using boost::algorithm::icontains;
981 return icontains(
name,
"eff" ) || icontains(
name,
"acc" ) || icontains(
name,
"filt" ) ||
982 icontains(
name,
"fltr" ) || icontains(
name,
"pass" );
984 template <
typename stream>
988 return o << fmt.str();
991 return printFormattedImpl( o,
format );
995 template <
typename stream>
998 if ( flag && effCounter(
name ) && 0 <= eff() && 0 <= effErr() && sum() <=
nEntries() &&
999 ( 0 ==
min() || 1 ==
min() ) && ( 0 ==
max() || 1 ==
max() ) ) {
1001 if ( tableFormat ) {
1002 if (
name.empty() ) {
1003 constexpr
auto fmt =
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
1005 ( efficiencyErr() * 100 );
1007 auto fmt =
" |*" + fmtHead +
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
1009 ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
1012 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
1014 ( efficiencyErr() * 100 );
1018 if ( tableFormat ) {
1019 if (
name.empty() ) {
1020 constexpr
auto fmt =
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
1024 auto fmt =
" | " + fmtHead +
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
1029 constexpr
auto fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
1035 std::string fmtHead =
"%|-48.48s|%|27t|" )
const {
1036 return printImpl( o, tableFormat,
name, flag, fmtHead );
1039 std::string fmtHead =
"%|-48.48s|%|27t|" )
const {
1040 return printImpl( o, tableFormat,
name, flag, fmtHead );
1043 return print( o,
true, tag,
true );
1046 return print( o,
true, tag,
true );
1050 return print( o, tableFormat, emptyName,
true );
1054 return print( o, tableFormat, emptyName,
true );
1065 #endif // GAUDIKERNEL_COUNTERS_H ContainedAccumulator< Arithmetic, atomicity::full > prime_type
stream & printImpl(stream &o, bool tableFormat, const std::string &name, bool flag, std::string const &fmtHead) const
static void merge(InternalType &a, Arithmetic b) noexcept
Definition of the MsgStream class used to transmit messages.
static void merge(InternalType &a, Arithmetic b) noexcept
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
std::ostream & print(std::ostream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
StatEntity & operator++()
PrintableCounter()=default
auto efficiencyErr() const
unsigned long nTrueEntries() const
decltype(std::atomic< T >{}.fetch_add(0)) has_fetch_add_
type_traits for checking the presence of fetch_add in std::atomic<T>
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
An empty ancester of all counters that provides a buffer method that returns a buffer on itself.
unsigned long nFalseEntries() const
void operator=(double by)
Data(Data< OtherAtomicity > const &other)
bool toBePrinted() const override
hint whether we should print that counter or not.
atomicity
Defines atomicity of the accumulators.
stream & printImpl(stream &o, bool tableFormat) const
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
A counter aiming at computing average and sum2 / variance / standard deviation.
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
An Adder ValueHandler operator(a, b) means a += b.
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
A counter aiming at computing sum and average.
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
int merge(const char *target, const char *source, bool fixup=false, bool dbg=true)
std::string toString() const
get a string representation
A functor always returning the value N.
std::string toString() const
An empty ancester of all counters that knows how to print themselves.
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
bool operator<(const StatEntity &se) const
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
stream & printImpl(stream &o, const std::string &tag) const
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
unsigned long add(const double v)
auto standard_deviation() const
unsigned int operator()(bool v) const
static constexpr OutputType getValue(const InternalType &v) noexcept
static constexpr OutputType DefaultValue()
virtual MsgStream & print(MsgStream &o, const std::string &tag) const
static constexpr OutputType DefaultValue()
GenericAccumulator operator+=(const InputType by)
virtual ~PrintableCounter()=default
destructor
StatEntity & operator+=(StatEntity by)
bool toBePrinted() const override
hint whether we should print that counter or not.
static constexpr OutputType getValue(InternalType const &v) noexcept
MsgStream & fillStream(MsgStream &o) const
void operator=(const Buffer &)=delete
std::conditional_t< Atomicity==atomicity::none, unsigned long, std::atomic< unsigned long > > count
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
StatEntity & operator--()
backward compatible StatEntity class.
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
static bool effCounter(const std::string &name)
bool toBePrinted() const override
hint whether we should print that counter or not.
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
bool toBePrinted() const override
hint whether we should print that counter or not.
stream & printImpl(stream &o, bool tableFormat) const
AccumulatorSet & operator+=(const InputType by)
static void merge(InternalType &orig, bool b)
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Buffer< Arithmetic, Accumulator > buffer()
constexpr AccumulatorSet()=default
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
MsgStream & msgStream() const
Return an uninitialized MsgStream.
GenericAccumulator & operator=(const GenericAccumulator &other)
A counter aiming at computing average and sum2 / variance / standard deviation.
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
unsigned int operator()(bool v) const
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
std::ostream & print(std::ostream &os, bool tableFormat) const override
prints the counter to a stream
std::ostream & fillStream(std::ostream &o) const
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
unsigned long nEntries() const
MsgStream & print(MsgStream &o, const std::string &tag) const override
constexpr T operator()(U &&) const noexcept
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
MsgCounter(OWNER *o, std::string const &msg, int nMax=10)
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
A counter dealing with binomial data.
unsigned long addFlag(const double v)
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
stream & printImpl(stream &o, bool tableFormat) const
stream & printImpl(stream &o, bool tableFormat) const
ValueHandler::InternalType m_value
static constexpr OutputType DefaultValue()
bool toBePrinted() const override
hint whether we should print that counter or not.
helper functor for the TrueAccumulator
helper functor for the FalseAccumulator
GenericAccumulator(std::in_place_t, Args &&... args)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
constexpr bool has_fetch_add_v
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Base type for all functors used as ValuesHandler.
StatEntity operator++(int)
double flagMeanErr() const
GenericAccumulator(const GenericAccumulator &other)
A basic counter counting input values.
static constexpr OutputType DefaultValue()
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
std::ostream & operator<<(std::ostream &s, const PrintableCounter &counter)
external printout operator to a stream type
StatEntity & operator+=(double by)
static void merge(InternalType &a, Arithmetic b) noexcept
MsgCounter & operator++()
static void merge(InternalType &a, Arithmetic b) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
stream & printImpl(stream &s, const std::string &tag) const
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override
StatEntity(OWNER *o, const std::string &tag)
std::decay_t< std::result_of_t< Identity(unsigned long)> > OutputType
auto unbiased_sample_variance() const
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
MsgStream & printFormatted(MsgStream &o, const std::string &format) const
static constexpr OutputType getValue(const InternalType &v) noexcept
stream & printImpl(stream &o, bool tableFormat) const
StatEntity & operator-=(double by)
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
void operator()(bool suppress=false) const
auto biased_sample_variance() const
unsigned long nEntries() const
CommonMessagingBase const * parent
ContainedAccumulator< Arithmetic, atomicity::none > base_type
MsgStream & print(MsgStream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
stream & printImpl(stream &o, bool tableFormat) const
Efficient counter implementations for Gaudi.
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b,...
Generic Accumulator, templated 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...
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
std::conditional_t< std::is_integral_v< Arithmetic >, Result, Arithmetic > fp_result_type
type_trait for the result type of a floating point operation on the type Arithmetic
constexpr Data(Logger const *p, unsigned long mx)
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
MsgStream & print(MsgStream &os, bool tableFormat) const override
StatEntity operator--(int)
stream & printFormattedImpl(stream &o, const std::string &format) const