Logo ROOT   6.14/05
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 "TClass.h"
20 #include "TSystem.h"
21 #include "THistPainter.h"
22 #include "TH2.h"
23 #include "TH2Poly.h"
24 #include "TH3.h"
25 #include "TProfile.h"
26 #include "TProfile2D.h"
27 #include "THStack.h"
28 #include "TF2.h"
29 #include "TF3.h"
30 #include "TCutG.h"
31 #include "TMatrixDBase.h"
32 #include "TMatrixFBase.h"
33 #include "TVectorD.h"
34 #include "TVectorF.h"
35 #include "TCanvas.h"
36 #include "TPad.h"
37 #include "TPaveStats.h"
38 #include "TFrame.h"
39 #include "TLatex.h"
40 #include "TLine.h"
41 #include "TPolyLine.h"
42 #include "TPoints.h"
43 #include "TStyle.h"
44 #include "TGraph.h"
45 #include "TMultiGraph.h"
46 #include "TPie.h"
47 #include "TGaxis.h"
48 #include "TColor.h"
49 #include "TPainter3dAlgorithms.h"
50 #include "TGraph2DPainter.h"
51 #include "TGraphDelaunay2D.h"
52 #include "TView.h"
53 #include "TMath.h"
54 #include "TRandom2.h"
55 #include "TObjArray.h"
56 #include "TVectorD.h"
57 #include "Hoption.h"
58 #include "Hparam.h"
59 #include "TPluginManager.h"
60 #include "TPaletteAxis.h"
61 #include "TCrown.h"
62 #include "TVirtualPadEditor.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 LEGO options](#HP17)
103 - [The "SURFace" options](#HP18)
104 - [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
105 - [Base line for bar-charts and lego plots](#HP20)
106 - [TH2Poly Drawing](#HP20a)
107 - [The SPEC option](#HP21)
108 - [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
109 - [Setting the color palette](#HP23)
110 - [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
111 - [Drawing options for 3D histograms](#HP25)
112 - [Drawing option for histograms' stacks](#HP26)
113 - [Drawing of 3D implicit functions](#HP27)
114 - [Associated functions drawing](#HP28)
115 - [Drawing using OpenGL](#HP29)
116  - [General information: plot types and supported options](#HP29a)
117  - [TH3 as color boxes](#HP290)
118  - [TH3 as boxes (spheres)](#HP29b)
119  - [TH3 as iso-surface(s)](#HP29c)
120  - [TF3 (implicit function)](#HP29d)
121  - [Parametric surfaces](#HP29e)
122  - [Interaction with the plots](#HP29f)
123  - [Selectable parts](#HP29g)
124  - [Rotation and zooming](#HP29h)
125  - [Panning](#HP29i)
126  - [Box cut](#HP29j)
127  - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
128  - [Surface with option "GLSURF"](#HP29l)
129  - [TF3](#HP29m)
130  - [Box](#HP29n)
131  - [Iso](#HP29o)
132  - [Parametric plot](#HP29p)
133 
134 
135 ## <a name="HP00"></a> Introduction
136 
137 
138 Histograms are drawn via the `THistPainter` class. Each histogram has a
139 pointer to its own painter (to be usable in a multithreaded program). When the
140 canvas has to be redrawn, the `Paint` function of each objects in the
141 pad is called. In case of histograms, `TH1::Paint` invokes directly
142 `THistPainter::Paint`.
143 
144 To draw a histogram `h` it is enough to do:
145 
146  h->Draw();
147 
148 `h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
149 be drawn, the `Draw()` method can be invoked with an option. For instance
150 to draw a 2D histogram as a lego plot it is enough to do:
151 
152  h->Draw("lego");
153 
154 `THistPainter` offers many options to paint 1D, 2D and 3D histograms.
155 
156 When the `Draw()` method of a histogram is called for the first time
157 (`TH1::Draw`), it creates a `THistPainter` object and saves a
158 pointer to this "painter" as a data member of the histogram. The
159 `THistPainter` class specializes in the drawing of histograms. It is
160 separated from the histogram so that one can have histograms without the
161 graphics overhead, for example in a batch program. Each histogram having its own
162 painter (rather than a central singleton painter painting all histograms), allows
163 two histograms to be drawn in two threads without overwriting the painter's
164 values.
165 
166 When a displayed histogram is filled again, there is no need to call the
167 `Draw()` method again; the image will be refreshed the next time the
168 pad will be updated.
169 
170 A pad is updated after one of these three actions:
171 
172 1. a carriage control on the ROOT command line,
173 2. a click inside the pad,
174 3. a call to `TPad::Update`.
175 
176 
177 By default a call to `TH1::Draw()` clears the pad of all objects
178 before drawing the new image of the histogram. One can use the `SAME`
179 option to leave the previous display intact and superimpose the new histogram.
180 The same histogram can be drawn with different graphics options in different
181 pads.
182 
183 When a displayed histogram is deleted, its image is automatically removed
184 from the pad.
185 
186 To create a copy of the histogram when drawing it, one can use
187 `TH1::DrawClone()`. This will clone the histogram and allow to change
188 and delete the original one without affecting the clone.
189 
190 
191 ### <a name="HP01"></a> Histograms' plotting options
192 
193 
194 Most options can be concatenated with or without spaces or commas, for example:
195 
196  h->Draw("E1 SAME");
197 
198 The options are not case sensitive:
199 
200  h->Draw("e1 same");
201 
202 
203 The default drawing option can be set with `TH1::SetOption` and retrieve
204 using `TH1::GetOption`:
205 
206  root [0] h->Draw(); // Draw "h" using the standard histogram representation.
207  root [1] h->Draw("E"); // Draw "h" using error bars
208  root [3] h->SetOption("E"); // Change the default drawing option for "h"
209  root [4] h->Draw(); // Draw "h" using error bars
210  root [5] h->GetOption(); // Retrieve the default drawing option for "h"
211  (const Option_t* 0xa3ff948)"E"
212 
213 
214 #### <a name="HP01a"></a> Options supported for 1D and 2D histograms
215 
216 | Option | Description |
217 |----------|-------------------------------------------------------------------|
218 | "E" | Draw error bars. |
219 | "AXIS" | Draw only axis. |
220 | "AXIG" | Draw only grid (if the grid is requested). |
221 | <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). |
222 | "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
223 | "SAME" | Superimpose on previous picture in the same pad. |
224 | "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
225 | "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
226 | "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
227 | "LEGO" | Draw a lego plot with hidden line removal. |
228 | "LEGO1" | Draw a lego plot with hidden surface removal. |
229 | "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.|
230 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
231 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
232 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
233 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
234 | "X+" | The X-axis is drawn on the top side of the plot. |
235 | "Y+" | The Y-axis is drawn on the right side of the plot. |
236 
237 #### <a name="HP01b"></a> Options supported for 1D histograms
238 
239 | Option | Description |
240 |----------|-------------------------------------------------------------------|
241 | " " | Default. |
242 | "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.|
243 | "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
244 | "B" | Bar chart option.|
245 | "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
246 | "HBAR" | Like option "BAR", but bars are drawn horizontally.|
247 | "C" | Draw a smooth Curve through the histogram bins.|
248 | "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
249 | "E1" | Draw error bars with perpendicular lines at the edges.|
250 | "E2" | Draw error bars with rectangles.|
251 | "E3" | Draw a fill area through the end points of the vertical error bars.|
252 | "E4" | Draw a smoothed filled area through the end points of the error bars.|
253 | "E5" | Like E3 but ignore the bins with 0 contents.|
254 | "E6" | Like E4 but ignore the bins with 0 contents.|
255 | "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
256 | "L" | Draw a line through the bin contents.|
257 | "P" | Draw current marker at each bin except empty bins.|
258 | "P0" | Draw current marker at each bin including empty bins.|
259 | "PIE" | Draw histogram as a Pie Chart.|
260 | "*H" | Draw histogram with a * at each bin.|
261 | "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.|
262 
263 
264 #### <a name="HP01c"></a> Options supported for 2D histograms
265 
266 | Option | Description |
267 |-----------|------------------------------------------------------------------|
268 | " " | Default (scatter plot).|
269 | "ARR" | Arrow mode. Shows gradient between adjacent cells.|
270 | "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.|
271 | "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.|
272 | "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.|
273 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
274 | "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
275 | "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
276 | "CANDLE" | Draw a candle plot along X axis.|
277 | "CANDLEX" | Same as "CANDLE".|
278 | "CANDLEY" | Draw a candle plot along Y axis.|
279 | "CANDLEXn"| Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
280 | "CANDLEYn"| Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
281 | "VIOLIN" | Draw a violin plot along X axis.|
282 | "VIOLINX" | Same as "VIOLIN".|
283 | "VIOLINY" | Draw a violin plot along Y axis.|
284 | "VIOLINXn"| Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
285 | "VIOLINYn"| Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
286 | "CONT" | Draw a contour plot (same as CONT0).|
287 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
288 | "CONT1" | Draw a contour plot using line styles to distinguish contours.|
289 | "CONT2" | Draw a contour plot using the same line style for all contours.|
290 | "CONT3" | Draw a contour plot using fill area colors.|
291 | "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
292 | "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
293 | "LIST" | Generate a list of TGraph objects for each contour.|
294 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
295 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
296 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
297 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
298 | "SURF" | Draw a surface plot with hidden line removal.|
299 | "SURF1" | Draw a surface plot with hidden surface removal.|
300 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
301 | "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
302 | "SURF4" | Draw a surface using Gouraud shading.|
303 | "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.|
304 | "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
305 | "FB" | With LEGO or SURFACE, suppress the Front-Box.|
306 | "BB" | With LEGO or SURFACE, suppress the Back-Box.|
307 | "A" | With LEGO or SURFACE, suppress the axis.|
308 | "SCAT" | Draw a scatter-plot (default).|
309 | "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
310 
311 
312 #### <a name="HP01d"></a> Options supported for 3D histograms
313 
314 | Option | Description |
315 |----------|-------------------------------------------------------------------|
316 | " " | Default (scatter plot).|
317 | "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)`.|
318 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
319 | "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
320 | "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
321 | "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
322 | "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
323 | "LEGO" | Same as `BOX`.|
324 
325 
326 #### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
327 
328 | Option | Description |
329 |------------|-----------------------------------------------------------------|
330 | " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
331 | "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
332 | "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
333 | "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.|
334 | "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
335 | "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
336 | "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
337 
338 
339 
340 ### <a name="HP02"></a> Setting the Style
341 
342 
343 Histograms use the current style (`gStyle`). When one changes the current
344 style and would like to propagate the changes to the histogram,
345 `TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
346 each histogram is needed.
347 
348 To force all the histogram to use the current style use:
349 
350  gROOT->ForceStyle();
351 
352 All the histograms read after this call will use the current style.
353 
354 
355 ### <a name="HP03"></a> Setting line, fill, marker, and text attributes
356 
357 
358 The histogram classes inherit from the attribute classes:
359 `TAttLine`, `TAttFill` and `TAttMarker`.
360 See the description of these classes for the list of options.
361 
362 
363 ### <a name="HP04"></a> Setting Tick marks on the histogram axis
364 
365 
366 The `TPad::SetTicks` method specifies the type of tick marks on the axis.
367 If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
368 
369  tx = 1; tick marks on top side are drawn (inside)
370  tx = 2; tick marks and labels on top side are drawn
371  ty = 1; tick marks on right side are drawn (inside)
372  ty = 2; tick marks and labels on right side are drawn
373 
374 By default only the left Y axis and X bottom axis are drawn
375 (`tx = ty = 0`)
376 
377 `TPad::SetTicks(tx,ty)` allows to set these options.
378 See also The `TAxis` functions to set specific axis attributes.
379 
380 In case multiple color filled histograms are drawn on the same pad, the fill
381 area may hide the axis tick marks. One can force a redraw of the axis over all
382 the histograms by calling:
383 
384  gPad->RedrawAxis();
385 
386 
387 ### <a name="HP05"></a> Giving titles to the X, Y and Z axis
388 
389 
390  h->GetXaxis()->SetTitle("X axis title");
391  h->GetYaxis()->SetTitle("Y axis title");
392 
393 The histogram title and the axis titles can be any `TLatex` string.
394 The titles are part of the persistent histogram.
395 
396 
397 ### <a name="HP060"></a> The option "SAME"
398 
399 
400 By default, when an histogram is drawn, the current pad is cleared before
401 drawing. In order to keep the previous drawing and draw on top of it the
402 option `SAME` should be use. The histogram drawn with the option
403 `SAME` uses the coordinates system available in the current pad.
404 
405 This option can be used alone or combined with any valid drawing option but
406 some combinations must be use with care.
407 
408 #### <a name="HP060a"></a> Limitations
409 
410 - It does not work when combined with the `LEGO` and `SURF` options unless the
411  histogram plotted with the option `SAME` has exactly the same
412  ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
413  lego plots [histograms' stacks](#HP26) should be used.</li>
414 
415 
416 ### <a name="HP061"></a> Colors automatically picked in palette
417 
418 \since **ROOT version 6.09/01**
419 
420 When several histograms are painted in the same canvas thanks to the option "SAME"
421 or via a `THStack` it might be useful to have an easy and automatic way to choose
422 their color. The simplest way is to pick colors in the current active color
423 palette. Palette coloring for histogram is activated thanks to the options `PFC`
424 (Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
425 When one of these options is given to `TH1::Draw` the histogram get its color
426 from the current color palette defined by `gStyle->SetPalette(…)`. The color
427 is determined according to the number of objects having palette coloring in
428 the current pad.
429 
430 Begin_Macro(source)
431 ../../../tutorials/hist/histpalettecolor.C
432 End_Macro
433 
434 Begin_Macro(source)
435 ../../../tutorials/hist/thstackpalettecolor.C
436 End_Macro
437 
438 Begin_Macro(source)
439 ../../../tutorials/hist/thstack2palettecolor.C
440 End_Macro
441 
442 ### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
443 
444 
445 The following example creates two histograms, the second histogram is the bins
446 integral of the first one. It shows a procedure to draw the two histograms in
447 the same pad and it draws the scale of the second histogram using a new vertical
448 axis on the right side. See also the tutorial `transpad.C` for a variant
449 of this example.
450 
451 Begin_Macro(source)
452 {
453  TCanvas *c1 = new TCanvas("c1","c1",600,400);
454  // create/fill draw h1
455  gStyle->SetOptStat(kFALSE);
456  TH1F *h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
457  Int_t i;
458  for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
459  h1->Draw();
460  c1->Update();
461 
462  // create hint1 filled with the bins integral of h1
463  TH1F *hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
464  Float_t sum = 0;
465  for (i=1;i<=100;i++) {
466  sum += h1->GetBinContent(i);
467  hint1->SetBinContent(i,sum);
468  }
469 
470  // scale hint1 to the pad coordinates
471  Float_t rightmax = 1.1*hint1->GetMaximum();
472  Float_t scale = gPad->GetUymax()/rightmax;
473  hint1->SetLineColor(kRed);
474  hint1->Scale(scale);
475  hint1->Draw("same");
476 
477  // draw an axis on the right side
478  TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
479  gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
480  axis->SetLineColor(kRed);
481  axis->SetTextColor(kRed);
482  axis->Draw();
483  return c1;
484 }
485 End_Macro
486 
487 
488 ### <a name="HP07"></a> Statistics Display
489 
490 
491 The type of information shown in the histogram statistics box can be selected
492 with:
493 
494  gStyle->SetOptStat(mode);
495 
496 The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
497 
498  mode = ksiourmen (default = 000001111)
499  k = 1; kurtosis printed
500  k = 2; kurtosis and kurtosis error printed
501  s = 1; skewness printed
502  s = 2; skewness and skewness error printed
503  i = 1; integral of bins printed
504  i = 2; integral of bins with option "width" printed
505  o = 1; number of overflows printed
506  u = 1; number of underflows printed
507  r = 1; standard deviation printed
508  r = 2; standard deviation and standard deviation error printed
509  m = 1; mean value printed
510  m = 2; mean and mean error values printed
511  e = 1; number of entries printed
512  n = 1; name of histogram is printed
513 
514 For example:
515 
516  gStyle->SetOptStat(11);
517 
518 displays only the name of histogram and the number of entries, whereas:
519 
520  gStyle->SetOptStat(1101);
521 
522 displays the name of histogram, mean value and standard deviation.
523 
524 <b>WARNING 1:</b> never do:
525 
526  gStyle->SetOptStat(0001111);
527 
528 but instead do:
529 
530  gStyle->SetOptStat(1111);
531 
532 because `0001111` will be taken as an octal number!
533 
534 <b>WARNING 2:</b> for backward compatibility with older versions
535 
536  gStyle->SetOptStat(1);
537 
538 is taken as:
539 
540  gStyle->SetOptStat(1111)
541 
542 To print only the name of the histogram do:
543 
544  gStyle->SetOptStat(1000000001);
545 
546 <b>NOTE</b> that in case of 2D histograms, when selecting only underflow
547 (10000) or overflow (100000), the statistics box will show all combinations
548 of underflow/overflows and not just one single number.
549 
550 The parameter mode can be any combination of the letters `kKsSiIourRmMen`
551 
552  k : kurtosis printed
553  K : kurtosis and kurtosis error printed
554  s : skewness printed
555  S : skewness and skewness error printed
556  i : integral of bins printed
557  I : integral of bins with option "width" printed
558  o : number of overflows printed
559  u : number of underflows printed
560  r : standard deviation printed
561  R : standard deviation and standard deviation error printed
562  m : mean value printed
563  M : mean value mean error values printed
564  e : number of entries printed
565  n : name of histogram is printed
566 
567 For example, to print only name of histogram and number of entries do:
568 
569  gStyle->SetOptStat("ne");
570 
571 To print only the name of the histogram do:
572 
573  gStyle->SetOptStat("n");
574 
575 The default value is:
576 
577  gStyle->SetOptStat("nemr");
578 
579 When a histogram is painted, a `TPaveStats` object is created and added
580 to the list of functions of the histogram. If a `TPaveStats` object
581 already exists in the histogram list of functions, the existing object is just
582 updated with the current histogram parameters.
583 
584 Once a histogram is painted, the statistics box can be accessed using
585 `h->FindObject("stats")`. In the command line it is enough to do:
586 
587  Root > h->Draw()
588  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
589 
590 because after `h->Draw()` the histogram is automatically painted. But
591 in a script file the painting should be forced using `gPad->Update()`
592 in order to make sure the statistics box is created:
593 
594  h->Draw();
595  gPad->Update();
596  TPaveStats *st = (TPaveStats*)h->FindObject("stats");
597 
598 Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
599 
600 When a histogram is drawn with the option `SAME`, the statistics box
601 is not drawn. To force the statistics box drawing with the option
602 `SAME`, the option `SAMES` must be used.
603 If the new statistics box hides the previous statistics box, one can change
604 its position with these lines (`h` being the pointer to the histogram):
605 
606  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
607  Root > st->SetX1NDC(newx1); //new x start position
608  Root > st->SetX2NDC(newx2); //new x end position
609 
610 To change the type of information for an histogram with an existing
611 `TPaveStats` one should do:
612 
613  st->SetOptStat(mode);
614 
615 Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
616 (see above).
617 
618 One can delete the statistics box for a histogram `TH1* h` with:
619 
620  h->SetStats(0)
621 
622 and activate it again with:
623 
624  h->SetStats(1).
625 
626 Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
627 `$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
628 
629 
630 ### <a name="HP08"></a> Fit Statistics
631 
632 
633 The type of information about fit parameters printed in the histogram statistics
634 box can be selected via the parameter mode. The parameter mode can be
635 `= pcev` (default `= 0111`)
636 
637  p = 1; print Probability
638  c = 1; print Chisquare/Number of degrees of freedom
639  e = 1; print errors (if e=1, v must be 1)
640  v = 1; print name/values of parameters
641 
642 Example:
643 
644  gStyle->SetOptFit(1011);
645 
646 print fit probability, parameter names/values and errors.
647 
648 1. When `v" = 1` is specified, only the non-fixed parameters are shown.
649 2. When `v" = 2` all parameters are shown.
650 
651 Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
652 to `gStyle->SetOptFit(111)`
653 
654 
655 ### <a name="HP09"></a> The error bars options
656 
657 
658 | Option | Description |
659 |----------|-------------------------------------------------------------------|
660 | "E" | Default. Shows only the error bars, not a marker.|
661 | "E1" | Small lines are drawn at the end of the error bars.|
662 | "E2" | Error rectangles are drawn.|
663 | "E3" | A filled area is drawn through the end points of the vertical error bars.|
664 | "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
665 | "E0" | Draw also bins with null contents.|
666 
667 Begin_Macro(source)
668 {
669  TCanvas *c1 = new TCanvas("c1","c1",600,400);
670  TH1F *he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
671  Int_t i;
672  for (i=0;i<10000;i++) he->Fill(gRandom->Gaus(0,1));
673  gStyle->SetEndErrorSize(3);
674  gStyle->SetErrorX(1.);
675  he->SetMarkerStyle(20);
676  he->Draw("E1");
677  return c1;
678 }
679 End_Macro
680 
681 The options "E3" and "E4" draw an error band through the end points of the
682 vertical error bars. With "E4" the error band is smoothed. Because of the
683 smoothing algorithm used some artefacts may appear at the end of the band
684 like in the following example. In such cases "E3" should be used instead
685 of "E4".
686 
687 Begin_Macro(source)
688 {
689  TCanvas *ce4 = new TCanvas("ce4","ce4",600,400);
690  ce4->Divide(2,1);
691  TH1F *he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
692  Int_t i;
693  for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
694  he4->SetFillColor(kRed);
695  he4->GetXaxis()->SetRange(40,48);
696  ce4->cd(1);
697  he4->Draw("E4");
698  ce4->cd(2);
699  TH1F *he3 = (TH1F*)he4->DrawClone("E3");
700  he3->SetTitle("Distribution drawn option E3");
701  return ce4;
702 }
703 End_Macro
704 
705 2D histograms can be drawn with error bars as shown is the following example:
706 
707 Begin_Macro(source)
708 {
709  TCanvas *c2e = new TCanvas("c2e","c2e",600,400);
710  TH2F *h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
711  Float_t px, py;
712  for (Int_t i = 0; i < 25000; i++) {
713  gRandom->Rannor(px,py);
714  h2e->Fill(px,5*py);
715  }
716  h2e->Draw("E");
717  return c2e;
718 }
719 End_Macro
720 
721 
722 ### <a name="HP100"></a> The bar chart option
723 
724 
725 The option "B" allows to draw simple vertical bar charts.
726 The bar width is controlled with `TH1::SetBarWidth()`,
727 and the bar offset within the bin, with `TH1::SetBarOffset()`.
728 These two settings are useful to draw several histograms on the
729 same plot as shown in the following example:
730 
731 Begin_Macro(source)
732 {
733  int i;
734  const Int_t nx = 8;
735  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
736  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
737  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
738 
739  TCanvas *cb = new TCanvas("cb","cb",600,400);
740  cb->SetGrid();
741 
742  gStyle->SetHistMinimumZero();
743 
744  TH1F *h1b = new TH1F("h1b","Option B example",nx,0,nx);
745  h1b->SetFillColor(4);
746  h1b->SetBarWidth(0.4);
747  h1b->SetBarOffset(0.1);
748  h1b->SetStats(0);
749  h1b->SetMinimum(-5);
750  h1b->SetMaximum(5);
751 
752  for (i=1; i<=nx; i++) {
753  h1b->SetBinContent(i, d_35_0[i-1]);
754  h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
755  }
756 
757  h1b->Draw("b");
758 
759  TH1F *h2b = new TH1F("h2b","h2b",nx,0,nx);
760  h2b->SetFillColor(38);
761  h2b->SetBarWidth(0.4);
762  h2b->SetBarOffset(0.5);
763  h2b->SetStats(0);
764  for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
765 
766  h2b->Draw("b same");
767 
768  return cb;
769 }
770 End_Macro
771 
772 
773 ### <a name="HP10"></a> The "BAR" and "HBAR" options
774 
775 
776 When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
777 bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
778 An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
779 `hbar2`, `hbar3`, `hbar4` (hbars.C).
780 
781 - The bar is filled with the histogram fill color.
782 - The left side of the bar is drawn with a light fill color.
783 - The right side of the bar is drawn with a dark fill color.
784 - The percentage of the bar drawn with either the light or dark color is:
785  - 0% for option "(h)bar" or "(h)bar0"
786  - 10% for option "(h)bar1"
787  - 20% for option "(h)bar2"
788  - 30% for option "(h)bar3"
789  - 40% for option "(h)bar4"
790 
791 When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
792 
793 Begin_Macro(source)
794 ../../../tutorials/hist/hbars.C
795 End_Macro
796 
797 To control the bar width (default is the bin width) `TH1::SetBarWidth()`
798 should be used.
799 
800 To control the bar offset (default is 0) `TH1::SetBarOffset()` should
801 be used.
802 
803 These two parameters are useful when several histograms are plotted using
804 the option `SAME`. They allow to plot the histograms next to each other.
805 
806 
807 ### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
808 
809 
810 For each cell (i,j) a number of points proportional to the cell content is
811 drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
812 `kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
813 If option is of the form `scat=ff`, (eg `scat=1.8`,
814 `scat=1e-3`), then `ff` is used as a scale factor to compute the
815 number of dots. `scat=1` is the default.
816 
817 By default the scatter plot is painted with a "dot marker" which not scalable
818 (see the `TAttMarker` documentation). To change the marker size, a scalable marker
819 type should be used. For instance a circle (marker style 20).
820 
821 Begin_Macro(source)
822 {
823  TCanvas *c1 = new TCanvas("c1","c1",600,400);
824  TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
825  Float_t px, py;
826  for (Int_t i = 0; i < 25000; i++) {
827  gRandom->Rannor(px,py);
828  hscat->Fill(px,5*py);
829  hscat->Fill(3+0.5*px,2*py-10.);
830  }
831  hscat->Draw("scat=0.5");
832  return c1;
833 }
834 End_Macro
835 
836 
837 ### <a name="HP12"></a> The ARRow option
838 
839 
840 Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
841 The orientation of the arrow follows the cell gradient.
842 
843 Begin_Macro(source)
844 {
845  TCanvas *c1 = new TCanvas("c1","c1",600,400);
846  TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
847  Float_t px, py;
848  for (Int_t i = 0; i < 25000; i++) {
849  gRandom->Rannor(px,py);
850  harr->Fill(px,5*py);
851  harr->Fill(3+0.5*px,2*py-10.,0.1);
852  }
853  harr->Draw("ARR");
854  return c1;
855 }
856 End_Macro
857 
858 
859 ### <a name="HP13"></a> The BOX option
860 
861 
862 For each cell (i,j) a box is drawn. The size (surface) of the box is
863 proportional to the absolute value of the cell content.
864 The cells with a negative content are drawn with a `X` on top of the box.
865 
866 Begin_Macro(source)
867 {
868  TCanvas *c1 = new TCanvas("c1","c1",600,400);
869  hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
870  hbox->SetFillColor(42);
871  hbox->Fill(0.5, 0.5, 1.);
872  hbox->Fill(0.5, 1.5, 4.);
873  hbox->Fill(0.5, 2.5, 3.);
874  hbox->Fill(1.5, 0.5, 2.);
875  hbox->Fill(1.5, 1.5, 12.);
876  hbox->Fill(1.5, 2.5, -6.);
877  hbox->Fill(2.5, 0.5, -4.);
878  hbox->Fill(2.5, 1.5, 6.);
879  hbox->Fill(2.5, 2.5, 0.5);
880  hbox->Draw("BOX");
881  return c1;
882 }
883 End_Macro
884 
885 With option `BOX1` a button is drawn for each cell with surface
886 proportional to content's absolute value. A sunken button is drawn for
887 negative values a raised one for positive.
888 
889 Begin_Macro(source)
890 {
891  TCanvas *c1 = new TCanvas("c1","c1",600,400);
892  hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
893  hbox1->SetFillColor(42);
894  hbox1->Fill(0.5, 0.5, 1.);
895  hbox1->Fill(0.5, 1.5, 4.);
896  hbox1->Fill(0.5, 2.5, 3.);
897  hbox1->Fill(1.5, 0.5, 2.);
898  hbox1->Fill(1.5, 1.5, 12.);
899  hbox1->Fill(1.5, 2.5, -6.);
900  hbox1->Fill(2.5, 0.5, -4.);
901  hbox1->Fill(2.5, 1.5, 6.);
902  hbox1->Fill(2.5, 2.5, 0.5);
903  hbox1->Draw("BOX1");
904  return c1;
905 }
906 End_Macro
907 
908 When the option `SAME` (or "SAMES") is used with the option `BOX`,
909 the boxes' sizes are computing taking the previous plots into account. The range
910 along the Z axis is imposed by the first plot (the one without option
911 `SAME`); therefore the order in which the plots are done is relevant.
912 
913 Begin_Macro(source)
914 {
915  TCanvas *c1 = new TCanvas("c1","c1",600,400);
916  TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
917  TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
918  TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
919  TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
920  for (Int_t i=0;i<1000;i++) {
921  double x,y;
922  gRandom->Rannor(x,y);
923  if (x>0 && y>0) hb1->Fill(x,y,4);
924  if (x<0 && y<0) hb2->Fill(x,y,3);
925  if (x>0 && y<0) hb3->Fill(x,y,2);
926  if (x<0 && y>0) hb4->Fill(x,y,1);
927  }
928  hb1->SetFillColor(1);
929  hb2->SetFillColor(2);
930  hb3->SetFillColor(3);
931  hb4->SetFillColor(4);
932  hb1->Draw("box");
933  hb2->Draw("box same");
934  hb3->Draw("box same");
935  hb4->Draw("box same");
936  return c1;
937 }
938 End_Macro
939 
940 
941 ### <a name="HP14"></a> The COLor option
942 
943 
944 For each cell (i,j) a box is drawn with a color proportional to the cell
945 content.
946 
947 The color table used is defined in the current style.
948 
949 If the histogram's minimum and maximum are the same (flat histogram), the
950 mapping on colors is not possible, therefore nothing is painted. To paint a
951 flat histogram it is enough to set the histogram minimum
952 (`TH1::SetMinimum()`) different from the bins' content.
953 
954 The default number of color levels used to paint the cells is 20.
955 It can be changed with `TH1::SetContour()` or
956 `TStyle::SetNumberContours()`. The higher this number is, the smoother
957 is the color change between cells.
958 
959 The color palette in TStyle can be modified via `gStyle->SetPalette()`.
960 
961 All the non-empty bins are painted. Empty bins are not painted unless
962 some bins have a negative content because in that case the null bins
963 might be not empty.
964 
965 `TProfile2D` histograms are handled differently because, for this type of 2D
966 histograms, it is possible to know if an empty bin has been filled or not. So even
967 if all the bins' contents are positive some empty bins might be painted. And vice versa,
968 if some bins have a negative content some empty bins might be not painted.
969 
970 Combined with the option `COL`, the option `Z` allows to
971 display the color palette defined by `gStyle->SetPalette()`.
972 
973 In the following example, the histogram has only positive bins; the empty
974 bins (containing 0) are not drawn.
975 
976 Begin_Macro(source)
977 {
978  TCanvas *c1 = new TCanvas("c1","c1",600,400);
979  TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
980  Float_t px, py;
981  for (Int_t i = 0; i < 25000; i++) {
982  gRandom->Rannor(px,py);
983  hcol1->Fill(px,5*py);
984  }
985  hcol1->Draw("COLZ");
986  return c1;
987 }
988 End_Macro
989 
990 In the first plot of following example, the histogram has some negative bins;
991 the empty bins (containing 0) are drawn. In some cases one wants to not draw
992 empty bins (containing 0) of histograms having a negative minimum. The option
993 `1`, used to produce the second plot in the following picture, allows to do that.
994 
995 Begin_Macro(source)
996 {
997  TCanvas *c1 = new TCanvas("c1","c1",600,600);
998  c1->Divide(1,2);
999  TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
1000  TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
1001  Float_t px, py;
1002  for (Int_t i = 0; i < 25000; i++) {
1003  gRandom->Rannor(px,py);
1004  hcol23->Fill(px,5*py);
1005  hcol24->Fill(px,5*py);
1006  }
1007  hcol23->Fill(0.,0.,-200.);
1008  hcol24->Fill(0.,0.,-200.);
1009  c1->cd(1); hcol23->Draw("COLZ");
1010  c1->cd(2); hcol24->Draw("COLZ1");
1011  return c1;
1012 }
1013 End_Macro
1014 
1015 When the maximum of the histogram is set to a smaller value than the real maximum,
1016  the bins having a content between the new maximum and the real maximum are
1017 painted with the color corresponding to the new maximum.
1018 
1019 When the minimum of the histogram is set to a greater value than the real minimum,
1020  the bins having a value between the real minimum and the new minimum are not drawn
1021  unless the option `0` is set.
1022 
1023 The following example illustrates the option `0` combined with the option `COL`.
1024 
1025 Begin_Macro(source)
1026 {
1027  TCanvas *c1 = new TCanvas("c1","c1",600,600);
1028  c1->Divide(1,2);
1029  TH2F *hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1030  TH2F *hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1031  Float_t px, py;
1032  for (Int_t i = 0; i < 25000; i++) {
1033  gRandom->Rannor(px,py);
1034  hcol21->Fill(px,5*py);
1035  hcol22->Fill(px,5*py);
1036  }
1037  hcol21->SetBit(TH1::kNoStats);
1038  hcol22->SetBit(TH1::kNoStats);
1039  c1->cd(1); hcol21->Draw("COLZ");
1040  c1->cd(2); hcol22->Draw("COLZ0");
1041  hcol22->SetMaximum(100);
1042  hcol22->SetMinimum(40);
1043  return c1;
1044 }
1045 End_Macro
1046 
1047 \since **ROOT version 6.09/01:**
1048 
1049 When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1050 are computing taking the previous plots into account. The range along the Z axis
1051 is imposed by the first plot (the one without option SAME); therefore the order
1052 in which the plots are done is relevant.
1053 
1054 Begin_Macro(source)
1055 {
1056  c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1057  TH2F *h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1058  TH2F *h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1059  TH2F *h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1060  TH2F *h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1061  h1->SetBit(TH1::kNoStats);
1062  for (Int_t i=0;i<5000;i++) {
1063  double x,y;
1064  gRandom->Rannor(x,y);
1065  if(x>0 && y>0) h1->Fill(x,y,4);
1066  if(x<0 && y<0) h2->Fill(x,y,3);
1067  if(x>0 && y<0) h3->Fill(x,y,2);
1068  if(x<0 && y>0) h4->Fill(x,y,1);
1069  }
1070  h1->Draw("colz");
1071  h2->Draw("col same");
1072  h3->Draw("col same");
1073  h4->Draw("col same");
1074 }
1075 End_Macro
1076 
1077 The option `COL` can be combined with the option `POL`:
1078 
1079 Begin_Macro(source)
1080 {
1081  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1082  TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1083  Float_t px, py;
1084  for (Int_t i = 0; i < 25000; i++) {
1085  gRandom->Rannor(px,py);
1086  hcol1->Fill(px,py);
1087  }
1088  hcol1->Draw("COLZPOL");
1089  return c1;
1090 }
1091 End_Macro
1092 
1093 \since **ROOT version 6.07/03:**
1094 
1095 A second rendering technique is also available with the COL2 and COLZ2 options.
1096 
1097 These options provide potential performance improvements compared to the standard
1098 COL option. The performance comparison of the COL2 to the COL option depends on
1099 the histogram and the size of the rendering region in the current pad. In general,
1100 a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1101 faster with the COL option.
1102 
1103 However, for larger histograms (approx. more than 100 bins per axis)
1104 that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1105 For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1106 faster with the COL2 option.
1107 
1108 The COL2 option will also scale its performance based on the size of the
1109 pixmap the histogram image is being rendered into. It also is much better optimized for
1110 sessions where the user is forwarding X11 windows through an `ssh` connection.
1111 
1112 For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1113 and COLZ options. There is one major difference and that concerns the treatment of
1114 bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1115 
1116 COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1117 graphics file format like PostScript or PDF (an empty image will be generated). It can
1118 be saved only in bitmap files like PNG format for instance.
1119 
1120 
1121 ### <a name="HP140"></a> The CANDLE and VIOLIN options
1122 
1123 The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1124 implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1125 the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1126 vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1127 (1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1128 
1129 Instead of using the predefined representations, the candle and violin parameters can be
1130 changed individually. In that case the option have the following form:
1131 
1132  CANDLEX(<option-string>)
1133  CANDLEY(<option-string>)
1134  VIOLINX(<option-string>)
1135  VIOLINY(<option-string>).
1136 
1137 All zeros at the beginning of `option-string` can be omitted.
1138 
1139 `option-string` consists eight values, defined as follow:
1140 
1141  "CANDLEX(zhpawMmb)"
1142 
1143 Where:
1144 
1145  - `b = 0`; no box drawn
1146  - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1147  makes sense in the very most cases to always draw the box
1148  - `b = 2`; draw a filled box with border
1149 
1150  - `m = 0`; no median drawn
1151  - `m = 1`; median is drawn as a line
1152  - `m = 2`; median is drawn with errors (notches)
1153  - `m = 3`; median is drawn as a circle
1154 
1155  - `M = 0`; no mean drawn
1156  - `M = 1`; mean is drawn as a dashed line
1157  - `M = 3`; mean is drawn as a circle
1158 
1159  - `w = 0`; no whisker drawn
1160  - `w = 1`; whisker is drawn to end of distribution.
1161  - `w = 2`; whisker is drawn to max 1.5*iqr
1162 
1163  - `a = 0`; no anchor drawn
1164  - `a = 1`; the anchors are drawn
1165 
1166  - `p = 0`; no points drawn
1167  - `p = 1`; only outliers are drawn
1168  - `p = 2`; all datapoints are drawn
1169  - `p = 3`: all datapoints are drawn scattered
1170 
1171  - `h = 0`; no histogram is drawn
1172  - `h = 1`; histogram at the left or bottom side is drawn
1173  - `h = 2`; histogram at the right or top side is drawn
1174  - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1175 
1176  - `z = 0`; no zero indicator line is drawn
1177  - `z = 1`; zero indicator line is drawn.
1178 
1179 As one can see all individual options for both candle and violin plots can be accessed by this
1180 mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1181 meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1182 vice versa, if you wish.
1183 
1184 Using a logarithmic x- or y-axis is possible for candle and violin charts.
1185 
1186 \since **ROOT version 6.11/01**
1187 
1188 a logarithmic z-axis is possible, too but will only affect violin charts of course.
1189 
1190 #### <a name="HP140a"></a> The CANDLE option
1191 
1192 <a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1193 a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1194 way to describe graphically a data distribution (D) with only five numbers:
1195 
1196  1. The minimum value of the distribution D (bottom or left whisker).
1197  2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1198  3. The median (M): 50% of the data points in D are less than M.
1199  4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1200  5. The maximum value of the distribution D (top or right whisker).
1201 
1202 In this implementation a TH2 is considered as a collection of TH1 along
1203 X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1204 Each TH1 is represented as one candle.
1205 
1206 Begin_Macro(source)
1207 ../../../tutorials/hist/candleplotwhiskers.C
1208 End_Macro
1209 
1210 The candle reduces the information coming from a whole distribution into few values.
1211 Independently from the number of entries or the significance of the underlying distribution
1212 a candle will always look like a candle. So candle plots should be used carefully in
1213 particular with unknown distributions. The definition of a candle is based on
1214 __unbinned data__. Here, candles are created from binned data. Because of this, the
1215 deviation is connected to the bin width used. The calculation of the quantiles
1216 normally done on unbinned data also. Because data are binned, this will
1217 only work the best possible way within the resolution of one bin
1218 
1219 Because of all these facts one should take care that:
1220 
1221  - there are enough points per candle
1222  - the bin width is small enough (more bins will increase the maximum
1223  available resolution of the quantiles although there will be some
1224  bins with no entries)
1225  - never make a candle-plot if the underlying distribution is double-distributed
1226  - only create candles of distributions that are more-or-less gaussian (the
1227  MPV should be not too far away from the mean).
1228 
1229 #### What a candle is made of
1230 
1231 \since **ROOT version 6.07/05**
1232 
1233 ##### The box
1234 The box displays the position of the inter-quantile-range of the underlying
1235 distribution. The box contains 25% of the distribution below the median
1236 and 25% of the distribution above the median. If the underlying distribution is large
1237 enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1238 (Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1239 the position of the box can be modified by SetBarWidth() and SetBarOffset().
1240 The +-25% quantiles are calculated by the GetQuantiles() methods.
1241 
1242 \since **ROOT version 6.11/01**
1243 
1244 Using the static function TCandle::SetBoxRange(double) the box definition will be
1245 overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1246 to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1247 The static function will affect all candle-charts in the running program.
1248 Default is 0.5.
1249 
1250 Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1251 whole candle) can be influenced. Deactivated, the width is constant (to be set by
1252 SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1253 amount of data in the corresponding candle, the maximum width can be influenced by
1254 SetBarWidth(). The static function will affect all candle-charts in the running program.
1255 Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1256 supported, yet
1257 
1258 ##### The Median
1259 For a sorted list of numbers, the median is the value in the middle of the list.
1260 E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1261 because it is in the middle of the list. If the number of entries is even the
1262 average of the two values in the middle will be used. As histograms are binned
1263 data, the situation is a bit more complex. The following example shows this:
1264 
1265 ~~~ {.cpp}
1266 void quantiles() {
1267  TH1I *h = new TH1I("h","h",10,0,10);
1268  //h->Fill(3);
1269  //h->Fill(3);
1270  h->Fill(4);
1271  h->Draw();
1272  Double_t *p = new Double_t[1];
1273  p[0] = 0.5;
1274  Double_t *q = new Double_t[1];
1275  q[0] = 0;
1276  h->GetQuantiles(1,q,p);
1277 
1278  cout << "Median is: " << q[0] << std::endl;
1279 }
1280 ~~~
1281 
1282 Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1283 the example will return a calculated median of 4.5, because that's the bin center
1284 of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1285 commented out, it will return 3.75, because the algorithm tries to evenly distribute
1286 the individual values of a bin with bin content > 0. It means the sorted list
1287 would be "3.25, 3.75, 4.5".
1288 
1289 The consequence is a median of 3.75. This shows how important it is to use a
1290 small enough bin-width when using candle-plots on binned data.
1291 If the distribution is large enough and gaussian shaped the median will be exactly
1292 equal to the mean.
1293 The median can be shown as a line or as a circle or not shown at all.
1294 
1295 In order to show the significance of the median notched candle plots apply a "notch" or
1296 narrowing of the box around the median. The significance is defined by
1297 \f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1298 (where iqr is the size of the box and N is the number of entries of the whole
1299 distribution). Candle plots like these are usually called "notched candle plots".
1300 
1301 In case the significance of the median is greater that the size of the box, the
1302 box will have an unnatural shape. Usually it means the chart has not enough data,
1303 or that representing this uncertainty is not useful
1304 
1305 ##### The Mean
1306 The mean can be drawn as a dashed line or as a circle or not drawn at all.
1307 The mean is the arithmetic average of the values in the distribution.
1308 It is calculated using GetMean(). Because histograms are
1309 binned data, the mean value can differ from a calculation on the raw-data.
1310 If the distribution is large enough and gaussian shaped the mean will be
1311 exactly the median.
1312 
1313 ##### The Whiskers
1314 The whiskers represent the part of the distribution not covered by the box.
1315 The upper 25% and the lower 25% of the distribution are located within the whiskers.
1316 Two representations are available.
1317 
1318  - A simple one (using w=1) defining the lower whisker from the lowest data value
1319  to the bottom of the box, and the upper whisker from the top of the box to the
1320  highest data value. In this representation the whisker-lines are dashed.
1321  - A more complex one having a further restriction. The whiskers are still connected
1322  to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1323  be that the outermost part of the underlying distribution will not be covered
1324  by the whiskers. Usually these missing parts will be represented by the outliers
1325  (see points). Of course the upper and the lower whisker may differ in length.
1326  In this representation the whiskers are drawn as solid lines.
1327 
1328 \since **ROOT version 6.11/01**
1329 
1330 Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1331 will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1332 the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1333 that candle. The static function will affect all candle-charts in the running program.
1334 Default is 1.
1335 
1336 If the distribution is large enough and gaussian shaped, the maximum length of
1337 the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
1338 1.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1339 (see picture above). In that case 99.3% of the total distribution will be covered
1340 by the box and the whiskers, whereas 0.7% are represented by the outliers.
1341 
1342 ##### The Anchors
1343 The anchors have no special meaning in terms of statistical calculation. They mark
1344 the end of the whiskers and they have the width of the box. Both representation
1345 with and without anchors are common.
1346 
1347 ##### The Points
1348 Depending on the configuration the points can have different meanings:
1349  - If p=1 the points represent the outliers. If they are shown, it means
1350  some parts of the underlying distribution are not covered by the whiskers.
1351  This can only occur when the whiskers are set to option w=2. Here the whiskers
1352  can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1353  whiskers will be drawn as outliers. The outliers will be represented by crosses.
1354  - If p=2 all points in the distribution will be painted as crosses. This is
1355  useful for small datasets only (up to 10 or 20 points per candle).
1356  The outliers are shown along the candle. Because the underlying distribution
1357  is binned, is frequently occurs that a bin contains more than one value.
1358  Because of this the points will be randomly scattered within their bin along
1359  the candle axis. If the bin content for a bin is exactly 1 (usually
1360  this happens for the outliers) if will be drawn in the middle of the bin along
1361  the candle axis. As the maximum number of points per candle is limited by kNMax/2
1362  on very large datasets scaling will be performed automatically. In that case one
1363  would loose all outliers because they have usually a bin content of 1 (and a
1364  bin content between 0 and 1 after the scaling). Because of this all bin contents
1365  between 0 and 1 - after the scaling - will be forced to be 1.
1366  - As the drawing of all values on large datasets can lead to big amounts of crosses,
1367  one can show all values as a scatter plot instead by choosing p=3. The points will be
1368  drawn as dots and will be scattered within the width of the candle. The color
1369  of the points will be the color of the candle-chart.
1370 
1371 ##### Other Options
1372 Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1373 with a histogram.
1374 
1375 #### How to use the candle-plots drawing option
1376 
1377 There are six predefined candle-plot representations:
1378 
1379  - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1380  - "CANDLEX2": Standard candle with better whisker definition + outliers.
1381  It is a good compromise
1382  - "CANDLEX3": Like candle2 but with a mean as a circle.
1383  It is easier to distinguish mean and median
1384  - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1385  (notched candle plots).
1386  For bigger datasets per candle
1387  - "CANDLEX5": Like candle2 but showing all data points.
1388  For very small datasets
1389  - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1390  For huge datasets
1391 
1392 
1393 The following picture shows how the six predefined representations look.
1394 
1395 Begin_Macro
1396 {
1397  TCanvas *c1 = new TCanvas("c1","c1",700,800);
1398  c1->Divide(2,3);
1399  gStyle->SetOptStat(kFALSE);
1400 
1401  TH2F *hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1402  Float_t px, py;
1403  for (Int_t i = 0; i < 15000; i++) {
1404  gRandom->Rannor(px,py);
1405  hcandle->Fill(px,5*py);
1406  }
1407  hcandle->SetMarkerSize(0.5);
1408 
1409  TH2F *h2;
1410  for (Int_t i=1; i<7; i++) {
1411  c1->cd(i);
1412  h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1413  h2->SetTitle(Form("CANDLE%d",i));
1414  }
1415 }
1416 End_Macro
1417 
1418 
1419 
1420 #### Example 1
1421 Box and improved whisker, no mean, no median, no anchor no outliers
1422 
1423  h1->Draw("CANDLEX(2001)");
1424 
1425 #### Example 2
1426 A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1427 
1428  h1->Draw("CANDLEX(112111)");
1429 
1430 #### Example 3
1431 The following example shows how several candle plots can be super-imposed using
1432 the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1433 Also the color, the line width, the size of the points and so on can be changed by the
1434 standard attribute setting methods such as SetLineColor() SetLineWidth().
1435 
1436 Begin_Macro(source)
1437 ../../../tutorials/hist/candleplot.C
1438 End_Macro
1439 
1440 #### <a name="HP140b"></a> The VIOLIN option
1441 
1442 <a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1443 that also encodes the pdf information at each point.
1444 
1445 
1446 Quartiles and mean are also represented at each point, with a marker
1447 and two lines.
1448 
1449 In this implementation a TH2 is considered as a collection of TH1 along
1450 X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1451 
1452 #### What a violin is made of
1453 
1454 \since **ROOT version 6.09/02**
1455 
1456 ##### The histogram
1457 The histogram is typically drawn to both directions with respect to the middle-line of the
1458 corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1459 one side (h=1, or h=2).
1460 The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1461 histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1462 be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1463 A solid fill style is recommended.
1464 
1465 \since **ROOT version 6.11/01**
1466 
1467 Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1468 violin can be influenced. Activated, the height of the bins of the individual violins will be
1469 scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1470 Deactivated, the height of the bin with the maximum content of each individual violin is
1471 set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1472 in the running program. Default is true. Scaling between multiple violin-charts
1473 (using "same" or THStack) is not supported, yet.
1474 
1475 ##### The zero indicator line
1476 Typical for violin charts is a line in the background over the whole histogram indicating
1477 the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1478 will always be the same as the fill-color of the histogram.
1479 
1480 ##### The Mean
1481 The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1482 
1483 ##### Whiskers
1484 The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1485 difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1486 the whiskers will be forced to be solid (usually hashed)
1487 
1488 ##### Points
1489 The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1490 better whisker definition (w=2) and outliers (p=1).
1491 
1492 ##### Other options
1493 It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1494 including a box-plot.
1495 
1496 #### How to use the violin-plots drawing option
1497 
1498 There are two predefined violin-plot representations:
1499  - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1500  zero indicator line)
1501  - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1502 
1503 A solid fill style is recommended for this plot (as opposed to a hollow or
1504 hashed style).
1505 
1506 Begin_Macro(source)
1507 {
1508  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1509  Int_t nx(6), ny(40);
1510  Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1511  TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1512  TF1 f1("f1", "gaus", +0,0 +4.0);
1513  Double_t x,y;
1514  for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1515  Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1516  f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1517  for(Int_t i=0; i<10000; ++i){
1518  x = xc;
1519  y = f1.GetRandom();
1520  hviolin->Fill(x, y);
1521  }
1522  }
1523  hviolin->SetFillColor(kGray);
1524  hviolin->SetMarkerStyle(20);
1525  hviolin->SetMarkerSize(0.5);
1526  hviolin->Draw("VIOLIN");
1527  c1->Update();
1528  return c1;
1529 }
1530 End_Macro
1531 
1532 The next example illustrates a time development of a certain value:
1533 
1534 Begin_Macro(source)
1535 ../../../tutorials/hist/candledecay.C
1536 End_Macro
1537 
1538 
1539 ### <a name="HP15"></a> The TEXT and TEXTnn Option
1540 
1541 
1542 For each bin the content is printed. The text attributes are:
1543 
1544 - text font = current TStyle font (`gStyle->SetTextFont()`).
1545 - text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1546  with the option `TEXT` the marker size can be changed with
1547  `h->SetMarkerSize(markersize)`).
1548 - text color = marker color.
1549 
1550 By default the format `g` is used. This format can be redefined
1551 by calling `gStyle->SetPaintTextFormat()`.
1552 
1553 It is also possible to use `TEXTnn` in order to draw the text with
1554 the angle `nn` (`0 < nn < 90`).
1555 
1556 For 2D histograms the text is plotted in the center of each non empty cells.
1557 It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`.
1558 For 1D histogram the text is plotted at a y position equal to the bin content.
1559 
1560 For 2D histograms when the option "E" (errors) is combined with the option
1561 text ("TEXTE"), the error for each bin is also printed.
1562 
1563 Begin_Macro(source)
1564 {
1565  TCanvas *c01 = new TCanvas("c01","c01",700,400);
1566  c01->Divide(2,1);
1567  TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1568  TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1569  Float_t px, py;
1570  for (Int_t i = 0; i < 25000; i++) {
1571  gRandom->Rannor(px,py);
1572  htext1->Fill(px,0.1);
1573  htext2->Fill(px,5*py,0.1);
1574  }
1575  gStyle->SetPaintTextFormat("4.1f m");
1576  htext2->SetMarkerSize(1.8);
1577  c01->cd(1);
1578  htext2->Draw("TEXT45");
1579  c01->cd(2);
1580  htext1->Draw();
1581  htext1->Draw("HIST TEXT0 SAME");
1582  return c01;
1583 }
1584 End_Macro
1585 
1586 \since **ROOT version 6.07/07:**
1587 
1588 In case several histograms are drawn on top ot each other (using option `SAME`),
1589 the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1590 text position in each cell, in percentage of the bin width.
1591 
1592 Begin_Macro(source)
1593 {
1594  TCanvas *c03 = new TCanvas("c03","c03",700,400);
1595  gStyle->SetOptStat(0);
1596  TH2F *htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1597  TH2F *htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1598  TH2F *htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1599  Float_t px, py;
1600  for (Int_t i = 0; i < 25000; i++) {
1601  gRandom->Rannor(px,py);
1602  htext3->Fill(4*px,20*py,0.1);
1603  htext4->Fill(4*px,20*py,0.5);
1604  htext5->Fill(4*px,20*py,1.0);
1605  }
1606  //gStyle->SetPaintTextFormat("4.1f m");
1607  htext4->SetMarkerSize(1.8);
1608  htext5->SetMarkerSize(1.8);
1609  htext5->SetMarkerColor(kRed);
1610  htext3->Draw("COL");
1611  htext4->SetBarOffset(0.2);
1612  htext4->Draw("TEXT SAME");
1613  htext5->SetBarOffset(-0.2);
1614  htext5->Draw("TEXT SAME");
1615  return c03;
1616 }
1617 End_Macro
1618 
1619 In the case of profile histograms it is possible to print the number
1620 of entries instead of the bin content. It is enough to combine the
1621 option "E" (for entries) with the option "TEXT".
1622 
1623 Begin_Macro(source)
1624 {
1625  TCanvas *c02 = new TCanvas("c02","c02",700,400);
1626  c02->Divide(2,1);
1627  gStyle->SetPaintTextFormat("g");
1628 
1629  TProfile *profile = new TProfile("profile","profile",10,0,10);
1630  profile->SetMarkerSize(2.2);
1631  profile->Fill(0.5,1);
1632  profile->Fill(1.5,2);
1633  profile->Fill(2.5,3);
1634  profile->Fill(3.5,4);
1635  profile->Fill(4.5,5);
1636  profile->Fill(5.5,5);
1637  profile->Fill(6.5,4);
1638  profile->Fill(7.5,3);
1639  profile->Fill(8.5,2);
1640  profile->Fill(9.5,1);
1641  c02->cd(1); profile->Draw("HIST TEXT0");
1642  c02->cd(2); profile->Draw("HIST TEXT0E");
1643 
1644  return c02;
1645 }
1646 End_Macro
1647 
1648 ### <a name="HP16"></a> The CONTour options
1649 
1650 
1651 The following contour options are supported:
1652 
1653 | Option | Description |
1654 |----------|-------------------------------------------------------------------|
1655 | "CONT" | Draw a contour plot (same as CONT0).|
1656 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1657 | "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1658 | "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1659 | "CONT3" | Draw a contour plot solid lines for all contours.|
1660 | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1661 | "CONT5" | Draw a contour plot using Delaunay triangles.|
1662 
1663 
1664 
1665 The following example shows a 2D histogram plotted with the option
1666 `CONTZ`. The option `CONT` draws a contour plot using surface
1667 colors to distinguish contours. Combined with the option `CONT` (or
1668 `CONT0`), the option `Z` allows to display the color palette
1669 defined by `gStyle->SetPalette()`.
1670 
1671 Begin_Macro(source)
1672 {
1673  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1674  TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1675  Float_t px, py;
1676  for (Int_t i = 0; i < 25000; i++) {
1677  gRandom->Rannor(px,py);
1678  hcontz->Fill(px-1,5*py);
1679  hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1680  }
1681  hcontz->Draw("CONTZ");
1682  return c1;
1683 }
1684 End_Macro
1685 
1686 The following example shows a 2D histogram plotted with the option
1687 `CONT1Z`. The option `CONT1` draws a contour plot using the
1688 line colors to distinguish contours. Combined with the option `CONT1`,
1689 the option `Z` allows to display the color palette defined by
1690 `gStyle->SetPalette()`.
1691 
1692 Begin_Macro(source)
1693 {
1694  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1695  TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1696  Float_t px, py;
1697  for (Int_t i = 0; i < 25000; i++) {
1698  gRandom->Rannor(px,py);
1699  hcont1->Fill(px-1,5*py);
1700  hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1701  }
1702  hcont1->Draw("CONT1Z");
1703  return c1;
1704 }
1705 End_Macro
1706 
1707 The following example shows a 2D histogram plotted with the option
1708 `CONT2`. The option `CONT2` draws a contour plot using the
1709 line styles to distinguish contours.
1710 
1711 Begin_Macro(source)
1712 {
1713  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1714  TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1715  Float_t px, py;
1716  for (Int_t i = 0; i < 25000; i++) {
1717  gRandom->Rannor(px,py);
1718  hcont2->Fill(px-1,5*py);
1719  hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1720  }
1721  hcont2->Draw("CONT2");
1722  return c1;
1723 }
1724 End_Macro
1725 
1726 The following example shows a 2D histogram plotted with the option
1727 `CONT3`. The option `CONT3` draws contour plot solid lines for
1728 all contours.
1729 
1730 Begin_Macro(source)
1731 {
1732  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1733  TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1734  Float_t px, py;
1735  for (Int_t i = 0; i < 25000; i++) {
1736  gRandom->Rannor(px,py);
1737  hcont3->Fill(px-1,5*py);
1738  hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1739  }
1740  hcont3->Draw("CONT3");
1741  return c1;
1742 }
1743 End_Macro
1744 
1745 The following example shows a 2D histogram plotted with the option
1746 `CONT4`. The option `CONT4` draws a contour plot using surface
1747 colors to distinguish contours (`SURF` option at theta = 0). Combined
1748 with the option `CONT` (or `CONT0`), the option `Z`
1749 allows to display the color palette defined by `gStyle->SetPalette()`.
1750 
1751 Begin_Macro(source)
1752 {
1753  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1754  TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1755  Float_t px, py;
1756  for (Int_t i = 0; i < 25000; i++) {
1757  gRandom->Rannor(px,py);
1758  hcont4->Fill(px-1,5*py);
1759  hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1760  }
1761  hcont4->Draw("CONT4Z");
1762  return c1;
1763 }
1764 End_Macro
1765 
1766 The default number of contour levels is 20 equidistant levels and can be changed
1767 with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1768 
1769 #### <a name="HP16a"></a> The LIST option
1770 
1771 When option `LIST` is specified together with option
1772 `CONT`, the points used to draw the contours are saved in
1773 `TGraph` objects:
1774 
1775  h->Draw("CONT LIST");
1776  gPad->Update();
1777 
1778 The contour are saved in `TGraph` objects once the pad is painted.
1779 Therefore to use this functionality in a macro, `gPad->Update()`
1780 should be performed after the histogram drawing. Once the list is
1781 built, the contours are accessible in the following way:
1782 
1783  TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1784  Int_t ncontours = contours->GetSize();
1785  TList *list = (TList*)contours->At(i);
1786 
1787 Where `i` is a contour number, and list contains a list of
1788 `TGraph` objects.
1789 For one given contour, more than one disjoint polyline may be generated.
1790 The number of TGraphs per contour is given by:
1791 
1792  list->GetSize();
1793 
1794 To access the first graph in the list one should do:
1795 
1796  TGraph *gr1 = (TGraph*)list->First();
1797 
1798 
1799 The following example (ContourList.C) shows how to use this functionality.
1800 
1801 Begin_Macro(source)
1802 ../../../tutorials/hist/ContourList.C
1803 End_Macro
1804 
1805 The following options select the `CONT4` option and are useful for
1806 sky maps or exposure maps (earth.C).
1807 
1808 | Option | Description |
1809 |--------------|---------------------------------------------------------------|
1810 | "AITOFF" | Draw a contour via an AITOFF projection.|
1811 | "MERCATOR" | Draw a contour via an Mercator projection.|
1812 | "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1813 | "PARABOLIC" | Draw a contour via an Parabolic projection.|
1814 
1815 Begin_Macro(source)
1816 ../../../tutorials/graphics/earth.C
1817 End_Macro
1818 
1819 
1820 ### <a name="HP17"></a> The LEGO options
1821 
1822 
1823 In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1824 is proportional to the cell content. The lego aspect is control with the
1825 following options:
1826 
1827 | Option | Description |
1828 |----------|-------------------------------------------------------------------|
1829 | "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1830 | "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1831 | "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1832 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1833 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1834 | "0" | When used with any LEGO option, the empty bins are not drawn.|
1835 
1836 
1837 See the limitations with [the option "SAME"](#HP060a).
1838 
1839 Line attributes can be used in lego plots to change the edges' style.
1840 
1841 The following example shows a 2D histogram plotted with the option
1842 `LEGO`. The option `LEGO` draws a lego plot using the hidden
1843 lines removal technique.
1844 
1845 Begin_Macro(source)
1846 {
1847  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1848  TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1849  Float_t px, py;
1850  for (Int_t i = 0; i < 25000; i++) {
1851  gRandom->Rannor(px,py);
1852  hlego->Fill(px-1,5*py);
1853  hlego->Fill(2+0.5*px,2*py-10.,0.1);
1854  }
1855  hlego->Draw("LEGO");
1856  return c2;
1857 }
1858 End_Macro
1859 
1860 The following example shows a 2D histogram plotted with the option
1861 `LEGO1`. The option `LEGO1` draws a lego plot using the
1862 hidden surface removal technique. Combined with any `LEGOn` option, the
1863 option `0` allows to not drawn the empty bins.
1864 
1865 Begin_Macro(source)
1866 {
1867  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1868  TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1869  Float_t px, py;
1870  for (Int_t i = 0; i < 25000; i++) {
1871  gRandom->Rannor(px,py);
1872  hlego1->Fill(px-1,5*py);
1873  hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1874  }
1875  hlego1->SetFillColor(kYellow);
1876  hlego1->Draw("LEGO1 0");
1877  return c2;
1878 }
1879 End_Macro
1880 
1881 The following example shows a 2D histogram plotted with the option
1882 `LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1883 draws a lego plot using the hidden surface removal technique but doesn't draw
1884 the border lines of each individual lego-bar. This is very useful for histograms
1885 having many bins. With such histograms the option `LEGO1` gives a black
1886 image because of the border lines. This option also works with stacked legos.
1887 
1888 Begin_Macro(source)
1889 {
1890  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1891  TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1892  Float_t px, py;
1893  for (Int_t i = 0; i < 25000; i++) {
1894  gRandom->Rannor(px,py);
1895  hlego3->Fill(px-1,5*py);
1896  hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1897  }
1898  hlego3->SetFillColor(kRed);
1899  hlego3->Draw("LEGO3");
1900  return c2;
1901 }
1902 End_Macro
1903 
1904 The following example shows a 2D histogram plotted with the option
1905 `LEGO2`. The option `LEGO2` draws a lego plot using colors to
1906 show the cell contents. Combined with the option `LEGO2`, the option
1907 `Z` allows to display the color palette defined by
1908 `gStyle->SetPalette()`.
1909 
1910 Begin_Macro(source)
1911 {
1912  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1913  TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1914  Float_t px, py;
1915  for (Int_t i = 0; i < 25000; i++) {
1916  gRandom->Rannor(px,py);
1917  hlego2->Fill(px-1,5*py);
1918  hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1919  }
1920  hlego2->Draw("LEGO2Z");
1921  return c2;
1922 }
1923 End_Macro
1924 
1925 
1926 
1927 ### <a name="HP18"></a> The "SURFace" options
1928 
1929 
1930 In a surface plot, cell contents are represented as a mesh.
1931 The height of the mesh is proportional to the cell content.
1932 
1933 | Option | Description |
1934 |----------|-------------------------------------------------------------------|
1935 | "SURF" | Draw a surface plot using the hidden line removal technique.|
1936 | "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1937 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
1938 | "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1939 | "SURF4" | Draw a surface using the Gouraud shading technique.|
1940 | "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1941 | "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.|
1942 | "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1943 
1944 
1945 
1946 See the limitations with [the option "SAME"](#HP060a).
1947 
1948 The following example shows a 2D histogram plotted with the option
1949 `SURF`. The option `SURF` draws a lego plot using the hidden
1950 lines removal technique.
1951 
1952 Begin_Macro(source)
1953 {
1954  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1955  TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1956  Float_t px, py;
1957  for (Int_t i = 0; i < 25000; i++) {
1958  gRandom->Rannor(px,py);
1959  hsurf->Fill(px-1,5*py);
1960  hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1961  }
1962  hsurf->Draw("SURF");
1963  return c2;
1964 }
1965 End_Macro
1966 
1967 The following example shows a 2D histogram plotted with the option
1968 `SURF1`. The option `SURF1` draws a surface plot using the
1969 hidden surface removal technique. Combined with the option `SURF1`,
1970 the option `Z` allows to display the color palette defined by
1971 `gStyle->SetPalette()`.
1972 
1973 Begin_Macro(source)
1974 {
1975  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1976  TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1977  Float_t px, py;
1978  for (Int_t i = 0; i < 25000; i++) {
1979  gRandom->Rannor(px,py);
1980  hsurf1->Fill(px-1,5*py);
1981  hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1982  }
1983  hsurf1->Draw("SURF1");
1984  return c2;
1985 }
1986 End_Macro
1987 
1988 The following example shows a 2D histogram plotted with the option
1989 `SURF2`. The option `SURF2` draws a surface plot using colors
1990 to show the cell contents. Combined with the option `SURF2`, the option
1991 `Z` allows to display the color palette defined by
1992 `gStyle->SetPalette()`.
1993 
1994 Begin_Macro(source)
1995 {
1996  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1997  TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
1998  Float_t px, py;
1999  for (Int_t i = 0; i < 25000; i++) {
2000  gRandom->Rannor(px,py);
2001  hsurf2->Fill(px-1,5*py);
2002  hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2003  }
2004  hsurf2->Draw("SURF2");
2005  return c2;
2006 }
2007 End_Macro
2008 
2009 The following example shows a 2D histogram plotted with the option
2010 `SURF3`. The option `SURF3` draws a surface plot using the
2011 hidden line removal technique with, in addition, a filled contour view drawn on the
2012 top. Combined with the option `SURF3`, the option `Z` allows
2013 to display the color palette defined by `gStyle->SetPalette()`.
2014 
2015 Begin_Macro(source)
2016 {
2017  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2018  TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2019  Float_t px, py;
2020  for (Int_t i = 0; i < 25000; i++) {
2021  gRandom->Rannor(px,py);
2022  hsurf3->Fill(px-1,5*py);
2023  hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2024  }
2025  hsurf3->Draw("SURF3");
2026  return c2;
2027 }
2028 End_Macro
2029 
2030 The following example shows a 2D histogram plotted with the option
2031 `SURF4`. The option `SURF4` draws a surface using the Gouraud
2032 shading technique.
2033 
2034 Begin_Macro(source)
2035 {
2036  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2037  TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2038  Float_t px, py;
2039  for (Int_t i = 0; i < 25000; i++) {
2040  gRandom->Rannor(px,py);
2041  hsurf4->Fill(px-1,5*py);
2042  hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2043  }
2044  hsurf4->SetFillColor(kOrange);
2045  hsurf4->Draw("SURF4");
2046  return c2;
2047 }
2048 End_Macro
2049 
2050 The following example shows a 2D histogram plotted with the option
2051 `SURF5 CYL`. Combined with the option `SURF5`, the option
2052 `Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2053 
2054 Begin_Macro(source)
2055 {
2056  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2057  TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2058  Float_t px, py;
2059  for (Int_t i = 0; i < 25000; i++) {
2060  gRandom->Rannor(px,py);
2061  hsurf5->Fill(px-1,5*py);
2062  hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2063  }
2064  hsurf5->Draw("SURF5 CYL");
2065  return c2;
2066 }
2067 End_Macro
2068 
2069 The following example shows a 2D histogram plotted with the option
2070 `SURF7`. The option `SURF7` draws a surface plot using the
2071 hidden surfaces removal technique with, in addition, a line contour view drawn on the
2072 top. Combined with the option `SURF7`, the option `Z` allows
2073 to display the color palette defined by `gStyle->SetPalette()`.
2074 
2075 Begin_Macro(source)
2076 {
2077  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2078  TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2079  Float_t px, py;
2080  for (Int_t i = 0; i < 25000; i++) {
2081  gRandom->Rannor(px,py);
2082  hsurf7->Fill(px-1,5*py);
2083  hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2084  }
2085  hsurf7->Draw("SURF7");
2086  return c2;
2087 }
2088 End_Macro
2089 
2090 As shown in the following example, when a contour plot is painted on top of a
2091 surface plot using the option `SAME`, the contours appear in 3D on the
2092 surface.
2093 
2094 Begin_Macro(source)
2095 {
2096  TCanvas *c20=new TCanvas("c20","c20",600,400);
2097  int NBins = 50;
2098  double d = 2;
2099  TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2100  for (int bx = 1; bx <= NBins; ++bx) {
2101  for (int by = 1; by <= NBins; ++by) {
2102  double x = hsc->GetXaxis()->GetBinCenter(bx);
2103  double y = hsc->GetYaxis()->GetBinCenter(by);
2104  hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2105  }
2106  }
2107  hsc->Draw("surf2");
2108  hsc->Draw("CONT1 SAME");
2109  return c20;
2110 }
2111 End_Macro
2112 
2113 
2114 ### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2115 
2116 
2117 Legos and surfaces plots are represented by default in Cartesian coordinates.
2118 Combined with any `LEGOn` or `SURFn` options the following
2119 options allow to draw a lego or a surface in other coordinates systems.
2120 
2121 | Option | Description |
2122 |----------|-------------------------------------------------------------------|
2123 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2124 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2125 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2126 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2127 
2128 
2129 
2130 <b>WARNING:</b> Axis are not drawn with these options.
2131 
2132 The following example shows the same histogram as a lego plot is the four
2133 different coordinates systems.
2134 
2135 Begin_Macro(source)
2136 {
2137  TCanvas *c3 = new TCanvas("c3","c3",600,400);
2138  c3->Divide(2,2);
2139  TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2140  Float_t px, py;
2141  for (Int_t i = 0; i < 25000; i++) {
2142  gRandom->Rannor(px,py);
2143  hlcc->Fill(px-1,5*py);
2144  hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2145  }
2146  hlcc->SetFillColor(kYellow);
2147  c3->cd(1); hlcc->Draw("LEGO1 CYL");
2148  c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2149  hlpc->SetTitle("Polar coordinates");
2150  c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2151  hlsc->SetTitle("Spherical coordinates");
2152  c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2153  hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2154  return c3;
2155 }
2156 End_Macro
2157 
2158 The following example shows the same histogram as a surface plot is the four different coordinates systems.
2159 
2160 Begin_Macro(source)
2161 {
2162  TCanvas *c4 = new TCanvas("c4","c4",600,400);
2163  c4->Divide(2,2);
2164  TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2165  Float_t px, py;
2166  for (Int_t i = 0; i < 25000; i++) {
2167  gRandom->Rannor(px,py);
2168  hscc->Fill(px-1,5*py);
2169  hscc->Fill(2+0.5*px,2*py-10.,0.1);
2170  }
2171  c4->cd(1); hscc->Draw("SURF1 CYL");
2172  c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2173  hspc->SetTitle("Polar coordinates");
2174  c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2175  hssc->SetTitle("Spherical coordinates");
2176  c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2177  hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2178  return c4;
2179 }
2180 End_Macro
2181 
2182 
2183 ### <a name="HP20"></a> Base line for bar-charts and lego plots
2184 
2185 
2186 By default the base line used to draw the boxes for bar-charts and lego plots is
2187 the histogram minimum. It is possible to force this base line to be 0 with the
2188 command:
2189 
2190  gStyle->SetHistMinimumZero();
2191 
2192 Begin_Macro(source)
2193 {
2194  TCanvas *c5 = new TCanvas("c5","c5",700,400);
2195  c5->Divide(2,1);
2196  gStyle->SetHistMinimumZero(1);
2197  TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2198  TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2199  Int_t i;
2200  Double_t x,y;
2201  hz1->SetFillColor(kBlue);
2202  hz2->SetFillColor(kBlue);
2203  for (i=0;i<10000;i++) {
2204  x = gRandom->Gaus(0,1);
2205  y = gRandom->Gaus(0,1);
2206  if (x>0) {
2207  hz1->Fill(x,1);
2208  hz2->Fill(x,y,1);
2209  } else {
2210  hz1->Fill(x,-1);
2211  hz2->Fill(x,y,-2);
2212  }
2213  }
2214  c5->cd(1); hz1->Draw("bar2");
2215  c5->cd(2); hz2->Draw("lego1");
2216  return c5;
2217 }
2218 End_Macro
2219 
2220 This option also works for horizontal plots. The example given in the section
2221 ["The bar chart option"](#HP100) appears as follow:
2222 
2223 Begin_Macro(source)
2224 {
2225  int i;
2226  const Int_t nx = 8;
2227  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2228  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2229  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2230 
2231  TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
2232  cbh->SetGrid();
2233 
2234  gStyle->SetHistMinimumZero();
2235 
2236  TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2237  h1bh->SetFillColor(4);
2238  h1bh->SetBarWidth(0.4);
2239  h1bh->SetBarOffset(0.1);
2240  h1bh->SetStats(0);
2241  h1bh->SetMinimum(-5);
2242  h1bh->SetMaximum(5);
2243 
2244  for (i=1; i<=nx; i++) {
2245  h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2246  h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2247  }
2248 
2249  h1bh->Draw("hbar");
2250 
2251  TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2252  h2bh->SetFillColor(38);
2253  h2bh->SetBarWidth(0.4);
2254  h2bh->SetBarOffset(0.5);
2255  h2bh->SetStats(0);
2256  for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2257 
2258  h2bh->Draw("hbar same");
2259 
2260  return cbh;
2261 }
2262 End_Macro
2263 
2264 
2265 ### <a name="HP20a"></a> TH2Poly Drawing
2266 
2267 
2268 The following options are supported:
2269 
2270 | Option | Description |
2271 |----------|-------------------------------------------------------------------|
2272 | "SCAT" | Draw a scatter plot (default).|
2273 | "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2274 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2275 | "0" | When used with any COL options, the empty bins are not drawn.|
2276 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2277 | "TEXTN" | Draw bin names as text.|
2278 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2279 | "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2280 | "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2281 | "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2282 
2283 
2284 
2285 `TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2286 shapes. The bins are defined as graphs. The following macro is a very simple
2287 example showing how to book a TH2Poly and draw it.
2288 
2289 Begin_Macro(source)
2290 {
2291  TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2292  TH2Poly *h2p = new TH2Poly();
2293  h2p->SetName("h2poly_name");
2294  h2p->SetTitle("h2poly_title");
2295  Double_t px1[] = {0, 5, 6};
2296  Double_t py1[] = {0, 0, 5};
2297  Double_t px2[] = {0, -1, -1, 0};
2298  Double_t py2[] = {0, 0, -1, 3};
2299  Double_t px3[] = {4, 3, 0, 1, 2.4};
2300  Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
2301  h2p->AddBin(3, px1, py1);
2302  h2p->AddBin(4, px2, py2);
2303  h2p->AddBin(5, px3, py3);
2304  h2p->Fill(0.1, 0.01, 3);
2305  h2p->Fill(-0.5, -0.5, 7);
2306  h2p->Fill(-0.7, -0.5, 1);
2307  h2p->Fill(1, 3, 1.5);
2308  Double_t fx[] = {0.1, -0.5, -0.7, 1};
2309  Double_t fy[] = {0.01, -0.5, -0.5, 3};
2310  Double_t fw[] = {3, 1, 1, 1.5};
2311  h2p->FillN(4, fx, fy, fw);
2312  h2p->Draw("col");
2313 }
2314 End_Macro
2315 
2316 Rectangular bins are a frequent case. The special version of
2317 the `AddBin` method allows to define them more easily like
2318 shown in the following example (th2polyBoxes.C).
2319 
2320 Begin_Macro(source)
2321 ../../../tutorials/hist/th2polyBoxes.C
2322 End_Macro
2323 
2324 One `TH2Poly` bin can be a list of polygons. Such bins are defined
2325 by calling `AddBin` with a `TMultiGraph`. The following example
2326 shows a such case:
2327 
2328 Begin_Macro(source)
2329 {
2330  TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2331 
2332  Int_t i, bin;
2333  const Int_t nx = 48;
2334  const char *states [nx] = {
2335  "alabama", "arizona", "arkansas", "california",
2336  "colorado", "connecticut", "delaware", "florida",
2337  "georgia", "idaho", "illinois", "indiana",
2338  "iowa", "kansas", "kentucky", "louisiana",
2339  "maine", "maryland", "massachusetts", "michigan",
2340  "minnesota", "mississippi", "missouri", "montana",
2341  "nebraska", "nevada", "new_hampshire", "new_jersey",
2342  "new_mexico", "new_york", "north_carolina", "north_dakota",
2343  "ohio", "oklahoma", "oregon", "pennsylvania",
2344  "rhode_island", "south_carolina", "south_dakota", "tennessee",
2345  "texas", "utah", "vermont", "virginia",
2346  "washington", "west_virginia", "wisconsin", "wyoming"
2347  };
2348  Double_t pop[nx] = {
2349  4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2350  9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2351  1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2352  1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2353  11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2354  24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2355  };
2356 
2357  Double_t lon1 = -130;
2358  Double_t lon2 = -65;
2359  Double_t lat1 = 24;
2360  Double_t lat2 = 50;
2361  TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2362 
2363  TFile::SetCacheFileDir(".");
2364  TFile *f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2365 
2366  TMultiGraph *mg;
2367  TKey *key;
2368  TIter nextkey(gDirectory->GetListOfKeys());
2369  while ((key = (TKey*)nextkey())) {
2370  TObject *obj = key->ReadObj();
2371  if (obj->InheritsFrom("TMultiGraph")) {
2372  mg = (TMultiGraph*)obj;
2373  bin = p->AddBin(mg);
2374  }
2375  }
2376 
2377  for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2378 
2379  gStyle->SetOptStat(11);
2380  p->Draw("COLZ L");
2381 }
2382 End_Macro
2383 
2384 `TH2Poly` histograms can also be plotted using the GL interface using
2385 the option "GLLEGO".
2386 
2387 \since **ROOT version 6.09/01**
2388 
2389 In some cases it can be useful to not draw the empty bins. the option "0"
2390 combined with the option "COL" et COLZ allows to do that.
2391 
2392 Begin_Macro(source)
2393 {
2394  TCanvas *chc = new TCanvas("chc","chc",600,400);
2395 
2396  TH2Poly *hc = new TH2Poly();
2397  hc->Honeycomb(0,0,.1,25,25);
2398  hc->SetName("hc");
2399  hc->SetTitle("Option COLZ 0");
2400  TRandom ran;
2401  for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2402  hc->Draw("colz 0");
2403 }
2404 End_Macro
2405 
2406 ### <a name="HP21"></a> The SPEC option
2407 
2408 
2409 This option allows to use the `TSpectrum2Painter` tools. See the full
2410 documentation in `TSpectrum2Painter::PaintSpectrum`.
2411 
2412 
2413 ### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2414 
2415 
2416 When this option is specified, a color palette with an axis indicating the value
2417 of the corresponding color is drawn on the right side of the picture. In case,
2418 not enough space is left, one can increase the size of the right margin by
2419 calling `TPad::SetRightMargin()`. The attributes used to display the
2420 palette axis values are taken from the Z axis of the object. For example, to
2421 set the labels size on the palette axis do:
2422 
2423  hist->GetZaxis()->SetLabelSize().
2424 
2425 <b>WARNING:</b> The palette axis is always drawn vertically.
2426 
2427 
2428 ### <a name="HP23"></a> Setting the color palette
2429 
2430 
2431 To change the color palette `TStyle::SetPalette` should be used, eg:
2432 
2433  gStyle->SetPalette(ncolors,colors);
2434 
2435 For example the option `COL` draws a 2D histogram with cells
2436 represented by a box filled with a color index which is a function
2437 of the cell content.
2438 If the cell content is N, the color index used will be the color number
2439 in `colors[N]`, etc. If the maximum cell content is greater than
2440 `ncolors`, all cell contents are scaled to `ncolors`.
2441 
2442 If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2443 defined. This palette is recommended for pads, labels ...
2444 
2445 `if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2446 Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2447 palette.
2448 
2449 Other pre-defined palettes with 255 colors are available when `colors == 0`.
2450 The following value of `ncolors` give access to:
2451 
2452 
2453  if ncolors = 51 and colors=0, a Deep Sea palette is used.
2454  if ncolors = 52 and colors=0, a Grey Scale palette is used.
2455  if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2456  if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2457  if ncolors = 55 and colors=0, a Rain Bow palette is used.
2458  if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2459 
2460 
2461 If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2462 
2463 The default palette defines:
2464 
2465 - index 0 to 9 : shades of grey
2466 - index 10 to 19 : shades of brown
2467 - index 20 to 29 : shades of blue
2468 - index 30 to 39 : shades of red
2469 - index 40 to 49 : basic colors
2470 
2471 The color numbers specified in the palette can be viewed by selecting
2472 the item `colors` in the `VIEW` menu of the canvas tool bar.
2473 The red, green, and blue components of a color can be changed thanks to
2474 `TColor::SetRGB()`.
2475 
2476 
2477 ### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2478 
2479 
2480 Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2481 histogram. One must create a graphical cut (mouse or C++) and specify the name
2482 of the cut between `[]` in the `Draw()` option.
2483 For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2484 
2485  myhist->Draw("surf1 [cutg]");
2486 
2487 To invert the cut, it is enough to put a `-` in front of its name:
2488 
2489  myhist->Draw("surf1 [-cutg]");
2490 
2491 It is possible to apply several cuts (`,` means logical AND):
2492 
2493  myhist->Draw("surf1 [cutg1,cutg2]");
2494 
2495 Begin_Macro(source)
2496 ../../../tutorials/fit/fit2a.C
2497 End_Macro
2498 
2499 ### <a name="HP25"></a> Drawing options for 3D histograms
2500 
2501 
2502 | Option | Description |
2503 |----------|-------------------------------------------------------------------|
2504 | "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)`|
2505 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2506 | "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2507 | "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2508 | "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2509 | "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2510 
2511 Note that instead of `BOX` one can also use `LEGO`.
2512 
2513 By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2514 
2515 The following example shows a 3D histogram plotted as a scatter plot.
2516 
2517 Begin_Macro(source)
2518 {
2519  auto c06 = new TCanvas("c06","c06",600,400);
2520  gStyle->SetOptStat(kFALSE);
2521  auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2522  Double_t x, y, z;
2523  for (Int_t i=0;i<10000;i++) {
2524  gRandom->Rannor(x, y);
2525  z = x*x + y*y;
2526  h3scat->Fill(x,y,z);
2527  }
2528  h3scat->Draw();
2529 }
2530 End_Macro
2531 
2532 The following example shows a 3D histogram plotted with the option `BOX`.
2533 
2534 Begin_Macro(source)
2535 {
2536  auto c16 = new TCanvas("c16","c16",600,400);
2537  gStyle->SetOptStat(kFALSE);
2538  auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2539  Double_t x, y, z;
2540  for (Int_t i=0;i<10000;i++) {
2541  gRandom->Rannor(x, y);
2542  z = x*x + y*y;
2543  h3box->Fill(x,y,z);
2544  }
2545  h3box->Draw("BOX");
2546 }
2547 End_Macro
2548 
2549 The following example shows a 3D histogram plotted with the option `BOX1`.
2550 
2551 Begin_Macro(source)
2552 {
2553  auto c36 = new TCanvas("c36","c36",600,400);
2554  gStyle->SetOptStat(kFALSE);
2555  auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2556  Double_t x, y, z;
2557  for (Int_t i=0;i<10000;i++) {
2558  gRandom->Rannor(x, y);
2559  z = abs(sin(x)/x + cos(y)*y);
2560  h3box->Fill(x,y,z);
2561  }
2562  h3box->SetFillColor(9);
2563  h3box->Draw("BOX1");
2564 }
2565 End_Macro
2566 
2567 The following example shows a 3D histogram plotted with the option `BOX2`.
2568 
2569 Begin_Macro(source)
2570 {
2571  auto c56 = new TCanvas("c56","c56",600,400);
2572  gStyle->SetOptStat(kFALSE);
2573  auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2574  Double_t x, y, z;
2575  for (Int_t i=0;i<10000;i++) {
2576  gRandom->Rannor(x, y);
2577  z = abs(sin(x)/x + cos(y)*y);
2578  h3box->Fill(x,y,z);
2579  }
2580  h3box->Draw("BOX2 Z");
2581 }
2582 End_Macro
2583 
2584 The following example shows a 3D histogram plotted with the option `BOX3`.
2585 
2586 Begin_Macro(source)
2587 {
2588  auto c46 = new TCanvas("c46","c46",600,400);
2589  c46->SetFillColor(38);
2590  gStyle->SetOptStat(kFALSE);
2591  auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2592  Double_t x, y, z;
2593  for (Int_t i=0;i<10000;i++) {
2594  gRandom->Rannor(x, y);
2595  z = x*x + y*y;
2596  h3box->Fill(x,y,z);
2597  }
2598  h3box->Draw("BOX3");
2599 }
2600 End_Macro
2601 
2602 For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2603 to the absolute value of the bin content. The bins with a negative content are
2604 drawn with a X on each face of the box as shown in the following example:
2605 
2606 Begin_Macro(source)
2607 {
2608  auto c = new TCanvas("c","c",600,400);
2609  gStyle->SetOptStat(kFALSE);
2610  auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2611  h3box->Fill(0., 2., 2., 10.);
2612  h3box->Fill(2., 2., 2., 5.);
2613  h3box->Fill(2., 2., .5, 2.);
2614  h3box->Fill(2., 2., 3., -1.);
2615  h3box->Fill(3., 2., 2., -10.);
2616  h3box->SetFillColor(8);
2617  h3box->Draw("box1");
2618 }
2619 End_Macro
2620 
2621 The following example shows a 3D histogram plotted with the option `ISO`.
2622 
2623 Begin_Macro(source)
2624 {
2625  auto c26 = new TCanvas("c26","c26",600,400);
2626  gStyle->SetOptStat(kFALSE);
2627  auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2628  Double_t x, y, z;
2629  for (Int_t i=0;i<10000;i++) {
2630  gRandom->Rannor(x, y);
2631  z = x*x + y*y;
2632  h3iso->Fill(x,y,z);
2633  }
2634  h3iso->SetFillColor(kCyan);
2635  h3iso->Draw("ISO");
2636 }
2637 End_Macro
2638 
2639 
2640 ### <a name="HP26"></a> Drawing option for histograms' stacks
2641 
2642 
2643 Stacks of histograms are managed with the `THStack`. A `THStack`
2644 is a collection of `TH1` (or derived) objects. For painting only the
2645 `THStack` containing `TH1` only or
2646 `THStack` containing `TH2` only will be considered.
2647 
2648 By default, histograms are shown stacked:
2649 
2650 1. The first histogram is paint.
2651 2. The the sum of the first and second, etc...
2652 
2653 If the option `NOSTACK` is specified, the histograms are all paint in
2654 the same pad as if the option `SAME` had been specified. This allows to
2655 compute X and Y scales common to all the histograms, like
2656 `TMultiGraph` does for graphs.
2657 
2658 If the option `PADS` is specified, the current pad/canvas is
2659 subdivided into a number of pads equal to the number of histograms and each
2660 histogram is paint into a separate pad.
2661 
2662 The following example shows various types of stacks (hstack.C).
2663 
2664 Begin_Macro(source)
2665 ../../../tutorials/hist/hstack.C
2666 End_Macro
2667 
2668 The option `nostackb` allows to draw the histograms next to each
2669 other as bar charts:
2670 
2671 Begin_Macro(source)
2672 {
2673  TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2674  THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2675 
2676  TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2677  h1->FillRandom("gaus",20000);
2678  h1->SetFillColor(kRed);
2679  hs->Add(h1);
2680 
2681  TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2682  h2->FillRandom("gaus",15000);
2683  h2->SetFillColor(kBlue);
2684  hs->Add(h2);
2685 
2686  TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2687  h3->FillRandom("gaus",10000);
2688  h3->SetFillColor(kGreen);
2689  hs->Add(h3);
2690 
2691  hs->Draw("nostackb");
2692  hs->GetXaxis()->SetNdivisions(-10);
2693  cst0->SetGridx();
2694  return cst0;
2695 }
2696 End_Macro
2697 
2698 If at least one of the histograms in the stack has errors, the whole stack is
2699 visualized by default with error bars. To visualize it without errors the
2700 option `HIST` should be used.
2701 
2702 Begin_Macro(source)
2703 {
2704  TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2705  cst1->Divide(2,1);
2706 
2707  TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2708  hst11->Sumw2();
2709  hst11->FillRandom("gaus", 1000);
2710  hst11->SetFillColor(kViolet);
2711  hst11->SetLineColor(kViolet);
2712 
2713  TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2714  hst12->FillRandom("gaus", 500);
2715  hst12->SetFillColor(kBlue);
2716  hst12->SetLineColor(kBlue);
2717 
2718  THStack st1("st1", "st1");
2719  st1.Add(hst11);
2720  st1.Add(hst12);
2721 
2722  cst1->cd(1); st1.Draw();
2723  cst1->cd(2); st1.Draw("hist");
2724 
2725  return cst1;
2726 }
2727 End_Macro
2728 
2729 ### <a name="HP27"></a> Drawing of 3D implicit functions
2730 
2731 
2732 3D implicit functions (`TF3`) can be drawn as iso-surfaces.
2733 The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2734 In the following example the options "FB" and "BB" suppress the
2735 "Front Box" and "Back Box" around the plot.
2736 
2737 Begin_Macro(source)
2738 {
2739  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2740  TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2741  f3->SetClippingBoxOn(0,0,0);
2742  f3->SetFillColor(30);
2743  f3->SetLineColor(15);
2744  f3->Draw("FBBB");
2745  return c2;
2746 }
2747 End_Macro
2748 
2749 
2750 ### <a name="HP28"></a> Associated functions drawing
2751 
2752 
2753 An associated function is created by `TH1::Fit`. More than on fitted
2754 function can be associated with one histogram (see `TH1::Fit`).
2755 
2756 A `TF1` object `f1` can be added to the list of associated
2757 functions of an histogram `h` without calling `TH1::Fit`
2758 simply doing:
2759 
2760  h->GetListOfFunctions()->Add(f1);
2761 
2762 or
2763 
2764  h->GetListOfFunctions()->Add(f1,someoption);
2765 
2766 To retrieve a function by name from this list, do:
2767 
2768  TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2769 
2770 or
2771 
2772  TF1 *f1 = h->GetFunction(name);
2773 
2774 Associated functions are automatically painted when an histogram is drawn.
2775 To avoid the painting of the associated functions the option `HIST`
2776 should be added to the list of the options used to paint the histogram.
2777 
2778 
2779 ### <a name="HP29"></a> Drawing using OpenGL
2780 
2781 
2782 The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2783 graphics library. The plotting options start with `GL` keyword.
2784 In addition, in order to inform canvases that OpenGL should be used to render
2785 3D representations, the following option should be set:
2786 
2787  gStyle->SetCanvasPreferGL(true);
2788 
2789 
2790 #### <a name="HP29a"></a> General information: plot types and supported options
2791 
2792 The following types of plots are provided:
2793 
2794 For lego plots the supported options are:
2795 
2796 | Option | Description |
2797 |----------|-------------------------------------------------------------------|
2798 | "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2799 | "GLLEGO2"| Bins with color levels.|
2800 | "GLLEGO3"| Cylindrical bars.|
2801 
2802 
2803 
2804 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2805 In polar only Z axis can be logarithmic, in cylindrical only Y.
2806 
2807 For surface plots (`TF2` and `TH2`) the supported options are:
2808 
2809 | Option | Description |
2810 |-----------|------------------------------------------------------------------|
2811 | "GLSURF" | Draw a surface.|
2812 | "GLSURF1" | Surface with color levels|
2813 | "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2814 | "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2815 | "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2816 
2817 
2818 
2819 The surface painting in cartesian coordinates supports logarithmic scales along
2820 X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2821 in cylindrical coordinates only the Y axis.
2822 
2823 Additional options to SURF and LEGO - Coordinate systems:
2824 
2825 | Option | Description |
2826 |----------|-------------------------------------------------------------------|
2827 | " " | Default, cartesian coordinates system.|
2828 | "POL" | Polar coordinates system.|
2829 | "CYL" | Cylindrical coordinates system.|
2830 | "SPH" | Spherical coordinates system.|
2831 
2832 
2833 
2834 #### <a name="HP290"></a> TH3 as color boxes
2835 
2836 The supported option is:
2837 
2838 | Option | Description |
2839 |----------|-------------------------------------------------------------------|
2840 | "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2841 
2842 
2843 
2844 #### <a name="HP29b"></a> TH3 as boxes (spheres)
2845 
2846 The supported options are:
2847 
2848 | Option | Description |
2849 |----------|-------------------------------------------------------------------|
2850 | "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2851 | "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2852 
2853 
2854 
2855 #### <a name="HP29c"></a> TH3 as iso-surface(s)
2856 
2857 The supported option is:
2858 
2859 | Option | Description |
2860 |----------|-------------------------------------------------------------------|
2861 | "GLISO" | TH3 is drawn using iso-surfaces.|
2862 
2863 
2864 
2865 #### <a name="HP29d"></a> TF3 (implicit function)
2866 
2867 The supported option is:
2868 
2869 | Option | Description |
2870 |----------|-------------------------------------------------------------------|
2871 | "GLTF3" | Draw a TF3.|
2872 
2873 
2874 
2875 #### <a name="HP29e"></a> Parametric surfaces
2876 
2877 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2878 equations and visualize the surface.
2879 
2880 #### <a name="HP29f"></a> Interaction with the plots
2881 
2882 All the interactions are implemented via standard methods
2883 `DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2884 interactions with the OpenGL plots are possible only when the mouse cursor is
2885 in the plot's area (the plot's area is the part of a the pad occupied by
2886 gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2887 pad interaction is performed.
2888 
2889 #### <a name="HP29g"></a> Selectable parts
2890 
2891 Different parts of the plot can be selected:
2892 
2893 - xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2894  if the dynamic slicing by this plane is supported, and it's highlighted in red,
2895  if the dynamic slicing is not supported.
2896 - The plot itself:
2897  On surfaces, the selected surface is outlined in red. (TF3 and
2898  ISO are not outlined). On lego plots, the selected bin is
2899  highlighted. The bin number and content are displayed in pad's
2900  status bar. In box plots, the box or sphere is highlighted and
2901  the bin info is displayed in pad's status bar.
2902 
2903 
2904 #### <a name="HP29h"></a> Rotation and zooming
2905 
2906 
2907 - Rotation:
2908  When the plot is selected, it can be rotated by pressing and
2909  holding the left mouse button and move the cursor.
2910 - Zoom/Unzoom:
2911  Mouse wheel or 'j', 'J', 'k', 'K' keys.
2912 
2913 
2914 #### <a name="HP29i"></a> Panning
2915 
2916 The selected plot can be moved in a pad's area by pressing and
2917 holding the left mouse button and the shift key.
2918 
2919 #### <a name="HP29j"></a> Box cut
2920 
2921 Surface, iso, box, TF3 and parametric painters support box cut by
2922 pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2923 area. That will display a transparent box, cutting away part of the
2924 surface (or boxes) in order to show internal part of plot. This box
2925 can be moved inside the plot's area (the full size of the box is
2926 equal to the plot's surrounding box) by selecting one of the box
2927 cut axes and pressing the left mouse button to move it.
2928 
2929 #### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2930 
2931 Currently, all gl-plots support some form of slicing. When back plane
2932 is selected (and if it's highlighted in green) you can press and hold
2933 left mouse button and shift key and move this back plane inside
2934 plot's area, creating the slice. During this "slicing" plot becomes
2935 semi-transparent. To remove all slices (and projected curves for
2936 surfaces) double click with left mouse button in a plot's area.
2937 
2938 #### <a name="HP29l"></a> Surface with option "GLSURF"
2939 
2940 The surface profile is displayed on the slicing plane.
2941 The profile projection is drawn on the back plane
2942 by pressing `'p'` or `'P'` key.
2943 
2944 #### <a name="HP29m"></a> TF3
2945 
2946 The contour plot is drawn on the slicing plane. For TF3 the color
2947 scheme can be changed by pressing 's' or 'S'.
2948 
2949 #### <a name="HP29n"></a> Box
2950 
2951 The contour plot corresponding to slice plane position is drawn in real time.
2952 
2953 #### <a name="HP29o"></a> Iso
2954 
2955 Slicing is similar to "GLBOX" option.
2956 
2957 #### <a name="HP29p"></a> Parametric plot
2958 
2959 No slicing. Additional keys: 's' or 'S' to change color scheme -
2960 about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2961 increase number of polygons ('l' for "level" of details), 'w' or 'W'
2962 to show outlines ('w' for "wireframe").
2963 
2964 */
2965 
2967 
2970 
2971 const Int_t kNMAX = 2000;
2972 
2973 const Int_t kMAXCONTOUR = 104;
2975 
2997 
2999 
3000 ////////////////////////////////////////////////////////////////////////////////
3001 /// Default constructor.
3002 
3004 {
3005 
3006  fH = 0;
3007  fXaxis = 0;
3008  fYaxis = 0;
3009  fZaxis = 0;
3010  fFunctions = 0;
3011  fXbuf = 0;
3012  fYbuf = 0;
3013  fNcuts = 0;
3014  fStack = 0;
3015  fLego = 0;
3016  fPie = 0;
3017  fGraph2DPainter = 0;
3018  fShowProjection = 0;
3019  fShowOption = "";
3020  for (int i=0; i<kMaxCuts; i++) {
3021  fCuts[i] = 0;
3022  fCutsOpt[i] = 0;
3023  }
3024 
3025  gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3026  gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3027  gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3028  gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3029  gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3030  gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3031  gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3032  gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3033  gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3034  gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3035  gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3036  gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3037  gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3038  gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3039  gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3040  gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3041  gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3042  gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3043  gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3044  gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3045  gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3046 }
3047 
3048 ////////////////////////////////////////////////////////////////////////////////
3049 /// Default destructor.
3050 
3052 {
3053 }
3054 
3055 ////////////////////////////////////////////////////////////////////////////////
3056 /// Compute the distance from the point px,py to a line.
3057 ///
3058 /// Compute the closest distance of approach from point px,py to elements of
3059 /// an histogram. The distance is computed in pixels units.
3060 ///
3061 /// Algorithm: Currently, this simple model computes the distance from the mouse
3062 /// to the histogram contour only.
3063 
3065 {
3066 
3067  Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3068 
3069  const Int_t big = 9999;
3070  const Int_t kMaxDiff = 7;
3071 
3072  if (fPie) return fPie->DistancetoPrimitive(px, py);
3073 
3074  Double_t x = gPad->AbsPixeltoX(px);
3075  Double_t x1 = gPad->AbsPixeltoX(px+1);
3076 
3077  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3078  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3079  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3080  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3081  Int_t curdist = big;
3082  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3083  Bool_t dsame;
3084  TObject *PadPointer = gPad->GetPadPointer();
3085  if (!PadPointer) return 0;
3086  TString doption = PadPointer->GetDrawOption();
3087  Double_t factor = 1;
3088  if (fH->GetNormFactor() != 0) {
3089  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3090  }
3091  // return if point is not in the histogram area
3092 
3093  // If a 3D view exists, check distance to axis
3094  TView *view = gPad->GetView();
3095  Int_t d1,d2,d3;
3096  if (view && Hoption.Contour != 14) {
3097  Double_t ratio;
3098  d3 = view->GetDistancetoAxis(3, px, py, ratio);
3099  if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3100  d1 = view->GetDistancetoAxis(1, px, py, ratio);
3101  if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3102  d2 = view->GetDistancetoAxis(2, px, py, ratio);
3103  if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3104  if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3105  goto FUNCTIONS;
3106  }
3107  // check if point is close to an axis
3108  doption.ToLower();
3109  dsame = kFALSE;
3110  if (doption.Contains("same")) dsame = kTRUE;
3111 
3112  dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3113  if (doption.Contains("y+")) {
3114  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3115  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3116  if (!dsame) {
3117  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3118  else gPad->SetSelected(fXaxis);
3119  return 0;
3120  }
3121  }
3122  } else {
3123  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3124  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3125  if (!dsame) {
3126  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3127  else gPad->SetSelected(fXaxis);
3128  return 0;
3129  }
3130  }
3131  }
3132 
3133  dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3134  if (doption.Contains("x+")) {
3135  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3136  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3137  if (!dsame) {
3138  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3139  else gPad->SetSelected(fYaxis);
3140  return 0;
3141  }
3142  }
3143  } else {
3144  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3145  if (yxaxis < puymin) yxaxis = puymin;
3146  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3147  if (!dsame) {
3148  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3149  else gPad->SetSelected(fYaxis);
3150  return 0;
3151  }
3152  }
3153  }
3154 
3155  // if object is 2D or 3D return this object
3156  if (fH->GetDimension() == 2) {
3157  if (fH->InheritsFrom(TH2Poly::Class())) {
3158  TH2Poly *th2 = (TH2Poly*)fH;
3159  Double_t xmin, ymin, xmax, ymax;
3160  gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3161  Double_t pxu = gPad->AbsPixeltoX(px);
3162  Double_t pyu = gPad->AbsPixeltoY(py);
3163  if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3164  curdist = big;
3165  goto FUNCTIONS;
3166  } else {
3167  Int_t bin = th2->FindBin(pxu, pyu);
3168  if (bin>0) curdist = 1;
3169  else curdist = big;
3170  goto FUNCTIONS;
3171  }
3172  }
3173  Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3174  if ( px > puxmin + delta2
3175  && px < puxmax - delta2
3176  && py > puymax + delta2
3177  && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3178  }
3179 
3180  // point is inside histogram area. Find channel number
3181  if (gPad->IsVertical()) {
3182  Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3183  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3184  Double_t binval = factor*fH->GetBinContent(bin);
3185  Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3186  if (binval == 0 && pybin < puymin) pybin = 10000;
3187  // special case if more than one bin for the pixel
3188  if (binsup-bin>1) {
3189  Double_t binvalmin, binvalmax;
3190  binvalmin=binval;
3191  binvalmax=binval;
3192  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3193  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3194  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3195  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3196  }
3197  Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3198  Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3199  if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3200  }
3201  if (bin != binsup) { // Mouse on bin border
3202  Double_t binsupval = factor*fH->GetBinContent(binsup);
3203  Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3204  if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3205  }
3206  if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3207  } else {
3208  Double_t y = gPad->AbsPixeltoY(py);
3209  Double_t y1 = gPad->AbsPixeltoY(py+1);
3210  Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3211  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3212  Double_t binval = factor*fH->GetBinContent(bin);
3213  Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3214  if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3215  // special case if more than one bin for the pixel
3216  if (binsup-bin>1) {
3217  Double_t binvalmin, binvalmax;
3218  binvalmin=binval;
3219  binvalmax=binval;
3220  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3221  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3222  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3223  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3224  }
3225  Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3226  Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3227  if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3228  }
3229  if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3230  }
3231  // Loop on the list of associated functions and user objects
3232 FUNCTIONS:
3233  TObject *f;
3234  TIter next(fFunctions);
3235  while ((f = (TObject*) next())) {
3236  Int_t dist;
3237  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3238  else dist = f->DistancetoPrimitive(px,py);
3239  if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3240  }
3241  return curdist;
3242 }
3243 
3244 ////////////////////////////////////////////////////////////////////////////////
3245 /// Display a panel with all histogram drawing options.
3246 
3248 {
3249 
3250  gCurrentHist = fH;
3251  if (!gPad) {
3252  Error("DrawPanel", "need to draw histogram first");
3253  return;
3254  }
3256  editor->Show();
3257  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3258  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3259 }
3260 
3261 ////////////////////////////////////////////////////////////////////////////////
3262 /// Execute the actions corresponding to `event`.
3263 ///
3264 /// This function is called when a histogram is clicked with the locator at
3265 /// the pixel position px,py.
3266 
3268 {
3269 
3270  if (!gPad) return;
3271 
3272  static Int_t bin, px1, py1, px2, py2, pyold;
3273  static TBox *zoombox;
3274  Double_t zbx1,zbx2,zby1,zby2;
3275 
3276  Int_t bin1, bin2;
3277  Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3278  Bool_t opaque = gPad->OpaqueMoving();
3279 
3280  if (!gPad->IsEditable()) return;
3281 
3282  if (fPie) {
3283  fPie->ExecuteEvent(event, px, py);
3284  return;
3285  }
3286  // come here if we have a lego/surface in the pad
3287  TView *view = gPad->GetView();
3288 
3289  if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3290  view->ExecuteRotateView(event, px, py);
3291  return;
3292  }
3293 
3294  TAxis *xaxis = fH->GetXaxis();
3295  TAxis *yaxis = fH->GetYaxis();
3296  Int_t dimension = fH->GetDimension();
3297 
3298  Double_t factor = 1;
3299  if (fH->GetNormFactor() != 0) {
3300  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3301  }
3302 
3303  switch (event) {
3304 
3305  case kButton1Down:
3306 
3307  if (!opaque) gVirtualX->SetLineColor(-1);
3308  fH->TAttLine::Modify();
3309 
3310  if (opaque && dimension ==2) {
3311  zbx1 = gPad->AbsPixeltoX(px);
3312  zbx2 = gPad->AbsPixeltoX(px);
3313  zby1 = gPad->AbsPixeltoY(py);
3314  zby2 = gPad->AbsPixeltoY(py);
3315  px1 = px;
3316  py1 = py;
3317  if (gPad->GetLogx()) {
3318  zbx1 = TMath::Power(10,zbx1);
3319  zbx2 = TMath::Power(10,zbx2);
3320  }
3321  if (gPad->GetLogy()) {
3322  zby1 = TMath::Power(10,zby1);
3323  zby2 = TMath::Power(10,zby2);
3324  }
3325  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3326  Int_t ci = TColor::GetColor("#7d7dff");
3327  TColor *zoomcolor = gROOT->GetColor(ci);
3328  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3329  else zoomcolor->SetAlpha(0.5);
3330  zoombox->SetFillColor(ci);
3331  zoombox->Draw();
3332  gPad->Modified();
3333  gPad->Update();
3334  }
3335  // No break !!!
3336 
3337  case kMouseMotion:
3338 
3339  if (fShowProjection) {ShowProjection3(px,py); break;}
3340 
3341  gPad->SetCursor(kPointer);
3342  if (dimension ==1) {
3343  if (Hoption.Bar) {
3344  baroffset = fH->GetBarOffset();
3345  barwidth = fH->GetBarWidth();
3346  } else {
3347  baroffset = 0;
3348  barwidth = 1;
3349  }
3350  x = gPad->AbsPixeltoX(px);
3351  bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3352  binwidth = fXaxis->GetBinWidth(bin);
3353  xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3354  xup = gPad->XtoPad(xlow + barwidth*binwidth);
3355  ylow = gPad->GetUymin();
3356  px1 = gPad->XtoAbsPixel(xlow);
3357  px2 = gPad->XtoAbsPixel(xup);
3358  py1 = gPad->YtoAbsPixel(ylow);
3359  py2 = py;
3360  pyold = py;
3361  if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3362  }
3363 
3364  break;
3365 
3366  case kButton1Motion:
3367 
3368  if (dimension ==1) {
3369  if (gROOT->GetEditHistograms()) {
3370  if (!opaque) {
3371  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3372  py2 += py - pyold;
3373  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3374  pyold = py;
3375  } else {
3376  py2 += py - pyold;
3377  pyold = py;
3378  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3379  fH->SetBinContent(bin,binval);
3380  gPad->Modified(kTRUE);
3381  }
3382  }
3383  }
3384 
3385  if (opaque && dimension ==2) {
3386  if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3387  zbx2 = gPad->AbsPixeltoX(px);
3388  zby2 = gPad->AbsPixeltoY(py);
3389  if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3390  if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3391  zoombox->SetX2(zbx2);
3392  zoombox->SetY2(zby2);
3393  gPad->Modified();
3394  gPad->Update();
3395  }
3396  }
3397 
3398  break;
3399 
3400  case kWheelUp:
3401 
3402  if (dimension ==2) {
3403  bin1 = xaxis->GetFirst()+1;
3404  bin2 = xaxis->GetLast()-1;
3405  bin1 = TMath::Max(bin1, 1);
3406  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3407  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3408  bin1 = yaxis->GetFirst()+1;
3409  bin2 = yaxis->GetLast()-1;
3410  bin1 = TMath::Max(bin1, 1);
3411  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3412  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3413  }
3414  gPad->Modified();
3415  gPad->Update();
3416 
3417  break;
3418 
3419  case kWheelDown:
3420 
3421  if (dimension == 2) {
3422  bin1 = xaxis->GetFirst()-1;
3423  bin2 = xaxis->GetLast()+1;
3424  bin1 = TMath::Max(bin1, 1);
3425  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3426  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3427  bin1 = yaxis->GetFirst()-1;
3428  bin2 = yaxis->GetLast()+1;
3429  bin1 = TMath::Max(bin1, 1);
3430  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3431  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3432  }
3433  gPad->Modified();
3434  gPad->Update();
3435 
3436  break;
3437 
3438  case kButton1Up:
3439  if (dimension ==1) {
3440  if (gROOT->GetEditHistograms()) {
3441  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3442  fH->SetBinContent(bin,binval);
3443  PaintInit(); // recalculate Hparam structure and recalculate range
3444  }
3445 
3446  // might resize pad pixmap so should be called before any paint routine
3447  RecalculateRange();
3448  }
3449  if (opaque && dimension ==2) {
3450  if (zoombox) {
3451  Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3452  Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3453  Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3454  Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3455  x1 = TMath::Max(x1,xaxis->GetXmin());
3456  x2 = TMath::Min(x2,xaxis->GetXmax());
3457  y1 = TMath::Max(y1,yaxis->GetXmin());
3458  y2 = TMath::Min(y2,yaxis->GetXmax());
3459  if (x1<x2 && y1<y2) {
3460  xaxis->SetRangeUser(x1, x2);
3461  yaxis->SetRangeUser(y1, y2);
3462  }
3463  zoombox->Delete();
3464  zoombox = 0;
3465  }
3466  }
3467  gPad->Modified(kTRUE);
3468  if (opaque) gVirtualX->SetLineColor(-1);
3469 
3470  break;
3471 
3472  case kButton1Locate:
3473 
3474  ExecuteEvent(kButton1Down, px, py);
3475 
3476  while (1) {
3477  px = py = 0;
3478  event = gVirtualX->RequestLocator(1, 1, px, py);
3479 
3480  ExecuteEvent(kButton1Motion, px, py);
3481 
3482  if (event != -1) { // button is released
3483  ExecuteEvent(kButton1Up, px, py);
3484  return;
3485  }
3486  }
3487  }
3488 }
3489 
3490 ////////////////////////////////////////////////////////////////////////////////
3491 /// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3492 
3494 {
3495 
3496 
3497 
3498  // Check if fH contains a TGraphDelaunay2D
3499  TList *hl = fH->GetListOfFunctions();
3500  TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3501  // try with the old painter
3502  TGraphDelaunay *dtOld = nullptr;
3503  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3504 
3505  if (!dt && !dtOld) return nullptr;
3506 
3507  gCurrentHist = fH;
3508 
3509  if (!fGraph2DPainter) {
3510  if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3511  else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3512  }
3513 
3514  return fGraph2DPainter->GetContourList(contour);
3515 }
3516 
3517 ////////////////////////////////////////////////////////////////////////////////
3518 /// Display the histogram info (bin number, contents, integral up to bin
3519 /// corresponding to cursor position px,py.
3520 
3522 {
3523 
3524  if (!gPad) return (char*)"";
3525  static char info[200];
3526  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3527  Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3528  Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3529  TString drawOption = fH->GetDrawOption();
3530  drawOption.ToLower();
3531  Double_t xmin, xmax, uxmin,uxmax;
3532  Double_t ymin, ymax, uymin,uymax;
3533  if (fH->GetDimension() == 2) {
3534  if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3535  uxmin=gPad->GetUxmin();
3536  uxmax=gPad->GetUxmax();
3537  xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
3538  xmax = fXaxis->GetBinUpEdge(fXaxis->GetLast());
3539  x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3540  uymin=gPad->GetUymin();
3541  uymax=gPad->GetUymax();
3542  ymin = fYaxis->GetBinLowEdge(fYaxis->GetFirst());
3543  ymax = fYaxis->GetBinUpEdge(fYaxis->GetLast());
3544  y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3545  }
3546  }
3547  Int_t binx,biny,binmin=0,binx1;
3548  if (gPad->IsVertical()) {
3549  binx = fXaxis->FindFixBin(x);
3550  if (drawOption.Index("same") >= 0) {
3551  TH1 *h1;
3552  TIter next(gPad->GetListOfPrimitives());
3553  while ((h1 = (TH1 *)next())) {
3554  if (!h1->InheritsFrom(TH1::Class())) continue;
3555  binmin = h1->GetXaxis()->GetFirst();
3556  break;
3557  }
3558  } else {
3559  binmin = fXaxis->GetFirst();
3560  }
3561  binx1 = fXaxis->FindFixBin(x1);
3562  // special case if more than 1 bin in x per pixel
3563  if (binx1-binx>1 && fH->GetDimension() == 1) {
3564  Double_t binval=fH->GetBinContent(binx);
3565  Int_t binnear=binx;
3566  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3567  Double_t binvaltmp = fH->GetBinContent(ibin);
3568  if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3569  binval=binvaltmp;
3570  binnear=ibin;
3571  }
3572  }
3573  binx = binnear;
3574  }
3575  } else {
3576  x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3577  binx = fXaxis->FindFixBin(y);
3578  if (drawOption.Index("same") >= 0) {
3579  TH1 *h1;
3580  TIter next(gPad->GetListOfPrimitives());
3581  while ((h1 = (TH1 *)next())) {
3582  if (!h1->InheritsFrom(TH1::Class())) continue;
3583  binmin = h1->GetXaxis()->GetFirst();
3584  break;
3585  }
3586  } else {
3587  binmin = fXaxis->GetFirst();
3588  }
3589  binx1 = fXaxis->FindFixBin(x1);
3590  // special case if more than 1 bin in x per pixel
3591  if (binx1-binx>1 && fH->GetDimension() == 1) {
3592  Double_t binval=fH->GetBinContent(binx);
3593  Int_t binnear=binx;
3594  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3595  Double_t binvaltmp = fH->GetBinContent(ibin);
3596  if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3597  binval=binvaltmp;
3598  binnear=ibin;
3599  }
3600  }
3601  binx = binnear;
3602  }
3603  }
3604  if (fH->GetDimension() == 1) {
3605  if (fH->InheritsFrom(TProfile::Class())) {
3606  TProfile *tp = (TProfile*)fH;
3607  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3608  x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3609  (Int_t) tp->GetBinEntries(binx));
3610  }
3611  else {
3612  Double_t integ = 0;
3613  for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3614  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3615  x,y,binx,fH->GetBinContent(binx),integ);
3616  }
3617  } else if (fH->GetDimension() == 2) {
3618  if (fH->InheritsFrom(TH2Poly::Class())) {
3619  TH2Poly *th2 = (TH2Poly*)fH;
3620  biny = th2->FindBin(x,y);
3621  snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3622  th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3623  }
3624  else if (fH->InheritsFrom(TProfile2D::Class())) {
3625  TProfile2D *tp = (TProfile2D*)fH;
3626  biny = fYaxis->FindFixBin(y);
3627  Int_t bin = fH->GetBin(binx,biny);
3628  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3629  x, y, binx, biny, fH->GetBinContent(bin),
3630  fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3631  } else {
3632  biny = fYaxis->FindFixBin(y);
3633  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3634  x,y,binx,biny,fH->GetBinContent(binx,biny),
3635  fH->GetBinError(binx,biny));
3636  }
3637  } else {
3638  // 3d case: retrieving the x,y,z bin is not yet implemented
3639  // print just the x,y info
3640  snprintf(info,200,"(x=%g, y=%g)",x,y);
3641  }
3642  return info;
3643 }
3644 
3645 ////////////////////////////////////////////////////////////////////////////////
3646 /// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3647 
3649 {
3650 
3651  for (Int_t i=0;i<fNcuts;i++) {
3652  Double_t x = fXaxis->GetBinCenter(ix);
3653  Double_t y = fYaxis->GetBinCenter(iy);
3654  if (fCutsOpt[i] > 0) {
3655  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3656  } else {
3657  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3658  }
3659  }
3660  return kTRUE;
3661 }
3662 
3663 ////////////////////////////////////////////////////////////////////////////////
3664 /// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3665 
3667 {
3668 
3669  for (Int_t i=0;i<fNcuts;i++) {
3670  if (fCutsOpt[i] > 0) {
3671  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3672  } else {
3673  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3674  }
3675  }
3676  return kTRUE;
3677 }
3678 
3679 ////////////////////////////////////////////////////////////////////////////////
3680 /// Decode string `choptin` and fill Hoption structure.
3681 
3683 {
3684 
3685  char *l;
3686  char chopt[128];
3687  Int_t nch = strlen(choptin);
3688  strlcpy(chopt,choptin,128);
3689  Int_t hdim = fH->GetDimension();
3690 
3691  Hoption.Axis = Hoption.Bar = Hoption.Curve = Hoption.Error = 0;
3692  Hoption.Hist = Hoption.Line = Hoption.Mark = Hoption.Fill = 0;
3693  Hoption.Same = Hoption.Func = Hoption.Scat = 0;
3694  Hoption.Star = Hoption.Arrow = Hoption.Box = Hoption.Text = 0;
3695  Hoption.Char = Hoption.Color = Hoption.Contour = Hoption.Logx = 0;
3696  Hoption.Logy = Hoption.Logz = Hoption.Lego = Hoption.Surf = 0;
3697  Hoption.Off = Hoption.Tri = Hoption.Proj = Hoption.AxisPos = 0;
3698  Hoption.Spec = Hoption.Pie = Hoption.Candle = 0;
3699 
3700  // special 2D options
3701  Hoption.List = 0;
3702  Hoption.Zscale = 0;
3703  Hoption.FrontBox = 1;
3704  Hoption.BackBox = 1;
3705  Hoption.System = kCARTESIAN;
3706 
3707  Hoption.Zero = 0;
3708 
3709  //check for graphical cuts
3710  MakeCuts(chopt);
3711 
3712  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3713  if (hdim > 1) Hoption.Scat = 1;
3714  if (!nch) Hoption.Hist = 1;
3715  if (fFunctions->First()) Hoption.Func = 1;
3716  if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3717 
3718  char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
3719  char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
3720  char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
3721  if (l1 || l2 || l3) {
3722  Int_t i = gPad->NextPaletteColor();
3723  if (l1) {strncpy(l1," ",3); fH->SetFillColor(i);}
3724  if (l2) {strncpy(l2," ",3); fH->SetLineColor(i);}
3725  if (l3) {strncpy(l3," ",3); fH->SetMarkerColor(i);}
3726  }
3727 
3728  l = strstr(chopt,"SPEC");
3729  if (l) {
3730  Hoption.Scat = 0;
3731  strncpy(l," ",4);
3732  Int_t bs=0;
3733  l = strstr(chopt,"BF(");
3734  if (l) {
3735  if (sscanf(&l[3],"%d",&bs) > 0) {
3736  Int_t i=0;
3737  while (l[i]!=')') {
3738  l[i] = ' ';
3739  i++;
3740  }
3741  l[i] = ' ';
3742  }
3743  }
3744  Hoption.Spec = TMath::Max(1600,bs);
3745  return 1;
3746  }
3747 
3748  l = strstr(chopt,"GL");
3749  if (l) {
3750  strncpy(l," ",2);
3751  }
3752  l = strstr(chopt,"X+");
3753  if (l) {
3754  Hoption.AxisPos = 10;
3755  strncpy(l," ",2);
3756  }
3757  l = strstr(chopt,"Y+");
3758  if (l) {
3759  Hoption.AxisPos += 1;
3760  strncpy(l," ",2);
3761  }
3762  if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
3763  if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
3764 
3765  l = strstr(chopt,"SAMES");
3766  if (l) {
3767  if (nch == 5) Hoption.Hist = 1;
3768  Hoption.Same = 2;
3769  strncpy(l," ",5);
3770  }
3771  l = strstr(chopt,"SAME");
3772  if (l) {
3773  if (nch == 4) Hoption.Hist = 1;
3774  Hoption.Same = 1;
3775  strncpy(l," ",4);
3776  }
3777 
3778  l = strstr(chopt,"PIE");
3779  if (l) {
3780  Hoption.Pie = 1;
3781  strncpy(l," ",3);
3782  }
3783 
3784 
3785  l = strstr(chopt,"CANDLE");
3786  if (l) {
3787  TCandle candle;
3788  Hoption.Candle = candle.ParseOption(l);
3789  Hoption.Scat = 0;
3790  }
3791 
3792  l = strstr(chopt,"VIOLIN");
3793  if (l) {
3794  TCandle candle;
3795  Hoption.Candle = candle.ParseOption(l);
3796  Hoption.Scat = 0;
3797  }
3798 
3799  l = strstr(chopt,"LEGO");
3800  if (l) {
3801  Hoption.Scat = 0;
3802  Hoption.Lego = 1; strncpy(l," ",4);
3803  if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
3804  if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
3805  if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
3806  if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
3807  if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
3808  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3809  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3810  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3811  }
3812 
3813  l = strstr(chopt,"SURF");
3814  if (l) {
3815  Hoption.Scat = 0;
3816  Hoption.Surf = 1; strncpy(l," ",4);
3817  if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
3818  if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
3819  if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
3820  if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
3821  if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
3822  if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
3823  if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
3824  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3825  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3826  }
3827 
3828  l = strstr(chopt,"TF3");
3829  if (l) {
3830  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3831  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3832  }
3833 
3834  l = strstr(chopt,"ISO");
3835  if (l) {
3836  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3837  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3838  }
3839 
3840  l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; strncpy(l," ",4);}
3841 
3842  l = strstr(chopt,"CONT");
3843  if (l) {
3844  strncpy(l," ",4);
3845  if (hdim>1) {
3846  Hoption.Scat = 0;
3847  Hoption.Contour = 1;
3848  if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
3849  if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
3850  if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
3851  if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
3852  if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
3853  } else {
3854  Hoption.Hist = 1;
3855  }
3856  }
3857  l = strstr(chopt,"HBAR");
3858  if (l) {
3859  Hoption.Hist = 0;
3860  Hoption.Bar = 20; strncpy(l," ",4);
3861  if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
3862  if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
3863  if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
3864  if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
3865  }
3866  l = strstr(chopt,"BAR");
3867  if (l) {
3868  Hoption.Hist = 0;
3869  Hoption.Bar = 10; strncpy(l," ",3);
3870  if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
3871  if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
3872  if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
3873  if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
3874  }
3875 
3876  l = strstr(chopt,"ARR" );
3877  if (l) {
3878  strncpy(l," ", 3);
3879  if (hdim>1) {
3880  Hoption.Arrow = 1;
3881  Hoption.Scat = 0;
3882  } else {
3883  Hoption.Hist = 1;
3884  }
3885  }
3886  l = strstr(chopt,"BOX" );
3887  if (l) {
3888  strncpy(l," ", 3);
3889  if (hdim>1) {
3890  Hoption.Scat = 0;
3891  Hoption.Box = 1;
3892  if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
3893  if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
3894  if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
3895  } else {
3896  Hoption.Hist = 1;
3897  }
3898  }
3899  l = strstr(chopt,"COLZ");
3900  if (l) {
3901  strncpy(l," ",4);
3902  if (hdim>1) {
3903  Hoption.Color = 1;
3904  Hoption.Scat = 0;
3905  Hoption.Zscale = 1;
3906  if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
3907  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3908  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3909  } else {
3910  Hoption.Hist = 1;
3911  }
3912  }
3913  l = strstr(chopt,"COL" );
3914  if (l) {
3915  strncpy(l," ", 3);
3916  if (hdim>1) {
3917  Hoption.Color = 1;
3918  Hoption.Scat = 0;
3919  if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
3920  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3921  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3922  } else {
3923  Hoption.Hist = 1;
3924  }
3925  }
3926  l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; strncpy(l," ",4); Hoption.Scat = 0; }
3927  l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; strncpy(l," ",4); Hoption.Hist = 0; }
3928  l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; strncpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
3929  l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; strncpy(l," ",4); }
3930  l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; strncpy(l," ",4); }
3931  l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; strncpy(l," ",4); }
3932  l = strstr(chopt,"TEXT");
3933  if (l) {
3934  Int_t angle;
3935  if (sscanf(&l[4],"%d",&angle) > 0) {
3936  if (angle < 0) angle=0;
3937  if (angle > 90) angle=90;
3938  Hoption.Text = 1000+angle;
3939  } else {
3940  Hoption.Text = 1;
3941  }
3942  strncpy(l," ", 4);
3943  l = strstr(chopt,"N");
3944  if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
3945  Hoption.Scat = 0;
3946  }
3947  l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; strncpy(l," ",3); }
3948  l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; strncpy(l," ",3); }
3949  l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; strncpy(l," ",3); }
3950  l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; strncpy(l," ",3); }
3951 
3952  l = strstr(chopt,"TRI");
3953  if (l) {
3954  Hoption.Scat = 0;
3955  Hoption.Color = 0;
3956  Hoption.Tri = 1; strncpy(l," ",3);
3957  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3958  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3959  l = strstr(chopt,"ERR"); if (l) strncpy(l," ",3);
3960  }
3961 
3962  l = strstr(chopt,"AITOFF");
3963  if (l) {
3964  Hoption.Proj = 1; strncpy(l," ",6); //Aitoff projection
3965  }
3966  l = strstr(chopt,"MERCATOR");
3967  if (l) {
3968  Hoption.Proj = 2; strncpy(l," ",8); //Mercator projection
3969  }
3970  l = strstr(chopt,"SINUSOIDAL");
3971  if (l) {
3972  Hoption.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
3973  }
3974  l = strstr(chopt,"PARABOLIC");
3975  if (l) {
3976  Hoption.Proj = 4; strncpy(l," ",9); //Parabolic projection
3977  }
3978  if (Hoption.Proj > 0) {
3979  Hoption.Scat = 0;
3980  Hoption.Contour = 14;
3981  }
3982 
3983  if (strstr(chopt,"A")) Hoption.Axis = -1;
3984  if (strstr(chopt,"B")) Hoption.Bar = 1;
3985  if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
3986  if (strstr(chopt,"F")) Hoption.Fill =1;
3987  if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
3988  if (strstr(chopt,"F2")) Hoption.Fill =2;
3989  if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
3990  if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
3991  if (strstr(chopt,"Z")) Hoption.Zscale =1;
3992  if (strstr(chopt,"*")) Hoption.Star =1;
3993  if (strstr(chopt,"H")) Hoption.Hist =2;
3994  if (strstr(chopt,"P0")) Hoption.Mark =10;
3995 
3996  if (fH->InheritsFrom(TH2Poly::Class())) {
3997  if (Hoption.Fill+Hoption.Line+Hoption.Mark != 0 ) Hoption.Scat = 0;
3998  }
3999 
4000  if (strstr(chopt,"E")) {
4001  if (hdim == 1) {
4002  Hoption.Error = 1;
4003  if (strstr(chopt,"E0")) Hoption.Error = 10;
4004  if (strstr(chopt,"E1")) Hoption.Error = 11;
4005  if (strstr(chopt,"E2")) Hoption.Error = 12;
4006  if (strstr(chopt,"E3")) Hoption.Error = 13;
4007  if (strstr(chopt,"E4")) Hoption.Error = 14;
4008  if (strstr(chopt,"E5")) Hoption.Error = 15;
4009  if (strstr(chopt,"E6")) Hoption.Error = 16;
4010  if (strstr(chopt,"X0")) {
4011  if (Hoption.Error == 1) Hoption.Error += 20;
4012  Hoption.Error += 10;
4013  }
4014  if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
4015  Hoption.Text += 2000;
4016  Hoption.Error = 0;
4017  }
4018  } else {
4019  if (Hoption.Error == 0) {
4020  Hoption.Error = 100;
4021  Hoption.Scat = 0;
4022  }
4023  if (Hoption.Text) {
4024  Hoption.Text += 2000;
4025  Hoption.Error = 0;
4026  }
4027  }
4028  }
4029 
4030  if (Hoption.Surf == 15) {
4031  if (Hoption.System == kPOLAR || Hoption.System == kCARTESIAN) {
4032  Hoption.Surf = 13;
4033  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4034  }
4035  }
4036 
4037  // Copy options from current style
4038  Hoption.Logx = gPad->GetLogx();
4039  Hoption.Logy = gPad->GetLogy();
4040  Hoption.Logz = gPad->GetLogz();
4041 
4042  // Check options incompatibilities
4043  if (Hoption.Bar == 1) Hoption.Hist = -1;
4044  return 1;
4045 }
4046 
4047 ////////////////////////////////////////////////////////////////////////////////
4048 /// Decode string `choptin` and fill Graphical cuts structure.
4049 
4051 {
4052 
4053  fNcuts = 0;
4054  char *left = (char*)strchr(choptin,'[');
4055  if (!left) return 0;
4056  char *right = (char*)strchr(choptin,']');
4057  if (!right) return 0;
4058  Int_t nch = right-left;
4059  if (nch < 2) return 0;
4060  char *cuts = left+1;
4061  *right = 0;
4062  char *comma, *minus;
4063  Int_t i;
4064  while (1) {
4065  comma = strchr(cuts,',');
4066  if (comma) *comma = 0;
4067  minus = strchr(cuts,'-');
4068  if (minus) cuts = minus+1;
4069  while (*cuts == ' ') cuts++;
4070  Int_t nc = strlen(cuts);
4071  while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4072  TIter next(gROOT->GetListOfSpecials());
4073  TCutG *cut=0;
4074  TObject *obj;
4075  while ((obj = next())) {
4076  if (!obj->InheritsFrom(TCutG::Class())) continue;
4077  if (strcmp(obj->GetName(),cuts)) continue;
4078  cut = (TCutG*)obj;
4079  break;
4080  }
4081  if (cut) {
4082  fCuts[fNcuts] = cut;
4083  fCutsOpt[fNcuts] = 1;
4084  if (minus) fCutsOpt[fNcuts] = -1;
4085  fNcuts++;
4086  }
4087  if (!comma) break;
4088  cuts = comma+1;
4089  }
4090  for (i=0;i<=nch;i++) left[i] = ' ';
4091  return fNcuts;
4092 }
4093 
4094 ////////////////////////////////////////////////////////////////////////////////
4095 /// [Control routine to paint any kind of histograms](#HP00)
4096 
4098 {
4099 
4100  if (fH->GetBuffer()) fH->BufferEmpty(-1);
4101 
4102  //For iOS: put the histogram on the top of stack of pickable objects.
4103  const TPickerStackGuard topPush(fH);
4104 
4105  gPad->SetVertical(kTRUE);
4106 
4107  TH1 *oldhist = gCurrentHist;
4108  gCurrentHist = fH;
4109  TH1 *hsave = fH;
4110  Double_t minsav = fH->GetMinimumStored();
4111 
4112  if (!MakeChopt(option)) return; //check options and fill Hoption structure
4113 
4114  // Paint using TSpectrum2Painter
4115  if (Hoption.Spec) {
4116  if (!TableInit()) return;
4117  if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4118  gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4119  (ULong_t)fH, option, Hoption.Spec));
4120  return;
4121  }
4122 
4123  if (Hoption.Pie) {
4124  if (fH->GetDimension() == 1) {
4125  if (!fPie) fPie = new TPie(fH);
4126  fPie->Paint(option);
4127  } else {
4128  Error("Paint", "Option PIE is for 1D histograms only");
4129  }
4130  return;
4131  } else {
4132  if (fPie) delete fPie;
4133  fPie = 0;
4134  }
4135 
4136  fXbuf = new Double_t[kNMAX];
4137  fYbuf = new Double_t[kNMAX];
4138  if (fH->GetDimension() > 2) {
4139  PaintH3(option);
4140  fH->SetMinimum(minsav);
4141  if (Hoption.Func) {
4142  Hoption_t hoptsave = Hoption;
4143  Hparam_t hparsave = Hparam;
4144  PaintFunction(option);
4145  SetHistogram(hsave);
4146  Hoption = hoptsave;
4147  Hparam = hparsave;
4148  }
4149  gCurrentHist = oldhist;
4150  delete [] fXbuf; delete [] fYbuf;
4151  return;
4152  }
4153  TView *view = gPad->GetView();
4154  if (view) {
4155  if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4156  delete view;
4157  gPad->SetView(0);
4158  }
4159  }
4160  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4161  // In case of 1D histogram, Z axis becomes Y axis.
4162  Int_t logysav=0, logzsav=0;
4163  if (fH->GetDimension() == 1) {
4164  logysav = Hoption.Logy;
4165  logzsav = Hoption.Logz;
4166  Hoption.Logz = 0;
4167  if (Hoption.Logy) {
4168  Hoption.Logz = 1;
4169  Hoption.Logy = 0;
4170  }
4171  }
4172  PaintTable(option);
4173  if (Hoption.Func) {
4174  Hoption_t hoptsave = Hoption;
4175  Hparam_t hparsave = Hparam;
4176  PaintFunction(option);
4177  SetHistogram(hsave);
4178  Hoption = hoptsave;
4179  Hparam = hparsave;
4180  }
4181  fH->SetMinimum(minsav);
4182  gCurrentHist = oldhist;
4183  delete [] fXbuf; delete [] fYbuf;
4184  if (fH->GetDimension() == 1) {
4185  Hoption.Logy = logysav;
4186  Hoption.Logz = logzsav;
4187  }
4188  return;
4189  }
4190 
4191  if (Hoption.Bar >= 20) {
4192  PaintBarH(option);
4193  delete [] fXbuf; delete [] fYbuf;
4194  return;
4195  }
4196 
4197  // fill Hparam structure with histo parameters
4198  if (!PaintInit()) {
4199  delete [] fXbuf; delete [] fYbuf;
4200  return;
4201  }
4202 
4203  // Picture surround (if new page) and page number (if requested).
4204  // Histogram surround (if not option "Same").
4205  PaintFrame();
4206 
4207  // Paint histogram axis only
4208  Bool_t gridx = gPad->GetGridx();
4209  Bool_t gridy = gPad->GetGridy();
4210  if (Hoption.Axis > 0) {
4211  if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4212  else {
4213  if (gridx) gPad->SetGridx(0);
4214  if (gridy) gPad->SetGridy(0);
4215  PaintAxis(kFALSE);
4216  if (gridx) gPad->SetGridx(1);
4217  if (gridy) gPad->SetGridy(1);
4218  }
4219  if (Hoption.Same ==1) Hoption.Same = 2;
4220  goto paintstat;
4221  }
4222  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4223 
4224  // test for options BAR or HBAR
4225  if (Hoption.Bar >= 10) {
4226  PaintBar(option);
4227  }
4228 
4229  // do not draw histogram if error bars required
4230  if (!Hoption.Error) {
4231  if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4232  }
4233 
4234  // test for error bars or option E
4235  if (Hoption.Error) {
4236  PaintErrors(option);
4237  if (Hoption.Hist == 2) PaintHist(option);
4238  }
4239 
4240  if (Hoption.Text) PaintText(option);
4241 
4242  // test for associated function
4243  if (Hoption.Func) {
4244  Hoption_t hoptsave = Hoption;
4245  Hparam_t hparsave = Hparam;
4246  PaintFunction(option);
4247  SetHistogram(hsave);
4248  Hoption = hoptsave;
4249  Hparam = hparsave;
4250  }
4251 
4252  if (gridx) gPad->SetGridx(0);
4253  if (gridy) gPad->SetGridy(0);
4254  PaintAxis(kFALSE);
4255  if (gridx) gPad->SetGridx(1);
4256  if (gridy) gPad->SetGridy(1);
4257 
4258  PaintTitle(); // Draw histogram title
4259 
4260  // Draw box with histogram statistics and/or fit parameters
4261 paintstat:
4262  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4263  TIter next(fFunctions);
4264  TObject *obj = 0;
4265  while ((obj = next())) {
4266  if (obj->InheritsFrom(TF1::Class())) break;
4267  obj = 0;
4268  }
4269 
4270  //Stat is painted twice (first, it will be in canvas' list of primitives),
4271  //second, it will be here, this is not required on iOS.
4272  //Condition is ALWAYS true on a platform different from iOS.
4273  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4274  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4275  }
4276  fH->SetMinimum(minsav);
4277  gCurrentHist = oldhist;
4278  delete [] fXbuf; fXbuf = 0;
4279  delete [] fYbuf; fYbuf = 0;
4280 
4281 }
4282 
4283 ////////////////////////////////////////////////////////////////////////////////
4284 /// [Control function to draw a table as an arrow plot](#HP12)
4285 
4287 {
4288  fH->TAttLine::Modify();
4289 
4290  Double_t xk, xstep, yk, ystep;
4291  Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
4292  Int_t ncx = Hparam.xlast - Hparam.xfirst + 1;
4293  Int_t ncy = Hparam.ylast - Hparam.yfirst + 1;
4294  Double_t xrg = gPad->GetUxmin();
4295  Double_t yrg = gPad->GetUymin();
4296  Double_t xln = gPad->GetUxmax() - xrg;
4297  Double_t yln = gPad->GetUymax() - yrg;
4298  Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4299  Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4300  Double_t dn = 1.E-30;
4301 
4302  for (Int_t id=1;id<=2;id++) {
4303  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4304  yk = fYaxis->GetBinLowEdge(j);
4305  ystep = fYaxis->GetBinWidth(j);
4306  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4307  xk = fXaxis->GetBinLowEdge(i);
4308  xstep = fXaxis->GetBinWidth(i);
4309  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4310  if (i == Hparam.xfirst) {
4311  dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4312  } else if (i == Hparam.xlast) {
4313  dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4314  } else {
4315  dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4316  }
4317  if (j == Hparam.yfirst) {
4318  dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4319  } else if (j == Hparam.ylast) {
4320  dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4321  } else {
4322  dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4323  }
4324  if (id == 1) {
4325  dn = TMath::Max(dn, TMath::Abs(dx));
4326  dn = TMath::Max(dn, TMath::Abs(dy));
4327  } else if (id == 2) {
4328  xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4329  dxn = cx*dx/dn;
4330  x1 = xc - dxn;
4331  x2 = xc + dxn;
4332  yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4333  dyn = cy*dy/dn;
4334  y1 = yc - dyn;
4335  y2 = yc + dyn;
4336  fXbuf[0] = x1;
4337  fXbuf[1] = x2;
4338  fYbuf[0] = y1;
4339  fYbuf[1] = y2;
4340  if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
4341  anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
4342  si = anr*(dxn + dyn);
4343  co = anr*(dxn - dyn);
4344  fXbuf[2] = x2 - si;
4345  fYbuf[2] = y2 + co;
4346  gPad->PaintPolyLine(3, fXbuf, fYbuf);
4347  fXbuf[0] = x2;
4348  fXbuf[1] = x2 - co;
4349  fYbuf[0] = y2;
4350  fYbuf[1] = y2 - si;
4351  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4352  }
4353  else {
4354  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4355  }
4356  }
4357  }
4358  }
4359  }
4360 
4361  if (Hoption.Zscale) PaintPalette();
4362 }
4363 
4364 ////////////////////////////////////////////////////////////////////////////////
4365 /// Draw axis (2D case) of an histogram.
4366 ///
4367 /// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4368 /// to draw the grid and the axis separately. In `THistPainter::Paint` this
4369 /// feature is used to make sure that the grid is drawn in the background and
4370 /// the axis tick marks in the foreground of the pad.
4371 
4373 {
4374 
4375  //On iOS, grid should not be pickable and can not be highlighted.
4376  //Condition is never true on a platform different from iOS.
4377  if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4378  return;
4379 
4380  if (Hoption.Axis == -1) return;
4381  if (Hoption.Same && Hoption.Axis <= 0) return;
4382 
4383  // Repainting alphanumeric labels axis on a plot done with
4384  // the option HBAR (horizontal) needs some adjustments.
4385  TAxis *xaxis = 0;
4386  TAxis *yaxis = 0;
4387  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4388  if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4389  TIter next(gPad->GetListOfPrimitives());
4390  TObject *obj;
4391  // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4392  while ((obj = next())) {
4393  if (!obj->InheritsFrom(TH1::Class()) &&
4394  !obj->InheritsFrom(THStack::Class())) continue;
4395  TString opt = obj->GetDrawOption();
4396  opt.ToLower();
4397  // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4398  if (strstr(opt,"hbar")) {
4399  gPad->SetVertical(kFALSE);
4400  xaxis = fXaxis;
4401  yaxis = fYaxis;
4402  if (!strcmp(xaxis->GetName(),"xaxis")) {
4403  fXaxis = yaxis;
4404  fYaxis = xaxis;
4405  }
4406  }
4407  break;
4408  }
4409  }
4410  }
4411 
4412  static char chopt[10] = "";
4413  Double_t gridl = 0;
4414  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4415  Int_t useHparam = 0;
4416  Double_t umin, umax, uminsave, umaxsave;
4417  Short_t xAxisPos = Hoption.AxisPos/10;
4418  Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4419 
4420  Double_t axmin = gPad->GetUxmin();
4421  Double_t axmax = gPad->GetUxmax();
4422  Double_t aymin = gPad->GetUymin();
4423  Double_t aymax = gPad->GetUymax();
4424  char *cw = 0;
4425  TGaxis axis;
4426 
4427  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4428  // Hparam must be use for the axis limits.
4429  if (Hoption.Contour == 14) useHparam = 1;
4430  if (Hoption.Same) {
4431  TObject *obj;
4432  TIter next(gPad->GetListOfPrimitives());
4433  while ((obj=next())) {
4434  if (strstr(obj->GetDrawOption(),"cont4")) {
4435  useHparam = 1;
4436  break;
4437  }
4438  }
4439  }
4440 
4441  // Paint X axis
4442 
4443  //To make X-axis selectable on iOS device.
4444  if (gPad->PadInSelectionMode())
4445  gPad->PushSelectableObject(fXaxis);
4446 
4447  //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4448  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4449  ndivx = fXaxis->GetNdivisions();
4450  if (ndivx > 1000) {
4451  nx2 = ndivx/100;
4452  nx1 = TMath::Max(1, ndivx%100);
4453  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4454  }
4455  axis.SetTextAngle(0);
4457 
4458  chopt[0] = 0;
4459  strlcat(chopt, "SDH",10);
4460  if (ndivx < 0) strlcat(chopt, "N",10);
4461  if (gPad->GetGridx()) {
4462  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4463  strlcat(chopt, "W",10);
4464  }
4465 
4466  // Define X-Axis limits
4467  if (Hoption.Logx) {
4468  strlcat(chopt, "G",10);
4469  ndiv = TMath::Abs(ndivx);
4470  if (useHparam) {
4471  umin = TMath::Power(10,Hparam.xmin);
4472  umax = TMath::Power(10,Hparam.xmax);
4473  } else {
4474  umin = TMath::Power(10,axmin);
4475  umax = TMath::Power(10,axmax);
4476  }
4477  } else {
4478  ndiv = TMath::Abs(ndivx);
4479  if (useHparam) {
4480  umin = Hparam.xmin;
4481  umax = Hparam.xmax;
4482  } else {
4483  umin = axmin;
4484  umax = axmax;
4485  }
4486  }
4487 
4488  // Display axis as time
4489  if (fXaxis->GetTimeDisplay()) {
4490  strlcat(chopt,"t",10);
4491  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4492  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam.xmax-Hparam.xmin));
4493  }
4494  }
4495 
4496  // The main X axis can be on the bottom or on the top of the pad
4497  Double_t xAxisYPos1, xAxisYPos2;
4498  if (xAxisPos == 1) {
4499  // Main X axis top
4500  xAxisYPos1 = aymax;
4501  xAxisYPos2 = aymin;
4502  } else {
4503  // Main X axis bottom
4504  xAxisYPos1 = aymin;
4505  xAxisYPos2 = aymax;
4506  }
4507 
4508  // Paint the main X axis (always)
4509  uminsave = umin;
4510  umaxsave = umax;
4511  ndivsave = ndiv;
4512  axis.SetOption(chopt);
4513  if (xAxisPos) {
4514  strlcat(chopt, "-",10);
4515  gridl = -gridl;
4516  }
4517  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4518  axis.SetLabelSize(0.);
4519  axis.SetTitle("");
4520  }
4521  axis.PaintAxis(axmin, xAxisYPos1,
4522  axmax, xAxisYPos1,
4523  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4524 
4525  // Paint additional X axis (if needed)
4526  // On iOS, this additional X axis is neither pickable, nor highlighted.
4527  // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4528  if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4529  if (xAxisPos) {
4530  cw=strstr(chopt,"-");
4531  *cw='z';
4532  } else {
4533  strlcat(chopt, "-",10);
4534  }
4535  if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4536  if ((cw=strstr(chopt,"W"))) *cw='z';
4537  axis.SetTitle("");
4538  axis.PaintAxis(axmin, xAxisYPos2,
4539  axmax, xAxisYPos2,
4540  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4541  }
4542  }//End of "if pad in selection mode etc".
4543 
4544  // Paint Y axis
4545  //On iOS, Y axis must pushed into the stack of selectable objects.
4546  if (gPad->PadInSelectionMode())
4547  gPad->PushSelectableObject(fYaxis);
4548 
4549  //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4550  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4551  ndivy = fYaxis->GetNdivisions();
4553 
4554  chopt[0] = 0;
4555  strlcat(chopt, "SDH",10);
4556  if (ndivy < 0) strlcat(chopt, "N",10);
4557  if (gPad->GetGridy()) {
4558  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4559  strlcat(chopt, "W",10);
4560  }
4561 
4562  // Define Y-Axis limits
4563  if (Hoption.Logy) {
4564  strlcat(chopt, "G",10);
4565  ndiv = TMath::Abs(ndivy);
4566  if (useHparam) {
4567  umin = TMath::Power(10,Hparam.ymin);
4568  umax = TMath::Power(10,Hparam.ymax);
4569  } else {
4570  umin = TMath::Power(10,aymin);
4571  umax = TMath::Power(10,aymax);
4572  }
4573  } else {
4574  ndiv = TMath::Abs(ndivy);
4575  if (useHparam) {
4576  umin = Hparam.ymin;
4577  umax = Hparam.ymax;
4578  } else {
4579  umin = aymin;
4580  umax = aymax;
4581  }
4582  }
4583 
4584  // Display axis as time
4585  if (fYaxis->GetTimeDisplay()) {
4586  strlcat(chopt,"t",10);
4587  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4588  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam.ymax-Hparam.ymin));
4589  }
4590  }
4591 
4592  // The main Y axis can be on the left or on the right of the pad
4593  Double_t yAxisXPos1, yAxisXPos2;
4594  if (yAxisPos == 1) {
4595  // Main Y axis left
4596  yAxisXPos1 = axmax;
4597  yAxisXPos2 = axmin;
4598  } else {
4599  // Main Y axis right
4600  yAxisXPos1 = axmin;
4601  yAxisXPos2 = axmax;
4602  }
4603 
4604  // Paint the main Y axis (always)
4605  uminsave = umin;
4606  umaxsave = umax;
4607  ndivsave = ndiv;
4608  axis.SetOption(chopt);
4609  if (yAxisPos) {
4610  strlcat(chopt, "+L",10);
4611  gridl = -gridl;
4612  }
4613  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4614  axis.SetLabelSize(0.);
4615  axis.SetTitle("");
4616  }
4617  axis.PaintAxis(yAxisXPos1, aymin,
4618  yAxisXPos1, aymax,
4619  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4620 
4621  // Paint the additional Y axis (if needed)
4622  // Additional checks for pad mode are required on iOS: this "second" axis is
4623  // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4624  if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4625  if (gPad->GetTicky() < 2) {
4626  strlcat(chopt, "U",10);
4627  axis.SetTickSize(-fYaxis->GetTickLength());
4628  } else {
4629  strlcat(chopt, "+L",10);
4630  }
4631  if ((cw=strstr(chopt,"W"))) *cw='z';
4632  axis.SetTitle("");
4633  axis.PaintAxis(yAxisXPos2, aymin,
4634  yAxisXPos2, aymax,
4635  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4636  }
4637  }//End of "if pad is in selection mode etc."
4638 
4639  // Reset the axis if they have been inverted in case of option HBAR
4640  if (xaxis) {
4641  fXaxis = xaxis;
4642  fYaxis = yaxis;
4643  }
4644 }
4645 
4646 ////////////////////////////////////////////////////////////////////////////////
4647 /// [Draw a bar-chart in a normal pad.](#HP10)
4648 
4650 {
4651 
4652  Int_t bar = Hoption.Bar - 10;
4653  Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4654  Double_t offset = fH->GetBarOffset();
4656  TBox box;
4657  Int_t hcolor = fH->GetFillColor();
4658  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4659  Int_t hstyle = fH->GetFillStyle();
4660  box.SetFillColor(hcolor);
4661  box.SetFillStyle(hstyle);
4662  for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4663  y = fH->GetBinContent(bin);
4664  xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4665  xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4666  ymin = gPad->GetUymin();
4667  ymax = gPad->YtoPad(y);
4668  if (ymax < gPad->GetUymin()) continue;
4669  if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4670  if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4671  if (gStyle->GetHistMinimumZero() && ymin < 0)
4672  ymin=TMath::Min(0.,gPad->GetUymax());
4673  w = (xmax-xmin)*width;
4674  xmin += offset*(xmax-xmin);
4675  xmax = xmin + w;
4676  if (bar < 1) {
4677  box.PaintBox(xmin,ymin,xmax,ymax);
4678  } else {
4679  umin = xmin + bar*(xmax-xmin)/10.;
4680  umax = xmax - bar*(xmax-xmin)/10.;
4681  //box.SetFillColor(hcolor+150); //bright
4682  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4683  box.PaintBox(xmin,ymin,umin,ymax);
4684  box.SetFillColor(hcolor);
4685  box.PaintBox(umin,ymin,umax,ymax);
4686  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4687  box.PaintBox(umax,ymin,xmax,ymax);
4688  }
4689  }
4690 }
4691 
4692 ////////////////////////////////////////////////////////////////////////////////
4693 /// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4694 
4696 {
4697 
4698  gPad->SetVertical(kFALSE);
4699 
4700  PaintInitH();
4701 
4702  TAxis *xaxis = fXaxis;
4703  TAxis *yaxis = fYaxis;
4704  if (!strcmp(xaxis->GetName(),"xaxis")) {
4705  fXaxis = yaxis;
4706  fYaxis = xaxis;
4707  }
4708 
4709  PaintFrame();
4710  PaintAxis(kFALSE);
4711 
4712  Int_t bar = Hoption.Bar - 20;
4713  Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4714  Double_t offset = fH->GetBarOffset();
4716  TBox box;
4717  Int_t hcolor = fH->GetFillColor();
4718  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4719  Int_t hstyle = fH->GetFillStyle();
4720  box.SetFillColor(hcolor);
4721  box.SetFillStyle(hstyle);
4722  for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4723  ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4724  ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4725  xmin = gPad->GetUxmin();
4726  xmax = gPad->XtoPad(fH->GetBinContent(bin));
4727  if (xmax < gPad->GetUxmin()) continue;
4728  if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4729  if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4730  if (gStyle->GetHistMinimumZero() && xmin < 0)
4731  xmin=TMath::Min(0.,gPad->GetUxmax());
4732  w = (ymax-ymin)*width;
4733  ymin += offset*(ymax-ymin);
4734  ymax = ymin + w;
4735  if (bar < 1) {
4736  box.PaintBox(xmin,ymin,xmax,ymax);
4737  } else {
4738  umin = ymin + bar*(ymax-ymin)/10.;
4739  umax = ymax - bar*(ymax-ymin)/10.;
4740  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4741  box.PaintBox(xmin,ymin,xmax,umin);
4742  box.SetFillColor(hcolor);
4743  box.PaintBox(xmin,umin,xmax,umax);
4744  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4745  box.PaintBox(xmin,umax,xmax,ymax);
4746  }
4747  }
4748 
4749  PaintTitle();
4750 
4751  // Draw box with histogram statistics and/or fit parameters
4752  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4753  TIter next(fFunctions);
4754  TObject *obj = 0;
4755  while ((obj = next())) {
4756  if (obj->InheritsFrom(TF1::Class())) break;
4757  obj = 0;
4758  }
4759  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4760  }
4761 
4762  fXaxis = xaxis;
4763  fYaxis = yaxis;
4764 }
4765 
4766 ////////////////////////////////////////////////////////////////////////////////
4767 /// [Control function to draw a 2D histogram as a box plot](#HP13)
4768 
4770 {
4771 
4772  Style_t fillsav = fH->GetFillStyle();
4773  Style_t colsav = fH->GetFillColor();
4774  if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
4775  if (Hoption.Box == 11) fH->SetFillStyle(1001);
4776  fH->TAttLine::Modify();
4777  fH->TAttFill::Modify();
4778 
4779  Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
4780  Double_t ux1 = gPad->PixeltoX(1);
4781  Double_t ux0 = gPad->PixeltoX(0);
4782  Double_t uy1 = gPad->PixeltoY(1);
4783  Double_t uy0 = gPad->PixeltoY(0);
4784  Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
4785  Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
4786 
4787  Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
4789  TMath::Abs(fH->GetMinimum()));
4790  Double_t zminlin = zmin, zmaxlin = zmax;
4791 
4792  // In case of option SAME, zmin and zmax values are taken from the
4793  // first plotted 2D histogram.
4794  if (Hoption.Same) {
4795  TH2 *h2;
4796  TIter next(gPad->GetListOfPrimitives());
4797  while ((h2 = (TH2 *)next())) {
4798  if (!h2->InheritsFrom(TH2::Class())) continue;
4799  zmin = TMath::Max(h2->GetMinimum(), 0.);
4800  zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
4801  TMath::Abs(h2->GetMinimum()));
4802  zminlin = zmin;
4803  zmaxlin = zmax;
4804  if (Hoption.Logz) {
4805  if (zmin <= 0) {
4806  zmin = TMath::Log10(zmax*0.001);
4807  } else {
4808  zmin = TMath::Log10(zmin);
4809  }
4810  zmax = TMath::Log10(zmax);
4811  }
4812  break;
4813  }
4814  } else {
4815  if (Hoption.Logz) {
4816  if (zmin > 0) {
4817  zmin = TMath::Log10(zmin);
4818  zmax = TMath::Log10(zmax);
4819  } else {
4820  return;
4821  }
4822  }
4823  }
4824 
4825  Double_t zratio, dz = zmax - zmin;
4826  Bool_t kZminNeg = kFALSE;
4827  if (fH->GetMinimum()<0) kZminNeg = kTRUE;
4828  Bool_t kZNeg = kFALSE;
4829 
4830  // Define the dark and light colors the "button style" boxes.
4831  Color_t color = fH->GetFillColor();
4832  Color_t light=0, dark=0;
4833  if (Hoption.Box == 11) {
4834  light = TColor::GetColorBright(color);
4835  dark = TColor::GetColorDark(color);
4836  }
4837 
4838  // Loop over all the bins and draw the boxes
4839  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4840  yk = fYaxis->GetBinLowEdge(j);
4841  ystep = fYaxis->GetBinWidth(j);
4842  ycent = 0.5*ystep;
4843  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4844  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4845  xk = fXaxis->GetBinLowEdge(i);
4846  xstep = fXaxis->GetBinWidth(i);
4847  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4848  xcent = 0.5*xstep;
4849  z = Hparam.factor*fH->GetBinContent(bin);
4850  kZNeg = kFALSE;
4851 
4852  if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
4853  if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
4854  if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
4855 
4856  if (z < 0) {
4857  if (Hoption.Logz) continue;
4858  z = -z;
4859  kZNeg = kTRUE;
4860  }
4861  if (Hoption.Logz) {
4862  if (z != 0) z = TMath::Log10(z);
4863  else z = zmin;
4864  }
4865 
4866  if (dz == 0) continue;
4867  zratio = TMath::Sqrt((z-zmin)/dz);
4868  if (zratio == 0) continue;
4869 
4870  xup = xcent*zratio + xk + xcent;
4871  xlow = 2*(xk + xcent) - xup;
4872  if (xup-xlow < dxmin) xup = xlow+dxmin;
4873  if (Hoption.Logx) {
4874  if (xup > 0) xup = TMath::Log10(xup);
4875  else continue;
4876  if (xlow > 0) xlow = TMath::Log10(xlow);
4877  else continue;
4878  }
4879 
4880  yup = ycent*zratio + yk + ycent;
4881  ylow = 2*(yk + ycent) - yup;
4882  if (yup-ylow < dymin) yup = ylow+dymin;
4883  if (Hoption.Logy) {
4884  if (yup > 0) yup = TMath::Log10(yup);
4885  else continue;
4886  if (ylow > 0) ylow = TMath::Log10(ylow);
4887  else continue;
4888  }
4889 
4890  xlow = TMath::Max(xlow, gPad->GetUxmin());
4891  ylow = TMath::Max(ylow, gPad->GetUymin());
4892  xup = TMath::Min(xup , gPad->GetUxmax());
4893  yup = TMath::Min(yup , gPad->GetUymax());
4894 
4895  if (xlow >= xup) continue;
4896  if (ylow >= yup) continue;
4897 
4898  if (Hoption.Box == 1) {
4899  fH->SetFillColor(color);
4900  fH->TAttFill::Modify();
4901  gPad->PaintBox(xlow, ylow, xup, yup);
4902  if (kZNeg) {
4903  gPad->PaintLine(xlow, ylow, xup, yup);
4904  gPad->PaintLine(xlow, yup, xup, ylow);
4905  }
4906  } else if (Hoption.Box == 11) {
4907  // Draw the center of the box
4908  fH->SetFillColor(color);
4909  fH->TAttFill::Modify();
4910  gPad->PaintBox(xlow, ylow, xup, yup);
4911 
4912  // Draw top&left part of the box
4913  Double_t x[7], y[7];
4914  Double_t bwidth = 0.1;
4915  x[0] = xlow; y[0] = ylow;
4916  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4917  x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
4918  x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
4919  x[4] = xup; y[4] = yup;
4920  x[5] = xlow; y[5] = yup;
4921  x[6] = xlow; y[6] = ylow;
4922  if (kZNeg) fH->SetFillColor(dark);
4923  else fH->SetFillColor(light);
4924  fH->TAttFill::Modify();
4925  gPad->PaintFillArea(7, x, y);
4926 
4927  // Draw bottom&right part of the box
4928  x[0] = xlow; y[0] = ylow;
4929  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4930  x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
4931  x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
4932  x[4] = xup; y[4] = yup;
4933  x[5] = xup; y[5] = ylow;
4934  x[6] = xlow; y[6] = ylow;
4935  if (kZNeg) fH->SetFillColor(light);
4936  else fH->SetFillColor(dark);
4937  fH->TAttFill::Modify();
4938  gPad->PaintFillArea(7, x, y);
4939  }
4940  }
4941  }
4942 
4943  if (Hoption.Zscale) PaintPalette();
4944  fH->SetFillStyle(fillsav);
4945  fH->SetFillColor(colsav);
4946  fH->TAttFill::Modify();
4947 }
4948 
4949 
4950 
4951 ////////////////////////////////////////////////////////////////////////////////
4952 /// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
4953 
4955 {
4956  TH1D *hproj;
4957  TH2D *h2 = (TH2D*)fH;
4958 
4959  TCandle myCandle;
4960  myCandle.SetOption((TCandle::CandleOption)Hoption.Candle);
4961  myCandle.SetMarkerColor(fH->GetLineColor());
4962  myCandle.SetLineColor(fH->GetLineColor());
4963  myCandle.SetLineWidth(fH->GetLineWidth());
4964  myCandle.SetFillColor(fH->GetFillColor());
4965  myCandle.SetFillStyle(fH->GetFillStyle());
4966  myCandle.SetMarkerSize(fH->GetMarkerSize());
4967  myCandle.SetMarkerStyle(fH->GetMarkerStyle());
4968  myCandle.SetLog(Hoption.Logx,Hoption.Logy, Hoption.Logz);
4969 
4970  Bool_t swapXY = myCandle.IsHorizontal();
4971  const Double_t standardCandleWidth = 0.66;
4972  const Double_t standardHistoWidth = 0.8;
4973 
4974  double allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
4975  double allMaxIntegral = 0;
4976 
4977  if (!swapXY) { // Vertical candle
4978  //Determining the slice with the maximum content
4979  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4980  hproj = h2->ProjectionY("_px", i, i);
4981  if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
4982  }
4983  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4984  Double_t binPosX = fXaxis->GetBinLowEdge(i);
4985  Double_t binWidth = fXaxis->GetBinWidth(i);
4986  hproj = h2->ProjectionY("_px", i, i);
4987  if (hproj->GetEntries() !=0) {
4988  Double_t candleWidth = fH->GetBarWidth();
4989  Double_t offset = fH->GetBarOffset()*binWidth;
4990  double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
4991  double myIntegral = hproj->Integral();
4992  Double_t histoWidth = candleWidth;
4993  if (candleWidth > 0.999 && candleWidth < 1.001) {
4994  candleWidth = standardCandleWidth;
4995  histoWidth = standardHistoWidth;
4996  }
4997  if (Hoption.Logz && myMaxContent > 0) {
4998  histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
4999  if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5000  } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5001  if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5002 
5003  myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5004  myCandle.SetCandleWidth(candleWidth*binWidth);
5005  myCandle.SetHistoWidth(histoWidth*binWidth);
5006  myCandle.SetHistogram(hproj);
5007  myCandle.Paint();
5008  }
5009  }
5010  } else { // Horizontal candle
5011  //Determining the slice with the maximum content
5012  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5013  hproj = h2->ProjectionX("_py", i, i);
5014  if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5015  }
5016  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5017  Double_t binPosY = fYaxis->GetBinLowEdge(i);
5018  Double_t binWidth = fYaxis->GetBinWidth(i);
5019  hproj = h2->ProjectionX("_py", i, i);
5020  if (hproj->GetEntries() !=0) {
5021  Double_t candleWidth = fH->GetBarWidth();
5022  Double_t offset = fH->GetBarOffset()*binWidth;
5023  double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5024  double myIntegral = hproj->Integral();
5025  Double_t histoWidth = candleWidth;
5026  if (candleWidth > 0.999 && candleWidth < 1.001) {
5027  candleWidth = standardCandleWidth;
5028  histoWidth = standardHistoWidth;
5029  }
5030  if (Hoption.Logz && myMaxContent > 0) {
5031  histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5032  if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5033  } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5034  if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5035 
5036  myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5037  myCandle.SetCandleWidth(candleWidth*binWidth);
5038  myCandle.SetHistoWidth(histoWidth*binWidth);
5039  myCandle.SetHistogram(hproj);
5040  myCandle.Paint();
5041  }
5042  }
5043  }
5044 }
5045 
5046 
5047 
5048 ////////////////////////////////////////////////////////////////////////////////
5049 /// Returns the rendering regions for an axis to use in the COL2 option
5050 ///
5051 /// The algorithm analyses the size of the axis compared to the size of
5052 /// the rendering region. It figures out the boundaries to use for each color
5053 /// of the rendering region. Only one axis is computed here.
5054 ///
5055 /// This allows for a single computation of the boundaries before iterating
5056 /// through all of the bins.
5057 ///
5058 /// \param pAxis the axis to consider
5059 /// \param nPixels the number of pixels to render axis into
5060 /// \param isLog whether the axis is log scale
5061 
5062 std::vector<THistRenderingRegion>
5064 {
5065  std::vector<THistRenderingRegion> regions;
5066 
5067  enum STRATEGY { Bins, Pixels } strategy;
5068 
5069  Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5070 
5071  if (nBins >= nPixels) {
5072  // more bins than pixels... we should loop over pixels and sample
5073  strategy = Pixels;
5074  } else {
5075  // fewer bins than pixels... we should loop over bins
5076  strategy = Bins;
5077  }
5078 
5079  if (isLog) {
5080 
5081  Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5082  Int_t binOffset=0;
5083  while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5084  binOffset++;
5085  xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5086  }
5087  if (xMin <= 0) {
5088  // this should cause an error if we have
5089  return regions;
5090  }
5091  Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5092 
5093  if (strategy == Bins) {
5094  // logarithmic plot. we find the pixel for the bin
5095  // pixel = eta * log10(V) - alpha
5096  // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5097  // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5098  // and V is axis value
5099  Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5100  Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5101 
5102  for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5103 
5104  // linear plot. we simply need to find the appropriate bin
5105  // for the
5106  Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5107  Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5108  Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5109  Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5110  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5111  std::make_pair(bin, bin+1)};
5112  regions.push_back(region);
5113  }
5114 
5115  } else {
5116 
5117  // loop over pixels
5118 
5119  Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5120 
5121  for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5122  // linear plot
5123  Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5124  Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5125  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5126  std::make_pair(binLow, binHigh)};
5127  regions.push_back(region);
5128  }
5129  }
5130  } else {
5131  // standard linear plot
5132 
5133  if (strategy == Bins) {
5134  // loop over bins
5135  for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5136 
5137  // linear plot. we simply need to find the appropriate bin
5138  // for the
5139  Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5140  Int_t xPx1 = xPx0 + nPixels/nBins;
5141 
5142  // make sure we don't compute beyond our bounds
5143  if (xPx1>= nPixels) xPx1 = nPixels-1;
5144 
5145  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5146  std::make_pair(bin, bin+1)};
5147  regions.push_back(region);
5148  }
5149  } else {
5150  // loop over pixels
5151  for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5152  // linear plot
5153  Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5154  Int_t binHigh = binLow + nBins/nPixels;
5155  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5156  std::make_pair(binLow, binHigh)};
5157  regions.push_back(region);
5158  }
5159  }
5160  }
5161 
5162  return regions;
5163 }
5164 
5165 ////////////////////////////////////////////////////////////////////////////////
5166 /// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5167 
5169 {
5170 
5171  if (Hoption.System != kCARTESIAN) {
5172  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5173  "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5174  PaintColorLevels(nullptr);
5175  return;
5176  }
5177 
5178  Double_t z;
5179 
5180  // Use existing max or min values. If either is already set
5181  // the appropriate value to use.
5182  Double_t zmin = fH->GetMinimumStored();
5183  Double_t zmax = fH->GetMaximumStored();
5184  Double_t originalZMin = zmin;
5185  Double_t originalZMax = zmax;
5186  if ((zmin == -1111) && (zmax == -1111)) {
5187  fH->GetMinimumAndMaximum(zmin, zmax);
5188  fH->SetMinimum(zmin);
5189  fH->SetMaximum(zmax);
5190  } else if (zmin == -1111) {
5191  zmin = fH->GetMinimum();
5192  fH->SetMinimum(zmin);
5193  } else if (zmax == -1111) {
5194  zmax = fH->GetMaximum();
5195  fH->SetMaximum(zmax);
5196  }
5197 
5198  Double_t dz = zmax - zmin;
5199  if (dz <= 0) { // Histogram filled with a constant value
5200  zmax += 0.1*TMath::Abs(zmax);
5201  zmin -= 0.1*TMath::Abs(zmin);
5202  dz = zmax - zmin;
5203  }
5204 
5205  if (Hoption.Logz) {
5206  if (zmin > 0) {
5207  zmin = TMath::Log10(zmin);
5208  zmax = TMath::Log10(zmax);
5209  dz = zmax - zmin;
5210  } else {
5211  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5212  "Cannot plot logz because bin content is less than 0.");
5213  return;
5214  }
5215  }
5216 
5217  // Initialize the levels on the Z axis
5218  Int_t ndiv = fH->GetContour();
5219  if (ndiv == 0 ) {
5220  ndiv = gStyle->GetNumberContours();
5221  fH->SetContour(ndiv);
5222  }
5223  std::vector<Double_t> colorBounds(ndiv);
5224  std::vector<Double_t> contours(ndiv, 0);
5225  if (fH->TestBit(TH1::kUserContour) == 0) {
5226  fH->SetContour(ndiv);
5227  } else {
5228  fH->GetContour(contours.data());
5229  }
5230 
5231  Double_t step = 1.0/ndiv;
5232  for (Int_t i=0; i<ndiv; ++i) {
5233  colorBounds[i] = step*i;
5234  }
5235 
5236  auto pFrame = gPad->GetFrame();
5237  Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5238  Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5239  Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5240  Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5241  Int_t nXPixels = px1-px0;
5242  Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5243 
5244  std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5245 
5246  auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5247  auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5248  if (xRegions.size() == 0 || yRegions.size() == 0) {
5249  Error("THistPainter::PaintColorLevelFast(Option_t*)",
5250  "Encountered error while computing rendering regions.");
5251  return;
5252  }
5253 
5254  Bool_t minExists = kFALSE;
5255  Bool_t maxExists = kFALSE;
5256  Double_t minValue = 1.;
5257  Double_t maxValue = 0.;
5258  for (auto& yRegion : yRegions) {
5259  for (auto& xRegion : xRegions ) {
5260 
5261  const auto& xBinRange = xRegion.fBinRange;
5262  const auto& yBinRange = yRegion.fBinRange;
5263 
5264  // sample the range
5265  z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5266 
5267  if (Hoption.Logz) {
5268  if (z > 0) z = TMath::Log10(z);
5269  else z = zmin;
5270  }
5271 
5272  // obey the user's max and min values if they were set
5273  if (z > zmax) z = zmax;
5274  if (z < zmin) z = zmin;
5275 
5276  if (fH->TestBit(TH1::kUserContour) == 1) {
5277  // contours are absolute values
5278  auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5279  z = colorBounds[index];
5280  } else {
5281  Int_t index = 0;
5282  if (dz != 0) {
5283  index = 0.001 + ((z - zmin)/dz)*ndiv;
5284  }
5285 
5286  if (index == static_cast<Int_t>(colorBounds.size())) {
5287  index--;
5288  }
5289 
5290  // Do a little bookkeeping to use later for getting libAfterImage to produce
5291  // the correct colors
5292  if (index == 0) {
5293  minExists = kTRUE;
5294  } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5295  maxExists = kTRUE;
5296  }
5297 
5298  z = colorBounds[index];
5299 
5300  if (z < minValue) {
5301  minValue = z;
5302  }
5303  if (z > maxValue) {
5304  maxValue = z;
5305  }
5306  }
5307 
5308  // fill in the actual pixels
5309  const auto& xPixelRange = xRegion.fPixelRange;
5310  const auto& yPixelRange = yRegion.fPixelRange;
5311  for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5312  for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5313  Int_t pixel = yPx*nXPixels + xPx;
5314  buffer[pixel] = z;
5315  }
5316  }
5317  } // end px loop
5318  } // end py loop
5319 
5320  // This is a bit of a hack to ensure that we span the entire color range and
5321  // don't screw up the colors for a sparse histogram. No one will notice that I set a
5322  // single pixel on the edge of the image to a different color. This is even more
5323  // true because the chosen pixels will be covered by the axis.
5324  if (minValue != maxValue) {
5325  if ( !minExists) {
5326  buffer.front() = 0;
5327  }
5328 
5329  if ( !maxExists) {
5330  buffer[buffer.size()-nXPixels] = 0.95;
5331  }
5332  }
5333 
5334  // Generate the TImage
5336  TImage* pImage = TImage::Create();
5338  pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5339  delete pPalette;
5340 
5341  Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5342  pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5343  delete pImage;
5344 
5345  if (Hoption.Zscale) PaintPalette();
5346 
5347  // Reset the maximum and minimum values to their original values
5348  // when this function was called. If we don't do this, an initial
5349  // value of -1111 will be replaced with the true max or min values.
5350  fH->SetMinimum(originalZMin);
5351  fH->SetMaximum(originalZMax);
5352 }
5353 
5354 ////////////////////////////////////////////////////////////////////////////////
5355 /// [Control function to draw a 2D histogram as a color plot.](#HP14)
5356 
5358 {
5359  Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5360 
5361  Double_t zmin = fH->GetMinimum();
5362  Double_t zmax = fH->GetMaximum();
5363 
5364  Double_t dz = zmax - zmin;
5365  if (dz <= 0) { // Histogram filled with a constant value
5366  zmax += 0.1*TMath::Abs(zmax);
5367  zmin -= 0.1*TMath::Abs(zmin);
5368  dz = zmax - zmin;
5369  }
5370 
5371  // In case of option SAME, zmin and zmax values are taken from the
5372  // first plotted 2D histogram.
5373  if (Hoption.Same) {
5374  TH2 *h2;
5375  TIter next(gPad->GetListOfPrimitives());
5376  while ((h2 = (TH2 *)next())) {
5377  if (!h2->InheritsFrom(TH2::Class())) continue;
5378  zmin = h2->GetMinimum();
5379  zmax = h2->GetMaximum();
5380  if (Hoption.Logz) {
5381  if (zmin <= 0) {
5382  zmin = TMath::Log10(zmax*0.001);
5383  } else {
5384  zmin = TMath::Log10(zmin);
5385  }
5386  zmax = TMath::Log10(zmax);
5387  }
5388  dz = zmax - zmin;
5389  break;
5390  }
5391  } else {
5392  if (Hoption.Logz) {
5393  if (zmin > 0) {
5394  zmin = TMath::Log10(zmin);
5395  zmax = TMath::Log10(zmax);
5396  dz = zmax - zmin;
5397  } else {
5398  return;
5399  }
5400  }
5401  }
5402 
5403  Style_t fillsav = fH->GetFillStyle();
5404  Style_t colsav = fH->GetFillColor();
5405  fH->SetFillStyle(1001);
5406  fH->TAttFill::Modify();
5407 
5408  // Initialize the levels on the Z axis
5409  Int_t ncolors = gStyle->GetNumberOfColors();
5410  Int_t ndiv = fH->GetContour();
5411  if (ndiv == 0 ) {
5412  ndiv = gStyle->GetNumberContours();
5413  fH->SetContour(ndiv);
5414  }
5415  Int_t ndivz = TMath::Abs(ndiv);
5416  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5417  Double_t scale = ndivz/dz;
5418 
5419  Int_t color;
5420  TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5421  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5422  yk = fYaxis->GetBinLowEdge(j);
5423  ystep = fYaxis->GetBinWidth(j);
5424  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5425  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5426  xk = fXaxis->GetBinLowEdge(i);
5427  xstep = fXaxis->GetBinWidth(i);
5428  if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5429  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5430  z = fH->GetBinContent(bin);
5431  // if fH is a profile histogram do not draw empty bins
5432  if (prof2d) {
5433  const Double_t binEntries = prof2d->GetBinEntries(bin);
5434  if (binEntries == 0)
5435  continue;
5436  } else {
5437  // don't draw the empty bins for non-profile histograms
5438  // with positive content
5439  if (z == 0) {
5440  if (zmin >= 0 || Hoption.Logz) continue;
5441  if (Hoption.Color == 2) continue;
5442  }
5443  }
5444 
5445  if (Hoption.Logz) {
5446  if (z > 0) z = TMath::Log10(z);
5447  else z = zmin;
5448  }
5449  if (z < zmin && !Hoption.Zero) continue;
5450  xup = xk + xstep;
5451  xlow = xk;
5452  if (Hoption.Logx) {
5453  if (xup > 0) xup = TMath::Log10(xup);
5454  else continue;
5455  if (xlow > 0) xlow = TMath::Log10(xlow);
5456  else continue;
5457  }
5458  yup = yk + ystep;
5459  ylow = yk;
5460  if (Hoption.System != kPOLAR) {
5461  if (Hoption.Logy) {
5462  if (yup > 0) yup = TMath::Log10(yup);
5463  else continue;
5464  if (ylow > 0) ylow = TMath::Log10(ylow);
5465  else continue;
5466  }
5467  if (xup < gPad->GetUxmin()) continue;
5468  if (yup < gPad->GetUymin()) continue;
5469  if (xlow > gPad->GetUxmax()) continue;
5470  if (ylow > gPad->GetUymax()) continue;
5471  if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5472  if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5473  if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5474  if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5475  }
5476 
5477  if (fH->TestBit(TH1::kUserContour)) {
5478  zc = fH->GetContourLevelPad(0);
5479  if (z < zc) continue;
5480  color = -1;
5481  for (Int_t k=0; k<ndiv; k++) {
5482  zc = fH->GetContourLevelPad(k);
5483  if (z < zc) {
5484  continue;
5485  } else {
5486  color++;
5487  }
5488  }
5489  } else {
5490  color = Int_t(0.01+(z-zmin)*scale);
5491  }
5492 
5493  Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5494  if (theColor > ncolors-1) theColor = ncolors-1;
5495  fH->SetFillColor(gStyle->GetColorPalette(theColor));
5496  fH->TAttFill::Modify();
5497  if (Hoption.System != kPOLAR) {
5498  gPad->PaintBox(xlow, ylow, xup, yup);
5499  } else {
5500  TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5501  crown.SetFillColor(gStyle->GetColorPalette(theColor));
5502  crown.Paint();
5503  }
5504  }
5505  }
5506 
5507  if (Hoption.Zscale) PaintPalette();
5508 
5509  fH->SetFillStyle(fillsav);
5510  fH->SetFillColor(colsav);
5511  fH->TAttFill::Modify();
5512 
5513 }
5514 
5515 ////////////////////////////////////////////////////////////////////////////////
5516 /// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5517 
5519 {
5520 
5521  Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5522  Int_t itars, mode, ir[4];
5523  Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5524 
5525  if (Hoption.Contour == 14) {
5526  Hoption.Surf = 12;
5527  Hoption.Axis = 1;
5528  thesave = gPad->GetTheta();
5529  phisave = gPad->GetPhi();
5530  gPad->SetPhi(0.);
5531  gPad->SetTheta(90.);
5532  PaintSurface(option);
5533  gPad->SetPhi(phisave);
5534  gPad->SetTheta(thesave);
5535  TView *view = gPad->GetView();
5536  if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5537  PaintAxis();
5538  return;
5539  }
5540 
5541  if (Hoption.Same) {
5542  // If the contour is painted on a 3d plot, the contour lines are
5543  // paint in 3d too.
5544  TObject *obj;
5545  TIter next(gPad->GetListOfPrimitives());
5546  while ((obj=next())) {
5547  if (strstr(obj->GetDrawOption(),"surf") ||
5548  strstr(obj->GetDrawOption(),"lego") ||
5549  strstr(obj->GetDrawOption(),"tri")) {
5550  Hoption.Surf = 16;
5551  PaintSurface(option);
5552  return;
5553  }
5554  }
5555  }
5556 
5557  if (Hoption.Contour == 15) {
5558  TGraphDelaunay2D *dt = nullptr;
5559  TGraphDelaunay *dtOld = nullptr;
5560  TList *hl = fH->GetListOfFunctions();
5561  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5562  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5563  if (!dt && !dtOld) return;
5564  if (!fGraph2DPainter) {
5565  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5566  else fGraph2DPainter = new TGraph2DPainter(dtOld);
5567  }
5568  fGraph2DPainter->Paint(option);
5569  return;
5570  }
5571 
5572  gPad->SetBit(TGraph::kClipFrame);
5573 
5574  Double_t *levels = new Double_t[2*kMAXCONTOUR];
5575  Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5576  Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5577  Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5578 
5579  Int_t npmax = 0;
5580  for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5581 
5582  ncontour = fH->GetContour();
5583  if (ncontour == 0) {
5584  ncontour = gStyle->GetNumberContours();
5585  fH->SetContour(ncontour);
5586  }
5587  if (ncontour > kMAXCONTOUR) {
5588  Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5589  kMAXCONTOUR, ncontour);
5590  ncontour = kMAXCONTOUR-1;
5591  }
5592  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5593 
5594  for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5595  Int_t linesav = fH->GetLineStyle();
5596  Int_t colorsav = fH->GetLineColor();
5597  Int_t fillsav = fH->GetFillColor();
5598  if (Hoption.Contour == 13) {
5599  fH->TAttLine::Modify();
5600  }
5601 
5602  TPolyLine **polys = 0;
5603  TPolyLine *poly=0;
5604  TObjArray *contours = 0;
5605  TList *list = 0;
5606  TGraph *graph = 0;
5607  Int_t *np = 0;
5608  if (Hoption.Contour == 1) {
5609  np = new Int_t[ncontour];
5610  for (i=0;i<ncontour;i++) np[i] = 0;
5611  polys = new TPolyLine*[ncontour];
5612  for (i=0;i<ncontour;i++) {
5613  polys[i] = new TPolyLine(100);
5614  }
5615  if (Hoption.List == 1) {
5616  contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5617  if (contours) {
5618  gROOT->GetListOfSpecials()->Remove(contours);
5619  count = contours->GetSize();
5620  for (i=0;i<count;i++) {
5621  list = (TList*)contours->At(i);
5622  if (list) list->Delete();
5623  }
5624  }
5625  contours = new TObjArray(ncontour);
5626  contours->SetName("contours");
5627  gROOT->GetListOfSpecials()->Add(contours);
5628  for (i=0;i<ncontour;i++) {
5629  list = new TList();
5630  contours->Add(list);
5631  }
5632  }
5633  }
5634  Int_t theColor;
5635  Int_t ncolors = gStyle->GetNumberOfColors();
5636  Int_t ndivz = TMath::Abs(ncontour);
5637 
5638  Int_t k,ipoly;
5639  for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5640  y[0] = fYaxis->GetBinCenter(j);
5641  y[1] = y[0];
5642  y[2] = fYaxis->GetBinCenter(j+1);
5643  y[3] = y[2];
5644  for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5645  zc[0] = fH->GetBinContent(i, j);
5646  zc[1] = fH->GetBinContent(i+1, j);
5647  zc[2] = fH->GetBinContent(i+1, j+1);
5648  zc[3] = fH->GetBinContent(i, j+1);
5649  if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5650  if (Hoption.Logz) {
5651  if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5652  else zc[0] = Hparam.zmin;
5653  if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5654  else zc[1] = Hparam.zmin;
5655  if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5656  else zc[2] = Hparam.zmin;
5657  if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5658  else zc[3] = Hparam.zmin;
5659  }
5660  for (k=0;k<4;k++) {
5661  ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5662  }
5663  if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5664  x[0] = fXaxis->GetBinCenter(i);
5665  x[3] = x[0];
5666  x[1] = fXaxis->GetBinCenter(i+1);
5667  x[2] = x[1];
5668  if (zc[0] <= zc[1]) n = 0; else n = 1;
5669  if (zc[2] <= zc[3]) m = 2; else m = 3;
5670  if (zc[n] > zc[m]) n = m;
5671  n++;
5672  lj=1;
5673  for (ix=1;ix<=4;ix++) {
5674  m = n%4 + 1;
5675  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5676  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5677  lj += 2*ljfill;
5678  n = m;
5679  }
5680 
5681  if (zc[0] <= zc[1]) n = 0; else n = 1;
5682  if (zc[2] <= zc[3]) m = 2; else m = 3;
5683  if (zc[n] > zc[m]) n = m;
5684  n++;
5685  lj=2;
5686  for (ix=1;ix<=4;ix++) {
5687  if (n == 1) m = 4;
5688  else m = n-1;
5689  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5690  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5691  lj += 2*ljfill;
5692  n = m;
5693  }
5694 
5695  // Re-order endpoints
5696 
5697  count = 0;
5698  for (ix=1; ix<=lj-5; ix +=2) {
5699  //count = 0;
5700  while (itarr[ix-1] != itarr[ix]) {
5701  xsave = xarr[ix];
5702  ysave = yarr[ix];
5703  itars = itarr[ix];
5704  for (jx=ix; jx<=lj-5; jx +=2) {
5705  xarr[jx] = xarr[jx+2];
5706  yarr[jx] = yarr[jx+2];
5707  itarr[jx] = itarr[jx+2];
5708  }
5709  xarr[lj-3] = xsave;
5710  yarr[lj-3] = ysave;
5711  itarr[lj-3] = itars;
5712  if (count > 100) break;
5713  count++;
5714  }
5715  }
5716 
5717  if (count > 100) continue;
5718  for (ix=1; ix<=lj-2; ix +=2) {
5719  theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5720  icol = gStyle->GetColorPalette(theColor);
5721  if (Hoption.Contour == 11) {
5722  fH->SetLineColor(icol);
5723  }
5724  if (Hoption.Contour == 12) {
5725  mode = icol%5;
5726  if (mode == 0) mode = 5;
5727  fH->SetLineStyle(mode);
5728  }
5729  if (Hoption.Contour != 1) {
5730  fH->TAttLine::Modify();
5731  gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5732  continue;
5733  }
5734 
5735  ipoly = itarr[ix-1];
5736  if (ipoly >=0 && ipoly <ncontour) {
5737  poly = polys[ipoly];
5738  poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5739  poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5740  np[ipoly] += 2;
5741  if (npmax < np[ipoly]) npmax = np[ipoly];
5742  }
5743  }
5744  } // end of if (ir[0]
5745  } //end of for (i
5746  } //end of for (j
5747 
5748  Double_t xmin,ymin;
5749  Double_t *xp, *yp;
5750  Int_t nadd,iminus,iplus;
5751  Double_t *xx, *yy;
5752  Int_t istart;
5753  Int_t first = ncontour;
5754  Int_t *polysort = 0;
5755  Int_t contListNb;
5756  if (Hoption.Contour != 1) goto theEND;
5757 
5758  //The 2 points line generated above are now sorted/merged to generate
5759  //a list of consecutive points.
5760  // If the option "List" has been specified, the list of points is saved
5761  // in the form of TGraph objects in the ROOT list of special objects.
5762  xmin = gPad->GetUxmin();
5763  ymin = gPad->GetUymin();
5764  xp = new Double_t[2*npmax];
5765  yp = new Double_t[2*npmax];
5766  polysort = new Int_t[ncontour];
5767  //find first positive contour
5768  for (ipoly=0;ipoly<ncontour;ipoly++) {
5769  if (levels[ipoly] >= 0) {first = ipoly; break;}
5770  }
5771  //store negative contours from 0 to minimum, then all positive contours
5772  k = 0;
5773  for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
5774  for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
5775  // we can now draw sorted contours
5776  contListNb = 0;
5777  fH->SetFillStyle(1001);
5778  for (k=0;k<ncontour;k++) {
5779  ipoly = polysort[k];
5780  if (np[ipoly] == 0) continue;
5781  if (Hoption.List) list = (TList*)contours->At(contListNb);
5782  contListNb++;
5783  poly = polys[ipoly];
5784  xx = poly->GetX();
5785  yy = poly->GetY();
5786  istart = 0;
5787  while (1) {
5788  iminus = npmax;
5789  iplus = iminus+1;
5790  xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
5791  xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
5792  xx[istart] = xmin; yy[istart] = ymin;
5793  xx[istart+1] = xmin; yy[istart+1] = ymin;
5794  while (1) {
5795  nadd = 0;
5796  for (i=2;i<np[ipoly];i+=2) {
5797  if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
5798  iplus++;
5799  xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
5800  xx[i] = xmin; yy[i] = ymin;
5801  xx[i+1] = xmin; yy[i+1] = ymin;
5802  nadd++;
5803  }
5804  if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
5805  iminus--;
5806  xp[iminus] = xx[i]; yp[iminus] = yy[i];
5807  xx[i] = xmin; yy[i] = ymin;
5808  xx[i+1] = xmin; yy[i+1] = ymin;
5809  nadd++;
5810  }
5811  }
5812  if (nadd == 0) break;
5813  }
5814  theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
5815  icol = gStyle->GetColorPalette(theColor);
5816  if (ndivz > 1) fH->SetFillColor(icol);
5817  fH->TAttFill::Modify();
5818  gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5819  if (Hoption.List) {
5820  graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5821  graph->SetFillColor(icol);
5822  graph->SetLineWidth(fH->GetLineWidth());
5823  list->Add(graph);
5824  }
5825  //check if more points are left
5826  istart = 0;
5827  for (i=2;i<np[ipoly];i+=2) {
5828  if (xx[i] != xmin && yy[i] != ymin) {
5829  istart = i;
5830  break;
5831  }
5832  }
5833  if (istart == 0) break;
5834  }
5835  }
5836 
5837  for (i=0;i<ncontour;i++) delete polys[i];
5838  delete [] polys;
5839  delete [] xp;
5840  delete [] yp;
5841  delete [] polysort;
5842 
5843 theEND:
5844  gPad->ResetBit(TGraph::kClipFrame);
5845  if (Hoption.Zscale) PaintPalette();
5846  fH->SetLineStyle(linesav);
5847  fH->SetLineColor(colorsav);
5848  fH->SetFillColor(fillsav);
5849  if (np) delete [] np;
5850  delete [] xarr;
5851  delete [] yarr;
5852  delete [] itarr;
5853  delete [] levels;
5854 }
5855 
5856 ////////////////////////////////////////////////////////////////////////////////
5857 /// Fill the matrix `xarr` and `yarr` for Contour Plot.
5858 
5860  Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
5861  Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
5862 {
5863 
5864  Bool_t vert;
5865  Double_t tlen, tdif, elev, diff, pdif, xlen;
5866  Int_t n, i, icount;
5867 
5868  if (x1 == x2) {
5869  vert = kTRUE;
5870  tlen = y2 - y1;
5871  } else {
5872  vert = kFALSE;
5873  tlen = x2 - x1;
5874  }
5875 
5876  n = icont1 +1;
5877  tdif = elev2 - elev1;
5878  i = 0;
5879  icount = 0;
5880  while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
5881  //elev = fH->GetContourLevel(n);
5882  elev = levels[n];
5883  diff = elev - elev1;
5884  pdif = diff/tdif;
5885  xlen = tlen*pdif;
5886  if (vert) {
5887  if (Hoption.Logx)
5888  xarr[i] = TMath::Log10(x1);
5889  else
5890  xarr[i] = x1;
5891  if (Hoption.Logy)
5892  yarr[i] = TMath::Log10(y1 + xlen);
5893  else
5894  yarr[i] = y1 + xlen;
5895  } else {
5896  if (Hoption.Logx)
5897  xarr[i] = TMath::Log10(x1 + xlen);
5898  else
5899  xarr[i] = x1 + xlen;
5900  if (Hoption.Logy)
5901  yarr[i] = TMath::Log10(y1);
5902  else
5903  yarr[i] = y1;
5904  }
5905  itarr[i] = n;
5906  icount++;
5907  i +=2;
5908  n++;
5909  }
5910  return icount;
5911 }
5912 
5913 ////////////////////////////////////////////////////////////////////////////////
5914 /// [Draw 1D histograms error bars.](#HP09)
5915 
5917 {
5918 
5919  // On iOS, we do not highlight histogram, if it's not picked at the moment
5920  // (but part of histogram (axis or pavestat) was picked, that's why this code
5921  // is called at all. This conditional statement never executes on non-iOS platform.
5922  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
5923 
5924  const Int_t kBASEMARKER=8;
5925  Double_t xp, yp, ex1, ex2, ey1, ey2;
5926  Double_t delta;
5927  Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
5928  Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
5929  Double_t xmin, xmax, ymin, ymax;
5930  Double_t logxmin = 0;
5931  Double_t logymin = 0;
5932  Int_t i, k, npoints, first, last, fixbin;
5933  Int_t if1 = 0;
5934  Int_t if2 = 0;
5935  Int_t drawmarker, errormarker;
5936  Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
5937 
5938  Double_t *xline = 0;
5939  Double_t *yline = 0;
5940  option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
5941  if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
5942  if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
5943  if (Hoption.Error == 10) option0 = 1;
5944  if (Hoption.Error == 11) option1 = 1;
5945  if (Hoption.Error == 12) option2 = 1;
5946  if (Hoption.Error == 13) option3 = 1;
5947  if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
5948  if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
5949  if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
5950  if (option2+option3 == 0) optionE = 1;
5951  if (Hoption.Error == 0) optionE = 0;
5952  if (fXaxis->GetXbins()->fN) fixbin = 0;
5953  else fixbin = 1;
5954 
5955  errormarker = fH->GetMarkerStyle();
5956  if (optionEX0) {
5957  xerror = 0;
5958  } else {
5959  xerror = gStyle->GetErrorX();
5960  }
5961  symbolsize = fH->GetMarkerSize();
5962  if (errormarker == 1) symbolsize = 0.01;
5963  sbase = symbolsize*kBASEMARKER;
5964  // set the graphics attributes
5965 
5966  fH->TAttLine::Modify();
5967  fH->TAttFill::Modify();
5968  fH->TAttMarker::Modify();
5969 
5970  // set the first and last bin
5971 
5972  Double_t factor = Hparam.factor;
5973  first = Hparam.xfirst;
5974  last = Hparam.xlast;
5975  npoints = last - first +1;
5976  xmin = gPad->GetUxmin();
5977  xmax = gPad->GetUxmax();
5978  ymin = gPad->GetUymin();
5979  ymax = gPad->GetUymax();
5980 
5981 
5982  if (option3) {
5983  xline = new Double_t[2*npoints];
5984  yline = new Double_t[2*npoints];
5985  if (!xline || !yline) {
5986  Error("PaintErrors", "too many points, out of memory");
5987  return;
5988  }
5989  if1 = 1;
5990  if2 = 2*npoints;
5991  }
5992 
5993  // compute the offset of the error bars due to the symbol size
5994  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
5995  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
5996 
5997  // compute size of the lines at the end of the error bars
5998  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
5999  bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6000  bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6001 
6002 
6003  if (fixbin) {
6004  if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6005  else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6006  } else {
6007  delta = fH->GetBinWidth(first);
6008  xp = fH->GetBinLowEdge(first) + 0.5*delta;
6009  }
6010 
6011  // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6012  if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6013  if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6014 
6015  // ---------------------- Loop over the points---------------------
6016  for (k=first; k<=last; k++) {
6017 
6018  // get the data
6019  // xp = X position of the current point
6020  // yp = Y position of the current point
6021  // ex1 = Low X error
6022  // ex2 = Up X error
6023  // ey1 = Low Y error
6024  // ey2 = Up Y error
6025  // (xi,yi) = Error bars coordinates
6026 
6027  if (Hoption.Logx) {
6028  if (xp <= 0) goto L30;
6029  if (xp < logxmin) goto L30;
6030  if (xp > TMath::Power(10,xmax)) break;
6031  } else {
6032  if (xp < xmin) goto L30;
6033  if (xp > xmax) break;
6034  }
6035  yp = factor*fH->GetBinContent(k);
6036  if (optionI0 && yp==0) goto L30;
6037  if (fixbin) {
6038  ex1 = xerror*Hparam.xbinsize;
6039  } else {
6040  delta = fH->GetBinWidth(k);
6041  ex1 = xerror*delta;
6042  }
6043  if (fH->GetBinErrorOption() == TH1::kNormal) {
6044  ey1 = factor*fH->GetBinError(k);
6045  ey2 = ey1;
6046  } else {
6047  ey1 = factor*fH->GetBinErrorLow(k);
6048  ey2 = factor*fH->GetBinErrorUp(k);
6049  }
6050  ex2 = ex1;
6051 
6052  xi4 = xp;
6053  xi3 = xp;
6054  xi2 = xp + ex2;
6055  xi1 = xp - ex1;
6056 
6057  yi1 = yp;
6058  yi2 = yp;
6059  yi3 = yp - ey1;
6060  yi4 = yp + ey2;
6061 
6062  // take the LOG if necessary
6063  if (Hoption.Logx) {
6064  xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6065  xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6066  xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6067  xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6068  }
6069  if (Hoption.Logy) {
6070  yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6071  yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6072  yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6073  yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6074  }
6075 
6076  // test if error bars are not outside the limits
6077  // otherwise they are truncated
6078 
6079  xi1 = TMath::Max(xi1,xmin);
6080  xi2 = TMath::Min(xi2,xmax);
6081  yi3 = TMath::Max(yi3,ymin);
6082  yi4 = TMath::Min(yi4,ymax);
6083 
6084  // test if the marker is on the frame limits. If "Yes", the
6085  // marker will not be drawn and the error bars will be readjusted.
6086 
6087  drawmarker = kTRUE;
6088  if (!option0 && !option3) {
6089  if (Hoption.Logy && yp < logymin) goto L30;
6090  if (yi1 < ymin || yi1 > ymax) goto L30;
6091  if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6092  }
6093  if (!symbolsize || !errormarker) drawmarker = kFALSE;
6094 
6095  // draw the error rectangles
6096  if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6097 
6098  // keep points for fill area drawing
6099  if (option3) {
6100  xline[if1-1] = xi3;
6101  xline[if2-1] = xi3;
6102  yline[if1-1] = yi4;
6103  yline[if2-1] = yi3;
6104  if1++;
6105  if2--;
6106  }
6107 
6108  // draw the error bars
6109  if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6110  if (optionE && drawmarker) {
6111  if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6112  if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6113  // don't duplicate the horizontal line
6114  if (Hoption.Hist != 2) {
6115  if (yi1<ymax && yi1>ymin) {
6116  if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6117  if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6118  }
6119  }
6120  }
6121  if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6122  if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6123  if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6124  // don't duplicate the horizontal line
6125  if (Hoption.Hist != 2) {
6126  if (yi1<ymax && yi1>ymin) {
6127  if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6128  if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6129  }
6130  }
6131  }
6132 
6133  // draw line at the end of the error bars
6134 
6135  if (option1 && drawmarker) {
6136  if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6137  if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6138  if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6139  if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6140  }
6141 
6142  // draw the marker
6143 
6144  if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6145 
6146 L30:
6147  if (fixbin) xp += Hparam.xbinsize;
6148  else {
6149  if (k < last) {
6150  delta = fH->GetBinWidth(k+1);
6151  xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6152  }
6153  }
6154  } //end of for loop
6155 
6156  // draw the filled area
6157 
6158  if (option3) {
6159  TGraph graph;
6160  graph.SetLineStyle(fH->GetLineStyle());
6161  graph.SetLineColor(fH->GetLineColor());
6162  graph.SetLineWidth(fH->GetLineWidth());
6163  graph.SetFillStyle(fH->GetFillStyle());
6164  graph.SetFillColor(fH->GetFillColor());
6165  Int_t logx = gPad->GetLogx();
6166  Int_t logy = gPad->GetLogy();
6167  gPad->SetLogx(0);
6168  gPad->SetLogy(0);
6169 
6170  // In some cases the number of points in the fill area is smaller than
6171  // 2*npoints. In such cases the array xline and yline must be arranged
6172  // before being plotted. The next loop does that.
6173  if (if2 > npoints) {
6174  for (i=1; i<if1; i++) {
6175  xline[if1-2+i] = xline[if2-1+i];
6176  yline[if1-2+i] = yline[if2-1+i];
6177  }
6178  npoints = if1-1;
6179  }
6180  if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6181  else graph.PaintGraph(2*npoints,xline,yline,"F");
6182  gPad->SetLogx(logx);
6183  gPad->SetLogy(logy);
6184  delete [] xline;
6185  delete [] yline;
6186  }
6187 }
6188 
6189 ////////////////////////////////////////////////////////////////////////////////
6190 /// Draw 2D histograms errors.
6191 
6193 {
6194 
6195  fH->TAttMarker::Modify();
6196  fH->TAttLine::Modify();
6197 
6198  // Define the 3D view
6199  fXbuf[0] = Hparam.xmin;
6200  fYbuf[0] = Hparam.xmax;
6201  fXbuf[1] = Hparam.ymin;
6202  fYbuf[1] = Hparam.ymax;
6203  fXbuf[2] = Hparam.zmin;
6204  fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6206  TView *view = gPad->GetView();
6207  if (!view) {
6208  Error("Paint2DErrors", "no TView in current pad");
6209  return;
6210  }
6211  Double_t thedeg = 90 - gPad->GetTheta();
6212  Double_t phideg = -90 - gPad->GetPhi();
6213  Double_t psideg = view->GetPsi();
6214  Int_t irep;
6215  view->SetView(phideg, thedeg, psideg, irep);
6216 
6217  // Set color/style for back box
6218  fLego->SetFillStyle(gPad->GetFrameFillStyle());
6219  fLego->SetFillColor(gPad->GetFrameFillColor());
6220  fLego->TAttFill::Modify();
6221  Int_t backcolor = gPad->GetFrameFillColor();
6222  if (Hoption.System != kCARTESIAN) backcolor = 0;
6223  view->PadRange(backcolor);
6226  fLego->TAttFill::Modify();
6227 
6228  // Paint the Back Box if needed
6229  if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6230  fLego->InitMoveScreen(-1.1,1.1);
6233  fLego->BackBox(90);
6234  }
6235 
6236  // Paint the Errors
6237  Double_t x, ex, x1, x2;
6238  Double_t y, ey, y1, y2;
6239  Double_t z, ez1, ez2, z1, z2;
6240  Double_t temp1[3],temp2[3];
6241  Double_t xyerror;
6242  if (Hoption.Error == 110) {
6243  xyerror = 0;
6244  } else {
6245  xyerror = gStyle->GetErrorX();
6246  }
6247 
6248  Double_t xk, xstep, yk, ystep;
6249  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6250  y = fYaxis->GetBinCenter(j);
6251  ey = fYaxis->GetBinWidth(j)*xyerror;
6252  y1 = y-ey;
6253  y2 = y+ey;
6254  if (Hoption.Logy) {
6255  if (y > 0) y = TMath::Log10(y);
6256  else continue;
6257  if (y1 > 0) y1 = TMath::Log10(y1);
6258  else y1 = Hparam.ymin;
6259  if (y2 > 0) y2 = TMath::Log10(y2);
6260  else y2 = Hparam.ymin;
6261  }
6262  yk = fYaxis->GetBinLowEdge(j);
6263  ystep = fYaxis->GetBinWidth(j);
6264  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6265  xk = fXaxis->GetBinLowEdge(i);
6266  xstep = fXaxis->GetBinWidth(i);
6267  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6268  Int_t bin = fH->GetBin(i,j);
6269  x = fXaxis->GetBinCenter(i);
6270  ex = fXaxis->GetBinWidth(i)*xyerror;
6271  x1 = x-ex;
6272  x2 = x+ex;
6273  if (Hoption.Logx) {
6274  if (x > 0) x = TMath::Log10(x);
6275  else continue;
6276  if (x1 > 0) x1 = TMath::Log10(x1);
6277  else x1 = Hparam.xmin;
6278  if (x2 > 0) x2 = TMath::Log10(x2);
6279  else x2 = Hparam.xmin;
6280  }
6281  z = fH->GetBinContent(bin);
6282  if (fH->GetBinErrorOption() == TH1::kNormal) {
6283  ez1 = fH->GetBinError(bin);
6284  ez2 = ez1;
6285  }
6286  else {
6287  ez1 = fH->GetBinErrorLow(bin);
6288  ez2 = fH->GetBinErrorUp(bin);
6289  }
6290  z1 = z - ez1;
6291  z2 = z + ez2;
6292  if (Hoption.Logz) {
6293  if (z > 0) z = TMath::Log10(z);
6294  else z = Hparam.zmin;
6295  if (z1 > 0) z1 = TMath::Log10(z1);
6296  else z1 = Hparam.zmin;
6297  if (z2 > 0) z2 = TMath::Log10(z2);
6298  else z2 = Hparam.zmin;
6299 
6300  }
6301  if (z <= Hparam.zmin) continue;
6302  if (z > Hparam.zmax) z = Hparam.zmax;
6303 
6304  temp1[0] = x1;
6305  temp1[1] = y;
6306  temp1[2] = z;
6307  temp2[0] = x2;
6308  temp2[1] = y;
6309  temp2[2] = z;
6310  gPad->PaintLine3D(temp1, temp2);
6311  temp1[0] = x;
6312  temp1[1] = y1;
6313  temp1[2] = z;
6314  temp2[0] = x;
6315  temp2[1] = y2;
6316  temp2[2] = z;
6317  gPad->PaintLine3D(temp1, temp2);
6318  temp1[0] = x;
6319  temp1[1] = y;
6320  temp1[2] = z1;
6321  temp2[0] = x;
6322  temp2[1] = y;
6323  temp2[2] = z2;
6324  gPad->PaintLine3D(temp1, temp2);
6325  temp1[0] = x;
6326  temp1[1] = y;
6327  temp1[2] = z;
6328  view->WCtoNDC(temp1, &temp2[0]);
6329  gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6330  }
6331  }
6332 
6333  // Paint the Front Box if needed
6334  if (Hoption.FrontBox) {
6335  fLego->InitMoveScreen(-1.1,1.1);
6337  fLego->FrontBox(90);
6338  }
6339 
6340  // Paint the Axis if needed
6341  if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6342  TGaxis *axis = new TGaxis();
6343  PaintLegoAxis(axis, 90);
6344  delete axis;
6345  }
6346 
6347  delete fLego; fLego = 0;
6348 }
6349 
6350 ////////////////////////////////////////////////////////////////////////////////
6351 /// Calculate range and clear pad (canvas).
6352 
6354 {
6355 
6356  if (Hoption.Same) return;
6357 
6358  RecalculateRange();
6359 
6360  if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6361  Hoption.Contour == 14 || Hoption.Error >= 100) {
6362  TObject *frame = gPad->FindObject("TFrame");
6363  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6364  return;
6365  }
6366 
6367  //The next statement is always executed on non-iOS platform,
6368  //on iOS depends on pad mode.
6369  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6370  gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6371 }
6372 
6373 ////////////////////////////////////////////////////////////////////////////////
6374 /// [Paint functions associated to an histogram.](#HP28")
6375 
6377 {
6378 
6380  TObject *obj;
6381 
6382  while (lnk) {
6383  obj = lnk->GetObject();
6384  TVirtualPad *padsave = gPad;
6385  if (obj->InheritsFrom(TF2::Class())) {
6386  if (obj->TestBit(TF2::kNotDraw) == 0) {
6387  if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6388  TF2 *f2 = (TF2*)obj;
6389  f2->SetMinimum(fH->GetMinimum());
6390  f2->SetMaximum(fH->GetMaximum());
6391  f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6392  f2->Paint("surf same");
6393  } else {
6394  obj->Paint("cont3 same");
6395  }
6396  }
6397  } else if (obj->InheritsFrom(TF1::Class())) {
6398  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6399  } else {
6400  //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6401  gPad->PushSelectableObject(obj);
6402 
6403  //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6404  //and picked object.
6405  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6406  obj->Paint(lnk->GetOption());
6407  }
6408  lnk = (TObjOptLink*)lnk->Next();
6409  padsave->cd();
6410  }
6411 }
6412 
6413 ////////////////////////////////////////////////////////////////////////////////
6414 /// [Control routine to draw 1D histograms](#HP01b)
6415 
6417 {
6418 
6419  //On iOS: do not highlight hist, if part of it was selected.
6420  //Never executes on non-iOS platform.
6421  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6422  return;
6423 
6424  static char chopth[17];
6425 
6426  Int_t htype, oldhtype;
6427  Int_t i, j, first, last, nbins, fixbin;
6428  Double_t c1, yb;
6429  yb = 0;
6430 
6431  strlcpy(chopth, " ",17);
6432 
6433  Double_t ymin = Hparam.ymin;
6434  Double_t ymax = Hparam.ymax;
6435  Double_t baroffset = fH->GetBarOffset();
6436  Double_t barwidth = fH->GetBarWidth();
6437  Double_t baroffsetsave = gStyle->GetBarOffset();
6438  Double_t barwidthsave = gStyle->GetBarWidth();
6439  gStyle->SetBarOffset(baroffset);
6440  gStyle->SetBarWidth(barwidth);
6441 
6442  // Create "LIFE" structure to keep current histogram status
6443 
6444  first = Hparam.xfirst;
6445  last = Hparam.xlast;
6446  nbins = last - first + 1;
6447 
6448  Double_t *keepx = 0;
6449  Double_t *keepy = 0;
6450  if (fXaxis->GetXbins()->fN) fixbin = 0;
6451  else fixbin = 1;
6452  if (fixbin) keepx = new Double_t[2];
6453  else keepx = new Double_t[nbins+1];
6454  keepy = new Double_t[nbins];
6455  Double_t logymin = 0;
6456  if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6457 
6458  // Loop on histogram bins
6459 
6460  for (j=first; j<=last;j++) {
6461  c1 = Hparam.factor*fH->GetBinContent(j);
6462  if (TMath::Abs(ymax-ymin) > 0) {
6463  if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6464  else yb = c1;
6465  }
6466  if (!Hoption.Line) {
6467  yb = TMath::Max(yb, ymin);
6468  yb = TMath::Min(yb, ymax);
6469  }
6470  keepy[j-first] = yb;
6471  }
6472 
6473  // Draw histogram according to value of FillStyle and FillColor
6474 
6475  if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6476  else {
6477  for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6478  keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6479  }
6480 
6481  // Prepare Fill area (systematic with option "Bar").
6482 
6483  oldhtype = fH->GetFillStyle();
6484  htype = oldhtype;
6485  if (Hoption.Bar) {
6486  if (htype == 0 || htype == 1000) htype = 1001;
6487  }
6488 
6489  Width_t lw = (Width_t)fH->GetLineWidth();
6490 
6491  // Code option for GrapHist
6492 
6493  if (Hoption.Line) chopth[0] = 'L';
6494  if (Hoption.Star) chopth[1] = '*';
6495  if (Hoption.Mark) chopth[2] = 'P';
6496  if (Hoption.Mark == 10) chopth[3] = '0';
6497  if (Hoption.Line || Hoption.Curve || Hoption.Hist || Hoption.Bar) {
6498  if (Hoption.Curve) chopth[3] = 'C';
6499  if (Hoption.Hist > 0) chopth[4] = 'H';
6500  else if (Hoption.Bar) chopth[5] = 'B';
6501  if (fH->GetFillColor() && htype) {
6502  if (Hoption.Logy) {
6503  chopth[6] = '1';
6504  }
6505  if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6506  chopth[7] = 'F';
6507  }
6508  }
6509  }
6510  if (!fixbin && strlen(chopth)) {
6511  chopth[8] = 'N';
6512  }
6513 
6514  if (Hoption.Fill == 2) chopth[13] = '2';
6515 
6516  // Option LOGX
6517 
6518  if (Hoption.Logx) {
6519  chopth[9] = 'G';
6520  chopth[10] = 'X';
6521  if (fixbin) {
6522  keepx[0] = TMath::Power(10,keepx[0]);
6523  keepx[1] = TMath::Power(10,keepx[1]);
6524  }
6525  }
6526 
6527  if (Hoption.Off) {
6528  chopth[11] = ']';
6529  chopth[12] = '[';
6530  }
6531 
6532  // Draw the histogram
6533 
6534  TGraph graph;
6535  graph.SetLineWidth(lw);
6536  graph.SetLineStyle(fH->GetLineStyle());
6537  graph.SetLineColor(fH->GetLineColor());
6538  graph.SetFillStyle(htype);
6539  graph.SetFillColor(fH->GetFillColor());
6540  graph.SetMarkerStyle(fH->GetMarkerStyle());
6541  graph.SetMarkerSize(fH->GetMarkerSize());
6542  graph.SetMarkerColor(fH->GetMarkerColor());
6543  if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6544 
6545  graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6546 
6547  delete [] keepx;
6548  delete [] keepy;
6549  gStyle->SetBarOffset(baroffsetsave);
6550  gStyle->SetBarWidth(barwidthsave);
6551 
6552  htype=oldhtype;
6553 }
6554 
6555 ////////////////////////////////////////////////////////////////////////////////
6556 /// [Control function to draw a 3D histograms.](#HP01d)
6557 
6559 {
6560 
6561  char *cmd;
6562  TString opt = option;
6563  opt.ToLower();
6564  Int_t irep;
6565 
6566  if (Hoption.Box || Hoption.Lego) {
6567  if (Hoption.Box == 11 || Hoption.Lego == 11) {
6568  PaintH3Box(1);
6569  } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
6570  PaintH3Box(2);
6571  } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
6572  PaintH3Box(3);
6573  } else {
6574  PaintH3BoxRaster();
6575  }
6576  return;
6577  } else if (strstr(opt,"iso")) {
6578  PaintH3Iso();
6579  return;
6580  } else if (strstr(opt,"tf3")) {
6581  PaintTF3();
6582  return;
6583  } else {
6584  cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6585  }
6586 
6587  if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6588  if (strstr(opt,"bb")) Hoption.BackBox = 0;
6589 
6590  TView *view = gPad->GetView();
6591  if (!view) return;
6592  Double_t thedeg = 90 - gPad->GetTheta();
6593  Double_t phideg = -90 - gPad->GetPhi();
6594  Double_t psideg = view->GetPsi();
6595  view->SetView(phideg, thedeg, psideg, irep);
6596 
6597  // Paint the data
6598  gROOT->ProcessLine(cmd);
6599 
6600  if (Hoption.Same) return;
6601 
6602  // Draw axis
6603  view->SetOutlineToCube();
6604  TSeqCollection *ol = view->GetOutline();
6605  if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6606  Hoption.System = kCARTESIAN;
6607  TGaxis *axis = new TGaxis();
6608  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6609  delete axis;
6610 
6611  // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6612  // be painted with the option colz.
6613  if (fH->GetDrawOption() && strstr(opt,"colz")) {
6614  Int_t ndiv = fH->GetContour();
6615  if (ndiv == 0 ) {
6616  ndiv = gStyle->GetNumberContours();
6617  fH->SetContour(ndiv);
6618  }
6619  PaintPalette();
6620  }
6621 
6622  // Draw title
6623  PaintTitle();
6624 
6625  //Draw stats and fit results
6626  TF1 *fit = 0;
6627  TIter next(fFunctions);
6628  TObject *obj;
6629  while ((obj = next())) {
6630  if (obj->InheritsFrom(TF1::Class())) {
6631  fit = (TF1*)obj;
6632  break;
6633  }
6634  }
6635  if (Hoption.Same != 1) {
6636  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6637  PaintStat3(gStyle->GetOptStat(),fit);
6638  }
6639  }
6640 
6641 }
6642 
6643 ////////////////////////////////////////////////////////////////////////////////
6644 /// Compute histogram parameters used by the drawing routines.
6645 
6647 {
6648 
6649  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6650 
6651  Int_t i;
6652  static const char *where = "PaintInit";
6653  Double_t yMARGIN = gStyle->GetHistTopMargin();
6654  Int_t maximum = 0;
6655  Int_t minimum = 0;
6656  if (fH->GetMaximumStored() != -1111) maximum = 1;
6657  if (fH->GetMinimumStored() != -1111) minimum = 1;
6658 
6659  // Compute X axis parameters
6660 
6661  Int_t last = fXaxis->GetLast();
6662  Int_t first = fXaxis->GetFirst();
6663  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6664  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6665  Hparam.xlast = last;
6666  Hparam.xfirst = first;
6667  Hparam.xmin = Hparam.xlowedge;
6668  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6669 
6670  // if log scale in X, replace xmin,max by the log
6671  if (Hoption.Logx) {
6672  if (Hparam.xmax<=0) {
6673  Error(where, "cannot set X axis to log scale");
6674  return 0;
6675  }
6676  if (Hparam.xlowedge <=0 ) {
6677  if (Hoption.Same) {
6678  Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
6679  } else {
6680  for (i=first; i<=last; i++) {
6681  Double_t binLow = fXaxis->GetBinLowEdge(i);
6682  if (binLow>0) {
6683  Hparam.xlowedge = binLow;
6684  break;
6685  }
6686  if (binLow == 0 && fH->GetBinContent(i) !=0) {
6687  Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6688  break;
6689  }
6690  }
6691  if (Hparam.xlowedge<=0) {
6692  Error(where, "cannot set X axis to log scale");
6693  return 0;
6694  }
6695  }
6696  Hparam.xmin = Hparam.xlowedge;
6697  }
6698  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
6699  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
6700  Hparam.xmin = TMath::Log10(Hparam.xmin);
6701  Hparam.xmax = TMath::Log10(Hparam.xmax);
6702  if (Hparam.xlast > last) Hparam.xlast = last;
6703  if (Hparam.xfirst < first) Hparam.xfirst = first;
6704  }
6705 
6706  // Compute Y axis parameters
6707  Double_t bigp = TMath::Power(10,32);
6708  Double_t ymax = -bigp;
6709  Double_t ymin = bigp;
6710  Double_t c1, e1;
6711  Double_t xv[1];
6712  Double_t fval;
6713  TObject *f;
6714  TF1 *f1;
6715  Double_t allchan = 0;
6716  Int_t nonNullErrors = 0;
6717  TIter next(fFunctions);
6718  for (i=first; i<=last;i++) {
6719  c1 = fH->GetBinContent(i);
6720  ymax = TMath::Max(ymax,c1);
6721  if (Hoption.Logy) {
6722  if (c1 > 0) ymin = TMath::Min(ymin,c1);
6723  } else {
6724  ymin = TMath::Min(ymin,c1);
6725  }
6726  if (Hoption.Error) {
6727  if (fH->GetBinErrorOption() == TH1::kNormal)
6728  e1 = fH->GetBinError(i);
6729  else
6730  e1 = fH->GetBinErrorUp(i);
6731  if (e1 > 0) nonNullErrors++;
6732  ymax = TMath::Max(ymax,c1+e1);
6733  if (fH->GetBinErrorOption() != TH1::kNormal)
6734  e1 = fH->GetBinErrorLow(i);
6735 
6736  if (Hoption.Logy) {
6737  if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6738  } else {
6739  ymin = TMath::Min(ymin,c1-e1);
6740  }
6741  }
6742  if (Hoption.Func) {
6743  xv[0] = fXaxis->GetBinCenter(i);
6744  while ((f = (TObject*) next())) {
6745  if (f->IsA() == TF1::Class()) {
6746  f1 = (TF1*)f;
6747  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6748  fval = f1->Eval(xv[0],0,0);
6749  if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6750  ymax = TMath::Max(ymax,fval);
6751  if (Hoption.Logy) {
6752  if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6753  }
6754  }
6755  }
6756  next.Reset();
6757  }
6758  allchan += c1;
6759  }
6760  if (!nonNullErrors) {
6761  if (Hoption.Error) {
6762  if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
6763  Hoption.Error=0;
6764  }
6765  }
6766 
6767 
6768  // Take into account maximum , minimum
6769 
6770  if (Hoption.Logy && ymin <= 0) {
6771  if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
6772  else ymin = 0.001*ymax;
6773  }
6774 
6775  Double_t xm = ymin;
6776  if (maximum) ymax = fH->GetMaximumStored();
6777  if (minimum) xm = fH->GetMinimumStored();
6778  if (Hoption.Logy && xm < 0) {
6779  Error(where, "log scale requested with a negative argument (%f)", xm);
6780  return 0;
6781  } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
6782  ymin = 0.01;
6783  ymax = 10.;
6784  } else {
6785  ymin = xm;
6786  }
6787 
6788  if (ymin >= ymax) {
6789  if (Hoption.Logy) {
6790  if (ymax > 0) ymin = 0.001*ymax;
6791  else {
6792  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
6793  return 0;
6794  }
6795  }
6796  else {
6797  if (ymin > 0) {
6798  ymin = 0;
6799  ymax *= 2;
6800  } else if (ymin < 0) {
6801  ymax = 0;
6802  ymin *= 2;
6803  } else {
6804  ymin = 0;
6805  ymax = 1;
6806  }
6807  }
6808  }
6809 
6810  // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
6811  if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
6812  ymin = ymin*(1-1E-14);
6813  ymax = ymax*(1+1E-14);
6814  }
6815 
6816  // take into account normalization factor
6817  Hparam.allchan = allchan;
6818  Double_t factor = allchan;
6819  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6820  if (allchan) factor /= allchan;
6821  if (factor == 0) factor = 1;
6822  Hparam.factor = factor;
6823  ymax = factor*ymax;
6824  ymin = factor*ymin;
6825  //just in case the norm factor is negative
6826  // this may happen with a positive norm factor and a negative integral !
6827  if (ymax < ymin) {
6828  Double_t temp = ymax;
6829  ymax = ymin;
6830  ymin = temp;
6831  }
6832 
6833  // For log scales, histogram coordinates are LOG10(ymin) and
6834  // LOG10(ymax). Final adjustment (if not option "Same"
6835  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6836  // Maximum and Minimum are not defined.
6837  if (Hoption.Logy) {
6838  if (ymin <=0 || ymax <=0) {
6839  Error(where, "Cannot set Y axis to log scale");
6840  return 0;
6841  }
6842  ymin = TMath::Log10(ymin);
6843  if (!minimum) ymin += TMath::Log10(0.5);
6844  ymax = TMath::Log10(ymax);
6845  if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
6846  if (!Hoption.Same) {
6847  Hparam.ymin = ymin;
6848  Hparam.ymax = ymax;
6849  }
6850  return 1;
6851  }
6852 
6853  // final adjustment of ymin for linear scale.
6854  // if minimum is not set , then ymin is set to zero if >0
6855  // or to ymin - margin if <0.
6856  if (!minimum) {
6857  if (gStyle->GetHistMinimumZero()) {
6858  if (ymin >= 0) ymin = 0;
6859  else ymin -= yMARGIN*(ymax-ymin);
6860  } else {
6861  Double_t dymin = yMARGIN*(ymax-ymin);
6862  if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
6863  else ymin -= dymin;
6864  }
6865  }
6866 
6867  // final adjustment of YMAXI for linear scale (if not option "Same"):
6868  // decrease histogram height to MAX% of allowed height if HMAXIM
6869  // has not been called.
6870  if (!maximum) {
6871  ymax += yMARGIN*(ymax-ymin);
6872  }
6873 
6874  Hparam.ymin = ymin;
6875  Hparam.ymax = ymax;
6876  return 1;
6877 }
6878 
6879 ////////////////////////////////////////////////////////////////////////////////
6880 /// Compute histogram parameters used by the drawing routines for a rotated pad.
6881 
6883 {
6884 
6885  static const char *where = "PaintInitH";
6886  Double_t yMARGIN = gStyle->GetHistTopMargin();
6887  Int_t maximum = 0;
6888  Int_t minimum = 0;
6889  if (fH->GetMaximumStored() != -1111) maximum = 1;
6890  if (fH->GetMinimumStored() != -1111) minimum = 1;
6891 
6892  // Compute X axis parameters
6893 
6894  Int_t last = fXaxis->GetLast();
6895  Int_t first = fXaxis->GetFirst();
6896  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6897  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6898  Hparam.xlast = last;
6899  Hparam.xfirst = first;
6900  Hparam.ymin = Hparam.xlowedge;
6901  Hparam.ymax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6902 
6903  // if log scale in Y, replace ymin,max by the log
6904  if (Hoption.Logy) {
6905  if (Hparam.xlowedge <=0 ) {
6906  Hparam.xlowedge = 0.1*Hparam.xbinsize;
6907  Hparam.ymin = Hparam.xlowedge;
6908  }
6909  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
6910  Error(where, "cannot set Y axis to log scale");
6911  return 0;
6912  }
6913  Hparam.xfirst= fXaxis->FindFixBin(Hparam.ymin);
6914  Hparam.xlast = fXaxis->FindFixBin(Hparam.ymax);
6915  Hparam.ymin = TMath::Log10(Hparam.ymin);
6916  Hparam.ymax = TMath::Log10(Hparam.ymax);
6917  if (Hparam.xlast > last) Hparam.xlast = last;
6918  }
6919 
6920  // Compute Y axis parameters
6921  Double_t bigp = TMath::Power(10,32);
6922  Double_t xmax = -bigp;
6923  Double_t xmin = bigp;
6924  Double_t c1, e1;
6925  Double_t xv[1];
6926  Double_t fval;
6927  Int_t i;
6928  TObject *f;
6929  TF1 *f1;
6930  Double_t allchan = 0;
6931  TIter next(fFunctions);
6932  for (i=first; i<=last;i++) {
6933  c1 = fH->GetBinContent(i);
6934  xmax = TMath::Max(xmax,c1);
6935  xmin = TMath::Min(xmin,c1);
6936  if (Hoption.Error) {
6937  e1 = fH->GetBinError(i);
6938  xmax = TMath::Max(xmax,c1+e1);
6939  xmin = TMath::Min(xmin,c1-e1);
6940  }
6941  if (Hoption.Func) {
6942  xv[0] = fXaxis->GetBinCenter(i);
6943  while ((f = (TObject*) next())) {
6944  if (f->IsA() == TF1::Class()) {
6945  f1 = (TF1*)f;
6946  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6947  fval = f1->Eval(xv[0],0,0);
6948  xmax = TMath::Max(xmax,fval);
6949  if (Hoption.Logy) {
6950  if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
6951  }
6952  }
6953  }
6954  next.Reset();
6955  }
6956  allchan += c1;
6957  }
6958 
6959  // Take into account maximum , minimum
6960 
6961  if (Hoption.Logx && xmin <= 0) {
6962  if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
6963  else xmin = 0.001*xmax;
6964  }
6965  Double_t xm = xmin;
6966  if (maximum) xmax = fH->GetMaximumStored();
6967  if (minimum) xm = fH->GetMinimumStored();
6968  if (Hoption.Logx && xm <= 0) {
6969  Error(where, "log scale requested with zero or negative argument (%f)", xm);
6970  return 0;
6971  }
6972  else xmin = xm;
6973  if (xmin >= xmax) {
6974  if (Hoption.Logx) {
6975  if (xmax > 0) xmin = 0.001*xmax;
6976  else {
6977  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
6978  return 0;
6979  }
6980  }
6981  else {
6982  if (xmin > 0) {
6983  xmin = 0;
6984  xmax *= 2;
6985  } else if (xmin < 0) {
6986  xmax = 0;
6987  xmin *= 2;
6988  } else {
6989  xmin = -1;
6990  xmax = 1;
6991  }
6992  }
6993  }
6994 
6995  // take into account normalization factor
6996  Hparam.allchan = allchan;
6997  Double_t factor = allchan;
6998  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6999  if (allchan) factor /= allchan;
7000  if (factor == 0) factor = 1;
7001  Hparam.factor = factor;
7002  xmax = factor*xmax;
7003  xmin = factor*xmin;
7004 
7005  // For log scales, histogram coordinates are LOG10(ymin) and
7006  // LOG10(ymax). Final adjustment (if not option "Same"
7007  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7008  // Maximum and Minimum are not defined.
7009  if (Hoption.Logx) {
7010  if (xmin <=0 || xmax <=0) {
7011  Error(where, "Cannot set Y axis to log scale");
7012  return 0;
7013  }
7014  xmin = TMath::Log10(xmin);
7015  if (!minimum) xmin += TMath::Log10(0.5);
7016  xmax = TMath::Log10(xmax);
7017  if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7018  if (!Hoption.Same) {
7019  Hparam.xmin = xmin;
7020  Hparam.xmax = xmax;
7021  }
7022  return 1;
7023  }
7024 
7025  // final adjustment of ymin for linear scale.
7026  // if minimum is not set , then ymin is set to zero if >0
7027  // or to ymin - margin if <0.
7028  if (!minimum) {
7029  if (xmin >= 0) xmin = 0;
7030  else xmin -= yMARGIN*(xmax-xmin);
7031  }
7032 
7033  // final adjustment of YMAXI for linear scale (if not option "Same"):
7034  // decrease histogram height to MAX% of allowed height if HMAXIM
7035  // has not been called.
7036  if (!maximum) {
7037  xmax += yMARGIN*(xmax-xmin);
7038  }
7039  Hparam.xmin = xmin;
7040  Hparam.xmax = xmax;
7041  return 1;
7042 }
7043 
7044 ////////////////////////////////////////////////////////////////////////////////
7045 /// [Control function to draw a 3D histogram with boxes.](#HP25)
7046 
7048 {
7049  // Predefined box structure
7050  Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7051  {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7052  Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7053  {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7054 
7055  // Define dimensions of world space
7056  TGaxis *axis = new TGaxis();
7057  TAxis *xaxis = fH->GetXaxis();
7058  TAxis *yaxis = fH->GetYaxis();
7059  TAxis *zaxis = fH->GetZaxis();
7060 
7061  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7062  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7063  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7064  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7065  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7066  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7067 
7069 
7070  // Set view
7071  TView *view = gPad->GetView();
7072  if (!view) {
7073  Error("PaintH3", "no TView in current pad");
7074  return;
7075  }
7076  Double_t thedeg = 90 - gPad->GetTheta();
7077  Double_t phideg = -90 - gPad->GetPhi();
7078  Double_t psideg = view->GetPsi();
7079  Int_t irep;
7080  view->SetView(phideg, thedeg, psideg, irep);
7081 
7082  Int_t backcolor = gPad->GetFrameFillColor();
7083  view->PadRange(backcolor);
7084 
7085  // Draw back surfaces of frame box
7086  fLego->InitMoveScreen(-1.1,1.1);
7087  if (Hoption.BackBox) {
7090  fLego->BackBox(90);
7091  }
7092 
7094 
7095  // Define order of drawing
7096  Double_t *tnorm = view->GetTnorm();
7097  if (!tnorm) return;
7098  Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7099  Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7100  Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7101  Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7102  Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7103  Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7104  Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7105  Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7106  Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7107 
7108  // Set graphic attributes (colour, style, etc.)
7109  Style_t fillsav = fH->GetFillStyle();
7110  Style_t colsav = fH->GetFillColor();
7111  Style_t coldark = TColor::GetColorDark(colsav);
7112  Style_t colbright = TColor::GetColorBright(colsav);
7113 
7114  fH->SetFillStyle(1001);
7115  fH->TAttFill::Modify();
7116  fH->TAttLine::Modify();
7117  Int_t ncolors = gStyle->GetNumberOfColors();
7118  Int_t theColor;
7119 
7120  // Create bin boxes and draw
7121  Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7123  TMath::Abs(fH->GetMinimum()));
7124 
7125  Double_t pmin[3], pmax[3], sxyz[8][3];
7126  for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7127  pmin[0] = xaxis->GetBinLowEdge(ix);
7128  pmax[0] = xaxis->GetBinUpEdge(ix);
7129  for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7130  pmin[1] = yaxis->GetBinLowEdge(iy);
7131  pmax[1] = yaxis->GetBinUpEdge(iy);
7132  for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7133  pmin[2] = zaxis->GetBinLowEdge(iz);
7134  pmax[2] = zaxis->GetBinUpEdge(iz);
7135  Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7136  Bool_t neg = kFALSE;
7137  Int_t n = 5;
7138  if (w<0) {
7139  w = -w;
7140  neg = kTRUE;
7141  }
7142  if (w < wmin) continue;
7143  if (w > wmax) w = wmax;
7144  Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7145  if (scale == 0) continue;
7146  for (Int_t i=0; i<3; ++i) {
7147  Double_t c = (pmax[i] + pmin[i])*0.5;
7148  Double_t d = (pmax[i] - pmin[i])*scale;
7149  for (Int_t k=0; k<8; ++k) { // set bin box vertices
7150  sxyz[k][i] = wxyz[k][i]*d + c;
7151  }
7152  }
7153  for (Int_t k=0; k<8; ++k) { // transform to normalized space
7154  view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7155  }
7156  Double_t x[8], y[8]; // draw bin box faces
7157  for (Int_t k=0; k<6; ++k) {
7158  for (Int_t i=0; i<4; ++i) {
7159  Int_t iv = iface[k][i];
7160  x[i] = sxyz[iv][0];
7161  y[i] = sxyz[iv][1];
7162  }
7163  x[4] = x[0] ; y[4] = y[0];
7164  if (neg) {
7165  x[5] = x[2] ; y[5] = y[2];
7166  x[6] = x[3] ; y[6] = y[3];
7167  x[7] = x[1] ; y[7] = y[1];
7168  n = 8;
7169  } else {
7170  n = 5;
7171  }
7172  Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7173  if (z <= 0.) continue;
7174  if (iopt == 2) {
7175  theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7176  fH->SetFillColor(gStyle->GetColorPalette(theColor));
7177  } else {
7178  if (k == 3 || k == 5) {
7179  fH->SetFillColor(coldark);
7180  } else if (k == 0 || k == 1) {
7181  fH->SetFillColor(colbright);
7182  } else {
7183  fH->SetFillColor(colsav);
7184  }
7185  }
7186  fH->TAttFill::Modify();
7187  gPad->PaintFillArea(4, x, y);
7188  if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7189  }
7190  }
7191  }
7192  }
7193 
7194  // Draw front surfaces of frame box
7195  if (Hoption.FrontBox) fLego->FrontBox(90);
7196 
7197  // Draw axis and title
7198  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7199  PaintTitle();
7200 
7201  // Draw palette. if needed.
7202  if (Hoption.Zscale) {
7203  Int_t ndiv = fH->GetContour();
7204  if (ndiv == 0 ) {
7205  ndiv = gStyle->GetNumberContours();
7206  fH->SetContour(ndiv);
7207  }
7208  PaintPalette();
7209  }
7210 
7211  delete axis;
7212  delete fLego; fLego = 0;
7213 
7214  fH->SetFillStyle(fillsav);
7215  fH->SetFillColor(colsav);
7216  fH->TAttFill::Modify();
7217 }
7218 
7219 ////////////////////////////////////////////////////////////////////////////////
7220 /// [Control function to draw a 3D histogram with boxes.](#HP25)
7221 
7223 {
7224  // Predefined box structure
7225  Double_t wxyz[8][3] = {
7226  {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7227  {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7228  };
7229  Int_t iface[6][4] = {
7230  {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7231  {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7232  };
7233  Double_t normal[6][3] = {
7234  {0,0,-1}, {0,0,1}, // Z-, Z+
7235  {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7236  };
7237 
7238  // Define dimensions of world space
7239  TGaxis *axis = new TGaxis();
7240  TAxis *xaxis = fH->GetXaxis();
7241  TAxis *yaxis = fH->GetYaxis();
7242  TAxis *zaxis = fH->GetZaxis();
7243 
7244  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7245  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7246  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7247  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7248  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7249  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7250 
7252 
7253  // Set view
7254  TView *view = gPad->GetView();
7255  if (!view) {
7256  Error("PaintH3", "no TView in current pad");
7257  return;
7258  }
7259  Double_t thedeg = 90 - gPad->GetTheta();
7260  Double_t phideg = -90 - gPad->GetPhi();
7261  Double_t psideg = view->GetPsi();
7262  Int_t irep;
7263  view->SetView(phideg, thedeg, psideg, irep);
7264 
7265  Int_t backcolor = gPad->GetFrameFillColor();
7266  view->PadRange(backcolor);
7267 
7268  // Draw front surfaces of frame box
7269  if (Hoption.FrontBox) {
7270  fLego->InitMoveScreen(-1.1,1.1);
7272  }
7273 
7274  // Initialize hidden line removal algorithm "raster screen"
7275  fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7276 
7277  // Define order of drawing
7278  Double_t *tnorm = view->GetTnorm();
7279  if (!tnorm) return;
7280  Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7281  Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7282  Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7283  Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7284  Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7285  Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7286  Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7287  Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7288  Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7289 
7290  // Set line attributes (colour, style, etc.)
7291  fH->TAttLine::Modify();
7292 
7293  // Create bin boxes and draw
7294  const Int_t NTMAX = 100;
7295  Double_t tt[NTMAX][2];
7296  Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7298  TMath::Abs(fH->GetMinimum()));
7299  Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7300  for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7301  pmin[0] = xaxis->GetBinLowEdge(ix);
7302  pmax[0] = xaxis->GetBinUpEdge(ix);
7303  for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7304  pmin[1] = yaxis->GetBinLowEdge(iy);
7305  pmax[1] = yaxis->GetBinUpEdge(iy);
7306  for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7307  pmin[2] = zaxis->GetBinLowEdge(iz);
7308  pmax[2] = zaxis->GetBinUpEdge(iz);
7309  Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7310  Bool_t neg = kFALSE;
7311  if (w<0) {
7312  w = -w;
7313  neg = kTRUE;
7314  }
7315  if (w < wmin) continue;
7316  if (w > wmax) w = wmax;
7317  Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7318  if (scale == 0) continue;
7319  for (Int_t i=0; i<3; ++i) {
7320  Double_t c = (pmax[i] + pmin[i])*0.5;
7321  Double_t d = (pmax[i] - pmin[i])*scale;
7322  for (Int_t k=0; k<8; ++k) { // set bin box vertices
7323  sxyz[k][i] = wxyz[k][i]*d + c;
7324  }
7325  }
7326  for (Int_t k=0; k<8; ++k) { // transform to normalized space
7327  view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7328  }
7329  for (Int_t k=0; k<6; ++k) { // draw box faces
7330  Double_t zn;
7331  view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7332  if (zn <= 0) continue;
7333  for (Int_t i=0; i<4; ++i) {
7334  Int_t ip = iface[k][i];
7335  pp[i][0] = sxyz[ip][0];
7336  pp[i][1] = sxyz[ip][1];
7337  }
7338  for (Int_t i=0; i<4; ++i) {
7339  Int_t i1 = i;
7340  Int_t i2 = (i == 3) ? 0 : i + 1;
7341  Int_t nt;
7342  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7343  Double_t xdel = pp[i2][0] - pp[i1][0];
7344  Double_t ydel = pp[i2][1] - pp[i1][1];
7345  Double_t x[2], y[2];
7346  for (Int_t it = 0; it < nt; ++it) {
7347  x[0] = pp[i1][0] + xdel*tt[it][0];
7348  y[0] = pp[i1][1] + ydel*tt[it][0];
7349  x[1] = pp[i1][0] + xdel*tt[it][1];
7350  y[1] = pp[i1][1] + ydel*tt[it][1];
7351  gPad->PaintPolyLine(2, x, y);
7352  }
7353  }
7354  if (neg) {
7355  Int_t i1 = 0;
7356  Int_t i2 = 2;
7357  Int_t nt;
7358  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7359  Double_t xdel = pp[i2][0] - pp[i1][0];
7360  Double_t ydel = pp[i2][1] - pp[i1][1];
7361  Double_t x[2], y[2];
7362  for (Int_t it = 0; it < nt; ++it) {
7363  x[0] = pp[i1][0] + xdel*tt[it][0];
7364  y[0] = pp[i1][1] + ydel*tt[it][0];
7365  x[1] = pp[i1][0] + xdel*tt[it][1];
7366  y[1] = pp[i1][1] + ydel*tt[it][1];
7367  gPad->PaintPolyLine(2, x, y);
7368  }
7369  i1 = 1;
7370  i2 = 3;
7371  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7372  xdel = pp[i2][0] - pp[i1][0];
7373  ydel = pp[i2][1] - pp[i1][1];
7374  for (Int_t it = 0; it < nt; ++it) {
7375  x[0] = pp[i1][0] + xdel*tt[it][0];
7376  y[0] = pp[i1][1] + ydel*tt[it][0];
7377  x[1] = pp[i1][0] + xdel*tt[it][1];
7378  y[1] = pp[i1][1] + ydel*tt[it][1];
7379  gPad->PaintPolyLine(2, x, y);
7380  }
7381  }
7382  fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7383  }
7384  }
7385  }
7386  }
7387 
7388  // Draw frame box
7389  if (Hoption.BackBox) {
7392  fLego->BackBox(90);
7393  }
7394 
7395  if (Hoption.FrontBox) fLego->FrontBox(90);
7396 
7397  // Draw axis and title
7398  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7399  PaintTitle();
7400 
7401  delete axis;
7402  delete fLego; fLego = 0;
7403 }
7404 
7405 ////////////////////////////////////////////////////////////////////////////////
7406 /// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7407 
7409 {
7410 
7411  const Double_t ydiff = 1;
7412  const Double_t yligh1 = 10;
7413  const Double_t qa = 0.15;
7414  const Double_t qd = 0.15;
7415  const Double_t qs = 0.8;
7416  Double_t fmin, fmax;
7417  Int_t i, irep;
7418  Int_t nbcol = 28;
7419  Int_t icol1 = 201;
7420  Int_t ic1 = icol1;
7421  Int_t ic2 = ic1+nbcol;
7422  Int_t ic3 = ic2+nbcol;
7423 
7424  TGaxis *axis = new TGaxis();
7425  TAxis *xaxis = fH->GetXaxis();
7426  TAxis *yaxis = fH->GetYaxis();
7427  TAxis *zaxis = fH->GetZaxis();
7428 
7429  Int_t nx = fH->GetNbinsX();
7430  Int_t ny = fH->GetNbinsY();
7431  Int_t nz = fH->GetNbinsZ();
7432 
7433  Double_t *x = new Double_t[nx];
7434  Double_t *y = new Double_t[ny];
7435  Double_t *z = new Double_t[nz];
7436 
7437  for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7438  for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7439  for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7440 
7441  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7442  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7443  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7444  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7445  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7446  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7447 
7448  Double_t s[3];
7449  s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7450  s[1] = 0.5*s[0];
7451  s[2] = 1.5*s[0];
7452 
7454 
7455  TView *view = gPad->GetView();
7456  if (!view) {
7457  Error("PaintH3Iso", "no TView in current pad");
7458  delete [] x;
7459  delete [] y;
7460  delete [] z;
7461  return;
7462  }
7463  Double_t thedeg = 90 - gPad->GetTheta();
7464  Double_t phideg = -90 - gPad->GetPhi();
7465  Double_t psideg = view->GetPsi();
7466  view->SetView(phideg, thedeg, psideg, irep);
7467 
7468  Int_t backcolor = gPad->GetFrameFillColor();
7469  if (Hoption.System != kCARTESIAN) backcolor = 0;
7470  view->PadRange(backcolor);
7471 
7472  Double_t dcol = 0.5/Double_t(nbcol);
7473  TColor *colref = gROOT->GetColor(fH->GetFillColor());
7474  if (!colref) {
7475  delete [] x;
7476  delete [] y;
7477  delete [] z;
7478  return;
7479  }
7480  Float_t r, g, b, hue, light, satur;
7481  colref->GetRGB(r,g,b);
7482  TColor::RGBtoHLS(r,g,b,hue,light,satur);
7483  TColor *acol;
7484  for (Int_t col=0;col<nbcol;col++) {
7485  acol = gROOT->GetColor(col+icol1);
7486  TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7487  if (acol) acol->SetRGB(r, g, b);
7488  }
7489 
7490  fLego->InitMoveScreen(-1.1,1.1);
7491 
7492  if (Hoption.BackBox) {
7495  fLego->BackBox(90);
7496  }
7497 
7498  fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7499  fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7500  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7501  fmin = ydiff*qa;
7502  fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7503  fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7504 
7505  fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7506 
7507  if (Hoption.FrontBox) {
7508  fLego->InitMoveScreen(-1.1,1.1);
7510  fLego->FrontBox(90);
7511  }
7512  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7513 
7514  PaintTitle();
7515 
7516  delete axis;
7517  delete fLego; fLego = 0;
7518  delete [] x;
7519  delete [] y;
7520  delete [] z;
7521 }
7522 
7523 ////////////////////////////////////////////////////////////////////////////////
7524 /// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7525 
7527 {
7528 
7529  Int_t raster = 1;
7530  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7531  Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7532  Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7533  Double_t zmin = Hparam.zmin;
7534  Double_t zmax = Hparam.zmax;
7535  Double_t xlab1 = Hparam.xmin;
7536  Double_t xlab2 = Hparam.xmax;
7537  Double_t ylab1 = Hparam.ymin;
7538  Double_t ylab2 = Hparam.ymax;
7539  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7540  Double_t deltaz = TMath::Abs(zmin);
7541  if (deltaz == 0) deltaz = 1;
7542  if (zmin >= zmax) {
7543  zmin -= 0.5*deltaz;
7544  zmax += 0.5*deltaz;
7545  }
7546  Double_t z1c = zmin;
7547  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7548 
7549  // Compute the lego limits and instantiate a lego object
7550  fXbuf[0] = -1;
7551  fYbuf[0] = 1;
7552  fXbuf[1] = -1;
7553  fYbuf[1] = 1;
7554  if (Hoption.System == kPOLAR) {
7555  fXbuf[2] = z1c;
7556  fYbuf[2] = z2c;
7557  } else if (Hoption.System == kCYLINDRICAL) {
7558  if (Hoption.Logy) {
7559  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7560  else fXbuf[2] = 0;
7561  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7562  else fYbuf[2] = 0;
7563  } else {
7564  fXbuf[2] = ylab1;
7565  fYbuf[2] = ylab2;
7566  }
7567  z1c = 0; z2c = 1;
7568  } else if (Hoption.System == kSPHERICAL) {
7569  fXbuf[2] = -1;
7570  fYbuf[2] = 1;
7571  z1c = 0; z2c = 1;
7572  } else if (Hoption.System == kRAPIDITY) {
7573  fXbuf[2] = -1/TMath::Tan(dangle);
7574  fYbuf[2] = 1/TMath::Tan(dangle);
7575  } else {
7576  fXbuf[0] = xlab1;
7577  fYbuf[0] = xlab2;
7578  fXbuf[1] = ylab1;
7579  fYbuf[1] = ylab2;
7580  fXbuf[2] = z1c;
7581  fYbuf[2] = z2c;
7582  raster = 0;
7583  }
7584 
7585  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
7586 
7587  Int_t nids = -1;
7588  TH1 * hid = NULL;
7589  Color_t colormain = -1, colordark = -1;
7590  Bool_t drawShadowsInLego1 = kTRUE;
7591 
7592  // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7593  if (Hoption.Lego == 13) {
7594  Hoption.Lego = 11;
7595  fLego->SetMesh(0);
7596  }
7597  // LEGO4 is like LEGO1 except no shadows are drawn.
7598  if (Hoption.Lego == 14) {
7599  Hoption.Lego = 11;
7600  drawShadowsInLego1 = kFALSE;
7601  }
7602 
7603  // Create axis object
7604 
7605  TGaxis *axis = new TGaxis();
7606 
7607  // Initialize the levels on the Z axis
7608  Int_t ndiv = fH->GetContour();
7609  if (ndiv == 0 ) {
7610  ndiv = gStyle->GetNumberContours();
7611  fH->SetContour(ndiv);
7612  }
7613  Int_t ndivz = TMath::Abs(ndiv);
7614  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7615 
7616  // Initialize colors
7617  if (!fStack) {
7619  } else {
7620  for (Int_t id=0;id<=fStack->GetSize();id++) {
7621  hid = (TH1*)fStack->At((id==0)?id:id-1);
7622  fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
7623  }
7624  }
7625 
7626  if (Hoption.Lego == 11) {
7627  nids = 1;
7628  if (fStack) nids = fStack->GetSize();
7629  hid = fH;
7630  for (Int_t id=0;id<=nids;id++) {
7631  if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7632  colormain = hid->GetFillColor();
7633  if (colormain == 1) colormain = 17; //avoid drawing with black
7634  if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7635  else colordark = colormain;
7636  fLego->SetColorMain(colormain,id);
7637  fLego->SetColorDark(colordark,id);
7638  if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7639  if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7640  }
7641  }
7642 
7643  // Now ready to draw the lego plot
7644  Int_t irep = 0;
7645 
7646  TView *view = gPad->GetView();
7647  if (!view) {
7648  Error("PaintLego", "no TView in current pad");
7649  return;
7650  }
7651 
7652  Double_t thedeg = 90 - gPad->GetTheta();
7653  Double_t phideg = -90 - gPad->GetPhi();
7654  Double_t psideg = view->GetPsi();
7655  view->SetView(phideg, thedeg, psideg, irep);
7656 
7657  fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7659 
7660  // Set color/style for back box
7661  fLego->SetFillStyle(gPad->GetFrameFillStyle());
7662  fLego->SetFillColor(gPad->GetFrameFillColor());
7663  fLego->TAttFill::Modify();
7664 
7665  Int_t backcolor = gPad->GetFrameFillColor();
7666  if (Hoption.System != kCARTESIAN) backcolor = 0;
7667  view->PadRange(backcolor);
7668 
7671  fLego->TAttFill::Modify();
7672 
7674 
7675  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7676  else fLego->InitMoveScreen(-1.1,1.1);
7677 
7678  if (Hoption.Lego == 19) {
7680  if (Hoption.BackBox) fLego->BackBox(90);
7681  if (Hoption.FrontBox) fLego->FrontBox(90);
7682  if (!Hoption.Axis) PaintLegoAxis(axis, 90);
7683  return;
7684  }
7685 
7686  if (Hoption.Lego == 11 || Hoption.Lego == 12) {
7687  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7689  fLego->BackBox(90);
7690  }
7691  }
7692 
7693  if (Hoption.Lego == 12) DefineColorLevels(ndivz);
7694 
7699  if (Hoption.System == kPOLAR) {
7700  if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
7701  if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
7702  if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
7703  } else if (Hoption.System == kCYLINDRICAL) {
7704  if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
7705  if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
7706  if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
7707  } else if (Hoption.System == kSPHERICAL) {
7708  if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
7709  if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
7710  if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
7711  } else if (Hoption.System == kRAPIDITY) {
7712  if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
7713  if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
7714  if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
7715  } else {
7716  if (Hoption.Lego == 1) {
7718  fLego->LegoCartesian(90,nx,ny,"FB");}
7719  if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
7720  if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
7721  }
7722 
7723  if (Hoption.Lego == 1 || Hoption.Lego == 11) {
7724  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7726  fLego->BackBox(90);
7727  }
7728  }
7729  if (Hoption.System == kCARTESIAN) {
7730  fLego->InitMoveScreen(-1.1,1.1);
7732  if (Hoption.FrontBox) fLego->FrontBox(90);
7733  }
7734  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7735  if (Hoption.Zscale) PaintPalette();
7736  delete axis;
7737  delete fLego; fLego = 0;
7738 }
7739 
7740 ////////////////////////////////////////////////////////////////////////////////
7741 /// Draw the axis for legos and surface plots.
7742 
7744 {
7745 
7746  static Double_t epsil = 0.001;
7747 
7748  Double_t cosa, sina;
7749  Double_t bmin, bmax;
7750  Double_t r[24] /* was [3][8] */;
7751  Int_t ndivx, ndivy, ndivz, i;
7752  Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
7753  static char chopax[8], chopay[8], chopaz[8];
7754  Int_t ix1, ix2, iy1, iy2, iz1, iz2;
7755  Double_t rad;
7756 
7757  TView *view = gPad->GetView();
7758  if (!view) {
7759  Error("PaintLegoAxis", "no TView in current pad");
7760  return;
7761  }
7762 
7763  // In polar coordinates, draw a short line going from the external circle
7764  // corresponding to r = 1 up to r = 1.1
7765  if (Hoption.System == kPOLAR) {
7766  r[0] = 1;
7767  r[1] = 0;
7768  r[2] = 0;
7769  view->WCtoNDC(r, x1);
7770  r[0] = 1.1;
7771  r[1] = 0;
7772  r[2] = 0;
7773  view->WCtoNDC(r, x2);
7774  gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
7775  return;
7776  }
7777 
7778  if (Hoption.System != kCARTESIAN) return;
7779 
7780  rad = TMath::ATan(1.) * 4. /180.;
7781  cosa = TMath::Cos(ang*rad);
7782  sina = TMath::Sin(ang*rad);
7783 
7784  view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
7785  for (i = 1; i <= 8; ++i) {
7786  r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
7787  r[i*3 - 2] = av[i*3 - 2]*sina;
7788  r[i*3 - 1] = av[i*3 - 1];
7789  }
7790 
7791  view->WCtoNDC(&r[ix1*3 - 3], x1);
7792  view->WCtoNDC(&r[ix2*3 - 3], x2);
7793  view->WCtoNDC(&r[iy1*3 - 3], y1);
7794  view->WCtoNDC(&r[iy2*3 - 3], y2);
7795  view->WCtoNDC(&r[iz1*3 - 3], z1);
7796  view->WCtoNDC(&r[iz2*3 - 3], z2);
7797 
7798  view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
7799 
7800  Double_t *rmin = view->GetRmin();
7801  Double_t *rmax = view->GetRmax();
7802  if (!rmin || !rmax) return;
7803 
7804  // Initialize the axis options
7805  if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
7806  else strlcpy(chopax, "SDH=-",8);
7807  if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
7808  else strlcpy(chopay, "SDH=-",8);
7809  if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
7810  else strlcpy(chopaz, "SDH=-",8);
7811 
7812  // Option LOG is required ?
7813  if (Hoption.Logx) strlcat(chopax,"G",8);
7814  if (Hoption.Logy) strlcat(chopay,"G",8);
7815  if (Hoption.Logz) strlcat(chopaz,"G",8);
7816 
7817  // Initialize the number of divisions. If the
7818  // number of divisions is negative, option 'N' is required.
7819  ndivx = fXaxis->GetNdivisions();
7820  ndivy = fYaxis->GetNdivisions();
7821  ndivz = fZaxis->GetNdivisions();
7822  if (ndivx < 0) {
7823  ndivx = TMath::Abs(ndivx);
7824  strlcat(chopax, "N",8);
7825  }
7826  if (ndivy < 0) {
7827  ndivy = TMath::Abs(ndivy);
7828  strlcat(chopay, "N",8);
7829  }
7830  if (ndivz < 0) {
7831  ndivz = TMath::Abs(ndivz);
7832  strlcat(chopaz, "N",8);
7833  }
7834 
7835  // Set Axis attributes.
7836  // The variable SCALE rescales the VSIZ
7837  // in order to have the same label size for all angles.
7838 
7839  axis->SetLineWidth(1);
7840 
7841  // X axis drawing
7842  if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
7845  if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
7846  bmin = TMath::Power(10, rmin[0]);
7847  bmax = TMath::Power(10, rmax[0]);
7848  } else {
7849  bmin = rmin[0];
7850  bmax = rmax[0];
7851  }
7852  // Option time display is required ?
7853  if (fXaxis->GetTimeDisplay()) {
7854  strlcat(chopax,"t",8);
7855  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
7856  axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
7857  } else {
7859  }
7860  }
7861  axis->SetOption(chopax);
7862  axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
7863  }
7864 
7865  // Y axis drawing
7866  if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
7869  if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
7870 
7871  if (fH->GetDimension() < 2) {
7872  strlcpy(chopay, "V=+UN",8);
7873  ndivy = 0;
7874  }
7875  if (TMath::Abs(y1[0] - y2[0]) < epsil) {
7876  y2[0] = y1[0];
7877  }
7878  if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
7879  bmin = TMath::Power(10, rmin[1]);
7880  bmax = TMath::Power(10, rmax[1]);
7881  } else {
7882  bmin = rmin[1];
7883  bmax = rmax[1];
7884  }
7885  // Option time display is required ?
7886  if (fYaxis->GetTimeDisplay()) {
7887  strlcat(chopay,"t",8);
7888  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
7889  axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
7890  } else {
7892  }
7893  }
7894  axis->SetOption(chopay);
7895  axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
7896  }
7897 
7898  // Z axis drawing
7899  if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
7901  if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
7902  bmin = TMath::Power(10, rmin[2]);
7903  bmax = TMath::Power(10, rmax[2]);
7904  } else {
7905  bmin = rmin[2];
7906  bmax = rmax[2];
7907  }
7908  // Option time display is required ?
7909  if (fZaxis->GetTimeDisplay()) {
7910  strlcat(chopaz,"t",8);
7911  if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
7912  axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
7913  } else {
7915  }
7916  }
7917  axis->SetOption(chopaz);
7918  axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
7919  }
7920 
7921  //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
7922 }
7923 
7924 ////////////////////////////////////////////////////////////////////////////////
7925 /// [Paint the color palette on the right side of the pad.](#HP22)
7926 
7928 {
7929 
7930  TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
7931  TView *view = gPad->GetView();
7932  if (palette) {
7933  if (view) {
7934  if (!palette->TestBit(TPaletteAxis::kHasView)) {
7935  fFunctions->Remove(palette);
7936  delete palette; palette = 0;
7937  }
7938  } else {
7939  if (palette->TestBit(TPaletteAxis::kHasView)) {
7940  fFunctions->Remove(palette);
7941  delete palette; palette = 0;
7942  }
7943  }
7944  // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
7945  if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
7946  }
7947 
7948  if (!palette) {
7949  Double_t xup = gPad->GetUxmax();
7950  Double_t x2 = gPad->PadtoX(gPad->GetX2());
7951  Double_t ymin = gPad->PadtoY(gPad->GetUymin());
7952  Double_t ymax = gPad->PadtoY(gPad->GetUymax());
7953  Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
7954  Double_t xmin = gPad->PadtoX(xup +0.1*xr);
7955  Double_t xmax = gPad->PadtoX(xup + xr);
7956  if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
7957  palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
7958  fFunctions->AddFirst(palette);
7959  palette->Paint();
7960  }
7961 }
7962 
7963 ////////////////////////////////////////////////////////////////////////////////
7964 /// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
7965 
7967 {
7968 
7969  fH->TAttMarker::Modify();
7970 
7971  Int_t k, marker;
7972  Double_t dz, z, xk,xstep, yk, ystep;
7973  Double_t scale = 1;
7974  Bool_t ltest = kFALSE;
7975  Double_t zmax = fH->GetMaximum();
7976  Double_t zmin = fH->GetMinimum();
7977  if (zmin == 0 && zmax == 0) return;
7978  if (zmin == zmax) {
7979  zmax += 0.1*TMath::Abs(zmax);
7980  zmin -= 0.1*TMath::Abs(zmin);
7981  }
7982  Int_t ncells = (Hparam.ylast-Hparam.yfirst)*(Hparam.xlast-Hparam.xfirst);
7983  if (Hoption.Logz) {
7984  if (zmin > 0) zmin = TMath::Log10(zmin);
7985  else zmin = 0;
7986  if (zmax > 0) zmax = TMath::Log10(zmax);
7987  else zmax = 0;
7988  if (zmin == 0 && zmax == 0) return;
7989  dz = zmax - zmin;
7990  scale = 100/dz;
7991  if (ncells > 10000) scale /= 5;
7992  ltest = kTRUE;
7993  } else {
7994  dz = zmax - zmin;
7995  if (dz >= kNMAX || zmax < 1) {
7996  scale = (kNMAX-1)/dz;
7997  if (ncells > 10000) scale /= 5;
7998  ltest = kTRUE;
7999  }
8000  }
8001  if (fH->GetMinimumStored() == -1111) {
8002  Double_t yMARGIN = gStyle->GetHistTopMargin();
8003  if (gStyle->GetHistMinimumZero()) {
8004  if (zmin >= 0) zmin = 0;
8005  else zmin -= yMARGIN*(zmax-zmin);
8006  } else {
8007  Double_t dzmin = yMARGIN*(zmax-zmin);
8008  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8009  else zmin -= dzmin;
8010  }
8011  }
8012 
8013  TString opt = option;
8014  opt.ToLower();
8015  if (opt.Contains("scat=")) {
8016  char optscat[100];
8017  strlcpy(optscat,opt.Data(),100);
8018  char *oscat = strstr(optscat,"scat=");
8019  char *blank = strstr(oscat," "); if (blank) *blank = 0;
8020  sscanf(oscat+5,"%lg",&scale);
8021  }
8022  // use an independent instance of a random generator
8023  // instead of gRandom to avoid conflicts and
8024  // to get same random numbers when drawing the same histogram
8025  TRandom2 random;
8026  marker=0;
8027  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8028  yk = fYaxis->GetBinLowEdge(j);
8029  ystep = fYaxis->GetBinWidth(j);
8030  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8031  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8032  xk = fXaxis->GetBinLowEdge(i);
8033  xstep = fXaxis->GetBinWidth(i);
8034  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8035  z = fH->GetBinContent(bin);
8036  if (z < zmin) z = zmin;
8037  if (z > zmax) z = zmax;
8038  if (Hoption.Logz) {
8039  if (z > 0) z = TMath::Log10(z) - zmin;
8040  } else {
8041  z -= zmin;
8042  }
8043  if (z <= 0) continue;
8044  k = Int_t(z*scale);
8045  if (ltest) k++;
8046  if (k > 0) {
8047  for (Int_t loop=0; loop<k; loop++) {
8048  if (k+marker >= kNMAX) {
8049  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8050  marker=0;
8051  }
8052  fXbuf[marker] = (random.Rndm()*xstep) + xk;
8053  fYbuf[marker] = (random.Rndm()*ystep) + yk;
8054  if (Hoption.Logx) {
8055  if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8056  else break;
8057  }
8058  if (Hoption.Logy) {
8059  if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8060  else break;
8061  }
8062  if (fXbuf[marker] < gPad->GetUxmin()) break;
8063  if (fYbuf[marker] < gPad->GetUymin()) break;
8064  if (fXbuf[marker] > gPad->GetUxmax()) break;
8065  if (fYbuf[marker] > gPad->GetUymax()) break;
8066  marker++;
8067  }
8068  }
8069  }
8070  }
8071  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8072 
8073  if (Hoption.Zscale) PaintPalette();
8074 }
8075 
8076 ////////////////////////////////////////////////////////////////////////////////
8077 /// Static function to paint special objects like vectors and matrices.
8078 /// This function is called via `gROOT->ProcessLine` to paint these objects
8079 /// without having a direct dependency of the graphics or histogramming
8080 /// system.
8081 
8083 {
8084 
8085  if (!obj) return;
8086  Bool_t status = TH1::AddDirectoryStatus();
8088 
8089  if (obj->InheritsFrom(TMatrixFBase::Class())) {
8090  // case TMatrixF
8091  TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8092  R__TMatrixFBase->SetBit(kCanDelete);
8093  R__TMatrixFBase->Draw(option);
8094 
8095  } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8096  // case TMatrixD
8097  TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8098  R__TMatrixDBase->SetBit(kCanDelete);
8099  R__TMatrixDBase->Draw(option);
8100 
8101  } else if (obj->InheritsFrom(TVectorF::Class())) {
8102  //case TVectorF
8103  TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8104  R__TVectorF->SetBit(kCanDelete);
8105  R__TVectorF->Draw(option);
8106 
8107  } else if (obj->InheritsFrom(TVectorD::Class())) {
8108  //case TVectorD
8109  TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8110  R__TVectorD->SetBit(kCanDelete);
8111  R__TVectorD->Draw(option);
8112  }
8113 
8114  TH1::AddDirectory(status);
8115 }
8116 
8117 ////////////////////////////////////////////////////////////////////////////////
8118 /// [Draw the statistics box for 1D and profile histograms.](#HP07)
8119 
8121 {
8122 
8123  static char t[100];
8124  Int_t dofit;
8125  TPaveStats *stats = 0;
8126  TIter next(fFunctions);
8127  TObject *obj;
8128  while ((obj = next())) {
8129  if (obj->InheritsFrom(TPaveStats::Class())) {
8130  stats = (TPaveStats*)obj;
8131  break;
8132  }
8133  }
8134 
8135  if (stats && dostat) {
8136  dofit = stats->GetOptFit();
8137  dostat = stats->GetOptStat();
8138  } else {
8139  dofit = gStyle->GetOptFit();
8140  }
8141  if (!dofit) fit = 0;
8142  if (dofit == 1) dofit = 111;
8143  if (dostat == 1) dostat = 1111;
8144  Int_t print_name = dostat%10;
8145  Int_t print_entries = (dostat/10)%10;
8146  Int_t print_mean = (dostat/100)%10;
8147  Int_t print_stddev = (dostat/1000)%10;
8148  Int_t print_under = (dostat/10000)%10;
8149  Int_t print_over = (dostat/100000)%10;
8150  Int_t print_integral= (dostat/1000000)%10;
8151  Int_t print_skew = (dostat/10000000)%10;
8152  Int_t print_kurt = (dostat/100000000)%10;
8153  Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8154  print_under + print_over + print_integral +
8155  print_skew + print_kurt;
8156  Int_t print_fval = dofit%10;
8157  Int_t print_ferrors = (dofit/10)%10;
8158  Int_t print_fchi2 = (dofit/100)%10;
8159  Int_t print_fprob = (dofit/1000)%10;
8160  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8161  if (fit) {
8162  if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8163  else nlinesf += fit->GetNpar();
8164  }
8165  if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8166 
8167  // Pavetext with statistics
8168  Bool_t done = kFALSE;
8169  if (!dostat && !fit) {
8170  if (stats) { fFunctions->Remove(stats); delete stats;}
8171  return;
8172  }
8173  Double_t statw = gStyle->GetStatW();
8174  if (fit) statw = 1.8*gStyle->GetStatW();
8175  Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8176  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8177  stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8178  }
8179  if (stats) {
8180  stats->Clear();
8181  done = kTRUE;
8182  } else {
8183  stats = new TPaveStats(
8184  gStyle->GetStatX()-statw,
8185  gStyle->GetStatY()-stath,
8186  gStyle->GetStatX(),
8187  gStyle->GetStatY(),"brNDC");
8188 
8189  stats->SetParent(fH);
8190  stats->SetOptFit(dofit);
8191  stats->SetOptStat(dostat);
8192  stats->SetFillColor(gStyle->GetStatColor());
8193  stats->SetFillStyle(gStyle->GetStatStyle());
8195  stats->SetTextFont(gStyle->GetStatFont());
8196  if (gStyle->GetStatFont()%10 > 2)
8197  stats->SetTextSize(gStyle->GetStatFontSize());
8198  stats->SetFitFormat(gStyle->GetFitFormat());
8199  stats->SetStatFormat(gStyle->GetStatFormat());
8200  stats->SetName("stats");
8201 
8203  stats->SetTextAlign(12);
8204  stats->SetBit(kCanDelete);
8205  stats->SetBit(kMustCleanup);
8206  }
8207  if (print_name) stats->AddText(fH->GetName());
8208  if (print_entries) {
8209  if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8210  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8211  stats->AddText(t);
8212  }
8213  char textstats[50];
8214  if (print_mean) {
8215  if (print_mean == 1) {
8216  snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8217  snprintf(t,100,textstats,fH->GetMean(1));
8218  } else {
8219  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8220  ,"%",stats->GetStatFormat());
8221  snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
8222  }
8223  stats->AddText(t);
8224  if (fH->InheritsFrom(TProfile::Class())) {
8225  if (print_mean == 1) {
8226  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8227  snprintf(t,100,textstats,fH->GetMean(2));
8228  } else {
8229  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8230  ,"%",stats->GetStatFormat());
8231  snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
8232  }
8233  stats->AddText(t);
8234  }
8235  }
8236  if (print_stddev) {
8237  if (print_stddev == 1) {
8238  snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8239  snprintf(t,100,textstats,fH->GetStdDev(1));
8240  } else {
8241  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8242  ,"%",stats->GetStatFormat());
8243  snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
8244  }
8245  stats->AddText(t);
8246  if (fH->InheritsFrom(TProfile::Class())) {
8247  if (print_stddev == 1) {
8248  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8249  snprintf(t,100,textstats,fH->GetStdDev(2));
8250  } else {
8251  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8252  ,"%",stats->GetStatFormat());
8253  snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
8254  }
8255  stats->AddText(t);
8256  }
8257  }
8258  if (print_under) {
8259  snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8260  snprintf(t,100,textstats,fH->GetBinContent(0));
8261  stats->AddText(t);
8262  }
8263  if (print_over) {
8264  snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8265  snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
8266  stats->AddText(t);
8267  }
8268  if (print_integral) {
8269  if (print_integral == 1) {
8270  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8271  snprintf(t,100,textstats,fH->Integral());
8272  } else {
8273  snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8274  snprintf(t,100,textstats,fH->Integral("width"));
8275  }
8276  stats->AddText(t);
8277  }
8278  if (print_skew) {
8279  if (print_skew == 1) {
8280  snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8281  snprintf(t,100,textstats,fH->GetSkewness(1));
8282  } else {
8283  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8284  ,"%",stats->GetStatFormat());
8285  snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
8286  }
8287  stats->AddText(t);
8288  }
8289  if (print_kurt) {
8290  if (print_kurt == 1) {
8291  snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8292  snprintf(t,100,textstats,fH->GetKurtosis(1));
8293  } else {
8294  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8295  ,"%",stats->GetStatFormat());
8296  snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
8297  }
8298  stats->AddText(t);
8299  }
8300 
8301  // Draw Fit parameters
8302  if (fit) {
8303  Int_t ndf = fit->GetNDF();
8304  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8305  snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
8306  if (print_fchi2) stats->AddText(t);
8307  if (print_fprob) {
8308  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
8309  snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8310  stats->AddText(t);
8311  }
8312  if (print_fval || print_ferrors) {
8313  Double_t parmin,parmax;
8314  Int_t a;
8315  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8316  fit->GetParLimits(ipar,parmin,parmax);
8317  if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8318  snprintf(t,100,"%-8s ",fit->GetParName(ipar));
8319  a = strlen(t);
8320  if (a>50) a = 50;
8321  if (print_ferrors) {
8322  snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
8323  GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8324  snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar)
8325  ,(Float_t)fit->GetParError(ipar));
8326  } else {
8327  snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
8328  snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar));
8329  }
8330  t[63] = 0;
8331  stats->AddText(t);
8332  }
8333  }
8334  }
8335 
8336  if (!done) fFunctions->Add(stats);
8337  stats->Paint();
8338 }
8339 
8340 ////////////////////////////////////////////////////////////////////////////////
8341 /// [Draw the statistics box for 2D histograms.](#HP07)
8342 
8344 {
8345 
8346  if (fH->GetDimension() != 2) return;
8347  TH2 *h2 = (TH2*)fH;
8348 
8349  static char t[100];
8350  Int_t dofit;
8351  TPaveStats *stats = 0;
8352  TIter next(fFunctions);
8353  TObject *obj;
8354  while ((obj = next())) {
8355  if (obj->InheritsFrom(TPaveStats::Class())) {
8356  stats = (TPaveStats*)obj;
8357  break;
8358  }
8359  }
8360  if (stats && dostat) {
8361  dofit = stats->GetOptFit();
8362  dostat = stats->GetOptStat();
8363  } else {
8364  dofit = gStyle->GetOptFit();
8365  }
8366  if (dostat == 1) dostat = 1111;
8367  Int_t print_name = dostat%10;
8368  Int_t print_entries = (dostat/10)%10;
8369  Int_t print_mean = (dostat/100)%10;
8370  Int_t print_stddev = (dostat/1000)%10;
8371  Int_t print_under = (dostat/10000)%10;
8372  Int_t print_over = (dostat/100000)%10;
8373  Int_t print_integral= (dostat/1000000)%10;
8374  Int_t print_skew = (dostat/10000000)%10;
8375  Int_t print_kurt = (dostat/100000000)%10;
8376  Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8377  if (print_under || print_over) nlines += 3;
8378 
8379  // Pavetext with statistics
8380  if (!gStyle->GetOptFit()) fit = 0;
8381  Bool_t done = kFALSE;
8382  if (!dostat && !fit) {
8383  if (stats) { fFunctions->Remove(stats); delete stats;}
8384  return;
8385  }
8386  Double_t statw = gStyle->GetStatW();
8387  if (fit) statw = 1.8*gStyle->GetStatW();
8388  Double_t stath = nlines*gStyle->GetStatFontSize();
8389  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8390  stath = 0.25*nlines*gStyle->GetStatH();
8391  }
8392  if (fit) stath += gStyle->GetStatH();
8393  if (stats) {
8394  stats->Clear();
8395  done = kTRUE;
8396  } else {
8397  stats = new TPaveStats(
8398  gStyle->GetStatX()-statw,
8399  gStyle->GetStatY()-stath,
8400  gStyle->GetStatX(),
8401  gStyle->GetStatY(),"brNDC");
8402 
8403  stats->SetParent(fH);
8404  stats->SetOptFit(dofit);
8405  stats->SetOptStat(dostat);
8406  stats->SetFillColor(gStyle->GetStatColor());
8407  stats->SetFillStyle(gStyle->GetStatStyle());
8409  stats->SetName("stats");
8410 
8412  stats->SetTextAlign(12);
8413  stats->SetTextFont(gStyle->GetStatFont());
8414  if (gStyle->GetStatFont()%10 > 2)
8415  stats->SetTextSize(gStyle->GetStatFontSize());
8416  stats->SetFitFormat(gStyle->GetFitFormat());
8417  stats->SetStatFormat(gStyle->GetStatFormat());
8418  stats->SetBit(kCanDelete);
8419  stats->SetBit(kMustCleanup);
8420  }
8421  if (print_name) stats->AddText(h2->GetName());
8422  if (print_entries) {
8423  if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8424  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8425  stats->AddText(t);
8426  }
8427  char textstats[50];
8428  if (print_mean) {
8429  if (print_mean == 1) {
8430  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8431  snprintf(t,50,textstats,h2->GetMean(1));
8432  stats->AddText(t);
8433  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8434  snprintf(t,100,textstats,h2->GetMean(2));
8435  stats->AddText(t);
8436  } else {
8437  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8438  ,"%",stats->GetStatFormat());
8439  snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
8440  stats->AddText(t);
8441  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8442  ,"%",stats->GetStatFormat());
8443  snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
8444  stats->AddText(t);
8445  }
8446  }
8447  if (print_stddev) {
8448  if (print_stddev == 1) {
8449  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8450  snprintf(t,100,textstats,h2->GetStdDev(1));
8451  stats->AddText(t);
8452  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8453  snprintf(t,100,textstats,h2->GetStdDev(2));
8454  stats->AddText(t);
8455  } else {
8456  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8457  ,"%",stats->GetStatFormat());
8458  snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
8459  stats->AddText(t);
8460  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8461  ,"%",stats->GetStatFormat());
8462  snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
8463  stats->AddText(t);
8464  }
8465  }
8466  if (print_integral) {
8467  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8468  snprintf(t,100,textstats,fH->Integral());
8469  stats->AddText(t);
8470  }
8471  if (print_skew) {
8472  if (print_skew == 1) {
8473  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8474  snprintf(t,100,textstats,h2->GetSkewness(1));
8475  stats->AddText(t);
8476  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8477  snprintf(t,100,textstats,h2->GetSkewness(2));
8478  stats->AddText(t);
8479  } else {
8480  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8481  ,"%",stats->GetStatFormat());
8482  snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
8483  stats->AddText(t);
8484  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8485  ,"%",stats->GetStatFormat());
8486  snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
8487  stats->AddText(t);
8488  }
8489  }
8490  if (print_kurt) {
8491  if (print_kurt == 1) {
8492  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8493  snprintf(t,100,textstats,h2->GetKurtosis(1));
8494  stats->AddText(t);
8495  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8496  snprintf(t,100,textstats,h2->GetKurtosis(2));
8497  stats->AddText(t);
8498  } else {
8499  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8500  ,"%",stats->GetStatFormat());
8501  snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
8502  stats->AddText(t);
8503  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8504  ,"%",stats->GetStatFormat());
8505  snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
8506  stats->AddText(t);
8507  }
8508  }
8509  if (print_under || print_over) {
8510  //get 3*3 under/overflows for 2d hist
8511  Double_t unov[9];
8512 
8513  Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8514  Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8515  Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8516  Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8517  Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8518  Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8519 
8520  unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8521  unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8522  unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8523  unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8524  unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8525  unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8526  unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8527  unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8528  unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8529 
8530  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8531  stats->AddText(t);
8532  if (h2->GetEntries() < 1e7)
8533  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8534  else
8535  snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8536  stats->AddText(t);
8537  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8538  stats->AddText(t);
8539  }
8540 
8541  // Draw Fit parameters
8542  if (fit) {
8543  Int_t ndf = fit->GetNDF();
8544  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8545  stats->AddText(t);
8546  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8547  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8548  ,(Float_t)fit->GetParameter(ipar)
8549  ,(Float_t)fit->GetParError(ipar));
8550  t[63] = 0;
8551  stats->AddText(t);
8552  }
8553  }
8554 
8555  if (!done) fFunctions->Add(stats);
8556  stats->Paint();
8557 }
8558 
8559 ////////////////////////////////////////////////////////////////////////////////
8560 /// [Draw the statistics box for 3D histograms.](#HP07)
8561 
8563 {
8564 
8565  if (fH->GetDimension() != 3) return;
8566  TH3 *h3 = (TH3*)fH;
8567 
8568  static char t[100];
8569  Int_t dofit;
8570  TPaveStats *stats = 0;
8571  TIter next(fFunctions);
8572  TObject *obj;
8573  while ((obj = next())) {
8574  if (obj->InheritsFrom(TPaveStats::Class())) {
8575  stats = (TPaveStats*)obj;
8576  break;
8577  }
8578  }
8579  if (stats && dostat) {
8580  dofit = stats->GetOptFit();
8581  dostat = stats->GetOptStat();
8582  } else {
8583  dofit = gStyle->GetOptFit();
8584  }
8585  if (dostat == 1) dostat = 1111;
8586  Int_t print_name = dostat%10;
8587  Int_t print_entries = (dostat/10)%10;
8588  Int_t print_mean = (dostat/100)%10;
8589  Int_t print_stddev = (dostat/1000)%10;
8590  Int_t print_under = (dostat/10000)%10;
8591  Int_t print_over = (dostat/100000)%10;
8592  Int_t print_integral= (dostat/1000000)%10;
8593  Int_t print_skew = (dostat/10000000)%10;
8594  Int_t print_kurt = (dostat/100000000)%10;
8595  Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8596  if (print_under || print_over) nlines += 3;
8597 
8598  // Pavetext with statistics
8599  if (!gStyle->GetOptFit()) fit = 0;
8600  Bool_t done = kFALSE;
8601  if (!dostat && !fit) {
8602  if (stats) { fFunctions->Remove(stats); delete stats;}
8603  return;
8604  }
8605  Double_t statw = gStyle->GetStatW();
8606  if (fit) statw = 1.8*gStyle->GetStatW();
8607  Double_t stath = nlines*gStyle->GetStatFontSize();
8608  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8609  stath = 0.25*nlines*gStyle->GetStatH();
8610  }
8611  if (fit) stath += gStyle->GetStatH();
8612  if (stats) {
8613  stats->Clear();
8614  done = kTRUE;
8615  } else {
8616  stats = new TPaveStats(
8617  gStyle->GetStatX()-statw,
8618  gStyle->GetStatY()-stath,
8619  gStyle->GetStatX(),
8620  gStyle->GetStatY(),"brNDC");
8621 
8622  stats->SetParent(fH);
8623  stats->SetOptFit(dofit);
8624  stats->SetOptStat(dostat);
8625  stats->SetFillColor(gStyle->GetStatColor());
8626  stats->SetFillStyle(gStyle->GetStatStyle());
8628  stats->SetName("stats");
8629 
8631  stats->SetTextAlign(12);
8632  stats->SetTextFont(gStyle->GetStatFont());
8633  stats->SetFitFormat(gStyle->GetFitFormat());
8634  stats->SetStatFormat(gStyle->GetStatFormat());
8635  stats->SetBit(kCanDelete);
8636  stats->SetBit(kMustCleanup);
8637  }
8638  if (print_name) stats->AddText(h3->GetName());
8639  if (print_entries) {
8640  if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8641  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8642  stats->AddText(t);
8643  }
8644  char textstats[50];
8645  if (print_mean) {
8646  if (print_mean == 1) {
8647  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8648  snprintf(t,100,textstats,h3->GetMean(1));
8649  stats->AddText(t);
8650  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8651  snprintf(t,100,textstats,h3->GetMean(2));
8652  stats->AddText(t);
8653  snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8654  snprintf(t,100,textstats,h3->GetMean(3));
8655  stats->AddText(t);
8656  } else {
8657  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8658  ,"%",stats->GetStatFormat());
8659  snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
8660  stats->AddText(t);
8661  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8662  ,"%",stats->GetStatFormat());
8663  snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
8664  stats->AddText(t);
8665  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8666  ,"%",stats->GetStatFormat());
8667  snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
8668  stats->AddText(t);
8669  }
8670  }
8671  if (print_stddev) {
8672  if (print_stddev == 1) {
8673  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8674  snprintf(t,100,textstats,h3->GetStdDev(1));
8675  stats->AddText(t);
8676  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8677  snprintf(t,100,textstats,h3->GetStdDev(2));
8678  stats->AddText(t);
8679  snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
8680  snprintf(t,100,textstats,h3->GetStdDev(3));
8681  stats->AddText(t);
8682  } else {
8683  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8684  ,"%",stats->GetStatFormat());
8685  snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
8686  stats->AddText(t);
8687  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8688  ,"%",stats->GetStatFormat());
8689  snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
8690  stats->AddText(t);
8691  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
8692  ,"%",stats->GetStatFormat());
8693  snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
8694  stats->AddText(t);
8695  }
8696  }
8697  if (print_integral) {
8698  snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
8699  stats->AddText(t);
8700  }
8701  if (print_skew) {
8702  if (print_skew == 1) {
8703  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8704  snprintf(t,100,textstats,h3->GetSkewness(1));
8705  stats->AddText(t);
8706  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8707  snprintf(t,100,textstats,h3->GetSkewness(2));
8708  stats->AddText(t);
8709  snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
8710  snprintf(t,100,textstats,h3->GetSkewness(3));
8711  stats->AddText(t);
8712  } else {
8713  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8714  ,"%",stats->GetStatFormat());
8715  snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
8716  stats->AddText(t);
8717  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8718  ,"%",stats->GetStatFormat());
8719  snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
8720  stats->AddText(t);
8721  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
8722  ,"%",stats->GetStatFormat());
8723  snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
8724  stats->AddText(t);
8725  }
8726  }
8727  if (print_kurt) {
8728  if (print_kurt == 1) {
8729  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8730  snprintf(t,100,textstats,h3->GetKurtosis(1));
8731  stats->AddText(t);
8732  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8733  snprintf(t,100,textstats,h3->GetKurtosis(2));
8734  stats->AddText(t);
8735  snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
8736  snprintf(t,100,textstats,h3->GetKurtosis(3));
8737  stats->AddText(t);
8738  } else {
8739  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8740  ,"%",stats->GetStatFormat());
8741  snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
8742  stats->AddText(t);
8743  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8744  ,"%",stats->GetStatFormat());
8745  snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
8746  stats->AddText(t);
8747  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
8748  ,"%",stats->GetStatFormat());
8749  snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
8750  stats->AddText(t);
8751  }
8752  }
8753  if (print_under || print_over) {
8754  // no underflow - overflow printing for a 3D histogram
8755  // one would need a 3D table
8756  }
8757 
8758  // Draw Fit parameters
8759  if (fit) {
8760  Int_t ndf = fit->GetNDF();
8761  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8762  stats->AddText(t);
8763  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8764  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8765  ,(Float_t)fit->GetParameter(ipar)
8766  ,(Float_t)fit->GetParError(ipar));
8767  t[32] = 0;
8768  stats->AddText(t);
8769  }
8770  }
8771 
8772  if (!done) fFunctions->Add(stats);
8773  stats->Paint();
8774 }
8775 
8776 ////////////////////////////////////////////////////////////////////////////////
8777 /// [Control function to draw a 2D histogram as a surface plot.](#HP18)
8778 
8780 {
8781 
8782  const Double_t ydiff = 1;
8783  const Double_t yligh1 = 10;
8784  const Double_t qa = 0.15;
8785  const Double_t qd = 0.15;
8786  const Double_t qs = 0.8;
8787  Double_t fmin, fmax;
8788  Int_t raster = 0;
8789  Int_t irep = 0;
8790 
8791  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8792  Int_t nx = Hparam.xlast - Hparam.xfirst;
8793  Int_t ny = Hparam.ylast - Hparam.yfirst;
8794  Double_t zmin = Hparam.zmin;
8795  Double_t zmax = Hparam.zmax;
8796  Double_t xlab1 = Hparam.xmin;
8797  Double_t xlab2 = Hparam.xmax;
8798  Double_t ylab1 = Hparam.ymin;
8799  Double_t ylab2 = Hparam.ymax;
8800  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
8801  Double_t deltaz = TMath::Abs(zmin);
8802  if (deltaz == 0) deltaz = 1;
8803  if (zmin >= zmax) {
8804  zmin -= 0.5*deltaz;
8805  zmax += 0.5*deltaz;
8806  }
8807  Double_t z1c = zmin;
8808  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
8809  // Compute the lego limits and instantiate a lego object
8810  fXbuf[0] = -1;
8811  fYbuf[0] = 1;
8812  fXbuf[1] = -1;
8813  fYbuf[1] = 1;
8814  if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
8815  if (Hoption.System == kPOLAR) {
8816  fXbuf[2] = z1c;
8817  fYbuf[2] = z2c;
8818  } else if (Hoption.System == kCYLINDRICAL) {
8819  if (Hoption.Logy) {
8820  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
8821  else fXbuf[2] = 0;
8822  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
8823  else fYbuf[2] = 0;
8824  } else {
8825  fXbuf[2] = ylab1;
8826  fYbuf[2] = ylab2;
8827  }
8828  z1c = 0; z2c = 1;
8829  } else if (Hoption.System == kSPHERICAL) {
8830  fXbuf[2] = -1;
8831  fYbuf[2] = 1;
8832  z1c = 0; z2c = 1;
8833  } else if (Hoption.System == kRAPIDITY) {
8834  fXbuf[2] = -1/TMath::Tan(dangle);
8835  fYbuf[2] = 1/TMath::Tan(dangle);
8836  } else {
8837  fXbuf[0] = xlab1;
8838  fYbuf[0] = xlab2;
8839  fXbuf[1] = ylab1;
8840  fYbuf[1] = ylab2;
8841  fXbuf[2] = z1c;
8842  fYbuf[2] = z2c;
8843  }
8844 
8845  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
8848 
8849  // Create axis object
8850 
8851  TGaxis *axis = new TGaxis();
8852 
8853  // Initialize the levels on the Z axis
8854  Int_t ndiv = fH->GetContour();
8855  if (ndiv == 0 ) {
8856  ndiv = gStyle->GetNumberContours();
8857  fH->SetContour(ndiv);
8858  }
8859  Int_t ndivz = TMath::Abs(ndiv);
8860  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8861 
8862  if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
8863  if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
8864 
8865  // Close the surface in case of non cartesian coordinates.
8866 
8867  if (Hoption.System != kCARTESIAN) {nx++; ny++;}
8868 
8869  // Now ready to draw the surface plot
8870 
8871  TView *view = gPad->GetView();
8872  if (!view) {
8873  Error("PaintSurface", "no TView in current pad");
8874  return;
8875  }
8876 
8877  Double_t thedeg = 90 - gPad->GetTheta();
8878  Double_t phideg = -90 - gPad->GetPhi();
8879  Double_t psideg = view->GetPsi();
8880  view->SetView(phideg, thedeg, psideg, irep);
8881 
8882  // Set color/style for back box
8883  if (Hoption.Same) {
8884  fLego->SetFillStyle(0);
8885  fLego->SetFillColor(1);
8886  } else {
8887  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8888  fLego->SetFillColor(gPad->GetFrameFillColor());
8889  }
8890  fLego->TAttFill::Modify();
8891 
8892  Int_t backcolor = gPad->GetFrameFillColor();
8893  if (Hoption.System != kCARTESIAN) backcolor = 0;
8894  view->PadRange(backcolor);
8895 
8898  fLego->TAttFill::Modify();
8899 
8900  // Draw the filled contour on top
8901  Int_t icol1 = fH->GetFillColor();
8902 
8903  Int_t hoption35 = Hoption.Surf;
8904  if (Hoption.Surf == 13 || Hoption.Surf == 15) {
8905  DefineColorLevels(ndivz);
8906  Hoption.Surf = 23;
8909  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8910  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8911  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8912  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8913  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8914  Hoption.Surf = hoption35;
8915  fLego->SetMesh(1);
8916  }
8917 
8918  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8919  else fLego->InitMoveScreen(-1.1,1.1);
8920 
8921  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
8923  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
8925  fLego->BackBox(90);
8926  }
8927  }
8928 
8929  // Gouraud Shading surface
8930  if (Hoption.Surf == 14) {
8931  // Set light sources
8932  fLego->LightSource(0, ydiff, 0,0,0,irep);
8933  fLego->LightSource(1, yligh1 ,1,1,1,irep);
8934  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
8935  fmin = ydiff*qa;
8936  fmax = fmin + (yligh1+0.1)*(qd+qs);
8937  Int_t nbcol = 28;
8938  icol1 = 201;
8939  Double_t dcol = 0.5/Double_t(nbcol);
8940  TColor *colref = gROOT->GetColor(fH->GetFillColor());
8941  if (!colref) return;
8942  Float_t r,g,b,hue,light,satur;
8943  colref->GetRGB(r,g,b);
8944  TColor::RGBtoHLS(r,g,b,hue,light,satur);
8945  TColor *acol;
8946  for (Int_t col=0;col<nbcol;col++) {
8947  acol = gROOT->GetColor(col+icol1);
8948  TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
8949  if (acol) acol->SetRGB(r,g,b);
8950  }
8951  fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
8954  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8955  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8956  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8957  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8958  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8959  } else if (Hoption.Surf == 15) {
8960  // The surface is not drawn in this case.
8961  } else {
8962  // Draw the surface
8963  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
8964  DefineColorLevels(ndivz);
8965  } else {
8967  }
8969  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceRaster1);
8970  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode2);
8971  if (Hoption.System == kPOLAR) {
8972  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
8973  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
8974  } else if (Hoption.System == kCYLINDRICAL) {
8975  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
8976  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8977  } else if (Hoption.System == kSPHERICAL) {
8978  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
8979  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8980  } else if (Hoption.System == kRAPIDITY) {
8981  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
8982  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8983  } else {
8984  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1);
8986  if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
8987  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
8988  }
8989  }
8990 
8991  // Paint the line contour on top for option SURF7
8992  if (Hoption.Surf == 17) {
8993  fLego->InitMoveScreen(-1.1,1.1);
8995  Hoption.Surf = 23;
8998  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
8999  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9000  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9001  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9002  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9003  }
9004 
9005  if ((!Hoption.Same) &&
9006  (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9007  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
9009  fLego->BackBox(90);
9010  }
9011  }
9012  if (Hoption.System == kCARTESIAN) {
9013  fLego->InitMoveScreen(-1.1,1.1);
9015  if (Hoption.FrontBox) fLego->FrontBox(90);
9016  }
9017  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9018 
9019  if (Hoption.Zscale) PaintPalette();
9020 
9021  delete axis;
9022  delete fLego; fLego = 0;
9023 }
9024 
9025 ////////////////////////////////////////////////////////////////////////////////
9026 /// Control function to draw a table using Delaunay triangles.
9027 
9029 {
9030 
9031  TGraphDelaunay2D *dt = nullptr;
9032  TGraphDelaunay *dtOld = nullptr;
9033 
9034  // Check if fH contains a TGraphDelaunay2D
9035  TList *hl = fH->GetListOfFunctions();
9036  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9037  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9038  if (!dt && !dtOld) return;
9039 
9040  // If needed, create a TGraph2DPainter
9041  if (!fGraph2DPainter) {
9042  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9043  else fGraph2DPainter = new TGraph2DPainter(dtOld);
9044  }
9045 
9046  // Define the 3D view
9047  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9048  if (Hoption.Same) {
9049  TView *viewsame = gPad->GetView();
9050  if (!viewsame) {
9051  Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9052  return;
9053  }
9054  Double_t *rmin = viewsame->GetRmin();
9055  Double_t *rmax = viewsame->GetRmax();
9056  if (!rmin || !rmax) return;
9057  fXbuf[0] = rmin[0];
9058  fYbuf[0] = rmax[0];
9059  fXbuf[1] = rmin[1];
9060  fYbuf[1] = rmax[1];
9061  fXbuf[2] = rmin[2];
9062  fYbuf[2] = rmax[2];
9063  } else {
9064  fXbuf[0] = Hparam.xmin;
9065  fYbuf[0] = Hparam.xmax;
9066  fXbuf[1] = Hparam.ymin;
9067  fYbuf[1] = Hparam.ymax;
9068  fXbuf[2] = Hparam.zmin;
9069  fYbuf[2] = Hparam.zmax;
9070  }
9071 
9073  TView *view = gPad->GetView();
9074  if (!view) {
9075  Error("PaintTriangles", "no TView in current pad");
9076  return;
9077  }
9078  Double_t thedeg = 90 - gPad->GetTheta();
9079  Double_t phideg = -90 - gPad->GetPhi();
9080  Double_t psideg = view->GetPsi();
9081  Int_t irep;
9082  view->SetView(phideg, thedeg, psideg, irep);
9083 
9084  // Set color/style for back box
9085  fLego->SetFillStyle(gPad->GetFrameFillStyle());
9086  fLego->SetFillColor(gPad->GetFrameFillColor());
9087  fLego->TAttFill::Modify();
9088  Int_t backcolor = gPad->GetFrameFillColor();
9089  if (Hoption.System != kCARTESIAN) backcolor = 0;
9090  view->PadRange(backcolor);
9093  fLego->TAttFill::Modify();
9094 
9095  // Paint the Back Box if needed
9096  if (Hoption.BackBox && !Hoption.Same) {
9097  fLego->InitMoveScreen(-1.1,1.1);
9100  fLego->BackBox(90);
9101  }
9102 
9103  // Paint the triangles
9104  fGraph2DPainter->Paint(option);
9105 
9106  // Paint the Front Box if needed
9107  if (Hoption.FrontBox) {
9108  fLego->InitMoveScreen(-1.1,1.1);
9110  fLego->FrontBox(90);
9111  }
9112 
9113  // Paint the Axis if needed
9114  if (!Hoption.Axis && !Hoption.Same) {
9115  TGaxis *axis = new TGaxis();
9116  PaintLegoAxis(axis, 90);
9117  delete axis;
9118  }
9119 
9120  if (Hoption.Zscale) PaintPalette();
9121 
9122  delete fLego; fLego = 0;
9123 }
9124 
9125 ////////////////////////////////////////////////////////////////////////////////
9126 /// Define the color levels used to paint legos, surfaces etc..
9127 
9129 {
9130 
9131  Int_t i, irep;
9132 
9133  // Initialize the color levels
9134  if (ndivz >= 100) {
9135  Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9136  ndivz = 8;
9137  }
9138  Double_t *funlevel = new Double_t[ndivz+1];
9139  Int_t *colorlevel = new Int_t[ndivz+1];
9140  Int_t theColor;
9141  Int_t ncolors = gStyle->GetNumberOfColors();
9142  for (i = 0; i < ndivz; ++i) {
9143  funlevel[i] = fH->GetContourLevelPad(i);
9144  theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9145  colorlevel[i] = gStyle->GetColorPalette(theColor);
9146  }
9147  colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9148  fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9149  delete [] colorlevel;
9150  delete [] funlevel;
9151 }
9152 
9153 ////////////////////////////////////////////////////////////////////////////////
9154 /// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9155 
9157 {
9158 
9159  // Fill Hparam structure with histo parameters
9160  if (!TableInit()) return;
9161 
9162  // Draw histogram frame
9163  PaintFrame();
9164 
9165  // If palette option not specified, delete a possible existing palette
9166  if (!Hoption.Zscale) {
9167  TObject *palette = fFunctions->FindObject("palette");
9168  if (palette) { fFunctions->Remove(palette); delete palette;}
9169  }
9170 
9171  // Do not draw the histogram. Only the attached functions will be drawn.
9172  if (Hoption.Func == 2) {
9173  if (Hoption.Zscale) {
9174  Int_t ndiv = fH->GetContour();
9175  if (ndiv == 0 ) {
9176  ndiv = gStyle->GetNumberContours();
9177  fH->SetContour(ndiv);
9178  }
9179  PaintPalette();
9180  }
9181 
9182  // Draw the histogram according to the option
9183  } else {
9184  if (fH->InheritsFrom(TH2Poly::Class())) {
9185  if (Hoption.Fill) PaintTH2PolyBins("f");
9186  if (Hoption.Color) PaintTH2PolyColorLevels(option);
9187  if (Hoption.Scat) PaintTH2PolyScatterPlot(option);
9188  if (Hoption.Text) PaintTH2PolyText(option);
9189  if (Hoption.Line) PaintTH2PolyBins("l");
9190  if (Hoption.Mark) PaintTH2PolyBins("P");
9191  } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9192  if (Hoption.Scat) PaintScatterPlot(option);
9193  if (Hoption.Arrow) PaintArrows(option);
9194  if (Hoption.Box) PaintBoxes(option);
9195  if (Hoption.Color) {
9196  if (Hoption.Color == 3) PaintColorLevelsFast(option);
9197  else PaintColorLevels(option);
9198  }
9199  if (Hoption.Contour) PaintContour(option);
9200  if (Hoption.Text) PaintText(option);
9201  if (Hoption.Error >= 100) Paint2DErrors(option);
9202  if (Hoption.Candle) PaintCandlePlot(option);
9203  }
9204  if (Hoption.Lego) PaintLego(option);
9205  if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9206  if (Hoption.Tri) PaintTriangles(option);
9207  }
9208 
9209  // Draw histogram title
9210  PaintTitle();
9211 
9212  // Draw the axes
9213  if (!Hoption.Lego && !Hoption.Surf &&
9214  !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9215 
9216  TF1 *fit = 0;
9217  TIter next(fFunctions);
9218  TObject *obj;
9219  while ((obj = next())) {
9220  if (obj->InheritsFrom(TF1::Class())) {
9221  fit = (TF1*)obj;
9222  break;
9223  }
9224  }
9225  if (Hoption.Same != 1) {
9226  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9227  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9228  //ALWAYS executed on non-iOS platform.
9229  //On iOS, depends on mode.
9230  PaintStat2(gStyle->GetOptStat(),fit);
9231  }
9232  }
9233  }
9234 }
9235 
9236 ////////////////////////////////////////////////////////////////////////////////
9237 /// Control function to draw a TH2Poly bins' contours.
9238 ///
9239 /// - option = "F" draw the bins as filled areas.
9240 /// - option = "L" draw the bins as line.
9241 /// - option = "P" draw the bins as markers.
9242 
9244 {
9245 
9246  //Do not highlight the histogram, if its part was picked.
9247  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9248 
9249  TString opt = option;
9250  opt.ToLower();
9251  Bool_t line = kFALSE;
9252  Bool_t fill = kFALSE;
9253  Bool_t mark = kFALSE;
9254  if (opt.Contains("l")) line = kTRUE;
9255  if (opt.Contains("f")) fill = kTRUE;
9256  if (opt.Contains("p")) mark = kTRUE;
9257 
9258  TH2PolyBin *b;
9259  Double_t z;
9260 
9261  TIter next(((TH2Poly*)fH)->GetBins());
9262  TObject *obj, *poly;
9263 
9264  while ((obj=next())) {
9265  b = (TH2PolyBin*)obj;
9266  z = b->GetContent();
9267  if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9268  poly = b->GetPolygon();
9269 
9270  // Paint the TGraph bins.
9271  if (poly->IsA() == TGraph::Class()) {
9272  TGraph *g = (TGraph*)poly;
9273  g->TAttLine::Modify();
9274  g->TAttMarker::Modify();
9275  g->TAttFill::Modify();
9276  if (line) {
9277  Int_t fs = g->GetFillStyle();
9278  Int_t fc = g->GetFillColor();
9279  g->SetFillStyle(0);
9280  g->SetFillColor(g->GetLineColor());
9281  g->Paint("F");
9282  g->SetFillStyle(fs);
9283  g->SetFillColor(fc);
9284  }
9285  if (fill) g->Paint("F");
9286  if (mark) g->Paint("P");
9287  }
9288 
9289  // Paint the TMultiGraph bins.
9290  if (poly->IsA() == TMultiGraph::Class()) {
9291  TMultiGraph *mg = (TMultiGraph*)poly;
9292  TList *gl = mg->GetListOfGraphs();
9293  if (!gl) return;
9294  TGraph *g;
9295  TIter nextg(gl);
9296  while ((g = (TGraph*) nextg())) {
9297  g->TAttLine::Modify();
9298  g->TAttMarker::Modify();
9299  g->TAttFill::Modify();
9300  if (line) {
9301  Int_t fs = g->GetFillStyle();
9302  Int_t fc = g->GetFillColor();
9303  g->SetFillStyle(0);
9304  g->SetFillColor(g->GetLineColor());
9305  g->Paint("F");
9306  g->SetFillStyle(fs);
9307  g->SetFillColor(fc);
9308  }
9309  if (fill) g->Paint("F");
9310  if (mark) g->Paint("P");
9311  }
9312  }
9313  }
9314 }
9315 
9316 ////////////////////////////////////////////////////////////////////////////////
9317 /// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9318 
9320 {
9321 
9322  //Do not highlight the histogram, if its part was picked.
9323  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9324  return;
9325 
9326  Int_t ncolors, color, theColor;
9327  Double_t z, zc;
9328  Double_t zmin = fH->GetMinimum();
9329  Double_t zmax = fH->GetMaximum();
9330  if (Hoption.Logz) {
9331  if (zmax > 0) {
9332  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9333  zmin = TMath::Log10(zmin);
9334  zmax = TMath::Log10(zmax);
9335  } else {
9336  return;
9337  }
9338  }
9339  Double_t dz = zmax - zmin;
9340 
9341  // Initialize the levels on the Z axis
9342  ncolors = gStyle->GetNumberOfColors();
9343  Int_t ndiv = fH->GetContour();
9344  if (ndiv == 0 ) {
9345  ndiv = gStyle->GetNumberContours();
9346  fH->SetContour(ndiv);
9347  }
9348  Int_t ndivz = TMath::Abs(ndiv);
9349  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9350  Double_t scale = ndivz/dz;
9351 
9352  TH2PolyBin *b;
9353 
9354  TIter next(((TH2Poly*)fH)->GetBins());
9355  TObject *obj, *poly;
9356 
9357  while ((obj=next())) {
9358  b = (TH2PolyBin*)obj;
9359  poly = b->GetPolygon();
9360 
9361  z = b->GetContent();
9362  if (z==0 && Hoption.Zero) continue;
9363  if (Hoption.Logz) {
9364  if (z > 0) z = TMath::Log10(z);
9365  else z = zmin;
9366  }
9367  if (z < zmin) continue;
9368 
9369  // Define the bin color.
9370  if (fH->TestBit(TH1::kUserContour)) {
9371  zc = fH->GetContourLevelPad(0);
9372  if (z < zc) continue;
9373  color = -1;
9374  for (Int_t k=0; k<ndiv; k++) {
9375  zc = fH->GetContourLevelPad(k);
9376  if (z < zc) {
9377  continue;
9378  } else {
9379  color++;
9380  }
9381  }
9382  } else {
9383  color = Int_t(0.01+(z-zmin)*scale);
9384  }
9385  theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9386  if (theColor > ncolors-1) theColor = ncolors-1;
9387 
9388  // Paint the TGraph bins.
9389  if (poly->IsA() == TGraph::Class()) {
9390  TGraph *g = (TGraph*)poly;
9391  g->SetFillColor(gStyle->GetColorPalette(theColor));
9392  g->TAttFill::Modify();
9393  g->Paint("F");
9394  }
9395 
9396  // Paint the TMultiGraph bins.
9397  if (poly->IsA() == TMultiGraph::Class()) {
9398  TMultiGraph *mg = (TMultiGraph*)poly;
9399  TList *gl = mg->GetListOfGraphs();
9400  if (!gl) return;
9401  TGraph *g;
9402  TIter nextg(gl);
9403  while ((g = (TGraph*) nextg())) {
9404  g->SetFillColor(gStyle->GetColorPalette(theColor));
9405  g->TAttFill::Modify();
9406  g->Paint("F");
9407  }
9408  }
9409  }
9410  if (Hoption.Zscale) PaintPalette();
9411 }
9412 
9413 ////////////////////////////////////////////////////////////////////////////////
9414 /// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9415 
9417 {
9418 
9419  //Do not highlight the histogram, if its part was selected.
9420  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9421  return;
9422 
9423  Int_t k, loop, marker=0;
9424  Double_t z, xk,xstep, yk, ystep, xp, yp;
9425  Double_t scale = 1;
9426  Double_t zmin = fH->GetMinimum();
9427  Double_t zmax = fH->GetMaximum();
9428  if (Hoption.Logz) {
9429  if (zmax > 0) {
9430  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9431  zmin = TMath::Log10(zmin);
9432  zmax = TMath::Log10(zmax);
9433  } else {
9434  return;
9435  }
9436  }
9437  Double_t dz = zmax - zmin;
9438  scale = (kNMAX-1)/dz;
9439 
9440 
9441  // use an independent instance of a random generator
9442  // instead of gRandom to avoid conflicts and
9443  // to get same random numbers when drawing the same histogram
9444  TRandom2 random;
9445 
9446  TH2PolyBin *b;
9447 
9448  TIter next(((TH2Poly*)fH)->GetBins());
9449  TObject *obj, *poly;
9450 
9451  Double_t maxarea = 0, a;
9452  while ((obj=next())) {
9453  b = (TH2PolyBin*)obj;
9454  a = b->GetArea();
9455  if (a>maxarea) maxarea = a;
9456  }
9457 
9458  next.Reset();
9459 
9460  while ((obj=next())) {
9461  b = (TH2PolyBin*)obj;
9462  poly = b->GetPolygon();
9463  z = b->GetContent();
9464  if (z < zmin) z = zmin;
9465  if (z > zmax) z = zmax;
9466  if (Hoption.Logz) {
9467  if (z > 0) z = TMath::Log10(z) - zmin;
9468  } else {
9469  z -= zmin;
9470  }
9471  k = Int_t((z*scale)*(b->GetArea()/maxarea));
9472  xk = b->GetXMin();
9473  yk = b->GetYMin();
9474  xstep = b->GetXMax()-xk;
9475  ystep = b->GetYMax()-yk;
9476 
9477  // Paint the TGraph bins.
9478  if (poly->IsA() == TGraph::Class()) {
9479  TGraph *g = (TGraph*)poly;
9480  if (k <= 0 || z <= 0) continue;
9481  loop = 0;
9482  while (loop<k) {
9483  if (k+marker >= kNMAX) {
9484  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9485  marker=0;
9486  }
9487  xp = (random.Rndm()*xstep) + xk;
9488  yp = (random.Rndm()*ystep) + yk;
9489  if (g->IsInside(xp,yp)) {
9490  fXbuf[marker] = xp;
9491  fYbuf[marker] = yp;
9492  marker++;
9493  loop++;
9494  }
9495  }
9496  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9497  }
9498 
9499  // Paint the TMultiGraph bins.
9500  if (poly->IsA() == TMultiGraph::Class()) {
9501  TMultiGraph *mg = (TMultiGraph*)poly;
9502  TList *gl = mg->GetListOfGraphs();
9503  if (!gl) return;
9504  if (k <= 0 || z <= 0) continue;
9505  loop = 0;
9506  while (loop<k) {
9507  if (k+marker >= kNMAX) {
9508  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9509  marker=0;
9510  }
9511  xp = (random.Rndm()*xstep) + xk;
9512  yp = (random.Rndm()*ystep) + yk;
9513  if (mg->IsInside(xp,yp)) {
9514  fXbuf[marker] = xp;
9515  fYbuf[marker] = yp;
9516  marker++;
9517  loop++;
9518  }
9519  }
9520  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9521  }
9522  }
9523  PaintTH2PolyBins("l");
9524 }
9525 
9526 ////////////////////////////////////////////////////////////////////////////////
9527 /// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9528 
9530 {
9531 
9532  TLatex text;
9533  text.SetTextFont(gStyle->GetTextFont());
9534  text.SetTextColor(fH->GetMarkerColor());
9535  text.SetTextSize(0.02*fH->GetMarkerSize());
9536 
9537  Double_t x, y, z, e, angle = 0;
9538  char value[50];
9539  char format[32];
9540  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9541  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9542  Int_t opt = (Int_t)Hoption.Text/1000;
9543 
9544  text.SetTextAlign(22);
9545  if (Hoption.Text == 1) angle = 0;
9546  text.SetTextAngle(angle);
9547  text.TAttText::Modify();
9548 
9549  TH2PolyBin *b;
9550 
9551  TIter next(((TH2Poly*)fH)->GetBins());
9552  TObject *obj, *p;
9553 
9554  while ((obj=next())) {
9555  b = (TH2PolyBin*)obj;
9556  p = b->GetPolygon();
9557  x = (b->GetXMin()+b->GetXMax())/2;
9558  if (Hoption.Logx) {
9559  if (x > 0) x = TMath::Log10(x);
9560  else continue;
9561  }
9562  y = (b->GetYMin()+b->GetYMax())/2;
9563  if (Hoption.Logy) {
9564  if (y > 0) y = TMath::Log10(y);
9565  else continue;
9566  }
9567  z = b->GetContent();
9568  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9569  if (opt==2) {
9570  e = fH->GetBinError(b->GetBinNumber());
9571  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9572  "%",gStyle->GetPaintTextFormat(),
9573  "%",gStyle->GetPaintTextFormat());
9574  snprintf(value,50,format,z,e);
9575  } else {
9576  snprintf(value,50,format,z);
9577  }
9578  if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9579  else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
9580  }
9581 
9582  PaintTH2PolyBins("l");
9583 }
9584 
9585 ////////////////////////////////////////////////////////////////////////////////
9586 /// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9587 
9589 {
9590 
9591  TLatex text;
9592  text.SetTextFont(gStyle->GetTextFont());
9593  text.SetTextColor(fH->GetMarkerColor());
9594  text.SetTextSize(0.02*fH->GetMarkerSize());
9595 
9596  Double_t x, y, z, e, angle = 0;
9597  char value[50];
9598  char format[32];
9599  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9600  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9601 
9602  // 1D histograms
9603  if (fH->GetDimension() == 1) {
9604  Bool_t getentries = kFALSE;
9605  Double_t yt;
9606  TProfile *hp = (TProfile*)fH;
9607  if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9608  Hoption.Text = Hoption.Text-2000;
9609  getentries = kTRUE;
9610  }
9611  if (Hoption.Text == 1) angle = 90;
9612  text.SetTextAlign(11);
9613  if (angle == 90) text.SetTextAlign(12);
9614  if (angle == 0) text.SetTextAlign(21);
9615  text.TAttText::Modify();
9616  Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9617  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9618  if (Hoption.Bar) {
9619  x = fH->GetXaxis()->GetBinLowEdge(i)+
9620  fH->GetXaxis()->GetBinWidth(i)*
9621  (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9622  } else {
9623  x = fH->GetXaxis()->GetBinCenter(i);
9624  }
9625  y = fH->GetBinContent(i);
9626  yt = y;
9627  if (gStyle->GetHistMinimumZero() && y<0) y = 0;
9628  if (getentries) yt = hp->GetBinEntries(i);
9629  if (yt == 0.) continue;
9630  snprintf(value,50,format,yt);
9631  if (Hoption.Logx) {
9632  if (x > 0) x = TMath::Log10(x);
9633  else continue;
9634  }
9635  if (Hoption.Logy) {
9636  if (y > 0) y = TMath::Log10(y);
9637  else continue;
9638  }
9639  if (y >= gPad->GetY2()) continue;
9640  if (y <= gPad->GetY1()) continue;
9641  text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
9642  }
9643 
9644  // 2D histograms
9645  } else {
9646  text.SetTextAlign(22);
9647  if (Hoption.Text == 1) angle = 0;
9648  text.SetTextAngle(angle);
9649  text.TAttText::Modify();
9650  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9651  y = fYaxis->GetBinCenter(j);
9652  if (Hoption.Logy) {
9653  if (y > 0) y = TMath::Log10(y);
9654  else continue;
9655  }
9656  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9657  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9658  x = fXaxis->GetBinCenter(i);
9659  if (Hoption.Logx) {
9660  if (x > 0) x = TMath::Log10(x);
9661  else continue;
9662  }
9663  if (!IsInside(x,y)) continue;
9664  z = fH->GetBinContent(bin);
9665  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9666  if (Hoption.Text>2000) {
9667  e = fH->GetBinError(bin);
9668  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9669  "%",gStyle->GetPaintTextFormat(),
9670  "%",gStyle->GetPaintTextFormat());
9671  snprintf(value,50,format,z,e);
9672  } else {
9673  snprintf(value,50,format,z);
9674  }
9675  text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9676  angle,0.02*fH->GetMarkerSize(),value);
9677  }
9678  }
9679  }
9680 }
9681 
9682 ////////////////////////////////////////////////////////////////////////////////
9683 /// [Control function to draw a 3D implicit functions.](#HP27)
9684 
9686 {
9687 
9688  Int_t irep;
9689 
9690  TGaxis *axis = new TGaxis();
9691  TAxis *xaxis = fH->GetXaxis();
9692  TAxis *yaxis = fH->GetYaxis();
9693  TAxis *zaxis = fH->GetZaxis();
9694 
9695  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
9696  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
9697  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
9698  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
9699  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
9700  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
9701 
9703 
9704  TView *view = gPad->GetView();
9705  if (!view) {
9706  Error("PaintTF3", "no TView in current pad");
9707  return;
9708  }
9709  Double_t thedeg = 90 - gPad->GetTheta();
9710  Double_t phideg = -90 - gPad->GetPhi();
9711  Double_t psideg = view->GetPsi();
9712  view->SetView(phideg, thedeg, psideg, irep);
9713 
9714  fLego->InitMoveScreen(-1.1,1.1);
9715 
9716  if (Hoption.BackBox) {
9719  fLego->BackBox(90);
9720  }
9721 
9723 
9725  fH->GetNbinsY(),
9726  fH->GetNbinsZ(), "BF");
9727 
9728  if (Hoption.FrontBox) {
9729  fLego->InitMoveScreen(-1.1,1.1);
9731  fLego->FrontBox(90);
9732  }
9733  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9734 
9735  PaintTitle();
9736 
9737  delete axis;
9738  delete fLego; fLego = 0;
9739 }
9740 
9741 ////////////////////////////////////////////////////////////////////////////////
9742 /// Draw the histogram title
9743 ///
9744 /// The title is drawn according to the title alignment returned by
9745 /// `GetTitleAlign()`. It is a 2 digits integer): hv
9746 ///
9747 /// where `h` is the horizontal alignment and `v` is the
9748 /// vertical alignment.
9749 ///
9750 /// - `h` can get the values 1 2 3 for left, center, and right
9751 /// - `v` can get the values 1 2 3 for bottom, middle and top
9752 ///
9753 /// for instance the default alignment is: 13 (left top)
9754 
9756 {
9757 
9758  if (Hoption.Same) return;
9759  if (fH->TestBit(TH1::kNoTitle)) return;
9760  Int_t nt = strlen(fH->GetTitle());
9761  TPaveText *title = 0;
9762  TObject *obj;
9763  TIter next(gPad->GetListOfPrimitives());
9764  while ((obj = next())) {
9765  if (!obj->InheritsFrom(TPaveText::Class())) continue;
9766  title = (TPaveText*)obj;
9767  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
9768  break;
9769  }
9770  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
9771  if (title) delete title;
9772  return;
9773  }
9774  Double_t ht = gStyle->GetTitleH();
9775  Double_t wt = gStyle->GetTitleW();
9776  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
9777  if (ht <= 0) ht = 0.05;
9778  if (wt <= 0) {
9779  TLatex l;
9780  l.SetTextSize(ht);
9781  l.SetTitle(fH->GetTitle());
9782  // adjustment in case the title has several lines (#splitline)
9783  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
9784  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
9785  wt = TMath::Min(0.7, 0.02+wndc);
9786  }
9787  if (title) {
9788  TText *t0 = (TText*)title->GetLine(0);
9789  if (t0) {
9790  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
9791  t0->SetTitle(fH->GetTitle());
9792  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
9793  }
9794  return;
9795  }
9796 
9797  Int_t talh = gStyle->GetTitleAlign()/10;
9798  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
9799  Int_t talv = gStyle->GetTitleAlign()%10;
9800  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
9801  Double_t xpos, ypos;
9802  xpos = gStyle->GetTitleX();
9803  ypos = gStyle->GetTitleY();
9804  if (talh == 2) xpos = xpos-wt/2.;
9805  if (talh == 3) xpos = xpos-wt;
9806  if (talv == 2) ypos = ypos+ht/2.;
9807  if (talv == 1) ypos = ypos+ht;
9808 
9809  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
9810 
9811  // box with the histogram title
9813  ptitle->SetFillStyle(gStyle->GetTitleStyle());
9814  ptitle->SetName("title");
9817  ptitle->SetTextFont(gStyle->GetTitleFont(""));
9818  if (gStyle->GetTitleFont("")%10 > 2)
9819  ptitle->SetTextSize(gStyle->GetTitleFontSize());
9820  ptitle->AddText(fH->GetTitle());
9821  ptitle->SetBit(kCanDelete);
9822  ptitle->Draw();
9823  ptitle->Paint();
9824 
9825  if(!gPad->IsEditable()) delete ptitle;
9826 }
9827 
9828 ////////////////////////////////////////////////////////////////////////////////
9829 /// Process message `mess`.
9830 
9831 void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
9832 {
9833 
9834  if (!strcmp(mess,"SetF3")) {
9836  } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
9838  } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
9839  TVectorD &v = (TVectorD&)(*obj);
9840  Double_t xclip = v(0);
9841  Double_t yclip = v(1);
9842  Double_t zclip = v(2);
9843  TPainter3dAlgorithms::SetF3ClippingBoxOn(xclip,yclip,zclip);
9844  }
9845 }
9846 
9847 ////////////////////////////////////////////////////////////////////////////////
9848 /// Static function.
9849 ///
9850 /// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
9851 /// This procedure can be used to create an all-sky map in Galactic
9852 /// coordinates with an equal-area Aitoff projection. Output map
9853 /// coordinates are zero longitude centered.
9854 /// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
9855 ///
9856 /// source: GMT
9857 ///
9858 /// code from Ernst-Jan Buis
9859 
9861 {
9862 
9863  Double_t x, y;
9864 
9865  Double_t alpha2 = (l/2)*TMath::DegToRad();
9866  Double_t delta = b*TMath::DegToRad();
9867  Double_t r2 = TMath::Sqrt(2.);
9868  Double_t f = 2*r2/TMath::Pi();
9869  Double_t cdec = TMath::Cos(delta);
9870  Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
9871  x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
9872  y = TMath::Sin(delta)*r2/denom;
9873  x *= TMath::RadToDeg()/f;
9874  y *= TMath::RadToDeg()/f;
9875  // x *= -1.; // for a skymap swap left<->right
9876  Al = x;
9877  Ab = y;
9878 
9879  return 0;
9880 }
9881 
9882 ////////////////////////////////////////////////////////////////////////////////
9883 /// Static function
9884 ///
9885 /// Probably the most famous of the various map projections, the Mercator projection
9886 /// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
9887 /// with no distortion along the equator.
9888 /// The Mercator projection has been used extensively for world maps in which the distortion towards
9889 /// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
9890 /// Greenland is larger than South America. In reality, the latter is about eight times the size of
9891 /// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
9892 /// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
9893 /// code from Ernst-Jan Buis
9894 
9896 {
9897 
9898  Al = l;
9900  Ab = TMath::Log(aid);
9901  return 0;
9902 }
9903 
9904 ////////////////////////////////////////////////////////////////////////////////
9905 /// Static function code from Ernst-Jan Buis
9906 
9908 {
9909 
9910  Al = l*cos(b*TMath::DegToRad());
9911  Ab = b;
9912  return 0;
9913 }
9914 
9915 ////////////////////////////////////////////////////////////////////////////////
9916 /// Static function code from Ernst-Jan Buis
9917 
9919 {
9920 
9921  Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
9922  Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
9923  return 0;
9924 }
9925 
9926 ////////////////////////////////////////////////////////////////////////////////
9927 /// Recompute the histogram range following graphics operations.
9928 
9930 {
9931 
9932  if (Hoption.Same) return;
9933 
9934  // Compute x,y range
9935  Double_t xmin = Hparam.xmin;
9936  Double_t xmax = Hparam.xmax;
9937  Double_t ymin = Hparam.ymin;
9938  Double_t ymax = Hparam.ymax;
9939 
9940  Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
9941  if (Hoption.Proj ==1) {
9942  // TODO : check x range not lower than -180 and not higher than 180
9943  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9944  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9945  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9946  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9947 
9948  if (xmin > xmin_aid) xmin = xmin_aid;
9949  if (ymin > ymin_aid) ymin = ymin_aid;
9950  if (xmax < xmax_aid) xmax = xmax_aid;
9951  if (ymax < ymax_aid) ymax = ymax_aid;
9952  if (Hparam.ymin<0 && Hparam.ymax>0) {
9953  // there is an 'equator', check its range in the plot..
9954  THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
9955  THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
9956  if (xmin >xmin_aid) xmin = xmin_aid;
9957  if (xmax <xmax_aid) xmax = xmax_aid;
9958  }
9959  if (Hparam.xmin<0 && Hparam.xmax>0) {
9960  THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
9961  THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
9962  if (ymin >ymin_aid) ymin = ymin_aid;
9963  if (ymax <ymax_aid) ymax = ymax_aid;
9964  }
9965  } else if ( Hoption.Proj ==2) {
9966  if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
9967  Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
9968  Hoption.Proj = 0;
9969  } else {
9970  THistPainter::ProjectMercator2xy(Hparam.xmin, Hparam.ymin, xmin, ymin);
9971  THistPainter::ProjectMercator2xy(Hparam.xmax, Hparam.ymax, xmax, ymax);
9972  }
9973  } else if (Hoption.Proj == 3) {
9974  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9975  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9976  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9977  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9978 
9979  if (xmin > xmin_aid) xmin = xmin_aid;
9980  if (ymin > ymin_aid) ymin = ymin_aid;
9981  if (xmax < xmax_aid) xmax = xmax_aid;
9982  if (ymax < ymax_aid) ymax = ymax_aid;
9983  if (Hparam.ymin<0 && Hparam.ymax>0) {
9984  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
9985  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
9986  if (xmin >xmin_aid) xmin = xmin_aid;
9987  if (xmax <xmax_aid) xmax = xmax_aid;
9988  }
9989  if (Hparam.xmin<0 && Hparam.xmax>0) {
9990  THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
9991  THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
9992  if (ymin >ymin_aid) ymin = ymin_aid;
9993  if (ymax <ymax_aid) ymax = ymax_aid;
9994  }
9995  } else if (Hoption.Proj == 4) {
9996  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9997  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9998  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9999  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
10000 
10001  if (xmin > xmin_aid) xmin = xmin_aid;
10002  if (ymin > ymin_aid) ymin = ymin_aid;
10003  if (xmax < xmax_aid) xmax = xmax_aid;
10004  if (ymax < ymax_aid) ymax = ymax_aid;
10005  if (Hparam.ymin<0 && Hparam.ymax>0) {
10006  THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10007  THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10008  if (xmin >xmin_aid) xmin = xmin_aid;
10009  if (xmax <xmax_aid) xmax = xmax_aid;
10010  }
10011  if (Hparam.xmin<0 && Hparam.xmax>0) {
10012  THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10013  THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10014  if (ymin >ymin_aid) ymin = ymin_aid;
10015  if (ymax <ymax_aid) ymax = ymax_aid;
10016  }
10017  }
10018  Hparam.xmin= xmin;
10019  Hparam.xmax= xmax;
10020  Hparam.ymin= ymin;
10021  Hparam.ymax= ymax;
10022 
10023  Double_t dx = xmax-xmin;
10024  Double_t dy = ymax-ymin;
10025  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10026  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10027 
10028  // Range() could change the size of the pad pixmap and therefore should
10029  // be called before the other paint routines
10030  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10031  ymin - dyr*gPad->GetBottomMargin(),
10032  xmax + dxr*gPad->GetRightMargin(),
10033  ymax + dyr*gPad->GetTopMargin());
10034  gPad->RangeAxis(xmin, ymin, xmax, ymax);
10035 }
10036 
10037 ////////////////////////////////////////////////////////////////////////////////
10038 /// Set current histogram to `h`
10039 
10041 {
10042 
10043  if (h == 0) return;
10044  fH = h;
10045  fXaxis = h->GetXaxis();
10046  fYaxis = h->GetYaxis();
10047  fZaxis = h->GetZaxis();
10049 }
10050 
10051 ////////////////////////////////////////////////////////////////////////////////
10052 /// Initialize various options to draw 2D histograms.
10053 
10055 {
10056 
10057  static const char *where = "TableInit";
10058 
10059  Int_t first, last;
10060  Double_t yMARGIN= gStyle->GetHistTopMargin();
10061  Double_t zmin, zmax;
10062  Int_t maximum = 0;
10063  Int_t minimum = 0;
10064  if (fH->GetMaximumStored() != -1111) maximum = 1;
10065  if (fH->GetMinimumStored() != -1111) minimum = 1;
10066 
10067  // ----------------- Compute X axis parameters
10068  first = fXaxis->GetFirst();
10069  last = fXaxis->GetLast();
10070  Hparam.xlast = last;
10071  Hparam.xfirst = first;
10072  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
10073  Hparam.xbinsize = fXaxis->GetBinWidth(first);
10074  Hparam.xmin = Hparam.xlowedge;
10075  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
10076 
10077  // if log scale in X, replace xmin,max by the log
10078  if (Hoption.Logx) {
10079  // find the first edge of a bin that is > 0
10080  if (Hparam.xlowedge <=0 ) {
10081  Hparam.xlowedge = fXaxis->GetBinUpEdge(fXaxis->FindFixBin(0.01*Hparam.xbinsize));
10082  Hparam.xmin = Hparam.xlowedge;
10083  }
10084  if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10085  Error(where, "cannot set X axis to log scale");
10086  return 0;
10087  }
10088  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
10089  if (Hparam.xfirst < first) Hparam.xfirst = first;
10090  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
10091  if (Hparam.xlast > last) Hparam.xlast = last;
10092  Hparam.xmin = TMath::Log10(Hparam.xmin);
10093  Hparam.xmax = TMath::Log10(Hparam.xmax);
10094  }
10095 
10096  // ----------------- Compute Y axis parameters
10097  first = fYaxis->GetFirst();
10098  last = fYaxis->GetLast();
10099  Hparam.ylast = last;
10100  Hparam.yfirst = first;
10101  Hparam.ylowedge = fYaxis->GetBinLowEdge(first);
10102  Hparam.ybinsize = fYaxis->GetBinWidth(first);
10103  if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10104  Hparam.ymin = Hparam.ylowedge;
10105  Hparam.ymax = fYaxis->GetBinLowEdge(last)+fYaxis->GetBinWidth(last);
10106 
10107  // if log scale in Y, replace ymin,max by the log
10108  if (Hoption.Logy) {
10109  if (Hparam.ylowedge <=0 ) {
10110  Hparam.ylowedge = fYaxis->GetBinUpEdge(fYaxis->FindFixBin(0.01*Hparam.ybinsize));
10111  Hparam.ymin = Hparam.ylowedge;
10112  }
10113  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10114  Error(where, "cannot set Y axis to log scale");
10115  return 0;
10116  }
10117  Hparam.yfirst= fYaxis->FindFixBin(Hparam.ymin);
10118  if (Hparam.yfirst < first) Hparam.yfirst = first;
10119  Hparam.ylast = fYaxis->FindFixBin(Hparam.ymax);
10120  if (Hparam.ylast > last) Hparam.ylast = last;
10121  Hparam.ymin = TMath::Log10(Hparam.ymin);
10122  Hparam.ymax = TMath::Log10(Hparam.ymax);
10123  }
10124 
10125 
10126  // ----------------- Compute Z axis parameters
10127  Double_t bigp = TMath::Power(10,32);
10128  zmax = -bigp;
10129  zmin = bigp;
10130  Double_t c1, e1;
10131  Double_t allchan = 0;
10132  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10133  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10134  c1 = fH->GetBinContent(i,j);
10135  zmax = TMath::Max(zmax,c1);
10136  if (Hoption.Error) {
10137  e1 = fH->GetBinError(i,j);
10138  zmax = TMath::Max(zmax,c1+e1);
10139  }
10140  zmin = TMath::Min(zmin,c1);
10141  allchan += c1;
10142  }
10143  }
10144 
10145  // Take into account maximum , minimum
10146 
10147  if (maximum) zmax = fH->GetMaximumStored();
10148  if (minimum) zmin = fH->GetMinimumStored();
10149  if (Hoption.Logz && zmax < 0) {
10150  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10151  return 0;
10152  } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10153  zmin = 0.01;
10154  zmax = 10.;
10155  }
10156  if (zmin >= zmax) {
10157  if (Hoption.Logz) {
10158  if (zmax > 0) zmin = 0.001*zmax;
10159  else {
10160  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10161  return 0;
10162  }
10163  }
10164  }
10165 
10166  // take into account normalization factor
10167  Hparam.allchan = allchan;
10168  Double_t factor = allchan;
10169  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10170  if (allchan) factor /= allchan;
10171  if (factor == 0) factor = 1;
10172  Hparam.factor = factor;
10173  zmax = factor*zmax;
10174  zmin = factor*zmin;
10175  c1 = zmax;
10176  if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10177 
10178  // For log scales, histogram coordinates are log10(ymin) and
10179  // log10(ymax). Final adjustment (if not option "Same")
10180  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10181  // Maximum and Minimum are not defined.
10182  if (Hoption.Logz) {
10183  if (zmin <= 0) {
10184  zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10185  fH->SetMinimum(zmin);
10186  }
10187  zmin = TMath::Log10(zmin);
10188  if (!minimum) zmin += TMath::Log10(0.5);
10189  zmax = TMath::Log10(zmax);
10190  if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10191  goto LZMIN;
10192  }
10193 
10194  // final adjustment of YMAXI for linear scale (if not option "Same"):
10195  // decrease histogram height to MAX% of allowed height if HMAXIM
10196  // has not been called.
10197  // MAX% is the value in percent which has been set in HPLSET
10198  // (default is 90%).
10199  if (!maximum) {
10200  zmax += yMARGIN*(zmax-zmin);
10201  }
10202 
10203  // final adjustment of ymin for linear scale.
10204  // if minimum is not set , then ymin is set to zero if >0
10205  // or to ymin - yMARGIN if <0.
10206  if (!minimum) {
10207  if (gStyle->GetHistMinimumZero()) {
10208  if (zmin >= 0) zmin = 0;
10209  else zmin -= yMARGIN*(zmax-zmin);
10210  } else {
10211  Double_t dzmin = yMARGIN*(zmax-zmin);
10212  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10213  else zmin -= dzmin;
10214  }
10215  }
10216 
10217 LZMIN:
10218  Hparam.zmin = zmin;
10219  Hparam.zmax = zmax;
10220 
10221  // Set bar offset and width
10222  Hparam.baroffset = fH->GetBarOffset();
10223  Hparam.barwidth = fH->GetBarWidth();
10224 
10225  return 1;
10226 }
10227 
10228 ////////////////////////////////////////////////////////////////////////////////
10229 /// This function returns the best format to print the error value (e)
10230 /// knowing the parameter value (v) and the format (f) used to print it.
10231 
10232 const char * THistPainter::GetBestFormat(Double_t v, Double_t e, const char *f)
10233 {
10234 
10235  static char ef[20];
10236  char tf[20], tv[64];
10237 
10238  // print v with the format f in tv.
10239  snprintf(tf,20,"%s%s","%",f);
10240  snprintf(tv,64,tf,v);
10241 
10242  // Analyse tv.
10243  TString sv = tv;
10244  int ie = sv.Index("e");
10245  int iE = sv.Index("E");
10246  int id = sv.Index(".");
10247 
10248  // v has been printed with the exponent notation.
10249  // There is 2 cases, the exponent is positive or negative
10250  if (ie >= 0 || iE >= 0) {
10251  if (sv.Index("+") >= 0) {
10252  if (e < 1) {
10253  snprintf(ef,20,"%s.1f","%");
10254  } else {
10255  if (ie >= 0) {
10256  snprintf(ef,20,"%s.%de","%",ie-id-1);
10257  } else {
10258  snprintf(ef,20,"%s.%dE","%",iE-id-1);
10259  }
10260  }
10261  } else {
10262  if (ie >= 0) {
10263  snprintf(ef,20,"%s.%de","%",ie-id-1);
10264  } else {
10265  snprintf(ef,20,"%s.%dE","%",iE-id-1);
10266  }
10267  }
10268 
10269  // There is not '.' in tv. e will be printed with one decimal digit.
10270  } else if (id < 0) {
10271  snprintf(ef,20,"%s.1f","%");
10272 
10273  // There is a '.' in tv and no exponent notation. e's decimal part will
10274  // have the same number of digits as v's one.
10275  } else {
10276  snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
10277  }
10278 
10279  return ef;
10280 }
10281 
10282 ////////////////////////////////////////////////////////////////////////////////
10283 /// Set projection.
10284 
10285 void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10286 {
10287 
10288  if (fShowProjection) return;
10289  TString opt = option;
10290  opt.ToLower();
10291  Int_t projection = 0;
10292  if (opt.Contains("x")) projection = 1;
10293  if (opt.Contains("y")) projection = 2;
10294  if (opt.Contains("z")) projection = 3;
10295  if (opt.Contains("xy")) projection = 4;
10296  if (opt.Contains("yx")) projection = 5;
10297  if (opt.Contains("xz")) projection = 6;
10298  if (opt.Contains("zx")) projection = 7;
10299  if (opt.Contains("yz")) projection = 8;
10300  if (opt.Contains("zy")) projection = 9;
10301  if (projection < 4) fShowOption = option+1;
10302  else fShowOption = option+2;
10303  fShowProjection = projection+100*nbins;
10304  gROOT->MakeDefCanvas();
10305  gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10306  gPad->SetGrid();
10307 }
10308 
10309 ////////////////////////////////////////////////////////////////////////////////
10310 /// Show projection onto X.
10311 
10313 {
10314 
10315  Int_t nbins = (Int_t)fShowProjection/100;
10316  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10317  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10318 
10319  // Erase old position and draw a line at current position
10320  static int pyold1 = 0;
10321  static int pyold2 = 0;
10322  float uxmin = gPad->GetUxmin();
10323  float uxmax = gPad->GetUxmax();
10324  int pxmin = gPad->XtoAbsPixel(uxmin);
10325  int pxmax = gPad->XtoAbsPixel(uxmax);
10326  Float_t upy = gPad->AbsPixeltoY(py);
10327  Float_t y = gPad->PadtoY(upy);
10328  Int_t biny1 = fH->GetYaxis()->FindBin(y);
10329  Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10330  Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10331  Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10332 
10333  if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10334  gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10335  pyold1 = py1;
10336  pyold2 = py2;
10337 
10338  // Create or set the new canvas proj x
10339  TVirtualPad *padsav = gPad;
10340  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10342  if (c) {
10343  c->Clear();
10344  } else {
10345  fShowProjection = 0;
10346  pyold1 = 0;
10347  pyold2 = 0;
10348  return;
10349  }
10350  c->cd();
10351  c->SetLogy(padsav->GetLogz());
10352  c->SetLogx(padsav->GetLogx());
10353 
10354  // Draw slice corresponding to mouse position
10355  TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10356  TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10357  if (hp) {
10358  hp->SetFillColor(38);
10359  // apply a patch from Oliver Freyermuth to set the title in the projection
10360  // using the range of the projected Y values
10361  if (biny1 == biny2) {
10362  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10363  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10364  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10365  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10366  if (fH->GetYaxis()->GetLabels() != NULL) {
10367  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10368  } else {
10369  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10370  }
10371  } else {
10372  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10373  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10374  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10375  // biny1 is used here to get equal precision no matter how large the binrange is,
10376  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10377  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10378  if (fH->GetYaxis()->GetLabels() != NULL) {
10379  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)));
10380  } else {
10381  hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10382  }
10383  }
10384  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10385  hp->SetYTitle("Number of Entries");
10386  hp->Draw();
10387  c->Update();
10388  padsav->cd();
10389  }
10390 }
10391 
10392 ////////////////////////////////////////////////////////////////////////////////
10393 /// Show projection onto Y.
10394 
10396 {
10397 
10398  Int_t nbins = (Int_t)fShowProjection/100;
10399  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10400  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10401 
10402  // Erase old position and draw a line at current position
10403  static int pxold1 = 0;
10404  static int pxold2 = 0;
10405  float uymin = gPad->GetUymin();
10406  float uymax = gPad->GetUymax();
10407  int pymin = gPad->YtoAbsPixel(uymin);
10408  int pymax = gPad->YtoAbsPixel(uymax);
10409  Float_t upx = gPad->AbsPixeltoX(px);
10410  Float_t x = gPad->PadtoX(upx);
10411  Int_t binx1 = fH->GetXaxis()->FindBin(x);
10412  Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10413  Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10414  Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10415 
10416  if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10417  gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10418  pxold1 = px1;
10419  pxold2 = px2;
10420 
10421  // Create or set the new canvas proj y
10422  TVirtualPad *padsav = gPad;
10423  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10425  if (c) {
10426  c->Clear();
10427  } else {
10428  fShowProjection = 0;
10429  pxold1 = 0;
10430  pxold2 = 0;
10431  return;
10432  }
10433  c->cd();
10434  c->SetLogy(padsav->GetLogz());
10435  c->SetLogx(padsav->GetLogy());
10436 
10437  // Draw slice corresponding to mouse position
10438  TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10439  TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10440  if (hp) {
10441  hp->SetFillColor(38);
10442  // apply a patch from Oliver Freyermuth to set the title in the projection
10443  // using the range of the projected X values
10444  if (binx1 == binx2) {
10445  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10446  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10447  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10448  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10449  if (fH->GetXaxis()->GetLabels() != NULL) {
10450  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10451  } else {
10452  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10453  }
10454  } else {
10455  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10456  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10457  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10458  // binx1 is used here to get equal precision no matter how large the binrange is,
10459  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10460  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10461  if (fH->GetXaxis()->GetLabels() != NULL) {
10462  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)));
10463  } else {
10464  hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10465  }
10466  }
10467  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10468  hp->SetYTitle("Number of Entries");
10469  hp->Draw();
10470  c->Update();
10471  padsav->cd();
10472  }
10473 }
10474 
10475 ////////////////////////////////////////////////////////////////////////////////
10476 /// Show projection (specified by `fShowProjection`) of a `TH3`.
10477 /// The drawing option for the projection is in `fShowOption`.
10478 ///
10479 /// First implementation; R.Brun
10480 ///
10481 /// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10482 
10484 {
10485 
10486  Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10487  if (fH->GetDimension() < 3) {
10488  if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10489  if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10490  }
10491 
10492  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10493  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10494 
10495  // Erase old position and draw a line at current position
10496  TView *view = gPad->GetView();
10497  if (!view) return;
10498  TH3 *h3 = (TH3*)fH;
10499  TAxis *xaxis = h3->GetXaxis();
10500  TAxis *yaxis = h3->GetYaxis();
10501  TAxis *zaxis = h3->GetZaxis();
10502  Double_t u[3],xx[3];
10503 
10504  static TPoint line1[2];//store end points of a line, initialised 0 by default
10505  static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10506  static TPoint line3[2];
10507  static TPoint line4[2];
10508  static TPoint endface1[5];
10509  static TPoint endface2[5];
10510  static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10511  static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10512 
10513  Double_t uxmin = gPad->GetUxmin();
10514  Double_t uxmax = gPad->GetUxmax();
10515  Double_t uymin = gPad->GetUymin();
10516  Double_t uymax = gPad->GetUymax();
10517 
10518  int pxmin = gPad->XtoAbsPixel(uxmin);
10519  int pxmax = gPad->XtoAbsPixel(uxmax);
10520  if (pxmin==pxmax) return;
10521  int pymin = gPad->YtoAbsPixel(uymin);
10522  int pymax = gPad->YtoAbsPixel(uymax);
10523  if (pymin==pymax) return;
10524  Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10525  Double_t cy = (pymax-pymin)/(uymax-uymin);
10526  TVirtualPad *padsav = gPad;
10527  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10529  if (!c) {
10530  fShowProjection = 0;
10531  return;
10532  }
10533 
10534  switch ((Int_t)fShowProjection%100) {
10535  case 1:
10536  // "x"
10537  {
10538  Int_t firstY = yaxis->GetFirst();
10539  Int_t lastY = yaxis->GetLast();
10540  Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10541  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10542  yaxis->SetRange(biny,biny2);
10543  Int_t firstZ = zaxis->GetFirst();
10544  Int_t lastZ = zaxis->GetLast();
10545  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10546  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10547  zaxis->SetRange(binz,binz2);
10548  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10549  if (nbins>1 && line1[0].GetX()) {
10550  gVirtualX->DrawPolyLine(2,line2);
10551  gVirtualX->DrawPolyLine(2,line3);
10552  gVirtualX->DrawPolyLine(2,line4);
10553  gVirtualX->DrawPolyLine(5,endface1);
10554  gVirtualX->DrawPolyLine(5,endface2);
10555  }
10556  xx[0] = xaxis->GetXmin();
10557  xx[2] = zaxis->GetBinCenter(binz);
10558  xx[1] = yaxis->GetBinCenter(biny);
10559  view->WCtoNDC(xx,u);
10560  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10561  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10562  xx[0] = xaxis->GetXmax();
10563  view->WCtoNDC(xx,u);
10564  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10565  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10566  gVirtualX->DrawPolyLine(2,line1);
10567  if (nbins>1) {
10568  xx[0] = xaxis->GetXmin();
10569  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10570  xx[1] = yaxis->GetBinCenter(biny);
10571  view->WCtoNDC(xx,u);
10572  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10573  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10574  xx[0] = xaxis->GetXmax();
10575  view->WCtoNDC(xx,u);
10576  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10577  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10578 
10579  xx[0] = xaxis->GetXmin();
10580  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10581  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10582  view->WCtoNDC(xx,u);
10583  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10584  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10585  xx[0] = xaxis->GetXmax();
10586  view->WCtoNDC(xx,u);
10587  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10588  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10589 
10590  xx[0] = xaxis->GetXmin();
10591  xx[2] = zaxis->GetBinCenter(binz);
10592  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10593  view->WCtoNDC(xx,u);
10594  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10595  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10596  xx[0] = xaxis->GetXmax();
10597  view->WCtoNDC(xx,u);
10598  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10599  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10600 
10601  endface1[0].SetX(line1[0].GetX());
10602  endface1[0].SetY(line1[0].GetY());
10603  endface1[1].SetX(line2[0].GetX());
10604  endface1[1].SetY(line2[0].GetY());
10605  endface1[2].SetX(line3[0].GetX());
10606  endface1[2].SetY(line3[0].GetY());
10607  endface1[3].SetX(line4[0].GetX());
10608  endface1[3].SetY(line4[0].GetY());
10609  endface1[4].SetX(line1[0].GetX());
10610  endface1[4].SetY(line1[0].GetY());
10611 
10612  endface2[0].SetX(line1[1].GetX());
10613  endface2[0].SetY(line1[1].GetY());
10614  endface2[1].SetX(line2[1].GetX());
10615  endface2[1].SetY(line2[1].GetY());
10616  endface2[2].SetX(line3[1].GetX());
10617  endface2[2].SetY(line3[1].GetY());
10618  endface2[3].SetX(line4[1].GetX());
10619  endface2[3].SetY(line4[1].GetY());
10620  endface2[4].SetX(line1[1].GetX());
10621  endface2[4].SetY(line1[1].GetY());
10622 
10623  gVirtualX->DrawPolyLine(2,line2);
10624  gVirtualX->DrawPolyLine(2,line3);
10625  gVirtualX->DrawPolyLine(2,line4);
10626  gVirtualX->DrawPolyLine(5,endface1);
10627  gVirtualX->DrawPolyLine(5,endface2);
10628  }
10629  c->Clear();
10630  c->cd();
10631  TH1 *hp = h3->Project3D("x");
10632  yaxis->SetRange(firstY,lastY);
10633  zaxis->SetRange(firstZ,lastZ);
10634  if (hp) {
10635  hp->SetFillColor(38);
10636  if (nbins == 1)
10637  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10638  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10639  else {
10640  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),
10641  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10642  }
10643  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10644  hp->SetYTitle("Number of Entries");
10645  hp->Draw(fShowOption.Data());
10646  }
10647  }
10648  break;
10649 
10650  case 2:
10651  // "y"
10652  {
10653  Int_t firstX = xaxis->GetFirst();
10654  Int_t lastX = xaxis->GetLast();
10655  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10656  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10657  xaxis->SetRange(binx,binx2);
10658  Int_t firstZ = zaxis->GetFirst();
10659  Int_t lastZ = zaxis->GetLast();
10660  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10661  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10662  zaxis->SetRange(binz,binz2);
10663  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10664  if (nbins>1 && line1[0].GetX()) {
10665  gVirtualX->DrawPolyLine(2,line2);
10666  gVirtualX->DrawPolyLine(2,line3);
10667  gVirtualX->DrawPolyLine(2,line4);
10668  gVirtualX->DrawPolyLine(5,endface1);
10669  gVirtualX->DrawPolyLine(5,endface2);
10670  }
10671  xx[0]=xaxis->GetBinCenter(binx);
10672  xx[2] = zaxis->GetBinCenter(binz);
10673  xx[1] = yaxis->GetXmin();
10674  view->WCtoNDC(xx,u);
10675  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10676  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10677  xx[1] = yaxis->GetXmax();
10678  view->WCtoNDC(xx,u);
10679  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10680  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10681  gVirtualX->DrawPolyLine(2,line1);
10682  if (nbins>1) {
10683  xx[1] = yaxis->GetXmin();
10684  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10685  xx[0] = xaxis->GetBinCenter(binx);
10686  view->WCtoNDC(xx,u);
10687  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10688  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10689  xx[1] = yaxis->GetXmax();
10690  view->WCtoNDC(xx,u);
10691  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10692  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10693 
10694  xx[1] = yaxis->GetXmin();
10695  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10696  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10697  view->WCtoNDC(xx,u);
10698  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10699  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10700  xx[1] = yaxis->GetXmax();
10701  view->WCtoNDC(xx,u);
10702  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10703  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10704 
10705  xx[1] = yaxis->GetXmin();
10706  xx[2] = zaxis->GetBinCenter(binz);
10707  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10708  view->WCtoNDC(xx,u);
10709  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10710  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10711  xx[1] = yaxis->GetXmax();
10712  view->WCtoNDC(xx,u);
10713  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10714  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10715 
10716  endface1[0].SetX(line1[0].GetX());
10717  endface1[0].SetY(line1[0].GetY());
10718  endface1[1].SetX(line2[0].GetX());
10719  endface1[1].SetY(line2[0].GetY());
10720  endface1[2].SetX(line3[0].GetX());
10721  endface1[2].SetY(line3[0].GetY());
10722  endface1[3].SetX(line4[0].GetX());
10723  endface1[3].SetY(line4[0].GetY());
10724  endface1[4].SetX(line1[0].GetX());
10725  endface1[4].SetY(line1[0].GetY());
10726 
10727  endface2[0].SetX(line1[1].GetX());
10728  endface2[0].SetY(line1[1].GetY());
10729  endface2[1].SetX(line2[1].GetX());
10730  endface2[1].SetY(line2[1].GetY());
10731  endface2[2].SetX(line3[1].GetX());
10732  endface2[2].SetY(line3[1].GetY());
10733  endface2[3].SetX(line4[1].GetX());
10734  endface2[3].SetY(line4[1].GetY());
10735  endface2[4].SetX(line1[1].GetX());
10736  endface2[4].SetY(line1[1].GetY());
10737 
10738  gVirtualX->DrawPolyLine(2,line2);
10739  gVirtualX->DrawPolyLine(2,line3);
10740  gVirtualX->DrawPolyLine(2,line4);
10741  gVirtualX->DrawPolyLine(5,endface1);
10742  gVirtualX->DrawPolyLine(5,endface2);
10743  }
10744  c->Clear();
10745  c->cd();
10746  TH1 *hp = h3->Project3D("y");
10747  xaxis->SetRange(firstX,lastX);
10748  zaxis->SetRange(firstZ,lastZ);
10749  if (hp) {
10750  hp->SetFillColor(38);
10751  if (nbins == 1)
10752  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10753  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10754  else
10755  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),
10756  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10757  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10758  hp->SetYTitle("Number of Entries");
10759  hp->Draw(fShowOption.Data());
10760  }
10761  }
10762  break;
10763 
10764  case 3:
10765  // "z"
10766  {
10767  Int_t firstX = xaxis->GetFirst();
10768  Int_t lastX = xaxis->GetLast();
10769  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10770  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10771  xaxis->SetRange(binx,binx2);
10772  Int_t firstY = yaxis->GetFirst();
10773  Int_t lastY = yaxis->GetLast();
10774  Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
10775  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10776  yaxis->SetRange(biny,biny2);
10777  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10778  if (nbins>1 && line1[0].GetX()) {
10779  gVirtualX->DrawPolyLine(2,line2);
10780  gVirtualX->DrawPolyLine(2,line3);
10781  gVirtualX->DrawPolyLine(2,line4);
10782  gVirtualX->DrawPolyLine(5,endface1);
10783  gVirtualX->DrawPolyLine(5,endface2);
10784  }
10785  xx[0] = xaxis->GetBinCenter(binx);
10786  xx[1] = yaxis->GetBinCenter(biny);
10787  xx[2] = zaxis->GetXmin();
10788  view->WCtoNDC(xx,u);
10789  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10790  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10791  xx[2] = zaxis->GetXmax();
10792  view->WCtoNDC(xx,u);
10793  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10794  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10795  gVirtualX->DrawPolyLine(2,line1);
10796  if (nbins>1) {
10797  xx[2] = zaxis->GetXmin();
10798  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10799  xx[0] = xaxis->GetBinCenter(binx);
10800  view->WCtoNDC(xx,u);
10801  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10802  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10803  xx[2] = zaxis->GetXmax();
10804  view->WCtoNDC(xx,u);
10805  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10806  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10807 
10808  xx[2] = zaxis->GetXmin();
10809  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10810  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10811  view->WCtoNDC(xx,u);
10812  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10813  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10814  xx[2] = zaxis->GetXmax();
10815  view->WCtoNDC(xx,u);
10816  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10817  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10818 
10819  xx[2] = zaxis->GetXmin();
10820  xx[1] = yaxis->GetBinCenter(biny);
10821  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10822  view->WCtoNDC(xx,u);
10823  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10824  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10825  xx[2] = zaxis->GetXmax();
10826  view->WCtoNDC(xx,u);
10827  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10828  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10829 
10830  endface1[0].SetX(line1[0].GetX());
10831  endface1[0].SetY(line1[0].GetY());
10832  endface1[1].SetX(line2[0].GetX());
10833  endface1[1].SetY(line2[0].GetY());
10834  endface1[2].SetX(line3[0].GetX());
10835  endface1[2].SetY(line3[0].GetY());
10836  endface1[3].SetX(line4[0].GetX());
10837  endface1[3].SetY(line4[0].GetY());
10838  endface1[4].SetX(line1[0].GetX());
10839  endface1[4].SetY(line1[0].GetY());
10840 
10841  endface2[0].SetX(line1[1].GetX());
10842  endface2[0].SetY(line1[1].GetY());
10843  endface2[1].SetX(line2[1].GetX());
10844  endface2[1].SetY(line2[1].GetY());
10845  endface2[2].SetX(line3[1].GetX());
10846  endface2[2].SetY(line3[1].GetY());
10847  endface2[3].SetX(line4[1].GetX());
10848  endface2[3].SetY(line4[1].GetY());
10849  endface2[4].SetX(line1[1].GetX());
10850  endface2[4].SetY(line1[1].GetY());
10851 
10852  gVirtualX->DrawPolyLine(2,line2);
10853  gVirtualX->DrawPolyLine(2,line3);
10854  gVirtualX->DrawPolyLine(2,line4);
10855  gVirtualX->DrawPolyLine(5,endface1);
10856  gVirtualX->DrawPolyLine(5,endface2);
10857  }
10858  c->Clear();
10859  c->cd();
10860  TH1 *hp = h3->Project3D("z");
10861  xaxis->SetRange(firstX,lastX);
10862  yaxis->SetRange(firstY,lastY);
10863  if (hp) {
10864  hp->SetFillColor(38);
10865  if (nbins == 1)
10866  hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10867  biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
10868  else
10869  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),
10870  biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
10871  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10872  hp->SetYTitle("Number of Entries");
10873  hp->Draw(fShowOption.Data());
10874  }
10875  }
10876  break;
10877 
10878  case 4:
10879  // "xy"
10880  {
10881  Int_t first = zaxis->GetFirst();
10882  Int_t last = zaxis->GetLast();
10883  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10884  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10885  zaxis->SetRange(binz,binz2);
10886  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10887  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10888  xx[0] = xaxis->GetXmin();
10889  xx[1] = yaxis->GetXmax();
10890  xx[2] = zaxis->GetBinCenter(binz);
10891  view->WCtoNDC(xx,u);
10892  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10893  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10894  rect1[4].SetX(rect1[0].GetX());
10895  rect1[4].SetY(rect1[0].GetY());
10896  xx[0] = xaxis->GetXmax();
10897  view->WCtoNDC(xx,u);
10898  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10899  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10900  xx[1] = yaxis->GetXmin();
10901  view->WCtoNDC(xx,u);
10902  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10903  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10904  xx[0] = xaxis->GetXmin();
10905  view->WCtoNDC(xx,u);
10906  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10907  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10908  gVirtualX->DrawPolyLine(5,rect1);
10909  if (nbins>1) {
10910  xx[0] = xaxis->GetXmin();
10911  xx[1] = yaxis->GetXmax();
10912  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10913  view->WCtoNDC(xx,u);
10914  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10915  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10916  rect2[4].SetX(rect2[0].GetX());
10917  rect2[4].SetY(rect2[0].GetY());
10918  xx[0] = xaxis->GetXmax();
10919  view->WCtoNDC(xx,u);
10920  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10921  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10922  xx[1] = yaxis->GetXmin();
10923  view->WCtoNDC(xx,u);
10924  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10925  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10926  xx[0] = xaxis->GetXmin();
10927  view->WCtoNDC(xx,u);
10928  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10929  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10930  gVirtualX->DrawPolyLine(5,rect2);
10931  }
10932 
10933  c->Clear();
10934  c->cd();
10935  TH2 *hp = (TH2*)h3->Project3D("xy");
10936  zaxis->SetRange(first,last);
10937  if (hp) {
10938  hp->SetFillColor(38);
10939  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
10940  else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
10941  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10942  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10943  hp->SetZTitle("Number of Entries");
10944  hp->Draw(fShowOption.Data());
10945  }
10946  }
10947  break;
10948 
10949  case 5:
10950  // "yx"
10951  {
10952  Int_t first = zaxis->GetFirst();
10953  Int_t last = zaxis->GetLast();
10954  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10955  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10956  zaxis->SetRange(binz,binz2);
10957  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10958  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10959  xx[0] = xaxis->GetXmin();
10960  xx[1] = yaxis->GetXmax();
10961  xx[2] = zaxis->GetBinCenter(binz);
10962  view->WCtoNDC(xx,u);
10963  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10964  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10965  rect1[4].SetX(rect1[0].GetX());
10966  rect1[4].SetY(rect1[0].GetY());
10967  xx[0] = xaxis->GetXmax();
10968  view->WCtoNDC(xx,u);
10969  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10970  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10971  xx[1] = yaxis->GetXmin();
10972  view->WCtoNDC(xx,u);
10973  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10974  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10975  xx[0] = xaxis->GetXmin();
10976  view->WCtoNDC(xx,u);
10977  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10978  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10979  gVirtualX->DrawPolyLine(5,rect1);
10980  if (nbins>1) {
10981  xx[0] = xaxis->GetXmin();
10982  xx[1] = yaxis->GetXmax();
10983  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10984  view->WCtoNDC(xx,u);
10985  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10986  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10987  rect2[4].SetX(rect2[0].GetX());
10988  rect2[4].SetY(rect2[0].GetY());
10989  xx[0] = xaxis->GetXmax();
10990  view->WCtoNDC(xx,u);
10991  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10992  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10993  xx[1] = yaxis->GetXmin();
10994  view->WCtoNDC(xx,u);
10995  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10996  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10997  xx[0] = xaxis->GetXmin();
10998  view->WCtoNDC(xx,u);
10999  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11000  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11001  gVirtualX->DrawPolyLine(5,rect2);
11002  }
11003  c->Clear();
11004  c->cd();
11005  TH2 *hp = (TH2*)h3->Project3D("yx");
11006  zaxis->SetRange(first,last);
11007  if (hp) {
11008  hp->SetFillColor(38);
11009  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11010  else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11011  hp->SetXTitle(fH->GetXaxis()->GetTitle());
11012  hp->SetYTitle(fH->GetYaxis()->GetTitle());
11013  hp->SetZTitle("Number of Entries");
11014  hp->Draw(fShowOption.Data());
11015  }
11016  }
11017  break;
11018 
11019  case 6:
11020  // "xz"
11021  {
11022  Int_t first = yaxis->GetFirst();
11023  Int_t last = yaxis->GetLast();
11024  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11025  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11026  yaxis->SetRange(biny,biny2);
11027  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11028  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11029  xx[0] = xaxis->GetXmin();
11030  xx[2] = zaxis->GetXmax();
11031  xx[1] = yaxis->GetBinCenter(biny);
11032  view->WCtoNDC(xx,u);
11033  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11034  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11035  rect1[4].SetX(rect1[0].GetX());
11036  rect1[4].SetY(rect1[0].GetY());
11037  xx[0] = xaxis->GetXmax();
11038  view->WCtoNDC(xx,u);
11039  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11040  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11041  xx[2] = zaxis->GetXmin();
11042  view->WCtoNDC(xx,u);
11043  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11044  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11045  xx[0] = xaxis->GetXmin();
11046  view->WCtoNDC(xx,u);
11047  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11048  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11049  gVirtualX->DrawPolyLine(5,rect1);
11050  if (nbins>1) {
11051  xx[0] = xaxis->GetXmin();
11052  xx[2] = zaxis->GetXmax();
11053  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11054  view->WCtoNDC(xx,u);
11055  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11056  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11057  rect2[4].SetX(rect2[0].GetX());
11058  rect2[4].SetY(rect2[0].GetY());
11059  xx[0] = xaxis->GetXmax();
11060  view->WCtoNDC(xx,u);
11061  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11062  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11063  xx[2] = zaxis->GetXmin();
11064  view->WCtoNDC(xx,u);
11065  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11066  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11067  xx[0] = xaxis->GetXmin();
11068  view->WCtoNDC(xx,u);
11069  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11070  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11071  gVirtualX->DrawPolyLine(5,rect2);
11072  }
11073  c->Clear();
11074  c->cd();
11075  TH2 *hp = (TH2*)h3->Project3D("xz");
11076  yaxis->SetRange(first,last);
11077  if (hp) {
11078  hp->SetFillColor(38);
11079  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11080  else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11081  hp->SetXTitle(fH->GetZaxis()->GetTitle());
11082  hp->SetYTitle(fH->GetXaxis()->GetTitle());
11083  hp->SetZTitle("Number of Entries");
11084  hp->Draw(fShowOption.Data());
11085  }
11086  }
11087  break;
11088 
11089  case 7:
11090  // "zx"
11091  {
11092  Int_t first = yaxis->GetFirst();
11093  Int_t last = yaxis->GetLast();
11094  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11095  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11096  yaxis->SetRange(biny,biny2);
11097  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11098  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11099  xx[0] = xaxis->GetXmin();
11100  xx[2] = zaxis->GetXmax();
11101  xx[1] = yaxis->GetBinCenter(biny);
11102  view->WCtoNDC(xx,u);
11103  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11104  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11105  rect1[4].SetX(rect1[0].GetX());
11106  rect1[4].SetY(rect1[0].GetY());
11107  xx[0] = xaxis->GetXmax();
11108  view->WCtoNDC(xx,u);
11109  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11110  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11111  xx[2] = zaxis->GetXmin();
11112  view->WCtoNDC(xx,u);
11113  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11114  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11115  xx[0] = xaxis->GetXmin();
11116  view->WCtoNDC(xx,u);
11117  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11118  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11119  gVirtualX->DrawPolyLine(5,rect1);
11120  if (nbins>1) {
11121  xx[0] = xaxis->GetXmin();
11122  xx[2] = zaxis->GetXmax();
11123  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11124  view->WCtoNDC(xx,u);
11125  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11126  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11127  rect2[4].SetX(rect2[0].GetX());
11128  rect2[4].SetY(rect2[0].GetY());
11129  xx[0] = xaxis->GetXmax();
11130  view->WCtoNDC(xx,u);
11131  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11132  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11133  xx[2] = zaxis->GetXmin();
11134  view->WCtoNDC(xx,u);
11135  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11136  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11137  xx[0] = xaxis->GetXmin();
11138  view->WCtoNDC(xx,u);
11139  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11140  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11141  gVirtualX->DrawPolyLine(5,rect2);
11142  }
11143  c->Clear();
11144  c->cd();
11145  TH2 *hp = (TH2*)h3->Project3D("zx");
11146  yaxis->SetRange(first,last);
11147  if (hp) {
11148  hp->SetFillColor(38);
11149  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11150  else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11151  hp->SetXTitle(fH->GetXaxis()->GetTitle());
11152  hp->SetYTitle(fH->GetZaxis()->GetTitle());
11153  hp->SetZTitle("Number of Entries");
11154  hp->Draw(fShowOption.Data());
11155  }
11156  }
11157  break;
11158 
11159  case 8:
11160  // "yz"
11161  {
11162  Int_t first = xaxis->GetFirst();
11163  Int_t last = xaxis->GetLast();
11164  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11165  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11166  xaxis->SetRange(binx,binx2);
11167  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11168  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11169  xx[2] = zaxis->GetXmin();
11170  xx[1] = yaxis->GetXmax();
11171  xx[0] = xaxis->GetBinCenter(binx);
11172  view->WCtoNDC(xx,u);
11173  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11174  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11175  rect1[4].SetX(rect1[0].GetX());
11176  rect1[4].SetY(rect1[0].GetY());
11177  xx[2] = zaxis->GetXmax();
11178  view->WCtoNDC(xx,u);
11179  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11180  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11181  xx[1] = yaxis->GetXmin();
11182  view->WCtoNDC(xx,u);
11183  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11184  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11185  xx[2] = zaxis->GetXmin();
11186  view->WCtoNDC(xx,u);
11187  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11188  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11189  gVirtualX->DrawPolyLine(5,rect1);
11190  if (nbins>1) {
11191  xx[2] = zaxis->GetXmin();
11192  xx[1] = yaxis->GetXmax();
11193  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11194  view->WCtoNDC(xx,u);
11195  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11196  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11197  rect2[4].SetX(rect2[0].GetX());
11198  rect2[4].SetY(rect2[0].GetY());
11199  xx[2] = zaxis->GetXmax();
11200  view->WCtoNDC(xx,u);
11201  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11202  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11203  xx[1] = yaxis->GetXmin();
11204  view->WCtoNDC(xx,u);
11205  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11206  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11207  xx[2] = zaxis->GetXmin();
11208  view->WCtoNDC(xx,u);
11209  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11210  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11211  gVirtualX->DrawPolyLine(5,rect2);
11212  }
11213  c->Clear();
11214  c->cd();
11215  TH2 *hp = (TH2*)h3->Project3D("yz");
11216  xaxis->SetRange(first,last);
11217  if (hp) {
11218  hp->SetFillColor(38);
11219  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11220  else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11221  hp->SetXTitle(fH->GetZaxis()->GetTitle());
11222  hp->SetYTitle(fH->GetYaxis()->GetTitle());
11223  hp->SetZTitle("Number of Entries");
11224  hp->Draw(fShowOption.Data());
11225  }
11226  }
11227  break;
11228 
11229  case 9:
11230  // "zy"
11231  {
11232  Int_t first = xaxis->GetFirst();
11233  Int_t last = xaxis->GetLast();
11234  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11235  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11236  xaxis->SetRange(binx,binx2);
11237  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11238  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11239  xx[2] = zaxis->GetXmin();
11240  xx[1] = yaxis->GetXmax();
11241  xx[0] = xaxis->GetBinCenter(binx);
11242  view->WCtoNDC(xx,u);
11243  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11244  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11245  rect1[4].SetX(rect1[0].GetX());
11246  rect1[4].SetY(rect1[0].GetY());
11247  xx[2] = zaxis->GetXmax();
11248  view->WCtoNDC(xx,u);
11249  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11250  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11251  xx[1] = yaxis->GetXmin();
11252  view->WCtoNDC(xx,u);
11253  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11254  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11255  xx[2] = zaxis->GetXmin();
11256  view->WCtoNDC(xx,u);
11257  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11258  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11259  gVirtualX->DrawPolyLine(5,rect1);
11260  if (nbins>1) {
11261  xx[2] = zaxis->GetXmin();
11262  xx[1] = yaxis->GetXmax();
11263  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11264  view->WCtoNDC(xx,u);
11265  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11266  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11267  rect2[4].SetX(rect2[0].GetX());
11268  rect2[4].SetY(rect2[0].GetY());
11269  xx[2] = zaxis->GetXmax();
11270  view->WCtoNDC(xx,u);
11271  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11272  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11273  xx[1] = yaxis->GetXmin();
11274  view->WCtoNDC(xx,u);
11275  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11276  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11277  xx[2] = zaxis->GetXmin();
11278  view->WCtoNDC(xx,u);
11279  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11280  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11281  gVirtualX->DrawPolyLine(5,rect2);
11282  }
11283  c->Clear();
11284  c->cd();
11285  TH2 *hp = (TH2*)h3->Project3D("zy");
11286  xaxis->SetRange(first,last);
11287  if (hp) {
11288  hp->SetFillColor(38);
11289  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11290  else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11291  hp->SetXTitle(fH->GetYaxis()->GetTitle());
11292  hp->SetYTitle(fH->GetZaxis()->GetTitle());
11293  hp->SetZTitle("Number of Entries");
11294  hp->Draw(fShowOption.Data());
11295  }
11296  }
11297  break;
11298  }
11299  c->Update();
11300  padsav->cd();
11301 }
Double_t * fYbuf
Definition: THistPainter.h:59
void PaintGrapHist(Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
Draw the (x,y) as a histogram.
Definition: TGraph.cxx:1977
virtual void SetZTitle(const char *title)
Definition: TH1.h:407
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:790
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Double_t GetMaximumStored() const
Definition: TH1.h:283
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
const Int_t kMAXCONTOUR
static TString gStringKurtosisX
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:44
int ncy
Definition: THbookFile.cxx:91
void SurfaceProperty(Double_t qqa, Double_t qqd, Double_t qqs, Int_t nnqs, Int_t &irep)
Set surface property coefficients.
int AxisPos
Axis position.
Definition: Hoption.h:59
Color_t GetStatColor() const
Definition: TStyle.h:244
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
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:7844
virtual void PaintFrame()
Calculate range and clear pad (canvas).
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1021
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:314
void SetX(SCoord_t x)
Definition: TPoint.h:49
virtual void SetAlpha(Float_t a)
Definition: TColor.h:66
An array of TObjects.
Definition: TObjArray.h:37
static TString gStringUnderflow
float xmin
Definition: THbookFile.cxx:93
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:293
To draw a Crown.
Definition: TCrown.h:19
virtual void PaintArrows(Option_t *option)
Control function to draw a table as an arrow plot
virtual void SetName(const char *name="")
Definition: TPave.h:72
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
Int_t FindBin(Double_t x, Double_t y, Double_t z=0)
Returns the bin number of the bin at the given coordinate.
Definition: TH2Poly.cxx:562
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:233
virtual void SetLogy(Int_t value=1)=0
auto * tt
Definition: textangle.C:16
virtual void PaintStat2(Int_t dostat, TF1 *fit)
Draw the statistics box for 2D histograms.
Int_t yfirst
first bin number along Y
Definition: Hparam.h:45
void LegoCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw stack of lego-plots in cartesian coordinates.
static TString gStringMeanX
virtual void PaintContour(Option_t *option)
Control function to draw a 2D histogram as a contour plot.
virtual Int_t GetLogy() const =0
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
Double_t factor
multiplication factor (normalization)
Definition: Hparam.h:39
static Int_t ProjectAitoff2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:390
Double_t * GetX() const
Definition: TPolyLine.h:54
virtual void PaintH3Box(Int_t iopt)
Control function to draw a 3D histogram with boxes.
auto * m
Definition: textangle.C:8
virtual Int_t GetLogz() const =0
short Style_t
Definition: RtypesCore.h:76
virtual TH1 * Project3D(Option_t *option="x") const
Project a 3-d histogram into 1 or 2-d histograms depending on the option parameter, which may contain a combination of the characters x,y,z,e.
Definition: TH3.cxx:2233
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
Bool_t IsHorizontal()
Definition: TCandle.h:116
const Int_t kMaxCuts
Definition: THistPainter.h:38
int Char
"CHAR" Draw 2D plot with a character set.
Definition: Hoption.h:41
Double_t Log(Double_t x)
Definition: TMath.h:759
Double_t ylowedge
low edge of axis
Definition: Hparam.h:32
Color_t GetTitleTextColor() const
Definition: TStyle.h:259
virtual Double_t GetBinError(Int_t bin) const
Returns the value of error associated to bin number bin.
Definition: TH2Poly.cxx:775
Double_t GetX2() const
Definition: TBox.h:53
Int_t GetNumberContours() const
Definition: TStyle.h:228
static TString gStringMean
void PaintGraph(Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
Draw the (x,y) as a graph.
Definition: TGraph.cxx:1968
TLine * line
Histogram option structure.
Definition: Hoption.h:24
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes distance from point (px,py) to the object.
Definition: TObject.cxx:186
float Float_t
Definition: RtypesCore.h:53
static TString gStringSkewnessX
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
static TString gStringSkewnessZ
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
const char Option_t
Definition: RtypesCore.h:62
virtual Double_t * GetRmax()=0
virtual Float_t GetBarOffset() const
Definition: TH1.h:250
void SetIsoSurfaceParameters(Double_t fmin, Double_t fmax, Int_t ncolor, Int_t ic1, Int_t ic2, Int_t ic3)
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
Int_t GetBinNumber() const
Definition: TH2Poly.h:37
return c1
Definition: legend1.C:41
float ymin
Definition: THbookFile.cxx:93
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1787
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:56
Create a Box.
Definition: TBox.h:24
#define g(i)
Definition: RSha256.hxx:105
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:27
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition: Hoption.h:47
THistPainter()
Default constructor.
image html pict1_TGaxis_012 png width
Define new text attributes for the label number "labNum".
Definition: TGaxis.cxx:2551
Double_t GetHistTopMargin() const
Definition: TStyle.h:225
virtual Double_t GetMinimumStored() const
Definition: TH1.h:287
virtual Double_t GetNormFactor() const
Definition: TH1.h:295
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:1929
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:58
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:2357
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7785
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
virtual void Update()=0
#define mark(osub)
Definition: triangle.c:1206
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
#define BIT(n)
Definition: Rtypes.h:78
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...
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:285
Definition: Rtypes.h:58
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:67
virtual void Paint(Option_t *option="")
Paint this crown with its current attributes.
Definition: TCrown.cxx:181
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7269
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4770
fill
Definition: fit1_py.py:6
static TString gStringIntegralBinWidth
virtual void SetHistogram(TH1 *h)
Set current histogram to h
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
TVectorT.
Definition: TMatrixTBase.h:77
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7293
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
See TView3D.
Definition: TView.h:25
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
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 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 SurfaceFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Service function for Surfaces.
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition: Hoption.h:51
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:2317
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:6961
virtual Int_t GetNbinsZ() const
Definition: TH1.h:293
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:391
#define gROOT
Definition: TROOT.h:410
static constexpr double bar
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:6930
Float_t GetEndErrorSize() const
Definition: TStyle.h:173
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:244
virtual void PaintTH2PolyBins(Option_t *option)
Control function to draw a TH2Poly bins&#39; contours.
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2690
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1829
void ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int_t &irep)
Set correspondance between function and color levels.
Basic string class.
Definition: TString.h:131
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:705
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:567
virtual Int_t PaintInit()
Compute histogram parameters used by the drawing routines.
virtual void Paint2DErrors(Option_t *option)
Draw 2D histograms errors.
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:906
#define f(i)
Definition: RSha256.hxx:104
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1202
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1100
int Int_t
Definition: RtypesCore.h:41
virtual void SetYTitle(const char *title)
Definition: TH1.h:406
bool Bool_t
Definition: RtypesCore.h:59
Double_t GetY2() const
Definition: TBox.h:55
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:313
static void HLStoRGB(Float_t h, Float_t l, Float_t s, Float_t &r, Float_t &g, Float_t &b)
Definition: TColor.h:72
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside one of the graphs 0 otherwise.
const Int_t kCARTESIAN
Definition: TView3D.cxx:32
static TString gStringStdDevZ
int Text
"TEXT" Draw 2D plot with the content of each cell.
Definition: Hoption.h:49
The histogram statistics painter class.
Definition: TPaveStats.h:18
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1817
user specified contour levels
Definition: TH1.h:161
void SetHistogram(TH1D *proj)
Definition: TCandle.h:127
An abstract interface to image processing library.
Definition: TImage.h:29
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
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:638
virtual void SetMinimum(Double_t minimum=-1111)
Set the minimum value along Y for this function In case the function is already drawn, set also the minimum in the helper histogram.
Definition: TF1.cxx:3313
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8445
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Double_t zmin
minimum value along Z
Definition: Hparam.h:37
Float_t GetTitleY() const
Definition: TStyle.h:268
TAxis * fYaxis
Definition: THistPainter.h:52
Double_t ymin
minimum value along y
Definition: Hparam.h:33
Profile Histogram.
Definition: TProfile.h:32
virtual void SetX2(Double_t x2)
Definition: TBox.h:64
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.
Double_t zmax
maximum value along Z
Definition: Hparam.h:38
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
static constexpr double rad
void InitMoveScreen(Double_t xmin, Double_t xmax)
Initialize "MOVING SCREEN" method.
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:50
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:66
don&#39;t draw the histogram title
Definition: TH1.h:165
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
const char * GetFitFormat() const
Definition: TStyle.h:187
void SetY(SCoord_t y)
Definition: TPoint.h:50
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:99
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
Double_t ymax
maximum value along y
Definition: Hparam.h:34
static Int_t ProjectMercator2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
static TString gStringMeanZ
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetImage(const Double_t *, UInt_t, UInt_t, TImagePalette *=0)
Definition: TImage.h:116
virtual void PaintColorLevelsFast(Option_t *option)
Rendering scheme for the COL2 and COLZ2 options
double cos(double)
don&#39;t draw stats box
Definition: TH1.h:160
void Reset()
Definition: TCollection.h:252
Double_t Prob(Double_t chi2, Int_t ndf)
void SetOption(CandleOption opt)
Definition: TCandle.h:121
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:734
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
static constexpr double mg
double beta(double x, double y)
Calculates the beta function.
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:256
virtual void PaintHist(Option_t *option)
Control routine to draw 1D histograms
virtual void PaintTriangles(Option_t *option)
Control function to draw a table using Delaunay triangles.
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1225
if object in a list can be deleted
Definition: TObject.h:58
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH3.cxx:1245
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
static void SetF3(TF3 *f3)
Static function Store pointer to current implicit function.
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:928
void DefineGridLevels(Int_t ndivz)
Define the grid levels drawn in the background of surface and lego plots.
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
Int_t GetTitleAlign()
Definition: TStyle.h:257
virtual void PaintPalette()
Paint the color palette on the right side of the pad.
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Int_t GetDimension() const
Definition: TH1.h:277
void LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in polar coordinates.
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7713
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3352
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:1776
virtual Double_t GetPsi()=0
CandleOption
Definition: TCandle.h:28
Sequenceable collection abstract base class.
Double_t GetXmin() const
Definition: TAxis.h:133
static const double x2[5]
Double_t GetYsize()
Return size of the formula along Y in pad coordinates.
Definition: TLatex.cxx:2597
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:802
virtual void PaintBoxes(Option_t *option)
Control function to draw a 2D histogram as a box plot
Graphical cut class.
Definition: TCutG.h:20
Double_t x[n]
Definition: legend1.C:17
int Surf
"SURF" Draw as a Surface (SURF,Surf=1, SURF1,Surf=11, SURF2,Surf=12)
Definition: Hoption.h:48
virtual void Paint(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:1959
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:814
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)
TH1 * GetHistogram()
Definition: TPaletteAxis.h:51
Float_t GetTitleFontSize() const
Definition: TStyle.h:261
virtual void ProcessMessage(const char *mess, const TObject *obj)
Process message mess.
virtual void PaintCandlePlot(Option_t *option)
Control function to draw a 2D histogram as a candle (box) plot or violin plot
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2286
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) ...
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
TCutG * fCuts[kMaxCuts]
Definition: THistPainter.h:62
const char * GetBinTitle(Int_t bin) const
Returns the bin title.
Definition: TH2Poly.cxx:801
void Class()
Definition: Class.C:29
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:410
const Double_t * GetBuffer() const
Definition: TH1.h:233
int Line
"L" A simple polyline beetwen every point is drawn.
Definition: Hoption.h:34
void LightSource(Int_t nl, Double_t yl, Double_t xscr, Double_t yscr, Double_t zscr, Int_t &irep)
Set light source.
void SetCandleWidth(const Double_t width)
Definition: TCandle.h:125
void SetHistoWidth(const Double_t width)
Definition: TCandle.h:126
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:311
void SetMesh(Int_t mesh=1)
virtual void PaintSurface(Option_t *option)
Control function to draw a 2D histogram as a surface plot.
virtual void PaintStat(Int_t dostat, TF1 *fit)
Draw the statistics box for 1D and profile histograms.
To draw Mathematical Formula.
Definition: TLatex.h:18
THashList * GetLabels() const
Definition: TAxis.h:117
Int_t GetOptFit() const
Definition: TStyle.h:231
virtual Int_t GetLogx() const =0
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:36
Double_t Log10(Double_t x)
Definition: TMath.h:763
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2682
Bool_t IsCandleScaled()
Definition: TCandle.cxx:185
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition: TMath.h:82
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
polygon * polys
Definition: X3DBuffer.c:22
virtual Int_t MakeCuts(char *cutsopt)
Decode string choptin and fill Graphical cuts structure.
void DrawFaceMode2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 2nd option (fill in correspondance with function levels)
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Int_t MakeChopt(Option_t *option)
Decode string choptin and fill Hoption structure.
virtual void PaintH3(Option_t *option="")
Control function to draw a 3D histograms.
int FrontBox
= 0 to suppress the front box
Definition: Hoption.h:55
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 Double_t * GetTnorm()=0
virtual TSeqCollection * GetOutline()=0
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2717
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:208
Base class for several text objects.
Definition: TText.h:23
virtual void PaintColorLevels(Option_t *option)
Control function to draw a 2D histogram as a color plot.
Double_t GetXMax()
Returns the maximum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1368
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:41
Float_t GetStatX() const
Definition: TStyle.h:251
TAxis * fZaxis
Definition: THistPainter.h:53
virtual Bool_t IsInside(Int_t x, Int_t y)
Return kTRUE if the cell ix, iy is inside one of the graphical cuts.
Float_t GetTitleX() const
Definition: TStyle.h:267
virtual void Show()
Double_t GetYMin()
Returns the minimum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1476
void ImplicitFunction(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...
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)
Double_t GetYMax()
Returns the maximum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1440
XFontStruct * id
Definition: TGX11.cxx:108
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
Float_t GetBarWidth() const
Definition: TStyle.h:171
Int_t xfirst
first bin number along X
Definition: Hparam.h:43
TH1F * h1
Definition: legend1.C:5
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:913
constexpr Double_t Pi()
Definition: TMath.h:38
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2038
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
virtual Double_t GetMaximumStored() const
Definition: TF1.h:457
Style_t GetStatStyle() const
Definition: TStyle.h:249
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) ...
virtual void PaintTH2PolyScatterPlot(Option_t *option)
Control function to draw a TH2Poly as a scatter plot.
const Int_t kSPHERICAL
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
int Fill
"F" A fill area is drawn ("CF" draw a smooth fill area).
Definition: Hoption.h:31
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
virtual void PaintTH2PolyText(Option_t *option)
Control function to draw a TH2Poly as a text plot.
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 SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:108
TList * fFunctions
Definition: THistPainter.h:54
short Color_t
Definition: RtypesCore.h:79
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7035
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
static TString gStringKurtosisZ
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
int Bar
"B" A Bar chart is drawn at each point.
Definition: Hoption.h:28
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition: TCanvas.cxx:2235
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
virtual Double_t GetBinContent(Int_t bin) const
Returns the content of the input bin For the overflow/underflow/sea bins: -1 | -2 | -3 ---+----+---- ...
Definition: TH2Poly.cxx:762
Definition: TPoint.h:31
A doubly linked list.
Definition: TList.h:44
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8025
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition: TColor.h:77
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7022
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:513
TObject * GetPolygon() const
Definition: TH2Poly.h:38
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:267
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:416
Float_t GetErrorX() const
Definition: TStyle.h:174
virtual void SetLogx(Int_t value=1)=0
const char * GetPaintTextFormat() const
Definition: TStyle.h:237
void SetDrawFace(DrawFaceFunc_t pointer)
Store pointer to current algorithm to draw faces.
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
static TString gStringEntries
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
virtual void SetOutlineToCube()=0
virtual Int_t PaintInitH()
Compute histogram parameters used by the drawing routines for a rotated pad.
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:1897
Int_t fN
Definition: TArray.h:38
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
virtual void RecalculateRange()
Recompute the histogram range following graphics operations.
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:903
float ymax
Definition: THbookFile.cxx:93
static TString gStringStdDevY
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:956
const Int_t kPOLAR
Definition: TView3D.cxx:33
void SetColorMain(Color_t color, Int_t n=0)
Store color for stack number n.
int Spec
TSpectrum graphics.
Definition: Hoption.h:60
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 FrontBox(Double_t ang)
Draw front surfaces of surrounding box & axes.
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
virtual void PaintText(Option_t *option)
Control function to draw a 1D/2D histograms with the bin values.
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:124
virtual Int_t TableInit()
Initialize various options to draw 2D histograms.
ROOT::R::TRInterface & r
Definition: Object.C:4
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition: TPie.cxx:168
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2510
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7105
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
Float_t GetTitleH() const
Definition: TStyle.h:270
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2974
Int_t fShowProjection
Definition: THistPainter.h:64
SVector< double, 2 > v
Definition: Dict.h:5
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:31
Style_t GetStatFont() const
Definition: TStyle.h:247
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
auto * a
Definition: textangle.C:12
A 3-Dim function with parameters.
Definition: TF3.h:28
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
Float_t GetStatY() const
Definition: TStyle.h:252
Double_t GetContent() const
Definition: TH2Poly.h:35
void LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots spheric coordinates.
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
TClass * Class()
Float_t GetStatW() const
Definition: TStyle.h:253
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:250
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...
The candle plot painter class.
Definition: TCandle.h:25
void LegoFunction(Int_t ia, Int_t ib, Int_t &nv, Double_t *ab, Double_t *vv, Double_t *t)
Service function for Legos.
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
Double_t * GetY() const
Definition: TPolyLine.h:55
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
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:8514
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:224
void SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in cylindrical coordinates.
virtual void PaintStat3(Int_t dostat, TF1 *fit)
Draw the statistics box for 3D histograms.
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:42
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
static TImagePalette * CreateCOLPalette(Int_t nContours)
Factory method to creates an image palette for histogram plotting.
Definition: TAttImage.cxx:748
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:405
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
TString fShowOption
Definition: THistPainter.h:65
virtual void Clear(Option_t *option="")=0
short Short_t
Definition: RtypesCore.h:35
int Arrow
"ARR" Draw 2D plot with Arrows.
Definition: Hoption.h:39
virtual ~THistPainter()
Default destructor.
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:1758
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
The axis painter class.
Definition: TGaxis.h:24
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7742
TAxis * GetYaxis()
Definition: TH1.h:316
Double_t xlowedge
low edge of axis
Definition: Hparam.h:28
float xmax
Definition: THbookFile.cxx:93
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute the actions corresponding to event.
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:285
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
void SetLog(int x, int y, int z)
Definition: TCandle.h:122
void SetName(const char *name)
Definition: TCollection.h:204
A 2-Dim function with parameters.
Definition: TF2.h:29
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
virtual Double_t GetXmin() const
Definition: TF1.h:536
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:610
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:4672
Definition: graph.py:1
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:979
virtual void PaintFunction(Option_t *option)
Paint functions associated to an histogram.
int Error
"E" Draw Errors with current marker type and size.
Definition: Hoption.h:30
void DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw level lines without hidden line removal.
Int_t ylast
last bin number along Y
Definition: Hparam.h:46
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)=0
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
virtual void PaintBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Option_t *option="")
Draw this box with new coordinates.
Definition: TBox.cxx:627
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual Double_t * GetRmin()=0
Linear Algebra Package.
#define gVirtualX
Definition: TVirtualX.h:350
constexpr Double_t E()
Base of natural log: .
Definition: TMath.h:97
virtual TObjLink * FirstLink() const
Definition: TList.h:108
int Curve
"C" A smooth Curve is drawn.
Definition: Hoption.h:29
#define h(i)
Definition: RSha256.hxx:106
virtual void PaintAxis(Bool_t drawGridOnly=kFALSE)
Draw axis (2D case) of an histogram.
virtual void PaintBarH(Option_t *option)
Draw a bar char in a rotated pad (X vertical, Y horizontal)
virtual void FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)=0
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition: TCandle.cxx:674
Double_t Cos(Double_t)
Definition: TMath.h:640
Color_t GetTitleFillColor() const
Definition: TStyle.h:258
void SetLegoFunction(LegoFunc_t pointer)
Store pointer to current lego function.
short Width_t
Definition: RtypesCore.h:78
Hoption_t Hoption
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:7929
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
const Bool_t kFALSE
Definition: RtypesCore.h:88
The histogram painter class.
Definition: THistPainter.h:47
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:61
virtual void SetMaximum(Double_t maximum=-1111)
Set the maximum value along Y for this function In case the function is already drawn, set also the maximum in the helper histogram.
Definition: TF1.cxx:3300
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition: TPie.cxx:393
virtual void SetY2(Double_t y2)
Definition: TBox.h:66
int Hist
"HIST" Draw only the histogram.
Definition: Hoption.h:45
long Long_t
Definition: RtypesCore.h:50
Width_t GetTitleBorderSize() const
Definition: TStyle.h:262
Float_t GetTitleW() const
Definition: TStyle.h:269
virtual Int_t GetSumw2N() const
Definition: TH1.h:309
Double_t GetChisquare() const
Definition: TF1.h:428
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
#define d(i)
Definition: RSha256.hxx:102
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:1336
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:150
long Candle
"CANDLE" Draw a 2D histogram as candle/box plot or violin plot (also with "VIOLIN").
Definition: Hoption.h:52
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:107
virtual void PaintLegoAxis(TGaxis *axis, Double_t ang)
Draw the axis for legos and surface plots.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8456
virtual Double_t Rndm()
TausWorth generator from L&#39;Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
const Int_t kCYLINDRICAL
static const double x1[5]
Double_t xbinsize
bin size in case of equidistant bins
Definition: Hparam.h:27
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
#define ClassImp(name)
Definition: Rtypes.h:359
static TString gStringSkewness
Double_t GetX1() const
Definition: TBox.h:52
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:61
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8372
double Double_t
Definition: RtypesCore.h:55
Int_t GetOptStat() const
Definition: TStyle.h:232
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:56
The Legos and Surfaces painter class.
TText * text
virtual void ShowProjectionX(Int_t px, Int_t py)
Show projection onto X.
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
Double_t * fXbuf
Definition: THistPainter.h:58
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
unsigned long ULong_t
Definition: RtypesCore.h:51
int Func
"FUNC" Draw only the function (for example in case of fit).
Definition: Hoption.h:44
Int_t GetOptStat() const
Return the stat option.
Definition: TPaveStats.cxx:265
Double_t y[n]
Definition: legend1.C:17
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its associated colors.
Definition: TColor.cxx:1696
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
static void SetF3ClippingBoxOn(Double_t xclip, Double_t yclip, Double_t zclip)
Static function Set the implicit function clipping box "on" and define the clipping box...
virtual Double_t GetXmax() const
Definition: TF1.h:540
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Double_t ey[n]
Definition: legend1.C:17
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
The TH1 histogram class.
Definition: TH1.h:56
Int_t xlast
last bin number along X
Definition: Hparam.h:44
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4185
void SetEdgeAtt(Color_t color=1, Style_t style=1, Width_t width=1, Int_t n=0)
Draw a Pie Chart,.
Definition: TPie.h:23
Abstract base class used by ROOT graphics editor.
The color creation and management class.
Definition: TColor.h:19
THist< 2, double, THistStatContent, THistStatUncertainty > TH2D
Definition: THist.hxx:290
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:722
virtual void PaintTitle()
Draw the histogram title.
TList * GetContourList(Double_t contour)
Returns the X and Y graphs building a contour.
Width_t GetStatBorderSize() const
Definition: TStyle.h:246
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:2887
int List
= 1 to generate the TObjArray "contours"
Definition: Hoption.h:57
void Spectrum(Int_t nl, Double_t fmin, Double_t fmax, Int_t ic, Int_t idc, Int_t &irep)
Set Spectrum.
A class to define a conversion from pixel values to pixel color.
Definition: TAttImage.h:33
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Definition: TProfile2D.h:27
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:557
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual void SetShowProjection(const char *option, Int_t nbins)
Set projection.
virtual void PaintLego(Option_t *option)
Control function to draw a 2D histogram as a lego plot.
virtual void ShowProjectionY(Int_t px, Int_t py)
Show projection onto Y.
int Off
"][" With H option, the first and last vertical lines are not drawn.
Definition: Hoption.h:32
TAxis * GetZaxis()
Definition: TH1.h:317
TList * fStack
Definition: THistPainter.h:63
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:180
TH1 * gCurrentHist
void BackBox(Double_t ang)
Draw back surfaces of surrounding box.
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition: TMath.h:74
virtual void DrawPanel()
Display a panel with all histogram drawing options.
static Int_t ProjectSinusoidal2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
Float_t GetStatFontSize() const
Definition: TStyle.h:248
static Int_t ProjectParabolic2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
Handle_t Window_t
Definition: GuiTypes.h:28
virtual Int_t GetNpar() const
Definition: TF1.h:465
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.
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1827
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
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")
virtual void SetXTitle(const char *title)
Definition: TH1.h:405
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:69
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:55
static TString gStringIntegral
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
Double_t xmin
minimum value along X
Definition: Hparam.h:29
static TString gStringStdDevX
static TString gStringKurtosisY
const UInt_t kCannotRotate
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:496
virtual void ShowProjection3(Int_t px, Int_t py)
Show projection (specified by fShowProjection) of a TH3.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
Float_t GetStatH() const
Definition: TStyle.h:254
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
1-Dim function class
Definition: TF1.h:211
static void SetF3ClippingBoxOff()
Static function Set the implicit function clipping box "off".
static void PaintSpecialObjects(const TObject *obj, Option_t *option)
Static function to paint special objects like vectors and matrices.
virtual void PaintErrors(Option_t *option)
Draw 1D histograms error bars.
Double_t xmax
maximum value along X
Definition: Hparam.h:30
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) ...
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Double_t Sin(Double_t)
Definition: TMath.h:636
static TString gStringKurtosis
Double_t GetArea()
Returns the area of the bin.
Definition: TH2Poly.cxx:1338
TF1 * f1
Definition: legend1.C:11
const Int_t kRAPIDITY
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
RooCmdArg Bins(Int_t nbin)
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:119
int System
type of coordinate system(1=car,2=pol,3=cyl,4=sph,5=psr)
Definition: Hoption.h:53
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
#define snprintf
Definition: civetweb.c:1351
THist< 1, double, THistStatContent, THistStatUncertainty > TH1D
Definition: THist.hxx:284
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:84
#define gPad
Definition: TVirtualPad.h:285
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
Bool_t IsViolinScaled()
Definition: TCandle.cxx:190
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
#define c(i)
Definition: RSha256.hxx:101
auto * th2
Definition: textalign.C:17
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8403
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1346
virtual void PaintScatterPlot(Option_t *option)
Control function to draw a 2D histogram as a scatter plot.
Double_t GetY1() const
Definition: TBox.h:54
void Add(TObject *obj)
Definition: TObjArray.h:73
void SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in polar coordinates.
virtual void Paint(Option_t *option="")
Paint the pave stat.
Definition: TPaveStats.cxx:319
Float_t GetBarOffset() const
Definition: TStyle.h:170
Style_t GetTitleStyle() const
Definition: TStyle.h:260
The TGraphDelaunay painting class.
Double_t allchan
integrated sum of contents
Definition: Hparam.h:40
void ResetBit(UInt_t f)
Definition: TObject.h:171
void SurfaceCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw surface in cartesian coordinate system.
virtual TList * GetContourList(Double_t contour) const
Get a contour (as a list of TGraphs) using the Delaunay triangulation.
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6192
void SetSurfaceFunction(SurfaceFunc_t pointer)
Store pointer to current surface function.
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
Definition: first.py:1
virtual Int_t GetNbinsX() const
Definition: TH1.h:291
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:54
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside the polygon defined by the graph vertices 0 otherwise...
Definition: TGraph.cxx:1823
virtual void Paint(Option_t *option="")
Paint the palette.
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
Double_t Sqrt(Double_t x)
Definition: TMath.h:690
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
int Same
"S" Histogram is plotted in the current PAD.
Definition: Hoption.h:36
static TImage * Create()
Create an image.
Definition: TImage.cxx:36
Color_t GetStatTextColor() const
Definition: TStyle.h:245
static TString gStringStdDev
Int_t GetNbins() const
Definition: TAxis.h:121
static TString gStringSkewnessY
int ncx
Definition: THbookFile.cxx:91
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Histogram parameters structure.
Definition: Hparam.h:26
void SetTitleOffset(Float_t titleoffset=1)
Definition: TGaxis.h:125
TClass * Class()
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
Double_t GetXMin()
Returns the minimum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1404
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TList * GetListOfFunctions() const
Definition: TH1.h:238
The palette painting class.
Definition: TPaletteAxis.h:29
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:291
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:57
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
static TString gStringMeanY
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:712
virtual void PadRange(Int_t rback)=0
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:6984
Double_t GetXmax() const
Definition: TAxis.h:134
Double_t ex[n]
Definition: legend1.C:17
Hparam_t Hparam
const Int_t n
Definition: legend1.C:16
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:7874
clip to the frame boundary
Definition: TGraph.h:70
Double_t Tan(Double_t)
Definition: TMath.h:644
constexpr Double_t PiOver2()
Definition: TMath.h:52
virtual Float_t GetBarWidth() const
Definition: TH1.h:251
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition: TMath.h:1221
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:42
void FillPolygonBorder(Int_t nn, Double_t *xy)
Fill a polygon including border ("RASTER SCREEN")
virtual void PaintH3BoxRaster()
Control function to draw a 3D histogram with boxes.
const TArrayD * GetXbins() const
Definition: TAxis.h:130
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:68
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:70
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
TAxis * fXaxis
Definition: THistPainter.h:51
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
const char * GetStatFormat() const
Definition: TStyle.h:250
static TString gStringOverflow
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
virtual Int_t GetNbinsY() const
Definition: TH1.h:292
void SetParent(TObject *obj)
Definition: TPaveStats.h:52
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8356
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:302
Int_t GetOptTitle() const
Definition: TStyle.h:233
const Int_t kNMAX
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:291
const char * Data() const
Definition: TString.h:364
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:123
Double_t ATan(Double_t)
Definition: TMath.h:674