Logo ROOT  
Reference Guide
THistPainter.cxx
Go to the documentation of this file.
1// @(#)root/histpainter:$Id$
2// Author: Rene Brun, Olivier Couet
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <stdlib.h>
13#include <string.h>
14#include <stdio.h>
15#include <ctype.h>
16
17#include "Riostream.h"
18#include "TROOT.h"
19#include "TSystem.h"
20#include "THistPainter.h"
21#include "TH2.h"
22#include "TH2Poly.h"
23#include "TH3.h"
24#include "TProfile.h"
25#include "TProfile2D.h"
26#include "THStack.h"
27#include "TF2.h"
28#include "TF3.h"
29#include "TCutG.h"
30#include "TMatrixDBase.h"
31#include "TMatrixFBase.h"
32#include "TVectorD.h"
33#include "TVectorF.h"
34#include "TCanvas.h"
35#include "TPad.h"
36#include "TPaveStats.h"
37#include "TFrame.h"
38#include "TLatex.h"
39#include "TLine.h"
40#include "TPolyLine.h"
41#include "TPoints.h"
42#include "TStyle.h"
43#include "TGraph.h"
44#include "TMultiGraph.h"
45#include "TPie.h"
46#include "TGaxis.h"
47#include "TColor.h"
49#include "TGraph2DPainter.h"
50#include "TGraphDelaunay2D.h"
51#include "TView.h"
52#include "TMath.h"
53#include "TRandom2.h"
54#include "TObjArray.h"
55#include "Hoption.h"
56#include "Hparam.h"
57#include "TPluginManager.h"
58#include "TPaletteAxis.h"
59#include "TCrown.h"
60#include "TArrow.h"
61#include "TVirtualPadEditor.h"
62#include "TVirtualX.h"
63#include "TEnv.h"
64#include "TPoint.h"
65#include "TImage.h"
66#include "TCandle.h"
67
68/*! \class THistPainter
69\ingroup Histpainter
70\brief The histogram painter class. Implements all histograms' drawing's options.
71
72- [Introduction](#HP00)
73- [Histograms' plotting options](#HP01)
74 - [Options supported for 1D and 2D histograms](#HP01a)
75 - [Options supported for 1D histograms](#HP01b)
76 - [Options supported for 2D histograms](#HP01c)
77 - [Options supported for 3D histograms](#HP01d)
78 - [Options supported for histograms' stacks (THStack)](#HP01e)
79- [Setting the Style](#HP02)
80- [Setting line, fill, marker, and text attributes](#HP03)
81- [Setting Tick marks on the histogram axis](#HP04)
82- [Giving titles to the X, Y and Z axis](#HP05)
83- [The option "SAME"](#HP060)
84 - [Limitations](#HP060a)
85- [Colors automatically picked in palette](#HP061)
86- [Superimposing two histograms with different scales in the same pad](#HP06)
87- [Statistics Display](#HP07)
88- [Fit Statistics](#HP08)
89- [The error bars options](#HP09)
90- [The bar chart option](#HP100)
91- [The "BAR" and "HBAR" options](#HP10)
92- [The SCATter plot option (default for 2D histograms)](#HP11)
93- [The ARRow option](#HP12)
94- [The BOX option](#HP13)
95- [The COLor option](#HP14)
96- [The CANDLE and VIOLIN options](#HP140)
97 - [The CANDLE option](#HP140a)
98 - [The VIOLIN option](#HP140b)
99- [The TEXT and TEXTnn Option](#HP15)
100- [The CONTour options](#HP16)
101 - [The LIST option](#HP16a)
102 - [The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options](#HP16b)
103- [The LEGO options](#HP17)
104- [The "SURFace" options](#HP18)
105- [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
106- [Base line for bar-charts and lego plots](#HP20)
107- [TH2Poly Drawing](#HP20a)
108- [The SPEC option](#HP21)
109- [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
110- [Setting the color palette](#HP23)
111- [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
112- [Drawing options for 3D histograms](#HP25)
113- [Drawing option for histograms' stacks](#HP26)
114- [Drawing of 3D implicit functions](#HP27)
115- [Associated functions drawing](#HP28)
116- [Drawing using OpenGL](#HP29)
117 - [General information: plot types and supported options](#HP29a)
118 - [TH3 as color boxes](#HP290)
119 - [TH3 as boxes (spheres)](#HP29b)
120 - [TH3 as iso-surface(s)](#HP29c)
121 - [TF3 (implicit function)](#HP29d)
122 - [Parametric surfaces](#HP29e)
123 - [Interaction with the plots](#HP29f)
124 - [Selectable parts](#HP29g)
125 - [Rotation and zooming](#HP29h)
126 - [Panning](#HP29i)
127 - [Box cut](#HP29j)
128 - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
129 - [Surface with option "GLSURF"](#HP29l)
130 - [TF3](#HP29m)
131 - [Box](#HP29n)
132 - [Iso](#HP29o)
133 - [Parametric plot](#HP29p)
134- [Highlight mode for histogram](#HP30)
135 - [Highlight mode and user function](#HP30a)
136
137
138## <a name="HP00"></a> Introduction
139
140
141Histograms are drawn via the `THistPainter` class. Each histogram has a
142pointer to its own painter (to be usable in a multithreaded program). When the
143canvas has to be redrawn, the `Paint` function of each objects in the
144pad is called. In case of histograms, `TH1::Paint` invokes directly
145`THistPainter::Paint`.
146
147To draw a histogram `h` it is enough to do:
148
149 h->Draw();
150
151`h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
152be drawn, the `Draw()` method can be invoked with an option. For instance
153to draw a 2D histogram as a lego plot it is enough to do:
154
155 h->Draw("lego");
156
157`THistPainter` offers many options to paint 1D, 2D and 3D histograms.
158
159When the `Draw()` method of a histogram is called for the first time
160(`TH1::Draw`), it creates a `THistPainter` object and saves a
161pointer to this "painter" as a data member of the histogram. The
162`THistPainter` class specializes in the drawing of histograms. It is
163separated from the histogram so that one can have histograms without the
164graphics overhead, for example in a batch program. Each histogram having its own
165painter (rather than a central singleton painter painting all histograms), allows
166two histograms to be drawn in two threads without overwriting the painter's
167values.
168
169When a displayed histogram is filled again, there is no need to call the
170`Draw()` method again; the image will be refreshed the next time the
171pad will be updated.
172
173A pad is updated after one of these three actions:
174
1751. a carriage control on the ROOT command line,
1762. a click inside the pad,
1773. a call to `TPad::Update`.
178
179
180By default a call to `TH1::Draw()` clears the pad of all objects
181before drawing the new image of the histogram. One can use the `SAME`
182option to leave the previous display intact and superimpose the new histogram.
183The same histogram can be drawn with different graphics options in different
184pads.
185
186When a displayed histogram is deleted, its image is automatically removed
187from the pad.
188
189To create a copy of the histogram when drawing it, one can use
190`TH1::DrawClone()`. This will clone the histogram and allow to change
191and delete the original one without affecting the clone.
192
193
194### <a name="HP01"></a> Histograms' plotting options
195
196
197Most options can be concatenated with or without spaces or commas, for example:
198
199 h->Draw("E1 SAME");
200
201The options are not case sensitive:
202
203 h->Draw("e1 same");
204
205
206The default drawing option can be set with `TH1::SetOption` and retrieve
207using `TH1::GetOption`:
208
209 root [0] h->Draw(); // Draw "h" using the standard histogram representation.
210 root [1] h->Draw("E"); // Draw "h" using error bars
211 root [3] h->SetOption("E"); // Change the default drawing option for "h"
212 root [4] h->Draw(); // Draw "h" using error bars
213 root [5] h->GetOption(); // Retrieve the default drawing option for "h"
214 (const Option_t* 0xa3ff948)"E"
215
216
217#### <a name="HP01a"></a> Options supported for 1D and 2D histograms
218
219| Option | Description |
220|----------|-------------------------------------------------------------------|
221| "E" | Draw error bars. |
222| "AXIS" | Draw only axis. |
223| "AXIG" | Draw only grid (if the grid is requested). |
224| <a name="OPTHIST">"HIST"</a> | When an histogram has errors it is visualized by default with error bars. To visualize it without errors use the option "HIST" together with the required option (eg "hist same c"). The "HIST" option can also be used to plot only the histogram and not the associated function(s). |
225| "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
226| "SAME" | Superimpose on previous picture in the same pad. |
227| "SAMES" | Same as "SAME" and draw the statistics box|
228| "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
229| "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
230| "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
231| "LEGO" | Draw a lego plot with hidden line removal. |
232| "LEGO1" | Draw a lego plot with hidden surface removal. |
233| "LEGO2" | Draw a lego plot using colors to show the cell contents When the option "0" is used with any LEGO option, the empty bins are not drawn.|
234| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
235| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
236| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
237| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
238| "X+" | The X-axis is drawn on the top side of the plot. |
239| "Y+" | The Y-axis is drawn on the right side of the plot. |
240| "MIN0" | Set minimum value for the Y axis to 0, equivalent to gStyle->SetHistMinimumZero(). |
241
242#### <a name="HP01b"></a> Options supported for 1D histograms
243
244| Option | Description |
245|----------|-------------------------------------------------------------------|
246| " " | Default. |
247| "AH" | Draw histogram without axis. "A" can be combined with any drawing option. For instance, "AC" draws the histogram as a smooth Curve without axis.|
248| "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
249| "B" | Bar chart option.|
250| "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
251| "HBAR" | Like option "BAR", but bars are drawn horizontally.|
252| "C" | Draw a smooth Curve through the histogram bins.|
253| "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
254| "E1" | Draw error bars with perpendicular lines at the edges.|
255| "E2" | Draw error bars with rectangles.|
256| "E3" | Draw a fill area through the end points of the vertical error bars.|
257| "E4" | Draw a smoothed filled area through the end points of the error bars.|
258| "E5" | Like E3 but ignore the bins with 0 contents.|
259| "E6" | Like E4 but ignore the bins with 0 contents.|
260| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
261| "L" | Draw a line through the bin contents.|
262| "P" | Draw current marker at each bin except empty bins.|
263| "P0" | Draw current marker at each bin including empty bins.|
264| "PIE" | Draw histogram as a Pie Chart.|
265| "*H" | Draw histogram with a * at each bin.|
266| "LF2" | Draw histogram like with option "L" but with a fill area. Note that "L" draws also a fill area if the hist fill color is set but the fill area corresponds to the histogram contour.|
267
268
269#### <a name="HP01c"></a> Options supported for 2D histograms
270
271| Option | Description |
272|-----------|------------------------------------------------------------------|
273| " " | Default (scatter plot).|
274| "ARR" | Arrow mode. Shows gradient between adjacent cells.|
275| "BOX" | A box is drawn for each cell with surface proportional to the content's absolute value. A negative content is marked with a X.|
276| "BOX1" | A button is drawn for each cell with surface proportional to content's absolute value. A sunken button is drawn for negative values a raised one for positive.|
277| "COL" | A box is drawn for each cell with a color scale varying with contents. All the none empty bins are painted. Empty bins are not painted unless some bins have a negative content because in that case the null bins might be not empty. `TProfile2D` histograms are handled differently because, for this type of 2D histograms, it is possible to know if an empty bin has been filled or not. So even if all the bins' contents are positive some empty bins might be painted. And vice versa, if some bins have a negative content some empty bins might be not painted.|
278| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
279| "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
280| "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
281| "Z CJUST" | In combination with colored options "COL","CONT0" etc: Justify labels in the color palette at color boudaries. For more details see `TPaletteAxis`|
282| "CANDLE" | Draw a candle plot along X axis.|
283| "CANDLEX" | Same as "CANDLE".|
284| "CANDLEY" | Draw a candle plot along Y axis.|
285| "CANDLEXn"| Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
286| "CANDLEYn"| Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
287| "VIOLIN" | Draw a violin plot along X axis.|
288| "VIOLINX" | Same as "VIOLIN".|
289| "VIOLINY" | Draw a violin plot along Y axis.|
290| "VIOLINXn"| Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
291| "VIOLINYn"| Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
292| "CONT" | Draw a contour plot (same as CONT0).|
293| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
294| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
295| "CONT2" | Draw a contour plot using the same line style for all contours.|
296| "CONT3" | Draw a contour plot using fill area colors.|
297| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
298| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
299| "LIST" | Generate a list of TGraph objects for each contour.|
300| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
301| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
302| "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. |
303| "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. |
304| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
305| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
306| "SURF" | Draw a surface plot with hidden line removal.|
307| "SURF1" | Draw a surface plot with hidden surface removal.|
308| "SURF2" | Draw a surface plot using colors to show the cell contents.|
309| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
310| "SURF4" | Draw a surface using Gouraud shading.|
311| "SURF5" | Same as SURF3 but only the colored contour is drawn. Used with option CYL, SPH or PSR it allows to draw colored contours on a sphere, a cylinder or a in pseudo rapidity space. In cartesian or polar coordinates, option SURF3 is used.|
312| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
313| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
314| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
315| "A" | With LEGO or SURFACE, suppress the axis.|
316| "SCAT" | Draw a scatter-plot (default).|
317| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
318
319
320#### <a name="HP01d"></a> Options supported for 3D histograms
321
322| Option | Description |
323|----------|-------------------------------------------------------------------|
324| " " | Default (scatter plot).|
325| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`.|
326| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
327| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
328| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
329| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
330| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
331| "LEGO" | Same as `BOX`.|
332
333
334#### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
335
336| Option | Description |
337|------------|-----------------------------------------------------------------|
338| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
339| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
340| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
341| "PADS" | The current pad/canvas is subdivided into a number of pads equal to the number of histograms in the stack and each histogram is paint into a separate pad.|
342| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
343| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
344| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
345
346
347
348### <a name="HP02"></a> Setting the Style
349
350
351Histograms use the current style (`gStyle`). When one changes the current
352style and would like to propagate the changes to the histogram,
353`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
354each histogram is needed.
355
356To force all the histogram to use the current style use:
357
358 gROOT->ForceStyle();
359
360All the histograms read after this call will use the current style.
361
362
363### <a name="HP03"></a> Setting line, fill, marker, and text attributes
364
365
366The histogram classes inherit from the attribute classes:
367`TAttLine`, `TAttFill` and `TAttMarker`.
368See the description of these classes for the list of options.
369
370
371### <a name="HP04"></a> Setting Tick marks on the histogram axis
372
373
374The `TPad::SetTicks` method specifies the type of tick marks on the axis.
375If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
376
377 tx = 1; tick marks on top side are drawn (inside)
378 tx = 2; tick marks and labels on top side are drawn
379 ty = 1; tick marks on right side are drawn (inside)
380 ty = 2; tick marks and labels on right side are drawn
381
382By default only the left Y axis and X bottom axis are drawn
383(`tx = ty = 0`)
384
385`TPad::SetTicks(tx,ty)` allows to set these options.
386See also The `TAxis` functions to set specific axis attributes.
387
388In case multiple color filled histograms are drawn on the same pad, the fill
389area may hide the axis tick marks. One can force a redraw of the axis over all
390the histograms by calling:
391
392 gPad->RedrawAxis();
393
394
395### <a name="HP05"></a> Giving titles to the X, Y and Z axis
396
397
398 h->GetXaxis()->SetTitle("X axis title");
399 h->GetYaxis()->SetTitle("Y axis title");
400
401The histogram title and the axis titles can be any `TLatex` string.
402The titles are part of the persistent histogram.
403
404
405### <a name="HP060"></a> The option "SAME"
406
407
408By default, when an histogram is drawn, the current pad is cleared before
409drawing. In order to keep the previous drawing and draw on top of it the
410option `SAME` should be use. The histogram drawn with the option
411`SAME` uses the coordinates system available in the current pad.
412
413This option can be used alone or combined with any valid drawing option but
414some combinations must be use with care.
415
416#### <a name="HP060a"></a> Limitations
417
418- It does not work when combined with the `LEGO` and `SURF` options unless the
419 histogram plotted with the option `SAME` has exactly the same
420 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
421 lego plots [histograms' stacks](#HP26) should be used.</li>
422
423
424### <a name="HP061"></a> Colors automatically picked in palette
425
426\since **ROOT version 6.09/01**
427
428When several histograms are painted in the same canvas thanks to the option "SAME"
429or via a `THStack` it might be useful to have an easy and automatic way to choose
430their color. The simplest way is to pick colors in the current active color
431palette. Palette coloring for histogram is activated thanks to the options `PFC`
432(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
433When one of these options is given to `TH1::Draw` the histogram get its color
434from the current color palette defined by `gStyle->SetPalette(…)`. The color
435is determined according to the number of objects having palette coloring in
436the current pad.
437
438Begin_Macro(source)
439../../../tutorials/hist/histpalettecolor.C
440End_Macro
441
442Begin_Macro(source)
443../../../tutorials/hist/thstackpalettecolor.C
444End_Macro
445
446Begin_Macro(source)
447../../../tutorials/hist/thstack2palettecolor.C
448End_Macro
449
450### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
451
452
453The following example creates two histograms, the second histogram is the bins
454integral of the first one. It shows a procedure to draw the two histograms in
455the same pad and it draws the scale of the second histogram using a new vertical
456axis on the right side. See also the tutorial `transpad.C` for a variant
457of this example.
458
459Begin_Macro(source)
460{
461 auto c1 = new TCanvas("c1","c1",600,400);
462 // create/fill draw h1
463 gStyle->SetOptStat(kFALSE);
464 auto h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
465 Int_t i;
466 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
467 h1->Draw();
468 c1->Update();
469
470 // create hint1 filled with the bins integral of h1
471 auto hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
472 float sum = 0.f;
473 for (i=1;i<=100;i++) {
474 sum += h1->GetBinContent(i);
475 hint1->SetBinContent(i,sum);
476 }
477
478 // scale hint1 to the pad coordinates
479 float rightmax = 1.1*hint1->GetMaximum();
480 float scale = gPad->GetUymax()/rightmax;
481 hint1->SetLineColor(kRed);
482 hint1->Scale(scale);
483 hint1->Draw("same");
484
485 // draw an axis on the right side
486 auto axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
487 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
488 axis->SetLineColor(kRed);
489 axis->SetTextColor(kRed);
490 axis->Draw();
491}
492End_Macro
493
494
495### <a name="HP07"></a> Statistics Display
496
497
498The type of information shown in the histogram statistics box can be selected
499with:
500
501 gStyle->SetOptStat(mode);
502
503The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
504
505 mode = ksiourmen (default = 000001111)
506 k = 1; kurtosis printed
507 k = 2; kurtosis and kurtosis error printed
508 s = 1; skewness printed
509 s = 2; skewness and skewness error printed
510 i = 1; integral of bins printed
511 i = 2; integral of bins with option "width" printed
512 o = 1; number of overflows printed
513 u = 1; number of underflows printed
514 r = 1; standard deviation printed
515 r = 2; standard deviation and standard deviation error printed
516 m = 1; mean value printed
517 m = 2; mean and mean error values printed
518 e = 1; number of entries printed
519 n = 1; name of histogram is printed
520
521For example:
522
523 gStyle->SetOptStat(11);
524
525displays only the name of histogram and the number of entries, whereas:
526
527 gStyle->SetOptStat(1101);
528
529displays the name of histogram, mean value and standard deviation.
530
531<b>WARNING 1:</b> never do:
532
533 gStyle->SetOptStat(0001111);
534
535but instead do:
536
537 gStyle->SetOptStat(1111);
538
539because `0001111` will be taken as an octal number!
540
541<b>WARNING 2:</b> for backward compatibility with older versions
542
543 gStyle->SetOptStat(1);
544
545is taken as:
546
547 gStyle->SetOptStat(1111)
548
549To print only the name of the histogram do:
550
551 gStyle->SetOptStat(1000000001);
552
553<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
554(10000) or overflow (100000), the statistics box will show all combinations
555of underflow/overflows and not just one single number.
556
557The parameter mode can be any combination of the letters `kKsSiIourRmMen`
558
559 k : kurtosis printed
560 K : kurtosis and kurtosis error printed
561 s : skewness printed
562 S : skewness and skewness error printed
563 i : integral of bins printed
564 I : integral of bins with option "width" printed
565 o : number of overflows printed
566 u : number of underflows printed
567 r : standard deviation printed
568 R : standard deviation and standard deviation error printed
569 m : mean value printed
570 M : mean value mean error values printed
571 e : number of entries printed
572 n : name of histogram is printed
573
574For example, to print only name of histogram and number of entries do:
575
576 gStyle->SetOptStat("ne");
577
578To print only the name of the histogram do:
579
580 gStyle->SetOptStat("n");
581
582The default value is:
583
584 gStyle->SetOptStat("nemr");
585
586When a histogram is painted, a `TPaveStats` object is created and added
587to the list of functions of the histogram. If a `TPaveStats` object
588already exists in the histogram list of functions, the existing object is just
589updated with the current histogram parameters.
590
591Once a histogram is painted, the statistics box can be accessed using
592`h->FindObject("stats")`. In the command line it is enough to do:
593
594 Root > h->Draw()
595 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
596
597because after `h->Draw()` the histogram is automatically painted. But
598in a script file the painting should be forced using `gPad->Update()`
599in order to make sure the statistics box is created:
600
601 h->Draw();
602 gPad->Update();
603 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
604
605Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
606
607When a histogram is drawn with the option `SAME`, the statistics box
608is not drawn. To force the statistics box drawing with the option
609`SAME`, the option `SAMES` must be used.
610If the new statistics box hides the previous statistics box, one can change
611its position with these lines (`h` being the pointer to the histogram):
612
613 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
614 Root > st->SetX1NDC(newx1); //new x start position
615 Root > st->SetX2NDC(newx2); //new x end position
616
617To change the type of information for an histogram with an existing
618`TPaveStats` one should do:
619
620 st->SetOptStat(mode);
621
622Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
623(see above).
624
625One can delete the statistics box for a histogram `TH1* h` with:
626
627 h->SetStats(0)
628
629and activate it again with:
630
631 h->SetStats(1).
632
633Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
634`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
635
636
637### <a name="HP08"></a> Fit Statistics
638
639
640The type of information about fit parameters printed in the histogram statistics
641box can be selected via the parameter mode. The parameter mode can be
642`= pcev` (default `= 0111`)
643
644 p = 1; print Probability
645 c = 1; print Chisquare/Number of degrees of freedom
646 e = 1; print errors (if e=1, v must be 1)
647 v = 1; print name/values of parameters
648
649Example:
650
651 gStyle->SetOptFit(1011);
652
653print fit probability, parameter names/values and errors.
654
6551. When `v = 1` is specified, only the non-fixed parameters are shown.
6562. When `v = 2` all parameters are shown.
657
658Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
659to `gStyle->SetOptFit(111)`
660
661
662### <a name="HP09"></a> The error bars options
663
664
665| Option | Description |
666|----------|-------------------------------------------------------------------|
667| "E" | Default. Shows only the error bars, not a marker.|
668| "E1" | Small lines are drawn at the end of the error bars.|
669| "E2" | Error rectangles are drawn.|
670| "E3" | A filled area is drawn through the end points of the vertical error bars.|
671| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
672| "E0" | Draw also bins with null contents.|
673
674Begin_Macro(source)
675{
676 auto c1 = new TCanvas("c1","c1",600,400);
677 auto he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
678 for (int i=0; i<10000; i++) he->Fill(gRandom->Gaus(0,1));
679 gStyle->SetEndErrorSize(3);
680 gStyle->SetErrorX(1.);
681 he->SetMarkerStyle(20);
682 he->Draw("E1");
683}
684End_Macro
685
686The options "E3" and "E4" draw an error band through the end points of the
687vertical error bars. With "E4" the error band is smoothed. Because of the
688smoothing algorithm used some artefacts may appear at the end of the band
689like in the following example. In such cases "E3" should be used instead
690of "E4".
691
692Begin_Macro(source)
693{
694 auto ce4 = new TCanvas("ce4","ce4",600,400);
695 ce4->Divide(2,1);
696 auto he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
697 Int_t i;
698 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
699 he4->SetFillColor(kRed);
700 he4->GetXaxis()->SetRange(40,48);
701 ce4->cd(1);
702 he4->Draw("E4");
703 ce4->cd(2);
704 auto he3 = (TH1F*)he4->DrawClone("E3");
705 he3->SetTitle("Distribution drawn option E3");
706}
707End_Macro
708
7092D histograms can be drawn with error bars as shown is the following example:
710
711Begin_Macro(source)
712{
713 auto c2e = new TCanvas("c2e","c2e",600,400);
714 auto h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
715 float px, py;
716 for (Int_t i = 0; i < 25000; i++) {
717 gRandom->Rannor(px,py);
718 h2e->Fill(px,5*py);
719 }
720 h2e->Draw("E");
721}
722End_Macro
723
724
725### <a name="HP100"></a> The bar chart option
726
727
728The option "B" allows to draw simple vertical bar charts.
729The bar width is controlled with `TH1::SetBarWidth()`,
730and the bar offset within the bin, with `TH1::SetBarOffset()`.
731These two settings are useful to draw several histograms on the
732same plot as shown in the following example:
733
734Begin_Macro(source)
735{
736 int i;
737 const Int_t nx = 8;
738 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
739 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
740 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
741
742 auto cb = new TCanvas("cb","cb",600,400);
743 cb->SetGrid();
744
745 gStyle->SetHistMinimumZero();
746
747 auto h1b = new TH1F("h1b","Option B example",nx,0,nx);
748 h1b->SetFillColor(4);
749 h1b->SetBarWidth(0.4);
750 h1b->SetBarOffset(0.1);
751 h1b->SetStats(0);
752 h1b->SetMinimum(-5);
753 h1b->SetMaximum(5);
754
755 for (i=1; i<=nx; i++) {
756 h1b->SetBinContent(i, d_35_0[i-1]);
757 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
758 }
759
760 h1b->Draw("b");
761
762 auto h2b = new TH1F("h2b","h2b",nx,0,nx);
763 h2b->SetFillColor(38);
764 h2b->SetBarWidth(0.4);
765 h2b->SetBarOffset(0.5);
766 h2b->SetStats(0);
767 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
768
769 h2b->Draw("b same");
770}
771End_Macro
772
773
774### <a name="HP10"></a> The "BAR" and "HBAR" options
775
776
777When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
778bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
779An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
780`hbar2`, `hbar3`, `hbar4` (hbars.C).
781
782- The bar is filled with the histogram fill color.
783- The left side of the bar is drawn with a light fill color.
784- The right side of the bar is drawn with a dark fill color.
785- The percentage of the bar drawn with either the light or dark color is:
786 - 0% for option "(h)bar" or "(h)bar0"
787 - 10% for option "(h)bar1"
788 - 20% for option "(h)bar2"
789 - 30% for option "(h)bar3"
790 - 40% for option "(h)bar4"
791
792When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
793
794Begin_Macro(source)
795../../../tutorials/hist/hbars.C
796End_Macro
797
798To control the bar width (default is the bin width) `TH1::SetBarWidth()`
799should be used.
800
801To control the bar offset (default is 0) `TH1::SetBarOffset()` should
802be used.
803
804These two parameters are useful when several histograms are plotted using
805the option `SAME`. They allow to plot the histograms next to each other.
806
807
808### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
809
810
811For each cell (i,j) a number of points proportional to the cell content is
812drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
813`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
814If option is of the form `scat=ff`, (eg `scat=1.8`,
815`scat=1e-3`), then `ff` is used as a scale factor to compute the
816number of dots. `scat=1` is the default.
817
818By default the scatter plot is painted with a "dot marker" which not scalable
819(see the `TAttMarker` documentation). To change the marker size, a scalable marker
820type should be used. For instance a circle (marker style 20).
821
822Begin_Macro(source)
823{
824 auto c1 = new TCanvas("c1","c1",600,400);
825 auto hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
826 float px, py;
827 for (Int_t i = 0; i < 25000; i++) {
828 gRandom->Rannor(px,py);
829 hscat->Fill(px,5*py);
830 hscat->Fill(3+0.5*px,2*py-10.);
831 }
832 hscat->Draw("scat=0.5");
833}
834End_Macro
835
836
837### <a name="HP12"></a> The ARRow option
838
839
840Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
841The orientation of the arrow follows the cell gradient.
842
843Begin_Macro(source)
844{
845 auto c1 = new TCanvas("c1","c1",600,400);
846 auto harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
847 harr->SetLineColor(kRed);
848 float px, py;
849 for (Int_t i = 0; i < 25000; i++) {
850 gRandom->Rannor(px,py);
851 harr->Fill(px,5*py);
852 harr->Fill(3+0.5*px,2*py-10.,0.1);
853 }
854 harr->Draw("ARR");
855}
856End_Macro
857
858\since **ROOT version 6.17/01**
859
860The option `ARR` can be combined with the option `COL` or `COLZ`.
861
862Begin_Macro(source)
863{
864 auto c1 = new TCanvas("c1","c1",600,400);
865 auto harr = new TH2F("harr","Option ARR + COLZ example",20,-4,4,20,-20,20);
866 harr->SetStats(0);
867 float px, py;
868 for (Int_t i = 0; i < 25000; i++) {
869 gRandom->Rannor(px,py);
870 harr->Fill(px,5*py);
871 harr->Fill(3+0.5*px,2*py-10.,0.1);
872 }
873 harr->Draw("ARR COLZ");
874}
875End_Macro
876
877
878### <a name="HP13"></a> The BOX option
879
880
881For each cell (i,j) a box is drawn. The size (surface) of the box is
882proportional to the absolute value of the cell content.
883The cells with a negative content are drawn with a `X` on top of the box.
884
885Begin_Macro(source)
886{
887 auto c1 = new TCanvas("c1","c1",600,400);
888 auto hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
889 hbox->SetFillColor(42);
890 hbox->Fill(0.5, 0.5, 1.);
891 hbox->Fill(0.5, 1.5, 4.);
892 hbox->Fill(0.5, 2.5, 3.);
893 hbox->Fill(1.5, 0.5, 2.);
894 hbox->Fill(1.5, 1.5, 12.);
895 hbox->Fill(1.5, 2.5, -6.);
896 hbox->Fill(2.5, 0.5, -4.);
897 hbox->Fill(2.5, 1.5, 6.);
898 hbox->Fill(2.5, 2.5, 0.5);
899 hbox->Draw("BOX");
900}
901End_Macro
902
903With option `BOX1` a button is drawn for each cell with surface
904proportional to content's absolute value. A sunken button is drawn for
905negative values a raised one for positive.
906
907Begin_Macro(source)
908{
909 auto c1 = new TCanvas("c1","c1",600,400);
910 auto hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
911 hbox1->SetFillColor(42);
912 hbox1->Fill(0.5, 0.5, 1.);
913 hbox1->Fill(0.5, 1.5, 4.);
914 hbox1->Fill(0.5, 2.5, 3.);
915 hbox1->Fill(1.5, 0.5, 2.);
916 hbox1->Fill(1.5, 1.5, 12.);
917 hbox1->Fill(1.5, 2.5, -6.);
918 hbox1->Fill(2.5, 0.5, -4.);
919 hbox1->Fill(2.5, 1.5, 6.);
920 hbox1->Fill(2.5, 2.5, 0.5);
921 hbox1->Draw("BOX1");
922}
923End_Macro
924
925When the option `SAME` (or "SAMES") is used with the option `BOX`,
926the boxes' sizes are computing taking the previous plots into account. The range
927along the Z axis is imposed by the first plot (the one without option
928`SAME`); therefore the order in which the plots are done is relevant.
929
930Begin_Macro(source)
931{
932 auto c1 = new TCanvas("c1","c1",600,400);
933 auto hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
934 auto hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
935 auto hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
936 auto hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
937 for (Int_t i=0;i<1000;i++) {
938 double x,y;
939 gRandom->Rannor(x,y);
940 if (x>0 && y>0) hb1->Fill(x,y,4);
941 if (x<0 && y<0) hb2->Fill(x,y,3);
942 if (x>0 && y<0) hb3->Fill(x,y,2);
943 if (x<0 && y>0) hb4->Fill(x,y,1);
944 }
945 hb1->SetFillColor(1);
946 hb2->SetFillColor(2);
947 hb3->SetFillColor(3);
948 hb4->SetFillColor(4);
949 hb1->Draw("box");
950 hb2->Draw("box same");
951 hb3->Draw("box same");
952 hb4->Draw("box same");
953}
954End_Macro
955
956\since **ROOT version 6.17/01:**
957
958Sometimes the change of the range of the Z axis is unwanted, in which case, one
959can use `SAME0` (or `SAMES0`) option to opt out of this change.
960
961Begin_Macro(source)
962{
963 auto h2 = new TH2F("h2"," ",10,0,10,10,20,30);
964 auto hf = (TH2F*)h2->Clone("hf");
965 h2->SetBit(TH1::kNoStats);
966 hf->SetBit(TH1::kNoStats);
967 h2->Fill(5,22);
968 h2->Fill(5,23);
969 h2->Fill(6,22);
970 h2->Fill(6,23);
971 hf->Fill(6,23);
972 hf->Fill(6,23);
973 hf->Fill(6,23);
974 hf->Fill(6,23);
975 hf->Fill(5,23);
976
977 auto hf_copy1 = hf->Clone("hf_copy1");
978 auto lt = new TLatex();
979
980 auto cx = new TCanvas(); cx->Divide(2,1);
981
982 cx->cd(1);
983 h2->Draw("box");
984 hf->Draw("text colz same");
985 lt->DrawLatexNDC(0.3,0.5,"SAME");
986
987 cx->cd(2);
988 h2->Draw("box");
989 hf_copy1->Draw("text colz same0");
990 lt->DrawLatexNDC(0.3,0.5,"SAME0");
991}
992End_Macro
993
994
995### <a name="HP14"></a> The COLor option
996
997
998For each cell (i,j) a box is drawn with a color proportional to the cell
999content.
1000
1001The color table used is defined in the current style.
1002
1003If the histogram's minimum and maximum are the same (flat histogram), the
1004mapping on colors is not possible, therefore nothing is painted. To paint a
1005flat histogram it is enough to set the histogram minimum
1006(`TH1::SetMinimum()`) different from the bins' content.
1007
1008The default number of color levels used to paint the cells is 20.
1009It can be changed with `TH1::SetContour()` or
1010`TStyle::SetNumberContours()`. The higher this number is, the smoother
1011is the color change between cells.
1012
1013The color palette in TStyle can be modified via `gStyle->SetPalette()`.
1014
1015All the non-empty bins are painted. Empty bins are not painted unless
1016some bins have a negative content because in that case the null bins
1017might be not empty.
1018
1019`TProfile2D` histograms are handled differently because, for this type of 2D
1020histograms, it is possible to know if an empty bin has been filled or not. So even
1021if all the bins' contents are positive some empty bins might be painted. And vice versa,
1022if some bins have a negative content some empty bins might be not painted.
1023
1024Combined with the option `COL`, the option `Z` allows to
1025display the color palette defined by `gStyle->SetPalette()`.
1026
1027In the following example, the histogram has only positive bins; the empty
1028bins (containing 0) are not drawn.
1029
1030Begin_Macro(source)
1031{
1032 auto c1 = new TCanvas("c1","c1",600,400);
1033 auto hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
1034 float px, py;
1035 for (Int_t i = 0; i < 25000; i++) {
1036 gRandom->Rannor(px,py);
1037 hcol1->Fill(px,5*py);
1038 }
1039 hcol1->Draw("COLZ");
1040}
1041End_Macro
1042
1043In the first plot of following example, the histogram has some negative bins;
1044the empty bins (containing 0) are drawn. In some cases one wants to not draw
1045empty bins (containing 0) of histograms having a negative minimum. The option
1046`1`, used to produce the second plot in the following picture, allows to do that.
1047
1048Begin_Macro(source)
1049{
1050 auto c1 = new TCanvas("c1","c1",600,600);
1051 c1->Divide(1,2);
1052 auto hcol23 = new TH2F("hcol23","Option COLZ example ",40,-4,4,40,-20,20);
1053 auto hcol24 = new TH2F("hcol24","Option COLZ1 example ",40,-4,4,40,-20,20);
1054 float px, py;
1055 for (Int_t i = 0; i < 25000; i++) {
1056 gRandom->Rannor(px,py);
1057 hcol23->Fill(px,5*py);
1058 hcol24->Fill(px,5*py);
1059 }
1060 hcol23->Fill(0.,0.,-200.);
1061 hcol24->Fill(0.,0.,-200.);
1062 c1->cd(1); hcol23->Draw("COLZ");
1063 c1->cd(2); hcol24->Draw("COLZ1");
1064}
1065End_Macro
1066
1067When the maximum of the histogram is set to a smaller value than the real maximum,
1068 the bins having a content between the new maximum and the real maximum are
1069painted with the color corresponding to the new maximum.
1070
1071When the minimum of the histogram is set to a greater value than the real minimum,
1072 the bins having a value between the real minimum and the new minimum are not drawn
1073 unless the option `0` is set.
1074
1075The following example illustrates the option `0` combined with the option `COL`.
1076
1077Begin_Macro(source)
1078{
1079 auto c1 = new TCanvas("c1","c1",600,600);
1080 c1->Divide(1,2);
1081 auto hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1082 auto hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1083 float px, py;
1084 for (Int_t i = 0; i < 25000; i++) {
1085 gRandom->Rannor(px,py);
1086 hcol21->Fill(px,5*py);
1087 hcol22->Fill(px,5*py);
1088 }
1089 hcol21->SetBit(TH1::kNoStats);
1090 hcol22->SetBit(TH1::kNoStats);
1091 c1->cd(1); hcol21->Draw("COLZ");
1092 c1->cd(2); hcol22->Draw("COLZ0");
1093 hcol22->SetMaximum(100);
1094 hcol22->SetMinimum(40);
1095}
1096End_Macro
1097
1098\since **ROOT version 6.09/01:**
1099
1100When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1101are computing taking the previous plots into account. The range along the Z axis
1102is imposed by the first plot (the one without option SAME); therefore the order
1103in which the plots are done is relevant. Same as [in the `BOX` option](#HP13), one can use
1104`SAME0` (or `SAMES0`) to opt out of this imposition.
1105
1106Begin_Macro(source)
1107{
1108 auto c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1109 auto h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1110 auto h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1111 auto h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1112 auto h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1113 h1->SetBit(TH1::kNoStats);
1114 for (Int_t i=0;i<5000;i++) {
1115 double x,y;
1116 gRandom->Rannor(x,y);
1117 if(x>0 && y>0) h1->Fill(x,y,4);
1118 if(x<0 && y<0) h2->Fill(x,y,3);
1119 if(x>0 && y<0) h3->Fill(x,y,2);
1120 if(x<0 && y>0) h4->Fill(x,y,1);
1121 }
1122 h1->Draw("colz");
1123 h2->Draw("col same");
1124 h3->Draw("col same");
1125 h4->Draw("col same");
1126}
1127End_Macro
1128
1129The option `COL` can be combined with the option `POL`:
1130
1131Begin_Macro(source)
1132{
1133 auto c1 = new TCanvas("c1","c1",600,400);
1134 auto hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1135 float px, py;
1136 for (Int_t i = 0; i < 25000; i++) {
1137 gRandom->Rannor(px,py);
1138 hcol1->Fill(px,py);
1139 }
1140 hcol1->Draw("COLZPOL");
1141}
1142End_Macro
1143
1144\since **ROOT version 6.07/03:**
1145
1146A second rendering technique is also available with the COL2 and COLZ2 options.
1147
1148These options provide potential performance improvements compared to the standard
1149COL option. The performance comparison of the COL2 to the COL option depends on
1150the histogram and the size of the rendering region in the current pad. In general,
1151a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1152faster with the COL option.
1153
1154However, for larger histograms (approx. more than 100 bins per axis)
1155that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1156For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1157faster with the COL2 option.
1158
1159The COL2 option will also scale its performance based on the size of the
1160pixmap the histogram image is being rendered into. It also is much better optimized for
1161sessions where the user is forwarding X11 windows through an `ssh` connection.
1162
1163For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1164and COLZ options. There is one major difference and that concerns the treatment of
1165bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1166
1167COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1168graphics file format like PostScript or PDF (an empty image will be generated). It can
1169be saved only in bitmap files like PNG format for instance.
1170
1171
1172### <a name="HP140"></a> The CANDLE and VIOLIN options
1173
1174The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1175implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1176the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1177vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1178(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1179
1180Instead of using the predefined representations, the candle and violin parameters can be
1181changed individually. In that case the option have the following form:
1182
1183 CANDLEX(<option-string>)
1184 CANDLEY(<option-string>)
1185 VIOLINX(<option-string>)
1186 VIOLINY(<option-string>).
1187
1188All zeros at the beginning of `option-string` can be omitted.
1189
1190`option-string` consists eight values, defined as follow:
1191
1192 "CANDLEX(zhpawMmb)"
1193
1194Where:
1195
1196 - `b = 0`; no box drawn
1197 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1198 makes sense in the very most cases to always draw the box
1199 - `b = 2`; draw a filled box with border
1200
1201 - `m = 0`; no median drawn
1202 - `m = 1`; median is drawn as a line
1203 - `m = 2`; median is drawn with errors (notches)
1204 - `m = 3`; median is drawn as a circle
1205
1206 - `M = 0`; no mean drawn
1207 - `M = 1`; mean is drawn as a dashed line
1208 - `M = 3`; mean is drawn as a circle
1209
1210 - `w = 0`; no whisker drawn
1211 - `w = 1`; whisker is drawn to end of distribution.
1212 - `w = 2`; whisker is drawn to max 1.5*iqr
1213
1214 - `a = 0`; no anchor drawn
1215 - `a = 1`; the anchors are drawn
1216
1217 - `p = 0`; no points drawn
1218 - `p = 1`; only outliers are drawn
1219 - `p = 2`; all datapoints are drawn
1220 - `p = 3`: all datapoints are drawn scattered
1221
1222 - `h = 0`; no histogram is drawn
1223 - `h = 1`; histogram at the left or bottom side is drawn
1224 - `h = 2`; histogram at the right or top side is drawn
1225 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1226
1227 - `z = 0`; no zero indicator line is drawn
1228 - `z = 1`; zero indicator line is drawn.
1229
1230As one can see all individual options for both candle and violin plots can be accessed by this
1231mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1232meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1233vice versa, if you wish.
1234
1235Using a logarithmic x- or y-axis is possible for candle and violin charts.
1236
1237\since **ROOT version 6.11/01**
1238
1239a logarithmic z-axis is possible, too but will only affect violin charts of course.
1240
1241#### <a name="HP140a"></a> The CANDLE option
1242
1243<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1244a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1245way to describe graphically a data distribution (D) with only five numbers:
1246
1247 1. The minimum value of the distribution D (bottom or left whisker).
1248 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1249 3. The median (M): 50% of the data points in D are less than M.
1250 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1251 5. The maximum value of the distribution D (top or right whisker).
1252
1253In this implementation a TH2 is considered as a collection of TH1 along
1254X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1255Each TH1 is represented as one candle.
1256
1257Begin_Macro(source)
1258../../../tutorials/hist/candleplotwhiskers.C
1259End_Macro
1260
1261The candle reduces the information coming from a whole distribution into few values.
1262Independently from the number of entries or the significance of the underlying distribution
1263a candle will always look like a candle. So candle plots should be used carefully in
1264particular with unknown distributions. The definition of a candle is based on
1265__unbinned data__. Here, candles are created from binned data. Because of this, the
1266deviation is connected to the bin width used. The calculation of the quantiles
1267normally done on unbinned data also. Because data are binned, this will
1268only work the best possible way within the resolution of one bin
1269
1270Because of all these facts one should take care that:
1271
1272 - there are enough points per candle
1273 - the bin width is small enough (more bins will increase the maximum
1274 available resolution of the quantiles although there will be some
1275 bins with no entries)
1276 - never make a candle-plot if the underlying distribution is double-distributed
1277 - only create candles of distributions that are more-or-less gaussian (the
1278 MPV should be not too far away from the mean).
1279
1280#### What a candle is made of
1281
1282\since **ROOT version 6.07/05**
1283
1284##### The box
1285The box displays the position of the inter-quantile-range of the underlying
1286distribution. The box contains 25% of the distribution below the median
1287and 25% of the distribution above the median. If the underlying distribution is large
1288enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1289(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1290the position of the box can be modified by SetBarWidth() and SetBarOffset().
1291The +-25% quantiles are calculated by the GetQuantiles() methods.
1292
1293\since **ROOT version 6.11/01**
1294
1295Using the static function TCandle::SetBoxRange(double) the box definition will be
1296overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1297to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1298The static function will affect all candle-charts in the running program.
1299Default is 0.5.
1300
1301Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1302whole candle) can be influenced. Deactivated, the width is constant (to be set by
1303SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1304amount of data in the corresponding candle, the maximum width can be influenced by
1305SetBarWidth(). The static function will affect all candle-charts in the running program.
1306Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1307supported, yet
1308
1309##### The Median
1310For a sorted list of numbers, the median is the value in the middle of the list.
1311E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1312because it is in the middle of the list. If the number of entries is even the
1313average of the two values in the middle will be used. As histograms are binned
1314data, the situation is a bit more complex. The following example shows this:
1315
1316~~~ {.cpp}
1317void quantiles() {
1318 auto h = new TH1I("h","h",10,0,10);
1319 //h->Fill(3);
1320 //h->Fill(3);
1321 h->Fill(4);
1322 h->Draw();
1323 double p = 0.;
1324 double q = 0.;
1325 h->GetQuantiles(1,&q,&p);
1326
1327 cout << "Median is: " << q << std::endl;
1328}
1329~~~
1330
1331Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1332the example will return a calculated median of 4.5, because that's the bin center
1333of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1334commented out, it will return 3.75, because the algorithm tries to evenly distribute
1335the individual values of a bin with bin content > 0. It means the sorted list
1336would be "3.25, 3.75, 4.5".
1337
1338The consequence is a median of 3.75. This shows how important it is to use a
1339small enough bin-width when using candle-plots on binned data.
1340If the distribution is large enough and gaussian shaped the median will be exactly
1341equal to the mean.
1342The median can be shown as a line or as a circle or not shown at all.
1343
1344In order to show the significance of the median notched candle plots apply a "notch" or
1345narrowing of the box around the median. The significance is defined by
1346\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1347(where iqr is the size of the box and N is the number of entries of the whole
1348distribution). Candle plots like these are usually called "notched candle plots".
1349
1350In case the significance of the median is greater that the size of the box, the
1351box will have an unnatural shape. Usually it means the chart has not enough data,
1352or that representing this uncertainty is not useful
1353
1354##### The Mean
1355The mean can be drawn as a dashed line or as a circle or not drawn at all.
1356The mean is the arithmetic average of the values in the distribution.
1357It is calculated using GetMean(). Because histograms are
1358binned data, the mean value can differ from a calculation on the raw-data.
1359If the distribution is large enough and gaussian shaped the mean will be
1360exactly the median.
1361
1362##### The Whiskers
1363The whiskers represent the part of the distribution not covered by the box.
1364The upper 25% and the lower 25% of the distribution are located within the whiskers.
1365Two representations are available.
1366
1367 - A simple one (using w=1) defining the lower whisker from the lowest data value
1368 to the bottom of the box, and the upper whisker from the top of the box to the
1369 highest data value. In this representation the whisker-lines are dashed.
1370 - A more complex one having a further restriction. The whiskers are still connected
1371 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1372 be that the outermost part of the underlying distribution will not be covered
1373 by the whiskers. Usually these missing parts will be represented by the outliers
1374 (see points). Of course the upper and the lower whisker may differ in length.
1375 In this representation the whiskers are drawn as solid lines.
1376
1377\since **ROOT version 6.11/01**
1378
1379Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1380will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1381the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1382that candle. The static function will affect all candle-charts in the running program.
1383Default is 1.
1384
1385If the distribution is large enough and gaussian shaped, the maximum length of
1386the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
13871.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1388(see picture above). In that case 99.3% of the total distribution will be covered
1389by the box and the whiskers, whereas 0.7% are represented by the outliers.
1390
1391##### The Anchors
1392The anchors have no special meaning in terms of statistical calculation. They mark
1393the end of the whiskers and they have the width of the box. Both representation
1394with and without anchors are common.
1395
1396##### The Points
1397Depending on the configuration the points can have different meanings:
1398 - If p=1 the points represent the outliers. If they are shown, it means
1399 some parts of the underlying distribution are not covered by the whiskers.
1400 This can only occur when the whiskers are set to option w=2. Here the whiskers
1401 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1402 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1403 - If p=2 all points in the distribution will be painted as crosses. This is
1404 useful for small datasets only (up to 10 or 20 points per candle).
1405 The outliers are shown along the candle. Because the underlying distribution
1406 is binned, is frequently occurs that a bin contains more than one value.
1407 Because of this the points will be randomly scattered within their bin along
1408 the candle axis. If the bin content for a bin is exactly 1 (usually
1409 this happens for the outliers) if will be drawn in the middle of the bin along
1410 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1411 on very large datasets scaling will be performed automatically. In that case one
1412 would loose all outliers because they have usually a bin content of 1 (and a
1413 bin content between 0 and 1 after the scaling). Because of this all bin contents
1414 between 0 and 1 - after the scaling - will be forced to be 1.
1415 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1416 one can show all values as a scatter plot instead by choosing p=3. The points will be
1417 drawn as dots and will be scattered within the width of the candle. The color
1418 of the points will be the color of the candle-chart.
1419
1420##### Other Options
1421Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1422with a histogram.
1423
1424#### How to use the candle-plots drawing option
1425
1426There are six predefined candle-plot representations:
1427
1428 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1429 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1430 It is a good compromise
1431 - "CANDLEX3": Like candle2 but with a mean as a circle.
1432 It is easier to distinguish mean and median
1433 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1434 (notched candle plots).
1435 For bigger datasets per candle
1436 - "CANDLEX5": Like candle2 but showing all data points.
1437 For very small datasets
1438 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1439 For huge datasets
1440
1441
1442The following picture shows how the six predefined representations look.
1443
1444Begin_Macro
1445{
1446 auto c1 = new TCanvas("c1","c1",700,800);
1447 c1->Divide(2,3);
1448 gStyle->SetOptStat(kFALSE);
1449
1450 auto hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1451 float px, py;
1452 for (Int_t i = 0; i < 15000; i++) {
1453 gRandom->Rannor(px,py);
1454 hcandle->Fill(px,5*py);
1455 }
1456 hcandle->SetMarkerSize(0.5);
1457
1458 TH2F *h2;
1459 for (Int_t i=1; i<7; i++) {
1460 c1->cd(i);
1461 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1462 h2->SetTitle(Form("CANDLE%d",i));
1463 }
1464}
1465End_Macro
1466
1467
1468#### Example 1
1469Box and improved whisker, no mean, no median, no anchor no outliers
1470
1471 h1->Draw("CANDLEX(2001)");
1472
1473#### Example 2
1474A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1475
1476 h1->Draw("CANDLEX(112111)");
1477
1478#### Example 3
1479The following example shows how several candle plots can be super-imposed using
1480the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1481Also the color, the line width, the size of the points and so on can be changed by the
1482standard attribute setting methods such as SetLineColor() SetLineWidth().
1483
1484Begin_Macro(source)
1485../../../tutorials/hist/candleplot.C
1486End_Macro
1487
1488#### <a name="HP140b"></a> The VIOLIN option
1489
1490<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1491that also encodes the pdf information at each point.
1492
1493
1494Quartiles and mean are also represented at each point, with a marker
1495and two lines.
1496
1497In this implementation a TH2 is considered as a collection of TH1 along
1498X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1499
1500#### What a violin is made of
1501
1502\since **ROOT version 6.09/02**
1503
1504##### The histogram
1505The histogram is typically drawn to both directions with respect to the middle-line of the
1506corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1507one side (h=1, or h=2).
1508The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1509histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1510be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1511A solid fill style is recommended.
1512
1513\since **ROOT version 6.11/01**
1514
1515Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1516violin can be influenced. Activated, the height of the bins of the individual violins will be
1517scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1518Deactivated, the height of the bin with the maximum content of each individual violin is
1519set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1520in the running program. Default is true. Scaling between multiple violin-charts
1521(using "same" or THStack) is not supported, yet.
1522
1523##### The zero indicator line
1524Typical for violin charts is a line in the background over the whole histogram indicating
1525the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1526will always be the same as the fill-color of the histogram.
1527
1528##### The Mean
1529The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1530
1531##### Whiskers
1532The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1533difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1534the whiskers will be forced to be solid (usually hashed)
1535
1536##### Points
1537The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1538better whisker definition (w=2) and outliers (p=1).
1539
1540##### Other options
1541It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1542including a box-plot.
1543
1544#### How to use the violin-plots drawing option
1545
1546There are two predefined violin-plot representations:
1547 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1548 zero indicator line)
1549 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1550
1551A solid fill style is recommended for this plot (as opposed to a hollow or
1552hashed style).
1553
1554Begin_Macro(source)
1555{
1556 auto c1 = new TCanvas("c1","c1",600,400);
1557 Int_t nx(6), ny(40);
1558 double xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1559 auto hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1560 TF1 f1("f1", "gaus", +0,0 +4.0);
1561 double x,y;
1562 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1563 double xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1564 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1565 for(Int_t i=0; i<10000; ++i){
1566 x = xc;
1567 y = f1.GetRandom();
1568 hviolin->Fill(x, y);
1569 }
1570 }
1571 hviolin->SetFillColor(kGray);
1572 hviolin->SetMarkerStyle(20);
1573 hviolin->SetMarkerSize(0.5);
1574 hviolin->Draw("VIOLIN");
1575 c1->Update();
1576}
1577End_Macro
1578
1579The next example illustrates a time development of a certain value:
1580
1581Begin_Macro(source)
1582../../../tutorials/hist/candledecay.C
1583End_Macro
1584
1585
1586### <a name="HP15"></a> The TEXT and TEXTnn Option
1587
1588
1589For each bin the content is printed. The text attributes are:
1590
1591- text font = current TStyle font (`gStyle->SetTextFont()`).
1592- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1593 with the option `TEXT` the marker size can be changed with
1594 `h->SetMarkerSize(markersize)`).
1595- text color = marker color.
1596
1597By default the format `g` is used. This format can be redefined
1598by calling `gStyle->SetPaintTextFormat()`.
1599
1600It is also possible to use `TEXTnn` in order to draw the text with
1601the angle `nn` (`0 < nn < 90`).
1602
1603For 2D histograms the text is plotted in the center of each non empty cells.
1604It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`
1605or providing MIN0 draw option. For 1D histogram the text is plotted at a y
1606position equal to the bin content.
1607
1608For 2D histograms when the option "E" (errors) is combined with the option
1609text ("TEXTE"), the error for each bin is also printed.
1610
1611Begin_Macro(source)
1612{
1613 auto c01 = new TCanvas("c01","c01",700,400);
1614 c01->Divide(2,1);
1615 auto htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1616 auto htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1617 float px, py;
1618 for (Int_t i = 0; i < 25000; i++) {
1619 gRandom->Rannor(px,py);
1620 htext1->Fill(px,0.1);
1621 htext2->Fill(px,5*py,0.1);
1622 }
1623 gStyle->SetPaintTextFormat("4.1f m");
1624 htext2->SetMarkerSize(1.8);
1625 c01->cd(1);
1626 htext2->Draw("TEXT45");
1627 c01->cd(2);
1628 htext1->Draw();
1629 htext1->Draw("HIST TEXT0 SAME");
1630}
1631End_Macro
1632
1633\since **ROOT version 6.07/07:**
1634
1635In case several histograms are drawn on top ot each other (using option `SAME`),
1636the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1637text position in each cell, in percentage of the bin width.
1638
1639Begin_Macro(source)
1640{
1641 auto c03 = new TCanvas("c03","c03",700,400);
1642 gStyle->SetOptStat(0);
1643 auto htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1644 auto htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1645 auto htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1646 float px, py;
1647 for (Int_t i = 0; i < 25000; i++) {
1648 gRandom->Rannor(px,py);
1649 htext3->Fill(4*px,20*py,0.1);
1650 htext4->Fill(4*px,20*py,0.5);
1651 htext5->Fill(4*px,20*py,1.0);
1652 }
1653 htext4->SetMarkerSize(1.8);
1654 htext5->SetMarkerSize(1.8);
1655 htext5->SetMarkerColor(kRed);
1656 htext3->Draw("COL");
1657 htext4->SetBarOffset(0.2);
1658 htext4->Draw("TEXT SAME");
1659 htext5->SetBarOffset(-0.2);
1660 htext5->Draw("TEXT SAME");
1661}
1662End_Macro
1663
1664In the case of profile histograms it is possible to print the number
1665of entries instead of the bin content. It is enough to combine the
1666option "E" (for entries) with the option "TEXT".
1667
1668Begin_Macro(source)
1669{
1670 auto c02 = new TCanvas("c02","c02",700,400);
1671 c02->Divide(2,1);
1672 gStyle->SetPaintTextFormat("g");
1673
1674 auto profile = new TProfile("profile","profile",10,0,10);
1675 profile->SetMarkerSize(2.2);
1676 profile->Fill(0.5,1);
1677 profile->Fill(1.5,2);
1678 profile->Fill(2.5,3);
1679 profile->Fill(3.5,4);
1680 profile->Fill(4.5,5);
1681 profile->Fill(5.5,5);
1682 profile->Fill(6.5,4);
1683 profile->Fill(7.5,3);
1684 profile->Fill(8.5,2);
1685 profile->Fill(9.5,1);
1686 c02->cd(1); profile->Draw("HIST TEXT0");
1687 c02->cd(2); profile->Draw("HIST TEXT0E");
1688}
1689End_Macro
1690
1691### <a name="HP16"></a> The CONTour options
1692
1693
1694The following contour options are supported:
1695
1696| Option | Description |
1697|----------|-------------------------------------------------------------------|
1698| "CONT" | Draw a contour plot (same as CONT0).|
1699| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1700| "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1701| "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1702| "CONT3" | Draw a contour plot solid lines for all contours.|
1703| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1704| "CONT5" | Draw a contour plot using Delaunay triangles.|
1705
1706
1707
1708The following example shows a 2D histogram plotted with the option
1709`CONTZ`. The option `CONT` draws a contour plot using surface
1710colors to distinguish contours. Combined with the option `CONT` (or
1711`CONT0`), the option `Z` allows to display the color palette
1712defined by `gStyle->SetPalette()`.
1713
1714Begin_Macro(source)
1715{
1716 auto c1 = new TCanvas("c1","c1",600,400);
1717 auto hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1718 float px, py;
1719 for (Int_t i = 0; i < 25000; i++) {
1720 gRandom->Rannor(px,py);
1721 hcontz->Fill(px-1,5*py);
1722 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1723 }
1724 hcontz->Draw("CONTZ");
1725}
1726End_Macro
1727
1728The following example shows a 2D histogram plotted with the option
1729`CONT1Z`. The option `CONT1` draws a contour plot using the
1730line colors to distinguish contours. Combined with the option `CONT1`,
1731the option `Z` allows to display the color palette defined by
1732`gStyle->SetPalette()`.
1733
1734Begin_Macro(source)
1735{
1736 auto c1 = new TCanvas("c1","c1",600,400);
1737 auto hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1738 float px, py;
1739 for (Int_t i = 0; i < 25000; i++) {
1740 gRandom->Rannor(px,py);
1741 hcont1->Fill(px-1,5*py);
1742 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1743 }
1744 hcont1->Draw("CONT1Z");
1745}
1746End_Macro
1747
1748The following example shows a 2D histogram plotted with the option
1749`CONT2`. The option `CONT2` draws a contour plot using the
1750line styles to distinguish contours.
1751
1752Begin_Macro(source)
1753{
1754 auto c1 = new TCanvas("c1","c1",600,400);
1755 auto hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1756 float px, py;
1757 for (Int_t i = 0; i < 25000; i++) {
1758 gRandom->Rannor(px,py);
1759 hcont2->Fill(px-1,5*py);
1760 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1761 }
1762 hcont2->Draw("CONT2");
1763}
1764End_Macro
1765
1766The following example shows a 2D histogram plotted with the option
1767`CONT3`. The option `CONT3` draws contour plot solid lines for
1768all contours.
1769
1770Begin_Macro(source)
1771{
1772 auto c1 = new TCanvas("c1","c1",600,400);
1773 auto hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1774 float px, py;
1775 for (Int_t i = 0; i < 25000; i++) {
1776 gRandom->Rannor(px,py);
1777 hcont3->Fill(px-1,5*py);
1778 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1779 }
1780 hcont3->Draw("CONT3");
1781}
1782End_Macro
1783
1784The following example shows a 2D histogram plotted with the option
1785`CONT4`. The option `CONT4` draws a contour plot using surface
1786colors to distinguish contours (`SURF` option at theta = 0). Combined
1787with the option `CONT` (or `CONT0`), the option `Z`
1788allows to display the color palette defined by `gStyle->SetPalette()`.
1789
1790Begin_Macro(source)
1791{
1792 auto c1 = new TCanvas("c1","c1",600,400);
1793 auto hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1794 float px, py;
1795 for (Int_t i = 0; i < 25000; i++) {
1796 gRandom->Rannor(px,py);
1797 hcont4->Fill(px-1,5*py);
1798 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1799 }
1800 hcont4->Draw("CONT4Z");
1801}
1802End_Macro
1803
1804The default number of contour levels is 20 equidistant levels and can be changed
1805with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1806
1807#### <a name="HP16a"></a> The LIST option
1808
1809When option `LIST` is specified together with option
1810`CONT`, the points used to draw the contours are saved in
1811`TGraph` objects:
1812
1813 h->Draw("CONT LIST");
1814 gPad->Update();
1815
1816The contour are saved in `TGraph` objects once the pad is painted.
1817Therefore to use this functionality in a macro, `gPad->Update()`
1818should be performed after the histogram drawing. Once the list is
1819built, the contours are accessible in the following way:
1820
1821 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
1822 Int_t ncontours = contours->GetSize();
1823 TList *list = (TList*)contours->At(i);
1824
1825Where `i` is a contour number, and list contains a list of
1826`TGraph` objects.
1827For one given contour, more than one disjoint polyline may be generated.
1828The number of TGraphs per contour is given by:
1829
1830 list->GetSize();
1831
1832To access the first graph in the list one should do:
1833
1834 TGraph *gr1 = (TGraph*)list->First();
1835
1836
1837The following example (ContourList.C) shows how to use this functionality.
1838
1839Begin_Macro(source)
1840../../../tutorials/hist/ContourList.C
1841End_Macro
1842
1843#### <a name="HP16b"></a> The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options
1844
1845The following options select the `CONT4` option and are useful for
1846sky maps or exposure maps (earth.C).
1847
1848| Option | Description |
1849|--------------|---------------------------------------------------------------|
1850| "AITOFF" | Draw a contour via an AITOFF projection.|
1851| "MERCATOR" | Draw a contour via an Mercator projection.|
1852| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1853| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1854
1855Begin_Macro(source)
1856../../../tutorials/graphics/earth.C
1857End_Macro
1858
1859
1860### <a name="HP17"></a> The LEGO options
1861
1862
1863In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1864is proportional to the cell content. The lego aspect is control with the
1865following options:
1866
1867| Option | Description |
1868|----------|-------------------------------------------------------------------|
1869| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1870| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1871| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1872| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1873| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1874| "0" | When used with any LEGO option, the empty bins are not drawn.|
1875
1876
1877See the limitations with [the option "SAME"](#HP060a).
1878
1879Line attributes can be used in lego plots to change the edges' style.
1880
1881The following example shows a 2D histogram plotted with the option
1882`LEGO`. The option `LEGO` draws a lego plot using the hidden
1883lines removal technique.
1884
1885Begin_Macro(source)
1886{
1887 auto c2 = new TCanvas("c2","c2",600,400);
1888 auto hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1889 float px, py;
1890 for (Int_t i = 0; i < 25000; i++) {
1891 gRandom->Rannor(px,py);
1892 hlego->Fill(px-1,5*py);
1893 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1894 }
1895 hlego->Draw("LEGO");
1896}
1897End_Macro
1898
1899The following example shows a 2D histogram plotted with the option
1900`LEGO1`. The option `LEGO1` draws a lego plot using the
1901hidden surface removal technique. Combined with any `LEGOn` option, the
1902option `0` allows to not drawn the empty bins.
1903
1904Begin_Macro(source)
1905{
1906 auto c2 = new TCanvas("c2","c2",600,400);
1907 auto hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1908 float px, py;
1909 for (Int_t i = 0; i < 25000; i++) {
1910 gRandom->Rannor(px,py);
1911 hlego1->Fill(px-1,5*py);
1912 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1913 }
1914 hlego1->SetFillColor(kYellow);
1915 hlego1->Draw("LEGO1 0");
1916}
1917End_Macro
1918
1919The following example shows a 2D histogram plotted with the option
1920`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1921draws a lego plot using the hidden surface removal technique but doesn't draw
1922the border lines of each individual lego-bar. This is very useful for histograms
1923having many bins. With such histograms the option `LEGO1` gives a black
1924image because of the border lines. This option also works with stacked legos.
1925
1926Begin_Macro(source)
1927{
1928 auto c2 = new TCanvas("c2","c2",600,400);
1929 auto hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1930 float px, py;
1931 for (Int_t i = 0; i < 25000; i++) {
1932 gRandom->Rannor(px,py);
1933 hlego3->Fill(px-1,5*py);
1934 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1935 }
1936 hlego3->SetFillColor(kRed);
1937 hlego3->Draw("LEGO3");
1938}
1939End_Macro
1940
1941The following example shows a 2D histogram plotted with the option
1942`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1943show the cell contents. Combined with the option `LEGO2`, the option
1944`Z` allows to display the color palette defined by
1945`gStyle->SetPalette()`.
1946
1947Begin_Macro(source)
1948{
1949 auto c2 = new TCanvas("c2","c2",600,400);
1950 auto hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1951 float px, py;
1952 for (Int_t i = 0; i < 25000; i++) {
1953 gRandom->Rannor(px,py);
1954 hlego2->Fill(px-1,5*py);
1955 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1956 }
1957 hlego2->Draw("LEGO2Z");
1958}
1959End_Macro
1960
1961
1962
1963### <a name="HP18"></a> The "SURFace" options
1964
1965
1966In a surface plot, cell contents are represented as a mesh.
1967The height of the mesh is proportional to the cell content.
1968
1969| Option | Description |
1970|----------|-------------------------------------------------------------------|
1971| "SURF" | Draw a surface plot using the hidden line removal technique.|
1972| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1973| "SURF2" | Draw a surface plot using colors to show the cell contents.|
1974| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1975| "SURF4" | Draw a surface using the Gouraud shading technique.|
1976| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1977| "SURF6" | This option should not be used directly. It is used internally when the CONT is used with option the option SAME on a 3D plot.|
1978| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1979
1980
1981
1982See the limitations with [the option "SAME"](#HP060a).
1983
1984The following example shows a 2D histogram plotted with the option
1985`SURF`. The option `SURF` draws a lego plot using the hidden
1986lines removal technique.
1987
1988Begin_Macro(source)
1989{
1990 auto c2 = new TCanvas("c2","c2",600,400);
1991 auto hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1992 float px, py;
1993 for (Int_t i = 0; i < 25000; i++) {
1994 gRandom->Rannor(px,py);
1995 hsurf->Fill(px-1,5*py);
1996 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1997 }
1998 hsurf->Draw("SURF");
1999}
2000End_Macro
2001
2002The following example shows a 2D histogram plotted with the option
2003`SURF1`. The option `SURF1` draws a surface plot using the
2004hidden surface removal technique. Combined with the option `SURF1`,
2005the option `Z` allows to display the color palette defined by
2006`gStyle->SetPalette()`.
2007
2008Begin_Macro(source)
2009{
2010 auto c2 = new TCanvas("c2","c2",600,400);
2011 auto hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
2012 float px, py;
2013 for (Int_t i = 0; i < 25000; i++) {
2014 gRandom->Rannor(px,py);
2015 hsurf1->Fill(px-1,5*py);
2016 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
2017 }
2018 hsurf1->Draw("SURF1");
2019}
2020End_Macro
2021
2022The following example shows a 2D histogram plotted with the option
2023`SURF2`. The option `SURF2` draws a surface plot using colors
2024to show the cell contents. Combined with the option `SURF2`, the option
2025`Z` allows to display the color palette defined by
2026`gStyle->SetPalette()`.
2027
2028Begin_Macro(source)
2029{
2030 auto c2 = new TCanvas("c2","c2",600,400);
2031 auto hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2032 float px, py;
2033 for (Int_t i = 0; i < 25000; i++) {
2034 gRandom->Rannor(px,py);
2035 hsurf2->Fill(px-1,5*py);
2036 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2037 }
2038 hsurf2->Draw("SURF2");
2039}
2040End_Macro
2041
2042The following example shows a 2D histogram plotted with the option
2043`SURF3`. The option `SURF3` draws a surface plot using the
2044hidden line removal technique with, in addition, a filled contour view drawn on the
2045top. Combined with the option `SURF3`, the option `Z` allows
2046to display the color palette defined by `gStyle->SetPalette()`.
2047
2048Begin_Macro(source)
2049{
2050 auto c2 = new TCanvas("c2","c2",600,400);
2051 auto hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2052 float px, py;
2053 for (Int_t i = 0; i < 25000; i++) {
2054 gRandom->Rannor(px,py);
2055 hsurf3->Fill(px-1,5*py);
2056 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2057 }
2058 hsurf3->Draw("SURF3");
2059}
2060End_Macro
2061
2062The following example shows a 2D histogram plotted with the option
2063`SURF4`. The option `SURF4` draws a surface using the Gouraud
2064shading technique.
2065
2066Begin_Macro(source)
2067{
2068 auto c2 = new TCanvas("c2","c2",600,400);
2069 auto hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2070 float px, py;
2071 for (Int_t i = 0; i < 25000; i++) {
2072 gRandom->Rannor(px,py);
2073 hsurf4->Fill(px-1,5*py);
2074 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2075 }
2076 hsurf4->SetFillColor(kOrange);
2077 hsurf4->Draw("SURF4");
2078}
2079End_Macro
2080
2081The following example shows a 2D histogram plotted with the option
2082`SURF5 CYL`. Combined with the option `SURF5`, the option
2083`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2084
2085Begin_Macro(source)
2086{
2087 auto c2 = new TCanvas("c2","c2",600,400);
2088 auto hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2089 float px, py;
2090 for (Int_t i = 0; i < 25000; i++) {
2091 gRandom->Rannor(px,py);
2092 hsurf5->Fill(px-1,5*py);
2093 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2094 }
2095 hsurf5->Draw("SURF5 CYL");
2096}
2097End_Macro
2098
2099The following example shows a 2D histogram plotted with the option
2100`SURF7`. The option `SURF7` draws a surface plot using the
2101hidden surfaces removal technique with, in addition, a line contour view drawn on the
2102top. Combined with the option `SURF7`, the option `Z` allows
2103to display the color palette defined by `gStyle->SetPalette()`.
2104
2105Begin_Macro(source)
2106{
2107 auto c2 = new TCanvas("c2","c2",600,400);
2108 auto hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2109 float px, py;
2110 for (Int_t i = 0; i < 25000; i++) {
2111 gRandom->Rannor(px,py);
2112 hsurf7->Fill(px-1,5*py);
2113 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2114 }
2115 hsurf7->Draw("SURF7");
2116}
2117End_Macro
2118
2119As shown in the following example, when a contour plot is painted on top of a
2120surface plot using the option `SAME`, the contours appear in 3D on the
2121surface.
2122
2123Begin_Macro(source)
2124{
2125 auto c20=new TCanvas("c20","c20",600,400);
2126 int NBins = 50;
2127 double d = 2;
2128 auto hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2129 for (int bx = 1; bx <= NBins; ++bx) {
2130 for (int by = 1; by <= NBins; ++by) {
2131 double x = hsc->GetXaxis()->GetBinCenter(bx);
2132 double y = hsc->GetYaxis()->GetBinCenter(by);
2133 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2134 }
2135 }
2136 hsc->Draw("surf2");
2137 hsc->Draw("CONT1 SAME");
2138}
2139End_Macro
2140
2141
2142### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2143
2144
2145Legos and surfaces plots are represented by default in Cartesian coordinates.
2146Combined with any `LEGOn` or `SURFn` options the following
2147options allow to draw a lego or a surface in other coordinates systems.
2148
2149| Option | Description |
2150|----------|-------------------------------------------------------------------|
2151| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2152| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2153| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2154| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2155
2156
2157
2158<b>WARNING:</b> Axis are not drawn with these options.
2159
2160The following example shows the same histogram as a lego plot is the four
2161different coordinates systems.
2162
2163Begin_Macro(source)
2164{
2165 auto c3 = new TCanvas("c3","c3",600,400);
2166 c3->Divide(2,2);
2167 auto hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2168 float px, py;
2169 for (Int_t i = 0; i < 25000; i++) {
2170 gRandom->Rannor(px,py);
2171 hlcc->Fill(px-1,5*py);
2172 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2173 }
2174 hlcc->SetFillColor(kYellow);
2175 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2176 c3->cd(2); auto hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2177 hlpc->SetTitle("Polar coordinates");
2178 c3->cd(3); auto hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2179 hlsc->SetTitle("Spherical coordinates");
2180 c3->cd(4); auto hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2181 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2182}
2183End_Macro
2184
2185The following example shows the same histogram as a surface plot is the four different coordinates systems.
2186
2187Begin_Macro(source)
2188{
2189 auto c4 = new TCanvas("c4","c4",600,400);
2190 c4->Divide(2,2);
2191 auto hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2192 float px, py;
2193 for (Int_t i = 0; i < 25000; i++) {
2194 gRandom->Rannor(px,py);
2195 hscc->Fill(px-1,5*py);
2196 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2197 }
2198 c4->cd(1); hscc->Draw("SURF1 CYL");
2199 c4->cd(2); auto hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2200 hspc->SetTitle("Polar coordinates");
2201 c4->cd(3); auto hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2202 hssc->SetTitle("Spherical coordinates");
2203 c4->cd(4); auto hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2204 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2205}
2206End_Macro
2207
2208
2209### <a name="HP20"></a> Base line for bar-charts and lego plots
2210
2211
2212By default the base line used to draw the boxes for bar-charts and lego plots is
2213the histogram minimum. It is possible to force this base line to be 0, using MIN0 draw
2214option or with the command:
2215
2216 gStyle->SetHistMinimumZero();
2217
2218Begin_Macro(source)
2219{
2220 auto c5 = new TCanvas("c5","c5",700,400);
2221 c5->Divide(2,1);
2222 auto hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2223 auto hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2224 Int_t i;
2225 double x,y;
2226 hz1->SetFillColor(kBlue);
2227 hz2->SetFillColor(kBlue);
2228 for (i=0;i<10000;i++) {
2229 x = gRandom->Gaus(0,1);
2230 y = gRandom->Gaus(0,1);
2231 if (x>0) {
2232 hz1->Fill(x,1);
2233 hz2->Fill(x,y,1);
2234 } else {
2235 hz1->Fill(x,-1);
2236 hz2->Fill(x,y,-2);
2237 }
2238 }
2239 c5->cd(1); hz1->Draw("bar2 min0");
2240 c5->cd(2); hz2->Draw("lego1 min0");
2241}
2242End_Macro
2243
2244This option also works for horizontal plots. The example given in the section
2245["The bar chart option"](#HP100) appears as follow:
2246
2247Begin_Macro(source)
2248{
2249 int i;
2250 const Int_t nx = 8;
2251 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2252 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2253 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2254
2255 auto cbh = new TCanvas("cbh","cbh",400,600);
2256 cbh->SetGrid();
2257
2258 auto h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2259 h1bh->SetFillColor(4);
2260 h1bh->SetBarWidth(0.4);
2261 h1bh->SetBarOffset(0.1);
2262 h1bh->SetStats(0);
2263 h1bh->SetMinimum(-5);
2264 h1bh->SetMaximum(5);
2265
2266 for (i=1; i<=nx; i++) {
2267 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2268 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2269 }
2270
2271 h1bh->Draw("hbar min0");
2272
2273 auto h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2274 h2bh->SetFillColor(38);
2275 h2bh->SetBarWidth(0.4);
2276 h2bh->SetBarOffset(0.5);
2277 h2bh->SetStats(0);
2278 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2279
2280 h2bh->Draw("hbar min0 same");
2281}
2282End_Macro
2283
2284
2285### <a name="HP20a"></a> TH2Poly Drawing
2286
2287
2288The following options are supported:
2289
2290| Option | Description |
2291|----------|-------------------------------------------------------------------|
2292| "SCAT" | Draw a scatter plot (default).|
2293| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2294| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2295| "0" | When used with any COL options, the empty bins are not drawn.|
2296| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2297| "TEXTN" | Draw bin names as text.|
2298| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2299| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2300| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2301| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2302
2303
2304
2305`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2306shapes. The bins are defined as graphs. The following macro is a very simple
2307example showing how to book a TH2Poly and draw it.
2308
2309Begin_Macro(source)
2310{
2311 auto ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2312 auto h2p = new TH2Poly();
2313 h2p->SetName("h2poly_name");
2314 h2p->SetTitle("h2poly_title");
2315 double px1[] = {0, 5, 6};
2316 double py1[] = {0, 0, 5};
2317 double px2[] = {0, -1, -1, 0};
2318 double py2[] = {0, 0, -1, 3};
2319 double px3[] = {4, 3, 0, 1, 2.4};
2320 double py3[] = {4, 3.7, 1, 3.7, 2.5};
2321 h2p->AddBin(3, px1, py1);
2322 h2p->AddBin(4, px2, py2);
2323 h2p->AddBin(5, px3, py3);
2324 h2p->Fill(0.1, 0.01, 3);
2325 h2p->Fill(-0.5, -0.5, 7);
2326 h2p->Fill(-0.7, -0.5, 1);
2327 h2p->Fill(1, 3, 1.5);
2328 double fx[] = {0.1, -0.5, -0.7, 1};
2329 double fy[] = {0.01, -0.5, -0.5, 3};
2330 double fw[] = {3, 1, 1, 1.5};
2331 h2p->FillN(4, fx, fy, fw);
2332 h2p->Draw("col");
2333}
2334End_Macro
2335
2336Rectangular bins are a frequent case. The special version of
2337the `AddBin` method allows to define them more easily like
2338shown in the following example (th2polyBoxes.C).
2339
2340Begin_Macro(source)
2341../../../tutorials/hist/th2polyBoxes.C
2342End_Macro
2343
2344One `TH2Poly` bin can be a list of polygons. Such bins are defined
2345by calling `AddBin` with a `TMultiGraph`. The following example
2346shows a such case:
2347
2348Begin_Macro(source)
2349{
2350 auto ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2351
2352 Int_t i, bin;
2353 const Int_t nx = 48;
2354 const char *states [nx] = {
2355 "alabama", "arizona", "arkansas", "california",
2356 "colorado", "connecticut", "delaware", "florida",
2357 "georgia", "idaho", "illinois", "indiana",
2358 "iowa", "kansas", "kentucky", "louisiana",
2359 "maine", "maryland", "massachusetts", "michigan",
2360 "minnesota", "mississippi", "missouri", "montana",
2361 "nebraska", "nevada", "new_hampshire", "new_jersey",
2362 "new_mexico", "new_york", "north_carolina", "north_dakota",
2363 "ohio", "oklahoma", "oregon", "pennsylvania",
2364 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2365 "texas", "utah", "vermont", "virginia",
2366 "washington", "west_virginia", "wisconsin", "wyoming"
2367 };
2368 Double_t pop[nx] = {
2369 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2370 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2371 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2372 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2373 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2374 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2375 };
2376
2377 Double_t lon1 = -130;
2378 Double_t lon2 = -65;
2379 Double_t lat1 = 24;
2380 Double_t lat2 = 50;
2381 auto p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2382
2383 TFile::SetCacheFileDir(".");
2384 auto f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2385
2386 TMultiGraph *mg;
2387 TKey *key;
2388 TIter nextkey(gDirectory->GetListOfKeys());
2389 while ((key = (TKey*)nextkey())) {
2390 TObject *obj = key->ReadObj();
2391 if (obj->InheritsFrom("TMultiGraph")) {
2392 mg = (TMultiGraph*)obj;
2393 bin = p->AddBin(mg);
2394 }
2395 }
2396
2397 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2398
2399 gStyle->SetOptStat(11);
2400 p->Draw("COLZ L");
2401}
2402End_Macro
2403
2404`TH2Poly` histograms can also be plotted using the GL interface using
2405the option "GLLEGO".
2406
2407\since **ROOT version 6.09/01**
2408
2409In some cases it can be useful to not draw the empty bins. the option "0"
2410combined with the option "COL" et COLZ allows to do that.
2411
2412Begin_Macro(source)
2413{
2414 auto chc = new TCanvas("chc","chc",600,400);
2415
2416 auto hc = new TH2Poly();
2417 hc->Honeycomb(0,0,.1,25,25);
2418 hc->SetName("hc");
2419 hc->SetTitle("Option COLZ 0");
2420 TRandom ran;
2421 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2422 hc->Draw("colz 0");
2423}
2424End_Macro
2425
2426### <a name="HP21"></a> The SPEC option
2427
2428
2429This option allows to use the `TSpectrum2Painter` tools. See the full
2430documentation in `TSpectrum2Painter::PaintSpectrum`.
2431
2432
2433### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2434
2435
2436When this option is specified, a color palette with an axis indicating the value
2437of the corresponding color is drawn on the right side of the picture. In case,
2438not enough space is left, one can increase the size of the right margin by
2439calling `TPad::SetRightMargin()`. The attributes used to display the
2440palette axis values are taken from the Z axis of the object. For example, to
2441set the labels size on the palette axis do:
2442
2443 hist->GetZaxis()->SetLabelSize().
2444
2445<b>WARNING:</b> The palette axis is always drawn vertically.
2446
2447
2448### <a name="HP23"></a> Setting the color palette
2449
2450
2451To change the color palette `TStyle::SetPalette` should be used, eg:
2452
2453 gStyle->SetPalette(ncolors,colors);
2454
2455For example the option `COL` draws a 2D histogram with cells
2456represented by a box filled with a color index which is a function
2457of the cell content.
2458If the cell content is N, the color index used will be the color number
2459in `colors[N]`, etc. If the maximum cell content is greater than
2460`ncolors`, all cell contents are scaled to `ncolors`.
2461
2462If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2463defined. This palette is recommended for pads, labels ...
2464
2465`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2466Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2467palette.
2468
2469Other pre-defined palettes with 255 colors are available when `colors == 0`.
2470The following value of `ncolors` give access to:
2471
2472
2473 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2474 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2475 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2476 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2477 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2478 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2479
2480
2481If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2482
2483The default palette defines:
2484
2485- index 0 to 9 : shades of grey
2486- index 10 to 19 : shades of brown
2487- index 20 to 29 : shades of blue
2488- index 30 to 39 : shades of red
2489- index 40 to 49 : basic colors
2490
2491The color numbers specified in the palette can be viewed by selecting
2492the item `colors` in the `VIEW` menu of the canvas tool bar.
2493The red, green, and blue components of a color can be changed thanks to
2494`TColor::SetRGB()`.
2495
2496\since **ROOT version 6.19/01**
2497
2498As default labels and ticks are drawn by `TGAxis` at equidistant (lin or log)
2499points as controlled by SetNdivisions.
2500If option "CJUST" is given labels and ticks are justified at the
2501color boundaries defined by the contour levels.
2502For more details see `TPaletteAxis`
2503
2504### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2505
2506
2507Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2508histogram. One must create a graphical cut (mouse or C++) and specify the name
2509of the cut between `[]` in the `Draw()` option.
2510For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2511
2512 myhist->Draw("surf1 [cutg]");
2513
2514To invert the cut, it is enough to put a `-` in front of its name:
2515
2516 myhist->Draw("surf1 [-cutg]");
2517
2518It is possible to apply several cuts (`,` means logical AND):
2519
2520 myhist->Draw("surf1 [cutg1,cutg2]");
2521
2522Begin_Macro(source)
2523../../../tutorials/fit/fit2a.C
2524End_Macro
2525
2526### <a name="HP25"></a> Drawing options for 3D histograms
2527
2528
2529| Option | Description |
2530|----------|-------------------------------------------------------------------|
2531| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`|
2532| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2533| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2534| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2535| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2536| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2537
2538Note that instead of `BOX` one can also use `LEGO`.
2539
2540By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2541
2542The following example shows a 3D histogram plotted as a scatter plot.
2543
2544Begin_Macro(source)
2545{
2546 auto c06 = new TCanvas("c06","c06",600,400);
2547 gStyle->SetOptStat(kFALSE);
2548 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2549 double x, y, z;
2550 for (Int_t i=0;i<10000;i++) {
2551 gRandom->Rannor(x, y);
2552 z = x*x + y*y;
2553 h3scat->Fill(x,y,z);
2554 }
2555 h3scat->Draw();
2556}
2557End_Macro
2558
2559The following example shows a 3D histogram plotted with the option `BOX`.
2560
2561Begin_Macro(source)
2562{
2563 auto c16 = new TCanvas("c16","c16",600,400);
2564 gStyle->SetOptStat(kFALSE);
2565 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2566 double x, y, z;
2567 for (Int_t i=0;i<10000;i++) {
2568 gRandom->Rannor(x, y);
2569 z = x*x + y*y;
2570 h3box->Fill(x,y,z);
2571 }
2572 h3box->Draw("BOX");
2573}
2574End_Macro
2575
2576The following example shows a 3D histogram plotted with the option `BOX1`.
2577
2578Begin_Macro(source)
2579{
2580 auto c36 = new TCanvas("c36","c36",600,400);
2581 gStyle->SetOptStat(kFALSE);
2582 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2583 double x, y, z;
2584 for (Int_t i=0;i<10000;i++) {
2585 gRandom->Rannor(x, y);
2586 z = abs(sin(x)/x + cos(y)*y);
2587 h3box->Fill(x,y,z);
2588 }
2589 h3box->SetFillColor(9);
2590 h3box->Draw("BOX1");
2591}
2592End_Macro
2593
2594The following example shows a 3D histogram plotted with the option `BOX2`.
2595
2596Begin_Macro(source)
2597{
2598 auto c56 = new TCanvas("c56","c56",600,400);
2599 gStyle->SetOptStat(kFALSE);
2600 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2601 double x, y, z;
2602 for (Int_t i=0;i<10000;i++) {
2603 gRandom->Rannor(x, y);
2604 z = abs(sin(x)/x + cos(y)*y);
2605 h3box->Fill(x,y,z);
2606 }
2607 h3box->Draw("BOX2 Z");
2608}
2609End_Macro
2610
2611The following example shows a 3D histogram plotted with the option `BOX3`.
2612
2613Begin_Macro(source)
2614{
2615 auto c46 = new TCanvas("c46","c46",600,400);
2616 c46->SetFillColor(38);
2617 gStyle->SetOptStat(kFALSE);
2618 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2619 double x, y, z;
2620 for (Int_t i=0;i<10000;i++) {
2621 gRandom->Rannor(x, y);
2622 z = x*x + y*y;
2623 h3box->Fill(x,y,z);
2624 }
2625 h3box->Draw("BOX3");
2626}
2627End_Macro
2628
2629For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2630to the absolute value of the bin content. The bins with a negative content are
2631drawn with a X on each face of the box as shown in the following example:
2632
2633Begin_Macro(source)
2634{
2635 auto c = new TCanvas("c","c",600,400);
2636 gStyle->SetOptStat(kFALSE);
2637 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2638 h3box->Fill(0., 2., 2., 10.);
2639 h3box->Fill(2., 2., 2., 5.);
2640 h3box->Fill(2., 2., .5, 2.);
2641 h3box->Fill(2., 2., 3., -1.);
2642 h3box->Fill(3., 2., 2., -10.);
2643 h3box->SetFillColor(8);
2644 h3box->Draw("box1");
2645}
2646End_Macro
2647
2648The following example shows a 3D histogram plotted with the option `ISO`.
2649
2650Begin_Macro(source)
2651{
2652 auto c26 = new TCanvas("c26","c26",600,400);
2653 gStyle->SetOptStat(kFALSE);
2654 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2655 double x, y, z;
2656 for (Int_t i=0;i<10000;i++) {
2657 gRandom->Rannor(x, y);
2658 z = x*x + y*y;
2659 h3iso->Fill(x,y,z);
2660 }
2661 h3iso->SetFillColor(kCyan);
2662 h3iso->Draw("ISO");
2663}
2664End_Macro
2665
2666
2667### <a name="HP26"></a> Drawing option for histograms' stacks
2668
2669
2670Stacks of histograms are managed with the `THStack`. A `THStack`
2671is a collection of `TH1` (or derived) objects. For painting only the
2672`THStack` containing `TH1` only or
2673`THStack` containing `TH2` only will be considered.
2674
2675By default, histograms are shown stacked:
2676
26771. The first histogram is paint.
26782. The the sum of the first and second, etc...
2679
2680If the option `NOSTACK` is specified, the histograms are all paint in
2681the same pad as if the option `SAME` had been specified. This allows to
2682compute X and Y scales common to all the histograms, like
2683`TMultiGraph` does for graphs.
2684
2685If the option `PADS` is specified, the current pad/canvas is
2686subdivided into a number of pads equal to the number of histograms and each
2687histogram is paint into a separate pad.
2688
2689The following example shows various types of stacks (hstack.C).
2690
2691Begin_Macro(source)
2692../../../tutorials/hist/hstack.C
2693End_Macro
2694
2695The option `nostackb` allows to draw the histograms next to each
2696other as bar charts:
2697
2698Begin_Macro(source)
2699{
2700 auto cst0 = new TCanvas("cst0","cst0",600,400);
2701 auto hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2702
2703 auto h1 = new TH1F("h1","h1",10,-4,4);
2704 h1->FillRandom("gaus",20000);
2705 h1->SetFillColor(kRed);
2706 hs->Add(h1);
2707
2708 auto h2 = new TH1F("h2","h2",10,-4,4);
2709 h2->FillRandom("gaus",15000);
2710 h2->SetFillColor(kBlue);
2711 hs->Add(h2);
2712
2713 auto h3 = new TH1F("h3","h3",10,-4,4);
2714 h3->FillRandom("gaus",10000);
2715 h3->SetFillColor(kGreen);
2716 hs->Add(h3);
2717
2718 hs->Draw("nostackb");
2719 hs->GetXaxis()->SetNdivisions(-10);
2720 cst0->SetGridx();
2721}
2722End_Macro
2723
2724If at least one of the histograms in the stack has errors, the whole stack is
2725visualized by default with error bars. To visualize it without errors the
2726option `HIST` should be used.
2727
2728Begin_Macro(source)
2729{
2730 auto cst1 = new TCanvas("cst1","cst1",700,400);
2731 cst1->Divide(2,1);
2732
2733 auto hst11 = new TH1F("hst11", "", 20, -10, 10);
2734 hst11->Sumw2();
2735 hst11->FillRandom("gaus", 1000);
2736 hst11->SetFillColor(kViolet);
2737 hst11->SetLineColor(kViolet);
2738
2739 auto hst12 = new TH1F("hst12", "", 20, -10, 10);
2740 hst12->FillRandom("gaus", 500);
2741 hst12->SetFillColor(kBlue);
2742 hst12->SetLineColor(kBlue);
2743
2744 THStack st1("st1", "st1");
2745 st1.Add(hst11);
2746 st1.Add(hst12);
2747
2748 cst1->cd(1); st1.Draw();
2749 cst1->cd(2); st1.Draw("hist");
2750}
2751End_Macro
2752
2753### <a name="HP27"></a> Drawing of 3D implicit functions
2754
2755
27563D implicit functions (`TF3`) can be drawn as iso-surfaces.
2757The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2758In the following example the options "FB" and "BB" suppress the
2759"Front Box" and "Back Box" around the plot.
2760
2761Begin_Macro(source)
2762{
2763 auto c2 = new TCanvas("c2","c2",600,400);
2764 auto f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2765 f3->SetClippingBoxOn(0,0,0);
2766 f3->SetFillColor(30);
2767 f3->SetLineColor(15);
2768 f3->Draw("FBBB");
2769}
2770End_Macro
2771
2772
2773### <a name="HP28"></a> Associated functions drawing
2774
2775
2776An associated function is created by `TH1::Fit`. More than on fitted
2777function can be associated with one histogram (see `TH1::Fit`).
2778
2779A `TF1` object `f1` can be added to the list of associated
2780functions of an histogram `h` without calling `TH1::Fit`
2781simply doing:
2782
2783 h->GetListOfFunctions()->Add(f1);
2784
2785or
2786
2787 h->GetListOfFunctions()->Add(f1,someoption);
2788
2789To retrieve a function by name from this list, do:
2790
2791 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2792
2793or
2794
2795 TF1 *f1 = h->GetFunction(name);
2796
2797Associated functions are automatically painted when an histogram is drawn.
2798To avoid the painting of the associated functions the option `HIST`
2799should be added to the list of the options used to paint the histogram.
2800
2801
2802### <a name="HP29"></a> Drawing using OpenGL
2803
2804
2805The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2806graphics library. The plotting options start with `GL` keyword.
2807In addition, in order to inform canvases that OpenGL should be used to render
28083D representations, the following option should be set:
2809
2810 gStyle->SetCanvasPreferGL(true);
2811
2812
2813#### <a name="HP29a"></a> General information: plot types and supported options
2814
2815The following types of plots are provided:
2816
2817For lego plots the supported options are:
2818
2819| Option | Description |
2820|----------|-------------------------------------------------------------------|
2821| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2822| "GLLEGO2"| Bins with color levels.|
2823| "GLLEGO3"| Cylindrical bars.|
2824
2825
2826
2827Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2828In polar only Z axis can be logarithmic, in cylindrical only Y.
2829
2830For surface plots (`TF2` and `TH2`) the supported options are:
2831
2832| Option | Description |
2833|-----------|------------------------------------------------------------------|
2834| "GLSURF" | Draw a surface.|
2835| "GLSURF1" | Surface with color levels|
2836| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2837| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2838| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2839
2840
2841
2842The surface painting in cartesian coordinates supports logarithmic scales along
2843X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2844in cylindrical coordinates only the Y axis.
2845
2846Additional options to SURF and LEGO - Coordinate systems:
2847
2848| Option | Description |
2849|----------|-------------------------------------------------------------------|
2850| " " | Default, cartesian coordinates system.|
2851| "POL" | Polar coordinates system.|
2852| "CYL" | Cylindrical coordinates system.|
2853| "SPH" | Spherical coordinates system.|
2854
2855
2856
2857#### <a name="HP290"></a> TH3 as color boxes
2858
2859The supported option is:
2860
2861| Option | Description |
2862|----------|-------------------------------------------------------------------|
2863| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2864
2865
2866
2867#### <a name="HP29b"></a> TH3 as boxes (spheres)
2868
2869The supported options are:
2870
2871| Option | Description |
2872|----------|-------------------------------------------------------------------|
2873| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2874| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2875
2876
2877
2878#### <a name="HP29c"></a> TH3 as iso-surface(s)
2879
2880The supported option is:
2881
2882| Option | Description |
2883|----------|-------------------------------------------------------------------|
2884| "GLISO" | TH3 is drawn using iso-surfaces.|
2885
2886
2887
2888#### <a name="HP29d"></a> TF3 (implicit function)
2889
2890The supported option is:
2891
2892| Option | Description |
2893|----------|-------------------------------------------------------------------|
2894| "GL" | Draw a TF3.|
2895
2896
2897
2898#### <a name="HP29e"></a> Parametric surfaces
2899
2900`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2901equations and visualize the surface.
2902
2903#### <a name="HP29f"></a> Interaction with the plots
2904
2905All the interactions are implemented via standard methods
2906`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2907interactions with the OpenGL plots are possible only when the mouse cursor is
2908in the plot's area (the plot's area is the part of a the pad occupied by
2909gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2910pad interaction is performed.
2911
2912#### <a name="HP29g"></a> Selectable parts
2913
2914Different parts of the plot can be selected:
2915
2916- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2917 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2918 if the dynamic slicing is not supported.
2919- The plot itself:
2920 On surfaces, the selected surface is outlined in red. (TF3 and
2921 ISO are not outlined). On lego plots, the selected bin is
2922 highlighted. The bin number and content are displayed in pad's
2923 status bar. In box plots, the box or sphere is highlighted and
2924 the bin info is displayed in pad's status bar.
2925
2926
2927#### <a name="HP29h"></a> Rotation and zooming
2928
2929
2930- Rotation:
2931 When the plot is selected, it can be rotated by pressing and
2932 holding the left mouse button and move the cursor.
2933- Zoom/Unzoom:
2934 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2935
2936
2937#### <a name="HP29i"></a> Panning
2938
2939The selected plot can be moved in a pad's area by pressing and
2940holding the left mouse button and the shift key.
2941
2942#### <a name="HP29j"></a> Box cut
2943
2944Surface, iso, box, TF3 and parametric painters support box cut by
2945pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2946area. That will display a transparent box, cutting away part of the
2947surface (or boxes) in order to show internal part of plot. This box
2948can be moved inside the plot's area (the full size of the box is
2949equal to the plot's surrounding box) by selecting one of the box
2950cut axes and pressing the left mouse button to move it.
2951
2952#### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2953
2954Currently, all gl-plots support some form of slicing. When back plane
2955is selected (and if it's highlighted in green) you can press and hold
2956left mouse button and shift key and move this back plane inside
2957plot's area, creating the slice. During this "slicing" plot becomes
2958semi-transparent. To remove all slices (and projected curves for
2959surfaces) double click with left mouse button in a plot's area.
2960
2961#### <a name="HP29l"></a> Surface with option "GLSURF"
2962
2963The surface profile is displayed on the slicing plane.
2964The profile projection is drawn on the back plane
2965by pressing `'p'` or `'P'` key.
2966
2967#### <a name="HP29m"></a> TF3
2968
2969The contour plot is drawn on the slicing plane. For TF3 the color
2970scheme can be changed by pressing 's' or 'S'.
2971
2972#### <a name="HP29n"></a> Box
2973
2974The contour plot corresponding to slice plane position is drawn in real time.
2975
2976#### <a name="HP29o"></a> Iso
2977
2978Slicing is similar to "GLBOX" option.
2979
2980#### <a name="HP29p"></a> Parametric plot
2981
2982No slicing. Additional keys: 's' or 'S' to change color scheme -
2983about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2984increase number of polygons ('l' for "level" of details), 'w' or 'W'
2985to show outlines ('w' for "wireframe").
2986
2987#### <a name="HP30"></a> Highlight mode for histogram
2988
2989\since **ROOT version 6.15/01**
2990
2991\image html hlHisto3_top.gif "Highlight mode"
2992
2993Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
2994highlight mode is on, mouse movement over the bin will be represented
2995graphically. Bin will be highlighted as "bin box" (presented by box
2996object). Moreover, any highlight (change of bin) emits signal
2997`TCanvas::Highlighted()` which allows the user to react and call their own
2998function. For a better understanding see also the tutorials
2999`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
3000
3001Highlight mode is switched on/off by `TH1::SetHighlight()` function
3002or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
3003whether the highlight mode enabled or disabled, default it is disabled.
3004
3005~~~ {.cpp}
3006 root [0] .x $ROOTSYS/tutorials/hsimple.C
3007 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
3008 root [2] hpx->IsHighlight()
3009 (bool) true
3010~~~
3011
3012\image html hlsimple_nofun.gif "Highlight mode for histogram"
3013
3014#### <a name="HP30a"></a> Highlight mode and user function
3015
3016The user can use (connect) `TCanvas::Highlighted()` signal, which is always
3017emitted if there is a highlight bin and call user function via signal
3018and slot communication mechanism. `TCanvas::Highlighted()` is similar
3019`TCanvas::Picked()`
3020
3021- when selected object (histogram as a whole) is different from previous
3022then emit `Picked()` signal
3023- when selected (highlighted) bin from histogram is different from previous
3024then emit `Highlighted()` signal
3025
3026Any user function (or functions) has to be defined
3027`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3028In example (see below) has name `PrintInfo()`. All parameters of user
3029function are taken from
3030
3031 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3032
3033- `pad` is pointer to pad with highlighted histogram
3034- `obj` is pointer to highlighted histogram
3035- `x` is highlighted x bin for 1D histogram
3036- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3037
3038Example how to create a connection from any `TCanvas` object to a user
3039`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3040
3041 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3042 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3043
3044or use non-static "simplified" function
3045`TCanvas::HighlightConnect(const char *slot)`
3046
3047 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3048
3049NOTE the signal and slot string must have a form
3050"(TVirtualPad*,TObject*,Int_t,Int_t)"
3051
3052 root [0] .x $ROOTSYS/tutorials/hsimple.C
3053 root [1] hpx->SetHighlight(kTRUE)
3054 root [2] .x hlprint.C
3055
3056file `hlprint.C`
3057~~~ {.cpp}
3058void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3059{
3060 auto h = (TH1F *)obj;
3061 if (!h->IsHighlight()) // after highlight disabled
3062 h->SetTitle("highlight disable");
3063 else
3064 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3065 h->GetBinCenter(x), h->GetBinContent(x)));
3066 pad->Update();
3067}
3068
3069void hlprint()
3070{
3071 if (!gPad) return;
3072 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3073}
3074~~~
3075
3076\image html hlsimple.gif "Highlight mode and simple user function"
3077
3078For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3079
3080*/
3081
3083
3086
3087const Int_t kNMAX = 2000;
3088
3089const Int_t kMAXCONTOUR = 104;
3091
3092static TBox *gXHighlightBox = 0; // highlight X box
3093static TBox *gYHighlightBox = 0; // highlight Y box
3094
3116
3118
3119////////////////////////////////////////////////////////////////////////////////
3120/// Default constructor.
3121
3123{
3124
3125 fH = 0;
3126 fXaxis = 0;
3127 fYaxis = 0;
3128 fZaxis = 0;
3129 fFunctions = 0;
3130 fXbuf = 0;
3131 fYbuf = 0;
3132 fNcuts = 0;
3133 fStack = 0;
3134 fLego = 0;
3135 fPie = 0;
3136 fGraph2DPainter = 0;
3137 fShowProjection = 0;
3138 fShowOption = "";
3139 for (int i=0; i<kMaxCuts; i++) {
3140 fCuts[i] = 0;
3141 fCutsOpt[i] = 0;
3142 }
3143 fXHighlightBin = -1;
3144 fYHighlightBin = -1;
3145 fCurrentF3 = nullptr;
3146
3147 gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3148 gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3149 gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3150 gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3151 gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3152 gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3153 gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3154 gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3155 gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3156 gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3157 gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3158 gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3159 gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3160 gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3161 gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3162 gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3163 gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3164 gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3165 gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3166 gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3167 gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3168}
3169
3170////////////////////////////////////////////////////////////////////////////////
3171/// Default destructor.
3172
3174{
3175 if (fPie) delete fPie;
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Compute the distance from the point px,py to a line.
3180///
3181/// Compute the closest distance of approach from point px,py to elements of
3182/// an histogram. The distance is computed in pixels units.
3183///
3184/// Algorithm: Currently, this simple model computes the distance from the mouse
3185/// to the histogram contour only.
3186
3188{
3189
3190 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3191
3192 const Int_t big = 9999;
3193 const Int_t kMaxDiff = 7;
3194
3195 if (fPie) return fPie->DistancetoPrimitive(px, py);
3196
3197 Double_t x = gPad->AbsPixeltoX(px);
3198 Double_t x1 = gPad->AbsPixeltoX(px+1);
3199
3200 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3201 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3202 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3203 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3204 Int_t curdist = big;
3205 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3206 Bool_t dsame;
3207 TObject *PadPointer = gPad->GetPadPointer();
3208 if (!PadPointer) return 0;
3209 TString doption = PadPointer->GetDrawOption();
3210 Double_t factor = 1;
3211 if (fH->GetNormFactor() != 0) {
3212 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3213 }
3214 // return if point is not in the histogram area
3215
3216 // If a 3D view exists, check distance to axis
3217 TView *view = gPad->GetView();
3218 Int_t d1,d2,d3;
3219 if (view && Hoption.Contour != 14) {
3220 Double_t ratio;
3221 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3222 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3223 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3224 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3225 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3226 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3227 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3228 goto FUNCTIONS;
3229 }
3230 // check if point is close to an axis
3231 doption.ToLower();
3232 dsame = kFALSE;
3233 if (doption.Contains("same")) dsame = kTRUE;
3234
3235 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3236 if (doption.Contains("y+")) {
3237 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3238 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3239 if (!dsame) {
3240 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3241 else gPad->SetSelected(fXaxis);
3242 return 0;
3243 }
3244 }
3245 } else {
3246 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3247 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3248 if (!dsame) {
3249 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3250 else gPad->SetSelected(fXaxis);
3251 return 0;
3252 }
3253 }
3254 }
3255
3256 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3257 if (doption.Contains("x+")) {
3258 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3259 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3260 if (!dsame) {
3261 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3262 else gPad->SetSelected(fYaxis);
3263 return 0;
3264 }
3265 }
3266 } else {
3267 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3268 if (yxaxis < puymin) yxaxis = puymin;
3269 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3270 if (!dsame) {
3271 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3272 else gPad->SetSelected(fYaxis);
3273 return 0;
3274 }
3275 }
3276 }
3277
3278 if (fH->IsHighlight()) { // only if highlight is enable
3279 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3280 HighlightBin(px, py);
3281 }
3282
3283 // if object is 2D or 3D return this object
3284 if (fH->GetDimension() == 2) {
3285 if (fH->InheritsFrom(TH2Poly::Class())) {
3286 TH2Poly *th2 = (TH2Poly*)fH;
3288 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3289 Double_t pxu = gPad->AbsPixeltoX(px);
3290 Double_t pyu = gPad->AbsPixeltoY(py);
3291 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3292 curdist = big;
3293 goto FUNCTIONS;
3294 } else {
3295 Int_t bin = th2->FindBin(pxu, pyu);
3296 if (bin>0) curdist = 1;
3297 else curdist = big;
3298 goto FUNCTIONS;
3299 }
3300 }
3301 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3302 if ( px > puxmin + delta2
3303 && px < puxmax - delta2
3304 && py > puymax + delta2
3305 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3306 }
3307
3308 // point is inside histogram area. Find channel number
3309 if (gPad->IsVertical()) {
3310 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3311 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3312 Double_t binval = factor*fH->GetBinContent(bin);
3313 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3314 if (binval == 0 && pybin < puymin) pybin = 10000;
3315 // special case if more than one bin for the pixel
3316 if (binsup-bin>1) {
3317 Double_t binvalmin, binvalmax;
3318 binvalmin=binval;
3319 binvalmax=binval;
3320 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3321 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3322 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3323 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3324 }
3325 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3326 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3327 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3328 }
3329 if (bin != binsup) { // Mouse on bin border
3330 Double_t binsupval = factor*fH->GetBinContent(binsup);
3331 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3332 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3333 }
3334 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3335 } else {
3336 Double_t y = gPad->AbsPixeltoY(py);
3337 Double_t y1 = gPad->AbsPixeltoY(py+1);
3338 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3339 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3340 Double_t binval = factor*fH->GetBinContent(bin);
3341 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3342 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3343 // special case if more than one bin for the pixel
3344 if (binsup-bin>1) {
3345 Double_t binvalmin, binvalmax;
3346 binvalmin=binval;
3347 binvalmax=binval;
3348 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3349 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3350 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3351 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3352 }
3353 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3354 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3355 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3356 }
3357 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3358 }
3359 // Loop on the list of associated functions and user objects
3360FUNCTIONS:
3361 TObject *f;
3362 TIter next(fFunctions);
3363 while ((f = (TObject*) next())) {
3364 Int_t dist;
3365 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3366 else dist = f->DistancetoPrimitive(px,py);
3367 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3368 }
3369 return curdist;
3370}
3371
3372////////////////////////////////////////////////////////////////////////////////
3373/// Display a panel with all histogram drawing options.
3374
3376{
3377
3378 gCurrentHist = fH;
3379 if (!gPad) {
3380 Error("DrawPanel", "need to draw histogram first");
3381 return;
3382 }
3384 editor->Show();
3385 gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3386 (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3387}
3388
3389////////////////////////////////////////////////////////////////////////////////
3390/// Execute the actions corresponding to `event`.
3391///
3392/// This function is called when a histogram is clicked with the locator at
3393/// the pixel position px,py.
3394
3396{
3397
3398 if (!gPad) return;
3399
3400 static Int_t bin, px1, py1, px2, py2, pyold;
3401 static TBox *zoombox;
3402 Double_t zbx1,zbx2,zby1,zby2;
3403
3404 Int_t bin1, bin2;
3405 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3406 Bool_t opaque = gPad->OpaqueMoving();
3407
3408 if (!gPad->IsEditable()) return;
3409
3410 if (fPie) {
3411 fPie->ExecuteEvent(event, px, py);
3412 return;
3413 }
3414 // come here if we have a lego/surface in the pad
3415 TView *view = gPad->GetView();
3416
3417 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3418 view->ExecuteRotateView(event, px, py);
3419 return;
3420 }
3421
3422 TAxis *xaxis = fH->GetXaxis();
3423 TAxis *yaxis = fH->GetYaxis();
3424 Int_t dimension = fH->GetDimension();
3425
3426 // In case of option SAME the axis must be the ones of the first drawn histogram
3427 TString IsSame = fH->GetDrawOption();
3428 IsSame.ToLower();
3429 if (IsSame.Index("same")>=0) {
3430 TH1 *h1;
3431 TIter next(gPad->GetListOfPrimitives());
3432 while ((h1 = (TH1 *)next())) {
3433 if (!h1->InheritsFrom(TH1::Class())) continue;
3434 xaxis = h1->GetXaxis();
3435 yaxis = h1->GetYaxis();
3436 break;
3437 }
3438 }
3439
3440 Double_t factor = 1;
3441 if (fH->GetNormFactor() != 0) {
3442 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3443 }
3444
3445 switch (event) {
3446
3447 case kButton1Down:
3448
3449 if (!opaque) gVirtualX->SetLineColor(-1);
3450 fH->TAttLine::Modify();
3451
3452 if (opaque && dimension ==2) {
3453 zbx1 = gPad->AbsPixeltoX(px);
3454 zbx2 = gPad->AbsPixeltoX(px);
3455 zby1 = gPad->AbsPixeltoY(py);
3456 zby2 = gPad->AbsPixeltoY(py);
3457 px1 = px;
3458 py1 = py;
3459 if (gPad->GetLogx()) {
3460 zbx1 = TMath::Power(10,zbx1);
3461 zbx2 = TMath::Power(10,zbx2);
3462 }
3463 if (gPad->GetLogy()) {
3464 zby1 = TMath::Power(10,zby1);
3465 zby2 = TMath::Power(10,zby2);
3466 }
3467 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3468 Int_t ci = TColor::GetColor("#7d7dff");
3469 TColor *zoomcolor = gROOT->GetColor(ci);
3470 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3471 else zoomcolor->SetAlpha(0.5);
3472 zoombox->SetFillColor(ci);
3473 zoombox->Draw();
3474 gPad->Modified();
3475 gPad->Update();
3476 }
3477 // No break !!!
3478
3479 case kMouseMotion:
3480
3481 if (fShowProjection) {ShowProjection3(px,py); break;}
3482
3483 gPad->SetCursor(kPointer);
3484 if (dimension ==1) {
3485 if (Hoption.Bar) {
3486 baroffset = fH->GetBarOffset();
3487 barwidth = fH->GetBarWidth();
3488 } else {
3489 baroffset = 0;
3490 barwidth = 1;
3491 }
3492 x = gPad->AbsPixeltoX(px);
3493 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3494 binwidth = fXaxis->GetBinWidth(bin);
3495 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3496 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3497 ylow = gPad->GetUymin();
3498 px1 = gPad->XtoAbsPixel(xlow);
3499 px2 = gPad->XtoAbsPixel(xup);
3500 py1 = gPad->YtoAbsPixel(ylow);
3501 py2 = py;
3502 pyold = py;
3503 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3504 }
3505
3506 break;
3507
3508 case kButton1Motion:
3509
3510 if (dimension ==1) {
3511 if (gROOT->GetEditHistograms()) {
3512 if (!opaque) {
3513 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3514 py2 += py - pyold;
3515 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3516 pyold = py;
3517 } else {
3518 py2 += py - pyold;
3519 pyold = py;
3520 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3521 fH->SetBinContent(bin,binval);
3522 gPad->Modified(kTRUE);
3523 }
3524 }
3525 }
3526
3527 if (opaque && dimension ==2) {
3528 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3529 zbx2 = gPad->AbsPixeltoX(px);
3530 zby2 = gPad->AbsPixeltoY(py);
3531 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3532 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3533 zoombox->SetX2(zbx2);
3534 zoombox->SetY2(zby2);
3535 gPad->Modified();
3536 gPad->Update();
3537 }
3538 }
3539
3540 break;
3541
3542 case kWheelUp:
3543
3544 if (dimension ==2) {
3545 bin1 = xaxis->GetFirst()+1;
3546 bin2 = xaxis->GetLast()-1;
3547 bin1 = TMath::Max(bin1, 1);
3548 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3549 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3550 bin1 = yaxis->GetFirst()+1;
3551 bin2 = yaxis->GetLast()-1;
3552 bin1 = TMath::Max(bin1, 1);
3553 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3554 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3555 }
3556 gPad->Modified();
3557 gPad->Update();
3558
3559 break;
3560
3561 case kWheelDown:
3562
3563 if (dimension == 2) {
3564 bin1 = xaxis->GetFirst()-1;
3565 bin2 = xaxis->GetLast()+1;
3566 bin1 = TMath::Max(bin1, 1);
3567 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3568 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3569 bin1 = yaxis->GetFirst()-1;
3570 bin2 = yaxis->GetLast()+1;
3571 bin1 = TMath::Max(bin1, 1);
3572 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3573 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3574 }
3575 gPad->Modified();
3576 gPad->Update();
3577
3578 break;
3579
3580 case kButton1Up:
3581 if (dimension ==1) {
3582 if (gROOT->GetEditHistograms()) {
3583 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3584 fH->SetBinContent(bin,binval);
3585 PaintInit(); // recalculate Hparam structure and recalculate range
3586 }
3587
3588 // might resize pad pixmap so should be called before any paint routine
3590 }
3591 if (opaque && dimension ==2) {
3592 if (zoombox) {
3593 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3594 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3595 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3596 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3597 x1 = TMath::Max(x1,xaxis->GetXmin());
3598 x2 = TMath::Min(x2,xaxis->GetXmax());
3599 y1 = TMath::Max(y1,yaxis->GetXmin());
3600 y2 = TMath::Min(y2,yaxis->GetXmax());
3601 if (x1<x2 && y1<y2) {
3602 xaxis->SetRangeUser(x1, x2);
3603 yaxis->SetRangeUser(y1, y2);
3604 }
3605 zoombox->Delete();
3606 zoombox = 0;
3607 }
3608 }
3609 gPad->Modified(kTRUE);
3610 if (opaque) gVirtualX->SetLineColor(-1);
3611
3612 break;
3613
3614 case kButton1Locate:
3615
3616 ExecuteEvent(kButton1Down, px, py);
3617
3618 while (1) {
3619 px = py = 0;
3620 event = gVirtualX->RequestLocator(1, 1, px, py);
3621
3623
3624 if (event != -1) { // button is released
3625 ExecuteEvent(kButton1Up, px, py);
3626 return;
3627 }
3628 }
3629 }
3630}
3631
3632////////////////////////////////////////////////////////////////////////////////
3633/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3634
3636{
3637
3638
3639
3640 // Check if fH contains a TGraphDelaunay2D
3641 TList *hl = fH->GetListOfFunctions();
3642 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3643 // try with the old painter
3644 TGraphDelaunay *dtOld = nullptr;
3645 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3646
3647 if (!dt && !dtOld) return nullptr;
3648
3649 gCurrentHist = fH;
3650
3651 if (!fGraph2DPainter) {
3652 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3653 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3654 }
3655
3656 return fGraph2DPainter->GetContourList(contour);
3657}
3658
3659////////////////////////////////////////////////////////////////////////////////
3660/// Display the histogram info (bin number, contents, integral up to bin
3661/// corresponding to cursor position px,py.
3662
3664{
3665
3666 if (!gPad) return (char*)"";
3667
3668 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3669 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3670 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3671 TString drawOption = fH->GetDrawOption();
3672 drawOption.ToLower();
3673 Double_t xmin, xmax, uxmin,uxmax;
3674 Double_t ymin, ymax, uymin,uymax;
3675 if (fH->GetDimension() == 2) {
3676 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3677 uxmin=gPad->GetUxmin();
3678 uxmax=gPad->GetUxmax();
3681 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3682 uymin=gPad->GetUymin();
3683 uymax=gPad->GetUymax();
3686 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3687 }
3688 }
3689 Int_t binx,biny,binmin=0,binx1;
3690 if (gPad->IsVertical()) {
3691 binx = fXaxis->FindFixBin(x);
3692 if (drawOption.Index("same") >= 0) {
3693 TH1 *h1;
3694 TIter next(gPad->GetListOfPrimitives());
3695 while ((h1 = (TH1 *)next())) {
3696 if (!h1->InheritsFrom(TH1::Class())) continue;
3697 binmin = h1->GetXaxis()->GetFirst();
3698 break;
3699 }
3700 } else {
3701 binmin = fXaxis->GetFirst();
3702 }
3703 binx1 = fXaxis->FindFixBin(x1);
3704 // special case if more than 1 bin in x per pixel
3705 if (binx1-binx>1 && fH->GetDimension() == 1) {
3706 Double_t binval=fH->GetBinContent(binx);
3707 Int_t binnear=binx;
3708 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3709 Double_t binvaltmp = fH->GetBinContent(ibin);
3710 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3711 binval=binvaltmp;
3712 binnear=ibin;
3713 }
3714 }
3715 binx = binnear;
3716 }
3717 } else {
3718 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3719 binx = fXaxis->FindFixBin(y);
3720 if (drawOption.Index("same") >= 0) {
3721 TH1 *h1;
3722 TIter next(gPad->GetListOfPrimitives());
3723 while ((h1 = (TH1 *)next())) {
3724 if (!h1->InheritsFrom(TH1::Class())) continue;
3725 binmin = h1->GetXaxis()->GetFirst();
3726 break;
3727 }
3728 } else {
3729 binmin = fXaxis->GetFirst();
3730 }
3731 binx1 = fXaxis->FindFixBin(x1);
3732 // special case if more than 1 bin in x per pixel
3733 if (binx1-binx>1 && fH->GetDimension() == 1) {
3734 Double_t binval=fH->GetBinContent(binx);
3735 Int_t binnear=binx;
3736 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3737 Double_t binvaltmp = fH->GetBinContent(ibin);
3738 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3739 binval=binvaltmp;
3740 binnear=ibin;
3741 }
3742 }
3743 binx = binnear;
3744 }
3745 }
3746 if (fH->GetDimension() == 1) {
3748 TProfile *tp = (TProfile*)fH;
3749 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3750 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3751 (Int_t) tp->GetBinEntries(binx));
3752 }
3753 else {
3754 Double_t integ = 0;
3755 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3756 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3757 x,y,binx,fH->GetBinContent(binx),integ);
3758 }
3759 } else if (fH->GetDimension() == 2) {
3760 if (fH->InheritsFrom(TH2Poly::Class())) {
3761 TH2Poly *th2 = (TH2Poly*)fH;
3762 biny = th2->FindBin(x,y);
3763 fObjectInfo.Form("%s (x=%g, y=%g, bin=%d, binc=%g)",
3764 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3765 }
3766 else if (fH->InheritsFrom(TProfile2D::Class())) {
3767 TProfile2D *tp = (TProfile2D*)fH;
3768 biny = fYaxis->FindFixBin(y);
3769 Int_t bin = fH->GetBin(binx,biny);
3770 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3771 x, y, binx, biny, fH->GetBinContent(bin),
3772 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3773 } else {
3774 biny = fYaxis->FindFixBin(y);
3775 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3776 x,y,binx,biny,fH->GetBinContent(binx,biny),
3777 fH->GetBinError(binx,biny));
3778 }
3779 } else {
3780 // 3d case: retrieving the x,y,z bin is not yet implemented
3781 // print just the x,y info
3782 fObjectInfo.Form("(x=%g, y=%g)",x,y);
3783 }
3784
3785 return (char *)fObjectInfo.Data();
3786}
3787
3788////////////////////////////////////////////////////////////////////////////////
3789/// Set highlight (enable/disable) mode for fH
3790
3792{
3793 if (fH->IsHighlight()) return;
3794
3795 fXHighlightBin = -1;
3796 fYHighlightBin = -1;
3797 // delete previous highlight box
3800 // emit Highlighted() signal (user can check on disabled)
3801 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3802}
3803
3804////////////////////////////////////////////////////////////////////////////////
3805/// Check on highlight bin
3806
3808{
3809 // call from DistancetoPrimitive (only if highlight is enable)
3810
3811 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3812 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3813 Int_t binx = fXaxis->FindFixBin(x);
3814 Int_t biny = fYaxis->FindFixBin(y);
3815 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3816
3817 Bool_t changedBin = kFALSE;
3818 if (binx != fXHighlightBin) {
3819 fXHighlightBin = binx;
3820 changedBin = kTRUE;
3821 } else if (fH->GetDimension() == 1) return;
3822 if (biny != fYHighlightBin) {
3823 fYHighlightBin = biny;
3824 changedBin = kTRUE;
3825 }
3826 if (!changedBin) return;
3827
3828 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3829 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3830
3831 // paint highlight bin as box (recursive calls PaintHighlightBin)
3832 gPad->Modified(kTRUE);
3833 gPad->Update();
3834
3835 // emit Highlighted() signal
3836 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3837}
3838
3839////////////////////////////////////////////////////////////////////////////////
3840/// Paint highlight bin as TBox object
3841
3843{
3844 // call from PaintTitle
3845
3846 if (!fH->IsHighlight()) return;
3847
3848 Double_t uxmin = gPad->GetUxmin();
3849 Double_t uxmax = gPad->GetUxmax();
3850 Double_t uymin = gPad->GetUymin();
3851 Double_t uymax = gPad->GetUymax();
3852 if (gPad->GetLogx()) {
3853 uxmin = TMath::Power(10.0, uxmin);
3854 uxmax = TMath::Power(10.0, uxmax);
3855 }
3856 if (gPad->GetLogy()) {
3857 uymin = TMath::Power(10.0, uymin);
3858 uymax = TMath::Power(10.0, uymax);
3859 }
3860
3861 // testing specific possibility (after zoom, draw with "same", log, etc.)
3862 Double_t hcenter;
3863 if (gPad->IsVertical()) {
3865 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3866 } else {
3868 if ((hcenter < uymin) || (hcenter > uymax)) return;
3869 }
3870 if (fH->GetDimension() == 2) {
3872 if ((hcenter < uymin) || (hcenter > uymax)) return;
3873 }
3874
3875 // paint X highlight bin (for 1D or 2D)
3876 Double_t hbx1, hbx2, hby1, hby2;
3877 if (gPad->IsVertical()) {
3880 hby1 = uymin;
3881 hby2 = uymax;
3882 } else {
3883 hbx1 = uxmin;
3884 hbx2 = uxmax;
3887 }
3888
3889 if (!gXHighlightBox) {
3890 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3894 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3895 }
3896 gXHighlightBox->SetX1(hbx1);
3897 gXHighlightBox->SetX2(hbx2);
3898 gXHighlightBox->SetY1(hby1);
3899 gXHighlightBox->SetY2(hby2);
3901
3902 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3903 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3904
3905 // paint Y highlight bin (only for 2D)
3906 if (fH->GetDimension() != 2) return;
3907 hbx1 = uxmin;
3908 hbx2 = uxmax;
3911
3912 if (!gYHighlightBox) {
3913 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3917 }
3918 gYHighlightBox->SetX1(hbx1);
3919 gYHighlightBox->SetX2(hbx2);
3920 gYHighlightBox->SetY1(hby1);
3921 gYHighlightBox->SetY2(hby2);
3923}
3924
3925////////////////////////////////////////////////////////////////////////////////
3926/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3927
3929{
3930
3931 for (Int_t i=0;i<fNcuts;i++) {
3934 if (fCutsOpt[i] > 0) {
3935 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3936 } else {
3937 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3938 }
3939 }
3940 return kTRUE;
3941}
3942
3943////////////////////////////////////////////////////////////////////////////////
3944/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3945
3947{
3948
3949 for (Int_t i=0;i<fNcuts;i++) {
3950 if (fCutsOpt[i] > 0) {
3951 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3952 } else {
3953 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3954 }
3955 }
3956 return kTRUE;
3957}
3958
3959////////////////////////////////////////////////////////////////////////////////
3960/// Decode string `choptin` and fill Hoption structure.
3961
3963{
3964
3965 char *l;
3966 char chopt[128];
3967 Int_t nch = strlen(choptin);
3968 strlcpy(chopt,choptin,128);
3969 Int_t hdim = fH->GetDimension();
3970
3979
3980 // special 2D options
3981 Hoption.List = 0;
3982 Hoption.Zscale = 0;
3983 Hoption.FrontBox = 1;
3984 Hoption.BackBox = 1;
3986
3987 Hoption.Zero = 0;
3988
3990
3991 //check for graphical cuts
3992 MakeCuts(chopt);
3993
3994 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3995 if (hdim > 1) Hoption.Scat = 1;
3996 if (!nch) Hoption.Hist = 1;
3997 if (fFunctions->First()) Hoption.Func = 1;
3998 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3999
4000 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
4001 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
4002 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
4003 if (l1 || l2 || l3) {
4004 Int_t i = gPad->NextPaletteColor();
4005 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
4006 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
4007 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
4008 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
4009 }
4010
4011 l = strstr(chopt,"MIN0");
4012 if (l) {
4013 Hoption.MinimumZero = 1;
4014 memcpy(l," ",4);
4015 }
4016
4017 l = strstr(chopt,"SPEC");
4018 if (l) {
4019 Hoption.Scat = 0;
4020 memcpy(l," ",4);
4021 Int_t bs=0;
4022 l = strstr(chopt,"BF(");
4023 if (l) {
4024 if (sscanf(&l[3],"%d",&bs) > 0) {
4025 Int_t i=0;
4026 while (l[i]!=')') {
4027 l[i] = ' ';
4028 i++;
4029 }
4030 l[i] = ' ';
4031 }
4032 }
4033 Hoption.Spec = TMath::Max(1600,bs);
4034 return 1;
4035 }
4036
4037 l = strstr(chopt,"GL");
4038 if (l) {
4039 memcpy(l," ",2);
4040 }
4041 l = strstr(chopt,"X+");
4042 if (l) {
4043 Hoption.AxisPos = 10;
4044 memcpy(l," ",2);
4045 }
4046 l = strstr(chopt,"Y+");
4047 if (l) {
4048 Hoption.AxisPos += 1;
4049 memcpy(l," ",2);
4050 }
4051 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4052 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4053
4054 l = strstr(chopt,"SAMES");
4055 if (l) {
4056 if (nch == 5) Hoption.Hist = 1;
4057 Hoption.Same = 2;
4058 memcpy(l," ",5);
4059 if (l[5] == '0') { Hoption.Same += 10; l[5] = ' '; }
4060 }
4061 l = strstr(chopt,"SAME");
4062 if (l) {
4063 if (nch == 4) Hoption.Hist = 1;
4064 Hoption.Same = 1;
4065 memcpy(l," ",4);
4066 if (l[4] == '0') { Hoption.Same += 10; l[4] = ' '; }
4067 }
4068
4069 l = strstr(chopt,"PIE");
4070 if (l) {
4071 Hoption.Pie = 1;
4072 memcpy(l," ",3);
4073 }
4074
4075
4076 l = strstr(chopt,"CANDLE");
4077 if (l) {
4078 TCandle candle;
4079 Hoption.Candle = candle.ParseOption(l);
4080 Hoption.Scat = 0;
4081 }
4082
4083 l = strstr(chopt,"VIOLIN");
4084 if (l) {
4085 TCandle candle;
4086 Hoption.Candle = candle.ParseOption(l);
4087 Hoption.Scat = 0;
4088 }
4089
4090 l = strstr(chopt,"LEGO");
4091 if (l) {
4092 Hoption.Scat = 0;
4093 Hoption.Lego = 1; memcpy(l," ",4);
4094 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4095 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4096 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4097 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4098 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4099 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4100 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4101 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4102 }
4103
4104 l = strstr(chopt,"SURF");
4105 if (l) {
4106 Hoption.Scat = 0;
4107 Hoption.Surf = 1; memcpy(l," ",4);
4108 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4109 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4110 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4111 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4112 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4113 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4114 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4115 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4116 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4117 }
4118
4119 l = strstr(chopt,"TF3");
4120 if (l) {
4121 memcpy(l," ",3);
4122 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4123 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4124 }
4125
4126 l = strstr(chopt,"ISO");
4127 if (l) {
4128 memcpy(l," ",3);
4129 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4130 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4131 }
4132
4133 l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4134
4135 l = strstr(chopt,"CONT");
4136 if (l) {
4137 memcpy(l," ",4);
4138 if (hdim>1) {
4139 Hoption.Scat = 0;
4140 Hoption.Contour = 1;
4141 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4142 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4143 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4144 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4145 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4146 } else {
4147 Hoption.Hist = 1;
4148 }
4149 }
4150 l = strstr(chopt,"HBAR");
4151 if (l) {
4152 Hoption.Hist = 0;
4153 Hoption.Bar = 20; memcpy(l," ",4);
4154 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4155 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4156 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4157 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4158 }
4159 l = strstr(chopt,"BAR");
4160 if (l) {
4161 Hoption.Hist = 0;
4162 Hoption.Bar = 10; memcpy(l," ",3);
4163 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4164 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4165 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4166 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4167 }
4168
4169 l = strstr(chopt,"ARR" );
4170 if (l) {
4171 memcpy(l," ", 3);
4172 if (hdim>1) {
4173 Hoption.Arrow = 1;
4174 Hoption.Scat = 0;
4175 l = strstr(chopt,"COL"); if (l) { Hoption.Arrow = 2; memcpy(l," ",3); }
4176 l = strstr(chopt,"Z"); if (l) { Hoption.Zscale = 1; memcpy(l," ",1); }
4177 } else {
4178 Hoption.Hist = 1;
4179 }
4180 }
4181 l = strstr(chopt,"BOX" );
4182 if (l) {
4183 memcpy(l," ", 3);
4184 if (hdim>1) {
4185 Hoption.Scat = 0;
4186 Hoption.Box = 1;
4187 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4188 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4189 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4190 } else {
4191 Hoption.Hist = 1;
4192 }
4193 }
4194 l = strstr(chopt,"COLZ");
4195 if (l) {
4196 memcpy(l," ",4);
4197 if (hdim>1) {
4198 Hoption.Color = 1;
4199 Hoption.Scat = 0;
4200 Hoption.Zscale = 1;
4201 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4202 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4203 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4204 } else {
4205 Hoption.Hist = 1;
4206 }
4207 }
4208 l = strstr(chopt,"COL" );
4209 if (l) {
4210 memcpy(l," ", 3);
4211 if (hdim>1) {
4212 Hoption.Color = 1;
4213 Hoption.Scat = 0;
4214 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4215 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4216 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4217 } else {
4218 Hoption.Hist = 1;
4219 }
4220 }
4221 l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; memcpy(l," ",4); Hoption.Scat = 0; }
4222 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4223 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4224 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4225 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4226 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4227 l = strstr(chopt,"TEXT");
4228 if (l) {
4229 Int_t angle;
4230 if (sscanf(&l[4],"%d",&angle) > 0) {
4231 if (angle < 0) angle=0;
4232 if (angle > 90) angle=90;
4233 Hoption.Text = 1000+angle;
4234 } else {
4235 Hoption.Text = 1;
4236 }
4237 memcpy(l," ", 4);
4238 l = strstr(chopt,"N");
4239 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4240 Hoption.Scat = 0;
4241 }
4242 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4243 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4244 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4245 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4246
4247 l = strstr(chopt,"TRI");
4248 if (l) {
4249 Hoption.Scat = 0;
4250 Hoption.Color = 0;
4251 Hoption.Tri = 1; memcpy(l," ",3);
4252 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4253 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4254 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4255 }
4256
4257 l = strstr(chopt,"AITOFF");
4258 if (l) {
4259 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4260 }
4261 l = strstr(chopt,"MERCATOR");
4262 if (l) {
4263 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4264 }
4265 l = strstr(chopt,"SINUSOIDAL");
4266 if (l) {
4267 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4268 }
4269 l = strstr(chopt,"PARABOLIC");
4270 if (l) {
4271 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4272 }
4273 if (Hoption.Proj > 0) {
4274 Hoption.Scat = 0;
4275 Hoption.Contour = 14;
4276 }
4277
4278 if (strstr(chopt,"A")) Hoption.Axis = -1;
4279 if (strstr(chopt,"B")) Hoption.Bar = 1;
4280 if (strstr(chopt,"C") && !strstr(chopt,"CJUST")) { Hoption.Curve =1; Hoption.Hist = -1;}
4281 if (strstr(chopt,"F")) Hoption.Fill =1;
4282 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4283 if (strstr(chopt,"F2")) Hoption.Fill =2;
4284 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4285 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4286 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4287 if (strstr(chopt,"*")) Hoption.Star =1;
4288 if (strstr(chopt,"H")) Hoption.Hist =2;
4289 if (strstr(chopt,"P0")) Hoption.Mark =10;
4290
4291 if (fH->InheritsFrom(TH2Poly::Class())) {
4293 }
4294
4295 if (strstr(chopt,"E")) {
4296 if (hdim == 1) {
4297 Hoption.Error = 1;
4298 if (strstr(chopt,"E0")) Hoption.Error = 10;
4299 if (strstr(chopt,"E1")) Hoption.Error = 11;
4300 if (strstr(chopt,"E2")) Hoption.Error = 12;
4301 if (strstr(chopt,"E3")) Hoption.Error = 13;
4302 if (strstr(chopt,"E4")) Hoption.Error = 14;
4303 if (strstr(chopt,"E5")) Hoption.Error = 15;
4304 if (strstr(chopt,"E6")) Hoption.Error = 16;
4305 if (strstr(chopt,"X0")) {
4306 if (Hoption.Error == 1) Hoption.Error += 20;
4307 Hoption.Error += 10;
4308 }
4310 Hoption.Text += 2000;
4311 Hoption.Error = 0;
4312 }
4313 } else {
4314 if (Hoption.Error == 0) {
4315 Hoption.Error = 100;
4316 Hoption.Scat = 0;
4317 }
4318 if (Hoption.Text) {
4319 Hoption.Text += 2000;
4320 Hoption.Error = 0;
4321 }
4322 }
4323 }
4324
4325 if (Hoption.Surf == 15) {
4327 Hoption.Surf = 13;
4328 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4329 }
4330 }
4331
4332 // Copy options from current style
4333 Hoption.Logx = gPad->GetLogx();
4334 Hoption.Logy = gPad->GetLogy();
4335 Hoption.Logz = gPad->GetLogz();
4336
4337 // Check options incompatibilities
4338 if (Hoption.Bar == 1) Hoption.Hist = -1;
4339 return 1;
4340}
4341
4342////////////////////////////////////////////////////////////////////////////////
4343/// Decode string `choptin` and fill Graphical cuts structure.
4344
4346{
4347
4348 fNcuts = 0;
4349 char *left = (char*)strchr(choptin,'[');
4350 if (!left) return 0;
4351 char *right = (char*)strchr(choptin,']');
4352 if (!right) return 0;
4353 Int_t nch = right-left;
4354 if (nch < 2) return 0;
4355 char *cuts = left+1;
4356 *right = 0;
4357 char *comma, *minus;
4358 Int_t i;
4359 while (1) {
4360 comma = strchr(cuts,',');
4361 if (comma) *comma = 0;
4362 minus = strchr(cuts,'-');
4363 if (minus) cuts = minus+1;
4364 while (*cuts == ' ') cuts++;
4365 Int_t nc = strlen(cuts);
4366 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4367 TIter next(gROOT->GetListOfSpecials());
4368 TCutG *cut=0;
4369 TObject *obj;
4370 while ((obj = next())) {
4371 if (!obj->InheritsFrom(TCutG::Class())) continue;
4372 if (strcmp(obj->GetName(),cuts)) continue;
4373 cut = (TCutG*)obj;
4374 break;
4375 }
4376 if (cut) {
4377 fCuts[fNcuts] = cut;
4378 fCutsOpt[fNcuts] = 1;
4379 if (minus) fCutsOpt[fNcuts] = -1;
4380 fNcuts++;
4381 }
4382 if (!comma) break;
4383 cuts = comma+1;
4384 }
4385 for (i=0;i<=nch;i++) left[i] = ' ';
4386 return fNcuts;
4387}
4388
4389////////////////////////////////////////////////////////////////////////////////
4390/// [Control routine to paint any kind of histograms](#HP00)
4391
4393{
4394
4395 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4396
4397 //For iOS: put the histogram on the top of stack of pickable objects.
4398 const TPickerStackGuard topPush(fH);
4399
4400 gPad->SetVertical(kTRUE);
4401
4402 TH1 *oldhist = gCurrentHist;
4403 gCurrentHist = fH;
4404 TH1 *hsave = fH;
4405 Double_t minsav = fH->GetMinimumStored();
4406
4407 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4408
4409 // Paint using TSpectrum2Painter
4410 if (Hoption.Spec) {
4411 if (!TableInit()) return;
4412 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4413 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4414 (ULong_t)fH, option, Hoption.Spec));
4415 return;
4416 }
4417
4418 if (Hoption.Pie) {
4419 if (fH->GetDimension() == 1) {
4420 if (!fPie) fPie = new TPie(fH);
4421 fPie->Paint(option);
4422 } else {
4423 Error("Paint", "Option PIE is for 1D histograms only");
4424 }
4425 return;
4426 } else {
4427 if (fPie) delete fPie;
4428 fPie = 0;
4429 }
4430
4431 fXbuf = new Double_t[kNMAX];
4432 fYbuf = new Double_t[kNMAX];
4433 if (fH->GetDimension() > 2) {
4434 PaintH3(option);
4435 fH->SetMinimum(minsav);
4436 if (Hoption.Func) {
4437 Hoption_t hoptsave = Hoption;
4438 Hparam_t hparsave = Hparam;
4439 PaintFunction(option);
4440 SetHistogram(hsave);
4441 Hoption = hoptsave;
4442 Hparam = hparsave;
4443 }
4444 gCurrentHist = oldhist;
4445 delete [] fXbuf; delete [] fYbuf;
4446 return;
4447 }
4448 TView *view = gPad->GetView();
4449 if (view) {
4450 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4451 delete view;
4452 gPad->SetView(0);
4453 }
4454 }
4455 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4456 // In case of 1D histogram, Z axis becomes Y axis.
4457 Int_t logysav=0, logzsav=0;
4458 if (fH->GetDimension() == 1) {
4459 logysav = Hoption.Logy;
4460 logzsav = Hoption.Logz;
4461 Hoption.Logz = 0;
4462 if (Hoption.Logy) {
4463 Hoption.Logz = 1;
4464 Hoption.Logy = 0;
4465 }
4466 }
4467 PaintTable(option);
4468 if (Hoption.Func) {
4469 Hoption_t hoptsave = Hoption;
4470 Hparam_t hparsave = Hparam;
4471 PaintFunction(option);
4472 SetHistogram(hsave);
4473 Hoption = hoptsave;
4474 Hparam = hparsave;
4475 }
4476 fH->SetMinimum(minsav);
4477 gCurrentHist = oldhist;
4478 delete [] fXbuf; delete [] fYbuf;
4479 if (fH->GetDimension() == 1) {
4480 Hoption.Logy = logysav;
4481 Hoption.Logz = logzsav;
4482 }
4483 return;
4484 }
4485
4486 if (Hoption.Bar >= 20) {
4487 PaintBarH(option);
4488 delete [] fXbuf; delete [] fYbuf;
4489 return;
4490 }
4491
4492 // fill Hparam structure with histo parameters
4493 if (!PaintInit()) {
4494 delete [] fXbuf; delete [] fYbuf;
4495 return;
4496 }
4497
4498 // Picture surround (if new page) and page number (if requested).
4499 // Histogram surround (if not option "Same").
4500 PaintFrame();
4501
4502 // Paint histogram axis only
4503 Bool_t gridx = gPad->GetGridx();
4504 Bool_t gridy = gPad->GetGridy();
4505 if (Hoption.Axis > 0) {
4506 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4507 else {
4508 if (gridx) gPad->SetGridx(0);
4509 if (gridy) gPad->SetGridy(0);
4511 if (gridx) gPad->SetGridx(1);
4512 if (gridy) gPad->SetGridy(1);
4513 }
4514 if ((Hoption.Same%10) ==1) Hoption.Same += 1;
4515 goto paintstat;
4516 }
4517 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4518
4519 // test for options BAR or HBAR
4520 if (Hoption.Bar >= 10) {
4521 PaintBar(option);
4522 }
4523
4524 // do not draw histogram if error bars required
4525 if (!Hoption.Error) {
4526 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4527 }
4528
4529 // test for error bars or option E
4530 if (Hoption.Error) {
4531 PaintErrors(option);
4532 if (Hoption.Hist == 2) PaintHist(option);
4533 }
4534
4535 if (Hoption.Text) PaintText(option);
4536
4537 // test for associated function
4538 if (Hoption.Func) {
4539 Hoption_t hoptsave = Hoption;
4540 Hparam_t hparsave = Hparam;
4541 PaintFunction(option);
4542 SetHistogram(hsave);
4543 Hoption = hoptsave;
4544 Hparam = hparsave;
4545 }
4546
4547 if (gridx) gPad->SetGridx(0);
4548 if (gridy) gPad->SetGridy(0);
4550 if (gridx) gPad->SetGridx(1);
4551 if (gridy) gPad->SetGridy(1);
4552
4553 PaintTitle(); // Draw histogram title
4554
4555 // Draw box with histogram statistics and/or fit parameters
4556paintstat:
4557 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4558 TIter next(fFunctions);
4559 TObject *obj = 0;
4560 while ((obj = next())) {
4561 if (obj->InheritsFrom(TF1::Class())) break;
4562 obj = 0;
4563 }
4564
4565 //Stat is painted twice (first, it will be in canvas' list of primitives),
4566 //second, it will be here, this is not required on iOS.
4567 //Condition is ALWAYS true on a platform different from iOS.
4568 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4569 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4570 }
4571 fH->SetMinimum(minsav);
4572 gCurrentHist = oldhist;
4573 delete [] fXbuf; fXbuf = 0;
4574 delete [] fYbuf; fYbuf = 0;
4575
4576}
4577
4578////////////////////////////////////////////////////////////////////////////////
4579/// [Control function to draw a table as an arrow plot](#HP12)
4580
4582{
4583 Double_t xk, xstep, yk, ystep;
4584 Double_t dx, dy, x1, x2, y1, y2, xc, yc, dxn, dyn;
4587 Double_t xrg = gPad->GetUxmin();
4588 Double_t yrg = gPad->GetUymin();
4589 Double_t xln = gPad->GetUxmax() - xrg;
4590 Double_t yln = gPad->GetUymax() - yrg;
4591 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4592 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4593 Double_t dn = 1.E-30;
4594
4595 auto arrow = new TArrow();
4596 arrow->SetAngle(30);
4597 arrow->SetFillStyle(1001);
4598 arrow->SetFillColor(fH->GetLineColor());
4599 arrow->SetLineColor(fH->GetLineColor());
4600 arrow->SetLineWidth(fH->GetLineWidth());
4601
4602 // Initialize the levels on the Z axis
4603 Int_t ncolors=0, ndivz=0;
4604 Double_t scale=0.;
4605 if (Hoption.Arrow>1) {
4606 ncolors = gStyle->GetNumberOfColors();
4607 Int_t ndiv = fH->GetContour();
4608 if (ndiv == 0 ) {
4609 ndiv = gStyle->GetNumberContours();
4610 fH->SetContour(ndiv);
4611 }
4612 ndivz = TMath::Abs(ndiv);
4613 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4614 scale = ndivz/(fH->GetMaximum()-fH->GetMinimum());
4615 }
4616
4617 for (Int_t id=1;id<=2;id++) {
4618 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4619 yk = fYaxis->GetBinLowEdge(j);
4620 ystep = fYaxis->GetBinWidth(j);
4621 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4622 xk = fXaxis->GetBinLowEdge(i);
4623 xstep = fXaxis->GetBinWidth(i);
4624 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4625 if (i == Hparam.xfirst) {
4626 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4627 } else if (i == Hparam.xlast) {
4628 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4629 } else {
4630 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4631 }
4632 if (j == Hparam.yfirst) {
4633 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4634 } else if (j == Hparam.ylast) {
4635 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4636 } else {
4637 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4638 }
4639 if (id == 1) {
4640 dn = TMath::Max(dn, TMath::Abs(dx));
4641 dn = TMath::Max(dn, TMath::Abs(dy));
4642 } else if (id == 2) {
4643 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4644 dxn = cx*dx/dn;
4645 x1 = xc - dxn;
4646 x2 = xc + dxn;
4647 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4648 dyn = cy*dy/dn;
4649 y1 = yc - dyn;
4650 y2 = yc + dyn;
4651 if (Hoption.Arrow>1) {
4652 int color = Int_t(0.01+(fH->GetBinContent(i, j)-fH->GetMinimum())*scale);
4653 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4654 if (theColor > ncolors-1) theColor = ncolors-1;
4655 arrow->SetFillColor(gStyle->GetColorPalette(theColor));
4656 arrow->SetLineColor(gStyle->GetColorPalette(theColor));
4657 }
4658 if (TMath::Abs(x2-x1) > 0. || TMath::Abs(y2-y1) > 0.) {
4659 arrow->PaintArrow(x1, y1, x2, y2, 0.015, "|>");
4660 } else {
4661 arrow->PaintArrow(x1, y1, x2, y2, 0.005, "|>");
4662 }
4663 }
4664 }
4665 }
4666 }
4667
4669}
4670
4671////////////////////////////////////////////////////////////////////////////////
4672/// Draw axis (2D case) of an histogram.
4673///
4674/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4675/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4676/// feature is used to make sure that the grid is drawn in the background and
4677/// the axis tick marks in the foreground of the pad.
4678
4680{
4681
4682 //On iOS, grid should not be pickable and can not be highlighted.
4683 //Condition is never true on a platform different from iOS.
4684 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4685 return;
4686
4687 if (Hoption.Axis == -1) return;
4688 if (Hoption.Same && Hoption.Axis <= 0) return;
4689
4690 // Repainting alphanumeric labels axis on a plot done with
4691 // the option HBAR (horizontal) needs some adjustments.
4692 TAxis *xaxis = 0;
4693 TAxis *yaxis = 0;
4694 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4695 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4696 TIter next(gPad->GetListOfPrimitives());
4697 TObject *obj;
4698 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4699 while ((obj = next())) {
4700 if (!obj->InheritsFrom(TH1::Class()) &&
4701 !obj->InheritsFrom(THStack::Class())) continue;
4702 TString opt = obj->GetDrawOption();
4703 opt.ToLower();
4704 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4705 if (strstr(opt,"hbar")) {
4706 gPad->SetVertical(kFALSE);
4707 xaxis = fXaxis;
4708 yaxis = fYaxis;
4709 if (!strcmp(xaxis->GetName(),"xaxis")) {
4710 fXaxis = yaxis;
4711 fYaxis = xaxis;
4712 }
4713 }
4714 break;
4715 }
4716 }
4717 }
4718
4719 static char chopt[10] = "";
4720 Double_t gridl = 0;
4721 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4722 Int_t useHparam = 0;
4723 Double_t umin, umax, uminsave, umaxsave;
4724 Short_t xAxisPos = Hoption.AxisPos/10;
4725 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4726
4727 Double_t axmin = gPad->GetUxmin();
4728 Double_t axmax = gPad->GetUxmax();
4729 Double_t aymin = gPad->GetUymin();
4730 Double_t aymax = gPad->GetUymax();
4731 char *cw = 0;
4732 TGaxis axis;
4733
4734 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4735 // Hparam must be use for the axis limits.
4736 if (Hoption.Contour == 14) useHparam = 1;
4737 if (Hoption.Same) {
4738 TObject *obj;
4739 TIter next(gPad->GetListOfPrimitives());
4740 while ((obj=next())) {
4741 if (strstr(obj->GetDrawOption(),"cont4")) {
4742 useHparam = 1;
4743 break;
4744 }
4745 }
4746 }
4747
4748 // Paint X axis
4749
4750 //To make X-axis selectable on iOS device.
4751 if (gPad->PadInSelectionMode())
4752 gPad->PushSelectableObject(fXaxis);
4753
4754 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4755 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4756 ndivx = fXaxis->GetNdivisions();
4757 if (ndivx > 1000) {
4758 nx2 = ndivx/100;
4759 nx1 = TMath::Max(1, ndivx%100);
4760 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4761 }
4762 axis.SetTextAngle(0);
4764
4765 chopt[0] = 0;
4766 strlcat(chopt, "SDH",10);
4767 if (ndivx < 0) strlcat(chopt, "N",10);
4768 if (gPad->GetGridx()) {
4769 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4770 strlcat(chopt, "W",10);
4771 }
4772
4773 // Define X-Axis limits
4774 if (Hoption.Logx) {
4775 strlcat(chopt, "G",10);
4776 ndiv = TMath::Abs(ndivx);
4777 if (useHparam) {
4778 umin = TMath::Power(10,Hparam.xmin);
4779 umax = TMath::Power(10,Hparam.xmax);
4780 } else {
4781 umin = TMath::Power(10,axmin);
4782 umax = TMath::Power(10,axmax);
4783 }
4784 } else {
4785 ndiv = TMath::Abs(ndivx);
4786 if (useHparam) {
4787 umin = Hparam.xmin;
4788 umax = Hparam.xmax;
4789 } else {
4790 umin = axmin;
4791 umax = axmax;
4792 }
4793 }
4794
4795 // Display axis as time
4796 if (fXaxis->GetTimeDisplay()) {
4797 strlcat(chopt,"t",10);
4798 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4800 }
4801 }
4802
4803 // The main X axis can be on the bottom or on the top of the pad
4804 Double_t xAxisYPos1, xAxisYPos2;
4805 if (xAxisPos == 1) {
4806 // Main X axis top
4807 xAxisYPos1 = aymax;
4808 xAxisYPos2 = aymin;
4809 } else {
4810 // Main X axis bottom
4811 xAxisYPos1 = aymin;
4812 xAxisYPos2 = aymax;
4813 }
4814
4815 // Paint the main X axis (always)
4816 uminsave = umin;
4817 umaxsave = umax;
4818 ndivsave = ndiv;
4819 axis.SetOption(chopt);
4820 if (xAxisPos) {
4821 strlcat(chopt, "-",10);
4822 gridl = -gridl;
4823 }
4824 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4825 axis.SetLabelSize(0.);
4826 axis.SetTitle("");
4827 }
4828 axis.PaintAxis(axmin, xAxisYPos1,
4829 axmax, xAxisYPos1,
4830 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4831
4832 // Paint additional X axis (if needed)
4833 // On iOS, this additional X axis is neither pickable, nor highlighted.
4834 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4835 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4836 if (xAxisPos) {
4837 cw=strstr(chopt,"-");
4838 *cw='z';
4839 } else {
4840 strlcat(chopt, "-",10);
4841 }
4842 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4843 if ((cw=strstr(chopt,"W"))) *cw='z';
4844 axis.SetTitle("");
4845 axis.PaintAxis(axmin, xAxisYPos2,
4846 axmax, xAxisYPos2,
4847 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4848 }
4849 }//End of "if pad in selection mode etc".
4850
4851 // Paint Y axis
4852 //On iOS, Y axis must pushed into the stack of selectable objects.
4853 if (gPad->PadInSelectionMode())
4854 gPad->PushSelectableObject(fYaxis);
4855
4856 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4857 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4858 ndivy = fYaxis->GetNdivisions();
4860
4861 chopt[0] = 0;
4862 strlcat(chopt, "SDH",10);
4863 if (ndivy < 0) strlcat(chopt, "N",10);
4864 if (gPad->GetGridy()) {
4865 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4866 strlcat(chopt, "W",10);
4867 }
4868
4869 // Define Y-Axis limits
4870 if (Hoption.Logy) {
4871 strlcat(chopt, "G",10);
4872 ndiv = TMath::Abs(ndivy);
4873 if (useHparam) {
4874 umin = TMath::Power(10,Hparam.ymin);
4875 umax = TMath::Power(10,Hparam.ymax);
4876 } else {
4877 umin = TMath::Power(10,aymin);
4878 umax = TMath::Power(10,aymax);
4879 }
4880 } else {
4881 ndiv = TMath::Abs(ndivy);
4882 if (useHparam) {
4883 umin = Hparam.ymin;
4884 umax = Hparam.ymax;
4885 } else {
4886 umin = aymin;
4887 umax = aymax;
4888 }
4889 }
4890
4891 // Display axis as time
4892 if (fYaxis->GetTimeDisplay()) {
4893 strlcat(chopt,"t",10);
4894 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4896 }
4897 }
4898
4899 // The main Y axis can be on the left or on the right of the pad
4900 Double_t yAxisXPos1, yAxisXPos2;
4901 if (yAxisPos == 1) {
4902 // Main Y axis left
4903 yAxisXPos1 = axmax;
4904 yAxisXPos2 = axmin;
4905 } else {
4906 // Main Y axis right
4907 yAxisXPos1 = axmin;
4908 yAxisXPos2 = axmax;
4909 }
4910
4911 // Paint the main Y axis (always)
4912 uminsave = umin;
4913 umaxsave = umax;
4914 ndivsave = ndiv;
4915 axis.SetOption(chopt);
4916 if (yAxisPos) {
4917 strlcat(chopt, "+L",10);
4918 gridl = -gridl;
4919 }
4920 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4921 axis.SetLabelSize(0.);
4922 axis.SetTitle("");
4923 }
4924 axis.PaintAxis(yAxisXPos1, aymin,
4925 yAxisXPos1, aymax,
4926 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4927
4928 // Paint the additional Y axis (if needed)
4929 // Additional checks for pad mode are required on iOS: this "second" axis is
4930 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4931 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4932 if (gPad->GetTicky() < 2) {
4933 strlcat(chopt, "U",10);
4935 } else {
4936 strlcat(chopt, "+L",10);
4937 }
4938 if ((cw=strstr(chopt,"W"))) *cw='z';
4939 axis.SetTitle("");
4940 axis.PaintAxis(yAxisXPos2, aymin,
4941 yAxisXPos2, aymax,
4942 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4943 }
4944 }//End of "if pad is in selection mode etc."
4945
4946 // Reset the axis if they have been inverted in case of option HBAR
4947 if (xaxis) {
4948 fXaxis = xaxis;
4949 fYaxis = yaxis;
4950 }
4951}
4952
4953////////////////////////////////////////////////////////////////////////////////
4954/// [Draw a bar-chart in a normal pad.](#HP10)
4955
4957{
4958
4959 Int_t bar = Hoption.Bar - 10;
4960 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4961 Double_t offset = fH->GetBarOffset();
4963 TBox box;
4964 Int_t hcolor = fH->GetFillColor();
4965 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4966 Int_t hstyle = fH->GetFillStyle();
4967 box.SetFillColor(hcolor);
4968 box.SetFillStyle(hstyle);
4969 box.SetLineStyle(fH->GetLineStyle());
4970 box.SetLineColor(fH->GetLineColor());
4971 box.SetLineWidth(fH->GetLineWidth());
4972 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4973 y = fH->GetBinContent(bin);
4974 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4975 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4976 ymin = gPad->GetUymin();
4977 ymax = gPad->YtoPad(y);
4978 if (ymax < gPad->GetUymin()) continue;
4979 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4980 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4981 if (Hoption.MinimumZero && ymin < 0)
4982 ymin=TMath::Min(0.,gPad->GetUymax());
4983 w = (xmax-xmin)*width;
4984 xmin += offset*(xmax-xmin);
4985 xmax = xmin + w;
4986 if (bar < 1) {
4987 box.PaintBox(xmin,ymin,xmax,ymax);
4988 } else {
4989 umin = xmin + bar*(xmax-xmin)/10.;
4990 umax = xmax - bar*(xmax-xmin)/10.;
4991 //box.SetFillColor(hcolor+150); //bright
4992 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4993 box.PaintBox(xmin,ymin,umin,ymax);
4994 box.SetFillColor(hcolor);
4995 box.PaintBox(umin,ymin,umax,ymax);
4996 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4997 box.PaintBox(umax,ymin,xmax,ymax);
4998 }
4999 }
5000}
5001
5002////////////////////////////////////////////////////////////////////////////////
5003/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
5004
5006{
5007
5008 gPad->SetVertical(kFALSE);
5009
5010 PaintInitH();
5011
5012 TAxis *xaxis = fXaxis;
5013 TAxis *yaxis = fYaxis;
5014 if (!strcmp(xaxis->GetName(),"xaxis")) {
5015 fXaxis = yaxis;
5016 fYaxis = xaxis;
5017 }
5018
5019 PaintFrame();
5021
5022 Int_t bar = Hoption.Bar - 20;
5023 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
5024 Double_t offset = fH->GetBarOffset();
5026 TBox box;
5027 Int_t hcolor = fH->GetFillColor();
5028 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5029 Int_t hstyle = fH->GetFillStyle();
5030 box.SetFillColor(hcolor);
5031 box.SetFillStyle(hstyle);
5032 box.SetLineStyle(fH->GetLineStyle());
5033 box.SetLineColor(fH->GetLineColor());
5034 box.SetLineWidth(fH->GetLineWidth());
5035 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
5036 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
5037 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
5038 xmin = gPad->GetUxmin();
5039 xmax = gPad->XtoPad(fH->GetBinContent(bin));
5040 if (xmax < gPad->GetUxmin()) continue;
5041 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
5042 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
5043 if (Hoption.MinimumZero && xmin < 0)
5044 xmin=TMath::Min(0.,gPad->GetUxmax());
5045 w = (ymax-ymin)*width;
5046 ymin += offset*(ymax-ymin);
5047 ymax = ymin + w;
5048 if (bar < 1) {
5049 box.PaintBox(xmin,ymin,xmax,ymax);
5050 } else {
5051 umin = ymin + bar*(ymax-ymin)/10.;
5052 umax = ymax - bar*(ymax-ymin)/10.;
5053 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5054 box.PaintBox(xmin,ymin,xmax,umin);
5055 box.SetFillColor(hcolor);
5056 box.PaintBox(xmin,umin,xmax,umax);
5057 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5058 box.PaintBox(xmin,umax,xmax,ymax);
5059 }
5060 }
5061
5062 PaintTitle();
5063
5064 // Draw box with histogram statistics and/or fit parameters
5065 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5066 TIter next(fFunctions);
5067 TObject *obj = 0;
5068 while ((obj = next())) {
5069 if (obj->InheritsFrom(TF1::Class())) break;
5070 obj = 0;
5071 }
5072 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5073 }
5074
5075 fXaxis = xaxis;
5076 fYaxis = yaxis;
5077}
5078
5079////////////////////////////////////////////////////////////////////////////////
5080/// [Control function to draw a 2D histogram as a box plot](#HP13)
5081
5083{
5084
5085 Style_t fillsav = fH->GetFillStyle();
5086 Style_t colsav = fH->GetFillColor();
5087 if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
5088 if (Hoption.Box == 11) fH->SetFillStyle(1001);
5089 fH->TAttLine::Modify();
5090 fH->TAttFill::Modify();
5091
5092 Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
5093 Double_t ux1 = gPad->PixeltoX(1);
5094 Double_t ux0 = gPad->PixeltoX(0);
5095 Double_t uy1 = gPad->PixeltoY(1);
5096 Double_t uy0 = gPad->PixeltoY(0);
5097 Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
5098 Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
5099
5100 Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
5103 Double_t zminlin = zmin, zmaxlin = zmax;
5104
5105 // In case of option SAME, zmin and zmax values are taken from the
5106 // first plotted 2D histogram.
5107 if (Hoption.Same > 0 && Hoption.Same < 10) {
5108 TH2 *h2;
5109 TIter next(gPad->GetListOfPrimitives());
5110 while ((h2 = (TH2 *)next())) {
5111 if (!h2->InheritsFrom(TH2::Class())) continue;
5112 zmin = TMath::Max(h2->GetMinimum(), 0.);
5113 zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
5114 TMath::Abs(h2->GetMinimum()));
5115 zminlin = zmin;
5116 zmaxlin = zmax;
5117 if (Hoption.Logz) {
5118 if (zmin <= 0) {
5119 zmin = TMath::Log10(zmax*0.001);
5120 } else {
5121 zmin = TMath::Log10(zmin);
5122 }
5123 zmax = TMath::Log10(zmax);
5124 }
5125 break;
5126 }
5127 } else {
5128 if (Hoption.Logz) {
5129 if (zmin > 0) {
5130 zmin = TMath::Log10(zmin);
5131 zmax = TMath::Log10(zmax);
5132 } else {
5133 return;
5134 }
5135 }
5136 }
5137
5138 Double_t zratio, dz = zmax - zmin;
5139 Bool_t kZminNeg = kFALSE;
5140 if (fH->GetMinimum()<0) kZminNeg = kTRUE;
5141 Bool_t kZNeg = kFALSE;
5142
5143 // Define the dark and light colors the "button style" boxes.
5144 Color_t color = fH->GetFillColor();
5145 Color_t light=0, dark=0;
5146 if (Hoption.Box == 11) {
5147 light = TColor::GetColorBright(color);
5148 dark = TColor::GetColorDark(color);
5149 }
5150
5151 // Loop over all the bins and draw the boxes
5152 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5153 yk = fYaxis->GetBinLowEdge(j);
5154 ystep = fYaxis->GetBinWidth(j);
5155 ycent = 0.5*ystep;
5156 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5157 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5158 xk = fXaxis->GetBinLowEdge(i);
5159 xstep = fXaxis->GetBinWidth(i);
5160 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5161 xcent = 0.5*xstep;
5162 z = Hparam.factor*fH->GetBinContent(bin);
5163 kZNeg = kFALSE;
5164
5165 if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
5166 if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
5167 if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
5168
5169 if (z < 0) {
5170 if (Hoption.Logz) continue;
5171 z = -z;
5172 kZNeg = kTRUE;
5173 }
5174 if (Hoption.Logz) {
5175 if (z != 0) z = TMath::Log10(z);
5176 else z = zmin;
5177 }
5178
5179 if (dz == 0) continue;
5180 zratio = TMath::Sqrt((z-zmin)/dz);
5181 if (zratio == 0) continue;
5182
5183 xup = xcent*zratio + xk + xcent;
5184 xlow = 2*(xk + xcent) - xup;
5185 if (xup-xlow < dxmin) xup = xlow+dxmin;
5186 if (Hoption.Logx) {
5187 if (xup > 0) xup = TMath::Log10(xup);
5188 else continue;
5189 if (xlow > 0) xlow = TMath::Log10(xlow);
5190 else continue;
5191 }
5192
5193 yup = ycent*zratio + yk + ycent;
5194 ylow = 2*(yk + ycent) - yup;
5195 if (yup-ylow < dymin) yup = ylow+dymin;
5196 if (Hoption.Logy) {
5197 if (yup > 0) yup = TMath::Log10(yup);
5198 else continue;
5199 if (ylow > 0) ylow = TMath::Log10(ylow);
5200 else continue;
5201 }
5202
5203 xlow = TMath::Max(xlow, gPad->GetUxmin());
5204 ylow = TMath::Max(ylow, gPad->GetUymin());
5205 xup = TMath::Min(xup , gPad->GetUxmax());
5206 yup = TMath::Min(yup , gPad->GetUymax());
5207
5208 if (xlow >= xup) continue;
5209 if (ylow >= yup) continue;
5210
5211 if (Hoption.Box == 1) {
5212 fH->SetFillColor(color);
5213 fH->TAttFill::Modify();
5214 gPad->PaintBox(xlow, ylow, xup, yup);
5215 if (kZNeg) {
5216 gPad->PaintLine(xlow, ylow, xup, yup);
5217 gPad->PaintLine(xlow, yup, xup, ylow);
5218 }
5219 } else if (Hoption.Box == 11) {
5220 // Draw the center of the box
5221 fH->SetFillColor(color);
5222 fH->TAttFill::Modify();
5223 gPad->PaintBox(xlow, ylow, xup, yup);
5224
5225 // Draw top&left part of the box
5226 Double_t x[7], y[7];
5227 Double_t bwidth = 0.1;
5228 x[0] = xlow; y[0] = ylow;
5229 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5230 x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
5231 x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
5232 x[4] = xup; y[4] = yup;
5233 x[5] = xlow; y[5] = yup;
5234 x[6] = xlow; y[6] = ylow;
5235 if (kZNeg) fH->SetFillColor(dark);
5236 else fH->SetFillColor(light);
5237 fH->TAttFill::Modify();
5238 gPad->PaintFillArea(7, x, y);
5239
5240 // Draw bottom&right part of the box
5241 x[0] = xlow; y[0] = ylow;
5242 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5243 x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
5244 x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
5245 x[4] = xup; y[4] = yup;
5246 x[5] = xup; y[5] = ylow;
5247 x[6] = xlow; y[6] = ylow;
5248 if (kZNeg) fH->SetFillColor(light);
5249 else fH->SetFillColor(dark);
5250 fH->TAttFill::Modify();
5251 gPad->PaintFillArea(7, x, y);
5252 }
5253 }
5254 }
5255
5257 fH->SetFillStyle(fillsav);
5258 fH->SetFillColor(colsav);
5259 fH->TAttFill::Modify();
5260}
5261
5262
5263
5264////////////////////////////////////////////////////////////////////////////////
5265/// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
5266
5268{
5269 TH1D *hproj;
5270 TH2D *h2 = (TH2D*)fH;
5271
5272 TCandle myCandle;
5274 myCandle.SetMarkerColor(fH->GetLineColor());
5275 myCandle.SetLineColor(fH->GetLineColor());
5276 myCandle.SetLineWidth(fH->GetLineWidth());
5277 myCandle.SetFillColor(fH->GetFillColor());
5278 myCandle.SetFillStyle(fH->GetFillStyle());
5279 myCandle.SetMarkerSize(fH->GetMarkerSize());
5280 myCandle.SetMarkerStyle(fH->GetMarkerStyle());
5282
5283 Bool_t swapXY = myCandle.IsHorizontal();
5284 const Double_t standardCandleWidth = 0.66;
5285 const Double_t standardHistoWidth = 0.8;
5286
5287 double allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
5288 double allMaxIntegral = 0;
5289
5290 if (!swapXY) { // Vertical candle
5291 //Determining the slice with the maximum content
5292 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5293 hproj = h2->ProjectionY("_px", i, i);
5294 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5295 }
5296 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5297 Double_t binPosX = fXaxis->GetBinLowEdge(i);
5298 Double_t binWidth = fXaxis->GetBinWidth(i);
5299 hproj = h2->ProjectionY("_px", i, i);
5300 if (hproj->GetEntries() !=0) {
5301 Double_t candleWidth = fH->GetBarWidth();
5302 Double_t offset = fH->GetBarOffset()*binWidth;
5303 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5304 double myIntegral = hproj->Integral();
5305 Double_t histoWidth = candleWidth;
5306 if (candleWidth > 0.999 && candleWidth < 1.001) {
5307 candleWidth = standardCandleWidth;
5308 histoWidth = standardHistoWidth;
5309 }
5310 if (Hoption.Logz && myMaxContent > 0) {
5311 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5312 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5313 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5314 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5315
5316 myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5317 myCandle.SetCandleWidth(candleWidth*binWidth);
5318 myCandle.SetHistoWidth(histoWidth*binWidth);
5319 myCandle.SetHistogram(hproj);
5320 myCandle.Paint();
5321 }
5322 }
5323 } else { // Horizontal candle
5324 //Determining the slice with the maximum content
5325 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5326 hproj = h2->ProjectionX("_py", i, i);
5327 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5328 }
5329 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5330 Double_t binPosY = fYaxis->GetBinLowEdge(i);
5331 Double_t binWidth = fYaxis->GetBinWidth(i);
5332 hproj = h2->ProjectionX("_py", i, i);
5333 if (hproj->GetEntries() !=0) {
5334 Double_t candleWidth = fH->GetBarWidth();
5335 Double_t offset = fH->GetBarOffset()*binWidth;
5336 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5337 double myIntegral = hproj->Integral();
5338 Double_t histoWidth = candleWidth;
5339 if (candleWidth > 0.999 && candleWidth < 1.001) {
5340 candleWidth = standardCandleWidth;
5341 histoWidth = standardHistoWidth;
5342 }
5343 if (Hoption.Logz && myMaxContent > 0) {
5344 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5345 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5346 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5347 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5348
5349 myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5350 myCandle.SetCandleWidth(candleWidth*binWidth);
5351 myCandle.SetHistoWidth(histoWidth*binWidth);
5352 myCandle.SetHistogram(hproj);
5353 myCandle.Paint();
5354 }
5355 }
5356 }
5357}
5358
5359
5360
5361////////////////////////////////////////////////////////////////////////////////
5362/// Returns the rendering regions for an axis to use in the COL2 option
5363///
5364/// The algorithm analyses the size of the axis compared to the size of
5365/// the rendering region. It figures out the boundaries to use for each color
5366/// of the rendering region. Only one axis is computed here.
5367///
5368/// This allows for a single computation of the boundaries before iterating
5369/// through all of the bins.
5370///
5371/// \param pAxis the axis to consider
5372/// \param nPixels the number of pixels to render axis into
5373/// \param isLog whether the axis is log scale
5374
5375std::vector<THistRenderingRegion>
5377{
5378 std::vector<THistRenderingRegion> regions;
5379
5380 enum STRATEGY { Bins, Pixels } strategy;
5381
5382 Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5383
5384 if (nBins >= nPixels) {
5385 // more bins than pixels... we should loop over pixels and sample
5386 strategy = Pixels;
5387 } else {
5388 // fewer bins than pixels... we should loop over bins
5389 strategy = Bins;
5390 }
5391
5392 if (isLog) {
5393
5394 Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5395 Int_t binOffset=0;
5396 while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5397 binOffset++;
5398 xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5399 }
5400 if (xMin <= 0) {
5401 // this should cause an error if we have
5402 return regions;
5403 }
5404 Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5405
5406 if (strategy == Bins) {
5407 // logarithmic plot. we find the pixel for the bin
5408 // pixel = eta * log10(V) - alpha
5409 // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5410 // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5411 // and V is axis value
5412 Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5413 Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5414
5415 for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5416
5417 // linear plot. we simply need to find the appropriate bin
5418 // for the
5419 Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5420 Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5421 Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5422 Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5423 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5424 std::make_pair(bin, bin+1)};
5425 regions.push_back(region);
5426 }
5427
5428 } else {
5429
5430 // loop over pixels
5431
5432 Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5433
5434 for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5435 // linear plot
5436 Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5437 Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5438 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5439 std::make_pair(binLow, binHigh)};
5440 regions.push_back(region);
5441 }
5442 }
5443 } else {
5444 // standard linear plot
5445
5446 if (strategy == Bins) {
5447 // loop over bins
5448 for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5449
5450 // linear plot. we simply need to find the appropriate bin
5451 // for the
5452 Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5453 Int_t xPx1 = xPx0 + nPixels/nBins;
5454
5455 // make sure we don't compute beyond our bounds
5456 if (xPx1>= nPixels) xPx1 = nPixels-1;
5457
5458 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5459 std::make_pair(bin, bin+1)};
5460 regions.push_back(region);
5461 }
5462 } else {
5463 // loop over pixels
5464 for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5465 // linear plot
5466 Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5467 Int_t binHigh = binLow + nBins/nPixels;
5468 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5469 std::make_pair(binLow, binHigh)};
5470 regions.push_back(region);
5471 }
5472 }
5473 }
5474
5475 return regions;
5476}
5477
5478////////////////////////////////////////////////////////////////////////////////
5479/// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5480
5482{
5483
5484 if (Hoption.System != kCARTESIAN) {
5485 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5486 "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5487 PaintColorLevels(nullptr);
5488 return;
5489 }
5490
5491 Double_t z;
5492
5493 // Use existing max or min values. If either is already set
5494 // the appropriate value to use.
5495 Double_t zmin = fH->GetMinimumStored();
5496 Double_t zmax = fH->GetMaximumStored();
5497 Double_t originalZMin = zmin;
5498 Double_t originalZMax = zmax;
5499 if ((zmin == -1111) && (zmax == -1111)) {
5500 fH->GetMinimumAndMaximum(zmin, zmax);
5501 fH->SetMinimum(zmin);
5502 fH->SetMaximum(zmax);
5503 } else if (zmin == -1111) {
5504 zmin = fH->GetMinimum();
5505 fH->SetMinimum(zmin);
5506 } else if (zmax == -1111) {
5507 zmax = fH->GetMaximum();
5508 fH->SetMaximum(zmax);
5509 }
5510
5511 Double_t dz = zmax - zmin;
5512 if (dz <= 0) { // Histogram filled with a constant value
5513 zmax += 0.1*TMath::Abs(zmax);
5514 zmin -= 0.1*TMath::Abs(zmin);
5515 dz = zmax - zmin;
5516 }
5517
5518 if (Hoption.Logz) {
5519 if (zmin > 0) {
5520 zmin = TMath::Log10(zmin);
5521 zmax = TMath::Log10(zmax);
5522 dz = zmax - zmin;
5523 } else {
5524 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5525 "Cannot plot logz because bin content is less than 0.");
5526 return;
5527 }
5528 }
5529
5530 // Initialize the levels on the Z axis
5531 Int_t ndiv = fH->GetContour();
5532 if (ndiv == 0 ) {
5533 ndiv = gStyle->GetNumberContours();
5534 fH->SetContour(ndiv);
5535 }
5536 std::vector<Double_t> colorBounds(ndiv);
5537 std::vector<Double_t> contours(ndiv, 0);
5538 if (fH->TestBit(TH1::kUserContour) == 0) {
5539 fH->SetContour(ndiv);
5540 } else {
5541 fH->GetContour(contours.data());
5542 }
5543
5544 Double_t step = 1.0/ndiv;
5545 for (Int_t i=0; i<ndiv; ++i) {
5546 colorBounds[i] = step*i;
5547 }
5548
5549 auto pFrame = gPad->GetFrame();
5550 Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5551 Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5552 Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5553 Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5554 Int_t nXPixels = px1-px0;
5555 Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5556
5557 std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5558
5559 auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5560 auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5561 if (xRegions.size() == 0 || yRegions.size() == 0) {
5562 Error("THistPainter::PaintColorLevelFast(Option_t*)",
5563 "Encountered error while computing rendering regions.");
5564 return;
5565 }
5566
5567 Bool_t minExists = kFALSE;
5568 Bool_t maxExists = kFALSE;
5569 Double_t minValue = 1.;
5570 Double_t maxValue = 0.;
5571 for (auto& yRegion : yRegions) {
5572 for (auto& xRegion : xRegions ) {
5573
5574 const auto& xBinRange = xRegion.fBinRange;
5575 const auto& yBinRange = yRegion.fBinRange;
5576
5577 // sample the range
5578 z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5579
5580 if (Hoption.Logz) {
5581 if (z > 0) z = TMath::Log10(z);
5582 else z = zmin;
5583 }
5584
5585 // obey the user's max and min values if they were set
5586 if (z > zmax) z = zmax;
5587 if (z < zmin) z = zmin;
5588
5589 if (fH->TestBit(TH1::kUserContour) == 1) {
5590 // contours are absolute values
5591 auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5592 z = colorBounds[index];
5593 } else {
5594 Int_t index = 0;
5595 if (dz != 0) {
5596 index = 0.001 + ((z - zmin)/dz)*ndiv;
5597 }
5598
5599 if (index == static_cast<Int_t>(colorBounds.size())) {
5600 index--;
5601 }
5602
5603 // Do a little bookkeeping to use later for getting libAfterImage to produce
5604 // the correct colors
5605 if (index == 0) {
5606 minExists = kTRUE;
5607 } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5608 maxExists = kTRUE;
5609 }
5610
5611 z = colorBounds[index];
5612
5613 if (z < minValue) {
5614 minValue = z;
5615 }
5616 if (z > maxValue) {
5617 maxValue = z;
5618 }
5619 }
5620
5621 // fill in the actual pixels
5622 const auto& xPixelRange = xRegion.fPixelRange;
5623 const auto& yPixelRange = yRegion.fPixelRange;
5624 for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5625 for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5626 Int_t pixel = yPx*nXPixels + xPx;
5627 buffer[pixel] = z;
5628 }
5629 }
5630 } // end px loop
5631 } // end py loop
5632
5633 // This is a bit of a hack to ensure that we span the entire color range and
5634 // don't screw up the colors for a sparse histogram. No one will notice that I set a
5635 // single pixel on the edge of the image to a different color. This is even more
5636 // true because the chosen pixels will be covered by the axis.
5637 if (minValue != maxValue) {
5638 if ( !minExists) {
5639 buffer.front() = 0;
5640 }
5641
5642 if ( !maxExists) {
5643 buffer[buffer.size()-nXPixels] = 0.95;
5644 }
5645 }
5646
5647 // Generate the TImage
5649 TImage* pImage = TImage::Create();
5651 pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5652 delete pPalette;
5653
5654 Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5655 pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5656 delete pImage;
5657
5659
5660 // Reset the maximum and minimum values to their original values
5661 // when this function was called. If we don't do this, an initial
5662 // value of -1111 will be replaced with the true max or min values.
5663 fH->SetMinimum(originalZMin);
5664 fH->SetMaximum(originalZMax);
5665}
5666
5667////////////////////////////////////////////////////////////////////////////////
5668/// [Control function to draw a 2D histogram as a color plot.](#HP14)
5669
5671{
5672 Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5673
5674 Double_t zmin = fH->GetMinimum();
5675 Double_t zmax = fH->GetMaximum();
5676
5677 Double_t dz = zmax - zmin;
5678 if (dz <= 0) { // Histogram filled with a constant value
5679 zmax += 0.1*TMath::Abs(zmax);
5680 zmin -= 0.1*TMath::Abs(zmin);
5681 dz = zmax - zmin;
5682 }
5683
5684 // In case of option SAME, zmin and zmax values are taken from the
5685 // first plotted 2D histogram.
5686 if (Hoption.Same > 0 && Hoption.Same < 10) {
5687 TH2 *h2;
5688 TIter next(gPad->GetListOfPrimitives());
5689 while ((h2 = (TH2 *)next())) {
5690 if (!h2->InheritsFrom(TH2::Class())) continue;
5691 zmin = h2->GetMinimum();
5692 zmax = h2->GetMaximum();
5693 fH->SetMinimum(zmin);
5694 fH->SetMaximum(zmax);
5695 if (Hoption.Logz) {
5696 if (zmin <= 0) {
5697 zmin = TMath::Log10(zmax*0.001);
5698 } else {
5699 zmin = TMath::Log10(zmin);
5700 }
5701 zmax = TMath::Log10(zmax);
5702 }
5703 dz = zmax - zmin;
5704 break;
5705 }
5706 } else {
5707 if (Hoption.Logz) {
5708 if (zmin > 0) {
5709 zmin = TMath::Log10(zmin);
5710 zmax = TMath::Log10(zmax);
5711 dz = zmax - zmin;
5712 } else {
5713 return;
5714 }
5715 }
5716 }
5717
5718 Style_t fillsav = fH->GetFillStyle();
5719 Style_t colsav = fH->GetFillColor();
5720 fH->SetFillStyle(1001);
5721 fH->TAttFill::Modify();
5722
5723 // Initialize the levels on the Z axis
5724 Int_t ncolors = gStyle->GetNumberOfColors();
5725 Int_t ndiv = fH->GetContour();
5726 if (ndiv == 0 ) {
5727 ndiv = gStyle->GetNumberContours();
5728 fH->SetContour(ndiv);
5729 }
5730 Int_t ndivz = TMath::Abs(ndiv);
5731 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5732 Double_t scale = (dz ? ndivz / dz : 1.0);
5733
5734 Int_t color;
5735 TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5736 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5737 yk = fYaxis->GetBinLowEdge(j);
5738 ystep = fYaxis->GetBinWidth(j);
5739 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5740 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5741 xk = fXaxis->GetBinLowEdge(i);
5742 xstep = fXaxis->GetBinWidth(i);
5743 if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5744 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5745 z = fH->GetBinContent(bin);
5746 // if fH is a profile histogram do not draw empty bins
5747 if (prof2d) {
5748 const Double_t binEntries = prof2d->GetBinEntries(bin);
5749 if (binEntries == 0)
5750 continue;
5751 } else {
5752 // don't draw the empty bins for non-profile histograms
5753 // with positive content
5754 if (z == 0) {
5755 if (zmin >= 0 || Hoption.Logz) continue;
5756 if (Hoption.Color == 2) continue;
5757 }
5758 }
5759
5760 if (Hoption.Logz) {
5761 if (z > 0) z = TMath::Log10(z);
5762 else z = zmin;
5763 }
5764 if (z < zmin && !Hoption.Zero) continue;
5765 xup = xk + xstep;
5766 xlow = xk;
5767 if (Hoption.Logx) {
5768 if (xup > 0) xup = TMath::Log10(xup);
5769 else continue;
5770 if (xlow > 0) xlow = TMath::Log10(xlow);
5771 else continue;
5772 }
5773 yup = yk + ystep;
5774 ylow = yk;
5775 if (Hoption.System != kPOLAR) {
5776 if (Hoption.Logy) {
5777 if (yup > 0) yup = TMath::Log10(yup);
5778 else continue;
5779 if (ylow > 0) ylow = TMath::Log10(ylow);
5780 else continue;
5781 }
5782 if (xup < gPad->GetUxmin()) continue;
5783 if (yup < gPad->GetUymin()) continue;
5784 if (xlow > gPad->GetUxmax()) continue;
5785 if (ylow > gPad->GetUymax()) continue;
5786 if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5787 if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5788 if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5789 if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5790 }
5791
5793 zc = fH->GetContourLevelPad(0);
5794 if (z < zc) continue;
5795 color = -1;
5796 for (Int_t k=0; k<ndiv; k++) {
5797 zc = fH->GetContourLevelPad(k);
5798 if (z < zc) {
5799 continue;
5800 } else {
5801 color++;
5802 }
5803 }
5804 } else {
5805 color = Int_t(0.01+(z-zmin)*scale);
5806 }
5807
5808 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5809 if (theColor > ncolors-1) theColor = ncolors-1;
5811 fH->TAttFill::Modify();
5812 if (Hoption.System != kPOLAR) {
5813 gPad->PaintBox(xlow, ylow, xup, yup);
5814 } else {
5815 TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5816 crown.SetFillColor(gStyle->GetColorPalette(theColor));
5817 crown.Paint();
5818 }
5819 }
5820 }
5821
5823
5824 fH->SetFillStyle(fillsav);
5825 fH->SetFillColor(colsav);
5826 fH->TAttFill::Modify();
5827
5828}
5829
5830////////////////////////////////////////////////////////////////////////////////
5831/// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5832
5834{
5835
5836 Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5837 Int_t itars, mode, ir[4];
5838 Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5839
5840 if (Hoption.Contour == 14) {
5841 Hoption.Surf = 12;
5842 Hoption.Axis = 1;
5843 thesave = gPad->GetTheta();
5844 phisave = gPad->GetPhi();
5845 gPad->SetPhi(0.);
5846 gPad->SetTheta(90.);
5847 PaintSurface(option);
5848 gPad->SetPhi(phisave);
5849 gPad->SetTheta(thesave);
5850 TView *view = gPad->GetView();
5851 if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5852 PaintAxis();
5853 return;
5854 }
5855
5856 if (Hoption.Same) {
5857 // If the contour is painted on a 3d plot, the contour lines are
5858 // paint in 3d too.
5859 TObject *obj;
5860 TIter next(gPad->GetListOfPrimitives());
5861 while ((obj=next())) {
5862 if (strstr(obj->GetDrawOption(),"surf") ||
5863 strstr(obj->GetDrawOption(),"lego") ||
5864 strstr(obj->GetDrawOption(),"tri")) {
5865 Hoption.Surf = 16;
5866 PaintSurface(option);
5867 return;
5868 }
5869 }
5870 }
5871
5872 if (Hoption.Contour == 15) {
5873 TGraphDelaunay2D *dt = nullptr;
5874 TGraphDelaunay *dtOld = nullptr;
5875 TList *hl = fH->GetListOfFunctions();
5876 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5877 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5878 if (!dt && !dtOld) return;
5879 if (!fGraph2DPainter) {
5880 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5881 else fGraph2DPainter = new TGraph2DPainter(dtOld);
5882 }
5883 fGraph2DPainter->Paint(option);
5884 return;
5885 }
5886
5887 gPad->SetBit(TGraph::kClipFrame);
5888
5889 Double_t *levels = new Double_t[2*kMAXCONTOUR];
5890 Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5891 Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5892 Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5893
5894 Int_t npmax = 0;
5895 for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5896
5897 ncontour = fH->GetContour();
5898 if (ncontour == 0) {
5899 ncontour = gStyle->GetNumberContours();
5900 fH->SetContour(ncontour);
5901 }
5902 if (ncontour > kMAXCONTOUR) {
5903 Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5904 kMAXCONTOUR, ncontour);
5905 ncontour = kMAXCONTOUR-1;
5906 }
5907 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5908
5909 for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5910 Int_t linesav = fH->GetLineStyle();
5911 Int_t colorsav = fH->GetLineColor();
5912 Int_t fillsav = fH->GetFillColor();
5913 if (Hoption.Contour == 13) {
5914 fH->TAttLine::Modify();
5915 }
5916
5917 TPolyLine **polys = 0;
5918 TPolyLine *poly=0;
5919 TObjArray *contours = 0;
5920 TList *list = 0;
5921 TGraph *graph = 0;
5922 Int_t *np = 0;
5923 if (Hoption.Contour == 1) {
5924 np = new Int_t[ncontour];
5925 for (i=0;i<ncontour;i++) np[i] = 0;
5926 polys = new TPolyLine*[ncontour];
5927 for (i=0;i<ncontour;i++) {
5928 polys[i] = new TPolyLine(100);
5929 }
5930 if (Hoption.List == 1) {
5931 contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5932 if (contours) {
5933 gROOT->GetListOfSpecials()->Remove(contours);
5934 count = contours->GetSize();
5935 for (i=0;i<count;i++) {
5936 list = (TList*)contours->At(i);
5937 if (list) list->Delete();
5938 }
5939 }
5940 contours = new TObjArray(ncontour);
5941 contours->SetName("contours");
5942 gROOT->GetListOfSpecials()->Add(contours);
5943 for (i=0;i<ncontour;i++) {
5944 list = new TList();
5945 contours->Add(list);
5946 }
5947 }
5948 }
5949 Int_t theColor;
5950 Int_t ncolors = gStyle->GetNumberOfColors();
5951 Int_t ndivz = TMath::Abs(ncontour);
5952
5953 Int_t k,ipoly;
5954 for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5955 y[0] = fYaxis->GetBinCenter(j);
5956 y[1] = y[0];
5957 y[2] = fYaxis->GetBinCenter(j+1);
5958 y[3] = y[2];
5959 for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5960 zc[0] = fH->GetBinContent(i, j);
5961 zc[1] = fH->GetBinContent(i+1, j);
5962 zc[2] = fH->GetBinContent(i+1, j+1);
5963 zc[3] = fH->GetBinContent(i, j+1);
5964 if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5965 if (Hoption.Logz) {
5966 if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5967 else zc[0] = Hparam.zmin;
5968 if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5969 else zc[1] = Hparam.zmin;
5970 if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5971 else zc[2] = Hparam.zmin;
5972 if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5973 else zc[3] = Hparam.zmin;
5974 }
5975 for (k=0;k<4;k++) {
5976 ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5977 }
5978 if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5979 x[0] = fXaxis->GetBinCenter(i);
5980 x[3] = x[0];
5981 x[1] = fXaxis->GetBinCenter(i+1);
5982 x[2] = x[1];
5983 if (zc[0] <= zc[1]) n = 0; else n = 1;
5984 if (zc[2] <= zc[3]) m = 2; else m = 3;
5985 if (zc[n] > zc[m]) n = m;
5986 n++;
5987 lj=1;
5988 for (ix=1;ix<=4;ix++) {
5989 m = n%4 + 1;
5990 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5991 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5992 lj += 2*ljfill;
5993 n = m;
5994 }
5995
5996 if (zc[0] <= zc[1]) n = 0; else n = 1;
5997 if (zc[2] <= zc[3]) m = 2; else m = 3;
5998 if (zc[n] > zc[m]) n = m;
5999 n++;
6000 lj=2;
6001 for (ix=1;ix<=4;ix++) {
6002 if (n == 1) m = 4;
6003 else m = n-1;
6004 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
6005 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
6006 lj += 2*ljfill;
6007 n = m;
6008 }
6009
6010 // Re-order endpoints
6011
6012 count = 0;
6013 for (ix=1; ix<=lj-5; ix +=2) {
6014 //count = 0;
6015 while (itarr[ix-1] != itarr[ix]) {
6016 xsave = xarr[ix];
6017 ysave = yarr[ix];
6018 itars = itarr[ix];
6019 for (jx=ix; jx<=lj-5; jx +=2) {
6020 xarr[jx] = xarr[jx+2];
6021 yarr[jx] = yarr[jx+2];
6022 itarr[jx] = itarr[jx+2];
6023 }
6024 xarr[lj-3] = xsave;
6025 yarr[lj-3] = ysave;
6026 itarr[lj-3] = itars;
6027 if (count > 100) break;
6028 count++;
6029 }
6030 }
6031
6032 if (count > 100) continue;
6033 for (ix=1; ix<=lj-2; ix +=2) {
6034 theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
6035 icol = gStyle->GetColorPalette(theColor);
6036 if (Hoption.Contour == 11) {
6037 fH->SetLineColor(icol);
6038 }
6039 if (Hoption.Contour == 12) {
6040 mode = icol%5;
6041 if (mode == 0) mode = 5;
6042 fH->SetLineStyle(mode);
6043 }
6044 if (Hoption.Contour != 1) {
6045 fH->TAttLine::Modify();
6046 gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
6047 continue;
6048 }
6049
6050 ipoly = itarr[ix-1];
6051 if (ipoly >=0 && ipoly <ncontour) {
6052 poly = polys[ipoly];
6053 poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
6054 poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
6055 np[ipoly] += 2;
6056 if (npmax < np[ipoly]) npmax = np[ipoly];
6057 }
6058 }
6059 } // end of if (ir[0]
6060 } //end of for (i
6061 } //end of for (j
6062
6064 Double_t *xp, *yp;
6065 Int_t nadd,iminus,iplus;
6066 Double_t *xx, *yy;
6067 Int_t istart;
6068 Int_t first = ncontour;
6069 Int_t *polysort = 0;
6070 Int_t contListNb;
6071 if (Hoption.Contour != 1) goto theEND;
6072
6073 //The 2 points line generated above are now sorted/merged to generate
6074 //a list of consecutive points.
6075 // If the option "List" has been specified, the list of points is saved
6076 // in the form of TGraph objects in the ROOT list of special objects.
6077 xmin = gPad->GetUxmin();
6078 ymin = gPad->GetUymin();
6079 xp = new Double_t[2*npmax];
6080 yp = new Double_t[2*npmax];
6081 polysort = new Int_t[ncontour];
6082 //find first positive contour
6083 for (ipoly=0;ipoly<ncontour;ipoly++) {
6084 if (levels[ipoly] >= 0) {first = ipoly; break;}
6085 }
6086 //store negative contours from 0 to minimum, then all positive contours
6087 k = 0;
6088 for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
6089 for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
6090 // we can now draw sorted contours
6091 contListNb = 0;
6092 fH->SetFillStyle(1001);
6093 for (k=0;k<ncontour;k++) {
6094 ipoly = polysort[k];
6095 if (np[ipoly] == 0) continue;
6096 if (Hoption.List) list = (TList*)contours->At(contListNb);
6097 contListNb++;
6098 poly = polys[ipoly];
6099 xx = poly->GetX();
6100 yy = poly->GetY();
6101 istart = 0;
6102 while (1) {
6103 iminus = npmax;
6104 iplus = iminus+1;
6105 xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
6106 xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
6107 xx[istart] = xmin; yy[istart] = ymin;
6108 xx[istart+1] = xmin; yy[istart+1] = ymin;
6109 while (1) {
6110 nadd = 0;
6111 for (i=2;i<np[ipoly];i+=2) {
6112 if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
6113 iplus++;
6114 xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
6115 xx[i] = xmin; yy[i] = ymin;
6116 xx[i+1] = xmin; yy[i+1] = ymin;
6117 nadd++;
6118 }
6119 if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
6120 iminus--;
6121 xp[iminus] = xx[i]; yp[iminus] = yy[i];
6122 xx[i] = xmin; yy[i] = ymin;
6123 xx[i+1] = xmin; yy[i+1] = ymin;
6124 nadd++;
6125 }
6126 }
6127 if (nadd == 0) break;
6128 }
6129 theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
6130 icol = gStyle->GetColorPalette(theColor);
6131 if (ndivz > 1) fH->SetFillColor(icol);
6132 fH->TAttFill::Modify();
6133 gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6134 if (Hoption.List) {
6135 graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6136 graph->SetFillColor(icol);
6137 graph->SetLineWidth(fH->GetLineWidth());
6138 list->Add(graph);
6139 }
6140 //check if more points are left
6141 istart = 0;
6142 for (i=2;i<np[ipoly];i+=2) {
6143 if (xx[i] != xmin && yy[i] != ymin) {
6144 istart = i;
6145 break;
6146 }
6147 }
6148 if (istart == 0) break;
6149 }
6150 }
6151
6152 for (i=0;i<ncontour;i++) delete polys[i];
6153 delete [] polys;
6154 delete [] xp;
6155 delete [] yp;
6156 delete [] polysort;
6157
6158theEND:
6159 gPad->ResetBit(TGraph::kClipFrame);
6161 fH->SetLineStyle(linesav);
6162 fH->SetLineColor(colorsav);
6163 fH->SetFillColor(fillsav);
6164 if (np) delete [] np;
6165 delete [] xarr;
6166 delete [] yarr;
6167 delete [] itarr;
6168 delete [] levels;
6169}
6170
6171////////////////////////////////////////////////////////////////////////////////
6172/// Fill the matrix `xarr` and `yarr` for Contour Plot.
6173
6175 Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
6176 Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
6177{
6178
6179 Bool_t vert;
6180 Double_t tlen, tdif, elev, diff, pdif, xlen;
6181 Int_t n, i, icount;
6182
6183 if (x1 == x2) {
6184 vert = kTRUE;
6185 tlen = y2 - y1;
6186 } else {
6187 vert = kFALSE;
6188 tlen = x2 - x1;
6189 }
6190
6191 n = icont1 +1;
6192 tdif = elev2 - elev1;
6193 i = 0;
6194 icount = 0;
6195 while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
6196 //elev = fH->GetContourLevel(n);
6197 elev = levels[n];
6198 diff = elev - elev1;
6199 pdif = diff/tdif;
6200 xlen = tlen*pdif;
6201 if (vert) {
6202 if (Hoption.Logx)
6203 xarr[i] = TMath::Log10(x1);
6204 else
6205 xarr[i] = x1;
6206 if (Hoption.Logy)
6207 yarr[i] = TMath::Log10(y1 + xlen);
6208 else
6209 yarr[i] = y1 + xlen;
6210 } else {
6211 if (Hoption.Logx)
6212 xarr[i] = TMath::Log10(x1 + xlen);
6213 else
6214 xarr[i] = x1 + xlen;
6215 if (Hoption.Logy)
6216 yarr[i] = TMath::Log10(y1);
6217 else
6218 yarr[i] = y1;
6219 }
6220 itarr[i] = n;
6221 icount++;
6222 i +=2;
6223 n++;
6224 }
6225 return icount;
6226}
6227
6228////////////////////////////////////////////////////////////////////////////////
6229/// [Draw 1D histograms error bars.](#HP09)
6230
6232{
6233
6234 // On iOS, we do not highlight histogram, if it's not picked at the moment
6235 // (but part of histogram (axis or pavestat) was picked, that's why this code
6236 // is called at all. This conditional statement never executes on non-iOS platform.
6237 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
6238
6239 const Int_t kBASEMARKER=8;
6240 Double_t xp, yp, ex1, ex2, ey1, ey2;
6241 Double_t delta;
6242 Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
6243 Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
6245 Double_t logxmin = 0;
6246 Double_t logymin = 0;
6247 Double_t offset = 0.;
6248 Double_t width = 0.;
6249 Int_t i, k, npoints, first, last, fixbin;
6250 Int_t if1 = 0;
6251 Int_t if2 = 0;
6252 Int_t drawmarker, errormarker;
6253 Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
6254
6255 Double_t *xline = 0;
6256 Double_t *yline = 0;
6257 option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
6258 if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
6259 if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
6260 if (Hoption.Error == 10) option0 = 1;
6261 if (Hoption.Error == 11) option1 = 1;
6262 if (Hoption.Error == 12) option2 = 1;
6263 if (Hoption.Error == 13) option3 = 1;
6264 if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
6265 if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
6266 if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
6267 if (option2+option3 == 0) optionE = 1;
6268 if (Hoption.Error == 0) optionE = 0;
6269 if (fXaxis->GetXbins()->fN) fixbin = 0;
6270 else fixbin = 1;
6271
6272 offset = fH->GetBarOffset();
6273 width = fH->GetBarWidth();
6274
6275 errormarker = fH->GetMarkerStyle();
6276 if (optionEX0) {
6277 xerror = 0;
6278 } else {
6279 xerror = gStyle->GetErrorX();
6280 }
6281 symbolsize = fH->GetMarkerSize();
6282 if (errormarker == 1) symbolsize = 0.01;
6283 sbase = symbolsize*kBASEMARKER;
6284 // set the graphics attributes
6285
6286 fH->TAttLine::Modify();
6287 fH->TAttFill::Modify();
6288 fH->TAttMarker::Modify();
6289
6290 // set the first and last bin
6291
6292 Double_t factor = Hparam.factor;
6294 last = Hparam.xlast;
6295 npoints = last - first +1;
6296 xmin = gPad->GetUxmin();
6297 xmax = gPad->GetUxmax();
6298 ymin = gPad->GetUymin();
6299 ymax = gPad->GetUymax();
6300
6301
6302 if (option3) {
6303 xline = new Double_t[2*npoints];
6304 yline = new Double_t[2*npoints];
6305 if (!xline || !yline) {
6306 Error("PaintErrors", "too many points, out of memory");
6307 return;
6308 }
6309 if1 = 1;
6310 if2 = 2*npoints;
6311 }
6312
6313 // compute the offset of the error bars due to the symbol size
6314 s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
6315 s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
6316
6317 // compute size of the lines at the end of the error bars
6318 Int_t dxend = Int_t(gStyle->GetEndErrorSize());
6319 bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6320 bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6321
6322
6323 if (fixbin) {
6324 if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6325 else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6326 } else {
6327 delta = fH->GetBinWidth(first);
6328 xp = fH->GetBinLowEdge(first) + 0.5*delta;
6329 }
6330
6331 // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6332 if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6333 if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6334
6335 // ---------------------- Loop over the points---------------------
6336 for (k=first; k<=last; k++) {
6337
6338 // get the data
6339 // xp = X position of the current point
6340 // yp = Y position of the current point
6341 // ex1 = Low X error
6342 // ex2 = Up X error
6343 // ey1 = Low Y error
6344 // ey2 = Up Y error
6345 // (xi,yi) = Error bars coordinates
6346
6347 // apply offset on errors for bar histograms
6348 Double_t xminTmp = gPad->XtoPad(fXaxis->GetBinLowEdge(k));
6349 Double_t xmaxTmp = gPad->XtoPad(fXaxis->GetBinUpEdge(k));
6350 if (Hoption.Logx) {
6351 xminTmp = TMath::Power(10, xminTmp);
6352 xmaxTmp = TMath::Power(10, xmaxTmp);
6353 }
6354 Double_t w = (xmaxTmp-xminTmp)*width;
6355 xminTmp += offset*(xmaxTmp-xminTmp);
6356 xmaxTmp = xminTmp + w;
6357 xp = (xminTmp+xmaxTmp)/2.;
6358
6359 if (Hoption.Logx) {
6360 if (xp <= 0) goto L30;
6361 if (xp < logxmin) goto L30;
6362 if (xp > TMath::Power(10,xmax)) break;
6363 } else {
6364 if (xp < xmin) goto L30;
6365 if (xp > xmax) break;
6366 }
6367 yp = factor*fH->GetBinContent(k);
6368 if (optionI0 && yp==0) goto L30;
6369 if (fixbin) {
6370 ex1 = xerror*Hparam.xbinsize;
6371 } else {
6372 delta = fH->GetBinWidth(k);
6373 ex1 = xerror*delta;
6374 }
6375 if (fH->GetBinErrorOption() == TH1::kNormal) {
6376 ey1 = factor*fH->GetBinError(k);
6377 ey2 = ey1;
6378 } else {
6379 ey1 = factor*fH->GetBinErrorLow(k);
6380 ey2 = factor*fH->GetBinErrorUp(k);
6381 }
6382 ex2 = ex1;
6383
6384 xi4 = xp;
6385 xi3 = xp;
6386 xi2 = xp + ex2;
6387 xi1 = xp - ex1;
6388
6389 yi1 = yp;
6390 yi2 = yp;
6391 yi3 = yp - ey1;
6392 yi4 = yp + ey2;
6393
6394 // take the LOG if necessary
6395 if (Hoption.Logx) {
6396 xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6397 xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6398 xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6399 xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6400 }
6401 if (Hoption.Logy) {
6402 yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6403 yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6404 yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6405 yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6406 }
6407
6408 // test if error bars are not outside the limits
6409 // otherwise they are truncated
6410
6411 xi1 = TMath::Max(xi1,xmin);
6412 xi2 = TMath::Min(xi2,xmax);
6413 yi3 = TMath::Max(yi3,ymin);
6414 yi4 = TMath::Min(yi4,ymax);
6415
6416 // test if the marker is on the frame limits. If "Yes", the
6417 // marker will not be drawn and the error bars will be readjusted.
6418
6419 drawmarker = kTRUE;
6420 if (!option0 && !option3) {
6421 if (Hoption.Logy && yp < logymin) goto L30;
6422 if (yi1 < ymin || yi1 > ymax) goto L30;
6423 if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6424 }
6425 if (!symbolsize || !errormarker) drawmarker = kFALSE;
6426
6427 // draw the error rectangles
6428 if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6429
6430 // keep points for fill area drawing
6431 if (option3) {
6432 xline[if1-1] = xi3;
6433 xline[if2-1] = xi3;
6434 yline[if1-1] = yi4;
6435 yline[if2-1] = yi3;
6436 if1++;
6437 if2--;
6438 }
6439
6440 // draw the error bars
6441 if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6442 if (optionE && drawmarker) {
6443 if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6444 if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6445 // don't duplicate the horizontal line
6446 if (Hoption.Hist != 2) {
6447 if (yi1<ymax && yi1>ymin) {
6448 if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6449 if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6450 }
6451 }
6452 }
6453 if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6454 if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6455 if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6456 // don't duplicate the horizontal line
6457 if (Hoption.Hist != 2) {
6458 if (yi1<ymax && yi1>ymin) {
6459 if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6460 if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6461 }
6462 }
6463 }
6464
6465 // draw line at the end of the error bars
6466
6467 if (option1 && drawmarker) {
6468 if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6469 if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6470 if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6471 if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6472 }
6473
6474 // draw the marker
6475
6476 if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6477
6478L30:
6479 if (fixbin) xp += Hparam.xbinsize;
6480 else {
6481 if (k < last) {
6482 delta = fH->GetBinWidth(k+1);
6483 xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6484 }
6485 }
6486 } //end of for loop
6487
6488 // draw the filled area
6489
6490 if (option3) {
6491 TGraph graph;
6492 graph.SetLineStyle(fH->GetLineStyle());
6493 graph.SetLineColor(fH->GetLineColor());
6494 graph.SetLineWidth(fH->GetLineWidth());
6495 graph.SetFillStyle(fH->GetFillStyle());
6496 graph.SetFillColor(fH->GetFillColor());
6497 Int_t logx = gPad->GetLogx();
6498 Int_t logy = gPad->GetLogy();
6499 gPad->SetLogx(0);
6500 gPad->SetLogy(0);
6501
6502 // In some cases the number of points in the fill area is smaller than
6503 // 2*npoints. In such cases the array xline and yline must be arranged
6504 // before being plotted. The next loop does that.
6505 if (if2 > npoints) {
6506 for (i=1; i<if1; i++) {
6507 xline[if1-2+i] = xline[if2-1+i];
6508 yline[if1-2+i] = yline[if2-1+i];
6509 }
6510 npoints = if1-1;
6511 }
6512 if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6513 else graph.PaintGraph(2*npoints,xline,yline,"F");
6514 gPad->SetLogx(logx);
6515 gPad->SetLogy(logy);
6516 delete [] xline;
6517 delete [] yline;
6518 }
6519}
6520
6521////////////////////////////////////////////////////////////////////////////////
6522/// Draw 2D histograms errors.
6523
6525{
6526
6527 fH->TAttMarker::Modify();
6528 fH->TAttLine::Modify();
6529
6530 // Define the 3D view
6531 fXbuf[0] = Hparam.xmin;
6532 fYbuf[0] = Hparam.xmax;
6533 fXbuf[1] = Hparam.ymin;
6534 fYbuf[1] = Hparam.ymax;
6535 fXbuf[2] = Hparam.zmin;
6536 fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6538 TView *view = gPad->GetView();
6539 if (!view) {
6540 Error("Paint2DErrors", "no TView in current pad");
6541 return;
6542 }
6543 Double_t thedeg = 90 - gPad->GetTheta();
6544 Double_t phideg = -90 - gPad->GetPhi();
6545 Double_t psideg = view->GetPsi();
6546 Int_t irep;
6547 view->SetView(phideg, thedeg, psideg, irep);
6548
6549 // Set color/style for back box
6550 fLego->SetFillStyle(gPad->GetFrameFillStyle());
6551 fLego->SetFillColor(gPad->GetFrameFillColor());
6552 fLego->TAttFill::Modify();
6553 Int_t backcolor = gPad->GetFrameFillColor();
6554 if (Hoption.System != kCARTESIAN) backcolor = 0;
6555 view->PadRange(backcolor);
6558 fLego->TAttFill::Modify();
6559
6560 // Paint the Back Box if needed
6561 if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6562 fLego->InitMoveScreen(-1.1,1.1);
6565 fLego->BackBox(90);
6566 }
6567
6568 // Paint the Errors
6569 Double_t x, ex, x1, x2;
6570 Double_t y, ey, y1, y2;
6571 Double_t z, ez1, ez2, z1, z2;
6572 Double_t temp1[3],temp2[3];
6573 Double_t xyerror;
6574 if (Hoption.Error == 110) {
6575 xyerror = 0;
6576 } else {
6577 xyerror = gStyle->GetErrorX();
6578 }
6579
6580 Double_t xk, xstep, yk, ystep;
6581 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6582 y = fYaxis->GetBinCenter(j);
6583 ey = fYaxis->GetBinWidth(j)*xyerror;
6584 y1 = y-ey;
6585 y2 = y+ey;
6586 if (Hoption.Logy) {
6587 if (y > 0) y = TMath::Log10(y);
6588 else continue;
6589 if (y1 > 0) y1 = TMath::Log10(y1);
6590 else y1 = Hparam.ymin;
6591 if (y2 > 0) y2 = TMath::Log10(y2);
6592 else y2 = Hparam.ymin;
6593 }
6594 yk = fYaxis->GetBinLowEdge(j);
6595 ystep = fYaxis->GetBinWidth(j);
6596 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6597 xk = fXaxis->GetBinLowEdge(i);
6598 xstep = fXaxis->GetBinWidth(i);
6599 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6600 Int_t bin = fH->GetBin(i,j);
6601 x = fXaxis->GetBinCenter(i);
6602 ex = fXaxis->GetBinWidth(i)*xyerror;
6603 x1 = x-ex;
6604 x2 = x+ex;
6605 if (Hoption.Logx) {
6606 if (x > 0) x = TMath::Log10(x);
6607 else continue;
6608 if (x1 > 0) x1 = TMath::Log10(x1);
6609 else x1 = Hparam.xmin;
6610 if (x2 > 0) x2 = TMath::Log10(x2);
6611 else x2 = Hparam.xmin;
6612 }
6613 z = fH->GetBinContent(bin);
6614 if (fH->GetBinErrorOption() == TH1::kNormal) {
6615 ez1 = fH->GetBinError(bin);
6616 ez2 = ez1;
6617 }
6618 else {
6619 ez1 = fH->GetBinErrorLow(bin);
6620 ez2 = fH->GetBinErrorUp(bin);
6621 }
6622 z1 = z - ez1;
6623 z2 = z + ez2;
6624 if (Hoption.Logz) {
6625 if (z > 0) z = TMath::Log10(z);
6626 else z = Hparam.zmin;
6627 if (z1 > 0) z1 = TMath::Log10(z1);
6628 else z1 = Hparam.zmin;
6629 if (z2 > 0) z2 = TMath::Log10(z2);
6630 else z2 = Hparam.zmin;
6631
6632 }
6633 if (z <= Hparam.zmin) continue;
6634 if (z > Hparam.zmax) z = Hparam.zmax;
6635
6636 temp1[0] = x1;
6637 temp1[1] = y;
6638 temp1[2] = z;
6639 temp2[0] = x2;
6640 temp2[1] = y;
6641 temp2[2] = z;
6642 gPad->PaintLine3D(temp1, temp2);
6643 temp1[0] = x;
6644 temp1[1] = y1;
6645 temp1[2] = z;
6646 temp2[0] = x;
6647 temp2[1] = y2;
6648 temp2[2] = z;
6649 gPad->PaintLine3D(temp1, temp2);
6650 temp1[0] = x;
6651 temp1[1] = y;
6652 temp1[2] = z1;
6653 temp2[0] = x;
6654 temp2[1] = y;
6655 temp2[2] = z2;
6656 gPad->PaintLine3D(temp1, temp2);
6657 temp1[0] = x;
6658 temp1[1] = y;
6659 temp1[2] = z;
6660 view->WCtoNDC(temp1, &temp2[0]);
6661 gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6662 }
6663 }
6664
6665 // Paint the Front Box if needed
6666 if (Hoption.FrontBox) {
6667 fLego->InitMoveScreen(-1.1,1.1);
6669 fLego->FrontBox(90);
6670 }
6671
6672 // Paint the Axis if needed
6673 if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6674 TGaxis *axis = new TGaxis();
6675 PaintLegoAxis(axis, 90);
6676 delete axis;
6677 }
6678
6679 delete fLego; fLego = 0;
6680}
6681
6682////////////////////////////////////////////////////////////////////////////////
6683/// Calculate range and clear pad (canvas).
6684
6686{
6687
6688 if (Hoption.Same) return;
6689
6691
6692 if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6693 Hoption.Contour == 14 || Hoption.Error >= 100) {
6694 TObject *frame = gPad->FindObject("TFrame");
6695 if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6696 return;
6697 }
6698
6699 //The next statement is always executed on non-iOS platform,
6700 //on iOS depends on pad mode.
6701 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6702 gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6703}
6704
6705////////////////////////////////////////////////////////////////////////////////
6706/// [Paint functions associated to an histogram.](#HP28")
6707
6709{
6710
6712 TObject *obj;
6713
6714 while (lnk) {
6715 obj = lnk->GetObject();
6716 TVirtualPad *padsave = gPad;
6717 if (obj->InheritsFrom(TF2::Class())) {
6718 if (obj->TestBit(TF2::kNotDraw) == 0) {
6719 if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6720 TF2 *f2 = (TF2*)obj;
6721 f2->SetMinimum(fH->GetMinimum());
6722 f2->SetMaximum(fH->GetMaximum());
6723 f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6724 f2->Paint("surf same");
6725 } else {
6726 obj->Paint("cont3 same");
6727 }
6728 }
6729 } else if (obj->InheritsFrom(TF1::Class())) {
6730 if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6731 } else {
6732 //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6733 gPad->PushSelectableObject(obj);
6734
6735 //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6736 //and picked object.
6737 if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6738 obj->Paint(lnk->GetOption());
6739 }
6740 lnk = (TObjOptLink*)lnk->Next();
6741 padsave->cd();
6742 }
6743}
6744
6745////////////////////////////////////////////////////////////////////////////////
6746/// [Control routine to draw 1D histograms](#HP01b)
6747
6749{
6750
6751 //On iOS: do not highlight hist, if part of it was selected.
6752 //Never executes on non-iOS platform.
6753 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6754 return;
6755
6756 static char chopth[17];
6757
6758 Int_t htype, oldhtype;
6759 Int_t i, j, first, last, nbins, fixbin;
6760 Double_t c1, yb;
6761 yb = 0;
6762
6763 strlcpy(chopth, " ",17);
6764
6767 Double_t baroffset = fH->GetBarOffset();
6768 Double_t barwidth = fH->GetBarWidth();
6769 Double_t baroffsetsave = gStyle->GetBarOffset();
6770 Double_t barwidthsave = gStyle->GetBarWidth();
6771 gStyle->SetBarOffset(baroffset);
6772 gStyle->SetBarWidth(barwidth);
6773
6774 // Create "LIFE" structure to keep current histogram status
6775
6777 last = Hparam.xlast;
6778 nbins = last - first + 1;
6779
6780 Double_t *keepx = 0;
6781 Double_t *keepy = 0;
6782 if (fXaxis->GetXbins()->fN) fixbin = 0;
6783 else fixbin = 1;
6784 if (fixbin) keepx = new Double_t[2];
6785 else keepx = new Double_t[nbins+1];
6786 keepy = new Double_t[nbins];
6787 Double_t logymin = 0;
6788 if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6789
6790 // Loop on histogram bins
6791
6792 for (j=first; j<=last;j++) {
6794 if (TMath::Abs(ymax-ymin) > 0) {
6795 if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6796 else yb = c1;
6797 }
6798 if (!Hoption.Line) {
6799 yb = TMath::Max(yb, ymin);
6800 yb = TMath::Min(yb, ymax);
6801 }
6802 keepy[j-first] = yb;
6803 }
6804
6805 // Draw histogram according to value of FillStyle and FillColor
6806
6807 if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6808 else {
6809 for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6810 keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6811 }
6812
6813 // Prepare Fill area (systematic with option "Bar").
6814
6815 oldhtype = fH->GetFillStyle();
6816 htype = oldhtype;
6817 if (Hoption.Bar) {
6818 if (htype == 0 || htype == 1000) htype = 1001;
6819 }
6820
6821 Width_t lw = (Width_t)fH->GetLineWidth();
6822
6823 // Code option for GrapHist
6824
6825 if (Hoption.Line) chopth[0] = 'L';
6826 if (Hoption.Star) chopth[1] = '*';
6827 if (Hoption.Mark) chopth[2] = 'P';
6828 if (Hoption.Mark == 10) chopth[3] = '0';
6830 if (Hoption.Curve) chopth[3] = 'C';
6831 if (Hoption.Hist > 0) chopth[4] = 'H';
6832 else if (Hoption.Bar) chopth[5] = 'B';
6833 if (fH->GetFillColor() && htype) {
6834 if (Hoption.Logy) {
6835 chopth[6] = '1';
6836 }
6837 if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6838 chopth[7] = 'F';
6839 }
6840 }
6841 }
6842 if (!fixbin && strlen(chopth)) {
6843 chopth[8] = 'N';
6844 }
6845
6846 if (Hoption.Fill == 2) chopth[13] = '2';
6847
6848 // Option LOGX
6849
6850 if (Hoption.Logx) {
6851 chopth[9] = 'G';
6852 chopth[10] = 'X';
6853 if (fixbin) {
6854 keepx[0] = TMath::Power(10,keepx[0]);
6855 keepx[1] = TMath::Power(10,keepx[1]);
6856 }
6857 }
6858
6859 if (Hoption.Off) {
6860 chopth[11] = ']';
6861 chopth[12] = '[';
6862 }
6863
6864 // Draw the histogram
6865
6866 TGraph graph;
6867 graph.SetLineWidth(lw);
6868 graph.SetLineStyle(fH->GetLineStyle());
6869 graph.SetLineColor(fH->GetLineColor());
6870 graph.SetFillStyle(htype);
6871 graph.SetFillColor(fH->GetFillColor());
6872 graph.SetMarkerStyle(fH->GetMarkerStyle());
6873 graph.SetMarkerSize(fH->GetMarkerSize());
6874 graph.SetMarkerColor(fH->GetMarkerColor());
6875 if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6876
6877 graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6878
6879 delete [] keepx;
6880 delete [] keepy;
6881 gStyle->SetBarOffset(baroffsetsave);
6882 gStyle->SetBarWidth(barwidthsave);
6883
6884 htype=oldhtype;
6885}
6886
6887////////////////////////////////////////////////////////////////////////////////
6888/// [Control function to draw a 3D histograms.](#HP01d)
6889
6891{
6892
6893 char *cmd;
6894 TString opt = option;
6895 opt.ToLower();
6896 Int_t irep;
6897
6898 if (fCurrentF3) {
6899 PaintTF3();
6900 return;
6901 } else if (Hoption.Box || Hoption.Lego) {
6902 if (Hoption.Box == 11 || Hoption.Lego == 11) {
6903 PaintH3Box(1);
6904 } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
6905 PaintH3Box(2);
6906 } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
6907 PaintH3Box(3);
6908 } else {
6910 }
6911 return;
6912 } else if (strstr(opt,"iso")) {
6913 PaintH3Iso();
6914 return;
6915 } else if (strstr(opt,"tf3")) {
6916 PaintTF3();
6917 return;
6918 } else {
6919 cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6920 }
6921
6922 if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6923 if (strstr(opt,"bb")) Hoption.BackBox = 0;
6924
6925 TView *view = gPad->GetView();
6926 if (!view) return;
6927 Double_t thedeg = 90 - gPad->GetTheta();
6928 Double_t phideg = -90 - gPad->GetPhi();
6929 Double_t psideg = view->GetPsi();
6930 view->SetView(phideg, thedeg, psideg, irep);
6931
6932 // Paint the data
6933 gROOT->ProcessLine(cmd);
6934
6935 if (Hoption.Same) return;
6936
6937 // Draw axis
6938 view->SetOutlineToCube();
6939 TSeqCollection *ol = view->GetOutline();
6940 if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6942 TGaxis *axis = new TGaxis();
6943 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6944 delete axis;
6945
6946 // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6947 // be painted with the option colz.
6948 if (fH->GetDrawOption() && strstr(opt,"colz")) {
6949 Int_t ndiv = fH->GetContour();
6950 if (ndiv == 0 ) {
6951 ndiv = gStyle->GetNumberContours();
6952 fH->SetContour(ndiv);
6953 }
6954 PaintPalette();
6955 }
6956
6957 // Draw title
6958 PaintTitle();
6959
6960 //Draw stats and fit results
6961 TF1 *fit = 0;
6962 TIter next(fFunctions);
6963 TObject *obj;
6964 while ((obj = next())) {
6965 if (obj->InheritsFrom(TF1::Class())) {
6966 fit = (TF1*)obj;
6967 break;
6968 }
6969 }
6970 if ((Hoption.Same%10) != 1) {
6971 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6973 }
6974 }
6975
6976}
6977
6978////////////////////////////////////////////////////////////////////////////////
6979/// Compute histogram parameters used by the drawing routines.
6980
6982{
6983
6984 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6985
6986 Int_t i;
6987 static const char *where = "PaintInit";
6988 Double_t yMARGIN = gStyle->GetHistTopMargin();
6989 Int_t maximum = 0;
6990 Int_t minimum = 0;
6991 if (fH->GetMaximumStored() != -1111) maximum = 1;
6992 if (fH->GetMinimumStored() != -1111) minimum = 1;
6993
6994 // Compute X axis parameters
6995
6996 Int_t last = fXaxis->GetLast();
7000 Hparam.xlast = last;
7004
7005 // if log scale in X, replace xmin,max by the log
7006 if (Hoption.Logx) {
7007 if (Hparam.xmax<=0) {
7008 Error(where, "cannot set X axis to log scale");
7009 return 0;
7010 }
7011 if (Hparam.xlowedge <=0 ) {
7012 if (Hoption.Same) {
7013 Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
7014 } else {
7015 for (i=first; i<=last; i++) {
7016 Double_t binLow = fXaxis->GetBinLowEdge(i);
7017 if (binLow>0) {
7018 Hparam.xlowedge = binLow;
7019 break;
7020 }
7021 if (binLow == 0 && fH->GetBinContent(i) !=0) {
7022 Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
7023 break;
7024 }
7025 }
7026 if (Hparam.xlowedge<=0) {
7027 Error(where, "cannot set X axis to log scale");
7028 return 0;
7029 }
7030 }
7032 }
7037 if (Hparam.xlast > last) Hparam.xlast = last;
7039 }
7040
7041 // Compute Y axis parameters
7042 Double_t bigp = TMath::Power(10,32);
7043 Double_t ymax = -bigp;
7044 Double_t ymin = bigp;
7045 Double_t c1, e1;
7046 Double_t xv[1];
7047 Double_t fval;
7048 TObject *f;
7049 TF1 *f1;
7050 Double_t allchan = 0;
7051 Int_t nonNullErrors = 0;
7052 TIter next(fFunctions);
7053 for (i=first; i<=last;i++) {
7054 c1 = fH->GetBinContent(i);
7056 if (Hoption.Logy) {
7057 if (c1 > 0) ymin = TMath::Min(ymin,c1);
7058 } else {
7060 }
7061 if (Hoption.Error) {
7063 e1 = fH->GetBinError(i);
7064 else
7065 e1 = fH->GetBinErrorUp(i);
7066 if (e1 > 0) nonNullErrors++;
7067 ymax = TMath::Max(ymax,c1+e1);
7069 e1 = fH->GetBinErrorLow(i);
7070
7071 if (Hoption.Logy) {
7072 if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
7073 } else {
7074 ymin = TMath::Min(ymin,c1-e1);
7075 }
7076 }
7077 if (Hoption.Func) {
7078 xv[0] = fXaxis->GetBinCenter(i);
7079 while ((f = (TObject*) next())) {
7080 if (f->IsA() == TF1::Class()) {
7081 f1 = (TF1*)f;
7082 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7083 fval = f1->Eval(xv[0],0,0);
7084 if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
7085 ymax = TMath::Max(ymax,fval);
7086 if (Hoption.Logy) {
7087 if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
7088 }
7089 }
7090 }
7091 next.Reset();
7092 }
7093 allchan += c1;
7094 }
7095 if (!nonNullErrors) {
7096 if (Hoption.Error) {
7097 if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
7098 Hoption.Error=0;
7099 }
7100 }
7101
7102
7103 // Take into account maximum , minimum
7104
7105 if (Hoption.Logy && ymin <= 0) {
7106 if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
7107 else ymin = 0.001*ymax;
7108 }
7109
7110 Double_t xm = ymin;
7111 if (maximum) ymax = fH->GetMaximumStored();
7112 if (minimum) xm = fH->GetMinimumStored();
7113 if (Hoption.Logy && xm < 0) {
7114 Error(where, "log scale requested with a negative argument (%f)", xm);
7115 return 0;
7116 } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
7117 ymin = 0.01;
7118 ymax = 10.;
7119 } else {
7120 ymin = xm;
7121 }
7122
7123 if (ymin >= ymax) {
7124 if (Hoption.Logy) {
7125 if (ymax > 0) ymin = 0.001*ymax;
7126 else {
7127 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
7128 return 0;
7129 }
7130 }
7131 else {
7132 if (ymin > 0) {
7133 ymin = 0;
7134 ymax *= 2;
7135 } else if (ymin < 0) {
7136 ymax = 0;
7137 ymin *= 2;
7138 } else {
7139 ymin = 0;
7140 ymax = 1;
7141 }
7142 }
7143 }
7144
7145 // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
7146 if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
7147 ymin = ymin*(1-1E-14);
7148 ymax = ymax*(1+1E-14);
7149 }
7150
7151 // take into account normalization factor
7152 Hparam.allchan = allchan;
7153 Double_t factor = allchan;
7154 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7155 if (allchan) factor /= allchan;
7156 if (factor == 0) factor = 1;
7157 Hparam.factor = factor;
7158 ymax = factor*ymax;
7159 ymin = factor*ymin;
7160 //just in case the norm factor is negative
7161 // this may happen with a positive norm factor and a negative integral !
7162 if (ymax < ymin) {
7163 Double_t temp = ymax;
7164 ymax = ymin;
7165 ymin = temp;
7166 }
7167
7168 // For log scales, histogram coordinates are LOG10(ymin) and
7169 // LOG10(ymax). Final adjustment (if not option "Same"
7170 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7171 // Maximum and Minimum are not defined.
7172 if (Hoption.Logy) {
7173 if (ymin <=0 || ymax <=0) {
7174 Error(where, "Cannot set Y axis to log scale");
7175 return 0;
7176 }
7178 if (!minimum) ymin += TMath::Log10(0.5);
7180 if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
7181 if (!Hoption.Same) {
7182 Hparam.ymin = ymin;
7183 Hparam.ymax = ymax;
7184 }
7185 return 1;
7186 }
7187
7188 // final adjustment of ymin for linear scale.
7189 // if minimum is not set , then ymin is set to zero if >0
7190 // or to ymin - margin if <0.
7191 if (!minimum) {
7192 if (Hoption.MinimumZero) {
7193 if (ymin >= 0) ymin = 0;
7194 else ymin -= yMARGIN*(ymax-ymin);
7195 } else {
7196 Double_t dymin = yMARGIN*(ymax-ymin);
7197 if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
7198 else ymin -= dymin;
7199 }
7200 }
7201
7202 // final adjustment of YMAXI for linear scale (if not option "Same"):
7203 // decrease histogram height to MAX% of allowed height if HMAXIM
7204 // has not been called.
7205 if (!maximum) {
7206 ymax += yMARGIN*(ymax-ymin);
7207 }
7208
7209 Hparam.ymin = ymin;
7210 Hparam.ymax = ymax;
7211 return 1;
7212}
7213
7214////////////////////////////////////////////////////////////////////////////////
7215/// Compute histogram parameters used by the drawing routines for a rotated pad.
7216
7218{
7219
7220 static const char *where = "PaintInitH";
7221 Double_t yMARGIN = gStyle->GetHistTopMargin();
7222 Int_t maximum = 0;
7223 Int_t minimum = 0;
7224 if (fH->GetMaximumStored() != -1111) maximum = 1;
7225 if (fH->GetMinimumStored() != -1111) minimum = 1;
7226
7227 // Compute X axis parameters
7228
7229 Int_t last = fXaxis->GetLast();
7233 Hparam.xlast = last;
7237
7238 // if log scale in Y, replace ymin,max by the log
7239 if (Hoption.Logy) {
7240 if (Hparam.xlowedge <=0 ) {
7243 }
7244 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
7245 Error(where, "cannot set Y axis to log scale");
7246 return 0;
7247 }
7252 if (Hparam.xlast > last) Hparam.xlast = last;
7253 }
7254
7255 // Compute Y axis parameters
7256 Double_t bigp = TMath::Power(10,32);
7257 Double_t xmax = -bigp;
7258 Double_t xmin = bigp;
7259 Double_t c1, e1;
7260 Double_t xv[1];
7261 Double_t fval;
7262 Int_t i;
7263 TObject *f;
7264 TF1 *f1;
7265 Double_t allchan = 0;
7266 TIter next(fFunctions);
7267 for (i=first; i<=last;i++) {
7268 c1 = fH->GetBinContent(i);
7271 if (Hoption.Error) {
7272 e1 = fH->GetBinError(i);
7273 xmax = TMath::Max(xmax,c1+e1);
7274 xmin = TMath::Min(xmin,c1-e1);
7275 }
7276 if (Hoption.Func) {
7277 xv[0] = fXaxis->GetBinCenter(i);
7278 while ((f = (TObject*) next())) {
7279 if (f->IsA() == TF1::Class()) {
7280 f1 = (TF1*)f;
7281 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7282 fval = f1->Eval(xv[0],0,0);
7283 xmax = TMath::Max(xmax,fval);
7284 if (Hoption.Logy) {
7285 if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
7286 }
7287 }
7288 }
7289 next.Reset();
7290 }
7291 allchan += c1;
7292 }
7293
7294 // Take into account maximum , minimum
7295
7296 if (Hoption.Logx && xmin <= 0) {
7297 if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
7298 else xmin = 0.001*xmax;
7299 }
7300 Double_t xm = xmin;
7301 if (maximum) xmax = fH->GetMaximumStored();
7302 if (minimum) xm = fH->GetMinimumStored();
7303 if (Hoption.Logx && xm <= 0) {
7304 Error(where, "log scale requested with zero or negative argument (%f)", xm);
7305 return 0;
7306 }
7307 else xmin = xm;
7308 if (xmin >= xmax) {
7309 if (Hoption.Logx) {
7310 if (xmax > 0) xmin = 0.001*xmax;
7311 else {
7312 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
7313 return 0;
7314 }
7315 }
7316 else {
7317 if (xmin > 0) {
7318 xmin = 0;
7319 xmax *= 2;
7320 } else if (xmin < 0) {
7321 xmax = 0;
7322 xmin *= 2;
7323 } else {
7324 xmin = -1;
7325 xmax = 1;
7326 }
7327 }
7328 }
7329
7330 // take into account normalization factor
7331 Hparam.allchan = allchan;
7332 Double_t factor = allchan;
7333 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7334 if (allchan) factor /= allchan;
7335 if (factor == 0) factor = 1;
7336 Hparam.factor = factor;
7337 xmax = factor*xmax;
7338 xmin = factor*xmin;
7339
7340 // For log scales, histogram coordinates are LOG10(ymin) and
7341 // LOG10(ymax). Final adjustment (if not option "Same"
7342 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7343 // Maximum and Minimum are not defined.
7344 if (Hoption.Logx) {
7345 if (xmin <=0 || xmax <=0) {
7346 Error(where, "Cannot set Y axis to log scale");
7347 return 0;
7348 }
7350 if (!minimum) xmin += TMath::Log10(0.5);
7352 if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7353 if (!Hoption.Same) {
7354 Hparam.xmin = xmin;
7355 Hparam.xmax = xmax;
7356 }
7357 return 1;
7358 }
7359
7360 // final adjustment of ymin for linear scale.
7361 // if minimum is not set , then ymin is set to zero if >0
7362 // or to ymin - margin if <0.
7363 if (!minimum) {
7364 if (xmin >= 0) xmin = 0;
7365 else xmin -= yMARGIN*(xmax-xmin);
7366 }
7367
7368 // final adjustment of YMAXI for linear scale (if not option "Same"):
7369 // decrease histogram height to MAX% of allowed height if HMAXIM
7370 // has not been called.
7371 if (!maximum) {
7372 xmax += yMARGIN*(xmax-xmin);
7373 }
7374 Hparam.xmin = xmin;
7375 Hparam.xmax = xmax;
7376 return 1;
7377}
7378
7379////////////////////////////////////////////////////////////////////////////////
7380/// [Control function to draw a 3D histogram with boxes.](#HP25)
7381
7383{
7384 // Predefined box structure
7385 Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7386 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7387 Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7388 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7389
7390 // Define dimensions of world space
7391 TGaxis *axis = new TGaxis();
7392 TAxis *xaxis = fH->GetXaxis();
7393 TAxis *yaxis = fH->GetYaxis();
7394 TAxis *zaxis = fH->GetZaxis();
7395
7396 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7397 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7398 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7399 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7400 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7401 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7402
7404
7405 // Set view
7406 TView *view = gPad->GetView();
7407 if (!view) {
7408 Error("PaintH3", "no TView in current pad");
7409 return;
7410 }
7411 Double_t thedeg = 90 - gPad->GetTheta();
7412 Double_t phideg = -90 - gPad->GetPhi();
7413 Double_t psideg = view->GetPsi();
7414 Int_t irep;
7415 view->SetView(phideg, thedeg, psideg, irep);
7416
7417 Int_t backcolor = gPad->GetFrameFillColor();
7418 view->PadRange(backcolor);
7419
7420 // Draw back surfaces of frame box
7421 fLego->InitMoveScreen(-1.1,1.1);
7422 if (Hoption.BackBox) {
7425 fLego->BackBox(90);
7426 }
7427
7429
7430 // Define order of drawing
7431 Double_t *tnorm = view->GetTnorm();
7432 if (!tnorm) return;
7433 Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7434 Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7435 Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7436 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7437 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7438 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7439 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7440 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7441 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7442
7443 // Set graphic attributes (colour, style, etc.)
7444 Style_t fillsav = fH->GetFillStyle();
7445 Style_t colsav = fH->GetFillColor();
7446 Style_t coldark = TColor::GetColorDark(colsav);
7447 Style_t colbright = TColor::GetColorBright(colsav);
7448
7449 fH->SetFillStyle(1001);
7450 fH->TAttFill::Modify();
7451 fH->TAttLine::Modify();
7452 Int_t ncolors = gStyle->GetNumberOfColors();
7453 Int_t theColor;
7454
7455 // Create bin boxes and draw
7456 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7459
7460 Double_t pmin[3], pmax[3], sxyz[8][3];
7461 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7462 pmin[0] = xaxis->GetBinLowEdge(ix);
7463 pmax[0] = xaxis->GetBinUpEdge(ix);
7464 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7465 pmin[1] = yaxis->GetBinLowEdge(iy);
7466 pmax[1] = yaxis->GetBinUpEdge(iy);
7467 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7468 pmin[2] = zaxis->GetBinLowEdge(iz);
7469 pmax[2] = zaxis->GetBinUpEdge(iz);
7470 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7471 Bool_t neg = kFALSE;
7472 Int_t n = 5;
7473 if (w<0) {
7474 w = -w;
7475 neg = kTRUE;
7476 }
7477 if (w < wmin) continue;
7478 if (w > wmax) w = wmax;
7479 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7480 if (scale == 0) continue;
7481 for (Int_t i=0; i<3; ++i) {
7482 Double_t c = (pmax[i] + pmin[i])*0.5;
7483 Double_t d = (pmax[i] - pmin[i])*scale;
7484 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7485 sxyz[k][i] = wxyz[k][i]*d + c;
7486 }
7487 }
7488 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7489 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7490 }
7491 Double_t x[8], y[8]; // draw bin box faces
7492 for (Int_t k=0; k<6; ++k) {
7493 for (Int_t i=0; i<4; ++i) {
7494 Int_t iv = iface[k][i];
7495 x[i] = sxyz[iv][0];
7496 y[i] = sxyz[iv][1];
7497 }
7498 x[4] = x[0] ; y[4] = y[0];
7499 if (neg) {
7500 x[5] = x[2] ; y[5] = y[2];
7501 x[6] = x[3] ; y[6] = y[3];
7502 x[7] = x[1] ; y[7] = y[1];
7503 n = 8;
7504 } else {
7505 n = 5;
7506 }
7507 Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7508 if (z <= 0.) continue;
7509 if (iopt == 2) {
7510 theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7512 } else {
7513 if (k == 3 || k == 5) {
7514 fH->SetFillColor(coldark);
7515 } else if (k == 0 || k == 1) {
7516 fH->SetFillColor(colbright);
7517 } else {
7518 fH->SetFillColor(colsav);
7519 }
7520 }
7521 fH->TAttFill::Modify();
7522 gPad->PaintFillArea(4, x, y);
7523 if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7524 }
7525 }
7526 }
7527 }
7528
7529 // Draw front surfaces of frame box
7530 if (Hoption.FrontBox) fLego->FrontBox(90);
7531
7532 // Draw axis and title
7533 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7534 PaintTitle();
7535
7536 // Draw palette. if needed.
7537 if (Hoption.Zscale) {
7538 Int_t ndiv = fH->GetContour();
7539 if (ndiv == 0 ) {
7540 ndiv = gStyle->GetNumberContours();
7541 fH->SetContour(ndiv);
7542 }
7543 PaintPalette();
7544 }
7545
7546 delete axis;
7547 delete fLego; fLego = 0;
7548
7549 fH->SetFillStyle(fillsav);
7550 fH->SetFillColor(colsav);
7551 fH->TAttFill::Modify();
7552}
7553
7554////////////////////////////////////////////////////////////////////////////////
7555/// [Control function to draw a 3D histogram with boxes.](#HP25)
7556
7558{
7559 // Predefined box structure
7560 Double_t wxyz[8][3] = {
7561 {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7562 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7563 };
7564 Int_t iface[6][4] = {
7565 {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7566 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7567 };
7568 Double_t normal[6][3] = {
7569 {0,0,-1}, {0,0,1}, // Z-, Z+
7570 {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7571 };
7572
7573 // Define dimensions of world space
7574 TGaxis *axis = new TGaxis();
7575 TAxis *xaxis = fH->GetXaxis();
7576 TAxis *yaxis = fH->GetYaxis();
7577 TAxis *zaxis = fH->GetZaxis();
7578
7579 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7580 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7581 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7582 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7583 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7584 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7585
7587
7588 // Set view
7589 TView *view = gPad->GetView();
7590 if (!view) {
7591 Error("PaintH3", "no TView in current pad");
7592 return;
7593 }
7594 Double_t thedeg = 90 - gPad->GetTheta();
7595 Double_t phideg = -90 - gPad->GetPhi();
7596 Double_t psideg = view->GetPsi();
7597 Int_t irep;
7598 view->SetView(phideg, thedeg, psideg, irep);
7599
7600 Int_t backcolor = gPad->GetFrameFillColor();
7601 view->PadRange(backcolor);
7602
7603 // Draw front surfaces of frame box
7604 if (Hoption.FrontBox) {
7605 fLego->InitMoveScreen(-1.1,1.1);
7607 }
7608
7609 // Initialize hidden line removal algorithm "raster screen"
7610 fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7611
7612 // Define order of drawing
7613 Double_t *tnorm = view->GetTnorm();
7614 if (!tnorm) return;
7615 Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7616 Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7617 Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7618 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7619 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7620 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7621 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7622 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7623 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7624
7625 // Set line attributes (colour, style, etc.)
7626 fH->TAttLine::Modify();
7627
7628 // Create bin boxes and draw
7629 const Int_t NTMAX = 100;
7630 Double_t tt[NTMAX][2];
7631 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7634 Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7635 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7636 pmin[0] = xaxis->GetBinLowEdge(ix);
7637 pmax[0] = xaxis->GetBinUpEdge(ix);
7638 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7639 pmin[1] = yaxis->GetBinLowEdge(iy);
7640 pmax[1] = yaxis->GetBinUpEdge(iy);
7641 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7642 pmin[2] = zaxis->GetBinLowEdge(iz);
7643 pmax[2] = zaxis->GetBinUpEdge(iz);
7644 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7645 Bool_t neg = kFALSE;
7646 if (w<0) {
7647 w = -w;
7648 neg = kTRUE;
7649 }
7650 if (w < wmin) continue;
7651 if (w > wmax) w = wmax;
7652 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7653 if (scale == 0) continue;
7654 for (Int_t i=0; i<3; ++i) {
7655 Double_t c = (pmax[i] + pmin[i])*0.5;
7656 Double_t d = (pmax[i] - pmin[i])*scale;
7657 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7658 sxyz[k][i] = wxyz[k][i]*d + c;
7659 }
7660 }
7661 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7662 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7663 }
7664 for (Int_t k=0; k<6; ++k) { // draw box faces
7665 Double_t zn;
7666 view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7667 if (zn <= 0) continue;
7668 for (Int_t i=0; i<4; ++i) {
7669 Int_t ip = iface[k][i];
7670 pp[i][0] = sxyz[ip][0];
7671 pp[i][1] = sxyz[ip][1];
7672 }
7673 for (Int_t i=0; i<4; ++i) {
7674 Int_t i1 = i;
7675 Int_t i2 = (i == 3) ? 0 : i + 1;
7676 Int_t nt;
7677 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7678 Double_t xdel = pp[i2][0] - pp[i1][0];
7679 Double_t ydel = pp[i2][1] - pp[i1][1];
7680 Double_t x[2], y[2];
7681 for (Int_t it = 0; it < nt; ++it) {
7682 x[0] = pp[i1][0] + xdel*tt[it][0];
7683 y[0] = pp[i1][1] + ydel*tt[it][0];
7684 x[1] = pp[i1][0] + xdel*tt[it][1];
7685 y[1] = pp[i1][1] + ydel*tt[it][1];
7686 gPad->PaintPolyLine(2, x, y);
7687 }
7688 }
7689 if (neg) {
7690 Int_t i1 = 0;
7691 Int_t i2 = 2;
7692 Int_t nt;
7693 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7694 Double_t xdel = pp[i2][0] - pp[i1][0];
7695 Double_t ydel = pp[i2][1] - pp[i1][1];
7696 Double_t x[2], y[2];
7697 for (Int_t it = 0; it < nt; ++it) {
7698 x[0] = pp[i1][0] + xdel*tt[it][0];
7699 y[0] = pp[i1][1] + ydel*tt[it][0];
7700 x[1] = pp[i1][0] + xdel*tt[it][1];
7701 y[1] = pp[i1][1] + ydel*tt[it][1];
7702 gPad->PaintPolyLine(2, x, y);
7703 }
7704 i1 = 1;
7705 i2 = 3;
7706 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7707 xdel = pp[i2][0] - pp[i1][0];
7708 ydel = pp[i2][1] - pp[i1][1];
7709 for (Int_t it = 0; it < nt; ++it) {
7710 x[0] = pp[i1][0] + xdel*tt[it][0];
7711 y[0] = pp[i1][1] + ydel*tt[it][0];
7712 x[1] = pp[i1][0] + xdel*tt[it][1];
7713 y[1] = pp[i1][1] + ydel*tt[it][1];
7714 gPad->PaintPolyLine(2, x, y);
7715 }
7716 }
7717 fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7718 }
7719 }
7720 }
7721 }
7722
7723 // Draw frame box
7724 if (Hoption.BackBox) {
7727 fLego->BackBox(90);
7728 }
7729
7730 if (Hoption.FrontBox) fLego->FrontBox(90);
7731
7732 // Draw axis and title
7733 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7734 PaintTitle();
7735
7736 delete axis;
7737 delete fLego; fLego = 0;
7738}
7739
7740////////////////////////////////////////////////////////////////////////////////
7741/// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7742
7744{
7745
7746 const Double_t ydiff = 1;
7747 const Double_t yligh1 = 10;
7748 const Double_t qa = 0.15;
7749 const Double_t qd = 0.15;
7750 const Double_t qs = 0.8;
7751 Double_t fmin, fmax;
7752 Int_t i, irep;
7753 Int_t nbcol = 28;
7754 Int_t icol1 = 201;
7755 Int_t ic1 = icol1;
7756 Int_t ic2 = ic1+nbcol;
7757 Int_t ic3 = ic2+nbcol;
7758
7759 TGaxis *axis = new TGaxis();
7760 TAxis *xaxis = fH->GetXaxis();
7761 TAxis *yaxis = fH->GetYaxis();
7762 TAxis *zaxis = fH->GetZaxis();
7763
7764 Int_t nx = fH->GetNbinsX();
7765 Int_t ny = fH->GetNbinsY();
7766 Int_t nz = fH->GetNbinsZ();
7767
7768 Double_t *x = new Double_t[nx];
7769 Double_t *y = new Double_t[ny];
7770 Double_t *z = new Double_t[nz];
7771
7772 for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7773 for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7774 for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7775
7776 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7777 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7778 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7779 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7780 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7781 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7782
7783 Double_t s[3];
7784 s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7785 s[1] = 0.5*s[0];
7786 s[2] = 1.5*s[0];
7787
7789
7790 TView *view = gPad->GetView();
7791 if (!view) {
7792 Error("PaintH3Iso", "no TView in current pad");
7793 delete [] x;
7794 delete [] y;
7795 delete [] z;
7796 return;
7797 }
7798 Double_t thedeg = 90 - gPad->GetTheta();
7799 Double_t phideg = -90 - gPad->GetPhi();
7800 Double_t psideg = view->GetPsi();
7801 view->SetView(phideg, thedeg, psideg, irep);
7802
7803 Int_t backcolor = gPad->GetFrameFillColor();
7804 if (Hoption.System != kCARTESIAN) backcolor = 0;
7805 view->PadRange(backcolor);
7806
7807 Double_t dcol = 0.5/Double_t(nbcol);
7808 TColor *colref = gROOT->GetColor(fH->GetFillColor());
7809 if (!colref) {
7810 delete [] x;
7811 delete [] y;
7812 delete [] z;
7813 return;
7814 }
7815 Float_t r, g, b, hue, light, satur;
7816 colref->GetRGB(r,g,b);
7817 TColor::RGBtoHLS(r,g,b,hue,light,satur);
7818 TColor *acol;
7819 for (Int_t col=0;col<nbcol;col++) {
7820 acol = gROOT->GetColor(col+icol1);
7821 TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7822 if (acol) acol->SetRGB(r, g, b);
7823 }
7824
7825 fLego->InitMoveScreen(-1.1,1.1);
7826
7827 if (Hoption.BackBox) {
7830 fLego->BackBox(90);
7831 }
7832
7833 fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7834 fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7835 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7836 fmin = ydiff*qa;
7837 fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7838 fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7839
7840 fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7841
7842 if (Hoption.FrontBox) {
7843 fLego->InitMoveScreen(-1.1,1.1);
7845 fLego->FrontBox(90);
7846 }
7847 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7848
7849 PaintTitle();
7850
7851 delete axis;
7852 delete fLego; fLego = 0;
7853 delete [] x;
7854 delete [] y;
7855 delete [] z;
7856}
7857
7858////////////////////////////////////////////////////////////////////////////////
7859/// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7860
7862{
7863
7864 Int_t raster = 1;
7865 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7866 Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7867 Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7868 Double_t zmin = Hparam.zmin;
7869 Double_t zmax = Hparam.zmax;
7870 Double_t xlab1 = Hparam.xmin;
7871 Double_t xlab2 = Hparam.xmax;
7872 Double_t ylab1 = Hparam.ymin;
7873 Double_t ylab2 = Hparam.ymax;
7874 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7875 Double_t deltaz = TMath::Abs(zmin);
7876 if (deltaz == 0) deltaz = 1;
7877 if (zmin >= zmax) {
7878 zmin -= 0.5*deltaz;
7879 zmax += 0.5*deltaz;
7880 }
7881 Double_t z1c = zmin;
7882 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7883
7884 // Compute the lego limits and instantiate a lego object
7885 fXbuf[0] = -1;
7886 fYbuf[0] = 1;
7887 fXbuf[1] = -1;
7888 fYbuf[1] = 1;
7889 if (Hoption.System == kPOLAR) {
7890 fXbuf[2] = z1c;
7891 fYbuf[2] = z2c;
7892 } else if (Hoption.System == kCYLINDRICAL) {
7893 if (Hoption.Logy) {
7894 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7895 else fXbuf[2] = 0;
7896 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7897 else fYbuf[2] = 0;
7898 } else {
7899 fXbuf[2] = ylab1;
7900 fYbuf[2] = ylab2;
7901 }
7902 z1c = 0; z2c = 1;
7903 } else if (Hoption.System == kSPHERICAL) {
7904 fXbuf[2] = -1;
7905 fYbuf[2] = 1;
7906 z1c = 0; z2c = 1;
7907 } else if (Hoption.System == kRAPIDITY) {
7908 fXbuf[2] = -1/TMath::Tan(dangle);
7909 fYbuf[2] = 1/TMath::Tan(dangle);
7910 } else {
7911 fXbuf[0] = xlab1;
7912 fYbuf[0] = xlab2;
7913 fXbuf[1] = ylab1;
7914 fYbuf[1] = ylab2;
7915 fXbuf[2] = z1c;
7916 fYbuf[2] = z2c;
7917 raster = 0;
7918 }
7919
7921
7922 Int_t nids = -1;
7923 TH1 * hid = NULL;
7924 Color_t colormain = -1, colordark = -1;
7925 Bool_t drawShadowsInLego1 = kTRUE;
7926
7927 // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7928 if (Hoption.Lego == 13) {
7929 Hoption.Lego = 11;
7930 fLego->SetMesh(0);
7931 }
7932 // LEGO4 is like LEGO1 except no shadows are drawn.
7933 if (Hoption.Lego == 14) {
7934 Hoption.Lego = 11;
7935 drawShadowsInLego1 = kFALSE;
7936 }
7937
7938 // Create axis object
7939
7940 TGaxis *axis = new TGaxis();
7941
7942 // Initialize the levels on the Z axis
7943 Int_t ndiv = fH->GetContour();
7944 if (ndiv == 0 ) {
7945 ndiv = gStyle->GetNumberContours();
7946 fH->SetContour(ndiv);
7947 }
7948 Int_t ndivz = TMath::Abs(ndiv);
7949 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7950
7951 // Initialize colors
7952 if (!fStack) {
7954 } else {
7955 for (Int_t id=0;id<=fStack->GetSize();id++) {
7956 hid = (TH1*)fStack->At((id==0)?id:id-1);
7958 }
7959 }
7960
7961 if (Hoption.Lego == 11) {
7962 nids = 1;
7963 if (fStack) nids = fStack->GetSize();
7964 hid = fH;
7965 for (Int_t id=0;id<=nids;id++) {
7966 if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7967 colormain = hid->GetFillColor();
7968 if (colormain == 1) colormain = 17; //avoid drawing with black
7969 if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7970 else colordark = colormain;
7971 fLego->SetColorMain(colormain,id);
7972 fLego->SetColorDark(colordark,id);
7973 if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7974 if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7975 }
7976 }
7977
7978 // Now ready to draw the lego plot
7979 Int_t irep = 0;
7980
7981 TView *view = gPad->GetView();
7982 if (!view) {
7983 Error("PaintLego", "no TView in current pad");
7984 return;
7985 }
7986
7987 Double_t thedeg = 90 - gPad->GetTheta();
7988 Double_t phideg = -90 - gPad->GetPhi();
7989 Double_t psideg = view->GetPsi();
7990 view->SetView(phideg, thedeg, psideg, irep);
7991
7992 fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7994
7995 // Set color/style for back box
7996 fLego->SetFillStyle(gPad->GetFrameFillStyle());
7997 fLego->SetFillColor(gPad->GetFrameFillColor());
7998 fLego->TAttFill::Modify();
7999
8000 Int_t backcolor = gPad->GetFrameFillColor();
8001 if (Hoption.System != kCARTESIAN) backcolor = 0;
8002 view->PadRange(backcolor);
8003
8006 fLego->TAttFill::Modify();
8007
8009
8010 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8011 else fLego->InitMoveScreen(-1.1,1.1);
8012
8013 if (Hoption.Lego == 19) {
8015 if (Hoption.BackBox) fLego->BackBox(90);
8016 if (Hoption.FrontBox) fLego->FrontBox(90);
8017 if (!Hoption.Axis) PaintLegoAxis(axis, 90);
8018 return;
8019 }
8020
8021 if (Hoption.Lego == 11 || Hoption.Lego == 12) {
8024 fLego->BackBox(90);
8025 }
8026 }
8027
8028 if (Hoption.Lego == 12) DefineColorLevels(ndivz);
8029
8034 if (Hoption.System == kPOLAR) {
8035 if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
8036 if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
8037 if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
8038 } else if (Hoption.System == kCYLINDRICAL) {
8039 if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
8040 if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
8041 if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
8042 } else if (Hoption.System == kSPHERICAL) {
8043 if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
8044 if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
8045 if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
8046 } else if (Hoption.System == kRAPIDITY) {
8047 if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
8048 if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
8049 if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
8050 } else {
8051 if (Hoption.Lego == 1) {
8053 fLego->LegoCartesian(90,nx,ny,"FB");}
8054 if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
8055 if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
8056 }
8057
8058 if (Hoption.Lego == 1 || Hoption.Lego == 11) {
8061 fLego->BackBox(90);
8062 }
8063 }
8064 if (Hoption.System == kCARTESIAN) {
8065 fLego->InitMoveScreen(-1.1,1.1);
8067 if (Hoption.FrontBox) fLego->FrontBox(90);
8068 }
8069 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8071 delete axis;
8072 delete fLego; fLego = 0;
8073}
8074
8075////////////////////////////////////////////////////////////////////////////////
8076/// Draw the axis for legos and surface plots.
8077
8079{
8080
8081 static Double_t epsil = 0.001;
8082
8083 Double_t cosa, sina;
8084 Double_t bmin, bmax;
8085 Double_t r[24] /* was [3][8] */;
8086 Int_t ndivx, ndivy, ndivz, i;
8087 Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
8088 static char chopax[8], chopay[8], chopaz[8];
8089 Int_t ix1, ix2, iy1, iy2, iz1, iz2;
8090 Double_t rad;
8091
8092 TView *view = gPad->GetView();
8093 if (!view) {
8094 Error("PaintLegoAxis", "no TView in current pad");
8095 return;
8096 }
8097
8098 // In polar coordinates, draw a short line going from the external circle
8099 // corresponding to r = 1 up to r = 1.1
8100 if (Hoption.System == kPOLAR) {
8101 r[0] = 1;
8102 r[1] = 0;
8103 r[2] = 0;
8104 view->WCtoNDC(r, x1);
8105 r[0] = 1.1;
8106 r[1] = 0;
8107 r[2] = 0;
8108 view->WCtoNDC(r, x2);
8109 gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
8110 return;
8111 }
8112
8113 if (Hoption.System != kCARTESIAN) return;
8114
8115 rad = TMath::ATan(1.) * 4. /180.;
8116 cosa = TMath::Cos(ang*rad);
8117 sina = TMath::Sin(ang*rad);
8118
8119 view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
8120 for (i = 1; i <= 8; ++i) {
8121 r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
8122 r[i*3 - 2] = av[i*3 - 2]*sina;
8123 r[i*3 - 1] = av[i*3 - 1];
8124 }
8125
8126 view->WCtoNDC(&r[ix1*3 - 3], x1);
8127 view->WCtoNDC(&r[ix2*3 - 3], x2);
8128 view->WCtoNDC(&r[iy1*3 - 3], y1);
8129 view->WCtoNDC(&r[iy2*3 - 3], y2);
8130 view->WCtoNDC(&r[iz1*3 - 3], z1);
8131 view->WCtoNDC(&r[iz2*3 - 3], z2);
8132
8133 view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
8134
8135 Double_t *rmin = view->GetRmin();
8136 Double_t *rmax = view->GetRmax();
8137 if (!rmin || !rmax) return;
8138
8139 // Initialize the axis options
8140 if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
8141 else strlcpy(chopax, "SDH=-",8);
8142 if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
8143 else strlcpy(chopay, "SDH=-",8);
8144 if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
8145 else strlcpy(chopaz, "SDH=-",8);
8146
8147 // Option LOG is required ?
8148 if (Hoption.Logx) strlcat(chopax,"G",8);
8149 if (Hoption.Logy) strlcat(chopay,"G",8);
8150 if (Hoption.Logz) strlcat(chopaz,"G",8);
8151
8152 // Initialize the number of divisions. If the
8153 // number of divisions is negative, option 'N' is required.
8154 ndivx = fXaxis->GetNdivisions();
8155 ndivy = fYaxis->GetNdivisions();
8156 ndivz = fZaxis->GetNdivisions();
8157 if (ndivx < 0) {
8158 ndivx = TMath::Abs(ndivx);
8159 strlcat(chopax, "N",8);
8160 }
8161 if (ndivy < 0) {
8162 ndivy = TMath::Abs(ndivy);
8163 strlcat(chopay, "N",8);
8164 }
8165 if (ndivz < 0) {
8166 ndivz = TMath::Abs(ndivz);
8167 strlcat(chopaz, "N",8);
8168 }
8169
8170 // Set Axis attributes.
8171 // The variable SCALE rescales the VSIZ
8172 // in order to have the same label size for all angles.
8173
8174 axis->SetLineWidth(1);
8175
8176 // X axis drawing
8177 if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
8180 if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
8181 bmin = TMath::Power(10, rmin[0]);
8182 bmax = TMath::Power(10, rmax[0]);
8183 } else {
8184 bmin = rmin[0];
8185 bmax = rmax[0];
8186 }
8187 // Option time display is required ?
8188 if (fXaxis->GetTimeDisplay()) {
8189 strlcat(chopax,"t",8);
8190 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
8191 axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
8192 } else {
8194 }
8195 }
8196 axis->SetOption(chopax);
8197 axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
8198 }
8199
8200 // Y axis drawing
8201 if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
8204 if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
8205
8206 if (fH->GetDimension() < 2) {
8207 strlcpy(chopay, "V=+UN",8);
8208 ndivy = 0;
8209 }
8210 if (TMath::Abs(y1[0] - y2[0]) < epsil) {
8211 y2[0] = y1[0];
8212 }
8213 if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
8214 bmin = TMath::Power(10, rmin[1]);
8215 bmax = TMath::Power(10, rmax[1]);
8216 } else {
8217 bmin = rmin[1];
8218 bmax = rmax[1];
8219 }
8220 // Option time display is required ?
8221 if (fYaxis->GetTimeDisplay()) {
8222 strlcat(chopay,"t",8);
8223 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
8224 axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
8225 } else {
8227 }
8228 }
8229 axis->SetOption(chopay);
8230 axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
8231 }
8232
8233 // Z axis drawing
8234 if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
8236 if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
8237 bmin = TMath::Power(10, rmin[2]);
8238 bmax = TMath::Power(10, rmax[2]);
8239 } else {
8240 bmin = rmin[2];
8241 bmax = rmax[2];
8242 }
8243 // Option time display is required ?
8244 if (fZaxis->GetTimeDisplay()) {
8245 strlcat(chopaz,"t",8);
8246 if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
8247 axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
8248 } else {
8250 }
8251 }
8252 axis->SetOption(chopaz);
8253 axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
8254 }
8255
8256 //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
8257}
8258
8259////////////////////////////////////////////////////////////////////////////////
8260/// [Paint the color palette on the right side of the pad.](#HP22)
8261
8263{
8264
8265 TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
8266 TView *view = gPad->GetView();
8267 if (palette) {
8268 if (view) {
8269 if (!palette->TestBit(TPaletteAxis::kHasView)) {
8270 fFunctions->Remove(palette);
8271 delete palette; palette = 0;
8272 }
8273 } else {
8274 if (palette->TestBit(TPaletteAxis::kHasView)) {
8275 fFunctions->Remove(palette);
8276 delete palette; palette = 0;
8277 }
8278 }
8279 // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
8280 if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
8281 }
8282
8283 if (!palette) {
8284 Double_t xup = gPad->GetUxmax();
8285 Double_t x2 = gPad->PadtoX(gPad->GetX2());
8286 Double_t ymin = gPad->PadtoY(gPad->GetUymin());
8287 Double_t ymax = gPad->PadtoY(gPad->GetUymax());
8288 Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
8289 Double_t xmin = gPad->PadtoX(xup +0.1*xr);
8290 Double_t xmax = gPad->PadtoX(xup + xr);
8291 if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
8292 palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
8293 fFunctions->AddFirst(palette);
8294 palette->Paint();
8295 }
8296}
8297
8298////////////////////////////////////////////////////////////////////////////////
8299/// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
8300
8302{
8303
8304 fH->TAttMarker::Modify();
8305
8306 Int_t k, marker;
8307 Double_t dz, z, xk,xstep, yk, ystep;
8308 Double_t scale = 1;
8309 Bool_t ltest = kFALSE;
8310 Double_t zmax = fH->GetMaximum();
8311 Double_t zmin = fH->GetMinimum();
8312 if (zmin == 0 && zmax == 0) return;
8313 if (zmin == zmax) {
8314 zmax += 0.1*TMath::Abs(zmax);
8315 zmin -= 0.1*TMath::Abs(zmin);
8316 }
8318 if (Hoption.Logz) {
8319 if (zmin > 0) zmin = TMath::Log10(zmin);
8320 else zmin = 0;
8321 if (zmax > 0) zmax = TMath::Log10(zmax);
8322 else zmax = 0;
8323 if (zmin == 0 && zmax == 0) return;
8324 dz = zmax - zmin;
8325 scale = 100/dz;
8326 if (ncells > 10000) scale /= 5;
8327 ltest = kTRUE;
8328 } else {
8329 dz = zmax - zmin;
8330 if (dz >= kNMAX || zmax < 1) {
8331 scale = (kNMAX-1)/dz;
8332 if (ncells > 10000) scale /= 5;
8333 ltest = kTRUE;
8334 }
8335 }
8336 if (fH->GetMinimumStored() == -1111) {
8337 Double_t yMARGIN = gStyle->GetHistTopMargin();
8338 if (Hoption.MinimumZero) {
8339 if (zmin >= 0) zmin = 0;
8340 else zmin -= yMARGIN*(zmax-zmin);
8341 } else {
8342 Double_t dzmin = yMARGIN*(zmax-zmin);
8343 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8344 else zmin -= dzmin;
8345 }
8346 }
8347
8348 TString opt = option;
8349 opt.ToLower();
8350 if (opt.Contains("scat=")) {
8351 char optscat[100];
8352 strlcpy(optscat,opt.Data(),100);
8353 char *oscat = strstr(optscat,"scat=");
8354 char *blank = strstr(oscat," "); if (blank) *blank = 0;
8355 sscanf(oscat+5,"%lg",&scale);
8356 }
8357 // use an independent instance of a random generator
8358 // instead of gRandom to avoid conflicts and
8359 // to get same random numbers when drawing the same histogram
8360 TRandom2 random;
8361 marker=0;
8362 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8363 yk = fYaxis->GetBinLowEdge(j);
8364 ystep = fYaxis->GetBinWidth(j);
8365 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8366 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8367 xk = fXaxis->GetBinLowEdge(i);
8368 xstep = fXaxis->GetBinWidth(i);
8369 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8370 z = fH->GetBinContent(bin);
8371 if (z < zmin) z = zmin;
8372 if (z > zmax) z = zmax;
8373 if (Hoption.Logz) {
8374 if (z > 0) z = TMath::Log10(z) - zmin;
8375 } else {
8376 z -= zmin;
8377 }
8378 if (z <= 0) continue;
8379 k = Int_t(z*scale);
8380 if (ltest) k++;
8381 if (k > 0) {
8382 for (Int_t loop=0; loop<k; loop++) {
8383 if (k+marker >= kNMAX) {
8384 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8385 marker=0;
8386 }
8387 fXbuf[marker] = (random.Rndm()*xstep) + xk;
8388 fYbuf[marker] = (random.Rndm()*ystep) + yk;
8389 if (Hoption.Logx) {
8390 if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8391 else break;
8392 }
8393 if (Hoption.Logy) {
8394 if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8395 else break;
8396 }
8397 if (fXbuf[marker] < gPad->GetUxmin()) break;
8398 if (fYbuf[marker] < gPad->GetUymin()) break;
8399 if (fXbuf[marker] > gPad->GetUxmax()) break;
8400 if (fYbuf[marker] > gPad->GetUymax()) break;
8401 marker++;
8402 }
8403 }
8404 }
8405 }
8406 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8407
8409}
8410
8411////////////////////////////////////////////////////////////////////////////////
8412/// Static function to paint special objects like vectors and matrices.
8413/// This function is called via `gROOT->ProcessLine` to paint these objects
8414/// without having a direct dependency of the graphics or histogramming
8415/// system.
8416
8418{
8419
8420 if (!obj) return;
8423
8424 if (obj->InheritsFrom(TMatrixFBase::Class())) {
8425 // case TMatrixF
8426 TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8427 R__TMatrixFBase->SetBit(kCanDelete);
8428 R__TMatrixFBase->Draw(option);
8429
8430 } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8431 // case TMatrixD
8432 TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8433 R__TMatrixDBase->SetBit(kCanDelete);
8434 R__TMatrixDBase->Draw(option);
8435
8436 } else if (obj->InheritsFrom(TVectorF::Class())) {
8437 //case TVectorF
8438 TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8439 R__TVectorF->SetBit(kCanDelete);
8440 R__TVectorF->Draw(option);
8441
8442 } else if (obj->InheritsFrom(TVectorD::Class())) {
8443 //case TVectorD
8444 TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8445 R__TVectorD->SetBit(kCanDelete);
8446 R__TVectorD->Draw(option);
8447 }
8448
8449 TH1::AddDirectory(status);
8450}
8451
8452////////////////////////////////////////////////////////////////////////////////
8453/// [Draw the statistics box for 1D and profile histograms.](#HP07)
8454
8456{
8457
8458 TString tt, tf;
8459 Int_t dofit;
8460 TPaveStats *stats = 0;
8461 TIter next(fFunctions);
8462 TObject *obj;
8463 while ((obj = next())) {
8464 if (obj->InheritsFrom(TPaveStats::Class())) {
8465 stats = (TPaveStats*)obj;
8466 break;
8467 }
8468 }
8469
8470 if (stats && dostat) {
8471 dofit = stats->GetOptFit();
8472 dostat = stats->GetOptStat();
8473 } else {
8474 dofit = gStyle->GetOptFit();
8475 }
8476 if (!dofit) fit = 0;
8477 if (dofit == 1) dofit = 111;
8478 if (dostat == 1) dostat = 1111;
8479 Int_t print_name = dostat%10;
8480 Int_t print_entries = (dostat/10)%10;
8481 Int_t print_mean = (dostat/100)%10;
8482 Int_t print_stddev = (dostat/1000)%10;
8483 Int_t print_under = (dostat/10000)%10;
8484 Int_t print_over = (dostat/100000)%10;
8485 Int_t print_integral= (dostat/1000000)%10;
8486 Int_t print_skew = (dostat/10000000)%10;
8487 Int_t print_kurt = (dostat/100000000)%10;
8488 Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8489 print_under + print_over + print_integral +
8490 print_skew + print_kurt;
8491 Int_t print_fval = dofit%10;
8492 Int_t print_ferrors = (dofit/10)%10;
8493 Int_t print_fchi2 = (dofit/100)%10;
8494 Int_t print_fprob = (dofit/1000)%10;
8495 Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8496 if (fit) {
8497 if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8498 else nlinesf += fit->GetNpar();
8499 }
8500 if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8501
8502 // Pavetext with statistics
8503 Bool_t done = kFALSE;
8504 if (!dostat && !fit) {
8505 if (stats) { fFunctions->Remove(stats); delete stats;}
8506 return;
8507 }
8508 Double_t statw = gStyle->GetStatW();
8509 if (fit) statw = 1.8*gStyle->GetStatW();
8510 Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8511 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8512 stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8513 }
8514 if (stats) {
8515 stats->Clear();
8516 done = kTRUE;
8517 } else {
8518 stats = new TPaveStats(
8519 gStyle->GetStatX()-statw,
8520 gStyle->GetStatY()-stath,
8521 gStyle->GetStatX(),
8522 gStyle->GetStatY(),"brNDC");
8523
8524 stats->SetParent(fH);
8525 stats->SetOptFit(dofit);
8526 stats->SetOptStat(dostat);
8527 stats->SetFillColor(gStyle->GetStatColor());
8528 stats->SetFillStyle(gStyle->GetStatStyle());
8530 stats->SetTextFont(gStyle->GetStatFont());
8531 if (gStyle->GetStatFont()%10 > 2)
8533 stats->SetFitFormat(gStyle->GetFitFormat());
8535 stats->SetName("stats");
8536
8538 stats->SetTextAlign(12);
8539 stats->SetBit(kCanDelete);
8540 stats->SetBit(kMustCleanup);
8541 }
8542 if (print_name) stats->AddText(fH->GetName());
8543 if (print_entries) {
8544 if (fH->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8545 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8546 stats->AddText(tt.Data());
8547 }
8548 if (print_mean) {
8549 if (print_mean == 1) {
8550 tf.Form("%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8551 tt.Form(tf.Data(),fH->GetMean(1));
8552 } else {
8553 tf.Form("%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8554 ,"%",stats->GetStatFormat());
8555 tt.Form(tf.Data(),fH->GetMean(1),fH->GetMeanError(1));
8556 }
8557 stats->AddText(tt.Data());
8559 if (print_mean == 1) {
8560 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8561 tt.Form(tf.Data(),fH->GetMean(2));
8562 } else {
8563 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8564 ,"%",stats->GetStatFormat());
8565 tt.Form(tf.Data(),fH->GetMean(2),fH->GetMeanError(2));
8566 }
8567 stats->AddText(tt.Data());
8568 }
8569 }
8570 if (print_stddev) {
8571 if (print_stddev == 1) {
8572 tf.Form("%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8573 tt.Form(tf.Data(),fH->GetStdDev(1));
8574 } else {
8575 tf.Form("%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8576 ,"%",stats->GetStatFormat());
8577 tt.Form(tf.Data(),fH->GetStdDev(1),fH->GetStdDevError(1));
8578 }
8579 stats->AddText(tt.Data());
8581 if (print_stddev == 1) {
8582 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8583 tt.Form(tf.Data(),fH->GetStdDev(2));
8584 } else {
8585 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8586 ,"%",stats->GetStatFormat());
8587 tt.Form(tf.Data(),fH->GetStdDev(2),fH->GetStdDevError(2));
8588 }
8589 stats->AddText(tt.Data());
8590 }
8591 }
8592 if (print_under) {
8593 tf.Form("%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8594 tt.Form(tf.Data(),fH->GetBinContent(0));
8595 stats->AddText(tt.Data());
8596 }
8597 if (print_over) {
8598 tf.Form("%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8599 tt.Form(tf.Data(),fH->GetBinContent(fXaxis->GetNbins()+1));
8600 stats->AddText(tt.Data());
8601 }
8602 if (print_integral) {
8603 if (print_integral == 1) {
8604 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8605 tt.Form(tf.Data(),fH->Integral());
8606 } else {
8607 tf.Form("%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8608 tt.Form(tf.Data(),fH->Integral("width"));
8609 }
8610 stats->AddText(tt.Data());
8611 }
8612 if (print_skew) {
8613 if (print_skew == 1) {
8614 tf.Form("%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8615 tt.Form(tf.Data(),fH->GetSkewness(1));
8616 } else {
8617 tf.Form("%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8618 ,"%",stats->GetStatFormat());
8619 tt.Form(tf.Data(),fH->GetSkewness(1),fH->GetSkewness(11));
8620 }
8621 stats->AddText(tt.Data());
8622 }
8623 if (print_kurt) {
8624 if (print_kurt == 1) {
8625 tf.Form("%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8626 tt.Form(tf.Data(),fH->GetKurtosis(1));
8627 } else {
8628 tf.Form("%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8629 ,"%",stats->GetStatFormat());
8630 tt.Form(tf.Data(),fH->GetKurtosis(1),fH->GetKurtosis(11));
8631 }
8632 stats->AddText(tt.Data());
8633 }
8634
8635 // Draw Fit parameters
8636 if (fit) {
8637 Int_t ndf = fit->GetNDF();
8638 tf.Form("#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8639 tt.Form(tf.Data(),(Float_t)fit->GetChisquare());
8640 if (print_fchi2) stats->AddText(tt.Data());
8641 if (print_fprob) {
8642 tf.Form("Prob = %s%s","%",stats->GetFitFormat());
8643 tt.Form(tf.Data(),(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8644 stats->AddText(tt.Data());
8645 }
8646 if (print_fval || print_ferrors) {
8647 Double_t parmin,parmax;
8648 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8649 fit->GetParLimits(ipar,parmin,parmax);
8650 if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8651 if (print_ferrors) {
8652 tf.Form("%-8s = %s%s #pm %s ", fit->GetParName(ipar), "%",stats->GetFitFormat(),
8653 GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8654 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar)
8655 ,(Float_t)fit->GetParError(ipar));
8656 } else {
8657 tf.Form("%-8s = %s%s ",fit->GetParName(ipar), "%",stats->GetFitFormat());
8658 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar));
8659 }
8660 stats->AddText(tt.Data());
8661 }
8662 }
8663 }
8664
8665 if (!done) fFunctions->Add(stats);
8666 stats->Paint();
8667}
8668
8669////////////////////////////////////////////////////////////////////////////////
8670/// [Draw the statistics box for 2D histograms.](#HP07)
8671
8673{
8674
8675 if (fH->GetDimension() != 2) return;
8676 TH2 *h2 = (TH2*)fH;
8677
8678 TString tt, tf;
8679 Int_t dofit;
8680 TPaveStats *stats = 0;
8681 TIter next(fFunctions);
8682 TObject *obj;
8683 while ((obj = next())) {
8684 if (obj->InheritsFrom(TPaveStats::Class())) {
8685 stats = (TPaveStats*)obj;
8686 break;
8687 }
8688 }
8689 if (stats && dostat) {
8690 dofit = stats->GetOptFit();
8691 dostat = stats->GetOptStat();
8692 } else {
8693 dofit = gStyle->GetOptFit();
8694 }
8695 if (dostat == 1) dostat = 1111;
8696 Int_t print_name = dostat%10;
8697 Int_t print_entries = (dostat/10)%10;
8698 Int_t print_mean = (dostat/100)%10;
8699 Int_t print_stddev = (dostat/1000)%10;
8700 Int_t print_under = (dostat/10000)%10;
8701 Int_t print_over = (dostat/100000)%10;
8702 Int_t print_integral= (dostat/1000000)%10;
8703 Int_t print_skew = (dostat/10000000)%10;
8704 Int_t print_kurt = (dostat/100000000)%10;
8705 Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8706 if (print_under || print_over) nlines += 3;
8707
8708 // Pavetext with statistics
8709 if (!gStyle->GetOptFit()) fit = 0;
8710 Bool_t done = kFALSE;
8711 if (!dostat && !fit) {
8712 if (stats) { fFunctions->Remove(stats); delete stats;}
8713 return;
8714 }
8715 Double_t statw = gStyle->GetStatW();
8716 if (fit) statw = 1.8*gStyle->GetStatW();
8717 Double_t stath = nlines*gStyle->GetStatFontSize();
8718 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8719 stath = 0.25*nlines*gStyle->GetStatH();
8720 }
8721 if (fit) stath += gStyle->GetStatH();
8722 if (stats) {
8723 stats->Clear();
8724 done = kTRUE;
8725 } else {
8726 stats = new TPaveStats(
8727 gStyle->GetStatX()-statw,
8728 gStyle->GetStatY()-stath,
8729 gStyle->GetStatX(),
8730 gStyle->GetStatY(),"brNDC");
8731
8732 stats->SetParent(fH);
8733 stats->SetOptFit(dofit);
8734 stats->SetOptStat(dostat);
8735 stats->SetFillColor(gStyle->GetStatColor());
8736 stats->SetFillStyle(gStyle->GetStatStyle());
8738 stats->SetName("stats");
8739
8741 stats->SetTextAlign(12);
8742 stats->SetTextFont(gStyle->GetStatFont());
8743 if (gStyle->GetStatFont()%10 > 2)
8745 stats->SetFitFormat(gStyle->GetFitFormat());
8747 stats->SetBit(kCanDelete);
8748 stats->SetBit(kMustCleanup);
8749 }
8750 if (print_name) stats->AddText(h2->GetName());
8751 if (print_entries) {
8752 if (h2->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8753 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8754 stats->AddText(tt.Data());
8755 }
8756 if (print_mean) {
8757 if (print_mean == 1) {
8758 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8759 tt.Form(tf.Data(),h2->GetMean(1));
8760 stats->AddText(tt.Data());
8761 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8762 tt.Form(tf.Data(),h2->GetMean(2));
8763 stats->AddText(tt.Data());
8764 } else {
8765 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8766 ,"%",stats->GetStatFormat());
8767 tt.Form(tf.Data(),h2->GetMean(1),h2->GetMeanError(1));
8768 stats->AddText(tt.Data());
8769 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8770 ,"%",stats->GetStatFormat());
8771 tt.Form(tf.Data(),h2->GetMean(2),h2->GetMeanError(2));
8772 stats->AddText(tt.Data());
8773 }
8774 }
8775 if (print_stddev) {
8776 if (print_stddev == 1) {
8777 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8778 tt.Form(tf.Data(),h2->GetStdDev(1));
8779 stats->AddText(tt.Data());
8780 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8781 tt.Form(tf.Data(),h2->GetStdDev(2));
8782 stats->AddText(tt.Data());
8783 } else {
8784 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8785 ,"%",stats->GetStatFormat());
8786 tt.Form(tf.Data(),h2->GetStdDev(1),h2->GetStdDevError(1));
8787 stats->AddText(tt.Data());
8788 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8789 ,"%",stats->GetStatFormat());
8790 tt.Form(tf.Data(),h2->GetStdDev(2),h2->GetStdDevError(2));
8791 stats->AddText(tt.Data());
8792 }
8793 }
8794 if (print_integral) {
8795 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8796 tt.Form(tf.Data(),fH->Integral());
8797 stats->AddText(tt.Data());
8798 }
8799 if (print_skew) {
8800 if (print_skew == 1) {
8801 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8802 tt.Form(tf.Data(),h2->GetSkewness(1));
8803 stats->AddText(tt.Data());
8804 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8805 tt.Form(tf.Data(),h2->GetSkewness(2));
8806 stats->AddText(tt.Data());
8807 } else {
8808 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8809 ,"%",stats->GetStatFormat());
8810 tt.Form(tf.Data(),h2->GetSkewness(1),h2->GetSkewness(11));
8811 stats->AddText(tt.Data());
8812 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8813 ,"%",stats->GetStatFormat());
8814 tt.Form(tf.Data(),h2->GetSkewness(2),h2->GetSkewness(12));
8815 stats->AddText(tt.Data());
8816 }
8817 }
8818 if (print_kurt) {
8819 if (print_kurt == 1) {
8820 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8821 tt.Form(tf.Data(),h2->GetKurtosis(1));
8822 stats->AddText(tt.Data());
8823 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8824 tt.Form(tf.Data(),h2->GetKurtosis(2));
8825 stats->AddText(tt.Data());
8826 } else {
8827 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8828 ,"%",stats->GetStatFormat());
8829 tt.Form(tf.Data(),h2->GetKurtosis(1),h2->GetKurtosis(11));
8830 stats->AddText(tt.Data());
8831 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8832 ,"%",stats->GetStatFormat());
8833 tt.Form(tf.Data(),h2->GetKurtosis(2),h2->GetKurtosis(12));
8834 stats->AddText(tt.Data());
8835 }
8836 }
8837 if (print_under || print_over) {
8838 //get 3*3 under/overflows for 2d hist
8839 Double_t unov[9];
8840
8841 Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8842 Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8843 Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8844 Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8845 Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8846 Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8847
8848 unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8849 unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8850 unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8851 unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8852 unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8853 unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8854 unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8855 unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8856 unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8857
8858 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8859 stats->AddText(tt.Data());
8860 if (TMath::Abs(unov[4]) < 1.e7)
8861 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8862 else
8863 tt.Form(" %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8864 stats->AddText(tt.Data());
8865 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8866 stats->AddText(tt.Data());
8867 }
8868
8869 // Draw Fit parameters
8870 if (fit) {
8871 Int_t ndf = fit->GetNDF();
8872 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8873 stats->AddText(tt.Data());
8874 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8875 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8876 ,(Float_t)fit->GetParameter(ipar)
8877 ,(Float_t)fit->GetParError(ipar));
8878 stats->AddText(tt.Data());
8879 }
8880 }
8881
8882 if (!done) fFunctions->Add(stats);
8883 stats->Paint();
8884}
8885
8886////////////////////////////////////////////////////////////////////////////////
8887/// [Draw the statistics box for 3D histograms.](#HP07)
8888
8890{
8891
8892 if (fH->GetDimension() != 3) return;
8893 TH3 *h3 = (TH3*)fH;
8894
8895 TString tt, tf;
8896 Int_t dofit;
8897 TPaveStats *stats = 0;
8898 TIter next(fFunctions);
8899 TObject *obj;
8900 while ((obj = next())) {
8901 if (obj->InheritsFrom(TPaveStats::Class())) {
8902 stats = (TPaveStats*)obj;
8903 break;
8904 }
8905 }
8906 if (stats && dostat) {
8907 dofit = stats->GetOptFit();
8908 dostat = stats->GetOptStat();
8909 } else {
8910 dofit = gStyle->GetOptFit();
8911 }
8912 if (dostat == 1) dostat = 1111;
8913 Int_t print_name = dostat%10;
8914 Int_t print_entries = (dostat/10)%10;
8915 Int_t print_mean = (dostat/100)%10;
8916 Int_t print_stddev = (dostat/1000)%10;
8917 Int_t print_under = (dostat/10000)%10;
8918 Int_t print_over = (dostat/100000)%10;
8919 Int_t print_integral= (dostat/1000000)%10;
8920 Int_t print_skew = (dostat/10000000)%10;
8921 Int_t print_kurt = (dostat/100000000)%10;
8922 Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8923 if (print_under || print_over) nlines += 3;
8924
8925 // Pavetext with statistics
8926 if (!gStyle->GetOptFit()) fit = 0;
8927 Bool_t done = kFALSE;
8928 if (!dostat && !fit) {
8929 if (stats) { fFunctions->Remove(stats); delete stats;}
8930 return;
8931 }
8932 Double_t statw = gStyle->GetStatW();
8933 if (fit) statw = 1.8*gStyle->GetStatW();
8934 Double_t stath = nlines*gStyle->GetStatFontSize();
8935 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8936 stath = 0.25*nlines*gStyle->GetStatH();
8937 }
8938 if (fit) stath += gStyle->GetStatH();
8939 if (stats) {
8940 stats->Clear();
8941 done = kTRUE;
8942 } else {
8943 stats = new TPaveStats(
8944 gStyle->GetStatX()-statw,
8945 gStyle->GetStatY()-stath,
8946 gStyle->GetStatX(),
8947 gStyle->GetStatY(),"brNDC");
8948
8949 stats->SetParent(fH);
8950 stats->SetOptFit(dofit);
8951 stats->SetOptStat(dostat);
8952 stats->SetFillColor(gStyle->GetStatColor());
8953 stats->SetFillStyle(gStyle->GetStatStyle());
8955 stats->SetName("stats");
8956
8958 stats->SetTextAlign(12);
8959 stats->SetTextFont(gStyle->GetStatFont());
8960 stats->SetFitFormat(gStyle->GetFitFormat());
8962 stats->SetBit(kCanDelete);
8963 stats->SetBit(kMustCleanup);
8964 }
8965 if (print_name) stats->AddText(h3->GetName());
8966 if (print_entries) {
8967 if (h3->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8968 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8969 stats->AddText(tt.Data());
8970 }
8971 if (print_mean) {
8972 if (print_mean == 1) {
8973 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8974 tt.Form(tf.Data(),h3->GetMean(1));
8975 stats->AddText(tt.Data());
8976 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8977 tt.Form(tf.Data(),h3->GetMean(2));
8978 stats->AddText(tt.Data());
8979 tf.Form("%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8980 tt.Form(tf.Data(),h3->GetMean(3));
8981 stats->AddText(tt.Data());
8982 } else {
8983 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8984 ,"%",stats->GetStatFormat());
8985 tt.Form(tf.Data(),h3->GetMean(1),h3->GetMeanError(1));
8986 stats->AddText(tt.Data());
8987 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8988 ,"%",stats->GetStatFormat());
8989 tt.Form(tf.Data(),h3->GetMean(2),h3->GetMeanError(2));
8990 stats->AddText(tt.Data());
8991 tf.Form("%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8992 ,"%",stats->GetStatFormat());
8993 tt.Form(tf.Data(),h3->GetMean(3),h3->GetMeanError(3));
8994 stats->AddText(tt.Data());
8995 }
8996 }
8997 if (print_stddev) {
8998 if (print_stddev == 1) {
8999 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
9000 tt.Form(tf.Data(),h3->GetStdDev(1));
9001 stats->AddText(tt.Data());
9002 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
9003 tt.Form(tf.Data(),h3->GetStdDev(2));
9004 stats->AddText(tt.Data());
9005 tf.Form("%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
9006 tt.Form(tf.Data(),h3->GetStdDev(3));
9007 stats->AddText(tt.Data());
9008 } else {
9009 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
9010 ,"%",stats->GetStatFormat());
9011 tt.Form(tf.Data(),h3->GetStdDev(1),h3->GetStdDevError(1));
9012 stats->AddText(tt.Data());
9013 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
9014 ,"%",stats->GetStatFormat());
9015 tt.Form(tf.Data(),h3->GetStdDev(2),h3->GetStdDevError(2));
9016 stats->AddText(tt.Data());
9017 tf.Form("%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
9018 ,"%",stats->GetStatFormat());
9019 tt.Form(tf.Data(),h3->GetStdDev(3),h3->GetStdDevError(3));
9020 stats->AddText(tt.Data());
9021 }
9022 }
9023 if (print_integral) {
9024 tt.Form("%s = %6.4g",gStringIntegral.Data(),h3->Integral());
9025 stats->AddText(tt.Data());
9026 }
9027 if (print_skew) {
9028 if (print_skew == 1) {
9029 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
9030 tt.Form(tf.Data(),h3->GetSkewness(1));
9031 stats->AddText(tt.Data());
9032 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
9033 tt.Form(tf.Data(),h3->GetSkewness(2));
9034 stats->AddText(tt.Data());
9035 tf.Form("%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
9036 tt.Form(tf.Data(),h3->GetSkewness(3));
9037 stats->AddText(tt.Data());
9038 } else {
9039 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
9040 ,"%",stats->GetStatFormat());
9041 tt.Form(tf.Data(),h3->GetSkewness(1),h3->GetSkewness(11));
9042 stats->AddText(tt.Data());
9043 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
9044 ,"%",stats->GetStatFormat());
9045 tt.Form(tf.Data(),h3->GetSkewness(2),h3->GetSkewness(12));
9046 stats->AddText(tt.Data());
9047 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
9048 ,"%",stats->GetStatFormat());
9049 tt.Form(tf.Data(),h3->GetSkewness(3),h3->GetSkewness(13));
9050 stats->AddText(tt.Data());
9051 }
9052 }
9053 if (print_kurt) {
9054 if (print_kurt == 1) {
9055 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
9056 tt.Form(tf.Data(),h3->GetKurtosis(1));
9057 stats->AddText(tt.Data());
9058 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
9059 tt.Form(tf.Data(),h3->GetKurtosis(2));
9060 stats->AddText(tt.Data());
9061 tf.Form("%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
9062 tt.Form(tf.Data(),h3->GetKurtosis(3));
9063 stats->AddText(tt.Data());
9064 } else {
9065 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
9066 ,"%",stats->GetStatFormat());
9067 tt.Form(tf.Data(),h3->GetKurtosis(1),h3->GetKurtosis(11));
9068 stats->AddText(tt.Data());
9069 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
9070 ,"%",stats->GetStatFormat());
9071 tt.Form(tf.Data(),h3->GetKurtosis(2),h3->GetKurtosis(12));
9072 stats->AddText(tt.Data());
9073 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
9074 ,"%",stats->GetStatFormat());
9075 tt.Form(tf.Data(),h3->GetKurtosis(3),h3->GetKurtosis(13));
9076 stats->AddText(tt.Data());
9077 }
9078 }
9079 if (print_under || print_over) {
9080 // no underflow - overflow printing for a 3D histogram
9081 // one would need a 3D table
9082 }
9083
9084 // Draw Fit parameters
9085 if (fit) {
9086 Int_t ndf = fit->GetNDF();
9087 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
9088 stats->AddText(tt.Data());
9089 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
9090 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
9091 ,(Float_t)fit->GetParameter(ipar)
9092 ,(Float_t)fit->GetParError(ipar));
9093 stats->AddText(tt.Data());
9094 }
9095 }
9096
9097 if (!done) fFunctions->Add(stats);
9098 stats->Paint();
9099}
9100
9101////////////////////////////////////////////////////////////////////////////////
9102/// [Control function to draw a 2D histogram as a surface plot.](#HP18)
9103
9105{
9106
9107 const Double_t ydiff = 1;
9108 const Double_t yligh1 = 10;
9109 const Double_t qa = 0.15;
9110 const Double_t qd = 0.15;
9111 const Double_t qs = 0.8;
9112 Double_t fmin, fmax;
9113 Int_t raster = 0;
9114 Int_t irep = 0;
9115
9116 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9119 Double_t zmin = Hparam.zmin;
9120 Double_t zmax = Hparam.zmax;
9121 Double_t xlab1 = Hparam.xmin;
9122 Double_t xlab2 = Hparam.xmax;
9123 Double_t ylab1 = Hparam.ymin;
9124 Double_t ylab2 = Hparam.ymax;
9125 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
9126 Double_t deltaz = TMath::Abs(zmin);
9127 if (deltaz == 0) deltaz = 1;
9128 if (zmin >= zmax) {
9129 zmin -= 0.5*deltaz;
9130 zmax += 0.5*deltaz;
9131 }
9132 Double_t z1c = zmin;
9133 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
9134 // Compute the lego limits and instantiate a lego object
9135 fXbuf[0] = -1;
9136 fYbuf[0] = 1;
9137 fXbuf[1] = -1;
9138 fYbuf[1] = 1;
9139 if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
9140 if (Hoption.System == kPOLAR) {
9141 fXbuf[2] = z1c;
9142 fYbuf[2] = z2c;
9143 } else if (Hoption.System == kCYLINDRICAL) {
9144 if (Hoption.Logy) {
9145 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
9146 else fXbuf[2] = 0;
9147 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
9148 else fYbuf[2] = 0;
9149 } else {
9150 fXbuf[2] = ylab1;
9151 fYbuf[2] = ylab2;
9152 }
9153 z1c = 0; z2c = 1;
9154 } else if (Hoption.System == kSPHERICAL) {
9155 fXbuf[2] = -1;
9156 fYbuf[2] = 1;
9157 z1c = 0; z2c = 1;
9158 } else if (Hoption.System == kRAPIDITY) {
9159 fXbuf[2] = -1/TMath::Tan(dangle);
9160 fYbuf[2] = 1/TMath::Tan(dangle);
9161 } else {
9162 fXbuf[0] = xlab1;
9163 fYbuf[0] = xlab2;
9164 fXbuf[1] = ylab1;
9165 fYbuf[1] = ylab2;
9166 fXbuf[2] = z1c;
9167 fYbuf[2] = z2c;
9168 }
9169
9173
9174 // Create axis object
9175
9176 TGaxis *axis = new TGaxis();
9177
9178 // Initialize the levels on the Z axis
9179 Int_t ndiv = fH->GetContour();
9180 if (ndiv == 0 ) {
9181 ndiv = gStyle->GetNumberContours();
9182 fH->SetContour(ndiv);
9183 }
9184 Int_t ndivz = TMath::Abs(ndiv);
9185 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9186
9187 if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
9188 if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
9189
9190 // Close the surface in case of non cartesian coordinates.
9191
9192 if (Hoption.System != kCARTESIAN) {nx++; ny++;}
9193
9194 // Now ready to draw the surface plot
9195
9196 TView *view = gPad->GetView();
9197 if (!view) {
9198 Error("PaintSurface", "no TView in current pad");
9199 return;
9200 }
9201
9202 Double_t thedeg = 90 - gPad->GetTheta();
9203 Double_t phideg = -90 - gPad->GetPhi();
9204 Double_t psideg = view->GetPsi();
9205 view->SetView(phideg, thedeg, psideg, irep);
9206
9207 // Set color/style for back box
9208 if (Hoption.Same) {
9209 fLego->SetFillStyle(0);
9210 fLego->SetFillColor(1);
9211 } else {
9212 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9213 fLego->SetFillColor(gPad->GetFrameFillColor());
9214 }
9215 fLego->TAttFill::Modify();
9216
9217 Int_t backcolor = gPad->GetFrameFillColor();
9218 if (Hoption.System != kCARTESIAN) backcolor = 0;
9219 view->PadRange(backcolor);
9220
9223 fLego->TAttFill::Modify();
9224
9225 // Draw the filled contour on top
9226 Int_t icol1 = fH->GetFillColor();
9227
9228 Int_t hoption35 = Hoption.Surf;
9229 if (Hoption.Surf == 13 || Hoption.Surf == 15) {
9230 DefineColorLevels(ndivz);
9231 Hoption.Surf = 23;
9234 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9235 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9236 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9237 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9238 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9239 Hoption.Surf = hoption35;
9240 fLego->SetMesh(1);
9241 }
9242
9243 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
9244 else fLego->InitMoveScreen(-1.1,1.1);
9245
9246 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
9250 fLego->BackBox(90);
9251 }
9252 }
9253
9254 // Gouraud Shading surface
9255 if (Hoption.Surf == 14) {
9256 // Set light sources
9257 fLego->LightSource(0, ydiff, 0,0,0,irep);
9258 fLego->LightSource(1, yligh1 ,1,1,1,irep);
9259 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
9260 fmin = ydiff*qa;
9261 fmax = fmin + (yligh1+0.1)*(qd+qs);
9262 Int_t nbcol = 28;
9263 icol1 = 201;
9264 Double_t dcol = 0.5/Double_t(nbcol);
9265 TColor *colref = gROOT->GetColor(fH->GetFillColor());
9266 if (!colref) return;
9267 Float_t r,g,b,hue,light,satur;
9268 colref->GetRGB(r,g,b);
9269 TColor::RGBtoHLS(r,g,b,hue,light,satur);
9270 TColor *acol;
9271 for (Int_t col=0;col<nbcol;col++) {
9272 acol = gROOT->GetColor(col+icol1);
9273 TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
9274 if (acol) acol->SetRGB(r,g,b);
9275 }
9276 fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
9279 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9280 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9281 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9282 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9283 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9284 } else if (Hoption.Surf == 15) {
9285 // The surface is not drawn in this case.
9286 } else {
9287 // Draw the surface
9288 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
9289 DefineColorLevels(ndivz);
9290 } else {
9292 }
9296 if (Hoption.System == kPOLAR) {
9297 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
9298 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
9299 } else if (Hoption.System == kCYLINDRICAL) {
9300 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9301 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9302 } else if (Hoption.System == kSPHERICAL) {
9303 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9304 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9305 } else if (Hoption.System == kRAPIDITY) {
9306 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9307 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9308 } else {
9311 if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
9312 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
9313 }
9314 }
9315
9316 // Paint the line contour on top for option SURF7
9317 if (Hoption.Surf == 17) {
9318 fLego->InitMoveScreen(-1.1,1.1);
9320 Hoption.Surf = 23;
9323 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
9324 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9325 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9326 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9327 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9328 }
9329
9330 if ((!Hoption.Same) &&
9331 (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9334 fLego->BackBox(90);
9335 }
9336 }
9337 if (Hoption.System == kCARTESIAN) {
9338 fLego->InitMoveScreen(-1.1,1.1);
9340 if (Hoption.FrontBox) fLego->FrontBox(90);
9341 }
9342 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9343
9345
9346 delete axis;
9347 delete fLego; fLego = 0;
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351/// Control function to draw a table using Delaunay triangles.
9352
9354{
9355
9356 TGraphDelaunay2D *dt = nullptr;
9357 TGraphDelaunay *dtOld = nullptr;
9358
9359 // Check if fH contains a TGraphDelaunay2D
9360 TList *hl = fH->GetListOfFunctions();
9361 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9362 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9363 if (!dt && !dtOld) return;
9364
9365 // If needed, create a TGraph2DPainter
9366 if (!fGraph2DPainter) {
9367 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9368 else fGraph2DPainter = new TGraph2DPainter(dtOld);
9369 }
9370
9371 // Define the 3D view
9372 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9373 if (Hoption.Same) {
9374 TView *viewsame = gPad->GetView();
9375 if (!viewsame) {
9376 Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9377 return;
9378 }
9379 Double_t *rmin = viewsame->GetRmin();
9380 Double_t *rmax = viewsame->GetRmax();
9381 if (!rmin || !rmax) return;
9382 fXbuf[0] = rmin[0];
9383 fYbuf[0] = rmax[0];
9384 fXbuf[1] = rmin[1];
9385 fYbuf[1] = rmax[1];
9386 fXbuf[2] = rmin[2];
9387 fYbuf[2] = rmax[2];
9388 } else {
9389 fXbuf[0] = Hparam.xmin;
9390 fYbuf[0] = Hparam.xmax;
9391 fXbuf[1] = Hparam.ymin;
9392 fYbuf[1] = Hparam.ymax;
9393 fXbuf[2] = Hparam.zmin;
9394 fYbuf[2] = Hparam.zmax;
9395 }
9396
9398 TView *view = gPad->GetView();
9399 if (!view) {
9400 Error("PaintTriangles", "no TView in current pad");
9401 return;
9402 }
9403 Double_t thedeg = 90 - gPad->GetTheta();
9404 Double_t phideg = -90 - gPad->GetPhi();
9405 Double_t psideg = view->GetPsi();
9406 Int_t irep;
9407 view->SetView(phideg, thedeg, psideg, irep);
9408
9409 // Set color/style for back box
9410 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9411 fLego->SetFillColor(gPad->GetFrameFillColor());
9412 fLego->TAttFill::Modify();
9413 Int_t backcolor = gPad->GetFrameFillColor();
9414 if (Hoption.System != kCARTESIAN) backcolor = 0;
9415 view->PadRange(backcolor);
9418 fLego->TAttFill::Modify();
9419
9420 // Paint the Back Box if needed
9421 if (Hoption.BackBox && !Hoption.Same) {
9422 fLego->InitMoveScreen(-1.1,1.1);
9425 fLego->BackBox(90);
9426 }
9427
9428 // Paint the triangles
9429 fGraph2DPainter->Paint(option);
9430
9431 // Paint the Front Box if needed
9432 if (Hoption.FrontBox) {
9433 fLego->InitMoveScreen(-1.1,1.1);
9435 fLego->FrontBox(90);
9436 }
9437
9438 // Paint the Axis if needed
9439 if (!Hoption.Axis && !Hoption.Same) {
9440 TGaxis *axis = new TGaxis();
9441 PaintLegoAxis(axis, 90);
9442 delete axis;
9443 }
9444
9446
9447 delete fLego; fLego = 0;
9448}
9449
9450////////////////////////////////////////////////////////////////////////////////
9451/// Define the color levels used to paint legos, surfaces etc..
9452
9454{
9455
9456 Int_t i, irep;
9457
9458 // Initialize the color levels
9459 if (ndivz >= 100) {
9460 Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9461 ndivz = 8;
9462 }
9463 Double_t *funlevel = new Double_t[ndivz+1];
9464 Int_t *colorlevel = new Int_t[ndivz+1];
9465 Int_t theColor;
9466 Int_t ncolors = gStyle->GetNumberOfColors();
9467 for (i = 0; i < ndivz; ++i) {
9468 funlevel[i] = fH->GetContourLevelPad(i);
9469 theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9470 colorlevel[i] = gStyle->GetColorPalette(theColor);
9471 }
9472 colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9473 fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9474 delete [] colorlevel;
9475 delete [] funlevel;
9476}
9477
9478////////////////////////////////////////////////////////////////////////////////
9479/// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9480
9482{
9483
9484 // Fill Hparam structure with histo parameters
9485 if (!TableInit()) return;
9486
9487 // Draw histogram frame
9488 PaintFrame();
9489
9490 // If palette option not specified, delete a possible existing palette
9491 if (!Hoption.Zscale) {
9492 TObject *palette = fFunctions->FindObject("palette");
9493 if (palette) { fFunctions->Remove(palette); delete palette;}
9494 }
9495
9496 // Do not draw the histogram. Only the attached functions will be drawn.
9497 if (Hoption.Func == 2) {
9498 if (Hoption.Zscale) {
9499 Int_t ndiv = fH->GetContour();
9500 if (ndiv == 0 ) {
9501 ndiv = gStyle->GetNumberContours();
9502 fH->SetContour(ndiv);
9503 }
9504 PaintPalette();
9505 }
9506
9507 // Draw the histogram according to the option
9508 } else {
9509 if (fH->InheritsFrom(TH2Poly::Class())) {
9510 if (Hoption.Fill) PaintTH2PolyBins("f");
9513 if (Hoption.Text) PaintTH2PolyText(option);
9514 if (Hoption.Line) PaintTH2PolyBins("l");
9515 if (Hoption.Mark) PaintTH2PolyBins("P");
9516 } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9517 if (Hoption.Scat) PaintScatterPlot(option);
9518 if (Hoption.Arrow) PaintArrows(option);
9519 if (Hoption.Box) PaintBoxes(option);
9520 if (Hoption.Color) {
9521 if (Hoption.Color == 3) PaintColorLevelsFast(option);
9522 else PaintColorLevels(option);
9523 }
9524 if (Hoption.Contour) PaintContour(option);
9525 if (Hoption.Text) PaintText(option);
9526 if (Hoption.Error >= 100) Paint2DErrors(option);
9527 if (Hoption.Candle) PaintCandlePlot(option);
9528 }
9529 if (Hoption.Lego) PaintLego(option);
9530 if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9531 if (Hoption.Tri) PaintTriangles(option);
9532 }
9533
9534 // Draw histogram title
9535 PaintTitle();
9536
9537 // Draw the axes
9538 if (!Hoption.Lego && !Hoption.Surf &&
9539 !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9540
9541 TF1 *fit = 0;
9542 TIter next(fFunctions);
9543 TObject *obj;
9544 while ((obj = next())) {
9545 if (obj->InheritsFrom(TF1::Class())) {
9546 fit = (TF1*)obj;
9547 break;
9548 }
9549 }
9550 if ((Hoption.Same%10) != 1) {
9551 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9552 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9553 //ALWAYS executed on non-iOS platform.
9554 //On iOS, depends on mode.
9556 }
9557 }
9558 }
9559}
9560
9561////////////////////////////////////////////////////////////////////////////////
9562/// Control function to draw a TH2Poly bins' contours.
9563///
9564/// - option = "F" draw the bins as filled areas.
9565/// - option = "L" draw the bins as line.
9566/// - option = "P" draw the bins as markers.
9567
9569{
9570
9571 //Do not highlight the histogram, if its part was picked.
9572 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9573
9574 TString opt = option;
9575 opt.ToLower();
9576 Bool_t line = kFALSE;
9577 Bool_t fill = kFALSE;
9578 Bool_t mark = kFALSE;
9579 if (opt.Contains("l")) line = kTRUE;
9580 if (opt.Contains("f")) fill = kTRUE;
9581 if (opt.Contains("p")) mark = kTRUE;
9582
9583 TH2PolyBin *b;
9584 Double_t z;
9585
9586 TIter next(((TH2Poly*)fH)->GetBins());
9587 TObject *obj, *poly;
9588
9589 while ((obj=next())) {
9590 b = (TH2PolyBin*)obj;
9591 z = b->GetContent();
9592 if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9593 poly = b->GetPolygon();
9594
9595 // Paint the TGraph bins.
9596 if (poly->IsA() == TGraph::Class()) {
9597 TGraph *g = (TGraph*)poly;
9598 g->TAttLine::Modify();
9599 g->TAttMarker::Modify();
9600 g->TAttFill::Modify();
9601 if (line) {
9602 Int_t fs = g->GetFillStyle();
9603 Int_t fc = g->GetFillColor();
9604 g->SetFillStyle(0);
9605 g->SetFillColor(g->GetLineColor());
9606 g->Paint("F");
9607 g->SetFillStyle(fs);
9608 g->SetFillColor(fc);
9609 }
9610 if (fill) g->Paint("F");
9611 if (mark) g->Paint("P");
9612 }
9613
9614 // Paint the TMultiGraph bins.
9615 if (poly->IsA() == TMultiGraph::Class()) {
9616 TMultiGraph *mg = (TMultiGraph*)poly;
9617 TList *gl = mg->GetListOfGraphs();
9618 if (!gl) return;
9619 TGraph *g;
9620 TIter nextg(gl);
9621 while ((g = (TGraph*) nextg())) {
9622 g->TAttLine::Modify();
9623 g->TAttMarker::Modify();
9624 g->TAttFill::Modify();
9625 if (line) {
9626 Int_t fs = g->GetFillStyle();
9627 Int_t fc = g->GetFillColor();
9628 g->SetFillStyle(0);
9629 g->SetFillColor(g->GetLineColor());
9630 g->Paint("F");
9631 g->SetFillStyle(fs);
9632 g->SetFillColor(fc);
9633 }
9634 if (fill) g->Paint("F");
9635 if (mark) g->Paint("P");
9636 }
9637 }
9638 }
9639}
9640
9641////////////////////////////////////////////////////////////////////////////////
9642/// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9643
9645{
9646
9647 //Do not highlight the histogram, if its part was picked.
9648 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9649 return;
9650
9651 Int_t ncolors, color, theColor;
9652 Double_t z, zc;
9653 Double_t zmin = fH->GetMinimum();
9654 Double_t zmax = fH->GetMaximum();
9655 if (Hoption.Logz) {
9656 if (zmax > 0) {
9657 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9658 zmin = TMath::Log10(zmin);
9659 zmax = TMath::Log10(zmax);
9660 } else {
9661 return;
9662 }
9663 }
9664 Double_t dz = zmax - zmin;
9665
9666 // Initialize the levels on the Z axis
9667 ncolors = gStyle->GetNumberOfColors();
9668 Int_t ndiv = fH->GetContour();
9669 if (ndiv == 0 ) {
9670 ndiv = gStyle->GetNumberContours();
9671 fH->SetContour(ndiv);
9672 }
9673 Int_t ndivz = TMath::Abs(ndiv);
9674 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9675 Double_t scale = ndivz/dz;
9676
9677 TH2PolyBin *b;
9678
9679 TIter next(((TH2Poly*)fH)->GetBins());
9680 TObject *obj, *poly;
9681
9682 while ((obj=next())) {
9683 b = (TH2PolyBin*)obj;
9684 poly = b->GetPolygon();
9685
9686 z = b->GetContent();
9687 if (z==0 && Hoption.Zero) continue;
9688 if (Hoption.Logz) {
9689 if (z > 0) z = TMath::Log10(z);
9690 else z = zmin;
9691 }
9692 if (z < zmin) continue;
9693
9694 // Define the bin color.
9696 zc = fH->GetContourLevelPad(0);
9697 if (z < zc) continue;
9698 color = -1;
9699 for (Int_t k=0; k<ndiv; k++) {
9700 zc = fH->GetContourLevelPad(k);
9701 if (z < zc) {
9702 continue;
9703 } else {
9704 color++;
9705 }
9706 }
9707 } else {
9708 color = Int_t(0.01+(z-zmin)*scale);
9709 }
9710 theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9711 if (theColor > ncolors-1) theColor = ncolors-1;
9712
9713 // Paint the TGraph bins.
9714 if (poly->IsA() == TGraph::Class()) {
9715 TGraph *g = (TGraph*)poly;
9716 g->SetFillColor(gStyle->GetColorPalette(theColor));
9717 g->TAttFill::Modify();
9718 g->Paint("F");
9719 }
9720
9721 // Paint the TMultiGraph bins.
9722 if (poly->IsA() == TMultiGraph::Class()) {
9723 TMultiGraph *mg = (TMultiGraph*)poly;
9724 TList *gl = mg->GetListOfGraphs();
9725 if (!gl) return;
9726 TGraph *g;
9727 TIter nextg(gl);
9728 while ((g = (TGraph*) nextg())) {
9729 g->SetFillColor(gStyle->GetColorPalette(theColor));
9730 g->TAttFill::Modify();
9731 g->Paint("F");
9732 }
9733 }
9734 }
9736}
9737
9738////////////////////////////////////////////////////////////////////////////////
9739/// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9740
9742{
9743
9744 //Do not highlight the histogram, if its part was selected.
9745 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9746 return;
9747
9748 Int_t k, loop, marker=0;
9749 Double_t z, xk,xstep, yk, ystep, xp, yp;
9750 Double_t scale = 1;
9751 Double_t zmin = fH->GetMinimum();
9752 Double_t zmax = fH->GetMaximum();
9753 if (Hoption.Logz) {
9754 if (zmax > 0) {
9755 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9756 zmin = TMath::Log10(zmin);
9757 zmax = TMath::Log10(zmax);
9758 } else {
9759 return;
9760 }
9761 }
9762 Double_t dz = zmax - zmin;
9763 scale = (kNMAX-1)/dz;
9764
9765
9766 // use an independent instance of a random generator
9767 // instead of gRandom to avoid conflicts and
9768 // to get same random numbers when drawing the same histogram
9769 TRandom2 random;
9770
9771 TH2PolyBin *b;
9772
9773 TIter next(((TH2Poly*)fH)->GetBins());
9774 TObject *obj, *poly;
9775
9776 Double_t maxarea = 0, a;
9777 while ((obj=next())) {
9778 b = (TH2PolyBin*)obj;
9779 a = b->GetArea();
9780 if (a>maxarea) maxarea = a;
9781 }
9782
9783 next.Reset();
9784
9785 while ((obj=next())) {
9786 b = (TH2PolyBin*)obj;
9787 poly = b->GetPolygon();
9788 z = b->GetContent();
9789 if (z < zmin) z = zmin;
9790 if (z > zmax) z = zmax;
9791 if (Hoption.Logz) {
9792 if (z > 0) z = TMath::Log10(z) - zmin;
9793 } else {
9794 z -= zmin;
9795 }
9796 k = Int_t((z*scale)*(b->GetArea()/maxarea));
9797 xk = b->GetXMin();
9798 yk = b->GetYMin();
9799 xstep = b->GetXMax()-xk;
9800 ystep = b->GetYMax()-yk;
9801
9802 // Paint the TGraph bins.
9803 if (poly->IsA() == TGraph::Class()) {
9804 TGraph *g = (TGraph*)poly;
9805 if (k <= 0 || z <= 0) continue;
9806 loop = 0;
9807 while (loop<k) {
9808 if (k+marker >= kNMAX) {
9809 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9810 marker=0;
9811 }
9812 xp = (random.Rndm()*xstep) + xk;
9813 yp = (random.Rndm()*ystep) + yk;
9814 if (g->IsInside(xp,yp)) {
9815 fXbuf[marker] = xp;
9816 fYbuf[marker] = yp;
9817 marker++;
9818 loop++;
9819 }
9820 }
9821 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9822 }
9823
9824 // Paint the TMultiGraph bins.
9825 if (poly->IsA() == TMultiGraph::Class()) {
9826 TMultiGraph *mg = (TMultiGraph*)poly;
9827 TList *gl = mg->GetListOfGraphs();
9828 if (!gl) return;
9829 if (k <= 0 || z <= 0) continue;
9830 loop = 0;
9831 while (loop<k) {
9832 if (k+marker >= kNMAX) {
9833 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9834 marker=0;
9835 }
9836 xp = (random.Rndm()*xstep) + xk;
9837 yp = (random.Rndm()*ystep) + yk;
9838 if (mg->IsInside(xp,yp)) {
9839 fXbuf[marker] = xp;
9840 fYbuf[marker] = yp;
9841 marker++;
9842 loop++;
9843 }
9844 }
9845 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9846 }
9847 }
9848 PaintTH2PolyBins("l");
9849}
9850
9851////////////////////////////////////////////////////////////////////////////////
9852/// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9853
9855{
9856
9857 TLatex text;
9861
9862 Double_t x, y, z, e, angle = 0;
9863 TString tt, tf;
9864 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9865 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9866 Int_t opt = (Int_t)Hoption.Text/1000;
9867
9868 text.SetTextAlign(22);
9869 if (Hoption.Text == 1) angle = 0;
9870 text.SetTextAngle(angle);
9871 text.TAttText::Modify();
9872
9873 TH2PolyBin *b;
9874
9875 TIter next(((TH2Poly*)fH)->GetBins());
9876 TObject *obj, *p;
9877
9878 while ((obj=next())) {
9879 b = (TH2PolyBin*)obj;
9880 p = b->GetPolygon();
9881 x = (b->GetXMin()+b->GetXMax())/2;
9882 if (Hoption.Logx) {
9883 if (x > 0) x = TMath::Log10(x);
9884 else continue;
9885 }
9886 y = (b->GetYMin()+b->GetYMax())/2;
9887 if (Hoption.Logy) {
9888 if (y > 0) y = TMath::Log10(y);
9889 else continue;
9890 }
9891 z = b->GetContent();
9892 if (z < fH->GetMinimum() || (z == 0 && !Hoption.MinimumZero)) continue;
9893 if (opt==2) {
9894 e = fH->GetBinError(b->GetBinNumber());
9895 tf.Form("#splitline{%s%s}{#pm %s%s}",
9897 "%",gStyle->GetPaintTextFormat());
9898 tt.Form(tf.Data(),z,e);
9899 } else {
9900 tt.Form(tf.Data(),z);
9901 }
9902 if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9903 else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),tt.Data());
9904 }
9905
9906 PaintTH2PolyBins("l");
9907}
9908
9909////////////////////////////////////////////////////////////////////////////////
9910/// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9911
9913{
9914
9915 TLatex text;
9919
9920 Double_t x, y, z, e, angle = 0;
9921 TString tt, tf;
9922 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9923 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9924
9925 // 1D histograms
9926 if (fH->GetDimension() == 1) {
9927 Bool_t getentries = kFALSE;
9928 Double_t yt;
9929 TProfile *hp = (TProfile*)fH;
9930 if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9931 Hoption.Text = Hoption.Text-2000;
9932 getentries = kTRUE;
9933 }
9934 if (Hoption.Text == 1) angle = 90;
9935 text.SetTextAlign(11);
9936 if (angle == 90) text.SetTextAlign(12);
9937 if (angle == 0) text.SetTextAlign(21);
9938 text.TAttText::Modify();
9939 Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9940 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9941 if (Hoption.Bar) {
9942 x = fH->GetXaxis()->GetBinLowEdge(i)+
9943 fH->GetXaxis()->GetBinWidth(i)*
9944 (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9945 } else {
9946 x = fH->GetXaxis()->GetBinCenter(i);
9947 }
9948 y = fH->GetBinContent(i);
9949 yt = y;
9950 if (Hoption.MinimumZero && y<0) y = 0;
9951 if (getentries) yt = hp->GetBinEntries(i);
9952 if (yt == 0.) continue;
9953 tt.Form(tf.Data(),yt);
9954 if (Hoption.Logx) {
9955 if (x > 0) x = TMath::Log10(x);
9956 else continue;
9957 }
9958 if (Hoption.Logy) {
9959 if (y > 0) y = TMath::Log10(y);
9960 else continue;
9961 }
9962 if (y >= gPad->GetY2()) continue;
9963 if (y <= gPad->GetY1()) continue;
9964 text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),tt.Data());
9965 }
9966
9967 // 2D histograms
9968 } else {
9969 text.SetTextAlign(22);
9970 if (Hoption.Text == 1) angle = 0;
9971 text.SetTextAngle(angle);
9972 text.TAttText::Modify();
9973 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9974 y = fYaxis->GetBinCenter(j);
9975 if (Hoption.Logy) {
9976 if (y > 0) y = TMath::Log10(y);
9977 else continue;
9978 }
9979 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9980 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9981 x = fXaxis->GetBinCenter(i);
9982 if (Hoption.Logx) {
9983 if (x > 0) x = TMath::Log10(x);
9984 else continue;
9985 }
9986 if (!IsInside(x,y)) continue;
9987 z = fH->GetBinContent(bin);
9988 if (z < Hparam.zmin || (z == 0 && !Hoption.MinimumZero)) continue;
9989 if (Hoption.Text>2000) {
9990 e = fH->GetBinError(bin);
9991 tf.Form("#splitline{%s%s}{#pm %s%s}",
9993 "%",gStyle->GetPaintTextFormat());
9994 tt.Form(tf.Data(),z,e);
9995 } else {
9996 tt.Form(tf.Data(),z);
9997 }
9998 text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9999 angle,0.02*fH->GetMarkerSize(),tt.Data());
10000 }
10001 }
10002 }
10003}
10004
10005////////////////////////////////////////////////////////////////////////////////
10006/// [Control function to draw a 3D implicit functions.](#HP27)
10007
10009{
10010
10011 Int_t irep;
10012
10013 TGaxis *axis = new TGaxis();
10014 TAxis *xaxis = fH->GetXaxis();
10015 TAxis *yaxis = fH->GetYaxis();
10016 TAxis *zaxis = fH->GetZaxis();
10017
10018 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
10019 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
10020 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
10021 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
10022 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
10023 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
10024
10026
10027 TView *view = gPad->GetView();
10028 if (!view) {
10029 Error("PaintTF3", "no TView in current pad");
10030 return;
10031 }
10032 Double_t thedeg = 90 - gPad->GetTheta();
10033 Double_t phideg = -90 - gPad->GetPhi();
10034 Double_t psideg = view->GetPsi();
10035 view->SetView(phideg, thedeg, psideg, irep);
10036
10037 fLego->InitMoveScreen(-1.1,1.1);
10038
10039 if (Hoption.BackBox) {
10042 fLego->BackBox(90);
10043 }
10044
10046
10048 fH->GetNbinsY(),
10049 fH->GetNbinsZ(), "BF");
10050
10051 if (Hoption.FrontBox) {
10052 fLego->InitMoveScreen(-1.1,1.1);
10054 fLego->FrontBox(90);
10055 }
10056 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
10057
10058 PaintTitle();
10059
10060 delete axis;
10061 delete fLego; fLego = 0;
10062}
10063
10064////////////////////////////////////////////////////////////////////////////////
10065/// Draw the histogram title
10066///
10067/// The title is drawn according to the title alignment returned by
10068/// `GetTitleAlign()`. It is a 2 digits integer): hv
10069///
10070/// where `h` is the horizontal alignment and `v` is the
10071/// vertical alignment.
10072///
10073/// - `h` can get the values 1 2 3 for left, center, and right
10074/// - `v` can get the values 1 2 3 for bottom, middle and top
10075///
10076/// for instance the default alignment is: 13 (left top)
10077
10079{
10080 // probably best place for calls PaintHighlightBin
10081 // calls after paint histo (1D or 2D) and before paint title and stats
10082 if (!gPad->GetView()) PaintHighlightBin();
10083
10084 if (Hoption.Same) return;
10085 if (fH->TestBit(TH1::kNoTitle)) return;
10086 Int_t nt = strlen(fH->GetTitle());
10087 TPaveText *title = 0;
10088 TObject *obj;
10089 TIter next(gPad->GetListOfPrimitives());
10090 while ((obj = next())) {
10091 if (!obj->InheritsFrom(TPaveText::Class())) continue;
10092 title = (TPaveText*)obj;
10093 if (strcmp(title->GetName(),"title")) {title = 0; continue;}
10094 break;
10095 }
10096 if (nt == 0 || gStyle->GetOptTitle() <= 0) {
10097 if (title) delete title;
10098 return;
10099 }
10100 Double_t ht = gStyle->GetTitleH();
10101 Double_t wt = gStyle->GetTitleW();
10102
10103 if (ht <= 0) {
10104 if (gStyle->GetTitleFont("")%10 == 3) {
10105 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
10106 (Double_t)gPad->YtoPixel(gPad->GetY1()));
10107 ht = 1.1*(gStyle->GetTitleSize("")/hw);
10108 } else {
10109 ht = 1.1*gStyle->GetTitleFontSize();
10110 }
10111 }
10112 if (ht <= 0) ht = 0.05;
10113 if (wt <= 0) {
10114 TLatex l;
10115 l.SetTextSize(ht);
10116 l.SetTitle(fH->GetTitle());
10117 // adjustment in case the title has several lines (#splitline)
10118 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
10119 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
10120 wt = TMath::Min(0.7, 0.02+wndc);
10121 }
10122 if (title) {
10123 TText *t0 = (TText*)title->GetLine(0);
10124 if (t0) {
10125 if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
10126 t0->SetTitle(fH->GetTitle());
10127 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
10128 }
10129 return;
10130 }
10131
10132 Int_t talh = gStyle->GetTitleAlign()/10;
10133 if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
10134 Int_t talv = gStyle->GetTitleAlign()%10;
10135 if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
10136 Double_t xpos, ypos;
10137 xpos = gStyle->GetTitleX();
10138 ypos = gStyle->GetTitleY();
10139 if (talh == 2) xpos = xpos-wt/2.;
10140 if (talh == 3) xpos = xpos-wt;
10141 if (talv == 2) ypos = ypos+ht/2.;
10142 if (talv == 1) ypos = ypos+ht;
10143
10144 TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
10145
10146 // box with the histogram title
10148 ptitle->SetFillStyle(gStyle->GetTitleStyle());
10149 ptitle->SetName("title");
10152 ptitle->SetTextFont(gStyle->GetTitleFont(""));
10153 if (gStyle->GetTitleFont("")%10 > 2)
10155 ptitle->AddText(fH->GetTitle());
10156 ptitle->SetBit(kCanDelete);
10157 ptitle->Draw();
10158 ptitle->Paint();
10159
10160 if(!gPad->IsEditable()) delete ptitle;
10161}
10162
10163////////////////////////////////////////////////////////////////////////////////
10164/// Process message `mess`.
10165
10166void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
10167{
10168 if (!strcmp(mess,"SetF3")) {
10169 fCurrentF3 = (TF3 *)obj;
10170 }
10171}
10172
10173////////////////////////////////////////////////////////////////////////////////
10174/// Static function.
10175///
10176/// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
10177/// This procedure can be used to create an all-sky map in Galactic
10178/// coordinates with an equal-area Aitoff projection. Output map
10179/// coordinates are zero longitude centered.
10180/// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
10181///
10182/// source: GMT
10183///
10184/// code from Ernst-Jan Buis
10185
10187{
10188
10189 Double_t x, y;
10190
10191 Double_t alpha2 = (l/2)*TMath::DegToRad();
10192 Double_t delta = b*TMath::DegToRad();
10193 Double_t r2 = TMath::Sqrt(2.);
10194 Double_t f = 2*r2/TMath::Pi();
10195 Double_t cdec = TMath::Cos(delta);
10196 Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
10197 x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
10198 y = TMath::Sin(delta)*r2/denom;
10199 x *= TMath::RadToDeg()/f;
10200 y *= TMath::RadToDeg()/f;
10201 // x *= -1.; // for a skymap swap left<->right
10202 Al = x;
10203 Ab = y;
10204
10205 return 0;
10206}
10207
10208////////////////////////////////////////////////////////////////////////////////
10209/// Static function
10210///
10211/// Probably the most famous of the various map projections, the Mercator projection
10212/// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
10213/// with no distortion along the equator.
10214/// The Mercator projection has been used extensively for world maps in which the distortion towards
10215/// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
10216/// Greenland is larger than South America. In reality, the latter is about eight times the size of
10217/// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
10218/// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
10219/// code from Ernst-Jan Buis
10220
10222{
10223
10224 Al = l;
10226 Ab = TMath::Log(aid);
10227 return 0;
10228}
10229
10230////////////////////////////////////////////////////////////////////////////////
10231/// Static function code from Ernst-Jan Buis
10232
10234{
10235
10236 Al = l*cos(b*TMath::DegToRad());
10237 Ab = b;
10238 return 0;
10239}
10240
10241////////////////////////////////////////////////////////////////////////////////
10242/// Static function code from Ernst-Jan Buis
10243
10245{
10246
10247 Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
10248 Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
10249 return 0;
10250}
10251
10252////////////////////////////////////////////////////////////////////////////////
10253/// Recompute the histogram range following graphics operations.
10254
10256{
10257
10258 if (Hoption.Same) return;
10259
10260 // Compute x,y range
10265
10266 Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
10267 if (Hoption.Proj ==1) {
10268 // TODO : check x range not lower than -180 and not higher than 180
10273
10274 if (xmin > xmin_aid) xmin = xmin_aid;
10275 if (ymin > ymin_aid) ymin = ymin_aid;
10276 if (xmax < xmax_aid) xmax = xmax_aid;
10277 if (ymax < ymax_aid) ymax = ymax_aid;
10278 if (Hparam.ymin<0 && Hparam.ymax>0) {
10279 // there is an 'equator', check its range in the plot..
10280 THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
10281 THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
10282 if (xmin >xmin_aid) xmin = xmin_aid;
10283 if (xmax <xmax_aid) xmax = xmax_aid;
10284 }
10285 if (Hparam.xmin<0 && Hparam.xmax>0) {
10286 THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10287 THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
10288 if (ymin >ymin_aid) ymin = ymin_aid;
10289 if (ymax <ymax_aid) ymax = ymax_aid;
10290 }
10291 } else if ( Hoption.Proj ==2) {
10292 if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
10293 Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
10294 Hoption.Proj = 0;
10295 } else {
10298 }
10299 } else if (Hoption.Proj == 3) {
10304
10305 if (xmin > xmin_aid) xmin = xmin_aid;
10306 if (ymin > ymin_aid) ymin = ymin_aid;
10307 if (xmax < xmax_aid) xmax = xmax_aid;
10308 if (ymax < ymax_aid) ymax = ymax_aid;
10309 if (Hparam.ymin<0 && Hparam.ymax>0) {
10310 THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10311 THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10312 if (xmin >xmin_aid) xmin = xmin_aid;
10313 if (xmax <xmax_aid) xmax = xmax_aid;
10314 }
10315 if (Hparam.xmin<0 && Hparam.xmax>0) {
10316 THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
10317 THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10318 if (ymin >ymin_aid) ymin = ymin_aid;
10319 if (ymax <ymax_aid) ymax = ymax_aid;
10320 }
10321 } else if (Hoption.Proj == 4) {
10326
10327 if (xmin > xmin_aid) xmin = xmin_aid;
10328 if (ymin > ymin_aid) ymin = ymin_aid;
10329 if (xmax < xmax_aid) xmax = xmax_aid;
10330 if (ymax < ymax_aid) ymax = ymax_aid;
10331 if (Hparam.ymin<0 && Hparam.ymax>0) {
10332 THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10333 THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10334 if (xmin >xmin_aid) xmin = xmin_aid;
10335 if (xmax <xmax_aid) xmax = xmax_aid;
10336 }
10337 if (Hparam.xmin<0 && Hparam.xmax>0) {
10338 THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10339 THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10340 if (ymin >ymin_aid) ymin = ymin_aid;
10341 if (ymax <ymax_aid) ymax = ymax_aid;
10342 }
10343 }
10344 Hparam.xmin= xmin;
10345 Hparam.xmax= xmax;
10346 Hparam.ymin= ymin;
10347 Hparam.ymax= ymax;
10348
10349 Double_t dx = xmax-xmin;
10350 Double_t dy = ymax-ymin;
10351 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10352 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10353
10354 // Range() could change the size of the pad pixmap and therefore should
10355 // be called before the other paint routines
10356 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10357 ymin - dyr*gPad->GetBottomMargin(),
10358 xmax + dxr*gPad->GetRightMargin(),
10359 ymax + dyr*gPad->GetTopMargin());
10360 gPad->RangeAxis(xmin, ymin, xmax, ymax);
10361}
10362
10363////////////////////////////////////////////////////////////////////////////////
10364/// Set current histogram to `h`
10365
10367{
10368
10369 if (h == 0) return;
10370 fH = h;
10371 fXaxis = h->GetXaxis();
10372 fYaxis = h->GetYaxis();
10373 fZaxis = h->GetZaxis();
10375}
10376
10377////////////////////////////////////////////////////////////////////////////////
10378/// Initialize various options to draw 2D histograms.
10379
10381{
10382
10383 static const char *where = "TableInit";
10384
10385 Int_t first, last;
10386 Double_t yMARGIN= gStyle->GetHistTopMargin();
10387 Double_t zmin, zmax;
10388 Int_t maximum = 0;
10389 Int_t minimum = 0;
10390 if (fH->GetMaximumStored() != -1111) maximum = 1;
10391 if (fH->GetMinimumStored() != -1111) minimum = 1;
10392
10393 // ----------------- Compute X axis parameters
10394 first = fXaxis->GetFirst();
10395 last = fXaxis->GetLast();
10396 Hparam.xlast = last;
10402
10403 // if log scale in X, replace xmin,max by the log
10404 if (Hoption.Logx) {
10405 // find the first edge of a bin that is > 0
10406 if (Hparam.xlowedge <=0 ) {
10409 }
10410 if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10411 Error(where, "cannot set X axis to log scale");
10412 return 0;
10413 }
10417 if (Hparam.xlast > last) Hparam.xlast = last;
10420 }
10421
10422 // ----------------- Compute Y axis parameters
10423 first = fYaxis->GetFirst();
10424 last = fYaxis->GetLast();
10425 Hparam.ylast = last;
10429 if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10432
10433 // if log scale in Y, replace ymin,max by the log
10434 if (Hoption.Logy) {
10435 if (Hparam.ylowedge <=0 ) {
10438 }
10439 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10440 Error(where, "cannot set Y axis to log scale");
10441 return 0;
10442 }
10446 if (Hparam.ylast > last) Hparam.ylast = last;
10449 }
10450
10451
10452 // ----------------- Compute Z axis parameters
10453 Double_t bigp = TMath::Power(10,32);
10454 zmax = -bigp;
10455 zmin = bigp;
10456 Double_t c1, e1;
10457 Double_t allchan = 0;
10458 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10459 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10460 c1 = fH->GetBinContent(i,j);
10461 zmax = TMath::Max(zmax,c1);
10462 if (Hoption.Error) {
10463 e1 = fH->GetBinError(i,j);
10464 zmax = TMath::Max(zmax,c1+e1);
10465 }
10466 zmin = TMath::Min(zmin,c1);
10467 allchan += c1;
10468 }
10469 }
10470
10471 // Take into account maximum , minimum
10472
10473 if (maximum) zmax = fH->GetMaximumStored();
10474 if (minimum) zmin = fH->GetMinimumStored();
10475 if (Hoption.Logz && zmax < 0) {
10476 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10477 return 0;
10478 } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10479 zmin = 0.01;
10480 zmax = 10.;
10481 }
10482 if (zmin >= zmax) {
10483 if (Hoption.Logz) {
10484 if (zmax > 0) zmin = 0.001*zmax;
10485 else {
10486 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10487 return 0;
10488 }
10489 }
10490 }
10491
10492 // take into account normalization factor
10493 Hparam.allchan = allchan;
10494 Double_t factor = allchan;
10495 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10496 if (allchan) factor /= allchan;
10497 if (factor == 0) factor = 1;
10498 Hparam.factor = factor;
10499 zmax = factor*zmax;
10500 zmin = factor*zmin;
10501 c1 = zmax;
10502 if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10503
10504 // For log scales, histogram coordinates are log10(ymin) and
10505 // log10(ymax). Final adjustment (if not option "Same")
10506 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10507 // Maximum and Minimum are not defined.
10508 if (Hoption.Logz) {
10509 if (zmin <= 0) {
10510 zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10511 fH->SetMinimum(zmin);
10512 }
10513 zmin = TMath::Log10(zmin);
10514 if (!minimum) zmin += TMath::Log10(0.5);
10515 zmax = TMath::Log10(zmax);
10516 if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10517 goto LZMIN;
10518 }
10519
10520 // final adjustment of YMAXI for linear scale (if not option "Same"):
10521 // decrease histogram height to MAX% of allowed height if HMAXIM
10522 // has not been called.
10523 // MAX% is the value in percent which has been set in HPLSET
10524 // (default is 90%).
10525 if (!maximum) {
10526 zmax += yMARGIN*(zmax-zmin);
10527 }
10528
10529 // final adjustment of ymin for linear scale.
10530 // if minimum is not set , then ymin is set to zero if >0
10531 // or to ymin - yMARGIN if <0.
10532 if (!minimum) {
10533 if (Hoption.MinimumZero) {
10534 if (zmin >= 0) zmin = 0;
10535 else zmin -= yMARGIN*(zmax-zmin);
10536 } else {
10537 Double_t dzmin = yMARGIN*(zmax-zmin);
10538 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10539 else zmin -= dzmin;
10540 }
10541 }
10542
10543LZMIN:
10544 Hparam.zmin = zmin;
10545 Hparam.zmax = zmax;
10546
10547 // Set bar offset and width
10550
10551 return 1;
10552}
10553
10554////////////////////////////////////////////////////////////////////////////////
10555/// This function returns the best format to print the error value (e)
10556/// knowing the parameter value (v) and the format (f) used to print it.
10557
10559{
10560
10561 static TString ef;
10562 TString tf, tv;
10563
10564 // print v with the format f in tv.
10565 tf.Form("%s%s","%",f);
10566 tv.Form(tf.Data(),v);
10567
10568 // Analyse tv.
10569 int ie = tv.Index("e");
10570 int iE = tv.Index("E");
10571 int id = tv.Index(".");
10572
10573 // v has been printed with the exponent notation.
10574 // There is 2 cases, the exponent is positive or negative
10575 if (ie >= 0 || iE >= 0) {
10576 if (tv.Index("+") >= 0) {
10577 if (e < 1) {
10578 ef.Form("%s.1f","%");
10579 } else {
10580 if (ie >= 0) {
10581 ef.Form("%s.%de","%",ie-id-1);
10582 } else {
10583 ef.Form("%s.%dE","%",iE-id-1);
10584 }
10585 }
10586 } else {
10587 if (ie >= 0) {
10588 ef.Form("%s.%de","%",ie-id-1);
10589 } else {
10590 ef.Form("%s.%dE","%",iE-id-1);
10591 }
10592 }
10593
10594 // There is not '.' in tv. e will be printed with one decimal digit.
10595 } else if (id < 0) {
10596 ef.Form("%s.1f","%");
10597
10598 // There is a '.' in tv and no exponent notation. e's decimal part will
10599 // have the same number of digits as v's one.
10600 } else {
10601 ef.Form("%s.%df","%",tv.Length()-id-1);
10602 }
10603
10604 return ef.Data();
10605}
10606
10607////////////////////////////////////////////////////////////////////////////////
10608/// Set projection.
10609
10610void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10611{
10612
10613 if (fShowProjection) return;
10614 TString opt = option;
10615 opt.ToLower();
10616 Int_t projection = 0;
10617 if (opt.Contains("x")) projection = 1;
10618 if (opt.Contains("y")) projection = 2;
10619 if (opt.Contains("z")) projection = 3;
10620 if (opt.Contains("xy")) projection = 4;
10621 if (opt.Contains("yx")) projection = 5;
10622 if (opt.Contains("xz")) projection = 6;
10623 if (opt.Contains("zx")) projection = 7;
10624 if (opt.Contains("yz")) projection = 8;
10625 if (opt.Contains("zy")) projection = 9;
10626 if (projection < 4) fShowOption = option+1;
10627 else fShowOption = option+2;
10628 fShowProjection = projection+100*nbins;
10629 gROOT->MakeDefCanvas();
10630 gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10631 gPad->SetGrid();
10632}
10633
10634////////////////////////////////////////////////////////////////////////////////
10635/// Show projection onto X.
10636
10638{
10639
10640 Int_t nbins = (Int_t)fShowProjection/100;
10641 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10642 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10643
10644 // Erase old position and draw a line at current position
10645 static int pyold1 = 0;
10646 static int pyold2 = 0;
10647 float uxmin = gPad->GetUxmin();
10648 float uxmax = gPad->GetUxmax();
10649 int pxmin = gPad->XtoAbsPixel(uxmin);
10650 int pxmax = gPad->XtoAbsPixel(uxmax);
10651 Float_t upy = gPad->AbsPixeltoY(py);
10652 Float_t y = gPad->PadtoY(upy);
10653 Int_t biny1 = fH->GetYaxis()->FindBin(y);
10654 Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10655 Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10656 Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10657
10658 if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10659 gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10660 pyold1 = py1;
10661 pyold2 = py2;
10662
10663 // Create or set the new canvas proj x
10664 TVirtualPad *padsav = gPad;
10665 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10667 if (c) {
10668 c->Clear();
10669 } else {
10670 fShowProjection = 0;
10671 pyold1 = 0;
10672 pyold2 = 0;
10673 return;
10674 }
10675 c->cd();
10676 c->SetLogy(padsav->GetLogz());
10677 c->SetLogx(padsav->GetLogx());
10678
10679 // Draw slice corresponding to mouse position
10680 TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10681 TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10682 if (hp) {
10683 hp->SetFillColor(38);
10684 // apply a patch from Oliver Freyermuth to set the title in the projection
10685 // using the range of the projected Y values
10686 if (biny1 == biny2) {
10687 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10688 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10689 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10690 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10691 if (fH->GetYaxis()->GetLabels() != NULL) {
10692 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10693 } else {
10694 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10695 }
10696 } else {
10697 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10698 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10699 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10700 // biny1 is used here to get equal precision no matter how large the binrange is,
10701 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10702 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10703 if (fH->GetYaxis()->GetLabels() != NULL) {
10704 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf] [%s..%s]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1), fH->GetYaxis()->GetBinLabel(biny2)));
10705 } else {
10706 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10707 }
10708 }
10709 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10710 hp->SetYTitle("Number of Entries");
10711 hp->Draw();
10712 c->Update();
10713 padsav->cd();
10714 }
10715}
10716
10717////////////////////////////////////////////////////////////////////////////////
10718/// Show projection onto Y.
10719
10721{
10722
10723 Int_t nbins = (Int_t)fShowProjection/100;
10724 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10725 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10726
10727 // Erase old position and draw a line at current position
10728 static int pxold1 = 0;
10729 static int pxold2 = 0;
10730 float uymin = gPad->GetUymin();
10731 float uymax = gPad->GetUymax();
10732 int pymin = gPad->YtoAbsPixel(uymin);
10733 int pymax = gPad->YtoAbsPixel(uymax);
10734 Float_t upx = gPad->AbsPixeltoX(px);
10735 Float_t x = gPad->PadtoX(upx);
10736 Int_t binx1 = fH->GetXaxis()->FindBin(x);
10737 Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10738 Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10739 Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10740
10741 if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10742 gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10743 pxold1 = px1;
10744 pxold2 = px2;
10745
10746 // Create or set the new canvas proj y
10747 TVirtualPad *padsav = gPad;
10748 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10750 if (c) {
10751 c->Clear();
10752 } else {
10753 fShowProjection = 0;
10754 pxold1 = 0;
10755 pxold2 = 0;
10756 return;
10757 }
10758 c->cd();
10759 c->SetLogy(padsav->GetLogz());
10760 c->SetLogx(padsav->GetLogy());
10761
10762 // Draw slice corresponding to mouse position
10763 TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10764 TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10765 if (hp) {
10766 hp->SetFillColor(38);
10767 // apply a patch from Oliver Freyermuth to set the title in the projection
10768 // using the range of the projected X values
10769 if (binx1 == binx2) {
10770 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10771 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10772 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10773 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10774 if (fH->GetXaxis()->GetLabels() != NULL) {
10775 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10776 } else {
10777 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10778 }
10779 } else {
10780 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10781 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10782 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10783 // binx1 is used here to get equal precision no matter how large the binrange is,
10784 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10785 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10786 if (fH->GetXaxis()->GetLabels() != NULL) {
10787 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf] [%s..%s]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1), fH->GetXaxis()->GetBinLabel(binx2)));
10788 } else {
10789 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10790 }
10791 }
10792 hp->SetXTitle(fH->GetYaxis()->GetTitle());
10793 hp->SetYTitle("Number of Entries");
10794 hp->Draw();
10795 c->Update();
10796 padsav->cd();
10797 }
10798}
10799
10800////////////////////////////////////////////////////////////////////////////////
10801/// Show projection (specified by `fShowProjection`) of a `TH3`.
10802/// The drawing option for the projection is in `fShowOption`.
10803///
10804/// First implementation; R.Brun
10805///
10806/// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10807
10809{
10810
10811 Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10812 if (fH->GetDimension() < 3) {
10813 if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10814 if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10815 }
10816
10817 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10818 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10819
10820 // Erase old position and draw a line at current position
10821 TView *view = gPad->GetView();
10822 if (!view) return;
10823 TH3 *h3 = (TH3*)fH;
10824 TAxis *xaxis = h3->GetXaxis();
10825 TAxis *yaxis = h3->GetYaxis();
10826 TAxis *zaxis = h3->GetZaxis();
10827 Double_t u[3],xx[3];
10828
10829 static TPoint line1[2];//store end points of a line, initialised 0 by default
10830 static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10831 static TPoint line3[2];
10832 static TPoint line4[2];
10833 static TPoint endface1[5];
10834 static TPoint endface2[5];
10835 static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10836 static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10837
10838 Double_t uxmin = gPad->GetUxmin();
10839 Double_t uxmax = gPad->GetUxmax();
10840 Double_t uymin = gPad->GetUymin();
10841 Double_t uymax = gPad->GetUymax();
10842
10843 int pxmin = gPad->XtoAbsPixel(uxmin);
10844 int pxmax = gPad->XtoAbsPixel(uxmax);
10845 if (pxmin==pxmax) return;
10846 int pymin = gPad->YtoAbsPixel(uymin);
10847 int pymax = gPad->YtoAbsPixel(uymax);
10848 if (pymin==pymax) return;
10849 Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10850 Double_t cy = (pymax-pymin)/(uymax-uymin);
10851 TVirtualPad *padsav = gPad;
10852 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10854 if (!c) {
10855 fShowProjection = 0;
10856 return;
10857 }
10858
10859 switch ((Int_t)fShowProjection%100) {
10860 case 1:
10861 // "x"
10862 {
10863 Int_t firstY = yaxis->GetFirst();
10864 Int_t lastY = yaxis->GetLast();
10865 Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10866 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10867 yaxis->SetRange(biny,biny2);
10868 Int_t firstZ = zaxis->GetFirst();
10869 Int_t lastZ = zaxis->GetLast();
10870 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10871 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10872 zaxis->SetRange(binz,binz2);
10873 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10874 if (nbins>1 && line1[0].GetX()) {
10875 gVirtualX->DrawPolyLine(2,line2);
10876 gVirtualX->DrawPolyLine(2,line3);
10877 gVirtualX->DrawPolyLine(2,line4);
10878 gVirtualX->DrawPolyLine(5,endface1);
10879 gVirtualX->DrawPolyLine(5,endface2);
10880 }
10881 xx[0] = xaxis->GetXmin();
10882 xx[2] = zaxis->GetBinCenter(binz);
10883 xx[1] = yaxis->GetBinCenter(biny);
10884 view->WCtoNDC(xx,u);
10885 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10886 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10887 xx[0] = xaxis->GetXmax();
10888 view->WCtoNDC(xx,u);
10889 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10890 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10891 gVirtualX->DrawPolyLine(2,line1);
10892 if (nbins>1) {
10893 xx[0] = xaxis->GetXmin();
10894 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10895 xx[1] = yaxis->GetBinCenter(biny);
10896 view->WCtoNDC(xx,u);
10897 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10898 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10899 xx[0] = xaxis->GetXmax();
10900 view->WCtoNDC(xx,u);
10901 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10902 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10903
10904 xx[0] = xaxis->GetXmin();
10905 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10906 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10907 view->WCtoNDC(xx,u);
10908 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10909 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10910 xx[0] = xaxis->GetXmax();
10911 view->WCtoNDC(xx,u);
10912 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10913 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10914
10915 xx[0] = xaxis->GetXmin();
10916 xx[2] = zaxis->GetBinCenter(binz);
10917 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10918 view->WCtoNDC(xx,u);
10919 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10920 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10921 xx[0] = xaxis->GetXmax();
10922 view->WCtoNDC(xx,u);
10923 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10924 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10925
10926 endface1[0].SetX(line1[0].GetX());
10927 endface1[0].SetY(line1[0].GetY());
10928 endface1[1].SetX(line2[0].GetX());
10929 endface1[1].SetY(line2[0].GetY());
10930 endface1[2].SetX(line3[0].GetX());
10931 endface1[2].SetY(line3[0].GetY());
10932 endface1[3].SetX(line4[0].GetX());
10933 endface1[3].SetY(line4[0].GetY());
10934 endface1[4].SetX(line1[0].GetX());
10935 endface1[4].SetY(line1[0].GetY());
10936
10937 endface2[0].SetX(line1[1].GetX());
10938 endface2[0].SetY(line1[1].GetY());
10939 endface2[1].SetX(line2[1].GetX());
10940 endface2[1].SetY(line2[1].GetY());
10941 endface2[2].SetX(line3[1].GetX());
10942 endface2[2].SetY(line3[1].GetY());
10943 endface2[3].SetX(line4[1].GetX());
10944 endface2[3].SetY(line4[1].GetY());
10945 endface2[4].SetX(line1[1].GetX());
10946 endface2[4].SetY(line1[1].GetY());
10947
10948 gVirtualX->DrawPolyLine(2,line2);
10949 gVirtualX->DrawPolyLine(2,line3);
10950 gVirtualX->DrawPolyLine(2,line4);
10951 gVirtualX->DrawPolyLine(5,endface1);
10952 gVirtualX->DrawPolyLine(5,endface2);
10953 }
10954 c->Clear();
10955 c->cd();
10956 TH1 *hp = h3->Project3D("x");
10957 yaxis->SetRange(firstY,lastY);
10958 zaxis->SetRange(firstZ,lastZ);
10959 if (hp) {
10960 hp->SetFillColor(38);
10961 if (nbins == 1)
10962 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10963 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10964 else {
10965 hp->SetTitle(TString::Format("ProjectionX, biny=[%d,%d] [y=%.1f..%.1f], binz=[%d,%d] [z=%.1f..%.1f]", biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2),
10966 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10967 }
10968 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10969 hp->SetYTitle("Number of Entries");
10970 hp->Draw(fShowOption.Data());
10971 }
10972 }
10973 break;
10974
10975 case 2:
10976 // "y"
10977 {
10978 Int_t firstX = xaxis->GetFirst();
10979 Int_t lastX = xaxis->GetLast();
10980 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10981 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10982 xaxis->SetRange(binx,binx2);
10983 Int_t firstZ = zaxis->GetFirst();
10984 Int_t lastZ = zaxis->GetLast();
10985 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10986 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10987 zaxis->SetRange(binz,binz2);
10988 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10989 if (nbins>1 && line1[0].GetX()) {
10990 gVirtualX->DrawPolyLine(2,line2);
10991 gVirtualX->DrawPolyLine(2,line3);
10992 gVirtualX->DrawPolyLine(2,line4);
10993 gVirtualX->DrawPolyLine(5,endface1);
10994 gVirtualX->DrawPolyLine(5,endface2);
10995 }
10996 xx[0]=xaxis->GetBinCenter(binx);
10997 xx[2] = zaxis->GetBinCenter(binz);
10998 xx[1] = yaxis->GetXmin();
10999 view->WCtoNDC(xx,u);
11000 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11001 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11002 xx[1] = yaxis->GetXmax();
11003 view->WCtoNDC(xx,u);
11004 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11005 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11006 gVirtualX->DrawPolyLine(2,line1);
11007 if (nbins>1) {
11008 xx[1] = yaxis->GetXmin();
11009 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11010 xx[0] = xaxis->GetBinCenter(binx);
11011 view->WCtoNDC(xx,u);
11012 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11013 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11014 xx[1] = yaxis->GetXmax();
11015 view->WCtoNDC(xx,u);
11016 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11017 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11018
11019 xx[1] = yaxis->GetXmin();
11020 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11021 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11022 view->WCtoNDC(xx,u);
11023 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11024 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11025 xx[1] = yaxis->GetXmax();
11026 view->WCtoNDC(xx,u);
11027 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11028 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11029
11030 xx[1] = yaxis->GetXmin();
11031 xx[2] = zaxis->GetBinCenter(binz);
11032 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11033 view->WCtoNDC(xx,u);
11034 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11035 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11036 xx[1] = yaxis->GetXmax();
11037 view->WCtoNDC(xx,u);
11038 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11039 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11040
11041 endface1[0].SetX(line1[0].GetX());
11042 endface1[0].SetY(line1[0].GetY());
11043 endface1[1].SetX(line2[0].GetX());
11044 endface1[1].SetY(line2[0].GetY());
11045 endface1[2].SetX(line3[0].GetX());
11046 endface1[2].SetY(line3[0].GetY());
11047 endface1[3].SetX(line4[0].GetX());
11048 endface1[3].SetY(line4[0].GetY());
11049 endface1[4].SetX(line1[0].GetX());
11050 endface1[4].SetY(line1[0].GetY());
11051
11052 endface2[0].SetX(line1[1].GetX());
11053 endface2[0].SetY(line1[1].GetY());
11054 endface2[1].SetX(line2[1].GetX());
11055 endface2[1].SetY(line2[1].GetY());
11056 endface2[2].SetX(line3[1].GetX());
11057 endface2[2].SetY(line3[1].GetY());
11058 endface2[3].SetX(line4[1].GetX());
11059 endface2[3].SetY(line4[1].GetY());
11060 endface2[4].SetX(line1[1].GetX());
11061 endface2[4].SetY(line1[1].GetY());
11062
11063 gVirtualX->DrawPolyLine(2,line2);
11064 gVirtualX->DrawPolyLine(2,line3);
11065 gVirtualX->DrawPolyLine(2,line4);
11066 gVirtualX->DrawPolyLine(5,endface1);
11067 gVirtualX->DrawPolyLine(5,endface2);
11068 }
11069 c->Clear();
11070 c->cd();
11071 TH1 *hp = h3->Project3D("y");
11072 xaxis->SetRange(firstX,lastX);
11073 zaxis->SetRange(firstZ,lastZ);
11074 if (hp) {
11075 hp->SetFillColor(38);
11076 if (nbins == 1)
11077 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11078 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11079 else
11080 hp->SetTitle(TString::Format("ProjectionY, binx=[%d,%d] [x=%.1f..%.1f], binz=[%d,%d] [z=%.1f..%.1f]", binx, binx2, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx2),
11081 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11082 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11083 hp->SetYTitle("Number of Entries");
11084 hp->Draw(fShowOption.Data());
11085 }
11086 }
11087 break;
11088
11089 case 3:
11090 // "z"
11091 {
11092 Int_t firstX = xaxis->GetFirst();
11093 Int_t lastX = xaxis->GetLast();
11094 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11095 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11096 xaxis->SetRange(binx,binx2);
11097 Int_t firstY = yaxis->GetFirst();
11098 Int_t lastY = yaxis->GetLast();
11099 Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
11100 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11101 yaxis->SetRange(biny,biny2);
11102 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11103 if (nbins>1 && line1[0].GetX()) {
11104 gVirtualX->DrawPolyLine(2,line2);
11105 gVirtualX->DrawPolyLine(2,line3);
11106 gVirtualX->DrawPolyLine(2,line4);
11107 gVirtualX->DrawPolyLine(5,endface1);
11108 gVirtualX->DrawPolyLine(5,endface2);
11109 }
11110 xx[0] = xaxis->GetBinCenter(binx);
11111 xx[1] = yaxis->GetBinCenter(biny);
11112 xx[2] = zaxis->GetXmin();
11113 view->WCtoNDC(xx,u);
11114 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11115 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11116 xx[2] = zaxis->GetXmax();
11117 view->WCtoNDC(xx,u);
11118 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11119 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11120 gVirtualX->DrawPolyLine(2,line1);
11121 if (nbins>1) {
11122 xx[2] = zaxis->GetXmin();
11123 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11124 xx[0] = xaxis->GetBinCenter(binx);
11125 view->WCtoNDC(xx,u);
11126 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11127 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11128 xx[2] = zaxis->GetXmax();
11129 view->WCtoNDC(xx,u);
11130 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11131 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11132
11133 xx[2] = zaxis->GetXmin();
11134 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11135 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11136 view->WCtoNDC(xx,u);
11137 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11138 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11139 xx[2] = zaxis->GetXmax();
11140 view->WCtoNDC(xx,u);
11141 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11142 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11143
11144 xx[2] = zaxis->GetXmin();
11145 xx[1] = yaxis->GetBinCenter(biny);
11146 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11147 view->WCtoNDC(xx,u);
11148 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11149 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11150 xx[2] = zaxis->GetXmax();
11151 view->WCtoNDC(xx,u);
11152 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11153 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11154
11155 endface1[0].SetX(line1[0].GetX());
11156 endface1[0].SetY(line1[0].GetY());
11157 endface1[1].SetX(line2[0].GetX());
11158 endface1[1].SetY(line2[0].GetY());
11159 endface1[2].SetX(line3[0].GetX());
11160 endface1[2].SetY(line3[0].GetY());
11161 endface1[3].SetX(line4[0].GetX());
11162 endface1[3].SetY(line4[0].GetY());
11163 endface1[4].SetX(line1[0].GetX());
11164 endface1[4].SetY(line1[0].GetY());
11165
11166 endface2[0].SetX(line1[1].GetX());
11167 endface2[0].SetY(line1[1].GetY());
11168 endface2[1].SetX(line2[1].GetX());
11169 endface2[1].SetY(line2[1].GetY());
11170 endface2[2].SetX(line3[1].GetX());
11171 endface2[2].SetY(line3[1].GetY());
11172 endface2[3].SetX(line4[1].GetX());
11173 endface2[3].SetY(line4[1].GetY());
11174 endface2[4].SetX(line1[1].GetX());
11175 endface2[4].SetY(line1[1].GetY());
11176
11177 gVirtualX->DrawPolyLine(2,line2);
11178 gVirtualX->DrawPolyLine(2,line3);
11179 gVirtualX->DrawPolyLine(2,line4);
11180 gVirtualX->DrawPolyLine(5,endface1);
11181 gVirtualX->DrawPolyLine(5,endface2);
11182 }
11183 c->Clear();
11184 c->cd();
11185 TH1 *hp = h3->Project3D("z");
11186 xaxis->SetRange(firstX,lastX);
11187 yaxis->SetRange(firstY,lastY);
11188 if (hp) {
11189 hp->SetFillColor(38);
11190 if (nbins == 1)
11191 hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11192 biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
11193 else
11194 hp->SetTitle(TString::Format("ProjectionZ, binx=[%d,%d] [x=%.1f..%.1f], biny=[%d,%d] [y=%.1f..%.1f]", binx, binx2, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx2),
11195 biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
11196 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11197 hp->SetYTitle("Number of Entries");
11198 hp->Draw(fShowOption.Data());
11199 }
11200 }
11201 break;
11202
11203 case 4:
11204 // "xy"
11205 {
11206 Int_t first = zaxis->GetFirst();
11207 Int_t last = zaxis->GetLast();
11208 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11209 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11210 zaxis->SetRange(binz,binz2);
11211 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11212 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11213 xx[0] = xaxis->GetXmin();
11214 xx[1] = yaxis->GetXmax();
11215 xx[2] = zaxis->GetBinCenter(binz);
11216 view->WCtoNDC(xx,u);
11217 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11218 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11219 rect1[4].SetX(rect1[0].GetX());
11220 rect1[4].SetY(rect1[0].GetY());
11221 xx[0] = xaxis->GetXmax();
11222 view->WCtoNDC(xx,u);
11223 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11224 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11225 xx[1] = yaxis->GetXmin();
11226 view->WCtoNDC(xx,u);
11227 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11228 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11229 xx[0] = xaxis->GetXmin();
11230 view->WCtoNDC(xx,u);
11231 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11232 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11233 gVirtualX->DrawPolyLine(5,rect1);
11234 if (nbins>1) {
11235 xx[0] = xaxis->GetXmin();
11236 xx[1] = yaxis->GetXmax();
11237 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11238 view->WCtoNDC(xx,u);
11239 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11240 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11241 rect2[4].SetX(rect2[0].GetX());
11242 rect2[4].SetY(rect2[0].GetY());
11243 xx[0] = xaxis->GetXmax();
11244 view->WCtoNDC(xx,u);
11245 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11246 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11247 xx[1] = yaxis->GetXmin();
11248 view->WCtoNDC(xx,u);
11249 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11250 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11251 xx[0] = xaxis->GetXmin();
11252 view->WCtoNDC(xx,u);
11253 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11254 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11255 gVirtualX->DrawPolyLine(5,rect2);
11256 }
11257
11258 c->Clear();
11259 c->cd();
11260 TH2 *hp = (TH2*)h3->Project3D("xy");
11261 zaxis->SetRange(first,last);
11262 if (hp) {
11263 hp->SetFillColor(38);
11264 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11265 else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11266 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11267 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11268 hp->SetZTitle("Number of Entries");
11269 hp->Draw(fShowOption.Data());
11270 }
11271 }
11272 break;
11273
11274 case 5:
11275 // "yx"
11276 {
11277 Int_t first = zaxis->GetFirst();
11278 Int_t last = zaxis->GetLast();
11279 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11280 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11281 zaxis->SetRange(binz,binz2);
11282 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11283 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11284 xx[0] = xaxis->GetXmin();
11285 xx[1] = yaxis->GetXmax();
11286 xx[2] = zaxis->GetBinCenter(binz);
11287 view->WCtoNDC(xx,u);
11288 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11289 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11290 rect1[4].SetX(rect1[0].GetX());
11291 rect1[4].SetY(rect1[0].GetY());
11292 xx[0] = xaxis->GetXmax();
11293 view->WCtoNDC(xx,u);
11294 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11295 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11296 xx[1] = yaxis->GetXmin();
11297 view->WCtoNDC(xx,u);
11298 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11299 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11300 xx[0] = xaxis->GetXmin();
11301 view->WCtoNDC(xx,u);
11302 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11303 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11304 gVirtualX->DrawPolyLine(5,rect1);
11305 if (nbins>1) {
11306 xx[0] = xaxis->GetXmin();
11307 xx[1] = yaxis->GetXmax();
11308 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11309 view->WCtoNDC(xx,u);
11310 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11311 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11312 rect2[4].SetX(rect2[0].GetX());
11313 rect2[4].SetY(rect2[0].GetY());
11314 xx[0] = xaxis->GetXmax();
11315 view->WCtoNDC(xx,u);
11316 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11317 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11318 xx[1] = yaxis->GetXmin();
11319 view->WCtoNDC(xx,u);
11320 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11321 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11322 xx[0] = xaxis->GetXmin();
11323 view->WCtoNDC(xx,u);
11324 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11325 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11326 gVirtualX->DrawPolyLine(5,rect2);
11327 }
11328 c->Clear();
11329 c->cd();
11330 TH2 *hp = (TH2*)h3->Project3D("yx");
11331 zaxis->SetRange(first,last);
11332 if (hp) {
11333 hp->SetFillColor(38);
11334 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11335 else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11336 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11337 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11338 hp->SetZTitle("Number of Entries");
11339 hp->Draw(fShowOption.Data());
11340 }
11341 }
11342 break;
11343
11344 case 6:
11345 // "xz"
11346 {
11347 Int_t first = yaxis->GetFirst();
11348 Int_t last = yaxis->GetLast();
11349 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11350 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11351 yaxis->SetRange(biny,biny2);
11352 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11353 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11354 xx[0] = xaxis->GetXmin();
11355 xx[2] = zaxis->GetXmax();
11356 xx[1] = yaxis->GetBinCenter(biny);
11357 view->WCtoNDC(xx,u);
11358 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11359 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11360 rect1[4].SetX(rect1[0].GetX());
11361 rect1[4].SetY(rect1[0].GetY());
11362 xx[0] = xaxis->GetXmax();
11363 view->WCtoNDC(xx,u);
11364 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11365 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11366 xx[2] = zaxis->GetXmin();
11367 view->WCtoNDC(xx,u);
11368 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11369 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11370 xx[0] = xaxis->GetXmin();
11371 view->WCtoNDC(xx,u);
11372 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11373 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11374 gVirtualX->DrawPolyLine(5,rect1);
11375 if (nbins>1) {
11376 xx[0] = xaxis->GetXmin();
11377 xx[2] = zaxis->GetXmax();
11378 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11379 view->WCtoNDC(xx,u);
11380 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11381 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11382 rect2[4].SetX(rect2[0].GetX());
11383 rect2[4].SetY(rect2[0].GetY());
11384 xx[0] = xaxis->GetXmax();
11385 view->WCtoNDC(xx,u);
11386 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11387 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11388 xx[2] = zaxis->GetXmin();
11389 view->WCtoNDC(xx,u);
11390 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11391 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11392 xx[0] = xaxis->GetXmin();
11393 view->WCtoNDC(xx,u);
11394 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11395 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11396 gVirtualX->DrawPolyLine(5,rect2);
11397 }
11398 c->Clear();
11399 c->cd();
11400 TH2 *hp = (TH2*)h3->Project3D("xz");
11401 yaxis->SetRange(first,last);
11402 if (hp) {
11403 hp->SetFillColor(38);
11404 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11405 else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11406 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11407 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11408 hp->SetZTitle("Number of Entries");
11409 hp->Draw(fShowOption.Data());
11410 }
11411 }
11412 break;
11413
11414 case 7:
11415 // "zx"
11416 {
11417 Int_t first = yaxis->GetFirst();
11418 Int_t last = yaxis->GetLast();
11419 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11420 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11421 yaxis->SetRange(biny,biny2);
11422 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11423 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11424 xx[0] = xaxis->GetXmin();
11425 xx[2] = zaxis->GetXmax();
11426 xx[1] = yaxis->GetBinCenter(biny);
11427 view->WCtoNDC(xx,u);
11428 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11429 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11430 rect1[4].SetX(rect1[0].GetX());
11431 rect1[4].SetY(rect1[0].GetY());
11432 xx[0] = xaxis->GetXmax();
11433 view->WCtoNDC(xx,u);
11434 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11435 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11436 xx[2] = zaxis->GetXmin();
11437 view->WCtoNDC(xx,u);
11438 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11439 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11440 xx[0] = xaxis->GetXmin();
11441 view->WCtoNDC(xx,u);
11442 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11443 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11444 gVirtualX->DrawPolyLine(5,rect1);
11445 if (nbins>1) {
11446 xx[0] = xaxis->GetXmin();
11447 xx[2] = zaxis->GetXmax();
11448 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11449 view->WCtoNDC(xx,u);
11450 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11451 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11452 rect2[4].SetX(rect2[0].GetX());
11453 rect2[4].SetY(rect2[0].GetY());
11454 xx[0] = xaxis->GetXmax();
11455 view->WCtoNDC(xx,u);
11456 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11457 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11458 xx[2] = zaxis->GetXmin();
11459 view->WCtoNDC(xx,u);
11460 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11461 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11462 xx[0] = xaxis->GetXmin();
11463 view->WCtoNDC(xx,u);
11464 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11465 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11466 gVirtualX->DrawPolyLine(5,rect2);
11467 }
11468 c->Clear();
11469 c->cd();
11470 TH2 *hp = (TH2*)h3->Project3D("zx");
11471 yaxis->SetRange(first,last);
11472 if (hp) {
11473 hp->SetFillColor(38);
11474 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11475 else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11476 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11477 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11478 hp->SetZTitle("Number of Entries");
11479 hp->Draw(fShowOption.Data());
11480 }
11481 }
11482 break;
11483
11484 case 8:
11485 // "yz"
11486 {
11487 Int_t first = xaxis->GetFirst();
11488 Int_t last = xaxis->GetLast();
11489 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11490 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11491 xaxis->SetRange(binx,binx2);
11492 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11493 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11494 xx[2] = zaxis->GetXmin();
11495 xx[1] = yaxis->GetXmax();
11496 xx[0] = xaxis->GetBinCenter(binx);
11497 view->WCtoNDC(xx,u);
11498 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11499 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11500 rect1[4].SetX(rect1[0].GetX());
11501 rect1[4].SetY(rect1[0].GetY());
11502 xx[2] = zaxis->GetXmax();
11503 view->WCtoNDC(xx,u);
11504 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11505 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11506 xx[1] = yaxis->GetXmin();
11507 view->WCtoNDC(xx,u);
11508 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11509 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11510 xx[2] = zaxis->GetXmin();
11511 view->WCtoNDC(xx,u);
11512 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11513 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11514 gVirtualX->DrawPolyLine(5,rect1);
11515 if (nbins>1) {
11516 xx[2] = zaxis->GetXmin();
11517 xx[1] = yaxis->GetXmax();
11518 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11519 view->WCtoNDC(xx,u);
11520 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11521 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11522 rect2[4].SetX(rect2[0].GetX());
11523 rect2[4].SetY(rect2[0].GetY());
11524 xx[2] = zaxis->GetXmax();
11525 view->WCtoNDC(xx,u);
11526 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11527 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11528 xx[1] = yaxis->GetXmin();
11529 view->WCtoNDC(xx,u);
11530 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11531 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11532 xx[2] = zaxis->GetXmin();
11533 view->WCtoNDC(xx,u);
11534 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11535 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11536 gVirtualX->DrawPolyLine(5,rect2);
11537 }
11538 c->Clear();
11539 c->cd();
11540 TH2 *hp = (TH2*)h3->Project3D("yz");
11541 xaxis->SetRange(first,last);
11542 if (hp) {
11543 hp->SetFillColor(38);
11544 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11545 else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11546 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11547 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11548 hp->SetZTitle("Number of Entries");
11549 hp->Draw(fShowOption.Data());
11550 }
11551 }
11552 break;
11553
11554 case 9:
11555 // "zy"
11556 {
11557 Int_t first = xaxis->GetFirst();
11558 Int_t last = xaxis->GetLast();
11559 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11560 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11561 xaxis->SetRange(binx,binx2);
11562 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11563 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11564 xx[2] = zaxis->GetXmin();
11565 xx[1] = yaxis->GetXmax();
11566 xx[0] = xaxis->GetBinCenter(binx);
11567 view->WCtoNDC(xx,u);
11568 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11569 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11570 rect1[4].SetX(rect1[0].GetX());
11571 rect1[4].SetY(rect1[0].GetY());
11572 xx[2] = zaxis->GetXmax();
11573 view->WCtoNDC(xx,u);
11574 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11575 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11576 xx[1] = yaxis->GetXmin();
11577 view->WCtoNDC(xx,u);
11578 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11579 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11580 xx[2] = zaxis->GetXmin();
11581 view->WCtoNDC(xx,u);
11582 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11583 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11584 gVirtualX->DrawPolyLine(5,rect1);
11585 if (nbins>1) {
11586 xx[2] = zaxis->GetXmin();
11587 xx[1] = yaxis->GetXmax();
11588 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11589 view->WCtoNDC(xx,u);
11590 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11591 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11592 rect2[4].SetX(rect2[0].GetX());
11593 rect2[4].SetY(rect2[0].GetY());
11594 xx[2] = zaxis->GetXmax();
11595 view->WCtoNDC(xx,u);
11596 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11597 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11598 xx[1] = yaxis->GetXmin();
11599 view->WCtoNDC(xx,u);
11600 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11601 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11602 xx[2] = zaxis->GetXmin();
11603 view->WCtoNDC(xx,u);
11604 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11605 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11606 gVirtualX->DrawPolyLine(5,rect2);
11607 }
11608 c->Clear();
11609 c->cd();
11610 TH2 *hp = (TH2*)h3->Project3D("zy");
11611 xaxis->SetRange(first,last);
11612 if (hp) {
11613 hp->SetFillColor(38);
11614 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11615 else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11616 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11617 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11618 hp->SetZTitle("Number of Entries");
11619 hp->Draw(fShowOption.Data());
11620 }
11621 }
11622 break;
11623 }
11624 c->Update();
11625 padsav->cd();
11626}
@ kMouseMotion
Definition: Buttons.h:23
@ kWheelUp
Definition: Buttons.h:18
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kWheelDown
Definition: Buttons.h:18
@ kButton1Down
Definition: Buttons.h:17
@ kButton1Locate
Definition: Buttons.h:22
void Class()
Definition: Class.C:29
@ kArrowVer
Definition: GuiTypes.h:373
@ kPointer
Definition: GuiTypes.h:374
Handle_t Window_t
Definition: GuiTypes.h:28
ROOT::R::TRInterface & r
Definition: Object.C:4
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:43
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
long Long_t
Definition: RtypesCore.h:52
short Width_t
Definition: RtypesCore.h:80
short Short_t
Definition: RtypesCore.h:37
double Double_t
Definition: RtypesCore.h:57
short Color_t
Definition: RtypesCore.h:81
short Style_t
Definition: RtypesCore.h:78
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define BIT(n)
Definition: Rtypes.h:83
#define ClassImp(name)
Definition: Rtypes.h:361
@ kBlack
Definition: Rtypes.h:63
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
XFontStruct * id
Definition: TGX11.cxx:108
float xmin
Definition: THbookFile.cxx:93
int ncx
Definition: THbookFile.cxx:91
float ymin
Definition: THbookFile.cxx:93
int ncy
Definition: THbookFile.cxx:91
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
static TBox * gYHighlightBox
static TString gStringStdDevZ
static TString gStringStdDevX
static TString gStringIntegralBinWidth
const UInt_t kCannotRotate
static TString gStringStdDev
const Int_t kNMAX
Hparam_t Hparam
const Int_t kMAXCONTOUR
static TBox * gXHighlightBox
static TString gStringOverflow
static TString gStringUnderflow
static TString gStringSkewnessY
static TString gStringMean
static TString gStringKurtosis
Hoption_t Hoption
static TString gStringMeanX
static TString gStringEntries
static TString gStringIntegral
static TString gStringKurtosisY
static TString gStringStdDevY
static TString gStringMeanY
static TString gStringSkewnessX
static TString gStringKurtosisX
static TString gStringSkewnessZ
TH1 * gCurrentHist
static TString gStringMeanZ
static TString gStringSkewness
static TString gStringKurtosisZ
const Int_t kMaxCuts
Definition: THistPainter.h:40
double cos(double)
const Int_t kCYLINDRICAL
const Int_t kSPHERICAL
const Int_t kRAPIDITY
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
const Int_t kCARTESIAN
Definition: TView3D.cxx:33
const Int_t kPOLAR
Definition: TView3D.cxx:34
#define gPad
Definition: TVirtualPad.h:287
#define gVirtualX
Definition: TVirtualX.h:338
polygon * polys
Definition: X3DBuffer.c:24
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3728
Int_t fN
Definition: TArray.h:38
Draw all kinds of Arrows.
Definition: TArrow.h:29
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:45
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:43
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:99
@ kImgBest
Definition: TAttImage.h:68
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:475
const TArrayD * GetXbins() const
Definition: TAxis.h:130
Double_t GetXmax() const
Definition: TAxis.h:134
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:437
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:290
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:515
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:416
const char * ChooseTimeFormat(Double_t axislength=0)
Choose a reasonable time format from the coordinates in the active pad and the number of divisions in...
Definition: TAxis.cxx:123
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:466
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:568
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
Set the viewing range for the axis from ufirst to ulast (in user coordinates).
Definition: TAxis.cxx:939
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:914
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:537
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:455
THashList * GetLabels() const
Definition: TAxis.h:117
Create a Box.
Definition: TBox.h:24
Double_t GetX1() const
Definition: TBox.h:52
virtual void SetY2(Double_t y2)
Definition: TBox.h:66
Double_t GetX2() const
Definition: TBox.h:53
Double_t GetY1() const
Definition: TBox.h:54
virtual void SetX1(Double_t x1)
Definition: TBox.h:63
Double_t GetY2() const
Definition: TBox.h:55
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:195
virtual void SetX2(Double_t x2)
Definition: TBox.h:64
virtual void SetY1(Double_t y1)
Definition: TBox.h:65
virtual void Paint(Option_t *option="")
Paint this box with its current attributes.
Definition: TBox.cxx:669
The candle plot painter class.
Definition: TCandle.h:26
void SetLog(int x, int y, int z)
Definition: TCandle.h:123
CandleOption
Definition: TCandle.h:29
void SetHistoWidth(const Double_t width)
Definition: TCandle.h:127
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition: TCandle.cxx:674
Bool_t IsViolinScaled()
Definition: TCandle.cxx:190
Bool_t IsHorizontal()
Definition: TCandle.h:117
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:244
void SetOption(CandleOption opt)
Definition: TCandle.h:122
void SetHistogram(TH1D *proj)
Definition: TCandle.h:128
Bool_t IsCandleScaled()
Definition: TCandle.cxx:185
void SetCandleWidth(const Double_t width)
Definition: TCandle.h:126
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:124
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition: TCanvas.cxx:2420
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2948
void SetName(const char *name)
Definition: TCollection.h:204
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
The color creation and management class.
Definition: TColor.h:19
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its associated colors.
Definition: TColor.cxx:1705
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition: TColor.h:78
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:51
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition: TColor.cxx:1769
static Int_t GetColorBright(Int_t color)
Static function: Returns the bright color number corresponding to n If the TColor object does not exi...
Definition: TColor.cxx:1916
static Int_t GetColorDark(Int_t color)
Static function: Returns the dark color number corresponding to n If the TColor object does not exist...
Definition: TColor.cxx:1948
static void HLStoRGB(Float_t h, Float_t l, Float_t s, Float_t &r, Float_t &g, Float_t &b)
Definition: TColor.h:73
virtual void SetAlpha(Float_t a)
Definition: TColor.h:67
To draw a Crown.
Definition: TCrown.h:19
virtual void Paint(Option_t *option="")
Paint this crown with its current attributes.
Definition: TCrown.cxx:181
Graphical cut class.
Definition: TCutG.h:20
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
1-Dim function class
Definition: TF1.h:210
virtual Double_t GetXmax() const
Definition: TF1.h:550
virtual Int_t GetNDF() const
Return the number of degrees of freedom in the fit the fNDF parameter has been previously computed du...
Definition: TF1.cxx:1872
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1923
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1913
Double_t GetChisquare() const
Definition: TF1.h:438
virtual void SetMaximum(Double_t maximum=-1111)
Set the maximum value along Y for this function In case the function is already drawn,...
Definition: TF1.cxx:3396
virtual Double_t GetMaximumStored() const
Definition: TF1.h:467
virtual Int_t GetNpar() const
Definition: TF1.h:475
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1883
@ kNotDraw
Definition: TF1.h:320
virtual void SetMinimum(Double_t minimum=-1111)
Set the minimum value along Y for this function In case the function is already drawn,...
Definition: TF1.cxx:3409
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:523
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1432
virtual Double_t GetXmin() const
Definition: TF1.h:546
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:506
A 2-Dim function with parameters.
Definition: TF2.h:29
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:722
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:150
A 3-Dim function with parameters.
Definition: TF3.h:28
The axis painter class.
Definition: TGaxis.h:24
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2721
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:954
void SetTitleOffset(Float_t titleoffset=1)
Definition: TGaxis.h:125
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2694
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:107
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:904
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:119
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:108
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2686
The TGraphDelaunay painting class.
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
TList * GetContourList(Double_t contour)
Returns the X and Y graphs building a contour.
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
@ kClipFrame
clip to the frame boundary
Definition: TGraph.h:70
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6345
TAxis * GetZaxis()
Definition: TH1.h:318
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:268
virtual Float_t GetBarWidth() const
Definition: TH1.h:252
virtual Double_t GetMinimumStored() const
Definition: TH1.h:288
virtual Float_t GetBarOffset() const
Definition: TH1.h:251
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7140
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8519
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual Double_t GetNormFactor() const
Definition: TH1.h:296
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:7086
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7192
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7904
virtual void SetXTitle(const char *title)
Definition: TH1.h:409
virtual Int_t GetDimension() const
Definition: TH1.h:278
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1226
@ kNoTitle
don't draw the histogram title
Definition: TH1.h:165
@ kUserContour
user specified contour levels
Definition: TH1.h:161
@ kNoStats
don't draw stats box
Definition: TH1.h:160
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition: TH1.cxx:4809
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:8006
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
TAxis * GetYaxis()
Definition: TH1.h:317
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8535
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7947
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7450
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8678
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8608
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4302
virtual void SetZTitle(const char *title)
Definition: TH1.h:411
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7117
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
virtual Double_t GetMaximumStored() const
Definition: TH1.h:284
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8187
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:8036
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4907
const Double_t * GetBuffer() const
Definition: TH1.h:234
virtual Bool_t IsHighlight() const
Definition: TH1.h:330
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8619
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8566
virtual void SetYTitle(const char *title)
Definition: TH1.h:410
virtual Int_t GetSumw2N() const
Definition: TH1.h:310
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7179
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:8091
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7426
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:706
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7875
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1347
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7262
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
TH1D * ProjectionY(const char *name="_py", Int_t firstxbin=0, Int_t lastxbin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along Y.
Definition: TH2.cxx:2340
TH1D * ProjectionX(const char *name="_px", Int_t firstybin=0, Int_t lastybin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along X.
Definition: TH2.cxx:2300
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1188
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:88
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH3.cxx:1212
virtual TH1 * Project3D(Option_t *option="x") const
Project a 3-d histogram into 1 or 2-d histograms depending on the option parameter,...
Definition: TH3.cxx:2226
The histogram painter class.
Definition: THistPainter.h:49
static Int_t ProjectSinusoidal2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
virtual Bool_t IsInside(Int_t x, Int_t y)
Return kTRUE if the cell ix, iy is inside one of the graphical cuts.
TAxis * fYaxis
Definition: THistPainter.h:54
Double_t * fXbuf
Definition: THistPainter.h:60
Int_t fXHighlightBin
Definition: THistPainter.h:68
TF3 * fCurrentF3
Definition: THistPainter.h:70
virtual void DrawPanel()
Display a panel with all histogram drawing options.
virtual void PaintErrors(Option_t *option)
Draw 1D histograms error bars.
virtual void SetHistogram(TH1 *h)
Set current histogram to h
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
virtual void PaintStat(Int_t dostat, TF1 *fit)
Draw the statistics box for 1D and profile histograms.
virtual Int_t TableInit()
Initialize various options to draw 2D histograms.
virtual void PaintTH2PolyScatterPlot(Option_t *option)
Control function to draw a TH2Poly as a scatter plot.
static Int_t ProjectAitoff2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintText(Option_t *option)
Control function to draw a 1D/2D histograms with the bin values.
virtual void PaintAxis(Bool_t drawGridOnly=kFALSE)
Draw axis (2D case) of an histogram.
virtual void PaintColorLevelsFast(Option_t *option)
[Rendering scheme for the COL2 and COLZ2 options] (#HP14)
virtual Int_t PaintInit()
Compute histogram parameters used by the drawing routines.
virtual void Paint2DErrors(Option_t *option)
Draw 2D histograms errors.
Int_t fYHighlightBin
Definition: THistPainter.h:69
virtual void PaintCandlePlot(Option_t *option)
Control function to draw a 2D histogram as a candle (box) plot or violin plot
virtual void PaintScatterPlot(Option_t *option)
Control function to draw a 2D histogram as a scatter plot.
virtual ~THistPainter()
Default destructor.
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Display the histogram info (bin number, contents, integral up to bin corresponding to cursor position...
virtual void PaintLego(Option_t *option)
Control function to draw a 2D histogram as a lego plot.
virtual void PaintH3(Option_t *option="")
Control function to draw a 3D histograms.
TString fShowOption
Definition: THistPainter.h:67
virtual void PaintHighlightBin(Option_t *option="")
Paint highlight bin as TBox object.
virtual void PaintTH2PolyBins(Option_t *option)
Control function to draw a TH2Poly bins' contours.
virtual Int_t PaintContourLine(Double_t elev1, Int_t icont1, Double_t x1, Double_t y1, Double_t elev2, Int_t icont2, Double_t x2, Double_t y2, Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
Fill the matrix xarr and yarr for Contour Plot.
Int_t fShowProjection
Definition: THistPainter.h:66
virtual void PaintLegoAxis(TGaxis *axis, Double_t ang)
Draw the axis for legos and surface plots.
virtual void PaintTriangles(Option_t *option)
Control function to draw a table using Delaunay triangles.
virtual void HighlightBin(Int_t px, Int_t py)
Check on highlight bin.
virtual void PaintH3Box(Int_t iopt)
Control function to draw a 3D histogram with boxes.
TList * fFunctions
Definition: THistPainter.h:56
static void PaintSpecialObjects(const TObject *obj, Option_t *option)
Static function to paint special objects like vectors and matrices.
virtual void PaintTitle()
Draw the histogram title.
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
virtual std::vector< THistRenderingRegion > ComputeRenderingRegions(TAxis *pAxis, Int_t nPixels, bool isLog)
Returns the rendering regions for an axis to use in the COL2 option.
virtual void ShowProjectionX(Int_t px, Int_t py)
Show projection onto X.
virtual void PaintPalette()
Paint the color palette on the right side of the pad.
virtual void ProcessMessage(const char *mess, const TObject *obj)
Process message mess.
Double_t * fYbuf
Definition: THistPainter.h:61
TAxis * fXaxis
Definition: THistPainter.h:53
virtual void PaintStat2(Int_t dostat, TF1 *fit)
Draw the statistics box for 2D histograms.
virtual void PaintArrows(Option_t *option)
Control function to draw a table as an arrow plot
virtual void RecalculateRange()
Recompute the histogram range following graphics operations.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
static Int_t ProjectParabolic2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:57
virtual void PaintBarH(Option_t *option)
Draw a bar char in a rotated pad (X vertical, Y horizontal)
virtual void PaintStat3(Int_t dostat, TF1 *fit)
Draw the statistics box for 3D histograms.
virtual void PaintSurface(Option_t *option)
Control function to draw a 2D histogram as a surface plot.
TList * fStack
Definition: THistPainter.h:65
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:58
THistPainter()
Default constructor.
virtual void PaintTH2PolyText(Option_t *option)
Control function to draw a TH2Poly as a text plot.
virtual void ShowProjection3(Int_t px, Int_t py)
Show projection (specified by fShowProjection) of a TH3.
TAxis * fZaxis
Definition: THistPainter.h:55
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
virtual void PaintFunction(Option_t *option)
[Paint functions associated to an histogram.](#HP28")
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
static Int_t ProjectMercator2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintBoxes(Option_t *option)
Control function to draw a 2D histogram as a box plot
virtual Int_t MakeChopt(Option_t *option)
Decode string choptin and fill Hoption structure.
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute the actions corresponding to event.
virtual void SetShowProjection(const char *option, Int_t nbins)
Set projection.
virtual void ShowProjectionY(Int_t px, Int_t py)
Show projection onto Y.
virtual void SetHighlight()
Set highlight (enable/disable) mode for fH.
static const char * GetBestFormat(Double_t v, Double_t e, const char *f)
This function returns the best format to print the error value (e) knowing the parameter value (v) an...
virtual void PaintContour(Option_t *option)
Control function to draw a 2D histogram as a contour plot.
TCutG * fCuts[kMaxCuts]
Definition: THistPainter.h:64
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
virtual TList * GetContourList(Double_t contour) const
Get a contour (as a list of TGraphs) using the Delaunay triangulation.
virtual Int_t PaintInitH()
Compute histogram parameters used by the drawing routines for a rotated pad.
virtual void PaintFrame()
Calculate range and clear pad (canvas).
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:63
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
virtual void PaintH3BoxRaster()
Control function to draw a 3D histogram with boxes.
virtual void PaintHist(Option_t *option)
Control routine to draw 1D histograms
virtual Int_t MakeCuts(char *cutsopt)
Decode string choptin and fill Graphical cuts structure.
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
TString fObjectInfo
Definition: THistPainter.h:73
virtual void PaintColorLevels(Option_t *option)
Control function to draw a 2D histogram as a color plot.
A class to define a conversion from pixel values to pixel color.
Definition: TAttImage.h:33
static TImagePalette * CreateCOLPalette(Int_t nContours)
Factory method to creates an image palette for histogram plotting.
Definition: TAttImage.cxx:748
An abstract interface to image processing library.
Definition: TImage.h:29
virtual void SetImage(const Double_t *, UInt_t, UInt_t, TImagePalette *=0)
Definition: TImage.h:116
static TImage * Create()
Create an image.
Definition: TImage.cxx:36
virtual void PaintImage(Drawable_t, Int_t, Int_t, Int_t=0, Int_t=0, UInt_t=0, UInt_t=0, Option_t *="")
Definition: TImage.h:243
void Reset()
Definition: TCollection.h:252
To draw Mathematical Formula.
Definition: TLatex.h:18
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:821
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:99
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:356
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:658
TMatrixTBase.
Definition: TMatrixTBase.h:85
TClass * Class()
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:36
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
void Add(TObject *obj)
Definition: TObjArray.h:74
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
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:187
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
@ kCannotPick
if object in a pad cannot be picked
Definition: TObject.h:63
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
The Legos and Surfaces painter class.
void DrawFaceMove3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 3rd variant for "MOVING SCREEN" algorithm (draw level lines only)
void SetDrawFace(DrawFaceFunc_t pointer)
Store pointer to current algorithm to draw faces.
void SetIsoSurfaceParameters(Double_t fmin, Double_t fmax, Int_t ncolor, Int_t ic1, Int_t ic2, Int_t ic3)
void IsoSurface(Int_t ns, Double_t *s, Int_t nx, Int_t ny, Int_t nz, Double_t *x, Double_t *y, Double_t *z, const char *chopt)
Draw set of iso-surfaces for a scalar function defined on a grid.
void DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw level lines without hidden line removal.
void SetLegoFunction(LegoFunc_t pointer)
Store pointer to current lego function.
void SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in cylindrical coordinates.
void SurfaceFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Service function for Surfaces.
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
void FillPolygonBorder(Int_t nn, Double_t *xy)
Fill a polygon including border ("RASTER SCREEN")
void LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots spheric coordinates.
void SurfaceCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw surface in cartesian coordinate system.
void SurfaceProperty(Double_t qqa, Double_t qqd, Double_t qqs, Int_t nnqs, Int_t &irep)
Set surface property coefficients.
void InitMoveScreen(Double_t xmin, Double_t xmax)
Initialize "MOVING SCREEN" method.
void FindVisibleLine(Double_t *p1, Double_t *p2, Int_t ntmax, Int_t &nt, Double_t *t)
Find visible part of a line ("RASTER SCREEN")
void LegoCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw stack of lego-plots in cartesian coordinates.
void DrawFaceMode1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 1st variant (2 colors: 1st for external surface, 2nd for internal)
void LightSource(Int_t nl, Double_t yl, Double_t xscr, Double_t yscr, Double_t zscr, Int_t &irep)
Set light source.
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
void DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "MOVING SCREEN" algorithm (draw face with level lines)
void SetSurfaceFunction(SurfaceFunc_t pointer)
Store pointer to current surface function.
void SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in polar coordinates.
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
void BackBox(Double_t ang)
Draw back surfaces of surrounding box.
void ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int_t &irep)
Set correspondence between function and color levels.
void DrawFaceRaster2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "RASTER SCREEN" algorithm (draw face for stacked lego plot)
void LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in polar coordinates.
void SetEdgeAtt(Color_t color=1, Style_t style=1, Width_t width=1, Int_t n=0)
void SetMesh(Int_t mesh=1)
void InitRaster(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Int_t nx, Int_t ny)
Initialize hidden lines removal algorithm (RASTER SCREEN)
void DefineGridLevels(Int_t ndivz)
Define the grid levels drawn in the background of surface and lego plots.
void LegoFunction(Int_t ia, Int_t ib, Int_t &nv, Double_t *ab, Double_t *vv, Double_t *t)
Service function for Legos.
void DrawFaceMove2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "MOVING SCREEN" algorithm (draw face for stacked lego plot)
void SetColorMain(Color_t color, Int_t n=0)
Store color for stack number n.
void Spectrum(Int_t nl, Double_t fmin, Double_t fmax, Int_t ic, Int_t idc, Int_t &irep)
Set Spectrum.
void DrawFaceRaster1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "RASTER SCREEN" algorithm (draw face with level lines)
void DrawFaceMode3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 3rd option (draw face for stacked lego plot)
void FrontBox(Double_t ang)
Draw front surfaces of surrounding box & axes.
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
void DrawFaceMode2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 2nd option (fill in correspondence with function levels)
void ImplicitFunction(TF3 *f3, Double_t *rmin, Double_t *rmax, Int_t nx, Int_t ny, Int_t nz, const char *chopt)
Draw implicit function FUN(X,Y,Z) = 0 in cartesian coordinates using hidden surface removal algorithm...
The palette painting class.
Definition: TPaletteAxis.h:29
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:57
virtual void Paint(Option_t *option="")
Paint the palette.
TH1 * GetHistogram()
Definition: TPaletteAxis.h:51
The histogram statistics painter class.
Definition: TPaveStats.h:18
Int_t GetOptStat() const
Return the stat option.
Definition: TPaveStats.cxx:266
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:312
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:303
virtual void SetParent(TObject *obj)
Definition: TPaveStats.h:52
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:286
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:257
virtual void Paint(Option_t *option="")
Paint the pave stat.
Definition: TPaveStats.cxx:320
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:294
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:36
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:182
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:233
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:410
virtual TText * GetLine(Int_t number) const
Get Pointer to line number in this pavetext.
Definition: TPaveText.cxx:274
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:208
virtual void SetName(const char *name="")
Definition: TPave.h:75
Option_t * GetName() const
Returns name of object.
Definition: TPave.h:56
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:73
Double_t GetX1NDC() const
Definition: TPave.h:59
virtual void SetX2NDC(Double_t x2)
Definition: TPave.h:79
Draw a Pie Chart,.
Definition: TPie.h:23
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:803
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition: TPie.cxx:394
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition: TPie.cxx:169
Definition: TPoint.h:31
void SetX(SCoord_t x)
Definition: TPoint.h:48
void SetY(SCoord_t y)
Definition: TPoint.h:49
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
Double_t * GetX() const
Definition: TPolyLine.h:54
virtual void SetPoint(Int_t point, Double_t x, Double_t y)
Set point number n to (x, y) If n is greater than the current size, the arrays are automatically exte...
Definition: TPolyLine.cxx:635
Double_t * GetY() const
Definition: TPolyLine.h:55
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X,...
Definition: TProfile2D.h:27
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:796
Profile Histogram.
Definition: TProfile.h:32
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:821
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:27
virtual Double_t Rndm()
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
Sequenceable collection abstract base class.
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
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
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:234
Color_t GetStatTextColor() const
Definition: TStyle.h:247
Float_t GetTitleX() const
Definition: TStyle.h:269
Int_t GetOptTitle() const
Definition: TStyle.h:235
Float_t GetStatFontSize() const
Definition: TStyle.h:250
Float_t GetBarOffset() const
Definition: TStyle.h:172
Float_t GetStatX() const
Definition: TStyle.h:253
Float_t GetTitleSize(Option_t *axis="X") const
Return title size.
Definition: TStyle.cxx:1188
Float_t GetTitleY() const
Definition: TStyle.h:270
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1164
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:226
Float_t GetStatY() const
Definition: TStyle.h:254
Color_t GetTitleFillColor() const
Definition: TStyle.h:260
Style_t GetTitleStyle() const
Definition: TStyle.h:262
Color_t GetStatColor() const
Definition: TStyle.h:246
Float_t GetBarWidth() const
Definition: TStyle.h:173
Float_t GetStatH() const
Definition: TStyle.h:256
Width_t GetTitleBorderSize() const
Definition: TStyle.h:264
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:1056
Float_t GetErrorX() const
Definition: TStyle.h:176
Double_t GetHistTopMargin() const
Definition: TStyle.h:227
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:317
Float_t GetEndErrorSize() const
Definition: TStyle.h:175
Width_t GetStatBorderSize() const
Definition: TStyle.h:248
Int_t GetTitleAlign()
Definition: TStyle.h:259
Color_t GetTitleTextColor() const
Definition: TStyle.h:261
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:318
Float_t GetTitleH() const
Definition: TStyle.h:272
Style_t GetStatStyle() const
Definition: TStyle.h:251
Float_t GetStatW() const
Definition: TStyle.h:255
const char * GetFitFormat() const
Definition: TStyle.h:189
const char * GetStatFormat() const
Definition: TStyle.h:252
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:1122
Int_t GetOptFit() const
Definition: TStyle.h:233
Int_t GetNumberContours() const
Definition: TStyle.h:230
const char * GetPaintTextFormat() const
Definition: TStyle.h:239
Style_t GetStatFont() const
Definition: TStyle.h:249
Float_t GetTitleFontSize() const
Definition: TStyle.h:263
Float_t GetTitleW() const
Definition: TStyle.h:271
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1850
Base class for several text objects.
Definition: TText.h:23
TVectorT.
Definition: TVectorT.h:27
TClass * Class()
See TView3D.
Definition: TView.h:25
virtual Double_t GetPsi()=0
virtual Double_t * GetRmax()=0
virtual void SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)=0
virtual Double_t * GetRmin()=0
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
virtual void SetOutlineToCube()=0
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)=0
virtual Double_t * GetTnorm()=0
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)=0
virtual TSeqCollection * GetOutline()=0
virtual void PadRange(Int_t rback)=0
virtual void FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)=0
virtual void AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)=0
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
Abstract base class used by ROOT graphics editor.
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
virtual void Show()
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:51
virtual Int_t GetLogz() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Int_t GetLogy() const =0
virtual Int_t GetLogx() const =0
TText * text
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
RooCmdArg Bins(Int_t nbin)
double beta(double x, double y)
Calculates the beta function.
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
Double_t ey[n]
Definition: legend1.C:17
Double_t ex[n]
Definition: legend1.C:17
TH1F * h1
Definition: legend1.C:5
TF1 * f1
Definition: legend1.C:11
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static constexpr double bar
static constexpr double rad
static constexpr double s
static constexpr double mg
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:703
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:614
Double_t ATan(Double_t)
Definition: TMath.h:665
constexpr Double_t PiOver2()
Definition: TMath.h:52
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Double_t Log(Double_t x)
Definition: TMath.h:750
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition: TMath.h:82
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:725
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Double_t Cos(Double_t)
Definition: TMath.h:631
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:418
Double_t Sin(Double_t)
Definition: TMath.h:627
Double_t Tan(Double_t)
Definition: TMath.h:635
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition: TMath.h:74
Double_t Log10(Double_t x)
Definition: TMath.h:754
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: first.py:1
fill
Definition: fit1_py.py:6
Definition: graph.py:1
Histogram option structure.
Definition: Hoption.h:24
int Curve
"C" A smooth Curve is drawn.
Definition: Hoption.h:29
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:58
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition: Hoption.h:47
int Text
"TEXT" Draw 2D plot with the content of each cell.
Definition: Hoption.h:49
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
int AxisPos
Axis position.
Definition: Hoption.h:59
int List
= 1 to generate the TObjArray "contours"
Definition: Hoption.h:57
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:67
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:54
int MinimumZero
"MIN0" or gStyle->GetHistMinimumZero()
Definition: Hoption.h:62
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
int Off
"][" With H option, the first and last vertical lines are not drawn.
Definition: Hoption.h:32
int Func
"FUNC" Draw only the function (for example in case of fit).
Definition: Hoption.h:44
long Candle
"CANDLE" Draw a 2D histogram as candle/box plot or violin plot (also with "VIOLIN").
Definition: Hoption.h:52
int Spec
TSpectrum graphics.
Definition: Hoption.h:60
int FrontBox
= 0 to suppress the front box
Definition: Hoption.h:55
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition: Hoption.h:51
int Char
"CHAR" Draw 2D plot with a character set.
Definition: Hoption.h:41
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:61
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:69
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:56
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
int Arrow
"ARR" Draw 2D plot with Arrows.
Definition: Hoption.h:39
int Line
"L" A simple polyline beetwen every point is drawn.
Definition: Hoption.h:34
int Same
"S" Histogram is plotted in the current PAD.
Definition: Hoption.h:36
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
int Bar
"B" A Bar chart is drawn at each point.
Definition: Hoption.h:28
int Fill
"F" A fill area is drawn ("CF" draw a smooth fill area).
Definition: Hoption.h:31
int Hist
"HIST" Draw only the histogram.
Definition: Hoption.h:45
int Surf
"SURF" Draw as a Surface (SURF,Surf=1, SURF1,Surf=11, SURF2,Surf=12)
Definition: Hoption.h:48
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:68
int System
type of coordinate system(1=car,2=pol,3=cyl,4=sph,5=psr)
Definition: Hoption.h:53
int Error
"E" Draw Errors with current marker type and size.
Definition: Hoption.h:30
Histogram parameters structure.
Definition: Hparam.h:26
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:41
Double_t ylowedge
low edge of axis
Definition: Hparam.h:32
Double_t xmin
minimum value along X
Definition: Hparam.h:29
Int_t ylast
last bin number along Y
Definition: Hparam.h:46
Int_t xfirst
first bin number along X
Definition: Hparam.h:43
Double_t zmin
minimum value along Z
Definition: Hparam.h:37
Double_t xbinsize
bin size in case of equidistant bins
Definition: Hparam.h:27
Double_t ymin
minimum value along y
Definition: Hparam.h:33
Double_t allchan
integrated sum of contents
Definition: Hparam.h:40
Double_t xlowedge
low edge of axis
Definition: Hparam.h:28
Double_t ymax
maximum value along y
Definition: Hparam.h:34
Double_t factor
multiplication factor (normalization)
Definition: Hparam.h:39
Int_t xlast
last bin number along X
Definition: Hparam.h:44
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:31
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:42
Double_t zmax
maximum value along Z
Definition: Hparam.h:38
Double_t xmax
maximum value along X
Definition: Hparam.h:30
Int_t yfirst
first bin number along Y
Definition: Hparam.h:45
auto * th2
Definition: textalign.C:17
auto * m
Definition: textangle.C:8
auto * tt
Definition: textangle.C:16
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
#define mark(osub)
Definition: triangle.c:1206