The Gaudi Framework  master (d98a2936)
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 
26 std::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 
34 std::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 
41 std::pair<DataObject*, AIDA::IHistogram1D*> Gaudi::createH1D( ISvcLocator* svcLocator, const std::string& path,
42  const AIDA::IHistogram1D& hist ) {
43  TH1D* h = getRepresentation<AIDA::IHistogram1D, TH1D>( 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 
49 namespace 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 
73 Gaudi::Histogram1D::Histogram1D() : Base( new TH1D() ) { init( "", false ); }
74 
76  m_rep.reset( rep );
77  init( m_rep->GetTitle() );
78  initSums();
79 }
80 
81 void 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 
116 bool 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;
121  m_sumEntries += entries;
122  return true;
123 }
124 
125 bool Gaudi::Histogram1D::setRms( double rms ) {
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
142 bool 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 
160 bool 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 
167 void 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 }
ISvcLocator::monitoringHub
Gaudi::Monitoring::Hub & monitoringHub()
Definition: ISvcLocator.cpp:24
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:23
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
MonitoringHub.h
Gaudi::Histogram1D::Histogram1D
Histogram1D()
Standard constructor.
Definition: H1D.cpp:73
gaudirun.s
string s
Definition: gaudirun.py:346
Gaudi::Histogram1D::fill
bool fill(double x, double weight) override
Fill the Profile1D with a value and the corresponding weight.
Definition: H1D.cpp:160
Gaudi::Generic1D::adoptRepresentation
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
ISvcLocator
Definition: ISvcLocator.h:42
StreamBuffer.h
ObjectFactory.h
Gaudi::Histogram1D::serialize
StreamBuffer & serialize(StreamBuffer &s)
Serialization mechanism, Serialize the object for reading.
Definition: H1D.cpp:212
StreamBuffer
Definition: StreamBuffer.h:48
HistogramUtility.h
Gaudi::Histogram1D::setStatistics
virtual bool setStatistics(int allEntries, double eqBinEntries, double mean, double rms)
set histogram statistics
Definition: H1D.cpp:142
Gaudi::svcLocator
GAUDI_API ISvcLocator * svcLocator()
ProduceConsume.j
j
Definition: ProduceConsume.py:104
Gaudi::Histogram1D::setRms
bool setRms(double rms)
Update histogram RMS.
Definition: H1D.cpp:125
AlgSequencer.h
h
Definition: AlgSequencer.py:31
Gaudi::Histogram1D::reset
bool reset() override
Definition: H1D.cpp:101
GaudiPython.Bindings.nullptr
nullptr
Definition: Bindings.py:87
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(std::string c, std::string n, std::string t, T &ent)
Definition: MonitoringHub.h:137
Gaudi::Histogram1D::init
void init(const std::string &title, bool initialize_axis=true)
Definition: H1D.cpp:81
H1D.h
Gaudi::Histogram1D::setBinContents
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
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::Generic1D::cast
void * cast(const std::string &cl) const override
Manual cast by class name.
GaudiPI.h
Gaudi::Edges
std::vector< double > Edges
Definition: GaudiPI.h:27
Gaudi::Histogram1D::copyFromAida
void copyFromAida(const AIDA::IHistogram1D &h)
Create new histogram from any AIDA based histogram.
Definition: H1D.cpp:167
Gaudi::Histogram1D::adoptRepresentation
void adoptRepresentation(TObject *rep) override
Adopt ROOT histogram representation.
Definition: H1D.cpp:108
Gaudi::Generic1D
Definition: Generic1D.h:45
Gaudi::createH1D
std::pair< DataObject *, AIDA::IHistogram1D * > createH1D(ISvcLocator *svcLocator, const std::string &path, const AIDA::IHistogram1D &hist)
Copy constructor.
Gaudi::Histogram1D::initSums
void initSums()
Definition: H1D.cpp:92
ProduceConsume.key
key
Definition: ProduceConsume.py:84
Gaudi::ParticleProperties::index
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
Definition: IParticlePropertySvc.cpp:39