2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
7 //____________________________________________________________________
9 inline Flex2DHisto<T> * Flex2DHisto<T>::create( unsigned nbinsx, const double& xmin, const double& xmax,
10 unsigned nbinsy, const double& ymin, const double& ymax )
12 return new(LWPools::acquire(sizeof(Flex2DHisto<T>)+extraAllocSize(nbinsx,nbinsy))) Flex2DHisto<T>(nbinsx,xmin,xmax,nbinsy,ymin,ymax);
15 //____________________________________________________________________
17 template <class TFloat>
18 inline Flex2DHisto<T> * Flex2DHisto<T>::create( unsigned nbinsx, const TFloat* xbins,
19 unsigned nbinsy, const double& ymin, const double& ymax )
21 return new(LWPools::acquire(sizeof(Flex2DHisto<T>)+extraAllocSize(nbinsx,nbinsy))) Flex2DHisto<T>(nbinsx,xbins,nbinsy,ymin,ymax);
24 //____________________________________________________________________
26 template <class TFloat>
27 inline Flex2DHisto<T> * Flex2DHisto<T>::create( unsigned nbinsx, const double& xmin, const double& xmax,
28 unsigned nbinsy, const TFloat* ybins )
30 return new(LWPools::acquire(sizeof(Flex2DHisto<T>)+extraAllocSize(nbinsx,nbinsy))) Flex2DHisto<T>(nbinsx,xmin,xmax,nbinsy,ybins);
33 //____________________________________________________________________
35 template <class TFloat>
36 inline Flex2DHisto<T> * Flex2DHisto<T>::create( unsigned nbinsx, const TFloat*xbins,
37 unsigned nbinsy, const TFloat*ybins )
39 return new(LWPools::acquire(sizeof(Flex2DHisto<T>)+extraAllocSize(nbinsx,nbinsy))) Flex2DHisto<T>(nbinsx,xbins,nbinsy,ybins);
42 //____________________________________________________________________
44 inline void Flex2DHisto<T>::destroy(Flex2DHisto<T> *h)
47 unsigned nx = h->getNBinsX();
48 unsigned ny = h->getNBinsY();
50 LWPools::release(reinterpret_cast<char*>(h),sizeof(Flex2DHisto<T>)+extraAllocSize(nx,ny));
54 //____________________________________________________________________
56 inline Flex2DHisto<T>::Flex2DHisto( unsigned nbinsx, const double& xmin, const double& xmax,
57 unsigned nbinsy, const double& ymin, const double& ymax )
58 : m_invDeltaX(nbinsx/(xmax-xmin)),
59 m_invDeltaY(nbinsy/(ymax-ymin)),
68 m_nbinsxPlus1(nbinsx+1),
69 m_nbinsyPlus1(nbinsy+1),
70 m_nbinsxPlus2(nbinsx+2),
77 m_flexArray((nbinsx+2)*(nbinsy+2))
83 assert(getNBinsX()==nbinsx);
84 assert(getNBinsY()==nbinsy);
87 //____________________________________________________________________
89 template <class TFloat>
90 inline Flex2DHisto<T>::Flex2DHisto( unsigned nbinsx, const TFloat*xbins,
91 unsigned nbinsy, const double& ymin, const double& ymax )
92 : m_invDeltaX(nbinsx/(xbins[nbinsx]-xbins[0])),
93 m_invDeltaY(nbinsy/(ymax-ymin)),
102 m_nbinsxPlus1(nbinsx+1),
103 m_nbinsyPlus1(nbinsy+1),
104 m_nbinsxPlus2(nbinsx+2),
106 m_xmax(xbins[nbinsx]),
109 m_varBinsX(LWPools::acquire<float>(nbinsx+1)),
111 m_flexArray((nbinsx+2)*(nbinsy+2))
113 assert(m_xmin<m_xmax);
114 assert(m_ymin<m_ymax);
118 for (unsigned i = 0; i<nbinsx;++i)
119 assert(xbins[i]<xbins[i+1]);
121 for (unsigned i = 0; i<m_nbinsxPlus1;++i)
122 m_varBinsX[i]=xbins[i];
125 //____________________________________________________________________
127 template <class TFloat>
128 inline Flex2DHisto<T>::Flex2DHisto( unsigned nbinsx, const double& xmin, const double& xmax,
129 unsigned nbinsy, const TFloat* ybins )
130 : m_invDeltaX(nbinsx/(xmax-xmin)),
131 m_invDeltaY(nbinsy/(ybins[nbinsy]-ybins[0])),
140 m_nbinsxPlus1(nbinsx+1),
141 m_nbinsyPlus1(nbinsy+1),
142 m_nbinsxPlus2(nbinsx+2),
146 m_ymax(ybins[nbinsy]),
148 m_varBinsY(LWPools::acquire<float>(nbinsy+1)),
149 m_flexArray((nbinsx+2)*(nbinsy+2))
151 assert(m_xmin<m_xmax);
152 assert(m_ymin<m_ymax);
156 for (unsigned i = 0; i<nbinsy;++i)
157 assert(ybins[i]<ybins[i+1]);
159 for (unsigned i = 0; i<m_nbinsyPlus1;++i)
160 m_varBinsY[i]=ybins[i];
162 //____________________________________________________________________
164 template <class TFloat>
165 inline Flex2DHisto<T>::Flex2DHisto( unsigned nbinsx, const TFloat* xbins,
166 unsigned nbinsy, const TFloat* ybins )
167 : m_invDeltaX(nbinsx/(xbins[nbinsx]-xbins[0])),
168 m_invDeltaY(nbinsy/(ybins[nbinsy]-ybins[0])),
177 m_nbinsxPlus1(nbinsx+1),
178 m_nbinsyPlus1(nbinsy+1),
179 m_nbinsxPlus2(nbinsx+2),
181 m_xmax(xbins[nbinsx]),
183 m_ymax(ybins[nbinsy]),
184 m_varBinsX(LWPools::acquire<float>(nbinsx+1)),
185 m_varBinsY(LWPools::acquire<float>(nbinsy+1)),
186 m_flexArray((nbinsx+2)*(nbinsy+2))
188 assert(m_xmin<m_xmax);
189 assert(m_ymin<m_ymax);
193 for (unsigned i = 0; i<nbinsx;++i)
194 assert(xbins[i]<xbins[i+1]);
195 for (unsigned i = 0; i<nbinsy;++i)
196 assert(ybins[i]<ybins[i+1]);
198 for (unsigned i = 0; i<m_nbinsxPlus1;++i)
199 m_varBinsX[i]=xbins[i];
200 for (unsigned i = 0; i<m_nbinsyPlus1;++i)
201 m_varBinsY[i]=ybins[i];
204 //____________________________________________________________________
206 inline Flex2DHisto<T>::~Flex2DHisto()
209 LWPools::release(m_varBinsX,m_nbinsxPlus1);
211 LWPools::release(m_varBinsY,m_nbinsyPlus1);
214 //____________________________________________________________________
216 inline unsigned Flex2DHisto<T>::valueToXBin(const double& x) const
218 return LWBinUtils::valueToBin( x, m_varBinsX, m_invDeltaX, m_xmin, m_xmax, m_nbinsxPlus1 );
221 //____________________________________________________________________
223 inline unsigned Flex2DHisto<T>::valueToYBin(const double& y) const
225 return LWBinUtils::valueToBin( y, m_varBinsY, m_invDeltaY,m_ymin, m_ymax, m_nbinsyPlus1 );
229 //____________________________________________________________________
231 inline double Flex2DHisto<T>::getBinCenterX(int bin) const
233 return LWBinUtils::getBinCenter( bin, m_varBinsX,m_invDeltaX, m_xmin,m_nbinsxPlus1);
236 //____________________________________________________________________
238 inline double Flex2DHisto<T>::getBinCenterY(int bin) const
240 return LWBinUtils::getBinCenter( bin, m_varBinsY,m_invDeltaY, m_ymin,m_nbinsyPlus1);
243 //____________________________________________________________________
245 inline void Flex2DHisto<T>::fill(const double& x, const double& y)
247 unsigned binx(valueToXBin(x)), biny(valueToYBin(y));
249 if (binx==USHRT_MAX||biny==USHRT_MAX)
252 m_flexArray.fill(internal_bin(binx,biny));
253 //Update stats (sums not for over/under flow):
255 if (binx>0&&binx<m_nbinsxPlus1
256 &&biny>0&&biny<m_nbinsyPlus1) {
267 //____________________________________________________________________
269 inline void Flex2DHisto<T>::fill(const double& x, const double& y, const double& w)
273 std::cout<<"LWHisto: Saw NaN in fill weight"<<std::endl;
277 unsigned binx(valueToXBin(x)), biny(valueToYBin(y));
279 if (binx==USHRT_MAX||biny==USHRT_MAX)
282 m_flexArray.fill(internal_bin(binx,biny),w);
283 //Update stats (sums not for over/under flow):
285 if (binx>0&&binx<m_nbinsxPlus1
286 &&biny>0&&biny<m_nbinsyPlus1) {
287 //NB: root used to use fabs(w) instead of w in the formulas below:
290 const double tmpwy(w*y);
293 const double tmpwx(w*x);
300 //____________________________________________________________________
302 inline unsigned Flex2DHisto<T>::getEntries() const
307 //____________________________________________________________________
309 inline void Flex2DHisto<T>::setEntries(unsigned n)
314 //____________________________________________________________________
316 inline double Flex2DHisto<T>::getSumW() const
321 //____________________________________________________________________
323 inline double Flex2DHisto<T>::getSumW2() const
328 //____________________________________________________________________
330 inline double Flex2DHisto<T>::getSumWX() const
335 //____________________________________________________________________
337 inline double Flex2DHisto<T>::getSumWX2() const
342 //____________________________________________________________________
344 inline double Flex2DHisto<T>::getSumWY() const
349 //____________________________________________________________________
351 inline double Flex2DHisto<T>::getSumWY2() const
356 //____________________________________________________________________
358 inline double Flex2DHisto<T>::getSumWXY() const
363 //____________________________________________________________________
365 inline void Flex2DHisto<T>::setSums( const double& sumW,
368 const double& sumWX2,
370 const double& sumWY2,
371 const double& sumWXY )
382 //____________________________________________________________________
384 inline void Flex2DHisto<T>::copyContents(T*__restrict__ cont, double*__restrict__ err) const
386 m_flexArray.copyContents(cont,err);
389 //____________________________________________________________________
391 inline double Flex2DHisto<T>::Integral() const
393 double overflowbins( getBinContent(0,0)
394 +getBinContent(m_nbinsxPlus1,0)
395 +getBinContent(0,m_nbinsyPlus1)
396 +getBinContent(m_nbinsxPlus1,m_nbinsyPlus1));
397 for (unsigned ybin=1;ybin<m_nbinsyPlus1;++ybin) {
398 overflowbins += getBinContent(0,ybin);
399 overflowbins += getBinContent(m_nbinsxPlus1,ybin);
401 for (unsigned xbin=1;xbin<m_nbinsxPlus1;++xbin) {
402 overflowbins += getBinContent(xbin,0);
403 overflowbins += getBinContent(xbin,m_nbinsyPlus1);
405 return m_flexArray.Integral()-overflowbins;
408 //____________________________________________________________________
410 inline bool Flex2DHisto<T>::holdsSeparateSumW2Info() const
412 return m_flexArray.holdsSeparateSumW2Info();
415 //____________________________________________________________________
417 inline double Flex2DHisto<T>::getBinContent(unsigned binx, unsigned biny) const
419 #ifdef LW_STRICT_ROOT_BEHAVIOUR
420 if (binx>m_nbinsxPlus1) binx = m_nbinsxPlus1;
421 if (biny>m_nbinsyPlus1) biny = m_nbinsyPlus1;
423 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1)
426 assert(binx<m_nbinsxPlus1+1);
427 assert(biny<m_nbinsyPlus1+1);
428 return m_flexArray.getBinContent(internal_bin(binx,biny));
431 //____________________________________________________________________
433 inline double Flex2DHisto<T>::getBinError(unsigned binx,unsigned biny) const
435 #ifdef LW_STRICT_ROOT_BEHAVIOUR
436 if (binx>m_nbinsxPlus1) binx = m_nbinsxPlus1;
437 if (biny>m_nbinsyPlus1) biny = m_nbinsyPlus1;
439 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1)
442 return m_flexArray.getBinError(internal_bin(binx,biny));
445 //____________________________________________________________________
447 inline void Flex2DHisto<T>::getBinContentAndError(unsigned binx, unsigned biny, double& cont, double& err ) const
449 //float/integer version
450 #ifdef LW_STRICT_ROOT_BEHAVIOUR
451 if (binx>m_nbinsxPlus1) binx = m_nbinsxPlus1;
452 if (biny>m_nbinsyPlus1) biny = m_nbinsyPlus1;
454 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1) {
461 m_flexArray.getBinContentAndError(internal_bin(binx,biny),tmp,err);
462 cont = static_cast<double>(tmp);
466 //____________________________________________________________________
468 inline void Flex2DHisto<double>::getBinContentAndError(unsigned binx, unsigned biny, double& cont, double& err ) const
471 #ifdef LW_STRICT_ROOT_BEHAVIOUR
472 if (binx>m_nbinsxPlus1) binx = m_nbinsxPlus1;
473 if (biny>m_nbinsyPlus1) biny = m_nbinsyPlus1;
475 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1) {
482 m_flexArray.getBinContentAndError(internal_bin(binx,biny),cont,err);
485 //____________________________________________________________________
487 inline void Flex2DHisto<T>::setBinContent(unsigned binx, unsigned biny, const double& c)
489 //Weird root behaviour: For 2D version of setBinContent we wrap rather than ignore:
490 #ifdef LW_STRICT_ROOT_BEHAVIOUR
491 if (binx>m_nbinsxPlus1)
492 binx = m_nbinsxPlus1;
493 if (biny>m_nbinsyPlus1)
494 biny = m_nbinsyPlus1;
496 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1)
499 m_flexArray.setBinContent(internal_bin(binx,biny),static_cast<T>(c));
500 //This is how it is done in ROOT, but is it really appropriate??:
502 m_sumW = 0;//As in ROOT
505 //____________________________________________________________________
507 inline void Flex2DHisto<T>::setBinError(unsigned binx, unsigned biny, const double& e)
509 //Weird root behaviour: For 2D version of setBinError we ignore rather than wrap:
510 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1) {//as in root
513 m_flexArray.setBinError(internal_bin(binx,biny),e);
516 //Weird ROOT behaviour (should file bug report): for get/set
517 //bincontent/binerror 1D/2D we have different choices of what to do
518 //with bins out of range... (constrain to valid value vs. ignore).
520 //____________________________________________________________________
522 inline void Flex2DHisto<T>::setBinContentAndError(unsigned binx, unsigned biny, const double& cont, const double& err )
524 if (binx>m_nbinsxPlus1||biny>m_nbinsyPlus1) {
525 #ifdef LW_STRICT_ROOT_BEHAVIOUR
526 //Annoyingly enough, root has different behaviour for SetBinContent
527 //(wrap) and SetBinError (ignore) in this case:
528 setBinContent(binx,biny,cont);
532 m_flexArray.setBinContentAndError(internal_bin(binx,biny),static_cast<T>(cont),err);
533 //FIXME: It seems that the next two lines are not executed for the last bin in ROOT!!!!!!!
535 m_sumW = 0;//As in ROOT
538 //____________________________________________________________________
540 inline void Flex2DHisto<T>::resetActiveBinLoop()
542 m_flexArray.resetActiveBinLoop();
545 //____________________________________________________________________
547 inline bool Flex2DHisto<T>::getNextActiveBin(unsigned& binx, unsigned&biny, double& content, double& error)
549 //float/integer version
550 unsigned internalbin;
552 if (m_flexArray.getNextActiveBin(internalbin,tmp,error)) {
553 binx = internalbin % m_nbinsxPlus2;
554 biny = (internalbin-binx) / m_nbinsxPlus2;
555 assert(internal_bin(binx,biny)==internalbin);
556 content = static_cast<double>(tmp);
563 //____________________________________________________________________
565 inline bool Flex2DHisto<double>::getNextActiveBin(unsigned& binx, unsigned&biny, double& content, double& error)
568 unsigned internalbin;
569 if (m_flexArray.getNextActiveBin(internalbin,content,error)) {
570 LWBinUtils::unpack_internal_bin(internalbin,binx,biny,m_nbinsxPlus2);
577 //____________________________________________________________________
579 inline void Flex2DHisto<T>::scaleContentsAndErrors( const double& fact )
582 m_sumW2 *= fact*fact;
588 m_flexArray.scaleContentsAndErrors(fact);
592 #ifdef LW_DEBUG_HEAVY_USERS
594 //____________________________________________________________________
596 inline void Flex2DHisto<T>::countCall(const std::pair<void*,void*>&addresses)
598 std::map<std::pair<void*,void*>,unsigned long>::iterator it = m_callmap.find(addresses);
599 if (it==m_callmap.end())
600 m_callmap[addresses]=0;
605 //____________________________________________________________________
607 inline void Flex2DHisto<T>::produceReport(const char*histname)
609 std::map<std::pair<void*,void*>,unsigned long>::iterator it,itE(m_callmap.end());
610 for(it=m_callmap.begin();it!=itE;++it) {
612 char * caller = LWHistTraceUtils::getSymbol(it->first.second);
613 char * calledmethod = LWHistTraceUtils::getSymbol(it->first.first);
614 std::cout<<"LWHists WARNING: Method in histogram called "<<it->second<<" times: "<<calledmethod<<" from "<<caller<<" (histogram named \""<<histname<<"\")"<<std::endl;
615 //fixme: do free on caller and calledmethod