The Gaudi Framework  v32r2 (46d42edc)
Counters.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_COUNTERS_H
2 #define GAUDIKERNEL_COUNTERS_H 1
3 
131 #include "boost/algorithm/string/predicate.hpp"
132 #include "boost/format.hpp"
133 #include <atomic>
134 #include <cmath>
135 #include <iostream>
136 #include <limits>
137 #include <sstream>
138 #include <tuple>
139 #include <type_traits>
140 #include <utility>
141 
143 #include "GaudiKernel/MsgStream.h"
144 #include "GaudiKernel/detected.h"
145 
146 namespace Gaudi::Accumulators {
147 
149  enum class atomicity { none, full };
150 
152  template <class T>
153  auto sqrt( T d );
154 
158  template <typename T, T N>
159  struct Constant {
160  template <typename U>
161  constexpr T operator()( U&& ) const noexcept {
162  return N;
163  }
164  };
165 
169  struct Identity {
170  template <typename U>
171  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
172  return std::forward<U>( v );
173  }
174  };
175 
179  struct Square {
180  template <typename U>
181  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
182  return v * v;
183  }
184  };
185 
189  template <typename T, typename = int>
190  using has_fetch_add_ = decltype( std::atomic<T>{}.fetch_add( 0 ) );
191  template <typename T>
192  inline constexpr bool has_fetch_add_v = Gaudi::cpp17::is_detected_v<has_fetch_add_, T>;
193 
197  template <typename Arithmetic, typename Result = double>
198  using fp_result_type = std::conditional_t<std::is_integral_v<Arithmetic>, Result, Arithmetic>;
199 
203  template <typename Arithmetic, atomicity Atomicity>
205 
209  template <typename Arithmetic>
210  struct BaseValueHandler<Arithmetic, atomicity::none> {
211  using OutputType = Arithmetic;
212  using InternalType = Arithmetic;
213  static constexpr OutputType getValue( const InternalType& v ) noexcept { return v; };
214  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return std::exchange( v, newv ); }
215  };
216 
220  template <typename Arithmetic>
221  struct BaseValueHandler<Arithmetic, atomicity::full> {
222  using OutputType = Arithmetic;
224  static constexpr OutputType getValue( const InternalType& v ) noexcept {
225  return v.load( std::memory_order_relaxed );
226  };
227  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
228  };
229 
234  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
235  struct Adder;
236 
240  template <typename Arithmetic>
241  struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
244  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
245  static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; };
246  };
247 
251  template <typename Arithmetic>
252  struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
255  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
256  static void merge( InternalType& a, Arithmetic b ) noexcept {
257  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
258  if constexpr ( has_fetch_add_v<InternalType> ) {
259  a.fetch_add( b, std::memory_order_relaxed );
260  } else {
262  while ( !a.compare_exchange_weak( current, current + b ) )
263  ;
264  }
265  };
266  };
267 
272  template <typename Arithmetic, atomicity Atomicity, typename Compare, Arithmetic ( *Initial )()>
273  struct Extremum;
274 
278  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
279  struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
282  static constexpr OutputType DefaultValue() { return Initial(); }
283  static void merge( InternalType& a, Arithmetic b ) noexcept {
284  if ( Compare{}( b, a ) ) a = b;
285  };
286  };
287 
291  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
292  struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
295  static constexpr OutputType DefaultValue() { return Initial(); }
296  static void merge( InternalType& a, Arithmetic b ) noexcept {
297  Arithmetic prev_value = BaseValueHandler<Arithmetic, atomicity::full>::getValue( a );
298  while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
299  ;
300  };
301  };
302 
307  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
309 
314  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
316 
334  template <typename InputType, typename InnerType, atomicity Atomicity = atomicity::full,
335  typename InputTransform = Identity, typename OutputTransform = Identity,
336  typename ValueHandler = Adder<InnerType, Atomicity>>
338  template <typename, typename, atomicity, typename, typename, typename>
339  friend class GenericAccumulator;
340 
341  public:
342  using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
343  GenericAccumulator operator+=( const InputType by ) {
344  ValueHandler::merge( m_value, InputTransform{}( by ) );
345  return *this;
346  }
347  GenericAccumulator() : m_value( ValueHandler::DefaultValue() ) {}
348  template <typename... Args>
349  GenericAccumulator( std::in_place_t, Args&&... args ) : m_value( std::forward<Args>( args )... ) {}
350  GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
352  m_value = ValueHandler::getValue( other.m_value );
353  return *this;
354  }
355  OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
356  void reset() { reset( ValueHandler::DefaultValue() ); }
357  template <atomicity ato, typename VH>
359  ValueHandler::merge( m_value, VH::exchange( other.m_value, VH::DefaultValue() ) );
360  }
361 
362  protected:
363  void reset( InnerType in ) { m_value = std::move( in ); }
364 
365  private:
366  typename ValueHandler::InternalType m_value;
367  };
368 
374  template <typename Arithmetic, atomicity Atomicity, template <typename, atomicity> class... Bases>
375  class AccumulatorSet : public Bases<Arithmetic, Atomicity>... {
376  public:
377  using InputType = Arithmetic;
379  constexpr AccumulatorSet() = default;
381  ( Bases<Arithmetic, Atomicity>::operator+=( by ), ... );
382  return *this;
383  }
384  OutputType value() const { return std::make_tuple( Bases<Arithmetic, Atomicity>::value()... ); }
385  void reset() { ( Bases<Arithmetic, Atomicity>::reset(), ... ); }
386  template <atomicity Ato>
388  ( Bases<Arithmetic, Atomicity>::mergeAndReset( static_cast<Bases<Arithmetic, Ato>&&>( other ) ), ... );
389  }
390 
391  protected:
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 );
394  }
395  };
396 
401  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
403  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
404  Arithmetic max() const { return this->value(); }
405  };
406 
411  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
413  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
414  Arithmetic min() const { return this->value(); }
415  };
416 
421  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
422  struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
423  unsigned long nEntries() const { return this->value(); }
424  };
425 
430  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
431  struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
432  Arithmetic sum() const { return this->value(); }
433  };
434 
439  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
440  struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
441  Arithmetic sum2() const { return this->value(); };
442  };
443 
445  struct TrueTo1 {
446  unsigned int operator()( bool v ) const { return v; }
447  };
448 
454  template <typename Arithmetic, atomicity Atomicity>
455  struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
456  unsigned long nTrueEntries() const { return this->value(); };
457  };
458 
460  struct FalseTo1 {
461  unsigned int operator()( bool v ) const { return !v; }
462  };
463 
469  template <typename Arithmetic, atomicity Atomicity>
470  struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
471  unsigned long nFalseEntries() const { return this->value(); };
472  };
473 
479  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
480  struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, TrueAccumulator, FalseAccumulator> {
481  unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); };
482 
483  template <typename Result = fp_result_type<Arithmetic>>
484  auto efficiency() const {
485  auto nbEntries = nEntries();
486  if ( 1 > nbEntries ) return Result{-1};
487  return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
488  }
489  auto eff() const { return efficiency(); }
490 
491  template <typename Result = fp_result_type<Arithmetic>>
492  auto efficiencyErr() const {
493  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
494  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
496  using std::sqrt;
497  auto nbEntries = nEntries();
498  if ( 1 > nbEntries ) return Result{-1};
499  return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
500  }
501  auto effErr() const { return efficiencyErr(); }
502  };
503 
508  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
509  struct AveragingAccumulator : AccumulatorSet<Arithmetic, Atomicity, CountAccumulator, SumAccumulator> {
510 
511  template <typename Result = fp_result_type<Arithmetic>>
512  auto mean() const {
513  auto n = this->nEntries();
514  Result sum = this->sum();
515  return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
516  }
517  };
518 
523  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
524  struct SigmaAccumulator : AccumulatorSet<Arithmetic, Atomicity, AveragingAccumulator, SquareAccumulator> {
525 
526  template <typename Result = fp_result_type<Arithmetic>>
527  auto biased_sample_variance() const {
528  auto n = this->nEntries();
529  Result sum = this->sum();
530  return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
531  }
532 
533  template <typename Result = fp_result_type<Arithmetic>>
535  auto n = this->nEntries();
536  Result sum = this->sum();
537  return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
538  }
539 
540  template <typename Result = fp_result_type<Arithmetic>>
541  auto standard_deviation() const {
542  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
543  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
545  using std::sqrt;
546  Result v = biased_sample_variance();
547  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
548  }
549  [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
550  return standard_deviation();
551  }
552 
553  template <typename Result = fp_result_type<Arithmetic>>
554  auto meanErr() const {
555  auto n = this->nEntries();
556  if ( 0 == n ) return Result{};
557  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
558  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
560  using std::sqrt;
561  Result v = biased_sample_variance();
562  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
563  }
564  };
565 
570  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
572 
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>;
583 
584  public:
585  Buffer() = delete;
586  Buffer( prime_type& p ) : base_type(), m_prime( p ) {}
587  Buffer( const Buffer& ) = delete;
588  void operator=( const Buffer& ) = delete;
589  Buffer( Buffer&& other ) : base_type( other ), m_prime( other.m_prime ) { other.reset(); }
590  void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *this ) ); }
591  ~Buffer() { push(); }
592 
593  private:
595  };
596 
602  PrintableCounter() = default;
603  template <class OWNER>
604  PrintableCounter( OWNER* o, const std::string& tag ) {
605  o->declareCounter( tag, *this );
606  }
608  virtual ~PrintableCounter() = default;
609  // add tag to printout
610  template <typename stream>
611  stream& printImpl( stream& s, const std::string& tag ) const {
612  s << boost::format{" | %|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
613  return print( s, true );
614  }
616  virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
617  virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
619  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const { return printImpl( o, tag ); }
620  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const { return printImpl( o, tag ); }
623  virtual bool toBePrinted() const { return true; }
626  std::ostringstream ost;
627  print( ost );
628  return ost.str();
629  }
630  };
631 
635  inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
636  inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
642  template <typename Arithmetic, atomicity Atomicity, template <typename Int, atomicity Ato> class Accumulator>
645  Buffer<Arithmetic, Accumulator> buffer() { return {*static_cast<Accumulator<Arithmetic, Atomicity>*>( this )}; }
646  };
647 
652  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
653  struct Counter : BufferableCounter<Arithmetic, Atomicity, Counter>, CountAccumulator<Arithmetic, Atomicity> {
656  ( *this ) += Arithmetic{};
657  return *this;
658  }
660  auto copy = *this;
661  ++( *this );
662  return copy;
663  }
665 
666  template <typename stream>
667  stream& printImpl( stream& o, bool tableFormat ) const {
668  // Avoid printing empty counters in non DEBUG mode
669  auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
670  return o << boost::format{fmt} % this->nEntries();
671  }
672 
673  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
674  return printImpl( o, tableFormat );
675  }
676  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
677  bool toBePrinted() const override {
678  return this->nEntries() > 0;
679  ;
680  }
681  };
682 
687  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
688  struct AveragingCounter : BufferableCounter<Arithmetic, Atomicity, AveragingCounter>,
689  AveragingAccumulator<Arithmetic, Atomicity> {
692 
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|" );
696  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean();
697  }
698 
699  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
700  return printImpl( o, tableFormat );
701  }
702  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
703 
704  bool toBePrinted() const override {
705  return this->nEntries() > 0;
706  ;
707  }
708  };
709  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
711 
716  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
717  struct SigmaCounter : BufferableCounter<Arithmetic, Atomicity, SigmaCounter>,
718  SigmaAccumulator<Arithmetic, Atomicity> {
721 
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|" );
726  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
727  }
728 
729  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
730  return printImpl( o, tableFormat );
731  }
732  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
733  bool toBePrinted() const override {
734  return this->nEntries() > 0;
735  ;
736  }
737  };
738 
743  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
744  struct StatCounter : BufferableCounter<Arithmetic, Atomicity, StatCounter>, StatAccumulator<Arithmetic, Atomicity> {
747 
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|" );
752  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
753  this->min() % this->max();
754  }
755 
756  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
757  return printImpl( o, tableFormat );
758  }
759  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
760  bool toBePrinted() const override { return this->nEntries() > 0; }
761  };
762 
767  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
768  struct BinomialCounter : BufferableCounter<Arithmetic, Atomicity, BinomialCounter>,
769  BinomialAccumulator<Arithmetic, Atomicity> {
771 
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|)%%|" );
776  return o << boost::format{fmt} % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
777  ( this->efficiencyErr() * 100 );
778  }
779 
780  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
781  return printImpl( o, tableFormat );
782  }
783  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
784 
785  template <typename stream>
786  stream& printImpl( stream& o, const std::string& tag ) const {
787  // override default print to add a '*' in from of the name
788  o << boost::format{" |*%|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
789  return print( o, true );
790  }
792  std::ostream& print( std::ostream& o, const std::string& tag ) const override { return printImpl( o, tag ); }
793  MsgStream& print( MsgStream& o, const std::string& tag ) const override { return printImpl( o, tag ); }
794  bool toBePrinted() const override { return this->nEntries() > 0; }
795  };
796 
798  struct Logger {
802 
803  void operator()( bool suppress = false ) const {
804  if ( suppress ) {
805  parent->msgStream( lvl ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
806  } else {
807  parent->msgStream( lvl ) << msg << endmsg;
808  }
809  }
810  };
811 
812  template <atomicity Atomicity>
813  struct Data {
814  std::conditional_t<Atomicity == atomicity::none, unsigned long, std::atomic<unsigned long>> count = {0};
815  unsigned long max = 0;
816  Logger const* logger = nullptr;
817 
818  constexpr Data( Logger const* p, unsigned long mx ) : max{mx}, logger{p} {}
819 
820  template <atomicity OtherAtomicity>
821  Data( Data<OtherAtomicity> const& other ) {
822  count = other.count;
823  max = other.max;
824  logger = other.logger;
825  }
826  };
827 
828  template <atomicity Atomicity>
829  struct Handler {
832 
833  static constexpr OutputType getValue( InternalType const& v ) noexcept { return v; }
834 
835  static void merge( InternalType& orig, bool b ) {
836  if ( b ) {
837  auto count = ++orig.count;
838  if ( UNLIKELY( count <= orig.max ) ) ( *orig.logger )( count == orig.max );
839  }
840  }
841  };
843  template <atomicity Atomicity>
844  constexpr unsigned long operator()( Data<Atomicity> const& v ) const noexcept {
845  return v.count;
846  }
847  };
848  } // namespace details::MsgCounter
849 
850  template <MSG::Level level, atomicity Atomicity = atomicity::full>
851  struct MsgCounter
853  details::MsgCounter::Logger,
854  GenericAccumulator<bool, details::MsgCounter::Data<Atomicity>, Atomicity, Identity,
855  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>> {
856  template <typename OWNER>
857  MsgCounter( OWNER* o, std::string const& msg, int nMax = 10 )
858  : PrintableCounter( o, msg )
859  , details::MsgCounter::Logger{o, msg, level}
861  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>>{
862  std::in_place, this, nMax} {}
864  ( *this ) += true;
865  return *this;
866  }
867  template <typename stream>
868  stream& printImpl( stream& o, bool tableFormat ) const {
869  return o << boost::format{tableFormat ? "|%|10d| |" : "#=%|-7lu|"} % this->value();
870  }
872  std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
873  MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
874  };
875 
881  template <typename Counter, typename Container, typename Fun>
882  void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
883  auto b = counter.buffer();
884  for ( const auto& elem : container ) b += f( elem );
885  }
886 
887 } // namespace Gaudi::Accumulators
888 
894  public Gaudi::Accumulators::AccumulatorSet<double, Gaudi::Accumulators::atomicity::full,
895  Gaudi::Accumulators::StatAccumulator,
896  Gaudi::Accumulators::BinomialAccumulator> {
897 public:
903  using AccParent::reset;
905  StatEntity() = default;
906  template <class OWNER>
907  StatEntity( OWNER* o, const std::string& tag ) {
908  o->declareCounter( tag, *this );
909  }
910  StatEntity( const unsigned long entries, const double flag, const double flag2, const double minFlag,
911  const double maxFlag ) {
912  reset( std::make_tuple(
913  std::make_tuple( std::make_tuple( std::make_tuple( entries, flag ), flag2 ), minFlag, maxFlag ),
914  std::make_tuple( 0, 0 ) ) );
915  }
916  void reset() { AccParent::reset(); }
917  void operator=( double by ) {
918  this->reset();
919  ( *this ) += by;
920  }
921  StatEntity& operator-=( double by ) {
922  ( *this ) += ( -by );
923  return *this;
924  }
926  ( *this ) += 1.0;
927  return *this;
928  }
930  auto copy = *this;
931  ++( *this );
932  return copy;
933  }
935  ( *this ) += -1.0;
936  return *this;
937  }
939  auto copy = *this;
940  --( *this );
941  return copy;
942  }
943  bool operator<( const StatEntity& se ) const {
944  return std::make_tuple( nEntries(), sum(), min(), max(), sum2() ) <
945  std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
946  };
947  // using AccumulatorSet::operator+=;
948  StatEntity& operator+=( double by ) {
949  this->AccumulatorSet::operator+=( by );
950  return *this;
951  }
953  mergeAndReset( std::move( by ) );
954  return *this;
955  }
956  unsigned long add( const double v ) {
957  *this += v;
958  return nEntries();
959  }
960  unsigned long addFlag( const double v ) { return add( v ); }
961  // aliases (a'la ROOT)
962  double Sum() const { return sum(); } // get sum
963  double Mean() const { return mean(); } // get mean
964  double MeanErr() const { return meanErr(); } // get error in mean
965  double rms() const { return standard_deviation(); } // get rms
966  double Rms() const { return standard_deviation(); } // get rms
967  double RMS() const { return standard_deviation(); } // get rms
968  double Eff() const { return eff(); } // get efficiency
969  double Min() const { return min(); } // get minimal value
970  double Max() const { return max(); } // get maximal value
971  // some legacy methods, to be removed ...
972  double flag() const { return sum(); }
973  double flag2() const { return sum2(); }
974  double flagMean() const { return mean(); }
975  double flagRMS() const { return standard_deviation(); }
976  double flagMeanErr() const { return meanErr(); }
977  double flagMin() const { return min(); }
978  double flagMax() const { return max(); }
979  static bool effCounter( const std::string& name ) {
980  using boost::algorithm::icontains;
981  return icontains( name, "eff" ) || icontains( name, "acc" ) || icontains( name, "filt" ) ||
982  icontains( name, "fltr" ) || icontains( name, "pass" );
983  }
984  template <typename stream>
985  stream& printFormattedImpl( stream& o, const std::string& format ) const {
986  boost::format fmt{format};
987  fmt % nEntries() % sum() % mean() % standard_deviation() % min() % max();
988  return o << fmt.str();
989  }
991  return printFormattedImpl( o, format );
992  }
993  MsgStream& printFormatted( MsgStream& o, const std::string& format ) const { return printFormattedImpl( o, format ); }
995  template <typename stream>
996  stream& printImpl( stream& o, bool tableFormat, const std::string& name, bool flag,
997  std::string const& fmtHead ) const {
998  if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() && sum() <= nEntries() &&
999  ( 0 == min() || 1 == min() ) && ( 0 == max() || 1 == max() ) ) {
1000  // efficiency printing
1001  if ( tableFormat ) {
1002  if ( name.empty() ) {
1003  constexpr auto fmt = "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
1004  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
1005  ( efficiencyErr() * 100 );
1006  } else {
1007  auto fmt = " |*" + fmtHead + "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
1008  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % BinomialAccParent::nEntries() % sum() %
1009  ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
1010  }
1011  } else {
1012  constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
1013  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
1014  ( efficiencyErr() * 100 );
1015  }
1016  } else {
1017  // Standard printing
1018  if ( tableFormat ) {
1019  if ( name.empty() ) {
1020  constexpr auto fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
1021  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
1022 
1023  } else {
1024  auto fmt = " | " + fmtHead + "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
1025  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % nEntries() % sum() % mean() % standard_deviation() %
1026  min() % max();
1027  }
1028  } else {
1029  constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
1030  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
1031  }
1032  }
1033  }
1034  std::ostream& print( std::ostream& o, bool tableFormat, const std::string& name, bool flag = true,
1035  std::string fmtHead = "%|-48.48s|%|27t|" ) const {
1036  return printImpl( o, tableFormat, name, flag, fmtHead );
1037  }
1038  MsgStream& print( MsgStream& o, bool tableFormat, const std::string& name, bool flag = true,
1039  std::string fmtHead = "%|-48.48s|%|27t|" ) const {
1040  return printImpl( o, tableFormat, name, flag, fmtHead );
1041  }
1042  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const override {
1043  return print( o, true, tag, true );
1044  }
1045  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const override {
1046  return print( o, true, tag, true );
1047  }
1048  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1049  std::string emptyName;
1050  return print( o, tableFormat, emptyName, true );
1051  }
1052  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override {
1053  std::string emptyName;
1054  return print( o, tableFormat, emptyName, true );
1055  }
1057  std::ostringstream ost;
1058  print( ost );
1059  return ost.str();
1060  }
1061  std::ostream& fillStream( std::ostream& o ) const { return print( o ); }
1062  MsgStream& fillStream( MsgStream& o ) const { return print( o ); }
1063 };
1064 
1065 #endif // GAUDIKERNEL_COUNTERS_H
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
Definition: Counters.h:581
stream & printImpl(stream &o, bool tableFormat, const std::string &name, bool flag, std::string const &fmtHead) const
Definition: Counters.h:996
#define UNLIKELY(x)
Definition: Kernel.h:96
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:283
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:296
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
Definition: Counters.h:387
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
Definition: Counters.h:1034
Buffer(prime_type &p)
Definition: Counters.h:586
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:109
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:673
StatEntity & operator++()
Definition: Counters.h:925
double flagMean() const
Definition: Counters.h:974
unsigned long nTrueEntries() const
Definition: Counters.h:456
decltype(std::atomic< T >{}.fetch_add(0)) has_fetch_add_
type_traits for checking the presence of fetch_add in std::atomic<T>
Definition: Counters.h:190
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
Definition: Counters.h:900
An empty ancester of all counters that provides a buffer method that returns a buffer on itself.
Definition: Counters.h:643
unsigned long nFalseEntries() const
Definition: Counters.h:471
void operator=(double by)
Definition: Counters.h:917
double rms() const
Definition: Counters.h:965
Data(Data< OtherAtomicity > const &other)
Definition: Counters.h:821
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:704
atomicity
Defines atomicity of the accumulators.
Definition: Counters.h:149
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:694
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:699
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:744
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:759
An Adder ValueHandler operator(a, b) means a += b.
Definition: Counters.h:235
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:202
A counter aiming at computing sum and average.
Definition: Counters.h:688
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:756
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:780
int merge(const char *target, const char *source, bool fixup=false, bool dbg=true)
Definition: merge.C:420
STL namespace.
constexpr unsigned long operator()(Data< Atomicity > const &v) const noexcept
Definition: Counters.h:844
std::string toString() const
get a string representation
Definition: Counters.h:625
T make_tuple(T... args)
A functor always returning the value N.
Definition: Counters.h:159
std::string toString() const
Definition: Counters.h:1056
An empty ancester of all counters that knows how to print themselves.
Definition: Counters.h:601
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
Definition: Counters.h:792
bool operator<(const StatEntity &se) const
Definition: Counters.h:943
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:215
stream & printImpl(stream &o, const std::string &tag) const
Definition: Counters.h:786
double flagRMS() const
Definition: Counters.h:975
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:732
unsigned long add(const double v)
Definition: Counters.h:956
unsigned int operator()(bool v) const
Definition: Counters.h:446
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:224
STL class.
virtual MsgStream & print(MsgStream &o, const std::string &tag) const
Definition: Counters.h:620
double Eff() const
Definition: Counters.h:968
int N
Definition: IOTest.py:100
GenericAccumulator operator+=(const InputType by)
Definition: Counters.h:343
virtual ~PrintableCounter()=default
destructor
StatEntity & operator+=(StatEntity by)
Definition: Counters.h:952
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:794
static constexpr OutputType getValue(InternalType const &v) noexcept
Definition: Counters.h:833
MsgStream & fillStream(MsgStream &o) const
Definition: Counters.h:1062
void operator=(const Buffer &)=delete
std::conditional_t< Atomicity==atomicity::none, unsigned long, std::atomic< unsigned long > > count
Definition: Counters.h:814
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:783
StatEntity & operator--()
Definition: Counters.h:934
backward compatible StatEntity class.
Definition: Counters.h:893
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:1048
static bool effCounter(const std::string &name)
Definition: Counters.h:979
double flagMin() const
Definition: Counters.h:977
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:760
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:214
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:733
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:667
double flagMax() const
Definition: Counters.h:978
AccumulatorSet & operator+=(const InputType by)
Definition: Counters.h:380
static void merge(InternalType &orig, bool b)
Definition: Counters.h:835
A Square functor.
Definition: Counters.h:179
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Definition: Counters.h:580
double MeanErr() const
Definition: Counters.h:964
T str(T... args)
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:676
Buffer< Arithmetic, Accumulator > buffer()
Definition: Counters.h:645
constexpr AccumulatorSet()=default
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:702
MsgStream & msgStream() const
Return an uninitialized MsgStream.
GenericAccumulator & operator=(const GenericAccumulator &other)
Definition: Counters.h:351
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:717
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Definition: Counters.h:358
unsigned int operator()(bool v) const
Definition: Counters.h:461
T move(T... args)
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
Definition: Counters.h:901
std::ostream & print(std::ostream &os, bool tableFormat) const override
prints the counter to a stream
Definition: Counters.h:872
std::ostream & fillStream(std::ostream &o) const
Definition: Counters.h:1061
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
Definition: Counters.h:375
unsigned long nEntries() const
Definition: Counters.h:423
double Mean() const
Definition: Counters.h:963
MsgStream & print(MsgStream &o, const std::string &tag) const override
Definition: Counters.h:793
Buffer(Buffer &&other)
Definition: Counters.h:589
constexpr T operator()(U &&) const noexcept
Definition: Counters.h:161
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition: Counters.h:28
MsgCounter(OWNER *o, std::string const &msg, int nMax=10)
Definition: Counters.h:857
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
Definition: Counters.h:571
double flag2() const
Definition: Counters.h:973
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
Definition: Counters.h:392
A counter dealing with binomial data.
Definition: Counters.h:768
unsigned long addFlag(const double v)
Definition: Counters.h:960
T fetch_add(T... args)
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
Definition: Counters.h:910
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:773
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:868
ValueHandler::InternalType m_value
Definition: Counters.h:366
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:677
helper functor for the TrueAccumulator
Definition: Counters.h:445
helper functor for the FalseAccumulator
Definition: Counters.h:460
GenericAccumulator(std::in_place_t, Args &&... args)
Definition: Counters.h:349
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:729
constexpr bool has_fetch_add_v
Definition: Counters.h:192
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Definition: Counters.h:623
An Identity functor.
Definition: Counters.h:169
Base type for all functors used as ValuesHandler.
Definition: Counters.h:204
StatEntity operator++(int)
Definition: Counters.h:929
double flagMeanErr() const
Definition: Counters.h:976
GenericAccumulator(const GenericAccumulator &other)
Definition: Counters.h:350
string s
Definition: gaudirun.py:318
A basic counter counting input values.
Definition: Counters.h:653
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
Definition: Counters.h:990
std::ostream & operator<<(std::ostream &s, const PrintableCounter &counter)
external printout operator to a stream type
Definition: Counters.h:635
StatEntity & operator+=(double by)
Definition: Counters.h:948
double Max() const
Definition: Counters.h:970
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:245
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:256
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:227
double Sum() const
Definition: Counters.h:962
stream & printImpl(stream &s, const std::string &tag) const
Definition: Counters.h:611
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override
Definition: Counters.h:1045
StatEntity(OWNER *o, const std::string &tag)
Definition: Counters.h:907
std::decay_t< std::result_of_t< Identity(unsigned long)> > OutputType
Definition: Counters.h:342
T sqrt(T... args)
double Min() const
Definition: Counters.h:969
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
Definition: Counters.h:1042
MsgStream & printFormatted(MsgStream &o, const std::string &format) const
Definition: Counters.h:993
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:213
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:723
StatEntity & operator-=(double by)
Definition: Counters.h:921
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:1052
void operator()(bool suppress=false) const
Definition: Counters.h:803
ContainedAccumulator< Arithmetic, atomicity::none > base_type
Definition: Counters.h:582
MsgStream & print(MsgStream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
Definition: Counters.h:1038
double RMS() const
Definition: Counters.h:967
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:749
STL class.
Efficient counter implementations for Gaudi.
Definition: Counters.h:18
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b,...
Definition: Counters.h:273
Generic Accumulator, templated by.
Definition: Counters.h:337
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...
Definition: Counters.h:882
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
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
Definition: Counters.h:198
constexpr Data(Logger const *p, unsigned long mx)
Definition: Counters.h:818
double flag() const
Definition: Counters.h:972
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
Definition: Counters.h:619
double Rms() const
Definition: Counters.h:966
MsgStream & print(MsgStream &os, bool tableFormat) const override
Definition: Counters.h:873
StatEntity operator--(int)
Definition: Counters.h:938
stream & printFormattedImpl(stream &o, const std::string &format) const
Definition: Counters.h:985