The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
H3D.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 <Gaudi/MonitoringHub.h>
19#include <GaudiCommonSvc/H3D.h>
23
24#include "GaudiPI.h"
25#include <TH3D.h>
26
27#include <cmath>
28
29namespace Gaudi {
30 template <>
32 TH3D* imp = dynamic_cast<TH3D*>( rep );
33 if ( !imp ) throw std::runtime_error( "Cannot adopt native histogram representation." );
34 m_rep.reset( imp );
35 m_xAxis.initialize( m_rep->GetXaxis(), true );
36 m_yAxis.initialize( m_rep->GetYaxis(), true );
37 m_zAxis.initialize( m_rep->GetZaxis(), true );
38 const TArrayD* a = m_rep->GetSumw2();
39 if ( !a || ( a && a->GetSize() == 0 ) ) m_rep->Sumw2();
40 setTitle( m_rep->GetTitle() );
41 }
42} // namespace Gaudi
43
45std::pair<DataObject*, AIDA::IHistogram3D*> Gaudi::createH3D( ISvcLocator* svcLocator, const std::string& path,
46 const std::string& title, int nBinsX, double xlow,
47 double xup, int nBinsY, double ylow, double yup,
48 int nBinsZ, double zlow, double zup ) {
49 auto p = new Histogram3D(
50 new TH3D( title.c_str(), title.c_str(), nBinsX, xlow, xup, nBinsY, ylow, yup, nBinsZ, zlow, zup ) );
51 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
52 return { p, p };
53}
54
56std::pair<DataObject*, AIDA::IHistogram3D*> Gaudi::createH3D( ISvcLocator* svcLocator, const std::string& path,
57 const std::string& title, const Edges& eX,
58 const Edges& eY, const Edges& eZ ) {
59 auto p = new Histogram3D( new TH3D( title.c_str(), title.c_str(), eX.size() - 1, &eX.front(), eY.size() - 1,
60 &eY.front(), eZ.size() - 1, &eZ.front() ) );
61 svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *p );
62 return { p, p };
63}
64
65std::pair<DataObject*, AIDA::IHistogram3D*> Gaudi::createH3D( ISvcLocator* svcLocator, const std::string& path,
66 const AIDA::IHistogram3D& hist ) {
68 Histogram3D* n = h ? new Histogram3D( new TH3D( *h ) ) : nullptr;
69 if ( n ) { svcLocator->monitoringHub().registerEntity( "", path, "histogram:Histogram:double", *n ); }
70 return { n, n };
71}
72
74 setTitle( "" );
75 m_rep->Sumw2();
76 m_sumwx = 0;
77 m_sumwy = 0;
78 m_sumwz = 0;
79 m_rep->SetDirectory( nullptr );
80}
81
84 m_sumwx = 0;
85 m_sumwy = 0;
86 m_sumwz = 0;
87 m_rep->SetDirectory( nullptr );
88}
89
90// set bin content (entries and centre are not used )
91bool Gaudi::Histogram3D::setBinContents( int i, int j, int k, int entries, double height, double error, double centreX,
92 double centreY, double centreZ ) {
93 m_rep->SetBinContent( rIndexX( i ), rIndexY( j ), rIndexZ( k ), height );
94 m_rep->SetBinError( rIndexX( i ), rIndexY( j ), rIndexZ( k ), error );
95 // accumulate sum bin centers
96 if ( i >= 0 && j >= 0 && k >= 0 ) {
97 m_sumwx += centreX * height;
98 m_sumwy += centreY * height;
99 m_sumwz += centreZ * height;
100 }
102 return true;
103}
104
106 m_sumwx = 0;
107 m_sumwy = 0;
108 m_sumwz = 0;
109 m_sumEntries = 0;
110 m_rep->Reset();
111 return true;
112}
113
114bool Gaudi::Histogram3D::fill( double x, double y, double z, double weight ) {
115 // avoid race conditiosn when filling the histogram
116 auto guard = std::scoped_lock{ m_fillSerialization };
117 m_rep->Fill( x, y, z, weight );
118 return true;
119}
120
121void* Gaudi::Histogram3D::cast( const std::string& className ) const {
122 if ( className == "AIDA::IHistogram3D" ) {
123 return (AIDA::IHistogram3D*)this;
124 } else if ( className == "AIDA::IHistogram" ) {
125 return (AIDA::IHistogram*)this;
126 }
127 return nullptr;
128}
129
130bool Gaudi::Histogram3D::setRms( double rmsX, double rmsY, double rmsZ ) {
131 m_rep->SetEntries( m_sumEntries );
132 std::vector<double> stat( 11 );
133 // sum weights
134 stat[0] = sumBinHeights();
135 stat[1] = 0;
136 if ( std::abs( equivalentBinEntries() ) > std::numeric_limits<double>::epsilon() )
137 stat[1] = ( sumBinHeights() * sumBinHeights() ) / equivalentBinEntries();
138 stat[2] = m_sumwx;
139 stat[4] = m_sumwy;
140 stat[6] = 0;
141 stat[7] = m_sumwz;
142 double meanX = 0;
143 double meanY = 0;
144 double meanZ = 0;
145 if ( std::abs( sumBinHeights() ) > std::numeric_limits<double>::epsilon() ) {
149 }
150 stat[3] = ( meanX * meanX + rmsX * rmsX ) * sumBinHeights();
151 stat[5] = ( meanY * meanY + rmsY * rmsY ) * sumBinHeights();
152 stat[8] = ( meanZ * meanZ + rmsZ * rmsZ ) * sumBinHeights();
153 // do not need to use sumwxy sumwxz and sumwyz
154 m_rep->PutStats( &stat.front() );
155 return true;
156}
157
158void Gaudi::Histogram3D::copyFromAida( const AIDA::IHistogram3D& h ) {
159 // implement here the copy
160 std::string titlestr = h.title();
161 const char* title = titlestr.c_str();
162 if ( h.xAxis().isFixedBinning() && h.yAxis().isFixedBinning() && h.zAxis().isFixedBinning() ) {
163 m_rep = std::make_unique<TH3D>( title, title, h.xAxis().bins(), h.xAxis().lowerEdge(), h.xAxis().upperEdge(),
164 h.yAxis().bins(), h.yAxis().lowerEdge(), h.yAxis().upperEdge(), h.zAxis().bins(),
165 h.zAxis().lowerEdge(), h.zAxis().upperEdge() );
166 } else {
167 Edges eX, eY, eZ;
168 for ( int i = 0; i < h.xAxis().bins(); ++i ) eX.push_back( h.xAxis().binLowerEdge( i ) );
169 // add also upperedges at the end
170 eX.push_back( h.xAxis().upperEdge() );
171 for ( int i = 0; i < h.yAxis().bins(); ++i ) eY.push_back( h.yAxis().binLowerEdge( i ) );
172 // add also upperedges at the end
173 eY.push_back( h.yAxis().upperEdge() );
174 for ( int i = 0; i < h.zAxis().bins(); ++i ) eZ.push_back( h.zAxis().binLowerEdge( i ) );
175 // add also upperedges at the end
176 eZ.push_back( h.zAxis().upperEdge() );
177 m_rep.reset(
178 new TH3D( title, title, eX.size() - 1, &eX.front(), eY.size() - 1, &eY.front(), eZ.size() - 1, &eZ.front() ) );
179 }
180 m_xAxis.initialize( m_rep->GetXaxis(), true );
181 m_yAxis.initialize( m_rep->GetYaxis(), true );
182 m_zAxis.initialize( m_rep->GetZaxis(), true );
183 const TArrayD* a = m_rep->GetSumw2();
184 if ( !a || ( a && a->GetSize() == 0 ) ) m_rep->Sumw2();
185 m_sumEntries = 0;
186 m_sumwx = 0;
187 m_sumwy = 0;
188 m_sumwz = 0;
189
190 // statistics
191 double sumw = h.sumBinHeights();
192 double sumw2 = 0;
193 if ( std::abs( h.equivalentBinEntries() ) > std::numeric_limits<double>::epsilon() )
194 sumw2 = ( sumw * sumw ) / h.equivalentBinEntries();
195 double sumwx = h.meanX() * h.sumBinHeights();
196 double sumwx2 = ( h.meanX() * h.meanX() + h.rmsX() * h.rmsX() ) * h.sumBinHeights();
197 double sumwy = h.meanY() * h.sumBinHeights();
198 double sumwy2 = ( h.meanY() * h.meanY() + h.rmsY() * h.rmsY() ) * h.sumBinHeights();
199 double sumwz = h.meanZ() * h.sumBinHeights();
200 double sumwz2 = ( h.meanZ() * h.meanZ() + h.rmsZ() * h.rmsZ() ) * h.sumBinHeights();
201 double sumwxy = 0;
202 double sumwxz = 0;
203 double sumwyz = 0;
204
205 // copy the contents in (AIDA underflow/overflow are -2,-1)
206 for ( int i = -2; i < xAxis().bins(); ++i ) {
207 for ( int j = -2; j < yAxis().bins(); ++j ) {
208 for ( int k = -2; k < zAxis().bins(); ++k ) {
209 m_rep->SetBinContent( rIndexX( i ), rIndexY( j ), rIndexZ( k ), h.binHeight( i, j, k ) );
210 m_rep->SetBinError( rIndexX( i ), rIndexY( j ), rIndexZ( k ), h.binError( i, j, k ) );
211 // calculate statistics
212 if ( i >= 0 && j >= 0 && k >= 0 ) {
213 sumwxy += h.binHeight( i, j, k ) * h.binMeanX( i, j, k ) * h.binMeanY( i, j, k );
214 sumwxz += h.binHeight( i, j, k ) * h.binMeanX( i, j, k ) * h.binMeanZ( i, j, k );
215 sumwyz += h.binHeight( i, j, k ) * h.binMeanY( i, j, k ) * h.binMeanZ( i, j, k );
216 }
217 }
218 }
219 }
220 // need to do set entries after setting contents otherwise root will recalulate them
221 // taking into account how many time SetBinContents() has been called
222 m_rep->SetEntries( h.allEntries() );
223
224 // fill stat vector
225 std::vector<double> stat( 11 );
226 stat[0] = sumw;
227 stat[1] = sumw2;
228 stat[2] = sumwx;
229 stat[3] = sumwx2;
230 stat[4] = sumwy;
231 stat[5] = sumwy2;
232 stat[6] = sumwxy;
233 stat[7] = sumwz;
234 stat[8] = sumwz2;
235 stat[9] = sumwxz;
236 stat[10] = sumwyz;
237 m_rep->PutStats( &stat.front() );
238}
const AIDA::IAxis & zAxis() const override
Definition Generic3D.h:184
Generic3D< AIDA::IHistogram3D, TH3D > Base
Definition Generic3D.h:47
double equivalentBinEntries() const override
Definition Generic3D.h:281
std::string title() const override
Definition Generic3D.h:64
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
const AIDA::IAxis & yAxis() const override
Definition Generic3D.h:182
const AIDA::IAxis & xAxis() const override
Definition Generic3D.h:180
bool setTitle(const std::string &title) override
Definition Generic3D.h:237
AIDA implementation for 3 D histograms using ROOT THD2.
Definition H3D.h:29
double m_sumwy
Definition H3D.h:60
virtual bool setBinContents(int i, int j, int k, int entries, double height, double error, double centreX, double centreY, double centreZ)
Fast filling method for a given bin. It can be also the over/underflow bin.
Definition H3D.cpp:91
bool reset() override
Definition H3D.cpp:105
virtual bool setRms(double rmsX, double rmsY, double rmsZ)
Sets the rms of the histogram.
Definition H3D.cpp:130
void * cast(const std::string &className) const override
Introspection method.
Definition H3D.cpp:121
Histogram3D()
Standard Constructor.
Definition H3D.cpp:73
void copyFromAida(const AIDA::IHistogram3D &h)
Create new histogram from any AIDA based histogram.
Definition H3D.cpp:158
std::mutex m_fillSerialization
Definition H3D.h:64
double m_sumwz
Definition H3D.h:61
double m_sumwx
Definition H3D.h:59
bool fill(double x, double y, double z, double weight) override
Fill bin content.
Definition H3D.cpp:114
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Gaudi::Monitoring::Hub & monitoringHub()
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::IHistogram3D * > createH3D(ISvcLocator *svcLocator, const std::string &path, const AIDA::IHistogram3D &hist)
Copy constructor.
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.
Definition ParticleID.h:191
void registerEntity(std::string c, std::string n, std::string t, T &ent)