SFrame 3.6
plug-ins/include/SH1.icc
Go to the documentation of this file.
00001 // Dear emacs, this is -*- c++ -*-
00002 // $Id: SH1.icc 313 2012-04-21 19:03:42Z krasznaa $
00003 /***************************************************************************
00004  * @Project: SFrame - ROOT-based analysis framework for ATLAS
00005  * @Package: Plug-ins
00006  *
00007  * @author Stefan Ask       <Stefan.Ask@cern.ch>           - Manchester
00008  * @author David Berge      <David.Berge@cern.ch>          - CERN
00009  * @author Johannes Haller  <Johannes.Haller@cern.ch>      - Hamburg
00010  * @author A. Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN/Debrecen
00011  *
00012  ***************************************************************************/
00013 
00014 #ifndef SFRAME_PLUGINS_SH1_ICC
00015 #define SFRAME_PLUGINS_SH1_ICC
00016 
00017 // System include(s):
00018 //#include <cstring>
00019 
00020 // ROOT include(s):
00021 #include <TCollection.h>
00022 #include <TH1.h>
00023 #include <TMath.h>
00024 
00025 // SFrame include(s):
00026 #include "core/include/SLogger.h"
00027 
00032 template< typename Type >
00033 SH1< Type >::SH1()
00034    : TNamed(), m_arraySize( 0 ), m_content( 0 ), m_errors( 0 ), m_entries( 0 ),
00035      m_bins( 0 ), m_low( 0.0 ), m_high( 0.0 ), m_computeErrors( kFALSE ) {
00036 
00037 }
00038 
00047 template< typename Type >
00048 template< typename T >
00049 SH1< Type >::SH1( const SH1< T >& parent )
00050    : TNamed( parent ), m_arraySize( parent.m_arraySize ), m_content( 0 ), m_errors( 0 ),
00051      m_entries( parent.m_entries ), m_bins( parent.m_bins ), m_low( parent.m_low ),
00052      m_high( parent.m_high ), m_computeErrors( parent.m_computeErrors ) {
00053 
00054    m_content = new Type[ m_arraySize ];
00055    if( m_computeErrors ) m_errors = new Type[ m_arraySize ];
00056    for( Int_t i = 0; i < m_arraySize; ++i ) {
00057       m_content[ i ] = static_cast< Type >( parent.m_content[ i ] );
00058       if( m_computeErrors ) m_errors[ i ] = static_cast< Type >( parent.m_errors[ i ] );
00059    }
00060 }
00061 
00075 template< typename Type >
00076 SH1< Type >::SH1( const char* name, const char* title, Int_t bins,
00077                   Double_t low, Double_t high, Bool_t computeErrors )
00078    : TNamed( name, title ), m_arraySize( bins + 2 ), m_content( 0 ), m_errors( 0 ),
00079      m_entries( 0 ), m_bins( bins ), m_low( low ), m_high( high ),
00080      m_computeErrors( computeErrors ) {
00081 
00082    m_content = new Type[ m_arraySize ];
00083    memset( m_content, 0, m_arraySize * sizeof( Type ) );
00084    if( m_computeErrors ) {
00085       m_errors = new Type[ m_arraySize ];
00086       memset( m_errors, 0, m_arraySize * sizeof( Type ) );
00087    }
00088 }
00089 
00094 template< typename Type >
00095 SH1< Type >::~SH1() {
00096 
00097    delete[] m_content; m_content = 0;
00098    if( m_errors ) {
00099       delete[] m_errors; m_errors = 0;
00100    }
00101 }
00102 
00115 template< typename Type >
00116 void SH1< Type >::Fill( Double_t pos, Type weight ) throw( SError ) {
00117 
00118    // Check if the given parameters make sense:
00119    if( TMath::IsNaN( pos ) || TMath::IsNaN( weight ) ) {
00120       SLogger m_logger( this ); // The name of the variable is like this on purpose
00121       REPORT_FATAL( "Fill( pos = " << pos << ", weight = " << weight
00122                     << " ): NaN received. Aborting..." );
00123       SError error( SError::StopExecution );
00124       error << "NaN received by Fill(...) function of histogram: " << GetName();
00125       throw error;
00126    }
00127 
00128    Int_t bin;
00129    m_content[ bin = FindBin( pos ) ] += weight;
00130    if( m_computeErrors ) m_errors[ bin ] += weight * weight;
00131    ++m_entries;
00132 
00133    return;
00134 }
00135 
00139 template< typename Type >
00140 Int_t SH1< Type >::GetNBins() const {
00141 
00142    return m_bins;
00143 }
00144 
00154 template< typename Type >
00155 Int_t SH1< Type >::FindBin( Double_t pos ) const {
00156 
00157    if( pos < m_low ) return 0;
00158    if( pos > m_high ) return ( m_bins + 1 );
00159 
00160    return static_cast< Int_t >( ( pos - m_low ) / ( ( m_high - m_low ) / m_bins ) + 1 );
00161 }
00162 
00170 template< typename Type >
00171 Type SH1< Type >::GetBinContent( Int_t bin ) const {
00172 
00173    return m_content[ bin ];
00174 }
00175 
00184 template< typename Type >
00185 void SH1< Type >::SetBinContent( Int_t bin, Type content ) {
00186 
00187    m_content[ bin ] = content;
00188    return;
00189 }
00190 
00198 template< typename Type >
00199 Type SH1< Type >::GetBinError( Int_t bin ) const {
00200 
00201    if( ! m_computeErrors ) return 0;
00202    else return static_cast< Type >( TMath::Sqrt( m_errors[ bin ] ) );
00203 }
00204 
00212 template< typename Type >
00213 void SH1< Type >::SetBinError( Int_t bin, Type error ) {
00214 
00215    if( ! m_computeErrors ) return;
00216    else m_errors[ bin ] = error * error;
00217 
00218    return;
00219 }
00220 
00224 template< typename Type >
00225 Int_t SH1< Type >::GetEntries() const {
00226 
00227    return m_entries;
00228 }
00229 
00233 template< typename Type >
00234 void SH1< Type >::SetEntries( Int_t entries ) {
00235 
00236    m_entries = entries;
00237    return;
00238 }
00239 
00249 template< typename Type >
00250 TH1* SH1< Type >::ToHist() const {
00251 
00252    TH1* hist = 0;
00253    if( ! strcmp( typeid( Type ).name(), "f" ) ) {
00254       hist = new TH1F( GetName(), GetTitle(), GetNBins(), m_low, m_high );
00255    } else if( ! strcmp( typeid( Type ).name(), "d" ) ) {
00256       hist = new TH1D( GetName(), GetTitle(), GetNBins(), m_low, m_high );
00257    } else if( ! strcmp( typeid( Type ).name(), "i" ) ) {
00258       hist = new TH1I( GetName(), GetTitle(), GetNBins(), m_low, m_high );
00259    } else {
00260       SLogger logger( this->ClassName() );
00261       logger << ERROR << "ToHist(): Can't find appropriate TH1 histogram type!"
00262              << SLogger::endmsg;
00263       return 0;
00264    }
00265 
00266    for( Int_t i = 0; i < m_arraySize; ++i ) {
00267       hist->SetBinContent( i, GetBinContent( i ) );
00268       hist->SetBinError( i, GetBinError( i ) );
00269    }
00270    hist->SetEntries( GetEntries() );
00271 
00272    return hist;
00273 }
00274 
00279 template< typename Type >
00280 Int_t SH1< Type >::Merge( TCollection* coll ) {
00281 
00282    SLogger m_logger( this->ClassName() ); // The name of the variable is like this on purpose...
00283 
00284    //
00285    // Return right away if the input is flawed:
00286    //
00287    if( ! coll ) return 0;
00288    if( coll->IsEmpty() ) return 0;
00289 
00290    //
00291    // Select the elements from the collection that can actually be merged:
00292    //
00293    TIter next( coll );
00294    TObject* obj = 0;
00295    while( ( obj = next() ) ) {
00296 
00297       SH1< Type >* hist = dynamic_cast< SH1< Type >* >( obj );
00298       if( ! hist ) {
00299          REPORT_ERROR( "Trying to merge \"" << obj->ClassName()
00300                        << "\" object into \"" << this->ClassName() << "\"" );
00301          continue;
00302       }
00303 
00304       if( ( TMath::Abs( hist->m_low - m_low ) > 0.001 ) ||
00305           ( TMath::Abs( hist->m_high - m_high ) > 0.001 ) ||
00306           ( m_bins != hist->m_bins ) ||
00307           ( m_computeErrors != hist->m_computeErrors ) ) {
00308          REPORT_ERROR( "Trying to merge histograms with different settings" );
00309          continue;
00310       }
00311 
00312       for( Int_t i = 0; i < m_arraySize; ++i ) {
00313          m_content[ i ] += hist->m_content[ i ];
00314          if( m_computeErrors ) m_errors[ i ] += hist->m_errors[ i ];
00315       }
00316       m_entries += hist->m_entries;
00317 
00318    }
00319 
00320    return 1;
00321 }
00322 
00328 template< typename Type >
00329 Int_t SH1< Type >::Write( const char* name, Int_t option, Int_t bufsize ) const {
00330 
00331    TH1* hist = ToHist();
00332    if( ! hist ) return 0;
00333 
00334    hist->Write( name, option, bufsize );
00335    delete hist;
00336 
00337    return 1;
00338 }
00339 
00340 template< typename Type >
00341 Int_t SH1< Type >::Write( const char* name, Int_t option, Int_t bufsize ) {
00342 
00343    return const_cast< const SH1< Type >* >( this )->Write( name, option, bufsize );
00344 }
00345 
00346 #endif // SFRAME_PLUGINS_SH1_ICC