Logo ROOT   6.12/07
Reference Guide
TH2Poly.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // TH2Poly v2.1
3 // Author: Olivier Couet, Deniz Gunceler, Danilo Piparo
4 
5 /*************************************************************************
6  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7  * All rights reserved. *
8  * *
9  * For the licensing terms see $ROOTSYS/LICENSE. *
10  * For the list of contributors see $ROOTSYS/README/CREDITS. *
11  *************************************************************************/
12 
13 #include "TH2Poly.h"
14 #include "TMultiGraph.h"
15 #include "TGraph.h"
16 #include "TClass.h"
17 #include "TList.h"
18 #include "TMath.h"
19 
21 
22 /** \class TH2Poly
23  \ingroup Hist
24 2D Histogram with Polygonal Bins
25 
26 ## Overview
27 `TH2Poly` is a 2D Histogram class (TH2) allowing to define polygonal
28 bins of arbitrary shape.
29 
30 Each bin in the `TH2Poly` histogram is a `TH2PolyBin` object.
31 `TH2PolyBin` is a very simple class containing the vertices (stored
32 as `TGraph`s or `TMultiGraph`s ) and contents of the polygonal
33 bin as well as several related functions.
34 
35 Essentially, a `TH2Poly` is a TList of `TH2PolyBin` objects
36 with methods to manipulate them.
37 
38 Bins are defined using one of the `AddBin()` methods. The bin definition
39 should be done before filling.
40 
41 The histogram can be filled with `Fill(Double_t x, Double_t y, Double_t w)
42 `. `w` is the weight.
43 If no weight is specified, it is assumed to be 1.
44 
45 Not all histogram's area need to be binned. Filling an area without bins,
46 will falls into the overflows. Adding a bin is not retroactive; it doesn't
47 affect previous fillings. A `Fill()` call, that
48 was previously ignored due to the lack of a bin at the specified location, is
49 not reconsidered when that location is binned later.
50 
51 If there are two overlapping bins, the first one in the list will be incremented
52 by `Fill()`.
53 
54 The histogram may automatically extends its limits if a bin outside the
55 histogram limits is added. This is done when the default constructor (with no
56 arguments) is used. It generates a histogram with no limits along the X and Y
57 axis. Adding bins to it will extend it up to a proper size.
58 
59 `TH2Poly` implements a partitioning algorithm to speed up bins' filling.
60 The partitioning algorithm divides the histogram into regions called cells.
61 The bins that each cell intersects are recorded in an array of `TList`s.
62 When a coordinate in the histogram is to be filled; the method (quickly) finds
63 which cell the coordinate belongs. It then only loops over the bins
64 intersecting that cell to find the bin the input coordinate corresponds to.
65 The partitioning of the histogram is updated continuously as each bin is added.
66 The default number of cells on each axis is 25. This number could be set to
67 another value in the constructor or adjusted later by calling the
68 `ChangePartition(Int_t, Int_t)` method. The partitioning algorithm is
69 considerably faster than the brute force algorithm (i.e. checking if each bin
70 contains the input coordinates), especially if the histogram is to be filled
71 many times.
72 
73 The following very simple macro shows how to build and fill a `TH2Poly`:
74 ~~~ {.cpp}
75 {
76  TH2Poly *h2p = new TH2Poly();
77 
78  Double_t x1[] = {0, 5, 6};
79  Double_t y1[] = {0, 0, 5};
80  Double_t x2[] = {0, -1, -1, 0};
81  Double_t y2[] = {0, 0, -1, 3};
82  Double_t x3[] = {4, 3, 0, 1, 2.4};
83  Double_t y3[] = {4, 3.7, 1, 3.7, 2.5};
84 
85  h2p->AddBin(3, x1, y1);
86  h2p->AddBin(4, x2, y2);
87  h2p->AddBin(5, x3, y3);
88 
89  h2p->Fill(0.1, 0.01, 3);
90  h2p->Fill(-0.5, -0.5, 7);
91  h2p->Fill(-0.7, -0.5, 1);
92  h2p->Fill(1, 3, 1.5);
93 }
94 ~~~
95 
96 More examples can be found in th2polyBoxes.C, th2polyEurope.C, th2polyHoneycomb.C
97 and th2polyUSA.C.
98 
99 ## Partitioning Algorithm
100 The partitioning algorithm forms an essential part of the `TH2Poly`
101 class. It is implemented to speed up the filling of bins.
102 
103 With the brute force approach, the filling is done in the following way: An
104 iterator loops over all bins in the `TH2Poly` and invokes the
105 method `IsInside()` for each of them.
106 This method checks if the input location is in that bin. If the filling
107 coordinate is inside, the bin is filled. Looping over all the bin is
108 very slow.
109 
110 The alternative is to divide the histogram into virtual rectangular regions
111 called "cells". Each cell stores the pointers of the bins intersecting it.
112 When a coordinate is to be filled, the method finds which cell the coordinate
113 falls into. Since the cells are rectangular, this can be done very quickly.
114 It then only loops over the bins associated with that cell.
115 
116 The addition of bins to the appropriate cells is done when the bin is added
117 to the histogram. To do this, `AddBin()` calls the
118 `AddBinToPartition()` method.
119 This method adds the input bin to the partitioning matrix.
120 
121 The number of partition cells per axis can be specified in the constructor.
122 If it is not specified, the default value of 25 along each axis will be
123 assigned. This value was chosen because it is small enough to avoid slowing
124 down AddBin(), while being large enough to enhance Fill() by a considerable
125 amount. Regardless of how it is initialized at construction time, it can be
126 changed later with the `ChangePartition()` method.
127 `ChangePartition()` deletes the
128 old partition matrix and generates a new one with the specified number of cells
129 on each axis.
130 
131 The optimum number of partition cells per axis changes with the number of
132 times `Fill()` will be called. Although partitioning greatly speeds up
133 filling, it also adds a constant time delay into the code. When `Fill()`
134 is to be called many times, it is more efficient to divide the histogram into
135 a large number cells. However, if the histogram is to be filled only a few
136 times, it is better to divide into a small number of cells.
137 */
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Default Constructor. No boundaries specified.
141 
143 {
144  Initialize(0., 0., 0., 0., 25, 25);
145  SetName("NoName");
146  SetTitle("NoTitle");
147  SetFloat();
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Constructor with specified name and boundaries,
152 /// but no partition cell number.
153 
154 TH2Poly::TH2Poly(const char *name,const char *title, Double_t xlow,Double_t xup
155  , Double_t ylow,Double_t yup)
156 {
157  Initialize(xlow, xup, ylow, yup, 25, 25);
158  SetName(name);
159  SetTitle(title);
160  SetFloat(kFALSE);
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Constructor with specified name and boundaries and partition cell number.
165 
166 TH2Poly::TH2Poly(const char *name,const char *title,
167  Int_t nX, Double_t xlow, Double_t xup,
168  Int_t nY, Double_t ylow, Double_t yup)
169 {
170  Initialize(xlow, xup, ylow, yup, nX, nY);
171  SetName(name);
172  SetTitle(title);
173  SetFloat(kFALSE);
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Destructor.
178 
180 {
181  delete[] fCells;
182  delete[] fIsEmpty;
183  delete[] fCompletelyInside;
184  // delete at the end the bin List since it owns the objects
185  delete fBins;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Create appropriate histogram bin.
190 /// e.g. TH2Poly creates TH2PolyBin,
191 /// TProfile2Poly creates TProfile2PolyBin
192 /// This is done so that TH2Poly::AddBin does not have to be duplicated,
193 /// but only create needs to be reimplemented for additional histogram types
194 
196 {
197  if (!poly) return 0;
198 
199  if (fBins == 0) {
200  fBins = new TList();
201  fBins->SetOwner();
202  }
203 
204  fNcells++;
205  Int_t ibin = fNcells - kNOverflow;
206  return new TH2PolyBin(poly, ibin);
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Adds a new bin to the histogram. It can be any object having the method
211 /// IsInside(). It returns the bin number in the histogram. It returns 0 if
212 /// it failed to add. To allow the histogram limits to expand when a bin
213 /// outside the limits is added, call SetFloat() before adding the bin.
214 
216 {
217  Int_t ibin = fNcells-kNOverflow;
218  auto *bin = CreateBin(poly);
219  if(!bin) return 0;
220 
221  // If the bin lies outside histogram boundaries, then extends the boundaries.
222  // Also changes the partition information accordingly
223  Bool_t flag = kFALSE;
224  if (fFloat) {
225  if (fXaxis.GetXmin() > bin->GetXMin()) {
226  fXaxis.Set(100, bin->GetXMin(), fXaxis.GetXmax());
227  flag = kTRUE;
228  }
229  if (fXaxis.GetXmax() < bin->GetXMax()) {
230  fXaxis.Set(100, fXaxis.GetXmin(), bin->GetXMax());
231  flag = kTRUE;
232  }
233  if (fYaxis.GetXmin() > bin->GetYMin()) {
234  fYaxis.Set(100, bin->GetYMin(), fYaxis.GetXmax());
235  flag = kTRUE;
236  }
237  if (fYaxis.GetXmax() < bin->GetYMax()) {
238  fYaxis.Set(100, fYaxis.GetXmin(), bin->GetYMax());
239  flag = kTRUE;
240  }
241  if (flag) ChangePartition(fCellX, fCellY);
242  } else {
243  /*Implement polygon clipping code here*/
244  }
245 
246  fBins->Add((TObject*) bin);
248 
249  // Adds the bin to the partition matrix
250  AddBinToPartition(bin);
251 
252  return ibin;
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 /// Adds a new bin to the histogram. The number of vertices and their (x,y)
257 /// coordinates are required as input. It returns the bin number in the
258 /// histogram.
259 
261 {
262  TGraph *g = new TGraph(n, x, y);
263  Int_t bin = AddBin(g);
264  return bin;
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Add a new bin to the histogram. The bin shape is a rectangle.
269 /// It returns the bin number of the bin in the histogram.
270 
272 {
273  Double_t x[] = {x1, x1, x2, x2, x1};
274  Double_t y[] = {y1, y2, y2, y1, y1};
275  TGraph *g = new TGraph(5, x, y);
276  Int_t bin = AddBin(g);
277  return bin;
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Performs the operation: this = this + c1*h1.
282 
284 {
285  Int_t bin;
286 
287  TH2Poly *h1p = (TH2Poly *)h1;
288 
289  // Check if number of bins is the same.
290  if (h1p->GetNumberOfBins() != GetNumberOfBins()) {
291  Error("Add", "Attempt to add histograms with different number of bins");
292  return kFALSE;
293  }
294 
295  // Check if the bins are the same.
296  TList *h1pBins = h1p->GetBins();
297  TH2PolyBin *thisBin, *h1pBin;
298  for (bin = 1; bin <= GetNumberOfBins(); bin++) {
299  thisBin = (TH2PolyBin *)fBins->At(bin - 1);
300  h1pBin = (TH2PolyBin *)h1pBins->At(bin - 1);
301  if (thisBin->GetXMin() != h1pBin->GetXMin() ||
302  thisBin->GetXMax() != h1pBin->GetXMax() ||
303  thisBin->GetYMin() != h1pBin->GetYMin() ||
304  thisBin->GetYMax() != h1pBin->GetYMax()) {
305  Error("Add", "Attempt to add histograms with different bin limits");
306  return kFALSE;
307  }
308  }
309 
310 
311  // Create Sumw2 if h1p has Sumw2 set
312  if (fSumw2.fN == 0 && h1p->GetSumw2N() != 0) Sumw2();
313 
314  // statistics can be preserved only in case of positive coefficients
315  // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
316  Bool_t resetStats = (c1 < 0);
317  Double_t s1[kNstat] = {0};
318  Double_t s2[kNstat] = {0};
319  if (!resetStats) {
320  // need to initialize to zero s1 and s2 since
321  // GetStats fills only used elements depending on dimension and type
322  GetStats(s1);
323  h1->GetStats(s2);
324  }
325 
326  // Perform the Add.
327  Double_t factor = 1;
328  if (h1p->GetNormFactor() != 0)
329  factor = h1p->GetNormFactor() / h1p->GetSumOfWeights();
330  for (bin = 0; bin < fNcells; bin++) {
331  Double_t y = h1p->RetrieveBinContent(bin) + c1 * h1p->RetrieveBinContent(bin);
332  UpdateBinContent(bin, y);
333  if (fSumw2.fN) {
334  Double_t esq = factor * factor * h1p->GetBinErrorSqUnchecked(bin);
335  fSumw2.fArray[bin] += c1 * c1 * factor * factor * esq;
336  }
337  }
338  // for (bin = 1; bin <= GetNumberOfBins(); bin++) {
339  // thisBin = (TH2PolyBin *)fBins->At(bin - 1);
340  // h1pBin = (TH2PolyBin *)h1pBins->At(bin - 1);
341  // thisBin->SetContent(thisBin->GetContent() + c1 * h1pBin->GetContent());
342  // if (fSumw2.fN) {
343  // Double_t e1 = factor * h1p->GetBinError(bin);
344  // fSumw2.fArray[bin] += c1 * c1 * e1 * e1;
345  // }
346  // }
347 
348  // update statistics (do here to avoid changes by SetBinContent)
349  if (resetStats) {
350  // statistics need to be reset in case coefficient are negative
351  ResetStats();
352  } else {
353  for (Int_t i = 0; i < kNstat; i++) {
354  if (i == 1) s1[i] += c1 * c1 * s2[i];
355  else s1[i] += c1 * s2[i];
356  }
357  PutStats(s1);
358  SetEntries(std::abs(GetEntries() + c1 * h1->GetEntries()));
359  }
360  return kTRUE;
361 }
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /// Performs the operation: this = this + c1*f1.
365 
367 {
368  Warning("Add","Not implement for TH2Poly");
369  return kFALSE;
370 }
371 
372 ////////////////////////////////////////////////////////////////////////////////
373 /// Replace contents of this histogram by the addition of h1 and h2.
374 
376 {
377  Warning("Add","Not implement for TH2Poly");
378  return kFALSE;
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////
382 /// Adds the input bin into the partition cell matrix. This method is called
383 /// in AddBin() and ChangePartition().
384 
386 {
387  // Cell Info
388  Int_t nl, nr, mb, mt; // Max/min indices of the cells that contain the bin
389  Double_t xclipl, xclipr, yclipb, yclipt; // x and y coordinates of a cell
390  Double_t binXmax, binXmin, binYmax, binYmin; // The max/min bin coordinates
391 
392  binXmax = bin->GetXMax();
393  binXmin = bin->GetXMin();
394  binYmax = bin->GetYMax();
395  binYmin = bin->GetYMin();
396  nl = (Int_t)(floor((binXmin - fXaxis.GetXmin())/fStepX));
397  nr = (Int_t)(floor((binXmax - fXaxis.GetXmin())/fStepX));
398  mb = (Int_t)(floor((binYmin - fYaxis.GetXmin())/fStepY));
399  mt = (Int_t)(floor((binYmax - fYaxis.GetXmin())/fStepY));
400 
401  // Make sure the array indices are correct.
402  if (nr>=fCellX) nr = fCellX-1;
403  if (mt>=fCellY) mt = fCellY-1;
404  if (nl<0) nl = 0;
405  if (mb<0) mb = 0;
406 
407  // number of cells in the grid
408  //N.B. not to be confused with fNcells (the number of bins) !
410 
411  // Loop over all cells
412  for (int i = nl; i <= nr; i++) {
413  xclipl = fXaxis.GetXmin() + i*fStepX;
414  xclipr = xclipl + fStepX;
415  for (int j = mb; j <= mt; j++) {
416  yclipb = fYaxis.GetXmin() + j*fStepY;
417  yclipt = yclipb + fStepY;
418 
419  // If the bin is completely inside the cell,
420  // add that bin to the cell then return
421  if ((binXmin >= xclipl) && (binXmax <= xclipr) &&
422  (binYmax <= yclipt) && (binYmin >= yclipb)){
423  fCells[i + j*fCellX].Add((TObject*) bin);
424  fIsEmpty[i + j*fCellX] = kFALSE; // Makes the cell non-empty
425  return;
426  }
427 
428  // If any of the sides of the cell intersect with any side of the bin,
429  // add that bin then continue
430  if (IsIntersecting(bin, xclipl, xclipr, yclipb, yclipt)) {
431  fCells[i + j*fCellX].Add((TObject*) bin);
432  fIsEmpty[i + j*fCellX] = kFALSE; // Makes the cell non-empty
433  continue;
434  }
435  // If a corner of the cell is inside the bin and since there is no
436  // intersection, then that cell completely inside the bin.
437  if((bin->IsInside(xclipl,yclipb)) || (bin->IsInside(xclipl,yclipt))){
438  fCells[i + j*fCellX].Add((TObject*) bin);
439  fIsEmpty[i + j*fCellX] = kFALSE; // Makes the cell non-empty
440  fCompletelyInside[i + fCellX*j] = kTRUE;
441  continue;
442  }
443  if((bin->IsInside(xclipr,yclipb)) || (bin->IsInside(xclipr,yclipt))){
444  fCells[i + j*fCellX].Add((TObject*) bin);
445  fIsEmpty[i + j*fCellX] = kFALSE; // Makes the cell non-empty
446  fCompletelyInside[i + fCellX*j] = kTRUE;
447  continue;
448  }
449  }
450  }
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Changes the number of partition cells in the histogram.
455 /// Deletes the old partition and constructs a new one.
456 
458 {
459  fCellX = n; // Set the number of cells
460  fCellY = m; // Set the number of cells
461 
462  delete [] fCells; // Deletes the old partition
463 
464  // number of cells in the grid
465  //N.B. not to be confused with fNcells (the number of bins) !
467  fCells = new TList [fNCells]; // Sets an empty partition
468 
470  fStepY = (fYaxis.GetXmax() - fYaxis.GetXmin())/fCellY;
471 
472  delete [] fIsEmpty;
473  delete [] fCompletelyInside;
474  fIsEmpty = new Bool_t [fNCells];
476 
477  // Initializes the flags
478  for (int i = 0; i<fNCells; i++) {
479  fIsEmpty[i] = kTRUE;
481  }
482 
483  // TList iterator
484  TIter next(fBins);
485  TObject *obj;
486 
487  while((obj = next())){ // Loop over bins and add them to the partition
489  }
490 }
491 
492 ////////////////////////////////////////////////////////////////////////////////
493 /// Make a complete copy of the underlying object. If 'newname' is set,
494 /// the copy's name will be set to that name.
495 
496 TObject* TH2Poly::Clone(const char* newname) const
497 {
498  // TH1::Clone relies on ::Copy to implemented by the derived class.
499  // Until this is implemented, revert to the much slower default version
500  // (and possibly non-thread safe).
501 
502  return TNamed::Clone(newname);
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 /// Clears the contents of all bins in the histogram.
507 
509 {
510  TIter next(fBins);
511  TObject *obj;
512  TH2PolyBin *bin;
513 
514  // Clears the bin contents
515  while ((obj = next())) {
516  bin = (TH2PolyBin*) obj;
517  bin->ClearContent();
518  }
519 
520  // Clears the statistics
521  fTsumw = 0;
522  fTsumwx = 0;
523  fTsumwx2 = 0;
524  fTsumwy = 0;
525  fTsumwy2 = 0;
526  fEntries = 0;
527 }
528 
529 ////////////////////////////////////////////////////////////////////////////////
530 /// Reset this histogram: contents, errors, etc.
531 
533 {
534  TIter next(fBins);
535  TObject *obj;
536  TH2PolyBin *bin;
537 
538  // Clears the bin contents
539  while ((obj = next())) {
540  bin = (TH2PolyBin*) obj;
541  bin->ClearContent();
542  }
543 
544  TH2::Reset(opt);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Returns the bin number of the bin at the given coordinate. -1 to -9 are
549 /// the overflow and underflow bins. overflow bin -5 is the unbinned areas in
550 /// the histogram (also called "the sea"). The third parameter can be left
551 /// blank.
552 /// The overflow/underflow bins are:
553 ///~~~ {.cpp}
554 /// -1 | -2 | -3
555 /// -------------
556 /// -4 | -5 | -6
557 /// -------------
558 /// -7 | -8 | -9
559 ///~~~
560 /// where -5 means is the "sea" bin (i.e. unbinned areas)
561 
563 {
564 
565  // Checks for overflow/underflow
566  Int_t overflow = 0;
567  if (y > fYaxis.GetXmax()) overflow += -1;
568  else if (y > fYaxis.GetXmin()) overflow += -4;
569  else overflow += -7;
570  if (x > fXaxis.GetXmax()) overflow += -2;
571  else if (x > fXaxis.GetXmin()) overflow += -1;
572  if (overflow != -5) return overflow;
573 
574  // Finds the cell (x,y) coordinates belong to
575  Int_t n = (Int_t)(floor((x-fXaxis.GetXmin())/fStepX));
576  Int_t m = (Int_t)(floor((y-fYaxis.GetXmin())/fStepY));
577 
578  // Make sure the array indices are correct.
579  if (n>=fCellX) n = fCellX-1;
580  if (m>=fCellY) m = fCellY-1;
581  if (n<0) n = 0;
582  if (m<0) m = 0;
583 
584  if (fIsEmpty[n+fCellX*m]) return -5;
585 
586  TH2PolyBin *bin;
587 
588  TIter next(&fCells[n+fCellX*m]);
589  TObject *obj;
590 
591  // Search for the bin in the cell
592  while ((obj=next())) {
593  bin = (TH2PolyBin*)obj;
594  if (bin->IsInside(x,y)) return bin->GetBinNumber();
595  }
596 
597  // If the search has not returned a bin, the point must be on "the sea"
598  return -5;
599 }
600 
601 ////////////////////////////////////////////////////////////////////////////////
602 /// Increment the bin containing (x,y) by 1.
603 /// Uses the partitioning algorithm.
604 
606 {
607  return Fill(x, y, 1.0);
608 }
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 /// Increment the bin containing (x,y) by w.
612 /// Uses the partitioning algorithm.
613 
615 {
616  if (fNcells <= kNOverflow) return 0;
617  Int_t overflow = 0;
618  if (y > fYaxis.GetXmax()) overflow += -1;
619  else if (y > fYaxis.GetXmin()) overflow += -4;
620  else overflow += -7;
621  if (x > fXaxis.GetXmax()) overflow += -2;
622  else if(x > fXaxis.GetXmin()) overflow += -1;
623  if (overflow != -5) {
624  fOverflow[-overflow - 1]+= w;
625  if (fSumw2.fN) fSumw2.fArray[-overflow - 1] += w*w;
626  return overflow;
627  }
628 
629  // Finds the cell (x,y) coordinates belong to
630  Int_t n = (Int_t)(floor((x-fXaxis.GetXmin())/fStepX));
631  Int_t m = (Int_t)(floor((y-fYaxis.GetXmin())/fStepY));
632 
633  // Make sure the array indices are correct.
634  if (n>=fCellX) n = fCellX-1;
635  if (m>=fCellY) m = fCellY-1;
636  if (n<0) n = 0;
637  if (m<0) m = 0;
638 
639  if (fIsEmpty[n+fCellX*m]) {
640  fOverflow[4]+= w;
641  if (fSumw2.fN) fSumw2.fArray[4] += w*w;
642  return -5;
643  }
644 
645  TH2PolyBin *bin;
646  Int_t bi;
647 
648  TIter next(&fCells[n+fCellX*m]);
649  TObject *obj;
650 
651  while ((obj=next())) {
652  bin = (TH2PolyBin*)obj;
653  // needs to account offset in array for overflow bins
654  bi = bin->GetBinNumber()-1+kNOverflow;
655  if (bin->IsInside(x,y)) {
656  bin->Fill(w);
657 
658  // Statistics
659  fTsumw = fTsumw + w;
660  fTsumwx = fTsumwx + w*x;
661  fTsumwx2 = fTsumwx2 + w*x*x;
662  fTsumwy = fTsumwy + w*y;
663  fTsumwy2 = fTsumwy2 + w*y*y;
664  if (fSumw2.fN) fSumw2.fArray[bi] += w*w;
665  fEntries++;
666 
668 
669  return bin->GetBinNumber();
670  }
671  }
672 
673  fOverflow[4]+= w;
674  if (fSumw2.fN) fSumw2.fArray[4] += w*w;
675  return -5;
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// Increment the bin named "name" by w.
680 
682 {
683  TString sname(name);
684 
685  TIter next(fBins);
686  TObject *obj;
687  TH2PolyBin *bin;
688 
689  while ((obj = next())) {
690  bin = (TH2PolyBin*) obj;
691  if (!sname.CompareTo(bin->GetPolygon()->GetName())) {
692  bin->Fill(w);
693  fEntries++;
695  return bin->GetBinNumber();
696  }
697  }
698 
699  return 0;
700 }
701 
702 ////////////////////////////////////////////////////////////////////////////////
703 /// Fills a 2-D histogram with an array of values and weights.
704 ///
705 /// \param [in] ntimes: number of entries in arrays x and w
706 /// (array size must be ntimes*stride)
707 /// \param [in] x: array of x values to be histogrammed
708 /// \param [in] y: array of y values to be histogrammed
709 /// \param [in] w: array of weights
710 /// \param [in] stride: step size through arrays x, y and w
711 
712 void TH2Poly::FillN(Int_t ntimes, const Double_t* x, const Double_t* y,
713  const Double_t* w, Int_t stride)
714 {
715  for (int i = 0; i < ntimes; i += stride) {
716  Fill(x[i], y[i], w[i]);
717  }
718 }
719 
720 ////////////////////////////////////////////////////////////////////////////////
721 /// Returns the integral of bin contents.
722 /// By default the integral is computed as the sum of bin contents.
723 /// If option "width" or "area" is specified, the integral is the sum of
724 /// the bin contents multiplied by the area of the bin.
725 
727 {
728  TString opt = option;
729  opt.ToLower();
730 
731  if ((opt.Contains("width")) || (opt.Contains("area"))) {
732  Double_t w;
733  Double_t integral = 0.;
734 
735  TIter next(fBins);
736  TObject *obj;
737  TH2PolyBin *bin;
738  while ((obj=next())) {
739  bin = (TH2PolyBin*) obj;
740  w = bin->GetArea();
741  integral += w*(bin->GetContent());
742  }
743 
744  return integral;
745  } else {
746  return fTsumw;
747  }
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Returns the content of the input bin
752 /// For the overflow/underflow/sea bins:
753 ///~~~ {.cpp}
754 /// -1 | -2 | -3
755 /// ---+----+----
756 /// -4 | -5 | -6
757 /// ---+----+----
758 /// -7 | -8 | -9
759 ///~~~
760 /// where -5 is the "sea" bin (i.e. unbinned areas)
761 
763 {
764  if (bin > GetNumberOfBins() || bin == 0 || bin < -kNOverflow) return 0;
765  if (bin<0) return fOverflow[-bin - 1];
766  return ((TH2PolyBin*) fBins->At(bin-1))->GetContent();
767 }
768 
769 ////////////////////////////////////////////////////////////////////////////////
770 /// Returns the value of error associated to bin number bin.
771 /// If the sum of squares of weights has been defined (via Sumw2),
772 /// this function returns the sqrt(sum of w2).
773 /// otherwise it returns the sqrt(contents) for this bin.
774 
776 {
777  if (bin == 0 || bin > GetNumberOfBins() || bin < - kNOverflow) return 0;
778  if (fBuffer) ((TH1*)this)->BufferEmpty();
779  if (fSumw2.fN) {
780  Int_t binIndex = (bin < 0) ? bin+kNOverflow-1 : -(bin+1);
781  Double_t err2 = fSumw2.fArray[binIndex];
782  return TMath::Sqrt(err2);
783  }
784  Double_t error2 = TMath::Abs(GetBinContent(bin));
785  return TMath::Sqrt(error2);
786 }
787 
788 ////////////////////////////////////////////////////////////////////////////////
789 /// Returns the bin name.
790 
791 const char *TH2Poly::GetBinName(Int_t bin) const
792 {
793  if (bin > GetNumberOfBins()) return "";
794  if (bin < 0) return "";
795  return ((TH2PolyBin*) fBins->At(bin-1))->GetPolygon()->GetName();
796 }
797 
798 ////////////////////////////////////////////////////////////////////////////////
799 /// Returns the bin title.
800 
801 const char *TH2Poly::GetBinTitle(Int_t bin) const
802 {
803  if (bin > GetNumberOfBins()) return "";
804  if (bin < 0) return "";
805  return ((TH2PolyBin*) fBins->At(bin-1))->GetPolygon()->GetTitle();
806 }
807 
808 ////////////////////////////////////////////////////////////////////////////////
809 /// Returns the maximum value of the histogram.
810 
812 {
813  if (fNcells <= kNOverflow) return 0;
814  if (fMaximum != -1111) return fMaximum;
815 
816  TH2PolyBin *b;
817 
818  TIter next(fBins);
819  TObject *obj;
820  Double_t max,c;
821 
822  max = ((TH2PolyBin*) next())->GetContent();
823 
824  while ((obj=next())) {
825  b = (TH2PolyBin*)obj;
826  c = b->GetContent();
827  if (c>max) max = c;
828  }
829  return max;
830 }
831 
832 ////////////////////////////////////////////////////////////////////////////////
833 /// Returns the maximum value of the histogram that is less than maxval.
834 
836 {
837  if (fNcells <= kNOverflow) return 0;
838  if (fMaximum != -1111) return fMaximum;
839 
840  TH2PolyBin *b;
841 
842  TIter next(fBins);
843  TObject *obj;
844  Double_t max,c;
845 
846  max = ((TH2PolyBin*) next())->GetContent();
847 
848  while ((obj=next())) {
849  b = (TH2PolyBin*)obj;
850  c = b->GetContent();
851  if (c>max && c<maxval) max=c;
852  }
853  return max;
854 }
855 
856 ////////////////////////////////////////////////////////////////////////////////
857 /// Returns the minimum value of the histogram.
858 
860 {
861  if (fNcells <= kNOverflow) return 0;
862  if (fMinimum != -1111) return fMinimum;
863 
864  TH2PolyBin *b;
865 
866  TIter next(fBins);
867  TObject *obj;
868  Double_t min,c;
869 
870  min = ((TH2PolyBin*) next())->GetContent();
871 
872  while ((obj=next())) {
873  b = (TH2PolyBin*)obj;
874  c = b->GetContent();
875  if (c<min) min=c;
876  }
877  return min;
878 }
879 
880 ////////////////////////////////////////////////////////////////////////////////
881 /// Returns the minimum value of the histogram that is greater than minval.
882 
884 {
885  if (fNcells <= kNOverflow) return 0;
886  if (fMinimum != -1111) return fMinimum;
887 
888  TH2PolyBin *b;
889 
890  TIter next(fBins);
891  TObject *obj;
892  Double_t min,c;
893 
894  min = ((TH2PolyBin*) next())->GetContent();
895 
896  while ((obj=next())) {
897  b = (TH2PolyBin*)obj;
898  c = b->GetContent();
899  if (c<min && c>minval) min=c;
900  }
901  return min;
902 }
903 
904 ////////////////////////////////////////////////////////////////////////////////
905 /// Bins the histogram using a honeycomb structure
906 
908  Int_t k, Int_t s)
909 {
910  // Add the bins
911  Double_t numberOfHexagonsInTheRow;
912  Double_t x[6], y[6];
913  Double_t xloop, yloop, xtemp;
914  xloop = xstart; yloop = ystart + a/2.0;
915  for (int sCounter = 0; sCounter < s; sCounter++) {
916 
917  xtemp = xloop; // Resets the temp variable
918 
919  // Determine the number of hexagons in that row
920  if(sCounter%2 == 0){numberOfHexagonsInTheRow = k;}
921  else{numberOfHexagonsInTheRow = k - 1;}
922 
923  for (int kCounter = 0; kCounter < numberOfHexagonsInTheRow; kCounter++) {
924 
925  // Go around the hexagon
926  x[0] = xtemp;
927  y[0] = yloop;
928  x[1] = x[0];
929  y[1] = y[0] + a;
930  x[2] = x[1] + a*TMath::Sqrt(3)/2.0;
931  y[2] = y[1] + a/2.0;
932  x[3] = x[2] + a*TMath::Sqrt(3)/2.0;
933  y[3] = y[1];
934  x[4] = x[3];
935  y[4] = y[0];
936  x[5] = x[2];
937  y[5] = y[4] - a/2.0;
938 
939  this->AddBin(6, x, y);
940 
941  // Go right
942  xtemp += a*TMath::Sqrt(3);
943  }
944 
945  // Increment the starting position
946  if (sCounter%2 == 0) xloop += a*TMath::Sqrt(3)/2.0;
947  else xloop -= a*TMath::Sqrt(3)/2.0;
948  yloop += 1.5*a;
949  }
950 }
951 
952 ////////////////////////////////////////////////////////////////////////////////
953 /// Initializes the TH2Poly object. This method is called by the constructor.
954 
956  Double_t ylow, Double_t yup, Int_t n, Int_t m)
957 {
958  Int_t i;
959  fDimension = 2; //The dimension of the histogram
960 
961  fBins = 0;
963 
964  // Sets the boundaries of the histogram
965  fXaxis.Set(100, xlow, xup);
966  fYaxis.Set(100, ylow, yup);
967 
968  for (i=0; i<9; i++) fOverflow[i] = 0.;
969 
970  // Statistics
971  fEntries = 0; // The total number of entries
972  fTsumw = 0.; // Total amount of content in the histogram
973  fTsumwx = 0.; // Weighted sum of x coordinates
974  fTsumwx2 = 0.; // Weighted sum of the squares of x coordinates
975  fTsumwy2 = 0.; // Weighted sum of the squares of y coordinates
976  fTsumwy = 0.; // Weighted sum of y coordinates
977 
978  fCellX = n; // Set the number of cells to default
979  fCellY = m; // Set the number of cells to default
980 
981  // number of cells in the grid
982  //N.B. not to be confused with fNcells (the number of bins) !
984  fCells = new TList [fNCells]; // Sets an empty partition
985  fStepX = (fXaxis.GetXmax() - fXaxis.GetXmin())/fCellX; // Cell width
986  fStepY = (fYaxis.GetXmax() - fYaxis.GetXmin())/fCellY; // Cell height
987 
988  fIsEmpty = new Bool_t [fNCells]; // Empty partition
989  fCompletelyInside = new Bool_t [fNCells]; // Cell is completely inside bin
990 
991  for (i = 0; i<fNCells; i++) { // Initializes the flags
992  fIsEmpty[i] = kTRUE;
994  }
995 
996  // 3D Painter flags
999 }
1000 
1001 ////////////////////////////////////////////////////////////////////////////////
1002 /// Returns kTRUE if the input bin is intersecting with the
1003 /// input rectangle (xclipl, xclipr, yclipb, yclipt)
1004 
1006  Double_t xclipl, Double_t xclipr,
1007  Double_t yclipb, Double_t yclipt)
1008 {
1009  Int_t gn;
1010  Double_t *gx;
1011  Double_t *gy;
1012  Bool_t inter = kFALSE;
1013  TObject *poly = bin->GetPolygon();
1014 
1015  if (poly->IsA() == TGraph::Class()) {
1016  TGraph *g = (TGraph*)poly;
1017  gx = g->GetX();
1018  gy = g->GetY();
1019  gn = g->GetN();
1020  inter = IsIntersectingPolygon(gn, gx, gy, xclipl, xclipr, yclipb, yclipt);
1021  }
1022 
1023  if (poly->IsA() == TMultiGraph::Class()) {
1024  TMultiGraph *mg = (TMultiGraph*)poly;
1025  TList *gl = mg->GetListOfGraphs();
1026  if (!gl) return inter;
1027  TGraph *g;
1028  TIter next(gl);
1029  while ((g = (TGraph*) next())) {
1030  gx = g->GetX();
1031  gy = g->GetY();
1032  gn = g->GetN();
1033  inter = IsIntersectingPolygon(gn, gx, gy, xclipl, xclipr,
1034  yclipb, yclipt);
1035  if (inter) return inter;
1036  }
1037  }
1038 
1039  return inter;
1040 }
1041 
1042 ////////////////////////////////////////////////////////////////////////////////
1043 /// Returns kTRUE if the input polygon (bn, x, y) is intersecting with the
1044 /// input rectangle (xclipl, xclipr, yclipb, yclipt)
1045 
1047  Double_t xclipl, Double_t xclipr,
1048  Double_t yclipb, Double_t yclipt)
1049 {
1050  Bool_t p0R, p0L, p0T, p0B, p0xM, p0yM, p1R, p1L, p1T;
1051  Bool_t p1B, p1xM, p1yM, p0In, p1In;
1052 
1053  for (int counter = 0; counter < (bn-1); counter++) {
1054  // If both are on the same side, return kFALSE
1055  p0L = x[counter] <= xclipl; // Point 0 is on the left
1056  p1L = x[counter + 1] <= xclipl; // Point 1 is on the left
1057  if (p0L && p1L) continue;
1058  p0R = x[counter] >= xclipr; // Point 0 is on the right
1059  p1R = x[counter + 1] >= xclipr; // Point 1 is on the right
1060  if (p0R && p1R) continue;
1061  p0T = y[counter] >= yclipt; // Point 0 is at the top
1062  p1T = y[counter + 1] >= yclipt; // Point 1 is at the top
1063  if (p0T && p1T) continue;
1064  p0B = y[counter] <= yclipb; // Point 0 is at the bottom
1065  p1B = y[counter + 1] <= yclipb; // Point 1 is at the bottom
1066  if (p0B && p1B) continue;
1067 
1068  // Checks to see if any are inside
1069  p0xM = !p0R && !p0L; // Point 0 is inside along x
1070  p0yM = !p0T && !p0B; // Point 1 is inside along x
1071  p1xM = !p1R && !p1L; // Point 0 is inside along y
1072  p1yM = !p1T && !p1B; // Point 1 is inside along y
1073  p0In = p0xM && p0yM; // Point 0 is inside
1074  p1In = p1xM && p1yM; // Point 1 is inside
1075  if (p0In) {
1076  if (p1In) continue;
1077  return kTRUE;
1078  } else {
1079  if (p1In) return kTRUE;
1080  }
1081 
1082  // We know by now that the points are not in the same side and not inside.
1083 
1084  // Checks to see if they are opposite
1085 
1086  if (p0xM && p1xM) return kTRUE;
1087  if (p0yM && p1yM) return kTRUE;
1088 
1089  // We now know that the points are in different x and y indices
1090 
1091  Double_t xcoord[3], ycoord[3];
1092  xcoord[0] = x[counter];
1093  xcoord[1] = x[counter + 1];
1094  ycoord[0] = y[counter];
1095  ycoord[1] = y[counter + 1];
1096 
1097  if (p0L) {
1098  if(p1T){
1099  xcoord[2] = xclipl;
1100  ycoord[2] = yclipb;
1101  if((TMath::IsInside(xclipl, yclipt, 3, xcoord, ycoord)) ||
1102  (TMath::IsInside(xclipr, yclipb, 3, xcoord, ycoord))) continue;
1103  else return kTRUE;
1104  } else if (p1B) {
1105  xcoord[2] = xclipl;
1106  ycoord[2] = yclipt;
1107  if((TMath::IsInside(xclipl, yclipb, 3, xcoord, ycoord)) ||
1108  (TMath::IsInside(xclipr, yclipt, 3, xcoord, ycoord))) continue;
1109  else return kTRUE;
1110  } else { // p1yM
1111  if (p0T) {
1112  xcoord[2] = xclipl;
1113  ycoord[2] = yclipb;
1114  if (TMath::IsInside(xclipr, yclipt, 3, xcoord, ycoord)) continue;
1115  else return kTRUE;
1116  }
1117  if (p0B) {
1118  xcoord[2] = xclipl;
1119  ycoord[2] = yclipt;
1120  if (TMath::IsInside(xclipr, yclipb, 3, xcoord, ycoord)) continue;
1121  else return kTRUE;
1122  }
1123  }
1124  } else if (p0R) {
1125  if (p1T) {
1126  xcoord[2] = xclipl;
1127  ycoord[2] = yclipb;
1128  if ((TMath::IsInside(xclipr, yclipb, 3, xcoord, ycoord)) ||
1129  (TMath::IsInside(xclipl, yclipt, 3, xcoord, ycoord))) continue;
1130  else return kTRUE;
1131  } else if (p1B) {
1132  xcoord[2] = xclipl;
1133  ycoord[2] = yclipt;
1134  if ((TMath::IsInside(xclipl, yclipb, 3, xcoord, ycoord)) ||
1135  (TMath::IsInside(xclipr, yclipt, 3, xcoord, ycoord))) continue;
1136  else return kTRUE;
1137  } else{ // p1yM
1138  if (p0T) {
1139  xcoord[2] = xclipr;
1140  ycoord[2] = yclipb;
1141  if (TMath::IsInside(xclipl, yclipt, 3, xcoord, ycoord)) continue;
1142  else return kTRUE;
1143  }
1144  if (p0B) {
1145  xcoord[2] = xclipr;
1146  ycoord[2] = yclipt;
1147  if (TMath::IsInside(xclipl, yclipb, 3, xcoord, ycoord)) continue;
1148  else return kTRUE;
1149  }
1150  }
1151  }
1152  }
1153  return kFALSE;
1154 }
1155 
1156 ////////////////////////////////////////////////////////////////////////////////
1157 /// Merge TH2Polys
1158 /// Given the special nature of the TH2Poly, the merge is implemented in
1159 /// terms of subsequent TH2Poly::Add calls.
1161 {
1162  for (auto h2pAsObj : *coll) {
1163  if (!Add((TH1*)h2pAsObj, 1.)) {
1164  Warning("Merge", "An issue was encountered during the merge operation.");
1165  return 0L;
1166  }
1167  }
1168  return GetEntries();
1169 }
1170 
1171 ////////////////////////////////////////////////////////////////////////////////
1172 /// Save primitive as a C++ statement(s) on output stream out
1173 
1174 void TH2Poly::SavePrimitive(std::ostream &out, Option_t *option)
1175 {
1176  out <<" "<<std::endl;
1177  out <<" "<< ClassName() <<" *";
1178 
1179  //histogram pointer has by default the histogram name.
1180  //however, in case histogram has no directory, it is safer to add a
1181  //incremental suffix
1182  static Int_t hcounter = 0;
1183  TString histName = GetName();
1184  if (!fDirectory && !histName.Contains("Graph")) {
1185  hcounter++;
1186  histName += "__";
1187  histName += hcounter;
1188  }
1189  const char *hname = histName.Data();
1190 
1191  //Construct the class initialization
1192  out << hname << " = new " << ClassName() << "(\"" << hname << "\", \""
1193  << GetTitle() << "\", " << fCellX << ", " << fXaxis.GetXmin()
1194  << ", " << fXaxis.GetXmax()
1195  << ", " << fCellY << ", " << fYaxis.GetXmin() << ", "
1196  << fYaxis.GetXmax() << ");" << std::endl;
1197 
1198  // Save Bins
1199  TIter next(fBins);
1200  TObject *obj;
1201  TH2PolyBin *th2pBin;
1202 
1203  while((obj = next())){
1204  th2pBin = (TH2PolyBin*) obj;
1205  th2pBin->GetPolygon()->SavePrimitive(out,
1206  TString::Format("th2poly%s",histName.Data()));
1207  }
1208 
1209  // save bin contents
1210  out<<" "<<std::endl;
1211  Int_t bin;
1212  for (bin=1;bin<=GetNumberOfBins();bin++) {
1213  Double_t bc = GetBinContent(bin);
1214  if (bc) {
1215  out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
1216  }
1217  }
1218 
1219  // save bin errors
1220  if (fSumw2.fN) {
1221  for (bin=1;bin<=GetNumberOfBins();bin++) {
1222  Double_t be = GetBinError(bin);
1223  if (be) {
1224  out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
1225  }
1226  }
1227  }
1228  TH1::SavePrimitiveHelp(out, hname, option);
1229 }
1230 
1231 ////////////////////////////////////////////////////////////////////////////////
1232 /// Multiply this histogram by a constant c1.
1233 
1235 {
1236  for( int i = 0; i < this->GetNumberOfBins(); i++ ) {
1237  this->SetBinContent(i+1, c1*this->GetBinContent(i+1));
1238  }
1239  for( int i = 0; i < kNOverflow; i++ ) {
1240  this->SetBinContent(-i-1, c1*this->GetBinContent(-i-1) );
1241  }
1242 }
1243 
1244 ////////////////////////////////////////////////////////////////////////////////
1245 /// Sets the contents of the input bin to the input content
1246 /// Negative values between -1 and -9 are for the overflows and the sea
1247 
1249 {
1250  if (bin > GetNumberOfBins() || bin == 0 || bin < -9 ) return;
1251  if (bin > 0) {
1252  ((TH2PolyBin*) fBins->At(bin-1))->SetContent(content);
1253  }
1254  else
1255  fOverflow[-bin - 1] = content;
1257 }
1258 
1259 ////////////////////////////////////////////////////////////////////////////////
1260 /// When set to kTRUE, allows the histogram to expand if a bin outside the
1261 /// limits is added.
1262 
1264 {
1265  fFloat = flag;
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Return "true" if the point (x,y) is inside the bin of binnr.
1270 
1272 {
1273  if (!fBins) return false;
1274  TH2PolyBin* bin = (TH2PolyBin*)fBins->At(binnr);
1275  if (!bin) return false;
1276  return bin->IsInside(x,y);
1277 }
1278 
1279 void TH2Poly::GetStats(Double_t *stats) const
1280 {
1281  stats[0] = fTsumw;
1282  stats[1] = fTsumw2;
1283  stats[2] = fTsumwx;
1284  stats[3] = fTsumwx2;
1285  stats[4] = fTsumwy;
1286  stats[5] = fTsumwy2;
1287  stats[6] = fTsumwxy;
1288 }
1289 
1290 /** \class TH2PolyBin
1291  \ingroup Hist
1292 Helper class to represent a bin in the TH2Poly histogram
1293 */
1294 
1295 ////////////////////////////////////////////////////////////////////////////////
1296 /// Default constructor.
1297 
1299 {
1300  fPoly = 0;
1301  fContent = 0.;
1302  fNumber = 0;
1303  fXmax = -1111;
1304  fXmin = -1111;
1305  fYmax = -1111;
1306  fYmin = -1111;
1307  fArea = 0;
1308  SetChanged(kTRUE);
1309 }
1310 
1311 ////////////////////////////////////////////////////////////////////////////////
1312 /// Normal constructor.
1313 
1315 {
1316  fContent = 0.;
1317  fNumber = bin_number;
1318  fArea = 0.;
1319  fPoly = poly;
1320  fXmax = -1111;
1321  fXmin = -1111;
1322  fYmax = -1111;
1323  fYmin = -1111;
1324  SetChanged(kTRUE);
1325 }
1326 
1327 ////////////////////////////////////////////////////////////////////////////////
1328 /// Destructor.
1329 
1331 {
1332  if (fPoly) delete fPoly;
1333 }
1334 
1335 ////////////////////////////////////////////////////////////////////////////////
1336 /// Returns the area of the bin.
1337 
1339 {
1340  Int_t bn;
1341 
1342  if (fArea == 0) {
1343  if (fPoly->IsA() == TGraph::Class()) {
1344  TGraph *g = (TGraph*)fPoly;
1345  bn = g->GetN();
1346  fArea = g->Integral(0,bn-1);
1347  }
1348 
1349  if (fPoly->IsA() == TMultiGraph::Class()) {
1350  TMultiGraph *mg = (TMultiGraph*)fPoly;
1351  TList *gl = mg->GetListOfGraphs();
1352  if (!gl) return fArea;
1353  TGraph *g;
1354  TIter next(gl);
1355  while ((g = (TGraph*) next())) {
1356  bn = g->GetN();
1357  fArea = fArea + g->Integral(0,bn-1);
1358  }
1359  }
1360  }
1361 
1362  return fArea;
1363 }
1364 
1365 ////////////////////////////////////////////////////////////////////////////////
1366 /// Returns the maximum value for the x coordinates of the bin.
1367 
1369 {
1370  if (fXmax != -1111) return fXmax;
1371 
1372  Int_t bn,i;
1373  Double_t *bx;
1374 
1375  if (fPoly->IsA() == TGraph::Class()) {
1376  TGraph *g = (TGraph*)fPoly;
1377  bx = g->GetX();
1378  bn = g->GetN();
1379  fXmax = bx[0];
1380  for (i=1; i<bn; i++) {if (fXmax < bx[i]) fXmax = bx[i];}
1381  }
1382 
1383  if (fPoly->IsA() == TMultiGraph::Class()) {
1384  TMultiGraph *mg = (TMultiGraph*)fPoly;
1385  TList *gl = mg->GetListOfGraphs();
1386  if (!gl) return fXmax;
1387  TGraph *g;
1388  TIter next(gl);
1389  Bool_t first = kTRUE;
1390  while ((g = (TGraph*) next())) {
1391  bx = g->GetX();
1392  bn = g->GetN();
1393  if (first) {fXmax = bx[0]; first = kFALSE;}
1394  for (i=0; i<bn; i++) {if (fXmax < bx[i]) fXmax = bx[i];}
1395  }
1396  }
1397 
1398  return fXmax;
1399 }
1400 
1401 ////////////////////////////////////////////////////////////////////////////////
1402 /// Returns the minimum value for the x coordinates of the bin.
1403 
1405 {
1406  if (fXmin != -1111) return fXmin;
1407 
1408  Int_t bn,i;
1409  Double_t *bx;
1410 
1411  if (fPoly->IsA() == TGraph::Class()) {
1412  TGraph *g = (TGraph*)fPoly;
1413  bx = g->GetX();
1414  bn = g->GetN();
1415  fXmin = bx[0];
1416  for (i=1; i<bn; i++) {if (fXmin > bx[i]) fXmin = bx[i];}
1417  }
1418 
1419  if (fPoly->IsA() == TMultiGraph::Class()) {
1420  TMultiGraph *mg = (TMultiGraph*)fPoly;
1421  TList *gl = mg->GetListOfGraphs();
1422  if (!gl) return fXmin;
1423  TGraph *g;
1424  TIter next(gl);
1425  Bool_t first = kTRUE;
1426  while ((g = (TGraph*) next())) {
1427  bx = g->GetX();
1428  bn = g->GetN();
1429  if (first) {fXmin = bx[0]; first = kFALSE;}
1430  for (i=0; i<bn; i++) {if (fXmin > bx[i]) fXmin = bx[i];}
1431  }
1432  }
1433 
1434  return fXmin;
1435 }
1436 
1437 ////////////////////////////////////////////////////////////////////////////////
1438 /// Returns the maximum value for the y coordinates of the bin.
1439 
1441 {
1442  if (fYmax != -1111) return fYmax;
1443 
1444  Int_t bn,i;
1445  Double_t *by;
1446 
1447  if (fPoly->IsA() == TGraph::Class()) {
1448  TGraph *g = (TGraph*)fPoly;
1449  by = g->GetY();
1450  bn = g->GetN();
1451  fYmax = by[0];
1452  for (i=1; i<bn; i++) {if (fYmax < by[i]) fYmax = by[i];}
1453  }
1454 
1455  if (fPoly->IsA() == TMultiGraph::Class()) {
1456  TMultiGraph *mg = (TMultiGraph*)fPoly;
1457  TList *gl = mg->GetListOfGraphs();
1458  if (!gl) return fYmax;
1459  TGraph *g;
1460  TIter next(gl);
1461  Bool_t first = kTRUE;
1462  while ((g = (TGraph*) next())) {
1463  by = g->GetY();
1464  bn = g->GetN();
1465  if (first) {fYmax = by[0]; first = kFALSE;}
1466  for (i=0; i<bn; i++) {if (fYmax < by[i]) fYmax = by[i];}
1467  }
1468  }
1469 
1470  return fYmax;
1471 }
1472 
1473 ////////////////////////////////////////////////////////////////////////////////
1474 /// Returns the minimum value for the y coordinates of the bin.
1475 
1477 {
1478  if (fYmin != -1111) return fYmin;
1479 
1480  Int_t bn,i;
1481  Double_t *by;
1482 
1483  if (fPoly->IsA() == TGraph::Class()) {
1484  TGraph *g = (TGraph*)fPoly;
1485  by = g->GetY();
1486  bn = g->GetN();
1487  fYmin = by[0];
1488  for (i=1; i<bn; i++) {if (fYmin > by[i]) fYmin = by[i];}
1489  }
1490 
1491  if (fPoly->IsA() == TMultiGraph::Class()) {
1492  TMultiGraph *mg = (TMultiGraph*)fPoly;
1493  TList *gl = mg->GetListOfGraphs();
1494  if (!gl) return fYmin;
1495  TGraph *g;
1496  TIter next(gl);
1497  Bool_t first = kTRUE;
1498  while ((g = (TGraph*) next())) {
1499  by = g->GetY();
1500  bn = g->GetN();
1501  if (first) {fYmin = by[0]; first = kFALSE;}
1502  for (i=0; i<bn; i++) {if (fYmin > by[i]) fYmin = by[i];}
1503  }
1504  }
1505 
1506  return fYmin;
1507 }
1508 
1509 ////////////////////////////////////////////////////////////////////////////////
1510 /// Return "true" if the point (x,y) is inside the bin.
1511 
1513 {
1514  Int_t in=0;
1515 
1516  if (fPoly->IsA() == TGraph::Class()) {
1517  TGraph *g = (TGraph*)fPoly;
1518  in = g->IsInside(x, y);
1519  }
1520 
1521  if (fPoly->IsA() == TMultiGraph::Class()) {
1522  TMultiGraph *mg = (TMultiGraph*)fPoly;
1523  in = mg->IsInside(x, y);
1524  }
1525 
1526  return in;
1527 }
Double_t Integral(Option_t *option="") const
Returns the integral of bin contents.
Definition: TH2Poly.cxx:726
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Int_t FindBin(Double_t x, Double_t y, Double_t z=0)
Returns the bin number of the bin at the given coordinate.
Definition: TH2Poly.cxx:562
long long Long64_t
Definition: RtypesCore.h:69
auto * m
Definition: textangle.C:8
Bool_t * fCompletelyInside
Definition: TH2Poly.h:142
virtual Double_t GetBinError(Int_t bin) const
Returns the value of error associated to bin number bin.
Definition: TH2Poly.cxx:775
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition: TH2.cxx:2337
const char Option_t
Definition: RtypesCore.h:62
Double_t fStepX
Definition: TH2Poly.h:140
Bool_t IsInsideBin(Int_t binnr, Double_t x, Double_t y)
Return "true" if the point (x,y) is inside the bin of binnr.
Definition: TH2Poly.cxx:1271
Int_t GetBinNumber() const
Definition: TH2Poly.h:37
return c1
Definition: legend1.C:41
void ChangePartition(Int_t n, Int_t m)
Changes the number of partition cells in the histogram.
Definition: TH2Poly.cxx:457
virtual Double_t GetNormFactor() const
Definition: TH1.h:295
TAxis fYaxis
Y axis descriptor.
Definition: TH1.h:88
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH2Poly.cxx:1234
Long64_t Merge(TCollection *)
Merge TH2Polys Given the special nature of the TH2Poly, the merge is implemented in terms of subseque...
Definition: TH2Poly.cxx:1160
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7232
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
void Initialize(Double_t xlow, Double_t xup, Double_t ylow, Double_t yup, Int_t n, Int_t m)
Initializes the TH2Poly object. This method is called by the constructor.
Definition: TH2Poly.cxx:955
Basic string class.
Definition: TString.h:125
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual Bool_t Add(const TH1 *h1, Double_t c1)
Performs the operation: this = this + c1*h1.
Definition: TH2Poly.cxx:283
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside one of the graphs 0 otherwise.
Bool_t IsInside(Double_t x, Double_t y) const
Return "true" if the point (x,y) is inside the bin.
Definition: TH2Poly.cxx:1512
TArrayD fSumw2
Array of sum of squares of weights.
Definition: TH1.h:101
void SetBinContentChanged(Bool_t flag)
Definition: TH2Poly.h:123
virtual Double_t Integral(Int_t first=0, Int_t last=-1) const
Integrate the TGraph data within a given (index) range.
Definition: TGraph.cxx:1790
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
void AddBinToPartition(TH2PolyBin *bin)
For the 3D Painter.
Definition: TH2Poly.cxx:385
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition: TH1.h:96
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:7150
static constexpr double mg
Bool_t * fIsEmpty
Definition: TH2Poly.h:141
Int_t fCellX
Definition: TH2Poly.h:136
TDirectory * fDirectory
!Pointer to directory holding this histogram
Definition: TH1.h:106
Double_t GetXmin() const
Definition: TAxis.h:133
static const double x2[5]
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
TList * fCells
Definition: TH2Poly.h:139
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2365
const char * GetBinTitle(Int_t bin) const
Returns the bin title.
Definition: TH2Poly.cxx:801
void Class()
Definition: Class.C:29
const char * GetBinName(Int_t bin) const
Returns the bin name.
Definition: TH2Poly.cxx:791
virtual Int_t AddBin(TObject *poly)
Adds a new bin to the histogram.
Definition: TH2Poly.cxx:215
Bool_t IsIntersecting(TH2PolyBin *bin, Double_t xclipl, Double_t xclipr, Double_t yclipb, Double_t yclipt)
Returns kTRUE if the input bin is intersecting with the input rectangle (xclipl, xclipr, yclipb, yclipt)
Definition: TH2Poly.cxx:1005
Double_t * fArray
Definition: TArrayD.h:30
virtual ~TH2Poly()
Destructor.
Definition: TH2Poly.cxx:179
static constexpr double L
Double_t fTsumwy2
Definition: TH2.h:35
Double_t GetXMax()
Returns the maximum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1368
Double_t GetYMin()
Returns the minimum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1476
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
Definition: TMath.h:1204
Double_t GetYMax()
Returns the maximum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1440
TH1F * h1
Definition: legend1.C:5
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition: TH1.cxx:7663
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculates from bin cont...
Definition: TH1.cxx:7217
Double_t fTsumwx
Total Sum of weight*X.
Definition: TH1.h:95
virtual Double_t GetBinContent(Int_t bin) const
Returns the content of the input bin For the overflow/underflow/sea bins: -1 | -2 | -3 ---+----+---- ...
Definition: TH2Poly.cxx:762
Bool_t fFloat
Definition: TH2Poly.h:143
A doubly linked list.
Definition: TList.h:44
Double_t fMinimum
Minimum value for plotting.
Definition: TH1.h:98
TObject * GetPolygon() const
Definition: TH2Poly.h:38
virtual TH2PolyBin * CreateBin(TObject *poly)
Create appropriate histogram bin.
Definition: TH2Poly.cxx:195
Int_t fN
Definition: TArray.h:38
TObject * Clone(const char *newname="") const
Make a complete copy of the underlying object.
Definition: TH2Poly.cxx:496
TList * GetBins()
Definition: TH2Poly.h:94
Int_t fCellY
Definition: TH2Poly.h:137
void SetBinContent(Int_t bin, Double_t content)
Sets the contents of the input bin to the input content Negative values between -1 and -9 are for the...
Definition: TH2Poly.cxx:1248
auto * a
Definition: textangle.C:12
virtual ~TH2PolyBin()
Destructor.
Definition: TH2Poly.cxx:1330
Double_t GetContent() const
Definition: TH2Poly.h:35
Double_t fTsumwxy
Definition: TH2.h:36
Double_t fTsumwy
Definition: TH2.h:34
Collection abstract base class.
Definition: TCollection.h:63
Double_t fEntries
Number of entries.
Definition: TH1.h:92
Int_t GetNumberOfBins() const
Definition: TH2Poly.h:110
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
double floor(double)
Int_t GetN() const
Definition: TGraph.h:122
Int_t fNCells
Definition: TH2Poly.h:138
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
void SetFloat(Bool_t flag=true)
When set to kTRUE, allows the histogram to expand if a bin outside the limits is added.
Definition: TH2Poly.cxx:1263
const Bool_t kFALSE
Definition: RtypesCore.h:88
TList * fBins
Definition: TH2Poly.h:134
virtual void UpdateBinContent(Int_t bin, Double_t content)
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Definition: TH2Poly.h:155
Double_t * GetX() const
Definition: TGraph.h:129
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8217
virtual Int_t GetSumw2N() const
Definition: TH1.h:309
Double_t fTsumw2
Total Sum of squares of weights.
Definition: TH1.h:94
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: TH2Poly.cxx:1279
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
virtual void SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option="")
Helper function for the SavePrimitive functions from TH1 or classes derived from TH1, eg TProfile, TProfile2D.
Definition: TH1.cxx:6740
Double_t fTsumw
Total Sum of weights.
Definition: TH1.h:93
Double_t y[n]
Definition: legend1.C:17
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition: TH2Poly.cxx:859
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:570
The TH1 histogram class.
Definition: TH1.h:56
static constexpr double s
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4178
void Honeycomb(Double_t xstart, Double_t ystart, Double_t a, Int_t k, Int_t s)
Bins the histogram using a honeycomb structure.
Definition: TH2Poly.cxx:907
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:396
void ClearContent()
Definition: TH2Poly.h:32
void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH2Poly.cxx:1174
void ClearBinContents()
Clears the contents of all bins in the histogram.
Definition: TH2Poly.cxx:508
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
Mother of all ROOT objects.
Definition: TObject.h:37
Double_t fMaximum
Maximum value for plotting.
Definition: TH1.h:97
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:69
Double_t * GetY() const
Definition: TGraph.h:130
Double_t fOverflow[kNOverflow]
Definition: TH2Poly.h:135
virtual void Reset(Option_t *option)
Reset this histogram: contents, errors, etc.
Definition: TH2Poly.cxx:532
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition: TH1.h:435
1-Dim function class
Definition: TF1.h:211
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8276
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Double_t GetArea()
Returns the area of the bin.
Definition: TH2Poly.cxx:1338
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
Definition: TRolke.cxx:630
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
Definition: TH1.h:107
Double_t fStepY
Definition: TH2Poly.h:140
virtual void SetEntries(Double_t n)
Definition: TH1.h:378
TAxis fXaxis
X axis descriptor.
Definition: TH1.h:87
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6154
Definition: first.py:1
void Fill(Double_t w)
Definition: TH2Poly.h:33
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside the polygon defined by the graph vertices 0 otherwise...
Definition: TGraph.cxx:1823
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH2.cxx:2455
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition: TAxis.cxx:717
Double_t GetXMin()
Returns the minimum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1404
Double_t * fBuffer
[fBufferSize] entry buffer
Definition: TH1.h:105
const Bool_t kTRUE
Definition: RtypesCore.h:87
Bool_t IsIntersectingPolygon(Int_t bn, Double_t *x, Double_t *y, Double_t xclipl, Double_t xclipr, Double_t yclipb, Double_t yclipt)
Returns kTRUE if the input polygon (bn, x, y) is intersecting with the input rectangle (xclipl...
Definition: TH2Poly.cxx:1046
Double_t GetXmax() const
Definition: TAxis.h:134
const Int_t n
Definition: legend1.C:16
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition: TH2Poly.cxx:811
void FillN(Int_t ntimes, const Double_t *x, const Double_t *y, const Double_t *w, Int_t stride=1)
Fills a 2-D histogram with an array of values and weights.
Definition: TH2Poly.cxx:712
char name[80]
Definition: TGX11.cxx:109
virtual Int_t Fill(Double_t x, Double_t y)
Increment the bin containing (x,y) by 1.
Definition: TH2Poly.cxx:605
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
TH2Poly()
Default Constructor. No boundaries specified.
Definition: TH2Poly.cxx:142
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
void SetNewBinAdded(Bool_t flag)
Definition: TH2Poly.h:125
TH2PolyBin()
Default constructor.
Definition: TH2Poly.cxx:1298
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: TH2Poly.h:152
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows
Definition: TH1.h:86
const char * Data() const
Definition: TString.h:345
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:664
static constexpr double g