15 #define PRINTRANGE(a, b, bn) \ 16 Printf(" base: %f %f %d, %s: %f %f %d", a->GetXmin(), a->GetXmax(), a->GetNbins(), bn, b->GetXmin(), b->GetXmax(), \ 32 if (
gDebug)
Info(
"Merge",
"Histogram Merge type is %d and new axis flag is %d",(
int) type,(
int)
fNewAxisFlag);
55 if (ret)
return kTRUE;
59 Error(
"TH1Merger",
"Unknown type of Merge for histogram %s",
fH0->
GetName());
81 Error(
"AutoP2BuildAxes",
"undefined histogram: %p", h);
87 Error(
"AutoP2BuildAxes",
"not in autobin-power-of-2 mode!");
99 a0->
Set(a1->GetNbins(), a1->GetXmin(), a1->GetXmax());
107 Double_t bwmin = (a1->GetXmax() - a1->GetXmin()) / a1->GetNbins();
115 Error(
"AutoP2BuildAxes",
"minimal bin width negative or null: %f", bwmin);
120 Double_t re = std::modf(bwmax / bwmin, &rt);
123 Error(
"AutoP2BuildAxes",
"bin widths not in integer ratio: %f", re);
130 if (a0->
GetXmin() < a1->GetXmin()) {
131 if (a0->
GetXmax() < a1->GetXmin()) {
134 Error(
"AutoP2BuildAxes",
"ranges are disconnected and under/overflows: cannot merge");
137 xmax = a1->GetXmax();
141 if (a0->
GetXmax() >= a1->GetXmax()) {
142 xmax = a1->GetXmax();
143 xmin = a1->GetXmin();
147 xmin = a1->GetXmin();
152 if (a1->GetXmax() < a0->
GetXmin()) {
155 Error(
"AutoP2BuildAxes",
"ranges are disconnected and under/overflows: cannot merge");
159 xmin = a1->GetXmin();
162 if (a1->GetXmax() >= a0->
GetXmax()) {
167 xmax = a1->GetXmax();
175 re = std::modf(range / bwmax, &rt);
178 Error(
"MergeCompatibleHistograms",
"range smaller than bin width: %f %f %f", range, bwmax, rt);
192 a0->
Set(nb, xmin, xmax);
250 Error(
"Merge",
"Cannot merge histogram - dimensions are different\n " 262 allHaveLimits = allHaveLimits && hasLimits;
263 allSameLimits &= allHaveLimits;
266 Error(
"Merge",
"Cannot merge histogram - some are in autobin-power-of-2 mode, but not %s!", h->
GetName());
270 Error(
"Merge",
"Cannot merge histogram - %s is in autobin-power-of-2 mode, but not the previous ones",
293 if (!initialLimitsFound) {
294 initialLimitsFound =
kTRUE;
321 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n " 322 "first: %s (%d, %f, %f), second: %s (%d, %f, %f)",
fH0->
GetName(),
336 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n " 337 "first: %s (%d, %f, %f), second: %s (%d, %f, %f)",
fH0->
GetName(),
347 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n " 348 "first: %s (%d, %f, %f), second: %s (%d, %f, %f)",
fH0->
GetName(),
355 allSameLimits = sameLimitsX && sameLimitsY && sameLimitsZ;
365 if (allHaveLabels && !histoIsEmpty) {
367 Bool_t haveOneLabel = (hlabels !=
nullptr);
369 if (foundLabelHist && allHaveLabels && !haveOneLabel) {
370 Warning(
"Merge",
"Not all histograms have labels. I will ignore labels," 371 " falling back to bin numbering mode.");
374 allHaveLabels &= (haveOneLabel);
376 if (haveOneLabel) foundLabelHist =
kTRUE;
378 if (foundLabelHist &&
gDebug)
379 Info(
"TH1Merger::ExamineHistogram",
"Histogram %s has labels",h->
GetName() );
388 Info(
"TH1Merger::ExamineHistogram",
"Histogram %s to be merged is empty and we are merging with %s that has labels. Force the axis to be extended",
fH0->
GetName(),h->
GetName());
396 Info(
"TH1Merger::ExamineHistogram",
"Histogram %s to be merged has label but axis cannot be extended - using bin numeric mode to merge. Call TH1::SetExtendAllAxes() if want to merge using label mode",
fH0->
GetName());
406 Int_t non_zero_bins = 0;
409 for (
Int_t i = 1; i <= nbins; i++) {
415 Warning(
"TH1Merger::ExamineHistograms",
"Histogram %s contains non-empty bins without labels - falling back to bin numbering mode",h->
GetName() );
422 Info(
"TH1Merger::ExamineHistogram",
"Examine histogram %s - labels %d - same limits %d - axis found %d",h->
GetName(),allHaveLabels,allSameLimits,initialLimitsFound );
424 }
while ( ( h = dynamic_cast<TH1*> ( next() ) ) != NULL );
426 if (!h && (*next) ) {
427 Error(
"Merge",
"Attempt to merge object of class: %s to a %s",
446 if (!initialLimitsFound) {
528 if (newLimitsX)
Info(
"DefineNewAxis",
"A new X axis has been defined Nbins=%d , [%f,%f]",
fH0->
fXaxis.
GetNbins(),
530 if (newLimitsY)
Info(
"DefineNewAxis",
"A new Y axis has been defined Nbins=%d , [%f,%f]",
fH0->
fYaxis.
GetNbins(),
532 if (newLimitsZ)
Info(
"DefineNewAxis",
"A new Z axis has been defined Nbins=%d , [%f,%f]",
fH0->
fZaxis.
GetNbins(),
546 Warning(
"TH1Merger::CopyMerge",
"invalid inputs: %p, %p, %p, %p -> do nothing", hsrc, hdes, p1, p2);
553 for (
Int_t i = 0; i < nbentries; i++)
557 auto h2 =
dynamic_cast<TH2 *
>(hdes);
559 for (
Int_t i = 0; i < nbentries; i++)
563 auto h3 =
dynamic_cast<TH3 *
>(hdes);
565 for (
Int_t i = 0; i < nbentries; i++)
574 TH1 *href = 0, *hist = 0;
579 while ((hist = (
TH1 *)nextref()) && !href) {
596 while ((hist = (
TH1 *)next())) {
599 Info(
"AutoP2BufferMerge",
"merging buffer of %s into %s", hist->GetName(), href->
GetName());
619 totstats[i] = stats[i] = 0;
629 while ((hist = (
TH1 *)next())) {
637 Info(
"TH1Merger::AutoP2Merge",
"all histograms look empty!");
643 Error(
"TH1Merger::AutoP2Merge",
"cannot create axes from %s", hist->
GetName());
647 while ((h = (
TH1 *)next())) {
649 Error(
"TH1Merger::AutoP2Merge",
"cannot merge histogram %s: not merge compatible", h->
GetName());
670 while ((hist = (
TH1 *)next())) {
675 Info(
"TH1Merger::AutoP2Merge",
"merging histogram %s into %s (entries: %f)", hist->
GetName(),
fH0->
GetName(),
685 totstats[i] += stats[i];
716 while (
TH1* hist = (
TH1*)next()) {
721 Info(
"TH1Merger::BufferMerge",
"Merging histogram %s into %s",hist->GetName(),
fH0->
GetName() );
743 totstats[i] = stats[i] = 0;
749 while (
TH1* hist=(
TH1*)next()) {
754 Info(
"TH1Merger::SameAxesMerge",
"Merging histogram %s into %s",hist->GetName(),
fH0->
GetName() );
757 if (hist->IsEmpty())
continue;
760 hist->GetStats(stats);
762 totstats[i] += stats[i];
763 nentries += hist->GetEntries();
767 for (
Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
769 Double_t cu = hist->RetrieveBinContent(ibin);
771 if (
fH0->
fSumw2.
fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
799 while (
TH1* hist=(
TH1*)next()) {
802 Info(
"TH1Merger::DifferentAxesMerge",
"Merging histogram %s into %s",hist->GetName(),
fH0->
GetName() );
805 if (hist->IsEmpty())
continue;
808 hist->GetStats(stats);
810 totstats[i] += stats[i];
811 nentries += hist->GetEntries();
814 for (
Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
816 Double_t cu = hist->RetrieveBinContent(ibin);
818 if (
fH0->
fSumw2.
fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
821 if (cu == 0 && e1sq == 0)
continue;
823 Int_t binx,biny,binz;
824 hist->GetBinXYZ(ibin, binx, biny, binz);
827 if (binx <= 0 || binx >= hist->GetNbinsX() + 1) {
829 Error(
"TH1Merger::DifferentAxesMerge",
"Cannot merge histograms - the histograms %s can extend the X axis or have" 830 " different limits and underflows/overflows are present in the histogram %s.",
fH0->
GetName(),hist->GetName());
834 if (biny <= 0 || biny >= hist->GetNbinsY() + 1) {
836 Error(
"TH1Merger::DifferentAxesMerge",
"Cannot merge histograms - the histograms %s can extend the Y axis or have" 837 " different limits and underflows/overflows are present in the histogram %s.",
fH0->
GetName(),hist->GetName());
841 if (binz <= 0 || binz >= hist->GetNbinsZ() + 1) {
843 Error(
"TH1Merger::DifferentAxesMerge",
"Cannot merge histograms - the histograms %s can extend the Z axis or have" 844 " different limits and underflows/overflows are present in the histogram %s.",
fH0->
GetName(),hist->GetName());
863 Fatal(
"TH1Merger::LabelMerge",
"Fatal error merging histogram %s - bin number is %d and array size is %d",
891 while (
TH1* hist=(
TH1*)next()) {
894 Info(
"TH1Merger::LabelMerge",
"Merging histogram %s into %s",hist->GetName(),
fH0->
GetName() );
897 if (hist->IsEmpty())
continue;
900 hist->GetStats(stats);
902 totstats[i] += stats[i];
903 nentries += hist->GetEntries();
905 auto labelsX = hist->GetXaxis()->GetLabels();
906 auto labelsY = hist->GetYaxis()->GetLabels();
907 auto labelsZ = hist->GetZaxis()->GetLabels();
908 R__ASSERT(!( labelsX ==
nullptr && labelsY ==
nullptr && labelsZ ==
nullptr));
911 for (
Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
913 Double_t cu = hist->RetrieveBinContent(ibin);
915 if (
fH0->
fSumw2.
fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
918 if (cu == 0 && e1sq == 0)
continue;
920 Int_t binx,biny,binz;
921 hist->GetBinXYZ(ibin, binx, biny, binz);
924 const char * labelX = 0;
925 const char * labelY = 0;
926 const char * labelZ = 0;
927 labelX=hist->GetXaxis()->GetBinLabel(binx);
928 if (
fH0->
fDimension > 1) labelY = hist->GetYaxis()->GetBinLabel(biny);
929 if (
fH0->
fDimension > 2) labelZ = hist->GetYaxis()->GetBinLabel(binz);
939 if (binx == 0 &&
TString(labelX) ==
"" ) ix = 0;
942 if (biny == 0 &&
TString(labelY) ==
"" ) iy = 0;
946 if (binz == 0 &&
TString(labelZ) ==
"" ) iz = 0;
974 Info(
"TH1Merge::LabelMerge",
"Merge bin [%d,%d,%d] with label [%s,%s,%s] into bin [%d,%d,%d]",
975 binx,biny,binz,labelX,labelY,labelZ,ix,iy,iz);
979 Fatal(
"TH1Merger::LabelMerge",
"Fatal error merging histogram %s - bin number is %d and array size is %d",
virtual const char * GetName() const
Returns name of object.
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
TH1 * fHClone
histogram on which the list is merged
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Int_t GetFirst() const
Return first bin on the axis i.e.
#define PRINTRANGE(a, b, bn)
static Bool_t AxesHaveLimits(const TH1 *h)
void DefineNewAxes()
Function to define new histogram axis when merging It is call only in case of merging with different ...
void Fatal(const char *location, const char *msgfmt,...)
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
TAxis fYaxis
Y axis descriptor.
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
const Double_t * GetArray() const
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
virtual Int_t GetEntries() const
Bool_t LabelMerge()
Merge histograms with labels.
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
static Int_t FindFixBinNumber(Int_t ibin, const TAxis &inAxis, const TAxis &outAxis)
TList fInputList
copy of fH0 - managed by this class
TArrayD fSumw2
Array of sum of squares of weights.
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
TAxis fZaxis
Z axis descriptor.
Bool_t AutoP2BufferMerge()
void CopyBuffer(TH1 *hsrc, TH1 *hdes)
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
virtual Int_t GetDimension() const
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Bool_t operator()()
Function performing the actual merge.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Use Power(2)-based algorithm for autobinning.
THashList * GetLabels() const
static double p2(double t, double a, double b, double c)
void Info(const char *location, const char *msgfmt,...)
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
void Error(const char *location, const char *msgfmt,...)
The 3-D histogram classes derived from the 1-D histogram classes.
Bool_t DifferentAxesMerge()
Merged histogram when axis can be different.
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Int_t GetLast() const
Return last bin on the axis i.e.
Service class for 2-Dim histogram classes.
Class to manage histogram axis.
void SetCanExtend(Bool_t canExtend)
Bool_t AutoP2BuildAxes(TH1 *)
Determine final boundaries and number of bins for histograms created in power-of-2 autobin mode...
virtual TObject * Remove(TObject *obj)
Remove object from the list.
virtual void Copy(TObject &hnew) const
Copy this histogram structure to newth1.
static double p1(double t, double a, double b)
void Warning(const char *location, const char *msgfmt,...)
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
virtual Double_t RetrieveBinContent(Int_t bin) const
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
virtual Int_t GetSumw2N() const
Bool_t CanBeAlphanumeric()
EMergerType ExamineHistograms()
Examine the list of histograms to find out which type of Merge we need to do Pass the input list cont...
virtual Double_t GetEntries() const
Return the current number of entries.
virtual UInt_t SetCanExtend(UInt_t extendBitMask)
Make the histogram axes extendable / not extendable according to the bit mask returns the previous bi...
virtual void Add(TObject *obj)
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
virtual void SetBinsLength(Int_t=-1)
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
virtual void SetEntries(Double_t n)
TAxis fXaxis
X axis descriptor.
virtual Int_t GetSize() const
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Double_t * fBuffer
[fBufferSize] entry buffer
void Set(Int_t n)
Set size of this array to n doubles.
const TArrayD * GetXbins() const
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows