Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

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:  $, 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 // ============================================================================
00027 
00028 #ifdef __ICC
00029 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
00030 //  A lot of comparisons are done and "meant".
00031 #pragma warning(disable:1572)
00032 // disable icc remark #2259: non-pointer conversion from "long double" to "double" may lose significant bits
00033 //  Internal operations are done with "long double", but the interface exposes only
00034 //  "double", so the conversions are required.
00035 #pragma warning(disable:2259)
00036 #endif
00037 
00038 
00044 // ============================================================================
00045 // The full contructor from all important values
00046 // ============================================================================
00047 StatEntity::StatEntity
00048 ( const unsigned long entries , 
00049   const double        flag    ,
00050   const double        flag2   ,
00051   const double        minFlag , 
00052   const double        maxFlag ) 
00053   : m_se_nEntries            ( entries )
00054   , m_se_accumulatedFlag     ( flag    ) 
00055   , m_se_accumulatedFlag2    ( flag2   ) 
00056   , m_se_minimalFlag         ( minFlag ) 
00057   , m_se_maximalFlag         ( maxFlag ) 
00058   , m_se_nEntriesBeforeReset ( -1      )
00059 {}
00060 // ============================================================================
00061 // the internal format description 
00062 // ============================================================================
00063 const std::string& StatEntity::format() 
00064 {
00065   // check for "X" or "L"
00066   BOOST_STATIC_ASSERT(((sizeof(unsigned long)==4)||(sizeof(unsigned long)==8)));
00067   // check for "D"
00068   BOOST_STATIC_ASSERT((sizeof(double)==8))        ; 
00069   //
00070   static const std::string s_fmt = 
00071     ( ( 8 == sizeof(unsigned long) ) ?"X:1;" : "L:1;" ) + std::string("D:4") ;
00072   return s_fmt ;
00073 } 
00074 // ============================================================================
00075 // the actual size of published data 
00076 // ============================================================================
00077 int StatEntity::size  () 
00078 { 
00079   static const int s_size = sizeof(unsigned long) + 4 * sizeof(double) ; 
00080   return s_size ;
00081 }   
00082 // ============================================================================
00083 // mean value of flag 
00084 // ============================================================================
00085 double StatEntity::mean   () const 
00086 { 
00087   if ( 0 >= nEntries() ) { return 0 ;}
00088   const long double f1 = m_se_accumulatedFlag ;
00089   const long double f2 = m_se_nEntries ;
00090   return f1 / f2 ;
00091 }
00092 // ============================================================================
00093 // r.m.s of flag
00094 // ============================================================================
00095 double StatEntity::rms    () const 
00096 {
00097   if ( 0 >= nEntries() ) { return 0 ; }
00098   const long double f1  = m_se_accumulatedFlag  ;
00099   const long double f2  = f1 / nEntries () ;
00100   const long double f3  = m_se_accumulatedFlag2 ;
00101   const long double f4  = f3 / nEntries () ;
00102   const long double result = f4 - f2 * f2  ;
00103   return ( 0 > result ) ? 0 : ::sqrtl ( result ) ; 
00104 } 
00105 // ============================================================================
00106 // error in mean value of flag 
00107 // ============================================================================
00108 double StatEntity::meanErr() const 
00109 {
00110   if ( 0 >= nEntries () ) { return 0 ; }
00111   const long double f1  = m_se_accumulatedFlag  ;
00112   const long double f2  = f1 / nEntries () ;
00113   const long double f3  = m_se_accumulatedFlag2 ;
00114   const long double f4  = f3 / nEntries () ;
00115   const long double result = f4 - f2 * f2  ;
00116   if ( 0 > result      ) { return 0 ; }
00117   //
00118   return ::sqrtl ( result / nEntries () ) ;
00119 }
00120 // ============================================================================
00121 // interprete the content as efficiency
00122 // ============================================================================
00123 double StatEntity::efficiency    () const 
00124 {
00125   if ( 1 > nEntries () || 0 > sum() || sum() > nEntries() ) { return -1 ; }
00126   const long double fMin = min () ;
00127   if ( 0 != fMin && 1 != fMin ) { return -1 ; }
00128   const long double fMax = max () ;
00129   if ( 0 != fMax && 1 != fMax ) { return -1 ; }
00130   return mean() ;
00131 }
00132 // ============================================================================
00133 // evaluate the binomial error in efficiency
00134 // ============================================================================
00135 double StatEntity::efficiencyErr () const 
00136 {
00137   if ( 0 > efficiency() ) { return -1 ; }
00138   //
00139   long double n1 = sum () ;
00140   // treat properly the bins with eff=0 
00141   if ( 0 == n1 ) { n1 = 1 ; } 
00142   const long double n3 = nEntries  () ;
00143   long double       n2 = n3 - flag () ;
00144   // treat properly the bins with eff=100% 
00145   if ( 1 > fabsl( n2 ) ) { n2 = 1 ; } 
00146   //
00147   return ::sqrtl( n1 * n2 / n3 ) / n3 ;
00148 }
00149 // ============================================================================
00150 // increment with other entity 
00151 // ============================================================================
00152 StatEntity& StatEntity::operator+=( const StatEntity& other ) 
00153 {
00154   m_se_nEntries         += other.m_se_nEntries ;
00155   m_se_accumulatedFlag  += other.m_se_accumulatedFlag  ;
00156   m_se_accumulatedFlag2 += other.m_se_accumulatedFlag2 ;
00157   m_se_minimalFlag = std::min ( m_se_minimalFlag , other.m_se_minimalFlag ) ;
00158   m_se_maximalFlag = std::max ( m_se_maximalFlag , other.m_se_maximalFlag ) ;
00159   //
00160   return *this ;
00161 }
00162 // ============================================================================
00164 // ============================================================================
00165 bool StatEntity::operator< ( const StatEntity& se ) const 
00166 {  
00167   if      ( &se == this                     ) { return false ; }
00168   else if ( nEntries () <   se.nEntries ()  ) { return true  ; }
00169   else if ( nEntries () ==  se.nEntries () && 
00170             sum      () <   se.sum      ()  ) { return true  ; } 
00171   else if ( nEntries () ==  se.nEntries () && 
00172             sum      () ==  se.sum      () &&  
00173             min      () <   se.min      ()  ) { return true  ; } 
00174   else if ( nEntries () ==  se.nEntries () && 
00175             sum      () ==  se.sum      () &&  
00176             min      () ==  se.min      () &&
00177             max      () <   se.max      ()  ) { return true  ; } 
00178   else if ( nEntries () ==  se.nEntries () && 
00179             sum      () ==  se.flag     () &&  
00180             min      () ==  se.min      () &&
00181             max      () ==  se.max      () && 
00182             sum2     () <   se.sum2     ()  ) { return true  ; }
00184   return false; 
00185 }
00186 // ============================================================================
00187 // increment a flag  
00188 // ============================================================================
00189 unsigned long StatEntity::add ( const double Flag ) 
00190 {  
00191   //
00192   if      ( 0 <  m_se_nEntriesBeforeReset ) { --m_se_nEntriesBeforeReset; }
00193   else if ( 0 == m_se_nEntriesBeforeReset ) { reset(); } 
00194 
00195   m_se_accumulatedFlag   += Flag        ; // accumulate the flag
00197   m_se_minimalFlag = std::min ( m_se_minimalFlag , Flag ) ; // evaluate min/max 
00198   m_se_maximalFlag = std::max ( m_se_maximalFlag , Flag ) ; // evaluate min/max 
00199   // accumulate statistics, but avoid FPE for small flags... 
00200   static const double s_min1 = 2 * ::sqrt ( std::numeric_limits<double>::min() ) ;
00201   if ( s_min1 < Flag || -s_min1 > Flag )  
00202   { m_se_accumulatedFlag2  += Flag * Flag ; }// accumulate statistics:
00203   //
00204   return ++m_se_nEntries ;  
00205 }
00206 // ============================================================================
00207 // reset all quantities
00208 // ============================================================================
00209 void StatEntity::reset()
00210 {
00211   //
00212   m_se_nEntries            =        0 ;
00213   m_se_accumulatedFlag     =        0 ; 
00214   m_se_minimalFlag         =       std::numeric_limits<double>::max() ;
00215   m_se_maximalFlag         =  -1 * std::numeric_limits<double>::max() ;
00216   m_se_accumulatedFlag2    =        0 ;
00217   m_se_nEntriesBeforeReset =       -1 ; // ? 
00218 }
00219 // ============================================================================
00221 // ============================================================================
00222 void StatEntity::setnEntriesBeforeReset(unsigned long nEntriesBeforeReset )
00223 { m_se_nEntriesBeforeReset = nEntriesBeforeReset; }
00224 // ============================================================================
00225 // representation as string
00226 // ============================================================================
00227 std::string StatEntity::toString () const
00228 {
00229   std::ostringstream ost ;
00230   print ( ost )  ;
00231   return ost.str () ;
00232 } 
00233 // ============================================================================
00234 // printout to std::ostream
00235 // ============================================================================
00236 std::ostream& StatEntity::print ( std::ostream& o ) const
00237 {
00238   boost::format fmt1 ("#=%|-7lu| Sum=%|-11.5g|" ) ;
00239   o << fmt1 % nEntries() % sum() ;
00240   boost::format fmt2 ( " Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" ) ;
00241   o << fmt2 % mean() % rms() % min() % max() ;
00242   return o ;
00243 }
00244 // ============================================================================
00245 // external operator for addition of StatEntity and a number
00246 // ============================================================================
00247 StatEntity operator+( const StatEntity& entity , const double      value  ) 
00248 { StatEntity aux ( entity ) ; return aux+=value ; }
00249 // ============================================================================
00250 // external operator for addition of StatEntity and a number
00251 // ============================================================================
00252 StatEntity operator+( const double      value  , const StatEntity& entity ) 
00253 { return entity + value ; }
00254 // ============================================================================
00255 // external operator for addition of StatEntity and a number
00256 // ============================================================================
00257 StatEntity operator-( const StatEntity& entity , const double      value  ) 
00258 { StatEntity aux ( entity ) ; return aux-=value ; }
00259 // ============================================================================
00260 // external operator for addition of StatEntity and a number
00261 // ============================================================================
00262 StatEntity operator+( const StatEntity& entity , const StatEntity& value  ) 
00263 { StatEntity aux ( entity ) ; return aux+=value ; }
00264 // ============================================================================
00265 // external printout operator to std::ostream
00266 // ============================================================================
00267 std::ostream& operator<<( std::ostream& stream , const StatEntity& entity ) 
00268 { return entity.print ( stream ) ; }
00269 // ============================================================================
00270 namespace 
00271 {
00280   inline bool effCounter ( const std::string& name ) 
00281   {
00282     const std::string lower  =  boost::algorithm::to_lower_copy( name ) ;
00283     return  
00284       std::string::npos != lower.find ( "eff"  ) ||
00285       std::string::npos != lower.find ( "acc"  ) ||
00286       std::string::npos != lower.find ( "filt" ) ||
00287       std::string::npos != lower.find ( "fltr" ) ||
00288       std::string::npos != lower.find ( "pass" )  ;
00289   }
00290 }
00291 // ============================================================================
00292 /*  Format the counter in a form of the table row
00293  *  @param name    the name associated with the counter
00294  *  @param counter counter to be printed 
00295  *  @param flag    use the special format for "efficiency" rows
00296  *  @param format1 row format for the regular rows 
00297  *  @param format2 special row format for the "efficiency" rows 
00298  *  @return formatted row in the table 
00299  */
00300 // ============================================================================
00301 std::string Gaudi::Utils::formatAsTableRow 
00302 ( const StatEntity&  counter , 
00303   const bool         flag    , 
00304   const std::string& format1 ,
00305   const std::string& format2 )
00306 {
00307   using namespace boost::io ;
00308   if ( flag && 0 <= counter.eff() && 0 <= counter.effErr() ) 
00309   {
00310     boost::format fmt( format2 ) ;
00311     fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00312     fmt 
00313       %   counter.nEntries ()       
00314       %   counter.sum      () 
00315       % ( counter.eff      () * 100 ) 
00316       % ( counter.effErr   () * 100 ) ;
00317     return fmt.str() ;
00318   }
00319   boost::format fmt  ( format1 ) ;
00320   fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00321   fmt 
00322     %   counter.nEntries () 
00323     %   counter.sum      () 
00324     %   counter.mean     () 
00325     %   counter.rms      ()  
00326     %   counter.min      () 
00327     %   counter.max      () ;
00328   return fmt.str() ;
00329 }
00330 // ============================================================================
00331 /* Format the counter in a form of the table row
00332  * @param name the name associated with the counter
00333  * @param counter counter to be printed 
00334  * @param flag use the special format for efficiency rows
00335  * @param format1 row format for the regular rows 
00336  * @param format2 the special row format for the "efficiency" rows 
00337  * @return formatted row in the table 
00338  */
00339 // ============================================================================
00340 std::string Gaudi::Utils::formatAsTableRow 
00341 ( const std::string& name    ,
00342   const StatEntity&  counter , 
00343   const bool         flag    , 
00344   const std::string& format1 , 
00345   const std::string& format2 )
00346 {
00347   using namespace boost::io ;
00348   if ( flag && effCounter ( name ) && 0 <= counter.eff() && 0 <= counter.effErr() ) 
00349   {
00350     boost::format fmt( format2 ) ;
00351     fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00352     fmt 
00353       % ( "\"" + name + "\"" ) 
00354       %   counter.nEntries ()       
00355       %   counter.sum      () 
00356       % ( counter.eff      () * 100 ) 
00357       % ( counter.effErr   () * 100 ) ;
00358     return fmt.str() ;
00359   }
00360   boost::format fmt  ( format1 ) ;
00361   fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00362   fmt 
00363     % ( "\"" + name + "\"" ) 
00364     %   counter.nEntries () 
00365     %   counter.sum      () 
00366     %   counter.mean     () 
00367     %   counter.rms      ()  
00368     %   counter.min      () 
00369     %   counter.max      () ;
00370   return fmt.str() ;
00371 }
00372 // ============================================================================
00373 /* Format the counter in a form of the table row
00374  * @param name the name associated with the counter
00375  * @param group the group associated with the counter
00376  * @param counter counter to be printed 
00377  * @param flag use the special format for efficiency rows
00378  * @param format1 row format for the regular rows 
00379  * @param format2 the special row format for the "efficiency" rows 
00380  * @return formatted row in the table 
00381  */
00382 // ============================================================================
00383 std::string Gaudi::Utils::formatAsTableRow 
00384 ( const std::string& name    ,
00385   const std::string& group   ,
00386   const StatEntity&  counter ,
00387   const bool         flag    , 
00388   const std::string& format1 , 
00389   const std::string& format2 )
00390 {
00391   using namespace boost::io ;
00392   if ( flag && ( effCounter ( name ) || effCounter ( group ) ) 
00393        && 0 <= counter.eff() && 0 <= counter.effErr() ) 
00394   {
00395     boost::format fmt( format2 ) ;
00396     fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00397     fmt 
00398       % ( "\"" + name  + ":"  ) 
00399       % ( ":"  + group + "\"" ) 
00400       %   counter.nEntries () 
00401       %   counter.sum      () 
00402       % ( counter.eff      () * 100 ) 
00403       % ( counter.effErr   () * 100 ) ;
00404     return fmt.str() ;
00405   }
00406   boost::format fmt  ( format1 ) ;
00407   fmt.exceptions ( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ) ;
00408   fmt 
00409     % ( "\""  + name  + ":"  ) 
00410     % ( ":"   + group + "\"" ) 
00411     %   counter.nEntries () 
00412     %   counter.sum      () 
00413     %   counter.mean     () 
00414     %   counter.rms      ()  
00415     %   counter.min      () 
00416     %   counter.max      () ;
00417   return fmt.str() ;
00418 }
00419 // ============================================================================
00420 
00421 
00422 // ============================================================================
00423 // The END 
00424 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:24:44 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004