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();
99 for (i=0;i<
TH1::kNstat;i++) {s0[i] = s1[i] = s2[i] = 0;}
104 if (i == 1) s0[i] = c1*c1*s1[i] + c2*c2*s2[i];
105 else s0[i] = ac1*s1[i] + ac2*s2[i];
116 if (p->fBinSumw2.fN == 0 && (p1->fBinSumw2.fN != 0 || p2->fBinSumw2.fN != 0) ) p->Sumw2();
118 if (ew1 == 0) ew1 = en1;
119 if (ew2 == 0) ew2 = en2;
120 for (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];
129 template <
typename T>
136 p->fBinEntries.Set(p->fNcells);
137 p->fSumw2.Set(p->fNcells);
142 template <
typename T>
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 );
166 template <
typename T>
203 Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
204 allHaveLimits = allHaveLimits && hasLimits;
212 if (firstNonEmptyHist ) {
215 if (!p->SameLimitsAndNBins(p->fXaxis, *(h->GetXaxis())) )
216 p->fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax());
217 if (!p->SameLimitsAndNBins(p->fYaxis, *(h->GetYaxis())) )
218 p->fYaxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
219 if (!p->SameLimitsAndNBins(p->fZaxis, *(h->GetZaxis())) )
220 p->fZaxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),h->GetZaxis()->GetXmax());
222 firstNonEmptyHist =
kFALSE;
228 if (!initialLimitsFound) {
229 initialLimitsFound =
kTRUE;
230 newXAxis.
Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
231 h->GetXaxis()->GetXmax());
232 if ( p->GetDimension() >= 2 )
233 newYAxis.
Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
234 h->GetYaxis()->GetXmax());
235 if ( p->GetDimension() >= 3 )
236 newZAxis.
Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
237 h->GetZaxis()->GetXmax());
241 if (!p->SameLimitsAndNBins(newXAxis, *(h->GetXaxis())) ||
242 !p->SameLimitsAndNBins(newYAxis, *(h->GetYaxis())) ||
243 !p->SameLimitsAndNBins(newZAxis, *(h->GetZaxis())) ) {
250 if (!p->RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
251 Error(
"TProfileHelper::Merge",
"Cannot merge profiles %d dim - limits are inconsistent:\n " 252 "first: (%d, %f, %f), second: (%d, %f, %f)",p->GetDimension(),
254 h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
255 h->GetXaxis()->GetXmax());
258 if (p->GetDimension() >= 2 && !p->RecomputeAxisLimits(newYAxis, *(h->GetYaxis()))) {
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->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
263 h->GetYaxis()->GetXmax());
266 if (p->GetDimension() >= 3 && !p->RecomputeAxisLimits(newZAxis, *(h->GetZaxis()))) {
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->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
271 h->GetZaxis()->GetXmax());
277 }
while ( ( h = dynamic_cast<T*> ( next() ) ) != NULL );
278 if (!h && (*next) ) {
279 Error(
"TProfileHelper::Merge",
"Attempt to merge object of class: %s to a %s",
280 (*next)->ClassName(),p->ClassName());
291 if (!allSameLimits) {
296 hclone = (
T*)p->IsA()->New();
298 hclone->SetDirectory(0);
307 if (!allSameLimits && initialLimitsFound) {
315 if (!allHaveLimits) {
317 while ( (h = dynamic_cast<T*> (next()) ) ) {
318 if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && h->fBuffer) {
322 for (
Int_t i = 0; i < nbentries; i++)
323 if ( p->GetDimension() == 3 ) {
324 v[0] = h->fBuffer[5*i + 2];
325 v[1] = h->fBuffer[5*i + 3];
326 v[2] = h->fBuffer[5*i + 4];
327 v[3] = h->fBuffer[5*i + 5];
328 v[4] = h->fBuffer[5*i + 1];
330 }
else if ( p->GetDimension() == 2 ) {
331 v[0] = h->fBuffer[4*i + 2];
332 v[1] = h->fBuffer[4*i + 3];
333 v[2] = h->fBuffer[4*i + 4];
334 v[3] = h->fBuffer[4*i + 1];
338 else if ( p->GetDimension() == 1 ) {
339 v[0] = h->fBuffer[3*i + 2];
340 v[1] = h->fBuffer[3*i + 3];
341 v[2] = h->fBuffer[3*i + 1];
347 if (!initialLimitsFound) {
352 return (
Int_t) p->GetEntries();
360 p->GetStats(totstats);
362 Bool_t canExtend = p->CanExtendAllAxes();
365 while ( (h=static_cast<T*>(next())) ) {
368 if (h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
372 totstats[i] += stats[i];
373 nentries += h->GetEntries();
375 for (
Int_t hbin = 0; hbin < h->fN; ++hbin ) {
377 if (!allSameLimits) {
382 if ( h->GetW()[hbin] != 0 && (h->IsBinUnderflow(hbin) || h->IsBinOverflow(hbin)) ) {
384 Error(
"TProfileHelper::Merge",
"Cannot merge profiles - they have" 385 " different limits and underflows/overflows are present." 386 " The initial profile is now broken!");
389 Int_t hbinx, hbiny, hbinz;
390 h->GetBinXYZ(hbin, hbinx, hbiny, hbinz);
392 pbin = p->GetBin( p->fXaxis.FindBin( h->GetXaxis()->GetBinCenter(hbinx) ),
393 p->fYaxis.FindBin( h->GetYaxis()->GetBinCenter(hbiny) ),
394 p->fZaxis.FindBin( h->GetZaxis()->GetBinCenter(hbinz) ) );
398 p->fArray[pbin] += h->GetW()[hbin];
399 p->fSumw2.fArray[pbin] += h->GetW2()[hbin];
400 p->fBinEntries.fArray[pbin] += h->GetB()[hbin];
401 if (p->fBinSumw2.fN) {
402 if ( h->GetB2() ) p->fBinSumw2.fArray[pbin] += h->GetB2()[hbin];
403 else p->fBinSumw2.fArray[pbin] += h->GetB()[hbin];
411 p->PutStats(totstats);
412 p->SetEntries(nentries);
420 template <
typename T>
435 if (axis->
GetNbins() <= 0)
return 0;
438 if (!p->FindNewAxisLimits(axis, x, xmin, xmax))
442 T* hold = (
T*)p->IsA()->New();
444 hold->SetDirectory(0);
448 if (p->fBinSumw2.fN) hold->Sumw2();
450 Int_t nbinsx = p->fXaxis.GetNbins();
451 Int_t nbinsy = p->fYaxis.GetNbins();
452 Int_t nbinsz = p->fZaxis.GetNbins();
458 Int_t ix, iy, iz, binx, biny, binz;
459 for (binz=1;binz<=nbinsz;binz++) {
460 bz = hold->GetZaxis()->GetBinCenter(binz);
461 iz = p->fZaxis.FindFixBin(bz);
462 for (biny=1;biny<=nbinsy;biny++) {
463 by = hold->GetYaxis()->GetBinCenter(biny);
464 iy = p->fYaxis.FindFixBin(by);
465 for (binx=1;binx<=nbinsx;binx++) {
466 bx = hold->GetXaxis()->GetBinCenter(binx);
467 ix = p->fXaxis.FindFixBin(bx);
469 Int_t sourceBin = hold->GetBin(binx,biny,binz);
470 Int_t destinationBin = p->GetBin(ix,iy,iz);
471 p->AddBinContent(destinationBin, hold->fArray[sourceBin]);
472 p->fBinEntries.fArray[destinationBin] += hold->fBinEntries.fArray[sourceBin];
473 p->fSumw2.fArray[destinationBin] += hold->fSumw2.fArray[sourceBin];
474 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[destinationBin] += hold->fBinSumw2.fArray[sourceBin];
481 template <
typename T>
491 for (bin=0;bin<p->fN;bin++) {
492 p->fArray[bin] = c1*cu1[bin];
493 p->fSumw2.fArray[bin] = ac1*ac1*er1[bin];
494 p->fBinEntries.fArray[bin] = en1[bin];
498 template <
typename T>
511 if (p->fBinSumw2.fN > 0 ) p->fBinSumw2.Set(0);
515 if ( p->fBinSumw2.fN == p->fNcells) {
516 if (!p->fgDefaultSumw2)
517 Warning(
"Sumw2",
"Sum of squares of profile bin weights structure already created");
521 p->fBinSumw2.Set(p->fNcells);
524 for (
Int_t bin=0; bin<p->fNcells; bin++) {
525 p->fBinSumw2.fArray[bin] = p->fBinEntries.fArray[bin];
529 template <
typename T>
538 TAxis *axis = p->GetXaxis();
539 if (ax[0] ==
'y' || ax[0] ==
'Y') axis = p->GetYaxis();
540 if (ax[0] ==
'z' || ax[0] ==
'Z') axis = p->GetZaxis();
542 Error(
"TProfileHelper::LabelsDeflate",
"Invalid axis option %s",ax);
553 while ((obj = next())) {
555 if (ibin > nbins) nbins = ibin;
557 if (nbins < 1) nbins = 1;
560 if (nbins==axis->
GetNbins())
return;
562 T *hold = (
T*)p->IsA()->New();;
563 hold->SetDirectory(0);
571 axis->
Set(nbins,xmin,xmax);
572 p->SetBinsLength(-1);
573 p->fBinEntries.Set(p->fN);
574 p->fSumw2.Set(p->fN);
575 if (p->fBinSumw2.fN) p->fBinSumw2.Set(p->fN);
581 Int_t bin,binx,biny,binz;
582 for (bin =0; bin < hold->fN; ++bin)
584 hold->GetBinXYZ(bin, binx, biny, binz);
585 Int_t ibin = p->GetBin(binx, biny, binz);
586 p->fArray[ibin] += hold->fArray[bin];
587 p->fBinEntries.fArray[ibin] += hold->fBinEntries.fArray[bin];
588 p->fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
589 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[ibin] += hold->fBinSumw2.fArray[bin];
595 template <
typename T>
604 TAxis *axis = p->GetXaxis();
605 if (ax[0] ==
'y' || ax[0] ==
'Y') axis = p->GetYaxis();
606 T *hold = (
T*)p->IsA()->New();;
607 hold->SetDirectory(0);
616 xmax = xmin + 2*(xmax-
xmin);
620 axis->
Set(nbins,xmin,xmax);
622 p->SetBinsLength(-1);
623 Int_t ncells = p->fN;
624 p->fBinEntries.Set(ncells);
625 p->fSumw2.Set(ncells);
626 if (p->fBinSumw2.fN) p->fBinSumw2.Set(ncells);
629 for (
Int_t ibin =0; ibin < p->fN; ibin++)
631 Int_t binx, biny, binz;
632 p->GetBinXYZ(ibin, binx, biny, binz);
633 Int_t bin = hold->GetBin(binx, biny, binz);
635 if (p->IsBinUnderflow(ibin) || p->IsBinOverflow(ibin)) {
636 p->UpdateBinContent(ibin, 0.0);
637 p->fBinEntries.fArray[ibin] = 0.0;
638 p->fSumw2.fArray[ibin] = 0.0;
639 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[ibin] = 0.0;
641 p->fArray[ibin] = hold->fArray[bin];
642 p->fBinEntries.fArray[ibin] = hold->fBinEntries.fArray[bin];
643 p->fSumw2.fArray[ibin] = hold->fSumw2.fArray[bin];
644 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[ibin] = hold->fBinSumw2.fArray[bin];
650 template <
typename T>
661 template <
typename T>
666 if (p->fBuffer) p->BufferEmpty();
668 if (bin < 0 || bin >= p->fNcells)
return 0;
671 Double_t err2 = p->fSumw2.fArray[bin];
672 Double_t neff = p->GetBinEffectiveEntries(bin);
673 if (sum == 0)
return 0;
693 if (err2 != 0 && neff < 5) test = eprim2*sum/err2;
695 if (p->fgApproximate && (test < 1.e-4 || eprim2 <= 0)) {
701 if (p->GetDimension() == 2) index = 7;
702 if (p->GetDimension() == 3) index = 11;
725 template <
typename T>
731 if (bin < 0 || bin >= p->fNcells)
return;
732 p->fBinEntries.fArray[bin] = w;
733 if (p->fBinSumw2.fN) p->fBinSumw2.fArray[bin] = w;
static void SetBinEntries(T *p, Int_t bin, Double_t w)
virtual UInt_t GetUniqueID() const
Return the unique object id.
static void Scale(T *p, Double_t c1, Option_t *option)
static long int sum(long int i)
virtual void SetLimits(Double_t xmin, Double_t xmax)
static Double_t GetBinError(T *p, Int_t bin)
static void SetErrorOption(T *p, Option_t *opt)
static void LabelsInflate(T *p, Option_t *)
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
void ToLower()
Change string to lower-case.
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
static void BuildArray(T *p)
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
THashList * GetLabels() const
static double p2(double t, double a, double b, double c)
static void LabelsDeflate(T *p, Option_t *)
static T * ExtendAxis(T *p, Double_t x, TAxis *axis)
void Error(const char *location, const char *msgfmt,...)
NOTE: Must always be 0 !!!
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Class to manage histogram axis.
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Collection abstract base class.
static double p1(double t, double a, double b)
void Warning(const char *location, const char *msgfmt,...)
static Bool_t Add(T *p, const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2=1)
virtual Bool_t IsEmpty() const
static Double_t GetBinEffectiveEntries(T *p, Int_t bin)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Mother of all ROOT objects.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
static void Sumw2(T *p, Bool_t flag)
Double_t Sqrt(Double_t x)
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
static Long64_t Merge(T *p, TCollection *list)