ATLAS Offline Software
Flex1DHisto.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "RVersion.h"
6 
7 //____________________________________________________________________
8 template <class T>
9 inline Flex1DHisto<T> * Flex1DHisto<T>::create(unsigned nbins, const double& xmin, const double& xmax)
10 {
11  return new(LWPools::acquire(sizeof(Flex1DHisto<T>)+extraAllocSize(nbins))) Flex1DHisto<T>(nbins,xmin,xmax);
12 }
13 
14 //____________________________________________________________________
15 template <class T>
16 template <class TFloat>
17 inline Flex1DHisto<T> * Flex1DHisto<T>::create(unsigned nbins, const TFloat* xbins )
18 {
19  return new(LWPools::acquire(sizeof(Flex1DHisto<T>)+extraAllocSize(nbins))) Flex1DHisto<T>(nbins,xbins);
20 }
21 
22 //____________________________________________________________________
23 template <class T>
24 inline void Flex1DHisto<T>::destroy(Flex1DHisto<T> *h)
25 {
26  if (h) {
27  unsigned nx = h->getNBins();
28  h->~Flex1DHisto<T>();
29  LWPools::release(reinterpret_cast<char*>(h),sizeof(Flex1DHisto<T>)+extraAllocSize(nx));
30  }
31 }
32 
33 //____________________________________________________________________
34 template <class T>
35 inline Flex1DHisto<T>::Flex1DHisto( unsigned nbins,
36  const double& xmin, const double& xmax )
37  : m_invDelta(nbins/(xmax-xmin)),
38  m_sumW(0),
39  m_sumW2(0),
40  m_sumWX(0),
41  m_sumWX2(0),
42  m_nEntries(0),
43  m_nbinsPlus1(nbins+1),
44  m_xmin(xmin),
45  m_xmax(xmax),
46  m_varBins(0),
47  m_flexArray(nbins+2)
48 {
49  assert(xmin<xmax);
50  assert(nbins>0);
51 }
52 
53 //____________________________________________________________________
54 template <class T>
55 template <class TFloat>
56 inline Flex1DHisto<T>::Flex1DHisto( unsigned nbins, const TFloat* xbins )
57  : m_invDelta(nbins/(xbins[nbins]-xbins[0])),
58  m_sumW(0),
59  m_sumW2(0),
60  m_sumWX(0),
61  m_sumWX2(0),
62  m_nEntries(0),
63  m_nbinsPlus1(nbins+1),
64  m_xmin(xbins[0]),
65  m_xmax(xbins[nbins]),
66  m_varBins(LWPools::acquire<float>(nbins+1)),
67  m_flexArray(nbins+2)
68 {
69  assert(xbins);
70  assert(m_xmin<m_xmax);
71  assert(nbins>0);
72 #ifndef NDEBUG
73  for (unsigned i = 0; i<nbins;++i)
74  assert(xbins[i]<xbins[i+1]);
75 #endif
76  for (unsigned i = 0; i<m_nbinsPlus1;++i)
77  m_varBins[i]=xbins[i];
78 }
79 
80 //____________________________________________________________________
81 template <class T>
82 inline Flex1DHisto<T>::~Flex1DHisto()
83 {
84  if (m_varBins)
85  LWPools::release(m_varBins,m_nbinsPlus1);
86 }
87 
88 //____________________________________________________________________
89 template <class T>
90 inline unsigned Flex1DHisto<T>::valueToBin(const double& x) const
91 {
92  return LWBinUtils::valueToBin( x, m_varBins, m_invDelta,m_xmin, m_xmax,m_nbinsPlus1 );
93 }
94 
95 //____________________________________________________________________
96 template <class T>
97 inline double Flex1DHisto<T>::getBinCenter(int bin) const
98 {
99  return LWBinUtils::getBinCenter( bin, m_varBins,m_invDelta, m_xmin,m_nbinsPlus1);
100 }
101 
102 //____________________________________________________________________
103 template <class T>
104 inline void Flex1DHisto<T>::fill(const double& x)
105 {
106  //Fixme: make sure that we always abort on nan's (in non-strict-root mode)
107  unsigned bin = valueToBin(x);
108 #ifndef NDEBUG
109  if (bin==USHRT_MAX)
110  return;
111 #endif
112  m_flexArray.fill(bin);
113  //Update stats (sums not for over/under flow):
114  ++m_nEntries;
115  if (bin>0&&bin<m_nbinsPlus1) {
116  ++m_sumW;
117  ++m_sumW2;
118  m_sumWX += x;
119  m_sumWX2 += x*x;
120  }
121 }
122 
123 //____________________________________________________________________
124 template <class T>
125 inline void Flex1DHisto<T>::fill(const double& x, const double& w)
126 {
127 #ifndef NDEBUG
128  if (w!=w) {
129  std::cout<<"LWHisto: Saw NaN in fill weight"<<std::endl;
130  return;
131  }
132 #endif
133  unsigned bin = valueToBin(x);
134 #ifndef NDEBUG
135  if (bin==USHRT_MAX)
136  return;
137 #endif
138  m_flexArray.fill(bin,w);
139  //Update stats (sums not for over/under flow):
140  ++m_nEntries;
141  if (bin>0&&bin<m_nbinsPlus1) {
142  //NB: root used to use fabs(w) instead of w in the formulas below:
143  m_sumW += w;
144  m_sumW2 += w*w;
145  double z(w*x);
146  m_sumWX += z;
147  m_sumWX2 += z*x;
148  }
149 }
150 
151 //____________________________________________________________________
152 template <class T>
153 inline unsigned Flex1DHisto<T>::getEntries() const
154 {
155  return m_nEntries;
156 }
157 
158 //____________________________________________________________________
159 template <class T>
160 inline void Flex1DHisto<T>::setEntries(unsigned n)
161 {
162  m_nEntries = n;
163 }
164 
165 //____________________________________________________________________
166 template <class T>
167 inline double Flex1DHisto<T>::getSumW() const
168 {
169  return m_sumW;
170 }
171 
172 //____________________________________________________________________
173 template <class T>
174 inline double Flex1DHisto<T>::getSumW2() const
175 {
176  return m_sumW2;
177 }
178 
179 //____________________________________________________________________
180 template <class T>
181 inline double Flex1DHisto<T>::getSumWX() const
182 {
183  return m_sumWX;
184 }
185 
186 //____________________________________________________________________
187 template <class T>
188 inline double Flex1DHisto<T>::getSumWX2() const
189 {
190  return m_sumWX2;
191 }
192 
193 //____________________________________________________________________
194 template <class T>
195 inline void Flex1DHisto<T>::setSums( const double& sumW,
196  const double& sumW2,
197  const double& sumWX,
198  const double& sumWX2 )
199 {
200  m_sumW = sumW;
201  m_sumW2 = sumW2;
202  m_sumWX = sumWX;
203  m_sumWX2 = sumWX2;
204 }
205 
206 //____________________________________________________________________
207 template <class T>
208 inline void Flex1DHisto<T>::copyContents(T*__restrict__ cont, double*__restrict__ err) const
209 {
210  m_flexArray.copyContents(cont,err);
211 }
212 
213 //____________________________________________________________________
214 template <class T>
215 inline double Flex1DHisto<T>::Integral() const
216 {
217  return m_flexArray.Integral()-m_flexArray.getBinContent(0)-m_flexArray.getBinContent(m_nbinsPlus1);
218 }
219 
220 //____________________________________________________________________
221 template <class T>
222 inline bool Flex1DHisto<T>::holdsSeparateSumW2Info() const
223 {
224  return m_flexArray.holdsSeparateSumW2Info();
225 }
226 
227 //____________________________________________________________________
228 template <class T>
229 inline double Flex1DHisto<T>::getBinContent(unsigned bin) const
230 {
231  if (bin>m_nbinsPlus1)
232 #ifdef LW_STRICT_ROOT_BEHAVIOUR
233  bin = m_nbinsPlus1;
234 #else
235  return 0.0;
236 #endif
237  assert(bin<m_nbinsPlus1+1);
238  return m_flexArray.getBinContent(bin);
239 }
240 
241 //____________________________________________________________________
242 template <class T>
243 inline double Flex1DHisto<T>::getBinError(unsigned bin) const
244 {
245  if (bin>m_nbinsPlus1)
246 #ifdef LW_STRICT_ROOT_BEHAVIOUR
247  bin = m_nbinsPlus1;
248 #else
249  return 0.0;
250 #endif
251  assert(bin<m_nbinsPlus1+1);
252  return m_flexArray.getBinError(bin);
253 }
254 
255 //____________________________________________________________________
256 template <class T>
257 inline void Flex1DHisto<T>::getBinContentAndError(unsigned bin, double& cont, double& err ) const
258 {
259  //float/integer version
260  if (bin>m_nbinsPlus1)
261 #ifdef LW_STRICT_ROOT_BEHAVIOUR
262  bin = m_nbinsPlus1;
263 #else
264  return;
265 #endif
266  assert(bin<m_nbinsPlus1+1);
267  T tmp;
268  m_flexArray.getBinContentAndError(bin,tmp,err);
269  cont = static_cast<double>(tmp);
270 }
271 
272 //____________________________________________________________________
273 template <>
274 inline void Flex1DHisto<double>::getBinContentAndError(unsigned bin, double& cont, double& err ) const
275 {
276  //double version
277  if (bin>m_nbinsPlus1) {
278 #ifdef LW_STRICT_ROOT_BEHAVIOUR
279  bin = m_nbinsPlus1;
280 #else
281  cont = 0;
282  err = 0;
283  return;
284 #endif
285  }
286  assert(bin<m_nbinsPlus1+1);
287  m_flexArray.getBinContentAndError(bin,cont,err);
288 }
289 
290 //____________________________________________________________________
291 template <class T>
292 inline void Flex1DHisto<T>::setBinContent(unsigned bin, const double& c)
293 {
294  if (bin>m_nbinsPlus1)
295  return;
296  assert(bin<m_nbinsPlus1+1);
297  m_flexArray.setBinContent(bin,static_cast<T>(c));
298 #ifdef LW_STRICT_ROOT_BEHAVIOUR
299  if (bin==m_nbinsPlus1)//inconsistent root behaviour for last bin...
300  return;
301 #endif
302  ++m_nEntries;
303  m_sumW = 0;//As in ROOT
304 }
305 
306 //____________________________________________________________________
307 template <class T>
308 inline void Flex1DHisto<T>::setBinError(unsigned bin, const double& e)
309 {
310  if (bin>m_nbinsPlus1) {//as in root
311  return;
312  }
313  assert(bin<m_nbinsPlus1+1);
314  m_flexArray.setBinError(bin,e);
315 }
316 
317 //____________________________________________________________________
318 template <class T>
319 inline void Flex1DHisto<T>::setBinContentAndError(unsigned bin, const double& cont, const double& err )
320 {
321  if (bin>m_nbinsPlus1) {//as in root
322  return;
323  }
324  assert(bin<m_nbinsPlus1+1);
325  m_flexArray.setBinContentAndError(bin,static_cast<T>(cont),err);
326 #ifdef LW_STRICT_ROOT_BEHAVIOUR
327  if (bin==m_nbinsPlus1)//inconsistent root behaviour for last bin...
328  return;
329 #endif
330  ++m_nEntries;
331  m_sumW = 0;//As in ROOT
332 }
333 
334 //____________________________________________________________________
335 template <class T>
336 inline void Flex1DHisto<T>::resetActiveBinLoop()
337 {
338  m_flexArray.resetActiveBinLoop();
339 }
340 
341 //____________________________________________________________________
342 template <class T>
343 inline bool Flex1DHisto<T>::getNextActiveBin(unsigned& bin, double& content, double& error)
344 {
345  //float/integer version
346  T tmp(0);//init to avoid gcc43 warning.
347  bool b = m_flexArray.getNextActiveBin(bin,tmp,error);
348  content = static_cast<double>(tmp);
349  return b;
350 }
351 
352 //____________________________________________________________________
353 template <>
354 inline bool Flex1DHisto<double>::getNextActiveBin(unsigned& bin, double& content, double& error)
355 {
356  //double version
357  return m_flexArray.getNextActiveBin(bin,content,error);
358 }
359 
360 //____________________________________________________________________
361 template <class T>
362 inline void Flex1DHisto<T>::scaleContentsAndErrors( const double& fact )
363 {
364  m_sumW *= fact;
365  m_sumW2 *= fact*fact;
366  m_sumWX *= fact;
367  m_sumWX2 *= fact;
368  m_flexArray.scaleContentsAndErrors(fact);
369 }
370 
371 
372 #ifdef LW_DEBUG_HEAVY_USERS
373 
374 //____________________________________________________________________
375 template <class T>
376 inline void Flex1DHisto<T>::countCall(const std::pair<void*,void*>&addresses)
377 {
378  std::map<std::pair<void*,void*>,unsigned long>::iterator it = m_callmap.find(addresses);
379  if (it==m_callmap.end())
380  m_callmap[addresses]=0;
381  else
382  ++(it->second);
383 }
384 
385 //____________________________________________________________________
386 template <class T>
387 inline void Flex1DHisto<T>::produceReport(const char*histname)
388 {
389  std::map<std::pair<void*,void*>,unsigned long>::iterator it,itE(m_callmap.end());
390  for(it=m_callmap.begin();it!=itE;++it) {
391  if (it->second>0) {
392  const char * caller = LWHistTraceUtils::getSymbol(it->first.second);
393  const char * calledmethod = LWHistTraceUtils::getSymbol(it->first.first);
394  std::cout<<"LWHists WARNING: Method in histogram called "<<it->second<<" times: "<<calledmethod<<" from "<<caller<<" (histogram named \""<<histname<<"\")"<<std::endl;
395  //fixme: do free on caller and calledmethod
396  }
397  }
398 }
399 
400 #endif