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