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