Logo ROOT   6.08/07
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 ////////////////////////////////////////////////////////////////////////////////
69 /*! \class THistPainter
70 \ingroup Histpainter
71 \brief The histogram painter class. Implements all histograms' drawing's options.
72 
73 - [Introduction](#HP00)
74 - [Histograms' plotting options](#HP01)
75  - [Options supported for 1D and 2D histograms](#HP01a)
76  - [Options supported for 1D histograms](#HP01b)
77  - [Options supported for 2D histograms](#HP01c)
78  - [Options supported for 3D histograms](#HP01d)
79  - [Options supported for histograms' stacks (THStack)](#HP01e)
80 - [Setting the Style](#HP02)
81 - [Setting line, fill, marker, and text attributes](#HP03)
82 - [Setting Tick marks on the histogram axis](#HP04)
83 - [Giving titles to the X, Y and Z axis](#HP05)
84 - [The option "SAME"](#HP060)
85  - [Limitations](#HP060a)
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 option](#HP140)
97 - [The VIOLIN option](#HP141)
98 - [The TEXT and TEXTnn Option](#HP15)
99 - [The CONTour options](#HP16)
100  - [The LIST option](#HP16a)
101 - [The LEGO options](#HP17)
102 - [The "SURFace" options](#HP18)
103 - [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
104 - [Base line for bar-charts and lego plots](#HP20)
105 - [TH2Poly Drawing](#HP20a)
106 - [The SPEC option](#HP21)
107 - [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
108 - [Setting the color palette](#HP23)
109 - [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
110 - [Drawing options for 3D histograms](#HP25)
111 - [Drawing option for histograms' stacks](#HP26)
112 - [Drawing of 3D implicit functions](#HP27)
113 - [Associated functions drawing](#HP28)
114 - [Drawing using OpenGL](#HP29)
115  - [General information: plot types and supported options](#HP29a)
116  - [TH3 as color boxes](#HP290)
117  - [TH3 as boxes (spheres)](#HP29b)
118  - [TH3 as iso-surface(s)](#HP29c)
119  - [TF3 (implicit function)](#HP29d)
120  - [Parametric surfaces](#HP29e)
121  - [Interaction with the plots](#HP29f)
122  - [Selectable parts](#HP29g)
123  - [Rotation and zooming](#HP29h)
124  - [Panning](#HP29i)
125  - [Box cut](#HP29j)
126  - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
127  - [Surface with option "GLSURF"](#HP29l)
128  - [TF3](#HP29m)
129  - [Box](#HP29n)
130  - [Iso](#HP29o)
131  - [Parametric plot](#HP29p)
132 
133 
134 ## <a name="HP00"></a> Introduction
135 
136 
137 Histograms are drawn via the `THistPainter` class. Each histogram has a
138 pointer to its own painter (to be usable in a multithreaded program). When the
139 canvas has to be redrawn, the `Paint` function of each objects in the
140 pad is called. In case of histograms, `TH1::Paint` invokes directly
141 `THistPainter::Paint`.
142 
143 To draw a histogram `h` it is enough to do:
144 
145  h->Draw();
146 
147 `h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
148 be drawn, the `Draw()` method can be invoked with an option. For instance
149 to draw a 2D histogram as a lego plot it is enough to do:
150 
151  h->Draw("lego");
152 
153 `THistPainter` offers many options to paint 1D, 2D and 3D histograms.
154 
155 When the `Draw()` method of a histogram is called for the first time
156 (`TH1::Draw`), it creates a `THistPainter` object and saves a
157 pointer to this "painter" as a data member of the histogram. The
158 `THistPainter` class specializes in the drawing of histograms. It is
159 separated from the histogram so that one can have histograms without the
160 graphics overhead, for example in a batch program. Each histogram having its own
161 painter (rather than a central singleton painter painting all histograms), allows
162 two histograms to be drawn in two threads without overwriting the painter's
163 values.
164 
165 When a displayed histogram is filled again, there is no need to call the
166 `Draw()` method again; the image will be refreshed the next time the
167 pad will be updated.
168 
169 A pad is updated after one of these three actions:
170 
171 1. a carriage control on the ROOT command line,
172 2. a click inside the pad,
173 3. a call to `TPad::Update`.
174 
175 
176 By default a call to `TH1::Draw()` clears the pad of all objects
177 before drawing the new image of the histogram. One can use the `SAME`
178 option to leave the previous display intact and superimpose the new histogram.
179 The same histogram can be drawn with different graphics options in different
180 pads.
181 
182 When a displayed histogram is deleted, its image is automatically removed
183 from the pad.
184 
185 To create a copy of the histogram when drawing it, one can use
186 `TH1::DrawClone()`. This will clone the histogram and allow to change
187 and delete the original one without affecting the clone.
188 
189 
190 ### <a name="HP01"></a> Histograms' plotting options
191 
192 
193 Most options can be concatenated with or without spaces or commas, for example:
194 
195  h->Draw("E1 SAME");
196 
197 The options are not case sensitive:
198 
199  h->Draw("e1 same");
200 
201 
202 The default drawing option can be set with `TH1::SetOption` and retrieve
203 using `TH1::GetOption`:
204 
205  root [0] h->Draw(); // Draw "h" using the standard histogram representation.
206  root [1] h->Draw("E"); // Draw "h" using error bars
207  root [3] h->SetOption("E"); // Change the default drawing option for "h"
208  root [4] h->Draw(); // Draw "h" using error bars
209  root [5] h->GetOption(); // Retrieve the default drawing option for "h"
210  (const Option_t* 0xa3ff948)"E"
211 
212 
213 #### <a name="HP01a"></a> Options supported for 1D and 2D histograms
214 
215 | Option | Description |
216 |----------|-------------------------------------------------------------------|
217 | "E" | Draw error bars. |
218 | "AXIS" | Draw only axis. |
219 | "AXIG" | Draw only grid (if the grid is requested). |
220 | <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). |
221 | "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
222 | "SAME" | Superimpose on previous picture in the same pad. |
223 | "LEGO" | Draw a lego plot with hidden line removal. |
224 | "LEGO1" | Draw a lego plot with hidden surface removal. |
225 | "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.|
226 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
227 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
228 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
229 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
230 | "X+" | The X-axis is drawn on the top side of the plot. |
231 | "Y+" | The Y-axis is drawn on the right side of the plot. |
232 
233 #### <a name="HP01b"></a> Options supported for 1D histograms
234 
235 | Option | Description |
236 |----------|-------------------------------------------------------------------|
237 | " " | Default. |
238 | "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.|
239 | "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
240 | "B" | Bar chart option.|
241 | "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
242 | "HBAR" | Like option "BAR", but bars are drawn horizontally.|
243 | "C" | Draw a smooth Curve through the histogram bins.|
244 | "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
245 | "E1" | Draw error bars with perpendicular lines at the edges.|
246 | "E2" | Draw error bars with rectangles.|
247 | "E3" | Draw a fill area through the end points of the vertical error bars.|
248 | "E4" | Draw a smoothed filled area through the end points of the error bars.|
249 | "E5" | Like E3 but ignore the bins with 0 contents.|
250 | "E6" | Like E4 but ignore the bins with 0 contents.|
251 | "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
252 | "L" | Draw a line through the bin contents.|
253 | "P" | Draw current marker at each bin except empty bins.|
254 | "P0" | Draw current marker at each bin including empty bins.|
255 | "PIE" | Draw histogram as a Pie Chart.|
256 | "*H" | Draw histogram with a * at each bin.|
257 | "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.|
258 
259 
260 #### <a name="HP01c"></a> Options supported for 2D histograms
261 
262 | Option | Description |
263 |-----------|------------------------------------------------------------------|
264 | " " | Default (scatter plot).|
265 | "ARR" | Arrow mode. Shows gradient between adjacent cells.|
266 | "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.|
267 | "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.|
268 | "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.|
269 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
270 | "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
271 | "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
272 | "CANDLE" | Draw a candle plot along X axis.|
273 | "CANDLEX" | Same as "CANDLE".|
274 | "CANDLEY" | Draw a candle plot along Y axis.|
275 | "VIOLIN" | Draw a violin plot along X axis.|
276 | "VIOLINX" | Same as "VIOLIN".|
277 | "VIOLINY" | Draw a violin plot along Y axis.|
278 | "CONT" | Draw a contour plot (same as CONT0).|
279 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
280 | "CONT1" | Draw a contour plot using line styles to distinguish contours.|
281 | "CONT2" | Draw a contour plot using the same line style for all contours.|
282 | "CONT3" | Draw a contour plot using fill area colors.|
283 | "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
284 | "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
285 | "LIST" | Generate a list of TGraph objects for each contour.|
286 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
287 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
288 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
289 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
290 | "SURF" | Draw a surface plot with hidden line removal.|
291 | "SURF1" | Draw a surface plot with hidden surface removal.|
292 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
293 | "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
294 | "SURF4" | Draw a surface using Gouraud shading.|
295 | "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.|
296 | "FB" | With LEGO or SURFACE, suppress the Front-Box.|
297 | "BB" | With LEGO or SURFACE, suppress the Back-Box.|
298 | "A" | With LEGO or SURFACE, suppress the axis.|
299 | "SCAT" | Draw a scatter-plot (default).|
300 | "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
301 
302 
303 #### <a name="HP01d"></a> Options supported for 3D histograms
304 
305 | Option | Description |
306 |----------|-------------------------------------------------------------------|
307 | " " | Default (scatter plot).|
308 | "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)`.|
309 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value.|
310 | "LEGO" | Same as `BOX`.|
311 
312 
313 #### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
314 
315 | Option | Description |
316 |------------|-----------------------------------------------------------------|
317 | " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
318 | "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
319 | "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
320 | "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.|
321 
322 
323 
324 ### <a name="HP02"></a> Setting the Style
325 
326 
327 Histograms use the current style (`gStyle`). When one changes the current
328 style and would like to propagate the changes to the histogram,
329 `TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
330 each histogram is needed.
331 
332 To force all the histogram to use the current style use:
333 
334  gROOT->ForceStyle();
335 
336 All the histograms read after this call will use the current style.
337 
338 
339 ### <a name="HP03"></a> Setting line, fill, marker, and text attributes
340 
341 
342 The histogram classes inherit from the attribute classes:
343 `TAttLine`, `TAttFill` and `TAttMarker`.
344 See the description of these classes for the list of options.
345 
346 
347 ### <a name="HP04"></a> Setting Tick marks on the histogram axis
348 
349 
350 The `TPad::SetTicks` method specifies the type of tick marks on the axis.
351 If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
352 
353  tx = 1; tick marks on top side are drawn (inside)
354  tx = 2; tick marks and labels on top side are drawn
355  ty = 1; tick marks on right side are drawn (inside)
356  ty = 2; tick marks and labels on right side are drawn
357 
358 By default only the left Y axis and X bottom axis are drawn
359 (`tx = ty = 0`)
360 
361 `TPad::SetTicks(tx,ty)` allows to set these options.
362 See also The `TAxis` functions to set specific axis attributes.
363 
364 In case multiple color filled histograms are drawn on the same pad, the fill
365 area may hide the axis tick marks. One can force a redraw of the axis over all
366 the histograms by calling:
367 
368  gPad->RedrawAxis();
369 
370 
371 
372 ### <a name="HP05"></a> Giving titles to the X, Y and Z axis
373 
374 
375  h->GetXaxis()->SetTitle("X axis title");
376  h->GetYaxis()->SetTitle("Y axis title");
377 
378 The histogram title and the axis titles can be any `TLatex` string.
379 The titles are part of the persistent histogram.
380 
381 
382 ### <a name="HP060"></a> The option "SAME"
383 
384 
385 By default, when an histogram is drawn, the current pad is cleared before
386 drawing. In order to keep the previous drawing and draw on top of it the
387 option `SAME` should be use. The histogram drawn with the option
388 `SAME` uses the coordinates system available in the current pad.
389 
390 This option can be used alone or combined with any valid drawing option but
391 some combinations must be use with care.
392 
393 #### <a name="HP060a"></a> Limitations
394 
395 - It does not work when combined with the `LEGO` and `SURF` options unless the
396  histogram plotted with the option `SAME` has exactly the same
397  ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
398  lego plots [histograms' stacks](#HP26) should be used.</li>
399 
400 
401 ### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
402 
403 
404 The following example creates two histograms, the second histogram is the bins
405 integral of the first one. It shows a procedure to draw the two histograms in
406 the same pad and it draws the scale of the second histogram using a new vertical
407 axis on the right side. See also the tutorial `transpad.C` for a variant
408 of this example.
409 
410 Begin_Macro(source)
411 {
412  TCanvas *c1 = new TCanvas("c1","c1",600,400);
413  // create/fill draw h1
414  gStyle->SetOptStat(kFALSE);
415  TH1F *h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
416  Int_t i;
417  for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
418  h1->Draw();
419  c1->Update();
420 
421  // create hint1 filled with the bins integral of h1
422  TH1F *hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
423  Float_t sum = 0;
424  for (i=1;i<=100;i++) {
425  sum += h1->GetBinContent(i);
426  hint1->SetBinContent(i,sum);
427  }
428 
429  // scale hint1 to the pad coordinates
430  Float_t rightmax = 1.1*hint1->GetMaximum();
431  Float_t scale = gPad->GetUymax()/rightmax;
432  hint1->SetLineColor(kRed);
433  hint1->Scale(scale);
434  hint1->Draw("same");
435 
436  // draw an axis on the right side
437  TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
438  gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
439  axis->SetLineColor(kRed);
440  axis->SetTextColor(kRed);
441  axis->Draw();
442  return c1;
443 }
444 End_Macro
445 
446 
447 ### <a name="HP07"></a> Statistics Display
448 
449 
450 The type of information shown in the histogram statistics box can be selected
451 with:
452 
453  gStyle->SetOptStat(mode);
454 
455 The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
456 
457  mode = ksiourmen (default = 000001111)
458  k = 1; kurtosis printed
459  k = 2; kurtosis and kurtosis error printed
460  s = 1; skewness printed
461  s = 2; skewness and skewness error printed
462  i = 1; integral of bins printed
463  i = 2; integral of bins with option "width" printed
464  o = 1; number of overflows printed
465  u = 1; number of underflows printed
466  r = 1; standard deviation printed
467  r = 2; standard deviation and standard deviation error printed
468  m = 1; mean value printed
469  m = 2; mean and mean error values printed
470  e = 1; number of entries printed
471  n = 1; name of histogram is printed
472 
473 For example:
474 
475  gStyle->SetOptStat(11);
476 
477 displays only the name of histogram and the number of entries, whereas:
478 
479  gStyle->SetOptStat(1101);
480 
481 displays the name of histogram, mean value and standard deviation.
482 
483 <b>WARNING 1:</b> never do:
484 
485  gStyle->SetOptStat(0001111);
486 
487 but instead do:
488 
489  gStyle->SetOptStat(1111);
490 
491 because `0001111` will be taken as an octal number!
492 
493 <b>WARNING 2:</b> for backward compatibility with older versions
494 
495  gStyle->SetOptStat(1);
496 
497 is taken as:
498 
499  gStyle->SetOptStat(1111)
500 
501 To print only the name of the histogram do:
502 
503  gStyle->SetOptStat(1000000001);
504 
505 <b>NOTE</b> that in case of 2D histograms, when selecting only underflow
506 (10000) or overflow (100000), the statistics box will show all combinations
507 of underflow/overflows and not just one single number.
508 
509 The parameter mode can be any combination of the letters `kKsSiIourRmMen`
510 
511  k : kurtosis printed
512  K : kurtosis and kurtosis error printed
513  s : skewness printed
514  S : skewness and skewness error printed
515  i : integral of bins printed
516  I : integral of bins with option "width" printed
517  o : number of overflows printed
518  u : number of underflows printed
519  r : standard deviation printed
520  R : standard deviation and standard deviation error printed
521  m : mean value printed
522  M : mean value mean error values printed
523  e : number of entries printed
524  n : name of histogram is printed
525 
526 For example, to print only name of histogram and number of entries do:
527 
528  gStyle->SetOptStat("ne");
529 
530 To print only the name of the histogram do:
531 
532  gStyle->SetOptStat("n");
533 
534 The default value is:
535 
536  gStyle->SetOptStat("nemr");
537 
538 When a histogram is painted, a `TPaveStats` object is created and added
539 to the list of functions of the histogram. If a `TPaveStats` object
540 already exists in the histogram list of functions, the existing object is just
541 updated with the current histogram parameters.
542 
543 Once a histogram is painted, the statistics box can be accessed using
544 `h->FindObject("stats")`. In the command line it is enough to do:
545 
546  Root > h->Draw()
547  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
548 
549 because after `h->Draw()` the histogram is automatically painted. But
550 in a script file the painting should be forced using `gPad->Update()`
551 in order to make sure the statistics box is created:
552 
553  h->Draw();
554  gPad->Update();
555  TPaveStats *st = (TPaveStats*)h->FindObject("stats");
556 
557 Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
558 
559 When a histogram is drawn with the option `SAME`, the statistics box
560 is not drawn. To force the statistics box drawing with the option
561 `SAME`, the option `SAMES` must be used.
562 If the new statistics box hides the previous statistics box, one can change
563 its position with these lines (`h` being the pointer to the histogram):
564 
565  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
566  Root > st->SetX1NDC(newx1); //new x start position
567  Root > st->SetX2NDC(newx2); //new x end position
568 
569 To change the type of information for an histogram with an existing
570 `TPaveStats` one should do:
571 
572  st->SetOptStat(mode);
573 
574 Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
575 (see above).
576 
577 One can delete the statistics box for a histogram `TH1* h` with:
578 
579  h->SetStats(0)
580 
581 and activate it again with:
582 
583  h->SetStats(1).
584 
585 Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
586 `$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
587 
588 
589 ### <a name="HP08"></a> Fit Statistics
590 
591 
592 The type of information about fit parameters printed in the histogram statistics
593 box can be selected via the parameter mode. The parameter mode can be
594 `= pcev` (default `= 0111`)
595 
596  p = 1; print Probability
597  c = 1; print Chisquare/Number of degrees of freedom
598  e = 1; print errors (if e=1, v must be 1)
599  v = 1; print name/values of parameters
600 
601 Example:
602 
603  gStyle->SetOptFit(1011);
604 
605 print fit probability, parameter names/values and errors.
606 
607 1. When `v" = 1` is specified, only the non-fixed parameters are shown.
608 2. When `v" = 2` all parameters are shown.
609 
610 Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
611 to `gStyle->SetOptFit(111)`
612 
613 
614 ### <a name="HP09"></a> The error bars options
615 
616 
617 | Option | Description |
618 |----------|-------------------------------------------------------------------|
619 | "E" | Default. Shows only the error bars, not a marker.|
620 | "E1" | Small lines are drawn at the end of the error bars.|
621 | "E2" | Error rectangles are drawn.|
622 | "E3" | A filled area is drawn through the end points of the vertical error bars.|
623 | "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
624 | "E0" | Draw also bins with null contents.|
625 
626 Begin_Macro(source)
627 {
628  TCanvas *c1 = new TCanvas("c1","c1",600,400);
629  TH1F *he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
630  Int_t i;
631  for (i=0;i<10000;i++) he->Fill(gRandom->Gaus(0,1));
632  gStyle->SetEndErrorSize(3);
633  gStyle->SetErrorX(1.);
634  he->SetMarkerStyle(20);
635  he->Draw("E1");
636  return c1;
637 }
638 End_Macro
639 
640 The options "E3" and "E4" draw an error band through the end points of the
641 vertical error bars. With "E4" the error band is smoothed. Because of the
642 smoothing algorithm used some artefacts may appear at the end of the band
643 like in the following example. In such cases "E3" should be used instead
644 of "E4".
645 
646 Begin_Macro(source)
647 {
648  TCanvas *ce4 = new TCanvas("ce4","ce4",600,400);
649  ce4->Divide(2,1);
650  TH1F *he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
651  Int_t i;
652  for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
653  he4->SetFillColor(kRed);
654  he4->GetXaxis()->SetRange(40,48);
655  ce4->cd(1);
656  he4->Draw("E4");
657  ce4->cd(2);
658  TH1F *he3 = (TH1F*)he4->DrawClone("E3");
659  he3->SetTitle("Distribution drawn option E3");
660  return ce4;
661 }
662 End_Macro
663 
664 2D histograms can be drawn with error bars as shown is the following example:
665 
666 Begin_Macro(source)
667 {
668  TCanvas *c2e = new TCanvas("c2e","c2e",600,400);
669  TH2F *h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
670  Float_t px, py;
671  for (Int_t i = 0; i < 25000; i++) {
672  gRandom->Rannor(px,py);
673  h2e->Fill(px,5*py);
674  }
675  h2e->Draw("E");
676  return c2e;
677 }
678 End_Macro
679 
680 
681 ### <a name="HP100"></a> The bar chart option
682 
683 
684 The option "B" allows to draw simple vertical bar charts.
685 The bar width is controlled with `TH1::SetBarWidth()`,
686 and the bar offset within the bin, with `TH1::SetBarOffset()`.
687 These two settings are useful to draw several histograms on the
688 same plot as shown in the following example:
689 
690 Begin_Macro(source)
691 {
692  int i;
693  const Int_t nx = 8;
694  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
695  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
696  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
697 
698  TCanvas *cb = new TCanvas("cb","cb",600,400);
699  cb->SetGrid();
700 
701  gStyle->SetHistMinimumZero();
702 
703  TH1F *h1b = new TH1F("h1b","Option B example",nx,0,nx);
704  h1b->SetFillColor(4);
705  h1b->SetBarWidth(0.4);
706  h1b->SetBarOffset(0.1);
707  h1b->SetStats(0);
708  h1b->SetMinimum(-5);
709  h1b->SetMaximum(5);
710 
711  for (i=1; i<=nx; i++) {
712  h1b->SetBinContent(i, d_35_0[i-1]);
713  h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
714  }
715 
716  h1b->Draw("b");
717 
718  TH1F *h2b = new TH1F("h2b","h2b",nx,0,nx);
719  h2b->SetFillColor(38);
720  h2b->SetBarWidth(0.4);
721  h2b->SetBarOffset(0.5);
722  h2b->SetStats(0);
723  for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
724 
725  h2b->Draw("b same");
726 
727  return cb;
728 }
729 End_Macro
730 
731 
732 ### <a name="HP10"></a> The "BAR" and "HBAR" options
733 
734 
735 When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
736 bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
737 An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
738 `hbar2`, `hbar3`, `hbar4` (hbars.C).
739 
740 - The bar is filled with the histogram fill color.
741 - The left side of the bar is drawn with a light fill color.
742 - The right side of the bar is drawn with a dark fill color.
743 - The percentage of the bar drawn with either the light or dark color is:
744  - 0% for option "(h)bar" or "(h)bar0"
745  - 10% for option "(h)bar1"
746  - 20% for option "(h)bar2"
747  - 30% for option "(h)bar3"
748  - 40% for option "(h)bar4"
749 
750 When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
751 
752 Begin_Macro(source)
753 ../../../tutorials/hist/hbars.C
754 End_Macro
755 
756 To control the bar width (default is the bin width) `TH1::SetBarWidth()`
757 should be used.
758 
759 To control the bar offset (default is 0) `TH1::SetBarOffset()` should
760 be used.
761 
762 These two parameters are useful when several histograms are plotted using
763 the option `SAME`. They allow to plot the histograms next to each other.
764 
765 
766 ### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
767 
768 
769 For each cell (i,j) a number of points proportional to the cell content is
770 drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
771 `kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
772 If option is of the form `scat=ff`, (eg `scat=1.8`,
773 `scat=1e-3`), then `ff` is used as a scale factor to compute the
774 number of dots. `scat=1` is the default.
775 
776 By default the scatter plot is painted with a "dot marker" which not scalable
777 (see the `TAttMarker` documentation). To change the marker size, a scalable marker
778 type should be used. For instance a circle (marker style 20).
779 
780 Begin_Macro(source)
781 {
782  TCanvas *c1 = new TCanvas("c1","c1",600,400);
783  TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
784  Float_t px, py;
785  for (Int_t i = 0; i < 25000; i++) {
786  gRandom->Rannor(px,py);
787  hscat->Fill(px,5*py);
788  hscat->Fill(3+0.5*px,2*py-10.);
789  }
790  hscat->Draw("scat=0.5");
791  return c1;
792 }
793 End_Macro
794 
795 
796 ### <a name="HP12"></a> The ARRow option
797 
798 
799 Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
800 The orientation of the arrow follows the cell gradient.
801 
802 Begin_Macro(source)
803 {
804  TCanvas *c1 = new TCanvas("c1","c1",600,400);
805  TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
806  Float_t px, py;
807  for (Int_t i = 0; i < 25000; i++) {
808  gRandom->Rannor(px,py);
809  harr->Fill(px,5*py);
810  harr->Fill(3+0.5*px,2*py-10.,0.1);
811  }
812  harr->Draw("ARR");
813  return c1;
814 }
815 End_Macro
816 
817 
818 ### <a name="HP13"></a> The BOX option
819 
820 
821 For each cell (i,j) a box is drawn. The size (surface) of the box is
822 proportional to the absolute value of the cell content.
823 The cells with a negative content draw with a `X` on top of the boxes.
824 
825 Begin_Macro(source)
826 {
827  TCanvas *c1 = new TCanvas("c1","c1",600,400);
828  hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
829  hbox->SetFillColor(42);
830  hbox->Fill(0.5, 0.5, 1.);
831  hbox->Fill(0.5, 1.5, 4.);
832  hbox->Fill(0.5, 2.5, 3.);
833  hbox->Fill(1.5, 0.5, 2.);
834  hbox->Fill(1.5, 1.5, 12.);
835  hbox->Fill(1.5, 2.5, -6.);
836  hbox->Fill(2.5, 0.5, -4.);
837  hbox->Fill(2.5, 1.5, 6.);
838  hbox->Fill(2.5, 2.5, 0.5);
839  hbox->Draw("BOX");
840  return c1;
841 }
842 End_Macro
843 
844 With option `BOX1` a button is drawn for each cell with surface
845 proportional to content's absolute value. A sunken button is drawn for
846 negative values a raised one for positive.
847 
848 Begin_Macro(source)
849 {
850  TCanvas *c1 = new TCanvas("c1","c1",600,400);
851  hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
852  hbox1->SetFillColor(42);
853  hbox1->Fill(0.5, 0.5, 1.);
854  hbox1->Fill(0.5, 1.5, 4.);
855  hbox1->Fill(0.5, 2.5, 3.);
856  hbox1->Fill(1.5, 0.5, 2.);
857  hbox1->Fill(1.5, 1.5, 12.);
858  hbox1->Fill(1.5, 2.5, -6.);
859  hbox1->Fill(2.5, 0.5, -4.);
860  hbox1->Fill(2.5, 1.5, 6.);
861  hbox1->Fill(2.5, 2.5, 0.5);
862  hbox1->Draw("BOX1");
863  return c1;
864 }
865 End_Macro
866 
867 When the option `SAME` (or "SAMES") is used with the option `BOX`,
868 the boxes' sizes are computing taking the previous plots into account. The range
869 along the Z axis is imposed by the first plot (the one without option
870 `SAME`); therefore the order in which the plots are done is relevant.
871 
872 Begin_Macro(source)
873 {
874  TCanvas *c1 = new TCanvas("c1","c1",600,400);
875  TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
876  TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
877  TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
878  TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
879  for (Int_t i=0;i<1000;i++) {
880  double x,y;
881  gRandom->Rannor(x,y);
882  if (x>0 && y>0) hb1->Fill(x,y,4);
883  if (x<0 && y<0) hb2->Fill(x,y,3);
884  if (x>0 && y<0) hb3->Fill(x,y,2);
885  if (x<0 && y>0) hb4->Fill(x,y,1);
886  }
887  hb1->SetFillColor(1);
888  hb2->SetFillColor(2);
889  hb3->SetFillColor(3);
890  hb4->SetFillColor(4);
891  hb1->Draw("box");
892  hb2->Draw("box same");
893  hb3->Draw("box same");
894  hb4->Draw("box same");
895  return c1;
896 }
897 End_Macro
898 
899 
900 ### <a name="HP14"></a> The COLor option
901 
902 
903 For each cell (i,j) a box is drawn with a color proportional to the cell
904 content.
905 
906 The color table used is defined in the current style.
907 
908 If the histogram's minimum and maximum are the same (flat histogram), the
909 mapping on colors is not possible, therefore nothing is painted. To paint a
910 flat histogram it is enough to set the histogram minimum
911 (`TH1::SetMinimum()`) different from the bins' content.
912 
913 The default number of color levels used to paint the cells is 20.
914 It can be changed with `TH1::SetContour()` or
915 `TStyle::SetNumberContours()`. The higher this number is, the smoother
916 is the color change between cells.
917 
918 The color palette in TStyle can be modified via `gStyle->SetPalette()`.
919 
920 All the non-empty bins are painted. Empty bins are not painted unless
921 some bins have a negative content because in that case the null bins
922 might be not empty.
923 
924 `TProfile2D` histograms are handled differently because, for this type of 2D
925 histograms, it is possible to know if an empty bin has been filled or not. So even
926 if all the bins' contents are positive some empty bins might be painted. And vice versa,
927 if some bins have a negative content some empty bins might be not painted.
928 
929 Combined with the option `COL`, the option `Z` allows to
930 display the color palette defined by `gStyle->SetPalette()`.
931 
932 In the following example, the histogram has only positive bins; the empty
933 bins (containing 0) are not drawn.
934 
935 Begin_Macro(source)
936 {
937  TCanvas *c1 = new TCanvas("c1","c1",600,400);
938  TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
939  Float_t px, py;
940  for (Int_t i = 0; i < 25000; i++) {
941  gRandom->Rannor(px,py);
942  hcol1->Fill(px,5*py);
943  }
944  gStyle->SetPalette(kBird);
945  hcol1->Draw("COLZ");
946  return c1;
947 }
948 End_Macro
949 
950 In the first plot of following example, the histogram has some negative bins;
951 the empty bins (containing 0) are drawn. In some cases one wants to not draw
952 empty bins (containing 0) of histograms having a negative minimum. The option
953 `1`, used to produce the second plot in the following picture, allows to do that.
954 
955 Begin_Macro(source)
956 {
957  TCanvas *c1 = new TCanvas("c1","c1",600,600);
958  c1->Divide(1,2);
959  TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
960  TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
961  Float_t px, py;
962  for (Int_t i = 0; i < 25000; i++) {
963  gRandom->Rannor(px,py);
964  hcol23->Fill(px,5*py);
965  hcol24->Fill(px,5*py);
966  }
967  hcol23->Fill(0.,0.,-200.);
968  hcol24->Fill(0.,0.,-200.);
969  gStyle->SetPalette(kBird);
970  c1->cd(1); hcol23->Draw("COLZ");
971  c1->cd(2); hcol24->Draw("COLZ1");
972  return c1;
973 }
974 End_Macro
975 
976 When the maximum of the histogram is set to a smaller value than the real maximum,
977  the bins having a content between the new maximum and the real maximum are
978 painted with the color corresponding to the new maximum.
979 
980 When the minimum of the histogram is set to a greater value than the real minimum,
981  the bins having a value between the real minimum and the new minimum are not drawn
982  unless the option `0` is set.
983 
984 The following example illustrates the option `0` combined with the option `COL`.
985 
986 Begin_Macro(source)
987 {
988  TCanvas *c1 = new TCanvas("c1","c1",600,600);
989  c1->Divide(1,2);
990  TH2F *hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
991  TH2F *hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
992  Float_t px, py;
993  for (Int_t i = 0; i < 25000; i++) {
994  gRandom->Rannor(px,py);
995  hcol21->Fill(px,5*py);
996  hcol22->Fill(px,5*py);
997  }
998  hcol21->SetBit(TH1::kNoStats);
999  hcol22->SetBit(TH1::kNoStats);
1000  gStyle->SetPalette(kBird);
1001  c1->cd(1); hcol21->Draw("COLZ");
1002  c1->cd(2); hcol22->Draw("COLZ0");
1003  hcol22->SetMaximum(100);
1004  hcol22->SetMinimum(40);
1005  return c1;
1006 }
1007 End_Macro
1008 
1009 The option `COL` can be combined with the option `POL`:
1010 
1011 Begin_Macro(source)
1012 {
1013  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1014  TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1015  Float_t px, py;
1016  for (Int_t i = 0; i < 25000; i++) {
1017  gRandom->Rannor(px,py);
1018  hcol1->Fill(px,py);
1019  }
1020  gStyle->SetPalette(kBird);
1021  hcol1->Draw("COLZPOL");
1022  return c1;
1023 }
1024 End_Macro
1025 
1026 \since **ROOT version 6.07/03:**
1027 A second rendering technique is also available with the COL2 and COLZ2 options.
1028 
1029 These options provide potential performance improvements compared to the standard
1030 COL option. The performance comparison of the COL2 to the COL option depends on
1031 the histogram and the size of the rendering region in the current pad. In general,
1032 a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1033 faster with the COL option.
1034 
1035 However, for larger histograms (approx. more than 100 bins per axis)
1036 that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1037 For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1038 faster with the COL2 option.
1039 
1040 The COL2 option will also scale its performance based on the size of the
1041 pixmap the histogram image is being rendered into. It also is much better optimized for
1042 sessions where the user is forwarding X11 windows through an `ssh` connection.
1043 
1044 For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1045 and COLZ options. There is one major difference and that concerns the treatment of
1046 bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1047 
1048 
1049 ### <a name="HP140"></a> The CANDLE option
1050 
1051 
1052 <a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1053 a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1054 way to describe graphically a data distribution (D) with only five numbers:
1055 
1056  1. The minimum value of the distribution D (bottom or left whisker).
1057  2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1058  3. The median (M): 50% of the data points in D are less than M.
1059  4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1060  5. The maximum value of the distribution D (top or right whisker).
1061 
1062 In this implementation a TH2 is considered as a collection of TH1 along
1063 X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1064 Each TH1 is represented as a candle plot.
1065 
1066 Begin_Macro
1067 ../../../tutorials/hist/candleplotwhiskers.C
1068 End_Macro
1069 
1070 The candle reduces the information coming from a whole distribution into few values.
1071 Independently from the number of entries or the significance of the underlying distribution
1072 a candle will always look like a candle. So candle plots should be used carefully in
1073 particular with unknown distributions. The definition of a candle is based on
1074 __unbinned data__. Here, candles are created from binned data. Because of this, the
1075 deviation is connected to the bin width used. The calculation of the quantiles
1076 normally done on unbinned data also. Because data are binned, this will
1077 only work the best possible way within the resolution of one bin
1078 
1079 Because of all these facts one should take care that:
1080 
1081  - there are enough points per candle
1082  - the bin width is small enough (more bins will increase the maximum
1083  available resolution of the quantiles although there will be some
1084  bins with no entries)
1085  - never make a candle-plot if the underlying distribution is double-distributed
1086  - only create candles of distributions that are more-or-less gaussian (the
1087  MPV should be not too far away from the mean).
1088 
1089 #### What a candle is made of
1090 
1091 \since **ROOT version 6.07/05**
1092 
1093 ##### The box
1094 The box displays the position of the inter-quantile-range of the underlying
1095 distribution. The box contains 25% of the distribution below the median
1096 and 25% of the distribution above the median. If the underlying distribution is large
1097 enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1098 (Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1099 the position of the box can be modified by SetBarWidth() and SetBarOffset().
1100 The +-25% quantiles are calculated by the GetQuantiles() methods.
1101 
1102 ##### The Median
1103 For a sorted list of numbers, the median is the value in the middle of the list.
1104 E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1105 because it is in the middle of the list. If the number of entries is even the
1106 average of the two values in the middle will be used. As histograms are binned
1107 data, the situation is a bit more complex. The following example shows this:
1108 
1109 ~~~ {.cpp}
1110 void quantiles() {
1111  TH1I *h = new TH1I("h","h",10,0,10);
1112  //h->Fill(3);
1113  //h->Fill(3);
1114  h->Fill(4);
1115  h->Draw();
1116  Double_t *p = new Double_t[1];
1117  p[0] = 0.5;
1118  Double_t *q = new Double_t[1];
1119  q[0] = 0;
1120  h->GetQuantiles(1,q,p);
1121 
1122  cout << "Median is: " << q[0] << std::endl;
1123 }
1124 ~~~
1125 
1126 Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1127 the example will return a calculated median of 4.5, because that's the bin center
1128 of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1129 commented out, it will return 3.75, because the algorithm tries to evenly distribute
1130 the individual values of a bin with bin content > 0. It means the sorted list
1131 would be "3.25, 3.75, 4.5".
1132 
1133 The consequence is a median of 3.75. This shows how important it is to use a
1134 small enough bin-width when using candle-plots on binned data.
1135 If the distribution is large enough and gaussian shaped the median will be exactly
1136 equal to the mean.
1137 The median can be shown as a line or as a circle or not shown at all.
1138 
1139 In order to show the significance of the median notched candle plots apply a "notch" or
1140 narrowing of the box around the median. The significance is defined by
1141 \f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1142 (where iqr is the size of the box and N is the number of entries of the whole
1143 distribution). Candle plots like these are usually called "notched candle plots".
1144 
1145 In case the significance of the median is greater that the size of the box, the
1146 box will have an unnatural shape. Usually it means the chart has not enough data,
1147 or that representing this uncertainty is not useful
1148 
1149 ##### The Mean
1150 The mean can be drawn as a dashed line or as a circle or not drawn at all.
1151 The mean is the arithmetic average of the values in the distribution.
1152 It is calculated using GetMean(). Because histograms are
1153 binned data, the mean value can differ from a calculation on the raw-data.
1154 If the distribution is large enough and gaussian shaped the mean will be
1155 exactly the median.
1156 
1157 ##### The Whiskers
1158 The whiskers represent the part of the distribution not covered by the box.
1159 The upper 25% and the lower 25% of the distribution are located within the whiskers.
1160 Two representations are available.
1161 
1162  - A simple one (using w=1) defining the lower whisker from the lowest data value
1163  to the bottom of the box, and the upper whisker from the top of the box to the
1164  highest data value. In this representation the whisker-lines are dashed.
1165  - A more complex one having a further restriction. The whiskers are still connected
1166  to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1167  be that the outermost part of the underlying distribution will not be covered
1168  by the whiskers. Usually these missing parts will be represented by the outliers
1169  (see points). Of course the upper and the lower whisker may differ in length.
1170  In this representation the whiskers are drawn as solid lines.
1171 
1172 If the distribution is large enough and gaussian shaped, the maximum length of
1173 the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
1174 1.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1175 (see picture above). In that case 99.3% of the total distribution will be covered
1176 by the box and the whiskers, whereas 0.7% are represented by the outliers.
1177 
1178 ##### The Anchors
1179 The anchors have no special meaning in terms of statistical calculation. They mark
1180 the end of the whiskers and they have the width of the box. Both representation
1181 with and without anchors are common.
1182 
1183 ##### The Points
1184 Depending on the configuration the points can have different meanings:
1185  - If p=1 the points represent the outliers. If they are shown, it means
1186  some parts of the underlying distribution are not covered by the whiskers.
1187  This can only occur when the whiskers are set to option w=2. Here the whiskers
1188  can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1189  whiskers will be drawn as outliers. The outliers will be represented by crosses.
1190  - If p=2 all points in the distribution will be painted as crosses. This is
1191  useful for small datasets only (up to 10 or 20 points per candle).
1192  The outliers are shown along the candle. Because the underlying distribution
1193  is binned, is frequently occurs that a bin contains more than one value.
1194  Because of this the points will be randomly scattered within their bin along
1195  the candle axis. If the bin content for a bin is exactly 1 (usually
1196  this happens for the outliers) if will be drawn in the middle of the bin along
1197  the candle axis. As the maximum number of points per candle is limited by kNMax/2
1198  on very large datasets scaling will be performed automatically. In that case one
1199  would loose all outliers because they have usually a bin content of 1 (and a
1200  bin content between 0 and 1 after the scaling). Because of this all bin contents
1201  between 0 and 1 - after the scaling - will be forced to be 1.
1202  - As the drawing of all values on large datasets can lead to big amounts of crosses,
1203  one can show all values as a scatter plot instead by choosing p=3. The points will be
1204  drawn as dots and will be scattered within the width of the candle. The color
1205  of the points will be the color of the candle-chart.
1206 
1207 
1208 #### How to use the candle-plots drawing option
1209 
1210 There are six predefined candle-plot representations:
1211 
1212  - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1213  - "CANDLEX2": Standard candle with better whisker definition + outliers.
1214  It is a good compromise
1215  - "CANDLEX3": Like candle2 but with a mean as a circle.
1216  It is easier to distinguish mean and median
1217  - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1218  (notched candle plots).
1219  For bigger datasets per candle
1220  - "CANDLEX5": Like candle2 but showing all data points.
1221  For very small datasets
1222  - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1223  For huge datasets
1224 
1225 Of course "CANDLEY" works as well. X shows vertical candles, Y shows
1226 horizontal candles
1227 
1228 The option "CANDLE" is equivalent to "CANDLE1X" or "CANDLEX".
1229 
1230 The option "CANDLEY" is equivalent to "CANDLEY1"
1231 
1232 There is no difference between options "CANDLE1X" and "CANDLEX1".
1233 
1234 Instead of "X" or "Y" one can use "V" or "H"
1235 
1236 The following picture shows how the six predefined representations look.
1237 
1238 Begin_Macro
1239 {
1240  TCanvas *c1 = new TCanvas("c1","c1",700,800);
1241  c1->Divide(2,3);
1242  gStyle->SetOptStat(kFALSE);
1243 
1244  TH2F *hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1245  Float_t px, py;
1246  for (Int_t i = 0; i < 15000; i++) {
1247  gRandom->Rannor(px,py);
1248  hcandle->Fill(px,5*py);
1249  }
1250  hcandle->SetMarkerSize(0.5);
1251 
1252  TH2F *h2;
1253  for (Int_t i=1; i<7; i++) {
1254  c1->cd(i);
1255  h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1256  h2->SetTitle(Form("CANDLE%d",i));
1257  }
1258 }
1259 End_Macro
1260 
1261 Instead of using the predefined representations, the candle parameters can be
1262 changed individually. In that case the option has the following form:
1263 
1264  CANDLEX(<option-string>)
1265 
1266 or
1267 
1268  CANDLEY(<option-string>).
1269 
1270 All zeros at the beginning of `option-string` can be omitted.
1271 
1272 `option-string` consists six values, defined as follow:
1273 
1274  "CANDLEX(pawMmb)"
1275 
1276 Where:
1277 
1278  - `b = 0`; no box drawn
1279  - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1280  makes sense in the very most cases to always draw the box.
1281  `b = 2`; draw a filled box with border.
1282 
1283  - `m = 0`; no median drawn
1284  - `m = 1`; median is drawn as a line
1285  - `m = 2`; median is drawn with errors (notches)
1286  - `m = 3`; median is drawn as a circle
1287 
1288  - `M = 0`; no mean drawn
1289  - `M = 1`; mean is drawn as a dashed line
1290  - `M = 3`; mean is drawn as a circle
1291 
1292  - `w = 0`; no whisker drawn
1293  - `w = 1`; whisker is drawn to end of distribution.
1294  - `w = 2`; whisker is drawn to max 1.5*iqr
1295 
1296  - `a = 0`; no anchor drawn
1297  - `a = 1`; the anchors are drawn
1298 
1299  - `p = 0`; no points drawn
1300  - `p = 1`; only outliers are drawn
1301  - `p = 2`; all datapoints are drawn
1302  - `p = 3`: all datapoints are drawn scattered
1303 
1304 The values on the left of `option-string` are in the middle of the candle,
1305 the values on the right of `option-string` are in the outer part of the candle.
1306 
1307 #### Example 1
1308 Box and improved whisker, no mean, no median, no anchor no outliers
1309 
1310  h1->Draw("CANDLEX(2001)");
1311 
1312 #### Example 2
1313 A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1314 
1315  h1->Draw("CANDLEX(112111)");
1316 
1317 #### Example 3
1318 The following example shows how several candle plots can be super-imposed using
1319 the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1320 Also the color, the line width, the size of the points and so on can be changed by the
1321 standard attribute setting methods such as SetLineColor() SetLineWidth().
1322 
1323 Begin_Macro(source)
1324 ../../../tutorials/hist/candleplot.C
1325 End_Macro
1326 
1327 ### <a name="HP141"></a> The VIOLIN option
1328 
1329 
1330 <a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1331 that also encodes the pdf information at each point.
1332 
1333 
1334 Quartiles and mean are also represented at each point, with a marker
1335 and two lines.
1336 
1337 In this implementation a TH2 is considered as a collection of TH1 along
1338 X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1339 
1340 A solid fill style is recommended for this plot (as opposed to a hollow or
1341 hashed style).
1342 
1343 Begin_Macro(source)
1344 {
1345  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1346  Int_t nx(6), ny(40);
1347  Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1348  TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1349  TF1 f1("f1", "gaus", +0,0 +4.0);
1350  Double_t x,y;
1351  for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1352  Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1353  f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1354  for(Int_t i=0; i<10000; ++i){
1355  x = xc;
1356  y = f1.GetRandom();
1357  hviolin->Fill(x, y);
1358  }
1359  }
1360  hviolin->SetFillColor(kGray);
1361  hviolin->SetMarkerStyle(20);
1362  hviolin->SetMarkerSize(0.5);
1363  hviolin->Draw("VIOLIN");
1364  c1->Update();
1365  return c1;
1366 }
1367 End_Macro
1368 
1369 
1370 ### <a name="HP15"></a> The TEXT and TEXTnn Option
1371 
1372 
1373 For each bin the content is printed. The text attributes are:
1374 
1375 - text font = current TStyle font (`gStyle->SetTextFont()`).
1376 - text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1377  with the option `TEXT` the marker size can be changed with
1378  `h->SetMarkerSize(markersize)`).
1379 - text color = marker color.
1380 
1381 By default the format `g` is used. This format can be redefined
1382 by calling `gStyle->SetPaintTextFormat()`.
1383 
1384 It is also possible to use `TEXTnn` in order to draw the text with
1385 the angle `nn` (`0 < nn < 90`).
1386 
1387 For 2D histograms the text is plotted in the center of each non empty cells.
1388 It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`.
1389 For 1D histogram the text is plotted at a y position equal to the bin content.
1390 
1391 For 2D histograms when the option "E" (errors) is combined with the option
1392 text ("TEXTE"), the error for each bin is also printed.
1393 
1394 Begin_Macro(source)
1395 {
1396  TCanvas *c01 = new TCanvas("c01","c01",700,400);
1397  c01->Divide(2,1);
1398  TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1399  TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1400  Float_t px, py;
1401  for (Int_t i = 0; i < 25000; i++) {
1402  gRandom->Rannor(px,py);
1403  htext1->Fill(px,0.1);
1404  htext2->Fill(px,5*py,0.1);
1405  }
1406  gStyle->SetPaintTextFormat("4.1f m");
1407  htext2->SetMarkerSize(1.8);
1408  c01->cd(1);
1409  htext2->Draw("TEXT45");
1410  c01->cd(2);
1411  htext1->Draw();
1412  htext1->Draw("HIST TEXT0 SAME");
1413  return c01;
1414 }
1415 End_Macro
1416 
1417 \since **ROOT version 6.07/07:**
1418 In case several histograms are drawn on top ot each other (using option `SAME`),
1419 the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1420 text position in each cell, in percentage of the bin width.
1421 
1422 Begin_Macro(source)
1423 {
1424  TCanvas *c03 = new TCanvas("c03","c03",700,400);
1425  gStyle->SetOptStat(0);
1426  TH2F *htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1427  TH2F *htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1428  TH2F *htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1429  Float_t px, py;
1430  for (Int_t i = 0; i < 25000; i++) {
1431  gRandom->Rannor(px,py);
1432  htext3->Fill(4*px,20*py,0.1);
1433  htext4->Fill(4*px,20*py,0.5);
1434  htext5->Fill(4*px,20*py,1.0);
1435  }
1436  //gStyle->SetPaintTextFormat("4.1f m");
1437  htext4->SetMarkerSize(1.8);
1438  htext5->SetMarkerSize(1.8);
1439  htext5->SetMarkerColor(kRed);
1440  htext3->Draw("COL");
1441  htext4->SetBarOffset(0.2);
1442  htext4->Draw("TEXT SAME");
1443  htext5->SetBarOffset(-0.2);
1444  htext5->Draw("TEXT SAME");
1445  return c03;
1446 }
1447 End_Macro
1448 
1449 In the case of profile histograms it is possible to print the number
1450 of entries instead of the bin content. It is enough to combine the
1451 option "E" (for entries) with the option "TEXT".
1452 
1453 Begin_Macro(source)
1454 {
1455  TCanvas *c02 = new TCanvas("c02","c02",700,400);
1456  c02->Divide(2,1);
1457  gStyle->SetPaintTextFormat("g");
1458 
1459  TProfile *profile = new TProfile("profile","profile",10,0,10);
1460  profile->SetMarkerSize(2.2);
1461  profile->Fill(0.5,1);
1462  profile->Fill(1.5,2);
1463  profile->Fill(2.5,3);
1464  profile->Fill(3.5,4);
1465  profile->Fill(4.5,5);
1466  profile->Fill(5.5,5);
1467  profile->Fill(6.5,4);
1468  profile->Fill(7.5,3);
1469  profile->Fill(8.5,2);
1470  profile->Fill(9.5,1);
1471  c02->cd(1); profile->Draw("HIST TEXT0");
1472  c02->cd(2); profile->Draw("HIST TEXT0E");
1473 
1474  return c02;
1475 }
1476 End_Macro
1477 
1478 ### <a name="HP16"></a> The CONTour options
1479 
1480 
1481 The following contour options are supported:
1482 
1483 | Option | Description |
1484 |----------|-------------------------------------------------------------------|
1485 | "CONT" | Draw a contour plot (same as CONT0).|
1486 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1487 | "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1488 | "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1489 | "CONT3" | Draw a contour plot solid lines for all contours.|
1490 | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1491 | "CONT5" | Draw a contour plot using Delaunay triangles.|
1492 
1493 
1494 
1495 The following example shows a 2D histogram plotted with the option
1496 `CONTZ`. The option `CONT` draws a contour plot using surface
1497 colors to distinguish contours. Combined with the option `CONT` (or
1498 `CONT0`), the option `Z` allows to display the color palette
1499 defined by `gStyle->SetPalette()`.
1500 
1501 Begin_Macro(source)
1502 {
1503  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1504  TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1505  Float_t px, py;
1506  for (Int_t i = 0; i < 25000; i++) {
1507  gRandom->Rannor(px,py);
1508  hcontz->Fill(px-1,5*py);
1509  hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1510  }
1511  gStyle->SetPalette(kBird);
1512  hcontz->Draw("CONTZ");
1513  return c1;
1514 }
1515 End_Macro
1516 
1517 The following example shows a 2D histogram plotted with the option
1518 `CONT1Z`. The option `CONT1` draws a contour plot using the
1519 line colors to distinguish contours. Combined with the option `CONT1`,
1520 the option `Z` allows to display the color palette defined by
1521 `gStyle->SetPalette()`.
1522 
1523 Begin_Macro(source)
1524 {
1525  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1526  TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1527  Float_t px, py;
1528  for (Int_t i = 0; i < 25000; i++) {
1529  gRandom->Rannor(px,py);
1530  hcont1->Fill(px-1,5*py);
1531  hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1532  }
1533  gStyle->SetPalette(kBird);
1534  hcont1->Draw("CONT1Z");
1535  return c1;
1536 }
1537 End_Macro
1538 
1539 The following example shows a 2D histogram plotted with the option
1540 `CONT2`. The option `CONT2` draws a contour plot using the
1541 line styles to distinguish contours.
1542 
1543 Begin_Macro(source)
1544 {
1545  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1546  TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1547  Float_t px, py;
1548  for (Int_t i = 0; i < 25000; i++) {
1549  gRandom->Rannor(px,py);
1550  hcont2->Fill(px-1,5*py);
1551  hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1552  }
1553  hcont2->Draw("CONT2");
1554  return c1;
1555 }
1556 End_Macro
1557 
1558 The following example shows a 2D histogram plotted with the option
1559 `CONT3`. The option `CONT3` draws contour plot solid lines for
1560 all contours.
1561 
1562 Begin_Macro(source)
1563 {
1564  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1565  TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1566  Float_t px, py;
1567  for (Int_t i = 0; i < 25000; i++) {
1568  gRandom->Rannor(px,py);
1569  hcont3->Fill(px-1,5*py);
1570  hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1571  }
1572  hcont3->Draw("CONT3");
1573  return c1;
1574 }
1575 End_Macro
1576 
1577 The following example shows a 2D histogram plotted with the option
1578 `CONT4`. The option `CONT4` draws a contour plot using surface
1579 colors to distinguish contours (`SURF` option at theta = 0). Combined
1580 with the option `CONT` (or `CONT0`), the option `Z`
1581 allows to display the color palette defined by `gStyle->SetPalette()`.
1582 
1583 Begin_Macro(source)
1584 {
1585  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1586  TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1587  Float_t px, py;
1588  for (Int_t i = 0; i < 25000; i++) {
1589  gRandom->Rannor(px,py);
1590  hcont4->Fill(px-1,5*py);
1591  hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1592  }
1593  gStyle->SetPalette(kBird);
1594  hcont4->Draw("CONT4Z");
1595  return c1;
1596 }
1597 End_Macro
1598 
1599 The default number of contour levels is 20 equidistant levels and can be changed
1600 with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1601 
1602 #### <a name="HP16a"></a> The LIST option
1603 
1604 When option `LIST` is specified together with option
1605 `CONT`, the points used to draw the contours are saved in
1606 `TGraph` objects:
1607 
1608  h->Draw("CONT LIST");
1609  gPad->Update();
1610 
1611 The contour are saved in `TGraph` objects once the pad is painted.
1612 Therefore to use this functionality in a macro, `gPad->Update()`
1613 should be performed after the histogram drawing. Once the list is
1614 built, the contours are accessible in the following way:
1615 
1616  TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1617  Int_t ncontours = contours->GetSize();
1618  TList *list = (TList*)contours->At(i);
1619 
1620 Where `i` is a contour number, and list contains a list of
1621 `TGraph` objects.
1622 For one given contour, more than one disjoint polyline may be generated.
1623 The number of TGraphs per contour is given by:
1624 
1625  list->GetSize();
1626 
1627 To access the first graph in the list one should do:
1628 
1629  TGraph *gr1 = (TGraph*)list->First();
1630 
1631 
1632 The following example (ContourList.C) shows how to use this functionality.
1633 
1634 Begin_Macro(source)
1635 ../../../tutorials/hist/ContourList.C
1636 End_Macro
1637 
1638 The following options select the `CONT4` option and are useful for
1639 sky maps or exposure maps (earth.C).
1640 
1641 | Option | Description |
1642 |--------------|---------------------------------------------------------------|
1643 | "AITOFF" | Draw a contour via an AITOFF projection.|
1644 | "MERCATOR" | Draw a contour via an Mercator projection.|
1645 | "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1646 | "PARABOLIC" | Draw a contour via an Parabolic projection.|
1647 
1648 Begin_Macro(source)
1649 ../../../tutorials/graphics/earth.C
1650 End_Macro
1651 
1652 
1653 ### <a name="HP17"></a> The LEGO options
1654 
1655 
1656 In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1657 is proportional to the cell content. The lego aspect is control with the
1658 following options:
1659 
1660 | Option | Description |
1661 |----------|-------------------------------------------------------------------|
1662 | "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1663 | "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1664 | "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1665 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1666 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1667 | "0" | When used with any LEGO option, the empty bins are not drawn.|
1668 
1669 
1670 See the limitations with [the option "SAME"](#HP060a).
1671 
1672 Line attributes can be used in lego plots to change the edges' style.
1673 
1674 The following example shows a 2D histogram plotted with the option
1675 `LEGO`. The option `LEGO` draws a lego plot using the hidden
1676 lines removal technique.
1677 
1678 Begin_Macro(source)
1679 {
1680  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1681  TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1682  Float_t px, py;
1683  for (Int_t i = 0; i < 25000; i++) {
1684  gRandom->Rannor(px,py);
1685  hlego->Fill(px-1,5*py);
1686  hlego->Fill(2+0.5*px,2*py-10.,0.1);
1687  }
1688  hlego->Draw("LEGO");
1689  return c2;
1690 }
1691 End_Macro
1692 
1693 The following example shows a 2D histogram plotted with the option
1694 `LEGO1`. The option `LEGO1` draws a lego plot using the
1695 hidden surface removal technique. Combined with any `LEGOn` option, the
1696 option `0` allows to not drawn the empty bins.
1697 
1698 Begin_Macro(source)
1699 {
1700  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1701  TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1702  Float_t px, py;
1703  for (Int_t i = 0; i < 25000; i++) {
1704  gRandom->Rannor(px,py);
1705  hlego1->Fill(px-1,5*py);
1706  hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1707  }
1708  hlego1->SetFillColor(kYellow);
1709  hlego1->Draw("LEGO1 0");
1710  return c2;
1711 }
1712 End_Macro
1713 
1714 The following example shows a 2D histogram plotted with the option
1715 `LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1716 draws a lego plot using the hidden surface removal technique but doesn't draw
1717 the border lines of each individual lego-bar. This is very useful for histograms
1718 having many bins. With such histograms the option `LEGO1` gives a black
1719 image because of the border lines. This option also works with stacked legos.
1720 
1721 Begin_Macro(source)
1722 {
1723  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1724  TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1725  Float_t px, py;
1726  for (Int_t i = 0; i < 25000; i++) {
1727  gRandom->Rannor(px,py);
1728  hlego3->Fill(px-1,5*py);
1729  hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1730  }
1731  hlego3->SetFillColor(kRed);
1732  hlego3->Draw("LEGO3");
1733  return c2;
1734  }
1735 End_Macro
1736 
1737 The following example shows a 2D histogram plotted with the option
1738 `LEGO2`. The option `LEGO2` draws a lego plot using colors to
1739 show the cell contents. Combined with the option `LEGO2`, the option
1740 `Z` allows to display the color palette defined by
1741 `gStyle->SetPalette()`.
1742 
1743 Begin_Macro(source)
1744 {
1745  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1746  TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1747  Float_t px, py;
1748  for (Int_t i = 0; i < 25000; i++) {
1749  gRandom->Rannor(px,py);
1750  hlego2->Fill(px-1,5*py);
1751  hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1752  }
1753  gStyle->SetPalette(kBird);
1754  hlego2->Draw("LEGO2Z");
1755  return c2;
1756 }
1757 End_Macro
1758 
1759 
1760 
1761 ### <a name="HP18"></a> The "SURFace" options
1762 
1763 
1764 In a surface plot, cell contents are represented as a mesh.
1765 The height of the mesh is proportional to the cell content.
1766 
1767 | Option | Description |
1768 |----------|-------------------------------------------------------------------|
1769 | "SURF" | Draw a surface plot using the hidden line removal technique.|
1770 | "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1771 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
1772 | "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1773 | "SURF4" | Draw a surface using the Gouraud shading technique.|
1774 | "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1775 | "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.|
1776 | "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1777 
1778 
1779 
1780 See the limitations with [the option "SAME"](#HP060a).
1781 
1782 The following example shows a 2D histogram plotted with the option
1783 `SURF`. The option `SURF` draws a lego plot using the hidden
1784 lines removal technique.
1785 
1786 Begin_Macro(source)
1787 {
1788  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1789  TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1790  Float_t px, py;
1791  for (Int_t i = 0; i < 25000; i++) {
1792  gRandom->Rannor(px,py);
1793  hsurf->Fill(px-1,5*py);
1794  hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1795  }
1796  hsurf->Draw("SURF");
1797  return c2;
1798 }
1799 End_Macro
1800 
1801 The following example shows a 2D histogram plotted with the option
1802 `SURF1`. The option `SURF1` draws a surface plot using the
1803 hidden surface removal technique. Combined with the option `SURF1`,
1804 the option `Z` allows to display the color palette defined by
1805 `gStyle->SetPalette()`.
1806 
1807 Begin_Macro(source)
1808 {
1809  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1810  gStyle->SetPalette(kBird);
1811  TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1812  Float_t px, py;
1813  for (Int_t i = 0; i < 25000; i++) {
1814  gRandom->Rannor(px,py);
1815  hsurf1->Fill(px-1,5*py);
1816  hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1817  }
1818  hsurf1->Draw("SURF1");
1819  return c2;
1820 }
1821 End_Macro
1822 
1823 The following example shows a 2D histogram plotted with the option
1824 `SURF2`. The option `SURF2` draws a surface plot using colors
1825 to show the cell contents. Combined with the option `SURF2`, the option
1826 `Z` allows to display the color palette defined by
1827 `gStyle->SetPalette()`.
1828 
1829 Begin_Macro(source)
1830 {
1831  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1832  gStyle->SetPalette(kBird);
1833  TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
1834  Float_t px, py;
1835  for (Int_t i = 0; i < 25000; i++) {
1836  gRandom->Rannor(px,py);
1837  hsurf2->Fill(px-1,5*py);
1838  hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
1839  }
1840  hsurf2->Draw("SURF2");
1841  return c2;
1842 }
1843 End_Macro
1844 
1845 The following example shows a 2D histogram plotted with the option
1846 `SURF3`. The option `SURF3` draws a surface plot using the
1847 hidden line removal technique with, in addition, a filled contour view drawn on the
1848 top. Combined with the option `SURF3`, the option `Z` allows
1849 to display the color palette defined by `gStyle->SetPalette()`.
1850 
1851 Begin_Macro(source)
1852 {
1853  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1854  gStyle->SetPalette(kBird);
1855  TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
1856  Float_t px, py;
1857  for (Int_t i = 0; i < 25000; i++) {
1858  gRandom->Rannor(px,py);
1859  hsurf3->Fill(px-1,5*py);
1860  hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
1861  }
1862  hsurf3->Draw("SURF3");
1863  return c2;
1864 }
1865 End_Macro
1866 
1867 The following example shows a 2D histogram plotted with the option
1868 `SURF4`. The option `SURF4` draws a surface using the Gouraud
1869 shading technique.
1870 
1871 Begin_Macro(source)
1872 {
1873  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1874  TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
1875  Float_t px, py;
1876  for (Int_t i = 0; i < 25000; i++) {
1877  gRandom->Rannor(px,py);
1878  hsurf4->Fill(px-1,5*py);
1879  hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
1880  }
1881  hsurf4->SetFillColor(kOrange);
1882  hsurf4->Draw("SURF4");
1883  return c2;
1884 }
1885 End_Macro
1886 
1887 The following example shows a 2D histogram plotted with the option
1888 `SURF5 CYL`. Combined with the option `SURF5`, the option
1889 `Z` allows to display the color palette defined by `gStyle->SetPalette()`.
1890 
1891 Begin_Macro(source)
1892 {
1893  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1894  gStyle->SetPalette(kBird);
1895  TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
1896  Float_t px, py;
1897  for (Int_t i = 0; i < 25000; i++) {
1898  gRandom->Rannor(px,py);
1899  hsurf5->Fill(px-1,5*py);
1900  hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
1901  }
1902  hsurf5->SetFillColor(kOrange);
1903  hsurf5->Draw("SURF5 CYL");
1904  return c2;
1905 }
1906 End_Macro
1907 
1908 The following example shows a 2D histogram plotted with the option
1909 `SURF7`. The option `SURF7` draws a surface plot using the
1910 hidden surfaces removal technique with, in addition, a line contour view drawn on the
1911 top. Combined with the option `SURF7`, the option `Z` allows
1912 to display the color palette defined by `gStyle->SetPalette()`.
1913 
1914 Begin_Macro(source)
1915 {
1916  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1917  gStyle->SetPalette(kBird);
1918  TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
1919  Float_t px, py;
1920  for (Int_t i = 0; i < 25000; i++) {
1921  gRandom->Rannor(px,py);
1922  hsurf7->Fill(px-1,5*py);
1923  hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
1924  }
1925  hsurf7->Draw("SURF7");
1926  return c2;
1927 }
1928 End_Macro
1929 
1930 As shown in the following example, when a contour plot is painted on top of a
1931 surface plot using the option `SAME`, the contours appear in 3D on the
1932 surface.
1933 
1934 Begin_Macro(source)
1935 {
1936  TCanvas *c20=new TCanvas("c20","c20",600,400);
1937  int NBins = 50;
1938  double d = 2;
1939  TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
1940  for (int bx = 1; bx <= NBins; ++bx) {
1941  for (int by = 1; by <= NBins; ++by) {
1942  double x = hsc->GetXaxis()->GetBinCenter(bx);
1943  double y = hsc->GetYaxis()->GetBinCenter(by);
1944  hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
1945  }
1946  }
1947  gStyle->SetPalette(kBird);
1948  hsc->Draw("surf2");
1949  hsc->Draw("CONT1 SAME");
1950  return c20;
1951 }
1952 End_Macro
1953 
1954 
1955 ### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
1956 
1957 
1958 Legos and surfaces plots are represented by default in Cartesian coordinates.
1959 Combined with any `LEGOn` or `SURFn` options the following
1960 options allow to draw a lego or a surface in other coordinates systems.
1961 
1962 | Option | Description |
1963 |----------|-------------------------------------------------------------------|
1964 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
1965 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
1966 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
1967 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
1968 
1969 
1970 
1971 <b>WARNING:</b> Axis are not drawn with these options.
1972 
1973 The following example shows the same histogram as a lego plot is the four
1974 different coordinates systems.
1975 
1976 Begin_Macro(source)
1977 {
1978  TCanvas *c3 = new TCanvas("c3","c3",600,400);
1979  c3->Divide(2,2);
1980  TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
1981  Float_t px, py;
1982  for (Int_t i = 0; i < 25000; i++) {
1983  gRandom->Rannor(px,py);
1984  hlcc->Fill(px-1,5*py);
1985  hlcc->Fill(2+0.5*px,2*py-10.,0.1);
1986  }
1987  hlcc->SetFillColor(kYellow);
1988  c3->cd(1); hlcc->Draw("LEGO1 CYL");
1989  c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
1990  hlpc->SetTitle("Polar coordinates");
1991  c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
1992  hlsc->SetTitle("Spherical coordinates");
1993  c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
1994  hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
1995  return c3;
1996 }
1997 End_Macro
1998 
1999 The following example shows the same histogram as a surface plot is the four different coordinates systems.
2000 
2001 Begin_Macro(source)
2002 {
2003  TCanvas *c4 = new TCanvas("c4","c4",600,400);
2004  c4->Divide(2,2);
2005  TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2006  Float_t px, py;
2007  for (Int_t i = 0; i < 25000; i++) {
2008  gRandom->Rannor(px,py);
2009  hscc->Fill(px-1,5*py);
2010  hscc->Fill(2+0.5*px,2*py-10.,0.1);
2011  }
2012  gStyle->SetPalette(kBird);
2013  c4->cd(1); hscc->Draw("SURF1 CYL");
2014  c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2015  hspc->SetTitle("Polar coordinates");
2016  c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2017  hssc->SetTitle("Spherical coordinates");
2018  c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2019  hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2020  return c4;
2021 }
2022 End_Macro
2023 
2024 
2025 ### <a name="HP20"></a> Base line for bar-charts and lego plots
2026 
2027 
2028 By default the base line used to draw the boxes for bar-charts and lego plots is
2029 the histogram minimum. It is possible to force this base line to be 0 with the
2030 command:
2031 
2032  gStyle->SetHistMinimumZero();
2033 
2034 Begin_Macro(source)
2035 {
2036  TCanvas *c5 = new TCanvas("c5","c5",700,400);
2037  c5->Divide(2,1);
2038  gStyle->SetHistMinimumZero(1);
2039  TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2040  TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2041  Int_t i;
2042  Double_t x,y;
2043  hz1->SetFillColor(kBlue);
2044  hz2->SetFillColor(kBlue);
2045  for (i=0;i<10000;i++) {
2046  x = gRandom->Gaus(0,1);
2047  y = gRandom->Gaus(0,1);
2048  if (x>0) {
2049  hz1->Fill(x,1);
2050  hz2->Fill(x,y,1);
2051  } else {
2052  hz1->Fill(x,-1);
2053  hz2->Fill(x,y,-2);
2054  }
2055  }
2056  c5->cd(1); hz1->Draw("bar2");
2057  c5->cd(2); hz2->Draw("lego1");
2058  return c5;
2059 }
2060 End_Macro
2061 
2062 This option also works for horizontal plots. The example given in the section
2063 ["The bar chart option"](#HP100) appears as follow:
2064 
2065 Begin_Macro(source)
2066 {
2067  int i;
2068  const Int_t nx = 8;
2069  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2070  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2071  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2072 
2073  TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
2074  cbh->SetGrid();
2075 
2076  gStyle->SetHistMinimumZero();
2077 
2078  TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2079  h1bh->SetFillColor(4);
2080  h1bh->SetBarWidth(0.4);
2081  h1bh->SetBarOffset(0.1);
2082  h1bh->SetStats(0);
2083  h1bh->SetMinimum(-5);
2084  h1bh->SetMaximum(5);
2085 
2086  for (i=1; i<=nx; i++) {
2087  h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2088  h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2089  }
2090 
2091  h1bh->Draw("hbar");
2092 
2093  TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2094  h2bh->SetFillColor(38);
2095  h2bh->SetBarWidth(0.4);
2096  h2bh->SetBarOffset(0.5);
2097  h2bh->SetStats(0);
2098  for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2099 
2100  h2bh->Draw("hbar same");
2101 
2102  return cbh;
2103 }
2104 End_Macro
2105 
2106 
2107 ### <a name="HP20a"></a> TH2Poly Drawing
2108 
2109 
2110 The following options are supported:
2111 
2112 | Option | Description |
2113 |----------|-------------------------------------------------------------------|
2114 | "SCAT" | Draw a scatter plot (default).|
2115 | "COL" | Draw a color plot. All the none empty bins are painted. Empty bins are not painted.|
2116 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2117 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2118 | "TEXTN" | Draw bin names as text.|
2119 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2120 | "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2121 | "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2122 | "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2123 
2124 
2125 
2126 `TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2127 shapes. The bins are defined as graphs. The following macro is a very simple
2128 example showing how to book a TH2Poly and draw it.
2129 
2130 Begin_Macro(source)
2131 {
2132  TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2133  TH2Poly *h2p = new TH2Poly();
2134  h2p->SetName("h2poly_name");
2135  h2p->SetTitle("h2poly_title");
2136  Double_t px1[] = {0, 5, 6};
2137  Double_t py1[] = {0, 0, 5};
2138  Double_t px2[] = {0, -1, -1, 0};
2139  Double_t py2[] = {0, 0, -1, 3};
2140  Double_t px3[] = {4, 3, 0, 1, 2.4};
2141  Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
2142  h2p->AddBin(3, px1, py1);
2143  h2p->AddBin(4, px2, py2);
2144  h2p->AddBin(5, px3, py3);
2145  h2p->Fill(0.1, 0.01, 3);
2146  h2p->Fill(-0.5, -0.5, 7);
2147  h2p->Fill(-0.7, -0.5, 1);
2148  h2p->Fill(1, 3, 1.5);
2149  Double_t fx[] = {0.1, -0.5, -0.7, 1};
2150  Double_t fy[] = {0.01, -0.5, -0.5, 3};
2151  Double_t fw[] = {3, 1, 1, 1.5};
2152  h2p->FillN(4, fx, fy, fw);
2153  gStyle->SetPalette(kBird);
2154  h2p->Draw("col");
2155  return ch2p1;
2156 }
2157 End_Macro
2158 
2159 Rectangular bins are a frequent case. The special version of
2160 the `AddBin` method allows to define them more easily like
2161 shown in the following example (th2polyBoxes.C).
2162 
2163 Begin_Macro(source)
2164 ../../../tutorials/hist/th2polyBoxes.C
2165 End_Macro
2166 
2167 One `TH2Poly` bin can be a list of polygons. Such bins are defined
2168 by calling `AddBin` with a `TMultiGraph`. The following example
2169 shows a such case:
2170 
2171 Begin_Macro(source)
2172 {
2173  TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2174 
2175  Int_t i, bin;
2176  const Int_t nx = 48;
2177  const char *states [nx] = {
2178  "alabama", "arizona", "arkansas", "california",
2179  "colorado", "connecticut", "delaware", "florida",
2180  "georgia", "idaho", "illinois", "indiana",
2181  "iowa", "kansas", "kentucky", "louisiana",
2182  "maine", "maryland", "massachusetts", "michigan",
2183  "minnesota", "mississippi", "missouri", "montana",
2184  "nebraska", "nevada", "new_hampshire", "new_jersey",
2185  "new_mexico", "new_york", "north_carolina", "north_dakota",
2186  "ohio", "oklahoma", "oregon", "pennsylvania",
2187  "rhode_island", "south_carolina", "south_dakota", "tennessee",
2188  "texas", "utah", "vermont", "virginia",
2189  "washington", "west_virginia", "wisconsin", "wyoming"
2190  };
2191  Double_t pop[nx] = {
2192  4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2193  9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2194  1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2195  1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2196  11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2197  24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2198  };
2199 
2200  Double_t lon1 = -130;
2201  Double_t lon2 = -65;
2202  Double_t lat1 = 24;
2203  Double_t lat2 = 50;
2204  TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2205 
2206  TFile *f;
2207  f = TFile::Open("http://root.cern.ch/files/usa.root");
2208 
2209  TMultiGraph *mg;
2210  TKey *key;
2211  TIter nextkey(gDirectory->GetListOfKeys());
2212  while ((key = (TKey*)nextkey())) {
2213  TObject *obj = key->ReadObj();
2214  if (obj->InheritsFrom("TMultiGraph")) {
2215  mg = (TMultiGraph*)obj;
2216  bin = p->AddBin(mg);
2217  }
2218  }
2219 
2220  for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2221 
2222  gStyle->SetOptStat(11);
2223  gStyle->SetPalette(kBird);
2224  p->Draw("COLZ L");
2225  return ch2p2;
2226 }
2227 End_Macro
2228 
2229 `TH2Poly` histograms can also be plotted using the GL interface using
2230 the option "GLLEGO".
2231 
2232 ### <a name="HP21"></a> The SPEC option
2233 
2234 
2235 This option allows to use the `TSpectrum2Painter` tools. See the full
2236 documentation in `TSpectrum2Painter::PaintSpectrum`.
2237 
2238 
2239 ### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2240 
2241 
2242 When this option is specified, a color palette with an axis indicating the value
2243 of the corresponding color is drawn on the right side of the picture. In case,
2244 not enough space is left, one can increase the size of the right margin by
2245 calling `TPad::SetRightMargin()`. The attributes used to display the
2246 palette axis values are taken from the Z axis of the object. For example, to
2247 set the labels size on the palette axis do:
2248 
2249  hist->GetZaxis()->SetLabelSize().
2250 
2251 <b>WARNING:</b> The palette axis is always drawn vertically.
2252 
2253 
2254 ### <a name="HP23"></a> Setting the color palette
2255 
2256 
2257 To change the color palette `TStyle::SetPalette` should be used, eg:
2258 
2259  gStyle->SetPalette(ncolors,colors);
2260 
2261 For example the option `COL` draws a 2D histogram with cells
2262 represented by a box filled with a color index which is a function
2263 of the cell content.
2264 If the cell content is N, the color index used will be the color number
2265 in `colors[N]`, etc. If the maximum cell content is greater than
2266 `ncolors`, all cell contents are scaled to `ncolors`.
2267 
2268 If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2269 defined. This palette is recommended for pads, labels ...
2270 
2271 `if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2272 Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2273 palette.
2274 
2275 Other pre-defined palettes with 255 colors are available when `colors == 0`.
2276 The following value of `ncolors` give access to:
2277 
2278 
2279  if ncolors = 51 and colors=0, a Deep Sea palette is used.
2280  if ncolors = 52 and colors=0, a Grey Scale palette is used.
2281  if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2282  if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2283  if ncolors = 55 and colors=0, a Rain Bow palette is used.
2284  if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2285 
2286 
2287 If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2288 
2289 The default palette defines:
2290 
2291 - index 0 to 9 : shades of grey
2292 - index 10 to 19 : shades of brown
2293 - index 20 to 29 : shades of blue
2294 - index 30 to 39 : shades of red
2295 - index 40 to 49 : basic colors
2296 
2297 The color numbers specified in the palette can be viewed by selecting
2298 the item `colors` in the `VIEW` menu of the canvas tool bar.
2299 The red, green, and blue components of a color can be changed thanks to
2300 `TColor::SetRGB()`.
2301 
2302 
2303 ### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2304 
2305 
2306 Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2307 histogram. One must create a graphical cut (mouse or C++) and specify the name
2308 of the cut between `[]` in the `Draw()` option.
2309 For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2310 
2311  myhist->Draw("surf1 [cutg]");
2312 
2313 To invert the cut, it is enough to put a `-` in front of its name:
2314 
2315  myhist->Draw("surf1 [-cutg]");
2316 
2317 It is possible to apply several cuts (`,` means logical AND):
2318 
2319  myhist->Draw("surf1 [cutg1,cutg2]");
2320 
2321 Begin_Macro(source)
2322 ../../../tutorials/fit/fit2a.C
2323 End_Macro
2324 
2325 ### <a name="HP25"></a> Drawing options for 3D histograms
2326 
2327 
2328 | Option | Description |
2329 |----------|-------------------------------------------------------------------|
2330 | "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)`|
2331 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value.|
2332 
2333 
2334 
2335 By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2336 
2337 The following example shows a 3D histogram plotted as a scatter plot.
2338 
2339 Begin_Macro(source)
2340 {
2341  TCanvas *c06 = new TCanvas("c06","c06",600,400);
2342  gStyle->SetOptStat(kFALSE);
2343  TH3F *h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2344  Double_t x, y, z;
2345  for (Int_t i=0;i<10000;i++) {
2346  gRandom->Rannor(x, y);
2347  z = x*x + y*y;
2348  h3scat->Fill(x,y,z);
2349  }
2350  h3scat->Draw();
2351  return c06;
2352 }
2353 End_Macro
2354 
2355 The following example shows a 3D histogram plotted with the option `BOX`.
2356 
2357 Begin_Macro(source)
2358 {
2359  TCanvas *c16 = new TCanvas("c16","c16",600,400);
2360  gStyle->SetOptStat(kFALSE);
2361  TH3F *h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2362  Double_t x, y, z;
2363  for (Int_t i=0;i<10000;i++) {
2364  gRandom->Rannor(x, y);
2365  z = x*x + y*y;
2366  h3box->Fill(x,y,z);
2367  }
2368  h3box->Draw("BOX");
2369  return c16;
2370 }
2371 End_Macro
2372 
2373 The following example shows a 3D histogram plotted with the option `ISO`.
2374 
2375 Begin_Macro(source)
2376 {
2377  TCanvas *c26 = new TCanvas("c26","c26",600,400);
2378  gStyle->SetOptStat(kFALSE);
2379  TH3F *h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2380  Double_t x, y, z;
2381  for (Int_t i=0;i<10000;i++) {
2382  gRandom->Rannor(x, y);
2383  z = x*x + y*y;
2384  h3iso->Fill(x,y,z);
2385  }
2386  h3iso->SetFillColor(kCyan);
2387  h3iso->Draw("ISO");
2388  return c26;
2389 }
2390 End_Macro
2391 
2392 
2393 ### <a name="HP26"></a> Drawing option for histograms' stacks
2394 
2395 
2396 Stacks of histograms are managed with the `THStack`. A `THStack`
2397 is a collection of `TH1` (or derived) objects. For painting only the
2398 `THStack` containing `TH1` only or
2399 `THStack` containing `TH2` only will be considered.
2400 
2401 By default, histograms are shown stacked:
2402 
2403 1. The first histogram is paint.
2404 2. The the sum of the first and second, etc...
2405 
2406 If the option `NOSTACK` is specified, the histograms are all paint in
2407 the same pad as if the option `SAME` had been specified. This allows to
2408 compute X and Y scales common to all the histograms, like
2409 `TMultiGraph` does for graphs.
2410 
2411 If the option `PADS` is specified, the current pad/canvas is
2412 subdivided into a number of pads equal to the number of histograms and each
2413 histogram is paint into a separate pad.
2414 
2415 The following example shows various types of stacks (hstack.C).
2416 
2417 Begin_Macro(source)
2418 ../../../tutorials/hist/hstack.C
2419 End_Macro
2420 
2421 The option `nostackb` allows to draw the histograms next to each
2422 other as bar charts:
2423 
2424 Begin_Macro(source)
2425 {
2426  TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2427  THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2428 
2429  TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2430  h1->FillRandom("gaus",20000);
2431  h1->SetFillColor(kRed);
2432  hs->Add(h1);
2433 
2434  TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2435  h2->FillRandom("gaus",15000);
2436  h2->SetFillColor(kBlue);
2437  hs->Add(h2);
2438 
2439  TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2440  h3->FillRandom("gaus",10000);
2441  h3->SetFillColor(kGreen);
2442  hs->Add(h3);
2443 
2444  hs->Draw("nostackb");
2445  hs->GetXaxis()->SetNdivisions(-10);
2446  cst0->SetGridx();
2447  return cst0;
2448 }
2449 End_Macro
2450 
2451 If at least one of the histograms in the stack has errors, the whole stack is
2452 visualized by default with error bars. To visualize it without errors the
2453 option `HIST` should be used.
2454 
2455 Begin_Macro(source)
2456 {
2457  TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2458  cst1->Divide(2,1);
2459 
2460  TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2461  hst11->Sumw2();
2462  hst11->FillRandom("gaus", 1000);
2463  hst11->SetFillColor(kViolet);
2464  hst11->SetLineColor(kViolet);
2465 
2466  TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2467  hst12->FillRandom("gaus", 500);
2468  hst12->SetFillColor(kBlue);
2469  hst12->SetLineColor(kBlue);
2470 
2471  THStack st1("st1", "st1");
2472  st1.Add(hst11);
2473  st1.Add(hst12);
2474 
2475  cst1->cd(1); st1.Draw();
2476  cst1->cd(2); st1.Draw("hist");
2477 
2478  return cst1;
2479 }
2480 End_Macro
2481 
2482 ### <a name="HP27"></a> Drawing of 3D implicit functions
2483 
2484 
2485 3D implicit functions (`TF3`) can be drawn as iso-surfaces.
2486 The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2487 In the following example the options "FB" and "BB" suppress the
2488 "Front Box" and "Back Box" around the plot.
2489 
2490 Begin_Macro(source)
2491 {
2492  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2493  TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2494  f3->SetClippingBoxOn(0,0,0);
2495  f3->SetFillColor(30);
2496  f3->SetLineColor(15);
2497  f3->Draw("FBBB");
2498  return c2;
2499 }
2500 End_Macro
2501 
2502 
2503 ### <a name="HP28"></a> Associated functions drawing
2504 
2505 
2506 An associated function is created by `TH1::Fit`. More than on fitted
2507 function can be associated with one histogram (see `TH1::Fit`).
2508 
2509 A `TF1` object `f1` can be added to the list of associated
2510 functions of an histogram `h` without calling `TH1::Fit`
2511 simply doing:
2512 
2513  h->GetListOfFunctions()->Add(f1);
2514 
2515 or
2516 
2517  h->GetListOfFunctions()->Add(f1,someoption);
2518 
2519 To retrieve a function by name from this list, do:
2520 
2521  TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2522 
2523 or
2524 
2525  TF1 *f1 = h->GetFunction(name);
2526 
2527 Associated functions are automatically painted when an histogram is drawn.
2528 To avoid the painting of the associated functions the option `HIST`
2529 should be added to the list of the options used to paint the histogram.
2530 
2531 
2532 ### <a name="HP29"></a> Drawing using OpenGL
2533 
2534 
2535 The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2536 graphics library. The plotting options start with `GL` keyword.
2537 In addition, in order to inform canvases that OpenGL should be used to render
2538 3D representations, the following option should be set:
2539 
2540  gStyle->SetCanvasPreferGL(true);
2541 
2542 
2543 #### <a name="HP29a"></a> General information: plot types and supported options
2544 
2545 The following types of plots are provided:
2546 
2547 For lego plots the supported options are:
2548 
2549 | Option | Description |
2550 |----------|-------------------------------------------------------------------|
2551 | "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2552 | "GLLEGO2"| Bins with color levels.|
2553 | "GLLEGO3"| Cylindrical bars.|
2554 
2555 
2556 
2557 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2558 In polar only Z axis can be logarithmic, in cylindrical only Y.
2559 
2560 For surface plots (`TF2` and `TH2`) the supported options are:
2561 
2562 | Option | Description |
2563 |-----------|------------------------------------------------------------------|
2564 | "GLSURF" | Draw a surface.|
2565 | "GLSURF1" | Surface with color levels|
2566 | "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2567 | "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2568 | "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2569 
2570 
2571 
2572 The surface painting in cartesian coordinates supports logarithmic scales along
2573 X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2574 in cylindrical coordinates only the Y axis.
2575 
2576 Additional options to SURF and LEGO - Coordinate systems:
2577 
2578 | Option | Description |
2579 |----------|-------------------------------------------------------------------|
2580 | " " | Default, cartesian coordinates system.|
2581 | "POL" | Polar coordinates system.|
2582 | "CYL" | Cylindrical coordinates system.|
2583 | "SPH" | Spherical coordinates system.|
2584 
2585 
2586 
2587 #### <a name="HP290"></a> TH3 as color boxes
2588 
2589 The supported option is:
2590 
2591 | Option | Description |
2592 |----------|-------------------------------------------------------------------|
2593 | "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2594 
2595 
2596 
2597 #### <a name="HP29b"></a> TH3 as boxes (spheres)
2598 
2599 The supported options are:
2600 
2601 | Option | Description |
2602 |----------|-------------------------------------------------------------------|
2603 | "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2604 | "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2605 
2606 
2607 
2608 #### <a name="HP29c"></a> TH3 as iso-surface(s)
2609 
2610 The supported option is:
2611 
2612 | Option | Description |
2613 |----------|-------------------------------------------------------------------|
2614 | "GLISO" | TH3 is drawn using iso-surfaces.|
2615 
2616 
2617 
2618 #### <a name="HP29d"></a> TF3 (implicit function)
2619 
2620 The supported option is:
2621 
2622 | Option | Description |
2623 |----------|-------------------------------------------------------------------|
2624 | "GLTF3" | Draw a TF3.|
2625 
2626 
2627 
2628 #### <a name="HP29e"></a> Parametric surfaces
2629 
2630 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2631 equations and visualize the surface.
2632 
2633 #### <a name="HP29f"></a> Interaction with the plots
2634 
2635 All the interactions are implemented via standard methods
2636 `DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2637 interactions with the OpenGL plots are possible only when the mouse cursor is
2638 in the plot's area (the plot's area is the part of a the pad occupied by
2639 gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2640 pad interaction is performed.
2641 
2642 #### <a name="HP29g"></a> Selectable parts
2643 
2644 Different parts of the plot can be selected:
2645 
2646 - xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2647  if the dynamic slicing by this plane is supported, and it's highlighted in red,
2648  if the dynamic slicing is not supported.
2649 - The plot itself:
2650  On surfaces, the selected surface is outlined in red. (TF3 and
2651  ISO are not outlined). On lego plots, the selected bin is
2652  highlighted. The bin number and content are displayed in pad's
2653  status bar. In box plots, the box or sphere is highlighted and
2654  the bin info is displayed in pad's status bar.
2655 
2656 
2657 #### <a name="HP29h"></a> Rotation and zooming
2658 
2659 
2660 - Rotation:
2661  When the plot is selected, it can be rotated by pressing and
2662  holding the left mouse button and move the cursor.
2663 - Zoom/Unzoom:
2664  Mouse wheel or 'j', 'J', 'k', 'K' keys.
2665 
2666 
2667 #### <a name="HP29i"></a> Panning
2668 
2669 The selected plot can be moved in a pad's area by pressing and
2670 holding the left mouse button and the shift key.
2671 
2672 #### <a name="HP29j"></a> Box cut
2673 
2674 Surface, iso, box, TF3 and parametric painters support box cut by
2675 pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2676 area. That will display a transparent box, cutting away part of the
2677 surface (or boxes) in order to show internal part of plot. This box
2678 can be moved inside the plot's area (the full size of the box is
2679 equal to the plot's surrounding box) by selecting one of the box
2680 cut axes and pressing the left mouse button to move it.
2681 
2682 #### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2683 
2684 Currently, all gl-plots support some form of slicing. When back plane
2685 is selected (and if it's highlighted in green) you can press and hold
2686 left mouse button and shift key and move this back plane inside
2687 plot's area, creating the slice. During this "slicing" plot becomes
2688 semi-transparent. To remove all slices (and projected curves for
2689 surfaces) double click with left mouse button in a plot's area.
2690 
2691 #### <a name="HP29l"></a> Surface with option "GLSURF"
2692 
2693 The surface profile is displayed on the slicing plane.
2694 The profile projection is drawn on the back plane
2695 by pressing `'p'` or `'P'` key.
2696 
2697 #### <a name="HP29m"></a> TF3
2698 
2699 The contour plot is drawn on the slicing plane. For TF3 the color
2700 scheme can be changed by pressing 's' or 'S'.
2701 
2702 #### <a name="HP29n"></a> Box
2703 
2704 The contour plot corresponding to slice plane position is drawn in real time.
2705 
2706 #### <a name="HP29o"></a> Iso
2707 
2708 Slicing is similar to "GLBOX" option.
2709 
2710 #### <a name="HP29p"></a> Parametric plot
2711 
2712 No slicing. Additional keys: 's' or 'S' to change color scheme -
2713 about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2714 increase number of polygons ('l' for "level" of details), 'w' or 'W'
2715 to show outlines ('w' for "wireframe").
2716 
2717 */
2718 
2719 TH1 *gCurrentHist = 0;
2720 
2723 
2724 const Int_t kNMAX = 2000;
2725 
2726 const Int_t kMAXCONTOUR = 104;
2728 
2731 static TString gStringMeanX;
2733 static TString gStringMeanZ;
2736 static TString gStringStdDevY;
2753 ////////////////////////////////////////////////////////////////////////////////
2754 /// Default constructor.
2758 
2759  fH = 0;
2760  fXaxis = 0;
2761  fYaxis = 0;
2762  fZaxis = 0;
2763  fFunctions = 0;
2764  fXbuf = 0;
2765  fYbuf = 0;
2766  fNcuts = 0;
2767  fStack = 0;
2768  fLego = 0;
2769  fPie = 0;
2770  fGraph2DPainter = 0;
2771  fShowProjection = 0;
2772  fShowOption = "";
2773  for (int i=0; i<kMaxCuts; i++) {
2774  fCuts[i] = 0;
2775  fCutsOpt[i] = 0;
2776  }
2777 
2778  gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
2779  gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
2780  gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
2781  gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
2782  gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
2783  gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
2784  gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
2785  gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
2786  gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
2787  gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
2788  gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
2789  gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
2790  gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
2791  gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
2792  gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
2793  gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
2794  gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
2795  gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
2796  gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
2797  gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
2798  gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
2799 }
2800 
2801 ////////////////////////////////////////////////////////////////////////////////
2802 /// Default destructor.
2803 
2805 {
2806 }
2807 
2808 ////////////////////////////////////////////////////////////////////////////////
2809 /// Compute the distance from the point px,py to a line.
2810 ///
2811 /// Compute the closest distance of approach from point px,py to elements of
2812 /// an histogram. The distance is computed in pixels units.
2813 ///
2814 /// Algorithm: Currently, this simple model computes the distance from the mouse
2815 /// to the histogram contour only.
2816 
2818 {
2819 
2820  Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
2821 
2822  const Int_t big = 9999;
2823  const Int_t kMaxDiff = 7;
2824 
2825  if (fPie) return fPie->DistancetoPrimitive(px, py);
2826 
2827  Double_t x = gPad->AbsPixeltoX(px);
2828  Double_t x1 = gPad->AbsPixeltoX(px+1);
2829 
2830  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
2831  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
2832  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
2833  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
2834  Int_t curdist = big;
2835  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
2836  Bool_t dsame;
2837  TObject *PadPointer = gPad->GetPadPointer();
2838  if (!PadPointer) return 0;
2839  TString doption = PadPointer->GetDrawOption();
2840  Double_t factor = 1;
2841  if (fH->GetNormFactor() != 0) {
2842  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
2843  }
2844  // return if point is not in the histogram area
2845 
2846  // If a 3D view exists, check distance to axis
2847  TView *view = gPad->GetView();
2848  Int_t d1,d2,d3;
2849  if (view && Hoption.Contour != 14) {
2850  Double_t ratio;
2851  d3 = view->GetDistancetoAxis(3, px, py, ratio);
2852  if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
2853  d1 = view->GetDistancetoAxis(1, px, py, ratio);
2854  if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
2855  d2 = view->GetDistancetoAxis(2, px, py, ratio);
2856  if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
2857  if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
2858  goto FUNCTIONS;
2859  }
2860  // check if point is close to an axis
2861  doption.ToLower();
2862  dsame = kFALSE;
2863  if (doption.Contains("same")) dsame = kTRUE;
2864 
2865  dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
2866  if (doption.Contains("y+")) {
2867  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2868  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
2869  if (!dsame) {
2870  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2871  else gPad->SetSelected(fXaxis);
2872  return 0;
2873  }
2874  }
2875  } else {
2876  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2877  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
2878  if (!dsame) {
2879  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2880  else gPad->SetSelected(fXaxis);
2881  return 0;
2882  }
2883  }
2884  }
2885 
2886  dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
2887  if (doption.Contains("x+")) {
2888  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2889  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
2890  if (!dsame) {
2891  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2892  else gPad->SetSelected(fYaxis);
2893  return 0;
2894  }
2895  }
2896  } else {
2897  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2898  if (yxaxis < puymin) yxaxis = puymin;
2899  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
2900  if (!dsame) {
2901  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2902  else gPad->SetSelected(fYaxis);
2903  return 0;
2904  }
2905  }
2906  }
2907 
2908  // if object is 2D or 3D return this object
2909  if (fH->GetDimension() == 2) {
2910  if (fH->InheritsFrom(TH2Poly::Class())) {
2911  TH2Poly *th2 = (TH2Poly*)fH;
2912  Double_t xmin, ymin, xmax, ymax;
2913  gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
2914  Double_t pxu = gPad->AbsPixeltoX(px);
2915  Double_t pyu = gPad->AbsPixeltoY(py);
2916  if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
2917  curdist = big;
2918  goto FUNCTIONS;
2919  } else {
2920  Int_t bin = th2->FindBin(pxu, pyu);
2921  if (bin>0) curdist = 1;
2922  else curdist = big;
2923  goto FUNCTIONS;
2924  }
2925  }
2926  Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
2927  if ( px > puxmin + delta2
2928  && px < puxmax - delta2
2929  && py > puymax + delta2
2930  && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
2931  }
2932 
2933  // point is inside histogram area. Find channel number
2934  if (gPad->IsVertical()) {
2935  Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
2936  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
2937  Double_t binval = factor*fH->GetBinContent(bin);
2938  Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
2939  if (binval == 0 && pybin < puymin) pybin = 10000;
2940  // special case if more than one bin for the pixel
2941  if (binsup-bin>1) {
2942  Double_t binvalmin, binvalmax;
2943  binvalmin=binval;
2944  binvalmax=binval;
2945  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2946  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2947  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2948  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2949  }
2950  Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
2951  Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
2952  if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
2953  }
2954  if (bin != binsup) { // Mouse on bin border border
2955  Double_t binsupval = factor*fH->GetBinContent(binsup);
2956  Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
2957  if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin)) return 0;
2958  }
2959  if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
2960  } else {
2961  Double_t y = gPad->AbsPixeltoY(py);
2962  Double_t y1 = gPad->AbsPixeltoY(py+1);
2963  Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
2964  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
2965  Double_t binval = factor*fH->GetBinContent(bin);
2966  Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
2967  if (binval == 0 && pxbin > puxmin) pxbin = 10000;
2968  // special case if more than one bin for the pixel
2969  if (binsup-bin>1) {
2970  Double_t binvalmin, binvalmax;
2971  binvalmin=binval;
2972  binvalmax=binval;
2973  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2974  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2975  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2976  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2977  }
2978  Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
2979  Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
2980  if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
2981  }
2982  if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
2983  }
2984  // Loop on the list of associated functions and user objects
2985 FUNCTIONS:
2986  TObject *f;
2987  TIter next(fFunctions);
2988  while ((f = (TObject*) next())) {
2989  Int_t dist;
2990  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
2991  else dist = f->DistancetoPrimitive(px,py);
2992  if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
2993  }
2994  return curdist;
2995 }
2996 
2997 ////////////////////////////////////////////////////////////////////////////////
2998 /// Display a panel with all histogram drawing options.
2999 
3001 {
3002 
3003  gCurrentHist = fH;
3004  if (!gPad) {
3005  Error("DrawPanel", "need to draw histogram first");
3006  return;
3007  }
3009  editor->Show();
3010  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3011  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3012 }
3013 
3014 ////////////////////////////////////////////////////////////////////////////////
3015 /// Execute the actions corresponding to `event`.
3016 ///
3017 /// This function is called when a histogram is clicked with the locator at
3018 /// the pixel position px,py.
3019 
3020 void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3021 {
3022 
3023  if (!gPad) return;
3024 
3025  static Int_t bin, px1, py1, px2, py2, pyold;
3026  static TBox *zoombox;
3027  Double_t zbx1,zbx2,zby1,zby2;
3029  Int_t bin1, bin2;
3030  Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3031  Bool_t opaque = gPad->OpaqueMoving();
3032 
3033  if (!gPad->IsEditable()) return;
3034 
3035  if (fPie) {
3036  fPie->ExecuteEvent(event, px, py);
3037  return;
3038  }
3039  // come here if we have a lego/surface in the pad
3040  TView *view = gPad->GetView();
3041 
3042  if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3043  view->ExecuteRotateView(event, px, py);
3044  return;
3045  }
3046 
3047  TAxis *xaxis = fH->GetXaxis();
3048  TAxis *yaxis = fH->GetYaxis();
3049  Int_t dimension = fH->GetDimension();
3050 
3051  Double_t factor = 1;
3052  if (fH->GetNormFactor() != 0) {
3053  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3054  }
3055 
3056  switch (event) {
3057 
3058  case kButton1Down:
3059 
3060  if (!opaque) gVirtualX->SetLineColor(-1);
3061  fH->TAttLine::Modify();
3062 
3063  if (opaque && dimension ==2) {
3064  zbx1 = gPad->AbsPixeltoX(px);
3065  zbx2 = gPad->AbsPixeltoX(px);
3066  zby1 = gPad->AbsPixeltoY(py);
3067  zby2 = gPad->AbsPixeltoY(py);
3068  px1 = px;
3069  py1 = py;
3070  if (gPad->GetLogx()) {
3071  zbx1 = TMath::Power(10,zbx1);
3072  zbx2 = TMath::Power(10,zbx2);
3073  }
3074  if (gPad->GetLogy()) {
3075  zby1 = TMath::Power(10,zby1);
3076  zby2 = TMath::Power(10,zby2);
3077  }
3078  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3079  Int_t ci = TColor::GetColor("#7d7dff");
3080  TColor *zoomcolor = gROOT->GetColor(ci);
3081  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3082  else zoomcolor->SetAlpha(0.5);
3083  zoombox->SetFillColor(ci);
3084  zoombox->Draw();
3085  gPad->Modified();
3086  gPad->Update();
3087  }
3088  // No break !!!
3089 
3090  case kMouseMotion:
3091 
3092  if (fShowProjection) {ShowProjection3(px,py); break;}
3093 
3094  gPad->SetCursor(kPointer);
3095  if (dimension ==1) {
3096  if (Hoption.Bar) {
3097  baroffset = fH->GetBarOffset();
3098  barwidth = fH->GetBarWidth();
3099  } else {
3100  baroffset = 0;
3101  barwidth = 1;
3102  }
3103  x = gPad->AbsPixeltoX(px);
3104  bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3105  binwidth = fXaxis->GetBinWidth(bin);
3106  xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3107  xup = gPad->XtoPad(xlow + barwidth*binwidth);
3108  ylow = gPad->GetUymin();
3109  px1 = gPad->XtoAbsPixel(xlow);
3110  px2 = gPad->XtoAbsPixel(xup);
3111  py1 = gPad->YtoAbsPixel(ylow);
3112  py2 = py;
3113  pyold = py;
3114  if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3115  }
3116 
3117  break;
3118 
3119  case kButton1Motion:
3120 
3121  if (dimension ==1) {
3122  if (gROOT->GetEditHistograms()) {
3123  if (!opaque) {
3124  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3125  py2 += py - pyold;
3126  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3127  pyold = py;
3128  } else {
3129  py2 += py - pyold;
3130  pyold = py;
3131  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3132  fH->SetBinContent(bin,binval);
3133  gPad->Modified(kTRUE);
3134  }
3135  }
3136  }
3137 
3138  if (opaque && dimension ==2) {
3139  if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3140  zbx2 = gPad->AbsPixeltoX(px);
3141  zby2 = gPad->AbsPixeltoY(py);
3142  if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3143  if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3144  zoombox->SetX2(zbx2);
3145  zoombox->SetY2(zby2);
3146  gPad->Modified();
3147  gPad->Update();
3148  }
3149  }
3150 
3151  break;
3152 
3153  case kWheelUp:
3154 
3155  if (dimension ==2) {
3156  bin1 = xaxis->GetFirst()+1;
3157  bin2 = xaxis->GetLast()-1;
3158  bin1 = TMath::Max(bin1, 1);
3159  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3160  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3161  bin1 = yaxis->GetFirst()+1;
3162  bin2 = yaxis->GetLast()-1;
3163  bin1 = TMath::Max(bin1, 1);
3164  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3165  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3166  }
3167  gPad->Modified();
3168  gPad->Update();
3169 
3170  break;
3171 
3172  case kWheelDown:
3173 
3174  if (dimension == 2) {
3175  bin1 = xaxis->GetFirst()-1;
3176  bin2 = xaxis->GetLast()+1;
3177  bin1 = TMath::Max(bin1, 1);
3178  bin2 = TMath::Min(bin2, xaxis->GetNbins());
3179  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3180  bin1 = yaxis->GetFirst()-1;
3181  bin2 = yaxis->GetLast()+1;
3182  bin1 = TMath::Max(bin1, 1);
3183  bin2 = TMath::Min(bin2, yaxis->GetNbins());
3184  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3185  }
3186  gPad->Modified();
3187  gPad->Update();
3188 
3189  break;
3190 
3191  case kButton1Up:
3192  if (dimension ==1) {
3193  if (gROOT->GetEditHistograms()) {
3194  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3195  fH->SetBinContent(bin,binval);
3196  PaintInit(); // recalculate Hparam structure and recalculate range
3197  }
3198 
3199  // might resize pad pixmap so should be called before any paint routine
3200  RecalculateRange();
3201  }
3202  if (opaque && dimension ==2) {
3203  if (zoombox) {
3204  Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3205  Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3206  Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3207  Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3208  x1 = TMath::Max(x1,xaxis->GetXmin());
3209  x2 = TMath::Min(x2,xaxis->GetXmax());
3210  y1 = TMath::Max(y1,yaxis->GetXmin());
3211  y2 = TMath::Min(y2,yaxis->GetXmax());
3212  if (x1<x2 && y1<y2) {
3213  xaxis->SetRangeUser(x1, x2);
3214  yaxis->SetRangeUser(y1, y2);
3215  }
3216  zoombox->Delete();
3217  zoombox = 0;
3218  }
3219  }
3220  gPad->Modified(kTRUE);
3221  if (opaque) gVirtualX->SetLineColor(-1);
3222 
3223  break;
3224 
3225  case kButton1Locate:
3226 
3227  ExecuteEvent(kButton1Down, px, py);
3228 
3229  while (1) {
3230  px = py = 0;
3231  event = gVirtualX->RequestLocator(1, 1, px, py);
3232 
3233  ExecuteEvent(kButton1Motion, px, py);
3234 
3235  if (event != -1) { // button is released
3236  ExecuteEvent(kButton1Up, px, py);
3237  return;
3238  }
3239  }
3240  }
3241 }
3242 
3243 ////////////////////////////////////////////////////////////////////////////////
3244 /// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3245 
3247 {
3248 
3249 
3250 
3251  // Check if fH contains a TGraphDelaunay2D
3252  TList *hl = fH->GetListOfFunctions();
3253  TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3254  // try with the old painter
3255  TGraphDelaunay *dtOld = nullptr;
3256  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3257 
3258  if (!dt && !dtOld) return nullptr;
3259 
3260  gCurrentHist = fH;
3261 
3262  if (!fGraph2DPainter) {
3263  if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3264  else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3265  }
3266 
3267  return fGraph2DPainter->GetContourList(contour);
3268 }
3269 
3270 ////////////////////////////////////////////////////////////////////////////////
3271 /// Display the histogram info (bin number, contents, integral up to bin
3272 /// corresponding to cursor position px,py.
3273 
3274 char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
3275 {
3276 
3277  if (!gPad) return (char*)"";
3278  static char info[200];
3279  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3280  Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3281  Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3282  TString drawOption = fH->GetDrawOption();
3283  drawOption.ToLower();
3284  Double_t xmin, xmax, uxmin,uxmax;
3285  Double_t ymin, ymax, uymin,uymax;
3286  if (fH->GetDimension() == 2) {
3287  if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3288  uxmin=gPad->GetUxmin();
3289  uxmax=gPad->GetUxmax();
3290  xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
3291  xmax = fXaxis->GetBinUpEdge(fXaxis->GetLast());
3292  x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3293  uymin=gPad->GetUymin();
3294  uymax=gPad->GetUymax();
3295  ymin = fYaxis->GetBinLowEdge(fYaxis->GetFirst());
3296  ymax = fYaxis->GetBinUpEdge(fYaxis->GetLast());
3297  y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3298  }
3299  }
3300  Int_t binx,biny,binmin=0,binx1;
3301  if (gPad->IsVertical()) {
3302  binx = fXaxis->FindFixBin(x);
3303  if (drawOption.Index("same") >= 0) {
3304  TH1 *h1;
3305  TIter next(gPad->GetListOfPrimitives());
3306  while ((h1 = (TH1 *)next())) {
3307  if (!h1->InheritsFrom(TH1::Class())) continue;
3308  binmin = h1->GetXaxis()->GetFirst();
3309  break;
3310  }
3311  } else {
3312  binmin = fXaxis->GetFirst();
3313  }
3314  binx1 = fXaxis->FindFixBin(x1);
3315  // special case if more than 1 bin in x per pixel
3316  if (binx1-binx>1 && fH->GetDimension() == 1) {
3317  Double_t binval=fH->GetBinContent(binx);
3318  Int_t binnear=binx;
3319  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3320  Double_t binvaltmp = fH->GetBinContent(ibin);
3321  if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3322  binval=binvaltmp;
3323  binnear=ibin;
3324  }
3325  }
3326  binx = binnear;
3327  }
3328  } else {
3329  x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3330  binx = fXaxis->FindFixBin(y);
3331  if (drawOption.Index("same") >= 0) {
3332  TH1 *h1;
3333  TIter next(gPad->GetListOfPrimitives());
3334  while ((h1 = (TH1 *)next())) {
3335  if (!h1->InheritsFrom(TH1::Class())) continue;
3336  binmin = h1->GetXaxis()->GetFirst();
3337  break;
3338  }
3339  } else {
3340  binmin = fXaxis->GetFirst();
3341  }
3342  binx1 = fXaxis->FindFixBin(x1);
3343  // special case if more than 1 bin in x per pixel
3344  if (binx1-binx>1 && fH->GetDimension() == 1) {
3345  Double_t binval=fH->GetBinContent(binx);
3346  Int_t binnear=binx;
3347  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3348  Double_t binvaltmp = fH->GetBinContent(ibin);
3349  if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3350  binval=binvaltmp;
3351  binnear=ibin;
3352  }
3353  }
3354  binx = binnear;
3355  }
3356  }
3357  if (fH->GetDimension() == 1) {
3358  if (fH->InheritsFrom(TProfile::Class())) {
3359  TProfile *tp = (TProfile*)fH;
3360  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3361  x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3362  (Int_t) tp->GetBinEntries(binx));
3363  }
3364  else {
3365  Double_t integ = 0;
3366  for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3367  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3368  x,y,binx,fH->GetBinContent(binx),integ);
3369  }
3370  } else if (fH->GetDimension() == 2) {
3371  if (fH->InheritsFrom(TH2Poly::Class())) {
3372  TH2Poly *th2 = (TH2Poly*)fH;
3373  biny = th2->FindBin(x,y);
3374  snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3375  th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3376  }
3377  else if (fH->InheritsFrom(TProfile2D::Class())) {
3378  TProfile2D *tp = (TProfile2D*)fH;
3379  biny = fYaxis->FindFixBin(y);
3380  Int_t bin = fH->GetBin(binx,biny);
3381  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3382  x, y, binx, biny, fH->GetBinContent(bin),
3383  fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3384  } else {
3385  biny = fYaxis->FindFixBin(y);
3386  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3387  x,y,binx,biny,fH->GetBinContent(binx,biny),
3388  fH->GetBinError(binx,biny));
3389  }
3390  } else {
3391  // 3d case: retrieving the x,y,z bin is not yet implemented
3392  // print just the x,y info
3393  snprintf(info,200,"(x=%g, y=%g)",x,y);
3394  }
3395  return info;
3396 }
3397 
3398 ////////////////////////////////////////////////////////////////////////////////
3399 /// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3400 
3402 {
3403 
3404  for (Int_t i=0;i<fNcuts;i++) {
3405  Double_t x = fXaxis->GetBinCenter(ix);
3406  Double_t y = fYaxis->GetBinCenter(iy);
3407  if (fCutsOpt[i] > 0) {
3408  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3409  } else {
3410  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3411  }
3412  }
3413  return kTRUE;
3414 }
3415 
3416 ////////////////////////////////////////////////////////////////////////////////
3417 /// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3418 
3420 {
3421 
3422  for (Int_t i=0;i<fNcuts;i++) {
3423  if (fCutsOpt[i] > 0) {
3424  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3425  } else {
3426  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3427  }
3428  }
3429  return kTRUE;
3430 }
3431 
3432 ////////////////////////////////////////////////////////////////////////////////
3433 /// Decode string `choptin` and fill Hoption structure.
3434 
3436 {
3437 
3438  char *l;
3439  char chopt[128];
3440  Int_t nch = strlen(choptin);
3441  strlcpy(chopt,choptin,128);
3442  Int_t hdim = fH->GetDimension();
3444  Hoption.Axis = Hoption.Bar = Hoption.Curve = Hoption.Error = 0;
3445  Hoption.Hist = Hoption.Line = Hoption.Mark = Hoption.Fill = 0;
3446  Hoption.Same = Hoption.Func = Hoption.Scat = 0;
3447  Hoption.Star = Hoption.Arrow = Hoption.Box = Hoption.Text = 0;
3448  Hoption.Char = Hoption.Color = Hoption.Contour = Hoption.Logx = 0;
3449  Hoption.Logy = Hoption.Logz = Hoption.Lego = Hoption.Surf = 0;
3450  Hoption.Off = Hoption.Tri = Hoption.Proj = Hoption.AxisPos = 0;
3451  Hoption.Spec = Hoption.Pie = Hoption.Candle = Hoption.Violin = 0;
3452 
3453  // special 2D options
3454  Hoption.List = 0;
3455  Hoption.Zscale = 0;
3456  Hoption.FrontBox = 1;
3457  Hoption.BackBox = 1;
3458  Hoption.System = kCARTESIAN;
3459 
3460  Hoption.Zero = 0;
3461 
3462  //check for graphical cuts
3463  MakeCuts(chopt);
3464 
3465  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3466  if (hdim > 1) Hoption.Scat = 1;
3467  if (!nch) Hoption.Hist = 1;
3468  if (fFunctions->First()) Hoption.Func = 1;
3469  if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3470 
3471  l = strstr(chopt,"SPEC");
3472  if (l) {
3473  Hoption.Scat = 0;
3474  strncpy(l," ",4);
3475  Int_t bs=0;
3476  l = strstr(chopt,"BF(");
3477  if (l) {
3478  if (sscanf(&l[3],"%d",&bs) > 0) {
3479  Int_t i=0;
3480  while (l[i]!=')') {
3481  l[i] = ' ';
3482  i++;
3483  }
3484  l[i] = ' ';
3485  }
3486  }
3487  Hoption.Spec = TMath::Max(1600,bs);
3488  return 1;
3489  }
3490 
3491  l = strstr(chopt,"GL");
3492  if (l) {
3493  strncpy(l," ",2);
3494  }
3495  l = strstr(chopt,"X+");
3496  if (l) {
3497  Hoption.AxisPos = 10;
3498  strncpy(l," ",2);
3499  }
3500  l = strstr(chopt,"Y+");
3501  if (l) {
3502  Hoption.AxisPos += 1;
3503  strncpy(l," ",2);
3504  }
3505  if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
3506  if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
3507 
3508  l = strstr(chopt,"SAMES");
3509  if (l) {
3510  if (nch == 5) Hoption.Hist = 1;
3511  Hoption.Same = 2;
3512  strncpy(l," ",5);
3513  }
3514  l = strstr(chopt,"SAME");
3515  if (l) {
3516  if (nch == 4) Hoption.Hist = 1;
3517  Hoption.Same = 1;
3518  strncpy(l," ",4);
3519  }
3520 
3521  l = strstr(chopt,"PIE");
3522  if (l) {
3523  Hoption.Pie = 1;
3524  strncpy(l," ",3);
3525  }
3526 
3527 
3528  l = strstr(chopt,"CANDLE");
3529  if (l) {
3530  TCandle candle;
3531  Hoption.Candle = candle.ParseOption(l);
3532  Hoption.Scat = 0;
3533  }
3534 
3535  l = strstr(chopt,"VIOLIN");
3536  if (l) {
3537  Hoption.Scat = 0;
3538  Hoption.Violin = 1;
3539  strncpy(l," ",6);
3540  if (l[6] == 'X') { Hoption.Violin = 1; l[6] = ' '; }
3541  if (l[6] == 'Y') { Hoption.Violin = 2; l[6] = ' '; }
3542  }
3543 
3544  l = strstr(chopt,"LEGO");
3545  if (l) {
3546  Hoption.Scat = 0;
3547  Hoption.Lego = 1; strncpy(l," ",4);
3548  if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
3549  if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
3550  if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
3551  if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
3552  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3553  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3554  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3555  }
3556 
3557  l = strstr(chopt,"SURF");
3558  if (l) {
3559  Hoption.Scat = 0;
3560  Hoption.Surf = 1; strncpy(l," ",4);
3561  if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
3562  if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
3563  if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
3564  if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
3565  if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
3566  if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
3567  if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
3568  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3569  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3570  }
3571 
3572  l = strstr(chopt,"TF3");
3573  if (l) {
3574  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3575  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3576  }
3577 
3578  l = strstr(chopt,"ISO");
3579  if (l) {
3580  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3581  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3582  }
3583 
3584  l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; strncpy(l," ",4);}
3585 
3586  l = strstr(chopt,"CONT");
3587  if (l) {
3588  strncpy(l," ",4);
3589  if (hdim>1) {
3590  Hoption.Scat = 0;
3591  Hoption.Contour = 1;
3592  if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
3593  if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
3594  if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
3595  if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
3596  if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
3597  } else {
3598  Hoption.Hist = 1;
3599  }
3600  }
3601  l = strstr(chopt,"HBAR");
3602  if (l) {
3603  Hoption.Hist = 0;
3604  Hoption.Bar = 20; strncpy(l," ",4);
3605  if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
3606  if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
3607  if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
3608  if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
3609  }
3610  l = strstr(chopt,"BAR");
3611  if (l) {
3612  Hoption.Hist = 0;
3613  Hoption.Bar = 10; strncpy(l," ",3);
3614  if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
3615  if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
3616  if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
3617  if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
3618  }
3619 
3620  l = strstr(chopt,"ARR" );
3621  if (l) {
3622  strncpy(l," ", 3);
3623  if (hdim>1) {
3624  Hoption.Arrow = 1;
3625  Hoption.Scat = 0;
3626  } else {
3627  Hoption.Hist = 1;
3628  }
3629  }
3630  l = strstr(chopt,"BOX" );
3631  if (l) {
3632  strncpy(l," ", 3);
3633  if (hdim>1) {
3634  Hoption.Scat = 0;
3635  Hoption.Box = 1;
3636  if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
3637  } else {
3638  Hoption.Hist = 1;
3639  }
3640  }
3641  l = strstr(chopt,"COLZ");
3642  if (l) {
3643  strncpy(l," ",4);
3644  if (hdim>1) {
3645  Hoption.Color = 1;
3646  Hoption.Scat = 0;
3647  Hoption.Zscale = 1;
3648  if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
3649  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3650  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3651  } else {
3652  Hoption.Hist = 1;
3653  }
3654  }
3655  l = strstr(chopt,"COL" );
3656  if (l) {
3657  strncpy(l," ", 3);
3658  if (hdim>1) {
3659  Hoption.Color = 1;
3660  Hoption.Scat = 0;
3661  if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
3662  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3663  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3664  } else {
3665  Hoption.Hist = 1;
3666  }
3667  }
3668  l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; strncpy(l," ",4); Hoption.Scat = 0; }
3669  l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; strncpy(l," ",4); Hoption.Hist = 0; }
3670  l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; strncpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
3671  l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; strncpy(l," ",4); }
3672  l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; strncpy(l," ",4); }
3673  l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; strncpy(l," ",4); }
3674  l = strstr(chopt,"TEXT");
3675  if (l) {
3676  Int_t angle;
3677  if (sscanf(&l[4],"%d",&angle) > 0) {
3678  if (angle < 0) angle=0;
3679  if (angle > 90) angle=90;
3680  Hoption.Text = 1000+angle;
3681  } else {
3682  Hoption.Text = 1;
3683  }
3684  strncpy(l," ", 4);
3685  l = strstr(chopt,"N");
3686  if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
3687  Hoption.Scat = 0;
3688  }
3689  l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; strncpy(l," ",3); }
3690  l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; strncpy(l," ",3); }
3691  l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; strncpy(l," ",3); }
3692  l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; strncpy(l," ",3); }
3693 
3694  l = strstr(chopt,"TRI");
3695  if (l) {
3696  Hoption.Scat = 0;
3697  Hoption.Color = 0;
3698  Hoption.Tri = 1; strncpy(l," ",3);
3699  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3700  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3701  l = strstr(chopt,"ERR"); if (l) strncpy(l," ",3);
3702  }
3703 
3704  l = strstr(chopt,"AITOFF");
3705  if (l) {
3706  Hoption.Proj = 1; strncpy(l," ",6); //Aitoff projection
3707  }
3708  l = strstr(chopt,"MERCATOR");
3709  if (l) {
3710  Hoption.Proj = 2; strncpy(l," ",8); //Mercator projection
3711  }
3712  l = strstr(chopt,"SINUSOIDAL");
3713  if (l) {
3714  Hoption.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
3715  }
3716  l = strstr(chopt,"PARABOLIC");
3717  if (l) {
3718  Hoption.Proj = 4; strncpy(l," ",9); //Parabolic projection
3719  }
3720  if (Hoption.Proj > 0) {
3721  Hoption.Scat = 0;
3722  Hoption.Contour = 14;
3723  }
3724 
3725  if (strstr(chopt,"A")) Hoption.Axis = -1;
3726  if (strstr(chopt,"B")) Hoption.Bar = 1;
3727  if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
3728  if (strstr(chopt,"F")) Hoption.Fill =1;
3729  if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
3730  if (strstr(chopt,"F2")) Hoption.Fill =2;
3731  if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
3732  if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
3733  if (strstr(chopt,"Z")) Hoption.Zscale =1;
3734  if (strstr(chopt,"*")) Hoption.Star =1;
3735  if (strstr(chopt,"H")) Hoption.Hist =2;
3736  if (strstr(chopt,"P0")) Hoption.Mark =10;
3737 
3738  if (fH->InheritsFrom(TH2Poly::Class())) {
3739  if (Hoption.Fill+Hoption.Line+Hoption.Mark != 0 ) Hoption.Scat = 0;
3740  }
3741 
3742  if (strstr(chopt,"E")) {
3743  if (hdim == 1) {
3744  Hoption.Error = 1;
3745  if (strstr(chopt,"E0")) Hoption.Error = 10;
3746  if (strstr(chopt,"E1")) Hoption.Error = 11;
3747  if (strstr(chopt,"E2")) Hoption.Error = 12;
3748  if (strstr(chopt,"E3")) Hoption.Error = 13;
3749  if (strstr(chopt,"E4")) Hoption.Error = 14;
3750  if (strstr(chopt,"E5")) Hoption.Error = 15;
3751  if (strstr(chopt,"E6")) Hoption.Error = 16;
3752  if (strstr(chopt,"X0")) {
3753  if (Hoption.Error == 1) Hoption.Error += 20;
3754  Hoption.Error += 10;
3755  }
3756  if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
3757  Hoption.Text += 2000;
3758  Hoption.Error = 0;
3759  }
3760  } else {
3761  if (Hoption.Error == 0) {
3762  Hoption.Error = 100;
3763  Hoption.Scat = 0;
3764  }
3765  if (Hoption.Text) {
3766  Hoption.Text += 2000;
3767  Hoption.Error = 0;
3768  }
3769  }
3770  }
3771 
3772  if (Hoption.Surf == 15) {
3773  if (Hoption.System == kPOLAR || Hoption.System == kCARTESIAN) {
3774  Hoption.Surf = 13;
3775  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
3776  }
3777  }
3778 
3779  // Copy options from current style
3780  Hoption.Logx = gPad->GetLogx();
3781  Hoption.Logy = gPad->GetLogy();
3782  Hoption.Logz = gPad->GetLogz();
3783 
3784  // Check options incompatibilities
3785  if (Hoption.Bar == 1) Hoption.Hist = -1;
3786  return 1;
3787 }
3788 
3789 ////////////////////////////////////////////////////////////////////////////////
3790 /// Decode string `choptin` and fill Graphical cuts structure.
3791 
3792 Int_t THistPainter::MakeCuts(char *choptin)
3793 {
3794 
3795  fNcuts = 0;
3796  char *left = (char*)strchr(choptin,'[');
3797  if (!left) return 0;
3798  char *right = (char*)strchr(choptin,']');
3799  if (!right) return 0;
3800  Int_t nch = right-left;
3801  if (nch < 2) return 0;
3802  char *cuts = left+1;
3803  *right = 0;
3804  char *comma, *minus;
3805  Int_t i;
3806  while (1) {
3807  comma = strchr(cuts,',');
3808  if (comma) *comma = 0;
3809  minus = strchr(cuts,'-');
3810  if (minus) cuts = minus+1;
3811  while (*cuts == ' ') cuts++;
3812  Int_t nc = strlen(cuts);
3813  while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
3814  TIter next(gROOT->GetListOfSpecials());
3815  TCutG *cut=0;
3816  TObject *obj;
3817  while ((obj = next())) {
3818  if (!obj->InheritsFrom(TCutG::Class())) continue;
3819  if (strcmp(obj->GetName(),cuts)) continue;
3820  cut = (TCutG*)obj;
3821  break;
3822  }
3823  if (cut) {
3824  fCuts[fNcuts] = cut;
3825  fCutsOpt[fNcuts] = 1;
3826  if (minus) fCutsOpt[fNcuts] = -1;
3827  fNcuts++;
3828  }
3829  if (!comma) break;
3830  cuts = comma+1;
3831  }
3832  for (i=0;i<=nch;i++) left[i] = ' ';
3833  return fNcuts;
3834 }
3835 
3836 ////////////////////////////////////////////////////////////////////////////////
3837 /// [Control routine to paint any kind of histograms](#HP00)
3838 
3839 void THistPainter::Paint(Option_t *option)
3840 {
3841 
3842  if (fH->GetBuffer()) fH->BufferEmpty(-1);
3843 
3844  //For iOS: put the histogram on the top of stack of pickable objects.
3845  const TPickerStackGuard topPush(fH);
3846 
3847  gPad->SetVertical(kTRUE);
3848 
3849  TH1 *oldhist = gCurrentHist;
3850  gCurrentHist = fH;
3851  TH1 *hsave = fH;
3852  Double_t minsav = fH->GetMinimumStored();
3853 
3854  if (!MakeChopt(option)) return; //check options and fill Hoption structure
3855 
3856  // Paint using TSpectrum2Painter
3857  if (Hoption.Spec) {
3858  if (!TableInit()) return;
3859  if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
3860  gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
3861  (ULong_t)fH, option, Hoption.Spec));
3862  return;
3863  }
3864 
3865  if (Hoption.Pie) {
3866  if (fH->GetDimension() == 1) {
3867  if (!fPie) fPie = new TPie(fH);
3868  fPie->Paint(option);
3869  } else {
3870  Error("Paint", "Option PIE is for 1D histograms only");
3871  }
3872  return;
3873  } else {
3874  if (fPie) delete fPie;
3875  fPie = 0;
3876  }
3877 
3878  fXbuf = new Double_t[kNMAX];
3879  fYbuf = new Double_t[kNMAX];
3880  if (fH->GetDimension() > 2) {
3881  PaintH3(option);
3882  fH->SetMinimum(minsav);
3883  if (Hoption.Func) {
3884  Hoption_t hoptsave = Hoption;
3885  Hparam_t hparsave = Hparam;
3886  PaintFunction(option);
3887  SetHistogram(hsave);
3888  Hoption = hoptsave;
3889  Hparam = hparsave;
3890  }
3891  gCurrentHist = oldhist;
3892  delete [] fXbuf; delete [] fYbuf;
3893  return;
3894  }
3895  TView *view = gPad->GetView();
3896  if (view) {
3897  if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
3898  delete view;
3899  gPad->SetView(0);
3900  }
3901  }
3902  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
3903  // In case of 1D histogram, Z axis becomes Y axis.
3904  Int_t logysav=0, logzsav=0;
3905  if (fH->GetDimension() == 1) {
3906  logysav = Hoption.Logy;
3907  logzsav = Hoption.Logz;
3908  Hoption.Logz = 0;
3909  if (Hoption.Logy) {
3910  Hoption.Logz = 1;
3911  Hoption.Logy = 0;
3912  }
3913  }
3914  PaintTable(option);
3915  if (Hoption.Func) {
3916  Hoption_t hoptsave = Hoption;
3917  Hparam_t hparsave = Hparam;
3918  PaintFunction(option);
3919  SetHistogram(hsave);
3920  Hoption = hoptsave;
3921  Hparam = hparsave;
3922  }
3923  fH->SetMinimum(minsav);
3924  gCurrentHist = oldhist;
3925  delete [] fXbuf; delete [] fYbuf;
3926  if (fH->GetDimension() == 1) {
3927  Hoption.Logy = logysav;
3928  Hoption.Logz = logzsav;
3929  }
3930  return;
3931  }
3932 
3933  if (Hoption.Bar >= 20) {PaintBarH(option);
3934  delete [] fXbuf; delete [] fYbuf;
3935  return;
3936  }
3937 
3938  // fill Hparam structure with histo parameters
3939  if (!PaintInit()) {
3940  delete [] fXbuf; delete [] fYbuf;
3941  return;
3942  }
3943 
3944  // Picture surround (if new page) and page number (if requested).
3945  // Histogram surround (if not option "Same").
3946  PaintFrame();
3947 
3948  // Paint histogram axis only
3949  Bool_t gridx = gPad->GetGridx();
3950  Bool_t gridy = gPad->GetGridy();
3951  if (Hoption.Axis > 0) {
3952  if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
3953  else {
3954  if (gridx) gPad->SetGridx(0);
3955  if (gridy) gPad->SetGridy(0);
3956  PaintAxis(kFALSE);
3957  if (gridx) gPad->SetGridx(1);
3958  if (gridy) gPad->SetGridy(1);
3959  }
3960  if (Hoption.Same ==1) Hoption.Same = 2;
3961  goto paintstat;
3962  }
3963  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
3964 
3965  // test for options BAR or HBAR
3966  if (Hoption.Bar >= 10) {
3967  PaintBar(option);
3968  }
3969 
3970  // do not draw histogram if error bars required
3971  if (!Hoption.Error) {
3972  if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
3973  }
3974 
3975  // test for error bars or option E
3976  if (Hoption.Error) {
3977  PaintErrors(option);
3978  if (Hoption.Hist == 2) PaintHist(option);
3979  }
3980 
3981  if (Hoption.Text) PaintText(option);
3982 
3983  // test for associated function
3984  if (Hoption.Func) {
3985  Hoption_t hoptsave = Hoption;
3986  Hparam_t hparsave = Hparam;
3987  PaintFunction(option);
3988  SetHistogram(hsave);
3989  Hoption = hoptsave;
3990  Hparam = hparsave;
3991  }
3992 
3993  if (gridx) gPad->SetGridx(0);
3994  if (gridy) gPad->SetGridy(0);
3995  PaintAxis(kFALSE);
3996  if (gridx) gPad->SetGridx(1);
3997  if (gridy) gPad->SetGridy(1);
3998 
3999  PaintTitle(); // Draw histogram title
4000 
4001  // Draw box with histogram statistics and/or fit parameters
4002 paintstat:
4003  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4004  TIter next(fFunctions);
4005  TObject *obj = 0;
4006  while ((obj = next())) {
4007  if (obj->InheritsFrom(TF1::Class())) break;
4008  obj = 0;
4009  }
4010 
4011  //Stat is painted twice (first, it will be in canvas' list of primitives),
4012  //second, it will be here, this is not required on iOS.
4013  //Condition is ALWAYS true on a platform different from iOS.
4014  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4015  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4016  }
4017  fH->SetMinimum(minsav);
4018  gCurrentHist = oldhist;
4019  delete [] fXbuf; fXbuf = 0;
4020  delete [] fYbuf; fYbuf = 0;
4021 
4022 }
4023 
4024 ////////////////////////////////////////////////////////////////////////////////
4025 /// [Control function to draw a table as an arrow plot](#HP12)
4026 
4028 {
4029 
4030  Style_t linesav = fH->GetLineStyle();
4031  Width_t widthsav = fH->GetLineWidth();
4032  fH->SetLineStyle(1);
4033  fH->SetLineWidth(1);
4034  fH->TAttLine::Modify();
4036  Double_t xk, xstep, yk, ystep;
4037  Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
4038  Int_t ncx = Hparam.xlast - Hparam.xfirst + 1;
4039  Int_t ncy = Hparam.ylast - Hparam.yfirst + 1;
4040  Double_t xrg = gPad->GetUxmin();
4041  Double_t yrg = gPad->GetUymin();
4042  Double_t xln = gPad->GetUxmax() - xrg;
4043  Double_t yln = gPad->GetUymax() - yrg;
4044  Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4045  Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4046  Double_t dn = 1.E-30;
4047 
4048  for (Int_t id=1;id<=2;id++) {
4049  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4050  yk = fYaxis->GetBinLowEdge(j);
4051  ystep = fYaxis->GetBinWidth(j);
4052  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4053  xk = fXaxis->GetBinLowEdge(i);
4054  xstep = fXaxis->GetBinWidth(i);
4055  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4056  if (i == Hparam.xfirst) {
4057  dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4058  } else if (i == Hparam.xlast) {
4059  dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4060  } else {
4061  dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4062  }
4063  if (j == Hparam.yfirst) {
4064  dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4065  } else if (j == Hparam.ylast) {
4066  dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4067  } else {
4068  dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4069  }
4070  if (id == 1) {
4071  dn = TMath::Max(dn, TMath::Abs(dx));
4072  dn = TMath::Max(dn, TMath::Abs(dy));
4073  } else if (id == 2) {
4074  xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4075  dxn = cx*dx/dn;
4076  x1 = xc - dxn;
4077  x2 = xc + dxn;
4078  yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4079  dyn = cy*dy/dn;
4080  y1 = yc - dyn;
4081  y2 = yc + dyn;
4082  fXbuf[0] = x1;
4083  fXbuf[1] = x2;
4084  fYbuf[0] = y1;
4085  fYbuf[1] = y2;
4086  if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
4087  anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
4088  si = anr*(dxn + dyn);
4089  co = anr*(dxn - dyn);
4090  fXbuf[2] = x2 - si;
4091  fYbuf[2] = y2 + co;
4092  gPad->PaintPolyLine(3, fXbuf, fYbuf);
4093  fXbuf[0] = x2;
4094  fXbuf[1] = x2 - co;
4095  fYbuf[0] = y2;
4096  fYbuf[1] = y2 - si;
4097  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4098  }
4099  else {
4100  gPad->PaintPolyLine(2, fXbuf, fYbuf);
4101  }
4102  }
4103  }
4104  }
4105  }
4106 
4107  if (Hoption.Zscale) PaintPalette();
4108  fH->SetLineStyle(linesav);
4109  fH->SetLineWidth(widthsav);
4110  fH->TAttLine::Modify();
4111 }
4112 
4113 ////////////////////////////////////////////////////////////////////////////////
4114 /// Draw axis (2D case) of an histogram.
4115 ///
4116 /// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4117 /// to draw the grid and the axis separately. In `THistPainter::Paint` this
4118 /// feature is used to make sure that the grid is drawn in the background and
4119 /// the axis tick marks in the foreground of the pad.
4120 
4121 void THistPainter::PaintAxis(Bool_t drawGridOnly)
4122 {
4123 
4124  //On iOS, grid should not be pickable and can not be highlighted.
4125  //Condition is never true on a platform different from iOS.
4126  if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4127  return;
4128 
4129  if (Hoption.Axis == -1) return;
4130  if (Hoption.Same && Hoption.Axis <= 0) return;
4131 
4132  // Repainting alphanumeric labels axis on a plot done with
4133  // the option HBAR (horizontal) needs some adjustments.
4134  TAxis *xaxis = 0;
4135  TAxis *yaxis = 0;
4136  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4137  if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4138  TIter next(gPad->GetListOfPrimitives());
4139  TObject *obj;
4140  // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4141  while ((obj = next())) {
4142  if (!obj->InheritsFrom(TH1::Class()) &&
4143  !obj->InheritsFrom(THStack::Class())) continue;
4144  TString opt = obj->GetDrawOption();
4145  opt.ToLower();
4146  // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4147  if (strstr(opt,"hbar")) {
4148  gPad->SetVertical(kFALSE);
4149  xaxis = fXaxis;
4150  yaxis = fYaxis;
4151  if (!strcmp(xaxis->GetName(),"xaxis")) {
4152  fXaxis = yaxis;
4153  fYaxis = xaxis;
4154  }
4155  }
4156  break;
4157  }
4158  }
4159  }
4160 
4161  static char chopt[10] = "";
4162  Double_t gridl = 0;
4163  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4164  Int_t useHparam = 0;
4165  Double_t umin, umax, uminsave, umaxsave;
4166  Short_t xAxisPos = Hoption.AxisPos/10;
4167  Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4168 
4169  Double_t axmin = gPad->GetUxmin();
4170  Double_t axmax = gPad->GetUxmax();
4171  Double_t aymin = gPad->GetUymin();
4172  Double_t aymax = gPad->GetUymax();
4173  char *cw = 0;
4174  TGaxis axis;
4175 
4176  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4177  // Hparam must be use for the axis limits.
4178  if (Hoption.Contour == 14) useHparam = 1;
4179  if (Hoption.Same) {
4180  TObject *obj;
4181  TIter next(gPad->GetListOfPrimitives());
4182  while ((obj=next())) {
4183  if (strstr(obj->GetDrawOption(),"cont4")) {
4184  useHparam = 1;
4185  break;
4186  }
4187  }
4188  }
4189 
4190  // Paint X axis
4191 
4192  //To make X-axis selectable on iOS device.
4193  if (gPad->PadInSelectionMode())
4194  gPad->PushSelectableObject(fXaxis);
4195 
4196  //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4197  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4198  ndivx = fXaxis->GetNdivisions();
4199  if (ndivx > 1000) {
4200  nx2 = ndivx/100;
4201  nx1 = TMath::Max(1, ndivx%100);
4202  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4203  }
4204  axis.SetTextAngle(0);
4206 
4207  chopt[0] = 0;
4208  strlcat(chopt, "SDH",10);
4209  if (ndivx < 0) strlcat(chopt, "N",10);
4210  if (gPad->GetGridx()) {
4211  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4212  strlcat(chopt, "W",10);
4213  }
4214 
4215  // Define X-Axis limits
4216  if (Hoption.Logx) {
4217  strlcat(chopt, "G",10);
4218  ndiv = TMath::Abs(ndivx);
4219  if (useHparam) {
4220  umin = TMath::Power(10,Hparam.xmin);
4221  umax = TMath::Power(10,Hparam.xmax);
4222  } else {
4223  umin = TMath::Power(10,axmin);
4224  umax = TMath::Power(10,axmax);
4225  }
4226  } else {
4227  ndiv = TMath::Abs(ndivx);
4228  if (useHparam) {
4229  umin = Hparam.xmin;
4230  umax = Hparam.xmax;
4231  } else {
4232  umin = axmin;
4233  umax = axmax;
4234  }
4235  }
4236 
4237  // Display axis as time
4238  if (fXaxis->GetTimeDisplay()) {
4239  strlcat(chopt,"t",10);
4240  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4241  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam.xmax-Hparam.xmin));
4242  }
4243  }
4244 
4245  // The main X axis can be on the bottom or on the top of the pad
4246  Double_t xAxisYPos1, xAxisYPos2;
4247  if (xAxisPos == 1) {
4248  // Main X axis top
4249  xAxisYPos1 = aymax;
4250  xAxisYPos2 = aymin;
4251  } else {
4252  // Main X axis bottom
4253  xAxisYPos1 = aymin;
4254  xAxisYPos2 = aymax;
4255  }
4256 
4257  // Paint the main X axis (always)
4258  uminsave = umin;
4259  umaxsave = umax;
4260  ndivsave = ndiv;
4261  axis.SetOption(chopt);
4262  if (xAxisPos) {
4263  strlcat(chopt, "-",10);
4264  gridl = -gridl;
4265  }
4266  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4267  axis.SetLabelSize(0.);
4268  axis.SetTitle("");
4269  }
4270  axis.PaintAxis(axmin, xAxisYPos1,
4271  axmax, xAxisYPos1,
4272  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4273 
4274  // Paint additional X axis (if needed)
4275  // On iOS, this additional X axis is neither pickable, nor highlighted.
4276  // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4277  if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4278  if (xAxisPos) {
4279  cw=strstr(chopt,"-");
4280  *cw='z';
4281  } else {
4282  strlcat(chopt, "-",10);
4283  }
4284  if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4285  if ((cw=strstr(chopt,"W"))) *cw='z';
4286  axis.SetTitle("");
4287  axis.PaintAxis(axmin, xAxisYPos2,
4288  axmax, xAxisYPos2,
4289  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4290  }
4291  }//End of "if pad in selection mode etc".
4292 
4293  // Paint Y axis
4294  //On iOS, Y axis must pushed into the stack of selectable objects.
4295  if (gPad->PadInSelectionMode())
4296  gPad->PushSelectableObject(fYaxis);
4297 
4298  //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4299  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4300  ndivy = fYaxis->GetNdivisions();
4302 
4303  chopt[0] = 0;
4304  strlcat(chopt, "SDH",10);
4305  if (ndivy < 0) strlcat(chopt, "N",10);
4306  if (gPad->GetGridy()) {
4307  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4308  strlcat(chopt, "W",10);
4309  }
4310 
4311  // Define Y-Axis limits
4312  if (Hoption.Logy) {
4313  strlcat(chopt, "G",10);
4314  ndiv = TMath::Abs(ndivy);
4315  if (useHparam) {
4316  umin = TMath::Power(10,Hparam.ymin);
4317  umax = TMath::Power(10,Hparam.ymax);
4318  } else {
4319  umin = TMath::Power(10,aymin);
4320  umax = TMath::Power(10,aymax);
4321  }
4322  } else {
4323  ndiv = TMath::Abs(ndivy);
4324  if (useHparam) {
4325  umin = Hparam.ymin;
4326  umax = Hparam.ymax;
4327  } else {
4328  umin = aymin;
4329  umax = aymax;
4330  }
4331  }
4332 
4333  // Display axis as time
4334  if (fYaxis->GetTimeDisplay()) {
4335  strlcat(chopt,"t",10);
4336  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4337  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam.ymax-Hparam.ymin));
4338  }
4339  }
4340 
4341  // The main Y axis can be on the left or on the right of the pad
4342  Double_t yAxisXPos1, yAxisXPos2;
4343  if (yAxisPos == 1) {
4344  // Main Y axis left
4345  yAxisXPos1 = axmax;
4346  yAxisXPos2 = axmin;
4347  } else {
4348  // Main Y axis right
4349  yAxisXPos1 = axmin;
4350  yAxisXPos2 = axmax;
4351  }
4352 
4353  // Paint the main Y axis (always)
4354  uminsave = umin;
4355  umaxsave = umax;
4356  ndivsave = ndiv;
4357  axis.SetOption(chopt);
4358  if (yAxisPos) {
4359  strlcat(chopt, "+L",10);
4360  gridl = -gridl;
4361  }
4362  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4363  axis.SetLabelSize(0.);
4364  axis.SetTitle("");
4365  }
4366  axis.PaintAxis(yAxisXPos1, aymin,
4367  yAxisXPos1, aymax,
4368  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4369 
4370  // Paint the additional Y axis (if needed)
4371  // Additional checks for pad mode are required on iOS: this "second" axis is
4372  // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4373  if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4374  if (gPad->GetTicky() < 2) {
4375  strlcat(chopt, "U",10);
4376  axis.SetTickSize(-fYaxis->GetTickLength());
4377  } else {
4378  strlcat(chopt, "+L",10);
4379  }
4380  if ((cw=strstr(chopt,"W"))) *cw='z';
4381  axis.SetTitle("");
4382  axis.PaintAxis(yAxisXPos2, aymin,
4383  yAxisXPos2, aymax,
4384  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4385  }
4386  }//End of "if pad is in selection mode etc."
4387 
4388  // Reset the axis if they have been inverted in case of option HBAR
4389  if (xaxis) {
4390  fXaxis = xaxis;
4391  fYaxis = yaxis;
4392  }
4393 }
4394 
4395 ////////////////////////////////////////////////////////////////////////////////
4396 /// [Draw a bar-chart in a normal pad.](#HP10)
4397 
4399 {
4400 
4401  Int_t bar = Hoption.Bar - 10;
4402  Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4403  Double_t offset = fH->GetBarOffset();
4404  Double_t width = fH->GetBarWidth();
4405  TBox box;
4406  Int_t hcolor = fH->GetFillColor();
4407  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4408  Int_t hstyle = fH->GetFillStyle();
4409  box.SetFillColor(hcolor);
4410  box.SetFillStyle(hstyle);
4411  for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4412  y = fH->GetBinContent(bin);
4413  xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4414  xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4415  ymin = gPad->GetUymin();
4416  ymax = gPad->YtoPad(y);
4417  if (ymax < gPad->GetUymin()) continue;
4418  if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4419  if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4420  if (gStyle->GetHistMinimumZero() && ymin < 0)
4421  ymin=TMath::Min(0.,gPad->GetUymax());
4422  w = (xmax-xmin)*width;
4423  xmin += offset*(xmax-xmin);
4424  xmax = xmin + w;
4425  if (bar < 1) {
4426  box.PaintBox(xmin,ymin,xmax,ymax);
4427  } else {
4428  umin = xmin + bar*(xmax-xmin)/10.;
4429  umax = xmax - bar*(xmax-xmin)/10.;
4430  //box.SetFillColor(hcolor+150); //bright
4431  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4432  box.PaintBox(xmin,ymin,umin,ymax);
4433  box.SetFillColor(hcolor);
4434  box.PaintBox(umin,ymin,umax,ymax);
4435  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4436  box.PaintBox(umax,ymin,xmax,ymax);
4437  }
4438  }
4439 }
4440 
4441 ////////////////////////////////////////////////////////////////////////////////
4442 /// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4443 
4445 {
4446 
4447  gPad->SetVertical(kFALSE);
4448 
4449  PaintInitH();
4450 
4451  TAxis *xaxis = fXaxis;
4452  TAxis *yaxis = fYaxis;
4453  if (!strcmp(xaxis->GetName(),"xaxis")) {
4454  fXaxis = yaxis;
4455  fYaxis = xaxis;
4456  }
4457 
4458  PaintFrame();
4459 
4460  Int_t bar = Hoption.Bar - 20;
4461  Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4462  Double_t offset = fH->GetBarOffset();
4463  Double_t width = fH->GetBarWidth();
4464  TBox box;
4465  Int_t hcolor = fH->GetFillColor();
4466  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4467  Int_t hstyle = fH->GetFillStyle();
4468  box.SetFillColor(hcolor);
4469  box.SetFillStyle(hstyle);
4470  for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4471  ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4472  ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4473  xmin = gPad->GetUxmin();
4474  xmax = gPad->XtoPad(fH->GetBinContent(bin));
4475  if (xmax < gPad->GetUxmin()) continue;
4476  if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4477  if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4478  if (gStyle->GetHistMinimumZero() && xmin < 0)
4479  xmin=TMath::Min(0.,gPad->GetUxmax());
4480  w = (ymax-ymin)*width;
4481  ymin += offset*(ymax-ymin);
4482  ymax = ymin + w;
4483  if (bar < 1) {
4484  box.PaintBox(xmin,ymin,xmax,ymax);
4485  } else {
4486  umin = ymin + bar*(ymax-ymin)/10.;
4487  umax = ymax - bar*(ymax-ymin)/10.;
4488  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4489  box.PaintBox(xmin,ymin,xmax,umin);
4490  box.SetFillColor(hcolor);
4491  box.PaintBox(xmin,umin,xmax,umax);
4492  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4493  box.PaintBox(xmin,umax,xmax,ymax);
4494  }
4495  }
4496 
4497  PaintTitle();
4498  // Draw box with histogram statistics and/or fit parameters
4499  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4500  TIter next(fFunctions);
4501  TObject *obj = 0;
4502  while ((obj = next())) {
4503  if (obj->InheritsFrom(TF1::Class())) break;
4504  obj = 0;
4505  }
4506  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4507  }
4508 
4509  PaintAxis(kFALSE);
4510  fXaxis = xaxis;
4511  fYaxis = yaxis;
4512 }
4513 
4514 ////////////////////////////////////////////////////////////////////////////////
4515 /// [Control function to draw a 2D histogram as a box plot](#HP13)
4516 
4518 {
4519 
4520  Style_t fillsav = fH->GetFillStyle();
4521  Style_t colsav = fH->GetFillColor();
4522  if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
4523  if (Hoption.Box == 11) fH->SetFillStyle(1001);
4524  fH->TAttLine::Modify();
4525  fH->TAttFill::Modify();
4526 
4527  Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
4528  Double_t ux1 = gPad->PixeltoX(1);
4529  Double_t ux0 = gPad->PixeltoX(0);
4530  Double_t uy1 = gPad->PixeltoY(1);
4531  Double_t uy0 = gPad->PixeltoY(0);
4532  Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
4533  Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
4534 
4535  Double_t zmin = fH->GetMinimum();
4537  TMath::Abs(fH->GetMinimum()));
4538 
4539  // In case of option SAME, zmin and zmax values are taken from the
4540  // first plotted 2D histogram.
4541  if (Hoption.Same) {
4542  TH2 *h2;
4543  TIter next(gPad->GetListOfPrimitives());
4544  while ((h2 = (TH2 *)next())) {
4545  if (!h2->InheritsFrom(TH2::Class())) continue;
4546  zmin = h2->GetMinimum();
4547  zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
4548  TMath::Abs(h2->GetMinimum()));
4549  if (Hoption.Logz) {
4550  zmax = TMath::Log10(zmax);
4551  if (zmin <= 0) {
4552  zmin = TMath::Log10(zmax*0.001);
4553  } else {
4554  zmin = TMath::Log10(zmin);
4555  }
4556  }
4557  break;
4558  }
4559  }
4560 
4561  if (Hoption.Logz) {
4562  if (zmin > 0) {
4563  zmin = TMath::Log10(zmin*0.1);
4564  zmax = TMath::Log10(zmax);
4565  } else {
4566  return;
4567  }
4568  }
4569 
4570  Double_t zratio, dz = zmax - zmin;
4571  Bool_t kZNeg = kFALSE;
4572 
4573  // Define the dark and light colors the "button style" boxes.
4574  Color_t color = fH->GetFillColor();
4575  Color_t light=0, dark=0;
4576  if (Hoption.Box == 11) {
4577  light = TColor::GetColorBright(color);
4578  dark = TColor::GetColorDark(color);
4579  }
4580 
4581  // Loop over all the bins and draw the boxes
4582  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4583  yk = fYaxis->GetBinLowEdge(j);
4584  ystep = fYaxis->GetBinWidth(j);
4585  ycent = 0.5*ystep;
4586  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4587  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4588  xk = fXaxis->GetBinLowEdge(i);
4589  xstep = fXaxis->GetBinWidth(i);
4590  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4591  xcent = 0.5*xstep;
4592  z = Hparam.factor*fH->GetBinContent(bin);
4593  kZNeg = kFALSE;
4594 
4595  if (z < zmin) continue; // Can be the case with
4596  if (z > zmax) z = zmax; // option Same
4597 
4598  if (z < 0) {
4599  if (Hoption.Logz) continue;
4600  z = -z;
4601  kZNeg = kTRUE;
4602  }
4603  if (Hoption.Logz) {
4604  if (z != 0) z = TMath::Log10(z);
4605  else z = zmin;
4606  }
4607 
4608  if (dz == 0) continue;
4609  zratio = TMath::Sqrt((z-zmin)/dz);
4610  if (zratio == 0) continue;
4611 
4612  xup = xcent*zratio + xk + xcent;
4613  xlow = 2*(xk + xcent) - xup;
4614  if (xup-xlow < dxmin) xup = xlow+dxmin;
4615  if (Hoption.Logx) {
4616  if (xup > 0) xup = TMath::Log10(xup);
4617  else continue;
4618  if (xlow > 0) xlow = TMath::Log10(xlow);
4619  else continue;
4620  }
4621 
4622  yup = ycent*zratio + yk + ycent;
4623  ylow = 2*(yk + ycent) - yup;
4624  if (yup-ylow < dymin) yup = ylow+dymin;
4625  if (Hoption.Logy) {
4626  if (yup > 0) yup = TMath::Log10(yup);
4627  else continue;
4628  if (ylow > 0) ylow = TMath::Log10(ylow);
4629  else continue;
4630  }
4631 
4632  xlow = TMath::Max(xlow, gPad->GetUxmin());
4633  ylow = TMath::Max(ylow, gPad->GetUymin());
4634  xup = TMath::Min(xup , gPad->GetUxmax());
4635  yup = TMath::Min(yup , gPad->GetUymax());
4636 
4637  if (xlow >= xup) continue;
4638  if (ylow >= yup) continue;
4639 
4640  if (Hoption.Box == 1) {
4641  fH->SetFillColor(color);
4642  fH->TAttFill::Modify();
4643  gPad->PaintBox(xlow, ylow, xup, yup);
4644  if (kZNeg) {
4645  gPad->PaintLine(xlow, ylow, xup, yup);
4646  gPad->PaintLine(xlow, yup, xup, ylow);
4647  }
4648  } else if (Hoption.Box == 11) {
4649  // Draw the center of the box
4650  fH->SetFillColor(color);
4651  fH->TAttFill::Modify();
4652  gPad->PaintBox(xlow, ylow, xup, yup);
4653 
4654  // Draw top&left part of the box
4655  Double_t x[7], y[7];
4656  Double_t bwidth = 0.1;
4657  x[0] = xlow; y[0] = ylow;
4658  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4659  x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
4660  x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
4661  x[4] = xup; y[4] = yup;
4662  x[5] = xlow; y[5] = yup;
4663  x[6] = xlow; y[6] = ylow;
4664  if (kZNeg) fH->SetFillColor(dark);
4665  else fH->SetFillColor(light);
4666  fH->TAttFill::Modify();
4667  gPad->PaintFillArea(7, x, y);
4668 
4669  // Draw bottom&right part of the box
4670  x[0] = xlow; y[0] = ylow;
4671  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4672  x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
4673  x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
4674  x[4] = xup; y[4] = yup;
4675  x[5] = xup; y[5] = ylow;
4676  x[6] = xlow; y[6] = ylow;
4677  if (kZNeg) fH->SetFillColor(light);
4678  else fH->SetFillColor(dark);
4679  fH->TAttFill::Modify();
4680  gPad->PaintFillArea(7, x, y);
4681  }
4682  }
4683  }
4684 
4685  if (Hoption.Zscale) PaintPalette();
4686  fH->SetFillStyle(fillsav);
4687  fH->SetFillColor(colsav);
4688  fH->TAttFill::Modify();
4689 }
4690 
4691 
4692 
4693 ////////////////////////////////////////////////////////////////////////////////
4694 /// [Control function to draw a 2D histogram as a candle (box) plot.](#HP14)
4695 
4697 {
4698  TH1D *hproj;
4699  TH2D *h2 = (TH2D*)fH;
4700 
4701 
4702  TCandle myCandle;
4703  myCandle.SetOption((TCandle::CandleOption)Hoption.Candle);
4705  myCandle.SetLineColor(fH->GetLineColor());
4706  myCandle.SetFillColor(fH->GetFillColor());
4707  myCandle.SetFillStyle(fH->GetFillStyle());
4708  myCandle.SetMarkerSize(fH->GetMarkerSize());
4709  myCandle.SetMarkerStyle(fH->GetMarkerStyle());
4710  myCandle.SetLog(Hoption.Logx,Hoption.Logy);
4711 
4712  Bool_t swapXY = myCandle.IsHorizontal();
4713  const Double_t standardCandleWidth = 0.66;
4714 
4715  if (!swapXY) { // Vertical candle
4716  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4717  Double_t binPosX = fXaxis->GetBinLowEdge(i);
4718  Double_t binWidth = fXaxis->GetBinWidth(i);
4719  hproj = h2->ProjectionY("_px", i, i);
4720  if (hproj->GetEntries() !=0) {
4721  Double_t width = fH->GetBarWidth();
4722  Double_t offset = fH->GetBarOffset()*binWidth;
4723  if (width > 0.999) width = standardCandleWidth;
4724  myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
4725  myCandle.SetWidth(width*binWidth);
4726  myCandle.SetHistogram(hproj);
4727  myCandle.Paint();
4728  }
4729  }
4730  } else { // Horizontal candle
4731  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4732  Double_t binPosY = fYaxis->GetBinLowEdge(i);
4733  Double_t binWidth = fYaxis->GetBinWidth(i);
4734  hproj = h2->ProjectionX("_py", i, i);
4735  if (hproj->GetEntries() !=0) {
4736  Double_t width = fH->GetBarWidth();
4737  Double_t offset = fH->GetBarOffset()*binWidth;
4738  if (width > 0.999) width = standardCandleWidth;
4739  myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
4740  myCandle.SetWidth(width*binWidth);
4741  myCandle.SetHistogram(hproj);
4742  myCandle.Paint();
4743  }
4744  }
4745  }
4746 }
4747 
4748 ////////////////////////////////////////////////////////////////////////////////
4749 /// [Control function to draw a 2D histogram as a violin plot](#HP141)
4750 
4752 {
4753  Double_t x,y,w;
4754  Double_t bw, bcen, bcon;
4755  Double_t xpm[1], ypm[1];
4756 
4757  TH1D *hp;
4758  TH2D *h2 = (TH2D*)fH;
4760  Double_t *quantiles = new Double_t[5];
4761  quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
4762  Double_t *prob = new Double_t[5];
4763  prob[0]=1E-15; prob[1]=0.25; prob[2]=0.5; prob[3]=0.75; prob[4]=1-1E-15;
4764 
4765  Style_t fillsav = h2->GetFillStyle();
4766  Style_t colsav = h2->GetFillColor();
4767  Style_t linesav = h2->GetLineStyle();
4768  Style_t widthsav = h2->GetLineWidth();
4769  Style_t pmssav = h2->GetMarkerStyle();
4770 
4771  if (h2->GetFillColor() == 0) h2->SetFillStyle(0);
4772 
4773  h2->SetMarkerStyle(pmssav);
4774  h2->TAttLine::Modify();
4775  h2->TAttFill::Modify();
4776  h2->TAttMarker::Modify();
4777 
4778  // Violin plot along X
4779  if (Hoption.Violin == 1) {
4780  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4781  x = fXaxis->GetBinCenter(i);
4782  w = fXaxis->GetBinWidth(i);
4783  hp = h2->ProjectionY("_px", i, i);
4784  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4785  hp->Scale(1.0/hp->Integral());
4786  hp->Scale(w/hp->GetMaximum());
4787  hp->GetQuantiles(5, quantiles, prob);
4788  ypm[0] = hp->GetMean();
4789 
4790  TAxis *ax = hp->GetXaxis();
4791  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4792  bw = ax->GetBinWidth(j);
4793  bcen = ax->GetBinCenter(j);
4794  bcon = hp->GetBinContent(j);
4795  gPad->PaintBox(x-0.5*bcon, bcen-0.5*bw, x+0.5*bcon, bcen+0.5*bw);
4796  }
4797 
4798  h2->SetLineWidth(widthsav);
4799  h2->TAttLine::Modify();
4800 
4801  h2->SetLineStyle(linesav);
4802  h2->TAttLine::Modify();
4803  gPad->PaintLine(x, quantiles[3], x, quantiles[4]);
4804  gPad->PaintLine(x, quantiles[0], x, quantiles[1]);
4805 
4806  xpm[0] = x;
4807  gPad->PaintPolyMarker(1,xpm,ypm);
4808  }
4809  }
4810  // Violin plot along Y
4811  } else {
4812  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4813  y = fYaxis->GetBinCenter(i);
4814  w = fYaxis->GetBinWidth(i);
4815  hp = h2->ProjectionX("_py", i, i);
4816  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4817  hp->Scale(1.0/hp->Integral());
4818  hp->Scale(w/hp->GetMaximum());
4819  hp->GetQuantiles(5, quantiles, prob);
4820  xpm[0] = hp->GetMean();
4821 
4822  h2->SetLineWidth(1);
4823  h2->TAttLine::Modify();
4824  TAxis *ax = hp->GetXaxis();
4825  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4826  bw = ax->GetBinWidth(j);
4827  bcen = ax->GetBinCenter(j);
4828  bcon = hp->GetBinContent(j);
4829  gPad->PaintBox(bcen-0.5*bw, y-0.5*bcon, bcen+0.5*bw, y+0.5*bcon);
4830  }
4831 
4832  hp->GetQuantiles(5, quantiles, prob);
4833  xpm[0] = hp->GetMean();
4834 
4835  h2->SetLineWidth(widthsav);
4836  h2->SetLineStyle(2);
4837  h2->TAttLine::Modify();
4838  gPad->PaintLine(quantiles[3], y, quantiles[4], y);
4839  gPad->PaintLine(quantiles[0], y, quantiles[1], y);
4840 
4841  ypm[0] = y;
4842  gPad->PaintPolyMarker(1,xpm,ypm);
4843  }
4844  }
4845  }
4846 
4847  h2->SetFillStyle(fillsav);
4848  h2->SetFillColor(colsav);
4849  h2->SetLineStyle(linesav);
4850  h2->SetMarkerStyle(pmssav);
4851  h2->SetLineWidth(widthsav);
4852  h2->TAttFill::Modify();
4853  h2->TAttLine::Modify();
4854  h2->TAttMarker::Modify();
4855 
4856  delete [] prob;
4857  delete [] quantiles;
4858 }
4859 
4860 ////////////////////////////////////////////////////////////////////////////////
4861 /// Returns the rendering regions for an axis to use in the COL2 option
4862 ///
4863 /// The algorithm analyses the size of the axis compared to the size of
4864 /// the rendering region. It figures out the boundaries to use for each color
4865 /// of the rendering region. Only one axis is computed here.
4866 ///
4867 /// This allows for a single computation of the boundaries before iterating
4868 /// through all of the bins.
4869 ///
4870 /// \param pAxis the axis to consider
4871 /// \param nPixels the number of pixels to render axis into
4872 /// \param isLog whether the axis is log scale
4873 
4874 std::vector<THistRenderingRegion>
4876 {
4877  std::vector<THistRenderingRegion> regions;
4878 
4879  enum STRATEGY { Bins, Pixels } strategy;
4880 
4881  Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
4882 
4883  if (nBins >= nPixels) {
4884  // more bins than pixels... we should loop over pixels and sample
4885  strategy = Pixels;
4886  } else {
4887  // fewer bins than pixels... we should loop over bins
4888  strategy = Bins;
4889  }
4890 
4891  if (isLog) {
4892 
4893  Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
4894  Int_t binOffset=0;
4895  while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
4896  binOffset++;
4897  xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
4898  }
4899  if (xMin <= 0) {
4900  // this should cause an error if we have
4901  return regions;
4902  }
4903  Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
4904 
4905  if (strategy == Bins) {
4906  // logarithmic plot. we find the pixel for the bin
4907  // pixel = eta * log10(V) - alpha
4908  // where eta = nPixels/(log10(Vmax)-log10(Vmin))
4909  // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
4910  // and V is axis value
4911  Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
4912  Double_t offset = -1.0 * eta * TMath::Log10(xMin);
4913 
4914  for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
4915 
4916  // linear plot. we simply need to find the appropriate bin
4917  // for the
4918  Double_t xLowValue = pAxis->GetBinLowEdge(bin);
4919  Double_t xUpValue = pAxis->GetBinUpEdge(bin);
4920  Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
4921  Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
4922  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
4923  std::make_pair(bin, bin+1)};
4924  regions.push_back(region);
4925  }
4926 
4927  } else {
4928 
4929  // loop over pixels
4930 
4931  Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
4932 
4933  for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
4934  // linear plot
4935  Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
4936  Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
4937  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
4938  std::make_pair(binLow, binHigh)};
4939  regions.push_back(region);
4940  }
4941  }
4942  } else {
4943  // standard linear plot
4944 
4945  if (strategy == Bins) {
4946  // loop over bins
4947  for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
4948 
4949  // linear plot. we simply need to find the appropriate bin
4950  // for the
4951  Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
4952  Int_t xPx1 = xPx0 + nPixels/nBins;
4953 
4954  // make sure we don't compute beyond our bounds
4955  if (xPx1>= nPixels) xPx1 = nPixels-1;
4956 
4957  THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
4958  std::make_pair(bin, bin+1)};
4959  regions.push_back(region);
4960  }
4961  } else {
4962  // loop over pixels
4963  for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
4964  // linear plot
4965  Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
4966  Int_t binHigh = binLow + nBins/nPixels;
4967  THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
4968  std::make_pair(binLow, binHigh)};
4969  regions.push_back(region);
4970  }
4971  }
4972  }
4973 
4974  return regions;
4975 }
4976 
4977 ////////////////////////////////////////////////////////////////////////////////
4978 /// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
4979 
4981 {
4982 
4983  if (Hoption.System != kCARTESIAN) {
4984  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
4985  "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
4986  PaintColorLevels(nullptr);
4987  return;
4988  }
4989 
4990  Double_t z;
4991 
4992  // Use existing max or min values. If either is already set
4993  // the appropriate value to use.
4994  Double_t zmin = fH->GetMinimumStored();
4995  Double_t zmax = fH->GetMaximumStored();
4996  if ((zmin == -1111) && (zmax == -1111)) {
4997  fH->GetMinimumAndMaximum(zmin, zmax);
4998  fH->SetMinimum(zmin);
4999  fH->SetMaximum(zmax);
5000  } else if (zmin == -1111) {
5001  zmin = fH->GetMinimum();
5002  fH->SetMinimum(zmin);
5003  } else if (zmax == -1111) {
5004  zmax = fH->GetMaximum();
5005  fH->SetMaximum(zmax);
5006  }
5007 
5008  Double_t dz = zmax - zmin;
5009  if (dz <= 0) { // Histogram filled with a constant value
5010  zmax += 0.1*TMath::Abs(zmax);
5011  zmin -= 0.1*TMath::Abs(zmin);
5012  dz = zmax - zmin;
5013  }
5014 
5015  if (Hoption.Logz) {
5016  if (zmin > 0) {
5017  zmin = TMath::Log10(zmin);
5018  zmax = TMath::Log10(zmax);
5019  dz = zmax - zmin;
5020  } else {
5021  Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5022  "Cannot plot logz because bin content is less than 0.");
5023  return;
5024  }
5025  }
5026 
5027  // Initialize the levels on the Z axis
5028  Int_t ndiv = fH->GetContour();
5029  if (ndiv == 0 ) {
5030  ndiv = gStyle->GetNumberContours();
5031  fH->SetContour(ndiv);
5032  }
5033  std::vector<Double_t> colorBounds(ndiv);
5034  std::vector<Double_t> contours(ndiv, 0);
5035  if (fH->TestBit(TH1::kUserContour) == 0) {
5036  fH->SetContour(ndiv);
5037  } else {
5038  fH->GetContour(contours.data());
5039  }
5040 
5041  Double_t step = 1.0/ndiv;
5042  for (Int_t i=0; i<ndiv; ++i) {
5043  colorBounds[i] = step*i;
5044  }
5045 
5046  auto pFrame = gPad->GetFrame();
5047  Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5048  Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5049  Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5050  Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5051  Int_t nXPixels = px1-px0;
5052  Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5053 
5054  std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5055 
5056  auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5057  auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5058  if (xRegions.size() == 0 || yRegions.size() == 0) {
5059  Error("THistPainter::PaintColorLevelFast(Option_t*)",
5060  "Encountered error while computing rendering regions.");
5061  return;
5062  }
5063 
5064  Bool_t minExists = kFALSE;
5065  Bool_t maxExists = kFALSE;
5066  Double_t minValue = 1.;
5067  Double_t maxValue = 0.;
5068  for (auto& yRegion : yRegions) {
5069  for (auto& xRegion : xRegions ) {
5070 
5071  const auto& xBinRange = xRegion.fBinRange;
5072  const auto& yBinRange = yRegion.fBinRange;
5073 
5074  // sample the range
5075  z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5076 
5077  if (Hoption.Logz) {
5078  if (z > 0) z = TMath::Log10(z);
5079  else z = zmin;
5080  }
5081 
5082  // obey the user's max and min values if they were set
5083  if (z > zmax) z = zmax;
5084  if (z < zmin) z = zmin;
5085 
5086  if (fH->TestBit(TH1::kUserContour) == 1) {
5087  // contours are absolute values
5088  auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5089  z = colorBounds[index];
5090  } else {
5091  Int_t index = 0;
5092  if (dz != 0) {
5093  index = 0.001 + ((z - zmin)/dz)*ndiv;
5094  }
5095 
5096  if (index == static_cast<Int_t>(colorBounds.size())) {
5097  index--;
5098  }
5099 
5100  // Do a little bookkeeping to use later for getting libAfterImage to produce
5101  // the correct colors
5102  if (index == 0) {
5103  minExists = kTRUE;
5104  } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5105  maxExists = kTRUE;
5106  }
5107 
5108  z = colorBounds[index];
5109 
5110  if (z < minValue) {
5111  minValue = z;
5112  }
5113  if (z > maxValue) {
5114  maxValue = z;
5115  }
5116  }
5117 
5118  // fill in the actual pixels
5119  const auto& xPixelRange = xRegion.fPixelRange;
5120  const auto& yPixelRange = yRegion.fPixelRange;
5121  for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5122  for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5123  Int_t pixel = yPx*nXPixels + xPx;
5124  buffer[pixel] = z;
5125  }
5126  }
5127  } // end px loop
5128  } // end py loop
5129 
5130  // This is a bit of a hack to ensure that we span the entire color range and
5131  // don't screw up the colors for a sparse histogram. No one will notice that I set a
5132  // single pixel on the edge of the image to a different color. This is even more
5133  // true because the chosen pixels will be covered by the axis.
5134  if (minValue != maxValue) {
5135  if ( !minExists) {
5136  buffer.front() = 0;
5137  }
5138 
5139  if ( !maxExists) {
5140  buffer[buffer.size()-nXPixels] = 0.95;
5141  }
5142  }
5143 
5144  // Generate the TImage
5146  TImage* pImage = TImage::Create();
5148  pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5149  delete pPalette;
5150 
5151  Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5152  pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5153  delete pImage;
5154 
5155  if (Hoption.Zscale) PaintPalette();
5156 
5157 }
5158 
5159 ////////////////////////////////////////////////////////////////////////////////
5160 /// [Control function to draw a 2D histogram as a color plot.](#HP14)
5162 {
5163  Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5164 
5165  Double_t zmin = fH->GetMinimum();
5166  Double_t zmax = fH->GetMaximum();
5167 
5168  Double_t dz = zmax - zmin;
5169  if (dz <= 0) { // Histogram filled with a constant value
5170  zmax += 0.1*TMath::Abs(zmax);
5171  zmin -= 0.1*TMath::Abs(zmin);
5172  dz = zmax - zmin;
5173  }
5174 
5175  if (Hoption.Logz) {
5176  if (zmin > 0) {
5177  zmin = TMath::Log10(zmin);
5178  zmax = TMath::Log10(zmax);
5179  dz = zmax - zmin;
5180  } else {
5181  return;
5182  }
5183  }
5184 
5185  Style_t fillsav = fH->GetFillStyle();
5186  Style_t colsav = fH->GetFillColor();
5187  fH->SetFillStyle(1001);
5188  fH->TAttFill::Modify();
5189 
5190  // Initialize the levels on the Z axis
5191  Int_t ncolors = gStyle->GetNumberOfColors();
5192  Int_t ndiv = fH->GetContour();
5193  if (ndiv == 0 ) {
5194  ndiv = gStyle->GetNumberContours();
5195  fH->SetContour(ndiv);
5196  }
5197  Int_t ndivz = TMath::Abs(ndiv);
5198  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5199  Double_t scale = ndivz/dz;
5200 
5201  Int_t color;
5202  TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5203  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5204  yk = fYaxis->GetBinLowEdge(j);
5205  ystep = fYaxis->GetBinWidth(j);
5206  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5207  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5208  xk = fXaxis->GetBinLowEdge(i);
5209  xstep = fXaxis->GetBinWidth(i);
5210  if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5211  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5212  z = fH->GetBinContent(bin);
5213  // if fH is a profile histogram do not draw empty bins
5214  if (prof2d) {
5215  const Double_t binEntries = prof2d->GetBinEntries(bin);
5216  if (binEntries == 0)
5217  continue;
5218  } else {
5219  // don't draw the empty bins for non-profile histograms
5220  // with positive content
5221  if (z == 0) {
5222  if (zmin >= 0 || Hoption.Logz) continue;
5223  if (Hoption.Color == 2) continue;
5224  }
5225  }
5226 
5227  if (Hoption.Logz) {
5228  if (z > 0) z = TMath::Log10(z);
5229  else z = zmin;
5230  }
5231  if (z < zmin && !Hoption.Zero) continue;
5232  xup = xk + xstep;
5233  xlow = xk;
5234  if (Hoption.Logx) {
5235  if (xup > 0) xup = TMath::Log10(xup);
5236  else continue;
5237  if (xlow > 0) xlow = TMath::Log10(xlow);
5238  else continue;
5239  }
5240  yup = yk + ystep;
5241  ylow = yk;
5242  if (Hoption.System != kPOLAR) {
5243  if (Hoption.Logy) {
5244  if (yup > 0) yup = TMath::Log10(yup);
5245  else continue;
5246  if (ylow > 0) ylow = TMath::Log10(ylow);
5247  else continue;
5248  }
5249  if (xup < gPad->GetUxmin()) continue;
5250  if (yup < gPad->GetUymin()) continue;
5251  if (xlow > gPad->GetUxmax()) continue;
5252  if (ylow > gPad->GetUymax()) continue;
5253  if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5254  if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5255  if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5256  if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5257  }
5258 
5259  if (fH->TestBit(TH1::kUserContour)) {
5260  zc = fH->GetContourLevelPad(0);
5261  if (z < zc) continue;
5262  color = -1;
5263  for (Int_t k=0; k<ndiv; k++) {
5264  zc = fH->GetContourLevelPad(k);
5265  if (z < zc) {
5266  continue;
5267  } else {
5268  color++;
5269  }
5270  }
5271  } else {
5272  color = Int_t(0.01+(z-zmin)*scale);
5273  }
5274 
5275  Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5276  if (theColor > ncolors-1) theColor = ncolors-1;
5277  fH->SetFillColor(gStyle->GetColorPalette(theColor));
5278  fH->TAttFill::Modify();
5279  if (Hoption.System != kPOLAR) {
5280  gPad->PaintBox(xlow, ylow, xup, yup);
5281  } else {
5282  TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5283  crown.SetFillColor(gStyle->GetColorPalette(theColor));
5284  crown.Paint();
5285  }
5286  }
5287  }
5288 
5289  if (Hoption.Zscale) PaintPalette();
5290 
5291  fH->SetFillStyle(fillsav);
5292  fH->SetFillColor(colsav);
5293  fH->TAttFill::Modify();
5294 
5295 }
5296 
5297 ////////////////////////////////////////////////////////////////////////////////
5298 /// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5299 
5301 {
5302 
5303  Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5304  Int_t itars, mode, ir[4];
5305  Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5306 
5307  if (Hoption.Contour == 14) {
5308  Hoption.Surf = 12;
5309  Hoption.Axis = 1;
5310  thesave = gPad->GetTheta();
5311  phisave = gPad->GetPhi();
5312  gPad->SetPhi(0.);
5313  gPad->SetTheta(90.);
5314  PaintSurface(option);
5315  gPad->SetPhi(phisave);
5316  gPad->SetTheta(thesave);
5317  TView *view = gPad->GetView();
5318  if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5319  PaintAxis();
5320  return;
5321  }
5322 
5323  if (Hoption.Same) {
5324  // If the contour is painted on a 3d plot, the contour lines are
5325  // paint in 3d too.
5326  TObject *obj;
5327  TIter next(gPad->GetListOfPrimitives());
5328  while ((obj=next())) {
5329  if (strstr(obj->GetDrawOption(),"surf") ||
5330  strstr(obj->GetDrawOption(),"lego") ||
5331  strstr(obj->GetDrawOption(),"tri")) {
5332  Hoption.Surf = 16;
5333  PaintSurface(option);
5334  return;
5335  }
5336  }
5337  }
5338 
5339  if (Hoption.Contour == 15) {
5340  TGraphDelaunay2D *dt = nullptr;
5341  TGraphDelaunay *dtOld = nullptr;
5342  TList *hl = fH->GetListOfFunctions();
5343  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5344  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5345  if (!dt && !dtOld) return;
5346  if (!fGraph2DPainter) {
5347  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5348  else fGraph2DPainter = new TGraph2DPainter(dtOld);
5349  }
5350  fGraph2DPainter->Paint(option);
5351  return;
5352  }
5353 
5354  gPad->SetBit(TGraph::kClipFrame);
5355 
5356  Double_t *levels = new Double_t[2*kMAXCONTOUR];
5357  Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5358  Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5359  Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5360 
5361  Int_t npmax = 0;
5362  for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5363 
5364  ncontour = fH->GetContour();
5365  if (ncontour == 0) {
5366  ncontour = gStyle->GetNumberContours();
5367  fH->SetContour(ncontour);
5368  }
5369  if (ncontour > kMAXCONTOUR) {
5370  Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5371  kMAXCONTOUR, ncontour);
5372  ncontour = kMAXCONTOUR-1;
5373  }
5374  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5375 
5376  for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5377  Int_t linesav = fH->GetLineStyle();
5378  Int_t colorsav = fH->GetLineColor();
5379  Int_t fillsav = fH->GetFillColor();
5380  if (Hoption.Contour == 13) {
5381  fH->TAttLine::Modify();
5382  }
5383 
5384  TPolyLine **polys = 0;
5385  TPolyLine *poly=0;
5386  TObjArray *contours = 0;
5387  TList *list = 0;
5388  TGraph *graph = 0;
5389  Int_t *np = 0;
5390  if (Hoption.Contour == 1) {
5391  np = new Int_t[ncontour];
5392  for (i=0;i<ncontour;i++) np[i] = 0;
5393  polys = new TPolyLine*[ncontour];
5394  for (i=0;i<ncontour;i++) {
5395  polys[i] = new TPolyLine(100);
5396  }
5397  if (Hoption.List == 1) {
5398  contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5399  if (contours) {
5400  gROOT->GetListOfSpecials()->Remove(contours);
5401  count = contours->GetSize();
5402  for (i=0;i<count;i++) {
5403  list = (TList*)contours->At(i);
5404  if (list) list->Delete();
5405  }
5406  }
5407  contours = new TObjArray(ncontour);
5408  contours->SetName("contours");
5409  gROOT->GetListOfSpecials()->Add(contours);
5410  for (i=0;i<ncontour;i++) {
5411  list = new TList();
5412  contours->Add(list);
5413  }
5414  }
5415  }
5416  Int_t theColor;
5417  Int_t ncolors = gStyle->GetNumberOfColors();
5418  Int_t ndivz = TMath::Abs(ncontour);
5419 
5420  Int_t k,ipoly;
5421  for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5422  y[0] = fYaxis->GetBinCenter(j);
5423  y[1] = y[0];
5424  y[2] = fYaxis->GetBinCenter(j+1);
5425  y[3] = y[2];
5426  for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5427  zc[0] = fH->GetBinContent(i, j);
5428  zc[1] = fH->GetBinContent(i+1, j);
5429  zc[2] = fH->GetBinContent(i+1, j+1);
5430  zc[3] = fH->GetBinContent(i, j+1);
5431  if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5432  if (Hoption.Logz) {
5433  if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5434  else zc[0] = Hparam.zmin;
5435  if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5436  else zc[1] = Hparam.zmin;
5437  if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5438  else zc[2] = Hparam.zmin;
5439  if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5440  else zc[3] = Hparam.zmin;
5441  }
5442  for (k=0;k<4;k++) {
5443  ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5444  }
5445  if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5446  x[0] = fXaxis->GetBinCenter(i);
5447  x[3] = x[0];
5448  x[1] = fXaxis->GetBinCenter(i+1);
5449  x[2] = x[1];
5450  if (zc[0] <= zc[1]) n = 0; else n = 1;
5451  if (zc[2] <= zc[3]) m = 2; else m = 3;
5452  if (zc[n] > zc[m]) n = m;
5453  n++;
5454  lj=1;
5455  for (ix=1;ix<=4;ix++) {
5456  m = n%4 + 1;
5457  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5458  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5459  lj += 2*ljfill;
5460  n = m;
5461  }
5462 
5463  if (zc[0] <= zc[1]) n = 0; else n = 1;
5464  if (zc[2] <= zc[3]) m = 2; else m = 3;
5465  if (zc[n] > zc[m]) n = m;
5466  n++;
5467  lj=2;
5468  for (ix=1;ix<=4;ix++) {
5469  if (n == 1) m = 4;
5470  else m = n-1;
5471  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5472  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5473  lj += 2*ljfill;
5474  n = m;
5475  }
5476 
5477  // Re-order endpoints
5478 
5479  count = 0;
5480  for (ix=1; ix<=lj-5; ix +=2) {
5481  //count = 0;
5482  while (itarr[ix-1] != itarr[ix]) {
5483  xsave = xarr[ix];
5484  ysave = yarr[ix];
5485  itars = itarr[ix];
5486  for (jx=ix; jx<=lj-5; jx +=2) {
5487  xarr[jx] = xarr[jx+2];
5488  yarr[jx] = yarr[jx+2];
5489  itarr[jx] = itarr[jx+2];
5490  }
5491  xarr[lj-3] = xsave;
5492  yarr[lj-3] = ysave;
5493  itarr[lj-3] = itars;
5494  if (count > 100) break;
5495  count++;
5496  }
5497  }
5498 
5499  if (count > 100) continue;
5500  for (ix=1; ix<=lj-2; ix +=2) {
5501  theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5502  icol = gStyle->GetColorPalette(theColor);
5503  if (Hoption.Contour == 11) {
5504  fH->SetLineColor(icol);
5505  }
5506  if (Hoption.Contour == 12) {
5507  mode = icol%5;
5508  if (mode == 0) mode = 5;
5509  fH->SetLineStyle(mode);
5510  }
5511  if (Hoption.Contour != 1) {
5512  fH->TAttLine::Modify();
5513  gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5514  continue;
5515  }
5516 
5517  ipoly = itarr[ix-1];
5518  if (ipoly >=0 && ipoly <ncontour) {
5519  poly = polys[ipoly];
5520  poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5521  poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5522  np[ipoly] += 2;
5523  if (npmax < np[ipoly]) npmax = np[ipoly];
5524  }
5525  }
5526  } // end of if (ir[0]
5527  } //end of for (i
5528  } //end of for (j
5529 
5530  Double_t xmin,ymin;
5531  Double_t *xp, *yp;
5532  Int_t nadd,iminus,iplus;
5533  Double_t *xx, *yy;
5534  Int_t istart;
5535  Int_t first = ncontour;
5536  Int_t *polysort = 0;
5537  Int_t contListNb;
5538  if (Hoption.Contour != 1) goto theEND;
5539 
5540  //The 2 points line generated above are now sorted/merged to generate
5541  //a list of consecutive points.
5542  // If the option "List" has been specified, the list of points is saved
5543  // in the form of TGraph objects in the ROOT list of special objects.
5544  xmin = gPad->GetUxmin();
5545  ymin = gPad->GetUymin();
5546  xp = new Double_t[2*npmax];
5547  yp = new Double_t[2*npmax];
5548  polysort = new Int_t[ncontour];
5549  //find first positive contour
5550  for (ipoly=0;ipoly<ncontour;ipoly++) {
5551  if (levels[ipoly] >= 0) {first = ipoly; break;}
5552  }
5553  //store negative contours from 0 to minimum, then all positive contours
5554  k = 0;
5555  for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
5556  for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
5557  // we can now draw sorted contours
5558  contListNb = 0;
5559  fH->SetFillStyle(1001);
5560  for (k=0;k<ncontour;k++) {
5561  ipoly = polysort[k];
5562  if (np[ipoly] == 0) continue;
5563  if (Hoption.List) list = (TList*)contours->At(contListNb);
5564  contListNb++;
5565  poly = polys[ipoly];
5566  xx = poly->GetX();
5567  yy = poly->GetY();
5568  istart = 0;
5569  while (1) {
5570  iminus = npmax;
5571  iplus = iminus+1;
5572  xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
5573  xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
5574  xx[istart] = xmin; yy[istart] = ymin;
5575  xx[istart+1] = xmin; yy[istart+1] = ymin;
5576  while (1) {
5577  nadd = 0;
5578  for (i=2;i<np[ipoly];i+=2) {
5579  if (xx[i] == xp[iplus] && yy[i] == yp[iplus]) {
5580  iplus++;
5581  xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
5582  xx[i] = xmin; yy[i] = ymin;
5583  xx[i+1] = xmin; yy[i+1] = ymin;
5584  nadd++;
5585  }
5586  if (xx[i+1] == xp[iminus] && yy[i+1] == yp[iminus]) {
5587  iminus--;
5588  xp[iminus] = xx[i]; yp[iminus] = yy[i];
5589  xx[i] = xmin; yy[i] = ymin;
5590  xx[i+1] = xmin; yy[i+1] = ymin;
5591  nadd++;
5592  }
5593  }
5594  if (nadd == 0) break;
5595  }
5596  theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
5597  icol = gStyle->GetColorPalette(theColor);
5598  if (ndivz > 1) fH->SetFillColor(icol);
5599  fH->TAttFill::Modify();
5600  gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5601  if (Hoption.List) {
5602  graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5603  graph->SetFillColor(icol);
5604  graph->SetLineWidth(fH->GetLineWidth());
5605  list->Add(graph);
5606  }
5607  //check if more points are left
5608  istart = 0;
5609  for (i=2;i<np[ipoly];i+=2) {
5610  if (xx[i] != xmin && yy[i] != ymin) {
5611  istart = i;
5612  break;
5613  }
5614  }
5615  if (istart == 0) break;
5616  }
5617  }
5618 
5619  for (i=0;i<ncontour;i++) delete polys[i];
5620  delete [] polys;
5621  delete [] xp;
5622  delete [] yp;
5623  delete [] polysort;
5624 
5625 theEND:
5626  gPad->ResetBit(TGraph::kClipFrame);
5627  if (Hoption.Zscale) PaintPalette();
5628  fH->SetLineStyle(linesav);
5629  fH->SetLineColor(colorsav);
5630  fH->SetFillColor(fillsav);
5631  if (np) delete [] np;
5632  delete [] xarr;
5633  delete [] yarr;
5634  delete [] itarr;
5635  delete [] levels;
5636 }
5637 
5638 ////////////////////////////////////////////////////////////////////////////////
5639 /// Fill the matrix `xarr` and `yarr` for Contour Plot.
5640 
5642  Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
5643  Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
5644 {
5645 
5646  Bool_t vert;
5647  Double_t tlen, tdif, elev, diff, pdif, xlen;
5648  Int_t n, i, icount;
5650  if (x1 == x2) {
5651  vert = kTRUE;
5652  tlen = y2 - y1;
5653  } else {
5654  vert = kFALSE;
5655  tlen = x2 - x1;
5656  }
5657 
5658  n = icont1 +1;
5659  tdif = elev2 - elev1;
5660  i = 0;
5661  icount = 0;
5662  while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
5663  //elev = fH->GetContourLevel(n);
5664  elev = levels[n];
5665  diff = elev - elev1;
5666  pdif = diff/tdif;
5667  xlen = tlen*pdif;
5668  if (vert) {
5669  if (Hoption.Logx)
5670  xarr[i] = TMath::Log10(x1);
5671  else
5672  xarr[i] = x1;
5673  if (Hoption.Logy)
5674  yarr[i] = TMath::Log10(y1 + xlen);
5675  else
5676  yarr[i] = y1 + xlen;
5677  } else {
5678  if (Hoption.Logx)
5679  xarr[i] = TMath::Log10(x1 + xlen);
5680  else
5681  xarr[i] = x1 + xlen;
5682  if (Hoption.Logy)
5683  yarr[i] = TMath::Log10(y1);
5684  else
5685  yarr[i] = y1;
5686  }
5687  itarr[i] = n;
5688  icount++;
5689  i +=2;
5690  n++;
5691  }
5692  return icount;
5693 }
5694 
5695 ////////////////////////////////////////////////////////////////////////////////
5696 /// [Draw 1D histograms error bars.](#HP09)
5697 
5699 {
5700 
5701  // On iOS, we do not highlight histogram, if it's not picked at the moment
5702  // (but part of histogram (axis or pavestat) was picked, that's why this code
5703  // is called at all. This conditional statement never executes on non-iOS platform.
5704  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
5705 
5706  const Int_t kBASEMARKER=8;
5707  Double_t xp, yp, ex1, ex2, ey1, ey2;
5708  Double_t delta;
5709  Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
5710  Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
5711  Double_t xmin, xmax, ymin, ymax;
5712  Double_t logxmin = 0;
5713  Double_t logymin = 0;
5714  Int_t i, k, npoints, first, last, fixbin;
5715  Int_t if1 = 0;
5716  Int_t if2 = 0;
5717  Int_t drawmarker, errormarker;
5718  Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
5719 
5720  Double_t *xline = 0;
5721  Double_t *yline = 0;
5722  option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
5723  if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
5724  if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
5725  if (Hoption.Error == 10) option0 = 1;
5726  if (Hoption.Error == 11) option1 = 1;
5727  if (Hoption.Error == 12) option2 = 1;
5728  if (Hoption.Error == 13) option3 = 1;
5729  if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
5730  if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
5731  if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
5732  if (option2+option3 == 0) optionE = 1;
5733  if (Hoption.Error == 0) optionE = 0;
5734  if (fXaxis->GetXbins()->fN) fixbin = 0;
5735  else fixbin = 1;
5736 
5737  errormarker = fH->GetMarkerStyle();
5738  if (optionEX0) {
5739  xerror = 0;
5740  } else {
5741  xerror = gStyle->GetErrorX();
5742  }
5743  symbolsize = fH->GetMarkerSize();
5744  if (errormarker == 1) symbolsize = 0.01;
5745  sbase = symbolsize*kBASEMARKER;
5746  // set the graphics attributes
5747 
5748  fH->TAttLine::Modify();
5749  fH->TAttFill::Modify();
5750  fH->TAttMarker::Modify();
5751 
5752  // set the first and last bin
5753 
5754  Double_t factor = Hparam.factor;
5755  first = Hparam.xfirst;
5756  last = Hparam.xlast;
5757  npoints = last - first +1;
5758  xmin = gPad->GetUxmin();
5759  xmax = gPad->GetUxmax();
5760  ymin = gPad->GetUymin();
5761  ymax = gPad->GetUymax();
5762 
5763 
5764  if (option3) {
5765  xline = new Double_t[2*npoints];
5766  yline = new Double_t[2*npoints];
5767  if (!xline || !yline) {
5768  Error("PaintErrors", "too many points, out of memory");
5769  return;
5770  }
5771  if1 = 1;
5772  if2 = 2*npoints;
5773  }
5774 
5775  // compute the offset of the error bars due to the symbol size
5776  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
5777  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
5778 
5779  // compute size of the lines at the end of the error bars
5780  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
5781  bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
5782  bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
5783 
5784 
5785  if (fixbin) {
5786  if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
5787  else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
5788  } else {
5789  delta = fH->GetBinWidth(first);
5790  xp = fH->GetBinLowEdge(first) + 0.5*delta;
5791  }
5792 
5793  // if errormarker = 0 or symbolsize = 0. no symbol is drawn
5794  if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
5795  if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
5796 
5797  // ---------------------- Loop over the points---------------------
5798  for (k=first; k<=last; k++) {
5799 
5800  // get the data
5801  // xp = X position of the current point
5802  // yp = Y position of the current point
5803  // ex1 = Low X error
5804  // ex2 = Up X error
5805  // ey1 = Low Y error
5806  // ey2 = Up Y error
5807  // (xi,yi) = Error bars coordinates
5808 
5809  if (Hoption.Logx) {
5810  if (xp <= 0) goto L30;
5811  if (xp < logxmin) goto L30;
5812  if (xp > TMath::Power(10,xmax)) break;
5813  } else {
5814  if (xp < xmin) goto L30;
5815  if (xp > xmax) break;
5816  }
5817  yp = factor*fH->GetBinContent(k);
5818  if (optionI0 && yp==0) goto L30;
5819  if (fixbin) {
5820  ex1 = xerror*Hparam.xbinsize;
5821  } else {
5822  delta = fH->GetBinWidth(k);
5823  ex1 = xerror*delta;
5824  }
5825  if (fH->GetBinErrorOption() == TH1::kNormal) {
5826  ey1 = factor*fH->GetBinError(k);
5827  ey2 = ey1;
5828  } else {
5829  ey1 = factor*fH->GetBinErrorLow(k);
5830  ey2 = factor*fH->GetBinErrorUp(k);
5831  }
5832  ex2 = ex1;
5833 
5834  xi4 = xp;
5835  xi3 = xp;
5836  xi2 = xp + ex2;
5837  xi1 = xp - ex1;
5838 
5839  yi1 = yp;
5840  yi2 = yp;
5841  yi3 = yp - ey1;
5842  yi4 = yp + ey2;
5843 
5844  // take the LOG if necessary
5845  if (Hoption.Logx) {
5846  xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
5847  xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
5848  xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
5849  xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
5850  }
5851  if (Hoption.Logy) {
5852  yi1 = TMath::Log10(TMath::Max(yi1,logymin));
5853  yi2 = TMath::Log10(TMath::Max(yi2,logymin));
5854  yi3 = TMath::Log10(TMath::Max(yi3,logymin));
5855  yi4 = TMath::Log10(TMath::Max(yi4,logymin));
5856  }
5857 
5858  // test if error bars are not outside the limits
5859  // otherwise they are truncated
5860 
5861  xi1 = TMath::Max(xi1,xmin);
5862  xi2 = TMath::Min(xi2,xmax);
5863  yi3 = TMath::Max(yi3,ymin);
5864  yi4 = TMath::Min(yi4,ymax);
5865 
5866  // test if the marker is on the frame limits. If "Yes", the
5867  // marker will not be drawn and the error bars will be readjusted.
5868 
5869  drawmarker = kTRUE;
5870  if (!option0 && !option3) {
5871  if (Hoption.Logy && yp < logymin) goto L30;
5872  if (yi1 < ymin || yi1 > ymax) goto L30;
5873  if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
5874  }
5875  if (!symbolsize || !errormarker) drawmarker = kFALSE;
5876 
5877  // draw the error rectangles
5878  if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
5879 
5880  // keep points for fill area drawing
5881  if (option3) {
5882  xline[if1-1] = xi3;
5883  xline[if2-1] = xi3;
5884  yline[if1-1] = yi4;
5885  yline[if2-1] = yi3;
5886  if1++;
5887  if2--;
5888  }
5889 
5890  // draw the error bars
5891  if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
5892  if (optionE && drawmarker) {
5893  if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
5894  if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
5895  // don't duplicate the horizontal line
5896  if (Hoption.Hist != 2) {
5897  if (yi1<ymax && yi1>ymin) {
5898  if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
5899  if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
5900  }
5901  }
5902  }
5903  if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
5904  if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
5905  if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
5906  // don't duplicate the horizontal line
5907  if (Hoption.Hist != 2) {
5908  if (yi1<ymax && yi1>ymin) {
5909  if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
5910  if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
5911  }
5912  }
5913  }
5914 
5915  // draw line at the end of the error bars
5916 
5917  if (option1 && drawmarker) {
5918  if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
5919  if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
5920  if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
5921  if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
5922  }
5923 
5924  // draw the marker
5925 
5926  if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
5927 
5928 L30:
5929  if (fixbin) xp += Hparam.xbinsize;
5930  else {
5931  if (k < last) {
5932  delta = fH->GetBinWidth(k+1);
5933  xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
5934  }
5935  }
5936  } //end of for loop
5937 
5938  // draw the filled area
5939 
5940  if (option3) {
5941  TGraph graph;
5942  graph.SetLineStyle(fH->GetLineStyle());
5943  graph.SetLineColor(fH->GetLineColor());
5944  graph.SetLineWidth(fH->GetLineWidth());
5945  graph.SetFillStyle(fH->GetFillStyle());
5946  graph.SetFillColor(fH->GetFillColor());
5947  Int_t logx = gPad->GetLogx();
5948  Int_t logy = gPad->GetLogy();
5949  gPad->SetLogx(0);
5950  gPad->SetLogy(0);
5951 
5952  // In some cases the number of points in the fill area is smaller than
5953  // 2*npoints. In such cases the array xline and yline must be arranged
5954  // before being plotted. The next loop does that.
5955  if (if2 > npoints) {
5956  for (i=1; i<if1; i++) {
5957  xline[if1-2+i] = xline[if2-1+i];
5958  yline[if1-2+i] = yline[if2-1+i];
5959  }
5960  npoints = if1-1;
5961  }
5962  if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
5963  else graph.PaintGraph(2*npoints,xline,yline,"F");
5964  gPad->SetLogx(logx);
5965  gPad->SetLogy(logy);
5966  delete [] xline;
5967  delete [] yline;
5968  }
5969 }
5970 
5971 ////////////////////////////////////////////////////////////////////////////////
5972 /// Draw 2D histograms errors.
5973 
5975 {
5976 
5977  fH->TAttMarker::Modify();
5978  fH->TAttLine::Modify();
5979 
5980  // Define the 3D view
5981  fXbuf[0] = Hparam.xmin;
5982  fYbuf[0] = Hparam.xmax;
5983  fXbuf[1] = Hparam.ymin;
5984  fYbuf[1] = Hparam.ymax;
5985  fXbuf[2] = Hparam.zmin;
5986  fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
5988  TView *view = gPad->GetView();
5989  if (!view) {
5990  Error("Paint2DErrors", "no TView in current pad");
5991  return;
5992  }
5993  Double_t thedeg = 90 - gPad->GetTheta();
5994  Double_t phideg = -90 - gPad->GetPhi();
5995  Double_t psideg = view->GetPsi();
5996  Int_t irep;
5997  view->SetView(phideg, thedeg, psideg, irep);
5998 
5999  // Set color/style for back box
6000  fLego->SetFillStyle(gPad->GetFrameFillStyle());
6001  fLego->SetFillColor(gPad->GetFrameFillColor());
6002  fLego->TAttFill::Modify();
6003  Int_t backcolor = gPad->GetFrameFillColor();
6004  if (Hoption.System != kCARTESIAN) backcolor = 0;
6005  view->PadRange(backcolor);
6008  fLego->TAttFill::Modify();
6009 
6010  // Paint the Back Box if needed
6011  if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6012  fLego->InitMoveScreen(-1.1,1.1);
6015  fLego->BackBox(90);
6016  }
6017 
6018  // Paint the Errors
6019  Double_t x, ex, x1, x2;
6020  Double_t y, ey, y1, y2;
6021  Double_t z, ez1, ez2, z1, z2;
6022  Double_t temp1[3],temp2[3];
6023  Double_t xyerror;
6024  if (Hoption.Error == 110) {
6025  xyerror = 0;
6026  } else {
6027  xyerror = gStyle->GetErrorX();
6028  }
6029 
6030  Double_t xk, xstep, yk, ystep;
6031  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6032  y = fYaxis->GetBinCenter(j);
6033  ey = fYaxis->GetBinWidth(j)*xyerror;
6034  y1 = y-ey;
6035  y2 = y+ey;
6036  if (Hoption.Logy) {
6037  if (y > 0) y = TMath::Log10(y);
6038  else continue;
6039  if (y1 > 0) y1 = TMath::Log10(y1);
6040  else y1 = Hparam.ymin;
6041  if (y2 > 0) y2 = TMath::Log10(y2);
6042  else y2 = Hparam.ymin;
6043  }
6044  yk = fYaxis->GetBinLowEdge(j);
6045  ystep = fYaxis->GetBinWidth(j);
6046  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6047  xk = fXaxis->GetBinLowEdge(i);
6048  xstep = fXaxis->GetBinWidth(i);
6049  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6050  Int_t bin = fH->GetBin(i,j);
6051  x = fXaxis->GetBinCenter(i);
6052  ex = fXaxis->GetBinWidth(i)*xyerror;
6053  x1 = x-ex;
6054  x2 = x+ex;
6055  if (Hoption.Logx) {
6056  if (x > 0) x = TMath::Log10(x);
6057  else continue;
6058  if (x1 > 0) x1 = TMath::Log10(x1);
6059  else x1 = Hparam.xmin;
6060  if (x2 > 0) x2 = TMath::Log10(x2);
6061  else x2 = Hparam.xmin;
6062  }
6063  z = fH->GetBinContent(bin);
6064  if (fH->GetBinErrorOption() == TH1::kNormal) {
6065  ez1 = fH->GetBinError(bin);
6066  ez2 = ez1;
6067  }
6068  else {
6069  ez1 = fH->GetBinErrorLow(bin);
6070  ez2 = fH->GetBinErrorUp(bin);
6071  }
6072  z1 = z - ez1;
6073  z2 = z + ez2;
6074  if (Hoption.Logz) {
6075  if (z > 0) z = TMath::Log10(z);
6076  else z = Hparam.zmin;
6077  if (z1 > 0) z1 = TMath::Log10(z1);
6078  else z1 = Hparam.zmin;
6079  if (z2 > 0) z2 = TMath::Log10(z2);
6080  else z2 = Hparam.zmin;
6081 
6082  }
6083  if (z <= Hparam.zmin) continue;
6084  if (z > Hparam.zmax) z = Hparam.zmax;
6085 
6086  temp1[0] = x1;
6087  temp1[1] = y;
6088  temp1[2] = z;
6089  temp2[0] = x2;
6090  temp2[1] = y;
6091  temp2[2] = z;
6092  gPad->PaintLine3D(temp1, temp2);
6093  temp1[0] = x;
6094  temp1[1] = y1;
6095  temp1[2] = z;
6096  temp2[0] = x;
6097  temp2[1] = y2;
6098  temp2[2] = z;
6099  gPad->PaintLine3D(temp1, temp2);
6100  temp1[0] = x;
6101  temp1[1] = y;
6102  temp1[2] = z1;
6103  temp2[0] = x;
6104  temp2[1] = y;
6105  temp2[2] = z2;
6106  gPad->PaintLine3D(temp1, temp2);
6107  temp1[0] = x;
6108  temp1[1] = y;
6109  temp1[2] = z;
6110  view->WCtoNDC(temp1, &temp2[0]);
6111  gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6112  }
6113  }
6114 
6115  // Paint the Front Box if needed
6116  if (Hoption.FrontBox) {
6117  fLego->InitMoveScreen(-1.1,1.1);
6119  fLego->FrontBox(90);
6120  }
6121 
6122  // Paint the Axis if needed
6123  if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6124  TGaxis *axis = new TGaxis();
6125  PaintLegoAxis(axis, 90);
6126  delete axis;
6127  }
6128 
6129  delete fLego; fLego = 0;
6130 }
6131 
6132 ////////////////////////////////////////////////////////////////////////////////
6133 /// Calculate range and clear pad (canvas).
6134 
6136 {
6137 
6138  if (Hoption.Same) return;
6139 
6140  RecalculateRange();
6141 
6142  if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6143  Hoption.Contour == 14 || Hoption.Error >= 100) {
6144  TObject *frame = gPad->FindObject("TFrame");
6145  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6146  return;
6147  }
6148 
6149  //The next statement is always executed on non-iOS platform,
6150  //on iOS depends on pad mode.
6151  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6152  gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6153 }
6154 
6155 ////////////////////////////////////////////////////////////////////////////////
6156 /// [Paint functions associated to an histogram.](#HP28")
6157 
6159 {
6160 
6162  TObject *obj;
6163 
6164  while (lnk) {
6165  obj = lnk->GetObject();
6166  TVirtualPad *padsave = gPad;
6167  if (obj->InheritsFrom(TF2::Class())) {
6168  if (obj->TestBit(TF2::kNotDraw) == 0) {
6169  if (Hoption.Lego || Hoption.Surf) {
6170  TF2 *f2 = (TF2*)obj;
6171  f2->SetMinimum(fH->GetMinimum());
6172  f2->SetMaximum(fH->GetMaximum());
6173  f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6174  f2->Paint("surf same");
6175  } else {
6176  obj->Paint("cont3 same");
6177  }
6178  }
6179  } else if (obj->InheritsFrom(TF1::Class())) {
6180  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6181  } else {
6182  //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6183  gPad->PushSelectableObject(obj);
6184 
6185  //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6186  //and picked object.
6187  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6188  obj->Paint(lnk->GetOption());
6189  }
6190  lnk = (TObjOptLink*)lnk->Next();
6191  padsave->cd();
6192  }
6193 }
6194 
6195 ////////////////////////////////////////////////////////////////////////////////
6196 /// [Control routine to draw 1D histograms](#HP01b)
6197 
6199 {
6200 
6201  //On iOS: do not highlight hist, if part of it was selected.
6202  //Never executes on non-iOS platform.
6203  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6204  return;
6205 
6206  static char chopth[17];
6207 
6208  Int_t htype, oldhtype;
6209  Int_t i, j, first, last, nbins, fixbin;
6210  Double_t c1, yb;
6211  yb = 0;
6212 
6213  strlcpy(chopth, " ",17);
6214 
6215  Double_t ymin = Hparam.ymin;
6216  Double_t ymax = Hparam.ymax;
6217  Double_t baroffset = fH->GetBarOffset();
6218  Double_t barwidth = fH->GetBarWidth();
6219  Double_t baroffsetsave = gStyle->GetBarOffset();
6220  Double_t barwidthsave = gStyle->GetBarWidth();
6221  gStyle->SetBarOffset(baroffset);
6222  gStyle->SetBarWidth(barwidth);
6223 
6224  // Create "LIFE" structure to keep current histogram status
6225 
6226  first = Hparam.xfirst;
6227  last = Hparam.xlast;
6228  nbins = last - first + 1;
6229 
6230  Double_t *keepx = 0;
6231  Double_t *keepy = 0;
6232  if (fXaxis->GetXbins()->fN) fixbin = 0;
6233  else fixbin = 1;
6234  if (fixbin) keepx = new Double_t[2];
6235  else keepx = new Double_t[nbins+1];
6236  keepy = new Double_t[nbins];
6237  Double_t logymin = 0;
6238  if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6239 
6240  // Loop on histogram bins
6241 
6242  for (j=first; j<=last;j++) {
6243  c1 = Hparam.factor*fH->GetBinContent(j);
6244  if (TMath::Abs(ymax-ymin) > 0) {
6245  if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6246  else yb = c1;
6247  }
6248  if (!Hoption.Line) {
6249  yb = TMath::Max(yb, ymin);
6250  yb = TMath::Min(yb, ymax);
6251  }
6252  keepy[j-first] = yb;
6253  }
6254 
6255  // Draw histogram according to value of FillStyle and FillColor
6256 
6257  if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6258  else {
6259  for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6260  keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6261  }
6262 
6263  // Prepare Fill area (systematic with option "Bar").
6264 
6265  oldhtype = fH->GetFillStyle();
6266  htype = oldhtype;
6267  if (Hoption.Bar) {
6268  if (htype == 0 || htype == 1000) htype = 1001;
6269  }
6270 
6271  Width_t lw = (Width_t)fH->GetLineWidth();
6272 
6273  // Code option for GrapHist
6274 
6275  if (Hoption.Line) chopth[0] = 'L';
6276  if (Hoption.Star) chopth[1] = '*';
6277  if (Hoption.Mark) chopth[2] = 'P';
6278  if (Hoption.Mark == 10) chopth[3] = '0';
6279  if (Hoption.Line || Hoption.Curve || Hoption.Hist || Hoption.Bar) {
6280  if (Hoption.Curve) chopth[3] = 'C';
6281  if (Hoption.Hist > 0) chopth[4] = 'H';
6282  else if (Hoption.Bar) chopth[5] = 'B';
6283  if (fH->GetFillColor() && htype) {
6284  if (Hoption.Logy) {
6285  chopth[6] = '1';
6286  }
6287  if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6288  chopth[7] = 'F';
6289  }
6290  }
6291  }
6292  if (!fixbin && strlen(chopth)) {
6293  chopth[8] = 'N';
6294  }
6295 
6296  if (Hoption.Fill == 2) chopth[13] = '2';
6297 
6298  // Option LOGX
6299 
6300  if (Hoption.Logx) {
6301  chopth[9] = 'G';
6302  chopth[10] = 'X';
6303  if (fixbin) {
6304  keepx[0] = TMath::Power(10,keepx[0]);
6305  keepx[1] = TMath::Power(10,keepx[1]);
6306  }
6307  }
6308 
6309  if (Hoption.Off) {
6310  chopth[11] = ']';
6311  chopth[12] = '[';
6312  }
6313 
6314  // Draw the histogram
6315 
6316  TGraph graph;
6317  graph.SetLineWidth(lw);
6318  graph.SetLineStyle(fH->GetLineStyle());
6319  graph.SetLineColor(fH->GetLineColor());
6320  graph.SetFillStyle(htype);
6321  graph.SetFillColor(fH->GetFillColor());
6322  graph.SetMarkerStyle(fH->GetMarkerStyle());
6323  graph.SetMarkerSize(fH->GetMarkerSize());
6324  graph.SetMarkerColor(fH->GetMarkerColor());
6325  if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6326 
6327  graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6328 
6329  delete [] keepx;
6330  delete [] keepy;
6331  gStyle->SetBarOffset(baroffsetsave);
6332  gStyle->SetBarWidth(barwidthsave);
6333 
6334  htype=oldhtype;
6335 }
6336 
6337 ////////////////////////////////////////////////////////////////////////////////
6338 /// [Control function to draw a 3D histograms.](#HP01d)
6339 
6340 void THistPainter::PaintH3(Option_t *option)
6341 {
6342 
6343  char *cmd;
6344  TString opt = fH->GetDrawOption();
6345  opt.ToLower();
6346  Int_t irep;
6347 
6348  if (fH->GetDrawOption() && (strstr(opt,"box") || strstr(opt,"lego"))) {
6349  cmd = Form("TMarker3DBox::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6350  } else if (fH->GetDrawOption() && strstr(opt,"iso")) {
6351  PaintH3Iso();
6352  return;
6353  } else if (strstr(option,"tf3")) {
6354  PaintTF3();
6355  return;
6356  } else {
6357  cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6358  }
6359 
6360  if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6361  if (strstr(opt,"bb")) Hoption.BackBox = 0;
6362 
6363  TView *view = gPad->GetView();
6364  if (!view) return;
6365  Double_t thedeg = 90 - gPad->GetTheta();
6366  Double_t phideg = -90 - gPad->GetPhi();
6367  Double_t psideg = view->GetPsi();
6368  view->SetView(phideg, thedeg, psideg, irep);
6369 
6370  // Paint the data
6371  gROOT->ProcessLine(cmd);
6372 
6373  if (Hoption.Same) return;
6374 
6375  // Draw axis
6376  view->SetOutlineToCube();
6377  TSeqCollection *ol = view->GetOutline();
6378  if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6379  Hoption.System = kCARTESIAN;
6380  TGaxis *axis = new TGaxis();
6381  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6382  delete axis;
6383 
6384  // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6385  // be painted with the option colz.
6386  if (fH->GetDrawOption() && strstr(opt,"colz")) {
6387  Int_t ndiv = fH->GetContour();
6388  if (ndiv == 0 ) {
6389  ndiv = gStyle->GetNumberContours();
6390  fH->SetContour(ndiv);
6391  }
6392  PaintPalette();
6393  }
6394 
6395  // Draw title
6396  PaintTitle();
6397 
6398  //Draw stats and fit results
6399  TF1 *fit = 0;
6400  TIter next(fFunctions);
6401  TObject *obj;
6402  while ((obj = next())) {
6403  if (obj->InheritsFrom(TF1::Class())) {
6404  fit = (TF1*)obj;
6405  break;
6406  }
6407  }
6408  if (Hoption.Same != 1) {
6409  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6410  PaintStat3(gStyle->GetOptStat(),fit);
6411  }
6412  }
6413 
6414 }
6415 
6416 ////////////////////////////////////////////////////////////////////////////////
6417 /// Compute histogram parameters used by the drawing routines.
6418 
6420 {
6421 
6422  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6423 
6424  Int_t i;
6425  static const char *where = "PaintInit";
6426  Double_t yMARGIN = gStyle->GetHistTopMargin();
6427  Int_t maximum = 0;
6428  Int_t minimum = 0;
6429  if (fH->GetMaximumStored() != -1111) maximum = 1;
6430  if (fH->GetMinimumStored() != -1111) minimum = 1;
6431 
6432  // Compute X axis parameters
6433 
6434  Int_t last = fXaxis->GetLast();
6435  Int_t first = fXaxis->GetFirst();
6436  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6437  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6438  Hparam.xlast = last;
6439  Hparam.xfirst = first;
6440  Hparam.xmin = Hparam.xlowedge;
6441  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6442 
6443  // if log scale in X, replace xmin,max by the log
6444  if (Hoption.Logx) {
6445  if (Hparam.xmax<=0) {
6446  Error(where, "cannot set X axis to log scale");
6447  return 0;
6448  }
6449  if (Hparam.xlowedge <=0 ) {
6450  if (Hoption.Same) {
6451  Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
6452  } else {
6453  for (i=first; i<=last; i++) {
6454  Double_t binLow = fXaxis->GetBinLowEdge(i);
6455  if (binLow>0) {
6456  Hparam.xlowedge = binLow;
6457  break;
6458  }
6459  if (binLow == 0 && fH->GetBinContent(i) !=0) {
6460  Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6461  break;
6462  }
6463  }
6464  if (Hparam.xlowedge<=0) {
6465  Error(where, "cannot set X axis to log scale");
6466  return 0;
6467  }
6468  }
6469  Hparam.xmin = Hparam.xlowedge;
6470  }
6471  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
6472  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
6473  Hparam.xmin = TMath::Log10(Hparam.xmin);
6474  Hparam.xmax = TMath::Log10(Hparam.xmax);
6475  if (Hparam.xlast > last) Hparam.xlast = last;
6476  if (Hparam.xfirst < first) Hparam.xfirst = first;
6477  }
6478 
6479  // Compute Y axis parameters
6480  Double_t bigp = TMath::Power(10,32);
6481  Double_t ymax = -bigp;
6482  Double_t ymin = bigp;
6483  Double_t c1, e1;
6484  Double_t xv[1];
6485  Double_t fval;
6486  TObject *f;
6487  TF1 *f1;
6488  Double_t allchan = 0;
6489  Int_t nonNullErrors = 0;
6490  TIter next(fFunctions);
6491  for (i=first; i<=last;i++) {
6492  c1 = fH->GetBinContent(i);
6493  ymax = TMath::Max(ymax,c1);
6494  if (Hoption.Logy) {
6495  if (c1 > 0) ymin = TMath::Min(ymin,c1);
6496  } else {
6497  ymin = TMath::Min(ymin,c1);
6498  }
6499  if (Hoption.Error) {
6500  if (fH->GetBinErrorOption() == TH1::kNormal)
6501  e1 = fH->GetBinError(i);
6502  else
6503  e1 = fH->GetBinErrorUp(i);
6504  if (e1 > 0) nonNullErrors++;
6505  ymax = TMath::Max(ymax,c1+e1);
6506  if (fH->GetBinErrorOption() != TH1::kNormal)
6507  e1 = fH->GetBinErrorLow(i);
6508 
6509  if (Hoption.Logy) {
6510  if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6511  } else {
6512  ymin = TMath::Min(ymin,c1-e1);
6513  }
6514  }
6515  if (Hoption.Func) {
6516  xv[0] = fXaxis->GetBinCenter(i);
6517  while ((f = (TObject*) next())) {
6518  if (f->IsA() == TF1::Class()) {
6519  f1 = (TF1*)f;
6520  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6521  fval = f1->Eval(xv[0],0,0);
6522  if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6523  ymax = TMath::Max(ymax,fval);
6524  if (Hoption.Logy) {
6525  if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6526  }
6527  }
6528  }
6529  next.Reset();
6530  }
6531  allchan += c1;
6532  }
6533  if (!nonNullErrors) {
6534  if (Hoption.Error) {
6535  if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
6536  Hoption.Error=0;
6537  }
6538  }
6539 
6540 
6541  // Take into account maximum , minimum
6542 
6543  if (Hoption.Logy && ymin <= 0) {
6544  if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
6545  else ymin = 0.001*ymax;
6546  }
6547 
6548  Double_t xm = ymin;
6549  if (maximum) ymax = fH->GetMaximumStored();
6550  if (minimum) xm = fH->GetMinimumStored();
6551  if (Hoption.Logy && xm < 0) {
6552  Error(where, "log scale requested with a negative argument (%f)", xm);
6553  return 0;
6554  } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
6555  ymin = 0.01;
6556  ymax = 10.;
6557  } else {
6558  ymin = xm;
6559  }
6560 
6561  if (ymin >= ymax) {
6562  if (Hoption.Logy) {
6563  if (ymax > 0) ymin = 0.001*ymax;
6564  else {
6565  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
6566  return 0;
6567  }
6568  }
6569  else {
6570  if (ymin > 0) {
6571  ymin = 0;
6572  ymax *= 2;
6573  } else if (ymin < 0) {
6574  ymax = 0;
6575  ymin *= 2;
6576  } else {
6577  ymin = 0;
6578  ymax = 1;
6579  }
6580  }
6581  }
6582 
6583  // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
6584  if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
6585  ymin = ymin*(1-1E-14);
6586  ymax = ymax*(1+1E-14);
6587  }
6588 
6589  // take into account normalization factor
6590  Hparam.allchan = allchan;
6591  Double_t factor = allchan;
6592  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6593  if (allchan) factor /= allchan;
6594  if (factor == 0) factor = 1;
6595  Hparam.factor = factor;
6596  ymax = factor*ymax;
6597  ymin = factor*ymin;
6598  //just in case the norm factor is negative
6599  // this may happen with a positive norm factor and a negative integral !
6600  if (ymax < ymin) {
6601  Double_t temp = ymax;
6602  ymax = ymin;
6603  ymin = temp;
6604  }
6605 
6606  // For log scales, histogram coordinates are LOG10(ymin) and
6607  // LOG10(ymax). Final adjustment (if not option "Same"
6608  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6609  // Maximum and Minimum are not defined.
6610  if (Hoption.Logy) {
6611  if (ymin <=0 || ymax <=0) {
6612  Error(where, "Cannot set Y axis to log scale");
6613  return 0;
6614  }
6615  ymin = TMath::Log10(ymin);
6616  if (!minimum) ymin += TMath::Log10(0.5);
6617  ymax = TMath::Log10(ymax);
6618  if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
6619  if (!Hoption.Same) {
6620  Hparam.ymin = ymin;
6621  Hparam.ymax = ymax;
6622  }
6623  return 1;
6624  }
6625 
6626  // final adjustment of ymin for linear scale.
6627  // if minimum is not set , then ymin is set to zero if >0
6628  // or to ymin - margin if <0.
6629  if (!minimum) {
6630  if (gStyle->GetHistMinimumZero()) {
6631  if (ymin >= 0) ymin = 0;
6632  else ymin -= yMARGIN*(ymax-ymin);
6633  } else {
6634  Double_t dymin = yMARGIN*(ymax-ymin);
6635  if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
6636  else ymin -= dymin;
6637  }
6638  }
6639 
6640  // final adjustment of YMAXI for linear scale (if not option "Same"):
6641  // decrease histogram height to MAX% of allowed height if HMAXIM
6642  // has not been called.
6643  if (!maximum) {
6644  ymax += yMARGIN*(ymax-ymin);
6645  }
6646 
6647  Hparam.ymin = ymin;
6648  Hparam.ymax = ymax;
6649  return 1;
6650 }
6651 
6652 ////////////////////////////////////////////////////////////////////////////////
6653 /// Compute histogram parameters used by the drawing routines for a rotated pad.
6654 
6656 {
6657 
6658  static const char *where = "PaintInitH";
6659  Double_t yMARGIN = gStyle->GetHistTopMargin();
6660  Int_t maximum = 0;
6661  Int_t minimum = 0;
6662  if (fH->GetMaximumStored() != -1111) maximum = 1;
6663  if (fH->GetMinimumStored() != -1111) minimum = 1;
6664 
6665  // Compute X axis parameters
6666 
6667  Int_t last = fXaxis->GetLast();
6668  Int_t first = fXaxis->GetFirst();
6669  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6670  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6671  Hparam.xlast = last;
6672  Hparam.xfirst = first;
6673  Hparam.ymin = Hparam.xlowedge;
6674  Hparam.ymax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6675 
6676  // if log scale in Y, replace ymin,max by the log
6677  if (Hoption.Logy) {
6678  if (Hparam.xlowedge <=0 ) {
6679  Hparam.xlowedge = 0.1*Hparam.xbinsize;
6680  Hparam.ymin = Hparam.xlowedge;
6681  }
6682  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
6683  Error(where, "cannot set Y axis to log scale");
6684  return 0;
6685  }
6686  Hparam.xfirst= fXaxis->FindFixBin(Hparam.ymin);
6687  Hparam.xlast = fXaxis->FindFixBin(Hparam.ymax);
6688  Hparam.ymin = TMath::Log10(Hparam.ymin);
6689  Hparam.ymax = TMath::Log10(Hparam.ymax);
6690  if (Hparam.xlast > last) Hparam.xlast = last;
6691  }
6692 
6693  // Compute Y axis parameters
6694  Double_t bigp = TMath::Power(10,32);
6695  Double_t xmax = -bigp;
6696  Double_t xmin = bigp;
6697  Double_t c1, e1;
6698  Double_t xv[1];
6699  Double_t fval;
6700  Int_t i;
6701  TObject *f;
6702  TF1 *f1;
6703  Double_t allchan = 0;
6704  TIter next(fFunctions);
6705  for (i=first; i<=last;i++) {
6706  c1 = fH->GetBinContent(i);
6707  xmax = TMath::Max(xmax,c1);
6708  xmin = TMath::Min(xmin,c1);
6709  if (Hoption.Error) {
6710  e1 = fH->GetBinError(i);
6711  xmax = TMath::Max(xmax,c1+e1);
6712  xmin = TMath::Min(xmin,c1-e1);
6713  }
6714  if (Hoption.Func) {
6715  xv[0] = fXaxis->GetBinCenter(i);
6716  while ((f = (TObject*) next())) {
6717  if (f->IsA() == TF1::Class()) {
6718  f1 = (TF1*)f;
6719  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6720  fval = f1->Eval(xv[0],0,0);
6721  xmax = TMath::Max(xmax,fval);
6722  if (Hoption.Logy) {
6723  if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
6724  }
6725  }
6726  }
6727  next.Reset();
6728  }
6729  allchan += c1;
6730  }
6731 
6732  // Take into account maximum , minimum
6733 
6734  if (Hoption.Logx && xmin <= 0) {
6735  if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
6736  else xmin = 0.001*xmax;
6737  }
6738  Double_t xm = xmin;
6739  if (maximum) xmax = fH->GetMaximumStored();
6740  if (minimum) xm = fH->GetMinimumStored();
6741  if (Hoption.Logx && xm <= 0) {
6742  Error(where, "log scale requested with zero or negative argument (%f)", xm);
6743  return 0;
6744  }
6745  else xmin = xm;
6746  if (xmin >= xmax) {
6747  if (Hoption.Logx) {
6748  if (xmax > 0) xmin = 0.001*xmax;
6749  else {
6750  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
6751  return 0;
6752  }
6753  }
6754  else {
6755  if (xmin > 0) {
6756  xmin = 0;
6757  xmax *= 2;
6758  } else if (xmin < 0) {
6759  xmax = 0;
6760  xmin *= 2;
6761  } else {
6762  xmin = -1;
6763  xmax = 1;
6764  }
6765  }
6766  }
6767 
6768  // take into account normalization factor
6769  Hparam.allchan = allchan;
6770  Double_t factor = allchan;
6771  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6772  if (allchan) factor /= allchan;
6773  if (factor == 0) factor = 1;
6774  Hparam.factor = factor;
6775  xmax = factor*xmax;
6776  xmin = factor*xmin;
6777 
6778  // For log scales, histogram coordinates are LOG10(ymin) and
6779  // LOG10(ymax). Final adjustment (if not option "Same"
6780  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6781  // Maximum and Minimum are not defined.
6782  if (Hoption.Logx) {
6783  if (xmin <=0 || xmax <=0) {
6784  Error(where, "Cannot set Y axis to log scale");
6785  return 0;
6786  }
6787  xmin = TMath::Log10(xmin);
6788  if (!minimum) xmin += TMath::Log10(0.5);
6789  xmax = TMath::Log10(xmax);
6790  if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
6791  if (!Hoption.Same) {
6792  Hparam.xmin = xmin;
6793  Hparam.xmax = xmax;
6794  }
6795  return 1;
6796  }
6797 
6798  // final adjustment of ymin for linear scale.
6799  // if minimum is not set , then ymin is set to zero if >0
6800  // or to ymin - margin if <0.
6801  if (!minimum) {
6802  if (xmin >= 0) xmin = 0;
6803  else xmin -= yMARGIN*(xmax-xmin);
6804  }
6805 
6806  // final adjustment of YMAXI for linear scale (if not option "Same"):
6807  // decrease histogram height to MAX% of allowed height if HMAXIM
6808  // has not been called.
6809  if (!maximum) {
6810  xmax += yMARGIN*(xmax-xmin);
6811  }
6812  Hparam.xmin = xmin;
6813  Hparam.xmax = xmax;
6814  return 1;
6815 }
6816 
6817 ////////////////////////////////////////////////////////////////////////////////
6818 /// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
6819 
6821 {
6822 
6823  const Double_t ydiff = 1;
6824  const Double_t yligh1 = 10;
6825  const Double_t qa = 0.15;
6826  const Double_t qd = 0.15;
6827  const Double_t qs = 0.8;
6828  Double_t fmin, fmax;
6829  Int_t i, irep;
6830  Int_t nbcol = 28;
6831  Int_t icol1 = 201;
6832  Int_t ic1 = icol1;
6833  Int_t ic2 = ic1+nbcol;
6834  Int_t ic3 = ic2+nbcol;
6835 
6836  TGaxis *axis = new TGaxis();
6837  TAxis *xaxis = fH->GetXaxis();
6838  TAxis *yaxis = fH->GetYaxis();
6839  TAxis *zaxis = fH->GetZaxis();
6840 
6841  Int_t nx = fH->GetNbinsX();
6842  Int_t ny = fH->GetNbinsY();
6843  Int_t nz = fH->GetNbinsZ();
6844 
6845  Double_t *x = new Double_t[nx];
6846  Double_t *y = new Double_t[ny];
6847  Double_t *z = new Double_t[nz];
6848 
6849  for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
6850  for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
6851  for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
6852 
6853  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
6854  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
6855  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
6856  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
6857  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
6858  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
6859 
6860  Double_t s[3];
6861  s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
6862  s[1] = 0.5*s[0];
6863  s[2] = 1.5*s[0];
6864 
6866 
6867  TView *view = gPad->GetView();
6868  if (!view) {
6869  Error("PaintH3Iso", "no TView in current pad");
6870  delete [] x;
6871  delete [] y;
6872  delete [] z;
6873  return;
6874  }
6875  Double_t thedeg = 90 - gPad->GetTheta();
6876  Double_t phideg = -90 - gPad->GetPhi();
6877  Double_t psideg = view->GetPsi();
6878  view->SetView(phideg, thedeg, psideg, irep);
6879 
6880  Int_t backcolor = gPad->GetFrameFillColor();
6881  if (Hoption.System != kCARTESIAN) backcolor = 0;
6882  view->PadRange(backcolor);
6883 
6884  Double_t dcol = 0.5/Double_t(nbcol);
6885  TColor *colref = gROOT->GetColor(fH->GetFillColor());
6886  if (!colref) {
6887  delete [] x;
6888  delete [] y;
6889  delete [] z;
6890  return;
6891  }
6892  Float_t r, g, b, hue, light, satur;
6893  colref->GetRGB(r,g,b);
6894  TColor::RGBtoHLS(r,g,b,hue,light,satur);
6895  TColor *acol;
6896  for (Int_t col=0;col<nbcol;col++) {
6897  acol = gROOT->GetColor(col+icol1);
6898  TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
6899  if (acol) acol->SetRGB(r, g, b);
6900  }
6901 
6902  fLego->InitMoveScreen(-1.1,1.1);
6903 
6904  if (Hoption.BackBox) {
6907  fLego->BackBox(90);
6908  }
6909 
6910  fLego->LightSource(0, ydiff, 0, 0, 0, irep);
6911  fLego->LightSource(1, yligh1, 1, 1, 1, irep);
6912  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
6913  fmin = ydiff*qa;
6914  fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
6915  fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
6916 
6917  fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
6918 
6919  if (Hoption.FrontBox) {
6920  fLego->InitMoveScreen(-1.1,1.1);
6922  fLego->FrontBox(90);
6923  }
6924  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6925 
6926  PaintTitle();
6927 
6928  delete axis;
6929  delete fLego; fLego = 0;
6930  delete [] x;
6931  delete [] y;
6932  delete [] z;
6933 }
6934 
6935 ////////////////////////////////////////////////////////////////////////////////
6936 /// [Control function to draw a 2D histogram as a lego plot.](#HP17)
6937 
6939 {
6940 
6941  Int_t raster = 1;
6942  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
6943  Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
6944  Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
6945  Double_t zmin = Hparam.zmin;
6946  Double_t zmax = Hparam.zmax;
6947  Double_t xlab1 = Hparam.xmin;
6948  Double_t xlab2 = Hparam.xmax;
6949  Double_t ylab1 = Hparam.ymin;
6950  Double_t ylab2 = Hparam.ymax;
6951  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
6952  Double_t deltaz = TMath::Abs(zmin);
6953  if (deltaz == 0) deltaz = 1;
6954  if (zmin >= zmax) {
6955  zmin -= 0.5*deltaz;
6956  zmax += 0.5*deltaz;
6957  }
6958  Double_t z1c = zmin;
6959  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
6960 
6961  // Compute the lego limits and instantiate a lego object
6962  fXbuf[0] = -1;
6963  fYbuf[0] = 1;
6964  fXbuf[1] = -1;
6965  fYbuf[1] = 1;
6966  if (Hoption.System == kPOLAR) {
6967  fXbuf[2] = z1c;
6968  fYbuf[2] = z2c;
6969  } else if (Hoption.System == kCYLINDRICAL) {
6970  if (Hoption.Logy) {
6971  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
6972  else fXbuf[2] = 0;
6973  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
6974  else fYbuf[2] = 0;
6975  } else {
6976  fXbuf[2] = ylab1;
6977  fYbuf[2] = ylab2;
6978  }
6979  z1c = 0; z2c = 1;
6980  } else if (Hoption.System == kSPHERICAL) {
6981  fXbuf[2] = -1;
6982  fYbuf[2] = 1;
6983  z1c = 0; z2c = 1;
6984  } else if (Hoption.System == kRAPIDITY) {
6985  fXbuf[2] = -1/TMath::Tan(dangle);
6986  fYbuf[2] = 1/TMath::Tan(dangle);
6987  } else {
6988  fXbuf[0] = xlab1;
6989  fYbuf[0] = xlab2;
6990  fXbuf[1] = ylab1;
6991  fYbuf[1] = ylab2;
6992  fXbuf[2] = z1c;
6993  fYbuf[2] = z2c;
6994  raster = 0;
6995  }
6996 
6997  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
6998 
6999  Int_t nids = -1;
7000  TH1 * hid = NULL;
7001  Color_t colormain = -1, colordark = -1;
7002  Bool_t drawShadowsInLego1 = kTRUE;
7003 
7004  // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7005  if (Hoption.Lego == 13) {
7006  Hoption.Lego = 11;
7007  fLego->SetMesh(0);
7008  }
7009  // LEGO4 is like LEGO1 except no shadows are drawn.
7010  if (Hoption.Lego == 14) {
7011  Hoption.Lego = 11;
7012  drawShadowsInLego1 = kFALSE;
7013  }
7014 
7015  // Create axis object
7016 
7017  TGaxis *axis = new TGaxis();
7018 
7019  // Initialize the levels on the Z axis
7020  Int_t ndiv = fH->GetContour();
7021  if (ndiv == 0 ) {
7022  ndiv = gStyle->GetNumberContours();
7023  fH->SetContour(ndiv);
7024  }
7025  Int_t ndivz = TMath::Abs(ndiv);
7026  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7027 
7028  // Initialize colors
7029  if (!fStack) {
7031  } else {
7032  for (Int_t id=0;id<=fStack->GetSize();id++) {
7033  hid = (TH1*)fStack->At((id==0)?id:id-1);
7034  fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
7035  }
7036  }
7037 
7038  if (Hoption.Lego == 11) {
7039  nids = 1;
7040  if (fStack) nids = fStack->GetSize();
7041  hid = fH;
7042  for (Int_t id=0;id<=nids;id++) {
7043  if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7044  colormain = hid->GetFillColor();
7045  if (colormain == 1) colormain = 17; //avoid drawing with black
7046  if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7047  else colordark = colormain;
7048  fLego->SetColorMain(colormain,id);
7049  fLego->SetColorDark(colordark,id);
7050  if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7051  if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7052  }
7053  }
7054 
7055  // Now ready to draw the lego plot
7056  Int_t irep = 0;
7057 
7058  TView *view = gPad->GetView();
7059  if (!view) {
7060  Error("PaintLego", "no TView in current pad");
7061  return;
7062  }
7063 
7064  Double_t thedeg = 90 - gPad->GetTheta();
7065  Double_t phideg = -90 - gPad->GetPhi();
7066  Double_t psideg = view->GetPsi();
7067  view->SetView(phideg, thedeg, psideg, irep);
7068 
7069  fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7071 
7072  // Set color/style for back box
7073  fLego->SetFillStyle(gPad->GetFrameFillStyle());
7074  fLego->SetFillColor(gPad->GetFrameFillColor());
7075  fLego->TAttFill::Modify();
7076 
7077  Int_t backcolor = gPad->GetFrameFillColor();
7078  if (Hoption.System != kCARTESIAN) backcolor = 0;
7079  view->PadRange(backcolor);
7080 
7083  fLego->TAttFill::Modify();
7084 
7086 
7087  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7088  else fLego->InitMoveScreen(-1.1,1.1);
7089 
7090  if (Hoption.Lego == 11 || Hoption.Lego == 12) {
7091  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7093  fLego->BackBox(90);
7094  }
7095  }
7096 
7097  if (Hoption.Lego == 12) DefineColorLevels(ndivz);
7098 
7103  if (Hoption.System == kPOLAR) {
7104  if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
7105  if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
7106  if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
7107  } else if (Hoption.System == kCYLINDRICAL) {
7108  if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
7109  if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
7110  if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
7111  } else if (Hoption.System == kSPHERICAL) {
7112  if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
7113  if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
7114  if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
7115  } else if (Hoption.System == kRAPIDITY) {
7116  if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
7117  if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
7118  if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
7119  } else {
7120  if (Hoption.Lego == 1) {
7122  fLego->LegoCartesian(90,nx,ny,"FB");}
7123  if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
7124  if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
7125  }
7126 
7127  if (Hoption.Lego == 1 || Hoption.Lego == 11) {
7128  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7130  fLego->BackBox(90);
7131  }
7132  }
7133  if (Hoption.System == kCARTESIAN) {
7134  fLego->InitMoveScreen(-1.1,1.1);
7136  if (Hoption.FrontBox) fLego->FrontBox(90);
7137  }
7138  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7139  if (Hoption.Zscale) PaintPalette();
7140  delete axis;
7141  delete fLego; fLego = 0;
7142 }
7143 
7144 ////////////////////////////////////////////////////////////////////////////////
7145 /// Draw the axis for legos and surface plots.
7146 
7148 {
7149 
7150  static Double_t epsil = 0.001;
7151 
7152  Double_t cosa, sina;
7153  Double_t bmin, bmax;
7154  Double_t r[24] /* was [3][8] */;
7155  Int_t ndivx, ndivy, ndivz, i;
7156  Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
7157  static char chopax[8], chopay[8], chopaz[8];
7158  Int_t ix1, ix2, iy1, iy2, iz1, iz2;
7159  Double_t rad;
7160 
7161  TView *view = gPad->GetView();
7162  if (!view) {
7163  Error("PaintLegoAxis", "no TView in current pad");
7164  return;
7165  }
7166 
7167  // In polar coordinates, draw a short line going from the external circle
7168  // corresponding to r = 1 up to r = 1.1
7169  if (Hoption.System == kPOLAR) {
7170  r[0] = 1;
7171  r[1] = 0;
7172  r[2] = 0;
7173  view->WCtoNDC(r, x1);
7174  r[0] = 1.1;
7175  r[1] = 0;
7176  r[2] = 0;
7177  view->WCtoNDC(r, x2);
7178  gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
7179  return;
7180  }
7181 
7182  if (Hoption.System != kCARTESIAN) return;
7183 
7184  rad = TMath::ATan(1.) * 4. /180.;
7185  cosa = TMath::Cos(ang*rad);
7186  sina = TMath::Sin(ang*rad);
7187 
7188  view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
7189  for (i = 1; i <= 8; ++i) {
7190  r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
7191  r[i*3 - 2] = av[i*3 - 2]*sina;
7192  r[i*3 - 1] = av[i*3 - 1];
7193  }
7194 
7195  view->WCtoNDC(&r[ix1*3 - 3], x1);
7196  view->WCtoNDC(&r[ix2*3 - 3], x2);
7197  view->WCtoNDC(&r[iy1*3 - 3], y1);
7198  view->WCtoNDC(&r[iy2*3 - 3], y2);
7199  view->WCtoNDC(&r[iz1*3 - 3], z1);
7200  view->WCtoNDC(&r[iz2*3 - 3], z2);
7201 
7202  view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
7203 
7204  Double_t *rmin = view->GetRmin();
7205  Double_t *rmax = view->GetRmax();
7206  if (!rmin || !rmax) return;
7207 
7208  // Initialize the axis options
7209  if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
7210  else strlcpy(chopax, "SDH=-",8);
7211  if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
7212  else strlcpy(chopay, "SDH=-",8);
7213  strlcpy(chopaz, "SDH+=",8);
7214 
7215  // Option LOG is required ?
7216  if (Hoption.Logx) strlcat(chopax,"G",8);
7217  if (Hoption.Logy) strlcat(chopay,"G",8);
7218  if (Hoption.Logz) strlcat(chopaz,"G",8);
7219 
7220  // Initialize the number of divisions. If the
7221  // number of divisions is negative, option 'N' is required.
7222  ndivx = fXaxis->GetNdivisions();
7223  ndivy = fYaxis->GetNdivisions();
7224  ndivz = fZaxis->GetNdivisions();
7225  if (ndivx < 0) {
7226  ndivx = TMath::Abs(ndivx);
7227  strlcat(chopax, "N",8);
7228  }
7229  if (ndivy < 0) {
7230  ndivy = TMath::Abs(ndivy);
7231  strlcat(chopay, "N",8);
7232  }
7233  if (ndivz < 0) {
7234  ndivz = TMath::Abs(ndivz);
7235  strlcat(chopaz, "N",8);
7236  }
7237 
7238  // Set Axis attributes.
7239  // The variable SCALE rescales the VSIZ
7240  // in order to have the same label size for all angles.
7241 
7242  axis->SetLineWidth(1);
7243 
7244  // X axis drawing
7245  if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
7248  if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
7249  bmin = TMath::Power(10, rmin[0]);
7250  bmax = TMath::Power(10, rmax[0]);
7251  } else {
7252  bmin = rmin[0];
7253  bmax = rmax[0];
7254  }
7255  // Option time display is required ?
7256  if (fXaxis->GetTimeDisplay()) {
7257  strlcat(chopax,"t",8);
7258  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
7259  axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
7260  } else {
7262  }
7263  }
7264  axis->SetOption(chopax);
7265  axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
7266  }
7267 
7268  // Y axis drawing
7269  if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
7272 
7273  if (fH->GetDimension() < 2) {
7274  strlcpy(chopay, "V=+UN",8);
7275  ndivy = 0;
7276  }
7277  if (TMath::Abs(y1[0] - y2[0]) < epsil) {
7278  y2[0] = y1[0];
7279  }
7280  if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
7281  bmin = TMath::Power(10, rmin[1]);
7282  bmax = TMath::Power(10, rmax[1]);
7283  } else {
7284  bmin = rmin[1];
7285  bmax = rmax[1];
7286  }
7287  // Option time display is required ?
7288  if (fYaxis->GetTimeDisplay()) {
7289  strlcat(chopay,"t",8);
7290  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
7291  axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
7292  } else {
7294  }
7295  }
7296  axis->SetOption(chopay);
7297  axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
7298  }
7299 
7300  // Z axis drawing
7301  if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
7303  if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
7304  bmin = TMath::Power(10, rmin[2]);
7305  bmax = TMath::Power(10, rmax[2]);
7306  } else {
7307  bmin = rmin[2];
7308  bmax = rmax[2];
7309  }
7310  // Option time display is required ?
7311  if (fZaxis->GetTimeDisplay()) {
7312  strlcat(chopaz,"t",8);
7313  if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
7314  axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
7315  } else {
7317  }
7318  }
7319  axis->SetOption(chopaz);
7320  axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
7321  }
7322 
7323  //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
7324 }
7325 
7326 ////////////////////////////////////////////////////////////////////////////////
7327 /// [Paint the color palette on the right side of the pad.](#HP22)
7328 
7330 {
7331 
7332  TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
7333  TView *view = gPad->GetView();
7334  if (palette) {
7335  if (view) {
7336  if (!palette->TestBit(TPaletteAxis::kHasView)) {
7337  fFunctions->Remove(palette);
7338  delete palette; palette = 0;
7339  }
7340  } else {
7341  if (palette->TestBit(TPaletteAxis::kHasView)) {
7342  fFunctions->Remove(palette);
7343  delete palette; palette = 0;
7344  }
7345  }
7346  // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
7347  if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
7348  }
7349 
7350  if (!palette) {
7351  Double_t xup = gPad->GetUxmax();
7352  Double_t x2 = gPad->PadtoX(gPad->GetX2());
7353  Double_t ymin = gPad->PadtoY(gPad->GetUymin());
7354  Double_t ymax = gPad->PadtoY(gPad->GetUymax());
7355  Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
7356  Double_t xmin = gPad->PadtoX(xup +0.1*xr);
7357  Double_t xmax = gPad->PadtoX(xup + xr);
7358  if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
7359  palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
7360  fFunctions->AddFirst(palette);
7361  palette->Paint();
7362  }
7363 }
7364 
7365 ////////////////////////////////////////////////////////////////////////////////
7366 /// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
7367 
7369 {
7370 
7371  fH->TAttMarker::Modify();
7372 
7373  Int_t k, marker;
7374  Double_t dz, z, xk,xstep, yk, ystep;
7375  Double_t scale = 1;
7376  Bool_t ltest = kFALSE;
7377  Double_t zmax = fH->GetMaximum();
7378  Double_t zmin = fH->GetMinimum();
7379  if (zmin == 0 && zmax == 0) return;
7380  if (zmin == zmax) {
7381  zmax += 0.1*TMath::Abs(zmax);
7382  zmin -= 0.1*TMath::Abs(zmin);
7383  }
7384  Int_t ncells = (Hparam.ylast-Hparam.yfirst)*(Hparam.xlast-Hparam.xfirst);
7385  if (Hoption.Logz) {
7386  if (zmin > 0) zmin = TMath::Log10(zmin);
7387  else zmin = 0;
7388  if (zmax > 0) zmax = TMath::Log10(zmax);
7389  else zmax = 0;
7390  if (zmin == 0 && zmax == 0) return;
7391  dz = zmax - zmin;
7392  scale = 100/dz;
7393  if (ncells > 10000) scale /= 5;
7394  ltest = kTRUE;
7395  } else {
7396  dz = zmax - zmin;
7397  if (dz >= kNMAX || zmax < 1) {
7398  scale = (kNMAX-1)/dz;
7399  if (ncells > 10000) scale /= 5;
7400  ltest = kTRUE;
7401  }
7402  }
7403  if (fH->GetMinimumStored() == -1111) {
7404  Double_t yMARGIN = gStyle->GetHistTopMargin();
7405  if (gStyle->GetHistMinimumZero()) {
7406  if (zmin >= 0) zmin = 0;
7407  else zmin -= yMARGIN*(zmax-zmin);
7408  } else {
7409  Double_t dzmin = yMARGIN*(zmax-zmin);
7410  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
7411  else zmin -= dzmin;
7412  }
7413  }
7414 
7415  TString opt = option;
7416  opt.ToLower();
7417  if (opt.Contains("scat=")) {
7418  char optscat[100];
7419  strlcpy(optscat,opt.Data(),100);
7420  char *oscat = strstr(optscat,"scat=");
7421  char *blank = strstr(oscat," "); if (blank) *blank = 0;
7422  sscanf(oscat+5,"%lg",&scale);
7423  }
7424  // use an independent instance of a random generator
7425  // instead of gRandom to avoid conflicts and
7426  // to get same random numbers when drawing the same histogram
7427  TRandom2 random;
7428  marker=0;
7429  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
7430  yk = fYaxis->GetBinLowEdge(j);
7431  ystep = fYaxis->GetBinWidth(j);
7432  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
7433  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
7434  xk = fXaxis->GetBinLowEdge(i);
7435  xstep = fXaxis->GetBinWidth(i);
7436  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
7437  z = fH->GetBinContent(bin);
7438  if (z < zmin) z = zmin;
7439  if (z > zmax) z = zmax;
7440  if (Hoption.Logz) {
7441  if (z > 0) z = TMath::Log10(z) - zmin;
7442  } else {
7443  z -= zmin;
7444  }
7445  if (z <= 0) continue;
7446  k = Int_t(z*scale);
7447  if (ltest) k++;
7448  if (k > 0) {
7449  for (Int_t loop=0; loop<k; loop++) {
7450  if (k+marker >= kNMAX) {
7451  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7452  marker=0;
7453  }
7454  fXbuf[marker] = (random.Rndm()*xstep) + xk;
7455  fYbuf[marker] = (random.Rndm()*ystep) + yk;
7456  if (Hoption.Logx) {
7457  if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
7458  else break;
7459  }
7460  if (Hoption.Logy) {
7461  if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
7462  else break;
7463  }
7464  if (fXbuf[marker] < gPad->GetUxmin()) break;
7465  if (fYbuf[marker] < gPad->GetUymin()) break;
7466  if (fXbuf[marker] > gPad->GetUxmax()) break;
7467  if (fYbuf[marker] > gPad->GetUymax()) break;
7468  marker++;
7469  }
7470  }
7471  }
7472  }
7473  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7474 
7475  if (Hoption.Zscale) PaintPalette();
7476 }
7477 
7478 ////////////////////////////////////////////////////////////////////////////////
7479 /// Static function to paint special objects like vectors and matrices.
7480 /// This function is called via `gROOT->ProcessLine` to paint these objects
7481 /// without having a direct dependency of the graphics or histogramming
7482 /// system.
7483 
7484 void THistPainter::PaintSpecialObjects(const TObject *obj, Option_t *option)
7485 {
7486 
7487  if (!obj) return;
7488  Bool_t status = TH1::AddDirectoryStatus();
7490 
7491  if (obj->InheritsFrom(TMatrixFBase::Class())) {
7492  // case TMatrixF
7493  TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
7494  R__TMatrixFBase->SetBit(kCanDelete);
7495  R__TMatrixFBase->Draw(option);
7496 
7497  } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
7498  // case TMatrixD
7499  TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
7500  R__TMatrixDBase->SetBit(kCanDelete);
7501  R__TMatrixDBase->Draw(option);
7502 
7503  } else if (obj->InheritsFrom(TVectorF::Class())) {
7504  //case TVectorF
7505  TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
7506  R__TVectorF->SetBit(kCanDelete);
7507  R__TVectorF->Draw(option);
7508 
7509  } else if (obj->InheritsFrom(TVectorD::Class())) {
7510  //case TVectorD
7511  TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
7512  R__TVectorD->SetBit(kCanDelete);
7513  R__TVectorD->Draw(option);
7514  }
7515 
7516  TH1::AddDirectory(status);
7517 }
7518 
7519 ////////////////////////////////////////////////////////////////////////////////
7520 /// [Draw the statistics box for 1D and profile histograms.](#HP07)
7521 
7522 void THistPainter::PaintStat(Int_t dostat, TF1 *fit)
7523 {
7524 
7525  static char t[100];
7526  Int_t dofit;
7527  TPaveStats *stats = 0;
7528  TIter next(fFunctions);
7529  TObject *obj;
7530  while ((obj = next())) {
7531  if (obj->InheritsFrom(TPaveStats::Class())) {
7532  stats = (TPaveStats*)obj;
7533  break;
7534  }
7535  }
7536 
7537  if (stats && dostat) {
7538  dofit = stats->GetOptFit();
7539  dostat = stats->GetOptStat();
7540  } else {
7541  dofit = gStyle->GetOptFit();
7542  }
7543  if (!dofit) fit = 0;
7544  if (dofit == 1) dofit = 111;
7545  if (dostat == 1) dostat = 1111;
7546  Int_t print_name = dostat%10;
7547  Int_t print_entries = (dostat/10)%10;
7548  Int_t print_mean = (dostat/100)%10;
7549  Int_t print_stddev = (dostat/1000)%10;
7550  Int_t print_under = (dostat/10000)%10;
7551  Int_t print_over = (dostat/100000)%10;
7552  Int_t print_integral= (dostat/1000000)%10;
7553  Int_t print_skew = (dostat/10000000)%10;
7554  Int_t print_kurt = (dostat/100000000)%10;
7555  Int_t nlines = print_name + print_entries + print_mean + print_stddev +
7556  print_under + print_over + print_integral +
7557  print_skew + print_kurt;
7558  Int_t print_fval = dofit%10;
7559  Int_t print_ferrors = (dofit/10)%10;
7560  Int_t print_fchi2 = (dofit/100)%10;
7561  Int_t print_fprob = (dofit/1000)%10;
7562  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
7563  if (fit) {
7564  if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
7565  else nlinesf += fit->GetNpar();
7566  }
7567  if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
7568 
7569  // Pavetext with statistics
7570  Bool_t done = kFALSE;
7571  if (!dostat && !fit) {
7572  if (stats) { fFunctions->Remove(stats); delete stats;}
7573  return;
7574  }
7575  Double_t statw = gStyle->GetStatW();
7576  if (fit) statw = 1.8*gStyle->GetStatW();
7577  Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
7578  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7579  stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
7580  }
7581  if (stats) {
7582  stats->Clear();
7583  done = kTRUE;
7584  } else {
7585  stats = new TPaveStats(
7586  gStyle->GetStatX()-statw,
7587  gStyle->GetStatY()-stath,
7588  gStyle->GetStatX(),
7589  gStyle->GetStatY(),"brNDC");
7590 
7591  stats->SetParent(fH);
7592  stats->SetOptFit(dofit);
7593  stats->SetOptStat(dostat);
7594  stats->SetFillColor(gStyle->GetStatColor());
7595  stats->SetFillStyle(gStyle->GetStatStyle());
7597  stats->SetTextFont(gStyle->GetStatFont());
7598  if (gStyle->GetStatFont()%10 > 2)
7599  stats->SetTextSize(gStyle->GetStatFontSize());
7600  stats->SetFitFormat(gStyle->GetFitFormat());
7601  stats->SetStatFormat(gStyle->GetStatFormat());
7602  stats->SetName("stats");
7603 
7605  stats->SetTextAlign(12);
7606  stats->SetBit(kCanDelete);
7607  stats->SetBit(kMustCleanup);
7608  }
7609  if (print_name) stats->AddText(fH->GetName());
7610  if (print_entries) {
7611  if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
7612  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
7613  stats->AddText(t);
7614  }
7615  char textstats[50];
7616  if (print_mean) {
7617  if (print_mean == 1) {
7618  snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
7619  snprintf(t,100,textstats,fH->GetMean(1));
7620  } else {
7621  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
7622  ,"%",stats->GetStatFormat());
7623  snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
7624  }
7625  stats->AddText(t);
7626  if (fH->InheritsFrom(TProfile::Class())) {
7627  if (print_mean == 1) {
7628  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7629  snprintf(t,100,textstats,fH->GetMean(2));
7630  } else {
7631  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7632  ,"%",stats->GetStatFormat());
7633  snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
7634  }
7635  stats->AddText(t);
7636  }
7637  }
7638  if (print_stddev) {
7639  if (print_stddev == 1) {
7640  snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
7641  snprintf(t,100,textstats,fH->GetStdDev(1));
7642  } else {
7643  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
7644  ,"%",stats->GetStatFormat());
7645  snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
7646  }
7647  stats->AddText(t);
7648  if (fH->InheritsFrom(TProfile::Class())) {
7649  if (print_stddev == 1) {
7650  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7651  snprintf(t,100,textstats,fH->GetStdDev(2));
7652  } else {
7653  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7654  ,"%",stats->GetStatFormat());
7655  snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
7656  }
7657  stats->AddText(t);
7658  }
7659  }
7660  if (print_under) {
7661  snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
7662  snprintf(t,100,textstats,fH->GetBinContent(0));
7663  stats->AddText(t);
7664  }
7665  if (print_over) {
7666  snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
7667  snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
7668  stats->AddText(t);
7669  }
7670  if (print_integral) {
7671  if (print_integral == 1) {
7672  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7673  snprintf(t,100,textstats,fH->Integral());
7674  } else {
7675  snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
7676  snprintf(t,100,textstats,fH->Integral("width"));
7677  }
7678  stats->AddText(t);
7679  }
7680  if (print_skew) {
7681  if (print_skew == 1) {
7682  snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
7683  snprintf(t,100,textstats,fH->GetSkewness(1));
7684  } else {
7685  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
7686  ,"%",stats->GetStatFormat());
7687  snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
7688  }
7689  stats->AddText(t);
7690  }
7691  if (print_kurt) {
7692  if (print_kurt == 1) {
7693  snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
7694  snprintf(t,100,textstats,fH->GetKurtosis(1));
7695  } else {
7696  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
7697  ,"%",stats->GetStatFormat());
7698  snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
7699  }
7700  stats->AddText(t);
7701  }
7702 
7703  // Draw Fit parameters
7704  if (fit) {
7705  Int_t ndf = fit->GetNDF();
7706  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
7707  snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
7708  if (print_fchi2) stats->AddText(t);
7709  if (print_fprob) {
7710  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
7711  snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
7712  stats->AddText(t);
7713  }
7714  if (print_fval || print_ferrors) {
7715  Double_t parmin,parmax;
7716  Int_t a;
7717  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7718  fit->GetParLimits(ipar,parmin,parmax);
7719  if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
7720  snprintf(t,100,"%-8s ",fit->GetParName(ipar));
7721  a = strlen(t);
7722  if (a>50) a = 50;
7723  if (print_ferrors) {
7724  snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
7725  GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
7726  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar)
7727  ,(Float_t)fit->GetParError(ipar));
7728  } else {
7729  snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
7730  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar));
7731  }
7732  t[63] = 0;
7733  stats->AddText(t);
7734  }
7735  }
7736  }
7737 
7738  if (!done) fFunctions->Add(stats);
7739  stats->Paint();
7740 }
7741 
7742 ////////////////////////////////////////////////////////////////////////////////
7743 /// [Draw the statistics box for 2D histograms.](#HP07)
7744 
7745 void THistPainter::PaintStat2(Int_t dostat, TF1 *fit)
7746 {
7747 
7748  if (fH->GetDimension() != 2) return;
7749  TH2 *h2 = (TH2*)fH;
7750 
7751  static char t[100];
7752  Int_t dofit;
7753  TPaveStats *stats = 0;
7754  TIter next(fFunctions);
7755  TObject *obj;
7756  while ((obj = next())) {
7757  if (obj->InheritsFrom(TPaveStats::Class())) {
7758  stats = (TPaveStats*)obj;
7759  break;
7760  }
7761  }
7762  if (stats && dostat) {
7763  dofit = stats->GetOptFit();
7764  dostat = stats->GetOptStat();
7765  } else {
7766  dofit = gStyle->GetOptFit();
7767  }
7768  if (dostat == 1) dostat = 1111;
7769  Int_t print_name = dostat%10;
7770  Int_t print_entries = (dostat/10)%10;
7771  Int_t print_mean = (dostat/100)%10;
7772  Int_t print_stddev = (dostat/1000)%10;
7773  Int_t print_under = (dostat/10000)%10;
7774  Int_t print_over = (dostat/100000)%10;
7775  Int_t print_integral= (dostat/1000000)%10;
7776  Int_t print_skew = (dostat/10000000)%10;
7777  Int_t print_kurt = (dostat/100000000)%10;
7778  Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
7779  if (print_under || print_over) nlines += 3;
7780 
7781  // Pavetext with statistics
7782  if (!gStyle->GetOptFit()) fit = 0;
7783  Bool_t done = kFALSE;
7784  if (!dostat && !fit) {
7785  if (stats) { fFunctions->Remove(stats); delete stats;}
7786  return;
7787  }
7788  Double_t statw = gStyle->GetStatW();
7789  if (fit) statw = 1.8*gStyle->GetStatW();
7790  Double_t stath = nlines*gStyle->GetStatFontSize();
7791  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7792  stath = 0.25*nlines*gStyle->GetStatH();
7793  }
7794  if (fit) stath += gStyle->GetStatH();
7795  if (stats) {
7796  stats->Clear();
7797  done = kTRUE;
7798  } else {
7799  stats = new TPaveStats(
7800  gStyle->GetStatX()-statw,
7801  gStyle->GetStatY()-stath,
7802  gStyle->GetStatX(),
7803  gStyle->GetStatY(),"brNDC");
7804 
7805  stats->SetParent(fH);
7806  stats->SetOptFit(dofit);
7807  stats->SetOptStat(dostat);
7808  stats->SetFillColor(gStyle->GetStatColor());
7809  stats->SetFillStyle(gStyle->GetStatStyle());
7811  stats->SetName("stats");
7812 
7814  stats->SetTextAlign(12);
7815  stats->SetTextFont(gStyle->GetStatFont());
7816  if (gStyle->GetStatFont()%10 > 2)
7817  stats->SetTextSize(gStyle->GetStatFontSize());
7818  stats->SetFitFormat(gStyle->GetFitFormat());
7819  stats->SetStatFormat(gStyle->GetStatFormat());
7820  stats->SetBit(kCanDelete);
7821  stats->SetBit(kMustCleanup);
7822  }
7823  if (print_name) stats->AddText(h2->GetName());
7824  if (print_entries) {
7825  if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
7826  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
7827  stats->AddText(t);
7828  }
7829  char textstats[50];
7830  if (print_mean) {
7831  if (print_mean == 1) {
7832  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
7833  snprintf(t,50,textstats,h2->GetMean(1));
7834  stats->AddText(t);
7835  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7836  snprintf(t,100,textstats,h2->GetMean(2));
7837  stats->AddText(t);
7838  } else {
7839  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
7840  ,"%",stats->GetStatFormat());
7841  snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
7842  stats->AddText(t);
7843  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7844  ,"%",stats->GetStatFormat());
7845  snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
7846  stats->AddText(t);
7847  }
7848  }
7849  if (print_stddev) {
7850  if (print_stddev == 1) {
7851  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
7852  snprintf(t,100,textstats,h2->GetStdDev(1));
7853  stats->AddText(t);
7854  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7855  snprintf(t,100,textstats,h2->GetStdDev(2));
7856  stats->AddText(t);
7857  } else {
7858  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
7859  ,"%",stats->GetStatFormat());
7860  snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
7861  stats->AddText(t);
7862  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7863  ,"%",stats->GetStatFormat());
7864  snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
7865  stats->AddText(t);
7866  }
7867  }
7868  if (print_integral) {
7869  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7870  snprintf(t,100,textstats,fH->Integral());
7871  stats->AddText(t);
7872  }
7873  if (print_skew) {
7874  if (print_skew == 1) {
7875  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
7876  snprintf(t,100,textstats,h2->GetSkewness(1));
7877  stats->AddText(t);
7878  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
7879  snprintf(t,100,textstats,h2->GetSkewness(2));
7880  stats->AddText(t);
7881  } else {
7882  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
7883  ,"%",stats->GetStatFormat());
7884  snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
7885  stats->AddText(t);
7886  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
7887  ,"%",stats->GetStatFormat());
7888  snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
7889  stats->AddText(t);
7890  }
7891  }
7892  if (print_kurt) {
7893  if (print_kurt == 1) {
7894  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
7895  snprintf(t,100,textstats,h2->GetKurtosis(1));
7896  stats->AddText(t);
7897  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
7898  snprintf(t,100,textstats,h2->GetKurtosis(2));
7899  stats->AddText(t);
7900  } else {
7901  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
7902  ,"%",stats->GetStatFormat());
7903  snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
7904  stats->AddText(t);
7905  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
7906  ,"%",stats->GetStatFormat());
7907  snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
7908  stats->AddText(t);
7909  }
7910  }
7911  if (print_under || print_over) {
7912  //get 3*3 under/overflows for 2d hist
7913  Double_t unov[9];
7914 
7915  Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
7916  Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
7917  Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
7918  Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
7919  Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
7920  Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
7921 
7922  unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
7923  unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
7924  unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
7925  unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
7926  unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
7927  unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
7928  unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
7929  unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
7930  unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
7931 
7932  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
7933  stats->AddText(t);
7934  if (h2->GetEntries() < 1e7)
7935  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
7936  else
7937  snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
7938  stats->AddText(t);
7939  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
7940  stats->AddText(t);
7941  }
7942 
7943  // Draw Fit parameters
7944  if (fit) {
7945  Int_t ndf = fit->GetNDF();
7946  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
7947  stats->AddText(t);
7948  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7949  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
7950  ,(Float_t)fit->GetParameter(ipar)
7951  ,(Float_t)fit->GetParError(ipar));
7952  t[63] = 0;
7953  stats->AddText(t);
7954  }
7955  }
7956 
7957  if (!done) fFunctions->Add(stats);
7958  stats->Paint();
7959 }
7960 
7961 ////////////////////////////////////////////////////////////////////////////////
7962 /// [Draw the statistics box for 3D histograms.](#HP07)
7963 
7964 void THistPainter::PaintStat3(Int_t dostat, TF1 *fit)
7965 {
7966 
7967  if (fH->GetDimension() != 3) return;
7968  TH3 *h3 = (TH3*)fH;
7969 
7970  static char t[100];
7971  Int_t dofit;
7972  TPaveStats *stats = 0;
7973  TIter next(fFunctions);
7974  TObject *obj;
7975  while ((obj = next())) {
7976  if (obj->InheritsFrom(TPaveStats::Class())) {
7977  stats = (TPaveStats*)obj;
7978  break;
7979  }
7980  }
7981  if (stats && dostat) {
7982  dofit = stats->GetOptFit();
7983  dostat = stats->GetOptStat();
7984  } else {
7985  dofit = gStyle->GetOptFit();
7986  }
7987  if (dostat == 1) dostat = 1111;
7988  Int_t print_name = dostat%10;
7989  Int_t print_entries = (dostat/10)%10;
7990  Int_t print_mean = (dostat/100)%10;
7991  Int_t print_stddev = (dostat/1000)%10;
7992  Int_t print_under = (dostat/10000)%10;
7993  Int_t print_over = (dostat/100000)%10;
7994  Int_t print_integral= (dostat/1000000)%10;
7995  Int_t print_skew = (dostat/10000000)%10;
7996  Int_t print_kurt = (dostat/100000000)%10;
7997  Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
7998  if (print_under || print_over) nlines += 3;
7999 
8000  // Pavetext with statistics
8001  if (!gStyle->GetOptFit()) fit = 0;
8002  Bool_t done = kFALSE;
8003  if (!dostat && !fit) {
8004  if (stats) { fFunctions->Remove(stats); delete stats;}
8005  return;
8006  }
8007  Double_t statw = gStyle->GetStatW();
8008  if (fit) statw = 1.8*gStyle->GetStatW();
8009  Double_t stath = nlines*gStyle->GetStatFontSize();
8010  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8011  stath = 0.25*nlines*gStyle->GetStatH();
8012  }
8013  if (fit) stath += gStyle->GetStatH();
8014  if (stats) {
8015  stats->Clear();
8016  done = kTRUE;
8017  } else {
8018  stats = new TPaveStats(
8019  gStyle->GetStatX()-statw,
8020  gStyle->GetStatY()-stath,
8021  gStyle->GetStatX(),
8022  gStyle->GetStatY(),"brNDC");
8023 
8024  stats->SetParent(fH);
8025  stats->SetOptFit(dofit);
8026  stats->SetOptStat(dostat);
8027  stats->SetFillColor(gStyle->GetStatColor());
8028  stats->SetFillStyle(gStyle->GetStatStyle());
8030  stats->SetName("stats");
8031 
8033  stats->SetTextAlign(12);
8034  stats->SetTextFont(gStyle->GetStatFont());
8035  stats->SetFitFormat(gStyle->GetFitFormat());
8036  stats->SetStatFormat(gStyle->GetStatFormat());
8037  stats->SetBit(kCanDelete);
8038  stats->SetBit(kMustCleanup);
8039  }
8040  if (print_name) stats->AddText(h3->GetName());
8041  if (print_entries) {
8042  if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8043  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8044  stats->AddText(t);
8045  }
8046  char textstats[50];
8047  if (print_mean) {
8048  if (print_mean == 1) {
8049  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8050  snprintf(t,100,textstats,h3->GetMean(1));
8051  stats->AddText(t);
8052  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8053  snprintf(t,100,textstats,h3->GetMean(2));
8054  stats->AddText(t);
8055  snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8056  snprintf(t,100,textstats,h3->GetMean(3));
8057  stats->AddText(t);
8058  } else {
8059  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8060  ,"%",stats->GetStatFormat());
8061  snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
8062  stats->AddText(t);
8063  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8064  ,"%",stats->GetStatFormat());
8065  snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
8066  stats->AddText(t);
8067  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8068  ,"%",stats->GetStatFormat());
8069  snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
8070  stats->AddText(t);
8071  }
8072  }
8073  if (print_stddev) {
8074  if (print_stddev == 1) {
8075  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8076  snprintf(t,100,textstats,h3->GetStdDev(1));
8077  stats->AddText(t);
8078  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8079  snprintf(t,100,textstats,h3->GetStdDev(2));
8080  stats->AddText(t);
8081  snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
8082  snprintf(t,100,textstats,h3->GetStdDev(3));
8083  stats->AddText(t);
8084  } else {
8085  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8086  ,"%",stats->GetStatFormat());
8087  snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
8088  stats->AddText(t);
8089  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8090  ,"%",stats->GetStatFormat());
8091  snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
8092  stats->AddText(t);
8093  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
8094  ,"%",stats->GetStatFormat());
8095  snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
8096  stats->AddText(t);
8097  }
8098  }
8099  if (print_integral) {
8100  snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
8101  stats->AddText(t);
8102  }
8103  if (print_skew) {
8104  if (print_skew == 1) {
8105  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8106  snprintf(t,100,textstats,h3->GetSkewness(1));
8107  stats->AddText(t);
8108  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8109  snprintf(t,100,textstats,h3->GetSkewness(2));
8110  stats->AddText(t);
8111  snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
8112  snprintf(t,100,textstats,h3->GetSkewness(3));
8113  stats->AddText(t);
8114  } else {
8115  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8116  ,"%",stats->GetStatFormat());
8117  snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
8118  stats->AddText(t);
8119  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8120  ,"%",stats->GetStatFormat());
8121  snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
8122  stats->AddText(t);
8123  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
8124  ,"%",stats->GetStatFormat());
8125  snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
8126  stats->AddText(t);
8127  }
8128  }
8129  if (print_kurt) {
8130  if (print_kurt == 1) {
8131  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8132  snprintf(t,100,textstats,h3->GetKurtosis(1));
8133  stats->AddText(t);
8134  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8135  snprintf(t,100,textstats,h3->GetKurtosis(2));
8136  stats->AddText(t);
8137  snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
8138  snprintf(t,100,textstats,h3->GetKurtosis(3));
8139  stats->AddText(t);
8140  } else {
8141  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8142  ,"%",stats->GetStatFormat());
8143  snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
8144  stats->AddText(t);
8145  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8146  ,"%",stats->GetStatFormat());
8147  snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
8148  stats->AddText(t);
8149  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
8150  ,"%",stats->GetStatFormat());
8151  snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
8152  stats->AddText(t);
8153  }
8154  }
8155  if (print_under || print_over) {
8156  // no underflow - overflow printing for a 3D histogram
8157  // one would need a 3D table
8158  }
8159 
8160  // Draw Fit parameters
8161  if (fit) {
8162  Int_t ndf = fit->GetNDF();
8163  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8164  stats->AddText(t);
8165  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8166  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8167  ,(Float_t)fit->GetParameter(ipar)
8168  ,(Float_t)fit->GetParError(ipar));
8169  t[32] = 0;
8170  stats->AddText(t);
8171  }
8172  }
8173 
8174  if (!done) fFunctions->Add(stats);
8175  stats->Paint();
8176 }
8177 
8178 ////////////////////////////////////////////////////////////////////////////////
8179 /// [Control function to draw a 2D histogram as a surface plot.](#HP18)
8180 
8182 {
8183 
8184  const Double_t ydiff = 1;
8185  const Double_t yligh1 = 10;
8186  const Double_t qa = 0.15;
8187  const Double_t qd = 0.15;
8188  const Double_t qs = 0.8;
8189  Double_t fmin, fmax;
8190  Int_t raster = 0;
8191  Int_t irep = 0;
8192 
8193  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8194  Int_t nx = Hparam.xlast - Hparam.xfirst;
8195  Int_t ny = Hparam.ylast - Hparam.yfirst;
8196  Double_t zmin = Hparam.zmin;
8197  Double_t zmax = Hparam.zmax;
8198  Double_t xlab1 = Hparam.xmin;
8199  Double_t xlab2 = Hparam.xmax;
8200  Double_t ylab1 = Hparam.ymin;
8201  Double_t ylab2 = Hparam.ymax;
8202  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
8203  Double_t deltaz = TMath::Abs(zmin);
8204  if (deltaz == 0) deltaz = 1;
8205  if (zmin >= zmax) {
8206  zmin -= 0.5*deltaz;
8207  zmax += 0.5*deltaz;
8208  }
8209  Double_t z1c = zmin;
8210  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
8211  // Compute the lego limits and instantiate a lego object
8212  fXbuf[0] = -1;
8213  fYbuf[0] = 1;
8214  fXbuf[1] = -1;
8215  fYbuf[1] = 1;
8216  if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
8217  if (Hoption.System == kPOLAR) {
8218  fXbuf[2] = z1c;
8219  fYbuf[2] = z2c;
8220  } else if (Hoption.System == kCYLINDRICAL) {
8221  if (Hoption.Logy) {
8222  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
8223  else fXbuf[2] = 0;
8224  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
8225  else fYbuf[2] = 0;
8226  } else {
8227  fXbuf[2] = ylab1;
8228  fYbuf[2] = ylab2;
8229  }
8230  z1c = 0; z2c = 1;
8231  } else if (Hoption.System == kSPHERICAL) {
8232  fXbuf[2] = -1;
8233  fYbuf[2] = 1;
8234  z1c = 0; z2c = 1;
8235  } else if (Hoption.System == kRAPIDITY) {
8236  fXbuf[2] = -1/TMath::Tan(dangle);
8237  fYbuf[2] = 1/TMath::Tan(dangle);
8238  } else {
8239  fXbuf[0] = xlab1;
8240  fYbuf[0] = xlab2;
8241  fXbuf[1] = ylab1;
8242  fYbuf[1] = ylab2;
8243  fXbuf[2] = z1c;
8244  fYbuf[2] = z2c;
8245  }
8246 
8247  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
8250 
8251  // Create axis object
8252 
8253  TGaxis *axis = new TGaxis();
8254 
8255  // Initialize the levels on the Z axis
8256  Int_t ndiv = fH->GetContour();
8257  if (ndiv == 0 ) {
8258  ndiv = gStyle->GetNumberContours();
8259  fH->SetContour(ndiv);
8260  }
8261  Int_t ndivz = TMath::Abs(ndiv);
8262  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8263 
8264  if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
8265  if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
8266 
8267  // Close the surface in case of non cartesian coordinates.
8268 
8269  if (Hoption.System != kCARTESIAN) {nx++; ny++;}
8270 
8271  // Now ready to draw the surface plot
8272 
8273  TView *view = gPad->GetView();
8274  if (!view) {
8275  Error("PaintSurface", "no TView in current pad");
8276  return;
8277  }
8278 
8279  Double_t thedeg = 90 - gPad->GetTheta();
8280  Double_t phideg = -90 - gPad->GetPhi();
8281  Double_t psideg = view->GetPsi();
8282  view->SetView(phideg, thedeg, psideg, irep);
8283 
8284  // Set color/style for back box
8285  if (Hoption.Same) {
8286  fLego->SetFillStyle(0);
8287  fLego->SetFillColor(1);
8288  } else {
8289  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8290  fLego->SetFillColor(gPad->GetFrameFillColor());
8291  }
8292  fLego->TAttFill::Modify();
8293 
8294  Int_t backcolor = gPad->GetFrameFillColor();
8295  if (Hoption.System != kCARTESIAN) backcolor = 0;
8296  view->PadRange(backcolor);
8297 
8300  fLego->TAttFill::Modify();
8301 
8302  // Draw the filled contour on top
8303  Int_t icol1 = fH->GetFillColor();
8304 
8305  Int_t hoption35 = Hoption.Surf;
8306  if (Hoption.Surf == 13 || Hoption.Surf == 15) {
8307  DefineColorLevels(ndivz);
8308  Hoption.Surf = 23;
8311  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8312  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8313  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8314  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8315  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8316  Hoption.Surf = hoption35;
8317  fLego->SetMesh(1);
8318  }
8319 
8320  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8321  else fLego->InitMoveScreen(-1.1,1.1);
8322 
8323  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
8325  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
8327  fLego->BackBox(90);
8328  }
8329  }
8330 
8331  // Gouraud Shading surface
8332  if (Hoption.Surf == 14) {
8333  // Set light sources
8334  fLego->LightSource(0, ydiff, 0,0,0,irep);
8335  fLego->LightSource(1, yligh1 ,1,1,1,irep);
8336  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
8337  fmin = ydiff*qa;
8338  fmax = fmin + (yligh1+0.1)*(qd+qs);
8339  Int_t nbcol = 28;
8340  icol1 = 201;
8341  Double_t dcol = 0.5/Double_t(nbcol);
8342  TColor *colref = gROOT->GetColor(fH->GetFillColor());
8343  if (!colref) return;
8344  Float_t r,g,b,hue,light,satur;
8345  colref->GetRGB(r,g,b);
8346  TColor::RGBtoHLS(r,g,b,hue,light,satur);
8347  TColor *acol;
8348  for (Int_t col=0;col<nbcol;col++) {
8349  acol = gROOT->GetColor(col+icol1);
8350  TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
8351  if (acol) acol->SetRGB(r,g,b);
8352  }
8353  fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
8356  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
8357  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8358  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8359  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8360  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
8361  } else if (Hoption.Surf == 15) {
8362  // The surface is not drawn in this case.
8363  } else {
8364  // Draw the surface
8365  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
8366  DefineColorLevels(ndivz);
8367  } else {
8369  }
8371  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceRaster1);
8372  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode2);
8373  if (Hoption.System == kPOLAR) {
8374  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
8375  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
8376  } else if (Hoption.System == kCYLINDRICAL) {
8377  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
8378  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
8379  } else if (Hoption.System == kSPHERICAL) {
8380  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
8381  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
8382  } else if (Hoption.System == kRAPIDITY) {
8383  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
8384  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
8385  } else {
8386  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1);
8388  if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
8389  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
8390  }
8391  }
8392 
8393  // Paint the line contour on top for option SURF7
8394  if (Hoption.Surf == 17) {
8395  fLego->InitMoveScreen(-1.1,1.1);
8397  Hoption.Surf = 23;
8400  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
8401  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
8402  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
8403  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
8404  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
8405  }
8406 
8407  if ((!Hoption.Same) &&
8408  (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
8409  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
8411  fLego->BackBox(90);
8412  }
8413  }
8414  if (Hoption.System == kCARTESIAN) {
8415  fLego->InitMoveScreen(-1.1,1.1);
8417  if (Hoption.FrontBox) fLego->FrontBox(90);
8418  }
8419  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8420 
8421  if (Hoption.Zscale) PaintPalette();
8422 
8423  delete axis;
8424  delete fLego; fLego = 0;
8425 }
8426 
8427 ////////////////////////////////////////////////////////////////////////////////
8428 /// Control function to draw a table using Delaunay triangles.
8429 
8431 {
8432 
8433  TGraphDelaunay2D *dt = nullptr;
8434  TGraphDelaunay *dtOld = nullptr;
8435 
8436  // Check if fH contains a TGraphDelaunay2D
8437  TList *hl = fH->GetListOfFunctions();
8438  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
8439  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
8440  if (!dt && !dtOld) return;
8441 
8442  // If needed, create a TGraph2DPainter
8443  if (!fGraph2DPainter) {
8444  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
8445  else fGraph2DPainter = new TGraph2DPainter(dtOld);
8446  }
8447 
8448  // Define the 3D view
8449  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8450  if (Hoption.Same) {
8451  TView *viewsame = gPad->GetView();
8452  if (!viewsame) {
8453  Error("PaintTriangles", "no TView in current pad, do not use option SAME");
8454  return;
8455  }
8456  Double_t *rmin = viewsame->GetRmin();
8457  Double_t *rmax = viewsame->GetRmax();
8458  if (!rmin || !rmax) return;
8459  fXbuf[0] = rmin[0];
8460  fYbuf[0] = rmax[0];
8461  fXbuf[1] = rmin[1];
8462  fYbuf[1] = rmax[1];
8463  fXbuf[2] = rmin[2];
8464  fYbuf[2] = rmax[2];
8465  } else {
8466  fXbuf[0] = Hparam.xmin;
8467  fYbuf[0] = Hparam.xmax;
8468  fXbuf[1] = Hparam.ymin;
8469  fYbuf[1] = Hparam.ymax;
8470  fXbuf[2] = Hparam.zmin;
8471  fYbuf[2] = Hparam.zmax;
8472  }
8473 
8474  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8475  TView *view = gPad->GetView();
8476  if (!view) {
8477  Error("PaintTriangles", "no TView in current pad");
8478  return;
8479  }
8480  Double_t thedeg = 90 - gPad->GetTheta();
8481  Double_t phideg = -90 - gPad->GetPhi();
8482  Double_t psideg = view->GetPsi();
8483  Int_t irep;
8484  view->SetView(phideg, thedeg, psideg, irep);
8485 
8486  // Set color/style for back box
8487  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8488  fLego->SetFillColor(gPad->GetFrameFillColor());
8489  fLego->TAttFill::Modify();
8490  Int_t backcolor = gPad->GetFrameFillColor();
8491  if (Hoption.System != kCARTESIAN) backcolor = 0;
8492  view->PadRange(backcolor);
8495  fLego->TAttFill::Modify();
8496 
8497  // Paint the Back Box if needed
8498  if (Hoption.BackBox && !Hoption.Same) {
8499  fLego->InitMoveScreen(-1.1,1.1);
8502  fLego->BackBox(90);
8503  }
8504 
8505  // Paint the triangles
8506  fGraph2DPainter->Paint(option);
8507 
8508  // Paint the Front Box if needed
8509  if (Hoption.FrontBox) {
8510  fLego->InitMoveScreen(-1.1,1.1);
8512  fLego->FrontBox(90);
8513  }
8514 
8515  // Paint the Axis if needed
8516  if (!Hoption.Axis && !Hoption.Same) {
8517  TGaxis *axis = new TGaxis();
8518  PaintLegoAxis(axis, 90);
8519  delete axis;
8520  }
8521 
8522  if (Hoption.Zscale) PaintPalette();
8523 
8524  delete fLego; fLego = 0;
8525 }
8526 
8527 ////////////////////////////////////////////////////////////////////////////////
8528 /// Define the color levels used to paint legos, surfaces etc..
8529 
8531 {
8532 
8533  Int_t i, irep;
8534 
8535  // Initialize the color levels
8536  if (ndivz >= 100) {
8537  Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
8538  ndivz = 8;
8539  }
8540  Double_t *funlevel = new Double_t[ndivz+1];
8541  Int_t *colorlevel = new Int_t[ndivz+1];
8542  Int_t theColor;
8543  Int_t ncolors = gStyle->GetNumberOfColors();
8544  for (i = 0; i < ndivz; ++i) {
8545  funlevel[i] = fH->GetContourLevelPad(i);
8546  theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
8547  colorlevel[i] = gStyle->GetColorPalette(theColor);
8548  }
8549  colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
8550  fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
8551  delete [] colorlevel;
8552  delete [] funlevel;
8553 }
8554 
8555 ////////////////////////////////////////////////////////////////////////////////
8556 /// [Control function to draw 2D/3D histograms (tables).](#HP01c)
8557 
8558 void THistPainter::PaintTable(Option_t *option)
8559 {
8560 
8561  // Fill Hparam structure with histo parameters
8562  if (!TableInit()) return;
8563 
8564  // Draw histogram frame
8565  PaintFrame();
8567  // If palette option not specified, delete a possible existing palette
8568  if (!Hoption.Zscale) {
8569  TObject *palette = fFunctions->FindObject("palette");
8570  if (palette) { fFunctions->Remove(palette); delete palette;}
8571  }
8572 
8573  // Do not draw the histogram. Only the attached functions will be drawn.
8574  if (Hoption.Func == 2) {
8575  if (Hoption.Zscale) {
8576  Int_t ndiv = fH->GetContour();
8577  if (ndiv == 0 ) {
8578  ndiv = gStyle->GetNumberContours();
8579  fH->SetContour(ndiv);
8580  }
8581  PaintPalette();
8582  }
8583 
8584  // Draw the histogram according to the option
8585  } else {
8586  if (fH->InheritsFrom(TH2Poly::Class())) {
8587  if (Hoption.Fill) PaintTH2PolyBins("f");
8588  if (Hoption.Color) PaintTH2PolyColorLevels(option);
8589  if (Hoption.Scat) PaintTH2PolyScatterPlot(option);
8590  if (Hoption.Text) PaintTH2PolyText(option);
8591  if (Hoption.Line) PaintTH2PolyBins("l");
8592  if (Hoption.Mark) PaintTH2PolyBins("P");
8593  } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
8594  if (Hoption.Scat) PaintScatterPlot(option);
8595  if (Hoption.Arrow) PaintArrows(option);
8596  if (Hoption.Box) PaintBoxes(option);
8597  if (Hoption.Color) {
8598  if (Hoption.Color == 3) PaintColorLevelsFast(option);
8599  else PaintColorLevels(option);
8600  }
8601  if (Hoption.Contour) PaintContour(option);
8602  if (Hoption.Text) PaintText(option);
8603  if (Hoption.Error >= 100) Paint2DErrors(option);
8604  if (Hoption.Candle) PaintCandlePlot(option);
8605  if (Hoption.Violin) PaintViolinPlot(option);
8606  }
8607  if (Hoption.Lego) PaintLego(option);
8608  if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
8609  if (Hoption.Tri) PaintTriangles(option);
8610  }
8611 
8612  // Draw histogram title
8613  PaintTitle();
8614 
8615  // Draw the axes
8616  if (!Hoption.Lego && !Hoption.Surf &&
8617  !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
8618 
8619  TF1 *fit = 0;
8620  TIter next(fFunctions);
8621  TObject *obj;
8622  while ((obj = next())) {
8623  if (obj->InheritsFrom(TF1::Class())) {
8624  fit = (TF1*)obj;
8625  break;
8626  }
8627  }
8628  if (Hoption.Same != 1) {
8629  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
8630  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
8631  //ALWAYS executed on non-iOS platform.
8632  //On iOS, depends on mode.
8633  PaintStat2(gStyle->GetOptStat(),fit);
8634  }
8635  }
8636  }
8637 }
8638 
8639 ////////////////////////////////////////////////////////////////////////////////
8640 /// Control function to draw a TH2Poly bins' contours.
8641 ///
8642 /// - option = "F" draw the bins as filled areas.
8643 /// - option = "L" draw the bins as line.
8644 /// - option = "P" draw the bins as markers.
8645 
8647 {
8648 
8649  //Do not highlight the histogram, if its part was picked.
8650  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
8651 
8652  TString opt = option;
8653  opt.ToLower();
8655  Bool_t fill = kFALSE;
8656  Bool_t mark = kFALSE;
8657  if (opt.Contains("l")) line = kTRUE;
8658  if (opt.Contains("f")) fill = kTRUE;
8659  if (opt.Contains("p")) mark = kTRUE;
8660 
8661  TH2PolyBin *b;
8662 
8663  TIter next(((TH2Poly*)fH)->GetBins());
8664  TObject *obj, *poly;
8665 
8666  while ((obj=next())) {
8667  b = (TH2PolyBin*)obj;
8668  poly = b->GetPolygon();
8669 
8670  // Paint the TGraph bins.
8671  if (poly->IsA() == TGraph::Class()) {
8672  TGraph *g = (TGraph*)poly;
8673  g->TAttLine::Modify();
8674  g->TAttMarker::Modify();
8675  g->TAttFill::Modify();
8676  if (line) g->Paint("L");
8677  if (fill) g->Paint("F");
8678  if (mark) g->Paint("P");
8679  }
8680 
8681  // Paint the TMultiGraph bins.
8682  if (poly->IsA() == TMultiGraph::Class()) {
8683  TMultiGraph *mg = (TMultiGraph*)poly;
8684  TList *gl = mg->GetListOfGraphs();
8685  if (!gl) return;
8686  TGraph *g;
8687  TIter nextg(gl);
8688  while ((g = (TGraph*) nextg())) {
8689  g->TAttLine::Modify();
8690  g->TAttMarker::Modify();
8691  g->TAttFill::Modify();
8692  if (line) g->Paint("L");
8693  if (fill) g->Paint("F");
8694  if (mark) g->Paint("P");
8695  }
8696  }
8697  }
8698 }
8699 
8700 ////////////////////////////////////////////////////////////////////////////////
8701 /// [Control function to draw a TH2Poly as a color plot.](#HP20a)
8702 
8704 {
8705 
8706  //Do not highlight the histogram, if its part was picked.
8707  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8708  return;
8709 
8710  Int_t ncolors, color, theColor;
8712  Double_t zmin = fH->GetMinimum();
8713  Double_t zmax = fH->GetMaximum();
8714  if (Hoption.Logz) {
8715  if (zmax > 0) {
8716  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8717  zmin = TMath::Log10(zmin);
8718  zmax = TMath::Log10(zmax);
8719  } else {
8720  return;
8721  }
8722  }
8723  Double_t dz = zmax - zmin;
8724 
8725  // Initialize the levels on the Z axis
8726  ncolors = gStyle->GetNumberOfColors();
8727  Int_t ndiv = fH->GetContour();
8728  if (ndiv == 0 ) {
8729  ndiv = gStyle->GetNumberContours();
8730  fH->SetContour(ndiv);
8731  }
8732  Int_t ndivz = TMath::Abs(ndiv);
8733  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8734  Double_t scale = ndivz/dz;
8735 
8736  TH2PolyBin *b;
8737 
8738  TIter next(((TH2Poly*)fH)->GetBins());
8739  TObject *obj, *poly;
8740 
8741  while ((obj=next())) {
8742  b = (TH2PolyBin*)obj;
8743  poly = b->GetPolygon();
8744 
8745  z = b->GetContent();
8746  if (Hoption.Logz) {
8747  if (z > 0) z = TMath::Log10(z);
8748  else z = zmin;
8749  }
8750  if (z < zmin) continue;
8751 
8752  // Define the bin color.
8753  if (fH->TestBit(TH1::kUserContour)) {
8754  zc = fH->GetContourLevelPad(0);
8755  if (z < zc) continue;
8756  color = -1;
8757  for (Int_t k=0; k<ndiv; k++) {
8758  zc = fH->GetContourLevelPad(k);
8759  if (z < zc) {
8760  continue;
8761  } else {
8762  color++;
8763  }
8764  }
8765  } else {
8766  color = Int_t(0.01+(z-zmin)*scale);
8767  }
8768  theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
8769  if (theColor > ncolors-1) theColor = ncolors-1;
8770 
8771  // Paint the TGraph bins.
8772  if (poly->IsA() == TGraph::Class()) {
8773  TGraph *g = (TGraph*)poly;
8774  g->SetFillColor(gStyle->GetColorPalette(theColor));
8775  g->TAttFill::Modify();
8776  g->Paint("F");
8777  }
8778 
8779  // Paint the TMultiGraph bins.
8780  if (poly->IsA() == TMultiGraph::Class()) {
8781  TMultiGraph *mg = (TMultiGraph*)poly;
8782  TList *gl = mg->GetListOfGraphs();
8783  if (!gl) return;
8784  TGraph *g;
8785  TIter nextg(gl);
8786  while ((g = (TGraph*) nextg())) {
8787  g->SetFillColor(gStyle->GetColorPalette(theColor));
8788  g->TAttFill::Modify();
8789  g->Paint("F");
8790  }
8791  }
8792  }
8793  if (Hoption.Zscale) PaintPalette();
8794 }
8795 
8796 ////////////////////////////////////////////////////////////////////////////////
8797 /// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
8798 
8800 {
8801 
8802  //Do not highlight the histogram, if its part was selected.
8803  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8804  return;
8805 
8806  Int_t k, loop, marker=0;
8807  Double_t z, xk,xstep, yk, ystep, xp, yp;
8808  Double_t scale = 1;
8809  Double_t zmin = fH->GetMinimum();
8810  Double_t zmax = fH->GetMaximum();
8811  if (Hoption.Logz) {
8812  if (zmax > 0) {
8813  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8814  zmin = TMath::Log10(zmin);
8815  zmax = TMath::Log10(zmax);
8816  } else {
8817  return;
8818  }
8819  }
8820  Double_t dz = zmax - zmin;
8821  scale = (kNMAX-1)/dz;
8822 
8823 
8824  // use an independent instance of a random generator
8825  // instead of gRandom to avoid conflicts and
8826  // to get same random numbers when drawing the same histogram
8827  TRandom2 random;
8828 
8829  TH2PolyBin *b;
8830 
8831  TIter next(((TH2Poly*)fH)->GetBins());
8832  TObject *obj, *poly;
8833 
8834  Double_t maxarea = 0, a;
8835  while ((obj=next())) {
8836  b = (TH2PolyBin*)obj;
8837  a = b->GetArea();
8838  if (a>maxarea) maxarea = a;
8839  }
8840 
8841  next.Reset();
8842 
8843  while ((obj=next())) {
8844  b = (TH2PolyBin*)obj;
8845  poly = b->GetPolygon();
8846  z = b->GetContent();
8847  if (z < zmin) z = zmin;
8848  if (z > zmax) z = zmax;
8849  if (Hoption.Logz) {
8850  if (z > 0) z = TMath::Log10(z) - zmin;
8851  } else {
8852  z -= zmin;
8853  }
8854  k = Int_t((z*scale)*(b->GetArea()/maxarea));
8855  xk = b->GetXMin();
8856  yk = b->GetYMin();
8857  xstep = b->GetXMax()-xk;
8858  ystep = b->GetYMax()-yk;
8859 
8860  // Paint the TGraph bins.
8861  if (poly->IsA() == TGraph::Class()) {
8862  TGraph *g = (TGraph*)poly;
8863  if (k <= 0 || z <= 0) continue;
8864  loop = 0;
8865  while (loop<k) {
8866  if (k+marker >= kNMAX) {
8867  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8868  marker=0;
8869  }
8870  xp = (random.Rndm()*xstep) + xk;
8871  yp = (random.Rndm()*ystep) + yk;
8872  if (g->IsInside(xp,yp)) {
8873  fXbuf[marker] = xp;
8874  fYbuf[marker] = yp;
8875  marker++;
8876  loop++;
8877  }
8878  }
8879  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8880  }
8881 
8882  // Paint the TMultiGraph bins.
8883  if (poly->IsA() == TMultiGraph::Class()) {
8884  TMultiGraph *mg = (TMultiGraph*)poly;
8885  TList *gl = mg->GetListOfGraphs();
8886  if (!gl) return;
8887  if (k <= 0 || z <= 0) continue;
8888  loop = 0;
8889  while (loop<k) {
8890  if (k+marker >= kNMAX) {
8891  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8892  marker=0;
8893  }
8894  xp = (random.Rndm()*xstep) + xk;
8895  yp = (random.Rndm()*ystep) + yk;
8896  if (mg->IsInside(xp,yp)) {
8897  fXbuf[marker] = xp;
8898  fYbuf[marker] = yp;
8899  marker++;
8900  loop++;
8901  }
8902  }
8903  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8904  }
8905  }
8906  PaintTH2PolyBins("l");
8907 }
8908 
8909 ////////////////////////////////////////////////////////////////////////////////
8910 /// [Control function to draw a TH2Poly as a text plot.](#HP20a)
8911 
8913 {
8914 
8915  TLatex text;
8916  text.SetTextFont(gStyle->GetTextFont());
8917  text.SetTextColor(fH->GetMarkerColor());
8918  text.SetTextSize(0.02*fH->GetMarkerSize());
8919 
8920  Double_t x, y, z, e, angle = 0;
8921  char value[50];
8922  char format[32];
8923  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8924  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8925  Int_t opt = (Int_t)Hoption.Text/1000;
8926 
8927  text.SetTextAlign(22);
8928  if (Hoption.Text == 1) angle = 0;
8929  text.SetTextAngle(angle);
8930  text.TAttText::Modify();
8931 
8932  TH2PolyBin *b;
8933 
8934  TIter next(((TH2Poly*)fH)->GetBins());
8935  TObject *obj, *p;
8936 
8937  while ((obj=next())) {
8938  b = (TH2PolyBin*)obj;
8939  p = b->GetPolygon();
8940  x = (b->GetXMin()+b->GetXMax())/2;
8941  if (Hoption.Logx) {
8942  if (x > 0) x = TMath::Log10(x);
8943  else continue;
8944  }
8945  y = (b->GetYMin()+b->GetYMax())/2;
8946  if (Hoption.Logy) {
8947  if (y > 0) y = TMath::Log10(y);
8948  else continue;
8949  }
8950  z = b->GetContent();
8951  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
8952  if (opt==2) {
8953  e = fH->GetBinError(b->GetBinNumber());
8954  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
8955  "%",gStyle->GetPaintTextFormat(),
8956  "%",gStyle->GetPaintTextFormat());
8957  snprintf(value,50,format,z,e);
8958  } else {
8959  snprintf(value,50,format,z);
8960  }
8961  if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
8962  else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
8963  }
8964 
8965  PaintTH2PolyBins("l");
8966 }
8967 
8968 ////////////////////////////////////////////////////////////////////////////////
8969 /// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
8970 
8972 {
8973 
8974  TLatex text;
8975  text.SetTextFont(gStyle->GetTextFont());
8976  text.SetTextColor(fH->GetMarkerColor());
8977  text.SetTextSize(0.02*fH->GetMarkerSize());
8978 
8979  Double_t x, y, z, e, angle = 0;
8980  char value[50];
8981  char format[32];
8982  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8983  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8984 
8985  // 1D histograms
8986  if (fH->GetDimension() == 1) {
8987  Bool_t getentries = kFALSE;
8988  Double_t yt;
8989  TProfile *hp = (TProfile*)fH;
8990  if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
8991  Hoption.Text = Hoption.Text-2000;
8992  getentries = kTRUE;
8993  }
8994  if (Hoption.Text == 1) angle = 90;
8995  text.SetTextAlign(11);
8996  if (angle == 90) text.SetTextAlign(12);
8997  if (angle == 0) text.SetTextAlign(21);
8998  text.TAttText::Modify();
8999  Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9000  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9001  if (Hoption.Bar) {
9002  x = fH->GetXaxis()->GetBinLowEdge(i)+
9003  fH->GetXaxis()->GetBinWidth(i)*
9004  (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9005  } else {
9006  x = fH->GetXaxis()->GetBinCenter(i);
9007  }
9008  y = fH->GetBinContent(i);
9009  yt = y;
9010  if (gStyle->GetHistMinimumZero() && y<0) y = 0;
9011  if (getentries) yt = hp->GetBinEntries(i);
9012  if (yt == 0.) continue;
9013  snprintf(value,50,format,yt);
9014  if (Hoption.Logx) {
9015  if (x > 0) x = TMath::Log10(x);
9016  else continue;
9017  }
9018  if (Hoption.Logy) {
9019  if (y > 0) y = TMath::Log10(y);
9020  else continue;
9021  }
9022  if (y >= gPad->GetY2()) continue;
9023  if (y <= gPad->GetY1()) continue;
9024  text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
9025  }
9026 
9027  // 2D histograms
9028  } else {
9029  text.SetTextAlign(22);
9030  if (Hoption.Text == 1) angle = 0;
9031  text.SetTextAngle(angle);
9032  text.TAttText::Modify();
9033  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9034  y = fYaxis->GetBinCenter(j);
9035  if (Hoption.Logy) {
9036  if (y > 0) y = TMath::Log10(y);
9037  else continue;
9038  }
9039  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9040  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9041  x = fXaxis->GetBinCenter(i);
9042  if (Hoption.Logx) {
9043  if (x > 0) x = TMath::Log10(x);
9044  else continue;
9045  }
9046  if (!IsInside(x,y)) continue;
9047  z = fH->GetBinContent(bin);
9048  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9049  if (Hoption.Text>2000) {
9050  e = fH->GetBinError(bin);
9051  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9052  "%",gStyle->GetPaintTextFormat(),
9053  "%",gStyle->GetPaintTextFormat());
9054  snprintf(value,50,format,z,e);
9055  } else {
9056  snprintf(value,50,format,z);
9057  }
9058  text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9059  angle,0.02*fH->GetMarkerSize(),value);
9060  }
9061  }
9062  }
9063 }
9064 
9065 ////////////////////////////////////////////////////////////////////////////////
9066 /// [Control function to draw a 3D implicit functions.](#HP27)
9067 
9069 {
9070 
9071  Int_t irep;
9072 
9073  TGaxis *axis = new TGaxis();
9074  TAxis *xaxis = fH->GetXaxis();
9075  TAxis *yaxis = fH->GetYaxis();
9076  TAxis *zaxis = fH->GetZaxis();
9077 
9078  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
9079  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
9080  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
9081  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
9082  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
9083  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
9084 
9085  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
9086 
9087  TView *view = gPad->GetView();
9088  if (!view) {
9089  Error("PaintTF3", "no TView in current pad");
9090  return;
9091  }
9092  Double_t thedeg = 90 - gPad->GetTheta();
9093  Double_t phideg = -90 - gPad->GetPhi();
9094  Double_t psideg = view->GetPsi();
9095  view->SetView(phideg, thedeg, psideg, irep);
9096 
9097  fLego->InitMoveScreen(-1.1,1.1);
9098 
9099  if (Hoption.BackBox) {
9102  fLego->BackBox(90);
9103  }
9104 
9106 
9107  fLego->ImplicitFunction(fXbuf, fYbuf, fH->GetNbinsX(),
9108  fH->GetNbinsY(),
9109  fH->GetNbinsZ(), "BF");
9110 
9111  if (Hoption.FrontBox) {
9112  fLego->InitMoveScreen(-1.1,1.1);
9114  fLego->FrontBox(90);
9115  }
9116  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9117 
9118  PaintTitle();
9119 
9120  delete axis;
9121  delete fLego; fLego = 0;
9122 }
9123 
9124 ////////////////////////////////////////////////////////////////////////////////
9125 /// Draw the histogram title
9126 ///
9127 /// The title is drawn according to the title alignment returned by
9128 /// `GetTitleAlign()`. It is a 2 digits integer): hv
9129 ///
9130 /// where `h` is the horizontal alignment and `v` is the
9131 /// vertical alignment.
9132 ///
9133 /// - `h` can get the values 1 2 3 for left, center, and right
9134 /// - `v` can get the values 1 2 3 for bottom, middle and top
9135 ///
9136 /// for instance the default alignment is: 13 (left top)
9137 
9139 {
9140 
9141  if (Hoption.Same) return;
9142  if (fH->TestBit(TH1::kNoTitle)) return;
9143  Int_t nt = strlen(fH->GetTitle());
9144  TPaveText *title = 0;
9145  TObject *obj;
9146  TIter next(gPad->GetListOfPrimitives());
9147  while ((obj = next())) {
9148  if (!obj->InheritsFrom(TPaveText::Class())) continue;
9149  title = (TPaveText*)obj;
9150  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
9151  break;
9152  }
9153  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
9154  if (title) delete title;
9155  return;
9156  }
9157  Double_t ht = gStyle->GetTitleH();
9158  Double_t wt = gStyle->GetTitleW();
9159  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
9160  if (ht <= 0) ht = 0.05;
9161  if (wt <= 0) {
9162  TLatex l;
9163  l.SetTextSize(ht);
9164  l.SetTitle(fH->GetTitle());
9165  // adjustment in case the title has several lines (#splitline)
9166  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
9167  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
9168  wt = TMath::Min(0.7, 0.02+wndc);
9169  }
9170  if (title) {
9171  TText *t0 = (TText*)title->GetLine(0);
9172  if (t0) {
9173  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
9174  t0->SetTitle(fH->GetTitle());
9175  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
9176  }
9177  return;
9178  }
9179 
9180  Int_t talh = gStyle->GetTitleAlign()/10;
9181  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
9182  Int_t talv = gStyle->GetTitleAlign()%10;
9183  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
9184  Double_t xpos, ypos;
9185  xpos = gStyle->GetTitleX();
9186  ypos = gStyle->GetTitleY();
9187  if (talh == 2) xpos = xpos-wt/2.;
9188  if (talh == 3) xpos = xpos-wt;
9189  if (talv == 2) ypos = ypos+ht/2.;
9190  if (talv == 1) ypos = ypos+ht;
9191 
9192  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
9193 
9194  // box with the histogram title
9196  ptitle->SetFillStyle(gStyle->GetTitleStyle());
9197  ptitle->SetName("title");
9200  ptitle->SetTextFont(gStyle->GetTitleFont(""));
9201  if (gStyle->GetTitleFont("")%10 > 2)
9202  ptitle->SetTextSize(gStyle->GetTitleFontSize());
9203  ptitle->AddText(fH->GetTitle());
9204  ptitle->SetBit(kCanDelete);
9205  ptitle->Draw();
9206  ptitle->Paint();
9207 
9208  if(!gPad->IsEditable()) delete ptitle;
9209 }
9210 
9211 ////////////////////////////////////////////////////////////////////////////////
9212 /// Process message `mess`.
9213 
9214 void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
9215 {
9216 
9217  if (!strcmp(mess,"SetF3")) {
9219  } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
9221  } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
9222  TVectorD &v = (TVectorD&)(*obj);
9223  Double_t xclip = v(0);
9224  Double_t yclip = v(1);
9225  Double_t zclip = v(2);
9226  TPainter3dAlgorithms::SetF3ClippingBoxOn(xclip,yclip,zclip);
9227  }
9228 }
9229 
9230 ////////////////////////////////////////////////////////////////////////////////
9231 /// Static function.
9232 ///
9233 /// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
9234 /// This procedure can be used to create an all-sky map in Galactic
9235 /// coordinates with an equal-area Aitoff projection. Output map
9236 /// coordinates are zero longitude centered.
9237 /// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
9238 ///
9239 /// source: GMT
9240 ///
9241 /// code from Ernst-Jan Buis
9242 
9244 {
9245 
9246  Double_t x, y;
9247 
9248  Double_t alpha2 = (l/2)*TMath::DegToRad();
9249  Double_t delta = b*TMath::DegToRad();
9250  Double_t r2 = TMath::Sqrt(2.);
9252  Double_t cdec = TMath::Cos(delta);
9253  Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
9254  x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
9255  y = TMath::Sin(delta)*r2/denom;
9256  x *= TMath::RadToDeg()/f;
9257  y *= TMath::RadToDeg()/f;
9258  // x *= -1.; // for a skymap swap left<->right
9259  Al = x;
9260  Ab = y;
9261 
9262  return 0;
9263 }
9264 
9265 ////////////////////////////////////////////////////////////////////////////////
9266 /// Static function
9267 ///
9268 /// Probably the most famous of the various map projections, the Mercator projection
9269 /// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
9270 /// with no distortion along the equator.
9271 /// The Mercator projection has been used extensively for world maps in which the distortion towards
9272 /// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
9273 /// Greenland is larger than South America. In reality, the latter is about eight times the size of
9274 /// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
9275 /// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
9276 /// code from Ernst-Jan Buis
9277 
9279 {
9280 
9281  Al = l;
9283  Ab = TMath::Log(aid);
9284  return 0;
9285 }
9287 ////////////////////////////////////////////////////////////////////////////////
9288 /// Static function code from Ernst-Jan Buis
9289 
9291 {
9292 
9293  Al = l*cos(b*TMath::DegToRad());
9294  Ab = b;
9295  return 0;
9296 }
9297 
9298 ////////////////////////////////////////////////////////////////////////////////
9299 /// Static function code from Ernst-Jan Buis
9300 
9302 {
9303 
9304  Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
9305  Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
9306  return 0;
9307 }
9308 
9309 ////////////////////////////////////////////////////////////////////////////////
9310 /// Recompute the histogram range following graphics operations.
9311 
9313 {
9314 
9315  if (Hoption.Same) return;
9316 
9317  // Compute x,y range
9318  Double_t xmin = Hparam.xmin;
9319  Double_t xmax = Hparam.xmax;
9320  Double_t ymin = Hparam.ymin;
9321  Double_t ymax = Hparam.ymax;
9322 
9323  Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
9324  if (Hoption.Proj ==1) {
9325  // TODO : check x range not lower than -180 and not higher than 180
9326  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9327  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9328  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9329  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9330 
9331  if (xmin > xmin_aid) xmin = xmin_aid;
9332  if (ymin > ymin_aid) ymin = ymin_aid;
9333  if (xmax < xmax_aid) xmax = xmax_aid;
9334  if (ymax < ymax_aid) ymax = ymax_aid;
9335  if (Hparam.ymin<0 && Hparam.ymax>0) {
9336  // there is an 'equator', check its range in the plot..
9337  THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
9338  THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
9339  if (xmin >xmin_aid) xmin = xmin_aid;
9340  if (xmax <xmax_aid) xmax = xmax_aid;
9341  }
9342  if (Hparam.xmin<0 && Hparam.xmax>0) {
9343  THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
9344  THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
9345  if (ymin >ymin_aid) ymin = ymin_aid;
9346  if (ymax <ymax_aid) ymax = ymax_aid;
9347  }
9348  } else if ( Hoption.Proj ==2) {
9349  if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
9350  Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
9351  Hoption.Proj = 0;
9352  } else {
9353  THistPainter::ProjectMercator2xy(Hparam.xmin, Hparam.ymin, xmin, ymin);
9354  THistPainter::ProjectMercator2xy(Hparam.xmax, Hparam.ymax, xmax, ymax);
9355  }
9356  } else if (Hoption.Proj == 3) {
9357  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9358  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9359  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9360  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9361 
9362  if (xmin > xmin_aid) xmin = xmin_aid;
9363  if (ymin > ymin_aid) ymin = ymin_aid;
9364  if (xmax < xmax_aid) xmax = xmax_aid;
9365  if (ymax < ymax_aid) ymax = ymax_aid;
9366  if (Hparam.ymin<0 && Hparam.ymax>0) {
9367  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
9368  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
9369  if (xmin >xmin_aid) xmin = xmin_aid;
9370  if (xmax <xmax_aid) xmax = xmax_aid;
9371  }
9372  if (Hparam.xmin<0 && Hparam.xmax>0) {
9373  THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
9374  THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
9375  if (ymin >ymin_aid) ymin = ymin_aid;
9376  if (ymax <ymax_aid) ymax = ymax_aid;
9377  }
9378  } else if (Hoption.Proj == 4) {
9379  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
9380  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
9381  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
9382  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
9383 
9384  if (xmin > xmin_aid) xmin = xmin_aid;
9385  if (ymin > ymin_aid) ymin = ymin_aid;
9386  if (xmax < xmax_aid) xmax = xmax_aid;
9387  if (ymax < ymax_aid) ymax = ymax_aid;
9388  if (Hparam.ymin<0 && Hparam.ymax>0) {
9389  THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
9390  THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
9391  if (xmin >xmin_aid) xmin = xmin_aid;
9392  if (xmax <xmax_aid) xmax = xmax_aid;
9393  }
9394  if (Hparam.xmin<0 && Hparam.xmax>0) {
9395  THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
9396  THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
9397  if (ymin >ymin_aid) ymin = ymin_aid;
9398  if (ymax <ymax_aid) ymax = ymax_aid;
9399  }
9400  }
9401  Hparam.xmin= xmin;
9402  Hparam.xmax= xmax;
9403  Hparam.ymin= ymin;
9404  Hparam.ymax= ymax;
9405 
9406  Double_t dx = xmax-xmin;
9407  Double_t dy = ymax-ymin;
9408  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
9409  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
9410 
9411  // Range() could change the size of the pad pixmap and therefore should
9412  // be called before the other paint routines
9413  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
9414  ymin - dyr*gPad->GetBottomMargin(),
9415  xmax + dxr*gPad->GetRightMargin(),
9416  ymax + dyr*gPad->GetTopMargin());
9417  gPad->RangeAxis(xmin, ymin, xmax, ymax);
9418 }
9419 
9420 ////////////////////////////////////////////////////////////////////////////////
9421 /// Set current histogram to `h`
9422 
9424 {
9425 
9426  if (h == 0) return;
9427  fH = h;
9428  fXaxis = h->GetXaxis();
9429  fYaxis = h->GetYaxis();
9430  fZaxis = h->GetZaxis();
9432 }
9433 
9434 ////////////////////////////////////////////////////////////////////////////////
9435 /// Initialize various options to draw 2D histograms.
9436 
9438 {
9439 
9440  static const char *where = "TableInit";
9441 
9442  Int_t first, last;
9443  Double_t yMARGIN= gStyle->GetHistTopMargin();
9444  Double_t zmin, zmax;
9445  Int_t maximum = 0;
9446  Int_t minimum = 0;
9447  if (fH->GetMaximumStored() != -1111) maximum = 1;
9448  if (fH->GetMinimumStored() != -1111) minimum = 1;
9449 
9450  // ----------------- Compute X axis parameters
9451  first = fXaxis->GetFirst();
9452  last = fXaxis->GetLast();
9453  Hparam.xlast = last;
9454  Hparam.xfirst = first;
9455  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
9456  Hparam.xbinsize = fXaxis->GetBinWidth(first);
9457  Hparam.xmin = Hparam.xlowedge;
9458  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
9459 
9460  // if log scale in X, replace xmin,max by the log
9461  if (Hoption.Logx) {
9462  // find the first edge of a bin that is > 0
9463  if (Hparam.xlowedge <=0 ) {
9464  Hparam.xlowedge = fXaxis->GetBinUpEdge(fXaxis->FindFixBin(0.01*Hparam.xbinsize));
9465  Hparam.xmin = Hparam.xlowedge;
9466  }
9467  if (Hparam.xmin <=0 || Hparam.xmax <=0) {
9468  Error(where, "cannot set X axis to log scale");
9469  return 0;
9470  }
9471  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
9472  if (Hparam.xfirst < first) Hparam.xfirst = first;
9473  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
9474  if (Hparam.xlast > last) Hparam.xlast = last;
9475  Hparam.xmin = TMath::Log10(Hparam.xmin);
9476  Hparam.xmax = TMath::Log10(Hparam.xmax);
9477  }
9478 
9479  // ----------------- Compute Y axis parameters
9480  first = fYaxis->GetFirst();
9481  last = fYaxis->GetLast();
9482  Hparam.ylast = last;
9483  Hparam.yfirst = first;
9484  Hparam.ylowedge = fYaxis->GetBinLowEdge(first);
9485  Hparam.ybinsize = fYaxis->GetBinWidth(first);
9486  if (!Hparam.ybinsize) Hparam.ybinsize = 1;
9487  Hparam.ymin = Hparam.ylowedge;
9488  Hparam.ymax = fYaxis->GetBinLowEdge(last)+fYaxis->GetBinWidth(last);
9489 
9490  // if log scale in Y, replace ymin,max by the log
9491  if (Hoption.Logy) {
9492  if (Hparam.ylowedge <=0 ) {
9493  Hparam.ylowedge = fYaxis->GetBinUpEdge(fYaxis->FindFixBin(0.01*Hparam.ybinsize));
9494  Hparam.ymin = Hparam.ylowedge;
9495  }
9496  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
9497  Error(where, "cannot set Y axis to log scale");
9498  return 0;
9499  }
9500  Hparam.yfirst= fYaxis->FindFixBin(Hparam.ymin);
9501  if (Hparam.yfirst < first) Hparam.yfirst = first;
9502  Hparam.ylast = fYaxis->FindFixBin(Hparam.ymax);
9503  if (Hparam.ylast > last) Hparam.ylast = last;
9504  Hparam.ymin = TMath::Log10(Hparam.ymin);
9505  Hparam.ymax = TMath::Log10(Hparam.ymax);
9506  }
9507 
9508 
9509  // ----------------- Compute Z axis parameters
9510  Double_t bigp = TMath::Power(10,32);
9511  zmax = -bigp;
9512  zmin = bigp;
9513  Double_t c1, e1;
9514  Double_t allchan = 0;
9515  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9516  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9517  c1 = fH->GetBinContent(i,j);
9518  zmax = TMath::Max(zmax,c1);
9519  if (Hoption.Error) {
9520  e1 = fH->GetBinError(i,j);
9521  zmax = TMath::Max(zmax,c1+e1);
9522  }
9523  zmin = TMath::Min(zmin,c1);
9524  allchan += c1;
9525  }
9526  }
9527 
9528  // Take into account maximum , minimum
9529 
9530  if (maximum) zmax = fH->GetMaximumStored();
9531  if (minimum) zmin = fH->GetMinimumStored();
9532  if (Hoption.Logz && zmax < 0) {
9533  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9534  return 0;
9535  } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
9536  zmin = 0.01;
9537  zmax = 10.;
9538  }
9539  if (zmin >= zmax) {
9540  if (Hoption.Logz) {
9541  if (zmax > 0) zmin = 0.001*zmax;
9542  else {
9543  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9544  return 0;
9545  }
9546  }
9547  }
9548 
9549  // take into account normalization factor
9550  Hparam.allchan = allchan;
9551  Double_t factor = allchan;
9552  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
9553  if (allchan) factor /= allchan;
9554  if (factor == 0) factor = 1;
9555  Hparam.factor = factor;
9556  zmax = factor*zmax;
9557  zmin = factor*zmin;
9558  c1 = zmax;
9559  if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
9560 
9561  // For log scales, histogram coordinates are log10(ymin) and
9562  // log10(ymax). Final adjustment (if not option "Same")
9563  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
9564  // Maximum and Minimum are not defined.
9565  if (Hoption.Logz) {
9566  if (zmin <= 0) {
9567  zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9568  fH->SetMinimum(zmin);
9569  }
9570  zmin = TMath::Log10(zmin);
9571  if (!minimum) zmin += TMath::Log10(0.5);
9572  zmax = TMath::Log10(zmax);
9573  if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
9574  goto LZMIN;
9575  }
9576 
9577  // final adjustment of YMAXI for linear scale (if not option "Same"):
9578  // decrease histogram height to MAX% of allowed height if HMAXIM
9579  // has not been called.
9580  // MAX% is the value in percent which has been set in HPLSET
9581  // (default is 90%).
9582  if (!maximum) {
9583  zmax += yMARGIN*(zmax-zmin);
9584  }
9585 
9586  // final adjustment of ymin for linear scale.
9587  // if minimum is not set , then ymin is set to zero if >0
9588  // or to ymin - yMARGIN if <0.
9589  if (!minimum) {
9590  if (gStyle->GetHistMinimumZero()) {
9591  if (zmin >= 0) zmin = 0;
9592  else zmin -= yMARGIN*(zmax-zmin);
9593  } else {
9594  Double_t dzmin = yMARGIN*(zmax-zmin);
9595  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
9596  else zmin -= dzmin;
9597  }
9598  }
9599 
9600 LZMIN:
9601  Hparam.zmin = zmin;
9602  Hparam.zmax = zmax;
9603 
9604  // Set bar offset and width
9605  Hparam.baroffset = fH->GetBarOffset();
9606  Hparam.barwidth = fH->GetBarWidth();
9607 
9608  return 1;
9609 }
9610 
9611 ////////////////////////////////////////////////////////////////////////////////
9612 /// This function returns the best format to print the error value (e)
9613 /// knowing the parameter value (v) and the format (f) used to print it.
9614 
9615 const char * THistPainter::GetBestFormat(Double_t v, Double_t e, const char *f)
9616 {
9617 
9618  static char ef[20];
9619  char tf[20], tv[64];
9620 
9621  // print v with the format f in tv.
9622  snprintf(tf,20,"%s%s","%",f);
9623  snprintf(tv,64,tf,v);
9624 
9625  // Analyse tv.
9626  TString sv = tv;
9627  int ie = sv.Index("e");
9628  int iE = sv.Index("E");
9629  int id = sv.Index(".");
9630 
9631  // v has been printed with the exponent notation.
9632  // There is 2 cases, the exponent is positive or negative
9633  if (ie >= 0 || iE >= 0) {
9634  if (sv.Index("+") >= 0) {
9635  if (e < 1) {
9636  snprintf(ef,20,"%s.1f","%");
9637  } else {
9638  if (ie >= 0) {
9639  snprintf(ef,20,"%s.%de","%",ie-id-1);
9640  } else {
9641  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9642  }
9643  }
9644  } else {
9645  if (ie >= 0) {
9646  snprintf(ef,20,"%s.%de","%",ie-id-1);
9647  } else {
9648  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9649  }
9650  }
9651 
9652  // There is not '.' in tv. e will be printed with one decimal digit.
9653  } else if (id < 0) {
9654  snprintf(ef,20,"%s.1f","%");
9655 
9656  // There is a '.' in tv and no exponent notation. e's decimal part will
9657  // have the same number of digits as v's one.
9658  } else {
9659  snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
9660  }
9661 
9662  return ef;
9663 }
9664 
9665 ////////////////////////////////////////////////////////////////////////////////
9666 /// Set projection.
9667 
9668 void THistPainter::SetShowProjection(const char *option,Int_t nbins)
9669 {
9670 
9671  if (fShowProjection) return;
9672  TString opt = option;
9673  opt.ToLower();
9674  Int_t projection = 0;
9675  if (opt.Contains("x")) projection = 1;
9676  if (opt.Contains("y")) projection = 2;
9677  if (opt.Contains("z")) projection = 3;
9678  if (opt.Contains("xy")) projection = 4;
9679  if (opt.Contains("yx")) projection = 5;
9680  if (opt.Contains("xz")) projection = 6;
9681  if (opt.Contains("zx")) projection = 7;
9682  if (opt.Contains("yz")) projection = 8;
9683  if (opt.Contains("zy")) projection = 9;
9684  if (projection < 4) fShowOption = option+1;
9685  else fShowOption = option+2;
9686  fShowProjection = projection+100*nbins;
9687  gROOT->MakeDefCanvas();
9688  gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
9689  gPad->SetGrid();
9690 }
9691 
9692 ////////////////////////////////////////////////////////////////////////////////
9693 /// Show projection onto X.
9694 
9695 void THistPainter::ShowProjectionX(Int_t /*px*/, Int_t py)
9696 {
9697 
9698  Int_t nbins = (Int_t)fShowProjection/100;
9699  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9700  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9701 
9702  // Erase old position and draw a line at current position
9703  static int pyold1 = 0;
9704  static int pyold2 = 0;
9705  float uxmin = gPad->GetUxmin();
9706  float uxmax = gPad->GetUxmax();
9707  int pxmin = gPad->XtoAbsPixel(uxmin);
9708  int pxmax = gPad->XtoAbsPixel(uxmax);
9709  Float_t upy = gPad->AbsPixeltoY(py);
9710  Float_t y = gPad->PadtoY(upy);
9711  Int_t biny1 = fH->GetYaxis()->FindBin(y);
9712  Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
9713  Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
9714  Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
9715 
9716  if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
9717  gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
9718  pyold1 = py1;
9719  pyold2 = py2;
9720 
9721  // Create or set the new canvas proj x
9722  TVirtualPad *padsav = gPad;
9723  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9724  (ULong_t)fH, fShowProjection));
9725  if (c) {
9726  c->Clear();
9727  } else {
9728  fShowProjection = 0;
9729  pyold1 = 0;
9730  pyold2 = 0;
9731  return;
9732  }
9733  c->cd();
9734  c->SetLogy(padsav->GetLogz());
9735  c->SetLogx(padsav->GetLogx());
9736 
9737  // Draw slice corresponding to mouse position
9738  TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
9739  TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
9740  if (hp) {
9741  hp->SetFillColor(38);
9742  // apply a patch from Oliver Freyermuth to set the title in the projection
9743  // using the range of the projected Y values
9744  if (biny1 == biny2) {
9745  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9746  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
9747  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9748  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9749  if (fH->GetYaxis()->GetLabels() != NULL) {
9750  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
9751  } else {
9752  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
9753  }
9754  } else {
9755  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9756  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
9757  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9758  // biny1 is used here to get equal precision no matter how large the binrange is,
9759  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9760  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
9761  if (fH->GetYaxis()->GetLabels() != NULL) {
9762  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)));
9763  } else {
9764  hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
9765  }
9766  }
9767  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9768  hp->SetYTitle("Number of Entries");
9769  hp->Draw();
9770  c->Update();
9771  padsav->cd();
9772  }
9773 }
9774 
9775 ////////////////////////////////////////////////////////////////////////////////
9776 /// Show projection onto Y.
9777 
9778 void THistPainter::ShowProjectionY(Int_t px, Int_t /*py*/)
9779 {
9780 
9781  Int_t nbins = (Int_t)fShowProjection/100;
9782  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9783  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9784 
9785  // Erase old position and draw a line at current position
9786  static int pxold1 = 0;
9787  static int pxold2 = 0;
9788  float uymin = gPad->GetUymin();
9789  float uymax = gPad->GetUymax();
9790  int pymin = gPad->YtoAbsPixel(uymin);
9791  int pymax = gPad->YtoAbsPixel(uymax);
9792  Float_t upx = gPad->AbsPixeltoX(px);
9793  Float_t x = gPad->PadtoX(upx);
9794  Int_t binx1 = fH->GetXaxis()->FindBin(x);
9795  Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
9796  Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
9797  Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
9798 
9799  if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
9800  gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
9801  pxold1 = px1;
9802  pxold2 = px2;
9803 
9804  // Create or set the new canvas proj y
9805  TVirtualPad *padsav = gPad;
9806  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9807  (ULong_t)fH, fShowProjection));
9808  if (c) {
9809  c->Clear();
9810  } else {
9811  fShowProjection = 0;
9812  pxold1 = 0;
9813  pxold2 = 0;
9814  return;
9815  }
9816  c->cd();
9817  c->SetLogy(padsav->GetLogz());
9818  c->SetLogx(padsav->GetLogy());
9819 
9820  // Draw slice corresponding to mouse position
9821  TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
9822  TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
9823  if (hp) {
9824  hp->SetFillColor(38);
9825  // apply a patch from Oliver Freyermuth to set the title in the projection
9826  // using the range of the projected X values
9827  if (binx1 == binx2) {
9828  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9829  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
9830  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9831  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9832  if (fH->GetXaxis()->GetLabels() != NULL) {
9833  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
9834  } else {
9835  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
9836  }
9837  } else {
9838  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9839  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
9840  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9841  // binx1 is used here to get equal precision no matter how large the binrange is,
9842  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9843  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
9844  if (fH->GetXaxis()->GetLabels() != NULL) {
9845  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)));
9846  } else {
9847  hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
9848  }
9849  }
9850  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9851  hp->SetYTitle("Number of Entries");
9852  hp->Draw();
9853  c->Update();
9854  padsav->cd();
9855  }
9856 }
9857 
9858 ////////////////////////////////////////////////////////////////////////////////
9859 /// Show projection (specified by `fShowProjection`) of a `TH3`.
9860 /// The drawing option for the projection is in `fShowOption`.
9861 ///
9862 /// First implementation; R.Brun
9863 ///
9864 /// Full implementation: Tim Tran (timtran@jlab.org) April 2006
9865 
9867 {
9868 
9869  Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
9870  if (fH->GetDimension() < 3) {
9871  if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
9872  if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
9873  }
9875  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9876  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9877 
9878  // Erase old position and draw a line at current position
9879  TView *view = gPad->GetView();
9880  if (!view) return;
9881  TH3 *h3 = (TH3*)fH;
9882  TAxis *xaxis = h3->GetXaxis();
9883  TAxis *yaxis = h3->GetYaxis();
9884  TAxis *zaxis = h3->GetZaxis();
9885  Double_t u[3],xx[3];
9886 
9887  static TPoint line1[2];//store end points of a line, initialised 0 by default
9888  static TPoint line2[2];// second line when slice thickness > 1 bin thickness
9889  static TPoint line3[2];
9890  static TPoint line4[2];
9891  static TPoint endface1[5];
9892  static TPoint endface2[5];
9893  static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
9894  static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
9895 
9896  Double_t uxmin = gPad->GetUxmin();
9897  Double_t uxmax = gPad->GetUxmax();
9898  Double_t uymin = gPad->GetUymin();
9899  Double_t uymax = gPad->GetUymax();
9900 
9901  int pxmin = gPad->XtoAbsPixel(uxmin);
9902  int pxmax = gPad->XtoAbsPixel(uxmax);
9903  if (pxmin==pxmax) return;
9904  int pymin = gPad->YtoAbsPixel(uymin);
9905  int pymax = gPad->YtoAbsPixel(uymax);
9906  if (pymin==pymax) return;
9907  Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
9908  Double_t cy = (pymax-pymin)/(uymax-uymin);
9909  TVirtualPad *padsav = gPad;
9910  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9911  (ULong_t)fH, fShowProjection));
9912  if (!c) {
9913  fShowProjection = 0;
9914  return;
9915  }
9916 
9917  switch ((Int_t)fShowProjection%100) {
9918  case 1:
9919  // "x"
9920  {
9921  Int_t firstY = yaxis->GetFirst();
9922  Int_t lastY = yaxis->GetLast();
9923  Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
9924  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9925  yaxis->SetRange(biny,biny2);
9926  Int_t firstZ = zaxis->GetFirst();
9927  Int_t lastZ = zaxis->GetLast();
9928  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
9929  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9930  zaxis->SetRange(binz,binz2);
9931  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9932  if (nbins>1 && line1[0].GetX()) {
9933  gVirtualX->DrawPolyLine(2,line2);
9934  gVirtualX->DrawPolyLine(2,line3);
9935  gVirtualX->DrawPolyLine(2,line4);
9936  gVirtualX->DrawPolyLine(5,endface1);
9937  gVirtualX->DrawPolyLine(5,endface2);
9938  }
9939  xx[0] = xaxis->GetXmin();
9940  xx[2] = zaxis->GetBinCenter(binz);
9941  xx[1] = yaxis->GetBinCenter(biny);
9942  view->WCtoNDC(xx,u);
9943  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9944  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9945  xx[0] = xaxis->GetXmax();
9946  view->WCtoNDC(xx,u);
9947  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9948  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9949  gVirtualX->DrawPolyLine(2,line1);
9950  if (nbins>1) {
9951  xx[0] = xaxis->GetXmin();
9952  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9953  xx[1] = yaxis->GetBinCenter(biny);
9954  view->WCtoNDC(xx,u);
9955  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9956  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9957  xx[0] = xaxis->GetXmax();
9958  view->WCtoNDC(xx,u);
9959  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9960  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9961 
9962  xx[0] = xaxis->GetXmin();
9963  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9964  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9965  view->WCtoNDC(xx,u);
9966  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9967  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9968  xx[0] = xaxis->GetXmax();
9969  view->WCtoNDC(xx,u);
9970  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9971  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9972 
9973  xx[0] = xaxis->GetXmin();
9974  xx[2] = zaxis->GetBinCenter(binz);
9975  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9976  view->WCtoNDC(xx,u);
9977  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9978  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9979  xx[0] = xaxis->GetXmax();
9980  view->WCtoNDC(xx,u);
9981  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9982  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9983 
9984  endface1[0].SetX(line1[0].GetX());
9985  endface1[0].SetY(line1[0].GetY());
9986  endface1[1].SetX(line2[0].GetX());
9987  endface1[1].SetY(line2[0].GetY());
9988  endface1[2].SetX(line3[0].GetX());
9989  endface1[2].SetY(line3[0].GetY());
9990  endface1[3].SetX(line4[0].GetX());
9991  endface1[3].SetY(line4[0].GetY());
9992  endface1[4].SetX(line1[0].GetX());
9993  endface1[4].SetY(line1[0].GetY());
9994 
9995  endface2[0].SetX(line1[1].GetX());
9996  endface2[0].SetY(line1[1].GetY());
9997  endface2[1].SetX(line2[1].GetX());
9998  endface2[1].SetY(line2[1].GetY());
9999  endface2[2].SetX(line3[1].GetX());
10000  endface2[2].SetY(line3[1].GetY());
10001  endface2[3].SetX(line4[1].GetX());
10002  endface2[3].SetY(line4[1].GetY());
10003  endface2[4].SetX(line1[1].GetX());
10004  endface2[4].SetY(line1[1].GetY());
10005 
10006  gVirtualX->DrawPolyLine(2,line2);
10007  gVirtualX->DrawPolyLine(2,line3);
10008  gVirtualX->DrawPolyLine(2,line4);
10009  gVirtualX->DrawPolyLine(5,endface1);
10010  gVirtualX->DrawPolyLine(5,endface2);
10011  }
10012  c->Clear();
10013  c->cd();
10014  TH1 *hp = h3->Project3D("x");
10015  yaxis->SetRange(firstY,lastY);
10016  zaxis->SetRange(firstZ,lastZ);
10017  if (hp) {
10018  hp->SetFillColor(38);
10019  if (nbins == 1)
10020  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10021  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10022  else {
10023  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),
10024  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10025  }
10026  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10027  hp->SetYTitle("Number of Entries");
10028  hp->Draw(fShowOption.Data());
10029  }
10030  }
10031  break;
10032 
10033  case 2:
10034  // "y"
10035  {
10036  Int_t firstX = xaxis->GetFirst();
10037  Int_t lastX = xaxis->GetLast();
10038  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10039  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10040  xaxis->SetRange(binx,binx2);
10041  Int_t firstZ = zaxis->GetFirst();
10042  Int_t lastZ = zaxis->GetLast();
10043  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10044  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10045  zaxis->SetRange(binz,binz2);
10046  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10047  if (nbins>1 && line1[0].GetX()) {
10048  gVirtualX->DrawPolyLine(2,line2);
10049  gVirtualX->DrawPolyLine(2,line3);
10050  gVirtualX->DrawPolyLine(2,line4);
10051  gVirtualX->DrawPolyLine(5,endface1);
10052  gVirtualX->DrawPolyLine(5,endface2);
10053  }
10054  xx[0]=xaxis->GetBinCenter(binx);
10055  xx[2] = zaxis->GetBinCenter(binz);
10056  xx[1] = yaxis->GetXmin();
10057  view->WCtoNDC(xx,u);
10058  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10059  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10060  xx[1] = yaxis->GetXmax();
10061  view->WCtoNDC(xx,u);
10062  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10063  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10064  gVirtualX->DrawPolyLine(2,line1);
10065  if (nbins>1) {
10066  xx[1] = yaxis->GetXmin();
10067  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10068  xx[0] = xaxis->GetBinCenter(binx);
10069  view->WCtoNDC(xx,u);
10070  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10071  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10072  xx[1] = yaxis->GetXmax();
10073  view->WCtoNDC(xx,u);
10074  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10075  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10076 
10077  xx[1] = yaxis->GetXmin();
10078  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10079  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10080  view->WCtoNDC(xx,u);
10081  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10082  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10083  xx[1] = yaxis->GetXmax();
10084  view->WCtoNDC(xx,u);
10085  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10086  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10087 
10088  xx[1] = yaxis->GetXmin();
10089  xx[2] = zaxis->GetBinCenter(binz);
10090  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10091  view->WCtoNDC(xx,u);
10092  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10093  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10094  xx[1] = yaxis->GetXmax();
10095  view->WCtoNDC(xx,u);
10096  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10097  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10098 
10099  endface1[0].SetX(line1[0].GetX());
10100  endface1[0].SetY(line1[0].GetY());
10101  endface1[1].SetX(line2[0].GetX());
10102  endface1[1].SetY(line2[0].GetY());
10103  endface1[2].SetX(line3[0].GetX());
10104  endface1[2].SetY(line3[0].GetY());
10105  endface1[3].SetX(line4[0].GetX());
10106  endface1[3].SetY(line4[0].GetY());
10107  endface1[4].SetX(line1[0].GetX());
10108  endface1[4].SetY(line1[0].GetY());
10109 
10110  endface2[0].SetX(line1[1].GetX());
10111  endface2[0].SetY(line1[1].GetY());
10112  endface2[1].SetX(line2[1].GetX());
10113  endface2[1].SetY(line2[1].GetY());
10114  endface2[2].SetX(line3[1].GetX());
10115  endface2[2].SetY(line3[1].GetY());
10116  endface2[3].SetX(line4[1].GetX());
10117  endface2[3].SetY(line4[1].GetY());
10118  endface2[4].SetX(line1[1].GetX());
10119  endface2[4].SetY(line1[1].GetY());
10120 
10121  gVirtualX->DrawPolyLine(2,line2);
10122  gVirtualX->DrawPolyLine(2,line3);
10123  gVirtualX->DrawPolyLine(2,line4);
10124  gVirtualX->DrawPolyLine(5,endface1);
10125  gVirtualX->DrawPolyLine(5,endface2);
10126  }
10127  c->Clear();
10128  c->cd();
10129  TH1 *hp = h3->Project3D("y");
10130  xaxis->SetRange(firstX,lastX);
10131  zaxis->SetRange(firstZ,lastZ);
10132  if (hp) {
10133  hp->SetFillColor(38);
10134  if (nbins == 1)
10135  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10136  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10137  else
10138  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),
10139  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10140  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10141  hp->SetYTitle("Number of Entries");
10142  hp->Draw(fShowOption.Data());
10143  }
10144  }
10145  break;
10146 
10147  case 3:
10148  // "z"
10149  {
10150  Int_t firstX = xaxis->GetFirst();
10151  Int_t lastX = xaxis->GetLast();
10152  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10153  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10154  xaxis->SetRange(binx,binx2);
10155  Int_t firstY = yaxis->GetFirst();
10156  Int_t lastY = yaxis->GetLast();
10157  Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
10158  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10159  yaxis->SetRange(biny,biny2);
10160  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10161  if (nbins>1 && line1[0].GetX()) {
10162  gVirtualX->DrawPolyLine(2,line2);
10163  gVirtualX->DrawPolyLine(2,line3);
10164  gVirtualX->DrawPolyLine(2,line4);
10165  gVirtualX->DrawPolyLine(5,endface1);
10166  gVirtualX->DrawPolyLine(5,endface2);
10167  }
10168  xx[0] = xaxis->GetBinCenter(binx);
10169  xx[1] = yaxis->GetBinCenter(biny);
10170  xx[2] = zaxis->GetXmin();
10171  view->WCtoNDC(xx,u);
10172  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10173  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10174  xx[2] = zaxis->GetXmax();
10175  view->WCtoNDC(xx,u);
10176  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10177  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10178  gVirtualX->DrawPolyLine(2,line1);
10179  if (nbins>1) {
10180  xx[2] = zaxis->GetXmin();
10181  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10182  xx[0] = xaxis->GetBinCenter(binx);
10183  view->WCtoNDC(xx,u);
10184  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10185  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10186  xx[2] = zaxis->GetXmax();
10187  view->WCtoNDC(xx,u);
10188  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10189  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10190 
10191  xx[2] = zaxis->GetXmin();
10192  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10193  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10194  view->WCtoNDC(xx,u);
10195  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10196  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10197  xx[2] = zaxis->GetXmax();
10198  view->WCtoNDC(xx,u);
10199  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10200  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10201 
10202  xx[2] = zaxis->GetXmin();
10203  xx[1] = yaxis->GetBinCenter(biny);
10204  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10205  view->WCtoNDC(xx,u);
10206  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10207  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10208  xx[2] = zaxis->GetXmax();
10209  view->WCtoNDC(xx,u);
10210  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10211  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10212 
10213  endface1[0].SetX(line1[0].GetX());
10214  endface1[0].SetY(line1[0].GetY());
10215  endface1[1].SetX(line2[0].GetX());
10216  endface1[1].SetY(line2[0].GetY());
10217  endface1[2].SetX(line3[0].GetX());
10218  endface1[2].SetY(line3[0].GetY());
10219  endface1[3].SetX(line4[0].GetX());
10220  endface1[3].SetY(line4[0].GetY());
10221  endface1[4].SetX(line1[0].GetX());
10222  endface1[4].SetY(line1[0].GetY());
10223 
10224  endface2[0].SetX(line1[1].GetX());
10225  endface2[0].SetY(line1[1].GetY());
10226  endface2[1].SetX(line2[1].GetX());
10227  endface2[1].SetY(line2[1].GetY());
10228  endface2[2].SetX(line3[1].GetX());
10229  endface2[2].SetY(line3[1].GetY());
10230  endface2[3].SetX(line4[1].GetX());
10231  endface2[3].SetY(line4[1].GetY());
10232  endface2[4].SetX(line1[1].GetX());
10233  endface2[4].SetY(line1[1].GetY());
10234 
10235  gVirtualX->DrawPolyLine(2,line2);
10236  gVirtualX->DrawPolyLine(2,line3);
10237  gVirtualX->DrawPolyLine(2,line4);
10238  gVirtualX->DrawPolyLine(5,endface1);
10239  gVirtualX->DrawPolyLine(5,endface2);
10240  }
10241  c->Clear();
10242  c->cd();
10243  TH1 *hp = h3->Project3D("z");
10244  xaxis->SetRange(firstX,lastX);
10245  yaxis->SetRange(firstY,lastY);
10246  if (hp) {
10247  hp->SetFillColor(38);
10248  if (nbins == 1)
10249  hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
10250  biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
10251  else
10252  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),
10253  biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
10254  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10255  hp->SetYTitle("Number of Entries");
10256  hp->Draw(fShowOption.Data());
10257  }
10258  }
10259  break;
10260 
10261  case 4:
10262  // "xy"
10263  {
10264  Int_t first = zaxis->GetFirst();
10265  Int_t last = zaxis->GetLast();
10266  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10267  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10268  zaxis->SetRange(binz,binz2);
10269  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10270  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10271  xx[0] = xaxis->GetXmin();
10272  xx[1] = yaxis->GetXmax();
10273  xx[2] = zaxis->GetBinCenter(binz);
10274  view->WCtoNDC(xx,u);
10275  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10276  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10277  rect1[4].SetX(rect1[0].GetX());
10278  rect1[4].SetY(rect1[0].GetY());
10279  xx[0] = xaxis->GetXmax();
10280  view->WCtoNDC(xx,u);
10281  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10282  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10283  xx[1] = yaxis->GetXmin();
10284  view->WCtoNDC(xx,u);
10285  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10286  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10287  xx[0] = xaxis->GetXmin();
10288  view->WCtoNDC(xx,u);
10289  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10290  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10291  gVirtualX->DrawPolyLine(5,rect1);
10292  if (nbins>1) {
10293  xx[0] = xaxis->GetXmin();
10294  xx[1] = yaxis->GetXmax();
10295  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10296  view->WCtoNDC(xx,u);
10297  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10298  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10299  rect2[4].SetX(rect2[0].GetX());
10300  rect2[4].SetY(rect2[0].GetY());
10301  xx[0] = xaxis->GetXmax();
10302  view->WCtoNDC(xx,u);
10303  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10304  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10305  xx[1] = yaxis->GetXmin();
10306  view->WCtoNDC(xx,u);
10307  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10308  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10309  xx[0] = xaxis->GetXmin();
10310  view->WCtoNDC(xx,u);
10311  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10312  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10313  gVirtualX->DrawPolyLine(5,rect2);
10314  }
10315 
10316  c->Clear();
10317  c->cd();
10318  TH2 *hp = (TH2*)h3->Project3D("xy");
10319  zaxis->SetRange(first,last);
10320  if (hp) {
10321  hp->SetFillColor(38);
10322  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
10323  else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
10324  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10325  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10326  hp->SetZTitle("Number of Entries");
10327  hp->Draw(fShowOption.Data());
10328  }
10329  }
10330  break;
10331 
10332  case 5:
10333  // "yx"
10334  {
10335  Int_t first = zaxis->GetFirst();
10336  Int_t last = zaxis->GetLast();
10337  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10338  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10339  zaxis->SetRange(binz,binz2);
10340  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10341  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10342  xx[0] = xaxis->GetXmin();
10343  xx[1] = yaxis->GetXmax();
10344  xx[2] = zaxis->GetBinCenter(binz);
10345  view->WCtoNDC(xx,u);
10346  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10347  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10348  rect1[4].SetX(rect1[0].GetX());
10349  rect1[4].SetY(rect1[0].GetY());
10350  xx[0] = xaxis->GetXmax();
10351  view->WCtoNDC(xx,u);
10352  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10353  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10354  xx[1] = yaxis->GetXmin();
10355  view->WCtoNDC(xx,u);
10356  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10357  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10358  xx[0] = xaxis->GetXmin();
10359  view->WCtoNDC(xx,u);
10360  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10361  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10362  gVirtualX->DrawPolyLine(5,rect1);
10363  if (nbins>1) {
10364  xx[0] = xaxis->GetXmin();
10365  xx[1] = yaxis->GetXmax();
10366  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10367  view->WCtoNDC(xx,u);
10368  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10369  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10370  rect2[4].SetX(rect2[0].GetX());
10371  rect2[4].SetY(rect2[0].GetY());
10372  xx[0] = xaxis->GetXmax();
10373  view->WCtoNDC(xx,u);
10374  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10375  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10376  xx[1] = yaxis->GetXmin();
10377  view->WCtoNDC(xx,u);
10378  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10379  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10380  xx[0] = xaxis->GetXmin();
10381  view->WCtoNDC(xx,u);
10382  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10383  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10384  gVirtualX->DrawPolyLine(5,rect2);
10385  }
10386  c->Clear();
10387  c->cd();
10388  TH2 *hp = (TH2*)h3->Project3D("yx");
10389  zaxis->SetRange(first,last);
10390  if (hp) {
10391  hp->SetFillColor(38);
10392  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
10393  else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
10394  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10395  hp->SetYTitle(fH->GetYaxis()->GetTitle());
10396  hp->SetZTitle("Number of Entries");
10397  hp->Draw(fShowOption.Data());
10398  }
10399  }
10400  break;
10401 
10402  case 6:
10403  // "xz"
10404  {
10405  Int_t first = yaxis->GetFirst();
10406  Int_t last = yaxis->GetLast();
10407  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10408  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10409  yaxis->SetRange(biny,biny2);
10410  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10411  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10412  xx[0] = xaxis->GetXmin();
10413  xx[2] = zaxis->GetXmax();
10414  xx[1] = yaxis->GetBinCenter(biny);
10415  view->WCtoNDC(xx,u);
10416  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10417  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10418  rect1[4].SetX(rect1[0].GetX());
10419  rect1[4].SetY(rect1[0].GetY());
10420  xx[0] = xaxis->GetXmax();
10421  view->WCtoNDC(xx,u);
10422  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10423  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10424  xx[2] = zaxis->GetXmin();
10425  view->WCtoNDC(xx,u);
10426  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10427  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10428  xx[0] = xaxis->GetXmin();
10429  view->WCtoNDC(xx,u);
10430  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10431  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10432  gVirtualX->DrawPolyLine(5,rect1);
10433  if (nbins>1) {
10434  xx[0] = xaxis->GetXmin();
10435  xx[2] = zaxis->GetXmax();
10436  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10437  view->WCtoNDC(xx,u);
10438  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10439  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10440  rect2[4].SetX(rect2[0].GetX());
10441  rect2[4].SetY(rect2[0].GetY());
10442  xx[0] = xaxis->GetXmax();
10443  view->WCtoNDC(xx,u);
10444  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10445  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10446  xx[2] = zaxis->GetXmin();
10447  view->WCtoNDC(xx,u);
10448  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10449  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10450  xx[0] = xaxis->GetXmin();
10451  view->WCtoNDC(xx,u);
10452  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10453  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10454  gVirtualX->DrawPolyLine(5,rect2);
10455  }
10456  c->Clear();
10457  c->cd();
10458  TH2 *hp = (TH2*)h3->Project3D("xz");
10459  yaxis->SetRange(first,last);
10460  if (hp) {
10461  hp->SetFillColor(38);
10462  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10463  else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10464  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10465  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10466  hp->SetZTitle("Number of Entries");
10467  hp->Draw(fShowOption.Data());
10468  }
10469  }
10470  break;
10471 
10472  case 7:
10473  // "zx"
10474  {
10475  Int_t first = yaxis->GetFirst();
10476  Int_t last = yaxis->GetLast();
10477  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10478  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10479  yaxis->SetRange(biny,biny2);
10480  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10481  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10482  xx[0] = xaxis->GetXmin();
10483  xx[2] = zaxis->GetXmax();
10484  xx[1] = yaxis->GetBinCenter(biny);
10485  view->WCtoNDC(xx,u);
10486  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10487  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10488  rect1[4].SetX(rect1[0].GetX());
10489  rect1[4].SetY(rect1[0].GetY());
10490  xx[0] = xaxis->GetXmax();
10491  view->WCtoNDC(xx,u);
10492  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10493  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10494  xx[2] = zaxis->GetXmin();
10495  view->WCtoNDC(xx,u);
10496  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10497  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10498  xx[0] = xaxis->GetXmin();
10499  view->WCtoNDC(xx,u);
10500  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10501  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10502  gVirtualX->DrawPolyLine(5,rect1);
10503  if (nbins>1) {
10504  xx[0] = xaxis->GetXmin();
10505  xx[2] = zaxis->GetXmax();
10506  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10507  view->WCtoNDC(xx,u);
10508  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10509  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10510  rect2[4].SetX(rect2[0].GetX());
10511  rect2[4].SetY(rect2[0].GetY());
10512  xx[0] = xaxis->GetXmax();
10513  view->WCtoNDC(xx,u);
10514  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10515  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10516  xx[2] = zaxis->GetXmin();
10517  view->WCtoNDC(xx,u);
10518  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10519  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10520  xx[0] = xaxis->GetXmin();
10521  view->WCtoNDC(xx,u);
10522  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10523  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10524  gVirtualX->DrawPolyLine(5,rect2);
10525  }
10526  c->Clear();
10527  c->cd();
10528  TH2 *hp = (TH2*)h3->Project3D("zx");
10529  yaxis->SetRange(first,last);
10530  if (hp) {
10531  hp->SetFillColor(38);
10532  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10533  else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10534  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10535  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10536  hp->SetZTitle("Number of Entries");
10537  hp->Draw(fShowOption.Data());
10538  }
10539  }
10540  break;
10541 
10542  case 8:
10543  // "yz"
10544  {
10545  Int_t first = xaxis->GetFirst();
10546  Int_t last = xaxis->GetLast();
10547  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10548  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10549  xaxis->SetRange(binx,binx2);
10550  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10551  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10552  xx[2] = zaxis->GetXmin();
10553  xx[1] = yaxis->GetXmax();
10554  xx[0] = xaxis->GetBinCenter(binx);
10555  view->WCtoNDC(xx,u);
10556  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10557  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10558  rect1[4].SetX(rect1[0].GetX());
10559  rect1[4].SetY(rect1[0].GetY());
10560  xx[2] = zaxis->GetXmax();
10561  view->WCtoNDC(xx,u);
10562  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10563  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10564  xx[1] = yaxis->GetXmin();
10565  view->WCtoNDC(xx,u);
10566  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10567  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10568  xx[2] = zaxis->GetXmin();
10569  view->WCtoNDC(xx,u);
10570  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10571  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10572  gVirtualX->DrawPolyLine(5,rect1);
10573  if (nbins>1) {
10574  xx[2] = zaxis->GetXmin();
10575  xx[1] = yaxis->GetXmax();
10576  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10577  view->WCtoNDC(xx,u);
10578  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10579  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10580  rect2[4].SetX(rect2[0].GetX());
10581  rect2[4].SetY(rect2[0].GetY());
10582  xx[2] = zaxis->GetXmax();
10583  view->WCtoNDC(xx,u);
10584  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10585  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10586  xx[1] = yaxis->GetXmin();
10587  view->WCtoNDC(xx,u);
10588  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10589  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10590  xx[2] = zaxis->GetXmin();
10591  view->WCtoNDC(xx,u);
10592  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10593  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10594  gVirtualX->DrawPolyLine(5,rect2);
10595  }
10596  c->Clear();
10597  c->cd();
10598  TH2 *hp = (TH2*)h3->Project3D("yz");
10599  xaxis->SetRange(first,last);
10600  if (hp) {
10601  hp->SetFillColor(38);
10602  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10603  else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10604  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10605  hp->SetYTitle(fH->GetYaxis()->GetTitle());
10606  hp->SetZTitle("Number of Entries");
10607  hp->Draw(fShowOption.Data());
10608  }
10609  }
10610  break;
10611 
10612  case 9:
10613  // "zy"
10614  {
10615  Int_t first = xaxis->GetFirst();
10616  Int_t last = xaxis->GetLast();
10617  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10618  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10619  xaxis->SetRange(binx,binx2);
10620  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10621  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10622  xx[2] = zaxis->GetXmin();
10623  xx[1] = yaxis->GetXmax();
10624  xx[0] = xaxis->GetBinCenter(binx);
10625  view->WCtoNDC(xx,u);
10626  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10627  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10628  rect1[4].SetX(rect1[0].GetX());
10629  rect1[4].SetY(rect1[0].GetY());
10630  xx[2] = zaxis->GetXmax();
10631  view->WCtoNDC(xx,u);
10632  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10633  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10634  xx[1] = yaxis->GetXmin();
10635  view->WCtoNDC(xx,u);
10636  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10637  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10638  xx[2] = zaxis->GetXmin();
10639  view->WCtoNDC(xx,u);
10640  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10641  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10642  gVirtualX->DrawPolyLine(5,rect1);
10643  if (nbins>1) {
10644  xx[2] = zaxis->GetXmin();
10645  xx[1] = yaxis->GetXmax();
10646  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10647  view->WCtoNDC(xx,u);
10648  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10649  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10650  rect2[4].SetX(rect2[0].GetX());
10651  rect2[4].SetY(rect2[0].GetY());
10652  xx[2] = zaxis->GetXmax();
10653  view->WCtoNDC(xx,u);
10654  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10655  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10656  xx[1] = yaxis->GetXmin();
10657  view->WCtoNDC(xx,u);
10658  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10659  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10660  xx[2] = zaxis->GetXmin();
10661  view->WCtoNDC(xx,u);
10662  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10663  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10664  gVirtualX->DrawPolyLine(5,rect2);
10665  }
10666  c->Clear();
10667  c->cd();
10668  TH2 *hp = (TH2*)h3->Project3D("zy");
10669  xaxis->SetRange(first,last);
10670  if (hp) {
10671  hp->SetFillColor(38);
10672  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10673  else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10674  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10675  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10676  hp->SetZTitle("Number of Entries");
10677  hp->Draw(fShowOption.Data());
10678  }
10679  }
10680  break;
10681 
10682  }
10683  c->Update();
10684  padsav->cd();
10685 }
10686 
const int nx
Definition: kalman.C:16
Double_t * fYbuf
Definition: THistPainter.h:63
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:1948
virtual void SetZTitle(const char *title)
Definition: TH1.h:415
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:798
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual Double_t GetMaximumStored() const
Definition: TH1.h:293
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:49
const Int_t kMAXCONTOUR
static TString gStringKurtosisX
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:49
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:60
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:5936
Color_t GetStatColor() const
Definition: TStyle.h:257
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:7664
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:327
void SetX(SCoord_t x)
Definition: TPoint.h:51
virtual void SetAlpha(Float_t a)
Definition: TColor.h:70
An array of TObjects.
Definition: TObjArray.h:39
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:21
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:76
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
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:537
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:211
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:47
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:41
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:399
Double_t * GetX() const
Definition: TPolyLine.h:62
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 option may contain...
Definition: TH3.cxx:2202
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
Bool_t IsHorizontal()
Definition: TCandle.h:96
const Int_t kMaxCuts
Definition: THistPainter.h:42
int Char
"CHAR" Draw 2D plot with a character set.
Definition: Hoption.h:41
Double_t Log(Double_t x)
Definition: TMath.h:526
Double_t ylowedge
low edge of axis
Definition: Hparam.h:34
Color_t GetTitleTextColor() const
Definition: TStyle.h:272
Double_t GetBinError(Int_t bin) const
Returns the value of error associated to bin number bin.
Definition: TH2Poly.cxx:746
Double_t GetX2() const
Definition: TBox.h:65
Int_t GetNumberContours() const
Definition: TStyle.h:241
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:1939
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:246
float Float_t
Definition: RtypesCore.h:53
static TString gStringSkewnessX
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:45
static TString gStringSkewnessZ
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
return c
const char Option_t
Definition: RtypesCore.h:62
virtual Double_t * GetRmax()=0
virtual Float_t GetBarOffset() const
Definition: TH1.h:260
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:39
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:1613
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:57
Create a Box.
Definition: TBox.h:36
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:29
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition: Hoption.h:47
Double_t GetHistTopMargin() const
Definition: TStyle.h:239
virtual Double_t GetMinimumStored() const
Definition: TH1.h:297
virtual Double_t GetNormFactor() const
Definition: TH1.h:305
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:1848
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:59
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:2332
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7605
R__EXTERN TStyle * gStyle
Definition: TStyle.h:418
virtual void Update()=0
#define mark(osub)
Definition: triangle.c:1206
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
virtual void PaintViolinPlot(Option_t *option)
Control function to draw a 2D histogram as a violin plot
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
#define BIT(n)
Definition: Rtypes.h:120
Double_t DegToRad()
Definition: TMath.h:50
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:302
TH1 * h
Definition: legend2.C:5
Definition: Rtypes.h:60
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:68
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:7100
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4638
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:37
TVectorT.
Definition: TMatrixTBase.h:89
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=0)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition: TH1.cxx:4190
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7124
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:93
See TView3D.
Definition: TView.h:29
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:160
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:2292
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:6791
virtual Int_t GetNbinsZ() const
Definition: TH1.h:303
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:400
#define gROOT
Definition: TROOT.h:364
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:6760
Float_t GetEndErrorSize() const
Definition: TStyle.h:187
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:95
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:2431
Double_t RadToDeg()
Definition: TMath.h:49
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1819
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:137
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:575
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:692
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
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:1089
int Int_t
Definition: RtypesCore.h:41
virtual void SetYTitle(const char *title)
Definition: TH1.h:414
bool Bool_t
Definition: RtypesCore.h:59
Double_t GetY2() const
Definition: TBox.h:67
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:326
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:76
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:44
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:20
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1642
int nbins[3]
void SetHistogram(TH1D *proj)
Definition: TCandle.h:104
An abstract interface to image processing library.
Definition: TImage.h:37
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:46
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:3130
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8262
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:167
Double_t zmin
minimum value along Z
Definition: Hparam.h:39
Float_t GetTitleY() const
Definition: TStyle.h:281
TAxis * fYaxis
Definition: THistPainter.h:56
Double_t ymin
minimum value along y
Definition: Hparam.h:35
Profile Historam.
Definition: TProfile.h:34
const char * Class
Definition: TXMLSetup.cxx:64
virtual void SetX2(Double_t x2)
Definition: TBox.h:76
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:40
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:54
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:67
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:27
const char * GetFitFormat() const
Definition: TStyle.h:201
void SetY(SCoord_t y)
Definition: TPoint.h:52
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:105
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Double_t ymax
maximum value along y
Definition: Hparam.h:36
void SetLog(int x, int y)
Definition: TCandle.h:100
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:41
virtual void SetImage(const Double_t *, UInt_t, UInt_t, TImagePalette *=0)
Definition: TImage.h:124
virtual void PaintColorLevelsFast(Option_t *option)
Rendering scheme for the COL2 and COLZ2 options
double cos(double)
void Reset()
Definition: TCollection.h:161
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:99
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
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:497
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:56
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:37
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:925
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:51
Int_t GetTitleAlign()
Definition: TStyle.h:270
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:40
virtual Int_t GetDimension() const
Definition: TH1.h:287
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:7533
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:1602
virtual Double_t GetPsi()=0
Sequenceable collection abstract base class.
Double_t GetXmin() const
Definition: TAxis.h:139
static const double x2[5]
Double_t GetYsize()
Return size of the formula along Y in pad coordinates.
Definition: TLatex.cxx:2594
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:802
virtual void PaintBoxes(Option_t *option)
Control function to draw a 2D histogram as a box plot
Graphical cut class.
Definition: TCutG.h:22
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:1930
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:809
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:55
Float_t GetTitleFontSize() const
Definition: TStyle.h:274
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.
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:2335
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:66
const char * GetBinTitle(Int_t bin) const
Returns the bin title.
Definition: TH2Poly.cxx:772
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:132
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:392
const Double_t * GetBuffer() const
Definition: TH1.h:243
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
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:25
THashList * GetLabels() const
Definition: TAxis.h:123
Int_t GetOptFit() const
Definition: TStyle.h:244
virtual Int_t GetLogx() const =0
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:38
Double_t Log10(Double_t x)
Definition: TMath.h:529
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2423
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
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:43
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:56
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 TSeqCollection * GetOutline()=0
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2458
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:38
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:186
Base class for several text objects.
Definition: TText.h:33
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:1314
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:43
Float_t GetStatX() const
Definition: TStyle.h:264
TAxis * fZaxis
Definition: THistPainter.h:57
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:280
virtual void Show()
Double_t GetYMin()
Returns the minimum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1422
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:1386
XFontStruct * id
Definition: TGX11.cxx:108
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
Float_t GetBarWidth() const
Definition: TStyle.h:185
Int_t xfirst
first bin number along X
Definition: Hparam.h:45
TH1F * h1
Definition: legend1.C:5
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:735
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2038
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:59
virtual Double_t GetMaximumStored() const
Definition: TF1.h:347
Style_t GetStatStyle() const
Definition: TStyle.h:262
void DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "MOVING SCREEN" algorithm (draw face with level lines) ...
virtual void PaintTH2PolyScatterPlot(Option_t *option)
Control function to draw a TH2Poly as a scatter plot.
const Int_t kSPHERICAL
virtual const char * GetTimeFormat() const
Definition: TAxis.h:133
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:35
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:114
TList * fFunctions
Definition: THistPainter.h:58
short Color_t
Definition: RtypesCore.h:79
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:6865
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:41
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:47
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:2170
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:400
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:733
Definition: TPoint.h:33
A doubly linked list.
Definition: TList.h:47
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:7845
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition: TColor.h:81
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:6852
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:370
TObject * GetPolygon() const
Definition: TH2Poly.h:40
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:277
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:196
Float_t GetErrorX() const
Definition: TStyle.h:188
virtual void SetLogx(Int_t value=1)=0
const char * GetPaintTextFormat() const
Definition: TStyle.h:250
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:46
static TString gStringEntries
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:229
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:1816
Int_t fN
Definition: TArray.h:40
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:251
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:887
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:742
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:61
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 isosurfaces for a scalar function defined on a grid.
void FrontBox(Double_t ang)
Draw forward faces of surrounding box & axes.
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:557
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:36
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition: TPie.cxx:168
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2507
Class to manage histogram axis.
Definition: TAxis.h:36
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:6935
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
Float_t GetTitleH() const
Definition: TStyle.h:283
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2851
Int_t fShowProjection
Definition: THistPainter.h:68
SVector< double, 2 > v
Definition: Dict.h:5
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:33
Style_t GetStatFont() const
Definition: TStyle.h:260
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:42
A 3-Dim function with parameters.
Definition: TF3.h:30
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
Float_t GetStatY() const
Definition: TStyle.h:265
Double_t GetContent() const
Definition: TH2Poly.h:37
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:41
Float_t GetStatW() const
Definition: TStyle.h:266
tomato 2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:255
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:496
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:31
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:675
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
Double_t * GetY() const
Definition: TPolyLine.h:63
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:48
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:8323
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:238
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 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:925
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:390
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
TString fShowOption
Definition: THistPainter.h:69
void SetWidth(const Double_t width)
Definition: TCandle.h:103
virtual void Clear(Option_t *option="")=0
Double_t E()
Definition: TMath.h:54
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:1706
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
The axis painter class.
Definition: TGaxis.h:30
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:45
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7562
TAxis * GetYaxis()
Definition: TH1.h:325
Double_t xlowedge
low edge of axis
Definition: Hparam.h:30
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:311
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:37
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
void SetName(const char *name)
Definition: TCollection.h:116
don&#39;t draw stats box
Definition: TH1.h:172
A 2-Dim function with parameters.
Definition: TF2.h:33
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
virtual Double_t GetXmin() const
Definition: TF1.h:388
tomato 1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:618
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:4540
Definition: graph.py:1
don&#39;t draw the histogram title
Definition: TH1.h:177
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
Int_t ylast
last bin number along Y
Definition: Hparam.h:48
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:57
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:46
virtual Double_t * GetRmin()=0
Linear Algebra Package.
#define gVirtualX
Definition: TVirtualX.h:362
virtual TObjLink * FirstLink() const
Definition: TList.h:101
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 Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition: TCandle.cxx:207
Double_t Cos(Double_t)
Definition: TMath.h:424
Color_t GetTitleFillColor() const
Definition: TStyle.h:271
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:7749
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:86
The histogram painter class.
Definition: THistPainter.h:51
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:39
Double_t Pi()
Definition: TMath.h:44
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:65
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:3117
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition: TPie.cxx:393
virtual void SetY2(Double_t y2)
Definition: TBox.h:78
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:275
Float_t GetTitleW() const
Definition: TStyle.h:282
virtual Int_t GetSumw2N() const
Definition: TH1.h:319
Double_t GetChisquare() const
Definition: TF1.h:336
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:564
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:1196
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:154
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:113
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:8273
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:29
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:27
user specified contour levels
Definition: TH1.h:173
#define ClassImp(name)
Definition: Rtypes.h:279
static TString gStringSkewness
double f(double x)
Double_t GetX1() const
Definition: TBox.h:64
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:62
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8189
double Double_t
Definition: RtypesCore.h:55
Int_t GetOptStat() const
Definition: TStyle.h:245
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:60
The Legos and Surfaces painter class.
TText * text
virtual void ShowProjectionX(Int_t px, Int_t py)
Show projection onto X.
int Candle
"CANDLE" Draw a 2D histogram as candle/box plot.
Definition: Hoption.h:52
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
Double_t * fXbuf
Definition: THistPainter.h:62
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
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:1645
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:389
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:35
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:830
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
The TH1 histogram class.
Definition: TH1.h:80
Int_t xlast
last bin number along X
Definition: Hparam.h:46
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:4053
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:31
Abstract base class used by ROOT graphics editor.
The color creation and management class.
Definition: TColor.h:23
CandleOption
Definition: TCandle.h:34
THist< 2, double, THistStatContent, THistStatUncertainty > TH2D
Definition: THist.hxx:307
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:697
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:259
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:2893
int List
= 1 to generate the TObjArray "contours"
Definition: Hoption.h:58
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:39
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Definition: TProfile2D.h:31
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:48
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 Violin
"VIOLIN" Draw a 2D histogram as violin plot.
Definition: Hoption.h:53
int Off
"][" With H option, the first and last vertical lines are not drawn.
Definition: Hoption.h:32
TAxis * GetZaxis()
Definition: TH1.h:326
TList * fStack
Definition: THistPainter.h:67
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
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:261
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:30
Double_t PiOver2()
Definition: TMath.h:46
virtual Int_t GetNpar() const
Definition: TF1.h:349
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:1652
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual void SetXTitle(const char *title)
Definition: TH1.h:413
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:71
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:59
static TString gStringIntegral
virtual void Add(TObject *obj)
Definition: TList.h:81
Double_t xmin
minimum value along X
Definition: Hparam.h:31
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:359
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:202
Float_t GetStatH() const
Definition: TStyle.h:267
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
1-Dim function class
Definition: TF1.h:149
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:32
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:53
Double_t Sin(Double_t)
Definition: TMath.h:421
static TString gStringKurtosis
Double_t GetArea()
Returns the area of the bin.
Definition: TH2Poly.cxx:1284
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:125
int System
type of coordinate system(1=car,2=pol,3=cyl,4=sph,5=psr)
Definition: Hoption.h:54
#define NULL
Definition: Rtypes.h:82
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:31
#define snprintf
Definition: civetweb.c:822
THist< 1, double, THistStatContent, THistStatUncertainty > TH1D
Definition: THist.hxx:301
#define gPad
Definition: TVirtualPad.h:289
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:49
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8220
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:66
void Add(TObject *obj)
Definition: TObjArray.h:75
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:184
Style_t GetTitleStyle() const
Definition: TStyle.h:273
The TGraphDelaunay painting class.
Double_t allchan
integrated sum of contents
Definition: Hparam.h:42
void ResetBit(UInt_t f)
Definition: TObject.h:156
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:6027
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:36
Definition: first.py:1
virtual Int_t GetNbinsX() const
Definition: TH1.h:301
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:55
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:1794
virtual void Paint(Option_t *option="")
Paint the palette.
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:36
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:52
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:258
static TString gStringStdDev
Int_t GetNbins() const
Definition: TAxis.h:127
static TString gStringSkewnessY
int ncx
Definition: THbookFile.cxx:91
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:416
virtual Int_t GetSize() const
Definition: TCollection.h:95
Histogram parameters structure.
Definition: Hparam.h:28
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
const Bool_t kTRUE
Definition: Rtypes.h:91
Double_t GetXMin()
Returns the minimum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1350
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
TList * GetListOfFunctions() const
Definition: TH1.h:248
The palette painting class.
Definition: TPaletteAxis.h:33
THist< 2, float, THistStatContent, THistStatUncertainty > TH2F
Definition: THist.hxx:308
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:61
static TString gStringMeanY
Int_t Nint(T x)
Definition: TMath.h:480
virtual void PadRange(Int_t rback)=0
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:6814
Double_t GetXmax() const
Definition: TAxis.h:140
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:782
Double_t Tan(Double_t)
Definition: TMath.h:427
virtual Float_t GetBarWidth() const
Definition: TH1.h:261
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:931
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:44
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
const TArrayD * GetXbins() const
Definition: TAxis.h:136
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:69
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:74
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
TAxis * GetXaxis()
Definition: TH1.h:324
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
TAxis * fXaxis
Definition: THistPainter.h:55
if(line.BeginsWith("/*"))
Definition: HLFactory.cxx:443
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:68
const char * GetStatFormat() const
Definition: TStyle.h:263
static TString gStringOverflow
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
virtual Int_t GetNbinsY() const
Definition: TH1.h:302
void SetParent(TObject *obj)
Definition: TPaveStats.h:54
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8173
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:303
Int_t GetOptTitle() const
Definition: TStyle.h:246
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:296
const char * Data() const
Definition: TString.h:349
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:101
Double_t ATan(Double_t)
Definition: TMath.h:451