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