The Gaudi Framework  v30r4 (9b837755)
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/apply.h"
142 #include "GaudiKernel/detected.h"
143 
144 namespace Gaudi
145 {
146  namespace Accumulators
147  {
148 
150  enum class atomicity { none, full };
151 
155  template <unsigned long N>
156  struct Constant {
157  template <typename U>
158  constexpr unsigned long operator()( U&& ) const noexcept
159  {
160  return N;
161  }
162  };
163 
167  struct Identity {
168  template <typename U>
169  constexpr decltype( auto ) operator()( U&& v ) const noexcept
170  {
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  {
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  using has_fetch_add = typename Gaudi::cpp17::is_detected<has_fetch_add_, T>::value_t;
193 
197  template <typename Arithmetic, typename Result = double>
198  using fp_result_type = std::conditional_t<std::is_integral<Arithmetic>::value, 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  {
226  return v.load( std::memory_order_relaxed );
227  };
228  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
229  };
230 
235  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
236  struct Adder;
237 
241  template <typename Arithmetic>
242  struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
245  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
246  static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; };
247  };
248 
252  template <typename Arithmetic>
253  struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
256  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
257 #if __cplusplus > 201402L
258  static void merge( InternalType& a, Arithmetic b ) noexcept
259  {
260  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
261  // C++ 17 version
262  if
263  constexpr( has_fetch_add<InternalType>::value ) { a.fetch_add( b, std::memory_order_relaxed ); }
264  else {
266  while ( !a.compare_exchange_weak( current, current + b ) )
267  ;
268  }
269  };
270 #else
271  // C++11 version
272  private:
273  template <typename T>
274  static void add( InternalType& a, T b, std::false_type )
275  {
276  auto current = a.load( std::memory_order_relaxed );
277  while ( !a.compare_exchange_weak( current, current + b ) )
278  ;
279  }
280  template <typename T>
281  static void add( InternalType& a, T b, std::true_type )
282  {
283  a.fetch_add( b, std::memory_order_relaxed );
284  }
285 
286  public:
287  static void merge( InternalType& a, Arithmetic b ) noexcept
288  {
289  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
290  add( a, b, has_fetch_add<InternalType>{} );
291  }
292 #endif
293  };
294 
299  template <typename Arithmetic, atomicity Atomicity, typename Compare, Arithmetic ( *Initial )()>
300  struct Extremum;
301 
305  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
306  struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
309  static constexpr OutputType DefaultValue() { return Initial(); }
310  static void merge( InternalType& a, Arithmetic b ) noexcept
311  {
312  if ( Compare{}( b, a ) ) a = b;
313  };
314  };
315 
319  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
320  struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
323  static constexpr OutputType DefaultValue() { return Initial(); }
324  static void merge( InternalType& a, Arithmetic b ) noexcept
325  {
326  Arithmetic prev_value = BaseValueHandler<Arithmetic, atomicity::full>::getValue( a );
327  while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
328  ;
329  };
330  };
331 
336  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
338 
343  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
345 
363  template <typename InputType, typename InnerType, atomicity Atomicity = atomicity::full,
364  typename InputTransform = Identity, typename OutputTransform = Identity,
365  typename ValueHandler = Adder<InnerType, Atomicity>>
367  {
368  template <typename A, typename B, atomicity C, typename D, typename E, typename F>
369  friend class GenericAccumulator;
370 
371  public:
372  using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
373  GenericAccumulator operator+=( const InputType by )
374  {
375  ValueHandler::merge( m_value, InputTransform{}( by ) );
376  return *this;
377  }
378  GenericAccumulator() : m_value( ValueHandler::DefaultValue() ) {}
379  GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
381  {
382  m_value = ValueHandler::getValue( other.m_value );
383  return *this;
384  }
385  OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
386  void reset() { reset( ValueHandler::DefaultValue() ); }
387  template <atomicity ato, typename VH>
389  {
390  auto otherValue = VH::exchange( other.m_value, VH::DefaultValue() );
391  ValueHandler::merge( m_value, otherValue );
392  }
393 
394  protected:
395  void reset( InnerType in ) { m_value = std::move( in ); }
396 
397  private:
398  typename ValueHandler::InternalType m_value;
399  };
400 
406  template <typename Arithmetic, atomicity Atomicity, template <typename, atomicity> class... Bases>
407  class AccumulatorSet : public Bases<Arithmetic, Atomicity>...
408  {
409  public:
410  using InputType = Arithmetic;
412  constexpr AccumulatorSet() = default;
414  {
415  (void)std::initializer_list<int>{( Bases<Arithmetic, Atomicity>::operator+=( by ), 0 )...};
416  return *this;
417  }
418  OutputType value() const { return std::make_tuple( Bases<Arithmetic, Atomicity>::value()... ); }
419  void reset() { (void)std::initializer_list<int>{( Bases<Arithmetic, Atomicity>::reset(), 0 )...}; }
420  template <atomicity Ato>
422  {
424  ( Bases<Arithmetic, Atomicity>::mergeAndReset( static_cast<Bases<Arithmetic, Ato>&&>( other ) ), 0 )...};
425  }
426 
427  protected:
428  void reset( const std::tuple<typename Bases<Arithmetic, Atomicity>::OutputType...>& t )
429  {
430  Gaudi::apply(
431  [this]( const auto&... i ) {
432  (void)std::initializer_list<int>{( this->Bases<Arithmetic, Atomicity>::reset( i ), 0 )...};
433  },
434  t );
435  }
436  };
437 
442  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
444  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
445  Arithmetic max() const { return this->value(); }
446  };
447 
452  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
454  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
455  Arithmetic min() const { return this->value(); }
456  };
457 
462  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
463  struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<1>> {
464  unsigned long nEntries() const { return this->value(); }
465  };
466 
471  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
472  struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
473  Arithmetic sum() const { return this->value(); }
474  };
475 
480  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
481  struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
482  Arithmetic sum2() const { return this->value(); };
483  };
484 
486  struct TrueTo1 {
487  unsigned int operator()( bool v ) const { return v; }
488  };
489 
495  template <typename Arithmetic, atomicity Atomicity>
496  struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
497  unsigned long nTrueEntries() const { return this->value(); };
498  };
499 
501  struct FalseTo1 {
502  unsigned int operator()( bool v ) const { return !v; }
503  };
504 
510  template <typename Arithmetic, atomicity Atomicity>
511  struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
512  unsigned long nFalseEntries() const { return this->value(); };
513  };
514 
520  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
521  struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, TrueAccumulator, FalseAccumulator> {
522  unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); };
523 
524  template <typename Result = fp_result_type<Arithmetic>>
525  auto efficiency() const
526  {
527  auto nbEntries = nEntries();
528  if ( 1 > nbEntries ) return Result{-1};
529  return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
530  }
531  auto eff() const { return efficiency(); }
532 
533  template <typename Result = fp_result_type<Arithmetic>>
534  auto efficiencyErr() const
535  {
536  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
537  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
538  using std::sqrt;
539  auto nbEntries = nEntries();
540  if ( 1 > nbEntries ) return Result{-1};
541  return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
542  }
543  auto effErr() const { return efficiencyErr(); }
544  };
545 
550  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
551  struct AveragingAccumulator : AccumulatorSet<Arithmetic, Atomicity, CountAccumulator, SumAccumulator> {
552 
553  template <typename Result = fp_result_type<Arithmetic>>
554  auto mean() const
555  {
556  auto n = this->nEntries();
557  return ( n > 0 ) ? static_cast<Result>( this->sum() ) / n : Result{};
558  }
559  };
560 
565  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
566  struct SigmaAccumulator : AccumulatorSet<Arithmetic, Atomicity, AveragingAccumulator, SquareAccumulator> {
567 
568  template <typename Result = fp_result_type<Arithmetic>>
570  {
571  auto n = this->nEntries();
572  Result sum = this->sum();
573  return ( n > 0 ) ? ( this->sum2() - sum * ( sum / n ) ) / n : Result{};
574  }
575 
576  template <typename Result = fp_result_type<Arithmetic>>
578  {
579  auto n = this->nEntries();
580  Result sum = this->sum();
581  return ( n > 1 ) ? ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) : Result{};
582  }
583 
584  template <typename Result = fp_result_type<Arithmetic>>
585  auto standard_deviation() const
586  {
587  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
588  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
589  using std::sqrt;
590  Result v = biased_sample_variance();
591  return ( 0 > v ) ? Result{} : sqrt( v );
592  }
593  [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const
594  {
595  return standard_deviation();
596  }
597 
598  template <typename Result = fp_result_type<Arithmetic>>
599  auto meanErr() const
600  {
601  auto n = this->nEntries();
602  if ( 0 == n ) return Result{};
603  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
604  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
605  using std::sqrt;
606  Result v = biased_sample_variance();
607  return ( 0 > v ) ? Result{} : sqrt( v / n );
608  }
609  };
610 
615  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
617 
624  template <typename Arithmetic, template <typename Int, atomicity Ato> class ContainedAccumulator>
625  class Buffer : public ContainedAccumulator<Arithmetic, atomicity::none>
626  {
627  using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
628  using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
629 
630  public:
631  Buffer() = delete;
632  Buffer( prime_type& p ) : base_type(), m_prime( p ) {}
633  Buffer( const Buffer& ) = delete;
634  void operator=( const Buffer& ) = delete;
635  Buffer( Buffer&& other ) : base_type( other ), m_prime( other.m_prime ) { other.reset(); }
636  void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *this ) ); }
637  ~Buffer() { push(); }
638 
639  private:
641  };
642 
648  PrintableCounter() = default;
649  template <class OWNER>
650  PrintableCounter( OWNER* o, const std::string& tag )
651  {
652  o->registerCounter( tag, *this );
653  }
655  virtual ~PrintableCounter() = default;
657  virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
659  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const
660  {
661  o << boost::format{" | %|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
662  return print( o, true );
663  }
666  virtual bool toBePrinted() const { return true; }
669  {
670  std::ostringstream ost;
671  print( ost );
672  return ost.str();
673  }
674  };
675 
680  {
681  return counter.print( stream );
682  }
683 
689  template <typename Arithmetic, atomicity Atomicity, template <typename Int, atomicity Ato> class Accumulator>
692  Buffer<Arithmetic, Accumulator> buffer() { return {*static_cast<Accumulator<Arithmetic, Atomicity>*>( this )}; }
693  };
694 
699  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
700  struct Counter : BufferableCounter<Arithmetic, Atomicity, Counter>, CountAccumulator<Arithmetic, Atomicity> {
703  {
704  ( *this ) += Arithmetic{};
705  return *this;
706  }
708  {
709  auto copy = *this;
710  ++( *this );
711  return copy;
712  }
714  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
715  {
716  // Avoid printing empty counters in non DEBUG mode
717  std::string fmt( "#=%|-7lu|" );
718  if ( tableFormat ) {
719  fmt = "|%|10d| |";
720  }
721  o << boost::format{fmt} % this->nEntries();
722  return o;
723  }
724  virtual bool toBePrinted() const override
725  {
726  return this->nEntries() > 0;
727  ;
728  }
729  };
730 
735  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
736  struct AveragingCounter : BufferableCounter<Arithmetic, Atomicity, AveragingCounter>,
737  AveragingAccumulator<Arithmetic, Atomicity> {
740  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
741  {
742  std::string fmt;
743  if ( tableFormat ) {
744  fmt = "|%|10d| |%|11.7g| |%|#11.5g| |";
745  } else {
746  fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|";
747  }
748  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean();
749  }
750  virtual bool toBePrinted() const override
751  {
752  return this->nEntries() > 0;
753  ;
754  }
755  };
756  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
758 
763  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
764  struct SigmaCounter : BufferableCounter<Arithmetic, Atomicity, SigmaCounter>,
765  SigmaAccumulator<Arithmetic, Atomicity> {
768  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
769  {
770  std::string fmt;
771  if ( tableFormat ) {
772  fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |";
773  } else {
774  fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|";
775  }
776  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
777  }
778  virtual bool toBePrinted() const override
779  {
780  return this->nEntries() > 0;
781  ;
782  }
783  };
784 
789  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
790  struct StatCounter : BufferableCounter<Arithmetic, Atomicity, StatCounter>, StatAccumulator<Arithmetic, Atomicity> {
793  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
794  {
795  std::string fmt;
796  if ( tableFormat ) {
797  fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
798  } else {
799  fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
800  }
801  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
802  this->min() % this->max();
803  }
804  virtual bool toBePrinted() const override { return this->nEntries() > 0; }
805  };
806 
811  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
812  struct BinomialCounter : BufferableCounter<Arithmetic, Atomicity, BinomialCounter>,
813  BinomialAccumulator<Arithmetic, Atomicity> {
815  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
816  {
817  std::string fmt;
818  if ( tableFormat ) {
819  fmt = "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |";
820  } else {
821  fmt = "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
822  }
823  return o << boost::format{fmt} % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
824  ( this->efficiencyErr() * 100 );
825  }
827  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const override
828  {
829  // override default print to add a '*' in from of the name
830  o << boost::format{" |*%|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
831  return print( o, true );
832  }
833  };
834 
840  template <typename Counter, typename Container, typename Fun>
841  void accumulate( Counter& counter, const Container& container, Fun f = Identity{} )
842  {
843  auto b = counter.buffer();
844  for ( const auto& elem : container ) b += f( elem );
845  }
846 
847  } // namespace Accumulators
848 
849 } // namespace Gaudi
850 
856  public Gaudi::Accumulators::AccumulatorSet<double, Gaudi::Accumulators::atomicity::full,
857  Gaudi::Accumulators::StatAccumulator,
858  Gaudi::Accumulators::BinomialAccumulator>
859 {
860 public:
866  using AccParent::reset;
868  StatEntity() = default;
869  template <class OWNER>
870  StatEntity( OWNER* o, const std::string& tag )
871  {
872  o->registerCounter( tag, *this );
873  }
874  StatEntity( const unsigned long entries, const double flag, const double flag2, const double minFlag,
875  const double maxFlag )
876  {
877  reset( std::make_tuple(
878  std::make_tuple( std::make_tuple( std::make_tuple( entries, flag ), flag2 ), minFlag, maxFlag ),
879  std::make_tuple( 0, 0 ) ) );
880  }
881  void reset() { AccParent::reset(); }
882  void operator=( double by )
883  {
884  this->reset();
885  ( *this ) += by;
886  }
887  StatEntity& operator-=( double by )
888  {
889  ( *this ) += ( -by );
890  return *this;
891  }
893  {
894  ( *this ) += 1.0;
895  return *this;
896  }
898  {
899  auto copy = *this;
900  ++( *this );
901  return copy;
902  }
904  {
905  ( *this ) += -1.0;
906  return *this;
907  }
909  {
910  auto copy = *this;
911  --( *this );
912  return copy;
913  }
914  bool operator<( const StatEntity& se ) const
915  {
916  return std::make_tuple( nEntries(), sum(), min(), max(), sum2() ) <
917  std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
918  };
919  // using AccumulatorSet::operator+=;
920  StatEntity& operator+=( double by )
921  {
922  this->AccumulatorSet::operator+=( by );
923  return *this;
924  }
926  {
927  mergeAndReset( std::move( by ) );
928  return *this;
929  }
930  unsigned long add( const double v )
931  {
932  *this += v;
933  return nEntries();
934  }
935  unsigned long addFlag( const double v ) { return add( v ); }
936  // aliases (a'la ROOT)
937  double Sum() const { return sum(); } // get sum
938  double Mean() const { return mean(); } // get mean
939  double MeanErr() const { return meanErr(); } // get error in mean
940  double rms() const { return standard_deviation(); } // get rms
941  double Rms() const { return standard_deviation(); } // get rms
942  double RMS() const { return standard_deviation(); } // get rms
943  double Eff() const { return eff(); } // get efficiency
944  double Min() const { return min(); } // get minimal value
945  double Max() const { return max(); } // get maximal value
946  // some legacy methods, to be removed ...
947  double flag() const { return sum(); }
948  double flag2() const { return sum2(); }
949  double flagMean() const { return mean(); }
950  double flagRMS() const { return standard_deviation(); }
951  double flagMeanErr() const { return meanErr(); }
952  double flagMin() const { return min(); }
953  double flagMax() const { return max(); }
954  static bool effCounter( const std::string& name )
955  {
956  using boost::algorithm::icontains;
957  return icontains( name, "eff" ) || icontains( name, "acc" ) || icontains( name, "filt" ) ||
958  icontains( name, "fltr" ) || icontains( name, "pass" );
959  }
961  {
962  boost::format fmt{format};
963  fmt % nEntries() % sum() % mean() % standard_deviation() % min() % max();
964  return o << fmt.str();
965  }
967  std::ostream& print( std::ostream& o, bool tableFormat, const std::string& name, bool flag = true,
968  std::string fmtHead = "%|-48.48s|%|27t|" ) const
969  {
970  if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() && sum() <= nEntries() &&
971  ( 0 == min() || 1 == min() ) && ( 0 == max() || 1 == max() ) ) {
972  // efficiency printing
973  std::string fmt;
974  if ( tableFormat ) {
975  if ( name.empty() ) {
976  fmt = "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
977  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
978  ( efficiencyErr() * 100 );
979  } else {
980  fmt = " |*" + fmtHead + "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
981  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % BinomialAccParent::nEntries() % sum() %
982  ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
983  }
984  } else {
985  fmt = "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
986  return o << boost::format{fmt} % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
987  ( efficiencyErr() * 100 );
988  }
989  } else {
990  // Standard printing
991  std::string fmt;
992  if ( tableFormat ) {
993  if ( name.empty() ) {
994  fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
995  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
996 
997  } else {
998  fmt = " | " + fmtHead + "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
999  return o << boost::format{fmt} % ( "\"" + name + "\"" ) % nEntries() % sum() % mean() % standard_deviation() %
1000  min() % max();
1001  }
1002  } else {
1003  fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
1004  return o << boost::format{fmt} % nEntries() % sum() % mean() % standard_deviation() % min() % max();
1005  }
1006  }
1007  }
1008  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const override
1009  {
1010  return print( o, true, tag, true );
1011  }
1012  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override
1013  {
1014  std::string emptyName;
1015  return print( o, tableFormat, emptyName, true );
1016  }
1018  {
1019  std::ostringstream ost;
1020  print( ost );
1021  return ost.str();
1022  }
1023  std::ostream& fillStream( std::ostream& o ) const { return print( o ); }
1024 };
1025 
1026 #endif // GAUDIKERNEL_COUNTERS_H
constexpr unsigned long operator()(U &&) const noexcept
Definition: Counters.h:158
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
Definition: Counters.h:627
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:1008
std::string toString() const
Definition: Counters.h:1017
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:310
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:324
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
Definition: Counters.h:421
T empty(T...args)
double Min() const
Definition: Counters.h:944
Buffer(prime_type &p)
Definition: Counters.h:632
unsigned long nEntries() const
Definition: Counters.h:464
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
double Mean() const
Definition: Counters.h:938
double flagRMS() const
Definition: Counters.h:950
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:793
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
std::ostream & fillStream(std::ostream &o) const
Definition: Counters.h:1023
unsigned long nEntries() const
Definition: Counters.h:522
unsigned long nFalseEntries() const
Definition: Counters.h:512
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:815
An empty ancester of all counters that provides a buffer method that returns a buffer on itself...
Definition: Counters.h:690
double sum(double x, double y, double z)
unsigned long nTrueEntries() const
Definition: Counters.h:497
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:804
double flagMin() const
Definition: Counters.h:952
atomicity
Defines atomicity of the accumulators.
Definition: Counters.h:150
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:790
typename Gaudi::cpp17::is_detected< has_fetch_add_, T >::value_t has_fetch_add
Definition: Counters.h:192
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
Definition: Counters.h:864
An Adder ValueHandler operator(a, b) means a += b.
Definition: Counters.h:236
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
Definition: Counters.h:863
A counter aiming at computing sum and average.
Definition: Counters.h:736
class MergingTransformer< Out(const vector_of_const_< In > void
decltype(auto) constexpr apply(F &&f, Tuple &&t) noexcept(noexcept( detail::apply_impl(std::forward< F >(f), std::forward< Tuple >(t), std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple >>::value >{})))
Definition: apply.h:31
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:659
T make_tuple(T...args)
An functor always returning the value N.
Definition: Counters.h:156
void reset()
Definition: Counters.h:881
An empty ancester of all counters that knows how to print themselves.
Definition: Counters.h:647
double flagMeanErr() const
Definition: Counters.h:951
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
Definition: Counters.h:960
bool operator<(const StatEntity &se) const
Definition: Counters.h:914
StatEntity operator++(int)
Definition: Counters.h:897
static void add(InternalType &a, T b, std::true_type)
Definition: Counters.h:281
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:778
std::decay_t< std::result_of_t< Identity(unsigned long)>> OutputType
Definition: Counters.h:372
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:724
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:224
double Max() const
Definition: Counters.h:945
double flagMax() const
Definition: Counters.h:953
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:1012
STL class.
StatEntity & operator++()
Definition: Counters.h:892
int N
Definition: IOTest.py:101
PrintableCounter(OWNER *o, const std::string &tag)
Definition: Counters.h:650
GenericAccumulator operator+=(const InputType by)
Definition: Counters.h:373
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:841
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:198
static void add(InternalType &a, T b, std::false_type)
Definition: Counters.h:274
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Definition: Counters.h:666
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:214
double MeanErr() const
Definition: Counters.h:939
double flagMean() const
Definition: Counters.h:949
double Eff() const
Definition: Counters.h:943
unsigned int operator()(bool v) const
Definition: Counters.h:487
AccumulatorSet & operator+=(const InputType by)
Definition: Counters.h:413
StatEntity & operator-=(double by)
Definition: Counters.h:887
StatEntity(OWNER *o, const std::string &tag)
Definition: Counters.h:870
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:625
Buffer< Arithmetic, Accumulator > buffer()
Definition: Counters.h:692
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:827
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:967
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
double Sum() const
Definition: Counters.h:937
GenericAccumulator & operator=(const GenericAccumulator &other)
Definition: Counters.h:380
std::string toString() const
get a string representation
Definition: Counters.h:668
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Counters.h:764
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Definition: Counters.h:388
T move(T...args)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:768
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
Definition: Counters.h:407
virtual bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Counters.h:750
StatEntity & operator+=(StatEntity by)
Definition: Counters.h:925
Buffer(Buffer &&other)
Definition: Counters.h:635
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
Definition: Counters.h:616
StatEntity & operator--()
Definition: Counters.h:903
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
Definition: Counters.h:428
A counter dealing with binomial data.
Definition: Counters.h:812
T fetch_add(T...args)
static bool effCounter(const std::string &name)
Definition: Counters.h:954
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
ValueHandler::InternalType m_value
Definition: Counters.h:398
std::ostream & operator<<(std::ostream &stream, const PrintableCounter &counter)
external printout operator to std::ostream
Definition: Counters.h:679
helper functor for the TrueAccumulator
Definition: Counters.h:486
helper functor for the FalseAccumulator
Definition: Counters.h:501
An Identity functor.
Definition: Counters.h:167
unsigned long addFlag(const double v)
Definition: Counters.h:935
Base type for all functors used as ValuesHandler.
Definition: Counters.h:204
GenericAccumulator(const GenericAccumulator &other)
Definition: Counters.h:379
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:740
A basic counter counting input values.
Definition: Counters.h:700
T compare_exchange_weak(T...args)
double Rms() const
Definition: Counters.h:941
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:246
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Counters.h:287
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Counters.h:228
T sqrt(T...args)
double RMS() const
Definition: Counters.h:942
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
Definition: Counters.h:874
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Counters.h:213
double rms() const
Definition: Counters.h:940
backward compatible StatEntity class.
Definition: Counters.h:855
StatEntity operator--(int)
Definition: Counters.h:908
double flag2() const
Definition: Counters.h:948
StatEntity & operator+=(double by)
Definition: Counters.h:920
ContainedAccumulator< Arithmetic, atomicity::none > base_type
Definition: Counters.h:628
STL class.
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b...
Definition: Counters.h:300
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Counters.h:714
unsigned int operator()(bool v) const
Definition: Counters.h:502
Generic Accumulator, templated by.
Definition: Counters.h:366
Helper functions to set/get the application return code.
Definition: __init__.py:1
void operator=(double by)
Definition: Counters.h:882
double flag() const
Definition: Counters.h:947
T load(T...args)
unsigned long add(const double v)
Definition: Counters.h:930