![]() |
|
|
Generated: 18 Jul 2008 |
00001 // $Id: StatEntity.cpp,v 1.8 2008/07/15 10:53:26 marcocle Exp $ 00002 // ============================================================================ 00003 // CVS tag $Name: v25r2 $, version $Revision: 1.8 $ 00004 // ============================================================================ 00005 #define GAUDIKERNEL_STATENTITY_CPP 1 00006 // ============================================================================ 00007 // include files 00008 // ============================================================================ 00009 // STD & STL 00010 // ============================================================================ 00011 #include <iostream> 00012 #include <sstream> 00013 #include <string> 00014 #include <cmath> 00015 #include <limits> 00016 // ============================================================================ 00017 // GaudiKernel 00018 // ============================================================================ 00019 #include "GaudiKernel/StatEntity.h" 00020 // ============================================================================ 00021 // Boost 00022 // ============================================================================ 00023 #include "boost/format.hpp" 00024 #include "boost/static_assert.hpp" 00025 #include "boost/algorithm/string/case_conv.hpp" 00026 // ============================================================================ 00032 // ============================================================================ 00033 // The full contructor from all important values 00034 // ============================================================================ 00035 StatEntity::StatEntity 00036 ( const unsigned long entries , 00037 const double flag , 00038 const double flag2 , 00039 const double minFlag , 00040 const double maxFlag ) 00041 : m_se_nEntries ( entries ) 00042 , m_se_accumulatedFlag ( flag ) 00043 , m_se_accumulatedFlag2 ( flag2 ) 00044 , m_se_minimalFlag ( minFlag ) 00045 , m_se_maximalFlag ( maxFlag ) 00046 , m_se_nEntriesBeforeReset ( -1 ) 00047 {} 00048 // ============================================================================ 00049 // the internal format description 00050 // ============================================================================ 00051 const std::string& StatEntity::format() 00052 { 00053 // check for "X" or "L" 00054 BOOST_STATIC_ASSERT(((sizeof(unsigned long)==4)||(sizeof(unsigned long)==8))); 00055 // check for "D" 00056 BOOST_STATIC_ASSERT((sizeof(double)==8)) ; 00057 // 00058 static const std::string s_fmt = 00059 ( ( 8 == sizeof(unsigned long) ) ?"X:1;" : "L:1;" ) + std::string("D:4") ; 00060 return s_fmt ; 00061 } 00062 // ============================================================================ 00063 // the actual size of published data 00064 // ============================================================================ 00065 int StatEntity::size () 00066 { 00067 static const int s_size = sizeof(unsigned long) + 4 * sizeof(double) ; 00068 return s_size ; 00069 } 00070 // ============================================================================ 00071 // mean value of flag 00072 // ============================================================================ 00073 double StatEntity::flagMean () const 00074 { 00075 if ( 0 >= nEntries() ) { return 0 ;} 00076 const long double f1 = m_se_accumulatedFlag ; 00077 const long double f2 = m_se_nEntries ; 00078 return f1 / f2 ; 00079 } 00080 // ============================================================================ 00081 // r.m.s of flag 00082 // ============================================================================ 00083 double StatEntity::flagRMS () const 00084 { 00085 if ( 0 >= nEntries() ) { return 0 ; } 00086 const long double f1 = m_se_accumulatedFlag ; 00087 const long double f2 = f1 / nEntries () ; 00088 const long double f3 = m_se_accumulatedFlag2 ; 00089 const long double f4 = f3 / nEntries () ; 00090 const long double result = f4 - f2 * f2 ; 00091 return ( 0 > result ) ? 0 : ::sqrtl ( result ) ; 00092 } 00093 // ============================================================================ 00094 // error in mean value of flag 00095 // ============================================================================ 00096 double StatEntity::flagMeanErr() const 00097 { 00098 if ( 0 >= nEntries () ) { return 0 ; } 00099 const long double f1 = m_se_accumulatedFlag ; 00100 const long double f2 = f1 / nEntries () ; 00101 const long double f3 = m_se_accumulatedFlag2 ; 00102 const long double f4 = f3 / nEntries () ; 00103 const long double result = f4 - f2 * f2 ; 00104 if ( 0 > result ) { return 0 ; } 00105 // 00106 return ::sqrtl ( result / nEntries () ) ; 00107 } 00108 // ============================================================================ 00109 // interprete the content as efficiency 00110 // ============================================================================ 00111 double StatEntity::efficiency () const 00112 { 00113 if ( 1 > nEntries () || 0 > flag() || flag() > nEntries() ) { return -1 ; } 00114 const long double fMin = flagMin () ; 00115 if ( 0 != fMin && 1 != fMin ) { return -1 ; } 00116 const long double fMax = flagMax () ; 00117 if ( 0 != fMax && 1 != fMax ) { return -1 ; } 00118 return flagMean() ; 00119 } 00120 // ============================================================================ 00121 // evaluate the binomial error in efficiency 00122 // ============================================================================ 00123 double StatEntity::efficiencyErr () const 00124 { 00125 if ( 0 > efficiency() ) { return -1 ; } 00126 00127 long double n1 = flag() ; 00128 // treat properly the bins with eff=0 00129 if ( 0 == n1 ) { n1 = 1 ; } 00130 const long double n3 = nEntries () ; 00131 long double n2 = n3 - flag () ; 00132 // treat properly the bins with eff=100% 00133 if ( 1 > fabsl( n2 ) ) { n2 = 1 ; } 00134 // 00135 return ::sqrtl( n1 * n2 / n3 ) / n3 ; 00136 } 00137 // ============================================================================ 00138 // increment with other entity 00139 // ============================================================================ 00140 StatEntity& StatEntity::operator+=( const StatEntity& other ) 00141 { 00142 m_se_nEntries += other.m_se_nEntries ; 00143 m_se_accumulatedFlag += other.m_se_accumulatedFlag ; 00144 m_se_accumulatedFlag2 += other.m_se_accumulatedFlag2 ; 00145 m_se_minimalFlag = std::min ( m_se_minimalFlag , other.m_se_minimalFlag ) ; 00146 m_se_maximalFlag = std::max ( m_se_maximalFlag , other.m_se_maximalFlag ) ; 00147 // 00148 return *this ; 00149 } 00150 // ============================================================================ 00152 // ============================================================================ 00153 bool StatEntity::operator< ( const StatEntity& se ) const 00154 { 00155 if ( &se == this ) { return false ; } 00156 else if ( nEntries () < se.nEntries () ) { return true ; } 00157 else if ( nEntries () == se.nEntries () && 00158 flag () < se.flag () ) { return true ; } 00159 else if ( nEntries () == se.nEntries () && 00160 flag () == se.flag () && 00161 flagMin () < se.flagMin () ) { return true ; } 00162 else if ( nEntries () == se.nEntries () && 00163 flag () == se.flag () && 00164 flagMin () == se.flagMin () && 00165 flagMax () < se.flagMax () ) { return true ; } 00166 else if ( nEntries () == se.nEntries () && 00167 flag () == se.flag () && 00168 flagMin () == se.flagMin () && 00169 flagMax () == se.flagMax () && 00170 flag2 () < se.flag2 () ) { return true ; } 00172 return false; 00173 } 00174 // ============================================================================ 00175 // increment a flag 00176 // ============================================================================ 00177 unsigned long StatEntity::addFlag ( const double Flag ) 00178 { 00179 // 00180 if ( 0 < m_se_nEntriesBeforeReset ) { --m_se_nEntriesBeforeReset; } 00181 else if ( 0 == m_se_nEntriesBeforeReset ) { reset(); } 00182 00183 m_se_accumulatedFlag += Flag ; // accumulate the flag 00185 m_se_minimalFlag = std::min ( m_se_minimalFlag , Flag ) ; // evaluate min/max 00186 m_se_maximalFlag = std::max ( m_se_maximalFlag , Flag ) ; // evaluate min/max 00187 // accumulate statistics, but avoid FPE for small flags... 00188 static const double s_min1 = 2 * ::sqrt ( std::numeric_limits<double>::min() ) ; 00189 if ( s_min1 < Flag || -s_min1 > Flag ) 00190 { m_se_accumulatedFlag2 += Flag * Flag ; }// accumulate statistics: 00191 // 00192 return ++m_se_nEntries ; 00193 } 00194 // ============================================================================ 00195 // reset all quantities 00196 // ============================================================================ 00197 void StatEntity::reset() 00198 { 00199 // 00200 m_se_nEntries = 0 ; 00201 m_se_accumulatedFlag = 0 ; 00202 m_se_minimalFlag = std::numeric_limits<double>::max() ; 00203 m_se_maximalFlag = -1 * std::numeric_limits<double>::max() ; 00204 m_se_accumulatedFlag2 = 0 ; 00205 m_se_nEntriesBeforeReset = -1 ; // ? 00206 } 00207 // ============================================================================ 00209 // ============================================================================ 00210 void StatEntity::setnEntriesBeforeReset(unsigned long nEntriesBeforeReset ) 00211 { m_se_nEntriesBeforeReset = nEntriesBeforeReset; } 00212 // ============================================================================ 00213 // representation as string 00214 // ============================================================================ 00215 std::string StatEntity::toString () const 00216 { 00217 std::ostringstream ost ; 00218 print ( ost ) ; 00219 return ost.str () ; 00220 } 00221 // ============================================================================ 00222 // printout to std::ostream 00223 // ============================================================================ 00224 std::ostream& StatEntity::print ( std::ostream& o ) const 00225 { 00226 boost::format fmt1 ("#=%|-7lu| Sum=%|-11.5g|" ) ; 00227 o << fmt1 % nEntries() % flag() ; 00228 boost::format fmt2 ( " Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" ) ; 00229 o << fmt2 % flagMean() % flagRMS() % flagMin() % flagMax() ; 00230 return o ; 00231 } 00232 // ============================================================================ 00233 // external operator for addition of StatEntity and a number 00234 // ============================================================================ 00235 StatEntity operator+( const StatEntity& entity , const double value ) 00236 { StatEntity aux ( entity ) ; return aux+=value ; } 00237 // ============================================================================ 00238 // external operator for addition of StatEntity and a number 00239 // ============================================================================ 00240 StatEntity operator+( const double value , const StatEntity& entity ) 00241 { return entity + value ; } 00242 // ============================================================================ 00243 // external operator for addition of StatEntity and a number 00244 // ============================================================================ 00245 StatEntity operator-( const StatEntity& entity , const double value ) 00246 { StatEntity aux ( entity ) ; return aux-=value ; } 00247 // ============================================================================ 00248 // external operator for addition of StatEntity and a number 00249 // ============================================================================ 00250 StatEntity operator+( const StatEntity& entity , const StatEntity& value ) 00251 { StatEntity aux ( entity ) ; return aux+=value ; } 00252 // ============================================================================ 00253 // external printout operator to std::ostream 00254 // ============================================================================ 00255 std::ostream& operator<<( std::ostream& stream , const StatEntity& entity ) 00256 { return entity.print ( stream ) ; } 00257 // ============================================================================ 00258 namespace 00259 { 00268 inline bool effCounter ( const std::string& name ) 00269 { 00270 const std::string lower = boost::algorithm::to_lower_copy( name ) ; 00271 return 00272 std::string::npos != lower.find ( "eff" ) || 00273 std::string::npos != lower.find ( "acc" ) || 00274 std::string::npos != lower.find ( "filt" ) || 00275 std::string::npos != lower.find ( "fltr" ) || 00276 std::string::npos != lower.find ( "pass" ) ; 00277 } 00278 } 00279 // ============================================================================ 00280 /* Format the counter in a form of the table row 00281 * @param name the name associated with the counter 00282 * @param counter counter to be printed 00283 * @param flag use the special format for "efficiency" rows 00284 * @param format1 row format for the regular rows 00285 * @param format2 special row format for the "efficiency" rows 00286 * @return formatted row in the table 00287 */ 00288 // ============================================================================ 00289 std::string Gaudi::Utils::formatAsTableRow 00290 ( const StatEntity& counter , 00291 const bool flag , 00292 const std::string& format1 , 00293 const std::string& format2 ) 00294 { 00295 using namespace boost::io ; 00296 if ( flag && 0 <= counter.eff() && 0 <= counter.effErr() ) 00297 { 00298 boost::format fmt( format2 ) ; 00299 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00300 fmt 00301 % counter.nEntries () 00302 % counter.flag () 00303 % ( counter.eff () * 100 ) 00304 % ( counter.effErr () * 100 ) ; 00305 return fmt.str() ; 00306 } 00307 boost::format fmt ( format1 ) ; 00308 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00309 fmt 00310 % counter.nEntries () 00311 % counter.flag () 00312 % counter.flagMean () 00313 % counter.flagRMS () 00314 % counter.flagMin () 00315 % counter.flagMax () ; 00316 return fmt.str() ; 00317 } 00318 // ============================================================================ 00319 /* Format the counter in a form of the table row 00320 * @param name the name associated with the counter 00321 * @param counter counter to be printed 00322 * @param flag use the special format for efficiency rows 00323 * @param format1 row format for the regular rows 00324 * @param format2 the special row format for the "efficiency" rows 00325 * @return formatted row in the table 00326 */ 00327 // ============================================================================ 00328 std::string Gaudi::Utils::formatAsTableRow 00329 ( const std::string& name , 00330 const StatEntity& counter , 00331 const bool flag , 00332 const std::string& format1 , 00333 const std::string& format2 ) 00334 { 00335 using namespace boost::io ; 00336 if ( flag && effCounter ( name ) && 0 <= counter.eff() && 0 <= counter.effErr() ) 00337 { 00338 boost::format fmt( format2 ) ; 00339 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00340 fmt 00341 % ( "\"" + name + "\"" ) 00342 % counter.nEntries () 00343 % counter.flag () 00344 % ( counter.eff () * 100 ) 00345 % ( counter.effErr () * 100 ) ; 00346 return fmt.str() ; 00347 } 00348 boost::format fmt ( format1 ) ; 00349 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00350 fmt 00351 % ( "\"" + name + "\"" ) 00352 % counter.nEntries () 00353 % counter.flag () 00354 % counter.flagMean () 00355 % counter.flagRMS () 00356 % counter.flagMin () 00357 % counter.flagMax () ; 00358 return fmt.str() ; 00359 } 00360 // ============================================================================ 00361 /* Format the counter in a form of the table row 00362 * @param name the name associated with the counter 00363 * @param group the group associated with the counter 00364 * @param counter counter to be printed 00365 * @param flag use the special format for efficiency rows 00366 * @param format1 row format for the regular rows 00367 * @param format2 the special row format for the "efficiency" rows 00368 * @return formatted row in the table 00369 */ 00370 // ============================================================================ 00371 std::string Gaudi::Utils::formatAsTableRow 00372 ( const std::string& name , 00373 const std::string& group , 00374 const StatEntity& counter , 00375 const bool flag , 00376 const std::string& format1 , 00377 const std::string& format2 ) 00378 { 00379 using namespace boost::io ; 00380 if ( flag && ( effCounter ( name ) || effCounter ( group ) ) 00381 && 0 <= counter.eff() && 0 <= counter.effErr() ) 00382 { 00383 boost::format fmt( format2 ) ; 00384 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00385 fmt 00386 % ( "\"" + name + ":" ) 00387 % ( ":" + group + "\"" ) 00388 % counter.nEntries () 00389 % counter.flag () 00390 % ( counter.eff () * 100 ) 00391 % ( counter.effErr () * 100 ) ; 00392 return fmt.str() ; 00393 } 00394 boost::format fmt ( format1 ) ; 00395 fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ; 00396 fmt 00397 % ( "\"" + name + ":" ) 00398 % ( ":" + group + "\"" ) 00399 % counter.nEntries () 00400 % counter.flag () 00401 % counter.flagMean () 00402 % counter.flagRMS () 00403 % counter.flagMin () 00404 % counter.flagMax () ; 00405 return fmt.str() ; 00406 } 00407 // ============================================================================ 00408 00409 00410 // ============================================================================ 00411 // The END 00412 // ============================================================================