SFrame 3.6
|
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