The Gaudi Framework master (1fbcc22a)
Loading...
Searching...
No Matches
H1D.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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
12// Local includes
13#include "GaudiPI.h"
14
15// Framework includes
16#include <Gaudi/MonitoringHub.h>
17#include <GaudiCommonSvc/H1D.h>
21
22// STL includes
23#include <cmath>
24
26 const std::string& title, int nBins, double xlow,
27 double xup ) {
28 auto p = new Histogram1D( new TH1D( title.c_str(), title.c_str(), nBins, xlow, xup ) );
29 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
30 return { p, p };
31}
32
34 const std::string& title, const Edges& e ) {
35 auto p = new Histogram1D( new TH1D( title.c_str(), title.c_str(), e.size() - 1, &e.front() ) );
36 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
37 return { p, p };
38}
39
41 const AIDA::IHistogram1D& hist ) {
43 auto n = ( h ? new Histogram1D( new TH1D( *h ) ) : nullptr );
44 if ( n ) { svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *n ); }
45 return { n, n };
46}
47
48namespace Gaudi {
49
50 template <>
51 void* Generic1D<AIDA::IHistogram1D, TH1D>::cast( const std::string& className ) const {
52 if ( className == "AIDA::IHistogram1D" ) return const_cast<AIDA::IHistogram1D*>( (AIDA::IHistogram1D*)this );
53 if ( className == "AIDA::IHistogram" ) return const_cast<AIDA::IHistogram*>( (AIDA::IHistogram*)this );
54 return nullptr;
55 }
56
57 template <>
59 if ( binHeight( index ) <= 0 ) return 0;
60 double xx = binHeight( index ) / binError( index );
61 return int( xx * xx + 0.5 );
62 }
63
64 template <>
66 TH1D* imp = dynamic_cast<TH1D*>( rep );
67 if ( !imp ) throw std::runtime_error( "Cannot adopt native histogram representation." );
68 m_rep.reset( imp );
69 }
70} // namespace Gaudi
71
72Gaudi::Histogram1D::Histogram1D() : Base( new TH1D() ) { init( "", false ); }
73
75 m_rep.reset( rep );
76 init( m_rep->GetTitle() );
77 initSums();
78}
79
80void Gaudi::Histogram1D::init( const std::string& title, bool initialize_axis ) {
81 m_classType = "IHistogram1D";
82 if ( initialize_axis ) { m_axis.initialize( m_rep->GetXaxis(), false ); }
83 const TArrayD* a = m_rep->GetSumw2();
84 if ( !a || ( a && a->GetSize() == 0 ) ) m_rep->Sumw2();
85 setTitle( title );
86 m_rep->SetDirectory( nullptr );
87 m_sumEntries = 0;
88 m_sumwx = 0;
89}
90
92 m_sumwx = 0;
93 m_sumEntries = 0;
94 for ( int i = 1, n = m_rep->GetNbinsX(); i <= n; ++i ) {
95 m_sumwx += m_rep->GetBinContent( i ) * m_rep->GetBinCenter( i );
96 m_sumEntries += m_rep->GetBinContent( i );
97 }
98}
99
101 m_sumwx = 0;
102 m_sumEntries = 0;
103 return Base::reset();
104}
105
109 if ( m_rep ) {
110 init( m_rep->GetTitle() );
111 initSums();
112 }
113}
114
115bool Gaudi::Histogram1D::setBinContents( int i, int entries, double height, double error, double centre ) {
116 m_rep->SetBinContent( rIndex( i ), height );
117 m_rep->SetBinError( rIndex( i ), error );
118 // accumulate sumwx for in range bins
119 if ( i != AIDA::IAxis::UNDERFLOW_BIN && i != AIDA::IAxis::OVERFLOW_BIN ) m_sumwx += centre * height;
121 return true;
122}
123
125 m_rep->SetEntries( m_sumEntries );
126 std::vector<double> stat( 11 );
127 // sum weights
128 stat[0] = sumBinHeights();
129 stat[1] = 0;
131 stat[1] = ( sumBinHeights() * sumBinHeights() ) / equivalentBinEntries();
132 stat[2] = m_sumwx;
133 double mean = 0;
135 stat[3] = ( mean * mean + rms * rms ) * sumBinHeights();
136 m_rep->PutStats( &stat.front() );
137 return true;
138}
139
140// set histogram statistics
141bool Gaudi::Histogram1D::setStatistics( int allEntries, double eqBinEntries, double mean, double rms ) {
142 m_rep->SetEntries( allEntries );
143 // fill statistcal vector for Root
144 std::vector<double> stat( 11 );
145 // sum weights
146 stat[0] = sumBinHeights();
147 // sum weights **2
148 stat[1] = 0;
149 if ( std::abs( eqBinEntries ) > std::numeric_limits<double>::epsilon() )
150 stat[1] = ( sumBinHeights() * sumBinHeights() ) / eqBinEntries;
151 // sum weights * x
152 stat[2] = mean * sumBinHeights();
153 // sum weight * x **2
154 stat[3] = ( mean * mean + rms * rms ) * sumBinHeights();
155 m_rep->PutStats( &stat.front() );
156 return true;
157}
158
159bool Gaudi::Histogram1D::fill( double x, double weight ) {
160 // avoid race conditions when filling the histogram
161 auto guard = std::scoped_lock{ m_fillSerialization };
162 m_rep->Fill( x, weight );
163 return true;
164}
165
166void Gaudi::Histogram1D::copyFromAida( const AIDA::IHistogram1D& h ) {
167 // implement here the copy
168 std::string title = h.title() + "Copy";
169 if ( h.axis().isFixedBinning() ) {
170 m_rep.reset(
171 new TH1D( title.c_str(), title.c_str(), h.axis().bins(), h.axis().lowerEdge(), h.axis().upperEdge() ) );
172 } else {
173 Edges e;
174 for ( int i = 0; i < h.axis().bins(); ++i ) { e.push_back( h.axis().binLowerEdge( i ) ); }
175 // add also upperedges at the end
176 e.push_back( h.axis().upperEdge() );
177 m_rep.reset( new TH1D( title.c_str(), title.c_str(), e.size() - 1, &e.front() ) );
178 }
179 m_axis.initialize( m_rep->GetXaxis(), false );
180 m_rep->Sumw2();
181 m_sumEntries = 0;
182 m_sumwx = 0;
183 // sumw
184 double sumw = h.sumBinHeights();
185 // sumw2
186 double sumw2 = 0;
187 if ( std::abs( h.equivalentBinEntries() ) > std::numeric_limits<double>::epsilon() )
188 sumw2 = ( sumw * sumw ) / h.equivalentBinEntries();
189
190 double sumwx = h.mean() * h.sumBinHeights();
191 double sumwx2 = ( h.mean() * h.mean() + h.rms() * h.rms() ) * h.sumBinHeights();
192
193 // copy the contents in
194 for ( int i = -2; i < axis().bins(); ++i ) {
195 // root binning starts from one !
196 m_rep->SetBinContent( rIndex( i ), h.binHeight( i ) );
197 m_rep->SetBinError( rIndex( i ), h.binError( i ) );
198 }
199 // need to do set entries after setting contents otherwise root will recalulate them
200 // taking into account how many time SetBinContents() has been called
201 m_rep->SetEntries( h.allEntries() );
202 // stat vector
203 std::vector<double> stat( 11 );
204 stat[0] = sumw;
205 stat[1] = sumw2;
206 stat[2] = sumwx;
207 stat[3] = sumwx2;
208 m_rep->PutStats( &stat.front() );
209}
210
212 // DataObject::serialize(s);
213 std::string title;
214 int size;
215 s >> size;
216 for ( int j = 0; j < size; j++ ) {
217 std::string key, value;
218 s >> key >> value;
219 if ( !annotation().addItem( key, value ) ) { annotation().setValue( key, value ); };
220 if ( "Title" == key ) { title = value; }
221 }
222 double lowerEdge, upperEdge, binHeight, binError;
223 int isFixedBinning, bins;
224 s >> isFixedBinning >> bins;
225
226 if ( isFixedBinning ) {
227 s >> lowerEdge >> upperEdge;
228 m_rep.reset( new TH1D( title.c_str(), title.c_str(), bins, lowerEdge, upperEdge ) );
229 } else {
230 Edges edges;
231 edges.resize( bins );
232 for ( int i = 0; i <= bins; ++i ) s >> edges[i];
233 m_rep.reset( new TH1D( title.c_str(), title.c_str(), edges.size() - 1, &edges.front() ) );
234 }
235 m_axis.initialize( m_rep->GetXaxis(), true );
236 m_rep->Sumw2();
237 m_sumEntries = 0;
238 m_sumwx = 0;
239
240 for ( int i = 0; i <= bins + 1; ++i ) {
241 s >> binHeight >> binError;
242 m_rep->SetBinContent( i, binHeight );
243 m_rep->SetBinError( i, binError );
244 }
245 Stat_t allEntries;
246 s >> allEntries;
247 m_rep->SetEntries( allEntries );
248 Stat_t stats[4]; // stats array
249 s >> stats[0] >> stats[1] >> stats[2] >> stats[3];
250 m_rep->PutStats( stats );
251 return s;
252}
253
255 // DataObject::serialize(s);
256 s << static_cast<int>( annotation().size() );
257 for ( int i = 0; i < annotation().size(); i++ ) {
258 s << annotation().key( i );
259 s << annotation().value( i );
260 }
261 const AIDA::IAxis& axis( this->axis() );
262 const int isFixedBinning = axis.isFixedBinning();
263 const int bins = axis.bins();
264 s << isFixedBinning << bins;
265 if ( isFixedBinning ) {
266 s << axis.lowerEdge();
267 } else {
268 for ( int i = 0; i < bins; ++i ) s << axis.binLowerEdge( i );
269 }
270 s << axis.upperEdge();
271 for ( int i = 0; i <= bins + 1; ++i ) s << m_rep->GetBinContent( i ) << m_rep->GetBinError( i );
272
273 s << m_rep->GetEntries();
274 Stat_t stats[4]; // stats array
275 m_rep->GetStats( stats );
276 s << stats[0] << stats[1] << stats[2] << stats[3];
277 return s;
278}
_Tp abs(const complex< _Tp > &)
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
static constexpr _Tp epsilon() noexcept
const _CharT * c_str() const noexcept
constexpr const_reference front() const noexcept
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
StreamBuffer & serialize(StreamBuffer &s)
Serialization mechanism, Serialize the object for reading.
Definition H1D.cpp:211
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
Definition H1D.cpp:107
Histogram1D()
Standard constructor.
Definition H1D.cpp:72
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:124
std::mutex m_fillSerialization
Definition H1D.h:80
bool reset() override
Definition H1D.cpp:100
void initSums()
Definition H1D.cpp:91
virtual bool setStatistics(int allEntries, double eqBinEntries, double mean, double rms)
set histogram statistics
Definition H1D.cpp:141
void init(const std::string &title, bool initialize_axis=true)
Definition H1D.cpp:80
bool fill(double x, double weight) override
Fill the Profile1D with a value and the corresponding weight.
Definition H1D.cpp:159
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:115
void copyFromAida(const AIDA::IHistogram1D &h)
Create new histogram from any AIDA based histogram.
Definition H1D.cpp:166
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Gaudi::Monitoring::Hub & monitoringHub()
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.
void registerEntity(std::string c, std::string n, std::string t, T &ent)