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