12#ifndef ROOT_TProfileHelper
13#define ROOT_TProfileHelper
82 Int_t nx = p->GetNbinsX();
83 Int_t ny = p->GetNbinsY();
84 Int_t nz = p->GetNbinsZ();
86 if ( nx != p1->GetNbinsX() || nx != p2->GetNbinsX() ||
87 ny != p1->GetNbinsY() || ny != p2->GetNbinsY() ||
88 nz != p1->GetNbinsZ() || nz != p2->GetNbinsZ() ) {
89 Error(
"TProfileHelper::Add",
"Attempt to add profiles with different number of bins");
96 p->fEntries = ac1*p1->GetEntries() + ac2*p2->GetEntries();
105 else s0[i] = ac1*
s1[i] + ac2*s2[i];
110 if (p->fBinSumw2.fN == 0 && (p1->fBinSumw2.fN != 0 || p2->fBinSumw2.fN != 0)) p->Sumw2();
118 if (ew1 ==
nullptr) ew1 = en1;
119 if (ew2 ==
nullptr) ew2 = en2;
120 for (
Int_t bin = 0; bin < p->fN; bin++) {
121 p->fArray[bin] =
c1*cu1[bin] +
c2*cu2[bin];
122 p->fSumw2.fArray[bin] = ac1*er1[bin] + ac2*er2[bin];
123 p->fBinEntries.fArray[bin] = ac1*en1[bin] + ac2*en2[bin];
124 if (p->fBinSumw2.fN ) p->fBinSumw2.fArray[bin] = ac1*ac1*ew1[bin] + ac2*ac2*ew2[bin];
136 p->fBinEntries.Set(p->fNcells);
137 p->fSumw2.Set(p->fNcells);
153 if (p->fBuffer) p->BufferEmpty();
155 if (bin < 0 || bin >= p->fNcells)
return 0;
156 double sumOfWeights = p->fBinEntries.fArray[bin];
157 if ( p->fBinSumw2.fN == 0 || p->fBinSumw2.fN != p->fNcells) {
162 double sumOfWeightsSquare = p->fBinSumw2.fArray[bin];
163 return ( sumOfWeightsSquare > 0 ? sumOfWeights * sumOfWeights / sumOfWeightsSquare : 0 );
191 return (ret) ? p->GetEntries() : -1;
193#ifdef OLD_PROFILE_MERGE
211 Bool_t hasLimits =
h->GetXaxis()->GetXmin() <
h->GetXaxis()->GetXmax();
212 allHaveLimits = allHaveLimits && hasLimits;
220 if (firstNonEmptyHist ) {
223 if (!p->SameLimitsAndNBins(p->fXaxis, *(
h->GetXaxis())) )
224 p->fXaxis.Set(
h->GetXaxis()->GetNbins(),
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax());
225 if (!p->SameLimitsAndNBins(p->fYaxis, *(
h->GetYaxis())) )
226 p->fYaxis.Set(
h->GetYaxis()->GetNbins(),
h->GetYaxis()->GetXmin(),
h->GetYaxis()->GetXmax());
227 if (!p->SameLimitsAndNBins(p->fZaxis, *(
h->GetZaxis())) )
228 p->fZaxis.Set(
h->GetZaxis()->GetNbins(),
h->GetZaxis()->GetXmin(),
h->GetZaxis()->GetXmax());
230 firstNonEmptyHist =
kFALSE;
236 if (!initialLimitsFound) {
237 initialLimitsFound =
kTRUE;
238 newXAxis.
Set(
h->GetXaxis()->GetNbins(),
h->GetXaxis()->GetXmin(),
239 h->GetXaxis()->GetXmax());
240 if ( p->GetDimension() >= 2 )
241 newYAxis.
Set(
h->GetYaxis()->GetNbins(),
h->GetYaxis()->GetXmin(),
242 h->GetYaxis()->GetXmax());
243 if ( p->GetDimension() >= 3 )
244 newZAxis.
Set(
h->GetZaxis()->GetNbins(),
h->GetZaxis()->GetXmin(),
245 h->GetZaxis()->GetXmax());
249 if (!p->SameLimitsAndNBins(newXAxis, *(
h->GetXaxis())) ||
250 !p->SameLimitsAndNBins(newYAxis, *(
h->GetYaxis())) ||
251 !p->SameLimitsAndNBins(newZAxis, *(
h->GetZaxis())) ) {
258 if (!p->RecomputeAxisLimits(newXAxis, *(
h->GetXaxis()))) {
259 Error(
"TProfileHelper::Merge",
"Cannot merge profiles %d dim - limits are inconsistent:\n "
260 "first: (%d, %f, %f), second: (%d, %f, %f)",p->GetDimension(),
262 h->GetXaxis()->GetNbins(),
h->GetXaxis()->GetXmin(),
263 h->GetXaxis()->GetXmax());
266 if (p->GetDimension() >= 2 && !p->RecomputeAxisLimits(newYAxis, *(
h->GetYaxis()))) {
267 Error(
"TProfileHelper::Merge",
"Cannot merge profiles %d dim - limits are inconsistent:\n "
268 "first: (%d, %f, %f), second: (%d, %f, %f)",p->GetDimension(),
270 h->GetYaxis()->GetNbins(),
h->GetYaxis()->GetXmin(),
271 h->GetYaxis()->GetXmax());
274 if (p->GetDimension() >= 3 && !p->RecomputeAxisLimits(newZAxis, *(
h->GetZaxis()))) {
275 Error(
"TProfileHelper::Merge",
"Cannot merge profiles %d dim - limits are inconsistent:\n "
276 "first: (%d, %f, %f), second: (%d, %f, %f)",p->GetDimension(),
278 h->GetZaxis()->GetNbins(),
h->GetZaxis()->GetXmin(),
279 h->GetZaxis()->GetXmax());
285 }
while ( (
h =
dynamic_cast<T*
> ( next() ) ) != NULL );
286 if (!
h && (*next) ) {
287 Error(
"TProfileHelper::Merge",
"Attempt to merge object of class: %s to a %s",
288 (*next)->ClassName(),p->ClassName());
299 if (!allSameLimits) {
304 hclone = (T*)p->IsA()->New();
306 hclone->SetDirectory(0);
315 if (!allSameLimits && initialLimitsFound) {
323 if (!allHaveLimits) {
325 while ( (
h =
dynamic_cast<T*
> (next()) ) ) {
326 if (
h->GetXaxis()->GetXmin() >=
h->GetXaxis()->GetXmax() &&
h->fBuffer) {
330 for (
Int_t i = 0; i < nbentries; i++)
331 if ( p->GetDimension() == 3 ) {
332 v[0] =
h->fBuffer[5*i + 2];
333 v[1] =
h->fBuffer[5*i + 3];
334 v[2] =
h->fBuffer[5*i + 4];
335 v[3] =
h->fBuffer[5*i + 5];
336 v[4] =
h->fBuffer[5*i + 1];
338 }
else if ( p->GetDimension() == 2 ) {
339 v[0] =
h->fBuffer[4*i + 2];
340 v[1] =
h->fBuffer[4*i + 3];
341 v[2] =
h->fBuffer[4*i + 4];
342 v[3] =
h->fBuffer[4*i + 1];
346 else if ( p->GetDimension() == 1 ) {
347 v[0] =
h->fBuffer[3*i + 2];
348 v[1] =
h->fBuffer[3*i + 3];
349 v[2] =
h->fBuffer[3*i + 1];
355 if (!initialLimitsFound) {
360 return (
Int_t) p->GetEntries();
368 p->GetStats(totstats);
370 Bool_t canExtend = p->CanExtendAllAxes();
373 while ( (
h=
static_cast<T*
>(next())) ) {
376 if (
h->GetXaxis()->GetXmin() <
h->GetXaxis()->GetXmax()) {
380 totstats[i] += stats[i];
383 for (
Int_t hbin = 0; hbin <
h->fN; ++hbin ) {
385 if (!allSameLimits) {
390 if (
h->GetW()[hbin] != 0 && (
h->IsBinUnderflow(hbin) ||
h->IsBinOverflow(hbin)) ) {
392 Error(
"TProfileHelper::Merge",
"Cannot merge profiles - they have"
393 " different limits and underflows/overflows are present."
394 " The initial profile is now broken!");
397 Int_t hbinx, hbiny, hbinz;
398 h->GetBinXYZ(hbin, hbinx, hbiny, hbinz);
400 pbin = p->GetBin( p->fXaxis.FindBin(
h->GetXaxis()->GetBinCenter(hbinx) ),
401 p->fYaxis.FindBin(
h->GetYaxis()->GetBinCenter(hbiny) ),
402 p->fZaxis.FindBin(
h->GetZaxis()->GetBinCenter(hbinz) ) );
406 p->fArray[pbin] +=
h->GetW()[hbin];
407 p->fSumw2.fArray[pbin] +=
h->GetW2()[hbin];
408 p->fBinEntries.fArray[pbin] +=
h->GetB()[hbin];
409 if (p->fBinSumw2.fN) {
410 if (
h->GetB2() ) p->fBinSumw2.fArray[pbin] +=
h->GetB2()[hbin];
411 else p->fBinSumw2.fArray[pbin] +=
h->GetB()[hbin];
419 p->PutStats(totstats);
444 if (axis->
GetNbins() <= 0)
return 0;
450 if (!p->FindNewAxisLimits(axis,
x,
xmin,
xmax))
454 T* hold = (T*)p->IsA()->New();
456 hold->SetDirectory(0);
460 if (p->fBinSumw2.fN) hold->Sumw2();
463 Int_t nx = p->fXaxis.GetNbins() + 2;
464 Int_t ny = (p->GetDimension() > 1) ? p->fYaxis.GetNbins() + 2 : 1;
465 Int_t nz = (p->GetDimension() > 2) ? p->fZaxis.GetNbins() + 2 : 1;
468 if (axis == p->GetXaxis()) iaxis = 1;
469 if (axis == p->GetYaxis()) iaxis = 2;
470 if (axis == p->GetZaxis()) iaxis = 3;
478 Int_t ix, iy, iz, binx, biny, binz;
479 for (binz=0;binz< nz;binz++) {
480 zc = hold->GetZaxis()->GetBinCenter(binz);
481 iz = p->fZaxis.FindFixBin(zc);
482 for (biny=0;biny<ny;biny++) {
483 yc = hold->GetYaxis()->GetBinCenter(biny);
484 iy = p->fYaxis.FindFixBin(yc);
485 for (binx=0;binx<nx;binx++) {
486 xc = hold->GetXaxis()->GetBinCenter(binx);
487 ix = p->fXaxis.FindFixBin(xc);
488 Int_t sourceBin = hold->GetBin(binx,biny,binz);
490 if (hold->fBinEntries.fArray[sourceBin] == 0)
continue;
491 if (hold->IsBinUnderflow(sourceBin, iaxis) || hold->IsBinOverflow(sourceBin, iaxis)) {
494 "Histogram %s has underflow or overflow in the %s that is extendable"
495 " their content will be lost",p->GetName(),axis->
GetName());
500 Int_t destinationBin = p->GetBin(ix,iy,iz);
501 p->AddBinContent(destinationBin, hold->fArray[sourceBin]);
502 p->fBinEntries.fArray[destinationBin] += hold->fBinEntries.fArray[sourceBin];
503 p->fSumw2.fArray[destinationBin] += hold->fSumw2.fArray[sourceBin];
504 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[destinationBin] += hold->fBinSumw2.fArray[sourceBin];
521 for (bin=0;bin<p->fN;bin++) {
522 p->fArray[bin] =
c1*cu1[bin];
523 p->fSumw2.fArray[bin] = ac1*ac1*er1[bin];
524 p->fBinEntries.fArray[bin] = en1[bin];
541 if (p->fBinSumw2.fN > 0 ) p->fBinSumw2.Set(0);
545 if ( p->fBinSumw2.fN == p->fNcells) {
546 if (!p->fgDefaultSumw2)
547 Warning(
"Sumw2",
"Sum of squares of profile bin weights structure already created");
551 p->fBinSumw2.Set(p->fNcells);
554 for (
Int_t bin=0; bin<p->fNcells; bin++) {
555 p->fBinSumw2.fArray[bin] = p->fBinEntries.fArray[bin];
568 TAxis *axis = p->GetXaxis();
569 if (ax[0] ==
'y' || ax[0] ==
'Y') axis = p->GetYaxis();
570 if (ax[0] ==
'z' || ax[0] ==
'Z') axis = p->GetZaxis();
572 Error(
"TProfileHelper::LabelsDeflate",
"Invalid axis option %s",ax);
583 while ((obj = next())) {
585 if (ibin > nbins) nbins = ibin;
587 if (nbins < 1) nbins = 1;
590 if (nbins==axis->
GetNbins())
return;
592 T *hold = (T*)p->IsA()->New();;
593 hold->SetDirectory(0);
602 p->SetBinsLength(-1);
603 p->fBinEntries.Set(p->fN);
604 p->fSumw2.Set(p->fN);
605 if (p->fBinSumw2.fN) p->fBinSumw2.Set(p->fN);
611 Int_t bin,binx,biny,binz;
612 for (bin =0; bin < hold->fN; ++bin)
614 hold->GetBinXYZ(bin, binx, biny, binz);
615 Int_t ibin = p->GetBin(binx, biny, binz);
616 p->fArray[ibin] += hold->fArray[bin];
617 p->fBinEntries.fArray[ibin] += hold->fBinEntries.fArray[bin];
618 p->fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
619 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[ibin] += hold->fBinSumw2.fArray[bin];
633 if (
gDebug)
Info(
"LabelsInflate",
"Inflate label for axis %s of profile %s",ax,p->GetName());
635 Int_t iaxis = p->AxisChoice(ax);
637 if (iaxis == 1) axis = p->GetXaxis();
638 if (iaxis == 2) axis = p->GetYaxis();
639 if (iaxis == 3) axis = p->GetZaxis();
644 T *hold = (T*)p->IsA()->New();;
645 hold->SetDirectory(0);
660 p->SetBinsLength(-1);
661 Int_t ncells = p->fN;
662 p->fBinEntries.Set(ncells);
663 p->fSumw2.Set(ncells);
664 if (p->fBinSumw2.fN) p->fBinSumw2.Set(ncells);
670 Int_t binx, biny, binz = 0;
671 for (
Int_t ibin =0; ibin < hold->fNcells; ibin++) {
673 hold->GetBinXYZ(ibin,binx,biny,binz);
674 Int_t bin = p->GetBin(binx,biny,binz);
677 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
678 if (
gDebug && hold->fBinEntries.fArray[ibin] > 0)
Info(
"LabelsInflate",
"Content for underflow/overflow of bin (%d,%d,%d) will be lost",binx,biny,binz);
682 p->fArray[bin] = hold->fArray[ibin];
683 p->fBinEntries.fArray[bin] = hold->fBinEntries.fArray[ibin];
684 p->fSumw2.fArray[bin] = hold->fSumw2.fArray[ibin];
685 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[bin] = hold->fBinSumw2.fArray[ibin];
686 if (
gDebug)
Info(
"LabelsInflate",
"Copy Content from bin (%d,%d,%d) from %d in %d (%f,%f)",binx,biny,binz, ibin, bin, hold->fArray[ibin],hold->fBinEntries.fArray[ibin] );
708 if (p->fBuffer) p->BufferEmpty();
710 if (bin < 0 || bin >= p->fNcells)
return 0;
713 Double_t err2 = p->fSumw2.fArray[bin];
714 Double_t neff = p->GetBinEffectiveEntries(bin);
715 if (
sum == 0)
return 0;
735 if (err2 != 0 && neff < 5)
test = eprim2*
sum/err2;
737 if (p->fgApproximate && (
test < 1.e-4 || eprim2 <= 0)) {
743 if (p->GetDimension() == 2) index = 7;
744 if (p->GetDimension() == 3) index = 11;
773 if (bin < 0 || bin >= p->fNcells)
return;
774 p->fBinEntries.fArray[bin] = w;
775 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[bin] = w;
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Class to manage histogram axis.
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
virtual void SetLimits(Double_t xmin, Double_t xmax)
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
THashList * GetLabels() const
Collection abstract base class.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual Bool_t IsEmpty() const
TH1 is the base class of all histogram classes in ROOT.
@ kNoAxis
NOTE: Must always be 0 !!!
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
@ kNstat
Size of statistics data (up to TProfile3D)
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
virtual TObject * Remove(TObject *obj)
Remove object from the list.
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
virtual const char * GetName() const
Returns name of object.
Mother of all ROOT objects.
virtual UInt_t GetUniqueID() const
Return the unique object id.
static void LabelsInflate(T *p, Option_t *)
static Double_t GetBinError(T *p, Int_t bin)
static T * ExtendAxis(T *p, Double_t x, TAxis *axis)
static void Sumw2(T *p, Bool_t flag)
static void SetBinEntries(T *p, Int_t bin, Double_t w)
static void Scale(T *p, Double_t c1, Option_t *option)
static void SetErrorOption(T *p, Option_t *opt)
static Long64_t Merge(T *p, TCollection *list)
static void BuildArray(T *p)
static Bool_t Add(T *p, const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2=1)
static Double_t GetBinEffectiveEntries(T *p, Int_t bin)
static void LabelsDeflate(T *p, Option_t *)
void ToLower()
Change string to lower-case.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Double_t Sqrt(Double_t x)
static uint64_t sum(uint64_t i)