The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
H1D.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#ifdef __ICC
12// disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
13// TODO: To be removed, since it comes from ROOT TMathBase.h
14# pragma warning( disable : 2259 )
15#endif
16
17#include "GaudiPI.h"
18#include <Gaudi/MonitoringHub.h>
19#include <GaudiCommonSvc/H1D.h>
23
24#include <cmath>
25
26std::pair<DataObject*, AIDA::IHistogram1D*> Gaudi::createH1D( ISvcLocator* svcLocator, const std::string& path,
27 const std::string& title, int nBins, double xlow,
28 double xup ) {
29 auto p = new Histogram1D( new TH1D( title.c_str(), title.c_str(), nBins, xlow, xup ) );
30 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
31 return { p, p };
32}
33
34std::pair<DataObject*, AIDA::IHistogram1D*> Gaudi::createH1D( ISvcLocator* svcLocator, const std::string& path,
35 const std::string& title, const Edges& e ) {
36 auto p = new Histogram1D( new TH1D( title.c_str(), title.c_str(), e.size() - 1, &e.front() ) );
37 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
38 return { p, p };
39}
40
41std::pair<DataObject*, AIDA::IHistogram1D*> Gaudi::createH1D( ISvcLocator* svcLocator, const std::string& path,
42 const AIDA::IHistogram1D& hist ) {
44 auto n = ( h ? new Histogram1D( new TH1D( *h ) ) : nullptr );
45 if ( n ) { svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *n ); }
46 return { n, n };
47}
48
49namespace Gaudi {
50
51 template <>
52 void* Generic1D<AIDA::IHistogram1D, TH1D>::cast( const std::string& className ) const {
53 if ( className == "AIDA::IHistogram1D" ) return const_cast<AIDA::IHistogram1D*>( (AIDA::IHistogram1D*)this );
54 if ( className == "AIDA::IHistogram" ) return const_cast<AIDA::IHistogram*>( (AIDA::IHistogram*)this );
55 return nullptr;
56 }
57
58 template <>
60 if ( binHeight( index ) <= 0 ) return 0;
61 double xx = binHeight( index ) / binError( index );
62 return int( xx * xx + 0.5 );
63 }
64
65 template <>
67 TH1D* imp = dynamic_cast<TH1D*>( rep );
68 if ( !imp ) throw std::runtime_error( "Cannot adopt native histogram representation." );
69 m_rep.reset( imp );
70 }
71} // namespace Gaudi
72
73Gaudi::Histogram1D::Histogram1D() : Base( new TH1D() ) { init( "", false ); }
74
76 m_rep.reset( rep );
77 init( m_rep->GetTitle() );
78 initSums();
79}
80
81void Gaudi::Histogram1D::init( const std::string& title, bool initialize_axis ) {
82 m_classType = "IHistogram1D";
83 if ( initialize_axis ) { m_axis.initialize( m_rep->GetXaxis(), false ); }
84 const TArrayD* a = m_rep->GetSumw2();
85 if ( !a || ( a && a->GetSize() == 0 ) ) m_rep->Sumw2();
86 setTitle( title );
87 m_rep->SetDirectory( nullptr );
88 m_sumEntries = 0;
89 m_sumwx = 0;
90}
91
93 m_sumwx = 0;
94 m_sumEntries = 0;
95 for ( int i = 1, n = m_rep->GetNbinsX(); i <= n; ++i ) {
96 m_sumwx += m_rep->GetBinContent( i ) * m_rep->GetBinCenter( i );
97 m_sumEntries += m_rep->GetBinContent( i );
98 }
99}
100
102 m_sumwx = 0;
103 m_sumEntries = 0;
104 return Base::reset();
105}
106
110 if ( m_rep ) {
111 init( m_rep->GetTitle() );
112 initSums();
113 }
114}
115
116bool Gaudi::Histogram1D::setBinContents( int i, int entries, double height, double error, double centre ) {
117 m_rep->SetBinContent( rIndex( i ), height );
118 m_rep->SetBinError( rIndex( i ), error );
119 // accumulate sumwx for in range bins
120 if ( i != AIDA::IAxis::UNDERFLOW_BIN && i != AIDA::IAxis::OVERFLOW_BIN ) m_sumwx += centre * height;
122 return true;
123}
124
126 m_rep->SetEntries( m_sumEntries );
127 std::vector<double> stat( 11 );
128 // sum weights
129 stat[0] = sumBinHeights();
130 stat[1] = 0;
131 if ( std::abs( equivalentBinEntries() ) > std::numeric_limits<double>::epsilon() )
132 stat[1] = ( sumBinHeights() * sumBinHeights() ) / equivalentBinEntries();
133 stat[2] = m_sumwx;
134 double mean = 0;
135 if ( std::abs( sumBinHeights() ) > std::numeric_limits<double>::epsilon() ) mean = m_sumwx / sumBinHeights();
136 stat[3] = ( mean * mean + rms * rms ) * sumBinHeights();
137 m_rep->PutStats( &stat.front() );
138 return true;
139}
140
141// set histogram statistics
142bool Gaudi::Histogram1D::setStatistics( int allEntries, double eqBinEntries, double mean, double rms ) {
143 m_rep->SetEntries( allEntries );
144 // fill statistcal vector for Root
145 std::vector<double> stat( 11 );
146 // sum weights
147 stat[0] = sumBinHeights();
148 // sum weights **2
149 stat[1] = 0;
150 if ( std::abs( eqBinEntries ) > std::numeric_limits<double>::epsilon() )
151 stat[1] = ( sumBinHeights() * sumBinHeights() ) / eqBinEntries;
152 // sum weights * x
153 stat[2] = mean * sumBinHeights();
154 // sum weight * x **2
155 stat[3] = ( mean * mean + rms * rms ) * sumBinHeights();
156 m_rep->PutStats( &stat.front() );
157 return true;
158}
159
160bool Gaudi::Histogram1D::fill( double x, double weight ) {
161 // avoid race conditions when filling the histogram
162 auto guard = std::scoped_lock{ m_fillSerialization };
163 m_rep->Fill( x, weight );
164 return true;
165}
166
167void Gaudi::Histogram1D::copyFromAida( const AIDA::IHistogram1D& h ) {
168 // implement here the copy
169 std::string title = h.title() + "Copy";
170 if ( h.axis().isFixedBinning() ) {
171 m_rep.reset(
172 new TH1D( title.c_str(), title.c_str(), h.axis().bins(), h.axis().lowerEdge(), h.axis().upperEdge() ) );
173 } else {
174 Edges e;
175 for ( int i = 0; i < h.axis().bins(); ++i ) { e.push_back( h.axis().binLowerEdge( i ) ); }
176 // add also upperedges at the end
177 e.push_back( h.axis().upperEdge() );
178 m_rep.reset( new TH1D( title.c_str(), title.c_str(), e.size() - 1, &e.front() ) );
179 }
180 m_axis.initialize( m_rep->GetXaxis(), false );
181 m_rep->Sumw2();
182 m_sumEntries = 0;
183 m_sumwx = 0;
184 // sumw
185 double sumw = h.sumBinHeights();
186 // sumw2
187 double sumw2 = 0;
188 if ( std::abs( h.equivalentBinEntries() ) > std::numeric_limits<double>::epsilon() )
189 sumw2 = ( sumw * sumw ) / h.equivalentBinEntries();
190
191 double sumwx = h.mean() * h.sumBinHeights();
192 double sumwx2 = ( h.mean() * h.mean() + h.rms() * h.rms() ) * h.sumBinHeights();
193
194 // copy the contents in
195 for ( int i = -2; i < axis().bins(); ++i ) {
196 // root binning starts from one !
197 m_rep->SetBinContent( rIndex( i ), h.binHeight( i ) );
198 m_rep->SetBinError( rIndex( i ), h.binError( i ) );
199 }
200 // need to do set entries after setting contents otherwise root will recalulate them
201 // taking into account how many time SetBinContents() has been called
202 m_rep->SetEntries( h.allEntries() );
203 // stat vector
204 std::vector<double> stat( 11 );
205 stat[0] = sumw;
206 stat[1] = sumw2;
207 stat[2] = sumwx;
208 stat[3] = sumwx2;
209 m_rep->PutStats( &stat.front() );
210}
211
213 // DataObject::serialize(s);
214 std::string title;
215 int size;
216 s >> size;
217 for ( int j = 0; j < size; j++ ) {
218 std::string key, value;
219 s >> key >> value;
220 if ( !annotation().addItem( key, value ) ) { annotation().setValue( key, value ); };
221 if ( "Title" == key ) { title = value; }
222 }
223 double lowerEdge, upperEdge, binHeight, binError;
224 int isFixedBinning, bins;
225 s >> isFixedBinning >> bins;
226
227 if ( isFixedBinning ) {
228 s >> lowerEdge >> upperEdge;
229 m_rep.reset( new TH1D( title.c_str(), title.c_str(), bins, lowerEdge, upperEdge ) );
230 } else {
231 Edges edges;
232 edges.resize( bins );
233 for ( int i = 0; i <= bins; ++i ) s >> edges[i];
234 m_rep.reset( new TH1D( title.c_str(), title.c_str(), edges.size() - 1, &edges.front() ) );
235 }
236 m_axis.initialize( m_rep->GetXaxis(), true );
237 m_rep->Sumw2();
238 m_sumEntries = 0;
239 m_sumwx = 0;
240
241 for ( int i = 0; i <= bins + 1; ++i ) {
242 s >> binHeight >> binError;
243 m_rep->SetBinContent( i, binHeight );
244 m_rep->SetBinError( i, binError );
245 }
246 Stat_t allEntries;
247 s >> allEntries;
248 m_rep->SetEntries( allEntries );
249 Stat_t stats[4]; // stats array
250 s >> stats[0] >> stats[1] >> stats[2] >> stats[3];
251 m_rep->PutStats( stats );
252 return s;
253}
254
256 // DataObject::serialize(s);
257 s << static_cast<int>( annotation().size() );
258 for ( int i = 0; i < annotation().size(); i++ ) {
259 s << annotation().key( i );
260 s << annotation().value( i );
261 }
262 const AIDA::IAxis& axis( this->axis() );
263 const int isFixedBinning = axis.isFixedBinning();
264 const int bins = axis.bins();
265 s << isFixedBinning << bins;
266 if ( isFixedBinning ) {
267 s << axis.lowerEdge();
268 } else {
269 for ( int i = 0; i < bins; ++i ) s << axis.binLowerEdge( i );
270 }
271 s << axis.upperEdge();
272 for ( int i = 0; i <= bins + 1; ++i ) s << m_rep->GetBinContent( i ) << m_rep->GetBinError( i );
273
274 s << m_rep->GetEntries();
275 Stat_t stats[4]; // stats array
276 m_rep->GetStats( stats );
277 s << stats[0] << stats[1] << stats[2] << stats[3];
278 return s;
279}
AIDA::IAnnotation & annotation() override
Definition Generic1D.h:73
int binEntries(int index) const override
Number of entries in the corresponding bin (ie the number of times fill was called for this bin).
std::string title() const override
Definition Generic1D.h:65
double binHeight(int index) const override
Definition Generic1D.h:173
virtual double equivalentBinEntries() const
Definition Generic1D.h:194
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
void * cast(const std::string &cl) const override
Manual cast by class name.
bool setTitle(const std::string &title) override
Definition Generic1D.h:148
Generic1D< AIDA::IHistogram1D, TH1D > Base
Definition Generic1D.h:47
double binError(int index) const override
Definition Generic1D.h:178
virtual int rIndex(int index) const
Definition Generic1D.h:112
AIDA implementation for 1 D histograms using ROOT THD1.
Definition H1D.h:31
StreamBuffer & serialize(StreamBuffer &s)
Serialization mechanism, Serialize the object for reading.
Definition H1D.cpp:212
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
Definition H1D.cpp:108
Histogram1D()
Standard constructor.
Definition H1D.cpp:73
double m_sumwx
cache sumwx when setting contents since I don't have bin mean
Definition H1D.h:38
bool setRms(double rms)
Update histogram RMS.
Definition H1D.cpp:125
std::mutex m_fillSerialization
Definition H1D.h:80
bool reset() override
Definition H1D.cpp:101
void initSums()
Definition H1D.cpp:92
virtual bool setStatistics(int allEntries, double eqBinEntries, double mean, double rms)
set histogram statistics
Definition H1D.cpp:142
void init(const std::string &title, bool initialize_axis=true)
Definition H1D.cpp:81
bool fill(double x, double weight) override
Fill the Profile1D with a value and the corresponding weight.
Definition H1D.cpp:160
virtual bool setBinContents(int i, int entries, double height, double error, double centre)
set bin content (entries and centre are not used )
Definition H1D.cpp:116
void copyFromAida(const AIDA::IHistogram1D &h)
Create new histogram from any AIDA based histogram.
Definition H1D.cpp:167
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
The stream buffer is a small object collecting object data.
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
GAUDI_API ISvcLocator * svcLocator()
T * getRepresentation(const Q &hist)
std::pair< DataObject *, AIDA::IHistogram1D * > createH1D(ISvcLocator *svcLocator, const std::string &path, const AIDA::IHistogram1D &hist)
Copy constructor.
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.
Definition ParticleID.h:191