Gaudi Framework, version v20r2

Generated: 18 Jul 2008

StatEntity.cpp

Go to the documentation of this file.
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 // ============================================================================

Generated at Fri Jul 18 11:59:22 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004