Logo ROOT   6.14/05
Reference Guide
TH1Merger.cxx
Go to the documentation of this file.
1 // Helper clas implementing some of the TH1 functionality
2 
3 #include "TH1Merger.h"
4 #include "TH1.h"
5 #include "TH2.h"
6 #include "TH3.h"
7 #include "TAxis.h"
8 #include "TError.h"
9 #include "THashList.h"
10 #include "TClass.h"
11 #include <iostream>
12 #include <limits>
13 #include <utility>
14 
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(), \
17  b->GetNbins());
18 
20  Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
21  if (h->GetDimension() > 1) hasLimits &= h->GetYaxis()->GetXmin() < h->GetYaxis()->GetXmax();
22  if (h->GetDimension() > 2) hasLimits &= h->GetZaxis()->GetXmin() < h->GetZaxis()->GetXmax();
23  return hasLimits;
24 }
25 
26 /// Function performing the actual merge
28 
29 
31 
32  if (gDebug) Info("Merge","Histogram Merge type is %d and new axis flag is %d",(int) type,(int) fNewAxisFlag);
33 
34  if (type == kNotCompatible) return kFALSE;
35 
36  if (type == kAllSameAxes)
37  return SameAxesMerge();
38 
39  if (type == kAllLabel)
40  return LabelMerge();
41 
42  if (type == kAllNoLimits)
43  return BufferMerge();
44 
45  if (type == kAutoP2HaveLimits || (type == kAutoP2NeedLimits && AutoP2BufferMerge()))
46  return AutoP2Merge();
47 
48  // this is the mixed case - more complicated
49  if (type == kHasNewLimits) {
50  // we need to define some new axes
51  DefineNewAxes();
52  // we might need to merge some histogram using the buffer
53  Bool_t ret = BufferMerge();
54  // if ret is true the merge is completed and we can exit
55  if (ret) return kTRUE;
56  // in the other cases then we merge using FindBin
57  return DifferentAxesMerge();
58  }
59  Error("TH1Merger","Unknown type of Merge for histogram %s",fH0->GetName());
60  return kFALSE;
61 }
62 
63 /////////////////////////////////////////////////////////////////////////////////////////
64 /// Determine final boundaries and number of bins for histograms created in power-of-2
65 /// autobin mode.
66 ///
67 /// Return kTRUE if compatible, updating fNewXaxis accordingly; return kFALSE if something
68 /// wrong.
69 ///
70 /// The histograms are not merge-compatible if
71 ///
72 /// 1. have different variable-size bins
73 /// 2. larger bin size is not an integer multiple of the smaller one
74 /// 3. the final estimated range is smalle then the bin size
75 ///
76 
78 {
79  // They must be both defined
80  if (!h) {
81  Error("AutoP2BuildAxes", "undefined histogram: %p", h);
82  return kFALSE;
83  }
84 
85  // They must be created in power-of-2 autobin mode
86  if (!h->TestBit(TH1::kAutoBinPTwo)) {
87  Error("AutoP2BuildAxes", "not in autobin-power-of-2 mode!");
88  return kFALSE;
89  }
90 
91  // Point to axes
92  TAxis *a0 = &fNewXAxis, *a1 = h->GetXaxis();
93 
94  // This is for future merging of detached ranges (only possible if no over/underflows)
95  Bool_t canextend = (h->GetBinContent(0) > 0 || h->GetBinContent(a1->GetNbins() + 1) > 0) ? kFALSE : kTRUE;
96 
97  // The first time we just copy the boundaries and bins
98  if (a0->GetFirst() == a0->GetLast()) {
99  a0->Set(a1->GetNbins(), a1->GetXmin(), a1->GetXmax());
100  // This is for future merging of detached ranges (only possible if no over/underflows)
101  a0->SetCanExtend(canextend);
102  return kTRUE;
103  }
104 
105  // Bin sizes must be in integer ratio
106  Double_t bwmax = (a0->GetXmax() - a0->GetXmin()) / a0->GetNbins();
107  Double_t bwmin = (a1->GetXmax() - a1->GetXmin()) / a1->GetNbins();
108  Bool_t b0 = kTRUE;
109  if (bwmin > bwmax) {
110  std::swap(bwmax, bwmin);
111  b0 = kFALSE;
112  }
113  if (!(bwmin > 0.)) {
114  PRINTRANGE(a0, a1, h->GetName());
115  Error("AutoP2BuildAxes", "minimal bin width negative or null: %f", bwmin);
116  return kFALSE;
117  }
118 
119  Double_t rt;
120  Double_t re = std::modf(bwmax / bwmin, &rt);
122  PRINTRANGE(a0, a1, h->GetName());
123  Error("AutoP2BuildAxes", "bin widths not in integer ratio: %f", re);
124  return kFALSE;
125  }
126 
127  // Range of the merged histogram, taking into account overlaps
128  Bool_t domax = kFALSE;
129  Double_t xmax, xmin;
130  if (a0->GetXmin() < a1->GetXmin()) {
131  if (a0->GetXmax() < a1->GetXmin()) {
132  if (!a0->CanExtend() || !canextend) {
133  PRINTRANGE(a0, a1, h->GetName());
134  Error("AutoP2BuildAxes", "ranges are disconnected and under/overflows: cannot merge");
135  return kFALSE;
136  }
137  xmax = a1->GetXmax();
138  xmin = a0->GetXmin();
139  domax = b0 ? kTRUE : kFALSE;
140  } else {
141  if (a0->GetXmax() >= a1->GetXmax()) {
142  xmax = a1->GetXmax();
143  xmin = a1->GetXmin();
144  domax = !b0 ? kTRUE : kFALSE;
145  } else {
146  xmax = a0->GetXmax();
147  xmin = a1->GetXmin();
148  domax = !b0 ? kTRUE : kFALSE;
149  }
150  }
151  } else {
152  if (a1->GetXmax() < a0->GetXmin()) {
153  if (!a0->CanExtend() || !canextend) {
154  PRINTRANGE(a0, a1, h->GetName());
155  Error("AutoP2BuildAxes", "ranges are disconnected and under/overflows: cannot merge");
156  return kFALSE;
157  }
158  xmax = a0->GetXmax();
159  xmin = a1->GetXmin();
160  domax = !b0 ? kTRUE : kFALSE;
161  } else {
162  if (a1->GetXmax() >= a0->GetXmax()) {
163  xmax = a0->GetXmax();
164  xmin = a0->GetXmin();
165  domax = b0 ? kTRUE : kFALSE;
166  } else {
167  xmax = a1->GetXmax();
168  xmin = a0->GetXmin();
169  domax = b0 ? kTRUE : kFALSE;
170  }
171  }
172  }
173  Double_t range = xmax - xmin;
174 
175  re = std::modf(range / bwmax, &rt);
176  if (rt < 1.) {
177  PRINTRANGE(a0, a1, h->GetName());
178  Error("MergeCompatibleHistograms", "range smaller than bin width: %f %f %f", range, bwmax, rt);
179  return kFALSE;
180  }
182  if (domax) {
183  xmax -= bwmax * re;
184  } else {
185  xmin += bwmax * re;
186  }
187  }
188  // Number of bins
189  Int_t nb = (Int_t)rt;
190 
191  // Set the result
192  a0->Set(nb, xmin, xmax);
193 
194  // This is for future merging of detached ranges (only possible if no over/underflows)
195  if (!a0->CanExtend())
196  a0->SetCanExtend(canextend);
197 
198  // Done
199  return kTRUE;
200 }
201 
202 /**
203  Examine the list of histograms to find out which type of Merge we need to do
204  Pass the input list containing the histogram to merge and h0 which is the initial histogram
205  on which all the histogram of the list will be merged
206  This are the possible cases:
207  - 1. All histogram have the same axis (allSameLimits = true)
208  - 2. Histogram have different axis but compatible (allSameLimits = false) and sameLimitsX,Y,Z specifies which axis
209  has different limits
210  - 3. Histogram do not have limits (so the Buffer is used) allHaveLimits = false
211  - 3b. One histogram has limits the other not : allHaveLimits = false AND initialLimitsFound = true
212  - 4. Histogram Have labels = allHaveLabels = true
213 
214 
215 */
217 
218 
219 
220  Bool_t initialLimitsFound = kFALSE;
221  Bool_t allHaveLabels = kTRUE; // assume all histo have labels and check later
222  Bool_t allHaveLimits = kTRUE;
223  Bool_t allSameLimits = kTRUE;
224  Bool_t sameLimitsX = kTRUE;
225  Bool_t sameLimitsY = kTRUE;
226  Bool_t sameLimitsZ = kTRUE;
227  Bool_t foundLabelHist = kFALSE;
228  Bool_t haveWeights = kFALSE;
229 
230  Bool_t isAutoP2 = kFALSE;
231 
232  // TAxis newXAxis;
233  // TAxis newYAxis;
234  // TAxis newZAxis;
235 
236  TIter next(&fInputList);
237  TH1 * h = fH0; // start with fH0
238 
239  int dimension = fH0->GetDimension();
240 
241  isAutoP2 = fH0->TestBit(TH1::kAutoBinPTwo) ? kTRUE : kFALSE;
242 
243  // start looping on the histograms
244 
245  do {
246 
247  // check first histogram compatibility
248  if (h != fH0) {
249  if (h->GetDimension() != dimension) {
250  Error("Merge", "Cannot merge histogram - dimensions are different\n "
251  "%s has dim=%d and %s has dim=%d",fH0->GetName(),dimension,h->GetName(),h->GetDimension());
252  return kNotCompatible;
253  }
254  }
255 
256  // check if one of the histogram is weighted
257  haveWeights |= h->GetSumw2N() != 0;
258 
259  // do not skip anymore empty histograms
260  // since are used to set the limits
261  Bool_t hasLimits = TH1Merger::AxesHaveLimits(h);
262  allHaveLimits = allHaveLimits && hasLimits;
263  allSameLimits &= allHaveLimits;
264 
265  if (isAutoP2 && !h->TestBit(TH1::kAutoBinPTwo)) {
266  Error("Merge", "Cannot merge histogram - some are in autobin-power-of-2 mode, but not %s!", h->GetName());
267  return kNotCompatible;
268  }
269  if (!isAutoP2 && h->TestBit(TH1::kAutoBinPTwo)) {
270  Error("Merge", "Cannot merge histogram - %s is in autobin-power-of-2 mode, but not the previous ones",
271  h->GetName());
272  return kNotCompatible;
273  }
274 
275  if (hasLimits) {
276  h->BufferEmpty();
277 
278 // // this is done in case the first histograms are empty and
279 // // the histogram have different limits
280 // #ifdef LATER
281 // if (firstHistWithLimits ) {
282 // // set axis limits in the case the first histogram did not have limits
283 // if (h != this && !SameLimitsAndNBins( fXaxis, *h->GetXaxis()) ) {
284 // if (h->GetXaxis()->GetXbins()->GetSize() != 0) fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXbins()->GetArray());
285 // else fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
286 // }
287 // firstHistWithLimits = kFALSE;
288 // }
289 // #endif
290 
291  // this is executed the first time an histogram with limits is found
292  // to set some initial values on the new axis
293  if (!initialLimitsFound) {
294  initialLimitsFound = kTRUE;
295  if (h->GetXaxis()->GetXbins()->GetSize() != 0)
296  fNewXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXbins()->GetArray());
297  else
298  fNewXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
299  if (dimension > 1) {
300  if (h->GetYaxis()->GetXbins()->GetSize() != 0)
301  fNewYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXbins()->GetArray());
302  else
303  fNewYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
304  }
305  if (dimension > 2) {
306  if (h->GetZaxis()->GetXbins()->GetSize() != 0)
307  fNewZAxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXbins()->GetArray());
308  else
309  fNewZAxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(), h->GetZaxis()->GetXmax());
310 
311  }
312  }
313  else {
314  // check first if histograms have same bins in X
315  if (!TH1::SameLimitsAndNBins(fNewXAxis, *(h->GetXaxis())) ) {
316  sameLimitsX = kFALSE;
317  // recompute the limits in this case the optimal limits
318  // The condition to works is that the histogram have same bin with
319  // and one common bin edge
321  Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
322  "first: %s (%d, %f, %f), second: %s (%d, %f, %f)", fH0->GetName(),
324  h->GetName(),h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
325  h->GetXaxis()->GetXmax());
326  return kNotCompatible;
327  }
328  }
329  // check first if histograms have same bins in Y
330  if (dimension > 1 && !TH1::SameLimitsAndNBins(fNewYAxis, *(h->GetYaxis()))) {
331  sameLimitsY = kFALSE;
332  // recompute in this case the optimal limits
333  // The condition to works is that the histogram have same bin with
334  // and one common bin edge
336  Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
337  "first: %s (%d, %f, %f), second: %s (%d, %f, %f)", fH0->GetName(),
339  h->GetName(), h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
340  h->GetYaxis()->GetXmax());
341  return kNotCompatible;
342  }
343  }
344  if(dimension > 2 && !fH0->SameLimitsAndNBins(fNewZAxis, *(h->GetZaxis()))) {
345  sameLimitsZ = kFALSE;
347  Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
348  "first: %s (%d, %f, %f), second: %s (%d, %f, %f)", fH0->GetName(),
350  h->GetName(),h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
351  h->GetZaxis()->GetXmax());
352  return kNotCompatible;
353  }
354  }
355  allSameLimits = sameLimitsX && sameLimitsY && sameLimitsZ;
356 
357 
358  }
359  }
360  Bool_t histoIsEmpty = h->IsEmpty();
361  // std::cout << "considering histo " << h->GetName() << " labels - " << allHaveLabels << " is empty "
362  // << histoIsEmpty << std::endl;
363 
364  // if histogram is empty it does not matter if it has label or not
365  if (allHaveLabels && !histoIsEmpty) {
366  THashList* hlabels=h->GetXaxis()->GetLabels();
367  Bool_t haveOneLabel = (hlabels != nullptr);
368  // do here to print message only one time
369  if (foundLabelHist && allHaveLabels && !haveOneLabel) {
370  Warning("Merge","Not all histograms have labels. I will ignore labels,"
371  " falling back to bin numbering mode.");
372  }
373 
374  allHaveLabels &= (haveOneLabel);
375  // for the error message
376  if (haveOneLabel) foundLabelHist = kTRUE;
377 
378  if (foundLabelHist && gDebug)
379  Info("TH1Merger::ExamineHistogram","Histogram %s has labels",h->GetName() );
380 
381  // If histograms have labels but CanExtendAllAxes() is false
382  // use bin center mode
383  if (allHaveLabels && !fH0->CanExtendAllAxes()) {
384  // special case for this histogram when is empty
385  // and axis cannot be extended (because it is the default)
386  if ( fH0->IsEmpty() ) {
387  if (gDebug)
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());
389  UInt_t bitMaskX = fH0->GetXaxis()->CanBeAlphanumeric() & TH1::kXaxis;
390  UInt_t bitMaskY = (fH0->GetYaxis()->CanBeAlphanumeric() << 1 ) & TH1::kYaxis;
391  UInt_t bitMaskZ = (fH0->GetZaxis()->CanBeAlphanumeric() << 2 ) & TH1::kZaxis;
392  fH0->SetCanExtend(bitMaskX | bitMaskY | bitMaskZ );
393  }
394  if (!fH0->CanExtendAllAxes()) {
395  if (gDebug)
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());
397  allHaveLabels = kFALSE;
398  }
399  }
400  // I could add a check if histogram contains bins without a label
401  // and with non-zero bin content
402  // Do we want to support this ???
403  // only in case the !h->CanExtendAllAxes()
404  if (allHaveLabels && !h->CanExtendAllAxes()) {
405  // count number of bins with non-null content
406  Int_t non_zero_bins = 0;
407  Int_t nbins = h->GetXaxis()->GetNbins();
408  if (nbins > hlabels->GetEntries() ) {
409  for (Int_t i = 1; i <= nbins; i++) {
410  if (h->RetrieveBinContent(i) != 0 || (fH0->fSumw2.fN && h->GetBinError(i) != 0) ) {
411  non_zero_bins++;
412  }
413  }
414  if (non_zero_bins > hlabels->GetEntries() ) {
415  Warning("TH1Merger::ExamineHistograms","Histogram %s contains non-empty bins without labels - falling back to bin numbering mode",h->GetName() );
416  allHaveLabels = kFALSE;
417  }
418  }
419  }
420  }
421  if (gDebug)
422  Info("TH1Merger::ExamineHistogram","Examine histogram %s - labels %d - same limits %d - axis found %d",h->GetName(),allHaveLabels,allSameLimits,initialLimitsFound );
423 
424  } while ( ( h = dynamic_cast<TH1*> ( next() ) ) != NULL );
425 
426  if (!h && (*next) ) {
427  Error("Merge","Attempt to merge object of class: %s to a %s",
428  (*next)->ClassName(),fH0->ClassName());
429  return kNotCompatible;
430  }
431 
432  // in case of weighted histogram set Sumw2() on fH0 is is not weighted
433  if (haveWeights && fH0->GetSumw2N() == 0)
434  fH0->Sumw2();
435 
436  // AutoP2
437  if (isAutoP2) {
438  if (allHaveLimits)
439  return kAutoP2HaveLimits;
440  return kAutoP2NeedLimits;
441  }
442 
443  // return the type of merge
444  if (allHaveLabels) return kAllLabel;
445  if (allSameLimits) return kAllSameAxes;
446  if (!initialLimitsFound) {
447  R__ASSERT(!allHaveLimits);
448  // case where no limits are found and the buffer is used
449  return kAllNoLimits;
450  }
451  // remaining case should be the mixed one. Some histogram have limits some not
452  fNewAxisFlag = 0;
453  if (!sameLimitsX) fNewAxisFlag |= TH1::kXaxis;
454  if (!sameLimitsY) fNewAxisFlag |= TH1::kYaxis;
455  if (!sameLimitsZ) fNewAxisFlag |= TH1::kZaxis;
456 
457  // we need to set the flag also in case this histogram has no limits
458  // we need to set explicitly the flag to re-define a new axis
460  if (dimension > 1 && fH0->GetYaxis()->GetXmin() >= fH0->GetYaxis()->GetXmax()) fNewAxisFlag |= TH1::kYaxis;
461  if (dimension > 2 && fH0->GetZaxis()->GetXmin() >= fH0->GetZaxis()->GetXmax()) fNewAxisFlag |= TH1::kZaxis;
462 
463 
464  return kHasNewLimits;
465 
466 }
467 
468 /**
469  Function to define new histogram axis when merging
470  It is call only in case of merging with different axis or with the
471  buffer (kHasNewLimits)
472 */
473 
475 
476  // first we need to create a copy of the histogram in case is not empty
477 
478  if (!fH0->IsEmpty() ) {
479  Bool_t mustCleanup = fH0->TestBit(kMustCleanup);
480  if (mustCleanup) fH0->ResetBit(kMustCleanup);
481  fHClone = (TH1*)fH0->IsA()->New();
482  fHClone->SetDirectory(0);
483  fH0->Copy(*fHClone);
484  if (mustCleanup) fH0->SetBit(kMustCleanup);
485  fH0->BufferEmpty(1); // To remove buffer.
486  fH0->Reset(); // BufferEmpty sets limits so we can't use it later.
487  fH0->SetEntries(0);
489 
490  }
491 
492  bool newLimitsX = (fNewAxisFlag & TH1::kXaxis);
493  bool newLimitsY = (fNewAxisFlag & TH1::kYaxis);
494  bool newLimitsZ = (fNewAxisFlag & TH1::kZaxis);
495  if (newLimitsX) {
496  fH0->fXaxis.SetRange(0,0);
497  if (fNewXAxis.GetXbins()->GetSize() != 0)
499  else
501  }
502  if (newLimitsY) {
503  fH0->fYaxis.SetRange(0,0);
504  if (fNewYAxis.GetXbins()->GetSize() != 0)
506  else
508  }
509  if (newLimitsZ) {
510  fH0->fZaxis.SetRange(0,0);
511  if (fNewZAxis.GetXbins()->GetSize() != 0)
513  else
515  }
516 
517  // we need to recompute fNcells and set the array size (as in TH1::SetBins)
518  fH0->fNcells = fH0->fXaxis.GetNbins()+2;
519  if (fH0->fDimension > 1) fH0->fNcells *= fH0->fYaxis.GetNbins()+2;
520  if (fH0->fDimension > 2) fH0->fNcells *= fH0->fZaxis.GetNbins()+2;
522  if (fH0->fSumw2.fN) fH0->fSumw2.Set(fH0->fNcells);
523  // set dummy Y and Z axis for lower dim histogras
524  if (fH0->fDimension < 3) fH0->fZaxis.Set(1,0,1);
525  if (fH0->fDimension < 2) fH0->fYaxis.Set(1,0,1);
526 
527  if (gDebug) {
528  if (newLimitsX) Info("DefineNewAxis","A new X axis has been defined Nbins=%d , [%f,%f]", fH0->fXaxis.GetNbins(),
529  fH0->fXaxis.GetXmin(), fH0->fXaxis.GetXmax() );
530  if (newLimitsY) Info("DefineNewAxis","A new Y axis has been defined Nbins=%d , [%f,%f]", fH0->fYaxis.GetNbins(),
531  fH0->fYaxis.GetXmin(), fH0->fYaxis.GetXmax() );
532  if (newLimitsZ) Info("DefineNewAxis","A new Z axis has been defined Nbins=%d , [%f,%f]", fH0->fZaxis.GetNbins(),
533  fH0->fZaxis.GetXmin(), fH0->fZaxis.GetXmax() );
534  }
535 
536  return;
537 
538 }
539 
540 void TH1Merger::CopyBuffer(TH1 *hsrc, TH1 *hdes)
541 {
542  // Check inputs
543  //if (!hsrc || !hsrc->fBuffer || !hdes || !hdes->fBuffer) {
544  if (!hsrc || !hsrc->fBuffer || !hdes ) {
545  void *p1 = hsrc ? hsrc->fBuffer : 0;
546  //void *p2 = hdes ? hdes->fBuffer : 0;
547  //Warning("TH1Merger::CopyMerge", "invalid inputs: %p, %p, %p, %p -> do nothing", hsrc, hdes, p1, p2);
548  Warning("TH1Merger::CopyMerge", "invalid inputs: %p, %p, %p, -> do nothing", hsrc, hdes, p1);
549  }
550 
551  // Entries from buffers have to be filled one by one
552  // because FillN doesn't resize histograms.
553  Int_t nbentries = (Int_t)hsrc->fBuffer[0];
554  if (hdes->fDimension == 1) {
555  for (Int_t i = 0; i < nbentries; i++)
556  hdes->Fill(hsrc->fBuffer[2 * i + 2], hsrc->fBuffer[2 * i + 1]);
557  }
558  if (hdes->fDimension == 2) {
559  auto h2 = dynamic_cast<TH2 *>(hdes);
560  R__ASSERT(h2);
561  for (Int_t i = 0; i < nbentries; i++)
562  h2->Fill(hsrc->fBuffer[3 * i + 2], hsrc->fBuffer[3 * i + 3], hsrc->fBuffer[3 * i + 1]);
563  }
564  if (hdes->fDimension == 3) {
565  auto h3 = dynamic_cast<TH3 *>(hdes);
566  R__ASSERT(h3);
567  for (Int_t i = 0; i < nbentries; i++)
568  h3->Fill(hsrc->fBuffer[4 * i + 2], hsrc->fBuffer[4 * i + 3], hsrc->fBuffer[4 * i + 4],
569  hsrc->fBuffer[4 * i + 1]);
570  }
571 }
572 
574 {
575 
576  TH1 *href = 0, *hist = 0;
577  TIter nextref(&fInputList);
579  href = fH0;
580  } else {
581  while ((hist = (TH1 *)nextref()) && !href) {
582  if (TH1Merger::AxesHaveLimits(hist))
583  href = hist;
584  }
585  }
586  Bool_t resetfH0 = kFALSE;
587  if (!href) {
588  // Merge all histograms to fH0 and do a final projection
589  href = fH0;
590  } else {
591  if (href != fH0) {
592  // Temporary add fH0 to the list for buffer merging
593  fInputList.Add(fH0);
594  resetfH0 = kTRUE;
595  }
596  }
597  TIter next(&fInputList);
598  while ((hist = (TH1 *)next())) {
599  if (!TH1Merger::AxesHaveLimits(hist) && hist->fBuffer) {
600  if (gDebug)
601  Info("AutoP2BufferMerge", "merging buffer of %s into %s", hist->GetName(), href->GetName());
602  CopyBuffer(hist, href);
603  fInputList.Remove(hist);
604  }
605  }
606  // Final projection
607  if (href->fBuffer)
608  href->BufferEmpty(1);
609  // Reset fH0, if already added, to avoid double counting
610  if (resetfH0)
611  fH0->Reset("ICES");
612  // Done, all histos have been processed
613  return kTRUE;
614 }
615 
617 {
618 
619  Double_t stats[TH1::kNstat], totstats[TH1::kNstat];
620  for (Int_t i = 0; i < TH1::kNstat; i++) {
621  totstats[i] = stats[i] = 0;
622  }
623 
624  TIter next(&fInputList);
625  TH1 *hist = 0;
626  // Calculate boundaries and bins
627  Double_t xmin = 0., xmax = 0.;
628  if (!(fH0->IsEmpty())) {
629  hist = fH0;
630  } else {
631  while ((hist = (TH1 *)next())) {
632  if (!hist->IsEmpty())
633  break;
634  }
635  }
636 
637  if (!hist) {
638  if (gDebug)
639  Info("TH1Merger::AutoP2Merge", "all histograms look empty!");
640  return kFALSE;
641  }
642 
643  // Start building the axes from the reference histogram
644  if (!AutoP2BuildAxes(hist)) {
645  Error("TH1Merger::AutoP2Merge", "cannot create axes from %s", hist->GetName());
646  return kFALSE;
647  }
648  TH1 *h = 0;
649  while ((h = (TH1 *)next())) {
650  if (!AutoP2BuildAxes(h)) {
651  Error("TH1Merger::AutoP2Merge", "cannot merge histogram %s: not merge compatible", h->GetName());
652  return kFALSE;
653  }
654  }
655  xmin = fNewXAxis.GetXmin();
656  xmax = fNewXAxis.GetXmax();
657  Int_t nbins = fNewXAxis.GetNbins();
658 
659  // Prepare stats
660  fH0->GetStats(totstats);
661  // Clone fH0 and add it to the list
662  if (!fH0->IsEmpty())
663  fInputList.Add(fH0->Clone());
664 
665  // reset fH0
666  fH0->Reset("ICES");
667  // Set the new boundaries
668  fH0->SetBins(nbins, xmin, xmax);
669 
670  next.Reset();
671  Double_t nentries = 0.;
672  while ((hist = (TH1 *)next())) {
673  // process only if the histogram has limits; otherwise it was processed before
674  // in the case of an existing buffer (see if statement just before)
675 
676  if (gDebug)
677  Info("TH1Merger::AutoP2Merge", "merging histogram %s into %s (entries: %f)", hist->GetName(), fH0->GetName(),
678  hist->GetEntries());
679 
680  // skip empty histograms
681  if (hist->IsEmpty())
682  continue;
683 
684  // import statistics
685  hist->GetStats(stats);
686  for (Int_t i = 0; i < TH1::kNstat; i++)
687  totstats[i] += stats[i];
688  nentries += hist->GetEntries();
689 
690  // Int_t nx = hist->GetXaxis()->GetNbins();
691  // loop on bins of the histogram and do the merge
692  for (Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
693 
694  Double_t cu = hist->RetrieveBinContent(ibin);
695  Double_t e1sq = TMath::Abs(cu);
696  if (fH0->fSumw2.fN)
697  e1sq = hist->GetBinErrorSqUnchecked(ibin);
698 
699  Double_t xu = hist->GetBinCenter(ibin);
700  Int_t jbin = fH0->FindBin(xu);
701 
702  fH0->AddBinContent(jbin, cu);
703  if (fH0->fSumw2.fN)
704  fH0->fSumw2.fArray[jbin] += e1sq;
705  }
706  }
707  // copy merged stats
708  fH0->PutStats(totstats);
709  fH0->SetEntries(nentries);
710 
711  return kTRUE;
712 }
713 
715 {
716 
717  TIter next(&fInputList);
718  while (TH1* hist = (TH1*)next()) {
719  // support also case where some histogram have limits and some have the buffer
720  if ( !TH1Merger::AxesHaveLimits(hist) && hist->fBuffer ) {
721 
722  if (gDebug)
723  Info("TH1Merger::BufferMerge","Merging histogram %s into %s",hist->GetName(), fH0->GetName() );
724  CopyBuffer(hist, fH0);
725  fInputList.Remove(hist);
726  }
727  }
728  // return true if the merge is completed
729  if (fInputList.GetSize() == 0) {
730  // all histo have been merged
731  return kTRUE;
732  }
733  // we need to reset the buffer in case of merging later on
734  // is this really needed ???
735  if (fH0->fBuffer) fH0->BufferEmpty(1);
736 
737  return kFALSE;
738 }
739 
741 
742 
743  Double_t stats[TH1::kNstat], totstats[TH1::kNstat];
744  for (Int_t i=0;i<TH1::kNstat;i++) {
745  totstats[i] = stats[i] = 0;
746  }
747  fH0->GetStats(totstats);
749 
750  TIter next(&fInputList);
751  while (TH1* hist=(TH1*)next()) {
752  // process only if the histogram has limits; otherwise it was processed before
753  // in the case of an existing buffer (see if statement just before)
754 
755  if (gDebug)
756  Info("TH1Merger::SameAxesMerge","Merging histogram %s into %s",hist->GetName(), fH0->GetName() );
757 
758  // skip empty histograms
759  if (hist->IsEmpty()) continue;
760 
761  // import statistics
762  hist->GetStats(stats);
763  for (Int_t i=0; i<TH1::kNstat; i++)
764  totstats[i] += stats[i];
765  nentries += hist->GetEntries();
766 
767  //Int_t nx = hist->GetXaxis()->GetNbins();
768  // loop on bins of the histogram and do the merge
769  for (Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
770 
771  Double_t cu = hist->RetrieveBinContent(ibin);
772  Double_t e1sq = TMath::Abs(cu);
773  if (fH0->fSumw2.fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
774 
775  fH0->AddBinContent(ibin,cu);
776  if (fH0->fSumw2.fN) fH0->fSumw2.fArray[ibin] += e1sq;
777 
778  }
779  }
780  //copy merged stats
781  fH0->PutStats(totstats);
782  fH0->SetEntries(nentries);
783 
784  return kTRUE;
785 }
786 
787 
788 /**
789  Merged histogram when axis can be different.
790  Histograms are merged looking at bin center positions
791 
792  */
794 
795  Double_t stats[TH1::kNstat], totstats[TH1::kNstat];
796  for (Int_t i=0;i<TH1::kNstat;i++) {totstats[i] = stats[i] = 0;}
797  fH0->GetStats(totstats);
799 
800  TIter next(&fInputList);
801  while (TH1* hist=(TH1*)next()) {
802 
803  if (gDebug)
804  Info("TH1Merger::DifferentAxesMerge","Merging histogram %s into %s",hist->GetName(), fH0->GetName() );
805 
806  // skip empty histograms
807  if (hist->IsEmpty()) continue;
808 
809  // import statistics
810  hist->GetStats(stats);
811  for (Int_t i=0;i<TH1::kNstat;i++)
812  totstats[i] += stats[i];
813  nentries += hist->GetEntries();
814 
815  // loop on bins of the histogram and do the merge
816  for (Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
817 
818  Double_t cu = hist->RetrieveBinContent(ibin);
819  Double_t e1sq = TMath::Abs(cu);
820  if (fH0->fSumw2.fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
821 
822  // if bin is empty we can skip it
823  if (cu == 0 && e1sq == 0) continue;
824 
825  Int_t binx,biny,binz;
826  hist->GetBinXYZ(ibin, binx, biny, binz);
827 
828  // case of underflow/overflows in the histogram being merged
829  if (binx <= 0 || binx >= hist->GetNbinsX() + 1) {
830  if (fH0->fXaxis.CanExtend() || ( hist->fXaxis.GetBinCenter(binx) > fH0->fXaxis.GetXmin() && hist->fXaxis.GetBinCenter(binx) < fH0->fXaxis.GetXmax()) ) {
831  Error("TH1Merger::DifferentAxesMerge", "Cannot merge histograms - the histograms %s can extend the X axis or have"
832  " different limits and underflows/overflows are present in the histogram %s.",fH0->GetName(),hist->GetName());
833  return kFALSE;
834  }
835  }
836  if (biny <= 0 || biny >= hist->GetNbinsY() + 1) {
837  if (fH0->fYaxis.CanExtend() || ( hist->fYaxis.GetBinCenter(biny) > fH0->fYaxis.GetXmin() && hist->fYaxis.GetBinCenter(biny) < fH0->fYaxis.GetXmax()) ) {
838  Error("TH1Merger::DifferentAxesMerge", "Cannot merge histograms - the histograms %s can extend the Y axis or have"
839  " different limits and underflows/overflows are present in the histogram %s.",fH0->GetName(),hist->GetName());
840  return kFALSE;
841  }
842  }
843  if (binz <= 0 || binz >= hist->GetNbinsZ() + 1) {
844  if (fH0->fZaxis.CanExtend() || ( hist->fZaxis.GetBinCenter(binz) > fH0->fZaxis.GetXmin() && hist->fZaxis.GetBinCenter(binz) < fH0->fZaxis.GetXmax()) ) {
845  Error("TH1Merger::DifferentAxesMerge", "Cannot merge histograms - the histograms %s can extend the Z axis or have"
846  " different limits and underflows/overflows are present in the histogram %s.",fH0->GetName(),hist->GetName());
847  return kFALSE;
848  }
849  }
850 
851  Int_t ix = 0;
852  Int_t iy = 0;
853  Int_t iz = 0;
854 
855  // we can extend eventually the axis if histogram is capable of doing it
856  // by using FindBin
857  ix = fH0->fXaxis.FindBin(hist->GetXaxis()->GetBinCenter(binx));
858  if (fH0->fDimension > 1)
859  iy = fH0->fYaxis.FindBin(hist->GetYaxis()->GetBinCenter(biny));
860  if (fH0->fDimension > 2)
861  iz = fH0->fZaxis.FindBin(hist->GetZaxis()->GetBinCenter(binz));
862 
863  Int_t ib = fH0->GetBin(ix,iy,iz);
864  if (ib < 0 || ib > fH0->fNcells) {
865  Fatal("TH1Merger::LabelMerge","Fatal error merging histogram %s - bin number is %d and array size is %d",
866  fH0->GetName(), ib,fH0->fNcells);
867  }
868 
869  fH0->AddBinContent(ib,cu);
870  if (fH0->fSumw2.fN) fH0->fSumw2.fArray[ib] += e1sq;
871  }
872  }
873  //copy merged stats
874  fH0->PutStats(totstats);
875  fH0->SetEntries(nentries);
876 
877  return kTRUE;
878 }
879 
880 
881 /**
882  Merge histograms with labels
883 */
885 
886 
887  Double_t stats[TH1::kNstat], totstats[TH1::kNstat];
888  for (Int_t i=0;i<TH1::kNstat;i++) {totstats[i] = stats[i] = 0;}
889  fH0->GetStats(totstats);
891 
892  TIter next(&fInputList);
893  while (TH1* hist=(TH1*)next()) {
894 
895  if (gDebug)
896  Info("TH1Merger::LabelMerge","Merging histogram %s into %s",hist->GetName(), fH0->GetName() );
897 
898  // skip empty histograms
899  if (hist->IsEmpty()) continue;
900 
901  // import statistics
902  hist->GetStats(stats);
903  for (Int_t i=0;i<TH1::kNstat;i++)
904  totstats[i] += stats[i];
905  nentries += hist->GetEntries();
906 
907  auto labelsX = hist->GetXaxis()->GetLabels();
908  auto labelsY = hist->GetYaxis()->GetLabels();
909  auto labelsZ = hist->GetZaxis()->GetLabels();
910  R__ASSERT(!( labelsX == nullptr && labelsY == nullptr && labelsZ == nullptr));
911 
912  // loop on bins of the histogram and do the merge
913  for (Int_t ibin = 0; ibin < hist->fNcells; ibin++) {
914 
915  Double_t cu = hist->RetrieveBinContent(ibin);
916  Double_t e1sq = cu;
917  if (fH0->fSumw2.fN) e1sq= hist->GetBinErrorSqUnchecked(ibin);
918 
919  // if bin is empty we can skip it
920  if (cu == 0 && e1sq == 0) continue;
921 
922  Int_t binx,biny,binz;
923  hist->GetBinXYZ(ibin, binx, biny, binz);
924 
925  // here only in the case of bins with labels
926  const char * labelX = 0;
927  const char * labelY = 0;
928  const char * labelZ = 0;
929  labelX=hist->GetXaxis()->GetBinLabel(binx);
930  if (fH0->fDimension > 1) labelY = hist->GetYaxis()->GetBinLabel(biny);
931  if (fH0->fDimension > 2) labelZ = hist->GetYaxis()->GetBinLabel(binz);
932  // do we need to support case when there are bins with labels and bins without them ??
933  // this case should have been detected before when examining the histograms
934 
935 
936  Int_t ix = -1;
937  Int_t iy = (fH0->fDimension > 1) ? -1 : 0;
938  Int_t iz = (fH0->fDimension > 2) ? -1 : 0;
939 
940  // special case for underflow/overflows which have normally empty labels
941  if (binx == 0 && TString(labelX) == "" ) ix = 0;
942  if (binx == hist->fXaxis.GetNbins() +1 && TString(labelX) == "" ) ix = fH0->fXaxis.GetNbins() +1;
943  if (fH0->fDimension > 1 ) {
944  if (biny == 0 && TString(labelY) == "" ) iy = 0;
945  if (biny == hist->fYaxis.GetNbins() +1 && TString(labelY) == "" ) iy = fH0->fYaxis.GetNbins() +1;
946  }
947  if (fH0->fDimension > 2 ) {
948  if (binz == 0 && TString(labelZ) == "" ) iz = 0;
949  if (binz == hist->fZaxis.GetNbins() +1 && TString(labelZ) == "" ) iz = fH0->fZaxis.GetNbins() +1;
950  }
951 
952 
953 
954  // find corresponding case (in case bin is not overflow)
955  if (ix == -1) {
956  if (labelsX)
957  ix = fH0->fXaxis.FindBin(labelX);
958  else
959  ix = FindFixBinNumber(binx, hist->fXaxis, fH0->fXaxis);
960  }
961 
962  if (iy == -1 && fH0->fDimension> 1 ) { // check on dim should not be needed
963  if (labelsY)
964  iy= fH0->fYaxis.FindBin(labelY);
965  else
966  iy = FindFixBinNumber(biny, hist->fYaxis, fH0->fYaxis);
967  }
968  if (iz == -1 && fH0->fDimension> 2) {
969  if (labelsZ)
970  iz= fH0->fZaxis.FindBin(labelZ);
971  else
972  iz = FindFixBinNumber(binz, hist->fZaxis, fH0->fZaxis);
973  }
974 
975  if (gDebug)
976  Info("TH1Merge::LabelMerge","Merge bin [%d,%d,%d] with label [%s,%s,%s] into bin [%d,%d,%d]",
977  binx,biny,binz,labelX,labelY,labelZ,ix,iy,iz);
978 
979  Int_t ib = fH0->GetBin(ix,iy,iz);
980  if (ib < 0 || ib >= fH0->fNcells) {
981  Fatal("TH1Merger::LabelMerge","Fatal error merging histogram %s - bin number is %d and array size is %d",
982  fH0->GetName(), ib,fH0->fNcells);
983  }
984 
985  fH0->AddBinContent(ib,cu);
986  if (fH0->fSumw2.fN) fH0->fSumw2.fArray[ib] += e1sq;
987  }
988  }
989  //copy merged stats
990  fH0->PutStats(totstats);
991  fH0->SetEntries(nentries);
992 
993  return kTRUE;
994 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition: TH1.cxx:3572
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3251
TH1 * fHClone
histogram on which the list is merged
Definition: TH1Merger.h:92
float xmin
Definition: THbookFile.cxx:93
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8434
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
#define PRINTRANGE(a, b, bn)
Definition: TH1Merger.cxx:15
static Bool_t AxesHaveLimits(const TH1 *h)
Definition: TH1Merger.cxx:19
void DefineNewAxes()
Function to define new histogram axis when merging It is call only in case of merging with different ...
Definition: TH1Merger.cxx:474
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 ...
Definition: TH1.cxx:8231
TAxis fNewYAxis
Definition: TH1Merger.h:95
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
TAxis fYaxis
Y axis descriptor.
Definition: TH1.h:88
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition: TH1.cxx:7239
const Double_t * GetArray() const
Definition: TArrayD.h:43
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8061
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition: TH1.cxx:5370
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4770
virtual Int_t GetEntries() const
Definition: TCollection.h:177
Bool_t LabelMerge()
Merge histograms with labels.
Definition: TH1Merger.cxx:884
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
#define R__ASSERT(e)
Definition: TError.h:96
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
static Int_t FindFixBinNumber(Int_t ibin, const TAxis &inAxis, const TAxis &outAxis)
Definition: TH1Merger.h:32
Basic string class.
Definition: TString.h:131
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TList fInputList
copy of fH0 - managed by this class
Definition: TH1Merger.h:93
TArrayD fSumw2
Array of sum of squares of weights.
Definition: TH1.h:101
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition: TH1.cxx:5381
TAxis fZaxis
Z axis descriptor.
Definition: TH1.h:89
Bool_t CanExtend() const
Definition: TAxis.h:82
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
Bool_t AutoP2BufferMerge()
Definition: TH1Merger.cxx:573
void CopyBuffer(TH1 *hsrc, TH1 *hdes)
Definition: TH1Merger.cxx:540
void Reset()
Definition: TCollection.h:252
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition: TH1.cxx:7188
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6125
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6583
TAxis fNewZAxis
Definition: TH1Merger.h:96
virtual Int_t GetDimension() const
Definition: TH1.h:277
Double_t GetXmin() const
Definition: TAxis.h:133
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
Bool_t operator()()
Function performing the actual merge.
Definition: TH1Merger.cxx:27
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
Use Power(2)-based algorithm for autobinning.
Definition: TH1.h:169
THashList * GetLabels() const
Definition: TAxis.h:117
void Info(const char *location, const char *msgfmt,...)
Double_t * fArray
Definition: TArrayD.h:30
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:1200
void Error(const char *location, const char *msgfmt,...)
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
Bool_t DifferentAxesMerge()
Merged histogram when axis can be different.
Definition: TH1Merger.cxx:793
UInt_t fNewAxisFlag
Definition: TH1Merger.h:97
Int_t fN
Definition: TArray.h:38
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
TAxis fNewXAxis
Definition: TH1Merger.h:94
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
Class to manage histogram axis.
Definition: TAxis.h:30
Int_t GetSize() const
Definition: TArray.h:47
void SetCanExtend(Bool_t canExtend)
Definition: TAxis.h:86
Bool_t AutoP2BuildAxes(TH1 *)
Determine final boundaries and number of bins for histograms created in power-of-2 autobin mode...
Definition: TH1Merger.cxx:77
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Copy(TObject &hnew) const
Copy this histogram structure to newth1.
Definition: TH1.cxx:2580
Bool_t SameAxesMerge()
Definition: TH1Merger.cxx:740
TAxis * GetYaxis()
Definition: TH1.h:316
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
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.
Definition: TH1.cxx:4672
REAL epsilon
Definition: triangle.c:617
#define h(i)
Definition: RSha256.hxx:106
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...
Definition: TH1.cxx:8732
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual Int_t GetSumw2N() const
Definition: TH1.h:309
Bool_t CanBeAlphanumeric()
Definition: TAxis.h:83
Bool_t BufferMerge()
Definition: TH1Merger.cxx:714
double Double_t
Definition: RtypesCore.h:55
EMergerType ExamineHistograms()
Examine the list of histograms to find out which type of Merge we need to do Pass the input list cont...
Definition: TH1Merger.cxx:216
int type
Definition: TGX11.cxx:120
int nentries
Definition: THbookFile.cxx:89
The TH1 histogram class.
Definition: TH1.h:56
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4185
TAxis * GetZaxis()
Definition: TH1.h:317
virtual UInt_t SetCanExtend(UInt_t extendBitMask)
Make the histogram axes extendable / not extendable according to the bit mask returns the previous bi...
Definition: TH1.cxx:6138
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition: TH1.h:435
virtual void SetBinsLength(Int_t=-1)
Definition: TH1.h:368
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8313
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2657
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
Definition: TH1.h:107
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1346
virtual void SetEntries(Double_t n)
Definition: TH1.h:378
TAxis fXaxis
X axis descriptor.
Definition: TH1.h:87
Bool_t IsEmpty() const
Check if an histogram is empty (this a protected method used mainly by TH1Merger ) ...
Definition: TH1.cxx:4873
void ResetBit(UInt_t f)
Definition: TObject.h:171
TH1 * fH0
Definition: TH1Merger.h:91
Int_t GetNbins() const
Definition: TAxis.h:121
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition: TAxis.cxx:717
Double_t * fBuffer
[fBufferSize] entry buffer
Definition: TH1.h:105
const Bool_t kTRUE
Definition: RtypesCore.h:87
void Set(Int_t n)
Set size of this array to n doubles.
Definition: TArrayD.cxx:106
Double_t GetXmax() const
Definition: TAxis.h:134
Bool_t AutoP2Merge()
Definition: TH1Merger.cxx:616
const TArrayD * GetXbins() const
Definition: TAxis.h:130
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8356
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows
Definition: TH1.h:86