Logo ROOT   6.10/09
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 | "FB" | With LEGO or SURFACE, suppress the Front-Box.|
305 | "BB" | With LEGO or SURFACE, suppress the Back-Box.|
306 | "A" | With LEGO or SURFACE, suppress the axis.|
307 | "SCAT" | Draw a scatter-plot (default).|
308 | "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
309 
310 
311 #### <a name="HP01d"></a> Options supported for 3D histograms
312 
313 | Option | Description |
314 |----------|-------------------------------------------------------------------|
315 | " " | Default (scatter plot).|
316 | "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)`.|
317 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
318 | "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
319 | "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
320 | "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
321 | "LEGO" | Same as `BOX`.|
322 
323 
324 #### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
325 
326 | Option | Description |
327 |------------|-----------------------------------------------------------------|
328 | " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
329 | "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
330 | "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
331 | "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.|
332 | "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
333 | "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
334 | "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
335 
336 
337 
338 ### <a name="HP02"></a> Setting the Style
339 
340 
341 Histograms use the current style (`gStyle`). When one changes the current
342 style and would like to propagate the changes to the histogram,
343 `TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
344 each histogram is needed.
345 
346 To force all the histogram to use the current style use:
347 
348  gROOT->ForceStyle();
349 
350 All the histograms read after this call will use the current style.
351 
352 
353 ### <a name="HP03"></a> Setting line, fill, marker, and text attributes
354 
355 
356 The histogram classes inherit from the attribute classes:
357 `TAttLine`, `TAttFill` and `TAttMarker`.
358 See the description of these classes for the list of options.
359 
360 
361 ### <a name="HP04"></a> Setting Tick marks on the histogram axis
362 
363 
364 The `TPad::SetTicks` method specifies the type of tick marks on the axis.
365 If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
366 
367  tx = 1; tick marks on top side are drawn (inside)
368  tx = 2; tick marks and labels on top side are drawn
369  ty = 1; tick marks on right side are drawn (inside)
370  ty = 2; tick marks and labels on right side are drawn
371 
372 By default only the left Y axis and X bottom axis are drawn
373 (`tx = ty = 0`)
374 
375 `TPad::SetTicks(tx,ty)` allows to set these options.
376 See also The `TAxis` functions to set specific axis attributes.
377 
378 In case multiple color filled histograms are drawn on the same pad, the fill
379 area may hide the axis tick marks. One can force a redraw of the axis over all
380 the histograms by calling:
381 
382  gPad->RedrawAxis();
383 
384 
385 ### <a name="HP05"></a> Giving titles to the X, Y and Z axis
386 
387 
388  h->GetXaxis()->SetTitle("X axis title");
389  h->GetYaxis()->SetTitle("Y axis title");
390 
391 The histogram title and the axis titles can be any `TLatex` string.
392 The titles are part of the persistent histogram.
393 
394 
395 ### <a name="HP060"></a> The option "SAME"
396 
397 
398 By default, when an histogram is drawn, the current pad is cleared before
399 drawing. In order to keep the previous drawing and draw on top of it the
400 option `SAME` should be use. The histogram drawn with the option
401 `SAME` uses the coordinates system available in the current pad.
402 
403 This option can be used alone or combined with any valid drawing option but
404 some combinations must be use with care.
405 
406 #### <a name="HP060a"></a> Limitations
407 
408 - It does not work when combined with the `LEGO` and `SURF` options unless the
409  histogram plotted with the option `SAME` has exactly the same
410  ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
411  lego plots [histograms' stacks](#HP26) should be used.</li>
412 
413 
414 ### <a name="HP061"></a> Colors automatically picked in palette
415 
416 \since **ROOT version 6.09/01**
417 
418 When several histograms are painted in the same canvas thanks to the option "SAME"
419 or via a `THStack` it might be useful to have an easy and automatic way to choose
420 their color. The simplest way is to pick colors in the current active color
421 palette. Palette coloring for histogram is activated thanks to the options `PFC`
422 (Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
423 When one of these options is given to `TH1::Draw` the histogram get its color
424 from the current color palette defined by `gStyle->SetPalette(…)`. The color
425 is determined according to the number of objects having palette coloring in
426 the current pad.
427 
428 Begin_Macro(source)
429 ../../../tutorials/hist/histpalettecolor.C
430 End_Macro
431 
432 Begin_Macro(source)
433 ../../../tutorials/hist/thstackpalettecolor.C
434 End_Macro
435 
436 Begin_Macro(source)
437 ../../../tutorials/hist/thstack2palettecolor.C
438 End_Macro
439 
440 ### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
441 
442 
443 The following example creates two histograms, the second histogram is the bins
444 integral of the first one. It shows a procedure to draw the two histograms in
445 the same pad and it draws the scale of the second histogram using a new vertical
446 axis on the right side. See also the tutorial `transpad.C` for a variant
447 of this example.
448 
449 Begin_Macro(source)
450 {
451  TCanvas *c1 = new TCanvas("c1","c1",600,400);
452  // create/fill draw h1
453  gStyle->SetOptStat(kFALSE);
454  TH1F *h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
455  Int_t i;
456  for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
457  h1->Draw();
458  c1->Update();
459 
460  // create hint1 filled with the bins integral of h1
461  TH1F *hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
462  Float_t sum = 0;
463  for (i=1;i<=100;i++) {
464  sum += h1->GetBinContent(i);
465  hint1->SetBinContent(i,sum);
466  }
467 
468  // scale hint1 to the pad coordinates
469  Float_t rightmax = 1.1*hint1->GetMaximum();
470  Float_t scale = gPad->GetUymax()/rightmax;
471  hint1->SetLineColor(kRed);
472  hint1->Scale(scale);
473  hint1->Draw("same");
474 
475  // draw an axis on the right side
476  TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
477  gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
478  axis->SetLineColor(kRed);
479  axis->SetTextColor(kRed);
480  axis->Draw();
481  return c1;
482 }
483 End_Macro
484 
485 
486 ### <a name="HP07"></a> Statistics Display
487 
488 
489 The type of information shown in the histogram statistics box can be selected
490 with:
491 
492  gStyle->SetOptStat(mode);
493 
494 The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
495 
496  mode = ksiourmen (default = 000001111)
497  k = 1; kurtosis printed
498  k = 2; kurtosis and kurtosis error printed
499  s = 1; skewness printed
500  s = 2; skewness and skewness error printed
501  i = 1; integral of bins printed
502  i = 2; integral of bins with option "width" printed
503  o = 1; number of overflows printed
504  u = 1; number of underflows printed
505  r = 1; standard deviation printed
506  r = 2; standard deviation and standard deviation error printed
507  m = 1; mean value printed
508  m = 2; mean and mean error values printed
509  e = 1; number of entries printed
510  n = 1; name of histogram is printed
511 
512 For example:
513 
514  gStyle->SetOptStat(11);
515 
516 displays only the name of histogram and the number of entries, whereas:
517 
518  gStyle->SetOptStat(1101);
519 
520 displays the name of histogram, mean value and standard deviation.
521 
522 <b>WARNING 1:</b> never do:
523 
524  gStyle->SetOptStat(0001111);
525 
526 but instead do:
527 
528  gStyle->SetOptStat(1111);
529 
530 because `0001111` will be taken as an octal number!
531 
532 <b>WARNING 2:</b> for backward compatibility with older versions
533 
534  gStyle->SetOptStat(1);
535 
536 is taken as:
537 
538  gStyle->SetOptStat(1111)
539 
540 To print only the name of the histogram do:
541 
542  gStyle->SetOptStat(1000000001);
543 
544 <b>NOTE</b> that in case of 2D histograms, when selecting only underflow
545 (10000) or overflow (100000), the statistics box will show all combinations
546 of underflow/overflows and not just one single number.
547 
548 The parameter mode can be any combination of the letters `kKsSiIourRmMen`
549 
550  k : kurtosis printed
551  K : kurtosis and kurtosis error printed
552  s : skewness printed
553  S : skewness and skewness error printed
554  i : integral of bins printed
555  I : integral of bins with option "width" printed
556  o : number of overflows printed
557  u : number of underflows printed
558  r : standard deviation printed
559  R : standard deviation and standard deviation error printed
560  m : mean value printed
561  M : mean value mean error values printed
562  e : number of entries printed
563  n : name of histogram is printed
564 
565 For example, to print only name of histogram and number of entries do:
566 
567  gStyle->SetOptStat("ne");
568 
569 To print only the name of the histogram do:
570 
571  gStyle->SetOptStat("n");
572 
573 The default value is:
574 
575  gStyle->SetOptStat("nemr");
576 
577 When a histogram is painted, a `TPaveStats` object is created and added
578 to the list of functions of the histogram. If a `TPaveStats` object
579 already exists in the histogram list of functions, the existing object is just
580 updated with the current histogram parameters.
581 
582 Once a histogram is painted, the statistics box can be accessed using
583 `h->FindObject("stats")`. In the command line it is enough to do:
584 
585  Root > h->Draw()
586  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
587 
588 because after `h->Draw()` the histogram is automatically painted. But
589 in a script file the painting should be forced using `gPad->Update()`
590 in order to make sure the statistics box is created:
591 
592  h->Draw();
593  gPad->Update();
594  TPaveStats *st = (TPaveStats*)h->FindObject("stats");
595 
596 Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
597 
598 When a histogram is drawn with the option `SAME`, the statistics box
599 is not drawn. To force the statistics box drawing with the option
600 `SAME`, the option `SAMES` must be used.
601 If the new statistics box hides the previous statistics box, one can change
602 its position with these lines (`h` being the pointer to the histogram):
603 
604  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
605  Root > st->SetX1NDC(newx1); //new x start position
606  Root > st->SetX2NDC(newx2); //new x end position
607 
608 To change the type of information for an histogram with an existing
609 `TPaveStats` one should do:
610 
611  st->SetOptStat(mode);
612 
613 Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
614 (see above).
615 
616 One can delete the statistics box for a histogram `TH1* h` with:
617 
618  h->SetStats(0)
619 
620 and activate it again with:
621 
622  h->SetStats(1).
623 
624 Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
625 `$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
626 
627 
628 ### <a name="HP08"></a> Fit Statistics
629 
630 
631 The type of information about fit parameters printed in the histogram statistics
632 box can be selected via the parameter mode. The parameter mode can be
633 `= pcev` (default `= 0111`)
634 
635  p = 1; print Probability
636  c = 1; print Chisquare/Number of degrees of freedom
637  e = 1; print errors (if e=1, v must be 1)
638  v = 1; print name/values of parameters
639 
640 Example:
641 
642  gStyle->SetOptFit(1011);
643 
644 print fit probability, parameter names/values and errors.
645 
646 1. When `v" = 1` is specified, only the non-fixed parameters are shown.
647 2. When `v" = 2` all parameters are shown.
648 
649 Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
650 to `gStyle->SetOptFit(111)`
651 
652 
653 ### <a name="HP09"></a> The error bars options
654 
655 
656 | Option | Description |
657 |----------|-------------------------------------------------------------------|
658 | "E" | Default. Shows only the error bars, not a marker.|
659 | "E1" | Small lines are drawn at the end of the error bars.|
660 | "E2" | Error rectangles are drawn.|
661 | "E3" | A filled area is drawn through the end points of the vertical error bars.|
662 | "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
663 | "E0" | Draw also bins with null contents.|
664 
665 Begin_Macro(source)
666 {
667  TCanvas *c1 = new TCanvas("c1","c1",600,400);
668  TH1F *he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
669  Int_t i;
670  for (i=0;i<10000;i++) he->Fill(gRandom->Gaus(0,1));
671  gStyle->SetEndErrorSize(3);
672  gStyle->SetErrorX(1.);
673  he->SetMarkerStyle(20);
674  he->Draw("E1");
675  return c1;
676 }
677 End_Macro
678 
679 The options "E3" and "E4" draw an error band through the end points of the
680 vertical error bars. With "E4" the error band is smoothed. Because of the
681 smoothing algorithm used some artefacts may appear at the end of the band
682 like in the following example. In such cases "E3" should be used instead
683 of "E4".
684 
685 Begin_Macro(source)
686 {
687  TCanvas *ce4 = new TCanvas("ce4","ce4",600,400);
688  ce4->Divide(2,1);
689  TH1F *he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
690  Int_t i;
691  for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
692  he4->SetFillColor(kRed);
693  he4->GetXaxis()->SetRange(40,48);
694  ce4->cd(1);
695  he4->Draw("E4");
696  ce4->cd(2);
697  TH1F *he3 = (TH1F*)he4->DrawClone("E3");
698  he3->SetTitle("Distribution drawn option E3");
699  return ce4;
700 }
701 End_Macro
702 
703 2D histograms can be drawn with error bars as shown is the following example:
704 
705 Begin_Macro(source)
706 {
707  TCanvas *c2e = new TCanvas("c2e","c2e",600,400);
708  TH2F *h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
709  Float_t px, py;
710  for (Int_t i = 0; i < 25000; i++) {
711  gRandom->Rannor(px,py);
712  h2e->Fill(px,5*py);
713  }
714  h2e->Draw("E");
715  return c2e;
716 }
717 End_Macro
718 
719 
720 ### <a name="HP100"></a> The bar chart option
721 
722 
723 The option "B" allows to draw simple vertical bar charts.
724 The bar width is controlled with `TH1::SetBarWidth()`,
725 and the bar offset within the bin, with `TH1::SetBarOffset()`.
726 These two settings are useful to draw several histograms on the
727 same plot as shown in the following example:
728 
729 Begin_Macro(source)
730 {
731  int i;
732  const Int_t nx = 8;
733  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
734  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
735  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
736 
737  TCanvas *cb = new TCanvas("cb","cb",600,400);
738  cb->SetGrid();
739 
740  gStyle->SetHistMinimumZero();
741 
742  TH1F *h1b = new TH1F("h1b","Option B example",nx,0,nx);
743  h1b->SetFillColor(4);
744  h1b->SetBarWidth(0.4);
745  h1b->SetBarOffset(0.1);
746  h1b->SetStats(0);
747  h1b->SetMinimum(-5);
748  h1b->SetMaximum(5);
749 
750  for (i=1; i<=nx; i++) {
751  h1b->SetBinContent(i, d_35_0[i-1]);
752  h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
753  }
754 
755  h1b->Draw("b");
756 
757  TH1F *h2b = new TH1F("h2b","h2b",nx,0,nx);
758  h2b->SetFillColor(38);
759  h2b->SetBarWidth(0.4);
760  h2b->SetBarOffset(0.5);
761  h2b->SetStats(0);
762  for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
763 
764  h2b->Draw("b same");
765 
766  return cb;
767 }
768 End_Macro
769 
770 
771 ### <a name="HP10"></a> The "BAR" and "HBAR" options
772 
773 
774 When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
775 bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
776 An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
777 `hbar2`, `hbar3`, `hbar4` (hbars.C).
778 
779 - The bar is filled with the histogram fill color.
780 - The left side of the bar is drawn with a light fill color.
781 - The right side of the bar is drawn with a dark fill color.
782 - The percentage of the bar drawn with either the light or dark color is:
783  - 0% for option "(h)bar" or "(h)bar0"
784  - 10% for option "(h)bar1"
785  - 20% for option "(h)bar2"
786  - 30% for option "(h)bar3"
787  - 40% for option "(h)bar4"
788 
789 When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
790 
791 Begin_Macro(source)
792 ../../../tutorials/hist/hbars.C
793 End_Macro
794 
795 To control the bar width (default is the bin width) `TH1::SetBarWidth()`
796 should be used.
797 
798 To control the bar offset (default is 0) `TH1::SetBarOffset()` should
799 be used.
800 
801 These two parameters are useful when several histograms are plotted using
802 the option `SAME`. They allow to plot the histograms next to each other.
803 
804 
805 ### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
806 
807 
808 For each cell (i,j) a number of points proportional to the cell content is
809 drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
810 `kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
811 If option is of the form `scat=ff`, (eg `scat=1.8`,
812 `scat=1e-3`), then `ff` is used as a scale factor to compute the
813 number of dots. `scat=1` is the default.
814 
815 By default the scatter plot is painted with a "dot marker" which not scalable
816 (see the `TAttMarker` documentation). To change the marker size, a scalable marker
817 type should be used. For instance a circle (marker style 20).
818 
819 Begin_Macro(source)
820 {
821  TCanvas *c1 = new TCanvas("c1","c1",600,400);
822  TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
823  Float_t px, py;
824  for (Int_t i = 0; i < 25000; i++) {
825  gRandom->Rannor(px,py);
826  hscat->Fill(px,5*py);
827  hscat->Fill(3+0.5*px,2*py-10.);
828  }
829  hscat->Draw("scat=0.5");
830  return c1;
831 }
832 End_Macro
833 
834 
835 ### <a name="HP12"></a> The ARRow option
836 
837 
838 Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
839 The orientation of the arrow follows the cell gradient.
840 
841 Begin_Macro(source)
842 {
843  TCanvas *c1 = new TCanvas("c1","c1",600,400);
844  TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
845  Float_t px, py;
846  for (Int_t i = 0; i < 25000; i++) {
847  gRandom->Rannor(px,py);
848  harr->Fill(px,5*py);
849  harr->Fill(3+0.5*px,2*py-10.,0.1);
850  }
851  harr->Draw("ARR");
852  return c1;
853 }
854 End_Macro
855 
856 
857 ### <a name="HP13"></a> The BOX option
858 
859 
860 For each cell (i,j) a box is drawn. The size (surface) of the box is
861 proportional to the absolute value of the cell content.
862 The cells with a negative content are drawn with a `X` on top of the box.
863 
864 Begin_Macro(source)
865 {
866  TCanvas *c1 = new TCanvas("c1","c1",600,400);
867  hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
868  hbox->SetFillColor(42);
869  hbox->Fill(0.5, 0.5, 1.);
870  hbox->Fill(0.5, 1.5, 4.);
871  hbox->Fill(0.5, 2.5, 3.);
872  hbox->Fill(1.5, 0.5, 2.);
873  hbox->Fill(1.5, 1.5, 12.);
874  hbox->Fill(1.5, 2.5, -6.);
875  hbox->Fill(2.5, 0.5, -4.);
876  hbox->Fill(2.5, 1.5, 6.);
877  hbox->Fill(2.5, 2.5, 0.5);
878  hbox->Draw("BOX");
879  return c1;
880 }
881 End_Macro
882 
883 With option `BOX1` a button is drawn for each cell with surface
884 proportional to content's absolute value. A sunken button is drawn for
885 negative values a raised one for positive.
886 
887 Begin_Macro(source)
888 {
889  TCanvas *c1 = new TCanvas("c1","c1",600,400);
890  hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
891  hbox1->SetFillColor(42);
892  hbox1->Fill(0.5, 0.5, 1.);
893  hbox1->Fill(0.5, 1.5, 4.);
894  hbox1->Fill(0.5, 2.5, 3.);
895  hbox1->Fill(1.5, 0.5, 2.);
896  hbox1->Fill(1.5, 1.5, 12.);
897  hbox1->Fill(1.5, 2.5, -6.);
898  hbox1->Fill(2.5, 0.5, -4.);
899  hbox1->Fill(2.5, 1.5, 6.);
900  hbox1->Fill(2.5, 2.5, 0.5);
901  hbox1->Draw("BOX1");
902  return c1;
903 }
904 End_Macro
905 
906 When the option `SAME` (or "SAMES") is used with the option `BOX`,
907 the boxes' sizes are computing taking the previous plots into account. The range
908 along the Z axis is imposed by the first plot (the one without option
909 `SAME`); therefore the order in which the plots are done is relevant.
910 
911 Begin_Macro(source)
912 {
913  TCanvas *c1 = new TCanvas("c1","c1",600,400);
914  TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
915  TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
916  TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
917  TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
918  for (Int_t i=0;i<1000;i++) {
919  double x,y;
920  gRandom->Rannor(x,y);
921  if (x>0 && y>0) hb1->Fill(x,y,4);
922  if (x<0 && y<0) hb2->Fill(x,y,3);
923  if (x>0 && y<0) hb3->Fill(x,y,2);
924  if (x<0 && y>0) hb4->Fill(x,y,1);
925  }
926  hb1->SetFillColor(1);
927  hb2->SetFillColor(2);
928  hb3->SetFillColor(3);
929  hb4->SetFillColor(4);
930  hb1->Draw("box");
931  hb2->Draw("box same");
932  hb3->Draw("box same");
933  hb4->Draw("box same");
934  return c1;
935 }
936 End_Macro
937 
938 
939 ### <a name="HP14"></a> The COLor option
940 
941 
942 For each cell (i,j) a box is drawn with a color proportional to the cell
943 content.
944 
945 The color table used is defined in the current style.
946 
947 If the histogram's minimum and maximum are the same (flat histogram), the
948 mapping on colors is not possible, therefore nothing is painted. To paint a
949 flat histogram it is enough to set the histogram minimum
950 (`TH1::SetMinimum()`) different from the bins' content.
951 
952 The default number of color levels used to paint the cells is 20.
953 It can be changed with `TH1::SetContour()` or
954 `TStyle::SetNumberContours()`. The higher this number is, the smoother
955 is the color change between cells.
956 
957 The color palette in TStyle can be modified via `gStyle->SetPalette()`.
958 
959 All the non-empty bins are painted. Empty bins are not painted unless
960 some bins have a negative content because in that case the null bins
961 might be not empty.
962 
963 `TProfile2D` histograms are handled differently because, for this type of 2D
964 histograms, it is possible to know if an empty bin has been filled or not. So even
965 if all the bins' contents are positive some empty bins might be painted. And vice versa,
966 if some bins have a negative content some empty bins might be not painted.
967 
968 Combined with the option `COL`, the option `Z` allows to
969 display the color palette defined by `gStyle->SetPalette()`.
970 
971 In the following example, the histogram has only positive bins; the empty
972 bins (containing 0) are not drawn.
973 
974 Begin_Macro(source)
975 {
976  TCanvas *c1 = new TCanvas("c1","c1",600,400);
977  TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
978  Float_t px, py;
979  for (Int_t i = 0; i < 25000; i++) {
980  gRandom->Rannor(px,py);
981  hcol1->Fill(px,5*py);
982  }
983  gStyle->SetPalette(kBird);
984  hcol1->Draw("COLZ");
985  return c1;
986 }
987 End_Macro
988 
989 In the first plot of following example, the histogram has some negative bins;
990 the empty bins (containing 0) are drawn. In some cases one wants to not draw
991 empty bins (containing 0) of histograms having a negative minimum. The option
992 `1`, used to produce the second plot in the following picture, allows to do that.
993 
994 Begin_Macro(source)
995 {
996  TCanvas *c1 = new TCanvas("c1","c1",600,600);
997  c1->Divide(1,2);
998  TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
999  TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
1000  Float_t px, py;
1001  for (Int_t i = 0; i < 25000; i++) {
1002  gRandom->Rannor(px,py);
1003  hcol23->Fill(px,5*py);
1004  hcol24->Fill(px,5*py);
1005  }
1006  hcol23->Fill(0.,0.,-200.);
1007  hcol24->Fill(0.,0.,-200.);
1008  gStyle->SetPalette(kBird);
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  gStyle->SetPalette(kBird);
1040  c1->cd(1); hcol21->Draw("COLZ");
1041  c1->cd(2); hcol22->Draw("COLZ0");
1042  hcol22->SetMaximum(100);
1043  hcol22->SetMinimum(40);
1044  return c1;
1045 }
1046 End_Macro
1047 
1048 \since **ROOT version 6.09/01:**
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  gStyle->SetPalette(kBird);
1089  hcol1->Draw("COLZPOL");
1090  return c1;
1091 }
1092 End_Macro
1093 
1094 \since **ROOT version 6.07/03:**
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 
1117 ### <a name="HP140"></a> The CANDLE and VIOLIN options
1118 
1119 The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1120 implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1121 the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1122 vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1123 (1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1124 
1125 Instead of using the predefined representations, the candle and violin parameters can be
1126 changed individually. In that case the option have the following form:
1127 
1128  CANDLEX(<option-string>)
1129  CANDLEY(<option-string>)
1130  VIOLINX(<option-string>)
1131  VIOLINY(<option-string>).
1132 
1133 All zeros at the beginning of `option-string` can be omitted.
1134 
1135 `option-string` consists eight values, defined as follow:
1136 
1137  "CANDLEX(zhpawMmb)"
1138 
1139 Where:
1140 
1141  - `b = 0`; no box drawn
1142  - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1143  makes sense in the very most cases to always draw the box
1144  - `b = 2`; draw a filled box with border
1145 
1146  - `m = 0`; no median drawn
1147  - `m = 1`; median is drawn as a line
1148  - `m = 2`; median is drawn with errors (notches)
1149  - `m = 3`; median is drawn as a circle
1150 
1151  - `M = 0`; no mean drawn
1152  - `M = 1`; mean is drawn as a dashed line
1153  - `M = 3`; mean is drawn as a circle
1154 
1155  - `w = 0`; no whisker drawn
1156  - `w = 1`; whisker is drawn to end of distribution.
1157  - `w = 2`; whisker is drawn to max 1.5*iqr
1158 
1159  - `a = 0`; no anchor drawn
1160  - `a = 1`; the anchors are drawn
1161 
1162  - `p = 0`; no points drawn
1163  - `p = 1`; only outliers are drawn
1164  - `p = 2`; all datapoints are drawn
1165  - `p = 3`: all datapoints are drawn scattered
1166 
1167  - `h = 0`; no histogram is drawn
1168  - `h = 1`; histogram at the left or bottom side is drawn
1169  - `h = 2`; histogram at the right or top side is drawn
1170  - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1171 
1172  - `z = 0`; no zero indicator line is drawn
1173  - `z = 1`; zero indicator line is drawn.
1174 
1175 As one can see all individual options for both candle and violin plots can be accessed by this
1176 mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1177 meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1178 vice versa, if you wish.
1179 
1180 
1181 #### <a name="HP140a"></a> The CANDLE option
1182 
1183 <a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1184 a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1185 way to describe graphically a data distribution (D) with only five numbers:
1186 
1187  1. The minimum value of the distribution D (bottom or left whisker).
1188  2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1189  3. The median (M): 50% of the data points in D are less than M.
1190  4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1191  5. The maximum value of the distribution D (top or right whisker).
1192 
1193 In this implementation a TH2 is considered as a collection of TH1 along
1194 X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1195 Each TH1 is represented as one candle.
1196 
1197 Begin_Macro(source)
1198 ../../../tutorials/hist/candleplotwhiskers.C
1199 End_Macro
1200 
1201 The candle reduces the information coming from a whole distribution into few values.
1202 Independently from the number of entries or the significance of the underlying distribution
1203 a candle will always look like a candle. So candle plots should be used carefully in
1204 particular with unknown distributions. The definition of a candle is based on
1205 __unbinned data__. Here, candles are created from binned data. Because of this, the
1206 deviation is connected to the bin width used. The calculation of the quantiles
1207 normally done on unbinned data also. Because data are binned, this will
1208 only work the best possible way within the resolution of one bin
1209 
1210 Because of all these facts one should take care that:
1211 
1212  - there are enough points per candle
1213  - the bin width is small enough (more bins will increase the maximum
1214  available resolution of the quantiles although there will be some
1215  bins with no entries)
1216  - never make a candle-plot if the underlying distribution is double-distributed
1217  - only create candles of distributions that are more-or-less gaussian (the
1218  MPV should be not too far away from the mean).
1219 
1220 #### What a candle is made of
1221 
1222 \since **ROOT version 6.07/05**
1223 
1224 ##### The box
1225 The box displays the position of the inter-quantile-range of the underlying
1226 distribution. The box contains 25% of the distribution below the median
1227 and 25% of the distribution above the median. If the underlying distribution is large
1228 enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1229 (Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1230 the position of the box can be modified by SetBarWidth() and SetBarOffset().
1231 The +-25% quantiles are calculated by the GetQuantiles() methods.
1232 
1233 ##### The Median
1234 For a sorted list of numbers, the median is the value in the middle of the list.
1235 E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1236 because it is in the middle of the list. If the number of entries is even the
1237 average of the two values in the middle will be used. As histograms are binned
1238 data, the situation is a bit more complex. The following example shows this:
1239 
1240 ~~~ {.cpp}
1241 void quantiles() {
1242  TH1I *h = new TH1I("h","h",10,0,10);
1243  //h->Fill(3);
1244  //h->Fill(3);
1245  h->Fill(4);
1246  h->Draw();
1247  Double_t *p = new Double_t[1];
1248  p[0] = 0.5;
1249  Double_t *q = new Double_t[1];
1250  q[0] = 0;
1251  h->GetQuantiles(1,q,p);
1252 
1253  cout << "Median is: " << q[0] << std::endl;
1254 }
1255 ~~~
1256 
1257 Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1258 the example will return a calculated median of 4.5, because that's the bin center
1259 of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1260 commented out, it will return 3.75, because the algorithm tries to evenly distribute
1261 the individual values of a bin with bin content > 0. It means the sorted list
1262 would be "3.25, 3.75, 4.5".
1263 
1264 The consequence is a median of 3.75. This shows how important it is to use a
1265 small enough bin-width when using candle-plots on binned data.
1266 If the distribution is large enough and gaussian shaped the median will be exactly
1267 equal to the mean.
1268 The median can be shown as a line or as a circle or not shown at all.
1269 
1270 In order to show the significance of the median notched candle plots apply a "notch" or
1271 narrowing of the box around the median. The significance is defined by
1272 \f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1273 (where iqr is the size of the box and N is the number of entries of the whole
1274 distribution). Candle plots like these are usually called "notched candle plots".
1275 
1276 In case the significance of the median is greater that the size of the box, the
1277 box will have an unnatural shape. Usually it means the chart has not enough data,
1278 or that representing this uncertainty is not useful
1279 
1280 ##### The Mean
1281 The mean can be drawn as a dashed line or as a circle or not drawn at all.
1282 The mean is the arithmetic average of the values in the distribution.
1283 It is calculated using GetMean(). Because histograms are
1284 binned data, the mean value can differ from a calculation on the raw-data.
1285 If the distribution is large enough and gaussian shaped the mean will be
1286 exactly the median.
1287 
1288 ##### The Whiskers
1289 The whiskers represent the part of the distribution not covered by the box.
1290 The upper 25% and the lower 25% of the distribution are located within the whiskers.
1291 Two representations are available.
1292 
1293  - A simple one (using w=1) defining the lower whisker from the lowest data value
1294  to the bottom of the box, and the upper whisker from the top of the box to the
1295  highest data value. In this representation the whisker-lines are dashed.
1296  - A more complex one having a further restriction. The whiskers are still connected
1297  to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1298  be that the outermost part of the underlying distribution will not be covered
1299  by the whiskers. Usually these missing parts will be represented by the outliers
1300  (see points). Of course the upper and the lower whisker may differ in length.
1301  In this representation the whiskers are drawn as solid lines.
1302 
1303 If the distribution is large enough and gaussian shaped, the maximum length of
1304 the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
1305 1.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1306 (see picture above). In that case 99.3% of the total distribution will be covered
1307 by the box and the whiskers, whereas 0.7% are represented by the outliers.
1308 
1309 ##### The Anchors
1310 The anchors have no special meaning in terms of statistical calculation. They mark
1311 the end of the whiskers and they have the width of the box. Both representation
1312 with and without anchors are common.
1313 
1314 ##### The Points
1315 Depending on the configuration the points can have different meanings:
1316  - If p=1 the points represent the outliers. If they are shown, it means
1317  some parts of the underlying distribution are not covered by the whiskers.
1318  This can only occur when the whiskers are set to option w=2. Here the whiskers
1319  can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1320  whiskers will be drawn as outliers. The outliers will be represented by crosses.
1321  - If p=2 all points in the distribution will be painted as crosses. This is
1322  useful for small datasets only (up to 10 or 20 points per candle).
1323  The outliers are shown along the candle. Because the underlying distribution
1324  is binned, is frequently occurs that a bin contains more than one value.
1325  Because of this the points will be randomly scattered within their bin along
1326  the candle axis. If the bin content for a bin is exactly 1 (usually
1327  this happens for the outliers) if will be drawn in the middle of the bin along
1328  the candle axis. As the maximum number of points per candle is limited by kNMax/2
1329  on very large datasets scaling will be performed automatically. In that case one
1330  would loose all outliers because they have usually a bin content of 1 (and a
1331  bin content between 0 and 1 after the scaling). Because of this all bin contents
1332  between 0 and 1 - after the scaling - will be forced to be 1.
1333  - As the drawing of all values on large datasets can lead to big amounts of crosses,
1334  one can show all values as a scatter plot instead by choosing p=3. The points will be
1335  drawn as dots and will be scattered within the width of the candle. The color
1336  of the points will be the color of the candle-chart.
1337 
1338 ##### Other Options
1339 Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1340 with a histogram.
1341 
1342 
1343 #### How to use the candle-plots drawing option
1344 
1345 There are six predefined candle-plot representations:
1346 
1347  - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1348  - "CANDLEX2": Standard candle with better whisker definition + outliers.
1349  It is a good compromise
1350  - "CANDLEX3": Like candle2 but with a mean as a circle.
1351  It is easier to distinguish mean and median
1352  - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1353  (notched candle plots).
1354  For bigger datasets per candle
1355  - "CANDLEX5": Like candle2 but showing all data points.
1356  For very small datasets
1357  - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1358  For huge datasets
1359 
1360 
1361 The following picture shows how the six predefined representations look.
1362 
1363 Begin_Macro
1364 {
1365  TCanvas *c1 = new TCanvas("c1","c1",700,800);
1366  c1->Divide(2,3);
1367  gStyle->SetOptStat(kFALSE);
1368 
1369  TH2F *hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1370  Float_t px, py;
1371  for (Int_t i = 0; i < 15000; i++) {
1372  gRandom->Rannor(px,py);
1373  hcandle->Fill(px,5*py);
1374  }
1375  hcandle->SetMarkerSize(0.5);
1376 
1377  TH2F *h2;
1378  for (Int_t i=1; i<7; i++) {
1379  c1->cd(i);
1380  h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1381  h2->SetTitle(Form("CANDLE%d",i));
1382  }
1383 }
1384 End_Macro
1385 
1386 
1387 
1388 #### Example 1
1389 Box and improved whisker, no mean, no median, no anchor no outliers
1390 
1391  h1->Draw("CANDLEX(2001)");
1392 
1393 #### Example 2
1394 A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1395 
1396  h1->Draw("CANDLEX(112111)");
1397 
1398 #### Example 3
1399 The following example shows how several candle plots can be super-imposed using
1400 the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1401 Also the color, the line width, the size of the points and so on can be changed by the
1402 standard attribute setting methods such as SetLineColor() SetLineWidth().
1403 
1404 Begin_Macro(source)
1405 ../../../tutorials/hist/candleplot.C
1406 End_Macro
1407 
1408 #### <a name="HP140b"></a> The VIOLIN option
1409 
1410 <a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1411 that also encodes the pdf information at each point.
1412 
1413 
1414 Quartiles and mean are also represented at each point, with a marker
1415 and two lines.
1416 
1417 In this implementation a TH2 is considered as a collection of TH1 along
1418 X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1419 
1420 #### What a violin is made of
1421 
1422 \since **ROOT version 6.09/02**
1423 
1424 ##### The histogram
1425 The histogram is typically drawn to both directions with respect to the middle-line of the
1426 corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1427 one side (h=1, or h=2).
1428 The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1429 histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1430 be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1431 A solid fill style is recommended.
1432 
1433 ##### The zero indicator line
1434 Typical for violin charts is a line in the background over the whole histogram indicating
1435 the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1436 will always be the same as the fill-color of the histogram.
1437 
1438 ##### The Mean
1439 The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1440 
1441 ##### Whiskers
1442 The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1443 difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1444 the whiskers will be forced to be solid (usually hashed)
1445 
1446 ##### Points
1447 The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1448 better whisker definition (w=2) and outliers (p=1).
1449 
1450 ##### Other options
1451 It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1452 including a box-plot.
1453 
1454 #### How to use the violin-plots drawing option
1455 
1456 There are two predefined violin-plot representations:
1457  - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1458  zero indicator line)
1459  - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1460 
1461 A solid fill style is recommended for this plot (as opposed to a hollow or
1462 hashed style).
1463 
1464 Begin_Macro(source)
1465 {
1466  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1467  Int_t nx(6), ny(40);
1468  Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1469  TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1470  TF1 f1("f1", "gaus", +0,0 +4.0);
1471  Double_t x,y;
1472  for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1473  Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1474  f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1475  for(Int_t i=0; i<10000; ++i){
1476  x = xc;
1477  y = f1.GetRandom();
1478  hviolin->Fill(x, y);
1479  }
1480  }
1481  hviolin->SetFillColor(kGray);
1482  hviolin->SetMarkerStyle(20);
1483  hviolin->SetMarkerSize(0.5);
1484  hviolin->Draw("VIOLIN");
1485  c1->Update();
1486  return c1;
1487 }
1488 End_Macro
1489 
1490 The next example illustrates a time development of a certain value:
1491 
1492 Begin_Macro(source)
1493 ../../../tutorials/hist/candledecay.C
1494 End_Macro
1495 
1496 
1497 ### <a name="HP15"></a> The TEXT and TEXTnn Option
1498 
1499 
1500 For each bin the content is printed. The text attributes are:
1501 
1502 - text font = current TStyle font (`gStyle->SetTextFont()`).
1503 - text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1504  with the option `TEXT` the marker size can be changed with
1505  `h->SetMarkerSize(markersize)`).
1506 - text color = marker color.
1507 
1508 By default the format `g` is used. This format can be redefined
1509 by calling `gStyle->SetPaintTextFormat()`.
1510 
1511 It is also possible to use `TEXTnn` in order to draw the text with
1512 the angle `nn` (`0 < nn < 90`).
1513 
1514 For 2D histograms the text is plotted in the center of each non empty cells.
1515 It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`.
1516 For 1D histogram the text is plotted at a y position equal to the bin content.
1517 
1518 For 2D histograms when the option "E" (errors) is combined with the option
1519 text ("TEXTE"), the error for each bin is also printed.
1520 
1521 Begin_Macro(source)
1522 {
1523  TCanvas *c01 = new TCanvas("c01","c01",700,400);
1524  c01->Divide(2,1);
1525  TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1526  TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1527  Float_t px, py;
1528  for (Int_t i = 0; i < 25000; i++) {
1529  gRandom->Rannor(px,py);
1530  htext1->Fill(px,0.1);
1531  htext2->Fill(px,5*py,0.1);
1532  }
1533  gStyle->SetPaintTextFormat("4.1f m");
1534  htext2->SetMarkerSize(1.8);
1535  c01->cd(1);
1536  htext2->Draw("TEXT45");
1537  c01->cd(2);
1538  htext1->Draw();
1539  htext1->Draw("HIST TEXT0 SAME");
1540  return c01;
1541 }
1542 End_Macro
1543 
1544 \since **ROOT version 6.07/07:**
1545 In case several histograms are drawn on top ot each other (using option `SAME`),
1546 the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1547 text position in each cell, in percentage of the bin width.
1548 
1549 Begin_Macro(source)
1550 {
1551  TCanvas *c03 = new TCanvas("c03","c03",700,400);
1552  gStyle->SetOptStat(0);
1553  TH2F *htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1554  TH2F *htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1555  TH2F *htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1556  Float_t px, py;
1557  for (Int_t i = 0; i < 25000; i++) {
1558  gRandom->Rannor(px,py);
1559  htext3->Fill(4*px,20*py,0.1);
1560  htext4->Fill(4*px,20*py,0.5);
1561  htext5->Fill(4*px,20*py,1.0);
1562  }
1563  //gStyle->SetPaintTextFormat("4.1f m");
1564  htext4->SetMarkerSize(1.8);
1565  htext5->SetMarkerSize(1.8);
1566  htext5->SetMarkerColor(kRed);
1567  htext3->Draw("COL");
1568  htext4->SetBarOffset(0.2);
1569  htext4->Draw("TEXT SAME");
1570  htext5->SetBarOffset(-0.2);
1571  htext5->Draw("TEXT SAME");
1572  return c03;
1573 }
1574 End_Macro
1575 
1576 In the case of profile histograms it is possible to print the number
1577 of entries instead of the bin content. It is enough to combine the
1578 option "E" (for entries) with the option "TEXT".
1579 
1580 Begin_Macro(source)
1581 {
1582  TCanvas *c02 = new TCanvas("c02","c02",700,400);
1583  c02->Divide(2,1);
1584  gStyle->SetPaintTextFormat("g");
1585 
1586  TProfile *profile = new TProfile("profile","profile",10,0,10);
1587  profile->SetMarkerSize(2.2);
1588  profile->Fill(0.5,1);
1589  profile->Fill(1.5,2);
1590  profile->Fill(2.5,3);
1591  profile->Fill(3.5,4);
1592  profile->Fill(4.5,5);
1593  profile->Fill(5.5,5);
1594  profile->Fill(6.5,4);
1595  profile->Fill(7.5,3);
1596  profile->Fill(8.5,2);
1597  profile->Fill(9.5,1);
1598  c02->cd(1); profile->Draw("HIST TEXT0");
1599  c02->cd(2); profile->Draw("HIST TEXT0E");
1600 
1601  return c02;
1602 }
1603 End_Macro
1604 
1605 ### <a name="HP16"></a> The CONTour options
1606 
1607 
1608 The following contour options are supported:
1609 
1610 | Option | Description |
1611 |----------|-------------------------------------------------------------------|
1612 | "CONT" | Draw a contour plot (same as CONT0).|
1613 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1614 | "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1615 | "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1616 | "CONT3" | Draw a contour plot solid lines for all contours.|
1617 | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1618 | "CONT5" | Draw a contour plot using Delaunay triangles.|
1619 
1620 
1621 
1622 The following example shows a 2D histogram plotted with the option
1623 `CONTZ`. The option `CONT` draws a contour plot using surface
1624 colors to distinguish contours. Combined with the option `CONT` (or
1625 `CONT0`), the option `Z` allows to display the color palette
1626 defined by `gStyle->SetPalette()`.
1627 
1628 Begin_Macro(source)
1629 {
1630  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1631  TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1632  Float_t px, py;
1633  for (Int_t i = 0; i < 25000; i++) {
1634  gRandom->Rannor(px,py);
1635  hcontz->Fill(px-1,5*py);
1636  hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1637  }
1638  gStyle->SetPalette(kBird);
1639  hcontz->Draw("CONTZ");
1640  return c1;
1641 }
1642 End_Macro
1643 
1644 The following example shows a 2D histogram plotted with the option
1645 `CONT1Z`. The option `CONT1` draws a contour plot using the
1646 line colors to distinguish contours. Combined with the option `CONT1`,
1647 the option `Z` allows to display the color palette defined by
1648 `gStyle->SetPalette()`.
1649 
1650 Begin_Macro(source)
1651 {
1652  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1653  TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1654  Float_t px, py;
1655  for (Int_t i = 0; i < 25000; i++) {
1656  gRandom->Rannor(px,py);
1657  hcont1->Fill(px-1,5*py);
1658  hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1659  }
1660  gStyle->SetPalette(kBird);
1661  hcont1->Draw("CONT1Z");
1662  return c1;
1663 }
1664 End_Macro
1665 
1666 The following example shows a 2D histogram plotted with the option
1667 `CONT2`. The option `CONT2` draws a contour plot using the
1668 line styles to distinguish contours.
1669 
1670 Begin_Macro(source)
1671 {
1672  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1673  TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1674  Float_t px, py;
1675  for (Int_t i = 0; i < 25000; i++) {
1676  gRandom->Rannor(px,py);
1677  hcont2->Fill(px-1,5*py);
1678  hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1679  }
1680  hcont2->Draw("CONT2");
1681  return c1;
1682 }
1683 End_Macro
1684 
1685 The following example shows a 2D histogram plotted with the option
1686 `CONT3`. The option `CONT3` draws contour plot solid lines for
1687 all contours.
1688 
1689 Begin_Macro(source)
1690 {
1691  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1692  TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1693  Float_t px, py;
1694  for (Int_t i = 0; i < 25000; i++) {
1695  gRandom->Rannor(px,py);
1696  hcont3->Fill(px-1,5*py);
1697  hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1698  }
1699  hcont3->Draw("CONT3");
1700  return c1;
1701 }
1702 End_Macro
1703 
1704 The following example shows a 2D histogram plotted with the option
1705 `CONT4`. The option `CONT4` draws a contour plot using surface
1706 colors to distinguish contours (`SURF` option at theta = 0). Combined
1707 with the option `CONT` (or `CONT0`), the option `Z`
1708 allows to display the color palette defined by `gStyle->SetPalette()`.
1709 
1710 Begin_Macro(source)
1711 {
1712  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1713  TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1714  Float_t px, py;
1715  for (Int_t i = 0; i < 25000; i++) {
1716  gRandom->Rannor(px,py);
1717  hcont4->Fill(px-1,5*py);
1718  hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1719  }
1720  gStyle->SetPalette(kBird);
1721  hcont4->Draw("CONT4Z");
1722  return c1;
1723 }
1724 End_Macro
1725 
1726 The default number of contour levels is 20 equidistant levels and can be changed
1727 with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1728 
1729 #### <a name="HP16a"></a> The LIST option
1730 
1731 When option `LIST` is specified together with option
1732 `CONT`, the points used to draw the contours are saved in
1733 `TGraph` objects:
1734 
1735  h->Draw("CONT LIST");
1736  gPad->Update();
1737 
1738 The contour are saved in `TGraph` objects once the pad is painted.
1739 Therefore to use this functionality in a macro, `gPad->Update()`
1740 should be performed after the histogram drawing. Once the list is
1741 built, the contours are accessible in the following way:
1742 
1743  TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1744  Int_t ncontours = contours->GetSize();
1745  TList *list = (TList*)contours->At(i);
1746 
1747 Where `i` is a contour number, and list contains a list of
1748 `TGraph` objects.
1749 For one given contour, more than one disjoint polyline may be generated.
1750 The number of TGraphs per contour is given by:
1751 
1752  list->GetSize();
1753 
1754 To access the first graph in the list one should do:
1755 
1756  TGraph *gr1 = (TGraph*)list->First();
1757 
1758 
1759 The following example (ContourList.C) shows how to use this functionality.
1760 
1761 Begin_Macro(source)
1762 ../../../tutorials/hist/ContourList.C
1763 End_Macro
1764 
1765 The following options select the `CONT4` option and are useful for
1766 sky maps or exposure maps (earth.C).
1767 
1768 | Option | Description |
1769 |--------------|---------------------------------------------------------------|
1770 | "AITOFF" | Draw a contour via an AITOFF projection.|
1771 | "MERCATOR" | Draw a contour via an Mercator projection.|
1772 | "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1773 | "PARABOLIC" | Draw a contour via an Parabolic projection.|
1774 
1775 Begin_Macro(source)
1776 ../../../tutorials/graphics/earth.C
1777 End_Macro
1778 
1779 
1780 ### <a name="HP17"></a> The LEGO options
1781 
1782 
1783 In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1784 is proportional to the cell content. The lego aspect is control with the
1785 following options:
1786 
1787 | Option | Description |
1788 |----------|-------------------------------------------------------------------|
1789 | "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1790 | "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1791 | "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1792 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1793 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1794 | "0" | When used with any LEGO option, the empty bins are not drawn.|
1795 
1796 
1797 See the limitations with [the option "SAME"](#HP060a).
1798 
1799 Line attributes can be used in lego plots to change the edges' style.
1800 
1801 The following example shows a 2D histogram plotted with the option
1802 `LEGO`. The option `LEGO` draws a lego plot using the hidden
1803 lines removal technique.
1804 
1805 Begin_Macro(source)
1806 {
1807  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1808  TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1809  Float_t px, py;
1810  for (Int_t i = 0; i < 25000; i++) {
1811  gRandom->Rannor(px,py);
1812  hlego->Fill(px-1,5*py);
1813  hlego->Fill(2+0.5*px,2*py-10.,0.1);
1814  }
1815  hlego->Draw("LEGO");
1816  return c2;
1817 }
1818 End_Macro
1819 
1820 The following example shows a 2D histogram plotted with the option
1821 `LEGO1`. The option `LEGO1` draws a lego plot using the
1822 hidden surface removal technique. Combined with any `LEGOn` option, the
1823 option `0` allows to not drawn the empty bins.
1824 
1825 Begin_Macro(source)
1826 {
1827  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1828  TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1829  Float_t px, py;
1830  for (Int_t i = 0; i < 25000; i++) {
1831  gRandom->Rannor(px,py);
1832  hlego1->Fill(px-1,5*py);
1833  hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1834  }
1835  hlego1->SetFillColor(kYellow);
1836  hlego1->Draw("LEGO1 0");
1837  return c2;
1838 }
1839 End_Macro
1840 
1841 The following example shows a 2D histogram plotted with the option
1842 `LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1843 draws a lego plot using the hidden surface removal technique but doesn't draw
1844 the border lines of each individual lego-bar. This is very useful for histograms
1845 having many bins. With such histograms the option `LEGO1` gives a black
1846 image because of the border lines. This option also works with stacked legos.
1847 
1848 Begin_Macro(source)
1849 {
1850  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1851  TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1852  Float_t px, py;
1853  for (Int_t i = 0; i < 25000; i++) {
1854  gRandom->Rannor(px,py);
1855  hlego3->Fill(px-1,5*py);
1856  hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1857  }
1858  hlego3->SetFillColor(kRed);
1859  hlego3->Draw("LEGO3");
1860  return c2;
1861 }
1862 End_Macro
1863 
1864 The following example shows a 2D histogram plotted with the option
1865 `LEGO2`. The option `LEGO2` draws a lego plot using colors to
1866 show the cell contents. Combined with the option `LEGO2`, the option
1867 `Z` allows to display the color palette defined by
1868 `gStyle->SetPalette()`.
1869 
1870 Begin_Macro(source)
1871 {
1872  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1873  TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1874  Float_t px, py;
1875  for (Int_t i = 0; i < 25000; i++) {
1876  gRandom->Rannor(px,py);
1877  hlego2->Fill(px-1,5*py);
1878  hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1879  }
1880  gStyle->SetPalette(kBird);
1881  hlego2->Draw("LEGO2Z");
1882  return c2;
1883 }
1884 End_Macro
1885 
1886 
1887 
1888 ### <a name="HP18"></a> The "SURFace" options
1889 
1890 
1891 In a surface plot, cell contents are represented as a mesh.
1892 The height of the mesh is proportional to the cell content.
1893 
1894 | Option | Description |
1895 |----------|-------------------------------------------------------------------|
1896 | "SURF" | Draw a surface plot using the hidden line removal technique.|
1897 | "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1898 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
1899 | "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1900 | "SURF4" | Draw a surface using the Gouraud shading technique.|
1901 | "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1902 | "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.|
1903 | "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1904 
1905 
1906 
1907 See the limitations with [the option "SAME"](#HP060a).
1908 
1909 The following example shows a 2D histogram plotted with the option
1910 `SURF`. The option `SURF` draws a lego plot using the hidden
1911 lines removal technique.
1912 
1913 Begin_Macro(source)
1914 {
1915  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1916  TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1917  Float_t px, py;
1918  for (Int_t i = 0; i < 25000; i++) {
1919  gRandom->Rannor(px,py);
1920  hsurf->Fill(px-1,5*py);
1921  hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1922  }
1923  hsurf->Draw("SURF");
1924  return c2;
1925 }
1926 End_Macro
1927 
1928 The following example shows a 2D histogram plotted with the option
1929 `SURF1`. The option `SURF1` draws a surface plot using the
1930 hidden surface removal technique. Combined with the option `SURF1`,
1931 the option `Z` allows to display the color palette defined by
1932 `gStyle->SetPalette()`.
1933 
1934 Begin_Macro(source)
1935 {
1936  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1937  gStyle->SetPalette(kBird);
1938  TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1939  Float_t px, py;
1940  for (Int_t i = 0; i < 25000; i++) {
1941  gRandom->Rannor(px,py);
1942  hsurf1->Fill(px-1,5*py);
1943  hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1944  }
1945  hsurf1->Draw("SURF1");
1946  return c2;
1947 }
1948 End_Macro
1949 
1950 The following example shows a 2D histogram plotted with the option
1951 `SURF2`. The option `SURF2` draws a surface plot using colors
1952 to show the cell contents. Combined with the option `SURF2`, the option
1953 `Z` allows to display the color palette defined by
1954 `gStyle->SetPalette()`.
1955 
1956 Begin_Macro(source)
1957 {
1958  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1959  gStyle->SetPalette(kBird);
1960  TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
1961  Float_t px, py;
1962  for (Int_t i = 0; i < 25000; i++) {
1963  gRandom->Rannor(px,py);
1964  hsurf2->Fill(px-1,5*py);
1965  hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
1966  }
1967  hsurf2->Draw("SURF2");
1968  return c2;
1969 }
1970 End_Macro
1971 
1972 The following example shows a 2D histogram plotted with the option
1973 `SURF3`. The option `SURF3` draws a surface plot using the
1974 hidden line removal technique with, in addition, a filled contour view drawn on the
1975 top. Combined with the option `SURF3`, the option `Z` allows
1976 to display the color palette defined by `gStyle->SetPalette()`.
1977 
1978 Begin_Macro(source)
1979 {
1980  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1981  gStyle->SetPalette(kBird);
1982  TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
1983  Float_t px, py;
1984  for (Int_t i = 0; i < 25000; i++) {
1985  gRandom->Rannor(px,py);
1986  hsurf3->Fill(px-1,5*py);
1987  hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
1988  }
1989  hsurf3->Draw("SURF3");
1990  return c2;
1991 }
1992 End_Macro
1993 
1994 The following example shows a 2D histogram plotted with the option
1995 `SURF4`. The option `SURF4` draws a surface using the Gouraud
1996 shading technique.
1997 
1998 Begin_Macro(source)
1999 {
2000  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2001  TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2002  Float_t px, py;
2003  for (Int_t i = 0; i < 25000; i++) {
2004  gRandom->Rannor(px,py);
2005  hsurf4->Fill(px-1,5*py);
2006  hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2007  }
2008  hsurf4->SetFillColor(kOrange);
2009  hsurf4->Draw("SURF4");
2010  return c2;
2011 }
2012 End_Macro
2013 
2014 The following example shows a 2D histogram plotted with the option
2015 `SURF5 CYL`. Combined with the option `SURF5`, the option
2016 `Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2017 
2018 Begin_Macro(source)
2019 {
2020  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2021  gStyle->SetPalette(kBird);
2022  TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2023  Float_t px, py;
2024  for (Int_t i = 0; i < 25000; i++) {
2025  gRandom->Rannor(px,py);
2026  hsurf5->Fill(px-1,5*py);
2027  hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2028  }
2029  hsurf5->SetFillColor(kOrange);
2030  hsurf5->Draw("SURF5 CYL");
2031  return c2;
2032 }
2033 End_Macro
2034 
2035 The following example shows a 2D histogram plotted with the option
2036 `SURF7`. The option `SURF7` draws a surface plot using the
2037 hidden surfaces removal technique with, in addition, a line contour view drawn on the
2038 top. Combined with the option `SURF7`, the option `Z` allows
2039 to display the color palette defined by `gStyle->SetPalette()`.
2040 
2041 Begin_Macro(source)
2042 {
2043  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2044  gStyle->SetPalette(kBird);
2045  TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2046  Float_t px, py;
2047  for (Int_t i = 0; i < 25000; i++) {
2048  gRandom->Rannor(px,py);
2049  hsurf7->Fill(px-1,5*py);
2050  hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2051  }
2052  hsurf7->Draw("SURF7");
2053  return c2;
2054 }
2055 End_Macro
2056 
2057 As shown in the following example, when a contour plot is painted on top of a
2058 surface plot using the option `SAME`, the contours appear in 3D on the
2059 surface.
2060 
2061 Begin_Macro(source)
2062 {
2063  TCanvas *c20=new TCanvas("c20","c20",600,400);
2064  int NBins = 50;
2065  double d = 2;
2066  TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2067  for (int bx = 1; bx <= NBins; ++bx) {
2068  for (int by = 1; by <= NBins; ++by) {
2069  double x = hsc->GetXaxis()->GetBinCenter(bx);
2070  double y = hsc->GetYaxis()->GetBinCenter(by);
2071  hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2072  }
2073  }
2074  gStyle->SetPalette(kBird);
2075  hsc->Draw("surf2");
2076  hsc->Draw("CONT1 SAME");
2077  return c20;
2078 }
2079 End_Macro
2080 
2081 
2082 ### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2083 
2084 
2085 Legos and surfaces plots are represented by default in Cartesian coordinates.
2086 Combined with any `LEGOn` or `SURFn` options the following
2087 options allow to draw a lego or a surface in other coordinates systems.
2088 
2089 | Option | Description |
2090 |----------|-------------------------------------------------------------------|
2091 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2092 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2093 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2094 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2095 
2096 
2097 
2098 <b>WARNING:</b> Axis are not drawn with these options.
2099 
2100 The following example shows the same histogram as a lego plot is the four
2101 different coordinates systems.
2102 
2103 Begin_Macro(source)
2104 {
2105  TCanvas *c3 = new TCanvas("c3","c3",600,400);
2106  c3->Divide(2,2);
2107  TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2108  Float_t px, py;
2109  for (Int_t i = 0; i < 25000; i++) {
2110  gRandom->Rannor(px,py);
2111  hlcc->Fill(px-1,5*py);
2112  hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2113  }
2114  hlcc->SetFillColor(kYellow);
2115  c3->cd(1); hlcc->Draw("LEGO1 CYL");
2116  c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2117  hlpc->SetTitle("Polar coordinates");
2118  c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2119  hlsc->SetTitle("Spherical coordinates");
2120  c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2121  hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2122  return c3;
2123 }
2124 End_Macro
2125 
2126 The following example shows the same histogram as a surface plot is the four different coordinates systems.
2127 
2128 Begin_Macro(source)
2129 {
2130  TCanvas *c4 = new TCanvas("c4","c4",600,400);
2131  c4->Divide(2,2);
2132  TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2133  Float_t px, py;
2134  for (Int_t i = 0; i < 25000; i++) {
2135  gRandom->Rannor(px,py);
2136  hscc->Fill(px-1,5*py);
2137  hscc->Fill(2+0.5*px,2*py-10.,0.1);
2138  }
2139  gStyle->SetPalette(kBird);
2140  c4->cd(1); hscc->Draw("SURF1 CYL");
2141  c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2142  hspc->SetTitle("Polar coordinates");
2143  c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2144  hssc->SetTitle("Spherical coordinates");
2145  c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2146  hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2147  return c4;
2148 }
2149 End_Macro
2150 
2151 
2152 ### <a name="HP20"></a> Base line for bar-charts and lego plots
2153 
2154 
2155 By default the base line used to draw the boxes for bar-charts and lego plots is
2156 the histogram minimum. It is possible to force this base line to be 0 with the
2157 command:
2158 
2159  gStyle->SetHistMinimumZero();
2160 
2161 Begin_Macro(source)
2162 {
2163  TCanvas *c5 = new TCanvas("c5","c5",700,400);
2164  c5->Divide(2,1);
2165  gStyle->SetHistMinimumZero(1);
2166  TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2167  TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2168  Int_t i;
2169  Double_t x,y;
2170  hz1->SetFillColor(kBlue);
2171  hz2->SetFillColor(kBlue);
2172  for (i=0;i<10000;i++) {
2173  x = gRandom->Gaus(0,1);
2174  y = gRandom->Gaus(0,1);
2175  if (x>0) {
2176  hz1->Fill(x,1);
2177  hz2->Fill(x,y,1);
2178  } else {
2179  hz1->Fill(x,-1);
2180  hz2->Fill(x,y,-2);
2181  }
2182  }
2183  c5->cd(1); hz1->Draw("bar2");
2184  c5->cd(2); hz2->Draw("lego1");
2185  return c5;
2186 }
2187 End_Macro
2188 
2189 This option also works for horizontal plots. The example given in the section
2190 ["The bar chart option"](#HP100) appears as follow:
2191 
2192 Begin_Macro(source)
2193 {
2194  int i;
2195  const Int_t nx = 8;
2196  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2197  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2198  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2199 
2200  TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
2201  cbh->SetGrid();
2202 
2203  gStyle->SetHistMinimumZero();
2204 
2205  TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2206  h1bh->SetFillColor(4);
2207  h1bh->SetBarWidth(0.4);
2208  h1bh->SetBarOffset(0.1);
2209  h1bh->SetStats(0);
2210  h1bh->SetMinimum(-5);
2211  h1bh->SetMaximum(5);
2212 
2213  for (i=1; i<=nx; i++) {
2214  h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2215  h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2216  }
2217 
2218  h1bh->Draw("hbar");
2219 
2220  TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2221  h2bh->SetFillColor(38);
2222  h2bh->SetBarWidth(0.4);
2223  h2bh->SetBarOffset(0.5);
2224  h2bh->SetStats(0);
2225  for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2226 
2227  h2bh->Draw("hbar same");
2228 
2229  return cbh;
2230 }
2231 End_Macro
2232 
2233 
2234 ### <a name="HP20a"></a> TH2Poly Drawing
2235 
2236 
2237 The following options are supported:
2238 
2239 | Option | Description |
2240 |----------|-------------------------------------------------------------------|
2241 | "SCAT" | Draw a scatter plot (default).|
2242 | "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2243 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2244 | "0" | When used with any COL options, the empty bins are not drawn.|
2245 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2246 | "TEXTN" | Draw bin names as text.|
2247 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2248 | "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2249 | "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2250 | "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2251 
2252 
2253 
2254 `TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2255 shapes. The bins are defined as graphs. The following macro is a very simple
2256 example showing how to book a TH2Poly and draw it.
2257 
2258 Begin_Macro(source)
2259 {
2260  TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2261  TH2Poly *h2p = new TH2Poly();
2262  h2p->SetName("h2poly_name");
2263  h2p->SetTitle("h2poly_title");
2264  Double_t px1[] = {0, 5, 6};
2265  Double_t py1[] = {0, 0, 5};
2266  Double_t px2[] = {0, -1, -1, 0};
2267  Double_t py2[] = {0, 0, -1, 3};
2268  Double_t px3[] = {4, 3, 0, 1, 2.4};
2269  Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
2270  h2p->AddBin(3, px1, py1);
2271  h2p->AddBin(4, px2, py2);
2272  h2p->AddBin(5, px3, py3);
2273  h2p->Fill(0.1, 0.01, 3);
2274  h2p->Fill(-0.5, -0.5, 7);
2275  h2p->Fill(-0.7, -0.5, 1);
2276  h2p->Fill(1, 3, 1.5);
2277  Double_t fx[] = {0.1, -0.5, -0.7, 1};
2278  Double_t fy[] = {0.01, -0.5, -0.5, 3};
2279  Double_t fw[] = {3, 1, 1, 1.5};
2280  h2p->FillN(4, fx, fy, fw);
2281  gStyle->SetPalette(kBird);
2282  h2p->Draw("col");
2283 }
2284 End_Macro
2285 
2286 Rectangular bins are a frequent case. The special version of
2287 the `AddBin` method allows to define them more easily like
2288 shown in the following example (th2polyBoxes.C).
2289 
2290 Begin_Macro(source)
2291 ../../../tutorials/hist/th2polyBoxes.C
2292 End_Macro
2293 
2294 One `TH2Poly` bin can be a list of polygons. Such bins are defined
2295 by calling `AddBin` with a `TMultiGraph`. The following example
2296 shows a such case:
2297 
2298 Begin_Macro(source)
2299 {
2300  TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2301 
2302  Int_t i, bin;
2303  const Int_t nx = 48;
2304  const char *states [nx] = {
2305  "alabama", "arizona", "arkansas", "california",
2306  "colorado", "connecticut", "delaware", "florida",
2307  "georgia", "idaho", "illinois", "indiana",
2308  "iowa", "kansas", "kentucky", "louisiana",
2309  "maine", "maryland", "massachusetts", "michigan",
2310  "minnesota", "mississippi", "missouri", "montana",
2311  "nebraska", "nevada", "new_hampshire", "new_jersey",
2312  "new_mexico", "new_york", "north_carolina", "north_dakota",
2313  "ohio", "oklahoma", "oregon", "pennsylvania",
2314  "rhode_island", "south_carolina", "south_dakota", "tennessee",
2315  "texas", "utah", "vermont", "virginia",
2316  "washington", "west_virginia", "wisconsin", "wyoming"
2317  };
2318  Double_t pop[nx] = {
2319  4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2320  9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2321  1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2322  1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2323  11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2324  24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2325  };
2326 
2327  Double_t lon1 = -130;
2328  Double_t lon2 = -65;
2329  Double_t lat1 = 24;
2330  Double_t lat2 = 50;
2331  TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2332 
2333  TFile::SetCacheFileDir(".");
2334  TFile *f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2335 
2336  TMultiGraph *mg;
2337  TKey *key;
2338  TIter nextkey(gDirectory->GetListOfKeys());
2339  while ((key = (TKey*)nextkey())) {
2340  TObject *obj = key->ReadObj();
2341  if (obj->InheritsFrom("TMultiGraph")) {
2342  mg = (TMultiGraph*)obj;
2343  bin = p->AddBin(mg);
2344  }
2345  }
2346 
2347  for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2348 
2349  gStyle->SetOptStat(11);
2350  gStyle->SetPalette(kBird);
2351  p->Draw("COLZ L");
2352 }
2353 End_Macro
2354 
2355 `TH2Poly` histograms can also be plotted using the GL interface using
2356 the option "GLLEGO".
2357 
2358 \since **ROOT version 6.09/01**
2359 
2360 In some cases it can be useful to not draw the empty bins. the option "0"
2361 combined with the option "COL" et COLZ allows to do that.
2362 
2363 Begin_Macro(source)
2364 {
2365  TCanvas *chc = new TCanvas("chc","chc",600,400);
2366 
2367  TH2Poly *hc = new TH2Poly();
2368  hc->Honeycomb(0,0,.1,25,25);
2369  hc->SetName("hc");
2370  hc->SetTitle("Option COLZ 0");
2371  TRandom ran;
2372  for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2373  hc->Draw("colz 0");
2374 }
2375 End_Macro
2376 
2377 ### <a name="HP21"></a> The SPEC option
2378 
2379 
2380 This option allows to use the `TSpectrum2Painter` tools. See the full
2381 documentation in `TSpectrum2Painter::PaintSpectrum`.
2382 
2383 
2384 ### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2385 
2386 
2387 When this option is specified, a color palette with an axis indicating the value
2388 of the corresponding color is drawn on the right side of the picture. In case,
2389 not enough space is left, one can increase the size of the right margin by
2390 calling `TPad::SetRightMargin()`. The attributes used to display the
2391 palette axis values are taken from the Z axis of the object. For example, to
2392 set the labels size on the palette axis do:
2393 
2394  hist->GetZaxis()->SetLabelSize().
2395 
2396 <b>WARNING:</b> The palette axis is always drawn vertically.
2397 
2398 
2399 ### <a name="HP23"></a> Setting the color palette
2400 
2401 
2402 To change the color palette `TStyle::SetPalette` should be used, eg:
2403 
2404  gStyle->SetPalette(ncolors,colors);
2405 
2406 For example the option `COL` draws a 2D histogram with cells
2407 represented by a box filled with a color index which is a function
2408 of the cell content.
2409 If the cell content is N, the color index used will be the color number
2410 in `colors[N]`, etc. If the maximum cell content is greater than
2411 `ncolors`, all cell contents are scaled to `ncolors`.
2412 
2413 If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2414 defined. This palette is recommended for pads, labels ...
2415 
2416 `if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2417 Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2418 palette.
2419 
2420 Other pre-defined palettes with 255 colors are available when `colors == 0`.
2421 The following value of `ncolors` give access to:
2422 
2423 
2424  if ncolors = 51 and colors=0, a Deep Sea palette is used.
2425  if ncolors = 52 and colors=0, a Grey Scale palette is used.
2426  if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2427  if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2428  if ncolors = 55 and colors=0, a Rain Bow palette is used.
2429  if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2430 
2431 
2432 If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2433 
2434 The default palette defines:
2435 
2436 - index 0 to 9 : shades of grey
2437 - index 10 to 19 : shades of brown
2438 - index 20 to 29 : shades of blue
2439 - index 30 to 39 : shades of red
2440 - index 40 to 49 : basic colors
2441 
2442 The color numbers specified in the palette can be viewed by selecting
2443 the item `colors` in the `VIEW` menu of the canvas tool bar.
2444 The red, green, and blue components of a color can be changed thanks to
2445 `TColor::SetRGB()`.
2446 
2447 
2448 ### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2449 
2450 
2451 Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2452 histogram. One must create a graphical cut (mouse or C++) and specify the name
2453 of the cut between `[]` in the `Draw()` option.
2454 For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2455 
2456  myhist->Draw("surf1 [cutg]");
2457 
2458 To invert the cut, it is enough to put a `-` in front of its name:
2459 
2460  myhist->Draw("surf1 [-cutg]");
2461 
2462 It is possible to apply several cuts (`,` means logical AND):
2463 
2464  myhist->Draw("surf1 [cutg1,cutg2]");
2465 
2466 Begin_Macro(source)
2467 ../../../tutorials/fit/fit2a.C
2468 End_Macro
2469 
2470 ### <a name="HP25"></a> Drawing options for 3D histograms
2471 
2472 
2473 | Option | Description |
2474 |----------|-------------------------------------------------------------------|
2475 | "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)`|
2476 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2477 | "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2478 | "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2479 | "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2480 
2481 Note that instead of `BOX` one can also use `LEGO`.
2482 
2483 By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2484 
2485 The following example shows a 3D histogram plotted as a scatter plot.
2486 
2487 Begin_Macro(source)
2488 {
2489  auto c06 = new TCanvas("c06","c06",600,400);
2490  gStyle->SetOptStat(kFALSE);
2491  auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2492  Double_t x, y, z;
2493  for (Int_t i=0;i<10000;i++) {
2494  gRandom->Rannor(x, y);
2495  z = x*x + y*y;
2496  h3scat->Fill(x,y,z);
2497  }
2498  h3scat->Draw();
2499 }
2500 End_Macro
2501 
2502 The following example shows a 3D histogram plotted with the option `BOX`.
2503 
2504 Begin_Macro(source)
2505 {
2506  auto c16 = new TCanvas("c16","c16",600,400);
2507  gStyle->SetOptStat(kFALSE);
2508  auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2509  Double_t x, y, z;
2510  for (Int_t i=0;i<10000;i++) {
2511  gRandom->Rannor(x, y);
2512  z = x*x + y*y;
2513  h3box->Fill(x,y,z);
2514  }
2515  h3box->Draw("BOX");
2516 }
2517 End_Macro
2518 
2519 The following example shows a 3D histogram plotted with the option `BOX1`.
2520 
2521 Begin_Macro(source)
2522 {
2523  auto c36 = new TCanvas("c36","c36",600,400);
2524  gStyle->SetOptStat(kFALSE);
2525  auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2526  Double_t x, y, z;
2527  for (Int_t i=0;i<10000;i++) {
2528  gRandom->Rannor(x, y);
2529  z = abs(sin(x)/x + cos(y)*y);
2530  h3box->Fill(x,y,z);
2531  }
2532  h3box->SetFillColor(9);
2533  h3box->Draw("BOX1");
2534 }
2535 End_Macro
2536 
2537 The following example shows a 3D histogram plotted with the option `BOX2`.
2538 
2539 Begin_Macro(source)
2540 {
2541  auto c56 = new TCanvas("c56","c56",600,400);
2542  gStyle->SetOptStat(kFALSE);
2543  auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2544  Double_t x, y, z;
2545  for (Int_t i=0;i<10000;i++) {
2546  gRandom->Rannor(x, y);
2547  z = abs(sin(x)/x + cos(y)*y);
2548  h3box->Fill(x,y,z);
2549  }
2550  h3box->Draw("BOX2");
2551 }
2552 End_Macro
2553 
2554 The following example shows a 3D histogram plotted with the option `BOX3`.
2555 
2556 Begin_Macro(source)
2557 {
2558  auto c46 = new TCanvas("c46","c46",600,400);
2559  c46->SetFillColor(38);
2560  gStyle->SetOptStat(kFALSE);
2561  auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2562  Double_t x, y, z;
2563  for (Int_t i=0;i<10000;i++) {
2564  gRandom->Rannor(x, y);
2565  z = x*x + y*y;
2566  h3box->Fill(x,y,z);
2567  }
2568  h3box->Draw("BOX3");
2569 }
2570 End_Macro
2571 
2572 For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2573 to the absolute value of the bin content. The bins with a negative content are
2574 drawn with a X on each face of the box as shown in the following example:
2575 
2576 Begin_Macro(source)
2577 {
2578  auto c = new TCanvas("c","c",600,400);
2579  gStyle->SetOptStat(kFALSE);
2580  auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2581  h3box->Fill(0., 2., 2., 10.);
2582  h3box->Fill(2., 2., 2., 5.);
2583  h3box->Fill(2., 2., .5, 2.);
2584  h3box->Fill(2., 2., 3., -1.);
2585  h3box->Fill(3., 2., 2., -10.);
2586  h3box->SetFillColor(8);
2587  h3box->Draw("box1");
2588 }
2589 End_Macro
2590 
2591 The following example shows a 3D histogram plotted with the option `ISO`.
2592 
2593 Begin_Macro(source)
2594 {
2595  auto c26 = new TCanvas("c26","c26",600,400);
2596  gStyle->SetOptStat(kFALSE);
2597  auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2598  Double_t x, y, z;
2599  for (Int_t i=0;i<10000;i++) {
2600  gRandom->Rannor(x, y);
2601  z = x*x + y*y;
2602  h3iso->Fill(x,y,z);
2603  }
2604  h3iso->SetFillColor(kCyan);
2605  h3iso->Draw("ISO");
2606 }
2607 End_Macro
2608 
2609 
2610 ### <a name="HP26"></a> Drawing option for histograms' stacks
2611 
2612 
2613 Stacks of histograms are managed with the `THStack`. A `THStack`
2614 is a collection of `TH1` (or derived) objects. For painting only the
2615 `THStack` containing `TH1` only or
2616 `THStack` containing `TH2` only will be considered.
2617 
2618 By default, histograms are shown stacked:
2619 
2620 1. The first histogram is paint.
2621 2. The the sum of the first and second, etc...
2622 
2623 If the option `NOSTACK` is specified, the histograms are all paint in
2624 the same pad as if the option `SAME` had been specified. This allows to
2625 compute X and Y scales common to all the histograms, like
2626 `TMultiGraph` does for graphs.
2627 
2628 If the option `PADS` is specified, the current pad/canvas is
2629 subdivided into a number of pads equal to the number of histograms and each
2630 histogram is paint into a separate pad.
2631 
2632 The following example shows various types of stacks (hstack.C).
2633 
2634 Begin_Macro(source)
2635 ../../../tutorials/hist/hstack.C
2636 End_Macro
2637 
2638 The option `nostackb` allows to draw the histograms next to each
2639 other as bar charts:
2640 
2641 Begin_Macro(source)
2642 {
2643  TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2644  THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2645 
2646  TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2647  h1->FillRandom("gaus",20000);
2648  h1->SetFillColor(kRed);
2649  hs->Add(h1);
2650 
2651  TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2652  h2->FillRandom("gaus",15000);
2653  h2->SetFillColor(kBlue);
2654  hs->Add(h2);
2655 
2656  TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2657  h3->FillRandom("gaus",10000);
2658  h3->SetFillColor(kGreen);
2659  hs->Add(h3);
2660 
2661  hs->Draw("nostackb");
2662  hs->GetXaxis()->SetNdivisions(-10);
2663  cst0->SetGridx();
2664  return cst0;
2665 }
2666 End_Macro
2667 
2668 If at least one of the histograms in the stack has errors, the whole stack is
2669 visualized by default with error bars. To visualize it without errors the
2670 option `HIST` should be used.
2671 
2672 Begin_Macro(source)
2673 {
2674  TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2675  cst1->Divide(2,1);
2676 
2677  TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2678  hst11->Sumw2();
2679  hst11->FillRandom("gaus", 1000);
2680  hst11->SetFillColor(kViolet);
2681  hst11->SetLineColor(kViolet);
2682 
2683  TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2684  hst12->FillRandom("gaus", 500);
2685  hst12->SetFillColor(kBlue);
2686  hst12->SetLineColor(kBlue);
2687 
2688  THStack st1("st1", "st1");
2689  st1.Add(hst11);
2690  st1.Add(hst12);
2691 
2692  cst1->cd(1); st1.Draw();
2693  cst1->cd(2); st1.Draw("hist");
2694 
2695  return cst1;
2696 }
2697 End_Macro
2698 
2699 ### <a name="HP27"></a> Drawing of 3D implicit functions
2700 
2701 
2702 3D implicit functions (`TF3`) can be drawn as iso-surfaces.
2703 The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2704 In the following example the options "FB" and "BB" suppress the
2705 "Front Box" and "Back Box" around the plot.
2706 
2707 Begin_Macro(source)
2708 {
2709  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2710  TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2711  f3->SetClippingBoxOn(0,0,0);
2712  f3->SetFillColor(30);
2713  f3->SetLineColor(15);
2714  f3->Draw("FBBB");
2715  return c2;
2716 }
2717 End_Macro
2718 
2719 
2720 ### <a name="HP28"></a> Associated functions drawing
2721 
2722 
2723 An associated function is created by `TH1::Fit`. More than on fitted
2724 function can be associated with one histogram (see `TH1::Fit`).
2725 
2726 A `TF1` object `f1` can be added to the list of associated
2727 functions of an histogram `h` without calling `TH1::Fit`
2728 simply doing:
2729 
2730  h->GetListOfFunctions()->Add(f1);
2731 
2732 or
2733 
2734  h->GetListOfFunctions()->Add(f1,someoption);
2735 
2736 To retrieve a function by name from this list, do:
2737 
2738  TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2739 
2740 or
2741 
2742  TF1 *f1 = h->GetFunction(name);
2743 
2744 Associated functions are automatically painted when an histogram is drawn.
2745 To avoid the painting of the associated functions the option `HIST`
2746 should be added to the list of the options used to paint the histogram.
2747 
2748 
2749 ### <a name="HP29"></a> Drawing using OpenGL
2750 
2751 
2752 The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2753 graphics library. The plotting options start with `GL` keyword.
2754 In addition, in order to inform canvases that OpenGL should be used to render
2755 3D representations, the following option should be set:
2756 
2757  gStyle->SetCanvasPreferGL(true);
2758 
2759 
2760 #### <a name="HP29a"></a> General information: plot types and supported options
2761 
2762 The following types of plots are provided:
2763 
2764 For lego plots the supported options are:
2765 
2766 | Option | Description |
2767 |----------|-------------------------------------------------------------------|
2768 | "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2769 | "GLLEGO2"| Bins with color levels.|
2770 | "GLLEGO3"| Cylindrical bars.|
2771 
2772 
2773 
2774 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2775 In polar only Z axis can be logarithmic, in cylindrical only Y.
2776 
2777 For surface plots (`TF2` and `TH2`) the supported options are:
2778 
2779 | Option | Description |
2780 |-----------|------------------------------------------------------------------|
2781 | "GLSURF" | Draw a surface.|
2782 | "GLSURF1" | Surface with color levels|
2783 | "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2784 | "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2785 | "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2786 
2787 
2788 
2789 The surface painting in cartesian coordinates supports logarithmic scales along
2790 X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2791 in cylindrical coordinates only the Y axis.
2792 
2793 Additional options to SURF and LEGO - Coordinate systems:
2794 
2795 | Option | Description |
2796 |----------|-------------------------------------------------------------------|
2797 | " " | Default, cartesian coordinates system.|
2798 | "POL" | Polar coordinates system.|
2799 | "CYL" | Cylindrical coordinates system.|
2800 | "SPH" | Spherical coordinates system.|
2801 
2802 
2803 
2804 #### <a name="HP290"></a> TH3 as color boxes
2805 
2806 The supported option is:
2807 
2808 | Option | Description |
2809 |----------|-------------------------------------------------------------------|
2810 | "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2811 
2812 
2813 
2814 #### <a name="HP29b"></a> TH3 as boxes (spheres)
2815 
2816 The supported options are:
2817 
2818 | Option | Description |
2819 |----------|-------------------------------------------------------------------|
2820 | "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2821 | "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2822 
2823 
2824 
2825 #### <a name="HP29c"></a> TH3 as iso-surface(s)
2826 
2827 The supported option is:
2828 
2829 | Option | Description |
2830 |----------|-------------------------------------------------------------------|
2831 | "GLISO" | TH3 is drawn using iso-surfaces.|
2832 
2833 
2834 
2835 #### <a name="HP29d"></a> TF3 (implicit function)
2836 
2837 The supported option is:
2838 
2839 | Option | Description |
2840 |----------|-------------------------------------------------------------------|
2841 | "GLTF3" | Draw a TF3.|
2842 
2843 
2844 
2845 #### <a name="HP29e"></a> Parametric surfaces
2846 
2847 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2848 equations and visualize the surface.
2849 
2850 #### <a name="HP29f"></a> Interaction with the plots
2851 
2852 All the interactions are implemented via standard methods
2853 `DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2854 interactions with the OpenGL plots are possible only when the mouse cursor is
2855 in the plot's area (the plot's area is the part of a the pad occupied by
2856 gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2857 pad interaction is performed.
2858 
2859 #### <a name="HP29g"></a> Selectable parts
2860 
2861 Different parts of the plot can be selected:
2862 
2863 - xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2864  if the dynamic slicing by this plane is supported, and it's highlighted in red,
2865  if the dynamic slicing is not supported.
2866 - The plot itself:
2867  On surfaces, the selected surface is outlined in red. (TF3 and
2868  ISO are not outlined). On lego plots, the selected bin is
2869  highlighted. The bin number and content are displayed in pad's
2870  status bar. In box plots, the box or sphere is highlighted and
2871  the bin info is displayed in pad's status bar.
2872 
2873 
2874 #### <a name="HP29h"></a> Rotation and zooming
2875 
2876 
2877 - Rotation:
2878  When the plot is selected, it can be rotated by pressing and
2879  holding the left mouse button and move the cursor.
2880 - Zoom/Unzoom:
2881  Mouse wheel or 'j', 'J', 'k', 'K' keys.
2882 
2883 
2884 #### <a name="HP29i"></a> Panning
2885 
2886 The selected plot can be moved in a pad's area by pressing and
2887 holding the left mouse button and the shift key.
2888 
2889 #### <a name="HP29j"></a> Box cut
2890 
2891 Surface, iso, box, TF3 and parametric painters support box cut by
2892 pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2893 area. That will display a transparent box, cutting away part of the
2894 surface (or boxes) in order to show internal part of plot. This box
2895 can be moved inside the plot's area (the full size of the box is
2896 equal to the plot's surrounding box) by selecting one of the box
2897 cut axes and pressing the left mouse button to move it.
2898 
2899 #### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2900 
2901 Currently, all gl-plots support some form of slicing. When back plane
2902 is selected (and if it's highlighted in green) you can press and hold
2903 left mouse button and shift key and move this back plane inside
2904 plot's area, creating the slice. During this "slicing" plot becomes
2905 semi-transparent. To remove all slices (and projected curves for
2906 surfaces) double click with left mouse button in a plot's area.
2907 
2908 #### <a name="HP29l"></a> Surface with option "GLSURF"
2909 
2910 The surface profile is displayed on the slicing plane.
2911 The profile projection is drawn on the back plane
2912 by pressing `'p'` or `'P'` key.
2913 
2914 #### <a name="HP29m"></a> TF3
2915 
2916 The contour plot is drawn on the slicing plane. For TF3 the color
2917 scheme can be changed by pressing 's' or 'S'.
2918 
2919 #### <a name="HP29n"></a> Box
2920 
2921 The contour plot corresponding to slice plane position is drawn in real time.
2922 
2923 #### <a name="HP29o"></a> Iso
2924 
2925 Slicing is similar to "GLBOX" option.
2926 
2927 #### <a name="HP29p"></a> Parametric plot
2928 
2929 No slicing. Additional keys: 's' or 'S' to change color scheme -
2930 about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2931 increase number of polygons ('l' for "level" of details), 'w' or 'W'
2932 to show outlines ('w' for "wireframe").
2933 
2934 */
2935 
2936 TH1 *gCurrentHist = 0;
2937 
2940 
2941 const Int_t kNMAX = 2000;
2942 
2943 const Int_t kMAXCONTOUR = 104;
2944 const UInt_t kCannotRotate = BIT(11);
2945 
2946 static TString gStringEntries;
2947 static TString gStringMean;
2949 static TString gStringMeanY;
2952 static TString gStringStdDevX;
2954 static TString gStringStdDevZ;
2957 static TString gStringIntegral;
2970 ////////////////////////////////////////////////////////////////////////////////
2971 /// Default constructor.
2976  fH = 0;
2977  fXaxis = 0;
2978  fYaxis = 0;
2979  fZaxis = 0;
2980  fFunctions = 0;
2981  fXbuf = 0;
2982  fYbuf = 0;
2983  fNcuts = 0;
2984  fStack = 0;
2985  fLego = 0;
2986  fPie = 0;
2987  fGraph2DPainter = 0;
2988  fShowProjection = 0;
2989  fShowOption = "";
2990  for (int i=0; i<kMaxCuts; i++) {
2991  fCuts[i] = 0;
2992  fCutsOpt[i] = 0;
2993  }
2994 
2995  gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
2996  gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
2997  gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
2998  gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
2999  gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3000  gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3001  gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3002  gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3003  gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3004  gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3005  gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3006  gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3007  gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3008  gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3009  gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3010  gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3011  gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3012  gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3013  gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3014  gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3015  gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3016 }
3017 
3018 ////////////////////////////////////////////////////////////////////////////////
3019 /// Default destructor.
3020 
3022 {
3023 }
3024 
3025 ////////////////////////////////////////////////////////////////////////////////
3026 /// Compute the distance from the point px,py to a line.
3027 ///
3028 /// Compute the closest distance of approach from point px,py to elements of
3029 /// an histogram. The distance is computed in pixels units.
3030 ///
3031 /// Algorithm: Currently, this simple model computes the distance from the mouse
3032 /// to the histogram contour only.
3035 {
3036 
3037  Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3038 
3039  const Int_t big = 9999;
3040  const Int_t kMaxDiff = 7;
3041 
3042  if (fPie) return fPie->DistancetoPrimitive(px, py);
3043 
3044  Double_t x = gPad->AbsPixeltoX(px);
3045  Double_t x1 = gPad->AbsPixeltoX(px+1);
3047  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3048  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3049  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3050  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3051  Int_t curdist = big;
3052  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3053  Bool_t dsame;
3054  TObject *PadPointer = gPad->GetPadPointer();
3055  if (!PadPointer) return 0;
3056  TString doption = PadPointer->GetDrawOption();
3057  Double_t factor = 1;
3058  if (fH->GetNormFactor() != 0) {
3059  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3060  }
3061  // return if point is not in the histogram area
3062 
3063  // If a 3D view exists, check distance to axis
3064  TView *view = gPad->GetView();
3065  Int_t d1,d2,d3;
3066  if (view && Hoption.Contour != 14) {
3067  Double_t ratio;
3068  d3 = view->GetDistancetoAxis(3, px, py, ratio);
3069  if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3070  d1 = view->GetDistancetoAxis(1, px, py, ratio);
3071  if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3072  d2 = view->GetDistancetoAxis(2, px, py, ratio);
3073  if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3074  if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3075  goto FUNCTIONS;
3076  }
3077  // check if point is close to an axis
3078  doption.ToLower();
3079  dsame = kFALSE;
3080  if (doption.Contains("same")) dsame = kTRUE;
3081 
3082  dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3083  if (doption.Contains("y+")) {
3084  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3085  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3086  if (!dsame) {
3087  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3088  else gPad->SetSelected(fXaxis);
3089  return 0;
3090  }
3091  }
3092  } else {
3093  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3094  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3095  if (!dsame) {
3096  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3097  else gPad->SetSelected(fXaxis);
3098  return 0;
3099  }
3100  }
3101  }
3102 
3103  dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3104  if (doption.Contains("x+")) {
3105  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3106  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3107  if (!dsame) {
3108  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3109  else gPad->SetSelected(fYaxis);
3110  return 0;
3111  }
3112  }
3113  } else {
3114  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3115  if (yxaxis < puymin) yxaxis = puymin;
3116  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3117  if (!dsame) {
3118  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3119  else gPad->SetSelected(fYaxis);
3120  return 0;
3121  }
3122  }
3123  }
3124 
3125  // if object is 2D or 3D return this object
3126  if (fH->GetDimension() == 2) {
3127  if (fH->InheritsFrom(TH2Poly::Class())) {
3128  TH2Poly *th2 = (TH2Poly*)fH;
3129  Double_t xmin, ymin, xmax, ymax;
3130  gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3131  Double_t pxu = gPad->AbsPixeltoX(px);
3132  Double_t pyu = gPad->AbsPixeltoY(py);
3133  if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3134  curdist = big;
3135  goto FUNCTIONS;
3136  } else {
3137  Int_t bin = th2->FindBin(pxu, pyu);
3138  if (bin>0) curdist = 1;
3139  else curdist = big;
3140  goto FUNCTIONS;
3141  }
3142  }
3143  Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3144  if ( px > puxmin + delta2
3145  && px < puxmax - delta2
3146  && py > puymax + delta2
3147  && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3148  }
3149 
3150  // point is inside histogram area. Find channel number
3151  if (gPad->IsVertical()) {
3152  Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3153  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3154  Double_t binval = factor*fH->GetBinContent(bin);
3155  Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3156  if (binval == 0 && pybin < puymin) pybin = 10000;
3157  // special case if more than one bin for the pixel
3158  if (binsup-bin>1) {
3159  Double_t binvalmin, binvalmax;
3160  binvalmin=binval;
3161  binvalmax=binval;
3162  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3163  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3164  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3165  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3166  }
3167  Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3168  Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3169  if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3170  }
3171  if (bin != binsup) { // Mouse on bin border border
3172  Double_t binsupval = factor*fH->GetBinContent(binsup);
3173  Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3174  if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin)) return 0;
3175  }
3176  if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3177  } else {
3178  Double_t y = gPad->AbsPixeltoY(py);
3179  Double_t y1 = gPad->AbsPixeltoY(py+1);
3180  Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3181  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3182  Double_t binval = factor*fH->GetBinContent(bin);
3183  Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3184  if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3185  // special case if more than one bin for the pixel
3186  if (binsup-bin>1) {
3187  Double_t binvalmin, binvalmax;
3188  binvalmin=binval;
3189  binvalmax=binval;
3190  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3191  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3192  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3193  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3194  }
3195  Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3196  Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3197  if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3198  }
3199  if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3200  }
3201  // Loop on the list of associated functions and user objects
3202 FUNCTIONS:
3203  TObject *f;
3204  TIter next(fFunctions);
3205  while ((f = (TObject*) next())) {
3206  Int_t dist;
3207  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3208  else dist = f->DistancetoPrimitive(px,py);
3209  if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3210  }
3211  return curdist;
3212 }
3213 
3214 ////////////////////////////////////////////////////////////////////////////////
3215 /// Display a panel with all histogram drawing options.
3216 
3218 {
3219 
3220  gCurrentHist = fH;
3221  if (!gPad) {
3222  Error("DrawPanel", "need to draw histogram first");
3223  return;
3224  }
3226  editor->Show();
3227  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3228  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3230 
3231 ////////////////////////////////////////////////////////////////////////////////
3232 /// Execute the actions corresponding to `event`.
3233 ///
3234 /// This function is called when a histogram is clicked with the locator at
3235 /// the pixel position px,py.
3236 
3237 void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3238 {
3239 
3240  if (!gPad) return;
3241 
3242  static Int_t bin, px1, py1, px2, py2, pyold;
3243  static TBox *zoombox;
3244  Double_t zbx1,zbx2,zby1,zby2;
3245 
3246  Int_t bin1, bin2;
3247  Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3248  Bool_t opaque = gPad->OpaqueMoving();
3250  if (!gPad->IsEditable()) return;
3251 
3252  if (fPie) {
3253  fPie->ExecuteEvent(event, px, py);
3254  return;
3255  }
3256  // come here if we have a lego/surface in the pad
3257  TView *view = gPad->GetView();
3258 
3259  if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3260  view->ExecuteRotateView(event, px, py);
3261  return;
3262  }
3263 
3264  TAxis *xaxis = fH->GetXaxis();
3265  TAxis *yaxis = fH->GetYaxis();
3266  Int_t dimension = fH->GetDimension();
3267 
3268  Double_t factor = 1;
3269  if (fH->GetNormFactor() != 0) {
3270  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3271  }
3272 
3273  switch (event) {
3274 
3275  case kButton1Down:
3276 
3277  if (!opaque) gVirtualX->SetLineColor(-1);
3278  fH->TAttLine::Modify();
3279 
3280  if (opaque && dimension ==2) {
3281  zbx1 = gPad->AbsPixeltoX(px);
3282  zbx2 = gPad->AbsPixeltoX(px);
3283  zby1 = gPad->AbsPixeltoY(py);
3284  zby2 = gPad->AbsPixeltoY(py);
3285  px1 = px;
3286  py1 = py;
3287  if (gPad->GetLogx()) {
3288  zbx1 = TMath::Power(10,zbx1);
3289  zbx2 = TMath::Power(10,zbx2);
3290  }
3291  if (gPad->GetLogy()) {
3292  zby1 = TMath::Power(10,zby1);
3293  zby2 = TMath::Power(10,zby2);
3294  }
3295  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3296  Int_t ci = TColor::GetColor("#7d7dff");
3297  TColor *zoomcolor = gROOT->GetColor(ci);
3298  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3299  else zoomcolor->SetAlpha(0.5);
3300  zoombox->SetFillColor(ci);
3301  zoombox->Draw();
3302  gPad->Modified();
3303  gPad->Update();
3304  }
3305  // No break !!!
3306 
3307  case kMouseMotion:
3308 
3309  if (fShowProjection) {ShowProjection3(px,py); break;}
3310 
3311  gPad->SetCursor(kPointer);
3312  if (dimension ==1) {
3313  if (Hoption.Bar) {
3314  baroffset = fH->GetBarOffset();
3315  barwidth = fH->GetBarWidth();
3316  } else {
3317  baroffset = 0;
3318  barwidth = 1;
3319  }
3320  x = gPad->AbsPixeltoX(px);
3321  bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3322  binwidth = fXaxis->GetBinWidth(bin);
3323  xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3324  xup = gPad->XtoPad(xlow + barwidth*binwidth);
3325  ylow = gPad->GetUymin();
3326  px1 = gPad->XtoAbsPixel(xlow);
3327  px2 = gPad->XtoAbsPixel(xup);
3328  py1 = gPad->YtoAbsPixel(ylow);
3329  py2 = py;
3330  pyold = py;
3331  if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3332  }
3333 
3334  break;
3335 
3336  case kButton1Motion:
3337 
3338  if (dimension ==1) {
3339  if (gROOT->GetEditHistograms()) {
3340  if (!opaque) {
3341  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3342  py2 += py - pyold;
3343  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3344  pyold = py;
3345  } else {
3346  py2 += py - pyold;
3347  pyold = py;
3348  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3349  fH->SetBinContent(bin,binval);
3350  gPad->Modified(kTRUE);
3351  }
3352  }
3353  }
3354 
3355  if (opaque && dimension ==2) {
3356  if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3357  zbx2 = gPad->AbsPixeltoX(px);
3358  zby2 = gPad->AbsPixeltoY(py);
3359  if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3360  if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3361  zoombox->SetX2(zbx2);
3362  zoombox->SetY2(zby2);
3363  gPad->Modified();
3364  gPad->Update();
3365  }
3366  }
3367 
3368  break;
3369 
3370  case kWheelUp:
3371 
3372  if (dimension ==2) {
3373  bin1 = xaxis->GetFirst()+1;
3374  bin2 = xaxis->GetLast()-1;
3375  bin1 = TMath::Max(bin1, 1);
3376  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3377  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3378  bin1 = yaxis->GetFirst()+1;
3379  bin2 = yaxis->GetLast()-1;
3380  bin1 = TMath::Max(bin1, 1);
3381  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3382  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3383  }
3384  gPad->Modified();
3385  gPad->Update();
3386 
3387  break;
3388 
3389  case kWheelDown:
3390 
3391  if (dimension == 2) {
3392  bin1 = xaxis->GetFirst()-1;
3393  bin2 = xaxis->GetLast()+1;
3394  bin1 = TMath::Max(bin1, 1);
3395  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3396  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3397  bin1 = yaxis->GetFirst()-1;
3398  bin2 = yaxis->GetLast()+1;
3399  bin1 = TMath::Max(bin1, 1);
3400  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3401  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3402  }
3403  gPad->Modified();
3404  gPad->Update();
3405 
3406  break;
3407 
3408  case kButton1Up:
3409  if (dimension ==1) {
3410  if (gROOT->GetEditHistograms()) {
3411  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3412  fH->SetBinContent(bin,binval);
3413  PaintInit(); // recalculate Hparam structure and recalculate range
3414  }
3415 
3416  // might resize pad pixmap so should be called before any paint routine
3417  RecalculateRange();
3418  }
3419  if (opaque && dimension ==2) {
3420  if (zoombox) {
3421  Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3422  Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3423  Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3424  Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3425  x1 = TMath::Max(x1,xaxis->GetXmin());
3426  x2 = TMath::Min(x2,xaxis->GetXmax());
3427  y1 = TMath::Max(y1,yaxis->GetXmin());
3428  y2 = TMath::Min(y2,yaxis->GetXmax());
3429  if (x1<x2 && y1<y2) {
3430  xaxis->SetRangeUser(x1, x2);
3431  yaxis->SetRangeUser(y1, y2);
3432  }
3433  zoombox->Delete();
3434  zoombox = 0;
3435  }
3436  }
3437  gPad->Modified(kTRUE);
3438  if (opaque) gVirtualX->SetLineColor(-1);
3439 
3440  break;
3441 
3442  case kButton1Locate:
3443 
3444  ExecuteEvent(kButton1Down, px, py);
3445 
3446  while (1) {
3447  px = py = 0;
3448  event = gVirtualX->RequestLocator(1, 1, px, py);
3449 
3450  ExecuteEvent(kButton1Motion, px, py);
3451 
3452  if (event != -1) { // button is released
3453  ExecuteEvent(kButton1Up, px, py);
3454  return;
3455  }
3456  }
3457  }
3458 }
3459 
3460 ////////////////////////////////////////////////////////////////////////////////
3461 /// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3462 
3464 {
3465 
3466 
3467 
3468  // Check if fH contains a TGraphDelaunay2D
3469  TList *hl = fH->GetListOfFunctions();
3470  TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3471  // try with the old painter
3472  TGraphDelaunay *dtOld = nullptr;
3473  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3474 
3475  if (!dt && !dtOld) return nullptr;
3476 
3477  gCurrentHist = fH;
3478 
3479  if (!fGraph2DPainter) {
3480  if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3481  else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3482  }
3483 
3484  return fGraph2DPainter->GetContourList(contour);
3485 }
3486 
3487 ////////////////////////////////////////////////////////////////////////////////
3488 /// Display the histogram info (bin number, contents, integral up to bin
3489 /// corresponding to cursor position px,py.
3490 
3491 char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
3492 {
3493 
3494  if (!gPad) return (char*)"";
3495  static char info[200];
3496  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3497  Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3498  Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3499  TString drawOption = fH->GetDrawOption();
3500  drawOption.ToLower();
3501  Double_t xmin, xmax, uxmin,uxmax;
3502  Double_t ymin, ymax, uymin,uymax;
3503  if (fH->GetDimension() == 2) {
3504  if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3505  uxmin=gPad->GetUxmin();
3506  uxmax=gPad->GetUxmax();
3507  xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
3508  xmax = fXaxis->GetBinUpEdge(fXaxis->GetLast());
3509  x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3510  uymin=gPad->GetUymin();
3511  uymax=gPad->GetUymax();
3512  ymin = fYaxis->GetBinLowEdge(fYaxis->GetFirst());
3513  ymax = fYaxis->GetBinUpEdge(fYaxis->GetLast());
3514  y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3515  }
3516  }
3517  Int_t binx,biny,binmin=0,binx1;
3518  if (gPad->IsVertical()) {
3519  binx = fXaxis->FindFixBin(x);
3520  if (drawOption.Index("same") >= 0) {
3521  TH1 *h1;
3522  TIter next(gPad->GetListOfPrimitives());
3523  while ((h1 = (TH1 *)next())) {
3524  if (!h1->InheritsFrom(TH1::Class())) continue;
3525  binmin = h1->GetXaxis()->GetFirst();
3526  break;
3527  }
3528  } else {
3529  binmin = fXaxis->GetFirst();
3530  }
3531  binx1 = fXaxis->FindFixBin(x1);
3532  // special case if more than 1 bin in x per pixel
3533  if (binx1-binx>1 && fH->GetDimension() == 1) {
3534  Double_t binval=fH->GetBinContent(binx);
3535  Int_t binnear=binx;
3536  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3537  Double_t binvaltmp = fH->GetBinContent(ibin);
3538  if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3539  binval=binvaltmp;
3540  binnear=ibin;
3541  }
3542  }
3543  binx = binnear;
3544  }
3545  } else {
3546  x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3547  binx = fXaxis->FindFixBin(y);
3548  if (drawOption.Index("same") >= 0) {
3549  TH1 *h1;
3550  TIter next(gPad->GetListOfPrimitives());
3551  while ((h1 = (TH1 *)next())) {
3552  if (!h1->InheritsFrom(TH1::Class())) continue;
3553  binmin = h1->GetXaxis()->GetFirst();
3554  break;
3555  }
3556  } else {
3557  binmin = fXaxis->GetFirst();
3558  }
3559  binx1 = fXaxis->FindFixBin(x1);
3560  // special case if more than 1 bin in x per pixel
3561  if (binx1-binx>1 && fH->GetDimension() == 1) {
3562  Double_t binval=fH->GetBinContent(binx);
3563  Int_t binnear=binx;
3564  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3565  Double_t binvaltmp = fH->GetBinContent(ibin);
3566  if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3567  binval=binvaltmp;
3568  binnear=ibin;
3569  }
3570  }
3571  binx = binnear;
3572  }
3573  }
3574  if (fH->GetDimension() == 1) {
3575  if (fH->InheritsFrom(TProfile::Class())) {
3576  TProfile *tp = (TProfile*)fH;
3577  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3578  x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3579  (Int_t) tp->GetBinEntries(binx));
3580  }
3581  else {
3582  Double_t integ = 0;
3583  for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3584  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3585  x,y,binx,fH->GetBinContent(binx),integ);
3586  }
3587  } else if (fH->GetDimension() == 2) {
3588  if (fH->InheritsFrom(TH2Poly::Class())) {
3589  TH2Poly *th2 = (TH2Poly*)fH;
3590  biny = th2->FindBin(x,y);
3591  snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3592  th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3593  }
3594  else if (fH->InheritsFrom(TProfile2D::Class())) {
3595  TProfile2D *tp = (TProfile2D*)fH;
3596  biny = fYaxis->FindFixBin(y);
3597  Int_t bin = fH->GetBin(binx,biny);
3598  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3599  x, y, binx, biny, fH->GetBinContent(bin),
3600  fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3601  } else {
3602  biny = fYaxis->FindFixBin(y);
3603  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3604  x,y,binx,biny,fH->GetBinContent(binx,biny),
3605  fH->GetBinError(binx,biny));
3606  }
3607  } else {
3608  // 3d case: retrieving the x,y,z bin is not yet implemented
3609  // print just the x,y info
3610  snprintf(info,200,"(x=%g, y=%g)",x,y);
3611  }
3612  return info;
3613 }
3614 
3615 ////////////////////////////////////////////////////////////////////////////////
3616 /// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3617 
3619 {
3620 
3621  for (Int_t i=0;i<fNcuts;i++) {
3622  Double_t x = fXaxis->GetBinCenter(ix);
3623  Double_t y = fYaxis->GetBinCenter(iy);
3624  if (fCutsOpt[i] > 0) {
3625  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3626  } else {
3627  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3628  }
3629  }
3630  return kTRUE;
3631 }
3632 
3633 ////////////////////////////////////////////////////////////////////////////////
3634 /// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3635 
3637 {
3638 
3639  for (Int_t i=0;i<fNcuts;i++) {
3640  if (fCutsOpt[i] > 0) {
3641  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3642  } else {
3643  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3644  }
3645  }
3646  return kTRUE;
3647 }
3649 ////////////////////////////////////////////////////////////////////////////////
3650 /// Decode string `choptin` and fill Hoption structure.
3651 
3653 {
3654 
3655  char *l;
3656  char chopt[128];
3657  Int_t nch = strlen(choptin);
3658  strlcpy(chopt,choptin,128);
3659  Int_t hdim = fH->GetDimension();
3660 
3661  Hoption.Axis = Hoption.Bar = Hoption.Curve = Hoption.Error = 0;
3662  Hoption.Hist = Hoption.Line = Hoption.Mark = Hoption.Fill = 0;
3663  Hoption.Same = Hoption.Func = Hoption.Scat = 0;
3664  Hoption.Star = Hoption.Arrow = Hoption.Box = Hoption.Text = 0;
3665  Hoption.Char = Hoption.Color = Hoption.Contour = Hoption.Logx = 0;
3666  Hoption.Logy = Hoption.Logz = Hoption.Lego = Hoption.Surf = 0;
3667  Hoption.Off = Hoption.Tri = Hoption.Proj = Hoption.AxisPos = 0;
3668  Hoption.Spec = Hoption.Pie = Hoption.Candle = 0;
3669 
3670  // special 2D options
3671  Hoption.List = 0;
3672  Hoption.Zscale = 0;
3673  Hoption.FrontBox = 1;
3674  Hoption.BackBox = 1;
3675  Hoption.System = kCARTESIAN;
3676 
3677  Hoption.Zero = 0;
3678 
3679  //check for graphical cuts
3680  MakeCuts(chopt);
3681 
3682  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3683  if (hdim > 1) Hoption.Scat = 1;
3684  if (!nch) Hoption.Hist = 1;
3685  if (fFunctions->First()) Hoption.Func = 1;
3686  if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3687 
3688  char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
3689  char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
3690  char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
3691  if (l1 || l2 || l3) {
3692  Int_t i = gPad->NextPaletteColor();
3693  if (l1) {strncpy(l1," ",3); fH->SetFillColor(i);}
3694  if (l2) {strncpy(l2," ",3); fH->SetLineColor(i);}
3695  if (l3) {strncpy(l3," ",3); fH->SetMarkerColor(i);}
3696  }
3697 
3698  l = strstr(chopt,"SPEC");
3699  if (l) {
3700  Hoption.Scat = 0;
3701  strncpy(l," ",4);
3702  Int_t bs=0;
3703  l = strstr(chopt,"BF(");
3704  if (l) {
3705  if (sscanf(&l[3],"%d",&bs) > 0) {
3706  Int_t i=0;
3707  while (l[i]!=')') {
3708  l[i] = ' ';
3709  i++;
3710  }
3711  l[i] = ' ';
3712  }
3713  }
3714  Hoption.Spec = TMath::Max(1600,bs);
3715  return 1;
3716  }
3717 
3718  l = strstr(chopt,"GL");
3719  if (l) {
3720  strncpy(l," ",2);
3721  }
3722  l = strstr(chopt,"X+");
3723  if (l) {
3724  Hoption.AxisPos = 10;
3725  strncpy(l," ",2);
3726  }
3727  l = strstr(chopt,"Y+");
3728  if (l) {
3729  Hoption.AxisPos += 1;
3730  strncpy(l," ",2);
3731  }
3732  if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
3733  if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
3734 
3735  l = strstr(chopt,"SAMES");
3736  if (l) {
3737  if (nch == 5) Hoption.Hist = 1;
3738  Hoption.Same = 2;
3739  strncpy(l," ",5);
3740  }
3741  l = strstr(chopt,"SAME");
3742  if (l) {
3743  if (nch == 4) Hoption.Hist = 1;
3744  Hoption.Same = 1;
3745  strncpy(l," ",4);
3746  }
3747 
3748  l = strstr(chopt,"PIE");
3749  if (l) {
3750  Hoption.Pie = 1;
3751  strncpy(l," ",3);
3752  }
3753 
3754 
3755  l = strstr(chopt,"CANDLE");
3756  if (l) {
3757  TCandle candle;
3758  Hoption.Candle = candle.ParseOption(l);
3759  Hoption.Scat = 0;
3760  }
3761 
3762  l = strstr(chopt,"VIOLIN");
3763  if (l) {
3764  TCandle candle;
3765  Hoption.Candle = candle.ParseOption(l);
3766  Hoption.Scat = 0;
3767  }
3768 
3769  l = strstr(chopt,"LEGO");
3770  if (l) {
3771  Hoption.Scat = 0;
3772  Hoption.Lego = 1; strncpy(l," ",4);
3773  if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
3774  if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
3775  if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
3776  if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
3777  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3778  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3779  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3780  }
3781 
3782  l = strstr(chopt,"SURF");
3783  if (l) {
3784  Hoption.Scat = 0;
3785  Hoption.Surf = 1; strncpy(l," ",4);
3786  if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
3787  if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
3788  if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
3789  if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
3790  if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
3791  if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
3792  if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
3793  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3794  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3795  }
3796 
3797  l = strstr(chopt,"TF3");
3798  if (l) {
3799  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3800  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3801  }
3802 
3803  l = strstr(chopt,"ISO");
3804  if (l) {
3805  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3806  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3807  }
3808 
3809  l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; strncpy(l," ",4);}
3810 
3811  l = strstr(chopt,"CONT");
3812  if (l) {
3813  strncpy(l," ",4);
3814  if (hdim>1) {
3815  Hoption.Scat = 0;
3816  Hoption.Contour = 1;
3817  if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
3818  if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
3819  if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
3820  if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
3821  if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
3822  } else {
3823  Hoption.Hist = 1;
3824  }
3825  }
3826  l = strstr(chopt,"HBAR");
3827  if (l) {
3828  Hoption.Hist = 0;
3829  Hoption.Bar = 20; strncpy(l," ",4);
3830  if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
3831  if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
3832  if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
3833  if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
3834  }
3835  l = strstr(chopt,"BAR");
3836  if (l) {
3837  Hoption.Hist = 0;
3838  Hoption.Bar = 10; strncpy(l," ",3);
3839  if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
3840  if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
3841  if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
3842  if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
3843  }
3844 
3845  l = strstr(chopt,"ARR" );
3846  if (l) {
3847  strncpy(l," ", 3);
3848  if (hdim>1) {
3849  Hoption.Arrow = 1;
3850  Hoption.Scat = 0;
3851  } else {
3852  Hoption.Hist = 1;
3853  }
3854  }
3855  l = strstr(chopt,"BOX" );
3856  if (l) {
3857  strncpy(l," ", 3);
3858  if (hdim>1) {
3859  Hoption.Scat = 0;
3860  Hoption.Box = 1;
3861  if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
3862  } else {
3863  Hoption.Hist = 1;
3864  }
3865  }
3866  l = strstr(chopt,"COLZ");
3867  if (l) {
3868  strncpy(l," ",4);
3869  if (hdim>1) {
3870  Hoption.Color = 1;
3871  Hoption.Scat = 0;
3872  Hoption.Zscale = 1;
3873  if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
3874  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3875  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3876  } else {
3877  Hoption.Hist = 1;
3878  }
3879  }
3880  l = strstr(chopt,"COL" );
3881  if (l) {
3882  strncpy(l," ", 3);
3883  if (hdim>1) {
3884  Hoption.Color = 1;
3885  Hoption.Scat = 0;
3886  if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
3887  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3888  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3889  } else {
3890  Hoption.Hist = 1;
3891  }
3892  }
3893  l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; strncpy(l," ",4); Hoption.Scat = 0; }
3894  l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; strncpy(l," ",4); Hoption.Hist = 0; }
3895  l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; strncpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
3896  l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; strncpy(l," ",4); }
3897  l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; strncpy(l," ",4); }
3898  l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; strncpy(l," ",4); }
3899  l = strstr(chopt,"TEXT");
3900  if (l) {
3901  Int_t angle;
3902  if (sscanf(&l[4],"%d",&angle) > 0) {
3903  if (angle < 0) angle=0;
3904  if (angle > 90) angle=90;
3905  Hoption.Text = 1000+angle;
3906  } else {
3907  Hoption.Text = 1;
3908  }
3909  strncpy(l," ", 4);
3910  l = strstr(chopt,"N");
3911  if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
3912  Hoption.Scat = 0;
3913  }
3914  l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; strncpy(l," ",3); }
3915  l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; strncpy(l," ",3); }
3916  l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; strncpy(l," ",3); }
3917  l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; strncpy(l," ",3); }
3918 
3919  l = strstr(chopt,"TRI");
3920  if (l) {
3921  Hoption.Scat = 0;
3922  Hoption.Color = 0;
3923  Hoption.Tri = 1; strncpy(l," ",3);
3924  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3925  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3926  l = strstr(chopt,"ERR"); if (l) strncpy(l," ",3);
3927  }
3928 
3929  l = strstr(chopt,"AITOFF");
3930  if (l) {
3931  Hoption.Proj = 1; strncpy(l," ",6); //Aitoff projection
3932  }
3933  l = strstr(chopt,"MERCATOR");
3934  if (l) {
3935  Hoption.Proj = 2; strncpy(l," ",8); //Mercator projection
3936  }
3937  l = strstr(chopt,"SINUSOIDAL");
3938  if (l) {
3939  Hoption.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
3940  }
3941  l = strstr(chopt,"PARABOLIC");
3942  if (l) {
3943  Hoption.Proj = 4; strncpy(l," ",9); //Parabolic projection
3944  }
3945  if (Hoption.Proj > 0) {
3946  Hoption.Scat = 0;
3947  Hoption.Contour = 14;
3948  }
3949 
3950  if (strstr(chopt,"A")) Hoption.Axis = -1;
3951  if (strstr(chopt,"B")) Hoption.Bar = 1;
3952  if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
3953  if (strstr(chopt,"F")) Hoption.Fill =1;
3954  if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
3955  if (strstr(chopt,"F2")) Hoption.Fill =2;
3956  if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
3957  if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
3958  if (strstr(chopt,"Z")) Hoption.Zscale =1;
3959  if (strstr(chopt,"*")) Hoption.Star =1;
3960  if (strstr(chopt,"H")) Hoption.Hist =2;
3961  if (strstr(chopt,"P0")) Hoption.Mark =10;
3962 
3963  if (fH->InheritsFrom(TH2Poly::Class())) {
3964  if (Hoption.Fill+Hoption.Line+Hoption.Mark != 0 ) Hoption.Scat = 0;
3965  }
3966 
3967  if (strstr(chopt,"E")) {
3968  if (hdim == 1) {
3969  Hoption.Error = 1;
3970  if (strstr(chopt,"E0")) Hoption.Error = 10;
3971  if (strstr(chopt,"E1")) Hoption.Error = 11;
3972  if (strstr(chopt,"E2")) Hoption.Error = 12;
3973  if (strstr(chopt,"E3")) Hoption.Error = 13;
3974  if (strstr(chopt,"E4")) Hoption.Error = 14;
3975  if (strstr(chopt,"E5")) Hoption.Error = 15;
3976  if (strstr(chopt,"E6")) Hoption.Error = 16;
3977  if (strstr(chopt,"X0")) {
3978  if (Hoption.Error == 1) Hoption.Error += 20;
3979  Hoption.Error += 10;
3980  }
3981  if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
3982  Hoption.Text += 2000;
3983  Hoption.Error = 0;
3984  }
3985  } else {
3986  if (Hoption.Error == 0) {
3987  Hoption.Error = 100;
3988  Hoption.Scat = 0;
3989  }
3990  if (Hoption.Text) {
3991  Hoption.Text += 2000;
3992  Hoption.Error = 0;
3993  }
3994  }
3995  }
3996 
3997  if (Hoption.Surf == 15) {
3998  if (Hoption.System == kPOLAR || Hoption.System == kCARTESIAN) {
3999  Hoption.Surf = 13;
4000  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4001  }
4002  }
4003 
4004  // Copy options from current style
4005  Hoption.Logx = gPad->GetLogx();
4006  Hoption.Logy = gPad->GetLogy();
4007  Hoption.Logz = gPad->GetLogz();
4008 
4009  // Check options incompatibilities
4010  if (Hoption.Bar == 1) Hoption.Hist = -1;
4011  return 1;
4012 }
4013 
4014 ////////////////////////////////////////////////////////////////////////////////
4015 /// Decode string `choptin` and fill Graphical cuts structure.
4016 
4017 Int_t THistPainter::MakeCuts(char *choptin)
4018 {
4019 
4020  fNcuts = 0;
4021  char *left = (char*)strchr(choptin,'[');
4022  if (!left) return 0;
4023  char *right = (char*)strchr(choptin,']');
4024  if (!right) return 0;
4025  Int_t nch = right-left;
4026  if (nch < 2) return 0;
4027  char *cuts = left+1;
4028  *right = 0;
4029  char *comma, *minus;
4030  Int_t i;
4031  while (1) {
4032  comma = strchr(cuts,',');
4033  if (comma) *comma = 0;
4034  minus = strchr(cuts,'-');
4035  if (minus) cuts = minus+1;
4036  while (*cuts == ' ') cuts++;
4037  Int_t nc = strlen(cuts);
4038  while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4039  TIter next(gROOT->GetListOfSpecials());
4040  TCutG *cut=0;
4041  TObject *obj;
4042  while ((obj = next())) {
4043  if (!obj->InheritsFrom(TCutG::Class())) continue;
4044  if (strcmp(obj->GetName(),cuts)) continue;
4045  cut = (TCutG*)obj;
4046  break;
4047  }
4048  if (cut) {
4049  fCuts[fNcuts] = cut;
4050  fCutsOpt[fNcuts] = 1;
4051  if (minus) fCutsOpt[fNcuts] = -1;
4052  fNcuts++;
4053  }
4054  if (!comma) break;
4055  cuts = comma+1;
4056  }
4057  for (i=0;i<=nch;i++) left[i] = ' ';
4058  return fNcuts;
4059 }
4060 
4061 ////////////////////////////////////////////////////////////////////////////////
4062 /// [Control routine to paint any kind of histograms](#HP00)
4063 
4064 void THistPainter::Paint(Option_t *option)
4065 {
4066 
4067  if (fH->GetBuffer()) fH->BufferEmpty(-1);
4068 
4069  //For iOS: put the histogram on the top of stack of pickable objects.
4070  const TPickerStackGuard topPush(fH);
4071 
4072  gPad->SetVertical(kTRUE);
4073 
4074  TH1 *oldhist = gCurrentHist;
4075  gCurrentHist = fH;
4076  TH1 *hsave = fH;
4077  Double_t minsav = fH->GetMinimumStored();
4078 
4079  if (!MakeChopt(option)) return; //check options and fill Hoption structure
4080 
4081  // Paint using TSpectrum2Painter
4082  if (Hoption.Spec) {
4083  if (!TableInit()) return;
4084  if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4085  gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4086  (ULong_t)fH, option, Hoption.Spec));
4087  return;
4088  }
4089 
4090  if (Hoption.Pie) {
4091  if (fH->GetDimension() == 1) {
4092  if (!fPie) fPie = new TPie(fH);
4093  fPie->Paint(option);
4094  } else {
4095  Error("Paint", "Option PIE is for 1D histograms only");
4096  }
4097  return;
4098  } else {
4099  if (fPie) delete fPie;
4100  fPie = 0;
4101  }
4102 
4103  fXbuf = new Double_t[kNMAX];
4104  fYbuf = new Double_t[kNMAX];
4105  if (fH->GetDimension() > 2) {
4106  PaintH3(option);
4107  fH->SetMinimum(minsav);
4108  if (Hoption.Func) {
4109  Hoption_t hoptsave = Hoption;
4110  Hparam_t hparsave = Hparam;
4111  PaintFunction(option);
4112  SetHistogram(hsave);
4113  Hoption = hoptsave;
4114  Hparam = hparsave;
4115  }
4116  gCurrentHist = oldhist;
4117  delete [] fXbuf; delete [] fYbuf;
4118  return;
4119  }
4120  TView *view = gPad->GetView();
4121  if (view) {
4122  if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4123  delete view;
4124  gPad->SetView(0);
4125  }
4126  }
4127  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4128  // In case of 1D histogram, Z axis becomes Y axis.
4129  Int_t logysav=0, logzsav=0;
4130  if (fH->GetDimension() == 1) {
4131  logysav = Hoption.Logy;
4132  logzsav = Hoption.Logz;
4133  Hoption.Logz = 0;
4134  if (Hoption.Logy) {
4135  Hoption.Logz = 1;
4136  Hoption.Logy = 0;
4137  }
4138  }
4139  PaintTable(option);
4140  if (Hoption.Func) {
4141  Hoption_t hoptsave = Hoption;
4142  Hparam_t hparsave = Hparam;
4143  PaintFunction(option);
4144  SetHistogram(hsave);
4145  Hoption = hoptsave;
4146  Hparam = hparsave;
4147  }
4148  fH->SetMinimum(minsav);
4149  gCurrentHist = oldhist;
4150  delete [] fXbuf; delete [] fYbuf;
4151  if (fH->GetDimension() == 1) {
4152  Hoption.Logy = logysav;
4153  Hoption.Logz = logzsav;
4154  }
4155  return;
4156  }
4157 
4158  if (Hoption.Bar >= 20) {PaintBarH(option);
4159  delete [] fXbuf; delete [] fYbuf;
4160  return;
4161  }
4162 
4163  // fill Hparam structure with histo parameters
4164  if (!PaintInit()) {
4165  delete [] fXbuf; delete [] fYbuf;
4166  return;
4167  }
4168 
4169  // Picture surround (if new page) and page number (if requested).
4170  // Histogram surround (if not option "Same").
4171  PaintFrame();
4172 
4173  // Paint histogram axis only
4174  Bool_t gridx = gPad->GetGridx();
4175  Bool_t gridy = gPad->GetGridy();
4176  if (Hoption.Axis > 0) {
4177  if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4178  else {
4179  if (gridx) gPad->SetGridx(0);
4180  if (gridy) gPad->SetGridy(0);
4181  PaintAxis(kFALSE);
4182  if (gridx) gPad->SetGridx(1);
4183  if (gridy) gPad->SetGridy(1);
4184  }
4185  if (Hoption.Same ==1) Hoption.Same = 2;
4186  goto paintstat;
4187  }
4188  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4189 
4190  // test for options BAR or HBAR
4191  if (Hoption.Bar >= 10) {
4192  PaintBar(option);
4193  }
4194 
4195  // do not draw histogram if error bars required
4196  if (!Hoption.Error) {
4197  if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4198  }
4199 
4200  // test for error bars or option E
4201  if (Hoption.Error) {
4202  PaintErrors(option);
4203  if (Hoption.Hist == 2) PaintHist(option);
4204  }
4205 
4206  if (Hoption.Text) PaintText(option);
4207 
4208  // test for associated function
4209  if (Hoption.Func) {
4210  Hoption_t hoptsave = Hoption;
4211  Hparam_t hparsave = Hparam;
4212  PaintFunction(option);
4213  SetHistogram(hsave);
4214  Hoption = hoptsave;
4215  Hparam = hparsave;
4216  }
4217 
4218  if (gridx) gPad->SetGridx(0);
4219  if (gridy) gPad->SetGridy(0);
4220  PaintAxis(kFALSE);
4221  if (gridx) gPad->SetGridx(1);
4222  if (gridy) gPad->SetGridy(1);
4223 
4224  PaintTitle(); // Draw histogram title
4225 
4226  // Draw box with histogram statistics and/or fit parameters
4227 paintstat:
4228  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4229  TIter next(fFunctions);
4230  TObject *obj = 0;
4231  while ((obj = next())) {
4232  if (obj->InheritsFrom(TF1::Class())) break;
4233  obj = 0;
4234  }
4235 
4236  //Stat is painted twice (first, it will be in canvas' list of primitives),
4237  //second, it will be here, this is not required on iOS.
4238  //Condition is ALWAYS true on a platform different from iOS.
4239  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4240  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4241  }
4242  fH->SetMinimum(minsav);
4243  gCurrentHist = oldhist;
4244  delete [] fXbuf; fXbuf = 0;
4245  delete [] fYbuf; fYbuf = 0;
4246 
4247 }
4248 
4249 ////////////////////////////////////////////////////////////////////////////////
4250 /// [Control function to draw a table as an arrow plot](#HP12)
4251 
4253 {
4254  fH->TAttLine::Modify();
4255 
4256  Double_t xk, xstep, yk, ystep;
4257  Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
4258  Int_t ncx = Hparam.xlast - Hparam.xfirst + 1;
4259  Int_t ncy = Hparam.ylast - Hparam.yfirst + 1;
4260  Double_t xrg = gPad->GetUxmin();
4261  Double_t yrg = gPad->GetUymin();
4262  Double_t xln = gPad->GetUxmax() - xrg;
4263  Double_t yln = gPad->GetUymax() - yrg;
4264  Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4265  Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4266  Double_t dn = 1.E-30;
4267 
4268  for (Int_t id=1;id<=2;id++) {
4269  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4270  yk = fYaxis->GetBinLowEdge(j);
4271  ystep = fYaxis->GetBinWidth(j);
4272  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4273  xk = fXaxis->GetBinLowEdge(i);
4274  xstep = fXaxis->GetBinWidth(i);
4275  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4276  if (i == Hparam.xfirst) {
4277  dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4278  } else if (i == Hparam.xlast) {
4279  dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4280  } else {
4281  dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4282  }
4283  if (j == Hparam.yfirst) {
4284  dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4285  } else if (j == Hparam.ylast) {
4286  dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4287  } else {
4288  dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4289  }
4290  if (id == 1) {
4291  dn = TMath::Max(dn, TMath::Abs(dx));
4292  dn = TMath::Max(dn, TMath::Abs(dy));
4293  } else if (id == 2) {
4294  xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4295  dxn = cx*dx/dn;
4296  x1 = xc - dxn;
4297  x2 = xc + dxn;
4298  yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4299  dyn = cy*dy/dn;
4300  y1 = yc - dyn;
4301  y2 = yc + dyn;
4302  fXbuf[0] = x1;
4303  fXbuf[1] = x2;
4304  fYbuf[0] = y1;
4305  fYbuf[1] = y2;
4306  if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
4307  anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
4308  si = anr*(dxn + dyn);
4309  co = anr*(dxn - dyn);
4310  fXbuf[2] = x2 - si;
4311  fYbuf[2] = y2 + co;
4312  gPad->PaintPolyLine(3, fXbuf, fYbuf);
4313  fXbuf[0] = x2;
4314  fXbuf[1] = x2 - co;
4315  fYbuf[0] = y2;
4316  fYbuf[1] = y2 - si;
4317  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4318  }
4319  else {
4320  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4321  }
4322  }
4323  }
4324  }
4325  }
4326 
4327  if (Hoption.Zscale) PaintPalette();
4328 }
4329 
4330 ////////////////////////////////////////////////////////////////////////////////
4331 /// Draw axis (2D case) of an histogram.
4332 ///
4333 /// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4334 /// to draw the grid and the axis separately. In `THistPainter::Paint` this
4335 /// feature is used to make sure that the grid is drawn in the background and
4336 /// the axis tick marks in the foreground of the pad.
4337 
4338 void THistPainter::PaintAxis(Bool_t drawGridOnly)
4339 {
4340 
4341  //On iOS, grid should not be pickable and can not be highlighted.
4342  //Condition is never true on a platform different from iOS.
4343  if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4344  return;
4345 
4346  if (Hoption.Axis == -1) return;
4347  if (Hoption.Same && Hoption.Axis <= 0) return;
4348 
4349  // Repainting alphanumeric labels axis on a plot done with
4350  // the option HBAR (horizontal) needs some adjustments.
4351  TAxis *xaxis = 0;
4352  TAxis *yaxis = 0;
4353  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4354  if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4355  TIter next(gPad->GetListOfPrimitives());
4356  TObject *obj;
4357  // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4358  while ((obj = next())) {
4359  if (!obj->InheritsFrom(TH1::Class()) &&
4360  !obj->InheritsFrom(THStack::Class())) continue;
4361  TString opt = obj->GetDrawOption();
4362  opt.ToLower();
4363  // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4364  if (strstr(opt,"hbar")) {
4365  gPad->SetVertical(kFALSE);
4366  xaxis = fXaxis;
4367  yaxis = fYaxis;
4368  if (!strcmp(xaxis->GetName(),"xaxis")) {
4369  fXaxis = yaxis;
4370  fYaxis = xaxis;
4371  }
4372  }
4373  break;
4374  }
4375  }
4376  }
4377 
4378  static char chopt[10] = "";
4379  Double_t gridl = 0;
4380  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4381  Int_t useHparam = 0;
4382  Double_t umin, umax, uminsave, umaxsave;
4383  Short_t xAxisPos = Hoption.AxisPos/10;
4384  Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4385 
4386  Double_t axmin = gPad->GetUxmin();
4387  Double_t axmax = gPad->GetUxmax();
4388  Double_t aymin = gPad->GetUymin();
4389  Double_t aymax = gPad->GetUymax();
4390  char *cw = 0;
4391  TGaxis axis;
4392 
4393  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4394  // Hparam must be use for the axis limits.
4395  if (Hoption.Contour == 14) useHparam = 1;
4396  if (Hoption.Same) {
4397  TObject *obj;
4398  TIter next(gPad->GetListOfPrimitives());
4399  while ((obj=next())) {
4400  if (strstr(obj->GetDrawOption(),"cont4")) {
4401  useHparam = 1;
4402  break;
4403  }
4404  }
4405  }
4406 
4407  // Paint X axis
4408 
4409  //To make X-axis selectable on iOS device.
4410  if (gPad->PadInSelectionMode())
4411  gPad->PushSelectableObject(fXaxis);
4412 
4413  //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4414  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4415  ndivx = fXaxis->GetNdivisions();
4416  if (ndivx > 1000) {
4417  nx2 = ndivx/100;
4418  nx1 = TMath::Max(1, ndivx%100);
4419  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4420  }
4421  axis.SetTextAngle(0);
4423 
4424  chopt[0] = 0;
4425  strlcat(chopt, "SDH",10);
4426  if (ndivx < 0) strlcat(chopt, "N",10);
4427  if (gPad->GetGridx()) {
4428  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4429  strlcat(chopt, "W",10);
4430  }
4431 
4432  // Define X-Axis limits
4433  if (Hoption.Logx) {
4434  strlcat(chopt, "G",10);
4435  ndiv = TMath::Abs(ndivx);
4436  if (useHparam) {
4437  umin = TMath::Power(10,Hparam.xmin);
4438  umax = TMath::Power(10,Hparam.xmax);
4439  } else {
4440  umin = TMath::Power(10,axmin);
4441  umax = TMath::Power(10,axmax);
4442  }
4443  } else {
4444  ndiv = TMath::Abs(ndivx);
4445  if (useHparam) {
4446  umin = Hparam.xmin;
4447  umax = Hparam.xmax;
4448  } else {
4449  umin = axmin;
4450  umax = axmax;
4451  }
4452  }
4453 
4454  // Display axis as time
4455  if (fXaxis->GetTimeDisplay()) {
4456  strlcat(chopt,"t",10);
4457  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4458  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam.xmax-Hparam.xmin));
4459  }
4460  }
4461 
4462  // The main X axis can be on the bottom or on the top of the pad
4463  Double_t xAxisYPos1, xAxisYPos2;
4464  if (xAxisPos == 1) {
4465  // Main X axis top
4466  xAxisYPos1 = aymax;
4467  xAxisYPos2 = aymin;
4468  } else {
4469  // Main X axis bottom
4470  xAxisYPos1 = aymin;
4471  xAxisYPos2 = aymax;
4472  }
4473 
4474  // Paint the main X axis (always)
4475  uminsave = umin;
4476  umaxsave = umax;
4477  ndivsave = ndiv;
4478  axis.SetOption(chopt);
4479  if (xAxisPos) {
4480  strlcat(chopt, "-",10);
4481  gridl = -gridl;
4482  }
4483  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4484  axis.SetLabelSize(0.);
4485  axis.SetTitle("");
4486  }
4487  axis.PaintAxis(axmin, xAxisYPos1,
4488  axmax, xAxisYPos1,
4489  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4490 
4491  // Paint additional X axis (if needed)
4492  // On iOS, this additional X axis is neither pickable, nor highlighted.
4493  // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4494  if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4495  if (xAxisPos) {
4496  cw=strstr(chopt,"-");
4497  *cw='z';
4498  } else {
4499  strlcat(chopt, "-",10);
4500  }
4501  if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4502  if ((cw=strstr(chopt,"W"))) *cw='z';
4503  axis.SetTitle("");
4504  axis.PaintAxis(axmin, xAxisYPos2,
4505  axmax, xAxisYPos2,
4506  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4507  }
4508  }//End of "if pad in selection mode etc".
4509 
4510  // Paint Y axis
4511  //On iOS, Y axis must pushed into the stack of selectable objects.
4512  if (gPad->PadInSelectionMode())
4513  gPad->PushSelectableObject(fYaxis);
4514 
4515  //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4516  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4517  ndivy = fYaxis->GetNdivisions();
4519 
4520  chopt[0] = 0;
4521  strlcat(chopt, "SDH",10);
4522  if (ndivy < 0) strlcat(chopt, "N",10);
4523  if (gPad->GetGridy()) {
4524  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4525  strlcat(chopt, "W",10);
4526  }
4527 
4528  // Define Y-Axis limits
4529  if (Hoption.Logy) {
4530  strlcat(chopt, "G",10);
4531  ndiv = TMath::Abs(ndivy);
4532  if (useHparam) {
4533  umin = TMath::Power(10,Hparam.ymin);
4534  umax = TMath::Power(10,Hparam.ymax);
4535  } else {
4536  umin = TMath::Power(10,aymin);
4537  umax = TMath::Power(10,aymax);
4538  }
4539  } else {
4540  ndiv = TMath::Abs(ndivy);
4541  if (useHparam) {
4542  umin = Hparam.ymin;
4543  umax = Hparam.ymax;
4544  } else {
4545  umin = aymin;
4546  umax = aymax;
4547  }
4548  }
4549 
4550  // Display axis as time
4551  if (fYaxis->GetTimeDisplay()) {
4552  strlcat(chopt,"t",10);
4553  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4554  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam.ymax-Hparam.ymin));
4555  }
4556  }
4557 
4558  // The main Y axis can be on the left or on the right of the pad
4559  Double_t yAxisXPos1, yAxisXPos2;
4560  if (yAxisPos == 1) {
4561  // Main Y axis left
4562  yAxisXPos1 = axmax;
4563  yAxisXPos2 = axmin;
4564  } else {
4565  // Main Y axis right
4566  yAxisXPos1 = axmin;
4567  yAxisXPos2 = axmax;
4568  }
4569 
4570  // Paint the main Y axis (always)
4571  uminsave = umin;
4572  umaxsave = umax;
4573  ndivsave = ndiv;
4574  axis.SetOption(chopt);
4575  if (yAxisPos) {
4576  strlcat(chopt, "+L",10);
4577  gridl = -gridl;
4578  }
4579  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4580  axis.SetLabelSize(0.);
4581  axis.SetTitle("");
4582  }
4583  axis.PaintAxis(yAxisXPos1, aymin,
4584  yAxisXPos1, aymax,
4585  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4586 
4587  // Paint the additional Y axis (if needed)
4588  // Additional checks for pad mode are required on iOS: this "second" axis is
4589  // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4590  if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4591  if (gPad->GetTicky() < 2) {
4592  strlcat(chopt, "U",10);
4593  axis.SetTickSize(-fYaxis->GetTickLength());
4594  } else {
4595  strlcat(chopt, "+L",10);
4596  }
4597  if ((cw=strstr(chopt,"W"))) *cw='z';
4598  axis.SetTitle("");
4599  axis.PaintAxis(yAxisXPos2, aymin,
4600  yAxisXPos2, aymax,
4601  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4602  }
4603  }//End of "if pad is in selection mode etc."
4604 
4605  // Reset the axis if they have been inverted in case of option HBAR
4606  if (xaxis) {
4607  fXaxis = xaxis;
4608  fYaxis = yaxis;
4609  }
4610 }
4611 
4612 ////////////////////////////////////////////////////////////////////////////////
4613 /// [Draw a bar-chart in a normal pad.](#HP10)
4614 
4616 {
4617 
4618  Int_t bar = Hoption.Bar - 10;
4619  Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4620  Double_t offset = fH->GetBarOffset();
4621  Double_t width = fH->GetBarWidth();
4622  TBox box;
4623  Int_t hcolor = fH->GetFillColor();
4624  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4625  Int_t hstyle = fH->GetFillStyle();
4626  box.SetFillColor(hcolor);
4627  box.SetFillStyle(hstyle);
4628  for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4629  y = fH->GetBinContent(bin);
4630  xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4631  xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4632  ymin = gPad->GetUymin();
4633  ymax = gPad->YtoPad(y);
4634  if (ymax < gPad->GetUymin()) continue;
4635  if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4636  if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4637  if (gStyle->GetHistMinimumZero() && ymin < 0)
4638  ymin=TMath::Min(0.,gPad->GetUymax());
4639  w = (xmax-xmin)*width;
4640  xmin += offset*(xmax-xmin);
4641  xmax = xmin + w;
4642  if (bar < 1) {
4643  box.PaintBox(xmin,ymin,xmax,ymax);
4644  } else {
4645  umin = xmin + bar*(xmax-xmin)/10.;
4646  umax = xmax - bar*(xmax-xmin)/10.;
4647  //box.SetFillColor(hcolor+150); //bright
4648  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4649  box.PaintBox(xmin,ymin,umin,ymax);
4650  box.SetFillColor(hcolor);
4651  box.PaintBox(umin,ymin,umax,ymax);
4652  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4653  box.PaintBox(umax,ymin,xmax,ymax);
4654  }
4655  }
4656 }
4657 
4658 ////////////////////////////////////////////////////////////////////////////////
4659 /// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4660 
4662 {
4663 
4664  gPad->SetVertical(kFALSE);
4665 
4666  PaintInitH();
4667 
4668  TAxis *xaxis = fXaxis;
4669  TAxis *yaxis = fYaxis;
4670  if (!strcmp(xaxis->GetName(),"xaxis")) {
4671  fXaxis = yaxis;
4672  fYaxis = xaxis;
4673  }
4674 
4675  PaintFrame();
4676 
4677  Int_t bar = Hoption.Bar - 20;
4678  Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4679  Double_t offset = fH->GetBarOffset();
4680  Double_t width = fH->GetBarWidth();
4681  TBox box;
4682  Int_t hcolor = fH->GetFillColor();
4683  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4684  Int_t hstyle = fH->GetFillStyle();
4685  box.SetFillColor(hcolor);
4686  box.SetFillStyle(hstyle);
4687  for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4688  ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4689  ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4690  xmin = gPad->GetUxmin();
4691  xmax = gPad->XtoPad(fH->GetBinContent(bin));
4692  if (xmax < gPad->GetUxmin()) continue;
4693  if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4694  if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4695  if (gStyle->GetHistMinimumZero() && xmin < 0)
4696  xmin=TMath::Min(0.,gPad->GetUxmax());
4697  w = (ymax-ymin)*width;
4698  ymin += offset*(ymax-ymin);
4699  ymax = ymin + w;
4700  if (bar < 1) {
4701  box.PaintBox(xmin,ymin,xmax,ymax);
4702  } else {
4703  umin = ymin + bar*(ymax-ymin)/10.;
4704  umax = ymax - bar*(ymax-ymin)/10.;
4705  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4706  box.PaintBox(xmin,ymin,xmax,umin);
4707  box.SetFillColor(hcolor);
4708  box.PaintBox(xmin,umin,xmax,umax);
4709  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4710  box.PaintBox(xmin,umax,xmax,ymax);
4711  }
4712  }
4713 
4714  PaintTitle();
4715  // Draw box with histogram statistics and/or fit parameters
4716  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4717  TIter next(fFunctions);
4718  TObject *obj = 0;
4719  while ((obj = next())) {
4720  if (obj->InheritsFrom(TF1::Class())) break;
4721  obj = 0;
4722  }
4723  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4724  }
4725 
4726  PaintAxis(kFALSE);
4727  fXaxis = xaxis;
4728  fYaxis = yaxis;
4729 }
4730 
4731 ////////////////////////////////////////////////////////////////////////////////
4732 /// [Control function to draw a 2D histogram as a box plot](#HP13)
4733 
4735 {
4736 
4737  Style_t fillsav = fH->GetFillStyle();
4738  Style_t colsav = fH->GetFillColor();
4739  if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
4740  if (Hoption.Box == 11) fH->SetFillStyle(1001);
4741  fH->TAttLine::Modify();
4742  fH->TAttFill::Modify();
4743 
4744  Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
4745  Double_t ux1 = gPad->PixeltoX(1);
4746  Double_t ux0 = gPad->PixeltoX(0);
4747  Double_t uy1 = gPad->PixeltoY(1);
4748  Double_t uy0 = gPad->PixeltoY(0);
4749  Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
4750  Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
4751 
4752  Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
4754  TMath::Abs(fH->GetMinimum()));
4755 
4756  // In case of option SAME, zmin and zmax values are taken from the
4757  // first plotted 2D histogram.
4758  if (Hoption.Same) {
4759  TH2 *h2;
4760  TIter next(gPad->GetListOfPrimitives());
4761  while ((h2 = (TH2 *)next())) {
4762  if (!h2->InheritsFrom(TH2::Class())) continue;
4763  zmin = TMath::Max(h2->GetMinimum(), 0.);
4764  zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
4765  TMath::Abs(h2->GetMinimum()));
4766  if (Hoption.Logz) {
4767  if (zmin <= 0) {
4768  zmin = TMath::Log10(zmax*0.001);
4769  } else {
4770  zmin = TMath::Log10(zmin);
4771  }
4772  zmax = TMath::Log10(zmax);
4773  }
4774  break;
4775  }
4776  } else {
4777  if (Hoption.Logz) {
4778  if (zmin > 0) {
4779  zmin = TMath::Log10(zmin);
4780  zmax = TMath::Log10(zmax);
4781  } else {
4782  return;
4783  }
4784  }
4785  }
4786 
4787  Double_t zratio, dz = zmax - zmin;
4788  Bool_t kZminNeg = kFALSE;
4789  if (fH->GetMinimum()<0) kZminNeg = kTRUE;
4790  Bool_t kZNeg = kFALSE;
4791 
4792  // Define the dark and light colors the "button style" boxes.
4793  Color_t color = fH->GetFillColor();
4794  Color_t light=0, dark=0;
4795  if (Hoption.Box == 11) {
4796  light = TColor::GetColorBright(color);
4797  dark = TColor::GetColorDark(color);
4798  }
4799 
4800  // Loop over all the bins and draw the boxes
4801  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4802  yk = fYaxis->GetBinLowEdge(j);
4803  ystep = fYaxis->GetBinWidth(j);
4804  ycent = 0.5*ystep;
4805  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4806  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4807  xk = fXaxis->GetBinLowEdge(i);
4808  xstep = fXaxis->GetBinWidth(i);
4809  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4810  xcent = 0.5*xstep;
4811  z = Hparam.factor*fH->GetBinContent(bin);
4812  kZNeg = kFALSE;
4813 
4814  if (TMath::Abs(z) < zmin) continue; // Can be the case with ...
4815  if (TMath::Abs(z) > zmax) z = zmax; // ... option Same
4816  if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
4817 
4818  if (z < 0) {
4819  if (Hoption.Logz) continue;
4820  z = -z;
4821  kZNeg = kTRUE;
4822  }
4823  if (Hoption.Logz) {
4824  if (z != 0) z = TMath::Log10(z);
4825  else z = zmin;
4826  }
4827 
4828  if (dz == 0) continue;
4829  zratio = TMath::Sqrt((z-zmin)/dz);
4830  if (zratio == 0) continue;
4831 
4832  xup = xcent*zratio + xk + xcent;
4833  xlow = 2*(xk + xcent) - xup;
4834  if (xup-xlow < dxmin) xup = xlow+dxmin;
4835  if (Hoption.Logx) {
4836  if (xup > 0) xup = TMath::Log10(xup);
4837  else continue;
4838  if (xlow > 0) xlow = TMath::Log10(xlow);
4839  else continue;
4840  }
4841 
4842  yup = ycent*zratio + yk + ycent;
4843  ylow = 2*(yk + ycent) - yup;
4844  if (yup-ylow < dymin) yup = ylow+dymin;
4845  if (Hoption.Logy) {
4846  if (yup > 0) yup = TMath::Log10(yup);
4847  else continue;
4848  if (ylow > 0) ylow = TMath::Log10(ylow);
4849  else continue;
4850  }
4851 
4852  xlow = TMath::Max(xlow, gPad->GetUxmin());
4853  ylow = TMath::Max(ylow, gPad->GetUymin());
4854  xup = TMath::Min(xup , gPad->GetUxmax());
4855  yup = TMath::Min(yup , gPad->GetUymax());
4856 
4857  if (xlow >= xup) continue;
4858  if (ylow >= yup) continue;
4859 
4860  if (Hoption.Box == 1) {
4861  fH->SetFillColor(color);
4862  fH->TAttFill::Modify();
4863  gPad->PaintBox(xlow, ylow, xup, yup);
4864  if (kZNeg) {
4865  gPad->PaintLine(xlow, ylow, xup, yup);
4866  gPad->PaintLine(xlow, yup, xup, ylow);
4867  }
4868  } else if (Hoption.Box == 11) {
4869  // Draw the center of the box
4870  fH->SetFillColor(color);
4871  fH->TAttFill::Modify();
4872  gPad->PaintBox(xlow, ylow, xup, yup);
4873 
4874  // Draw top&left part of the box
4875  Double_t x[7], y[7];
4876  Double_t bwidth = 0.1;
4877  x[0] = xlow; y[0] = ylow;
4878  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4879  x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
4880  x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
4881  x[4] = xup; y[4] = yup;
4882  x[5] = xlow; y[5] = yup;
4883  x[6] = xlow; y[6] = ylow;
4884  if (kZNeg) fH->SetFillColor(dark);
4885  else fH->SetFillColor(light);
4886  fH->TAttFill::Modify();
4887  gPad->PaintFillArea(7, x, y);
4888 
4889  // Draw bottom&right part of the box
4890  x[0] = xlow; y[0] = ylow;
4891  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4892  x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
4893  x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
4894  x[4] = xup; y[4] = yup;
4895  x[5] = xup; y[5] = ylow;
4896  x[6] = xlow; y[6] = ylow;
4897  if (kZNeg) fH->SetFillColor(light);
4898  else fH->SetFillColor(dark);
4899  fH->TAttFill::Modify();
4900  gPad->PaintFillArea(7, x, y);
4901  }
4902  }
4903  }
4904 
4905  if (Hoption.Zscale) PaintPalette();
4906  fH->SetFillStyle(fillsav);
4907  fH->SetFillColor(colsav);
4908  fH->TAttFill::Modify();
4909 }
4910 
4911 
4912 
4913 ////////////////////////////////////////////////////////////////////////////////
4914 /// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
4915 
4917 {
4918  TH1D *hproj;
4919  TH2D *h2 = (TH2D*)fH;
4920 
4921  TCandle myCandle;
4922  myCandle.SetOption((TCandle::CandleOption)Hoption.Candle);
4923  myCandle.SetMarkerColor(fH->GetLineColor());
4924  myCandle.SetLineColor(fH->GetLineColor());
4925  myCandle.SetFillColor(fH->GetFillColor());
4926  myCandle.SetFillStyle(fH->GetFillStyle());
4927  myCandle.SetMarkerSize(fH->GetMarkerSize());
4929  myCandle.SetLog(Hoption.Logx,Hoption.Logy);
4930 
4931  Bool_t swapXY = myCandle.IsHorizontal();
4932  const Double_t standardCandleWidth = 0.66;
4933 
4934  if (!swapXY) { // Vertical candle
4935  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4936  Double_t binPosX = fXaxis->GetBinLowEdge(i);
4937  Double_t binWidth = fXaxis->GetBinWidth(i);
4938  hproj = h2->ProjectionY("_px", i, i);
4939  if (hproj->GetEntries() !=0) {
4940  Double_t width = fH->GetBarWidth();
4941  Double_t offset = fH->GetBarOffset()*binWidth;
4942  if (width > 0.999 && width < 1.001) width = standardCandleWidth;
4943  myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
4944  myCandle.SetWidth(width*binWidth);
4945  myCandle.SetHistogram(hproj);
4946  myCandle.Paint();
4947  }
4948  }
4949  } else { // Horizontal candle
4950  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4951  Double_t binPosY = fYaxis->GetBinLowEdge(i);
4952  Double_t binWidth = fYaxis->GetBinWidth(i);
4953  hproj = h2->ProjectionX("_py", i, i);
4954  if (hproj->GetEntries() !=0) {
4955  Double_t width = fH->GetBarWidth();
4956  Double_t offset = fH->GetBarOffset()*binWidth;
4957  if (width > 0.999 && width < 1.001) width = standardCandleWidth;
4958  myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
4959  myCandle.SetWidth(width*binWidth);
4960  myCandle.SetHistogram(hproj);
4961  myCandle.Paint();
4962  }
4963  }
4964  }
4965 }
4966 
4967 
4968 
4969 ////////////////////////////////////////////////////////////////////////////////
4970 /// Returns the rendering regions for an axis to use in the COL2 option
4971 ///
4972 /// The algorithm analyses the size of the axis compared to the size of
4973 /// the rendering region. It figures out the boundaries to use for each color
4974 /// of the rendering region. Only one axis is computed here.
4975 ///
4976 /// This allows for a single computation of the boundaries before iterating
4977 /// through all of the bins.
4978 ///
4979 /// \param pAxis the axis to consider
4980 /// \param nPixels the number of pixels to render axis into
4981 /// \param isLog whether the axis is log scale
4982 
4983 std::vector<THistRenderingRegion>
4985 {
4986  std::vector<THistRenderingRegion> regions;
4987 
4988  enum STRATEGY { Bins, Pixels } strategy;
4989 
4990  Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
4991 
4992  if (nBins >= nPixels) {
4993  // more bins than pixels... we should loop over pixels and sample
4994  strategy = Pixels;
4995  } else {
4996  // fewer bins than pixels... we should loop over bins
4997  strategy = Bins;
4998  }
4999 
5000  if (isLog) {
5001 
5002  Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5003  Int_t binOffset=0;
5004  while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5005  binOffset++;
5006  xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5007  }
5008  if (xMin <= 0) {
5009  // this should cause an error if we have
5010  return regions;
5011  }
5012  Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5013 
5014  if (strategy == Bins) {
5015  // logarithmic plot. we find the pixel for the bin
5016  // pixel = eta * log10(V) - alpha
5017  // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5018  // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5019  // and V is axis value
5020  Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5021  Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5022 
5023  for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5024 
5025  // linear plot. we simply need to find the appropriate bin
5026  // for the
5027  Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5028  Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5029  Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5030  Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5031  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5032  std::make_pair(bin, bin+1)};
5033  regions.push_back(region);
5034  }
5035 
5036  } else {
5037 
5038  // loop over pixels
5039 
5040  Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5041 
5042  for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5043  // linear plot
5044  Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5045  Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5046  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5047  std::make_pair(binLow, binHigh)};
5048  regions.push_back(region);
5049  }
5050  }
5051  } else {
5052  // standard linear plot
5053 
5054  if (strategy == Bins) {
5055  // loop over bins
5056  for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5057 
5058  // linear plot. we simply need to find the appropriate bin
5059  // for the
5060  Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5061  Int_t xPx1 = xPx0 + nPixels/nBins;
5062 
5063  // make sure we don't compute beyond our bounds
5064  if (xPx1>= nPixels) xPx1 = nPixels-1;
5065 
5066  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5067  std::make_pair(bin, bin+1)};
5068  regions.push_back(region);
5069  }
5070  } else {
5071  // loop over pixels
5072  for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5073  // linear plot
5074  Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5075  Int_t binHigh = binLow + nBins/nPixels;
5076  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5077  std::make_pair(binLow, binHigh)};
5078  regions.push_back(region);
5079  }
5080  }
5081  }
5082 
5083  return regions;
5084 }
5085 
5086 ////////////////////////////////////////////////////////////////////////////////
5087 /// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5088 
5090 {
5091 
5092  if (Hoption.System != kCARTESIAN) {
5093  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5094  "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5095  PaintColorLevels(nullptr);
5096  return;
5097  }
5098 
5099  Double_t z;
5100 
5101  // Use existing max or min values. If either is already set
5102  // the appropriate value to use.
5103  Double_t zmin = fH->GetMinimumStored();
5104  Double_t zmax = fH->GetMaximumStored();
5105  Double_t originalZMin = zmin;
5106  Double_t originalZMax = zmax;
5107  if ((zmin == -1111) && (zmax == -1111)) {
5108  fH->GetMinimumAndMaximum(zmin, zmax);
5109  fH->SetMinimum(zmin);
5110  fH->SetMaximum(zmax);
5111  } else if (zmin == -1111) {
5112  zmin = fH->GetMinimum();
5113  fH->SetMinimum(zmin);
5114  } else if (zmax == -1111) {
5115  zmax = fH->GetMaximum();
5116  fH->SetMaximum(zmax);
5117  }
5118 
5119  Double_t dz = zmax - zmin;
5120  if (dz <= 0) { // Histogram filled with a constant value
5121  zmax += 0.1*TMath::Abs(zmax);
5122  zmin -= 0.1*TMath::Abs(zmin);
5123  dz = zmax - zmin;
5124  }
5125 
5126  if (Hoption.Logz) {
5127  if (zmin > 0) {
5128  zmin = TMath::Log10(zmin);
5129  zmax = TMath::Log10(zmax);
5130  dz = zmax - zmin;
5131  } else {
5132  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5133  "Cannot plot logz because bin content is less than 0.");
5134  return;
5135  }
5136  }
5137 
5138  // Initialize the levels on the Z axis
5139  Int_t ndiv = fH->GetContour();
5140  if (ndiv == 0 ) {
5141  ndiv = gStyle->GetNumberContours();
5142  fH->SetContour(ndiv);
5143  }
5144  std::vector<Double_t> colorBounds(ndiv);
5145  std::vector<Double_t> contours(ndiv, 0);
5146  if (fH->TestBit(TH1::kUserContour) == 0) {
5147  fH->SetContour(ndiv);
5148  } else {
5149  fH->GetContour(contours.data());
5150  }
5151 
5152  Double_t step = 1.0/ndiv;
5153  for (Int_t i=0; i<ndiv; ++i) {
5154  colorBounds[i] = step*i;
5155  }
5156 
5157  auto pFrame = gPad->GetFrame();
5158  Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5159  Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5160  Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5161  Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5162  Int_t nXPixels = px1-px0;
5163  Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5164 
5165  std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5166 
5167  auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5168  auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5169  if (xRegions.size() == 0 || yRegions.size() == 0) {
5170  Error("THistPainter::PaintColorLevelFast(Option_t*)",
5171  "Encountered error while computing rendering regions.");
5172  return;
5173  }
5174 
5175  Bool_t minExists = kFALSE;
5176  Bool_t maxExists = kFALSE;
5177  Double_t minValue = 1.;
5178  Double_t maxValue = 0.;
5179  for (auto& yRegion : yRegions) {
5180  for (auto& xRegion : xRegions ) {
5181 
5182  const auto& xBinRange = xRegion.fBinRange;
5183  const auto& yBinRange = yRegion.fBinRange;
5184 
5185  // sample the range
5186  z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5187 
5188  if (Hoption.Logz) {
5189  if (z > 0) z = TMath::Log10(z);
5190  else z = zmin;
5191  }
5192 
5193  // obey the user's max and min values if they were set
5194  if (z > zmax) z = zmax;
5195  if (z < zmin) z = zmin;
5196 
5197  if (fH->TestBit(TH1::kUserContour) == 1) {
5198  // contours are absolute values
5199  auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5200  z = colorBounds[index];
5201  } else {
5202  Int_t index = 0;
5203  if (dz != 0) {
5204  index = 0.001 + ((z - zmin)/dz)*ndiv;
5205  }
5206 
5207  if (index == static_cast<Int_t>(colorBounds.size())) {
5208  index--;
5209  }
5210 
5211  // Do a little bookkeeping to use later for getting libAfterImage to produce
5212  // the correct colors
5213  if (index == 0) {
5214  minExists = kTRUE;
5215  } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5216  maxExists = kTRUE;
5217  }
5218 
5219  z = colorBounds[index];
5220 
5221  if (z < minValue) {
5222  minValue = z;
5223  }
5224  if (z > maxValue) {
5225  maxValue = z;
5226  }
5227  }
5228 
5229  // fill in the actual pixels
5230  const auto& xPixelRange = xRegion.fPixelRange;
5231  const auto& yPixelRange = yRegion.fPixelRange;
5232  for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5233  for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5234  Int_t pixel = yPx*nXPixels + xPx;
5235  buffer[pixel] = z;
5236  }
5237  }
5238  } // end px loop
5239  } // end py loop
5240 
5241  // This is a bit of a hack to ensure that we span the entire color range and
5242  // don't screw up the colors for a sparse histogram. No one will notice that I set a
5243  // single pixel on the edge of the image to a different color. This is even more
5244  // true because the chosen pixels will be covered by the axis.
5245  if (minValue != maxValue) {
5246  if ( !minExists) {
5247  buffer.front() = 0;
5248  }
5249 
5250  if ( !maxExists) {
5251  buffer[buffer.size()-nXPixels] = 0.95;
5252  }
5253  }
5254 
5255  // Generate the TImage
5257  TImage* pImage = TImage::Create();
5259  pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5260  delete pPalette;
5261 
5262  Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5263  pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5264  delete pImage;
5265 
5266  if (Hoption.Zscale) PaintPalette();
5267 
5268  // Reset the maximum and minimum values to their original values
5269  // when this function was called. If we don't do this, an initial
5270  // value of -1111 will be replaced with the true max or min values.
5271  fH->SetMinimum(originalZMin);
5272  fH->SetMaximum(originalZMax);
5273 }
5274 
5275 ////////////////////////////////////////////////////////////////////////////////
5276 /// [Control function to draw a 2D histogram as a color plot.](#HP14)
5277 
5279 {
5280  Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5281 
5282  Double_t zmin = fH->GetMinimum();
5283  Double_t zmax = fH->GetMaximum();
5284 
5285  Double_t dz = zmax - zmin;
5286  if (dz <= 0) { // Histogram filled with a constant value
5287  zmax += 0.1*TMath::Abs(zmax);
5288  zmin -= 0.1*TMath::Abs(zmin);
5289  dz = zmax - zmin;
5290  }
5291 
5292  // In case of option SAME, zmin and zmax values are taken from the
5293  // first plotted 2D histogram.
5294  if (Hoption.Same) {
5295  TH2 *h2;
5296  TIter next(gPad->GetListOfPrimitives());
5297  while ((h2 = (TH2 *)next())) {
5298  if (!h2->InheritsFrom(TH2::Class())) continue;
5299  zmin = h2->GetMinimum();
5300  zmax = h2->GetMaximum();
5301  if (Hoption.Logz) {
5302  if (zmin <= 0) {
5303  zmin = TMath::Log10(zmax*0.001);
5304  } else {
5305  zmin = TMath::Log10(zmin);
5306  }
5307  zmax = TMath::Log10(zmax);
5308  }
5309  dz = zmax - zmin;
5310  break;
5311  }
5312  } else {
5313  if (Hoption.Logz) {
5314  if (zmin > 0) {
5315  zmin = TMath::Log10(zmin);
5316  zmax = TMath::Log10(zmax);
5317  dz = zmax - zmin;
5318  } else {
5319  return;
5320  }
5321  }
5322  }
5323 
5324  Style_t fillsav = fH->GetFillStyle();
5325  Style_t colsav = fH->GetFillColor();
5326  fH->SetFillStyle(1001);
5327  fH->TAttFill::Modify();
5328 
5329  // Initialize the levels on the Z axis
5330  Int_t ncolors = gStyle->GetNumberOfColors();
5331  Int_t ndiv = fH->GetContour();
5332  if (ndiv == 0 ) {
5333  ndiv = gStyle->GetNumberContours();
5334  fH->SetContour(ndiv);
5335  }
5336  Int_t ndivz = TMath::Abs(ndiv);
5337  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5338  Double_t scale = ndivz/dz;
5339 
5340  Int_t color;
5341  TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5342  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5343  yk = fYaxis->GetBinLowEdge(j);
5344  ystep = fYaxis->GetBinWidth(j);
5345  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5346  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5347  xk = fXaxis->GetBinLowEdge(i);
5348  xstep = fXaxis->GetBinWidth(i);
5349  if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5350  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5351  z = fH->GetBinContent(bin);
5352  // if fH is a profile histogram do not draw empty bins
5353  if (prof2d) {
5354  const Double_t binEntries = prof2d->GetBinEntries(bin);
5355  if (binEntries == 0)
5356  continue;
5357  } else {
5358  // don't draw the empty bins for non-profile histograms
5359  // with positive content
5360  if (z == 0) {
5361  if (zmin >= 0 || Hoption.Logz) continue;
5362  if (Hoption.Color == 2) continue;
5363  }
5364  }
5365 
5366  if (Hoption.Logz) {
5367  if (z > 0) z = TMath::Log10(z);
5368  else z = zmin;
5369  }
5370  if (z < zmin && !Hoption.Zero) continue;
5371  xup = xk + xstep;
5372  xlow = xk;
5373  if (Hoption.Logx) {
5374  if (xup > 0) xup = TMath::Log10(xup);
5375  else continue;
5376  if (xlow > 0) xlow = TMath::Log10(xlow);
5377  else continue;
5378  }
5379  yup = yk + ystep;
5380  ylow = yk;
5381  if (Hoption.System != kPOLAR) {
5382  if (Hoption.Logy) {
5383  if (yup > 0) yup = TMath::Log10(yup);
5384  else continue;
5385  if (ylow > 0) ylow = TMath::Log10(ylow);
5386  else continue;
5387  }
5388  if (xup < gPad->GetUxmin()) continue;
5389  if (yup < gPad->GetUymin()) continue;
5390  if (xlow > gPad->GetUxmax()) continue;
5391  if (ylow > gPad->GetUymax()) continue;
5392  if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5393  if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5394  if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5395  if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5396  }
5397 
5398  if (fH->TestBit(TH1::kUserContour)) {
5399  zc = fH->GetContourLevelPad(0);
5400  if (z < zc) continue;
5401  color = -1;
5402  for (Int_t k=0; k<ndiv; k++) {
5403  zc = fH->GetContourLevelPad(k);
5404  if (z < zc) {
5405  continue;
5406  } else {
5407  color++;
5408  }
5409  }
5410  } else {
5411  color = Int_t(0.01+(z-zmin)*scale);
5412  }
5413 
5414  Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5415  if (theColor > ncolors-1) theColor = ncolors-1;
5416  fH->SetFillColor(gStyle->GetColorPalette(theColor));
5417  fH->TAttFill::Modify();
5418  if (Hoption.System != kPOLAR) {
5419  gPad->PaintBox(xlow, ylow, xup, yup);
5420  } else {
5421  TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5422  crown.SetFillColor(gStyle->GetColorPalette(theColor));
5423  crown.Paint();
5424  }
5425  }
5426  }
5427 
5428  if (Hoption.Zscale) PaintPalette();
5429 
5430  fH->SetFillStyle(fillsav);
5431  fH->SetFillColor(colsav);
5432  fH->TAttFill::Modify();
5433 
5434 }
5435 
5436 ////////////////////////////////////////////////////////////////////////////////
5437 /// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5438 
5440 {
5441 
5442  Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5443  Int_t itars, mode, ir[4];
5444  Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5445 
5446  if (Hoption.Contour == 14) {
5447  Hoption.Surf = 12;
5448  Hoption.Axis = 1;
5449  thesave = gPad->GetTheta();
5450  phisave = gPad->GetPhi();
5451  gPad->SetPhi(0.);
5452  gPad->SetTheta(90.);
5453  PaintSurface(option);
5454  gPad->SetPhi(phisave);
5455  gPad->SetTheta(thesave);
5456  TView *view = gPad->GetView();
5457  if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5458  PaintAxis();
5459  return;
5460  }
5461 
5462  if (Hoption.Same) {
5463  // If the contour is painted on a 3d plot, the contour lines are
5464  // paint in 3d too.
5465  TObject *obj;
5466  TIter next(gPad->GetListOfPrimitives());
5467  while ((obj=next())) {
5468  if (strstr(obj->GetDrawOption(),"surf") ||
5469  strstr(obj->GetDrawOption(),"lego") ||
5470  strstr(obj->GetDrawOption(),"tri")) {
5471  Hoption.Surf = 16;
5472  PaintSurface(option);
5473  return;
5474  }
5475  }
5476  }
5477 
5478  if (Hoption.Contour == 15) {
5479  TGraphDelaunay2D *dt = nullptr;
5480  TGraphDelaunay *dtOld = nullptr;
5481  TList *hl = fH->GetListOfFunctions();
5482  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5483  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5484  if (!dt && !dtOld) return;
5485  if (!fGraph2DPainter) {
5486  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5487  else fGraph2DPainter = new TGraph2DPainter(dtOld);
5488  }
5489  fGraph2DPainter->Paint(option);
5490  return;
5491  }
5492 
5493  gPad->SetBit(TGraph::kClipFrame);
5494 
5495  Double_t *levels = new Double_t[2*kMAXCONTOUR];
5496  Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5497  Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5498  Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5499 
5500  Int_t npmax = 0;
5501  for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5502 
5503  ncontour = fH->GetContour();
5504  if (ncontour == 0) {
5505  ncontour = gStyle->GetNumberContours();
5506  fH->SetContour(ncontour);
5507  }
5508  if (ncontour > kMAXCONTOUR) {
5509  Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5510  kMAXCONTOUR, ncontour);
5511  ncontour = kMAXCONTOUR-1;
5512  }
5513  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5514 
5515  for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5516  Int_t linesav = fH->GetLineStyle();
5517  Int_t colorsav = fH->GetLineColor();
5518  Int_t fillsav = fH->GetFillColor();
5519  if (Hoption.Contour == 13) {
5520  fH->TAttLine::Modify();
5521  }
5522 
5523  TPolyLine **polys = 0;
5524  TPolyLine *poly=0;
5525  TObjArray *contours = 0;
5526  TList *list = 0;
5527  TGraph *graph = 0;
5528  Int_t *np = 0;
5529  if (Hoption.Contour == 1) {
5530  np = new Int_t[ncontour];
5531  for (i=0;i<ncontour;i++) np[i] = 0;
5532  polys = new TPolyLine*[ncontour];
5533  for (i=0;i<ncontour;i++) {
5534  polys[i] = new TPolyLine(100);
5535  }
5536  if (Hoption.List == 1) {
5537  contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5538  if (contours) {
5539  gROOT->GetListOfSpecials()->Remove(contours);
5540  count = contours->GetSize();
5541  for (i=0;i<count;i++) {
5542  list = (TList*)contours->At(i);
5543  if (list) list->Delete();
5544  }
5545  }
5546  contours = new TObjArray(ncontour);
5547  contours->SetName("contours");
5548  gROOT->GetListOfSpecials()->Add(contours);
5549  for (i=0;i<ncontour;i++) {
5550  list = new TList();
5551  contours->Add(list);
5552  }
5553  }
5554  }
5555  Int_t theColor;
5556  Int_t ncolors = gStyle->GetNumberOfColors();
5557  Int_t ndivz = TMath::Abs(ncontour);
5558 
5559  Int_t k,ipoly;
5560  for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5561  y[0] = fYaxis->GetBinCenter(j);
5562  y[1] = y[0];
5563  y[2] = fYaxis->GetBinCenter(j+1);
5564  y[3] = y[2];
5565  for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5566  zc[0] = fH->GetBinContent(i, j);
5567  zc[1] = fH->GetBinContent(i+1, j);
5568  zc[2] = fH->GetBinContent(i+1, j+1);
5569  zc[3] = fH->GetBinContent(i, j+1);
5570  if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5571  if (Hoption.Logz) {
5572  if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5573  else zc[0] = Hparam.zmin;
5574  if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5575  else zc[1] = Hparam.zmin;
5576  if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5577  else zc[2] = Hparam.zmin;
5578  if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5579  else zc[3] = Hparam.zmin;
5580  }
5581  for (k=0;k<4;k++) {
5582  ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5583  }
5584  if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5585  x[0] = fXaxis->GetBinCenter(i);
5586  x[3] = x[0];
5587  x[1] = fXaxis->GetBinCenter(i+1);
5588  x[2] = x[1];
5589  if (zc[0] <= zc[1]) n = 0; else n = 1;
5590  if (zc[2] <= zc[3]) m = 2; else m = 3;
5591  if (zc[n] > zc[m]) n = m;
5592  n++;
5593  lj=1;
5594  for (ix=1;ix<=4;ix++) {
5595  m = n%4 + 1;
5596  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5597  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5598  lj += 2*ljfill;
5599  n = m;
5600  }
5601 
5602  if (zc[0] <= zc[1]) n = 0; else n = 1;
5603  if (zc[2] <= zc[3]) m = 2; else m = 3;
5604  if (zc[n] > zc[m]) n = m;
5605  n++;
5606  lj=2;
5607  for (ix=1;ix<=4;ix++) {
5608  if (n == 1) m = 4;
5609  else m = n-1;
5610  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5611  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5612  lj += 2*ljfill;
5613  n = m;
5614  }
5615 
5616  // Re-order endpoints
5617 
5618  count = 0;
5619  for (ix=1; ix<=lj-5; ix +=2) {
5620  //count = 0;
5621  while (itarr[ix-1] != itarr[ix]) {
5622  xsave = xarr[ix];
5623  ysave = yarr[ix];
5624  itars = itarr[ix];
5625  for (jx=ix; jx<=lj-5; jx +=2) {
5626  xarr[jx] = xarr[jx+2];
5627  yarr[jx] = yarr[jx+2];
5628  itarr[jx] = itarr[jx+2];
5629  }
5630  xarr[lj-3] = xsave;
5631  yarr[lj-3] = ysave;
5632  itarr[lj-3] = itars;
5633  if (count > 100) break;
5634  count++;
5635  }
5636  }
5637 
5638  if (count > 100) continue;
5639  for (ix=1; ix<=lj-2; ix +=2) {
5640  theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5641  icol = gStyle->GetColorPalette(theColor);
5642  if (Hoption.Contour == 11) {
5643  fH->SetLineColor(icol);
5644  }
5645  if (Hoption.Contour == 12) {
5646  mode = icol%5;
5647  if (mode == 0) mode = 5;
5648  fH->SetLineStyle(mode);
5649  }
5650  if (Hoption.Contour != 1) {
5651  fH->TAttLine::Modify();
5652  gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5653  continue;
5654  }
5655 
5656  ipoly = itarr[ix-1];
5657  if (ipoly >=0 && ipoly <ncontour) {
5658  poly = polys[ipoly];
5659  poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5660  poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5661  np[ipoly] += 2;
5662  if (npmax < np[ipoly]) npmax = np[ipoly];
5663  }
5664  }
5665  } // end of if (ir[0]
5666  } //end of for (i
5667  } //end of for (j
5668 
5669  Double_t xmin,ymin;
5670  Double_t *xp, *yp;
5671  Int_t nadd,iminus,iplus;
5672  Double_t *xx, *yy;
5673  Int_t istart;
5674  Int_t first = ncontour;
5675  Int_t *polysort = 0;
5676  Int_t contListNb;
5677  if (Hoption.Contour != 1) goto theEND;
5678 
5679  //The 2 points line generated above are now sorted/merged to generate
5680  //a list of consecutive points.
5681  // If the option "List" has been specified, the list of points is saved
5682  // in the form of TGraph objects in the ROOT list of special objects.
5683  xmin = gPad->GetUxmin();
5684  ymin = gPad->GetUymin();
5685  xp = new Double_t[2*npmax];
5686  yp = new Double_t[2*npmax];
5687  polysort = new Int_t[ncontour];
5688  //find first positive contour
5689  for (ipoly=0;ipoly<ncontour;ipoly++) {
5690  if (levels[ipoly] >= 0) {first = ipoly; break;}
5691  }
5692  //store negative contours from 0 to minimum, then all positive contours
5693  k = 0;
5694  for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
5695  for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
5696  // we can now draw sorted contours
5697  contListNb = 0;
5698  fH->SetFillStyle(1001);
5699  for (k=0;k<ncontour;k++) {
5700  ipoly = polysort[k];
5701  if (np[ipoly] == 0) continue;
5702  if (Hoption.List) list = (TList*)contours->At(contListNb);
5703  contListNb++;
5704  poly = polys[ipoly];
5705  xx = poly->GetX();
5706  yy = poly->GetY();
5707  istart = 0;
5708  while (1) {
5709  iminus = npmax;
5710  iplus = iminus+1;
5711  xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
5712  xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
5713  xx[istart] = xmin; yy[istart] = ymin;
5714  xx[istart+1] = xmin; yy[istart+1] = ymin;
5715  while (1) {
5716  nadd = 0;
5717  for (i=2;i<np[ipoly];i+=2) {
5718  if (xx[i] == xp[iplus] && yy[i] == yp[iplus]) {
5719  iplus++;
5720  xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
5721  xx[i] = xmin; yy[i] = ymin;
5722  xx[i+1] = xmin; yy[i+1] = ymin;
5723  nadd++;
5724  }
5725  if (xx[i+1] == xp[iminus] && yy[i+1] == yp[iminus]) {
5726  iminus--;
5727  xp[iminus] = xx[i]; yp[iminus] = yy[i];
5728  xx[i] = xmin; yy[i] = ymin;
5729  xx[i+1] = xmin; yy[i+1] = ymin;
5730  nadd++;
5731  }
5732  }
5733  if (nadd == 0) break;
5734  }
5735  theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
5736  icol = gStyle->GetColorPalette(theColor);
5737  if (ndivz > 1) fH->SetFillColor(icol);
5738  fH->TAttFill::Modify();
5739  gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5740  if (Hoption.List) {
5741  graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5742  graph->SetFillColor(icol);
5743  graph->SetLineWidth(fH->GetLineWidth());
5744  list->Add(graph);
5745  }
5746  //check if more points are left
5747  istart = 0;
5748  for (i=2;i<np[ipoly];i+=2) {
5749  if (xx[i] != xmin && yy[i] != ymin) {
5750  istart = i;
5751  break;
5752  }
5753  }
5754  if (istart == 0) break;
5755  }
5756  }
5757 
5758  for (i=0;i<ncontour;i++) delete polys[i];
5759  delete [] polys;
5760  delete [] xp;
5761  delete [] yp;
5762  delete [] polysort;
5763 
5764 theEND:
5765  gPad->ResetBit(TGraph::kClipFrame);
5766  if (Hoption.Zscale) PaintPalette();
5767  fH->SetLineStyle(linesav);
5768  fH->SetLineColor(colorsav);
5769  fH->SetFillColor(fillsav);
5770  if (np) delete [] np;
5771  delete [] xarr;
5772  delete [] yarr;
5773  delete [] itarr;
5774  delete [] levels;
5775 }
5776 
5777 ////////////////////////////////////////////////////////////////////////////////
5778 /// Fill the matrix `xarr` and `yarr` for Contour Plot.
5779 
5781  Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
5782  Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
5783 {
5784 
5785  Bool_t vert;
5786  Double_t tlen, tdif, elev, diff, pdif, xlen;
5787  Int_t n, i, icount;
5788 
5789  if (x1 == x2) {
5790  vert = kTRUE;
5791  tlen = y2 - y1;
5792  } else {
5793  vert = kFALSE;
5794  tlen = x2 - x1;
5795  }
5796 
5797  n = icont1 +1;
5798  tdif = elev2 - elev1;
5799  i = 0;
5800  icount = 0;
5801  while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
5802  //elev = fH->GetContourLevel(n);
5803  elev = levels[n];
5804  diff = elev - elev1;
5805  pdif = diff/tdif;
5806  xlen = tlen*pdif;
5807  if (vert) {
5808  if (Hoption.Logx)
5809  xarr[i] = TMath::Log10(x1);
5810  else
5811  xarr[i] = x1;
5812  if (Hoption.Logy)
5813  yarr[i] = TMath::Log10(y1 + xlen);
5814  else
5815  yarr[i] = y1 + xlen;
5816  } else {
5817  if (Hoption.Logx)
5818  xarr[i] = TMath::Log10(x1 + xlen);
5819  else
5820  xarr[i] = x1 + xlen;
5821  if (Hoption.Logy)
5822  yarr[i] = TMath::Log10(y1);
5823  else
5824  yarr[i] = y1;
5825  }
5826  itarr[i] = n;
5827  icount++;
5828  i +=2;
5829  n++;
5830  }
5831  return icount;
5832 }
5833 
5834 ////////////////////////////////////////////////////////////////////////////////
5835 /// [Draw 1D histograms error bars.](#HP09)
5836 
5838 {
5839 
5840  // On iOS, we do not highlight histogram, if it's not picked at the moment
5841  // (but part of histogram (axis or pavestat) was picked, that's why this code
5842  // is called at all. This conditional statement never executes on non-iOS platform.
5843  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
5844 
5845  const Int_t kBASEMARKER=8;
5846  Double_t xp, yp, ex1, ex2, ey1, ey2;
5847  Double_t delta;
5848  Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
5849  Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
5850  Double_t xmin, xmax, ymin, ymax;
5851  Double_t logxmin = 0;
5852  Double_t logymin = 0;
5853  Int_t i, k, npoints, first, last, fixbin;
5854  Int_t if1 = 0;
5855  Int_t if2 = 0;
5856  Int_t drawmarker, errormarker;
5857  Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
5858 
5859  Double_t *xline = 0;
5860  Double_t *yline = 0;
5861  option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
5862  if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
5863  if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
5864  if (Hoption.Error == 10) option0 = 1;
5865  if (Hoption.Error == 11) option1 = 1;
5866  if (Hoption.Error == 12) option2 = 1;
5867  if (Hoption.Error == 13) option3 = 1;
5868  if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
5869  if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
5870  if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
5871  if (option2+option3 == 0) optionE = 1;
5872  if (Hoption.Error == 0) optionE = 0;
5873  if (fXaxis->GetXbins()->fN) fixbin = 0;
5874  else fixbin = 1;
5875 
5876  errormarker = fH->GetMarkerStyle();
5877  if (optionEX0) {
5878  xerror = 0;
5879  } else {
5880  xerror = gStyle->GetErrorX();
5881  }
5882  symbolsize = fH->GetMarkerSize();
5883  if (errormarker == 1) symbolsize = 0.01;
5884  sbase = symbolsize*kBASEMARKER;
5885  // set the graphics attributes
5886 
5887  fH->TAttLine::Modify();
5888  fH->TAttFill::Modify();
5889  fH->TAttMarker::Modify();
5890 
5891  // set the first and last bin
5892 
5893  Double_t factor = Hparam.factor;
5894  first = Hparam.xfirst;
5895  last = Hparam.xlast;
5896  npoints = last - first +1;
5897  xmin = gPad->GetUxmin();
5898  xmax = gPad->GetUxmax();
5899  ymin = gPad->GetUymin();
5900  ymax = gPad->GetUymax();
5901 
5902 
5903  if (option3) {
5904  xline = new Double_t[2*npoints];
5905  yline = new Double_t[2*npoints];
5906  if (!xline || !yline) {
5907  Error("PaintErrors", "too many points, out of memory");
5908  return;
5909  }
5910  if1 = 1;
5911  if2 = 2*npoints;
5912  }
5913 
5914  // compute the offset of the error bars due to the symbol size
5915  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
5916  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
5917 
5918  // compute size of the lines at the end of the error bars
5919  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
5920  bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
5921  bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
5922 
5923 
5924  if (fixbin) {
5925  if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
5926  else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
5927  } else {
5928  delta = fH->GetBinWidth(first);
5929  xp = fH->GetBinLowEdge(first) + 0.5*delta;
5930  }
5931 
5932  // if errormarker = 0 or symbolsize = 0. no symbol is drawn
5933  if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
5934  if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
5935 
5936  // ---------------------- Loop over the points---------------------
5937  for (k=first; k<=last; k++) {
5938 
5939  // get the data
5940  // xp = X position of the current point
5941  // yp = Y position of the current point
5942  // ex1 = Low X error
5943  // ex2 = Up X error
5944  // ey1 = Low Y error
5945  // ey2 = Up Y error
5946  // (xi,yi) = Error bars coordinates
5947 
5948  if (Hoption.Logx) {
5949  if (xp <= 0) goto L30;
5950  if (xp < logxmin) goto L30;
5951  if (xp > TMath::Power(10,xmax)) break;
5952  } else {
5953  if (xp < xmin) goto L30;
5954  if (xp > xmax) break;
5955  }
5956  yp = factor*fH->GetBinContent(k);
5957  if (optionI0 && yp==0) goto L30;
5958  if (fixbin) {
5959  ex1 = xerror*Hparam.xbinsize;
5960  } else {
5961  delta = fH->GetBinWidth(k);
5962  ex1 = xerror*delta;
5963  }
5964  if (fH->GetBinErrorOption() == TH1::kNormal) {
5965  ey1 = factor*fH->GetBinError(k);
5966  ey2 = ey1;
5967  } else {
5968  ey1 = factor*fH->GetBinErrorLow(k);
5969  ey2 = factor*fH->GetBinErrorUp(k);
5970  }
5971  ex2 = ex1;
5972 
5973  xi4 = xp;
5974  xi3 = xp;
5975  xi2 = xp + ex2;
5976  xi1 = xp - ex1;
5977 
5978  yi1 = yp;
5979  yi2 = yp;
5980  yi3 = yp - ey1;
5981  yi4 = yp + ey2;
5982 
5983  // take the LOG if necessary
5984  if (Hoption.Logx) {
5985  xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
5986  xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
5987  xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
5988  xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
5989  }
5990  if (Hoption.Logy) {
5991  yi1 = TMath::Log10(TMath::Max(yi1,logymin));
5992  yi2 = TMath::Log10(TMath::Max(yi2,logymin));
5993  yi3 = TMath::Log10(TMath::Max(yi3,logymin));
5994  yi4 = TMath::Log10(TMath::Max(yi4,logymin));
5995  }
5996 
5997  // test if error bars are not outside the limits
5998  // otherwise they are truncated
5999 
6000  xi1 = TMath::Max(xi1,xmin);
6001  xi2 = TMath::Min(xi2,xmax);
6002  yi3 = TMath::Max(yi3,ymin);
6003  yi4 = TMath::Min(yi4,ymax);
6004 
6005  // test if the marker is on the frame limits. If "Yes", the
6006  // marker will not be drawn and the error bars will be readjusted.
6007 
6008  drawmarker = kTRUE;
6009  if (!option0 && !option3) {
6010  if (Hoption.Logy && yp < logymin) goto L30;
6011  if (yi1 < ymin || yi1 > ymax) goto L30;
6012  if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6013  }
6014  if (!symbolsize || !errormarker) drawmarker = kFALSE;
6015 
6016  // draw the error rectangles
6017  if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6018 
6019  // keep points for fill area drawing
6020  if (option3) {
6021  xline[if1-1] = xi3;
6022  xline[if2-1] = xi3;
6023  yline[if1-1] = yi4;
6024  yline[if2-1] = yi3;
6025  if1++;
6026  if2--;
6027  }
6028 
6029  // draw the error bars
6030  if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6031  if (optionE && drawmarker) {
6032  if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6033  if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6034  // don't duplicate the horizontal line
6035  if (Hoption.Hist != 2) {
6036  if (yi1<ymax && yi1>ymin) {
6037  if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6038  if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6039  }
6040  }
6041  }
6042  if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6043  if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6044  if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6045  // don't duplicate the horizontal line
6046  if (Hoption.Hist != 2) {
6047  if (yi1<ymax && yi1>ymin) {
6048  if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6049  if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6050  }
6051  }
6052  }
6053 
6054  // draw line at the end of the error bars
6055 
6056  if (option1 && drawmarker) {
6057  if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6058  if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6059  if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6060  if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6061  }
6062 
6063  // draw the marker
6064 
6065  if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6066 
6067 L30:
6068  if (fixbin) xp += Hparam.xbinsize;
6069  else {
6070  if (k < last) {
6071  delta = fH->GetBinWidth(k+1);
6072  xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6073  }
6074  }
6075  } //end of for loop
6076 
6077  // draw the filled area
6078 
6079  if (option3) {
6080  TGraph graph;
6081  graph.SetLineStyle(fH->GetLineStyle());
6082  graph.SetLineColor(fH->GetLineColor());
6083  graph.SetLineWidth(fH->GetLineWidth());
6084  graph.SetFillStyle(fH->GetFillStyle());
6085  graph.SetFillColor(fH->GetFillColor());
6086  Int_t logx = gPad->GetLogx();
6087  Int_t logy = gPad->GetLogy();
6088  gPad->SetLogx(0);
6089  gPad->SetLogy(0);
6090 
6091  // In some cases the number of points in the fill area is smaller than
6092  // 2*npoints. In such cases the array xline and yline must be arranged
6093  // before being plotted. The next loop does that.
6094  if (if2 > npoints) {
6095  for (i=1; i<if1; i++) {
6096  xline[if1-2+i] = xline[if2-1+i];
6097  yline[if1-2+i] = yline[if2-1+i];
6098  }
6099  npoints = if1-1;
6100  }
6101  if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6102  else graph.PaintGraph(2*npoints,xline,yline,"F");
6103  gPad->SetLogx(logx);
6104  gPad->SetLogy(logy);
6105  delete [] xline;
6106  delete [] yline;
6107  }
6108 }
6109 
6110 ////////////////////////////////////////////////////////////////////////////////
6111 /// Draw 2D histograms errors.
6112 
6114 {
6115 
6116  fH->TAttMarker::Modify();
6117  fH->TAttLine::Modify();
6118 
6119  // Define the 3D view
6120  fXbuf[0] = Hparam.xmin;
6121  fYbuf[0] = Hparam.xmax;
6122  fXbuf[1] = Hparam.ymin;
6123  fYbuf[1] = Hparam.ymax;
6124  fXbuf[2] = Hparam.zmin;
6125  fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6127  TView *view = gPad->GetView();
6128  if (!view) {
6129  Error("Paint2DErrors", "no TView in current pad");
6130  return;
6131  }
6132  Double_t thedeg = 90 - gPad->GetTheta();
6133  Double_t phideg = -90 - gPad->GetPhi();
6134  Double_t psideg = view->GetPsi();
6135  Int_t irep;
6136  view->SetView(phideg, thedeg, psideg, irep);
6137 
6138  // Set color/style for back box
6139  fLego->SetFillStyle(gPad->GetFrameFillStyle());
6140  fLego->SetFillColor(gPad->GetFrameFillColor());
6141  fLego->TAttFill::Modify();
6142  Int_t backcolor = gPad->GetFrameFillColor();
6143  if (Hoption.System != kCARTESIAN) backcolor = 0;
6144  view->PadRange(backcolor);
6147  fLego->TAttFill::Modify();
6148 
6149  // Paint the Back Box if needed
6150  if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6151  fLego->InitMoveScreen(-1.1,1.1);
6154  fLego->BackBox(90);
6155  }
6156 
6157  // Paint the Errors
6158  Double_t x, ex, x1, x2;
6159  Double_t y, ey, y1, y2;
6160  Double_t z, ez1, ez2, z1, z2;
6161  Double_t temp1[3],temp2[3];
6162  Double_t xyerror;
6163  if (Hoption.Error == 110) {
6164  xyerror = 0;
6165  } else {
6166  xyerror = gStyle->GetErrorX();
6167  }
6168 
6169  Double_t xk, xstep, yk, ystep;
6170  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6171  y = fYaxis->GetBinCenter(j);
6172  ey = fYaxis->GetBinWidth(j)*xyerror;
6173  y1 = y-ey;
6174  y2 = y+ey;
6175  if (Hoption.Logy) {
6176  if (y > 0) y = TMath::Log10(y);
6177  else continue;
6178  if (y1 > 0) y1 = TMath::Log10(y1);
6179  else y1 = Hparam.ymin;
6180  if (y2 > 0) y2 = TMath::Log10(y2);
6181  else y2 = Hparam.ymin;
6182  }
6183  yk = fYaxis->GetBinLowEdge(j);
6184  ystep = fYaxis->GetBinWidth(j);
6185  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6186  xk = fXaxis->GetBinLowEdge(i);
6187  xstep = fXaxis->GetBinWidth(i);
6188  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6189  Int_t bin = fH->GetBin(i,j);
6190  x = fXaxis->GetBinCenter(i);
6191  ex = fXaxis->GetBinWidth(i)*xyerror;
6192  x1 = x-ex;
6193  x2 = x+ex;
6194  if (Hoption.Logx) {
6195  if (x > 0) x = TMath::Log10(x);
6196  else continue;
6197  if (x1 > 0) x1 = TMath::Log10(x1);
6198  else x1 = Hparam.xmin;
6199  if (x2 > 0) x2 = TMath::Log10(x2);
6200  else x2 = Hparam.xmin;
6201  }
6202  z = fH->GetBinContent(bin);
6203  if (fH->GetBinErrorOption() == TH1::kNormal) {
6204  ez1 = fH->GetBinError(bin);
6205  ez2 = ez1;
6206  }
6207  else {
6208  ez1 = fH->GetBinErrorLow(bin);
6209  ez2 = fH->GetBinErrorUp(bin);
6210  }
6211  z1 = z - ez1;
6212  z2 = z + ez2;
6213  if (Hoption.Logz) {
6214  if (z > 0) z = TMath::Log10(z);
6215  else z = Hparam.zmin;
6216  if (z1 > 0) z1 = TMath::Log10(z1);
6217  else z1 = Hparam.zmin;
6218  if (z2 > 0) z2 = TMath::Log10(z2);
6219  else z2 = Hparam.zmin;
6220 
6221  }
6222  if (z <= Hparam.zmin) continue;
6223  if (z > Hparam.zmax) z = Hparam.zmax;
6224 
6225  temp1[0] = x1;
6226  temp1[1] = y;
6227  temp1[2] = z;
6228  temp2[0] = x2;
6229  temp2[1] = y;
6230  temp2[2] = z;
6231  gPad->PaintLine3D(temp1, temp2);
6232  temp1[0] = x;
6233  temp1[1] = y1;
6234  temp1[2] = z;
6235  temp2[0] = x;
6236  temp2[1] = y2;
6237  temp2[2] = z;
6238  gPad->PaintLine3D(temp1, temp2);
6239  temp1[0] = x;
6240  temp1[1] = y;
6241  temp1[2] = z1;
6242  temp2[0] = x;
6243  temp2[1] = y;
6244  temp2[2] = z2;
6245  gPad->PaintLine3D(temp1, temp2);
6246  temp1[0] = x;
6247  temp1[1] = y;
6248  temp1[2] = z;
6249  view->WCtoNDC(temp1, &temp2[0]);
6250  gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6251  }
6252  }
6253 
6254  // Paint the Front Box if needed
6255  if (Hoption.FrontBox) {
6256  fLego->InitMoveScreen(-1.1,1.1);
6258  fLego->FrontBox(90);
6259  }
6260 
6261  // Paint the Axis if needed
6262  if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6263  TGaxis *axis = new TGaxis();
6264  PaintLegoAxis(axis, 90);
6265  delete axis;
6266  }
6267 
6268  delete fLego; fLego = 0;
6269 }
6270 
6271 ////////////////////////////////////////////////////////////////////////////////
6272 /// Calculate range and clear pad (canvas).
6273 
6275 {
6276 
6277  if (Hoption.Same) return;
6278 
6279  RecalculateRange();
6280 
6281  if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6282  Hoption.Contour == 14 || Hoption.Error >= 100) {
6283  TObject *frame = gPad->FindObject("TFrame");
6284  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6285  return;
6286  }
6287 
6288  //The next statement is always executed on non-iOS platform,
6289  //on iOS depends on pad mode.
6290  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6291  gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6292 }
6293 
6294 ////////////////////////////////////////////////////////////////////////////////
6295 /// [Paint functions associated to an histogram.](#HP28")
6296 
6298 {
6299 
6301  TObject *obj;
6302 
6303  while (lnk) {
6304  obj = lnk->GetObject();
6305  TVirtualPad *padsave = gPad;
6306  if (obj->InheritsFrom(TF2::Class())) {
6307  if (obj->TestBit(TF2::kNotDraw) == 0) {
6308  if (Hoption.Lego || Hoption.Surf) {
6309  TF2 *f2 = (TF2*)obj;
6310  f2->SetMinimum(fH->GetMinimum());
6311  f2->SetMaximum(fH->GetMaximum());
6312  f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6313  f2->Paint("surf same");
6314  } else {
6315  obj->Paint("cont3 same");
6316  }
6317  }
6318  } else if (obj->InheritsFrom(TF1::Class())) {
6319  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6320  } else {
6321  //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6322  gPad->PushSelectableObject(obj);
6323 
6324  //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6325  //and picked object.
6326  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6327  obj->Paint(lnk->GetOption());
6328  }
6329  lnk = (TObjOptLink*)lnk->Next();
6330  padsave->cd();
6331  }
6332 }
6333 
6334 ////////////////////////////////////////////////////////////////////////////////
6335 /// [Control routine to draw 1D histograms](#HP01b)
6336 
6338 {
6339 
6340  //On iOS: do not highlight hist, if part of it was selected.
6341  //Never executes on non-iOS platform.
6342  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6343  return;
6344 
6345  static char chopth[17];
6346 
6347  Int_t htype, oldhtype;
6348  Int_t i, j, first, last, nbins, fixbin;
6350  yb = 0;
6351 
6352  strlcpy(chopth, " ",17);
6353 
6354  Double_t ymin = Hparam.ymin;
6355  Double_t ymax = Hparam.ymax;
6356  Double_t baroffset = fH->GetBarOffset();
6357  Double_t barwidth = fH->GetBarWidth();
6358  Double_t baroffsetsave = gStyle->GetBarOffset();
6359  Double_t barwidthsave = gStyle->GetBarWidth();
6360  gStyle->SetBarOffset(baroffset);
6361  gStyle->SetBarWidth(barwidth);
6362 
6363  // Create "LIFE" structure to keep current histogram status
6364 
6365  first = Hparam.xfirst;
6366  last = Hparam.xlast;
6367  nbins = last - first + 1;
6368 
6369  Double_t *keepx = 0;
6370  Double_t *keepy = 0;
6371  if (fXaxis->GetXbins()->fN) fixbin = 0;
6372  else fixbin = 1;
6373  if (fixbin) keepx = new Double_t[2];
6374  else keepx = new Double_t[nbins+1];
6375  keepy = new Double_t[nbins];
6376  Double_t logymin = 0;
6377  if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6378 
6379  // Loop on histogram bins
6380 
6381  for (j=first; j<=last;j++) {
6382  c1 = Hparam.factor*fH->GetBinContent(j);
6383  if (TMath::Abs(ymax-ymin) > 0) {
6384  if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6385  else yb = c1;
6386  }
6387  if (!Hoption.Line) {
6388  yb = TMath::Max(yb, ymin);
6389  yb = TMath::Min(yb, ymax);
6390  }
6391  keepy[j-first] = yb;
6392  }
6393 
6394  // Draw histogram according to value of FillStyle and FillColor
6395 
6396  if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6397  else {
6398  for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6399  keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6400  }
6401 
6402  // Prepare Fill area (systematic with option "Bar").
6403 
6404  oldhtype = fH->GetFillStyle();
6405  htype = oldhtype;
6406  if (Hoption.Bar) {
6407  if (htype == 0 || htype == 1000) htype = 1001;
6408  }
6409 
6410  Width_t lw = (Width_t)fH->GetLineWidth();
6411 
6412  // Code option for GrapHist
6413 
6414  if (Hoption.Line) chopth[0] = 'L';
6415  if (Hoption.Star) chopth[1] = '*';
6416  if (Hoption.Mark) chopth[2] = 'P';
6417  if (Hoption.Mark == 10) chopth[3] = '0';
6418  if (Hoption.Line || Hoption.Curve || Hoption.Hist || Hoption.Bar) {
6419  if (Hoption.Curve) chopth[3] = 'C';
6420  if (Hoption.Hist > 0) chopth[4] = 'H';
6421  else if (Hoption.Bar) chopth[5] = 'B';
6422  if (fH->GetFillColor() && htype) {
6423  if (Hoption.Logy) {
6424  chopth[6] = '1';
6425  }
6426  if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6427  chopth[7] = 'F';
6428  }
6429  }
6430  }
6431  if (!fixbin && strlen(chopth)) {
6432  chopth[8] = 'N';
6433  }
6434 
6435  if (Hoption.Fill == 2) chopth[13] = '2';
6436 
6437  // Option LOGX
6438 
6439  if (Hoption.Logx) {
6440  chopth[9] = 'G';
6441  chopth[10] = 'X';
6442  if (fixbin) {
6443  keepx[0] = TMath::Power(10,keepx[0]);
6444  keepx[1] = TMath::Power(10,keepx[1]);
6445  }
6446  }
6447 
6448  if (Hoption.Off) {
6449  chopth[11] = ']';
6450  chopth[12] = '[';
6451  }
6452 
6453  // Draw the histogram
6454 
6455  TGraph graph;
6456  graph.SetLineWidth(lw);
6457  graph.SetLineStyle(fH->GetLineStyle());
6458  graph.SetLineColor(fH->GetLineColor());
6459  graph.SetFillStyle(htype);
6460  graph.SetFillColor(fH->GetFillColor());
6461  graph.SetMarkerStyle(fH->GetMarkerStyle());
6462  graph.SetMarkerSize(fH->GetMarkerSize());
6463  graph.SetMarkerColor(fH->GetMarkerColor());
6464  if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6465 
6466  graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6467 
6468  delete [] keepx;
6469  delete [] keepy;
6470  gStyle->SetBarOffset(baroffsetsave);
6471  gStyle->SetBarWidth(barwidthsave);
6472 
6473  htype=oldhtype;
6474 }
6475 
6476 ////////////////////////////////////////////////////////////////////////////////
6477 /// [Control function to draw a 3D histograms.](#HP01d)
6478 
6479 void THistPainter::PaintH3(Option_t *option)
6480 {
6481 
6482  char *cmd;
6483  TString opt = fH->GetDrawOption();
6484  opt.ToLower();
6485  Int_t irep;
6486 
6487  if (fH->GetDrawOption() && (strstr(opt,"box") || strstr(opt,"lego"))) {
6488  if (strstr(opt,"1")) {
6489  PaintH3Box(1);
6490  } else if (strstr(opt,"2")) {
6492  } else if (strstr(opt,"3")) {
6493  PaintH3Box(3);
6494  } else {
6495  PaintH3BoxRaster();
6496  }
6497  return;
6498  } else if (fH->GetDrawOption() && strstr(opt,"iso")) {
6499  PaintH3Iso();
6500  return;
6501  } else if (strstr(option,"tf3")) {
6502  PaintTF3();
6503  return;
6504  } else {
6505  cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6506  }
6507 
6508  if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6509  if (strstr(opt,"bb")) Hoption.BackBox = 0;
6510 
6511  TView *view = gPad->GetView();
6512  if (!view) return;
6513  Double_t thedeg = 90 - gPad->GetTheta();
6514  Double_t phideg = -90 - gPad->GetPhi();
6515  Double_t psideg = view->GetPsi();
6516  view->SetView(phideg, thedeg, psideg, irep);
6517 
6518  // Paint the data
6519  gROOT->ProcessLine(cmd);
6520 
6521  if (Hoption.Same) return;
6522 
6523  // Draw axis
6524  view->SetOutlineToCube();
6525  TSeqCollection *ol = view->GetOutline();
6526  if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6527  Hoption.System = kCARTESIAN;
6528  TGaxis *axis = new TGaxis();
6529  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6530  delete axis;
6531 
6532  // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6533  // be painted with the option colz.
6534  if (fH->GetDrawOption() && strstr(opt,"colz")) {
6535  Int_t ndiv = fH->GetContour();
6536  if (ndiv == 0 ) {
6537  ndiv = gStyle->GetNumberContours();
6538  fH->SetContour(ndiv);
6539  }
6540  PaintPalette();
6541  }
6542 
6543  // Draw title
6544  PaintTitle();
6545 
6546  //Draw stats and fit results
6547  TF1 *fit = 0;
6548  TIter next(fFunctions);
6549  TObject *obj;
6550  while ((obj = next())) {
6551  if (obj->InheritsFrom(TF1::Class())) {
6552  fit = (TF1*)obj;
6553  break;
6554  }
6555  }
6556  if (Hoption.Same != 1) {
6557  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6558  PaintStat3(gStyle->GetOptStat(),fit);
6559  }
6560  }
6561 
6562 }
6563 
6564 ////////////////////////////////////////////////////////////////////////////////
6565 /// Compute histogram parameters used by the drawing routines.
6566 
6568 {
6569 
6570  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6571 
6572  Int_t i;
6573  static const char *where = "PaintInit";
6574  Double_t yMARGIN = gStyle->GetHistTopMargin();
6575  Int_t maximum = 0;
6576  Int_t minimum = 0;
6577  if (fH->GetMaximumStored() != -1111) maximum = 1;
6578  if (fH->GetMinimumStored() != -1111) minimum = 1;
6580  // Compute X axis parameters
6581 
6582  Int_t last = fXaxis->GetLast();
6583  Int_t first = fXaxis->GetFirst();
6584  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6585  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6586  Hparam.xlast = last;
6587  Hparam.xfirst = first;
6588  Hparam.xmin = Hparam.xlowedge;
6589  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6590 
6591  // if log scale in X, replace xmin,max by the log
6592  if (Hoption.Logx) {
6593  if (Hparam.xmax<=0) {
6594  Error(where, "cannot set X axis to log scale");
6595  return 0;
6596  }
6597  if (Hparam.xlowedge <=0 ) {
6598  if (Hoption.Same) {
6599  Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
6600  } else {
6601  for (i=first; i<=last; i++) {
6602  Double_t binLow = fXaxis->GetBinLowEdge(i);
6603  if (binLow>0) {
6604  Hparam.xlowedge = binLow;
6605  break;
6606  }
6607  if (binLow == 0 && fH->GetBinContent(i) !=0) {
6608  Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6609  break;
6610  }
6611  }
6612  if (Hparam.xlowedge<=0) {
6613  Error(where, "cannot set X axis to log scale");
6614  return 0;
6615  }
6616  }
6617  Hparam.xmin = Hparam.xlowedge;
6618  }
6619  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
6620  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
6621  Hparam.xmin = TMath::Log10(Hparam.xmin);
6622  Hparam.xmax = TMath::Log10(Hparam.xmax);
6623  if (Hparam.xlast > last) Hparam.xlast = last;
6624  if (Hparam.xfirst < first) Hparam.xfirst = first;
6625  }
6626 
6627  // Compute Y axis parameters
6628  Double_t bigp = TMath::Power(10,32);
6629  Double_t ymax = -bigp;
6630  Double_t ymin = bigp;
6631  Double_t c1, e1;
6632  Double_t xv[1];
6633  Double_t fval;
6634  TObject *f;
6635  TF1 *f1;
6636  Double_t allchan = 0;
6637  Int_t nonNullErrors = 0;
6638  TIter next(fFunctions);
6639  for (i=first; i<=last;i++) {
6640  c1 = fH->GetBinContent(i);
6641  ymax = TMath::Max(ymax,c1);
6642  if (Hoption.Logy) {
6643  if (c1 > 0) ymin = TMath::Min(ymin,c1);
6644  } else {
6645  ymin = TMath::Min(ymin,c1);
6646  }
6647  if (Hoption.Error) {
6648  if (fH->GetBinErrorOption() == TH1::kNormal)
6649  e1 = fH->GetBinError(i);
6650  else
6651  e1 = fH->GetBinErrorUp(i);
6652  if (e1 > 0) nonNullErrors++;
6653  ymax = TMath::Max(ymax,c1+e1);
6654  if (fH->GetBinErrorOption() != TH1::kNormal)
6655  e1 = fH->GetBinErrorLow(i);
6656 
6657  if (Hoption.Logy) {
6658  if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6659  } else {
6660  ymin = TMath::Min(ymin,c1-e1);
6661  }
6662  }
6663  if (Hoption.Func) {
6664  xv[0] = fXaxis->GetBinCenter(i);
6665  while ((f = (TObject*) next())) {
6666  if (f->IsA() == TF1::Class()) {
6667  f1 = (TF1*)f;
6668  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6669  fval = f1->Eval(xv[0],0,0);
6670  if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6671  ymax = TMath::Max(ymax,fval);
6672  if (Hoption.Logy) {
6673  if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6674  }
6675  }
6676  }
6677  next.Reset();
6678  }
6679  allchan += c1;
6680  }
6681  if (!nonNullErrors) {
6682  if (Hoption.Error) {
6683  if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
6684  Hoption.Error=0;
6685  }
6686  }
6687 
6688 
6689  // Take into account maximum , minimum
6690 
6691  if (Hoption.Logy && ymin <= 0) {
6692  if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
6693  else ymin = 0.001*ymax;
6694  }
6695 
6696  Double_t xm = ymin;
6697  if (maximum) ymax = fH->GetMaximumStored();
6698  if (minimum) xm = fH->GetMinimumStored();
6699  if (Hoption.Logy && xm < 0) {
6700  Error(where, "log scale requested with a negative argument (%f)", xm);
6701  return 0;
6702  } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
6703  ymin = 0.01;
6704  ymax = 10.;
6705  } else {
6706  ymin = xm;
6707  }
6708 
6709  if (ymin >= ymax) {
6710  if (Hoption.Logy) {
6711  if (ymax > 0) ymin = 0.001*ymax;
6712  else {
6713  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
6714  return 0;
6715  }
6716  }
6717  else {
6718  if (ymin > 0) {
6719  ymin = 0;
6720  ymax *= 2;
6721  } else if (ymin < 0) {
6722  ymax = 0;
6723  ymin *= 2;
6724  } else {
6725  ymin = 0;
6726  ymax = 1;
6727  }
6728  }
6729  }
6730 
6731  // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
6732  if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
6733  ymin = ymin*(1-1E-14);
6734  ymax = ymax*(1+1E-14);
6735  }
6736 
6737  // take into account normalization factor
6738  Hparam.allchan = allchan;
6739  Double_t factor = allchan;
6740  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6741  if (allchan) factor /= allchan;
6742  if (factor == 0) factor = 1;
6743  Hparam.factor = factor;
6744  ymax = factor*ymax;
6745  ymin = factor*ymin;
6746  //just in case the norm factor is negative
6747  // this may happen with a positive norm factor and a negative integral !
6748  if (ymax < ymin) {
6749  Double_t temp = ymax;
6750  ymax = ymin;
6751  ymin = temp;
6752  }
6753 
6754  // For log scales, histogram coordinates are LOG10(ymin) and
6755  // LOG10(ymax). Final adjustment (if not option "Same"
6756  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6757  // Maximum and Minimum are not defined.
6758  if (Hoption.Logy) {
6759  if (ymin <=0 || ymax <=0) {
6760  Error(where, "Cannot set Y axis to log scale");
6761  return 0;
6762  }
6763  ymin = TMath::Log10(ymin);
6764  if (!minimum) ymin += TMath::Log10(0.5);
6765  ymax = TMath::Log10(ymax);
6766  if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
6767  if (!Hoption.Same) {
6768  Hparam.ymin = ymin;
6769  Hparam.ymax = ymax;
6770  }
6771  return 1;
6772  }
6773 
6774  // final adjustment of ymin for linear scale.
6775  // if minimum is not set , then ymin is set to zero if >0
6776  // or to ymin - margin if <0.
6777  if (!minimum) {
6778  if (gStyle->GetHistMinimumZero()) {
6779  if (ymin >= 0) ymin = 0;
6780  else ymin -= yMARGIN*(ymax-ymin);
6781  } else {
6782  Double_t dymin = yMARGIN*(ymax-ymin);
6783  if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
6784  else ymin -= dymin;
6785  }
6786  }
6787 
6788  // final adjustment of YMAXI for linear scale (if not option "Same"):
6789  // decrease histogram height to MAX% of allowed height if HMAXIM
6790  // has not been called.
6791  if (!maximum) {
6792  ymax += yMARGIN*(ymax-ymin);
6793  }
6794 
6795  Hparam.ymin = ymin;
6796  Hparam.ymax = ymax;
6797  return 1;
6798 }
6799 
6800 ////////////////////////////////////////////////////////////////////////////////
6801 /// Compute histogram parameters used by the drawing routines for a rotated pad.
6802 
6804 {
6805 
6806  static const char *where = "PaintInitH";
6807  Double_t yMARGIN = gStyle->GetHistTopMargin();
6808  Int_t maximum = 0;
6809  Int_t minimum = 0;
6810  if (fH->GetMaximumStored() != -1111) maximum = 1;
6811  if (fH->GetMinimumStored() != -1111) minimum = 1;
6812 
6813  // Compute X axis parameters
6814 
6815  Int_t last = fXaxis->GetLast();
6816  Int_t first = fXaxis->GetFirst();
6817  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6818  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6819  Hparam.xlast = last;
6820  Hparam.xfirst = first;
6821  Hparam.ymin = Hparam.xlowedge;
6822  Hparam.ymax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6823 
6824  // if log scale in Y, replace ymin,max by the log
6825  if (Hoption.Logy) {
6826  if (Hparam.xlowedge <=0 ) {
6827  Hparam.xlowedge = 0.1*Hparam.xbinsize;
6828  Hparam.ymin = Hparam.xlowedge;
6829  }
6830  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
6831  Error(where, "cannot set Y axis to log scale");
6832  return 0;
6833  }
6834  Hparam.xfirst= fXaxis->FindFixBin(Hparam.ymin);
6835  Hparam.xlast = fXaxis->FindFixBin(Hparam.ymax);
6836  Hparam.ymin = TMath::Log10(Hparam.ymin);
6837  Hparam.ymax = TMath::Log10(Hparam.ymax);
6838  if (Hparam.xlast > last) Hparam.xlast = last;
6839  }
6840 
6841  // Compute Y axis parameters
6842  Double_t bigp = TMath::Power(10,32);
6843  Double_t xmax = -bigp;
6844  Double_t xmin = bigp;
6845  Double_t c1, e1;
6846  Double_t xv[1];
6847  Double_t fval;
6848  Int_t i;
6849  TObject *f;
6850  TF1 *f1;
6851  Double_t allchan = 0;
6852  TIter next(fFunctions);
6853  for (i=first; i<=last;i++) {
6854  c1 = fH->GetBinContent(i);
6855  xmax = TMath::Max(xmax,c1);
6856  xmin = TMath::Min(xmin,c1);
6857  if (Hoption.Error) {
6858  e1 = fH->GetBinError(i);
6859  xmax = TMath::Max(xmax,c1+e1);
6860  xmin = TMath::Min(xmin,c1-e1);
6861  }
6862  if (Hoption.Func) {
6863  xv[0] = fXaxis->GetBinCenter(i);
6864  while ((f = (TObject*) next())) {
6865  if (f->IsA() == TF1::Class()) {
6866  f1 = (TF1*)f;
6867  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6868  fval = f1->Eval(xv[0],0,0);
6869  xmax = TMath::Max(xmax,fval);
6870  if (Hoption.Logy) {
6871  if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
6872  }
6873  }
6874  }
6875  next.Reset();
6876  }
6877  allchan += c1;
6878  }
6879 
6880  // Take into account maximum , minimum
6881 
6882  if (Hoption.Logx && xmin <= 0) {
6883  if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
6884  else xmin = 0.001*xmax;
6885  }
6886  Double_t xm = xmin;
6887  if (maximum) xmax = fH->GetMaximumStored();
6888  if (minimum) xm = fH->GetMinimumStored();
6889  if (Hoption.Logx && xm <= 0) {
6890  Error(where, "log scale requested with zero or negative argument (%f)", xm);
6891  return 0;
6892  }
6893  else xmin = xm;
6894  if (xmin >= xmax) {
6895  if (Hoption.Logx) {
6896  if (xmax > 0) xmin = 0.001*xmax;
6897  else {
6898  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
6899  return 0;
6900  }
6901  }
6902  else {
6903  if (xmin > 0) {
6904  xmin = 0;
6905  xmax *= 2;
6906  } else if (xmin < 0) {
6907  xmax = 0;
6908  xmin *= 2;
6909  } else {
6910  xmin = -1;
6911  xmax = 1;
6912  }
6913  }
6914  }
6915 
6916  // take into account normalization factor
6917  Hparam.allchan = allchan;
6918  Double_t factor = allchan;
6919  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6920  if (allchan) factor /= allchan;
6921  if (factor == 0) factor = 1;
6922  Hparam.factor = factor;
6923  xmax = factor*xmax;
6924  xmin = factor*xmin;
6925 
6926  // For log scales, histogram coordinates are LOG10(ymin) and
6927  // LOG10(ymax). Final adjustment (if not option "Same"
6928  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6929  // Maximum and Minimum are not defined.
6930  if (Hoption.Logx) {
6931  if (xmin <=0 || xmax <=0) {
6932  Error(where, "Cannot set Y axis to log scale");
6933  return 0;
6934  }
6935  xmin = TMath::Log10(xmin);
6936  if (!minimum) xmin += TMath::Log10(0.5);
6937  xmax = TMath::Log10(xmax);
6938  if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
6939  if (!Hoption.Same) {
6940  Hparam.xmin = xmin;
6941  Hparam.xmax = xmax;
6942  }
6943  return 1;
6944  }
6945 
6946  // final adjustment of ymin for linear scale.
6947  // if minimum is not set , then ymin is set to zero if >0
6948  // or to ymin - margin if <0.
6949  if (!minimum) {
6950  if (xmin >= 0) xmin = 0;
6951  else xmin -= yMARGIN*(xmax-xmin);
6952  }
6953 
6954  // final adjustment of YMAXI for linear scale (if not option "Same"):
6955  // decrease histogram height to MAX% of allowed height if HMAXIM
6956  // has not been called.
6957  if (!maximum) {
6958  xmax += yMARGIN*(xmax-xmin);
6959  }
6960  Hparam.xmin = xmin;
6961  Hparam.xmax = xmax;
6962  return 1;
6963 }
6964 
6965 ////////////////////////////////////////////////////////////////////////////////
6966 /// [Control function to draw a 3D histogram with boxes.](#HP25)
6967 
6969 {
6970  // Predefined box structure
6971  Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
6972  {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
6973  Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
6974  {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
6975 
6976  // Define dimensions of world space
6977  TGaxis *axis = new TGaxis();
6978  TAxis *xaxis = fH->GetXaxis();
6979  TAxis *yaxis = fH->GetYaxis();
6980  TAxis *zaxis = fH->GetZaxis();
6981 
6982  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
6983  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
6984  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
6985  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
6986  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
6987  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
6988 
6990 
6991  // Set view
6992  TView *view = gPad->GetView();
6993  if (!view) {
6994  Error("PaintH3", "no TView in current pad");
6995  return;
6996  }
6997  Double_t thedeg = 90 - gPad->GetTheta();
6998  Double_t phideg = -90 - gPad->GetPhi();
6999  Double_t psideg = view->GetPsi();
7000  Int_t irep;
7001  view->SetView(phideg, thedeg, psideg, irep);
7002 
7003  Int_t backcolor = gPad->GetFrameFillColor();
7004  view->PadRange(backcolor);
7005 
7006  // Draw back surfaces of frame box
7007  fLego->InitMoveScreen(-1.1,1.1);
7008  if (Hoption.BackBox) {
7011  fLego->BackBox(90);
7012  }
7013 
7015 
7016  // Define order of drawing
7017  Double_t *tnorm = view->GetTnorm();
7018  if (!tnorm) return;
7019  Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7020  Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7021  Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7022  Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7023  Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7024  Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7025  Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7026  Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7027  Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7028 
7029  // Set graphic attributes (colour, style, etc.)
7030  Style_t fillsav = fH->GetFillStyle();
7031  Style_t colsav = fH->GetFillColor();
7032  Style_t coldark = TColor::GetColorDark(colsav);
7033  Style_t colbright = TColor::GetColorBright(colsav);
7034 
7035  fH->SetFillStyle(1001);
7036  fH->TAttFill::Modify();
7037  fH->TAttLine::Modify();
7038  Int_t ncolors = gStyle->GetNumberOfColors();
7039  Int_t theColor;
7040 
7041  // Create bin boxes and draw
7042  Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7044  TMath::Abs(fH->GetMinimum()));
7045 
7046  Double_t pmin[3], pmax[3], sxyz[8][3];
7047  for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7048  pmin[0] = xaxis->GetBinLowEdge(ix);
7049  pmax[0] = xaxis->GetBinUpEdge(ix);
7050  for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7051  pmin[1] = yaxis->GetBinLowEdge(iy);
7052  pmax[1] = yaxis->GetBinUpEdge(iy);
7053  for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7054  pmin[2] = zaxis->GetBinLowEdge(iz);
7055  pmax[2] = zaxis->GetBinUpEdge(iz);
7056  Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7057  Bool_t neg = kFALSE;
7058  Int_t n = 5;
7059  if (w<0) {
7060  w = -w;
7061  neg = kTRUE;
7062  }
7063  if (w < wmin) continue;
7064  if (w > wmax) w = wmax;
7065  Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7066  if (scale == 0) continue;
7067  for (Int_t i=0; i<3; ++i) {
7068  Double_t c = (pmax[i] + pmin[i])*0.5;
7069  Double_t d = (pmax[i] - pmin[i])*scale;
7070  for (Int_t k=0; k<8; ++k) { // set bin box vertices
7071  sxyz[k][i] = wxyz[k][i]*d + c;
7072  }
7073  }
7074  for (Int_t k=0; k<8; ++k) { // transform to normalized space
7075  view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7076  }
7077  Double_t x[8], y[8]; // draw bin box faces
7078  for (Int_t k=0; k<6; ++k) {
7079  for (Int_t i=0; i<4; ++i) {
7080  Int_t iv = iface[k][i];
7081  x[i] = sxyz[iv][0];
7082  y[i] = sxyz[iv][1];
7083  }
7084  x[4] = x[0] ; y[4] = y[0];
7085  if (neg) {
7086  x[5] = x[2] ; y[5] = y[2];
7087  x[6] = x[3] ; y[6] = y[3];
7088  x[7] = x[1] ; y[7] = y[1];
7089  n = 8;
7090  } else {
7091  n = 5;
7092  }
7093  Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7094  if (z <= 0.) continue;
7095  if (iopt == 2) {
7096  theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7097  fH->SetFillColor(gStyle->GetColorPalette(theColor));
7098  } else {
7099  if (k == 3 || k == 5) {
7100  fH->SetFillColor(coldark);
7101  } else if (k == 0 || k == 1) {
7102  fH->SetFillColor(colbright);
7103  } else {
7104  fH->SetFillColor(colsav);
7105  }
7106  }
7107  fH->TAttFill::Modify();
7108  gPad->PaintFillArea(4, x, y);
7109  if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7110  }
7111  }
7112  }
7113  }
7114 
7115  // Draw front surfaces of frame box
7116  if (Hoption.FrontBox) fLego->FrontBox(90);
7117 
7118  // Draw axis and title
7119  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7120  PaintTitle();
7121 
7122  delete axis;
7123  delete fLego; fLego = 0;
7124 
7125  fH->SetFillStyle(fillsav);
7126  fH->SetFillColor(colsav);
7127  fH->TAttFill::Modify();
7128 }
7129 
7130 ////////////////////////////////////////////////////////////////////////////////
7131 /// [Control function to draw a 3D histogram with boxes.](#HP25)
7132 
7134 {
7135  // Predefined box structure
7136  Double_t wxyz[8][3] = {
7137  {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7138  {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7139  };
7140  Int_t iface[6][4] = {
7141  {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7142  {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7143  };
7144  Double_t normal[6][3] = {
7145  {0,0,-1}, {0,0,1}, // Z-, Z+
7146  {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7147  };
7148 
7149  // Define dimensions of world space
7150  TGaxis *axis = new TGaxis();
7151  TAxis *xaxis = fH->GetXaxis();
7152  TAxis *yaxis = fH->GetYaxis();
7153  TAxis *zaxis = fH->GetZaxis();
7154 
7155  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7156  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7157  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7158  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7159  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7160  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7161 
7163 
7164  // Set view
7165  TView *view = gPad->GetView();
7166  if (!view) {
7167  Error("PaintH3", "no TView in current pad");
7168  return;
7169  }
7170  Double_t thedeg = 90 - gPad->GetTheta();
7171  Double_t phideg = -90 - gPad->GetPhi();
7172  Double_t psideg = view->GetPsi();
7173  Int_t irep;
7174  view->SetView(phideg, thedeg, psideg, irep);
7175 
7176  Int_t backcolor = gPad->GetFrameFillColor();
7177  view->PadRange(backcolor);
7178 
7179  // Draw front surfaces of frame box
7180  if (Hoption.FrontBox) {
7181  fLego->InitMoveScreen(-1.1,1.1);
7183  }
7184 
7185  // Initialize hidden line removal algorithm "raster screen"
7186  fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7187 
7188  // Define order of drawing
7189  Double_t *tnorm = view->GetTnorm();
7190  if (!tnorm) return;
7191  Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7192  Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7193  Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7194  Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7195  Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7196  Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7197  Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7198  Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7199  Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7200 
7201  // Set line attributes (colour, style, etc.)
7202  fH->TAttLine::Modify();
7203 
7204  // Create bin boxes and draw
7205  const Int_t NTMAX = 100;
7206  Double_t tt[NTMAX][2];
7207  Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7209  TMath::Abs(fH->GetMinimum()));
7210  Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7211  for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7212  pmin[0] = xaxis->GetBinLowEdge(ix);
7213  pmax[0] = xaxis->GetBinUpEdge(ix);
7214  for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7215  pmin[1] = yaxis->GetBinLowEdge(iy);
7216  pmax[1] = yaxis->GetBinUpEdge(iy);
7217  for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7218  pmin[2] = zaxis->GetBinLowEdge(iz);
7219  pmax[2] = zaxis->GetBinUpEdge(iz);
7220  Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7221  Bool_t neg = kFALSE;
7222  if (w<0) {
7223  w = -w;
7224  neg = kTRUE;
7225  }
7226  if (w < wmin) continue;
7227  if (w > wmax) w = wmax;
7228  Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7229  if (scale == 0) continue;
7230  for (Int_t i=0; i<3; ++i) {
7231  Double_t c = (pmax[i] + pmin[i])*0.5;
7232  Double_t d = (pmax[i] - pmin[i])*scale;
7233  for (Int_t k=0; k<8; ++k) { // set bin box vertices
7234  sxyz[k][i] = wxyz[k][i]*d + c;
7235  }
7236  }
7237  for (Int_t k=0; k<8; ++k) { // transform to normalized space
7238  view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7239  }
7240  for (Int_t k=0; k<6; ++k) { // draw box faces
7241  Double_t zn;
7242  view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7243  if (zn <= 0) continue;
7244  for (Int_t i=0; i<4; ++i) {
7245  Int_t ip = iface[k][i];
7246  pp[i][0] = sxyz[ip][0];
7247  pp[i][1] = sxyz[ip][1];
7248  }
7249  for (Int_t i=0; i<4; ++i) {
7250  Int_t i1 = i;
7251  Int_t i2 = (i == 3) ? 0 : i + 1;
7252  Int_t nt;
7253  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7254  Double_t xdel = pp[i2][0] - pp[i1][0];
7255  Double_t ydel = pp[i2][1] - pp[i1][1];
7256  Double_t x[2], y[2];
7257  for (Int_t it = 0; it < nt; ++it) {
7258  x[0] = pp[i1][0] + xdel*tt[it][0];
7259  y[0] = pp[i1][1] + ydel*tt[it][0];
7260  x[1] = pp[i1][0] + xdel*tt[it][1];
7261  y[1] = pp[i1][1] + ydel*tt[it][1];
7262  gPad->PaintPolyLine(2, x, y);
7263  }
7264  }
7265  if (neg) {
7266  Int_t i1 = 0;
7267  Int_t i2 = 2;
7268  Int_t nt;
7269  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7270  Double_t xdel = pp[i2][0] - pp[i1][0];
7271  Double_t ydel = pp[i2][1] - pp[i1][1];
7272  Double_t x[2], y[2];
7273  for (Int_t it = 0; it < nt; ++it) {
7274  x[0] = pp[i1][0] + xdel*tt[it][0];
7275  y[0] = pp[i1][1] + ydel*tt[it][0];
7276  x[1] = pp[i1][0] + xdel*tt[it][1];
7277  y[1] = pp[i1][1] + ydel*tt[it][1];
7278  gPad->PaintPolyLine(2, x, y);
7279  }
7280  i1 = 1;
7281  i2 = 3;
7282  fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7283  xdel = pp[i2][0] - pp[i1][0];
7284  ydel = pp[i2][1] - pp[i1][1];
7285  for (Int_t it = 0; it < nt; ++it) {
7286  x[0] = pp[i1][0] + xdel*tt[it][0];
7287  y[0] = pp[i1][1] + ydel*tt[it][0];
7288  x[1] = pp[i1][0] + xdel*tt[it][1];
7289  y[1] = pp[i1][1] + ydel*tt[it][1];
7290  gPad->PaintPolyLine(2, x, y);
7291  }
7292  }
7293  fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7294  }
7295  }
7296  }
7297  }
7298 
7299  // Draw frame box
7300  if (Hoption.BackBox) {
7303  fLego->BackBox(90);
7304  }
7305 
7306  if (Hoption.FrontBox) fLego->FrontBox(90);
7307 
7308  // Draw axis and title
7309  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7310  PaintTitle();
7311 
7312  delete axis;
7313  delete fLego; fLego = 0;
7314 }
7315 
7316 ////////////////////////////////////////////////////////////////////////////////
7317 /// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7318 
7320 {
7321 
7322  const Double_t ydiff = 1;
7323  const Double_t yligh1 = 10;
7324  const Double_t qa = 0.15;
7325  const Double_t qd = 0.15;
7326  const Double_t qs = 0.8;
7327  Double_t fmin, fmax;
7328  Int_t i, irep;
7329  Int_t nbcol = 28;
7330  Int_t icol1 = 201;
7331  Int_t ic1 = icol1;
7332  Int_t ic2 = ic1+nbcol;
7333  Int_t ic3 = ic2+nbcol;
7334 
7335  TGaxis *axis = new TGaxis();
7336  TAxis *xaxis = fH->GetXaxis();
7337  TAxis *yaxis = fH->GetYaxis();
7338  TAxis *zaxis = fH->GetZaxis();
7339 
7340  Int_t nx = fH->GetNbinsX();
7341  Int_t ny = fH->GetNbinsY();
7342  Int_t nz = fH->GetNbinsZ();
7343 
7344  Double_t *x = new Double_t[nx];
7345  Double_t *y = new Double_t[ny];
7346  Double_t *z = new Double_t[nz];
7347 
7348  for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7349  for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7350  for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7351 
7352  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7353  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7354  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7355  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7356  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7357  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7358 
7359  Double_t s[3];
7360  s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7361  s[1] = 0.5*s[0];
7362  s[2] = 1.5*s[0];
7363 
7365 
7366  TView *view = gPad->GetView();
7367  if (!view) {
7368  Error("PaintH3Iso", "no TView in current pad");
7369  delete [] x;
7370  delete [] y;
7371  delete [] z;
7372  return;
7373  }
7374  Double_t thedeg = 90 - gPad->GetTheta();
7375  Double_t phideg = -90 - gPad->GetPhi();
7376  Double_t psideg = view->GetPsi();
7377  view->SetView(phideg, thedeg, psideg, irep);
7378 
7379  Int_t backcolor = gPad->GetFrameFillColor();
7380  if (Hoption.System != kCARTESIAN) backcolor = 0;
7381  view->PadRange(backcolor);
7382 
7383  Double_t dcol = 0.5/Double_t(nbcol);
7384  TColor *colref = gROOT->GetColor(fH->GetFillColor());
7385  if (!colref) {
7386  delete [] x;
7387  delete [] y;
7388  delete [] z;
7389  return;
7390  }
7391  Float_t r, g, b, hue, light, satur;
7392  colref->GetRGB(r,g,b);
7393  TColor::RGBtoHLS(r,g,b,hue,light,satur);
7394  TColor *acol;
7395  for (Int_t col=0;col<nbcol;col++) {
7396  acol = gROOT->GetColor(col+icol1);
7397  TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7398  if (acol) acol->SetRGB(r, g, b);
7399  }
7400 
7401  fLego->InitMoveScreen(-1.1,1.1);
7402 
7403  if (Hoption.BackBox) {
7406  fLego->BackBox(90);
7407  }
7408 
7409  fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7410  fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7411  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7412  fmin = ydiff*qa;
7413  fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7414  fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7415 
7416  fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7417 
7418  if (Hoption.FrontBox) {
7419  fLego->InitMoveScreen(-1.1,1.1);
7421  fLego->FrontBox(90);
7422  }
7423  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7424 
7425  PaintTitle();
7426 
7427  delete axis;
7428  delete fLego; fLego = 0;
7429  delete [] x;
7430  delete [] y;
7431  delete [] z;
7432 }
7433 
7434 ////////////////////////////////////////////////////////////////////////////////
7435 /// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7436 
7438 {
7439 
7440  Int_t raster = 1;
7441  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7442  Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7443  Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7444  Double_t zmin = Hparam.zmin;
7445  Double_t zmax = Hparam.zmax;
7446  Double_t xlab1 = Hparam.xmin;
7447  Double_t xlab2 = Hparam.xmax;
7448  Double_t ylab1 = Hparam.ymin;
7449  Double_t ylab2 = Hparam.ymax;
7450  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7451  Double_t deltaz = TMath::Abs(zmin);
7452  if (deltaz == 0) deltaz = 1;
7453  if (zmin >= zmax) {
7454  zmin -= 0.5*deltaz;
7455  zmax += 0.5*deltaz;
7456  }
7457  Double_t z1c = zmin;
7458  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7459 
7460  // Compute the lego limits and instantiate a lego object
7461  fXbuf[0] = -1;
7462  fYbuf[0] = 1;
7463  fXbuf[1] = -1;
7464  fYbuf[1] = 1;
7465  if (Hoption.System == kPOLAR) {
7466  fXbuf[2] = z1c;
7467  fYbuf[2] = z2c;
7468  } else if (Hoption.System == kCYLINDRICAL) {
7469  if (Hoption.Logy) {
7470  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7471  else fXbuf[2] = 0;
7472  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7473  else fYbuf[2] = 0;
7474  } else {
7475  fXbuf[2] = ylab1;
7476  fYbuf[2] = ylab2;
7477  }
7478  z1c = 0; z2c = 1;
7479  } else if (Hoption.System == kSPHERICAL) {
7480  fXbuf[2] = -1;
7481  fYbuf[2] = 1;
7482  z1c = 0; z2c = 1;
7483  } else if (Hoption.System == kRAPIDITY) {
7484  fXbuf[2] = -1/TMath::Tan(dangle);
7485  fYbuf[2] = 1/TMath::Tan(dangle);
7486  } else {
7487  fXbuf[0] = xlab1;
7488  fYbuf[0] = xlab2;
7489  fXbuf[1] = ylab1;
7490  fYbuf[1] = ylab2;
7491  fXbuf[2] = z1c;
7492  fYbuf[2] = z2c;
7493  raster = 0;
7494  }
7495 
7496  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
7497 
7498  Int_t nids = -1;
7499  TH1 * hid = NULL;
7500  Color_t colormain = -1, colordark = -1;
7501  Bool_t drawShadowsInLego1 = kTRUE;
7502 
7503  // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7504  if (Hoption.Lego == 13) {
7505  Hoption.Lego = 11;
7506  fLego->SetMesh(0);
7507  }
7508  // LEGO4 is like LEGO1 except no shadows are drawn.
7509  if (Hoption.Lego == 14) {
7510  Hoption.Lego = 11;
7511  drawShadowsInLego1 = kFALSE;
7512  }
7513 
7514  // Create axis object
7515 
7516  TGaxis *axis = new TGaxis();
7517 
7518  // Initialize the levels on the Z axis
7519  Int_t ndiv = fH->GetContour();
7520  if (ndiv == 0 ) {
7521  ndiv = gStyle->GetNumberContours();
7522  fH->SetContour(ndiv);
7523  }
7524  Int_t ndivz = TMath::Abs(ndiv);
7525  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7526 
7527  // Initialize colors
7528  if (!fStack) {
7530  } else {
7531  for (Int_t id=0;id<=fStack->GetSize();id++) {
7532  hid = (TH1*)fStack->At((id==0)?id:id-1);
7533  fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
7534  }
7535  }
7536 
7537  if (Hoption.Lego == 11) {
7538  nids = 1;
7539  if (fStack) nids = fStack->GetSize();
7540  hid = fH;
7541  for (Int_t id=0;id<=nids;id++) {
7542  if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7543  colormain = hid->GetFillColor();
7544  if (colormain == 1) colormain = 17; //avoid drawing with black
7545  if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7546  else colordark = colormain;
7547  fLego->SetColorMain(colormain,id);
7548  fLego->SetColorDark(colordark,id);
7549  if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7550  if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7551  }
7552  }
7553 
7554  // Now ready to draw the lego plot
7555  Int_t irep = 0;
7556 
7557  TView *view = gPad->GetView();
7558  if (!view) {
7559  Error("PaintLego", "no TView in current pad");
7560  return;
7561  }
7562 
7563  Double_t thedeg = 90 - gPad->GetTheta();
7564  Double_t phideg = -90 - gPad->GetPhi();
7565  Double_t psideg = view->GetPsi();
7566  view->SetView(phideg, thedeg, psideg, irep);
7567 
7568  fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7570 
7571  // Set color/style for back box
7572  fLego->SetFillStyle(gPad->GetFrameFillStyle());
7573  fLego->SetFillColor(gPad->GetFrameFillColor());
7574  fLego->TAttFill::Modify();
7575 
7576  Int_t backcolor = gPad->GetFrameFillColor();
7577  if (Hoption.System != kCARTESIAN) backcolor = 0;
7578  view->PadRange(backcolor);
7579 
7582  fLego->TAttFill::Modify();
7583 
7585 
7586  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7587  else fLego->InitMoveScreen(-1.1,1.1);
7588 
7589  if (Hoption.Lego == 11 || Hoption.Lego == 12) {
7590  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7592  fLego->BackBox(90);
7593  }
7594  }
7595 
7596  if (Hoption.Lego == 12) DefineColorLevels(ndivz);
7597 
7602  if (Hoption.System == kPOLAR) {
7603  if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
7604  if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
7605  if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
7606  } else if (Hoption.System == kCYLINDRICAL) {
7607  if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
7608  if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
7609  if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
7610  } else if (Hoption.System == kSPHERICAL) {
7611  if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
7612  if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
7613  if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
7614  } else if (Hoption.System == kRAPIDITY) {
7615  if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
7616  if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
7617  if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
7618  } else {
7619  if (Hoption.Lego == 1) {
7621  fLego->LegoCartesian(90,nx,ny,"FB");}
7622  if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
7623  if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
7624  }
7625 
7626  if (Hoption.Lego == 1 || Hoption.Lego == 11) {
7627  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7629  fLego->BackBox(90);
7630  }
7631  }
7632  if (Hoption.System == kCARTESIAN) {
7633  fLego->InitMoveScreen(-1.1,1.1);
7635  if (Hoption.FrontBox) fLego->FrontBox(90);
7636  }
7637  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7638  if (Hoption.Zscale) PaintPalette();
7639  delete axis;
7640  delete fLego; fLego = 0;
7641 }
7642 
7643 ////////////////////////////////////////////////////////////////////////////////
7644 /// Draw the axis for legos and surface plots.
7645 
7647 {
7648 
7649  static Double_t epsil = 0.001;
7650 
7651  Double_t cosa, sina;
7652  Double_t bmin, bmax;
7653  Double_t r[24] /* was [3][8] */;
7654  Int_t ndivx, ndivy, ndivz, i;
7655  Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
7656  static char chopax[8], chopay[8], chopaz[8];
7657  Int_t ix1, ix2, iy1, iy2, iz1, iz2;
7659 
7660  TView *view = gPad->GetView();
7661  if (!view) {
7662  Error("PaintLegoAxis", "no TView in current pad");
7663  return;
7664  }
7665 
7666  // In polar coordinates, draw a short line going from the external circle
7667  // corresponding to r = 1 up to r = 1.1
7668  if (Hoption.System == kPOLAR) {
7669  r[0] = 1;
7670  r[1] = 0;
7671  r[2] = 0;
7672  view->WCtoNDC(r, x1);
7673  r[0] = 1.1;
7674  r[1] = 0;
7675  r[2] = 0;
7676  view->WCtoNDC(r, x2);
7677  gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
7678  return;
7679  }
7680 
7681  if (Hoption.System != kCARTESIAN) return;
7682 
7683  rad = TMath::ATan(1.) * 4. /180.;
7684  cosa = TMath::Cos(ang*rad);
7685  sina = TMath::Sin(ang*rad);
7686 
7687  view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
7688  for (i = 1; i <= 8; ++i) {
7689  r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
7690  r[i*3 - 2] = av[i*3 - 2]*sina;
7691  r[i*3 - 1] = av[i*3 - 1];
7692  }
7693 
7694  view->WCtoNDC(&r[ix1*3 - 3], x1);
7695  view->WCtoNDC(&r[ix2*3 - 3], x2);
7696  view->WCtoNDC(&r[iy1*3 - 3], y1);
7697  view->WCtoNDC(&r[iy2*3 - 3], y2);
7698  view->WCtoNDC(&r[iz1*3 - 3], z1);
7699  view->WCtoNDC(&r[iz2*3 - 3], z2);
7700 
7701  view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
7702 
7703  Double_t *rmin = view->GetRmin();
7704  Double_t *rmax = view->GetRmax();
7705  if (!rmin || !rmax) return;
7706 
7707  // Initialize the axis options
7708  if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
7709  else strlcpy(chopax, "SDH=-",8);
7710  if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
7711  else strlcpy(chopay, "SDH=-",8);
7712  if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
7713  else strlcpy(chopaz, "SDH=-",8);
7714 
7715  // Option LOG is required ?
7716  if (Hoption.Logx) strlcat(chopax,"G",8);
7717  if (Hoption.Logy) strlcat(chopay,"G",8);
7718  if (Hoption.Logz) strlcat(chopaz,"G",8);
7719 
7720  // Initialize the number of divisions. If the
7721  // number of divisions is negative, option 'N' is required.
7722  ndivx = fXaxis->GetNdivisions();
7723  ndivy = fYaxis->GetNdivisions();
7724  ndivz = fZaxis->GetNdivisions();
7725  if (ndivx < 0) {
7726  ndivx = TMath::Abs(ndivx);
7727  strlcat(chopax, "N",8);
7728  }
7729  if (ndivy < 0) {
7730  ndivy = TMath::Abs(ndivy);
7731  strlcat(chopay, "N",8);
7732  }
7733  if (ndivz < 0) {
7734  ndivz = TMath::Abs(ndivz);
7735  strlcat(chopaz, "N",8);
7736  }
7737 
7738  // Set Axis attributes.
7739  // The variable SCALE rescales the VSIZ
7740  // in order to have the same label size for all angles.
7741 
7742  axis->SetLineWidth(1);
7743 
7744  // X axis drawing
7745  if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
7748  if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
7749  bmin = TMath::Power(10, rmin[0]);
7750  bmax = TMath::Power(10, rmax[0]);
7751  } else {
7752  bmin = rmin[0];
7753  bmax = rmax[0];
7754  }
7755  // Option time display is required ?
7756  if (fXaxis->GetTimeDisplay()) {
7757  strlcat(chopax,"t",8);
7758  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
7759  axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
7760  } else {
7762  }
7763  }
7764  axis->SetOption(chopax);
7765  axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
7766  }
7767 
7768  // Y axis drawing
7769  if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
7772  if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
7773 
7774  if (fH->GetDimension() < 2) {
7775  strlcpy(chopay, "V=+UN",8);
7776  ndivy = 0;
7777  }
7778  if (TMath::Abs(y1[0] - y2[0]) < epsil) {
7779  y2[0] = y1[0];
7780  }
7781  if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
7782  bmin = TMath::Power(10, rmin[1]);
7783  bmax = TMath::Power(10, rmax[1]);
7784  } else {
7785  bmin = rmin[1];
7786  bmax = rmax[1];
7787  }
7788  // Option time display is required ?
7789  if (fYaxis->GetTimeDisplay()) {
7790  strlcat(chopay,"t",8);
7791  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
7792  axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
7793  } else {
7795  }
7796  }
7797  axis->SetOption(chopay);
7798  axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
7799  }
7800 
7801  // Z axis drawing
7802  if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
7804  if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
7805  bmin = TMath::Power(10, rmin[2]);
7806  bmax = TMath::Power(10, rmax[2]);
7807  } else {
7808  bmin = rmin[2];
7809  bmax = rmax[2];
7810  }
7811  // Option time display is required ?
7812  if (fZaxis->GetTimeDisplay()) {
7813  strlcat(chopaz,"t",8);
7814  if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
7815  axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
7816  } else {
7818  }
7819  }
7820  axis->SetOption(chopaz);
7821  axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
7822  }
7823 
7824  //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
7825 }
7826 
7827 ////////////////////////////////////////////////////////////////////////////////
7828 /// [Paint the color palette on the right side of the pad.](#HP22)
7829 
7831 {
7832 
7833  TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
7834  TView *view = gPad->GetView();
7835  if (palette) {
7836  if (view) {
7837  if (!palette->TestBit(TPaletteAxis::kHasView)) {
7838  fFunctions->Remove(palette);
7839  delete palette; palette = 0;
7840  }
7841  } else {
7843  fFunctions->Remove(palette);
7844  delete palette; palette = 0;
7845  }
7846  }
7847  // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
7848  if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
7849  }
7850 
7851  if (!palette) {
7852  Double_t xup = gPad->GetUxmax();
7853  Double_t x2 = gPad->PadtoX(gPad->GetX2());
7854  Double_t ymin = gPad->PadtoY(gPad->GetUymin());
7855  Double_t ymax = gPad->PadtoY(gPad->GetUymax());
7856  Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
7857  Double_t xmin = gPad->PadtoX(xup +0.1*xr);
7858  Double_t xmax = gPad->PadtoX(xup + xr);
7859  if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
7860  palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
7861  fFunctions->AddFirst(palette);
7862  palette->Paint();
7863  }
7864 }
7865 
7866 ////////////////////////////////////////////////////////////////////////////////
7867 /// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
7868 
7870 {
7871 
7872  fH->TAttMarker::Modify();
7873 
7874  Int_t k, marker;
7875  Double_t dz, z, xk,xstep, yk, ystep;
7876  Double_t scale = 1;
7877  Bool_t ltest = kFALSE;
7878  Double_t zmax = fH->GetMaximum();
7879  Double_t zmin = fH->GetMinimum();
7880  if (zmin == 0 && zmax == 0) return;
7881  if (zmin == zmax) {
7882  zmax += 0.1*TMath::Abs(zmax);
7883  zmin -= 0.1*TMath::Abs(zmin);
7884  }
7885  Int_t ncells = (Hparam.ylast-Hparam.yfirst)*(Hparam.xlast-Hparam.xfirst);
7886  if (Hoption.Logz) {
7887  if (zmin > 0) zmin = TMath::Log10(zmin);
7888  else zmin = 0;
7889  if (zmax > 0) zmax = TMath::Log10(zmax);
7890  else zmax = 0;
7891  if (zmin == 0 && zmax == 0) return;
7892  dz = zmax - zmin;
7893  scale = 100/dz;
7894  if (ncells > 10000) scale /= 5;
7895  ltest = kTRUE;
7896  } else {
7897  dz = zmax - zmin;
7898  if (dz >= kNMAX || zmax < 1) {
7899  scale = (kNMAX-1)/dz;
7900  if (ncells > 10000) scale /= 5;
7901  ltest = kTRUE;
7902  }
7903  }
7904  if (fH->GetMinimumStored() == -1111) {
7905  Double_t yMARGIN = gStyle->GetHistTopMargin();
7906  if (gStyle->GetHistMinimumZero()) {
7907  if (zmin >= 0) zmin = 0;
7908  else zmin -= yMARGIN*(zmax-zmin);
7909  } else {
7910  Double_t dzmin = yMARGIN*(zmax-zmin);
7911  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
7912  else zmin -= dzmin;
7913  }
7914  }
7915 
7916  TString opt = option;
7917  opt.ToLower();
7918  if (opt.Contains("scat=")) {
7919  char optscat[100];
7920  strlcpy(optscat,opt.Data(),100);
7921  char *oscat = strstr(optscat,"scat=");
7922  char *blank = strstr(oscat," "); if (blank) *blank = 0;
7923  sscanf(oscat+5,"%lg",&scale);
7924  }
7925  // use an independent instance of a random generator
7926  // instead of gRandom to avoid conflicts and
7927  // to get same random numbers when drawing the same histogram
7928  TRandom2 random;
7929  marker=0;
7930  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
7931  yk = fYaxis->GetBinLowEdge(j);
7932  ystep = fYaxis->GetBinWidth(j);
7933  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
7934  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
7935  xk = fXaxis->GetBinLowEdge(i);
7936  xstep = fXaxis->GetBinWidth(i);
7937  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
7938  z = fH->GetBinContent(bin);
7939  if (z < zmin) z = zmin;
7940  if (z > zmax) z = zmax;
7941  if (Hoption.Logz) {
7942  if (z > 0) z = TMath::Log10(z) - zmin;
7943  } else {
7944  z -= zmin;
7945  }
7946  if (z <= 0) continue;
7947  k = Int_t(z*scale);
7948  if (ltest) k++;
7949  if (k > 0) {
7950  for (Int_t loop=0; loop<k; loop++) {
7951  if (k+marker >= kNMAX) {
7952  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7953  marker=0;
7954  }
7955  fXbuf[marker] = (random.Rndm()*xstep) + xk;
7956  fYbuf[marker] = (random.Rndm()*ystep) + yk;
7957  if (Hoption.Logx) {
7958  if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
7959  else break;
7960  }
7961  if (Hoption.Logy) {
7962  if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
7963  else break;
7964  }
7965  if (fXbuf[marker] < gPad->GetUxmin()) break;
7966  if (fYbuf[marker] < gPad->GetUymin()) break;
7967  if (fXbuf[marker] > gPad->GetUxmax()) break;
7968  if (fYbuf[marker] > gPad->GetUymax()) break;
7969  marker++;
7970  }
7971  }
7972  }
7973  }
7974  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7975 
7976  if (Hoption.Zscale) PaintPalette();
7977 }
7978 
7979 ////////////////////////////////////////////////////////////////////////////////
7980 /// Static function to paint special objects like vectors and matrices.
7981 /// This function is called via `gROOT->ProcessLine` to paint these objects
7982 /// without having a direct dependency of the graphics or histogramming
7983 /// system.
7984 
7985 void THistPainter::PaintSpecialObjects(const TObject *obj, Option_t *option)
7986 {
7987 
7988  if (!obj) return;
7989  Bool_t status = TH1::AddDirectoryStatus();
7991 
7992  if (obj->InheritsFrom(TMatrixFBase::Class())) {
7993  // case TMatrixF
7994  TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
7995  R__TMatrixFBase->SetBit(kCanDelete);
7996  R__TMatrixFBase->Draw(option);
7998  } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
7999  // case TMatrixD
8000  TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8001  R__TMatrixDBase->SetBit(kCanDelete);
8002  R__TMatrixDBase->Draw(option);
8003 
8004  } else if (obj->InheritsFrom(TVectorF::Class())) {
8005  //case TVectorF
8006  TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8007  R__TVectorF->SetBit(kCanDelete);
8008  R__TVectorF->Draw(option);
8009 
8010  } else if (obj->InheritsFrom(TVectorD::Class())) {
8011  //case TVectorD
8012  TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8013  R__TVectorD->SetBit(kCanDelete);
8014  R__TVectorD->Draw(option);
8015  }
8016 
8017  TH1::AddDirectory(status);
8018 }
8019 
8020 ////////////////////////////////////////////////////////////////////////////////
8021 /// [Draw the statistics box for 1D and profile histograms.](#HP07)
8022 
8023 void THistPainter::PaintStat(Int_t dostat, TF1 *fit)
8024 {
8025 
8026  static char t[100];
8027  Int_t dofit;
8028  TPaveStats *stats = 0;
8029  TIter next(fFunctions);
8030  TObject *obj;
8031  while ((obj = next())) {
8032  if (obj->InheritsFrom(TPaveStats::Class())) {
8033  stats = (TPaveStats*)obj;
8034  break;
8035  }
8036  }
8037 
8038  if (stats && dostat) {
8039  dofit = stats->GetOptFit();
8040  dostat = stats->GetOptStat();
8041  } else {
8042  dofit = gStyle->GetOptFit();
8043  }
8044  if (!dofit) fit = 0;
8045  if (dofit == 1) dofit = 111;
8046  if (dostat == 1) dostat = 1111;
8047  Int_t print_name = dostat%10;
8048  Int_t print_entries = (dostat/10)%10;
8049  Int_t print_mean = (dostat/100)%10;
8050  Int_t print_stddev = (dostat/1000)%10;
8051  Int_t print_under = (dostat/10000)%10;
8052  Int_t print_over = (dostat/100000)%10;
8053  Int_t print_integral= (dostat/1000000)%10;
8054  Int_t print_skew = (dostat/10000000)%10;
8055  Int_t print_kurt = (dostat/100000000)%10;
8056  Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8057  print_under + print_over + print_integral +
8058  print_skew + print_kurt;
8059  Int_t print_fval = dofit%10;
8060  Int_t print_ferrors = (dofit/10)%10;
8061  Int_t print_fchi2 = (dofit/100)%10;
8062  Int_t print_fprob = (dofit/1000)%10;
8063  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8064  if (fit) {
8065  if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8066  else nlinesf += fit->GetNpar();
8067  }
8068  if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8069 
8070  // Pavetext with statistics
8071  Bool_t done = kFALSE;
8072  if (!dostat && !fit) {
8073  if (stats) { fFunctions->Remove(stats); delete stats;}
8074  return;
8075  }
8076  Double_t statw = gStyle->GetStatW();
8077  if (fit) statw = 1.8*gStyle->GetStatW();
8078  Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8079  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8080  stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8081  }
8082  if (stats) {
8083  stats->Clear();
8084  done = kTRUE;
8085  } else {
8086  stats = new TPaveStats(
8087  gStyle->GetStatX()-statw,
8088  gStyle->GetStatY()-stath,
8089  gStyle->GetStatX(),
8090  gStyle->GetStatY(),"brNDC");
8091 
8092  stats->SetParent(fH);
8093  stats->SetOptFit(dofit);
8094  stats->SetOptStat(dostat);
8095  stats->SetFillColor(gStyle->GetStatColor());
8096  stats->SetFillStyle(gStyle->GetStatStyle());
8098  stats->SetTextFont(gStyle->GetStatFont());
8099  if (gStyle->GetStatFont()%10 > 2)
8100  stats->SetTextSize(gStyle->GetStatFontSize());
8101  stats->SetFitFormat(gStyle->GetFitFormat());
8102  stats->SetStatFormat(gStyle->GetStatFormat());
8103  stats->SetName("stats");
8104 
8106  stats->SetTextAlign(12);
8107  stats->SetBit(kCanDelete);
8108  stats->SetBit(kMustCleanup);
8109  }
8110  if (print_name) stats->AddText(fH->GetName());
8111  if (print_entries) {
8112  if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8113  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8114  stats->AddText(t);
8115  }
8116  char textstats[50];
8117  if (print_mean) {
8118  if (print_mean == 1) {
8119  snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8120  snprintf(t,100,textstats,fH->GetMean(1));
8121  } else {
8122  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8123  ,"%",stats->GetStatFormat());
8124  snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
8125  }
8126  stats->AddText(t);
8127  if (fH->InheritsFrom(TProfile::Class())) {
8128  if (print_mean == 1) {
8129  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8130  snprintf(t,100,textstats,fH->GetMean(2));
8131  } else {
8132  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8133  ,"%",stats->GetStatFormat());
8134  snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
8135  }
8136  stats->AddText(t);
8137  }
8138  }
8139  if (print_stddev) {
8140  if (print_stddev == 1) {
8141  snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8142  snprintf(t,100,textstats,fH->GetStdDev(1));
8143  } else {
8144  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8145  ,"%",stats->GetStatFormat());
8146  snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
8147  }
8148  stats->AddText(t);
8149  if (fH->InheritsFrom(TProfile::Class())) {
8150  if (print_stddev == 1) {
8151  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8152  snprintf(t,100,textstats,fH->GetStdDev(2));
8153  } else {
8154  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8155  ,"%",stats->GetStatFormat());
8156  snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
8157  }
8158  stats->AddText(t);
8159  }
8160  }
8161  if (print_under) {
8162  snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8163  snprintf(t,100,textstats,fH->GetBinContent(0));
8164  stats->AddText(t);
8165  }
8166  if (print_over) {
8167  snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8168  snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
8169  stats->AddText(t);
8170  }
8171  if (print_integral) {
8172  if (print_integral == 1) {
8173  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8174  snprintf(t,100,textstats,fH->Integral());
8175  } else {
8176  snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8177  snprintf(t,100,textstats,fH->Integral("width"));
8178  }
8179  stats->AddText(t);
8180  }
8181  if (print_skew) {
8182  if (print_skew == 1) {
8183  snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8184  snprintf(t,100,textstats,fH->GetSkewness(1));
8185  } else {
8186  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8187  ,"%",stats->GetStatFormat());
8188  snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
8189  }
8190  stats->AddText(t);
8191  }
8192  if (print_kurt) {
8193  if (print_kurt == 1) {
8194  snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8195  snprintf(t,100,textstats,fH->GetKurtosis(1));
8196  } else {
8197  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8198  ,"%",stats->GetStatFormat());
8199  snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
8200  }
8201  stats->AddText(t);
8202  }
8203 
8204  // Draw Fit parameters
8205  if (fit) {
8206  Int_t ndf = fit->GetNDF();
8207  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8208  snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
8209  if (print_fchi2) stats->AddText(t);
8210  if (print_fprob) {
8211  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
8212  snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8213  stats->AddText(t);
8214  }
8215  if (print_fval || print_ferrors) {
8216  Double_t parmin,parmax;
8217  Int_t a;
8218  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8219  fit->GetParLimits(ipar,parmin,parmax);
8220  if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8221  snprintf(t,100,"%-8s ",fit->GetParName(ipar));
8222  a = strlen(t);
8223  if (a>50) a = 50;
8224  if (print_ferrors) {
8225  snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
8226  GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8227  snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar)
8228  ,(Float_t)fit->GetParError(ipar));
8229  } else {
8230  snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
8231  snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar));
8232  }
8233  t[63] = 0;
8234  stats->AddText(t);
8235  }
8236  }
8237  }
8238 
8239  if (!done) fFunctions->Add(stats);
8240  stats->Paint();
8241 }
8242 
8243 ////////////////////////////////////////////////////////////////////////////////
8244 /// [Draw the statistics box for 2D histograms.](#HP07)
8245 
8246 void THistPainter::PaintStat2(Int_t dostat, TF1 *fit)
8247 {
8248 
8249  if (fH->GetDimension() != 2) return;
8250  TH2 *h2 = (TH2*)fH;
8251 
8252  static char t[100];
8253  Int_t dofit;
8254  TPaveStats *stats = 0;
8255  TIter next(fFunctions);
8256  TObject *obj;
8257  while ((obj = next())) {
8259  stats = (TPaveStats*)obj;
8260  break;
8261  }
8262  }
8263  if (stats && dostat) {
8264  dofit = stats->GetOptFit();
8265  dostat = stats->GetOptStat();
8266  } else {
8267  dofit = gStyle->GetOptFit();
8268  }
8269  if (dostat == 1) dostat = 1111;
8270  Int_t print_name = dostat%10;
8271  Int_t print_entries = (dostat/10)%10;
8272  Int_t print_mean = (dostat/100)%10;
8273  Int_t print_stddev = (dostat/1000)%10;
8274  Int_t print_under = (dostat/10000)%10;
8275  Int_t print_over = (dostat/100000)%10;
8276  Int_t print_integral= (dostat/1000000)%10;
8277  Int_t print_skew = (dostat/10000000)%10;
8278  Int_t print_kurt = (dostat/100000000)%10;
8279  Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8280  if (print_under || print_over) nlines += 3;
8281 
8282  // Pavetext with statistics
8283  if (!gStyle->GetOptFit()) fit = 0;
8284  Bool_t done = kFALSE;
8285  if (!dostat && !fit) {
8286  if (stats) { fFunctions->Remove(stats); delete stats;}
8287  return;
8288  }
8289  Double_t statw = gStyle->GetStatW();
8290  if (fit) statw = 1.8*gStyle->GetStatW();
8291  Double_t stath = nlines*gStyle->GetStatFontSize();
8292  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8293  stath = 0.25*nlines*gStyle->GetStatH();
8294  }
8295  if (fit) stath += gStyle->GetStatH();
8296  if (stats) {
8297  stats->Clear();
8298  done = kTRUE;
8299  } else {
8300  stats = new TPaveStats(
8301  gStyle->GetStatX()-statw,
8302  gStyle->GetStatY()-stath,
8303  gStyle->GetStatX(),
8304  gStyle->GetStatY(),"brNDC");
8305 
8306  stats->SetParent(fH);
8307  stats->SetOptFit(dofit);
8308  stats->SetOptStat(dostat);
8309  stats->SetFillColor(gStyle->GetStatColor());
8310  stats->SetFillStyle(gStyle->GetStatStyle());
8312  stats->SetName("stats");
8313 
8315  stats->SetTextAlign(12);
8316  stats->SetTextFont(gStyle->GetStatFont());
8317  if (gStyle->GetStatFont()%10 > 2)
8318  stats->SetTextSize(gStyle->GetStatFontSize());
8319  stats->SetFitFormat(gStyle->GetFitFormat());
8320  stats->SetStatFormat(gStyle->GetStatFormat());
8321  stats->SetBit(kCanDelete);
8322  stats->SetBit(kMustCleanup);
8323  }
8324  if (print_name) stats->AddText(h2->GetName());
8325  if (print_entries) {
8326  if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8327  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8328  stats->AddText(t);
8329  }
8330  char textstats[50];
8331  if (print_mean) {
8332  if (print_mean == 1) {
8333  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8334  snprintf(t,50,textstats,h2->GetMean(1));
8335  stats->AddText(t);
8336  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8337  snprintf(t,100,textstats,h2->GetMean(2));
8338  stats->AddText(t);
8339  } else {
8340  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8341  ,"%",stats->GetStatFormat());
8342  snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
8343  stats->AddText(t);
8344  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8345  ,"%",stats->GetStatFormat());
8346  snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
8347  stats->AddText(t);
8348  }
8349  }
8350  if (print_stddev) {
8351  if (print_stddev == 1) {
8352  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8353  snprintf(t,100,textstats,h2->GetStdDev(1));
8354  stats->AddText(t);
8355  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8356  snprintf(t,100,textstats,h2->GetStdDev(2));
8357  stats->AddText(t);
8358  } else {
8359  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8360  ,"%",stats->GetStatFormat());
8361  snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
8362  stats->AddText(t);
8363  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8364  ,"%",stats->GetStatFormat());
8365  snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
8366  stats->AddText(t);
8367  }
8368  }
8369  if (print_integral) {
8370  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8371  snprintf(t,100,textstats,fH->Integral());
8372  stats->AddText(t);
8373  }
8374  if (print_skew) {
8375  if (print_skew == 1) {
8376  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8377  snprintf(t,100,textstats,h2->GetSkewness(1));
8378  stats->AddText(t);
8379  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8380  snprintf(t,100,textstats,h2->GetSkewness(2));
8381  stats->AddText(t);
8382  } else {
8383  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8384  ,"%",stats->GetStatFormat());
8385  snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
8386  stats->AddText(t);
8387  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8388  ,"%",stats->GetStatFormat());
8389  snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
8390  stats->AddText(t);
8391  }
8392  }
8393  if (print_kurt) {
8394  if (print_kurt == 1) {
8395  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8396  snprintf(t,100,textstats,h2->GetKurtosis(1));
8397  stats->AddText(t);
8398  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8399  snprintf(t,100,textstats,h2->GetKurtosis(2));
8400  stats->AddText(t);
8401  } else {
8402  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8403  ,"%",stats->GetStatFormat());
8404  snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
8405  stats->AddText(t);
8406  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8407  ,"%",stats->GetStatFormat());
8408  snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
8409  stats->AddText(t);
8410  }
8411  }
8412  if (print_under || print_over) {
8413  //get 3*3 under/overflows for 2d hist
8414  Double_t unov[9];
8415 
8416  Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8417  Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8418  Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8419  Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8420  Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8421  Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8422 
8423  unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8424  unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8425  unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8426  unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8427  unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8428  unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8429  unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8430  unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8431  unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8432 
8433  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8434  stats->AddText(t);
8435  if (h2->GetEntries() < 1e7)
8436  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8437  else
8438  snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8439  stats->AddText(t);
8440  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8441  stats->AddText(t);
8442  }
8443 
8444  // Draw Fit parameters
8445  if (fit) {
8446  Int_t ndf = fit->GetNDF();
8447  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8448  stats->AddText(t);
8449  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8450  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8451  ,(Float_t)fit->GetParameter(ipar)
8452  ,(Float_t)fit->GetParError(ipar));
8453  t[63] = 0;
8454  stats->AddText(t);
8455  }
8456  }
8457 
8458  if (!done) fFunctions->Add(stats);
8459  stats->Paint();
8460 }
8461 
8462 ////////////////////////////////////////////////////////////////////////////////
8463 /// [Draw the statistics box for 3D histograms.](#HP07)
8464 
8465 void THistPainter::PaintStat3(Int_t dostat, TF1 *fit)
8466 {
8467 
8468  if (fH->GetDimension() != 3) return;
8469  TH3 *h3 = (TH3*)fH;
8470 
8471  static char t[100];
8472  Int_t dofit;
8473  TPaveStats *stats = 0;
8474  TIter next(fFunctions);
8475  TObject *obj;
8476  while ((obj = next())) {
8478  stats = (TPaveStats*)obj;
8479  break;
8480  }
8481  }
8482  if (stats && dostat) {
8483  dofit = stats->GetOptFit();
8484  dostat = stats->GetOptStat();
8485  } else {
8486  dofit = gStyle->GetOptFit();
8487  }
8488  if (dostat == 1) dostat = 1111;
8489  Int_t print_name = dostat%10;
8490  Int_t print_entries = (dostat/10)%10;
8491  Int_t print_mean = (dostat/100)%10;
8492  Int_t print_stddev = (dostat/1000)%10;
8493  Int_t print_under = (dostat/10000)%10;
8494  Int_t print_over = (dostat/100000)%10;
8495  Int_t print_integral= (dostat/1000000)%10;
8496  Int_t print_skew = (dostat/10000000)%10;
8497  Int_t print_kurt = (dostat/100000000)%10;
8498  Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8499  if (print_under || print_over) nlines += 3;
8500 
8501  // Pavetext with statistics
8502  if (!gStyle->GetOptFit()) fit = 0;
8503  Bool_t done = kFALSE;
8504  if (!dostat && !fit) {
8505  if (stats) { fFunctions->Remove(stats); delete stats;}
8506  return;
8507  }
8508  Double_t statw = gStyle->GetStatW();
8509  if (fit) statw = 1.8*gStyle->GetStatW();
8510  Double_t stath = nlines*gStyle->GetStatFontSize();
8511  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8512  stath = 0.25*nlines*gStyle->GetStatH();
8513  }
8514  if (fit) stath += gStyle->GetStatH();
8515  if (stats) {
8516  stats->Clear();
8517  done = kTRUE;
8518  } else {
8519  stats = new TPaveStats(
8520  gStyle->GetStatX()-statw,
8521  gStyle->GetStatY()-stath,
8522  gStyle->GetStatX(),
8523  gStyle->GetStatY(),"brNDC");
8524 
8525  stats->SetParent(fH);
8526  stats->SetOptFit(dofit);
8527  stats->SetOptStat(dostat);
8528  stats->SetFillColor(gStyle->GetStatColor());
8529  stats->SetFillStyle(gStyle->GetStatStyle());
8531  stats->SetName("stats");
8532 
8534  stats->SetTextAlign(12);
8535  stats->SetTextFont(gStyle->GetStatFont());
8536  stats->SetFitFormat(gStyle->GetFitFormat());
8537  stats->SetStatFormat(gStyle->GetStatFormat());
8538  stats->SetBit(kCanDelete);
8539  stats->SetBit(kMustCleanup);
8540  }
8541  if (print_name) stats->AddText(h3->GetName());
8542  if (print_entries) {
8543  if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8544  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8545  stats->AddText(t);
8546  }
8547  char textstats[50];
8548  if (print_mean) {
8549  if (print_mean == 1) {
8550  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8551  snprintf(t,100,textstats,h3->GetMean(1));
8552  stats->AddText(t);
8553  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8554  snprintf(t,100,textstats,h3->GetMean(2));
8555  stats->AddText(t);
8556  snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8557  snprintf(t,100,textstats,h3->GetMean(3));
8558  stats->AddText(t);
8559  } else {
8560  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8561  ,"%",stats->GetStatFormat());
8562  snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
8563  stats->AddText(t);
8564  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8565  ,"%",stats->GetStatFormat());
8566  snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
8567  stats->AddText(t);
8568  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8569  ,"%",stats->GetStatFormat());
8570  snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
8571  stats->AddText(t);
8572  }
8573  }
8574  if (print_stddev) {
8575  if (print_stddev == 1) {
8576  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8577  snprintf(t,100,textstats,h3->GetStdDev(1));
8578  stats->AddText(t);
8579  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8580  snprintf(t,100,textstats,h3->GetStdDev(2));
8581  stats->AddText(t);
8582  snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
8583  snprintf(t,100,textstats,h3->GetStdDev(3));
8584  stats->AddText(t);
8585  } else {
8586  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8587  ,"%",stats->GetStatFormat());
8588  snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
8589  stats->AddText(t);
8590  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8591  ,"%",stats->GetStatFormat());
8592  snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
8593  stats->AddText(t);
8594  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
8595  ,"%",stats->GetStatFormat());
8596  snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
8597  stats->AddText(t);
8598  }
8599  }
8600  if (print_integral) {
8601  snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
8602  stats->AddText(t);
8603  }
8604  if (print_skew) {
8605  if (print_skew == 1) {
8606  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8607  snprintf(t,100,textstats,h3->GetSkewness(1));
8608  stats->AddText(t);
8609  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8610  snprintf(t,100,textstats,h3->GetSkewness(2));
8611  stats->AddText(t);
8612  snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
8613  snprintf(t,100,textstats,h3->GetSkewness(3));
8614  stats->AddText(t);
8615  } else {
8616  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8617  ,"%",stats->GetStatFormat());
8618  snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
8619  stats->AddText(t);
8620  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8621  ,"%",stats->GetStatFormat());
8622  snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
8623  stats->AddText(t);
8624  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
8625  ,"%",stats->GetStatFormat());
8626  snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
8627  stats->AddText(t);
8628  }
8629  }
8630  if (print_kurt) {
8631  if (print_kurt == 1) {
8632  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8633  snprintf(t,100,textstats,h3->GetKurtosis(1));
8634  stats->AddText(t);
8635  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8636  snprintf(t,100,textstats,h3->GetKurtosis(2));
8637  stats->AddText(t);
8638  snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
8639  snprintf(t,100,textstats,h3->GetKurtosis(3));
8640  stats->AddText(t);
8641  } else {
8642  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8643  ,"%",stats->GetStatFormat());
8644  snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
8645  stats->AddText(t);
8646  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8647  ,"%",stats->GetStatFormat());
8648  snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
8649  stats->AddText(t);
8650  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
8651  ,"%",stats->GetStatFormat());
8652  snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
8653  stats->AddText(t);
8654  }
8655  }
8656  if (print_under || print_over) {
8657  // no underflow - overflow printing for a 3D histogram
8658  // one would need a 3D table
8659  }
8660 
8661  // Draw Fit parameters
8662  if (fit) {
8663  Int_t ndf = fit->GetNDF();
8664  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8665  stats->AddText(t);
8666  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8667  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8668  ,(Float_t)fit->GetParameter(ipar)
8669  ,(Float_t)fit->GetParError(ipar));
8670  t[32] = 0;
8671  stats->AddText(t);
8672  }
8673  }
8674 
8675  if (!done) fFunctions->Add(stats);
8676  stats->Paint();
8677 }
8678 
8679 ////////////////////////////////////////////////////////////////////////////////
8680 /// [Control function to draw a 2D histogram as a surface plot.](#HP18)
8681 
8683 {
8684 
8685  const Double_t ydiff = 1;
8686  const Double_t yligh1 = 10;
8687  const Double_t qa = 0.15;
8688  const Double_t qd = 0.15;
8689  const Double_t qs = 0.8;
8690  Double_t fmin, fmax;
8691  Int_t raster = 0;
8692  Int_t irep = 0;
8693 
8694  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8695  Int_t nx = Hparam.xlast - Hparam.xfirst;
8696  Int_t ny = Hparam.ylast - Hparam.yfirst;
8697  Double_t zmin = Hparam.zmin;
8698  Double_t zmax = Hparam.zmax;
8699  Double_t xlab1 = Hparam.xmin;
8700  Double_t xlab2 = Hparam.xmax;
8701  Double_t ylab1 = Hparam.ymin;
8702  Double_t ylab2 = Hparam.ymax;
8703  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
8704  Double_t deltaz = TMath::Abs(zmin);
8705  if (deltaz == 0) deltaz = 1;
8706  if (zmin >= zmax) {
8707  zmin -= 0.5*deltaz;
8708  zmax += 0.5*deltaz;
8709  }
8710  Double_t z1c = zmin;
8711  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
8712  // Compute the lego limits and instantiate a lego object
8713  fXbuf[0] = -1;
8714  fYbuf[0] = 1;
8715  fXbuf[1] = -1;
8716  fYbuf[1] = 1;
8717  if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
8718  if (Hoption.System == kPOLAR) {
8719  fXbuf[2] = z1c;
8720  fYbuf[2] = z2c;
8721  } else if (Hoption.System == kCYLINDRICAL) {
8722  if (Hoption.Logy) {
8723  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
8724  else fXbuf[2] = 0;
8725  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
8726  else fYbuf[2] = 0;
8727  } else {
8728  fXbuf[2] = ylab1;
8729  fYbuf[2] = ylab2;
8730  }
8731  z1c = 0; z2c = 1;
8732  } else if (Hoption.System == kSPHERICAL) {
8733  fXbuf[2] = -1;
8734  fYbuf[2] = 1;
8735  z1c = 0; z2c = 1;
8736  } else if (Hoption.System == kRAPIDITY) {
8737  fXbuf[2] = -1/TMath::Tan(dangle);
8738  fYbuf[2] = 1/TMath::Tan(dangle);
8739  } else {
8740  fXbuf[0] = xlab1;
8741  fYbuf[0] = xlab2;
8742  fXbuf[1] = ylab1;
8743  fYbuf[1] = ylab2;
8744  fXbuf[2] = z1c;
8745  fYbuf[2] = z2c;
8746  }
8747 
8748  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
8751 
8752  // Create axis object
8753 
8754  TGaxis *axis = new TGaxis();
8755 
8756  // Initialize the levels on the Z axis
8757  Int_t ndiv = fH->GetContour();
8758  if (ndiv == 0 ) {
8759  ndiv = gStyle->GetNumberContours();
8760  fH->SetContour(ndiv);
8761  }
8762  Int_t ndivz = TMath::Abs(ndiv);
8763  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8764 
8765  if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
8766  if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
8767 
8768  // Close the surface in case of non cartesian coordinates.
8769 
8770  if (Hoption.System != kCARTESIAN) {nx++; ny++;}
8771 
8772  // Now ready to draw the surface plot
8773 
8774  TView *view = gPad->GetView();
8775  if (!view) {
8776  Error("PaintSurface", "no TView in current pad");
8777  return;
8778  }
8779 
8780  Double_t thedeg = 90 - gPad->GetTheta();
8781  Double_t phideg = -90 - gPad->GetPhi();
8782  Double_t psideg = view->GetPsi();
8783  view->SetView(phideg, thedeg, psideg, irep);
8784 
8785  // Set color/style for back box
8786  if (Hoption.Same) {
8787  fLego->SetFillStyle(0);
8788  fLego->SetFillColor(1);
8789  } else {
8790  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8791  fLego->SetFillColor(gPad->GetFrameFillColor());
8792  }
8793  fLego->TAttFill::Modify();
8794 
8795  Int_t backcolor = gPad->GetFrameFillColor();
8796  if (Hoption.System != kCARTESIAN) backcolor = 0;
8797  view->PadRange(backcolor);
8798 
8801  fLego->TAttFill::Modify();
8802 
8803  // Draw the filled contour on top
8804  Int_t icol1 = fH->GetFillColor();
8805 
8806  Int_t hoption35 = Hoption.Surf;
8807  if (Hoption.Surf == 13 || Hoption.Surf == 15) {
8808  DefineColorLevels(ndivz);
8809  Hoption.Surf = 23;
8812  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8813  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8814  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8815  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8816  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8817  Hoption.Surf = hoption35;
8818  fLego->SetMesh(1);
8819  }
8820 
8821  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8822  else fLego->InitMoveScreen(-1.1,1.1);
8823 
8824  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
8826  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
8828  fLego->BackBox(90);
8829  }
8830  }
8831 
8832  // Gouraud Shading surface
8833  if (Hoption.Surf == 14) {
8834  // Set light sources
8835  fLego->LightSource(0, ydiff, 0,0,0,irep);
8836  fLego->LightSource(1, yligh1 ,1,1,1,irep);
8837  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
8838  fmin = ydiff*qa;
8839  fmax = fmin + (yligh1+0.1)*(qd+qs);
8840  Int_t nbcol = 28;
8841  icol1 = 201;
8842  Double_t dcol = 0.5/Double_t(nbcol);
8843  TColor *colref = gROOT->GetColor(fH->GetFillColor());
8844  if (!colref) return;
8845  Float_t r,g,b,hue,light,satur;
8846  colref->GetRGB(r,g,b);
8847  TColor::RGBtoHLS(r,g,b,hue,light,satur);
8848  TColor *acol;
8849  for (Int_t col=0;col<nbcol;col++) {
8850  acol = gROOT->GetColor(col+icol1);
8851  TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
8852  if (acol) acol->SetRGB(r,g,b);
8853  }
8854  fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
8857  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8858  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8859  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8860  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8861  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8862  } else if (Hoption.Surf == 15) {
8863  // The surface is not drawn in this case.
8864  } else {
8865  // Draw the surface
8866  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
8867  DefineColorLevels(ndivz);
8868  } else {
8870  }
8872  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceRaster1);
8873  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode2);
8874  if (Hoption.System == kPOLAR) {
8875  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
8876  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
8877  } else if (Hoption.System == kCYLINDRICAL) {
8878  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
8879  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8880  } else if (Hoption.System == kSPHERICAL) {
8881  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
8882  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8883  } else if (Hoption.System == kRAPIDITY) {
8884  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
8885  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8886  } else {
8887  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1);
8889  if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
8890  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
8891  }
8892  }
8893 
8894  // Paint the line contour on top for option SURF7
8895  if (Hoption.Surf == 17) {
8896  fLego->InitMoveScreen(-1.1,1.1);
8898  Hoption.Surf = 23;
8901  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
8902  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
8903  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
8904  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
8905  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
8906  }
8907 
8908  if ((!Hoption.Same) &&
8909  (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
8910  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
8912  fLego->BackBox(90);
8913  }
8914  }
8915  if (Hoption.System == kCARTESIAN) {
8916  fLego->InitMoveScreen(-1.1,1.1);
8918  if (Hoption.FrontBox) fLego->FrontBox(90);
8919  }
8920  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8921 
8922  if (Hoption.Zscale) PaintPalette();
8923 
8924  delete axis;
8925  delete fLego; fLego = 0;
8926 }
8927 
8928 ////////////////////////////////////////////////////////////////////////////////
8929 /// Control function to draw a table using Delaunay triangles.
8930 
8932 {
8933 
8934  TGraphDelaunay2D *dt = nullptr;
8935  TGraphDelaunay *dtOld = nullptr;
8936 
8937  // Check if fH contains a TGraphDelaunay2D
8938  TList *hl = fH->GetListOfFunctions();
8939  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
8940  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
8941  if (!dt && !dtOld) return;
8942 
8943  // If needed, create a TGraph2DPainter
8944  if (!fGraph2DPainter) {
8945  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
8946  else fGraph2DPainter = new TGraph2DPainter(dtOld);
8947  }
8948 
8949  // Define the 3D view
8950  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8951  if (Hoption.Same) {
8952  TView *viewsame = gPad->GetView();
8953  if (!viewsame) {
8954  Error("PaintTriangles", "no TView in current pad, do not use option SAME");
8955  return;
8956  }
8957  Double_t *rmin = viewsame->GetRmin();
8958  Double_t *rmax = viewsame->GetRmax();
8959  if (!rmin || !rmax) return;
8960  fXbuf[0] = rmin[0];
8961  fYbuf[0] = rmax[0];
8962  fXbuf[1] = rmin[1];
8963  fYbuf[1] = rmax[1];
8964  fXbuf[2] = rmin[2];
8965  fYbuf[2] = rmax[2];
8966  } else {
8967  fXbuf[0] = Hparam.xmin;
8968  fYbuf[0] = Hparam.xmax;
8969  fXbuf[1] = Hparam.ymin;
8970  fYbuf[1] = Hparam.ymax;
8971  fXbuf[2] = Hparam.zmin;
8972  fYbuf[2] = Hparam.zmax;
8973  }
8974 
8975  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8976  TView *view = gPad->GetView();
8977  if (!view) {
8978  Error("PaintTriangles", "no TView in current pad");
8979  return;
8980  }
8981  Double_t thedeg = 90 - gPad->GetTheta();
8982  Double_t phideg = -90 - gPad->GetPhi();
8983  Double_t psideg = view->GetPsi();
8984  Int_t irep;
8985  view->SetView(phideg, thedeg, psideg, irep);
8986 
8987  // Set color/style for back box
8988  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8989  fLego->SetFillColor(gPad->GetFrameFillColor());
8990  fLego->TAttFill::Modify();
8991  Int_t backcolor = gPad->GetFrameFillColor();
8992  if (Hoption.System != kCARTESIAN) backcolor = 0;
8993  view->PadRange(backcolor);
8996  fLego->TAttFill::Modify();
8997 
8998  // Paint the Back Box if needed
8999  if (Hoption.BackBox && !Hoption.Same) {
9000  fLego->InitMoveScreen(-1.1,1.1);
9003  fLego->BackBox(90);
9004  }
9005 
9006  // Paint the triangles
9007  fGraph2DPainter->Paint(option);
9008 
9009  // Paint the Front Box if needed
9010  if (Hoption.FrontBox) {
9011  fLego->InitMoveScreen(-1.1,1.1);
9013  fLego->FrontBox(90);
9014  }
9015 
9016  // Paint the Axis if needed
9017  if (!Hoption.Axis && !Hoption.Same) {
9018  TGaxis *axis = new TGaxis();
9019  PaintLegoAxis(axis, 90);
9020  delete axis;
9021  }
9022 
9023  if (Hoption.Zscale) PaintPalette();
9024 
9025  delete fLego; fLego = 0;
9026 }
9027 
9028 ////////////////////////////////////////////////////////////////////////////////
9029 /// Define the color levels used to paint legos, surfaces etc..
9030 
9032 {
9033 
9034  Int_t i, irep;
9035 
9036  // Initialize the color levels
9037  if (ndivz >= 100) {
9038  Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9039  ndivz = 8;
9040  }
9041  Double_t *funlevel = new Double_t[ndivz+1];
9042  Int_t *colorlevel = new Int_t[ndivz+1];
9043  Int_t theColor;
9044  Int_t ncolors = gStyle->GetNumberOfColors();
9045  for (i = 0; i < ndivz; ++i) {
9046  funlevel[i] = fH->GetContourLevelPad(i);
9047  theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9048  colorlevel[i] = gStyle->GetColorPalette(theColor);
9049  }
9050  colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9051  fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9052  delete [] colorlevel;
9053  delete [] funlevel;
9054 }
9055 
9056 ////////////////////////////////////////////////////////////////////////////////
9057 /// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9058 
9059 void THistPainter::PaintTable(Option_t *option)
9060 {
9061 
9062  // Fill Hparam structure with histo parameters
9063  if (!TableInit()) return;
9064 
9065  // Draw histogram frame
9066  PaintFrame();
9067 
9068  // If palette option not specified, delete a possible existing palette
9069  if (!Hoption.Zscale) {
9070  TObject *palette = fFunctions->FindObject("palette");
9071  if (palette) { fFunctions->Remove(palette); delete palette;}
9072  }
9073 
9074  // Do not draw the histogram. Only the attached functions will be drawn.
9075  if (Hoption.Func == 2) {
9076  if (Hoption.Zscale) {
9077  Int_t ndiv = fH->GetContour();
9078  if (ndiv == 0 ) {
9079  ndiv = gStyle->GetNumberContours();
9080  fH->SetContour(ndiv);
9081  }
9082  PaintPalette();
9083  }
9084 
9085  // Draw the histogram according to the option
9086  } else {
9087  if (fH->InheritsFrom(TH2Poly::Class())) {
9088  if (Hoption.Fill) PaintTH2PolyBins("f");
9089  if (Hoption.Color) PaintTH2PolyColorLevels(option);
9090  if (Hoption.Scat) PaintTH2PolyScatterPlot(option);
9091  if (Hoption.Text) PaintTH2PolyText(option);
9092  if (Hoption.Line) PaintTH2PolyBins("l");
9093  if (Hoption.Mark) PaintTH2PolyBins("P");
9094  } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9095  if (Hoption.Scat) PaintScatterPlot(option);
9096  if (Hoption.Arrow) PaintArrows(option);
9097  if (Hoption.Box) PaintBoxes(option);
9098  if (Hoption.Color) {
9099  if (Hoption.Color == 3) PaintColorLevelsFast(option);
9100  else PaintColorLevels(option);
9101  }
9102  if (Hoption.Contour) PaintContour(option);
9103  if (Hoption.Text) PaintText(option);
9104  if (Hoption.Error >= 100) Paint2DErrors(option);
9105  if (Hoption.Candle) PaintCandlePlot(option);
9106  }
9107  if (Hoption.Lego) PaintLego(option);
9108  if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9109  if (Hoption.Tri) PaintTriangles(option);
9110  }
9111 
9112  // Draw histogram title
9113  PaintTitle();
9114 
9115  // Draw the axes
9116  if (!Hoption.Lego && !Hoption.Surf &&
9117  !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9118 
9119  TF1 *fit = 0;
9120  TIter next(fFunctions);
9121  TObject *obj;
9122  while ((obj = next())) {
9123  if (obj->InheritsFrom(TF1::Class())) {
9124  fit = (TF1*)obj;
9125  break;
9126  }
9127  }
9128  if (Hoption.Same != 1) {
9129  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9130  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9131  //ALWAYS executed on non-iOS platform.
9132  //On iOS, depends on mode.
9133  PaintStat2(gStyle->GetOptStat(),fit);
9134  }
9135  }
9136  }
9137 }
9138 
9139 ////////////////////////////////////////////////////////////////////////////////
9140 /// Control function to draw a TH2Poly bins' contours.
9141 ///
9142 /// - option = "F" draw the bins as filled areas.
9143 /// - option = "L" draw the bins as line.
9144 /// - option = "P" draw the bins as markers.
9145 
9147 {
9148 
9149  //Do not highlight the histogram, if its part was picked.
9150  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9151 
9152  TString opt = option;
9153  opt.ToLower();
9154  Bool_t line = kFALSE;
9155  Bool_t fill = kFALSE;
9156  Bool_t mark = kFALSE;
9157  if (opt.Contains("l")) line = kTRUE;
9158  if (opt.Contains("f")) fill = kTRUE;
9159  if (opt.Contains("p")) mark = kTRUE;
9160 
9161  TH2PolyBin *b;
9162  Double_t z;
9163 
9164  TIter next(((TH2Poly*)fH)->GetBins());
9165  TObject *obj, *poly;
9166 
9167  while ((obj=next())) {
9168  b = (TH2PolyBin*)obj;
9169  z = b->GetContent();
9170  if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9171  poly = b->GetPolygon();
9172 
9173  // Paint the TGraph bins.
9174  if (poly->IsA() == TGraph::Class()) {
9175  TGraph *g = (TGraph*)poly;
9176  g->TAttLine::Modify();
9177  g->TAttMarker::Modify();
9178  g->TAttFill::Modify();
9179  if (line) {
9180  Int_t fs = g->GetFillStyle();
9181  Int_t fc = g->GetFillColor();
9182  g->SetFillStyle(0);
9183  g->SetFillColor(g->GetLineColor());
9184  g->Paint("F");
9185  g->SetFillStyle(fs);
9186  g->SetFillColor(fc);
9187  }
9188  if (fill) g->Paint("F");
9189  if (mark) g->Paint("P");
9190  }
9191 
9192  // Paint the TMultiGraph bins.
9193  if (poly->IsA() == TMultiGraph::Class()) {
9194  TMultiGraph *mg = (TMultiGraph*)poly;
9195  TList *gl = mg->GetListOfGraphs();
9196  if (!gl) return;
9197  TGraph *g;
9198  TIter nextg(gl);
9199  while ((g = (TGraph*) nextg())) {
9200  g->TAttLine::Modify();
9201  g->TAttMarker::Modify();
9202  g->TAttFill::Modify();
9203  if (line) {
9204  Int_t fs = g->GetFillStyle();
9205  Int_t fc = g->GetFillColor();
9206  g->SetFillStyle(0);
9207  g->SetFillColor(g->GetLineColor());
9208  g->Paint("F");
9209  g->SetFillStyle(fs);
9210  g->SetFillColor(fc);
9211  }
9212  if (fill) g->Paint("F");
9213  if (mark) g->Paint("P");
9214  }
9215  }
9216  }
9217 }
9218 
9219 ////////////////////////////////////////////////////////////////////////////////
9220 /// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9221 
9223 {
9224 
9225  //Do not highlight the histogram, if its part was picked.
9226  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9227  return;
9228 
9229  Int_t ncolors, color, theColor;
9230  Double_t z, zc;
9231  Double_t zmin = fH->GetMinimum();
9232  Double_t zmax = fH->GetMaximum();
9233  if (Hoption.Logz) {
9234  if (zmax > 0) {
9235  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9236  zmin = TMath::Log10(zmin);
9237  zmax = TMath::Log10(zmax);
9238  } else {
9239  return;
9240  }
9241  }
9242  Double_t dz = zmax - zmin;
9243 
9244  // Initialize the levels on the Z axis
9245  ncolors = gStyle->GetNumberOfColors();
9246  Int_t ndiv = fH->GetContour();
9247  if (ndiv == 0 ) {
9248  ndiv = gStyle->GetNumberContours();
9249  fH->SetContour(ndiv);
9250  }
9251  Int_t ndivz = TMath::Abs(ndiv);
9252  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9253  Double_t scale = ndivz/dz;
9254 
9255  TH2PolyBin *b;
9256 
9257  TIter next(((TH2Poly*)fH)->GetBins());
9258  TObject *obj, *poly;
9259 
9260  while ((obj=next())) {
9261  b = (TH2PolyBin*)obj;
9262  poly = b->GetPolygon();
9263 
9264  z = b->GetContent();
9265  if (z==0 && Hoption.Zero) continue;
9266  if (Hoption.Logz) {
9267  if (z > 0) z = TMath::Log10(z);
9268  else z = zmin;
9269  }
9270  if (z < zmin) continue;
9271 
9272  // Define the bin color.
9273  if (fH->TestBit(TH1::kUserContour)) {
9274  zc = fH->GetContourLevelPad(0);
9275  if (z < zc) continue;
9276  color = -1;
9277  for (Int_t k=0; k<ndiv; k++) {
9278  zc = fH->GetContourLevelPad(k);
9279  if (z < zc) {
9280  continue;
9281  } else {
9282  color++;
9283  }
9284  }
9285  } else {
9286  color = Int_t(0.01+(z-zmin)*scale);
9287  }
9288  theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9289  if (theColor > ncolors-1) theColor = ncolors-1;
9290 
9291  // Paint the TGraph bins.
9292  if (poly->IsA() == TGraph::Class()) {
9293  TGraph *g = (TGraph*)poly;
9294  g->SetFillColor(gStyle->GetColorPalette(theColor));
9295  g->TAttFill::Modify();
9296  g->Paint("F");
9297  }
9298 
9299  // Paint the TMultiGraph bins.
9300  if (poly->IsA() == TMultiGraph::Class()) {
9301  TMultiGraph *mg = (TMultiGraph*)poly;
9302  TList *gl = mg->GetListOfGraphs();
9303  if (!gl) return;
9304  TGraph *g;
9305  TIter nextg(gl);
9306  while ((g = (TGraph*) nextg())) {
9307  g->SetFillColor(gStyle->GetColorPalette(theColor));
9308  g->TAttFill::Modify();
9309  g->Paint("F");
9310  }
9311  }
9312  }
9313  if (Hoption.Zscale) PaintPalette();
9314 }
9315 
9316 ////////////////////////////////////////////////////////////////////////////////
9317 /// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9318 
9320 {
9321 
9322  //Do not highlight the histogram, if its part was selected.
9323  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9324  return;
9325 
9326  Int_t k, loop, marker=0;
9327  Double_t z, xk,xstep, yk, ystep, xp, yp;
9328  Double_t scale = 1;
9329  Double_t zmin = fH->GetMinimum();
9330  Double_t zmax = fH->GetMaximum();
9331  if (Hoption.Logz) {
9332  if (zmax > 0) {
9333  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9334  zmin = TMath::Log10(zmin);
9335  zmax = TMath::Log10(zmax);
9336  } else {
9337  return;
9338  }
9339  }
9340  Double_t dz = zmax - zmin;
9341  scale = (kNMAX-1)/dz;
9342 
9343 
9344  // use an independent instance of a random generator
9345  // instead of gRandom to avoid conflicts and
9346  // to get same random numbers when drawing the same histogram
9347  TRandom2 random;
9348 
9349  TH2PolyBin *b;
9350 
9351  TIter next(((TH2Poly*)fH)->GetBins());
9352  TObject *obj, *poly;
9353 
9354  Double_t maxarea = 0, a;
9355  while ((obj=next())) {
9356  b = (TH2PolyBin*)obj;
9357  a = b->GetArea();
9358  if (a>maxarea) maxarea = a;
9359  }
9360 
9361  next.Reset();
9362 
9363  while ((obj=next())) {
9364  b = (TH2PolyBin*)obj;
9365  poly = b->GetPolygon();
9366  z = b->GetContent();
9367  if (z < zmin) z = zmin;
9368  if (z > zmax) z = zmax;
9369  if (Hoption.Logz) {
9370  if (z > 0) z = TMath::Log10(z) - zmin;
9371  } else {
9372  z -= zmin;
9373  }
9374  k = Int_t((z*scale)*(b->GetArea()/maxarea));
9375  xk = b->GetXMin();
9376  yk = b->GetYMin();
9377  xstep = b->GetXMax()-xk;
9378  ystep = b->GetYMax()-yk;
9379 
9380  // Paint the TGraph bins.
9381  if (poly->IsA() == TGraph::Class()) {
9382  TGraph *g = (TGraph*)poly;
9383  if (k <= 0 || z <= 0) continue;
9384  loop = 0;
9385  while (loop<k) {
9386  if (k+marker >= kNMAX) {
9387  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9388  marker=0;
9389  }
9390  xp = (random.Rndm()*xstep) + xk;
9391  yp = (random.Rndm()*ystep) + yk;
9392  if (g->IsInside(xp,yp)) {
9393  fXbuf[marker] = xp;
9394  fYbuf[marker] = yp;
9395  marker++;
9396  loop++;
9397  }
9398  }
9399  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9400  }
9401 
9402  // Paint the TMultiGraph bins.
9403  if (poly->IsA() == TMultiGraph::Class()) {
9404  TMultiGraph *mg = (TMultiGraph*)poly;
9405  TList *gl = mg->GetListOfGraphs();
9406  if (!gl) return;
9407  if (k <= 0 || z <= 0) continue;
9408  loop = 0;
9409  while (loop<k) {
9410  if (k+marker >= kNMAX) {
9411  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9412  marker=0;
9413  }
9414  xp = (random.Rndm()*xstep) + xk;
9415  yp = (random.Rndm()*ystep) + yk;
9416  if (mg->IsInside(xp,yp)) {
9417  fXbuf[marker] = xp;
9418  fYbuf[marker] = yp;
9419  marker++;
9420  loop++;
9421  }
9422  }
9423  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9424  }
9425  }
9426  PaintTH2PolyBins("l");
9427 }
9428 
9429 ////////////////////////////////////////////////////////////////////////////////
9430 /// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9431 
9433 {
9434 
9435  TLatex text;
9436  text.SetTextFont(gStyle->GetTextFont());
9437  text.SetTextColor(fH->GetMarkerColor());
9438  text.SetTextSize(0.02*fH->GetMarkerSize());
9439 
9440  Double_t x, y, z, e, angle = 0;
9441  char value[50];
9442  char format[32];
9443  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9444  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9445  Int_t opt = (Int_t)Hoption.Text/1000;
9446 
9447  text.SetTextAlign(22);
9448  if (Hoption.Text == 1) angle = 0;
9449  text.SetTextAngle(angle);
9450  text.TAttText::Modify();
9451 
9452  TH2PolyBin *b;
9453 
9454  TIter next(((TH2Poly*)fH)->GetBins());
9455  TObject *obj, *p;
9456 
9457  while ((obj=next())) {
9458  b = (TH2PolyBin*)obj;
9459  p = b->GetPolygon();
9460  x = (b->GetXMin()+b->GetXMax())/2;
9461  if (Hoption.Logx) {
9462  if (x > 0) x = TMath::Log10(x);
9463  else continue;
9464  }
9465  y = (b->GetYMin()+b->GetYMax())/2;
9466  if (Hoption.Logy) {
9467  if (y > 0) y = TMath::Log10(y);
9468  else continue;
9469  }
9470  z = b->GetContent();
9471  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9472  if (opt==2) {
9473  e = fH->GetBinError(b->GetBinNumber());
9474  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9475  "%",gStyle->GetPaintTextFormat(),
9476  "%",gStyle->GetPaintTextFormat());
9477  snprintf(value,50,format,z,e);
9478  } else {
9479  snprintf(value,50,format,z);
9480  }
9481  if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9482  else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
9483  }
9484 
9485  PaintTH2PolyBins("l");
9486 }
9487 
9488 ////////////////////////////////////////////////////////////////////////////////
9489 /// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9490 
9492 {
9493 
9494  TLatex text;
9495  text.SetTextFont(gStyle->GetTextFont());
9496  text.SetTextColor(fH->GetMarkerColor());
9497  text.SetTextSize(0.02*fH->GetMarkerSize());
9498 
9499  Double_t x, y, z, e, angle = 0;
9500  char value[50];
9501  char format[32];
9502  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9503  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9504 
9505  // 1D histograms
9506  if (fH->GetDimension() == 1) {
9507  Bool_t getentries = kFALSE;
9508  Double_t yt;
9509  TProfile *hp = (TProfile*)fH;
9510  if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9511  Hoption.Text = Hoption.Text-2000;
9512  getentries = kTRUE;
9513  }
9514  if (Hoption.Text == 1) angle = 90;
9515  text.SetTextAlign(11);
9516  if (angle == 90) text.SetTextAlign(12);
9517  if (angle == 0) text.SetTextAlign(21);
9518  text.TAttText::Modify();
9519  Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9520  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9521  if (Hoption.Bar) {
9522  x = fH->GetXaxis()->GetBinLowEdge(i)+
9523  fH->GetXaxis()->GetBinWidth(i)*
9524  (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9525  } else {
9526  x = fH->GetXaxis()->GetBinCenter(i);
9527  }
9528  y = fH->GetBinContent(i);
9529  yt = y;
9530  if (gStyle->GetHistMinimumZero() && y<0) y = 0;
9531  if (getentries) yt = hp->GetBinEntries(i);
9532  if (yt == 0.) continue;
9533  snprintf(value,50,format,yt);
9534  if (Hoption.Logx) {
9535  if (x > 0) x = TMath::Log10(x);
9536  else continue;
9537  }
9538  if (Hoption.Logy) {
9539  if (y > 0) y = TMath::Log10(y);
9540  else continue;
9541  }
9542  if (y >= gPad->GetY2()) continue;
9543  if (y <= gPad->GetY1()) continue;
9544  text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
9545  }
9546 
9547  // 2D histograms
9548  } else {
9549  text.SetTextAlign(22);
9550  if (Hoption.Text == 1) angle = 0;
9551  text.SetTextAngle(angle);
9552  text.TAttText::Modify();
9553  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9554  y = fYaxis->GetBinCenter(j);
9555  if (Hoption.Logy) {
9556  if (y > 0) y = TMath::Log10(y);
9557  else continue;
9558  }
9559  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9560  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9561  x = fXaxis->GetBinCenter(i);
9562  if (Hoption.Logx) {
9563  if (x > 0) x = TMath::Log10(x);
9564  else continue;
9565  }
9566  if (!IsInside(x,y)) continue;
9567  z = fH->GetBinContent(bin);
9568  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9569  if (Hoption.Text>2000) {
9570  e = fH->GetBinError(bin);
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  text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9579  angle,0.02*fH->GetMarkerSize(),value);
9580  }
9581  }
9582  }
9583 }
9584 
9585 ////////////////////////////////////////////////////////////////////////////////
9586 /// [Control function to draw a 3D implicit functions.](#HP27)
9587 
9589 {
9590 
9591  Int_t irep;
9592 
9593  TGaxis *axis = new TGaxis();
9594  TAxis *xaxis = fH->GetXaxis();
9595  TAxis *yaxis = fH->GetYaxis();
9596  TAxis *zaxis = fH->GetZaxis();
9597 
9598  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
9599  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
9600  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
9601  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
9602  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
9603  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
9604 
9605  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
9606 
9607  TView *view = gPad->GetView();
9608  if (!view) {
9609  Error("PaintTF3", "no TView in current pad");
9610  return;
9611  }
9612  Double_t thedeg = 90 - gPad->GetTheta();
9613  Double_t phideg = -90 - gPad->GetPhi();
9614  Double_t psideg = view->GetPsi();
9615  view->SetView(phideg, thedeg, psideg, irep);
9616 
9617  fLego->InitMoveScreen(-1.1,1.1);
9618 
9619  if (Hoption.BackBox) {
9622  fLego->BackBox(90);
9623  }
9624 
9626 
9627  fLego->ImplicitFunction(fXbuf, fYbuf, fH->GetNbinsX(),
9628  fH->GetNbinsY(),
9629  fH->GetNbinsZ(), "BF");
9630 
9631  if (Hoption.FrontBox) {
9632  fLego->InitMoveScreen(-1.1,1.1);
9634  fLego->FrontBox(90);
9635  }
9636  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9637 
9638  PaintTitle();
9639 
9640  delete axis;
9641  delete fLego; fLego = 0;
9642 }
9643 
9644 ////////////////////////////////////////////////////////////////////////////////
9645 /// Draw the histogram title
9646 ///
9647 /// The title is drawn according to the title alignment returned by
9648 /// `GetTitleAlign()`. It is a 2 digits integer): hv
9649 ///
9650 /// where `h` is the horizontal alignment and `v` is the
9651 /// vertical alignment.
9652 ///
9653 /// - `h` can get the values 1 2 3 for left, center, and right
9654 /// - `v` can get the values 1 2 3 for bottom, middle and top
9655 ///
9656 /// for instance the default alignment is: 13 (left top)
9657 
9659 {
9660 
9661  if (Hoption.Same) return;
9662  if (fH->TestBit(TH1::kNoTitle)) return;
9663  Int_t nt = strlen(fH->GetTitle());
9664  TPaveText *title = 0;
9665  TObject *obj;
9666  TIter next(gPad->GetListOfPrimitives());
9667  while ((obj = next())) {
9668  if (!obj->InheritsFrom(TPaveText::Class())) continue;
9669  title = (TPaveText*)obj;
9670  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
9671  break;
9672  }
9673  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
9674  if (title) delete title;
9675  return;
9676  }
9677  Double_t ht = gStyle->GetTitleH();
9678  Double_t wt = gStyle->GetTitleW();
9679  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
9680  if (ht <= 0) ht = 0.05;
9681  if (wt <= 0) {
9682  TLatex l;
9683  l.SetTextSize(ht);
9684  l.SetTitle(fH->GetTitle());
9685  // adjustment in case the title has several lines (#splitline)
9686  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
9687  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
9688  wt = TMath::Min(0.7, 0.02+wndc);
9689  }
9690  if (title) {
9691  TText *t0 = (TText*)title->GetLine(0);
9692  if (t0) {
9693  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
9694  t0->SetTitle(fH->GetTitle());
9695  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
9696  }
9697  return;
9698  }
9699 
9700  Int_t talh = gStyle->GetTitleAlign()/10;
9701  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
9702  Int_t talv = gStyle->GetTitleAlign()%10;
9703  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
9704  Double_t xpos, ypos;
9705  xpos = gStyle->GetTitleX();
9706  ypos = gStyle->GetTitleY();
9707  if (talh == 2) xpos = xpos-wt/2.;
9708  if (talh == 3) xpos = xpos-wt;
9709  if (talv == 2) ypos = ypos+ht/2.;
9710  if (talv == 1) ypos = ypos+ht;
9711 
9712  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
9713 
9714  // box with the histogram title
9716  ptitle->SetFillStyle(gStyle->GetTitleStyle());
9717  ptitle->SetName("title");
9720  ptitle->SetTextFont(gStyle->GetTitleFont(""));
9721  if (gStyle->GetTitleFont("")%10 > 2)
9722  ptitle->SetTextSize(gStyle->GetTitleFontSize());
9723  ptitle->AddText(fH->GetTitle());
9724  ptitle->SetBit(kCanDelete);
9725  ptitle->Draw();
9726  ptitle->Paint();
9727 
9728  if(!gPad->IsEditable()) delete ptitle;
9729 }
9730 
9731 ////////////////////////////////////////////////////////////////////////////////
9732 /// Process message `mess`.
9733 
9734 void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
9735 {
9736 
9737  if (!strcmp(mess,"SetF3")) {
9739  } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
9741  } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
9742  TVectorD &v = (TVectorD&)(*obj);
9743  Double_t xclip = v(0);
9744  Double_t yclip = v(1);
9745  Double_t zclip = v(2);
9747  }
9748 }
9749 
9750 ////////////////////////////////////////////////////////////////////////////////
9751 /// Static function.
9752 ///
9753 /// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
9754 /// This procedure can be used to create an all-sky map in Galactic
9755 /// coordinates with an equal-area Aitoff projection. Output map
9756 /// coordinates are zero longitude centered.
9757 /// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
9758 ///
9759 /// source: GMT
9760 ///
9761 /// code from Ernst-Jan Buis
9762 
9764 {
9765 
9766  Double_t x, y;
9767 
9768  Double_t alpha2 = (l/2)*TMath::DegToRad();
9769  Double_t delta = b*TMath::DegToRad();
9770  Double_t r2 = TMath::Sqrt(2.);
9771  Double_t f = 2*r2/TMath::Pi();
9772  Double_t cdec = TMath::Cos(delta);
9773  Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
9774  x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
9775  y = TMath::Sin(delta)*r2/denom;
9776  x *= TMath::RadToDeg()/f;
9777  y *= TMath::RadToDeg()/f;
9778  // x *= -1.; // for a skymap swap left<->right
9779  Al = x;
9780  Ab = y;
9781 
9782  return 0;
9783 }
9784 
9785 ////////////////////////////////////////////////////////////////////////////////
9786 /// Static function
9787 ///
9788 /// Probably the most famous of the various map projections, the Mercator projection
9789 /// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
9790 /// with no distortion along the equator.
9791 /// The Mercator projection has been used extensively for world maps in which the distortion towards
9792 /// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
9793 /// Greenland is larger than South America. In reality, the latter is about eight times the size of
9794 /// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
9795 /// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
9796 /// code from Ernst-Jan Buis
9797 
9799 {
9800 
9801  Al = l;
9803  Ab = TMath::Log(aid);
9804  return 0;
9805 }
9806 
9807 ////////////////////////////////////////////////////////////////////////////////
9808 /// Static function code from Ernst-Jan Buis
9809 
9811 {
9812 
9813  Al = l*cos(b*TMath::DegToRad());
9814  Ab = b;
9815  return 0;
9816 }
9817 
9818 ////////////////////////////////////////////////////////////////////////////////
9819 /// Static function code from Ernst-Jan Buis
9820 
9823 
9824  Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
9825  Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
9826  return 0;
9827 }
9828 
9829 ////////////////////////////////////////////////////////////////////////////////
9830 /// Recompute the histogram range following graphics operations.
9831 
9834 
9835  if (Hoption.Same) return;
9836 
9837  // Compute x,y range
9838  Double_t xmin = Hparam.xmin;
9839  Double_t xmax = Hparam.xmax;
9840  Double_t ymin = Hparam.ymin;
9841  Double_t ymax = Hparam.ymax;
9842 
9843  Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
9844  if (Hoption.Proj ==1) {
9845  // TODO : check x range not lower than -180 and not higher than 180
9846  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9847  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9848  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9849  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9850 
9851  if (xmin > xmin_aid) xmin = xmin_aid;
9852  if (ymin > ymin_aid) ymin = ymin_aid;
9853  if (xmax < xmax_aid) xmax = xmax_aid;
9854  if (ymax < ymax_aid) ymax = ymax_aid;
9855  if (Hparam.ymin<0 && Hparam.ymax>0) {
9856  // there is an 'equator', check its range in the plot..
9857  THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
9858  THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
9859  if (xmin >xmin_aid) xmin = xmin_aid;
9860  if (xmax <xmax_aid) xmax = xmax_aid;
9861  }
9862  if (Hparam.xmin<0 && Hparam.xmax>0) {
9863  THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
9864  THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
9865  if (ymin >ymin_aid) ymin = ymin_aid;
9866  if (ymax <ymax_aid) ymax = ymax_aid;
9867  }
9868  } else if ( Hoption.Proj ==2) {
9869  if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
9870  Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
9871  Hoption.Proj = 0;
9872  } else {
9873  THistPainter::ProjectMercator2xy(Hparam.xmin, Hparam.ymin, xmin, ymin);
9874  THistPainter::ProjectMercator2xy(Hparam.xmax, Hparam.ymax, xmax, ymax);
9875  }
9876  } else if (Hoption.Proj == 3) {
9877  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9878  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9879  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9880  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9881 
9882  if (xmin > xmin_aid) xmin = xmin_aid;
9883  if (ymin > ymin_aid) ymin = ymin_aid;
9884  if (xmax < xmax_aid) xmax = xmax_aid;
9885  if (ymax < ymax_aid) ymax = ymax_aid;
9886  if (Hparam.ymin<0 && Hparam.ymax>0) {
9887  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
9888  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
9889  if (xmin >xmin_aid) xmin = xmin_aid;
9890  if (xmax <xmax_aid) xmax = xmax_aid;
9891  }
9892  if (Hparam.xmin<0 && Hparam.xmax>0) {
9893  THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
9894  THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
9895  if (ymin >ymin_aid) ymin = ymin_aid;
9896  if (ymax <ymax_aid) ymax = ymax_aid;
9897  }
9898  } else if (Hoption.Proj == 4) {
9899  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9900  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9901  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9902  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9903 
9904  if (xmin > xmin_aid) xmin = xmin_aid;
9905  if (ymin > ymin_aid) ymin = ymin_aid;
9906  if (xmax < xmax_aid) xmax = xmax_aid;
9907  if (ymax < ymax_aid) ymax = ymax_aid;
9908  if (Hparam.ymin<0 && Hparam.ymax>0) {
9909  THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
9910  THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
9911  if (xmin >xmin_aid) xmin = xmin_aid;
9912  if (xmax <xmax_aid) xmax = xmax_aid;
9913  }
9914  if (Hparam.xmin<0 && Hparam.xmax>0) {
9915  THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
9916  THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
9917  if (ymin >ymin_aid) ymin = ymin_aid;
9918  if (ymax <ymax_aid) ymax = ymax_aid;
9919  }
9920  }
9921  Hparam.xmin= xmin;
9922  Hparam.xmax= xmax;
9923  Hparam.ymin= ymin;
9924  Hparam.ymax= ymax;
9925 
9926  Double_t dx = xmax-xmin;
9927  Double_t dy = ymax-ymin;
9928  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
9929  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
9930 
9931  // Range() could change the size of the pad pixmap and therefore should
9932  // be called before the other paint routines
9933  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
9934  ymin - dyr*gPad->GetBottomMargin(),
9935  xmax + dxr*gPad->GetRightMargin(),
9936  ymax + dyr*gPad->GetTopMargin());
9937  gPad->RangeAxis(xmin, ymin, xmax, ymax);
9938 }
9939 
9940 ////////////////////////////////////////////////////////////////////////////////
9941 /// Set current histogram to `h`
9942 
9944 {
9945 
9946  if (h == 0) return;
9947  fH = h;
9948  fXaxis = h->GetXaxis();
9949  fYaxis = h->GetYaxis();
9950  fZaxis = h->GetZaxis();
9952 }
9953 
9954 ////////////////////////////////////////////////////////////////////////////////
9955 /// Initialize various options to draw 2D histograms.
9956 
9958 {
9959 
9960  static const char *where = "TableInit";
9961 
9962  Int_t first, last;
9963  Double_t yMARGIN= gStyle->GetHistTopMargin();
9964  Double_t zmin, zmax;
9965  Int_t maximum = 0;
9966  Int_t minimum = 0;
9967  if (fH->GetMaximumStored() != -1111) maximum = 1;
9968  if (fH->GetMinimumStored() != -1111) minimum = 1;
9970  // ----------------- Compute X axis parameters
9971  first = fXaxis->GetFirst();
9972  last = fXaxis->GetLast();
9973  Hparam.xlast = last;
9974  Hparam.xfirst = first;
9975  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
9976  Hparam.xbinsize = fXaxis->GetBinWidth(first);
9977  Hparam.xmin = Hparam.xlowedge;
9978  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
9979 
9980  // if log scale in X, replace xmin,max by the log
9981  if (Hoption.Logx) {
9982  // find the first edge of a bin that is > 0
9983  if (Hparam.xlowedge <=0 ) {
9984  Hparam.xlowedge = fXaxis->GetBinUpEdge(fXaxis->FindFixBin(0.01*Hparam.xbinsize));
9985  Hparam.xmin = Hparam.xlowedge;
9986  }
9987  if (Hparam.xmin <=0 || Hparam.xmax <=0) {
9988  Error(where, "cannot set X axis to log scale");
9989  return 0;
9990  }
9991  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
9992  if (Hparam.xfirst < first) Hparam.xfirst = first;
9993  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
9994  if (Hparam.xlast > last) Hparam.xlast = last;
9995  Hparam.xmin = TMath::Log10(Hparam.xmin);
9996  Hparam.xmax = TMath::Log10(Hparam.xmax);
9997  }
9998 
9999  // ----------------- Compute Y axis parameters
10000  first = fYaxis->GetFirst();
10001  last = fYaxis->GetLast();
10002  Hparam.ylast = last;
10003  Hparam.yfirst = first;
10004  Hparam.ylowedge = fYaxis->GetBinLowEdge(first);
10005  Hparam.ybinsize = fYaxis->GetBinWidth(first);
10006  if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10007  Hparam.ymin = Hparam.ylowedge;
10008  Hparam.ymax = fYaxis->GetBinLowEdge(last)+fYaxis->GetBinWidth(last);
10009 
10010  // if log scale in Y, replace ymin,max by the log
10011  if (Hoption.Logy) {
10012  if (Hparam.ylowedge <=0 ) {
10013  Hparam.ylowedge = fYaxis->GetBinUpEdge(fYaxis->FindFixBin(0.01*Hparam.ybinsize));
10014  Hparam.ymin = Hparam.ylowedge;
10015  }
10016  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10017  Error(where, "cannot set Y axis to log scale");
10018  return 0;
10019  }
10020  Hparam.yfirst= fYaxis->FindFixBin(Hparam.ymin);
10021  if (Hparam.yfirst < first) Hparam.yfirst = first;
10022  Hparam.ylast = fYaxis->FindFixBin(Hparam.ymax);
10023  if (Hparam.ylast > last) Hparam.ylast = last;
10024  Hparam.ymin = TMath::Log10(Hparam.ymin);
10025  Hparam.ymax = TMath::Log10(Hparam.ymax);
10026  }
10027 
10028 
10029  // ----------------- Compute Z axis parameters
10030  Double_t bigp = TMath::Power(10,32);
10031  zmax = -bigp;
10032  zmin = bigp;
10033  Double_t c1, e1;
10034  Double_t allchan = 0;
10035  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10036  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10037  c1 = fH->GetBinContent(i,j);
10038  zmax = TMath::Max(zmax,c1);
10039  if (Hoption.Error) {
10040  e1 = fH->GetBinError(i,j);
10041  zmax = TMath::Max(zmax,c1+e1);
10042  }
10043  zmin = TMath::Min(zmin,c1);
10044  allchan += c1;
10045  }
10046  }
10047 
10048  // Take into account maximum , minimum
10049 
10050  if (maximum) zmax = fH->GetMaximumStored();
10051  if (minimum) zmin = fH->GetMinimumStored();
10052  if (Hoption.Logz && zmax < 0) {
10053  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10054  return 0;
10055  } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10056  zmin = 0.01;
10057  zmax = 10.;
10058  }
10059  if (zmin >= zmax) {
10060  if (Hoption.Logz) {
10061  if (zmax > 0) zmin = 0.001*zmax;
10062  else {
10063  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10064  return 0;
10065  }
10066  }
10067  }
10068 
10069  // take into account normalization factor
10070  Hparam.allchan = allchan;
10071  Double_t factor = allchan;
10072  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10073  if (allchan) factor /= allchan;
10074  if (factor == 0) factor = 1;
10075  Hparam.factor = factor;
10076  zmax = factor*zmax;
10077  zmin = factor*zmin;
10078  c1 = zmax;
10079  if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10080 
10081  // For log scales, histogram coordinates are log10(ymin) and
10082  // log10(ymax). Final adjustment (if not option "Same")
10083  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10084  // Maximum and Minimum are not defined.
10085  if (Hoption.Logz) {
10086  if (zmin <= 0) {
10087  zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10088  fH->SetMinimum(zmin);
10089  }
10090  zmin = TMath::Log10(zmin);
10091  if (!minimum) zmin += TMath::Log10(0.5);
10092  zmax = TMath::Log10(zmax);
10093  if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10094  goto LZMIN;
10095  }
10096 
10097  // final adjustment of YMAXI for linear scale (if not option "Same"):
10098  // decrease histogram height to MAX% of allowed height if HMAXIM
10099  // has not been called.
10100  // MAX% is the value in percent which has been set in HPLSET
10101  // (default is 90%).
10102  if (!maximum) {
10103  zmax += yMARGIN*(zmax-zmin);
10104  }
10105 
10106  // final adjustment of ymin for linear scale.
10107  // if minimum is not set , then ymin is set to zero if >0
10108  // or to ymin - yMARGIN if <0.
10109  if (!minimum) {
10110  if (gStyle->GetHistMinimumZero()) {
10111  if (zmin >= 0) zmin = 0;
10112  else zmin -= yMARGIN*(zmax-zmin);
10113  } else {
10114  Double_t dzmin = yMARGIN*(zmax-zmin);
10115  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10116  else zmin -= dzmin;
10117  }
10118  }
10119 
10120 LZMIN:
10121  Hparam.zmin = zmin;
10122  Hparam.zmax = zmax;
10123 
10124  // Set bar offset and width
10125  Hparam.baroffset = fH->GetBarOffset();
10126  Hparam.barwidth = fH->GetBarWidth();
10127 
10128  return 1;
10129 }
10130 
10131 ////////////////////////////////////////////////////////////////////////////////
10132 /// This function returns the best format to print the error value (e)
10133 /// knowing the parameter value (v) and the format (f) used to print it.
10134 
10135 const char * THistPainter::GetBestFormat(Double_t v, Double_t e, const char *f)
10136 {
10137 
10138  static char ef[20];
10139  char tf[20], tv[64];
10140 
10141  // print v with the format f in tv.
10142  snprintf(tf,20,"%s%s","%",f);
10143  snprintf(tv,64,tf,v);
10144 
10145  // Analyse tv.
10146  TString sv = tv;
10147  int ie = sv.Index("e");
10148  int iE = sv.Index("E");
10149  int id = sv.Index(".");
10150 
10151  // v has been printed with the exponent notation.
10152  // There is 2 cases, the exponent is positive or negative
10153  if (ie >= 0 || iE >= 0) {
10154  if (sv.Index("+") >= 0) {
10155  if (e < 1) {
10156  snprintf(ef,20,"%s.1f","%");
10157  } else {
10158  if (ie >= 0) {
10159  snprintf(ef,20,"%s.%de","%",ie-id-1);
10160  } else {
10161  snprintf(ef,20,"%s.%dE","%",iE-id-1);
10162  }
10163  }
10164  } else {
10165  if (ie >= 0) {
10166  snprintf(ef,20,"%s.%de","%",ie-id-1);
10167  } else {
10168  snprintf(ef,20,"%s.%dE","%",iE-id-1);
10169  }
10170  }
10171 
10172  // There is not '.' in tv. e will be printed with one decimal digit.
10173  } else if (id < 0) {
10174  snprintf(ef,20,"%s.1f","%");
10175 
10176  // There is a '.' in tv and no exponent notation. e's decimal part will
10177  // have the same number of digits as v's one.
10178  } else {
10179  snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
10180  }
10181 
10182  return ef;
10183 }
10184 
10185 ////////////////////////////////////////////////////////////////////////////////
10186 /// Set projection.
10187 
10188 void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10189 {
10190 
10191  if (fShowProjection) return;
10192  TString opt = option;
10193  opt.ToLower();
10194  Int_t projection = 0;
10195  if (opt.Contains("x")) projection = 1;
10196  if (opt.Contains("y")) projection = 2;
10197  if (opt.Contains("z")) projection = 3;
10198  if (opt.Contains("xy")) projection = 4;
10199  if (opt.Contains("yx")) projection = 5;
10200  if (opt.Contains("xz")) projection = 6;
10201  if (opt.Contains("zx")) projection = 7;
10202  if (opt.Contains("yz")) projection = 8;
10203  if (opt.Contains("zy")) projection = 9;
10204  if (projection < 4) fShowOption = option+1;
10205  else fShowOption = option+2;
10206  fShowProjection = projection+100*nbins;
10207  gROOT->MakeDefCanvas();
10208  gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10209  gPad->SetGrid();
10210 }
10211 
10212 ////////////////////////////////////////////////////////////////////////////////
10213 /// Show projection onto X.
10214 
10215 void THistPainter::ShowProjectionX(Int_t /*px*/, Int_t py)
10216 {
10217 
10218  Int_t nbins = (Int_t)fShowProjection/100;
10219  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10220  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10221 
10222  // Erase old position and draw a line at current position
10223  static int pyold1 = 0;
10224  static int pyold2 = 0;
10225  float uxmin = gPad->GetUxmin();
10226  float uxmax = gPad->GetUxmax();
10227  int pxmin = gPad->XtoAbsPixel(uxmin);
10228  int pxmax = gPad->XtoAbsPixel(uxmax);
10229  Float_t upy = gPad->AbsPixeltoY(py);
10230  Float_t y = gPad->PadtoY(upy);
10231  Int_t biny1 = fH->GetYaxis()->FindBin(y);
10232  Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10233  Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10234  Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10235 
10236  if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10237  gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10238  pyold1 = py1;
10239  pyold2 = py2;
10240 
10241  // Create or set the new canvas proj x
10242  TVirtualPad *padsav = gPad;
10243  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10244  (ULong_t)fH, fShowProjection));
10245  if (c) {
10246  c->Clear();
10247  } else {
10248  fShowProjection = 0;
10249  pyold1 = 0;
10250  pyold2 = 0;
10251  return;
10252  }
10253  c->cd();
10254  c->SetLogy(padsav->GetLogz());
10255  c->SetLogx(padsav->GetLogx());
10256 
10257  // Draw slice corresponding to mouse position
10258  TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10259  TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10260  if (hp) {
10261  hp->SetFillColor(38);
10262  // apply a patch from Oliver Freyermuth to set the title in the projection
10263  // using the range of the projected Y values
10264  if (biny1 == biny2) {
10265  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10266  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10267  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10268  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10269  if (fH->GetYaxis()->GetLabels() != NULL) {
10270  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10271  } else {
10272  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10273  }
10274  } else {
10275  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10276  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10277  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10278  // biny1 is used here to get equal precision no matter how large the binrange is,
10279  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10280  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10281  if (fH->GetYaxis()->GetLabels() != NULL) {
10282  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)));
10283  } else {
10284  hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10285  }
10286  }
10287  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10288  hp->SetYTitle("Number of Entries");
10289  hp->Draw();
10290  c->Update();
10291  padsav->cd();
10292  }
10293 }
10294 
10295 ////////////////////////////////////////////////////////////////////////////////
10296 /// Show projection onto Y.
10297 
10298 void THistPainter::ShowProjectionY(Int_t px, Int_t /*py*/)
10299 {
10300 
10301  Int_t nbins = (Int_t)fShowProjection/100;
10302  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10303  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10304 
10305  // Erase old position and draw a line at current position
10306  static int pxold1 = 0;
10307  static int pxold2 = 0;
10308  float uymin = gPad->GetUymin();
10309  float uymax = gPad->GetUymax();
10310  int pymin = gPad->YtoAbsPixel(uymin);
10311  int pymax = gPad->YtoAbsPixel(uymax);
10312  Float_t upx = gPad->AbsPixeltoX(px);
10313  Float_t x = gPad->PadtoX(upx);
10314  Int_t binx1 = fH->GetXaxis()->FindBin(x);
10315  Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10316  Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10317  Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10318 
10319  if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10320  gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10321  pxold1 = px1;
10322  pxold2 = px2;
10323 
10324  // Create or set the new canvas proj y
10325  TVirtualPad *padsav = gPad;
10326  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10327  (ULong_t)fH, fShowProjection));
10328  if (c) {
10329  c->Clear();
10330  } else {
10331  fShowProjection = 0;
10332  pxold1 = 0;
10333  pxold2 = 0;
10334  return;
10335  }
10336  c->cd();
10337  c->SetLogy(padsav->GetLogz());
10338  c->SetLogx(padsav->GetLogy());
10339 
10340  // Draw slice corresponding to mouse position
10341  TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10342  TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10343  if (hp) {
10344  hp->SetFillColor(38);
10345  // apply a patch from Oliver Freyermuth to set the title in the projection
10346  // using the range of the projected X values
10347  if (binx1 == binx2) {
10348  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10349  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10350  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10351  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10352  if (fH->GetXaxis()->GetLabels() != NULL) {
10353  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10354  } else {
10355  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10356  }
10357  } else {
10358  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10359  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10360  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10361  // binx1 is used here to get equal precision no matter how large the binrange is,
10362  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10363  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10364  if (fH->GetXaxis()->GetLabels() != NULL) {
10365  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)));
10366  } else {
10367  hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10368  }
10369  }
10370  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10371  hp->SetYTitle("Number of Entries");
10372  hp->Draw();
10373  c->Update();
10374  padsav->cd();
10375  }
10376 }
10377 
10378 ////////////////////////////////////////////////////////////////////////////////
10379 /// Show projection (specified by `fShowProjection`) of a `TH3`.
10380 /// The drawing option for the projection is in `fShowOption`.
10381 ///
10382 /// First implementation; R.Brun
10383 ///
10384 /// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10385 
10387 {
10388 
10389  Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10390  if (fH->GetDimension() < 3) {
10391  if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10392  if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10393  }
10394 
10395  gPad->SetDoubleBuffer(0); // turn off double buffer mode
10396  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10397 
10398  // Erase old position and draw a line at current position
10399  TView *view = gPad->GetView();
10400  if (!view) return;
10401  TH3 *h3 = (TH3*)fH;
10402  TAxis *xaxis = h3->GetXaxis();
10403  TAxis *yaxis = h3->GetYaxis();
10404  TAxis *zaxis = h3->GetZaxis();
10405  Double_t u[3],xx[3];
10406 
10407  static TPoint line1[2];//store end points of a line, initialised 0 by default
10408  static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10409  static TPoint line3[2];
10410  static TPoint line4[2];
10411  static TPoint endface1[5];
10412  static TPoint endface2[5];
10413  static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10414  static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10415 
10416  Double_t uxmin = gPad->GetUxmin();
10417  Double_t uxmax = gPad->GetUxmax();
10418  Double_t uymin = gPad->GetUymin();
10419  Double_t uymax = gPad->GetUymax();
10420 
10421  int pxmin = gPad->XtoAbsPixel(uxmin);
10422  int pxmax = gPad->XtoAbsPixel(uxmax);
10423  if (pxmin==pxmax) return;
10424  int pymin = gPad->YtoAbsPixel(uymin);
10425  int pymax = gPad->YtoAbsPixel(uymax);
10426  if (pymin==pymax) return;
10427  Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10428  Double_t cy = (pymax-pymin)/(uymax-uymin);
10429  TVirtualPad *padsav = gPad;
10430  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10431  (ULong_t)fH, fShowProjection));
10432  if (!c) {
10433  fShowProjection = 0;
10434  return;
10435  }
10436 
10437  switch ((Int_t)fShowProjection%100) {
10438  case 1:
10439  // "x"
10440  {
10441  Int_t firstY = yaxis->GetFirst();
10442  Int_t lastY = yaxis->GetLast();
10443  Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10444  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10445  yaxis->SetRange(biny,biny2);
10446  Int_t firstZ = zaxis->GetFirst();
10447  Int_t lastZ = zaxis->GetLast();
10448  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10449  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10450  zaxis->SetRange(binz,binz2);
10451  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10452  if (nbins>1 && line1[0].GetX()) {
10453  gVirtualX->DrawPolyLine(2,line2);
10454  gVirtualX->DrawPolyLine(2,line3);
10455  gVirtualX->DrawPolyLine(2,line4);
10456  gVirtualX->DrawPolyLine(5,endface1);
10457  gVirtualX->DrawPolyLine(5,endface2);
10458  }
10459  xx[0] = xaxis->GetXmin();
10460  xx[2] = zaxis->GetBinCenter(binz);
10461  xx[1] = yaxis->GetBinCenter(biny);
10462  view->WCtoNDC(xx,u);
10463  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10464  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10465  xx[0] = xaxis->GetXmax();
10466  view->WCtoNDC(xx,u);
10467  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10468  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10469  gVirtualX->DrawPolyLine(2,line1);
10470  if (nbins>1) {
10471  xx[0] = xaxis->GetXmin();
10472  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10473  xx[1] = yaxis->GetBinCenter(biny);
10474  view->WCtoNDC(xx,u);
10475  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10476  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10477  xx[0] = xaxis->GetXmax();
10478  view->WCtoNDC(xx,u);
10479  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10480  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10481 
10482  xx[0] = xaxis->GetXmin();
10483  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10484  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10485  view->WCtoNDC(xx,u);
10486  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10487  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10488  xx[0] = xaxis->GetXmax();
10489  view->WCtoNDC(xx,u);
10490  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10491  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10492 
10493  xx[0] = xaxis->GetXmin();
10494  xx[2] = zaxis->GetBinCenter(binz);
10495  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10496  view->WCtoNDC(xx,u);
10497  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10498  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10499  xx[0] = xaxis->GetXmax();
10500  view->WCtoNDC(xx,u);
10501  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10502  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10503 
10504  endface1[0].SetX(line1[0].GetX());
10505  endface1[0].SetY(line1[0].GetY());
10506  endface1[1].SetX(line2[0].GetX());
10507  endface1[1].SetY(line2[0].GetY());
10508  endface1[2].SetX(line3[0].GetX());
10509  endface1[2].SetY(line3[0].GetY());
10510  endface1[3].SetX(line4[0].GetX());
10511  endface1[3].SetY(line4[0].GetY());
10512  endface1[4].SetX(line1[0].GetX());
10513  endface1[4].SetY(line1[0].GetY());
10514 
10515  endface2[0].SetX(line1[1].GetX());
10516  endface2[0].SetY(line1[1].GetY());
10517  endface2[1].SetX(line2[1].GetX());
10518  endface2[1].SetY(line2[1].GetY());
10519  endface2[2].SetX(line3[1].GetX());
10520  endface2[2].SetY(line3[1].GetY());
10521  endface2[3].SetX(line4[1].GetX());
10522  endface2[3].SetY(line4[1].GetY());
10523  endface2[4].SetX(line1[1].GetX());
10524  endface2[4].SetY(line1[1].GetY());
10525 
10526  gVirtualX->DrawPolyLine(2,line2);
10527  gVirtualX->DrawPolyLine(2,line3);
10528  gVirtualX->DrawPolyLine(2,line4);
10529  gVirtualX->DrawPolyLine(5,endface1);
10530  gVirtualX->DrawPolyLine(5,endface2);
10531  }
10532  c->Clear();
10533  c->cd();
10534  TH1 *hp = h3->Project3D("x");
10535  yaxis->SetRange(firstY,lastY);
10536  zaxis->SetRange(firstZ,lastZ);
10537  if (hp) {
10538  hp->SetFillColor(38);
10539  if (nbins == 1)
10540  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10541  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10542  else {
10543  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),
10544  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10545  }
10546  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10547  hp->SetYTitle("Number of Entries");
10548  hp->Draw(fShowOption.Data());
10549  }
10550  }
10551  break;
10552 
10553  case 2:
10554  // "y"
10555  {
10556  Int_t firstX = xaxis->GetFirst();
10557  Int_t lastX = xaxis->GetLast();
10558  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10559  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10560  xaxis->SetRange(binx,binx2);
10561  Int_t firstZ = zaxis->GetFirst();
10562  Int_t lastZ = zaxis->GetLast();
10563  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10564  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10565  zaxis->SetRange(binz,binz2);
10566  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10567  if (nbins>1 && line1[0].GetX()) {
10568  gVirtualX->DrawPolyLine(2,line2);
10569  gVirtualX->DrawPolyLine(2,line3);
10570  gVirtualX->DrawPolyLine(2,line4);
10571  gVirtualX->DrawPolyLine(5,endface1);
10572  gVirtualX->DrawPolyLine(5,endface2);
10573  }
10574  xx[0]=xaxis->GetBinCenter(binx);
10575  xx[2] = zaxis->GetBinCenter(binz);
10576  xx[1] = yaxis->GetXmin();
10577  view->WCtoNDC(xx,u);
10578  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10579  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10580  xx[1] = yaxis->GetXmax();
10581  view->WCtoNDC(xx,u);
10582  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10583  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10584  gVirtualX->DrawPolyLine(2,line1);
10585  if (nbins>1) {
10586  xx[1] = yaxis->GetXmin();
10587  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10588  xx[0] = xaxis->GetBinCenter(binx);
10589  view->WCtoNDC(xx,u);
10590  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10591  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10592  xx[1] = yaxis->GetXmax();
10593  view->WCtoNDC(xx,u);
10594  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10595  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10596 
10597  xx[1] = yaxis->GetXmin();
10598  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10599  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10600  view->WCtoNDC(xx,u);
10601  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10602  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10603  xx[1] = yaxis->GetXmax();
10604  view->WCtoNDC(xx,u);
10605  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10606  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10607 
10608  xx[1] = yaxis->GetXmin();
10609  xx[2] = zaxis->GetBinCenter(binz);
10610  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10611  view->WCtoNDC(xx,u);
10612  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10613  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10614  xx[1] = yaxis->GetXmax();
10615  view->WCtoNDC(xx,u);
10616  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10617  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10618 
10619  endface1[0].SetX(line1[0].GetX());
10620  endface1[0].SetY(line1[0].GetY());
10621  endface1[1].SetX(line2[0].GetX());
10622  endface1[1].SetY(line2[0].GetY());
10623  endface1[2].SetX(line3[0].GetX());
10624  endface1[2].SetY(line3[0].GetY());
10625  endface1[3].SetX(line4[0].GetX());
10626  endface1[3].SetY(line4[0].GetY());
10627  endface1[4].SetX(line1[0].GetX());
10628  endface1[4].SetY(line1[0].GetY());
10629 
10630  endface2[0].SetX(line1[1].GetX());
10631  endface2[0].SetY(line1[1].GetY());
10632  endface2[1].SetX(line2[1].GetX());
10633  endface2[1].SetY(line2[1].GetY());
10634  endface2[2].SetX(line3[1].GetX());
10635  endface2[2].SetY(line3[1].GetY());
10636  endface2[3].SetX(line4[1].GetX());
10637  endface2[3].SetY(line4[1].GetY());
10638  endface2[4].SetX(line1[1].GetX());
10639  endface2[4].SetY(line1[1].GetY());
10640 
10641  gVirtualX->DrawPolyLine(2,line2);
10642  gVirtualX->DrawPolyLine(2,line3);
10643  gVirtualX->DrawPolyLine(2,line4);
10644  gVirtualX->DrawPolyLine(5,endface1);
10645  gVirtualX->DrawPolyLine(5,endface2);
10646  }
10647  c->Clear();
10648  c->cd();
10649  TH1 *hp = h3->Project3D("y");
10650  xaxis->SetRange(firstX,lastX);
10651  zaxis->SetRange(firstZ,lastZ);
10652  if (hp) {
10653  hp->SetFillColor(38);
10654  if (nbins == 1)
10655  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10656  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10657  else
10658  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),
10659  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10660  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10661  hp->SetYTitle("Number of Entries");
10662  hp->Draw(fShowOption.Data());
10663  }
10664  }
10665  break;
10666 
10667  case 3:
10668  // "z"
10669  {
10670  Int_t firstX = xaxis->GetFirst();
10671  Int_t lastX = xaxis->GetLast();
10672  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10673  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10674  xaxis->SetRange(binx,binx2);
10675  Int_t firstY = yaxis->GetFirst();
10676  Int_t lastY = yaxis->GetLast();
10677  Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
10678  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10679  yaxis->SetRange(biny,biny2);
10680  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10681  if (nbins>1 && line1[0].GetX()) {
10682  gVirtualX->DrawPolyLine(2,line2);
10683  gVirtualX->DrawPolyLine(2,line3);
10684  gVirtualX->DrawPolyLine(2,line4);
10685  gVirtualX->DrawPolyLine(5,endface1);
10686  gVirtualX->DrawPolyLine(5,endface2);
10687  }
10688  xx[0] = xaxis->GetBinCenter(binx);
10689  xx[1] = yaxis->GetBinCenter(biny);
10690  xx[2] = zaxis->GetXmin();
10691  view->WCtoNDC(xx,u);
10692  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10693  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10694  xx[2] = zaxis->GetXmax();
10695  view->WCtoNDC(xx,u);
10696  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10697  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10698  gVirtualX->DrawPolyLine(2,line1);
10699  if (nbins>1) {
10700  xx[2] = zaxis->GetXmin();
10701  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10702  xx[0] = xaxis->GetBinCenter(binx);
10703  view->WCtoNDC(xx,u);
10704  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10705  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10706  xx[2] = zaxis->GetXmax();
10707  view->WCtoNDC(xx,u);
10708  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10709  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10710 
10711  xx[2] = zaxis->GetXmin();
10712  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10713  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10714  view->WCtoNDC(xx,u);
10715  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10716  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10717  xx[2] = zaxis->GetXmax();
10718  view->WCtoNDC(xx,u);
10719  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10720  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10721 
10722  xx[2] = zaxis->GetXmin();
10723  xx[1] = yaxis->GetBinCenter(biny);
10724  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10725  view->WCtoNDC(xx,u);
10726  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10727  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10728  xx[2] = zaxis->GetXmax();
10729  view->WCtoNDC(xx,u);
10730  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10731  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10732 
10733  endface1[0].SetX(line1[0].GetX());
10734  endface1[0].SetY(line1[0].GetY());
10735  endface1[1].SetX(line2[0].GetX());
10736  endface1[1].SetY(line2[0].GetY());
10737  endface1[2].SetX(line3[0].GetX());
10738  endface1[2].SetY(line3[0].GetY());
10739  endface1[3].SetX(line4[0].GetX());
10740  endface1[3].SetY(line4[0].GetY());
10741  endface1[4].SetX(line1[0].GetX());
10742  endface1[4].SetY(line1[0].GetY());
10743 
10744  endface2[0].SetX(line1[1].GetX());
10745  endface2[0].SetY(line1[1].GetY());
10746  endface2[1].SetX(line2[1].GetX());
10747  endface2[1].SetY(line2[1].GetY());
10748  endface2[2].SetX(line3[1].GetX());
10749  endface2[2].SetY(line3[1].GetY());
10750  endface2[3].SetX(line4[1].GetX());
10751  endface2[3].SetY(line4[1].GetY());
10752  endface2[4].SetX(line1[1].GetX());
10753  endface2[4].SetY(line1[1].GetY());
10754 
10755  gVirtualX->DrawPolyLine(2,line2);
10756  gVirtualX->DrawPolyLine(2,line3);
10757  gVirtualX->DrawPolyLine(2,line4);
10758  gVirtualX->DrawPolyLine(5,endface1);
10759  gVirtualX->DrawPolyLine(5,endface2);
10760  }
10761  c->Clear();
10762  c->cd();
10763  TH1 *hp = h3->Project3D("z");
10764  xaxis->SetRange(firstX,lastX);
10765  yaxis->SetRange(firstY,lastY);
10766  if (hp) {
10767  hp->SetFillColor(38);
10768  if (nbins == 1)
10769  hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10770  biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
10771  else
10772  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),
10773  biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
10774  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10775  hp->SetYTitle("Number of Entries");
10776  hp->Draw(fShowOption.Data());
10777  }
10778  }
10779  break;
10780 
10781  case 4:
10782  // "xy"
10783  {
10784  Int_t first = zaxis->GetFirst();
10785  Int_t last = zaxis->GetLast();
10786  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10787  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10788  zaxis->SetRange(binz,binz2);
10789  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10790  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10791  xx[0] = xaxis->GetXmin();
10792  xx[1] = yaxis->GetXmax();
10793  xx[2] = zaxis->GetBinCenter(binz);
10794  view->WCtoNDC(xx,u);
10795  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10796  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10797  rect1[4].SetX(rect1[0].GetX());
10798  rect1[4].SetY(rect1[0].GetY());
10799  xx[0] = xaxis->GetXmax();
10800  view->WCtoNDC(xx,u);
10801  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10802  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10803  xx[1] = yaxis->GetXmin();
10804  view->WCtoNDC(xx,u);
10805  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10806  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10807  xx[0] = xaxis->GetXmin();
10808  view->WCtoNDC(xx,u);
10809  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10810  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10811  gVirtualX->DrawPolyLine(5,rect1);
10812  if (nbins>1) {
10813  xx[0] = xaxis->GetXmin();
10814  xx[1] = yaxis->GetXmax();
10815  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10816  view->WCtoNDC(xx,u);
10817  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10818  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10819  rect2[4].SetX(rect2[0].GetX());
10820  rect2[4].SetY(rect2[0].GetY());
10821  xx[0] = xaxis->GetXmax();
10822  view->WCtoNDC(xx,u);
10823  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10824  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10825  xx[1] = yaxis->GetXmin();
10826  view->WCtoNDC(xx,u);
10827  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10828  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10829  xx[0] = xaxis->GetXmin();
10830  view->WCtoNDC(xx,u);
10831  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10832  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10833  gVirtualX->DrawPolyLine(5,rect2);
10834  }
10835 
10836  c->Clear();
10837  c->cd();
10838  TH2 *hp = (TH2*)h3->Project3D("xy");
10839  zaxis->SetRange(first,last);
10840  if (hp) {
10841  hp->SetFillColor(38);
10842  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
10843  else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
10844  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10845  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10846  hp->SetZTitle("Number of Entries");
10847  hp->Draw(fShowOption.Data());
10848  }
10849  }
10850  break;
10851 
10852  case 5:
10853  // "yx"
10854  {
10855  Int_t first = zaxis->GetFirst();
10856  Int_t last = zaxis->GetLast();
10857  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10858  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10859  zaxis->SetRange(binz,binz2);
10860  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10861  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10862  xx[0] = xaxis->GetXmin();
10863  xx[1] = yaxis->GetXmax();
10864  xx[2] = zaxis->GetBinCenter(binz);
10865  view->WCtoNDC(xx,u);
10866  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10867  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10868  rect1[4].SetX(rect1[0].GetX());
10869  rect1[4].SetY(rect1[0].GetY());
10870  xx[0] = xaxis->GetXmax();
10871  view->WCtoNDC(xx,u);
10872  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10873  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10874  xx[1] = yaxis->GetXmin();
10875  view->WCtoNDC(xx,u);
10876  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10877  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10878  xx[0] = xaxis->GetXmin();
10879  view->WCtoNDC(xx,u);
10880  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10881  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10882  gVirtualX->DrawPolyLine(5,rect1);
10883  if (nbins>1) {
10884  xx[0] = xaxis->GetXmin();
10885  xx[1] = yaxis->GetXmax();
10886  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10887  view->WCtoNDC(xx,u);
10888  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10889  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10890  rect2[4].SetX(rect2[0].GetX());
10891  rect2[4].SetY(rect2[0].GetY());
10892  xx[0] = xaxis->GetXmax();
10893  view->WCtoNDC(xx,u);
10894  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10895  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10896  xx[1] = yaxis->GetXmin();
10897  view->WCtoNDC(xx,u);
10898  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10899  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10900  xx[0] = xaxis->GetXmin();
10901  view->WCtoNDC(xx,u);
10902  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10903  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10904  gVirtualX->DrawPolyLine(5,rect2);
10905  }
10906  c->Clear();
10907  c->cd();
10908  TH2 *hp = (TH2*)h3->Project3D("yx");
10909  zaxis->SetRange(first,last);
10910  if (hp) {
10911  hp->SetFillColor(38);
10912  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
10913  else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
10914  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10915  hp->SetYTitle(fH->GetYaxis()->GetTitle());
10916  hp->SetZTitle("Number of Entries");
10917  hp->Draw(fShowOption.Data());
10918  }
10919  }
10920  break;
10921 
10922  case 6:
10923  // "xz"
10924  {
10925  Int_t first = yaxis->GetFirst();
10926  Int_t last = yaxis->GetLast();
10927  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10928  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10929  yaxis->SetRange(biny,biny2);
10930  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10931  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10932  xx[0] = xaxis->GetXmin();
10933  xx[2] = zaxis->GetXmax();
10934  xx[1] = yaxis->GetBinCenter(biny);
10935  view->WCtoNDC(xx,u);
10936  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10937  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10938  rect1[4].SetX(rect1[0].GetX());
10939  rect1[4].SetY(rect1[0].GetY());
10940  xx[0] = xaxis->GetXmax();
10941  view->WCtoNDC(xx,u);
10942  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10943  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10944  xx[2] = zaxis->GetXmin();
10945  view->WCtoNDC(xx,u);
10946  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10947  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10948  xx[0] = xaxis->GetXmin();
10949  view->WCtoNDC(xx,u);
10950  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10951  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10952  gVirtualX->DrawPolyLine(5,rect1);
10953  if (nbins>1) {
10954  xx[0] = xaxis->GetXmin();
10955  xx[2] = zaxis->GetXmax();
10956  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10957  view->WCtoNDC(xx,u);
10958  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10959  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10960  rect2[4].SetX(rect2[0].GetX());
10961  rect2[4].SetY(rect2[0].GetY());
10962  xx[0] = xaxis->GetXmax();
10963  view->WCtoNDC(xx,u);
10964  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10965  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10966  xx[2] = zaxis->GetXmin();
10967  view->WCtoNDC(xx,u);
10968  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10969  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10970  xx[0] = xaxis->GetXmin();
10971  view->WCtoNDC(xx,u);
10972  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10973  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10974  gVirtualX->DrawPolyLine(5,rect2);
10975  }
10976  c->Clear();
10977  c->cd();
10978  TH2 *hp = (TH2*)h3->Project3D("xz");
10979  yaxis->SetRange(first,last);
10980  if (hp) {
10981  hp->SetFillColor(38);
10982  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10983  else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10984  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10985  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10986  hp->SetZTitle("Number of Entries");
10987  hp->Draw(fShowOption.Data());
10988  }
10989  }
10990  break;
10991 
10992  case 7:
10993  // "zx"
10994  {
10995  Int_t first = yaxis->GetFirst();
10996  Int_t last = yaxis->GetLast();
10997  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10998  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10999  yaxis->SetRange(biny,biny2);
11000  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11001  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11002  xx[0] = xaxis->GetXmin();
11003  xx[2] = zaxis->GetXmax();
11004  xx[1] = yaxis->GetBinCenter(biny);
11005  view->WCtoNDC(xx,u);
11006  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11007  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11008  rect1[4].SetX(rect1[0].GetX());
11009  rect1[4].SetY(rect1[0].GetY());
11010  xx[0] = xaxis->GetXmax();
11011  view->WCtoNDC(xx,u);
11012  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11013  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11014  xx[2] = zaxis->GetXmin();
11015  view->WCtoNDC(xx,u);
11016  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11017  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11018  xx[0] = xaxis->GetXmin();
11019  view->WCtoNDC(xx,u);
11020  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11021  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11022  gVirtualX->DrawPolyLine(5,rect1);
11023  if (nbins>1) {
11024  xx[0] = xaxis->GetXmin();
11025  xx[2] = zaxis->GetXmax();
11026  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11027  view->WCtoNDC(xx,u);
11028  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11029  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11030  rect2[4].SetX(rect2[0].GetX());
11031  rect2[4].SetY(rect2[0].GetY());
11032  xx[0] = xaxis->GetXmax();
11033  view->WCtoNDC(xx,u);
11034  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11035  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11036  xx[2] = zaxis->GetXmin();
11037  view->WCtoNDC(xx,u);
11038  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11039  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11040  xx[0] = xaxis->GetXmin();
11041  view->WCtoNDC(xx,u);
11042  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11043  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11044  gVirtualX->DrawPolyLine(5,rect2);
11045  }
11046  c->Clear();
11047  c->cd();
11048  TH2 *hp = (TH2*)h3->Project3D("zx");
11049  yaxis->SetRange(first,last);
11050  if (hp) {
11051  hp->SetFillColor(38);
11052  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11053  else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11054  hp->SetXTitle(fH->GetXaxis()->GetTitle());
11055  hp->SetYTitle(fH->GetZaxis()->GetTitle());
11056  hp->SetZTitle("Number of Entries");
11057  hp->Draw(fShowOption.Data());
11058  }
11059  }
11060  break;
11061 
11062  case 8:
11063  // "yz"
11064  {
11065  Int_t first = xaxis->GetFirst();
11066  Int_t last = xaxis->GetLast();
11067  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11068  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11069  xaxis->SetRange(binx,binx2);
11070  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11071  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11072  xx[2] = zaxis->GetXmin();
11073  xx[1] = yaxis->GetXmax();
11074  xx[0] = xaxis->GetBinCenter(binx);
11075  view->WCtoNDC(xx,u);
11076  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11077  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11078  rect1[4].SetX(rect1[0].GetX());
11079  rect1[4].SetY(rect1[0].GetY());
11080  xx[2] = zaxis->GetXmax();
11081  view->WCtoNDC(xx,u);
11082  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11083  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11084  xx[1] = yaxis->GetXmin();
11085  view->WCtoNDC(xx,u);
11086  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11087  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11088  xx[2] = zaxis->GetXmin();
11089  view->WCtoNDC(xx,u);
11090  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11091  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11092  gVirtualX->DrawPolyLine(5,rect1);
11093  if (nbins>1) {
11094  xx[2] = zaxis->GetXmin();
11095  xx[1] = yaxis->GetXmax();
11096  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11097  view->WCtoNDC(xx,u);
11098  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11099  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11100  rect2[4].SetX(rect2[0].GetX());
11101  rect2[4].SetY(rect2[0].GetY());
11102  xx[2] = zaxis->GetXmax();
11103  view->WCtoNDC(xx,u);
11104  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11105  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11106  xx[1] = yaxis->GetXmin();
11107  view->WCtoNDC(xx,u);
11108  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11109  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11110  xx[2] = zaxis->GetXmin();
11111  view->WCtoNDC(xx,u);
11112  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11113  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11114  gVirtualX->DrawPolyLine(5,rect2);
11115  }
11116  c->Clear();
11117  c->cd();
11118  TH2 *hp = (TH2*)h3->Project3D("yz");
11119  xaxis->SetRange(first,last);
11120  if (hp) {
11121  hp->SetFillColor(38);
11122  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11123  else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11124  hp->SetXTitle(fH->GetZaxis()->GetTitle());
11125  hp->SetYTitle(fH->GetYaxis()->GetTitle());
11126  hp->SetZTitle("Number of Entries");
11127  hp->Draw(fShowOption.Data());
11128  }
11129  }
11130  break;
11131 
11132  case 9:
11133  // "zy"
11134  {
11135  Int_t first = xaxis->GetFirst();
11136  Int_t last = xaxis->GetLast();
11137  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11138  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11139  xaxis->SetRange(binx,binx2);
11140  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11141  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11142  xx[2] = zaxis->GetXmin();
11143  xx[1] = yaxis->GetXmax();
11144  xx[0] = xaxis->GetBinCenter(binx);
11145  view->WCtoNDC(xx,u);
11146  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11147  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11148  rect1[4].SetX(rect1[0].GetX());
11149  rect1[4].SetY(rect1[0].GetY());
11150  xx[2] = zaxis->GetXmax();
11151  view->WCtoNDC(xx,u);
11152  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11153  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11154  xx[1] = yaxis->GetXmin();
11155  view->WCtoNDC(xx,u);
11156  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11157  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11158  xx[2] = zaxis->GetXmin();
11159  view->WCtoNDC(xx,u);
11160  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11161  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11162  gVirtualX->DrawPolyLine(5,rect1);
11163  if (nbins>1) {
11164  xx[2] = zaxis->GetXmin();
11165  xx[1] = yaxis->GetXmax();
11166  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11167  view->WCtoNDC(xx,u);
11168  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11169  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11170  rect2[4].SetX(rect2[0].GetX());
11171  rect2[4].SetY(rect2[0].GetY());
11172  xx[2] = zaxis->GetXmax();
11173  view->WCtoNDC(xx,u);
11174  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11175  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11176  xx[1] = yaxis->GetXmin();
11177  view->WCtoNDC(xx,u);
11178  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11179  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11180  xx[2] = zaxis->GetXmin();
11181  view->WCtoNDC(xx,u);
11182  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11183  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11184  gVirtualX->DrawPolyLine(5,rect2);
11185  }
11186  c->Clear();
11187  c->cd();
11188  TH2 *hp = (TH2*)h3->Project3D("zy");
11189  xaxis->SetRange(first,last);
11190  if (hp) {
11191  hp->SetFillColor(38);
11192  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11193  else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11194  hp->SetXTitle(fH->GetYaxis()->GetTitle());
11195  hp->SetYTitle(fH->GetZaxis()->GetTitle());
11196  hp->SetZTitle("Number of Entries");
11197  hp->Draw(fShowOption.Data());
11198  }
11199  }
11200  break;
11201  }
11202  c->Update();
11203  padsav->cd();
11204 }
const int nx
Definition: kalman.C:16
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:1954
virtual void SetZTitle(const char *title)
Definition: TH1.h:391
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:791
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Double_t GetMaximumStored() const
Definition: TH1.h:269
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:241
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:7666
virtual void PaintFrame()
Calculate range and clear pad (canvas).
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:843
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:311
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:294
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:409
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:561
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:234
virtual void SetLogy(Int_t value=1)=0
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:375
Double_t * GetX() const
Definition: TPolyLine.h:54
virtual void PaintH3Box(Int_t iopt)
Control function to draw a 3D histogram with boxes.
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:2201
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
Bool_t IsHorizontal()
Definition: TCandle.h:105
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:649
Double_t ylowedge
low edge of axis
Definition: Hparam.h:32
Color_t GetTitleTextColor() const
Definition: TStyle.h:256
virtual Double_t GetBinError(Int_t bin) const
Returns the value of error associated to bin number bin.
Definition: TH2Poly.cxx:774
Double_t GetX2() const
Definition: TBox.h:53
Int_t GetNumberContours() const
Definition: TStyle.h:225
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:1945
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:193
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:236
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:1627
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:56
Create a Box.
Definition: TBox.h:24
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
Double_t GetHistTopMargin() const
Definition: TStyle.h:223
virtual Double_t GetMinimumStored() const
Definition: TH1.h:273
virtual Double_t GetNormFactor() const
Definition: TH1.h:281
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:1849
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:2328
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7607
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
virtual void Update()=0
#define mark(osub)
Definition: triangle.c:1206
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:159
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
#define BIT(n)
Definition: Rtypes.h:75
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:311
TH1 * h
Definition: legend2.C:5
Definition: Rtypes.h:55
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:7103
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4639
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:7127
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:183
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:2288
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:6794
virtual Int_t GetNbinsZ() const
Definition: TH1.h:279
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:376
#define gROOT
Definition: TROOT.h:375
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:6763
Float_t GetEndErrorSize() const
Definition: TStyle.h:171
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:587
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:135
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:2468
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1825
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:129
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:700
tomato 1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:551
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:688
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:1187
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
virtual void SetYTitle(const char *title)
Definition: TH1.h:390
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:310
TArc * a
Definition: textangle.C:12
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:1656
int nbins[3]
void SetHistogram(TH1D *proj)
Definition: TCandle.h:113
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:3176
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
#define NULL
Definition: RtypesCore.h:88
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8264
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
static std::string format(double x, double y, int digits, int width)
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:265
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
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
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
const char * GetFitFormat() const
Definition: TStyle.h:185
void SetY(SCoord_t y)
Definition: TPoint.h:50
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:99
Float_t delta
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
Double_t ymax
maximum value along y
Definition: Hparam.h:34
void SetLog(int x, int y)
Definition: TCandle.h:109
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)
void Reset()
Definition: TCollection.h:156
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:624
void SetOption(CandleOption opt)
Definition: TCandle.h:108
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:628
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:687
double beta(double x, double y)
Calculates the beta function.
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:501
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:257
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:1218
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:1213
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:927
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:254
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:263
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:7535
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:1956
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:1616
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:2601
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:803
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:1936
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:258
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:2345
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:800
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:411
const Double_t * GetBuffer() const
Definition: TH1.h:219
TText * tt
Definition: textangle.C:16
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.
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:312
clip to the frame boundary
Definition: TGraph.h:70
const int ny
Definition: kalman.C:17
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:228
virtual Int_t GetLogx() const =0
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:36
Double_t Log10(Double_t x)
Definition: TMath.h:652
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2460
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
constexpr Double_t DegToRad()
Definition: TMath.h:64
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
TText * th2
Definition: textalign.C:17
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:2495
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:209
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:1365
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:41
Float_t GetStatX() const
Definition: TStyle.h:248
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:264
virtual void Show()
Double_t GetYMin()
Returns the minimum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1473
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:1437
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:169
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:735
constexpr Double_t Pi()
Definition: TMath.h:40
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2042
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:427
Style_t GetStatStyle() const
Definition: TStyle.h:246
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.
user specified contour levels
Definition: TH1.h:149
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:6868
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:2195
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:348
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:761
Definition: TPoint.h:31
A doubly linked list.
Definition: TList.h:43
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:7847
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:6855
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:483
TObject * GetPolygon() const
Definition: TH2Poly.h:38
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:253
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:322
Float_t GetErrorX() const
Definition: TStyle.h:172
virtual void SetLogx(Int_t value=1)=0
const char * GetPaintTextFormat() const
Definition: TStyle.h:234
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
don&#39;t draw stats box
Definition: TH1.h:148
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:176
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:1817
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:889
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:738
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:561
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.
TRandom2 r(17)
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:169
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2514
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:6938
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
Float_t GetTitleH() const
Definition: TStyle.h:267
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2851
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:244
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
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:249
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:250
tomato 2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:249
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:482
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:679
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:436
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:8325
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:222
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
TMarker * m
Definition: textangle.C:8
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:388
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
TString fShowOption
Definition: THistPainter.h:65
void SetWidth(const Double_t width)
Definition: TCandle.h:112
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.
TLine * l
Definition: textangle.C:4
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:1707
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:7564
TAxis * GetYaxis()
Definition: TH1.h:301
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:315
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:286
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
void SetName(const char *name)
Definition: TCollection.h:111
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:506
tomato 1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:594
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:4541
Definition: graph.py:1
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:801
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:59
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()
Definition: TMath.h:74
virtual TObjLink * FirstLink() const
Definition: TList.h:97
int Curve
"C" A smooth Curve is drawn.
Definition: Hoption.h:29
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:523
Double_t Cos(Double_t)
Definition: TMath.h:551
Color_t GetTitleFillColor() const
Definition: TStyle.h:255
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:7751
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
const Bool_t kFALSE
Definition: RtypesCore.h:92
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:3163
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:394
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:259
Float_t GetTitleW() const
Definition: TStyle.h:266
virtual Int_t GetSumw2N() const
Definition: TH1.h:295
Double_t GetChisquare() const
Definition: TF1.h:398
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:512
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:1197
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:8275
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:58
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:336
static TString gStringSkewness
double f(double x)
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:8191
double Double_t
Definition: RtypesCore.h:55
Int_t GetOptStat() const
Definition: TStyle.h:229
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:170
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:266
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:1646
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:510
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.
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition: TH2Poly.cxx:858
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
The TH1 histogram class.
Definition: TH1.h:56
Int_t xlast
last bin number along X
Definition: Hparam.h:44
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:4054
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:316
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:698
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:243
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:2885
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:302
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()
Definition: TMath.h:60
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:245
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:435
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:1666
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:389
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:69
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:55
static TString gStringIntegral
virtual void Add(TObject *obj)
Definition: TList.h:77
Double_t xmin
minimum value along X
Definition: Hparam.h:29
static TString gStringStdDevX
double f2(const double *x)
static TString gStringKurtosisY
const UInt_t kCannotRotate
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:466
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:251
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
1-Dim function class
Definition: TF1.h:150
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:548
static TString gStringKurtosis
Double_t GetArea()
Returns the area of the bin.
Definition: TH2Poly.cxx:1335
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:822
THist< 1, double, THistStatContent, THistStatUncertainty > TH1D
Definition: THist.hxx:310
#define gPad
Definition: TVirtualPad.h:284
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8222
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1236
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:320
Float_t GetBarOffset() const
Definition: TStyle.h:168
Style_t GetTitleStyle() const
Definition: TStyle.h:257
The TGraphDelaunay painting class.
Double_t allchan
integrated sum of contents
Definition: Hparam.h:40
void ResetBit(UInt_t f)
Definition: TObject.h:158
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)
Change (i.e.
Definition: TH1.cxx:6028
const int strategy
Definition: testNdimFit.cxx:46
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
def normal(shape, name=None)
virtual Int_t GetNbinsX() const
Definition: TH1.h:277
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:1800
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:591
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:242
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:364
virtual Int_t GetSize() const
Definition: TCollection.h:89
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:1401
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
TList * GetListOfFunctions() const
Definition: TH1.h:224
The palette painting class.
Definition: TPaletteAxis.h:29
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:317
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:57
static TString gStringMeanY
const Bool_t kTRUE
Definition: RtypesCore.h:91
Int_t Nint(T x)
Definition: TMath.h:607
virtual void PadRange(Int_t rback)=0
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:6817
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
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition: TH2Poly.cxx:810
Double_t Tan(Double_t)
Definition: TMath.h:554
constexpr Double_t PiOver2()
Definition: TMath.h:48
virtual Float_t GetBarWidth() const
Definition: TH1.h:237
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:1093
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")
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
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:859
TAxis * GetXaxis()
Definition: TH1.h:300
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:247
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:278
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:8175
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
don&#39;t draw the histogram title
Definition: TH1.h:153
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:303
Int_t GetOptTitle() const
Definition: TStyle.h:230
const Int_t kNMAX
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
tomato 2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:290
const char * Data() const
Definition: TString.h:347
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:110
Double_t ATan(Double_t)
Definition: TMath.h:578