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