File indexing completed on 2025-03-13 09:10:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012 #include <Gaudi/Accumulators.h>
0013 #include <boost/algorithm/string/predicate.hpp>
0014 #include <boost/format.hpp>
0015
0016
0017
0018
0019
0020 class StatEntity : public Gaudi::Accumulators::PrintableCounter,
0021 public Gaudi::Accumulators::AccumulatorSet<double, Gaudi::Accumulators::atomicity::full, double,
0022 Gaudi::Accumulators::StatAccumulator,
0023 Gaudi::Accumulators::BinomialAccumulator> {
0024 public:
0025 inline static const std::string typeString{ "statentity" };
0026 using AccParent = Gaudi::Accumulators::AccumulatorSet<double, Gaudi::Accumulators::atomicity::full, double,
0027 Gaudi::Accumulators::StatAccumulator,
0028 Gaudi::Accumulators::BinomialAccumulator>;
0029 using BinomialAccParent = Gaudi::Accumulators::BinomialAccumulator<Gaudi::Accumulators::atomicity::full, double>;
0030 using Gaudi::Accumulators::StatAccumulator<Gaudi::Accumulators::atomicity::full, double>::nEntries;
0031 using AccParent::reset;
0032
0033 StatEntity() = default;
0034 StatEntity( const unsigned long entries, const double flag, const double flag2, const double minFlag,
0035 const double maxFlag ) {
0036 reset( std::make_tuple(
0037 std::make_tuple( std::make_tuple( std::make_tuple( entries, flag ), flag2 ), minFlag, maxFlag ),
0038 std::make_tuple( 0, 0 ) ) );
0039 }
0040 friend void reset( StatEntity& s ) { s.reset(); }
0041 void operator=( double by ) {
0042 this->reset();
0043 ( *this ) += by;
0044 }
0045 StatEntity& operator-=( double by ) {
0046 ( *this ) += ( -by );
0047 return *this;
0048 }
0049 StatEntity& operator++() {
0050 ( *this ) += 1.0;
0051 return *this;
0052 }
0053 StatEntity operator++( int ) {
0054 auto copy = *this;
0055 ++( *this );
0056 return copy;
0057 }
0058 StatEntity& operator--() {
0059 ( *this ) += -1.0;
0060 return *this;
0061 }
0062 StatEntity operator--( int ) {
0063 auto copy = *this;
0064 --( *this );
0065 return copy;
0066 }
0067 bool operator<( const StatEntity& se ) const {
0068 return std::make_tuple( nEntries(), sum(), min(), max(), sum2() ) <
0069 std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
0070 };
0071
0072 StatEntity& operator+=( double by ) {
0073 this->AccumulatorSet::operator+=( by );
0074 return *this;
0075 }
0076 StatEntity& operator+=( StatEntity by ) {
0077 mergeAndReset( by );
0078 return *this;
0079 }
0080 unsigned long add( const double v ) {
0081 *this += v;
0082 return nEntries();
0083 }
0084 unsigned long addFlag( const double v ) { return add( v ); }
0085
0086 double Sum() const { return sum(); }
0087 double Mean() const { return mean(); }
0088 double MeanErr() const { return meanErr(); }
0089 double rms() const { return standard_deviation(); }
0090 double Rms() const { return standard_deviation(); }
0091 double RMS() const { return standard_deviation(); }
0092 double Eff() const { return eff(); }
0093 double Min() const { return min(); }
0094 double Max() const { return max(); }
0095
0096 double flag() const { return sum(); }
0097 double flag2() const { return sum2(); }
0098 double flagMean() const { return mean(); }
0099 double flagRMS() const { return standard_deviation(); }
0100 double flagMeanErr() const { return meanErr(); }
0101 double flagMin() const { return min(); }
0102 double flagMax() const { return max(); }
0103 static bool effCounter( std::string_view name ) {
0104 using boost::algorithm::icontains;
0105 return icontains( name, "eff" ) || icontains( name, "acc" ) || icontains( name, "filt" ) ||
0106 icontains( name, "fltr" ) || icontains( name, "pass" );
0107 }
0108 template <typename stream>
0109 stream& printFormattedImpl( stream& o, const std::string& format ) const {
0110 boost::format fmt{ format };
0111 fmt % nEntries() % sum() % mean() % standard_deviation() % min() % max();
0112 return o << fmt.str();
0113 }
0114 std::ostream& printFormatted( std::ostream& o, const std::string& format ) const {
0115 return printFormattedImpl( o, format );
0116 }
0117 MsgStream& printFormatted( MsgStream& o, const std::string& format ) const { return printFormattedImpl( o, format ); }
0118 using Gaudi::Accumulators::PrintableCounter::print;
0119 template <typename stream>
0120 stream& printImpl( stream& o, bool tableFormat, std::string_view name, bool flag, std::string_view fmtHead ) const {
0121 if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() && sum() <= nEntries() &&
0122 ( essentiallyEqual( min(), 0 ) || essentiallyEqual( min(), 1 ) ) &&
0123 ( essentiallyEqual( max(), 0 ) || essentiallyEqual( max(), 1 ) ) ) {
0124
0125 if ( tableFormat ) {
0126 if ( name.empty() ) {
0127 constexpr auto fmt = "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
0128 return o << boost::format{ fmt } % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
0129 ( efficiencyErr() * 100 );
0130 } else {
0131 auto fmt = std::string{ " |*" }.append( fmtHead ).append(
0132 "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |" );
0133 return o << boost::format{ fmt } % ( std::string{ "\"" }.append( name ).append( "\"" ) ) %
0134 BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
0135 }
0136 } else {
0137 constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
0138 return o << boost::format{ fmt } % BinomialAccParent::nEntries() % sum() % ( efficiency() * 100 ) %
0139 ( efficiencyErr() * 100 );
0140 }
0141 } else {
0142
0143 if ( tableFormat ) {
0144 if ( name.empty() ) {
0145 constexpr auto fmt = "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
0146 return o << boost::format{ fmt } % nEntries() % sum() % mean() % standard_deviation() % min() % max();
0147
0148 } else {
0149 auto fmt = std::string{ " | " }.append( fmtHead ).append(
0150 "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" );
0151 return o << boost::format{ fmt } % std::string{ "\"" }.append( name ).append( "\"" ) % nEntries() % sum() %
0152 mean() % standard_deviation() % min() % max();
0153 }
0154 } else {
0155 constexpr auto fmt = "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
0156 return o << boost::format{ fmt } % nEntries() % sum() % mean() % standard_deviation() % min() % max();
0157 }
0158 }
0159 }
0160 std::ostream& print( std::ostream& o, bool tableFormat, std::string_view name, bool flag = true,
0161 std::string_view fmtHead = "%|-48.48s|%|27t|" ) const {
0162 return printImpl( o, tableFormat, name, flag, fmtHead );
0163 }
0164 MsgStream& print( MsgStream& o, bool tableFormat, std::string_view name, bool flag = true,
0165 std::string_view fmtHead = "%|-48.48s|%|27t|" ) const {
0166 return printImpl( o, tableFormat, name, flag, fmtHead );
0167 }
0168 virtual std::ostream& print( std::ostream& o, std::string_view tag ) const override {
0169 return print( o, true, tag, true );
0170 }
0171 virtual MsgStream& print( MsgStream& o, std::string_view tag ) const override { return print( o, true, tag, true ); }
0172 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
0173 std::string emptyName;
0174 return print( o, tableFormat, emptyName, true );
0175 }
0176 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override {
0177 std::string emptyName;
0178 return print( o, tableFormat, emptyName, true );
0179 }
0180 std::string toString() const {
0181 std::ostringstream ost;
0182 print( ost );
0183 return ost.str();
0184 }
0185 std::ostream& fillStream( std::ostream& o ) const { return print( o ); }
0186 MsgStream& fillStream( MsgStream& o ) const { return print( o ); }
0187
0188 friend void to_json( nlohmann::json& j, StatEntity const& s );
0189 static StatEntity fromJSON( const nlohmann::json& j ) {
0190 StatEntity res;
0191 res.reset( AccParent::extractJSONData(
0192 j, { { { { "nEntries", "sum" }, "sum2" }, "min", "max" }, { "nTrueEntries", "nFalseEntries" } } ) );
0193 return res;
0194 }
0195
0196 private:
0197 static constexpr bool essentiallyEqual( double const a, double const b ) {
0198 return std::abs( a - b ) <= std::max( std::abs( a ), std::abs( b ) ) * std::numeric_limits<double>::epsilon();
0199 }
0200 };