The Gaudi Framework  v32r0 (3325bb39)
Counters.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_COUNTERS_H
2 #define GAUDIKERNEL_COUNTERS_H 1
3 
129 #include "boost/algorithm/string/predicate.hpp"
130 #include "boost/format.hpp"
131 #include <atomic>
132 #include <cmath>
133 #include <initializer_list>
134 #include <iostream>
135 #include <limits>
136 #include <sstream>
137 #include <tuple>
138 #include <type_traits>
139 #include <utility>
140 
141 #include "GaudiKernel/MsgStream.h"
142 #include "GaudiKernel/detected.h"
143 
144 namespace Gaudi {
145  namespace Accumulators {
146 
148  enum class atomicity { none, full };
149 
151  template <class T>
152  auto sqrt( T d );
153 
157  template <unsigned long N>
158  struct Constant {
159  template <typename U>
160  constexpr unsigned long operator()( U&& ) const noexcept {
161  return N;
162  }
163  };
164 
168  struct Identity {
169  template <typename U>
170  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
171  return std::forward<U>( v );
172  }
173  };
174 
178  struct Square {
179  template <typename U>
180  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
181  return v * v;
182  }
183  };
184 
188  template <typename T, typename = int>
189  using has_fetch_add_ = decltype( std::atomic<T>{}.fetch_add( 0 ) );
190  template <typename T>
191  using has_fetch_add = typename Gaudi::cpp17::is_detected<has_fetch_add_, T>::value_t;
192 
196  template <typename Arithmetic, typename Result = double>
197  using fp_result_type = std::conditional_t<std::is_integral<Arithmetic>::value, Result, Arithmetic>;
198 
202  template <typename Arithmetic, atomicity Atomicity>
204 
208  template <typename Arithmetic>
209  struct BaseValueHandler<Arithmetic, atomicity::none> {
210  using OutputType = Arithmetic;
211  using InternalType = Arithmetic;
212  static constexpr OutputType getValue( const InternalType& v ) noexcept { return v; };
213  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return std::exchange( v, newv ); }
214  };
215 
219  template <typename Arithmetic>
220  struct BaseValueHandler<Arithmetic, atomicity::full> {
221  using OutputType = Arithmetic;
223  static constexpr OutputType getValue( const InternalType& v ) noexcept {
224  return v.load( std::memory_order_relaxed );
225  };
226  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
227  };
228 
233  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
234  struct Adder;
235 
239  template <typename Arithmetic>
240  struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
243  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
244  static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; };
245  };
246 
250  template <typename Arithmetic>
251  struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
254  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
255  static void merge( InternalType& a, Arithmetic b ) noexcept {
256  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
257  // C++ 17 version
258  if constexpr ( has_fetch_add<InternalType>::value ) {
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 A, typename B, atomicity C, typename D, typename E, typename F>
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  GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
350  m_value = ValueHandler::getValue( other.m_value );
351  return *this;
352  }
353  OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
354  void reset() { reset( ValueHandler::DefaultValue() ); }
355  template <atomicity ato, typename VH>
357  auto otherValue = VH::exchange( other.m_value, VH::DefaultValue() );
358  ValueHandler::merge( m_value, otherValue );
359  }
360 
361  protected:
362  void reset( InnerType in ) { m_value = std::move( in ); }
363 
364  private:
365  typename ValueHandler::InternalType m_value;
366  };
367 
373  template <typename Arithmetic, atomicity Atomicity, template <typename, atomicity> class... Bases>
374  class AccumulatorSet : public Bases<Arithmetic, Atomicity>... {
375  public:
376  using InputType = Arithmetic;
378  constexpr AccumulatorSet() = default;
380  (void)std::initializer_list<int>{( Bases<Arithmetic, Atomicity>::operator+=( by ), 0 )...};
381  return *this;
382  }
383  OutputType value() const { return std::make_tuple( Bases<Arithmetic, Atomicity>::value()... ); }
384  void reset() { (void)std::initializer_list<int>{( Bases<Arithmetic, Atomicity>::reset(), 0 )...}; }
385  template <atomicity Ato>
388  ( Bases<Arithmetic, Atomicity>::mergeAndReset( static_cast<Bases<Arithmetic, Ato>&&>( other ) ), 0 )...};
389  }
390 
391  protected:
392  void reset( const std::tuple<typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
393  std::apply(
394  [this]( const auto&... i ) {
395  (void)std::initializer_list<int>{( this->Bases<Arithmetic, Atomicity>::reset( i ), 0 )...};
396  },
397  t );
398  }
399  };
400 
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(); }
409  };
410 
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(); }
419  };
420 
425  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
426  struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<1>> {
427  unsigned long nEntries() const { return this->value(); }
428  };
429 
434  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
435  struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
436  Arithmetic sum() const { return this->value(); }
437  };
438 
443  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
444  struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
445  Arithmetic sum2() const { return this->value(); };
446  };
447 
449  struct TrueTo1 {
450  unsigned int operator()( bool v ) const { return v; }
451  };
452 
458  template <typename Arithmetic, atomicity Atomicity>
459  struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
460  unsigned long nTrueEntries() const { return this->value(); };
461  };
462 
464  struct FalseTo1 {
465  unsigned int operator()( bool v ) const { return !v; }
466  };
467 
473  template <typename Arithmetic, atomicity Atomicity>
474  struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
475  unsigned long nFalseEntries() const { return this->value(); };
476  };
477 
483  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
484  struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, TrueAccumulator, FalseAccumulator> {
485  unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); };
486 
487  template <typename Result = fp_result_type<Arithmetic>>
488  auto efficiency() const {
489  auto nbEntries = nEntries();
490  if ( 1 > nbEntries ) return Result{-1};
491  return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
492  }
493  auto eff() const { return efficiency(); }
494 
495  template <typename Result = fp_result_type<Arithmetic>>
496  auto efficiencyErr() const {
497  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
498  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
500  using std::sqrt;
501  auto nbEntries = nEntries();
502  if ( 1 > nbEntries ) return Result{-1};
503  return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
504  }
505  auto effErr() const { return efficiencyErr(); }
506  };
507 
512  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
513  struct AveragingAccumulator : AccumulatorSet<Arithmetic, Atomicity, CountAccumulator, SumAccumulator> {
514 
515  template <typename Result = fp_result_type<Arithmetic>>
516  auto mean() const {
517  auto n = this->nEntries();
518  Result sum = this->sum();
519  return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
520  }
521  };
522 
527  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
528  struct SigmaAccumulator : AccumulatorSet<Arithmetic, Atomicity, AveragingAccumulator, SquareAccumulator> {
529 
530  template <typename Result = fp_result_type<Arithmetic>>
531  auto biased_sample_variance() const {
532  auto n = this->nEntries();
533  Result sum = this->sum();
534  return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
535  }
536 
537  template <typename Result = fp_result_type<Arithmetic>>
539  auto n = this->nEntries();
540  Result sum = this->sum();
541  return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
542  }
543 
544  template <typename Result = fp_result_type<Arithmetic>>
545  auto standard_deviation() const {
546  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
547  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
549  using std::sqrt;
550  Result v = biased_sample_variance();
551  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
552  }
553  [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
554  return standard_deviation();
555  }
556 
557  template <typename Result = fp_result_type<Arithmetic>>
558  auto meanErr() const {
559  auto n = this->nEntries();
560  if ( 0 == n ) return Result{};
561  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
562  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
564  using std::sqrt;
565  Result v = biased_sample_variance();
566  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
567  }
568  };
569 
574  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
576 
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>;
587 
588  public:
589  Buffer() = delete;
590  Buffer( prime_type& p ) : base_type(), m_prime( p ) {}
591  Buffer( const Buffer& ) = delete;
592  void operator=( const Buffer& ) = delete;
593  Buffer( Buffer&& other ) : base_type( other ), m_prime( other.m_prime ) { other.reset(); }
594  void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *this ) ); }
595  ~Buffer() { push(); }
596 
597  private:
599  };
600 
606  PrintableCounter() = default;
607  template <class OWNER>
608  PrintableCounter( OWNER* o, const std::string& tag ) {
609  o->declareCounter( tag, *this );
610  }
612  virtual ~PrintableCounter() = default;
613  // add tag to printout
614  template <typename stream>
615  stream& printImpl( stream& s, const std::string& tag ) const {
616  s << boost::format{" | %|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
617  return print( s, true );
618  }
620  virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
621  virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
623  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const { return printImpl( o, tag ); }
624  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const { return printImpl( o, tag ); }
627  virtual bool toBePrinted() const { return true; }
630  std::ostringstream ost;
631  print( ost );
632  return ost.str();
633  }
634  };
635 
639  inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
640  inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
646  template <typename Arithmetic, atomicity Atomicity, template <typename Int, atomicity Ato> class Accumulator>
649  Buffer<Arithmetic, Accumulator> buffer() { return {*static_cast<Accumulator<Arithmetic, Atomicity>*>( this )}; }
650  };
651 
656  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
657  struct Counter : BufferableCounter<Arithmetic, Atomicity, Counter>, CountAccumulator<Arithmetic, Atomicity> {
660  ( *this ) += Arithmetic{};
661  return *this;
662  }
664  auto copy = *this;
665  ++( *this );
666  return copy;
667  }
669 
670  template <typename stream>
671  stream& printImpl( stream& o, bool tableFormat ) const {
672  // Avoid printing empty counters in non DEBUG mode
673  auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
674  o << boost::format{fmt} % this->nEntries();
675  return o;
676  }
677 
678  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
679  return printImpl( o, tableFormat );
680  }
681  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
682  virtual bool toBePrinted() const override {
683  return this->nEntries() > 0;
684  ;
685  }
686  };
687 
692  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
693  struct AveragingCounter : BufferableCounter<Arithmetic, Atomicity, AveragingCounter>,
694  AveragingAccumulator<Arithmetic, Atomicity> {
697 
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|" );
701  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean();
702  }
703 
704  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
705  return printImpl( o, tableFormat );
706  }
707  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
708 
709  virtual bool toBePrinted() const override {
710  return this->nEntries() > 0;
711  ;
712  }
713  };
714  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
716 
721  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
722  struct SigmaCounter : BufferableCounter<Arithmetic, Atomicity, SigmaCounter>,
723  SigmaAccumulator<Arithmetic, Atomicity> {
726 
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|" );
731  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
732  }
733 
734  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
735  return printImpl( o, tableFormat );
736  }
737  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
738  virtual bool toBePrinted() const override {
739  return this->nEntries() > 0;
740  ;
741  }
742  };
743 
748  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
749  struct StatCounter : BufferableCounter<Arithmetic, Atomicity, StatCounter>, StatAccumulator<Arithmetic, Atomicity> {
752 
753  template <typename stream>
754  stream& printImpl( stream& o, bool tableFormat ) const {
755  auto fmt =
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|" );
758  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
759  this->min() % this->max();
760  }
761 
762  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
763  return printImpl( o, tableFormat );
764  }
765  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
766  virtual bool toBePrinted() const override { return this->nEntries() > 0; }
767  };
768 
773  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
774  struct BinomialCounter : BufferableCounter<Arithmetic, Atomicity, BinomialCounter>,
775  BinomialAccumulator<Arithmetic, Atomicity> {
777 
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 );
784  }
785 
786  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
787  return printImpl( o, tableFormat );
788  }
789  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
790 
791  template <typename stream>
792  stream& printImpl( stream& o, const std::string& tag ) const {
793  // override default print to add a '*' in from of the name
794  o << boost::format{" |*%|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
795  return print( o, true );
796  }
798  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const override {
799  return printImpl( o, tag );
800  }
801  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const override { return printImpl( o, tag ); }
802  virtual bool toBePrinted() const override { return this->nEntries() > 0; }
803  };
804 
810  template <typename Counter, typename Container, typename Fun>
811  void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
812  auto b = counter.buffer();
813  for ( const auto& elem : container ) b += f( elem );
814  }
815 
816  } // namespace Accumulators
817 
818 } // namespace Gaudi
819 
825  public Gaudi::Accumulators::AccumulatorSet<double, Gaudi::Accumulators::atomicity::full,
826  Gaudi::Accumulators::StatAccumulator,
827  Gaudi::Accumulators::BinomialAccumulator> {
828 public:
834  using AccParent::reset;
836  StatEntity() = default;
837  template <class OWNER>
838  StatEntity( OWNER* o, const std::string& tag ) {
839  o->declareCounter( tag, *this );
840  }
841  StatEntity( const unsigned long entries, const double flag, const double flag2, const double minFlag,
842  const double maxFlag ) {
843  reset( std::make_tuple(
844  std::make_tuple( std::make_tuple( std::make_tuple( entries, flag ), flag2 ), minFlag, maxFlag ),
845  std::make_tuple( 0, 0 ) ) );
846  }
847  void reset() { AccParent::reset(); }
848  void operator=( double by ) {
849  this->reset();
850  ( *this ) += by;
851  }
852  StatEntity& operator-=( double by ) {
853  ( *this ) += ( -by );
854  return *this;
855  }
857  ( *this ) += 1.0;
858  return *this;
859  }
861  auto copy = *this;
862  ++( *this );
863  return copy;
864  }
866  ( *this ) += -1.0;
867  return *this;
868  }
870  auto copy = *this;
871  --( *this );
872  return copy;
873  }
874  bool operator<( const StatEntity& se ) const {
875  return std::make_tuple( nEntries(), sum(), min(), max(), sum2() ) <
876  std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
877  };
878  // using AccumulatorSet::operator+=;
879  StatEntity& operator+=( double by ) {
880  this->AccumulatorSet::operator+=( by );
881  return *this;
882  }
884  mergeAndReset( std::move( by ) );
885  return *this;
886  }
887  unsigned long add( const double v ) {
888  *this += v;
889  return nEntries();
890  }
891  unsigned long addFlag( const double v ) { return add( v ); }
892  // aliases (a'la ROOT)
893  double Sum() const { return sum(); } // get sum
894  double Mean() const { return mean(); } // get mean
895  double MeanErr() const { return meanErr(); } // get error in mean
896  double rms() const { return standard_deviation(); } // get rms
897  double Rms() const { return standard_deviation(); } // get rms
898  double RMS() const { return standard_deviation(); } // get rms
899  double Eff() const { return eff(); } // get efficiency
900  double Min() const { return min(); } // get minimal value
901  double Max() const { return max(); } // get maximal value
902  // some legacy methods, to be removed ...
903  double flag() const { return sum(); }
904  double flag2() const { return sum2(); }
905  double flagMean() const { return mean(); }
906  double flagRMS() const { return standard_deviation(); }
907  double flagMeanErr() const { return meanErr(); }
908  double flagMin() const { return min(); }
909  double flagMax() const { return max(); }
910  static bool effCounter( const std::string& name ) {
911  using boost::algorithm::icontains;
912  return icontains( name, "eff" ) || icontains( name, "acc" ) || icontains( name, "filt" ) ||
913  icontains( name, "fltr" ) || icontains( name, "pass" );
914  }
915  template <typename stream>
916  stream& printFormattedImpl( stream& o, const std::string& format ) const {
917  boost::format fmt{format};
918  fmt % nEntries() % sum() % mean() % standard_deviation() % min() % max();
919  return o << fmt.str();
920  }
922  return printFormattedImpl( o, format );
923  }
924  MsgStream& printFormatted( MsgStream& o, const std::string& format ) const { return printFormattedImpl( o, format ); }
926  template <typename stream>
927  stream& printImpl( stream& o, bool tableFormat, const std::string& name, bool flag,
928  std::string const& fmtHead ) const {
929  if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() && sum() <= nEntries() &&
930  ( 0 == min() || 1 == min() ) && ( 0 == max() || 1 == max() ) ) {
931  // efficiency printing
932  if ( tableFormat ) {
933  if ( name.empty() ) {
934  constexpr auto fmt = "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
935  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
936  ( efficiencyErr() * 100 );
937  } else {
938  auto fmt = " |*" + fmtHead + "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
939  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % BinomialAccParent::nEntries() % sum() %
940  ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
941  }
942  } else {
943  constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
944  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
945  ( efficiencyErr() * 100 );
946  }
947  } else {
948  // Standard printing
949  if ( tableFormat ) {
950  if ( name.empty() ) {
951  constexpr auto fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
952  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
953 
954  } else {
955  auto fmt = " | " + fmtHead + "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
956  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % nEntries() % sum() % mean() % standard_deviation() %
957  min() % max();
958  }
959  } else {
960  constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
961  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
962  }
963  }
964  }
965  std::ostream& print( std::ostream& o, bool tableFormat, const std::string& name, bool flag = true,
966  std::string fmtHead = "%|-48.48s|%|27t|" ) const {
967  return printImpl( o, tableFormat, name, flag, fmtHead );
968  }
969  MsgStream& print( MsgStream& o, bool tableFormat, const std::string& name, bool flag = true,
970  std::string fmtHead = "%|-48.48s|%|27t|" ) const {
971  return printImpl( o, tableFormat, name, flag, fmtHead );
972  }
973  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const override {
974  return print( o, true, tag, true );
975  }
976  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const override {
977  return print( o, true, tag, true );
978  }
979  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
980  std::string emptyName;
981  return print( o, tableFormat, emptyName, true );
982  }
983  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override {
984  std::string emptyName;
985  return print( o, tableFormat, emptyName, true );
986  }
988  std::ostringstream ost;
989  print( ost );
990  return ost.str();
991  }
992  std::ostream& fillStream( std::ostream& o ) const { return print( o ); }
993  MsgStream& fillStream( MsgStream& o ) const { return print( o ); }
994 };
995 
996 #endif // GAUDIKERNEL_COUNTERS_H
constexpr unsigned long operator()(U &&) const noexcept
Definition: Counters.h:160
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
Definition: Counters.h:585
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:973
std::string toString() const
Definition: Counters.h:987
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
stream & printImpl(stream &o, const std::string &tag) const
Definition: Counters.h:792
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:296
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
Definition: Counters.h:386
T empty(T...args)
double Min() const
Definition: Counters.h:900
Buffer(prime_type &p)
Definition: Counters.h:590
unsigned long nEntries() const
Definition: Counters.h:427
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:109
double Mean() const
Definition: Counters.h:894
double flagRMS() const
Definition: Counters.h:906
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
Definition: Counters.h:762
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:189
std::ostream & fillStream(std::ostream &o) const
Definition: Counters.h:992
unsigned long nEntries() const
Definition: Counters.h:485
unsigned long nFalseEntries() const
Definition: Counters.h:475
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:786
An empty ancester of all counters that provides a buffer method that returns a buffer on itself...
Definition: Counters.h:647
unsigned long nTrueEntries() const
Definition: Counters.h:460
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:766
double flagMin() const
Definition: Counters.h:908
atomicity
Defines atomicity of the accumulators.
Definition: Counters.h:148
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:749
typename Gaudi::cpp17::is_detected< has_fetch_add_, T >::value_t has_fetch_add
Definition: Counters.h:191
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
Definition: Counters.h:832
An Adder ValueHandler operator(a, b) means a += b.
Definition: Counters.h:234
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
Definition: Counters.h:831
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:202
A counter aiming at computing sum and average.
Definition: Counters.h:693
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
Definition: Counters.h:623
T make_tuple(T...args)
An functor always returning the value N.
Definition: Counters.h:158
void reset()
Definition: Counters.h:847
An empty ancester of all counters that knows how to print themselves.
Definition: Counters.h:605
double flagMeanErr() const
Definition: Counters.h:907
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
Definition: Counters.h:921
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:802
stream & printImpl(stream &o, bool tableFormat, const std::string &name, bool flag, std::string const &fmtHead) const
Definition: Counters.h:927
bool operator<(const StatEntity &se) const
Definition: Counters.h:874
StatEntity operator++(int)
Definition: Counters.h:860
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:215
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:738
std::decay_t< std::result_of_t< Identity(unsigned long)>> OutputType
Definition: Counters.h:342
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:682
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:223
double Max() const
Definition: Counters.h:901
double flagMax() const
Definition: Counters.h:909
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:681
PropertyMgr & operator=(const PropertyMgr &)=delete
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:979
STL class.
MsgStream & fillStream(MsgStream &o) const
Definition: Counters.h:993
StatEntity & operator++()
Definition: Counters.h:856
int N
Definition: IOTest.py:99
PrintableCounter(OWNER *o, const std::string &tag)
Definition: Counters.h:608
GenericAccumulator operator+=(const InputType by)
Definition: Counters.h:343
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:811
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 ...
Definition: Counters.h:197
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Definition: Counters.h:627
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:213
double MeanErr() const
Definition: Counters.h:895
double flagMean() const
Definition: Counters.h:905
double Eff() const
Definition: Counters.h:899
unsigned int operator()(bool v) const
Definition: Counters.h:450
AccumulatorSet & operator+=(const InputType by)
Definition: Counters.h:379
StatEntity & operator-=(double by)
Definition: Counters.h:852
StatEntity(OWNER *o, const std::string &tag)
Definition: Counters.h:838
A Square functor.
Definition: Counters.h:178
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Definition: Counters.h:584
Buffer< Arithmetic, Accumulator > buffer()
Definition: Counters.h:649
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:798
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:965
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:983
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override
Definition: Counters.h:976
double Sum() const
Definition: Counters.h:893
GenericAccumulator & operator=(const GenericAccumulator &other)
Definition: Counters.h:349
std::string toString() const
get a string representation
Definition: Counters.h:629
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:722
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Definition: Counters.h:356
T move(T...args)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:734
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:789
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
Definition: Counters.h:374
stream & printFormattedImpl(stream &o, const std::string &format) const
Definition: Counters.h:916
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:709
StatEntity & operator+=(StatEntity by)
Definition: Counters.h:883
Buffer(Buffer &&other)
Definition: Counters.h:593
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition: Counters.h:28
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:754
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:779
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
Definition: Counters.h:575
stream & printImpl(stream &s, const std::string &tag) const
Definition: Counters.h:615
StatEntity & operator--()
Definition: Counters.h:865
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:765
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
Definition: Counters.h:392
A counter dealing with binomial data.
Definition: Counters.h:774
T fetch_add(T...args)
static bool effCounter(const std::string &name)
Definition: Counters.h:910
MsgStream & printFormatted(MsgStream &o, const std::string &format) const
Definition: Counters.h:924
ValueHandler::InternalType m_value
Definition: Counters.h:365
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:728
helper functor for the TrueAccumulator
Definition: Counters.h:449
helper functor for the FalseAccumulator
Definition: Counters.h:464
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:671
An Identity functor.
Definition: Counters.h:168
unsigned long addFlag(const double v)
Definition: Counters.h:891
Base type for all functors used as ValuesHandler.
Definition: Counters.h:203
class MergingTransformer< Out(const vector_of_const_< In > void
GenericAccumulator(const GenericAccumulator &other)
Definition: Counters.h:348
string s
Definition: gaudirun.py:316
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:704
A basic counter counting input values.
Definition: Counters.h:657
MsgStream & print(MsgStream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
Definition: Counters.h:969
stream & printImpl(stream &o, bool tableFormat) const
Definition: Counters.h:699
std::ostream & operator<<(std::ostream &s, const PrintableCounter &counter)
external printout operator to a stream type
Definition: Counters.h:639
double Rms() const
Definition: Counters.h:897
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:244
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:255
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:226
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:707
T sqrt(T...args)
double RMS() const
Definition: Counters.h:898
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
Definition: Counters.h:841
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:212
double rms() const
Definition: Counters.h:896
backward compatible StatEntity class.
Definition: Counters.h:824
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Counters.h:737
StatEntity operator--(int)
Definition: Counters.h:869
double flag2() const
Definition: Counters.h:904
StatEntity & operator+=(double by)
Definition: Counters.h:879
ContainedAccumulator< Arithmetic, atomicity::none > base_type
Definition: Counters.h:586
STL class.
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b...
Definition: Counters.h:273
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:678
unsigned int operator()(bool v) const
Definition: Counters.h:465
Generic Accumulator, templated by.
Definition: Counters.h:337
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
void operator=(double by)
Definition: Counters.h:848
double flag() const
Definition: Counters.h:903
virtual MsgStream & print(MsgStream &o, const std::string &tag) const
Definition: Counters.h:624
unsigned long add(const double v)
Definition: Counters.h:887
virtual MsgStream & print(MsgStream &o, const std::string &tag) const override
Definition: Counters.h:801