ROOT  6.06/09
Reference Guide
THistPainter.cxx
Go to the documentation of this file.
1 // @(#)root/histpainter:$Id$
2 // Author: Rene Brun 26/08/99
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 
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /*! \class THistPainter
69 \ingroup Hist
70 \brief The histogram painter class. Implements all histograms' drawing's options.
71 
72 - [Introduction](#HP00)
73 - [Histograms' plotting options](#HP01)
74  - [Options supported for 1D and 2D histograms](#HP01a)
75  - [Options supported for 1D histograms](#HP01b)
76  - [Options supported for 2D histograms](#HP01c)
77  - [Options supported for 3D histograms](#HP01d)
78  - [Options supported for histograms' stacks (THStack)](#HP01e)
79 - [Setting the Style](#HP02)
80 - [Setting line, fill, marker, and text attributes](#HP03)
81 - [Setting Tick marks on the histogram axis](#HP04)
82 - [Giving titles to the X, Y and Z axis](#HP05)
83 - [The option "SAME"](#HP060)
84  - [Limitations](#HP060a)
85 - [Superimposing two histograms with different scales in the same pad](#HP06)
86 - [Statistics Display](#HP07)
87 - [Fit Statistics](#HP08)
88 - [The error bars options](#HP09)
89 - [The bar chart option](#HP100)
90 - [The "BAR" and "HBAR" options](#HP10)
91 - [The SCATter plot option (default for 2D histograms)](#HP11)
92 - [The ARRow option](#HP12)
93 - [The BOX option](#HP13)
94 - [The COLor option](#HP14)
95 - [The CANDLE option](#HP140)
96 - [The VIOLIN option](#HP141)
97 - [The TEXT and TEXTnn Option](#HP15)
98 - [The CONTour options](#HP16)
99  - [The LIST option](#HP16a)
100 - [The LEGO options](#HP17)
101 - [The "SURFace" options](#HP18)
102 - [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
103 - [Base line for bar-charts and lego plots](#HP20)
104 - [TH2Poly Drawing](#HP20a)
105 - [The SPEC option](#HP21)
106 - [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
107 - [Setting the color palette](#HP23)
108 - [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
109 - [Drawing options for 3D histograms](#HP25)
110 - [Drawing option for histograms' stacks](#HP26)
111 - [Drawing of 3D implicit functions](#HP27)
112 - [Associated functions drawing](#HP28)
113 - [Drawing using OpenGL](#HP29)
114  - [General information: plot types and supported options](#HP29a)
115  - [TH3 as color boxes](#HP290)
116  - [TH3 as boxes (spheres)](#HP29b)
117  - [TH3 as iso-surface(s)](#HP29c)
118  - [TF3 (implicit function)](#HP29d)
119  - [Parametric surfaces](#HP29e)
120  - [Interaction with the plots](#HP29f)
121  - [Selectable parts](#HP29g)
122  - [Rotation and zooming](#HP29h)
123  - [Panning](#HP29i)
124  - [Box cut](#HP29j)
125  - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
126  - [Surface with option "GLSURF"](#HP29l)
127  - [TF3](#HP29m)
128  - [Box](#HP29n)
129  - [Iso](#HP29o)
130  - [Parametric plot](#HP29p)
131 
132 
133 ## <a name="HP00"></a> Introduction
134 
135 
136 Histograms are drawn via the `THistPainter` class. Each histogram has a
137 pointer to its own painter (to be usable in a multithreaded program). When the
138 canvas has to be redrawn, the `Paint` function of each objects in the
139 pad is called. In case of histograms, `TH1::Paint` invokes directly
140 `THistPainter::Paint`.
141 
142 To draw a histogram `h` is enough to do:
143 
144  h->Draw();
145 
146 `h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
147 be drawn, the `Draw()` method can be invoked with an option. For instance
148 to draw a 2D histogram as a lego plot it is enough to do:
149 
150  h->Draw("lego");
151 
152 `THistPainter` offers many options to paint 1D, 2D and 3D histograms.
153 
154 When the `Draw()` method of a histogram is called for the first time
155 (`TH1::Draw`), it creates a `THistPainter` object and saves a
156 pointer to this "painter" as a data member of the histogram. The
157 `THistPainter` class specializes in the drawing of histograms. It is
158 separated from the histogram so that one can have histograms without the
159 graphics overhead, for example in a batch program. Each histogram have its own
160 painter rather than a central singleton painter painting all histograms, allows
161 two histograms to be drawn in two threads without overwriting the painter's
162 values.
163 
164 When a displayed histogram is filled again, there is not need to call the
165 `Draw()` method again; the image will be refreshed the next time the
166 pad will be updated.
167 
168 A pad is updated after one of these three actions:
169 
170 1. a carriage control on the ROOT command line,
171 2. a click inside the pad,
172 3. a call to `TPad::Update`.
173 
174 
175 By default a call to `TH1::Draw()` clears the pad of all objects
176 before drawing the new image of the histogram. One can use the `SAME`
177 option to leave the previous display intact and superimpose the new histogram.
178 The same histogram can be drawn with different graphics options in different
179 pads.
180 
181 When a displayed histogram is deleted, its image is automatically removed
182 from the pad.
183 
184 To create a copy of the histogram when drawing it, one can use
185 `TH1::DrawClone()`. This will clone the histogram and allow to change
186 and delete the original one without affecting the clone.
187 
188 
189 ### <a name="HP01"></a> Histograms' plotting options
190 
191 
192 Most options can be concatenated with or without spaces or commas, for example:
193 
194  h->Draw("E1 SAME");
195 
196 The options are not case sensitive:
197 
198  h->Draw("e1 same");
199 
200 
201 The default drawing option can be set with `TH1::SetOption` and retrieve
202 using `TH1::GetOption`:
203 
204  root [0] h->Draw(); // Draw "h" using the standard histogram representation.
205  root [1] h->Draw("E"); // Draw "h" using error bars
206  root [3] h->SetOption("E"); // Change the default drawing option for "h"
207  root [4] h->Draw(); // Draw "h" using error bars
208  root [5] h->GetOption(); // Retrieve the default drawing option for "h"
209  (const Option_t* 0xa3ff948)"E"
210 
211 
212 #### <a name="HP01a"></a> Options supported for 1D and 2D histograms
213 
214 | Option | Description |
215 |----------|-------------------------------------------------------------------|
216 | "E" | Draw error bars. |
217 | "AXIS" | Draw only axis. |
218 | "AXIG" | Draw only grid (if the grid is requested). |
219 | "HIST" | 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). |
220 | "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
221 | "SAME" | Superimpose on previous picture in the same pad. |
222 | "LEGO" | Draw a lego plot with hidden line removal. |
223 | "LEGO1" | Draw a lego plot with hidden surface removal. |
224 | "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.|
225 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
226 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
227 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
228 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
229 | "X+" | The X-axis is drawn on the top side of the plot. |
230 | "Y+" | The Y-axis is drawn on the right side of the plot. |
231 
232 #### <a name="HP01b"></a> Options supported for 1D histograms
233 
234 | Option | Description |
235 |----------|-------------------------------------------------------------------|
236 | " " | Default. |
237 | "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.|
238 | "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
239 | "B" | Bar chart option.|
240 | "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
241 | "HBAR" | Like option "BAR", but bars are drawn horizontally.|
242 | "C" | Draw a smooth Curve through the histogram bins.|
243 | "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
244 | "E1" | Draw error bars with perpendicular lines at the edges.|
245 | "E2" | Draw error bars with rectangles.|
246 | "E3" | Draw a fill area through the end points of the vertical error bars.|
247 | "E4" | Draw a smoothed filled area through the end points of the error bars.|
248 | "E5" | Like E3 but ignore the bins with 0 contents.|
249 | "E6" | Like E4 but ignore the bins with 0 contents.|
250 | "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
251 | "L" | Draw a line through the bin contents.|
252 | "P" | Draw current marker at each bin except empty bins.|
253 | "P0" | Draw current marker at each bin including empty bins.|
254 | "PIE" | Draw histogram as a Pie Chart.|
255 | "*H" | Draw histogram with a * at each bin.|
256 | "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.|
257 
258 
259 #### <a name="HP01c"></a> Options supported for 2D histograms
260 
261 | Option | Description |
262 |-----------|------------------------------------------------------------------|
263 | " " | Default (scatter plot).|
264 | "ARR" | Arrow mode. Shows gradient between adjacent cells.|
265 | "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.|
266 | "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.|
267 | "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.|
268 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
269 | "CANDLE" | Draw a candle plot along X axis.|
270 | "CANDLEX" | Same as "CANDLE".|
271 | "CANDLEY" | Draw a candle plot along Y axis.|
272 | "VIOLIN" | Draw a violin plot along X axis.|
273 | "VIOLINX" | Same as "VIOLIN".|
274 | "VIOLINY" | Draw a violin plot along Y axis.|
275 | "CONT" | Draw a contour plot (same as CONT0).|
276 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
277 | "CONT1" | Draw a contour plot using line styles to distinguish contours.|
278 | "CONT2" | Draw a contour plot using the same line style for all contours.|
279 | "CONT3" | Draw a contour plot using fill area colors.|
280 | "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
281 | "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
282 | "LIST" | Generate a list of TGraph objects for each contour.|
283 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
284 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
285 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
286 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
287 | "SURF" | Draw a surface plot with hidden line removal.|
288 | "SURF1" | Draw a surface plot with hidden surface removal.|
289 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
290 | "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
291 | "SURF4" | Draw a surface using Gouraud shading.|
292 | "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.|
293 | "FB" | With LEGO or SURFACE, suppress the Front-Box.|
294 | "BB" | With LEGO or SURFACE, suppress the Back-Box.|
295 | "A" | With LEGO or SURFACE, suppress the axis.|
296 | "SCAT" | Draw a scatter-plot (default).|
297 | "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
298 
299 
300 #### <a name="HP01d"></a> Options supported for 3D histograms
301 
302 | Option | Description |
303 |----------|-------------------------------------------------------------------|
304 | " " | Default (scatter plot).|
305 | "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)`.|
306 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value.|
307 | "LEGO" | Same as `BOX`.|
308 
309 
310 #### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
311 
312 | Option | Description |
313 |------------|-----------------------------------------------------------------|
314 | " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
315 | "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
316 | "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
317 | "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.|
318 
319 
320 
321 ### <a name="HP02"></a> Setting the Style
322 
323 
324 Histograms use the current style (`gStyle`). When one changes the current
325 style and would like to propagate the changes to the histogram,
326 `TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
327 each histogram is needed.
328 <br>
329 To force all the histogram to use the current style use:
330 
331  gROOT->ForceStyle();
332 
333 All the histograms read after this call will use the current style.
334 
335 
336 ### <a name="HP03"></a> Setting line, fill, marker, and text attributes
337 
338 
339 The histogram classes inherit from the attribute classes:
340 `TAttLine`, `TAttFill` and `TAttMarker`.
341 See the description of these classes for the list of options.
342 
343 
344 ### <a name="HP04"></a> Setting Tick marks on the histogram axis
345 
346 
347 The `TPad::SetTicks` method specifies the type of tick marks on the axis.
348 If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
349 
350  tx = 1; tick marks on top side are drawn (inside)
351  tx = 2; tick marks and labels on top side are drawn
352  ty = 1; tick marks on right side are drawn (inside)
353  ty = 2; tick marks and labels on right side are drawn
354 
355 By default only the left Y axis and X bottom axis are drawn
356 (`tx = ty = 0`)
357 
358 `TPad::SetTicks(tx,ty)` allows to set these options.
359 See also The `TAxis` functions to set specific axis attributes.
360 
361 In case multiple color filled histograms are drawn on the same pad, the fill
362 area may hide the axis tick marks. One can force a redraw of the axis over all
363 the histograms by calling:
364 
365  gPad->RedrawAxis();
366 
367 
368 
369 ### <a name="HP05"></a> Giving titles to the X, Y and Z axis
370 
371 
372  h->GetXaxis()->SetTitle("X axis title");
373  h->GetYaxis()->SetTitle("Y axis title");
374 
375 The histogram title and the axis titles can be any `TLatex` string.
376 The titles are part of the persistent histogram.
377 
378 
379 ### <a name="HP060"></a> The option "SAME"
380 
381 
382 By default, when an histogram is drawn, the current pad is cleared before
383 drawing. In order to keep the previous drawing and draw on top of it the
384 option `SAME` should be use. The histogram drawn with the option
385 `SAME` uses the coordinates system available in the current pad.
386 
387 This option can be used alone or combined with any valid drawing option but
388 some combinations must be use with care.
389 
390 #### <a name="HP060a"></a> Limitations
391 
392 - It does not work when combined with the `LEGO` and `SURF` options unless the
393  histogram plotted with the option `SAME` has exactly the same
394  ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
395  lego plots [histograms' stacks](#HP26) should be used.</li>
396 
397 
398 ### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
399 
400 
401 The following example creates two histograms, the second histogram is the bins
402 integral of the first one. It shows a procedure to draw the two histograms in
403 the same pad and it draws the scale of the second histogram using a new vertical
404 axis on the right side. See also the tutorial `transpad.C` for a variant
405 of this example.
406 
407 Begin_Macro(source)
408 {
409  TCanvas *c1 = new TCanvas("c1","c1",600,400);
410  // create/fill draw h1
411  gStyle->SetOptStat(kFALSE);
412  TH1F *h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
413  Int_t i;
414  for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
415  h1->Draw();
416  c1->Update();
417 
418  // create hint1 filled with the bins integral of h1
419  TH1F *hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
420  Float_t sum = 0;
421  for (i=1;i<=100;i++) {
422  sum += h1->GetBinContent(i);
423  hint1->SetBinContent(i,sum);
424  }
425 
426  // scale hint1 to the pad coordinates
427  Float_t rightmax = 1.1*hint1->GetMaximum();
428  Float_t scale = gPad->GetUymax()/rightmax;
429  hint1->SetLineColor(kRed);
430  hint1->Scale(scale);
431  hint1->Draw("same");
432 
433  // draw an axis on the right side
434  TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
435  gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
436  axis->SetLineColor(kRed);
437  axis->SetTextColor(kRed);
438  axis->Draw();
439  return c1;
440 }
441 End_Macro
442 
443 
444 ### <a name="HP07"></a> Statistics Display
445 
446 
447 The type of information shown in the histogram statistics box can be selected
448 with:
449 
450  gStyle->SetOptStat(mode);
451 
452 The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
453 
454  mode = ksiourmen (default = 000001111)
455  k = 1; kurtosis printed
456  k = 2; kurtosis and kurtosis error printed
457  s = 1; skewness printed
458  s = 2; skewness and skewness error printed
459  i = 1; integral of bins printed
460  i = 2; integral of bins with option "width" printed
461  o = 1; number of overflows printed
462  u = 1; number of underflows printed
463  r = 1; standard deviation printed
464  r = 2; standard deviation and standard deviation error printed
465  m = 1; mean value printed
466  m = 2; mean and mean error values printed
467  e = 1; number of entries printed
468  n = 1; name of histogram is printed
469 
470 For example:
471 
472  gStyle->SetOptStat(11);
473 
474 displays only the name of histogram and the number of entries, whereas:
475 
476  gStyle->SetOptStat(1101);
477 
478 displays the name of histogram, mean value and standard deviation.
479 
480 <b>WARNING 1:</b> never do:
481 
482  gStyle->SetOptStat(0001111);
483 
484 but instead do:
485 
486  gStyle->SetOptStat(1111);
487 
488 because `0001111` will be taken as an octal number!
489 
490 <b>WARNING 2:</b> for backward compatibility with older versions
491 
492  gStyle->SetOptStat(1);
493 
494 is taken as:
495 
496  gStyle->SetOptStat(1111)
497 
498 To print only the name of the histogram do:
499 
500  gStyle->SetOptStat(1000000001);
501 
502 <b>NOTE</b> that in case of 2D histograms, when selecting only underflow
503 (10000) or overflow (100000), the statistics box will show all combinations
504 of underflow/overflows and not just one single number.
505 
506 The parameter mode can be any combination of the letters `kKsSiIourRmMen`
507 
508  k : kurtosis printed
509  K : kurtosis and kurtosis error printed
510  s : skewness printed
511  S : skewness and skewness error printed
512  i : integral of bins printed
513  I : integral of bins with option "width" printed
514  o : number of overflows printed
515  u : number of underflows printed
516  r : standard deviation printed
517  R : standard deviation and standard deviation error printed
518  m : mean value printed
519  M : mean value mean error values printed
520  e : number of entries printed
521  n : name of histogram is printed
522 
523 For example, to print only name of histogram and number of entries do:
524 
525  gStyle->SetOptStat("ne");
526 
527 To print only the name of the histogram do:
528 
529  gStyle->SetOptStat("n");
530 
531 The default value is:
532 
533  gStyle->SetOptStat("nemr");
534 
535 When a histogram is painted, a `TPaveStats` object is created and added
536 to the list of functions of the histogram. If a `TPaveStats` object
537 already exists in the histogram list of functions, the existing object is just
538 updated with the current histogram parameters.
539 
540 Once a histogram is painted, the statistics box can be accessed using
541 `h->FindObject("stats")`. In the command line it is enough to do:
542 
543  Root > h->Draw()
544  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
545 
546 because after `h->Draw()` the histogram is automatically painted. But
547 in a script file the painting should be forced using `gPad->Update()`
548 in order to make sure the statistics box is created:
549 
550  h->Draw();
551  gPad->Update();
552  TPaveStats *st = (TPaveStats*)h->FindObject("stats");
553 
554 Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
555 
556 When a histogram is drawn with the option `SAME`, the statistics box
557 is not drawn. To force the statistics box drawing with the option
558 `SAME`, the option `SAMES` must be used.
559 If the new statistics box hides the previous statistics box, one can change
560 its position with these lines (`h` being the pointer to the histogram):
561 
562  Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
563  Root > st->SetX1NDC(newx1); //new x start position
564  Root > st->SetX2NDC(newx2); //new x end position
565 
566 To change the type of information for an histogram with an existing
567 `TPaveStats` one should do:
568 
569  st->SetOptStat(mode);
570 
571 Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
572 (see above).
573 
574 One can delete the statistics box for a histogram `TH1* h` with:
575 
576  h->SetStats(0)
577 
578 and activate it again with:
579 
580  h->SetStats(1).
581 
582 Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
583 `$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
584 
585 
586 ### <a name="HP08"></a> Fit Statistics
587 
588 
589 The type of information about fit parameters printed in the histogram statistics
590 box can be selected via the parameter mode. The parameter mode can be
591 `= pcev` (default `= 0111`)
592 
593  p = 1; print Probability
594  c = 1; print Chisquare/Number of degrees of freedom
595  e = 1; print errors (if e=1, v must be 1)
596  v = 1; print name/values of parameters
597 
598 Example:
599 
600  gStyle->SetOptFit(1011);
601 
602 print fit probability, parameter names/values and errors.
603 
604 1. When `v" = 1` is specified, only the non-fixed parameters are shown.
605 2. When `v" = 2` all parameters are shown.
606 
607 Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
608 to `gStyle->SetOptFit(111)`
609 
610 
611 ### <a name="HP09"></a> The error bars options
612 
613 
614 | Option | Description |
615 |----------|-------------------------------------------------------------------|
616 | "E" | Default. Shows only the error bars, not a marker.|
617 | "E1" | Small lines are drawn at the end of the error bars.|
618 | "E2" | Error rectangles are drawn.|
619 | "E3" | A filled area is drawn through the end points of the vertical error bars.|
620 | "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
621 | "E0" | Draw also bins with null contents.|
622 
623 Begin_Macro(source)
624 {
625  TCanvas *c1 = new TCanvas("c1","c1",600,400);
626  TH1F *he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
627  Int_t i;
628  for (i=0;i<10000;i++) he->Fill(gRandom->Gaus(0,1));
629  gStyle->SetEndErrorSize(3);
630  gStyle->SetErrorX(1.);
631  he->SetMarkerStyle(20);
632  he->Draw("E1");
633  return c1;
634 }
635 End_Macro
636 
637 The options "E3" and "E4" draw an error band through the end points of the
638 vertical error bars. With "E4" the error band is smoothed. Because of the
639 smoothing algorithm used some artefacts may appear at the end of the band
640 like in the following example. In such cases "E3" should be used instead
641 of "E4".
642 
643 Begin_Macro(source)
644 {
645  TCanvas *ce4 = new TCanvas("ce4","ce4",600,400);
646  ce4->Divide(2,1);
647  TH1F *he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
648  Int_t i;
649  for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
650  he4->SetFillColor(kRed);
651  he4->GetXaxis()->SetRange(40,48);
652  ce4->cd(1);
653  he4->Draw("E4");
654  ce4->cd(2);
655  TH1F *he3 = (TH1F*)he4->DrawClone("E3");
656  he3->SetTitle("Distribution drawn option E3");
657  return ce4;
658 }
659 End_Macro
660 
661 2D histograms can be drawn with error bars as shown is the following example:
662 
663 Begin_Macro(source)
664 {
665  TCanvas *c2e = new TCanvas("c2e","c2e",600,400);
666  TH2F *h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
667  Float_t px, py;
668  for (Int_t i = 0; i < 25000; i++) {
669  gRandom->Rannor(px,py);
670  h2e->Fill(px,5*py);
671  }
672  h2e->Draw("E");
673  return c2e;
674 }
675 End_Macro
676 
677 
678 ### <a name="HP100"></a> The bar chart option
679 
680 
681 The option "B" allows to draw simple vertical bar charts.
682 The bar width is controlled with `TH1::SetBarWidth()`,
683 and the bar offset wihtin the bin, with `TH1::SetBarOffset()`.
684 These two settings are useful to draw several histograms on the
685 same plot as shown in the following example:
686 
687 Begin_Macro(source)
688 {
689  int i;
690  const Int_t nx = 8;
691  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
692  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
693  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
694 
695  TCanvas *cb = new TCanvas("cb","cb",600,400);
696  cb->SetGrid();
697 
698  gStyle->SetHistMinimumZero();
699 
700  TH1F *h1b = new TH1F("h1b","Option B example",nx,0,nx);
701  h1b->SetFillColor(4);
702  h1b->SetBarWidth(0.4);
703  h1b->SetBarOffset(0.1);
704  h1b->SetStats(0);
705  h1b->SetMinimum(-5);
706  h1b->SetMaximum(5);
707 
708  for (i=1; i<=nx; i++) {
709  h1b->SetBinContent(i, d_35_0[i-1]);
710  h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
711  }
712 
713  h1b->Draw("b");
714 
715  TH1F *h2b = new TH1F("h2b","h2b",nx,0,nx);
716  h2b->SetFillColor(38);
717  h2b->SetBarWidth(0.4);
718  h2b->SetBarOffset(0.5);
719  h2b->SetStats(0);
720  for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
721 
722  h2b->Draw("b same");
723 
724  return cb;
725 }
726 End_Macro
727 
728 
729 ### <a name="HP10"></a> The "BAR" and "HBAR" options
730 
731 
732 When the option "bar" or "hbar" is specified, a bar chart is drawn. A vertical
733 bar-chart is drawn with the options `bar`, `bar0`,
734 `bar1`, `bar2`, `bar3`, `bar4`.
735 An horizontal bar-chart is drawn with the options `hbar`,
736 `hbar0`, `hbar1`, `hbar2``, `hbar3`,
737 `hbar4`.
738 
739 - The bar is filled with the histogram fill color.
740 - The left side of the bar is drawn with a light fill color.
741 - The right side of the bar is drawn with a dark fill color.
742 - The percentage of the bar drawn with either the light or dark color is:
743  - 0% for option "(h)bar" or "(h)bar0"
744  - 10% for option "(h)bar1"
745  - 20% for option "(h)bar2"
746  - 30% for option "(h)bar3"
747  - 40% for option "(h)bar4"
748 
749 
750 
751 Begin_Macro(source)
752 ../../../tutorials/hist/hbars.C
753 End_Macro
754 
755 To control the bar width (default is the bin width) `TH1::SetBarWidth()`
756 should be used.
757 <br>
758 To control the bar offset (default is 0) `TH1::SetBarOffset()` should
759 be used.
760 <br>
761 These two parameters are useful when several histograms are plotted using
762 the option `SAME`. They allow to plot the histograms next to each other.
763 
764 
765 ### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
766 
767 
768 For each cell (i,j) a number of points proportional to the cell content is
769 drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
770 `kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
771 If option is of the form `scat=ff`, (eg `scat=1.8`,
772 `scat=1e-3`), then `ff` is used as a scale factor to compute the
773 number of dots. `scat=1` is the default.
774 
775 By default the scatter plot is painted with a "dot marker" which not scalable
776 (see the `TAttMarker` documentation). To change the marker size, a scalable marker
777 type should be used. For instance a circle (marker style 20).
778 
779 Begin_Macro(source)
780 {
781  TCanvas *c1 = new TCanvas("c1","c1",600,400);
782  TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
783  Float_t px, py;
784  for (Int_t i = 0; i < 25000; i++) {
785  gRandom->Rannor(px,py);
786  hscat->Fill(px,5*py);
787  hscat->Fill(3+0.5*px,2*py-10.);
788  }
789  hscat->Draw("scat=0.5");
790  return c1;
791 }
792 End_Macro
793 
794 
795 ### <a name="HP12"></a> The ARRow option
796 
797 
798 Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
799 The orientation of the arrow follows the cell gradient.
800 
801 Begin_Macro(source)
802 {
803  TCanvas *c1 = new TCanvas("c1","c1",600,400);
804  TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
805  Float_t px, py;
806  for (Int_t i = 0; i < 25000; i++) {
807  gRandom->Rannor(px,py);
808  harr->Fill(px,5*py);
809  harr->Fill(3+0.5*px,2*py-10.,0.1);
810  }
811  harr->Draw("ARR");
812  return c1;
813 }
814 End_Macro
815 
816 
817 ### <a name="HP13"></a> The BOX option
818 
819 
820 For each cell (i,j) a box is drawn. The size (surface) of the box is
821 proportional to the absolute value of the cell content.
822 The cells with a negative content draw with a `X` on top of the boxes.
823 
824 Begin_Macro(source)
825 {
826  TCanvas *c1 = new TCanvas("c1","c1",600,400);
827  hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
828  hbox->SetFillColor(42);
829  hbox->Fill(0.5, 0.5, 1.);
830  hbox->Fill(0.5, 1.5, 4.);
831  hbox->Fill(0.5, 2.5, 3.);
832  hbox->Fill(1.5, 0.5, 2.);
833  hbox->Fill(1.5, 1.5, 12.);
834  hbox->Fill(1.5, 2.5, -6.);
835  hbox->Fill(2.5, 0.5, -4.);
836  hbox->Fill(2.5, 1.5, 6.);
837  hbox->Fill(2.5, 2.5, 0.5);
838  hbox->Draw("BOX");
839  return c1;
840 }
841 End_Macro
842 
843 With option `BOX1` a button is drawn for each cell with surface
844 proportional to content's absolute value. A sunken button is drawn for
845 negative values a raised one for positive.
846 
847 Begin_Macro(source)
848 {
849  TCanvas *c1 = new TCanvas("c1","c1",600,400);
850  hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
851  hbox1->SetFillColor(42);
852  hbox1->Fill(0.5, 0.5, 1.);
853  hbox1->Fill(0.5, 1.5, 4.);
854  hbox1->Fill(0.5, 2.5, 3.);
855  hbox1->Fill(1.5, 0.5, 2.);
856  hbox1->Fill(1.5, 1.5, 12.);
857  hbox1->Fill(1.5, 2.5, -6.);
858  hbox1->Fill(2.5, 0.5, -4.);
859  hbox1->Fill(2.5, 1.5, 6.);
860  hbox1->Fill(2.5, 2.5, 0.5);
861  hbox1->Draw("BOX1");
862  return c1;
863 }
864 End_Macro
865 
866 When the option `SAME` (or "SAMES") is used with the option `BOX`,
867 the boxes' sizes are computing taking the previous plots into account. The range
868 along the Z axis is imposed by the first plot (the one without option
869 `SAME`); therefore the order in which the plots are done is relevant.
870 
871 Begin_Macro(source)
872 {
873  TCanvas *c1 = new TCanvas("c1","c1",600,400);
874  TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
875  TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
876  TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
877  TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
878  for (Int_t i=0;i<1000;i++) {
879  double x,y;
880  gRandom->Rannor(x,y);
881  if (x>0 && y>0) hb1->Fill(x,y,4);
882  if (x<0 && y<0) hb2->Fill(x,y,3);
883  if (x>0 && y<0) hb3->Fill(x,y,2);
884  if (x<0 && y>0) hb4->Fill(x,y,1);
885  }
886  hb1->SetFillColor(1);
887  hb2->SetFillColor(2);
888  hb3->SetFillColor(3);
889  hb4->SetFillColor(4);
890  hb1->Draw("box");
891  hb2->Draw("box same");
892  hb3->Draw("box same");
893  hb4->Draw("box same");
894  return c1;
895 }
896 End_Macro
897 
898 
899 ### <a name="HP14"></a> The COLor option
900 
901 
902 For each cell (i,j) a box is drawn with a color proportional to the cell
903 content.
904 
905 The color table used is defined in the current style.
906 
907 If the histogram's minimum and maximum are the same (flat histogram), the
908 mapping on colors is not possible, therefore nothing is painted. To paint a
909 flat histogram it is enough to set the histogram minimum
910 (`TH1::SetMinimum()`) different from the bins' content.
911 
912 The default number of color levels used to paint the cells is 20.
913 It can be changed with `TH1::SetContour()` or
914 `TStyle::SetNumberContours()`. The higher this number is, the smoother
915 is the color change between cells.
916 
917 The color palette in TStyle can be modified via `gStyle->SetPalette()`.
918 
919 All the none empty bins are painted. Empty bins are not painted unless
920 some bins have a negative content because in that case the null bins
921 might be not empty.
922 
923 `TProfile2D` histograms are handled differently because, for this type of 2D
924 histograms, it is possible to know if an empty bin has been filled or not. So even
925 if all the bins' contents are positive some empty bins might be painted. And vice versa,
926 if some bins have a negative content some empty bins might be not painted.
927 
928 Combined with the option `COL`, the option `Z` allows to
929 display the color palette defined by `gStyle->SetPalette()`.
930 
931 In the following example, the histogram has only positive bins; the empty
932 bins (containing 0) are not drawn.
933 
934 Begin_Macro(source)
935 {
936  TCanvas *c1 = new TCanvas("c1","c1",600,400);
937  TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
938  Float_t px, py;
939  for (Int_t i = 0; i < 25000; i++) {
940  gRandom->Rannor(px,py);
941  hcol1->Fill(px,5*py);
942  }
943  gStyle->SetPalette(kBird);
944  hcol1->Draw("COLZ");
945  return c1;
946 }
947 End_Macro
948 
949 In the first plot of following example, the histogram has some negative bins;
950 the empty bins (containing 0) are drawn. In some cases one wants to not draw
951 empty bins (containing 0) of histograms having a negative minimum. The option
952 `1`, used to produce the second plot in the following picture, allows to do that.
953 
954 Begin_Macro(source)
955 {
956  TCanvas *c1 = new TCanvas("c1","c1",600,600);
957  c1->Divide(1,2);
958  TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
959  TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
960  Float_t px, py;
961  for (Int_t i = 0; i < 25000; i++) {
962  gRandom->Rannor(px,py);
963  hcol23->Fill(px,5*py);
964  hcol24->Fill(px,5*py);
965  }
966  hcol23->Fill(0.,0.,-200.);
967  hcol24->Fill(0.,0.,-200.);
968  gStyle->SetPalette(kBird);
969  c1->cd(1); hcol23->Draw("COLZ");
970  c1->cd(2); hcol24->Draw("COLZ1");
971  return c1;
972 }
973 End_Macro
974 
975 When the maximum of the histogram is set to a smaller value than the real maximum,
976  the bins having a content between the new maximum and the real maximum are
977 painted with the color corresponding to the new maximum.
978 
979 When the minimum of the histogram is set to a greater value than the real minimum,
980  the bins having a value between the real minimum and the new minimum are not drawn
981  unless the option `0` is set.
982 
983 The following example illustrates the option `0` combined with the option `COL`.
984 
985 Begin_Macro(source)
986 {
987  TCanvas *c1 = new TCanvas("c1","c1",600,600);
988  c1->Divide(1,2);
989  TH2F *hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
990  TH2F *hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
991  Float_t px, py;
992  for (Int_t i = 0; i < 25000; i++) {
993  gRandom->Rannor(px,py);
994  hcol21->Fill(px,5*py);
995  hcol22->Fill(px,5*py);
996  }
997  hcol21->SetBit(TH1::kNoStats);
998  hcol22->SetBit(TH1::kNoStats);
999  gStyle->SetPalette(kBird);
1000  c1->cd(1); hcol21->Draw("COLZ");
1001  c1->cd(2); hcol22->Draw("COLZ0");
1002  hcol22->SetMaximum(100);
1003  hcol22->SetMinimum(40);
1004  return c1;
1005 }
1006 End_Macro
1007 
1008 The option `COL` can be combined with the option `POL`:
1009 
1010 Begin_Macro(source)
1011 {
1012  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1013  TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1014  Float_t px, py;
1015  for (Int_t i = 0; i < 25000; i++) {
1016  gRandom->Rannor(px,py);
1017  hcol1->Fill(px,py);
1018  }
1019  gStyle->SetPalette(kBird);
1020  hcol1->Draw("COLZPOL");
1021  return c1;
1022 }
1023 End_Macro
1024 
1025 ### <a name="HP140"></a> The CANDLE option
1026 
1027 
1028 <a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1029 a "box-and whisker plot" or simply "box plot") is a convenient way to describe
1030 graphically a data distribution (D) with only five numbers. It was invented
1031 in 1977 by John Tukey.
1032 
1033 With the option CANDLEX five numbers are:
1034 
1035 1. The minimum value of the distribution D (bottom dashed line).
1036 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1037 3. The median (M): 50% of the data points in D are less than M (thick line segment inside the box).
1038 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1039 5. The maximum value of the distribution D (top dashed line).
1040 
1041 
1042 The mean value of the distribution D is also represented as a circle.
1043 
1044 In this implementation a TH2 is considered as a collection of TH1 along
1045 X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1046 Each TH1 is represented as a candle plot.
1047 
1048 Begin_Macro(source)
1049 {
1050  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1051  TH2F *hcandle = new TH2F("hcandle","Option CANDLE example ",40,-4,4,40,-20,20);
1052  Float_t px, py;
1053  for (Int_t i = 0; i < 25000; i++) {
1054  gRandom->Rannor(px,py);
1055  hcandle->Fill(px,5*py);
1056  }
1057  hcandle->SetMarkerSize(0.5);
1058  hcandle->Draw("CANDLE");
1059  return c1;
1060 }
1061 End_Macro
1062 
1063 ### <a name="HP141"></a> The VIOLIN option
1064 
1065 
1066 <a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a box plot
1067 that also encodes the pdf information at each point.
1068 
1069 
1070 Quartiles and mean are also represented at each point, with a marker
1071 and two lines.
1072 
1073 In this implementation a TH2 is considered as a collection of TH1 along
1074 X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1075 
1076 A solid fill style is recommended for this plot (as opposed to a hollow or
1077 hashed style).
1078 
1079 Begin_Macro(source)
1080 {
1081  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1082  Int_t nx(6), ny(40);
1083  Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1084  TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1085  TF1 f1("f1", "gaus", +0,0 +4.0);
1086  Double_t x,y;
1087  for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1088  Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1089  f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1090  for(Int_t i=0; i<10000; ++i){
1091  x = xc;
1092  y = f1.GetRandom();
1093  hviolin->Fill(x, y);
1094  }
1095  }
1096  hviolin->SetFillColor(kGray);
1097  hviolin->SetMarkerStyle(20);
1098  hviolin->SetMarkerSize(0.5);
1099  hviolin->Draw("VIOLIN");
1100  c1->Update();
1101  return c1;
1102 }
1103 End_Macro
1104 
1105 
1106 ### <a name="HP15"></a> The TEXT and TEXTnn Option
1107 
1108 
1109 For each bin the content is printed. The text attributes are:
1110 
1111 - text font = current TStyle font (`gStyle->SetTextFont()`).
1112 - text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1113  with the option `TEXT` the marker size can be changed with
1114  `h->SetMarkerSize(markersize)`).
1115 - text color = marker color.
1116 
1117 By default the format `g` is used. This format can be redefined
1118 by calling `gStyle->SetPaintTextFormat()`.
1119 
1120 It is also possible to use `TEXTnn` in order to draw the text with
1121 the angle `nn` (`0 < nn < 90`).
1122 
1123 For 2D histograms the text is plotted in the center of each non empty cells.
1124 It is possible to plot empty cells by calling gStyle->SetHistMinimumZero().
1125 For 1D histogram the text is plotted at a y position equal to the bin content.
1126 
1127 For 2D histograms when the option "E" (errors) is combined with the option
1128 text ("TEXTE"), the error for each bin is also printed.
1129 
1130 Begin_Macro(source)
1131 {
1132  TCanvas *c01 = new TCanvas("c01","c01",700,400);
1133  c01->Divide(2,1);
1134  TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1135  TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1136  Float_t px, py;
1137  for (Int_t i = 0; i < 25000; i++) {
1138  gRandom->Rannor(px,py);
1139  htext1->Fill(px,0.1);
1140  htext2->Fill(px,5*py,0.1);
1141  }
1142  gStyle->SetPaintTextFormat("4.1f m");
1143  htext2->SetMarkerSize(1.8);
1144  c01->cd(1);
1145  htext2->Draw("TEXT45");
1146  c01->cd(2);
1147  htext1->Draw();
1148  htext1->Draw("HIST TEXT0 SAME");
1149  return c01;
1150 }
1151 End_Macro
1152 
1153 In the case of profile histograms it is possible to print the number
1154 of entries instead of the bin content. It is enough to combine the
1155 option "E" (for entries) with the option "TEXT".
1156 
1157 Begin_Macro(source)
1158 {
1159  TCanvas *c02 = new TCanvas("c02","c02",700,400);
1160  c02->Divide(2,1);
1161  gStyle->SetPaintTextFormat("g");
1162 
1163  TProfile *profile = new TProfile("profile","profile",10,0,10);
1164  profile->SetMarkerSize(2.2);
1165  profile->Fill(0.5,1);
1166  profile->Fill(1.5,2);
1167  profile->Fill(2.5,3);
1168  profile->Fill(3.5,4);
1169  profile->Fill(4.5,5);
1170  profile->Fill(5.5,5);
1171  profile->Fill(6.5,4);
1172  profile->Fill(7.5,3);
1173  profile->Fill(8.5,2);
1174  profile->Fill(9.5,1);
1175  c02->cd(1); profile->Draw("HIST TEXT0");
1176  c02->cd(2); profile->Draw("HIST TEXT0E");
1177 
1178  return c02;
1179 }
1180 End_Macro
1181 
1182 ### <a name="HP16"></a> The CONTour options
1183 
1184 
1185 The following contour options are supported:
1186 
1187 | Option | Description |
1188 |----------|-------------------------------------------------------------------|
1189 | "CONT" | Draw a contour plot (same as CONT0).|
1190 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1191 | "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1192 | "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1193 | "CONT3" | Draw a contour plot solid lines for all contours.|
1194 | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1195 | "CONT5" | Draw a contour plot using Delaunay triangles.|
1196 
1197 
1198 
1199 The following example shows a 2D histogram plotted with the option
1200 `CONTZ`. The option `CONT` draws a contour plot using surface
1201 colors to distinguish contours. Combined with the option `CONT` (or
1202 `CONT0`), the option `Z` allows to display the color palette
1203 defined by `gStyle->SetPalette()`.
1204 
1205 Begin_Macro(source)
1206 {
1207  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1208  TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1209  Float_t px, py;
1210  for (Int_t i = 0; i < 25000; i++) {
1211  gRandom->Rannor(px,py);
1212  hcontz->Fill(px-1,5*py);
1213  hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1214  }
1215  gStyle->SetPalette(kBird);
1216  hcontz->Draw("CONTZ");
1217  return c1;
1218 }
1219 End_Macro
1220 
1221 The following example shows a 2D histogram plotted with the option
1222 `CONT1Z`. The option `CONT1` draws a contour plot using the
1223 line colors to distinguish contours. Combined with the option `CONT1`,
1224 the option `Z` allows to display the color palette defined by
1225 `gStyle->SetPalette()`.
1226 
1227 Begin_Macro(source)
1228 {
1229  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1230  TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1231  Float_t px, py;
1232  for (Int_t i = 0; i < 25000; i++) {
1233  gRandom->Rannor(px,py);
1234  hcont1->Fill(px-1,5*py);
1235  hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1236  }
1237  gStyle->SetPalette(kBird);
1238  hcont1->Draw("CONT1Z");
1239  return c1;
1240 }
1241 End_Macro
1242 
1243 The following example shows a 2D histogram plotted with the option
1244 `CONT2`. The option `CONT2` draws a contour plot using the
1245 line styles to distinguish contours.
1246 
1247 Begin_Macro(source)
1248 {
1249  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1250  TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1251  Float_t px, py;
1252  for (Int_t i = 0; i < 25000; i++) {
1253  gRandom->Rannor(px,py);
1254  hcont2->Fill(px-1,5*py);
1255  hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1256  }
1257  hcont2->Draw("CONT2");
1258  return c1;
1259 }
1260 End_Macro
1261 
1262 The following example shows a 2D histogram plotted with the option
1263 `CONT3`. The option `CONT3` draws contour plot solid lines for
1264 all contours.
1265 
1266 Begin_Macro(source)
1267 {
1268  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1269  TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1270  Float_t px, py;
1271  for (Int_t i = 0; i < 25000; i++) {
1272  gRandom->Rannor(px,py);
1273  hcont3->Fill(px-1,5*py);
1274  hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1275  }
1276  hcont3->Draw("CONT3");
1277  return c1;
1278 }
1279 End_Macro
1280 
1281 The following example shows a 2D histogram plotted with the option
1282 `CONT4`. The option `CONT4` draws a contour plot using surface
1283 colors to distinguish contours (`SURF` option at theta = 0). Combined
1284 with the option `CONT` (or `CONT0`), the option `Z`
1285 allows to display the color palette defined by `gStyle->SetPalette()`.
1286 
1287 Begin_Macro(source)
1288 {
1289  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1290  TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1291  Float_t px, py;
1292  for (Int_t i = 0; i < 25000; i++) {
1293  gRandom->Rannor(px,py);
1294  hcont4->Fill(px-1,5*py);
1295  hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1296  }
1297  gStyle->SetPalette(kBird);
1298  hcont4->Draw("CONT4Z");
1299  return c1;
1300 }
1301 End_Macro
1302 
1303 The default number of contour levels is 20 equidistant levels and can be changed
1304 with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1305 
1306 #### <a name="HP16a"></a> The LIST option
1307 
1308 When option `LIST` is specified together with option
1309 `CONT`, the points used to draw the contours are saved in
1310 `TGraph` objects:
1311 
1312  h->Draw("CONT LIST");
1313  gPad->Update();
1314 
1315 The contour are saved in `TGraph` objects once the pad is painted.
1316 Therefore to use this functionnality in a macro, `gPad->Update()`
1317 should be performed after the histogram drawing. Once the list is
1318 built, the contours are accessible in the following way:
1319 
1320  TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1321  Int_t ncontours = contours->GetSize();
1322  TList *list = (TList*)contours->At(i);
1323 
1324 Where `i` is a contour number, and list contains a list of
1325 `TGraph` objects.
1326 For one given contour, more than one disjoint polyline may be generated.
1327 The number of TGraphs per contour is given by:
1328 
1329  list->GetSize();
1330 
1331 To access the first graph in the list one should do:
1332 
1333  TGraph *gr1 = (TGraph*)list->First();
1334 
1335 
1336 The following example shows how to use this functionality.
1337 
1338 Begin_Macro(source)
1339 ../../../tutorials/hist/ContourList.C
1340 End_Macro
1341 
1342 The following options select the `CONT4` option and are useful for
1343 sky maps or exposure maps.
1344 
1345 | Option | Description |
1346 |--------------|---------------------------------------------------------------|
1347 | "AITOFF" | Draw a contour via an AITOFF projection.|
1348 | "MERCATOR" | Draw a contour via an Mercator projection.|
1349 | "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1350 | "PARABOLIC" | Draw a contour via an Parabolic projection.|
1351 
1352 Begin_Macro(source)
1353 ../../../tutorials/graphics/earth.C
1354 End_Macro
1355 
1356 
1357 ### <a name="HP17"></a> The LEGO options
1358 
1359 
1360 In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1361 is proportional to the cell content. The lego aspect is control with the
1362 following options:
1363 
1364 | Option | Description |
1365 |----------|-------------------------------------------------------------------|
1366 | "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1367 | "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1368 | "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1369 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1370 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1371 | "0" | When used with any LEGO option, the empty bins are not drawn.|
1372 
1373 
1374 See the limitations with [the option "SAME"](#HP060a).
1375 
1376 Line attributes can be used in lego plots to change the edges' style.
1377 
1378 The following example shows a 2D histogram plotted with the option
1379 `LEGO`. The option `LEGO` draws a lego plot using the hidden
1380 lines removal technique.
1381 
1382 Begin_Macro(source)
1383 {
1384  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1385  TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1386  Float_t px, py;
1387  for (Int_t i = 0; i < 25000; i++) {
1388  gRandom->Rannor(px,py);
1389  hlego->Fill(px-1,5*py);
1390  hlego->Fill(2+0.5*px,2*py-10.,0.1);
1391  }
1392  hlego->Draw("LEGO");
1393  return c2;
1394 }
1395 End_Macro
1396 
1397 The following example shows a 2D histogram plotted with the option
1398 `LEGO1`. The option `LEGO1` draws a lego plot using the
1399 hidden surface removal technique. Combined with any `LEGOn` option, the
1400 option `0` allows to not drawn the empty bins.
1401 
1402 Begin_Macro(source)
1403 {
1404  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1405  TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1406  Float_t px, py;
1407  for (Int_t i = 0; i < 25000; i++) {
1408  gRandom->Rannor(px,py);
1409  hlego1->Fill(px-1,5*py);
1410  hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1411  }
1412  hlego1->SetFillColor(kYellow);
1413  hlego1->Draw("LEGO1 0");
1414  return c2;
1415 }
1416 End_Macro
1417 
1418 The following example shows a 2D histogram plotted with the option
1419 `LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1420 draws a lego plot using the hidden surface removal technique but doesn't draw
1421 the border lines of each individual lego-bar. This is very useful for histograms
1422 having many bins. With such histograms the option `LEGO1` gives a black
1423 image because of the border lines. This option also works with stacked legos.
1424 
1425 Begin_Macro(source)
1426 {
1427  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1428  TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1429  Float_t px, py;
1430  for (Int_t i = 0; i < 25000; i++) {
1431  gRandom->Rannor(px,py);
1432  hlego3->Fill(px-1,5*py);
1433  hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1434  }
1435  hlego3->SetFillColor(kRed);
1436  hlego3->Draw("LEGO3");
1437  return c2;
1438  }
1439 End_Macro
1440 
1441 The following example shows a 2D histogram plotted with the option
1442 `LEGO2`. The option `LEGO2` draws a lego plot using colors to
1443 show the cell contents. Combined with the option `LEGO2`, the option
1444 `Z` allows to display the color palette defined by
1445 `gStyle->SetPalette()`.
1446 
1447 Begin_Macro(source)
1448 {
1449  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1450  TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1451  Float_t px, py;
1452  for (Int_t i = 0; i < 25000; i++) {
1453  gRandom->Rannor(px,py);
1454  hlego2->Fill(px-1,5*py);
1455  hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1456  }
1457  gStyle->SetPalette(kBird);
1458  hlego2->Draw("LEGO2Z");
1459  return c2;
1460 }
1461 End_Macro
1462 
1463 
1464 
1465 ### <a name="HP18"></a> The "SURFace" options
1466 
1467 
1468 In a surface plot, cell contents are represented as a mesh.
1469 The height of the mesh is proportional to the cell content.
1470 
1471 | Option | Description |
1472 |----------|-------------------------------------------------------------------|
1473 | "SURF" | Draw a surface plot using the hidden line removal technique.|
1474 | "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1475 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
1476 | "SURF3" | Same as `SURF` with an additionial filled contour plot on top.|
1477 | "SURF4" | Draw a surface using the Gouraud shading technique.|
1478 | "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1479 | "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.|
1480 | "SURF7" | Same as `SURF2` with an additionial line contour plot on top.|
1481 
1482 
1483 
1484 See the limitations with [the option "SAME"](#HP060a).
1485 
1486 The following example shows a 2D histogram plotted with the option
1487 `SURF`. The option `SURF` draws a lego plot using the hidden
1488 lines removal technique.
1489 
1490 Begin_Macro(source)
1491 {
1492  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1493  TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1494  Float_t px, py;
1495  for (Int_t i = 0; i < 25000; i++) {
1496  gRandom->Rannor(px,py);
1497  hsurf->Fill(px-1,5*py);
1498  hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1499  }
1500  hsurf->Draw("SURF");
1501  return c2;
1502 }
1503 End_Macro
1504 
1505 The following example shows a 2D histogram plotted with the option
1506 `SURF1`. The option `SURF1` draws a surface plot using the
1507 hidden surface removal technique. Combined with the option `SURF1`,
1508 the option `Z` allows to display the color palette defined by
1509 `gStyle->SetPalette()`.
1510 
1511 Begin_Macro(source)
1512 {
1513  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1514  gStyle->SetPalette(kBird);
1515  TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1516  Float_t px, py;
1517  for (Int_t i = 0; i < 25000; i++) {
1518  gRandom->Rannor(px,py);
1519  hsurf1->Fill(px-1,5*py);
1520  hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1521  }
1522  hsurf1->Draw("SURF1");
1523  return c2;
1524 }
1525 End_Macro
1526 
1527 The following example shows a 2D histogram plotted with the option
1528 `SURF2`. The option `SURF2` draws a surface plot using colors
1529 to show the cell contents. Combined with the option `SURF2`, the option
1530 `Z` allows to display the color palette defined by
1531 `gStyle->SetPalette()`.
1532 
1533 Begin_Macro(source)
1534 {
1535  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1536  gStyle->SetPalette(kBird);
1537  TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
1538  Float_t px, py;
1539  for (Int_t i = 0; i < 25000; i++) {
1540  gRandom->Rannor(px,py);
1541  hsurf2->Fill(px-1,5*py);
1542  hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
1543  }
1544  hsurf2->Draw("SURF2");
1545  return c2;
1546 }
1547 End_Macro
1548 
1549 The following example shows a 2D histogram plotted with the option
1550 `SURF3`. The option `SURF3` draws a surface plot using the
1551 hidden line removal technique with, in addition, a filled contour view drawn on the
1552 top. Combined with the option `SURF3`, the option `Z` allows
1553 to display the color palette defined by `gStyle->SetPalette()`.
1554 
1555 Begin_Macro(source)
1556 {
1557  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1558  gStyle->SetPalette(kBird);
1559  TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
1560  Float_t px, py;
1561  for (Int_t i = 0; i < 25000; i++) {
1562  gRandom->Rannor(px,py);
1563  hsurf3->Fill(px-1,5*py);
1564  hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
1565  }
1566  hsurf3->Draw("SURF3");
1567  return c2;
1568 }
1569 End_Macro
1570 
1571 The following example shows a 2D histogram plotted with the option
1572 `SURF4`. The option `SURF4` draws a surface using the Gouraud
1573 shading technique.
1574 
1575 Begin_Macro(source)
1576 {
1577  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1578  TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
1579  Float_t px, py;
1580  for (Int_t i = 0; i < 25000; i++) {
1581  gRandom->Rannor(px,py);
1582  hsurf4->Fill(px-1,5*py);
1583  hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
1584  }
1585  hsurf4->SetFillColor(kOrange);
1586  hsurf4->Draw("SURF4");
1587  return c2;
1588 }
1589 End_Macro
1590 
1591 The following example shows a 2D histogram plotted with the option
1592 `SURF5 CYL`. Combined with the option `SURF5`, the option
1593 `Z` allows to display the color palette defined by `gStyle->SetPalette()`.
1594 
1595 Begin_Macro(source)
1596 {
1597  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1598  gStyle->SetPalette(kBird);
1599  TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
1600  Float_t px, py;
1601  for (Int_t i = 0; i < 25000; i++) {
1602  gRandom->Rannor(px,py);
1603  hsurf5->Fill(px-1,5*py);
1604  hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
1605  }
1606  hsurf5->SetFillColor(kOrange);
1607  hsurf5->Draw("SURF5 CYL");
1608  return c2;
1609 }
1610 End_Macro
1611 
1612 The following example shows a 2D histogram plotted with the option
1613 `SURF7`. The option `SURF7` draws a surface plot using the
1614 hidden surfaces removal technique with, in addition, a line contour view drawn on the
1615 top. Combined with the option `SURF7`, the option `Z` allows
1616 to display the color palette defined by `gStyle->SetPalette()`.
1617 
1618 Begin_Macro(source)
1619 {
1620  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1621  gStyle->SetPalette(kBird);
1622  TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
1623  Float_t px, py;
1624  for (Int_t i = 0; i < 25000; i++) {
1625  gRandom->Rannor(px,py);
1626  hsurf7->Fill(px-1,5*py);
1627  hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
1628  }
1629  hsurf7->Draw("SURF7");
1630  return c2;
1631 }
1632 End_Macro
1633 
1634 As shown in the following example, when a contour plot is painted on top of a
1635 surface plot using the option `SAME`, the contours appear in 3D on the
1636 surface.
1637 
1638 Begin_Macro(source)
1639 {
1640  TCanvas *c20=new TCanvas("c20","c20",600,400);
1641  int NBins = 50;
1642  double d = 2;
1643  TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
1644  for (int bx = 1; bx <= NBins; ++bx) {
1645  for (int by = 1; by <= NBins; ++by) {
1646  double x = hsc->GetXaxis()->GetBinCenter(bx);
1647  double y = hsc->GetYaxis()->GetBinCenter(by);
1648  hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
1649  }
1650  }
1651  gStyle->SetPalette(kBird);
1652  hsc->Draw("surf2");
1653  hsc->Draw("CONT1 SAME");
1654  return c20;
1655 }
1656 End_Macro
1657 
1658 
1659 ### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
1660 
1661 
1662 Legos and surfaces plots are represented by default in Cartesian coordinates.
1663 Combined with any `LEGOn` or `SURFn` options the following
1664 options allow to draw a lego or a surface in other coordinates systems.
1665 
1666 | Option | Description |
1667 |----------|-------------------------------------------------------------------|
1668 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
1669 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
1670 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
1671 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
1672 
1673 
1674 
1675 <b>WARNING:</b> Axis are not drawn with these options.
1676 
1677 The following example shows the same histogram as a lego plot is the four
1678 different coordinates systems.
1679 
1680 Begin_Macro(source)
1681 {
1682  TCanvas *c3 = new TCanvas("c3","c3",600,400);
1683  c3->Divide(2,2);
1684  TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
1685  Float_t px, py;
1686  for (Int_t i = 0; i < 25000; i++) {
1687  gRandom->Rannor(px,py);
1688  hlcc->Fill(px-1,5*py);
1689  hlcc->Fill(2+0.5*px,2*py-10.,0.1);
1690  }
1691  hlcc->SetFillColor(kYellow);
1692  c3->cd(1); hlcc->Draw("LEGO1 CYL");
1693  c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
1694  hlpc->SetTitle("Polar coordinates");
1695  c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
1696  hlsc->SetTitle("Spherical coordinates");
1697  c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
1698  hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
1699  return c3;
1700 }
1701 End_Macro
1702 
1703 The following example shows the same histogram as a surface plot is the four different coordinates systems.
1704 
1705 Begin_Macro(source)
1706 {
1707  TCanvas *c4 = new TCanvas("c4","c4",600,400);
1708  c4->Divide(2,2);
1709  TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
1710  Float_t px, py;
1711  for (Int_t i = 0; i < 25000; i++) {
1712  gRandom->Rannor(px,py);
1713  hscc->Fill(px-1,5*py);
1714  hscc->Fill(2+0.5*px,2*py-10.,0.1);
1715  }
1716  gStyle->SetPalette(kBird);
1717  c4->cd(1); hscc->Draw("SURF1 CYL");
1718  c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
1719  hspc->SetTitle("Polar coordinates");
1720  c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
1721  hssc->SetTitle("Spherical coordinates");
1722  c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
1723  hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
1724  return c4;
1725 }
1726 End_Macro
1727 
1728 
1729 ### <a name="HP20"></a> Base line for bar-charts and lego plots
1730 
1731 
1732 By default the base line used to draw the boxes for bar-charts and lego plots is
1733 the histogram minimum. It is possible to force this base line to be 0 with the
1734 command:
1735 
1736  gStyle->SetHistMinimumZero();
1737 
1738 Begin_Macro(source)
1739 {
1740  TCanvas *c5 = new TCanvas("c5","c5",700,400);
1741  c5->Divide(2,1);
1742  gStyle->SetHistMinimumZero(1);
1743  TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
1744  TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
1745  Int_t i;
1746  Double_t x,y;
1747  hz1->SetFillColor(kBlue);
1748  hz2->SetFillColor(kBlue);
1749  for (i=0;i<10000;i++) {
1750  x = gRandom->Gaus(0,1);
1751  y = gRandom->Gaus(0,1);
1752  if (x>0) {
1753  hz1->Fill(x,1);
1754  hz2->Fill(x,y,1);
1755  } else {
1756  hz1->Fill(x,-1);
1757  hz2->Fill(x,y,-2);
1758  }
1759  }
1760  c5->cd(1); hz1->Draw("bar2");
1761  c5->cd(2); hz2->Draw("lego1");
1762  return c5;
1763 }
1764 End_Macro
1765 
1766 This option also works for horizontal plots. The example given in the section
1767 ["The bar chart option"](#HP100) appears as follow:
1768 
1769 Begin_Macro(source)
1770 {
1771  int i;
1772  const Int_t nx = 8;
1773  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
1774  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
1775  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
1776 
1777  TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
1778  cbh->SetGrid();
1779 
1780  gStyle->SetHistMinimumZero();
1781 
1782  TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
1783  h1bh->SetFillColor(4);
1784  h1bh->SetBarWidth(0.4);
1785  h1bh->SetBarOffset(0.1);
1786  h1bh->SetStats(0);
1787  h1bh->SetMinimum(-5);
1788  h1bh->SetMaximum(5);
1789 
1790  for (i=1; i<=nx; i++) {
1791  h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
1792  h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
1793  }
1794 
1795  h1bh->Draw("hbar");
1796 
1797  TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
1798  h2bh->SetFillColor(38);
1799  h2bh->SetBarWidth(0.4);
1800  h2bh->SetBarOffset(0.5);
1801  h2bh->SetStats(0);
1802  for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
1803 
1804  h2bh->Draw("hbar same");
1805 
1806  return cbh;
1807 }
1808 End_Macro
1809 
1810 
1811 ### <a name="HP20a"></a> TH2Poly Drawing
1812 
1813 
1814 The following options are supported:
1815 
1816 | Option | Description |
1817 |----------|-------------------------------------------------------------------|
1818 | "SCAT" | Draw a scatter plot (default).|
1819 | "COL" | Draw a color plot. All the none empty bins are painted. Empty bins are not painted.|
1820 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
1821 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
1822 | "TEXTN" | Draw bin names as text.|
1823 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
1824 | "L" | Draw the bins boundaries as lines. The lines attibutes are the TGraphs ones.|
1825 | "P" | Draw the bins boundaries as markers. The markers attibutes are the TGraphs ones.|
1826 | "F" | Draw the bins boundaries as filled polygons. The filled polygons attibutes are the TGraphs ones.|
1827 
1828 
1829 
1830 `TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
1831 shapes. The bins are defined as graphs. The following macro is a very simple
1832 example showing how to book a TH2Poly and draw it.
1833 
1834 Begin_Macro(source)
1835 {
1836  TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
1837  TH2Poly *h2p = new TH2Poly();
1838  h2p->SetName("h2poly_name");
1839  h2p->SetTitle("h2poly_title");
1840  Double_t px1[] = {0, 5, 6};
1841  Double_t py1[] = {0, 0, 5};
1842  Double_t px2[] = {0, -1, -1, 0};
1843  Double_t py2[] = {0, 0, -1, 3};
1844  Double_t px3[] = {4, 3, 0, 1, 2.4};
1845  Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
1846  h2p->AddBin(3, px1, py1);
1847  h2p->AddBin(4, px2, py2);
1848  h2p->AddBin(5, px3, py3);
1849  h2p->Fill(0.1, 0.01, 3);
1850  h2p->Fill(-0.5, -0.5, 7);
1851  h2p->Fill(-0.7, -0.5, 1);
1852  h2p->Fill(1, 3, 1.5);
1853  Double_t fx[] = {0.1, -0.5, -0.7, 1};
1854  Double_t fy[] = {0.01, -0.5, -0.5, 3};
1855  Double_t fw[] = {3, 1, 1, 1.5};
1856  h2p->FillN(4, fx, fy, fw);
1857  gStyle->SetPalette(kBird);
1858  h2p->Draw("col");
1859  return ch2p1;
1860 }
1861 End_Macro
1862 
1863 Rectangular bins are a frequent case. The special version of
1864 the `AddBin` method allows to define them more easily like
1865 shown in the following example.
1866 
1867 Begin_Macro(source)
1868 ../../../tutorials/hist/th2polyBoxes.C
1869 End_Macro
1870 
1871 One `TH2Poly` bin can be a list of polygons. Such bins are defined
1872 by calling `AddBin` with a `TMultiGraph`. The following example
1873 shows a such case:
1874 
1875 Begin_Macro(source)
1876 {
1877  TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
1878 
1879  Int_t i, bin;
1880  const Int_t nx = 48;
1881  const char *states [nx] = {
1882  "alabama", "arizona", "arkansas", "california",
1883  "colorado", "connecticut", "delaware", "florida",
1884  "georgia", "idaho", "illinois", "indiana",
1885  "iowa", "kansas", "kentucky", "louisiana",
1886  "maine", "maryland", "massachusetts", "michigan",
1887  "minnesota", "mississippi", "missouri", "montana",
1888  "nebraska", "nevada", "new_hampshire", "new_jersey",
1889  "new_mexico", "new_york", "north_carolina", "north_dakota",
1890  "ohio", "oklahoma", "oregon", "pennsylvania",
1891  "rhode_island", "south_carolina", "south_dakota", "tennessee",
1892  "texas", "utah", "vermont", "virginia",
1893  "washington", "west_virginia", "wisconsin", "wyoming"
1894  };
1895  Double_t pop[nx] = {
1896  4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
1897  9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
1898  1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
1899  1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
1900  11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
1901  24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
1902  };
1903 
1904  Double_t lon1 = -130;
1905  Double_t lon2 = -65;
1906  Double_t lat1 = 24;
1907  Double_t lat2 = 50;
1908  TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
1909 
1910  TFile *f;
1911  f = TFile::Open("http://root.cern.ch/files/usa.root");
1912 
1913  TMultiGraph *mg;
1914  TKey *key;
1915  TIter nextkey(gDirectory->GetListOfKeys());
1916  while ((key = (TKey*)nextkey())) {
1917  TObject *obj = key->ReadObj();
1918  if (obj->InheritsFrom("TMultiGraph")) {
1919  mg = (TMultiGraph*)obj;
1920  bin = p->AddBin(mg);
1921  }
1922  }
1923 
1924  for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
1925 
1926  gStyle->SetOptStat(11);
1927  gStyle->SetPalette(kBird);
1928  p->Draw("COLZ L");
1929  return ch2p2;
1930 }
1931 End_Macro
1932 
1933 `TH2Poly` histograms can also be plotted using the GL interface using
1934 the option "GLLEGO".
1935 
1936 ### <a name="HP21"></a> The SPEC option
1937 
1938 
1939 This option allows to use the `TSpectrum2Painter` tools. See the full
1940 documentation in `TSpectrum2Painter::PaintSpectrum`.
1941 
1942 
1943 ### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
1944 
1945 
1946 When this option is specified, a color palette with an axis indicating the value
1947 of the corresponding color is drawn on the right side of the picture. In case,
1948 not enough space is left, one can increase the size of the right margin by
1949 calling `TPad::SetRightMargin()`. The attributes used to display the
1950 palette axis values are taken from the Z axis of the object. For example, to
1951 set the labels size on the palette axis do:
1952 
1953  hist->GetZaxis()->SetLabelSize().
1954 
1955 <b>WARNING:</b> The palette axis is always drawn vertically.
1956 
1957 
1958 ### <a name="HP23"></a> Setting the color palette
1959 
1960 
1961 To change the color palette `TStyle::SetPalette` should be used, eg:
1962 
1963  gStyle->SetPalette(ncolors,colors);
1964 
1965 For example the option `COL` draws a 2D histogram with cells
1966 represented by a box filled with a color index which is a function
1967 of the cell content.
1968 If the cell content is N, the color index used will be the color number
1969 in `colors[N]`, etc. If the maximum cell content is greater than
1970 `ncolors`, all cell contents are scaled to `ncolors`.
1971 
1972 If ` ncolors <= 0`, a default palette (see below) of 50 colors is
1973 defined. This palette is recommended for pads, labels ...
1974 
1975 `if ncolors == 1 && colors == 0`, then a Pretty Palette with a
1976 Spectrum Violet->Red is created with 50 colors. That's the default rain bow
1977 palette.
1978 
1979 Other prefined palettes with 255 colors are available when `colors == 0`.
1980 The following value of `ncolors` give access to:
1981 
1982 
1983  if ncolors = 51 and colors=0, a Deep Sea palette is used.
1984  if ncolors = 52 and colors=0, a Grey Scale palette is used.
1985  if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
1986  if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
1987  if ncolors = 55 and colors=0, a Rain Bow palette is used.
1988  if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
1989 
1990 
1991 If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
1992 
1993 The default palette defines:
1994 
1995 - index 0 to 9 : shades of grey
1996 - index 10 to 19 : shades of brown
1997 - index 20 to 29 : shades of blue
1998 - index 30 to 39 : shades of red
1999 - index 40 to 49 : basic colors
2000 
2001 The color numbers specified in the palette can be viewed by selecting
2002 the item `colors` in the `VIEW` menu of the canvas tool bar.
2003 The red, green, and blue components of a color can be changed thanks to
2004 `TColor::SetRGB()`.
2005 
2006 
2007 ### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2008 
2009 
2010 Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2011 histogram. One must create a graphical cut (mouse or C++) and specify the name
2012 of the cut between `[]` in the `Draw()` option.
2013 For example, with a `TCutG` named `cutg`, one can call:
2014 
2015  myhist->Draw("surf1 [cutg]");
2016 
2017 To invert the cut, it is enough to put a `-` in front of its name:
2018 
2019  myhist->Draw("surf1 [-cutg]");
2020 
2021 It is possible to apply several cuts (`,` means logical AND):
2022 
2023  myhist->Draw("surf1 [cutg1,cutg2]");
2024 
2025 Begin_Macro(source)
2026 ../../../tutorials/fit/fit2a.C
2027 End_Macro
2028 
2029 ### <a name="HP25"></a> Drawing options for 3D histograms
2030 
2031 
2032 | Option | Description |
2033 |----------|-------------------------------------------------------------------|
2034 | "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)`|
2035 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value.|
2036 
2037 
2038 
2039 By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2040 
2041 The following example shows a 3D histogram plotted as a scatter plot.
2042 
2043 Begin_Macro(source)
2044 {
2045  TCanvas *c06 = new TCanvas("c06","c06",600,400);
2046  gStyle->SetOptStat(kFALSE);
2047  TH3F *h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2048  Double_t x, y, z;
2049  for (Int_t i=0;i<10000;i++) {
2050  gRandom->Rannor(x, y);
2051  z = x*x + y*y;
2052  h3scat->Fill(x,y,z);
2053  }
2054  h3scat->Draw();
2055  return c06;
2056 }
2057 End_Macro
2058 
2059 The following example shows a 3D histogram plotted with the option `BOX`.
2060 
2061 Begin_Macro(source)
2062 {
2063  TCanvas *c16 = new TCanvas("c16","c16",600,400);
2064  gStyle->SetOptStat(kFALSE);
2065  TH3F *h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2066  Double_t x, y, z;
2067  for (Int_t i=0;i<10000;i++) {
2068  gRandom->Rannor(x, y);
2069  z = x*x + y*y;
2070  h3box->Fill(x,y,z);
2071  }
2072  h3box->Draw("BOX");
2073  return c16;
2074 }
2075 End_Macro
2076 
2077 The following example shows a 3D histogram plotted with the option `ISO`.
2078 
2079 Begin_Macro(source)
2080 {
2081  TCanvas *c26 = new TCanvas("c26","c26",600,400);
2082  gStyle->SetOptStat(kFALSE);
2083  TH3F *h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2084  Double_t x, y, z;
2085  for (Int_t i=0;i<10000;i++) {
2086  gRandom->Rannor(x, y);
2087  z = x*x + y*y;
2088  h3iso->Fill(x,y,z);
2089  }
2090  h3iso->SetFillColor(kCyan);
2091  h3iso->Draw("ISO");
2092  return c26;
2093 }
2094 End_Macro
2095 
2096 
2097 ### <a name="HP26"></a> Drawing option for histograms' stacks
2098 
2099 
2100 Stacks of histograms are managed with the `THStack`. A `THStack`
2101 is a collection of `TH1` (or derived) objects. For painting only the
2102 `THStack` containing `TH1` only or
2103 `THStack` containing `TH2` only will be considered.
2104 
2105 By default, histograms are shown stacked:
2106 
2107 1. The first histogram is paint.
2108 2. The the sum of the first and second, etc...
2109 
2110 If the option `NOSTACK` is specified, the histograms are all paint in
2111 the same pad as if the option `SAME` had been specified. This allows to
2112 compute X and Y scales common to all the histograms, like
2113 `TMultiGraph` does for graphs.
2114 
2115 If the option `PADS` is specified, the current pad/canvas is
2116 subdivided into a number of pads equal to the number of histograms and each
2117 histogram is paint into a separate pad.
2118 
2119 The following example shows various types of stacks.
2120 
2121 Begin_Macro(source)
2122 ../../../tutorials/hist/hstack.C
2123 End_Macro
2124 
2125 The option `nostackb` allows to draw the histograms next to each
2126 other as bar charts:
2127 
2128 Begin_Macro(source)
2129 {
2130  TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2131  THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2132 
2133  TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2134  h1->FillRandom("gaus",20000);
2135  h1->SetFillColor(kRed);
2136  hs->Add(h1);
2137 
2138  TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2139  h2->FillRandom("gaus",15000);
2140  h2->SetFillColor(kBlue);
2141  hs->Add(h2);
2142 
2143  TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2144  h3->FillRandom("gaus",10000);
2145  h3->SetFillColor(kGreen);
2146  hs->Add(h3);
2147 
2148  hs->Draw("nostackb");
2149  hs->GetXaxis()->SetNdivisions(-10);
2150  cst0->SetGridx();
2151  return cst0;
2152 }
2153 End_Macro
2154 
2155 If at least one of the histograms in the stack has errors, the whole stack is
2156 visualized by default with error bars. To visualize it without errors the
2157 option `HIST` should be used.
2158 
2159 Begin_Macro(source)
2160 {
2161  TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2162  cst1->Divide(2,1);
2163 
2164  TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2165  hst11->Sumw2();
2166  hst11->FillRandom("gaus", 1000);
2167  hst11->SetFillColor(kViolet);
2168  hst11->SetLineColor(kViolet);
2169 
2170  TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2171  hst12->FillRandom("gaus", 500);
2172  hst12->SetFillColor(kBlue);
2173  hst12->SetLineColor(kBlue);
2174 
2175  THStack st1("st1", "st1");
2176  st1.Add(hst11);
2177  st1.Add(hst12);
2178 
2179  cst1->cd(1); st1.Draw();
2180  cst1->cd(2); st1.Draw("hist");
2181 
2182  return cst1;
2183 }
2184 End_Macro
2185 
2186 ### <a name="HP27"></a> Drawing of 3D implicit functions
2187 
2188 
2189 3D implicit functions (`TF3`) can be drawn as iso-surfaces.
2190 The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2191 In the following example the options "FB" and "BB" suppress the
2192 "Front Box" and "Back Box" around the plot.
2193 
2194 Begin_Macro(source)
2195 {
2196  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2197  TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2198  f3->SetClippingBoxOn(0,0,0);
2199  f3->SetFillColor(30);
2200  f3->SetLineColor(15);
2201  f3->Draw("FBBB");
2202  return c2;
2203 }
2204 End_Macro
2205 
2206 
2207 ### <a name="HP28"></a> Associated functions drawing
2208 
2209 
2210 An associated function is created by `TH1::Fit`. More than on fitted
2211 function can be associated with one histogram (see `TH1::Fit`).
2212 
2213 A `TF1` object `f1` can be added to the list of associated
2214 functions of an histogram `h` without calling `TH1::Fit`
2215 simply doing:
2216 
2217  h->GetListOfFunctions()->Add(f1);
2218 
2219 or
2220 
2221  h->GetListOfFunctions()->Add(f1,someoption);
2222 
2223 To retrieve a function by name from this list, do:
2224 
2225  TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2226 
2227 or
2228 
2229  TF1 *f1 = h->GetFunction(name);
2230 
2231 Associated functions are automatically painted when an histogram is drawn.
2232 To avoid the painting of the associated functions the option `HIST`
2233 should be added to the list of the options used to paint the histogram.
2234 
2235 
2236 ### <a name="HP29"></a> Drawing using OpenGL
2237 
2238 
2239 The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2240 graphics library. The plotting options start with `GL` keyword.
2241 In addition, in order to inform canvases that OpenGL should be used to render
2242 3D representations, the following option should be set:
2243 
2244  gStyle->SetCanvasPreferGL(true);
2245 
2246 
2247 #### <a name="HP29a"></a> General information: plot types and supported options
2248 
2249 The following types of plots are provided:
2250 
2251 For lego plots the supported options are:
2252 
2253 | Option | Description |
2254 |----------|-------------------------------------------------------------------|
2255 | "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2256 | "GLLEGO2"| Bins with color levels.|
2257 | "GLLEGO3"| Cylindrical bars.|
2258 
2259 
2260 
2261 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2262 In polar only Z axis can be logarithmic, in cylindrical only Y.
2263 
2264 For surface plots (`TF2` and `TH2`) the supported options are:
2265 
2266 | Option | Description |
2267 |-----------|------------------------------------------------------------------|
2268 | "GLSURF" | Draw a surface.|
2269 | "GLSURF1" | Surface with color levels|
2270 | "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2271 | "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2272 | "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2273 
2274 
2275 
2276 The surface painting in cartesian coordinates supports logarithmic scales along
2277 X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2278 in cylindrical coordinates only the Y axis.
2279 
2280 Additional options to SURF and LEGO - Coordinate systems:
2281 
2282 | Option | Description |
2283 |----------|-------------------------------------------------------------------|
2284 | " " | Default, cartesian coordinates system.|
2285 | "POL" | Polar coordinates system.|
2286 | "CYL" | Cylindrical coordinates system.|
2287 | "SPH" | Spherical coordinates system.|
2288 
2289 
2290 
2291 #### <a name="HP290"></a> TH3 as color boxes
2292 
2293 The supported option is:
2294 
2295 | Option | Description |
2296 |----------|-------------------------------------------------------------------|
2297 | "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2298 
2299 
2300 
2301 #### <a name="HP29b"></a> TH3 as boxes (spheres)
2302 
2303 The supported options are:
2304 
2305 | Option | Description |
2306 |----------|-------------------------------------------------------------------|
2307 | "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2308 | "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2309 
2310 
2311 
2312 #### <a name="HP29c"></a> TH3 as iso-surface(s)
2313 
2314 The supported option is:
2315 
2316 | Option | Description |
2317 |----------|-------------------------------------------------------------------|
2318 | "GLISO" | TH3 is drawn using iso-surfaces.|
2319 
2320 
2321 
2322 #### <a name="HP29d"></a> TF3 (implicit function)
2323 
2324 The supported option is:
2325 
2326 | Option | Description |
2327 |----------|-------------------------------------------------------------------|
2328 | "GLTF3" | Draw a TF3.|
2329 
2330 
2331 
2332 #### <a name="HP29e"></a> Parametric surfaces
2333 
2334 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2335 equations and visualize the surface.
2336 
2337 #### <a name="HP29f"></a> Interaction with the plots
2338 
2339 All the interactions are implemented via standard methods
2340 `DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2341 interactions with the OpenGL plots are possible only when the mouse cursor is
2342 in the plot's area (the plot's area is the part of a the pad occupied by
2343 gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2344 pad interaction is performed.
2345 
2346 #### <a name="HP29g"></a> Selectable parts
2347 
2348 Different parts of the plot can be selected:
2349 
2350 - xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2351  if the dynamic slicing by this plane is supported, and it's highlighted in red,
2352  if the dynamic slicing is not supported.
2353 - The plot itself:
2354  On surfaces, the selected surface is outlined in red. (TF3 and
2355  ISO are not outlined). On lego plots, the selected bin is
2356  highlighted. The bin number and content are displayed in pad's
2357  status bar. In box plots, the box or sphere is highlighted and
2358  the bin info is displayed in pad's status bar.
2359 
2360 
2361 #### <a name="HP29h"></a> Rotation and zooming
2362 
2363 
2364 - Rotation:
2365  When the plot is selected, it can be rotated by pressing and
2366  holding the left mouse button and move the cursor.
2367 - Zoom/Unzoom:
2368  Mouse wheel or 'j', 'J', 'k', 'K' keys.
2369 
2370 
2371 #### <a name="HP29i"></a> Panning
2372 
2373 The selected plot can be moved in a pad's area by pressing and
2374 holding the left mouse button and the shift key.
2375 
2376 #### <a name="HP29j"></a> Box cut
2377 
2378 Surface, iso, box, TF3 and parametric painters support box cut by
2379 pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2380 area. That will display a transparent box, cutting away part of the
2381 surface (or boxes) in order to show internal part of plot. This box
2382 can be moved inside the plot's area (the full size of the box is
2383 equal to the plot's surrounding box) by selecting one of the box
2384 cut axes and pressing the left mouse button to move it.
2385 
2386 #### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2387 
2388 Currently, all gl-plots support some form of slicing. When back plane
2389 is selected (and if it's highlighted in green) you can press and hold
2390 left mouse button and shift key and move this back plane inside
2391 plot's area, creating the slice. During this "slicing" plot becomes
2392 semi-transparent. To remove all slices (and projected curves for
2393 surfaces) double click with left mouse button in a plot's area.
2394 
2395 #### <a name="HP29l"></a> Surface with option "GLSURF"
2396 
2397 The surface profile is displayed on the slicing plane.
2398 The profile projection is drawn on the back plane
2399 by pressing `'p'` or `'P'` key.
2400 
2401 #### <a name="HP29m"></a> TF3
2402 
2403 The contour plot is drawn on the slicing plane. For TF3 the color
2404 scheme can be changed by pressing 's' or 'S'.
2405 
2406 #### <a name="HP29n"></a> Box
2407 
2408 The contour plot corresponding to slice plane position is drawn in real time.
2409 
2410 #### <a name="HP29o"></a> Iso
2411 
2412 Slicing is similar to "GLBOX" option.
2413 
2414 #### <a name="HP29p"></a> Parametric plot
2415 
2416 No slicing. Additional keys: 's' or 'S' to change color scheme -
2417 about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2418 increase number of polygons ('l' for "level" of details), 'w' or 'W'
2419 to show outlines ('w' for "wireframe").
2420 
2421 */
2422 
2423 TH1 *gCurrentHist = 0;
2424 
2427 
2428 const Int_t kNMAX = 2000;
2430 const Int_t kMAXCONTOUR = 104;
2433 static TString gStringEntries;
2435 static TString gStringMeanX;
2438 static TString gStringStdDev;
2458 ////////////////////////////////////////////////////////////////////////////////
2459 /// Default constructor.
2460 
2462 {
2463 
2464  fH = 0;
2465  fXaxis = 0;
2466  fYaxis = 0;
2467  fZaxis = 0;
2468  fFunctions = 0;
2469  fXbuf = 0;
2470  fYbuf = 0;
2471  fNcuts = 0;
2472  fStack = 0;
2473  fLego = 0;
2474  fPie = 0;
2475  fGraph2DPainter = 0;
2476  fShowProjection = 0;
2477  fShowOption = "";
2478  for (int i=0; i<kMaxCuts; i++) {
2479  fCuts[i] = 0;
2480  fCutsOpt[i] = 0;
2481  }
2482 
2483  gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
2484  gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
2485  gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
2486  gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
2487  gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
2488  gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
2489  gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
2490  gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
2491  gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
2492  gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
2493  gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
2494  gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
2495  gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
2496  gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
2497  gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
2498  gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
2499  gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
2500  gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
2501  gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
2502  gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
2503  gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
2504 }
2505 
2506 
2507 ////////////////////////////////////////////////////////////////////////////////
2508 /// Default destructor.
2509 
2511 {
2512 }
2513 
2514 
2515 ////////////////////////////////////////////////////////////////////////////////
2516 /// Compute the distance from the point px,py to a line.
2517 ///
2518 /// Compute the closest distance of approach from point px,py to elements of
2519 /// an histogram. The distance is computed in pixels units.
2520 ///
2521 /// Algorithm: Currently, this simple model computes the distance from the mouse
2522 /// to the histogram contour only.
2523 
2525 {
2526 
2527 
2528  const Int_t big = 9999;
2529  const Int_t kMaxDiff = 7;
2531  if (fPie) return fPie->DistancetoPrimitive(px, py);
2532 
2533  Double_t x = gPad->AbsPixeltoX(px);
2534  Double_t x1 = gPad->AbsPixeltoX(px+1);
2535 
2536  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
2537  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
2538  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
2539  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
2540  Int_t curdist = big;
2541  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
2542  Bool_t dsame;
2543  TObject *PadPointer = gPad->GetPadPointer();
2544  if (!PadPointer) return 0;
2545  TString doption = PadPointer->GetDrawOption();
2546  Double_t factor = 1;
2547  if (fH->GetNormFactor() != 0) {
2548  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
2549  }
2550  // return if point is not in the histogram area
2551 
2552  // If a 3D view exists, check distance to axis
2553  TView *view = gPad->GetView();
2554  Int_t d1,d2,d3;
2555  if (view && Hoption.Contour != 14) {
2556  Double_t ratio;
2557  d3 = view->GetDistancetoAxis(3, px, py, ratio);
2558  if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
2559  d1 = view->GetDistancetoAxis(1, px, py, ratio);
2560  if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
2561  d2 = view->GetDistancetoAxis(2, px, py, ratio);
2562  if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
2563  if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
2564  goto FUNCTIONS;
2565  }
2566  // check if point is close to an axis
2567  doption.ToLower();
2568  dsame = kFALSE;
2569  if (doption.Contains("same")) dsame = kTRUE;
2570 
2571  dyaxis = Int_t(2*(puymin-puymax)*fYaxis->GetLabelSize());
2572  if (doption.Contains("y+")) {
2573  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2574  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
2575  if (!dsame) {
2576  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2577  else gPad->SetSelected(fXaxis);
2578  return 0;
2579  }
2580  }
2581  } else {
2582  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2583  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
2584  if (!dsame) {
2585  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2586  else gPad->SetSelected(fXaxis);
2587  return 0;
2588  }
2589  }
2590  }
2591 
2592  dxaxis = Int_t((puymin-puymax)*fXaxis->GetLabelSize());
2593  if (doption.Contains("x+")) {
2594  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2595  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
2596  if (!dsame) {
2597  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2598  else gPad->SetSelected(fYaxis);
2599  return 0;
2600  }
2601  }
2602  } else {
2603  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2604  if (yxaxis < puymin) yxaxis = puymin;
2605  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
2606  if (!dsame) {
2607  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2608  else gPad->SetSelected(fYaxis);
2609  return 0;
2610  }
2611  }
2612  }
2613 
2614  // if object is 2D or 3D return this object
2615  if (fH->GetDimension() == 2) {
2616  if (fH->InheritsFrom(TH2Poly::Class())) {
2617  TH2Poly *th2 = (TH2Poly*)fH;
2618  Double_t xmin, ymin, xmax, ymax;
2619  gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
2620  Double_t pxu = gPad->AbsPixeltoX(px);
2621  Double_t pyu = gPad->AbsPixeltoY(py);
2622  if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
2623  curdist = big;
2624  goto FUNCTIONS;
2625  } else {
2626  Int_t bin = th2->FindBin(pxu, pyu);
2627  if (bin>0) curdist = 1;
2628  else curdist = big;
2629  goto FUNCTIONS;
2630  }
2631  }
2632  Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
2633  if ( px > puxmin + delta2
2634  && px < puxmax - delta2
2635  && py > puymax + delta2
2636  && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
2637  }
2638 
2639  // point is inside histogram area. Find channel number
2640  if (gPad->IsVertical()) {
2641  Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
2642  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
2643  Double_t binval = factor*fH->GetBinContent(bin);
2644  Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
2645  if (binval == 0 && pybin < puymin) pybin = 10000;
2646  // special case if more than one bin for the pixel
2647  if (binsup-bin>1) {
2648  Double_t binvalmin, binvalmax;
2649  binvalmin=binval;
2650  binvalmax=binval;
2651  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2652  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2653  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2654  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2655  }
2656  Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
2657  Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
2658  if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
2659  }
2660  if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
2661  } else {
2662  Double_t y = gPad->AbsPixeltoY(py);
2663  Double_t y1 = gPad->AbsPixeltoY(py+1);
2664  Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
2665  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
2666  Double_t binval = factor*fH->GetBinContent(bin);
2667  Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
2668  if (binval == 0 && pxbin > puxmin) pxbin = 10000;
2669  // special case if more than one bin for the pixel
2670  if (binsup-bin>1) {
2671  Double_t binvalmin, binvalmax;
2672  binvalmin=binval;
2673  binvalmax=binval;
2674  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2675  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2676  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2677  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2678  }
2679  Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
2680  Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
2681  if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
2682  }
2683  if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
2684  }
2685  // Loop on the list of associated functions and user objects
2686 FUNCTIONS:
2687  TObject *f;
2689  while ((f = (TObject*) next())) {
2690  Int_t dist;
2691  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
2692  else dist = f->DistancetoPrimitive(px,py);
2693  if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
2694  }
2695  return curdist;
2696 }
2697 
2698 
2699 ////////////////////////////////////////////////////////////////////////////////
2700 /// Display a panel with all histogram drawing options.
2701 
2703 {
2704 
2705  gCurrentHist = fH;
2706  if (!gPad) {
2707  Error("DrawPanel", "need to draw histogram first");
2708  return;
2709  }
2711  editor->Show();
2712  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
2713  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
2714 }
2715 
2716 
2717 ////////////////////////////////////////////////////////////////////////////////
2718 /// Execute the actions corresponding to `event`.
2719 ///
2720 /// This function is called when a histogram is clicked with the locator at
2721 /// the pixel position px,py.
2722 
2723 void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py)
2724 {
2725 
2726  if (!gPad) return;
2727 
2728  static Int_t bin, px1, py1, px2, py2, pyold;
2729  static TBox *zoombox;
2730  Double_t zbx1,zbx2,zby1,zby2;
2731 
2732  Int_t bin1, bin2;
2733  Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
2734  Bool_t opaque = gPad->OpaqueMoving();
2735 
2736  if (!gPad->IsEditable()) return;
2737 
2738  if (fPie) {
2739  fPie->ExecuteEvent(event, px, py);
2740  return;
2741  }
2742  // come here if we have a lego/surface in the pad
2743  TView *view = gPad->GetView();
2744 
2745  if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
2746  view->ExecuteRotateView(event, px, py);
2747  return;
2748  }
2749 
2750  TAxis *xaxis = fH->GetXaxis();
2751  TAxis *yaxis = fH->GetYaxis();
2752  Int_t dimension = fH->GetDimension();
2753 
2754  Double_t factor = 1;
2755  if (fH->GetNormFactor() != 0) {
2756  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
2757  }
2758 
2759  switch (event) {
2760 
2761  case kButton1Down:
2762 
2763  if (!opaque) gVirtualX->SetLineColor(-1);
2764  fH->TAttLine::Modify();
2765 
2766  if (opaque && dimension ==2) {
2767  zbx1 = gPad->AbsPixeltoX(px);
2768  zbx2 = gPad->AbsPixeltoX(px);
2769  zby1 = gPad->AbsPixeltoY(py);
2770  zby2 = gPad->AbsPixeltoY(py);
2771  px1 = px;
2772  py1 = py;
2773  if (gPad->GetLogx()) {
2774  zbx1 = TMath::Power(10,zbx1);
2775  zbx2 = TMath::Power(10,zbx2);
2776  }
2777  if (gPad->GetLogy()) {
2778  zby1 = TMath::Power(10,zby1);
2779  zby2 = TMath::Power(10,zby2);
2780  }
2781  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
2782  Int_t ci = TColor::GetColor("#7d7dff");
2783  TColor *zoomcolor = gROOT->GetColor(ci);
2784  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
2785  else zoomcolor->SetAlpha(0.5);
2786  zoombox->SetFillColor(ci);
2787  zoombox->Draw();
2788  gPad->Modified();
2789  gPad->Update();
2790  }
2791  // No break !!!
2792 
2793  case kMouseMotion:
2794 
2795  if (fShowProjection) {ShowProjection3(px,py); break;}
2796 
2797  gPad->SetCursor(kPointer);
2798  if (dimension ==1) {
2799  if (Hoption.Bar) {
2800  baroffset = fH->GetBarOffset();
2801  barwidth = fH->GetBarWidth();
2802  } else {
2803  baroffset = 0;
2804  barwidth = 1;
2805  }
2806  x = gPad->AbsPixeltoX(px);
2807  bin = fXaxis->FindFixBin(gPad->PadtoX(x));
2808  binwidth = fXaxis->GetBinWidth(bin);
2809  xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
2810  xup = gPad->XtoPad(xlow + barwidth*binwidth);
2811  ylow = gPad->GetUymin();
2812  px1 = gPad->XtoAbsPixel(xlow);
2813  px2 = gPad->XtoAbsPixel(xup);
2814  py1 = gPad->YtoAbsPixel(ylow);
2815  py2 = py;
2816  pyold = py;
2817  if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
2818  }
2819 
2820  break;
2821 
2822  case kButton1Motion:
2823 
2824  if (dimension ==1) {
2825  if (gROOT->GetEditHistograms()) {
2826  if (!opaque) {
2827  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
2828  py2 += py - pyold;
2829  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
2830  pyold = py;
2831  } else {
2832  py2 += py - pyold;
2833  pyold = py;
2834  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
2835  fH->SetBinContent(bin,binval);
2836  gPad->Modified(kTRUE);
2837  }
2838  }
2839  }
2840 
2841  if (opaque && dimension ==2) {
2842  if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
2843  zbx2 = gPad->AbsPixeltoX(px);
2844  zby2 = gPad->AbsPixeltoY(py);
2845  if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
2846  if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
2847  zoombox->SetX2(zbx2);
2848  zoombox->SetY2(zby2);
2849  gPad->Modified();
2850  gPad->Update();
2851  }
2852  }
2853 
2854  break;
2855 
2856  case kWheelUp:
2857 
2858  if (dimension ==2) {
2859  bin1 = xaxis->GetFirst()+1;
2860  bin2 = xaxis->GetLast()-1;
2861  bin1 = TMath::Max(bin1, 1);
2862  bin2 = TMath::Min(bin2, xaxis->GetNbins());
2863  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
2864  bin1 = yaxis->GetFirst()+1;
2865  bin2 = yaxis->GetLast()-1;
2866  bin1 = TMath::Max(bin1, 1);
2867  bin2 = TMath::Min(bin2, yaxis->GetNbins());
2868  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
2869  }
2870  gPad->Modified();
2871  gPad->Update();
2872 
2873  break;
2874 
2875  case kWheelDown:
2876 
2877  if (dimension == 2) {
2878  bin1 = xaxis->GetFirst()-1;
2879  bin2 = xaxis->GetLast()+1;
2880  bin1 = TMath::Max(bin1, 1);
2881  bin2 = TMath::Min(bin2, xaxis->GetNbins());
2882  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
2883  bin1 = yaxis->GetFirst()-1;
2884  bin2 = yaxis->GetLast()+1;
2885  bin1 = TMath::Max(bin1, 1);
2886  bin2 = TMath::Min(bin2, yaxis->GetNbins());
2887  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
2888  }
2889  gPad->Modified();
2890  gPad->Update();
2891 
2892  break;
2893 
2894  case kButton1Up:
2895  if (dimension ==1) {
2896  if (gROOT->GetEditHistograms()) {
2897  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
2898  fH->SetBinContent(bin,binval);
2899  PaintInit(); // recalculate Hparam structure and recalculate range
2900  }
2901 
2902  // might resize pad pixmap so should be called before any paint routine
2903  RecalculateRange();
2904  }
2905  if (opaque && dimension ==2) {
2906  if (zoombox) {
2907  Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
2908  Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
2909  Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
2910  Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
2911  x1 = TMath::Max(x1,xaxis->GetXmin());
2912  x2 = TMath::Min(x2,xaxis->GetXmax());
2913  y1 = TMath::Max(y1,yaxis->GetXmin());
2914  y2 = TMath::Min(y2,yaxis->GetXmax());
2915  if (x1<x2 && y1<y2) {
2916  xaxis->SetRangeUser(x1, x2);
2917  yaxis->SetRangeUser(y1, y2);
2918  }
2919  zoombox->Delete();
2920  zoombox = 0;
2921  }
2922  }
2923  gPad->Modified(kTRUE);
2924  if (opaque) gVirtualX->SetLineColor(-1);
2925 
2926  break;
2927 
2928  case kButton1Locate:
2929 
2930  ExecuteEvent(kButton1Down, px, py);
2931 
2932  while (1) {
2933  px = py = 0;
2934  event = gVirtualX->RequestLocator(1, 1, px, py);
2935 
2936  ExecuteEvent(kButton1Motion, px, py);
2937 
2938  if (event != -1) { // button is released
2939  ExecuteEvent(kButton1Up, px, py);
2940  return;
2941  }
2942  }
2943  }
2944 }
2945 
2946 
2947 ////////////////////////////////////////////////////////////////////////////////
2948 /// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
2949 
2951 {
2952 
2953 
2954 
2955  // Check if fH contains a TGraphDelaunay2D
2957  TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
2958  // try with the old painter
2959  TGraphDelaunay *dtOld = nullptr;
2960  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
2961 
2962  if (!dt && !dtOld) return nullptr;
2963 
2964  gCurrentHist = fH;
2965 
2966  if (!fGraph2DPainter) {
2967  if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
2968  else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
2969  }
2970 
2971  return fGraph2DPainter->GetContourList(contour);
2972 }
2973 
2974 
2975 ////////////////////////////////////////////////////////////////////////////////
2976 /// Display the histogram info (bin number, contents, integral up to bin
2977 /// corresponding to cursor position px,py.
2978 
2979 char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
2980 {
2981 
2982  if (!gPad) return (char*)"";
2983  static char info[200];
2984  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
2985  Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
2986  Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
2987  TString drawOption = fH->GetDrawOption();
2988  drawOption.ToLower();
2989  Double_t xmin, xmax, uxmin,uxmax;
2990  Double_t ymin, ymax, uymin,uymax;
2991  if (fH->GetDimension() == 2) {
2992  if (gPad->GetView() || drawOption.Index("cont") >= 0) {
2993  uxmin=gPad->GetUxmin();
2994  uxmax=gPad->GetUxmax();
2995  xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
2996  xmax = fXaxis->GetBinUpEdge(fXaxis->GetLast());
2997  x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
2998  uymin=gPad->GetUymin();
2999  uymax=gPad->GetUymax();
3000  ymin = fYaxis->GetBinLowEdge(fYaxis->GetFirst());
3001  ymax = fYaxis->GetBinUpEdge(fYaxis->GetLast());
3002  y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3003  }
3004  }
3005  Int_t binx,biny,binmin=0,binx1;
3006  if (gPad->IsVertical()) {
3007  binx = fXaxis->FindFixBin(x);
3008  if (drawOption.Index("same") >= 0) {
3009  TH1 *h1;
3010  TIter next(gPad->GetListOfPrimitives());
3011  while ((h1 = (TH1 *)next())) {
3012  if (!h1->InheritsFrom(TH1::Class())) continue;
3013  binmin = h1->GetXaxis()->GetFirst();
3014  break;
3015  }
3016  } else {
3017  binmin = fXaxis->GetFirst();
3018  }
3019  binx1 = fXaxis->FindFixBin(x1);
3020  // special case if more than 1 bin in x per pixel
3021  if (binx1-binx>1 && fH->GetDimension() == 1) {
3022  Double_t binval=fH->GetBinContent(binx);
3023  Int_t binnear=binx;
3024  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3025  Double_t binvaltmp = fH->GetBinContent(ibin);
3026  if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3027  binval=binvaltmp;
3028  binnear=ibin;
3029  }
3030  }
3031  binx = binnear;
3032  }
3033  } else {
3034  x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3035  binx = fXaxis->FindFixBin(y);
3036  if (drawOption.Index("same") >= 0) {
3037  TH1 *h1;
3038  TIter next(gPad->GetListOfPrimitives());
3039  while ((h1 = (TH1 *)next())) {
3040  if (!h1->InheritsFrom(TH1::Class())) continue;
3041  binmin = h1->GetXaxis()->GetFirst();
3042  break;
3043  }
3044  } else {
3045  binmin = fXaxis->GetFirst();
3046  }
3047  binx1 = fXaxis->FindFixBin(x1);
3048  // special case if more than 1 bin in x per pixel
3049  if (binx1-binx>1 && fH->GetDimension() == 1) {
3050  Double_t binval=fH->GetBinContent(binx);
3051  Int_t binnear=binx;
3052  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3053  Double_t binvaltmp = fH->GetBinContent(ibin);
3054  if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3055  binval=binvaltmp;
3056  binnear=ibin;
3057  }
3058  }
3059  binx = binnear;
3060  }
3061  }
3062  if (fH->GetDimension() == 1) {
3063  if (fH->InheritsFrom(TProfile::Class())) {
3064  TProfile *tp = (TProfile*)fH;
3065  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3066  x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3067  (Int_t) tp->GetBinEntries(binx));
3068  }
3069  else {
3070  Double_t integ = 0;
3071  for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3072  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3073  x,y,binx,fH->GetBinContent(binx),integ);
3074  }
3075  } else if (fH->GetDimension() == 2) {
3076  if (fH->InheritsFrom(TH2Poly::Class())) {
3077  TH2Poly *th2 = (TH2Poly*)fH;
3078  biny = th2->FindBin(x,y);
3079  snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3080  th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3081  }
3082  else if (fH->InheritsFrom(TProfile2D::Class())) {
3083  TProfile2D *tp = (TProfile2D*)fH;
3084  biny = fYaxis->FindFixBin(y);
3085  Int_t bin = fH->GetBin(binx,biny);
3086  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3087  x, y, binx, biny, fH->GetBinContent(bin),
3088  fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3089  } else {
3090  biny = fYaxis->FindFixBin(y);
3091  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3092  x,y,binx,biny,fH->GetBinContent(binx,biny),
3093  fH->GetBinError(binx,biny));
3094  }
3095  } else {
3096  // 3d case: retrieving the x,y,z bin is not yet implemented
3097  // print just the x,y info
3098  snprintf(info,200,"(x=%g, y=%g)",x,y);
3099  }
3100  return info;
3101 }
3102 
3103 
3104 ////////////////////////////////////////////////////////////////////////////////
3105 /// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3106 
3108 {
3109 
3110  for (Int_t i=0;i<fNcuts;i++) {
3111  Double_t x = fXaxis->GetBinCenter(ix);
3112  Double_t y = fYaxis->GetBinCenter(iy);
3113  if (fCutsOpt[i] > 0) {
3114  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3115  } else {
3116  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3117  }
3118  }
3119  return kTRUE;
3120 }
3121 
3122 
3123 ////////////////////////////////////////////////////////////////////////////////
3124 /// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3125 
3127 {
3128 
3129  for (Int_t i=0;i<fNcuts;i++) {
3130  if (fCutsOpt[i] > 0) {
3131  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3132  } else {
3133  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3134  }
3135  }
3136  return kTRUE;
3137 }
3138 
3139 
3140 ////////////////////////////////////////////////////////////////////////////////
3141 /// Decode string `choptin` and fill Hoption structure.
3142 
3144 {
3145 
3146  char *l;
3147  char chopt[128];
3148  Int_t nch = strlen(choptin);
3149  strlcpy(chopt,choptin,128);
3150  Int_t hdim = fH->GetDimension();
3151 
3152  Hoption.Axis = Hoption.Bar = Hoption.Curve = Hoption.Error = 0;
3153  Hoption.Hist = Hoption.Line = Hoption.Mark = Hoption.Fill = 0;
3154  Hoption.Same = Hoption.Func = Hoption.Scat = 0;
3155  Hoption.Star = Hoption.Arrow = Hoption.Box = Hoption.Text = 0;
3156  Hoption.Char = Hoption.Color = Hoption.Contour = Hoption.Logx = 0;
3157  Hoption.Logy = Hoption.Logz = Hoption.Lego = Hoption.Surf = 0;
3158  Hoption.Off = Hoption.Tri = Hoption.Proj = Hoption.AxisPos = 0;
3159  Hoption.Spec = Hoption.Pie = Hoption.Candle = Hoption.Violin = 0;
3160 
3161  // special 2D options
3162  Hoption.List = 0;
3163  Hoption.Zscale = 0;
3164  Hoption.FrontBox = 1;
3165  Hoption.BackBox = 1;
3166  Hoption.System = kCARTESIAN;
3167 
3168  Hoption.Zero = 0;
3169 
3170  //check for graphical cuts
3171  MakeCuts(chopt);
3172 
3173  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3174  if (hdim > 1) Hoption.Scat = 1;
3175  if (!nch) Hoption.Hist = 1;
3176  if (fFunctions->First()) Hoption.Func = 1;
3177  if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3178 
3179  l = strstr(chopt,"SPEC");
3180  if (l) {
3181  Hoption.Scat = 0;
3182  strncpy(l," ",4);
3183  Int_t bs=0;
3184  l = strstr(chopt,"BF(");
3185  if (l) {
3186  if (sscanf(&l[3],"%d",&bs) > 0) {
3187  Int_t i=0;
3188  while (l[i]!=')') {
3189  l[i] = ' ';
3190  i++;
3191  }
3192  l[i] = ' ';
3193  }
3194  }
3195  Hoption.Spec = TMath::Max(1600,bs);
3196  return 1;
3197  }
3198 
3199  l = strstr(chopt,"GL");
3200  if (l) {
3201  strncpy(l," ",2);
3202  }
3203  l = strstr(chopt,"X+");
3204  if (l) {
3205  Hoption.AxisPos = 10;
3206  strncpy(l," ",2);
3207  }
3208  l = strstr(chopt,"Y+");
3209  if (l) {
3210  Hoption.AxisPos += 1;
3211  strncpy(l," ",2);
3212  }
3213  if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
3214  if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
3215 
3216  l = strstr(chopt,"SAMES");
3217  if (l) {
3218  if (nch == 5) Hoption.Hist = 1;
3219  Hoption.Same = 2;
3220  strncpy(l," ",5);
3221  }
3222  l = strstr(chopt,"SAME");
3223  if (l) {
3224  if (nch == 4) Hoption.Hist = 1;
3225  Hoption.Same = 1;
3226  strncpy(l," ",4);
3227  }
3228 
3229  l = strstr(chopt,"PIE");
3230  if (l) {
3231  Hoption.Pie = 1;
3232  strncpy(l," ",3);
3233  }
3234 
3235  l = strstr(chopt,"CANDLE");
3236  if (l) {
3237  Hoption.Scat = 0;
3238  Hoption.Candle = 1;
3239  strncpy(l," ",6);
3240  if (l[6] == 'X') { Hoption.Candle = 1; l[6] = ' '; }
3241  if (l[6] == 'Y') { Hoption.Candle = 2; l[6] = ' '; }
3242  }
3243 
3244  l = strstr(chopt,"VIOLIN");
3245  if (l) {
3246  Hoption.Scat = 0;
3247  Hoption.Violin = 1;
3248  strncpy(l," ",6);
3249  if (l[6] == 'X') { Hoption.Violin = 1; l[6] = ' '; }
3250  if (l[6] == 'Y') { Hoption.Violin = 2; l[6] = ' '; }
3251  }
3252 
3253  l = strstr(chopt,"LEGO");
3254  if (l) {
3255  Hoption.Scat = 0;
3256  Hoption.Lego = 1; strncpy(l," ",4);
3257  if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
3258  if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
3259  if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
3260  if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
3261  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3262  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3263  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3264  }
3265 
3266  l = strstr(chopt,"SURF");
3267  if (l) {
3268  Hoption.Scat = 0;
3269  Hoption.Surf = 1; strncpy(l," ",4);
3270  if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
3271  if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
3272  if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
3273  if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
3274  if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
3275  if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
3276  if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
3277  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3278  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3279  }
3280 
3281  l = strstr(chopt,"TF3");
3282  if (l) {
3283  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3284  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3285  }
3286 
3287  l = strstr(chopt,"ISO");
3288  if (l) {
3289  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3290  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3291  }
3292 
3293  l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; strncpy(l," ",4);}
3294 
3295  l = strstr(chopt,"CONT");
3296  if (l) {
3297  strncpy(l," ",4);
3298  if (hdim>1) {
3299  Hoption.Scat = 0;
3300  Hoption.Contour = 1;
3301  if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
3302  if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
3303  if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
3304  if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
3305  if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
3306  } else {
3307  Hoption.Hist = 1;
3308  }
3309  }
3310  l = strstr(chopt,"HBAR");
3311  if (l) {
3312  Hoption.Hist = 0;
3313  Hoption.Bar = 20; strncpy(l," ",4);
3314  if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
3315  if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
3316  if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
3317  if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
3318  }
3319  l = strstr(chopt,"BAR");
3320  if (l) {
3321  Hoption.Hist = 0;
3322  Hoption.Bar = 10; strncpy(l," ",3);
3323  if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
3324  if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
3325  if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
3326  if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
3327  }
3328 
3329  l = strstr(chopt,"ARR" );
3330  if (l) {
3331  strncpy(l," ", 3);
3332  if (hdim>1) {
3333  Hoption.Arrow = 1;
3334  Hoption.Scat = 0;
3335  } else {
3336  Hoption.Hist = 1;
3337  }
3338  }
3339  l = strstr(chopt,"BOX" );
3340  if (l) {
3341  strncpy(l," ", 3);
3342  if (hdim>1) {
3343  Hoption.Scat = 0;
3344  Hoption.Box = 1;
3345  if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
3346  } else {
3347  Hoption.Hist = 1;
3348  }
3349  }
3350  l = strstr(chopt,"COLZ");
3351  if (l) {
3352  strncpy(l," ",4);
3353  if (hdim>1) {
3354  Hoption.Color = 1;
3355  Hoption.Scat = 0;
3356  Hoption.Zscale = 1;
3357  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3358  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3359  } else {
3360  Hoption.Hist = 1;
3361  }
3362  }
3363  l = strstr(chopt,"COL" );
3364  if (l) {
3365  strncpy(l," ", 3);
3366  if (hdim>1) {
3367  Hoption.Color = 1;
3368  Hoption.Scat = 0;
3369  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3370  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3371  } else {
3372  Hoption.Hist = 1;
3373  }
3374  }
3375  l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; strncpy(l," ",4); Hoption.Scat = 0; }
3376  l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; strncpy(l," ",4); Hoption.Hist = 0; }
3377  l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; strncpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
3378  l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; strncpy(l," ",4); }
3379  l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; strncpy(l," ",4); }
3380  l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; strncpy(l," ",4); }
3381  l = strstr(chopt,"TEXT");
3382  if (l) {
3383  Int_t angle;
3384  if (sscanf(&l[4],"%d",&angle) > 0) {
3385  if (angle < 0) angle=0;
3386  if (angle > 90) angle=90;
3387  Hoption.Text = 1000+angle;
3388  } else {
3389  Hoption.Text = 1;
3390  }
3391  strncpy(l," ", 4);
3392  l = strstr(chopt,"N");
3393  if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
3394  Hoption.Scat = 0;
3395  }
3396  l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; strncpy(l," ",3); }
3397  l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; strncpy(l," ",3); }
3398  l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; strncpy(l," ",3); }
3399  l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; strncpy(l," ",3); }
3400 
3401  l = strstr(chopt,"TRI");
3402  if (l) {
3403  Hoption.Scat = 0;
3404  Hoption.Color = 0;
3405  Hoption.Tri = 1; strncpy(l," ",3);
3406  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3407  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3408  l = strstr(chopt,"ERR"); if (l) strncpy(l," ",3);
3409  }
3410 
3411  l = strstr(chopt,"AITOFF");
3412  if (l) {
3413  Hoption.Proj = 1; strncpy(l," ",6); //Aitoff projection
3414  }
3415  l = strstr(chopt,"MERCATOR");
3416  if (l) {
3417  Hoption.Proj = 2; strncpy(l," ",8); //Mercator projection
3418  }
3419  l = strstr(chopt,"SINUSOIDAL");
3420  if (l) {
3421  Hoption.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
3422  }
3423  l = strstr(chopt,"PARABOLIC");
3424  if (l) {
3425  Hoption.Proj = 4; strncpy(l," ",9); //Parabolic projection
3426  }
3427  if (Hoption.Proj > 0) {
3428  Hoption.Scat = 0;
3429  Hoption.Contour = 14;
3430  }
3431 
3432  if (strstr(chopt,"A")) Hoption.Axis = -1;
3433  if (strstr(chopt,"B")) Hoption.Bar = 1;
3434  if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
3435  if (strstr(chopt,"F")) Hoption.Fill =1;
3436  if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
3437  if (strstr(chopt,"F2")) Hoption.Fill =2;
3438  if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
3439  if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
3440  if (strstr(chopt,"Z")) Hoption.Zscale =1;
3441  if (strstr(chopt,"*")) Hoption.Star =1;
3442  if (strstr(chopt,"H")) Hoption.Hist =2;
3443  if (strstr(chopt,"P0")) Hoption.Mark =10;
3444 
3445  if (fH->InheritsFrom(TH2Poly::Class())) {
3446  if (Hoption.Fill+Hoption.Line+Hoption.Mark != 0 ) Hoption.Scat = 0;
3447  }
3448 
3449  if (strstr(chopt,"E")) {
3450  if (hdim == 1) {
3451  Hoption.Error = 1;
3452  if (strstr(chopt,"E0")) Hoption.Error = 10;
3453  if (strstr(chopt,"E1")) Hoption.Error = 11;
3454  if (strstr(chopt,"E2")) Hoption.Error = 12;
3455  if (strstr(chopt,"E3")) Hoption.Error = 13;
3456  if (strstr(chopt,"E4")) Hoption.Error = 14;
3457  if (strstr(chopt,"E5")) Hoption.Error = 15;
3458  if (strstr(chopt,"E6")) Hoption.Error = 16;
3459  if (strstr(chopt,"X0")) {
3460  if (Hoption.Error == 1) Hoption.Error += 20;
3461  Hoption.Error += 10;
3462  }
3463  if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
3464  Hoption.Text += 2000;
3465  Hoption.Error = 0;
3466  }
3467  } else {
3468  if (Hoption.Error == 0) {
3469  Hoption.Error = 100;
3470  Hoption.Scat = 0;
3471  }
3472  if (Hoption.Text) {
3473  Hoption.Text += 2000;
3474  Hoption.Error = 0;
3475  }
3476  }
3477  }
3478 
3479  if (Hoption.Surf == 15) {
3480  if (Hoption.System == kPOLAR || Hoption.System == kCARTESIAN) {
3481  Hoption.Surf = 13;
3482  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
3483  }
3484  }
3485 
3486  // Copy options from current style
3487  Hoption.Logx = gPad->GetLogx();
3488  Hoption.Logy = gPad->GetLogy();
3489  Hoption.Logz = gPad->GetLogz();
3490 
3491  // Check options incompatibilities
3492  if (Hoption.Bar == 1) Hoption.Hist = -1;
3493  return 1;
3494 }
3495 
3496 
3497 ////////////////////////////////////////////////////////////////////////////////
3498 /// Decode string `choptin` and fill Graphical cuts structure.
3499 
3500 Int_t THistPainter::MakeCuts(char *choptin)
3501 {
3502 
3503  fNcuts = 0;
3504  char *left = (char*)strchr(choptin,'[');
3505  if (!left) return 0;
3506  char *right = (char*)strchr(choptin,']');
3507  if (!right) return 0;
3508  Int_t nch = right-left;
3509  if (nch < 2) return 0;
3510  char *cuts = left+1;
3511  *right = 0;
3512  char *comma, *minus;
3513  Int_t i;
3514  while (1) {
3515  comma = strchr(cuts,',');
3516  if (comma) *comma = 0;
3517  minus = strchr(cuts,'-');
3518  if (minus) cuts = minus+1;
3519  while (*cuts == ' ') cuts++;
3520  Int_t nc = strlen(cuts);
3521  while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
3522  TIter next(gROOT->GetListOfSpecials());
3523  TCutG *cut=0;
3524  TObject *obj;
3525  while ((obj = next())) {
3526  if (!obj->InheritsFrom(TCutG::Class())) continue;
3527  if (strcmp(obj->GetName(),cuts)) continue;
3528  cut = (TCutG*)obj;
3529  break;
3530  }
3531  if (cut) {
3532  fCuts[fNcuts] = cut;
3533  fCutsOpt[fNcuts] = 1;
3534  if (minus) fCutsOpt[fNcuts] = -1;
3535  fNcuts++;
3536  }
3537  if (!comma) break;
3538  cuts = comma+1;
3539  }
3540  for (i=0;i<=nch;i++) left[i] = ' ';
3541  return fNcuts;
3542 }
3543 
3544 
3545 ////////////////////////////////////////////////////////////////////////////////
3546 /// [Control routine to paint any kind of histograms](#HP00)
3547 
3548 void THistPainter::Paint(Option_t *option)
3549 {
3550 
3551  if (fH->GetBuffer()) fH->BufferEmpty(-1);
3552 
3553  //For iOS: put the histogram on the top of stack of pickable objects.
3554  const TPickerStackGuard topPush(fH);
3555 
3556  gPad->SetVertical(kTRUE);
3557 
3558  TH1 *oldhist = gCurrentHist;
3559  gCurrentHist = fH;
3560  TH1 *hsave = fH;
3561  Double_t minsav = fH->GetMinimumStored();
3562 
3563  if (!MakeChopt(option)) return; //check options and fill Hoption structure
3564 
3565  // Paint using TSpectrum2Painter
3566  if (Hoption.Spec) {
3567  if (!TableInit()) return;
3568  if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
3569  gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
3570  (ULong_t)fH, option, Hoption.Spec));
3571  return;
3572  }
3573 
3574  if (Hoption.Pie) {
3575  if (fH->GetDimension() == 1) {
3576  if (!fPie) fPie = new TPie(fH);
3577  fPie->Paint(option);
3578  } else {
3579  Error("Paint", "Option PIE is for 1D histograms only");
3580  }
3581  return;
3582  } else {
3583  if (fPie) delete fPie;
3584  fPie = 0;
3585  }
3586 
3587  fXbuf = new Double_t[kNMAX];
3588  fYbuf = new Double_t[kNMAX];
3589  if (fH->GetDimension() > 2) {
3590  PaintH3(option);
3591  fH->SetMinimum(minsav);
3592  if (Hoption.Func) {
3593  Hoption_t hoptsave = Hoption;
3594  Hparam_t hparsave = Hparam;
3595  PaintFunction(option);
3596  SetHistogram(hsave);
3597  Hoption = hoptsave;
3598  Hparam = hparsave;
3599  }
3600  gCurrentHist = oldhist;
3601  delete [] fXbuf; delete [] fYbuf;
3602  return;
3603  }
3604  TView *view = gPad->GetView();
3605  if (view) {
3606  if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
3607  delete view;
3608  gPad->SetView(0);
3609  }
3610  }
3611  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
3612  // In case of 1D histogram, Z axis becomes Y axis.
3613  Int_t logysav=0, logzsav=0;
3614  if (fH->GetDimension() == 1) {
3615  logysav = Hoption.Logy;
3616  logzsav = Hoption.Logz;
3617  Hoption.Logz = 0;
3618  if (Hoption.Logy) {
3619  Hoption.Logz = 1;
3620  Hoption.Logy = 0;
3621  }
3622  }
3623  PaintTable(option);
3624  fH->SetMinimum(minsav);
3625  if (Hoption.Func) {
3626  Hoption_t hoptsave = Hoption;
3627  Hparam_t hparsave = Hparam;
3628  PaintFunction(option);
3629  SetHistogram(hsave);
3630  Hoption = hoptsave;
3631  Hparam = hparsave;
3632  }
3633  gCurrentHist = oldhist;
3634  delete [] fXbuf; delete [] fYbuf;
3635  if (fH->GetDimension() == 1) {
3636  Hoption.Logy = logysav;
3637  Hoption.Logz = logzsav;
3638  }
3639  return;
3640  }
3641 
3642  if (Hoption.Bar >= 20) {PaintBarH(option);
3643  delete [] fXbuf; delete [] fYbuf;
3644  return;
3645  }
3646 
3647  // fill Hparam structure with histo parameters
3648  if (!PaintInit()) {
3649  delete [] fXbuf; delete [] fYbuf;
3650  return;
3651  }
3652 
3653  // Picture surround (if new page) and page number (if requested).
3654  // Histogram surround (if not option "Same").
3655  PaintFrame();
3656 
3657  // Paint histogram axis only
3658  Bool_t gridx = gPad->GetGridx();
3659  Bool_t gridy = gPad->GetGridy();
3660  if (Hoption.Axis > 0) {
3661  if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
3662  else {
3663  if (gridx) gPad->SetGridx(0);
3664  if (gridy) gPad->SetGridy(0);
3665  PaintAxis(kFALSE);
3666  if (gridx) gPad->SetGridx(1);
3667  if (gridy) gPad->SetGridy(1);
3668  }
3669  if (Hoption.Same ==1) Hoption.Same = 2;
3670  goto paintstat;
3671  }
3672  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
3673 
3674  // test for options BAR or HBAR
3675  if (Hoption.Bar >= 10) {
3676  PaintBar(option);
3677  }
3678 
3679  // do not draw histogram if error bars required
3680  if (!Hoption.Error) {
3681  if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
3682  }
3683 
3684  // test for error bars or option E
3685  if (Hoption.Error) {
3686  PaintErrors(option);
3687  if (Hoption.Hist == 2) PaintHist(option);
3688  }
3689 
3690  if (Hoption.Text) PaintText(option);
3691 
3692  // test for associated function
3693  if (Hoption.Func) {
3694  Hoption_t hoptsave = Hoption;
3695  Hparam_t hparsave = Hparam;
3696  PaintFunction(option);
3697  SetHistogram(hsave);
3698  Hoption = hoptsave;
3699  Hparam = hparsave;
3700  }
3701 
3702  if (gridx) gPad->SetGridx(0);
3703  if (gridy) gPad->SetGridy(0);
3704  PaintAxis(kFALSE);
3705  if (gridx) gPad->SetGridx(1);
3706  if (gridy) gPad->SetGridy(1);
3707 
3708  PaintTitle(); // Draw histogram title
3709 
3710  // Draw box with histogram statistics and/or fit parameters
3711 paintstat:
3712  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
3714  TObject *obj = 0;
3715  while ((obj = next())) {
3716  if (obj->InheritsFrom(TF1::Class())) break;
3717  obj = 0;
3718  }
3719 
3720  //Stat is painted twice (first, it will be in canvas' list of primitives),
3721  //second, it will be here, this is not required on iOS.
3722  //Condition is ALWAYS true on a platform different from iOS.
3723  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
3724  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
3725  }
3726  fH->SetMinimum(minsav);
3727  gCurrentHist = oldhist;
3728  delete [] fXbuf; fXbuf = 0;
3729  delete [] fYbuf; fYbuf = 0;
3730 
3731 }
3732 
3733 
3734 ////////////////////////////////////////////////////////////////////////////////
3735 /// [Control function to draw a table as an arrow plot](#HP12)
3736 
3738 {
3739 
3740  Style_t linesav = fH->GetLineStyle();
3741  Width_t widthsav = fH->GetLineWidth();
3742  fH->SetLineStyle(1);
3744  fH->TAttLine::Modify();
3745 
3746  Double_t xk, xstep, yk, ystep;
3747  Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
3748  Int_t ncx = Hparam.xlast - Hparam.xfirst + 1;
3749  Int_t ncy = Hparam.ylast - Hparam.yfirst + 1;
3750  Double_t xrg = gPad->GetUxmin();
3751  Double_t yrg = gPad->GetUymin();
3752  Double_t xln = gPad->GetUxmax() - xrg;
3753  Double_t yln = gPad->GetUymax() - yrg;
3754  Double_t cx = (xln/Double_t(ncx) -0.03)/2;
3755  Double_t cy = (yln/Double_t(ncy) -0.03)/2;
3756  Double_t dn = 1.E-30;
3757 
3758  for (Int_t id=1;id<=2;id++) {
3759  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
3760  yk = fYaxis->GetBinLowEdge(j);
3761  ystep = fYaxis->GetBinWidth(j);
3762  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
3763  xk = fXaxis->GetBinLowEdge(i);
3764  xstep = fXaxis->GetBinWidth(i);
3765  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
3766  if (i == Hparam.xfirst) {
3767  dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
3768  } else if (i == Hparam.xlast) {
3769  dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
3770  } else {
3771  dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
3772  }
3773  if (j == Hparam.yfirst) {
3774  dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
3775  } else if (j == Hparam.ylast) {
3776  dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
3777  } else {
3778  dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
3779  }
3780  if (id == 1) {
3781  dn = TMath::Max(dn, TMath::Abs(dx));
3782  dn = TMath::Max(dn, TMath::Abs(dy));
3783  } else if (id == 2) {
3784  xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
3785  dxn = cx*dx/dn;
3786  x1 = xc - dxn;
3787  x2 = xc + dxn;
3788  yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
3789  dyn = cy*dy/dn;
3790  y1 = yc - dyn;
3791  y2 = yc + dyn;
3792  fXbuf[0] = x1;
3793  fXbuf[1] = x2;
3794  fYbuf[0] = y1;
3795  fYbuf[1] = y2;
3796  if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
3797  anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
3798  si = anr*(dxn + dyn);
3799  co = anr*(dxn - dyn);
3800  fXbuf[2] = x2 - si;
3801  fYbuf[2] = y2 + co;
3802  gPad->PaintPolyLine(3, fXbuf, fYbuf);
3803  fXbuf[0] = x2;
3804  fXbuf[1] = x2 - co;
3805  fYbuf[0] = y2;
3806  fYbuf[1] = y2 - si;
3807  gPad->PaintPolyLine(2, fXbuf, fYbuf);
3808  }
3809  else {
3810  gPad->PaintPolyLine(2, fXbuf, fYbuf);
3811  }
3812  }
3813  }
3814  }
3815  }
3816 
3817  if (Hoption.Zscale) PaintPalette();
3818  fH->SetLineStyle(linesav);
3819  fH->SetLineWidth(widthsav);
3820  fH->TAttLine::Modify();
3821 }
3822 
3823 
3824 ////////////////////////////////////////////////////////////////////////////////
3825 /// Draw axis (2D case) of an histogram.
3826 ///
3827 /// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
3828 /// to draw the grid and the axis separately. In `THistPainter::Paint` this
3829 /// feature is used to make sure that the grid is drawn in the background and
3830 /// the axis tick marks in the foreground of the pad.
3831 
3832 void THistPainter::PaintAxis(Bool_t drawGridOnly)
3833 {
3834 
3835  //On iOS, grid should not be picable and can not be highlighted.
3836  //Condition is never true on a platform different from iOS.
3837  if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
3838  return;
3839 
3840  if (Hoption.Axis == -1) return;
3841  if (Hoption.Same && Hoption.Axis <= 0) return;
3842 
3843  // Repainting alphanumeric labels axis on a plot done with
3844  // the option HBAR (horizontal) needs some adjustements.
3845  TAxis *xaxis = 0;
3846  TAxis *yaxis = 0;
3847  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
3848  if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
3849  TIter next(gPad->GetListOfPrimitives());
3850  TObject *obj;
3851  // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
3852  while ((obj = next())) {
3853  if (!obj->InheritsFrom(TH1::Class()) &&
3854  !obj->InheritsFrom(THStack::Class())) continue;
3855  TString opt = obj->GetDrawOption();
3856  opt.ToLower();
3857  // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
3858  if (strstr(opt,"hbar")) {
3859  gPad->SetVertical(kFALSE);
3860  xaxis = fXaxis;
3861  yaxis = fYaxis;
3862  if (!strcmp(xaxis->GetName(),"xaxis")) {
3863  fXaxis = yaxis;
3864  fYaxis = xaxis;
3865  }
3866  }
3867  break;
3868  }
3869  }
3870  }
3871 
3872  static char chopt[10] = "";
3873  Double_t gridl = 0;
3874  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
3875  Int_t useHparam = 0;
3876  Double_t umin, umax, uminsave, umaxsave;
3877  Short_t xAxisPos = Hoption.AxisPos/10;
3878  Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
3879 
3880  Double_t axmin = gPad->GetUxmin();
3881  Double_t axmax = gPad->GetUxmax();
3882  Double_t aymin = gPad->GetUymin();
3883  Double_t aymax = gPad->GetUymax();
3884  char *cw = 0;
3885  TGaxis axis;
3886 
3887  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
3888  // Hparam must be use for the axis limits.
3889  if (Hoption.Contour == 14) useHparam = 1;
3890  if (Hoption.Same) {
3891  TObject *obj;
3892  TIter next(gPad->GetListOfPrimitives());
3893  while ((obj=next())) {
3894  if (strstr(obj->GetDrawOption(),"cont4")) {
3895  useHparam = 1;
3896  break;
3897  }
3898  }
3899  }
3900 
3901  // Paint X axis
3902 
3903  //To make X-axis selectable on iOS device.
3904  if (gPad->PadInSelectionMode())
3905  gPad->PushSelectableObject(fXaxis);
3906 
3907  //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
3908  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
3909  ndivx = fXaxis->GetNdivisions();
3910  if (ndivx > 1000) {
3911  nx2 = ndivx/100;
3912  nx1 = TMath::Max(1, ndivx%100);
3913  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
3914  }
3915  axis.SetTextAngle(0);
3917 
3918  chopt[0] = 0;
3919  strlcat(chopt, "SDH",10);
3920  if (ndivx < 0) strlcat(chopt, "N",10);
3921  if (gPad->GetGridx()) {
3922  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
3923  strlcat(chopt, "W",10);
3924  }
3925 
3926  // Define X-Axis limits
3927  if (Hoption.Logx) {
3928  strlcat(chopt, "G",10);
3929  ndiv = TMath::Abs(ndivx);
3930  if (useHparam) {
3931  umin = TMath::Power(10,Hparam.xmin);
3932  umax = TMath::Power(10,Hparam.xmax);
3933  } else {
3934  umin = TMath::Power(10,axmin);
3935  umax = TMath::Power(10,axmax);
3936  }
3937  } else {
3938  ndiv = TMath::Abs(ndivx);
3939  if (useHparam) {
3940  umin = Hparam.xmin;
3941  umax = Hparam.xmax;
3942  } else {
3943  umin = axmin;
3944  umax = axmax;
3945  }
3946  }
3947 
3948  // Display axis as time
3949  if (fXaxis->GetTimeDisplay()) {
3950  strlcat(chopt,"t",10);
3951  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
3952  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam.xmax-Hparam.xmin));
3953  }
3954  }
3955 
3956  // The main X axis can be on the bottom or on the top of the pad
3957  Double_t xAxisYPos1, xAxisYPos2;
3958  if (xAxisPos == 1) {
3959  // Main X axis top
3960  xAxisYPos1 = aymax;
3961  xAxisYPos2 = aymin;
3962  } else {
3963  // Main X axis bottom
3964  xAxisYPos1 = aymin;
3965  xAxisYPos2 = aymax;
3966  }
3967 
3968  // Paint the main X axis (always)
3969  uminsave = umin;
3970  umaxsave = umax;
3971  ndivsave = ndiv;
3972  axis.SetOption(chopt);
3973  if (xAxisPos) {
3974  strlcat(chopt, "-",10);
3975  gridl = -gridl;
3976  }
3977  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
3978  axis.SetLabelSize(0.);
3979  axis.SetTitle("");
3980  }
3981  axis.PaintAxis(axmin, xAxisYPos1,
3982  axmax, xAxisYPos1,
3983  umin, umax, ndiv, chopt, gridl, drawGridOnly);
3984 
3985  // Paint additional X axis (if needed)
3986  // On iOS, this additional X axis is neither pickable, nor highlighted.
3987  // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
3988  if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
3989  if (xAxisPos) {
3990  cw=strstr(chopt,"-");
3991  *cw='z';
3992  } else {
3993  strlcat(chopt, "-",10);
3994  }
3995  if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
3996  if ((cw=strstr(chopt,"W"))) *cw='z';
3997  axis.SetTitle("");
3998  axis.PaintAxis(axmin, xAxisYPos2,
3999  axmax, xAxisYPos2,
4000  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4001  }
4002  }//End of "if pad in selection mode etc".
4003 
4004  // Paint Y axis
4005  //On iOS, Y axis must pushed into the stack of selectable objects.
4006  if (gPad->PadInSelectionMode())
4007  gPad->PushSelectableObject(fYaxis);
4008 
4009  //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4010  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4011  ndivy = fYaxis->GetNdivisions();
4013 
4014  chopt[0] = 0;
4015  strlcat(chopt, "SDH",10);
4016  if (ndivy < 0) strlcat(chopt, "N",10);
4017  if (gPad->GetGridy()) {
4018  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4019  strlcat(chopt, "W",10);
4020  }
4021 
4022  // Define Y-Axis limits
4023  if (Hoption.Logy) {
4024  strlcat(chopt, "G",10);
4025  ndiv = TMath::Abs(ndivy);
4026  if (useHparam) {
4027  umin = TMath::Power(10,Hparam.ymin);
4028  umax = TMath::Power(10,Hparam.ymax);
4029  } else {
4030  umin = TMath::Power(10,aymin);
4031  umax = TMath::Power(10,aymax);
4032  }
4033  } else {
4034  ndiv = TMath::Abs(ndivy);
4035  if (useHparam) {
4036  umin = Hparam.ymin;
4037  umax = Hparam.ymax;
4038  } else {
4039  umin = aymin;
4040  umax = aymax;
4041  }
4042  }
4043 
4044  // Display axis as time
4045  if (fYaxis->GetTimeDisplay()) {
4046  strlcat(chopt,"t",10);
4047  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4048  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam.ymax-Hparam.ymin));
4049  }
4050  }
4051 
4052  // The main Y axis can be on the left or on the right of the pad
4053  Double_t yAxisXPos1, yAxisXPos2;
4054  if (yAxisPos == 1) {
4055  // Main Y axis left
4056  yAxisXPos1 = axmax;
4057  yAxisXPos2 = axmin;
4058  } else {
4059  // Main Y axis right
4060  yAxisXPos1 = axmin;
4061  yAxisXPos2 = axmax;
4062  }
4063 
4064  // Paint the main Y axis (always)
4065  uminsave = umin;
4066  umaxsave = umax;
4067  ndivsave = ndiv;
4068  axis.SetOption(chopt);
4069  if (yAxisPos) {
4070  strlcat(chopt, "+L",10);
4071  gridl = -gridl;
4072  }
4073  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4074  axis.SetLabelSize(0.);
4075  axis.SetTitle("");
4076  }
4077  axis.PaintAxis(yAxisXPos1, aymin,
4078  yAxisXPos1, aymax,
4079  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4080 
4081  // Paint the additional Y axis (if needed)
4082  // Additional checks for pad mode are required on iOS: this "second" axis is
4083  // neither pickable, nor highlihted. Additional checks have no effect on non-iOS platform.
4084  if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4085  if (gPad->GetTicky() < 2) {
4086  strlcat(chopt, "U",10);
4087  axis.SetTickSize(-fYaxis->GetTickLength());
4088  } else {
4089  strlcat(chopt, "+L",10);
4090  }
4091  if ((cw=strstr(chopt,"W"))) *cw='z';
4092  axis.SetTitle("");
4093  axis.PaintAxis(yAxisXPos2, aymin,
4094  yAxisXPos2, aymax,
4095  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4096  }
4097  }//End of "if pad is in selection mode etc."
4098 
4099  // Reset the axis if they have been inverted in case of option HBAR
4100  if (xaxis) {
4101  fXaxis = xaxis;
4102  fYaxis = yaxis;
4103  }
4104 }
4105 
4106 
4107 ////////////////////////////////////////////////////////////////////////////////
4108 /// [Draw a bar-chart in a normal pad.](#HP10)
4109 
4111 {
4112 
4113  Int_t bar = Hoption.Bar - 10;
4114  Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4115  Double_t offset = fH->GetBarOffset();
4117  TBox box;
4118  Int_t hcolor = fH->GetFillColor();
4119  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4120  Int_t hstyle = fH->GetFillStyle();
4121  box.SetFillColor(hcolor);
4122  box.SetFillStyle(hstyle);
4123  for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4124  y = fH->GetBinContent(bin);
4125  xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4126  xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4127  ymin = gPad->GetUymin();
4128  ymax = gPad->YtoPad(y);
4129  if (ymax < gPad->GetUymin()) continue;
4130  if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4131  if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4132  if (gStyle->GetHistMinimumZero() && ymin < 0)
4133  ymin=TMath::Min(0.,gPad->GetUymax());
4134  w = (xmax-xmin)*width;
4135  xmin += offset*(xmax-xmin);
4136  xmax = xmin + w;
4137  if (bar < 1) {
4138  box.PaintBox(xmin,ymin,xmax,ymax);
4139  } else {
4140  umin = xmin + bar*(xmax-xmin)/10.;
4141  umax = xmax - bar*(xmax-xmin)/10.;
4142  //box.SetFillColor(hcolor+150); //bright
4143  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4144  box.PaintBox(xmin,ymin,umin,ymax);
4145  box.SetFillColor(hcolor);
4146  box.PaintBox(umin,ymin,umax,ymax);
4147  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4148  box.PaintBox(umax,ymin,xmax,ymax);
4149  }
4150  }
4151 }
4152 
4153 
4154 ////////////////////////////////////////////////////////////////////////////////
4155 /// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4156 
4158 {
4159 
4160  gPad->SetVertical(kFALSE);
4161 
4162  PaintInitH();
4164  TAxis *xaxis = fXaxis;
4165  TAxis *yaxis = fYaxis;
4166  if (!strcmp(xaxis->GetName(),"xaxis")) {
4167  fXaxis = yaxis;
4168  fYaxis = xaxis;
4169  }
4170 
4171  PaintFrame();
4172 
4173  Int_t bar = Hoption.Bar - 20;
4174  Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4175  Double_t offset = fH->GetBarOffset();
4176  Double_t width = fH->GetBarWidth();
4177  TBox box;
4178  Int_t hcolor = fH->GetFillColor();
4179  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4180  Int_t hstyle = fH->GetFillStyle();
4181  box.SetFillColor(hcolor);
4182  box.SetFillStyle(hstyle);
4183  for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4184  ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4185  ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4186  xmin = gPad->GetUxmin();
4187  xmax = gPad->XtoPad(fH->GetBinContent(bin));
4188  if (xmax < gPad->GetUxmin()) continue;
4189  if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4190  if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4191  if (gStyle->GetHistMinimumZero() && xmin < 0)
4192  xmin=TMath::Min(0.,gPad->GetUxmax());
4193  w = (ymax-ymin)*width;
4194  ymin += offset*(ymax-ymin);
4195  ymax = ymin + w;
4196  if (bar < 1) {
4197  box.PaintBox(xmin,ymin,xmax,ymax);
4198  } else {
4199  umin = ymin + bar*(ymax-ymin)/10.;
4200  umax = ymax - bar*(ymax-ymin)/10.;
4201  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4202  box.PaintBox(xmin,ymin,xmax,umin);
4203  box.SetFillColor(hcolor);
4204  box.PaintBox(xmin,umin,xmax,umax);
4205  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4206  box.PaintBox(xmin,umax,xmax,ymax);
4207  }
4208  }
4209 
4210  PaintTitle();
4211  // Draw box with histogram statistics and/or fit parameters
4212  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4214  TObject *obj = 0;
4215  while ((obj = next())) {
4216  if (obj->InheritsFrom(TF1::Class())) break;
4217  obj = 0;
4218  }
4219  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4220  }
4221 
4222  PaintAxis(kFALSE);
4223  fXaxis = xaxis;
4224  fYaxis = yaxis;
4225 }
4226 
4227 
4228 ////////////////////////////////////////////////////////////////////////////////
4229 /// [Control function to draw a 2D histogram as a box plot](#HP13)
4230 
4232 {
4233 
4234  Style_t fillsav = fH->GetFillStyle();
4235  Style_t colsav = fH->GetFillColor();
4236  if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
4237  if (Hoption.Box == 11) fH->SetFillStyle(1001);
4238  fH->TAttLine::Modify();
4239  fH->TAttFill::Modify();
4240 
4241  Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
4242  Double_t ux1 = gPad->PixeltoX(1);
4243  Double_t ux0 = gPad->PixeltoX(0);
4244  Double_t uy1 = gPad->PixeltoY(1);
4245  Double_t uy0 = gPad->PixeltoY(0);
4246  Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
4247  Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
4248 
4249  Double_t zmin = fH->GetMinimum();
4251  TMath::Abs(fH->GetMinimum()));
4252 
4253  // In case of option SAME, zmin and zmax values are taken from the
4254  // first plotted 2D histogram.
4255  if (Hoption.Same) {
4256  TH2 *h2;
4257  TIter next(gPad->GetListOfPrimitives());
4258  while ((h2 = (TH2 *)next())) {
4259  if (!h2->InheritsFrom(TH2::Class())) continue;
4260  zmin = h2->GetMinimum();
4261  zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
4262  TMath::Abs(h2->GetMinimum()));
4263  if (Hoption.Logz) {
4264  zmax = TMath::Log10(zmax);
4265  if (zmin <= 0) {
4266  zmin = TMath::Log10(zmax*0.001);
4267  } else {
4268  zmin = TMath::Log10(zmin);
4269  }
4270  }
4271  break;
4272  }
4273  }
4274 
4275  if (Hoption.Logz) {
4276  if (zmin > 0) {
4277  zmin = TMath::Log10(zmin*0.1);
4278  zmax = TMath::Log10(zmax);
4279  } else {
4280  return;
4281  }
4282  }
4283 
4284  Double_t zratio, dz = zmax - zmin;
4285  Bool_t kZNeg = kFALSE;
4286 
4287  // Define the dark and light colors the "button style" boxes.
4288  Color_t color = fH->GetFillColor();
4289  Color_t light=0, dark=0;
4290  if (Hoption.Box == 11) {
4291  light = TColor::GetColorBright(color);
4292  dark = TColor::GetColorDark(color);
4293  }
4294 
4295  // Loop over all the bins and draw the boxes
4296  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4297  yk = fYaxis->GetBinLowEdge(j);
4298  ystep = fYaxis->GetBinWidth(j);
4299  ycent = 0.5*ystep;
4300  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4301  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4302  xk = fXaxis->GetBinLowEdge(i);
4303  xstep = fXaxis->GetBinWidth(i);
4304  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4305  xcent = 0.5*xstep;
4306  z = Hparam.factor*fH->GetBinContent(bin);
4307  kZNeg = kFALSE;
4308 
4309  if (z < zmin) continue; // Can be the case with
4310  if (z > zmax) z = zmax; // option Same
4311 
4312  if (z < 0) {
4313  if (Hoption.Logz) continue;
4314  z = -z;
4315  kZNeg = kTRUE;
4316  }
4317  if (Hoption.Logz) {
4318  if (z != 0) z = TMath::Log10(z);
4319  else z = zmin;
4320  }
4321 
4322  if (dz == 0) continue;
4323  zratio = TMath::Sqrt((z-zmin)/dz);
4324  if (zratio == 0) continue;
4325 
4326  xup = xcent*zratio + xk + xcent;
4327  xlow = 2*(xk + xcent) - xup;
4328  if (xup-xlow < dxmin) xup = xlow+dxmin;
4329  if (Hoption.Logx) {
4330  if (xup > 0) xup = TMath::Log10(xup);
4331  else continue;
4332  if (xlow > 0) xlow = TMath::Log10(xlow);
4333  else continue;
4334  }
4335 
4336  yup = ycent*zratio + yk + ycent;
4337  ylow = 2*(yk + ycent) - yup;
4338  if (yup-ylow < dymin) yup = ylow+dymin;
4339  if (Hoption.Logy) {
4340  if (yup > 0) yup = TMath::Log10(yup);
4341  else continue;
4342  if (ylow > 0) ylow = TMath::Log10(ylow);
4343  else continue;
4344  }
4345 
4346  xlow = TMath::Max(xlow, gPad->GetUxmin());
4347  ylow = TMath::Max(ylow, gPad->GetUymin());
4348  xup = TMath::Min(xup , gPad->GetUxmax());
4349  yup = TMath::Min(yup , gPad->GetUymax());
4350 
4351  if (xlow >= xup) continue;
4352  if (ylow >= yup) continue;
4353 
4354  if (Hoption.Box == 1) {
4355  fH->SetFillColor(color);
4356  fH->TAttFill::Modify();
4357  gPad->PaintBox(xlow, ylow, xup, yup);
4358  if (kZNeg) {
4359  gPad->PaintLine(xlow, ylow, xup, yup);
4360  gPad->PaintLine(xlow, yup, xup, ylow);
4361  }
4362  } else if (Hoption.Box == 11) {
4363  // Draw the center of the box
4364  fH->SetFillColor(color);
4365  fH->TAttFill::Modify();
4366  gPad->PaintBox(xlow, ylow, xup, yup);
4367 
4368  // Draw top&left part of the box
4369  Double_t x[7], y[7];
4370  Double_t bwidth = 0.1;
4371  x[0] = xlow; y[0] = ylow;
4372  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4373  x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
4374  x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
4375  x[4] = xup; y[4] = yup;
4376  x[5] = xlow; y[5] = yup;
4377  x[6] = xlow; y[6] = ylow;
4378  if (kZNeg) fH->SetFillColor(dark);
4379  else fH->SetFillColor(light);
4380  fH->TAttFill::Modify();
4381  gPad->PaintFillArea(7, x, y);
4382 
4383  // Draw bottom&right part of the box
4384  x[0] = xlow; y[0] = ylow;
4385  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4386  x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
4387  x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
4388  x[4] = xup; y[4] = yup;
4389  x[5] = xup; y[5] = ylow;
4390  x[6] = xlow; y[6] = ylow;
4391  if (kZNeg) fH->SetFillColor(light);
4392  else fH->SetFillColor(dark);
4393  fH->TAttFill::Modify();
4394  gPad->PaintFillArea(7, x, y);
4395  }
4396  }
4397  }
4398 
4399  if (Hoption.Zscale) PaintPalette();
4400  fH->SetFillStyle(fillsav);
4401  fH->SetFillColor(colsav);
4402  fH->TAttFill::Modify();
4403 }
4404 
4405 
4406 ////////////////////////////////////////////////////////////////////////////////
4407 /// [Control function to draw a 2D histogram as a candle (box) plot.](#HP14)
4408 
4410 {
4411  /* Begin_html
4412  End_html */
4413 
4414  Double_t x,y,w;
4415  Double_t m1 = 0.055, m2 = 0.25;
4416  Double_t xpm[1], ypm[1];
4417 
4418  TH1D *hp;
4419  TH2D *h2 = (TH2D*)fH;
4420 
4421  Double_t *quantiles = new Double_t[5];
4422  quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
4423  Double_t *prob = new Double_t[5];
4424  prob[0]=1E-15; prob[1]=0.25; prob[2]=0.5; prob[3]=0.75; prob[4]=1-1E-15;
4425 
4426  Style_t fillsav = h2->GetFillStyle();
4427  Style_t colsav = h2->GetFillColor();
4428  Style_t linesav = h2->GetLineStyle();
4429  Style_t widthsav = h2->GetLineWidth();
4430  Style_t pmssav = h2->GetMarkerStyle();
4431 
4432  if (h2->GetFillColor() == 0) h2->SetFillStyle(0);
4433 
4434  h2->SetMarkerStyle(24);
4435  h2->TAttLine::Modify();
4436  h2->TAttFill::Modify();
4437  h2->TAttMarker::Modify();
4438 
4439  // Candle plot along X
4440  Double_t xb1,xb2,yb1,yb2,xl1,xl2,yl1,yl2,xl3,yl3,xp1,yp1;
4441  if (Hoption.Candle == 1) {
4442  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4443  x = fXaxis->GetBinLowEdge(i);
4444  w = fXaxis->GetBinWidth(i);
4445  hp = h2->ProjectionY("_px", i, i);
4446  if (hp->GetEntries() !=0) {
4447  hp->GetQuantiles(5, quantiles, prob);
4448  yp1 = hp->GetMean();
4449  xb1 = x+m1*w;
4450  xb2 = x+(1-m1)*w;
4451  yb1 = quantiles[1];
4452  yb2 = quantiles[3];
4453  xl1 = x+m2*w;
4454  xl2 = x+(1-m2)*w;
4455  yl1 = quantiles[0];
4456  yl2 = quantiles[4];
4457  yl3 = quantiles[2];
4458  xp1 = x+w/2.;
4459  if (Hoption.Logy) {
4460  if (yb1 > 0) yb1 = TMath::Log10(yb1); else continue;
4461  if (yb2 > 0) yb2 = TMath::Log10(yb2); else continue;
4462  if (yl1 > 0) yl1 = TMath::Log10(yl1); else continue;
4463  if (yl2 > 0) yl2 = TMath::Log10(yl2); else continue;
4464  if (yl3 > 0) yl3 = TMath::Log10(yl3); else continue;
4465  if (yp1 > 0) yp1 = TMath::Log10(yp1); else continue;
4466  }
4467  if (Hoption.Logx) {
4468  if (xb1 > 0) xb1 = TMath::Log10(xb1); else continue;
4469  if (xb2 > 0) xb2 = TMath::Log10(xb2); else continue;
4470  if (xl1 > 0) xl1 = TMath::Log10(xl1); else continue;
4471  if (xl2 > 0) xl2 = TMath::Log10(xl2); else continue;
4472  if (xp1 > 0) xp1 = TMath::Log10(xp1); else continue;
4473  }
4474  ypm[0] = yp1;
4475  h2->SetLineStyle(1);
4476  h2->TAttLine::Modify();
4477  gPad->PaintBox (xb1, yb1, xb2, yb2);
4478  gPad->PaintLine(xl1, yl1, xl2, yl1);
4479  gPad->PaintLine(xl1, yl2, xl2, yl2);
4480  h2->SetLineWidth(3*widthsav);
4481  h2->TAttLine::Modify();
4482  gPad->PaintLine(xb1, yl3, xb2, yl3);
4483  h2->SetLineWidth(widthsav);
4484  h2->TAttLine::Modify();
4485 
4486  h2->SetLineStyle(2);
4487  h2->TAttLine::Modify();
4488  gPad->PaintLine(xp1, yb2, xp1, yl2);
4489  gPad->PaintLine(xp1, yl1, xp1, yb1);
4490 
4491  xpm[0] = xp1;
4492  gPad->PaintPolyMarker(1,xpm,ypm);
4493  }
4494  }
4495  // Candle plot along Y
4496  } else {
4497  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4498  y = fYaxis->GetBinLowEdge(i);
4499  w = fYaxis->GetBinWidth(i);
4500  hp = h2->ProjectionX("_py", i, i);
4501  if (hp->GetEntries() !=0) {
4502  hp->GetQuantiles(5, quantiles, prob);
4503  xp1 = hp->GetMean();
4504  yb1 = y+m1*w;
4505  yb2 = y+(1-m1)*w;
4506  xb1 = quantiles[1];
4507  xb2 = quantiles[3];
4508  yl1 = y+m2*w;
4509  yl2 = y+(1-m2)*w;
4510  xl1 = quantiles[0];
4511  xl2 = quantiles[4];
4512  xl3 = quantiles[2];
4513  yp1 = y+w/2.;
4514  if (Hoption.Logx) {
4515  if (xb1 > 0) xb1 = TMath::Log10(xb1); else continue;
4516  if (xb2 > 0) xb2 = TMath::Log10(xb2); else continue;
4517  if (xl1 > 0) xl1 = TMath::Log10(xl1); else continue;
4518  if (xl2 > 0) xl2 = TMath::Log10(xl2); else continue;
4519  if (xl3 > 0) xl3 = TMath::Log10(xl3); else continue;
4520  if (xp1 > 0) xp1 = TMath::Log10(xp1); else continue;
4521  }
4522  if (Hoption.Logy) {
4523  if (yb1 > 0) yb1 = TMath::Log10(yb1); else continue;
4524  if (yb2 > 0) yb2 = TMath::Log10(yb2); else continue;
4525  if (yl1 > 0) yl1 = TMath::Log10(yl1); else continue;
4526  if (yl2 > 0) yl2 = TMath::Log10(yl2); else continue;
4527  if (yp1 > 0) yp1 = TMath::Log10(yp1); else continue;
4528  }
4529  xpm[0] = xp1;
4530  h2->SetLineStyle(1);
4531  h2->TAttLine::Modify();
4532 
4533  gPad->PaintBox (xb1, yb1, xb2, yb2);
4534  gPad->PaintLine(xl1, yl1, xl1, yl2);
4535  gPad->PaintLine(xl2, yl1, xl2, yl2);
4536 
4537  h2->SetLineWidth(3*widthsav);
4538  h2->TAttLine::Modify();
4539  gPad->PaintLine(xl3, yb1, xl3, yb2);
4540 
4541  h2->SetLineWidth(widthsav);
4542  h2->TAttLine::Modify();
4543 
4544  h2->SetLineStyle(2);
4545  h2->TAttLine::Modify();
4546  gPad->PaintLine(xb2, yp1, xl2, yp1);
4547  gPad->PaintLine(xl1, yp1, xb1, yp1);
4548 
4549  ypm[0] = yp1;
4550  gPad->PaintPolyMarker(1,xpm,ypm);
4551  }
4552  }
4553  }
4554 
4555  h2->SetFillStyle(fillsav);
4556  h2->SetFillColor(colsav);
4557  h2->SetLineStyle(linesav);
4558  h2->SetMarkerStyle(pmssav);
4559  h2->SetLineWidth(widthsav);
4560  h2->TAttFill::Modify();
4561  h2->TAttLine::Modify();
4562  h2->TAttMarker::Modify();
4563 
4564  delete [] prob;
4565  delete [] quantiles;
4566 }
4567 
4568 ////////////////////////////////////////////////////////////////////////////////
4569 
4571 {
4572  /* Begin_html
4573  [Control function to draw a 2D histogram as a violin plot](#HP141)
4574  End_html */
4575 
4577  Double_t bw, bcen, bcon;
4578  Double_t xpm[1], ypm[1];
4579 
4580  TH1D *hp;
4581  TH2D *h2 = (TH2D*)fH;
4582 
4583  Double_t *quantiles = new Double_t[5];
4584  quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
4585  Double_t *prob = new Double_t[5];
4586  prob[0]=1E-15; prob[1]=0.25; prob[2]=0.5; prob[3]=0.75; prob[4]=1-1E-15;
4587 
4588  Style_t fillsav = h2->GetFillStyle();
4589  Style_t colsav = h2->GetFillColor();
4590  Style_t linesav = h2->GetLineStyle();
4591  Style_t widthsav = h2->GetLineWidth();
4592  Style_t pmssav = h2->GetMarkerStyle();
4593 
4594  if (h2->GetFillColor() == 0) h2->SetFillStyle(0);
4595 
4596  h2->SetMarkerStyle(pmssav);
4597  h2->TAttLine::Modify();
4598  h2->TAttFill::Modify();
4599  h2->TAttMarker::Modify();
4600 
4601  // Violin plot along X
4602  if (Hoption.Violin == 1) {
4603  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4604  x = fXaxis->GetBinCenter(i);
4605  w = fXaxis->GetBinWidth(i);
4606  hp = h2->ProjectionY("_px", i, i);
4607  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4608  hp->Scale(1.0/hp->Integral());
4609  hp->Scale(w/hp->GetMaximum());
4610  hp->GetQuantiles(5, quantiles, prob);
4611  ypm[0] = hp->GetMean();
4612 
4613  TAxis *ax = hp->GetXaxis();
4614  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4615  bw = ax->GetBinWidth(j);
4616  bcen = ax->GetBinCenter(j);
4617  bcon = hp->GetBinContent(j);
4618  gPad->PaintBox(x-0.5*bcon, bcen-0.5*bw, x+0.5*bcon, bcen+0.5*bw);
4619  }
4620 
4621  h2->SetLineWidth(widthsav);
4622  h2->TAttLine::Modify();
4623 
4624  h2->SetLineStyle(linesav);
4625  h2->TAttLine::Modify();
4626  gPad->PaintLine(x, quantiles[3], x, quantiles[4]);
4627  gPad->PaintLine(x, quantiles[0], x, quantiles[1]);
4628 
4629  xpm[0] = x;
4630  gPad->PaintPolyMarker(1,xpm,ypm);
4631  }
4632  }
4633  // Violin plot along Y
4634  } else {
4635  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4636  y = fYaxis->GetBinCenter(i);
4637  w = fYaxis->GetBinWidth(i);
4638  hp = h2->ProjectionX("_py", i, i);
4639  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4640  hp->Scale(1.0/hp->Integral());
4641  hp->Scale(w/hp->GetMaximum());
4642  hp->GetQuantiles(5, quantiles, prob);
4643  xpm[0] = hp->GetMean();
4644 
4645  h2->SetLineWidth(1);
4646  h2->TAttLine::Modify();
4647  TAxis *ax = hp->GetXaxis();
4648  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4649  bw = ax->GetBinWidth(j);
4650  bcen = ax->GetBinCenter(j);
4651  bcon = hp->GetBinContent(j);
4652  gPad->PaintBox(bcen-0.5*bw, y-0.5*bcon, bcen+0.5*bw, y+0.5*bcon);
4653  }
4654 
4655  hp->GetQuantiles(5, quantiles, prob);
4656  xpm[0] = hp->GetMean();
4657 
4658  h2->SetLineWidth(widthsav);
4659  h2->SetLineStyle(2);
4660  h2->TAttLine::Modify();
4661  gPad->PaintLine(quantiles[3], y, quantiles[4], y);
4662  gPad->PaintLine(quantiles[0], y, quantiles[1], y);
4663 
4664  ypm[0] = y;
4665  gPad->PaintPolyMarker(1,xpm,ypm);
4666  }
4667  }
4668  }
4669 
4670  h2->SetFillStyle(fillsav);
4671  h2->SetFillColor(colsav);
4672  h2->SetLineStyle(linesav);
4673  h2->SetMarkerStyle(pmssav);
4674  h2->SetLineWidth(widthsav);
4675  h2->TAttFill::Modify();
4676  h2->TAttLine::Modify();
4677  h2->TAttMarker::Modify();
4678 
4679  delete [] prob;
4680  delete [] quantiles;
4681 }
4682 
4683 ////////////////////////////////////////////////////////////////////////////////
4684 
4686 {
4687  /* Begin_html
4688  [Control function to draw a 2D histogram as a color plot.](#HP14)
4689  End_html */
4690 
4691  Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
4692 
4693  Double_t zmin = fH->GetMinimum();
4694  Double_t zmax = fH->GetMaximum();
4695 
4696  Double_t dz = zmax - zmin;
4697  if (dz <= 0) { // Histogram filled with a constant value
4698  zmax += 0.1*TMath::Abs(zmax);
4699  zmin -= 0.1*TMath::Abs(zmin);
4700  dz = zmax - zmin;
4701  }
4702 
4703  if (Hoption.Logz) {
4704  if (zmin > 0) {
4705  zmin = TMath::Log10(zmin);
4706  zmax = TMath::Log10(zmax);
4707  dz = zmax - zmin;
4708  } else {
4709  return;
4710  }
4711  }
4712 
4713  Style_t fillsav = fH->GetFillStyle();
4714  Style_t colsav = fH->GetFillColor();
4715  fH->SetFillStyle(1001);
4716  fH->TAttFill::Modify();
4717 
4718  // Initialize the levels on the Z axis
4719  Int_t ncolors = gStyle->GetNumberOfColors();
4720  Int_t ndiv = fH->GetContour();
4721  if (ndiv == 0 ) {
4722  ndiv = gStyle->GetNumberContours();
4723  fH->SetContour(ndiv);
4724  }
4725  Int_t ndivz = TMath::Abs(ndiv);
4726  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4727  Double_t scale = ndivz/dz;
4728 
4729  Int_t color;
4730  TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
4731  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4732  yk = fYaxis->GetBinLowEdge(j);
4733  ystep = fYaxis->GetBinWidth(j);
4734  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4735  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4736  xk = fXaxis->GetBinLowEdge(i);
4737  xstep = fXaxis->GetBinWidth(i);
4738  if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
4739  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4740  z = fH->GetBinContent(bin);
4741  // if fH is a profile histogram do not draw empty bins
4742  if (prof2d) {
4743  const Double_t binEntries = prof2d->GetBinEntries(bin);
4744  if (binEntries == 0)
4745  continue;
4746  } else {
4747  // don't draw the empty bins for non-profile histograms
4748  // with positive content
4749  if (z == 0) {
4750  if (zmin >= 0 || Hoption.Logz) continue;
4751  if (Hoption.Color == 2) continue;
4752  }
4753  }
4754 
4755  if (Hoption.Logz) {
4756  if (z > 0) z = TMath::Log10(z);
4757  else z = zmin;
4758  }
4759  if (z < zmin && !Hoption.Zero) continue;
4760  xup = xk + xstep;
4761  xlow = xk;
4762  if (Hoption.Logx) {
4763  if (xup > 0) xup = TMath::Log10(xup);
4764  else continue;
4765  if (xlow > 0) xlow = TMath::Log10(xlow);
4766  else continue;
4767  }
4768  yup = yk + ystep;
4769  ylow = yk;
4770  if (Hoption.System != kPOLAR) {
4771  if (Hoption.Logy) {
4772  if (yup > 0) yup = TMath::Log10(yup);
4773  else continue;
4774  if (ylow > 0) ylow = TMath::Log10(ylow);
4775  else continue;
4776  }
4777  if (xup < gPad->GetUxmin()) continue;
4778  if (yup < gPad->GetUymin()) continue;
4779  if (xlow > gPad->GetUxmax()) continue;
4780  if (ylow > gPad->GetUymax()) continue;
4781  if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
4782  if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
4783  if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
4784  if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
4785  }
4786 
4787  if (fH->TestBit(TH1::kUserContour)) {
4788  zc = fH->GetContourLevelPad(0);
4789  if (z < zc) continue;
4790  color = -1;
4791  for (Int_t k=0; k<ndiv; k++) {
4792  zc = fH->GetContourLevelPad(k);
4793  if (z < zc) {
4794  continue;
4795  } else {
4796  color++;
4797  }
4798  }
4799  } else {
4800  color = Int_t(0.01+(z-zmin)*scale);
4801  }
4802 
4803  Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4804  if (theColor > ncolors-1) theColor = ncolors-1;
4805  fH->SetFillColor(gStyle->GetColorPalette(theColor));
4806  fH->TAttFill::Modify();
4807  if (Hoption.System != kPOLAR) {
4808  gPad->PaintBox(xlow, ylow, xup, yup);
4809  } else {
4810  TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
4811  crown.SetFillColor(gStyle->GetColorPalette(theColor));
4812  crown.Paint();
4813  }
4814  }
4815  }
4816 
4817  if (Hoption.Zscale) PaintPalette();
4818 
4819  fH->SetFillStyle(fillsav);
4820  fH->SetFillColor(colsav);
4821  fH->TAttFill::Modify();
4822 
4823 }
4824 
4825 
4826 ////////////////////////////////////////////////////////////////////////////////
4827 /// [Control function to draw a 2D histogram as a contour plot.](#HP16)
4828 
4830 {
4831 
4832  Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
4833  Int_t itars, mode, ir[4];
4834  Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
4836  if (Hoption.Contour == 14) {
4837  Hoption.Surf = 12;
4838  Hoption.Axis = 1;
4839  thesave = gPad->GetTheta();
4840  phisave = gPad->GetPhi();
4841  gPad->SetPhi(0.);
4842  gPad->SetTheta(90.);
4843  PaintSurface(option);
4844  gPad->SetPhi(phisave);
4845  gPad->SetTheta(thesave);
4846  TView *view = gPad->GetView();
4847  if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
4848  PaintAxis();
4849  return;
4850  }
4851 
4852  if (Hoption.Same) {
4853  // If the contour is painted on a 3d plot, the contour lines are
4854  // paint in 3d too.
4855  TObject *obj;
4856  TIter next(gPad->GetListOfPrimitives());
4857  while ((obj=next())) {
4858  if (strstr(obj->GetDrawOption(),"surf") ||
4859  strstr(obj->GetDrawOption(),"lego") ||
4860  strstr(obj->GetDrawOption(),"tri")) {
4861  Hoption.Surf = 16;
4862  PaintSurface(option);
4863  return;
4864  }
4865  }
4866  }
4867 
4868  if (Hoption.Contour == 15) {
4869  TGraphDelaunay2D *dt = nullptr;
4870  TGraphDelaunay *dtOld = nullptr;
4871  TList *hl = fH->GetListOfFunctions();
4872  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
4873  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
4874  if (!dt && !dtOld) return;
4875  if (!fGraph2DPainter) {
4876  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
4877  else fGraph2DPainter = new TGraph2DPainter(dtOld);
4878  }
4879  fGraph2DPainter->Paint(option);
4880  return;
4881  }
4882 
4883  gPad->SetBit(TGraph::kClipFrame);
4884 
4885  Double_t *levels = new Double_t[2*kMAXCONTOUR];
4886  Double_t *xarr = new Double_t[2*kMAXCONTOUR];
4887  Double_t *yarr = new Double_t[2*kMAXCONTOUR];
4888  Int_t *itarr = new Int_t[2*kMAXCONTOUR];
4889 
4890  Int_t npmax = 0;
4891  for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
4892 
4893  ncontour = fH->GetContour();
4894  if (ncontour == 0) {
4895  ncontour = gStyle->GetNumberContours();
4896  fH->SetContour(ncontour);
4897  }
4898  if (ncontour > kMAXCONTOUR) {
4899  Warning("PaintContour", "maximum number of contours is %d, asked for %d",
4900  kMAXCONTOUR, ncontour);
4901  ncontour = kMAXCONTOUR-1;
4902  }
4903  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
4904 
4905  for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
4906  //for (i=0;i<ncontour;i++)
4907  // levels[i] = Hparam.zmin+(Hparam.zmax-Hparam.zmin)/ncontour*i;
4908  Int_t linesav = fH->GetLineStyle();
4909  Int_t colorsav = fH->GetLineColor();
4910  Int_t fillsav = fH->GetFillColor();
4911  if (Hoption.Contour == 13) {
4912  fH->TAttLine::Modify();
4913  }
4914 
4915  TPolyLine **polys = 0;
4916  TPolyLine *poly=0;
4917  TObjArray *contours = 0;
4918  TList *list = 0;
4919  TGraph *graph = 0;
4920  Int_t *np = 0;
4921  if (Hoption.Contour == 1) {
4922  np = new Int_t[ncontour];
4923  for (i=0;i<ncontour;i++) np[i] = 0;
4924  polys = new TPolyLine*[ncontour];
4925  for (i=0;i<ncontour;i++) {
4926  polys[i] = new TPolyLine(100);
4927  }
4928  if (Hoption.List == 1) {
4929  contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
4930  if (contours) {
4931  gROOT->GetListOfSpecials()->Remove(contours);
4932  count = contours->GetSize();
4933  for (i=0;i<count;i++) {
4934  list = (TList*)contours->At(i);
4935  if (list) list->Delete();
4936  }
4937  }
4938  contours = new TObjArray(ncontour);
4939  contours->SetName("contours");
4940  gROOT->GetListOfSpecials()->Add(contours);
4941  for (i=0;i<ncontour;i++) {
4942  list = new TList();
4943  contours->Add(list);
4944  }
4945  }
4946  }
4947  Int_t theColor;
4948  Int_t ncolors = gStyle->GetNumberOfColors();
4949  Int_t ndivz = TMath::Abs(ncontour);
4950 
4951  Int_t k,ipoly;
4952  for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
4953  y[0] = fYaxis->GetBinCenter(j);
4954  y[1] = y[0];
4955  y[2] = fYaxis->GetBinCenter(j+1);
4956  y[3] = y[2];
4957  for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
4958  zc[0] = fH->GetBinContent(i, j);
4959  zc[1] = fH->GetBinContent(i+1, j);
4960  zc[2] = fH->GetBinContent(i+1, j+1);
4961  zc[3] = fH->GetBinContent(i, j+1);
4962  if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
4963  if (Hoption.Logz) {
4964  if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
4965  else zc[0] = Hparam.zmin;
4966  if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
4967  else zc[1] = Hparam.zmin;
4968  if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
4969  else zc[2] = Hparam.zmin;
4970  if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
4971  else zc[3] = Hparam.zmin;
4972  }
4973  for (k=0;k<4;k++) {
4974  ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
4975  }
4976  if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
4977  x[0] = fXaxis->GetBinCenter(i);
4978  x[3] = x[0];
4979  x[1] = fXaxis->GetBinCenter(i+1);
4980  x[2] = x[1];
4981  if (zc[0] <= zc[1]) n = 0; else n = 1;
4982  if (zc[2] <= zc[3]) m = 2; else m = 3;
4983  if (zc[n] > zc[m]) n = m;
4984  n++;
4985  lj=1;
4986  for (ix=1;ix<=4;ix++) {
4987  m = n%4 + 1;
4988  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
4989  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
4990  lj += 2*ljfill;
4991  n = m;
4992  }
4993 
4994  if (zc[0] <= zc[1]) n = 0; else n = 1;
4995  if (zc[2] <= zc[3]) m = 2; else m = 3;
4996  if (zc[n] > zc[m]) n = m;
4997  n++;
4998  lj=2;
4999  for (ix=1;ix<=4;ix++) {
5000  if (n == 1) m = 4;
5001  else m = n-1;
5002  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5003  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5004  lj += 2*ljfill;
5005  n = m;
5006  }
5007 
5008  // Re-order endpoints
5009 
5010  count = 0;
5011  for (ix=1; ix<=lj-5; ix +=2) {
5012  //count = 0;
5013  while (itarr[ix-1] != itarr[ix]) {
5014  xsave = xarr[ix];
5015  ysave = yarr[ix];
5016  itars = itarr[ix];
5017  for (jx=ix; jx<=lj-5; jx +=2) {
5018  xarr[jx] = xarr[jx+2];
5019  yarr[jx] = yarr[jx+2];
5020  itarr[jx] = itarr[jx+2];
5021  }
5022  xarr[lj-3] = xsave;
5023  yarr[lj-3] = ysave;
5024  itarr[lj-3] = itars;
5025  if (count > 100) break;
5026  count++;
5027  }
5028  }
5029 
5030  if (count > 100) continue;
5031  for (ix=1; ix<=lj-2; ix +=2) {
5032  theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5033  icol = gStyle->GetColorPalette(theColor);
5034  if (Hoption.Contour == 11) {
5035  fH->SetLineColor(icol);
5036  }
5037  if (Hoption.Contour == 12) {
5038  mode = icol%5;
5039  if (mode == 0) mode = 5;
5040  fH->SetLineStyle(mode);
5041  }
5042  if (Hoption.Contour != 1) {
5043  fH->TAttLine::Modify();
5044  gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5045  continue;
5046  }
5047 
5048  ipoly = itarr[ix-1];
5049  if (ipoly >=0 && ipoly <ncontour) {
5050  poly = polys[ipoly];
5051  poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5052  poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5053  np[ipoly] += 2;
5054  if (npmax < np[ipoly]) npmax = np[ipoly];
5055  }
5056  }
5057  } // end of if (ir[0]
5058  } //end of for (i
5059  } //end of for (j
5060 
5061  Double_t xmin,ymin;
5062  Double_t *xp, *yp;
5063  Int_t nadd,iminus,iplus;
5064  Double_t *xx, *yy;
5065  Int_t istart;
5066  Int_t first = ncontour;
5067  Int_t *polysort = 0;
5068  Int_t contListNb;
5069  if (Hoption.Contour != 1) goto theEND;
5070 
5071  //The 2 points line generated above are now sorted/merged to generate
5072  //a list of consecutive points.
5073  // If the option "List" has been specified, the list of points is saved
5074  // in the form of TGraph objects in the ROOT list of special objects.
5075  xmin = gPad->GetUxmin();
5076  ymin = gPad->GetUymin();
5077  xp = new Double_t[2*npmax];
5078  yp = new Double_t[2*npmax];
5079  polysort = new Int_t[ncontour];
5080  //find first positive contour
5081  for (ipoly=0;ipoly<ncontour;ipoly++) {
5082  if (levels[ipoly] >= 0) {first = ipoly; break;}
5083  }
5084  //store negative contours from 0 to minimum, then all positive contours
5085  k = 0;
5086  for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
5087  for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
5088  // we can now draw sorted contours
5089  contListNb = 0;
5090  fH->SetFillStyle(1001);
5091  for (k=0;k<ncontour;k++) {
5092  ipoly = polysort[k];
5093  if (np[ipoly] == 0) continue;
5094  if (Hoption.List) list = (TList*)contours->At(contListNb);
5095  contListNb++;
5096  poly = polys[ipoly];
5097  xx = poly->GetX();
5098  yy = poly->GetY();
5099  istart = 0;
5100  while (1) {
5101  iminus = npmax;
5102  iplus = iminus+1;
5103  xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
5104  xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
5105  xx[istart] = xmin; yy[istart] = ymin;
5106  xx[istart+1] = xmin; yy[istart+1] = ymin;
5107  while (1) {
5108  nadd = 0;
5109  for (i=2;i<np[ipoly];i+=2) {
5110  if (xx[i] == xp[iplus] && yy[i] == yp[iplus]) {
5111  iplus++;
5112  xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
5113  xx[i] = xmin; yy[i] = ymin;
5114  xx[i+1] = xmin; yy[i+1] = ymin;
5115  nadd++;
5116  }
5117  if (xx[i+1] == xp[iminus] && yy[i+1] == yp[iminus]) {
5118  iminus--;
5119  xp[iminus] = xx[i]; yp[iminus] = yy[i];
5120  xx[i] = xmin; yy[i] = ymin;
5121  xx[i+1] = xmin; yy[i+1] = ymin;
5122  nadd++;
5123  }
5124  }
5125  if (nadd == 0) break;
5126  }
5127  theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
5128  icol = gStyle->GetColorPalette(theColor);
5129  if (ndivz > 1) fH->SetFillColor(icol);
5130  fH->TAttFill::Modify();
5131  gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5132  if (Hoption.List) {
5133  graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5134  graph->SetFillColor(icol);
5135  graph->SetLineWidth(fH->GetLineWidth());
5136  list->Add(graph);
5137  }
5138  //check if more points are left
5139  istart = 0;
5140  for (i=2;i<np[ipoly];i+=2) {
5141  if (xx[i] != xmin && yy[i] != ymin) {
5142  istart = i;
5143  break;
5144  }
5145  }
5146  if (istart == 0) break;
5147  }
5148  }
5149 
5150  for (i=0;i<ncontour;i++) delete polys[i];
5151  delete [] polys;
5152  delete [] xp;
5153  delete [] yp;
5154  delete [] polysort;
5155 
5156 theEND:
5157  gPad->ResetBit(TGraph::kClipFrame);
5158  if (Hoption.Zscale) PaintPalette();
5159  fH->SetLineStyle(linesav);
5160  fH->SetLineColor(colorsav);
5161  fH->SetFillColor(fillsav);
5162  if (np) delete [] np;
5163  delete [] xarr;
5164  delete [] yarr;
5165  delete [] itarr;
5166  delete [] levels;
5167 }
5168 
5169 
5170 ////////////////////////////////////////////////////////////////////////////////
5171 /// Fill the matrix `xarr` and `yarr` for Contour Plot.
5172 
5174  Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
5175  Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
5176 {
5177 
5178  Bool_t vert;
5179  Double_t tlen, tdif, elev, diff, pdif, xlen;
5180  Int_t n, i, icount;
5181 
5182  if (x1 == x2) {
5183  vert = kTRUE;
5184  tlen = y2 - y1;
5185  } else {
5186  vert = kFALSE;
5187  tlen = x2 - x1;
5188  }
5189 
5190  n = icont1 +1;
5191  tdif = elev2 - elev1;
5192  i = 0;
5193  icount = 0;
5194  while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
5195  //elev = fH->GetContourLevel(n);
5196  elev = levels[n];
5197  diff = elev - elev1;
5198  pdif = diff/tdif;
5199  xlen = tlen*pdif;
5200  if (vert) {
5201  if (Hoption.Logx)
5202  xarr[i] = TMath::Log10(x1);
5203  else
5204  xarr[i] = x1;
5205  if (Hoption.Logy)
5206  yarr[i] = TMath::Log10(y1 + xlen);
5207  else
5208  yarr[i] = y1 + xlen;
5209  } else {
5210  if (Hoption.Logx)
5211  xarr[i] = TMath::Log10(x1 + xlen);
5212  else
5213  xarr[i] = x1 + xlen;
5214  if (Hoption.Logy)
5215  yarr[i] = TMath::Log10(y1);
5216  else
5217  yarr[i] = y1;
5218  }
5219  itarr[i] = n;
5220  icount++;
5221  i +=2;
5222  n++;
5223  }
5224  return icount;
5225 }
5226 
5227 
5228 ////////////////////////////////////////////////////////////////////////////////
5229 /// [Draw 1D histograms error bars.](#HP09)
5230 
5232 {
5233 
5234  // On iOS, we do not highlight histogram, if it's not picked at the moment
5235  // (but part of histogram (axis or pavestat) was picked, that's why this code
5236  // is called at all. This conditional statement never executes on non-iOS platform.
5237  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
5238 
5239  const Int_t kBASEMARKER=8;
5240  Double_t xp, yp, ex1, ex2, ey1, ey2;
5241  Double_t delta;
5242  Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
5243  Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
5244  Double_t xmin, xmax, ymin, ymax;
5245  Double_t logxmin = 0;
5246  Double_t logymin = 0;
5247  Int_t i, k, npoints, first, last, fixbin;
5248  Int_t if1 = 0;
5249  Int_t if2 = 0;
5250  Int_t drawmarker, errormarker;
5251  Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
5252 
5253  Double_t *xline = 0;
5254  Double_t *yline = 0;
5255  option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
5256  if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
5257  if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
5258  if (Hoption.Error == 10) option0 = 1;
5259  if (Hoption.Error == 11) option1 = 1;
5260  if (Hoption.Error == 12) option2 = 1;
5261  if (Hoption.Error == 13) option3 = 1;
5262  if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
5263  if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
5264  if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
5265  if (option2+option3 == 0) optionE = 1;
5266  if (Hoption.Error == 0) optionE = 0;
5267  if (fXaxis->GetXbins()->fN) fixbin = 0;
5268  else fixbin = 1;
5269 
5270  errormarker = fH->GetMarkerStyle();
5271  if (optionEX0) {
5272  xerror = 0;
5273  } else {
5274  xerror = gStyle->GetErrorX();
5275  }
5276  symbolsize = fH->GetMarkerSize();
5277  if (errormarker == 1) symbolsize = 0.01;
5278  sbase = symbolsize*kBASEMARKER;
5279  // set the graphics attributes
5280 
5281  fH->TAttLine::Modify();
5282  fH->TAttFill::Modify();
5283  fH->TAttMarker::Modify();
5284 
5285  // set the first and last bin
5286 
5287  Double_t factor = Hparam.factor;
5288  first = Hparam.xfirst;
5289  last = Hparam.xlast;
5290  npoints = last - first +1;
5291  xmin = gPad->GetUxmin();
5292  xmax = gPad->GetUxmax();
5293  ymin = gPad->GetUymin();
5294  ymax = gPad->GetUymax();
5295 
5296 
5297  if (option3) {
5298  xline = new Double_t[2*npoints];
5299  yline = new Double_t[2*npoints];
5300  if (!xline || !yline) {
5301  Error("PaintErrors", "too many points, out of memory");
5302  return;
5303  }
5304  if1 = 1;
5305  if2 = 2*npoints;
5306  }
5307 
5308  // compute the offset of the error bars due to the symbol size
5309  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
5310  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
5311 
5312  // compute size of the lines at the end of the error bars
5313  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
5314  bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
5315  bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
5316 
5317 
5318  if (fixbin) {
5319  if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
5320  else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
5321  } else {
5322  delta = fH->GetBinWidth(first);
5323  xp = fH->GetBinLowEdge(first) + 0.5*delta;
5324  }
5325 
5326  // if errormarker = 0 or symbolsize = 0. no symbol is drawn
5327  if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
5328  if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
5329 
5330  // ---------------------- Loop over the points---------------------
5331  for (k=first; k<=last; k++) {
5332 
5333  // get the data
5334  // xp = X position of the current point
5335  // yp = Y position of the current point
5336  // ex1 = Low X error
5337  // ex2 = Up X error
5338  // ey1 = Low Y error
5339  // ey2 = Up Y error
5340  // (xi,yi) = Error bars coordinates
5341 
5342  if (Hoption.Logx) {
5343  if (xp <= 0) goto L30;
5344  if (xp < logxmin) goto L30;
5345  if (xp > TMath::Power(10,xmax)) break;
5346  } else {
5347  if (xp < xmin) goto L30;
5348  if (xp > xmax) break;
5349  }
5350  yp = factor*fH->GetBinContent(k);
5351  if (optionI0 && yp==0) goto L30;
5352  if (fixbin) {
5353  ex1 = xerror*Hparam.xbinsize;
5354  } else {
5355  delta = fH->GetBinWidth(k);
5356  ex1 = xerror*delta;
5357  }
5358  if (fH->GetBinErrorOption() == TH1::kNormal) {
5359  ey1 = factor*fH->GetBinError(k);
5360  ey2 = ey1;
5361  } else {
5362  ey1 = factor*fH->GetBinErrorLow(k);
5363  ey2 = factor*fH->GetBinErrorUp(k);
5364  }
5365  ex2 = ex1;
5366 
5367  xi4 = xp;
5368  xi3 = xp;
5369  xi2 = xp + ex2;
5370  xi1 = xp - ex1;
5371 
5372  yi1 = yp;
5373  yi2 = yp;
5374  yi3 = yp - ey1;
5375  yi4 = yp + ey2;
5376 
5377  // take the LOG if necessary
5378  if (Hoption.Logx) {
5379  xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
5380  xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
5381  xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
5382  xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
5383  }
5384  if (Hoption.Logy) {
5385  yi1 = TMath::Log10(TMath::Max(yi1,logymin));
5386  yi2 = TMath::Log10(TMath::Max(yi2,logymin));
5387  yi3 = TMath::Log10(TMath::Max(yi3,logymin));
5388  yi4 = TMath::Log10(TMath::Max(yi4,logymin));
5389  }
5390 
5391  // test if error bars are not outside the limits
5392  // otherwise they are truncated
5393 
5394  xi1 = TMath::Max(xi1,xmin);
5395  xi2 = TMath::Min(xi2,xmax);
5396  yi3 = TMath::Max(yi3,ymin);
5397  yi4 = TMath::Min(yi4,ymax);
5398 
5399  // test if the marker is on the frame limits. If "Yes", the
5400  // marker will not be drawn and the error bars will be readjusted.
5401 
5402  drawmarker = kTRUE;
5403  if (!option0 && !option3) {
5404  if (Hoption.Logy && yp < logymin) goto L30;
5405  if (yi1 < ymin || yi1 > ymax) goto L30;
5406  if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
5407  }
5408  if (!symbolsize || !errormarker) drawmarker = kFALSE;
5409 
5410  // draw the error rectangles
5411  if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
5412 
5413  // keep points for fill area drawing
5414  if (option3) {
5415  xline[if1-1] = xi3;
5416  xline[if2-1] = xi3;
5417  yline[if1-1] = yi4;
5418  yline[if2-1] = yi3;
5419  if1++;
5420  if2--;
5421  }
5422 
5423  // draw the error bars
5424  if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
5425  if (optionE && drawmarker) {
5426  if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
5427  if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
5428  // don't duplicate the horizontal line
5429  if (Hoption.Hist != 2) {
5430  if (yi1<ymax && yi1>ymin) {
5431  if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
5432  if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
5433  }
5434  }
5435  }
5436  if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
5437  if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
5438  if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
5439  // don't duplicate the horizontal line
5440  if (Hoption.Hist != 2) {
5441  if (yi1<ymax && yi1>ymin) {
5442  if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
5443  if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
5444  }
5445  }
5446  }
5447 
5448  // draw line at the end of the error bars
5449 
5450  if (option1 && drawmarker) {
5451  if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
5452  if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
5453  if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
5454  if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
5455  }
5456 
5457  // draw the marker
5458 
5459  if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
5460 
5461 L30:
5462  if (fixbin) xp += Hparam.xbinsize;
5463  else {
5464  if (k < last) {
5465  delta = fH->GetBinWidth(k+1);
5466  xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
5467  }
5468  }
5469  } //end of for loop
5470 
5471  // draw the filled area
5472 
5473  if (option3) {
5474  TGraph graph;
5475  graph.SetLineStyle(fH->GetLineStyle());
5476  graph.SetLineColor(fH->GetLineColor());
5477  graph.SetLineWidth(fH->GetLineWidth());
5478  graph.SetFillStyle(fH->GetFillStyle());
5479  graph.SetFillColor(fH->GetFillColor());
5480  Int_t logx = gPad->GetLogx();
5481  Int_t logy = gPad->GetLogy();
5482  gPad->SetLogx(0);
5483  gPad->SetLogy(0);
5484 
5485  // In some cases the number of points in the fill area is smaller than
5486  // 2*npoints. In such cases the array xline and yline must be arranged
5487  // before being plotted. The next loop does that.
5488  if (if2 > npoints) {
5489  for (i=1; i<if1; i++) {
5490  xline[if1-2+i] = xline[if2-1+i];
5491  yline[if1-2+i] = yline[if2-1+i];
5492  }
5493  npoints = if1-1;
5494  }
5495  if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
5496  else graph.PaintGraph(2*npoints,xline,yline,"F");
5497  gPad->SetLogx(logx);
5498  gPad->SetLogy(logy);
5499  delete [] xline;
5500  delete [] yline;
5501  }
5502 }
5503 
5504 
5505 ////////////////////////////////////////////////////////////////////////////////
5506 /// Draw 2D histograms errors.
5507 
5509 {
5510 
5511  fH->TAttMarker::Modify();
5512  fH->TAttLine::Modify();
5513 
5514  // Define the 3D view
5515  fXbuf[0] = Hparam.xmin;
5516  fYbuf[0] = Hparam.xmax;
5517  fXbuf[1] = Hparam.ymin;
5518  fYbuf[1] = Hparam.ymax;
5519  fXbuf[2] = Hparam.zmin;
5520  fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
5522  TView *view = gPad->GetView();
5523  if (!view) {
5524  Error("Paint2DErrors", "no TView in current pad");
5525  return;
5526  }
5527  Double_t thedeg = 90 - gPad->GetTheta();
5528  Double_t phideg = -90 - gPad->GetPhi();
5529  Double_t psideg = view->GetPsi();
5530  Int_t irep;
5531  view->SetView(phideg, thedeg, psideg, irep);
5532 
5533  // Set color/style for back box
5534  fLego->SetFillStyle(gPad->GetFrameFillStyle());
5535  fLego->SetFillColor(gPad->GetFrameFillColor());
5536  fLego->TAttFill::Modify();
5537  Int_t backcolor = gPad->GetFrameFillColor();
5538  if (Hoption.System != kCARTESIAN) backcolor = 0;
5539  view->PadRange(backcolor);
5542  fLego->TAttFill::Modify();
5543 
5544  // Paint the Back Box if needed
5545  if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
5546  fLego->InitMoveScreen(-1.1,1.1);
5549  fLego->BackBox(90);
5550  }
5551 
5552  // Paint the Errors
5553  Double_t x, ex, x1, x2;
5554  Double_t y, ey, y1, y2;
5555  Double_t z, ez1, ez2, z1, z2;
5556  Double_t temp1[3],temp2[3];
5557  Double_t xyerror;
5558  if (Hoption.Error == 110) {
5559  xyerror = 0;
5560  } else {
5561  xyerror = gStyle->GetErrorX();
5562  }
5563 
5564  Double_t xk, xstep, yk, ystep;
5565  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5566  y = fYaxis->GetBinCenter(j);
5567  ey = fYaxis->GetBinWidth(j)*xyerror;
5568  y1 = y-ey;
5569  y2 = y+ey;
5570  if (Hoption.Logy) {
5571  if (y > 0) y = TMath::Log10(y);
5572  else continue;
5573  if (y1 > 0) y1 = TMath::Log10(y1);
5574  else y1 = Hparam.ymin;
5575  if (y2 > 0) y2 = TMath::Log10(y2);
5576  else y2 = Hparam.ymin;
5577  }
5578  yk = fYaxis->GetBinLowEdge(j);
5579  ystep = fYaxis->GetBinWidth(j);
5580  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5581  xk = fXaxis->GetBinLowEdge(i);
5582  xstep = fXaxis->GetBinWidth(i);
5583  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5584  Int_t bin = fH->GetBin(i,j);
5585  x = fXaxis->GetBinCenter(i);
5586  ex = fXaxis->GetBinWidth(i)*xyerror;
5587  x1 = x-ex;
5588  x2 = x+ex;
5589  if (Hoption.Logx) {
5590  if (x > 0) x = TMath::Log10(x);
5591  else continue;
5592  if (x1 > 0) x1 = TMath::Log10(x1);
5593  else x1 = Hparam.xmin;
5594  if (x2 > 0) x2 = TMath::Log10(x2);
5595  else x2 = Hparam.xmin;
5596  }
5597  z = fH->GetBinContent(bin);
5598  if (fH->GetBinErrorOption() == TH1::kNormal) {
5599  ez1 = fH->GetBinError(bin);
5600  ez2 = ez1;
5601  }
5602  else {
5603  ez1 = fH->GetBinErrorLow(bin);
5604  ez2 = fH->GetBinErrorUp(bin);
5605  }
5606  z1 = z - ez1;
5607  z2 = z + ez2;
5608  if (Hoption.Logz) {
5609  if (z > 0) z = TMath::Log10(z);
5610  else z = Hparam.zmin;
5611  if (z1 > 0) z1 = TMath::Log10(z1);
5612  else z1 = Hparam.zmin;
5613  if (z2 > 0) z2 = TMath::Log10(z2);
5614  else z2 = Hparam.zmin;
5615 
5616  }
5617  if (z <= Hparam.zmin) continue;
5618  if (z > Hparam.zmax) z = Hparam.zmax;
5619 
5620  temp1[0] = x1;
5621  temp1[1] = y;
5622  temp1[2] = z;
5623  temp2[0] = x2;
5624  temp2[1] = y;
5625  temp2[2] = z;
5626  gPad->PaintLine3D(temp1, temp2);
5627  temp1[0] = x;
5628  temp1[1] = y1;
5629  temp1[2] = z;
5630  temp2[0] = x;
5631  temp2[1] = y2;
5632  temp2[2] = z;
5633  gPad->PaintLine3D(temp1, temp2);
5634  temp1[0] = x;
5635  temp1[1] = y;
5636  temp1[2] = z1;
5637  temp2[0] = x;
5638  temp2[1] = y;
5639  temp2[2] = z2;
5640  gPad->PaintLine3D(temp1, temp2);
5641  temp1[0] = x;
5642  temp1[1] = y;
5643  temp1[2] = z;
5644  view->WCtoNDC(temp1, &temp2[0]);
5645  gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
5646  }
5647  }
5648 
5649  // Paint the Front Box if needed
5650  if (Hoption.FrontBox) {
5651  fLego->InitMoveScreen(-1.1,1.1);
5653  fLego->FrontBox(90);
5654  }
5655 
5656  // Paint the Axis if needed
5657  if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
5658  TGaxis *axis = new TGaxis();
5659  PaintLegoAxis(axis, 90);
5660  delete axis;
5661  }
5662 
5663  delete fLego; fLego = 0;
5664 }
5665 
5666 
5667 ////////////////////////////////////////////////////////////////////////////////
5668 /// Calculate range and clear pad (canvas).
5669 
5671 {
5672 
5673  if (Hoption.Same) return;
5674 
5675  RecalculateRange();
5677  if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
5678  Hoption.Contour == 14 || Hoption.Error >= 100) {
5679  TObject *frame = gPad->FindObject("TFrame");
5680  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
5681  return;
5682  }
5683 
5684  //The next statement is always executed on non-iOS platform,
5685  //on iOS depends on pad mode.
5686  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
5687  gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
5688 }
5689 
5690 
5691 ////////////////////////////////////////////////////////////////////////////////
5692 /// [Paint functions associated to an histogram.](#HP28")
5693 
5695 {
5696 
5698  TObject *obj;
5699 
5700  while (lnk) {
5701  obj = lnk->GetObject();
5702  TVirtualPad *padsave = gPad;
5703  if (obj->InheritsFrom(TF2::Class())) {
5704  if (obj->TestBit(TF2::kNotDraw) == 0) {
5705  if (Hoption.Lego || Hoption.Surf) {
5706  TF2 *f2 = (TF2*)obj;
5707  f2->SetMinimum(fH->GetMinimum());
5708  f2->SetMaximum(fH->GetMaximum());
5709  f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
5710  f2->Paint("surf same");
5711  } else {
5712  obj->Paint("cont3 same");
5713  }
5714  }
5715  } else if (obj->InheritsFrom(TF1::Class())) {
5716  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
5717  } else {
5718  //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
5719  gPad->PushSelectableObject(obj);
5720 
5721  //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
5722  //and picked object.
5723  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
5724  obj->Paint(lnk->GetOption());
5725  }
5726  lnk = (TObjOptLink*)lnk->Next();
5727  padsave->cd();
5728  }
5729 }
5730 
5731 
5732 ////////////////////////////////////////////////////////////////////////////////
5733 /// [Control routine to draw 1D histograms](#HP01b)
5734 
5736 {
5737 
5738  //On iOS: do not highlight hist, if part of it was selected.
5739  //Never executes on non-iOS platform.
5740  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
5741  return;
5742 
5743  static char chopth[17];
5744 
5745  Int_t htype, oldhtype;
5746  Int_t i, j, first, last, nbins, fixbin;
5747  Double_t c1, yb;
5748  yb = 0;
5749 
5750  strlcpy(chopth, " ",17);
5751 
5752  Double_t ymin = Hparam.ymin;
5753  Double_t ymax = Hparam.ymax;
5754  Double_t baroffset = fH->GetBarOffset();
5755  Double_t barwidth = fH->GetBarWidth();
5756  Double_t baroffsetsave = gStyle->GetBarOffset();
5757  Double_t barwidthsave = gStyle->GetBarWidth();
5758  gStyle->SetBarOffset(baroffset);
5759  gStyle->SetBarWidth(barwidth);
5760 
5761  // Create "LIFE" structure to keep current histogram status
5762 
5763  first = Hparam.xfirst;
5764  last = Hparam.xlast;
5765  nbins = last - first + 1;
5766 
5767  Double_t *keepx = 0;
5768  Double_t *keepy = 0;
5769  if (fXaxis->GetXbins()->fN) fixbin = 0;
5770  else fixbin = 1;
5771  if (fixbin) keepx = new Double_t[2];
5772  else keepx = new Double_t[nbins+1];
5773  keepy = new Double_t[nbins];
5774  Double_t logymin = 0;
5775  if (Hoption.Logy) logymin = TMath::Power(10,ymin);
5776 
5777  // Loop on histogram bins
5778 
5779  for (j=first; j<=last;j++) {
5780  c1 = Hparam.factor*fH->GetBinContent(j);
5781  if (TMath::Abs(ymax-ymin) > 0) {
5782  if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
5783  else yb = c1;
5784  }
5785  if (!Hoption.Line) {
5786  yb = TMath::Max(yb, ymin);
5787  yb = TMath::Min(yb, ymax);
5788  }
5789  keepy[j-first] = yb;
5790  }
5791 
5792  // Draw histogram according to value of FillStyle and FillColor
5793 
5794  if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
5795  else {
5796  for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
5797  keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
5798  }
5799 
5800  // Prepare Fill area (systematic with option "Bar").
5801 
5802  oldhtype = fH->GetFillStyle();
5803  htype = oldhtype;
5804  if (Hoption.Bar) {
5805  if (htype == 0 || htype == 1000) htype = 1001;
5806  }
5807 
5808  Width_t lw = (Width_t)fH->GetLineWidth();
5809 
5810  // Code option for GrapHist
5811 
5812  if (Hoption.Line) chopth[0] = 'L';
5813  if (Hoption.Star) chopth[1] = '*';
5814  if (Hoption.Mark) chopth[2] = 'P';
5815  if (Hoption.Mark == 10) chopth[3] = '0';
5816  if (Hoption.Line || Hoption.Curve || Hoption.Hist || Hoption.Bar) {
5817  if (Hoption.Curve) chopth[3] = 'C';
5818  if (Hoption.Hist > 0) chopth[4] = 'H';
5819  else if (Hoption.Bar) chopth[5] = 'B';
5820  if (fH->GetFillColor() && htype) {
5821  if (Hoption.Logy) {
5822  chopth[6] = '1';
5823  }
5824  if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
5825  chopth[7] = 'F';
5826  }
5827  }
5828  }
5829  if (!fixbin && strlen(chopth)) {
5830  chopth[8] = 'N';
5831  }
5832 
5833  if (Hoption.Fill == 2) chopth[13] = '2';
5834 
5835  // Option LOGX
5836 
5837  if (Hoption.Logx) {
5838  chopth[9] = 'G';
5839  chopth[10] = 'X';
5840  if (fixbin) {
5841  keepx[0] = TMath::Power(10,keepx[0]);
5842  keepx[1] = TMath::Power(10,keepx[1]);
5843  }
5844  }
5845 
5846  if (Hoption.Off) {
5847  chopth[11] = ']';
5848  chopth[12] = '[';
5849  }
5850 
5851  // Draw the histogram
5852 
5853  TGraph graph;
5854  graph.SetLineWidth(lw);
5855  graph.SetLineStyle(fH->GetLineStyle());
5856  graph.SetLineColor(fH->GetLineColor());
5857  graph.SetFillStyle(htype);
5858  graph.SetFillColor(fH->GetFillColor());
5859  graph.SetMarkerStyle(fH->GetMarkerStyle());
5860  graph.SetMarkerSize(fH->GetMarkerSize());
5861  graph.SetMarkerColor(fH->GetMarkerColor());
5862  if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
5863 
5864  graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
5865 
5866  delete [] keepx;
5867  delete [] keepy;
5868  gStyle->SetBarOffset(baroffsetsave);
5869  gStyle->SetBarWidth(barwidthsave);
5870 
5871  htype=oldhtype;
5872 }
5873 
5874 
5875 ////////////////////////////////////////////////////////////////////////////////
5876 /// [Control function to draw a 3D histograms.](#HP01d)
5877 
5878 void THistPainter::PaintH3(Option_t *option)
5879 {
5880 
5881  char *cmd;
5882  TString opt = fH->GetDrawOption();
5883  opt.ToLower();
5884  Int_t irep;
5885 
5886  if (fH->GetDrawOption() && (strstr(opt,"box") || strstr(opt,"lego"))) {
5887  cmd = Form("TMarker3DBox::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
5888  } else if (fH->GetDrawOption() && strstr(opt,"iso")) {
5889  PaintH3Iso();
5890  return;
5891  } else if (strstr(option,"tf3")) {
5892  PaintTF3();
5893  return;
5894  } else {
5895  cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
5896  }
5897 
5898  if (strstr(opt,"fb")) Hoption.FrontBox = 0;
5899  if (strstr(opt,"bb")) Hoption.BackBox = 0;
5900 
5901  TView *view = gPad->GetView();
5902  if (!view) return;
5903  Double_t thedeg = 90 - gPad->GetTheta();
5904  Double_t phideg = -90 - gPad->GetPhi();
5905  Double_t psideg = view->GetPsi();
5906  view->SetView(phideg, thedeg, psideg, irep);
5907 
5908  // Paint the data
5909  gROOT->ProcessLine(cmd);
5910 
5911  if (Hoption.Same) return;
5912 
5913  // Draw axis
5914  view->SetOutlineToCube();
5915  TSeqCollection *ol = view->GetOutline();
5916  if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
5917  Hoption.System = kCARTESIAN;
5918  TGaxis *axis = new TGaxis();
5919  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
5920  delete axis;
5921 
5922  // Draw palette. In case of 4D plot with TTree::Draw() the palette should
5923  // be painted with the option colz.
5924  if (fH->GetDrawOption() && strstr(opt,"colz")) {
5925  Int_t ndiv = fH->GetContour();
5926  if (ndiv == 0 ) {
5927  ndiv = gStyle->GetNumberContours();
5928  fH->SetContour(ndiv);
5929  }
5930  PaintPalette();
5931  }
5932 
5933  // Draw title
5934  PaintTitle();
5935 
5936  //Draw stats and fit results
5937  TF1 *fit = 0;
5939  TObject *obj;
5940  while ((obj = next())) {
5941  if (obj->InheritsFrom(TF1::Class())) {
5942  fit = (TF1*)obj;
5943  break;
5944  }
5945  }
5946  if (Hoption.Same != 1) {
5947  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5948  PaintStat3(gStyle->GetOptStat(),fit);
5949  }
5950  }
5951 
5952 }
5953 
5954 
5955 ////////////////////////////////////////////////////////////////////////////////
5956 /// Compute histogram parameters used by the drawing routines.
5957 
5959 {
5960 
5961  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
5962 
5963  Int_t i;
5964  static const char *where = "PaintInit";
5965  Double_t yMARGIN = gStyle->GetHistTopMargin();
5966  Int_t maximum = 0;
5967  Int_t minimum = 0;
5968  if (fH->GetMaximumStored() != -1111) maximum = 1;
5969  if (fH->GetMinimumStored() != -1111) minimum = 1;
5970 
5971  // Compute X axis parameters
5972 
5973  Int_t last = fXaxis->GetLast();
5974  Int_t first = fXaxis->GetFirst();
5975  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
5976  Hparam.xbinsize = fXaxis->GetBinWidth(first);
5977  Hparam.xlast = last;
5978  Hparam.xfirst = first;
5979  Hparam.xmin = Hparam.xlowedge;
5980  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
5981 
5982  // if log scale in X, replace xmin,max by the log
5983  if (Hoption.Logx) {
5984  if (Hparam.xmax<=0) {
5985  Error(where, "cannot set X axis to log scale");
5986  return 0;
5987  }
5988  if (Hparam.xlowedge <=0 ) {
5989  if (Hoption.Same) {
5990  Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
5991  } else {
5992  for (i=first; i<=last; i++) {
5993  Double_t binLow = fXaxis->GetBinLowEdge(i);
5994  if (binLow>0) {
5995  Hparam.xlowedge = binLow;
5996  break;
5997  }
5998  if (binLow == 0 && fH->GetBinContent(i) !=0) {
5999  Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6000  break;
6001  }
6002  }
6003  if (Hparam.xlowedge<=0) {
6004  Error(where, "cannot set X axis to log scale");
6005  return 0;
6006  }
6007  }
6008  Hparam.xmin = Hparam.xlowedge;
6009  }
6010  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
6011  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
6012  Hparam.xmin = TMath::Log10(Hparam.xmin);
6013  Hparam.xmax = TMath::Log10(Hparam.xmax);
6014  if (Hparam.xlast > last) Hparam.xlast = last;
6015  if (Hparam.xfirst < first) Hparam.xfirst = first;
6016  }
6017 
6018  // Compute Y axis parameters
6019  Double_t bigp = TMath::Power(10,32);
6020  Double_t ymax = -bigp;
6021  Double_t ymin = bigp;
6022  Double_t c1, e1;
6023  Double_t xv[1];
6024  Double_t fval;
6025  TObject *f;
6026  TF1 *f1;
6027  Double_t allchan = 0;
6028  Int_t nonNullErrors = 0;
6030  for (i=first; i<=last;i++) {
6031  c1 = fH->GetBinContent(i);
6032  ymax = TMath::Max(ymax,c1);
6033  if (Hoption.Logy) {
6034  if (c1 > 0) ymin = TMath::Min(ymin,c1);
6035  } else {
6036  ymin = TMath::Min(ymin,c1);
6037  }
6038  if (Hoption.Error) {
6039  if (fH->GetBinErrorOption() == TH1::kNormal)
6040  e1 = fH->GetBinError(i);
6041  else
6042  e1 = fH->GetBinErrorUp(i);
6043  if (e1 > 0) nonNullErrors++;
6044  ymax = TMath::Max(ymax,c1+e1);
6045  if (fH->GetBinErrorOption() != TH1::kNormal)
6046  e1 = fH->GetBinErrorLow(i);
6047 
6048  if (Hoption.Logy) {
6049  if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6050  } else {
6051  ymin = TMath::Min(ymin,c1-e1);
6052  }
6053  }
6054  if (Hoption.Func) {
6055  xv[0] = fXaxis->GetBinCenter(i);
6056  while ((f = (TObject*) next())) {
6057  if (f->IsA() == TF1::Class()) {
6058  f1 = (TF1*)f;
6059  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6060  fval = f1->Eval(xv[0],0,0);
6061  if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6062  ymax = TMath::Max(ymax,fval);
6063  if (Hoption.Logy) {
6064  if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6065  }
6066  }
6067  }
6068  next.Reset();
6069  }
6070  allchan += c1;
6071  }
6072  if (!nonNullErrors) {
6073  if (Hoption.Error) {
6074  if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
6075  Hoption.Error=0;
6076  }
6077  }
6078 
6079 
6080  // Take into account maximum , minimum
6081 
6082  if (Hoption.Logy && ymin <= 0) {
6083  if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
6084  else ymin = 0.001*ymax;
6085  }
6086 
6087  Double_t xm = ymin;
6088  if (maximum) ymax = fH->GetMaximumStored();
6089  if (minimum) xm = fH->GetMinimumStored();
6090  if (Hoption.Logy && xm < 0) {
6091  Error(where, "log scale requested with a negative argument (%f)", xm);
6092  return 0;
6093  } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
6094  ymin = 0.01;
6095  ymax = 10.;
6096  } else {
6097  ymin = xm;
6098  }
6099 
6100  if (ymin >= ymax) {
6101  if (Hoption.Logy) {
6102  if (ymax > 0) ymin = 0.001*ymax;
6103  else {
6104  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
6105  return 0;
6106  }
6107  }
6108  else {
6109  if (ymin > 0) {
6110  ymin = 0;
6111  ymax *= 2;
6112  } else if (ymin < 0) {
6113  ymax = 0;
6114  ymin *= 2;
6115  } else {
6116  ymin = 0;
6117  ymax = 1;
6118  }
6119  }
6120  }
6121 
6122  // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
6123  if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
6124  ymin = ymin*(1-1E-14);
6125  ymax = ymax*(1+1E-14);
6126  }
6127 
6128  // take into account normalization factor
6129  Hparam.allchan = allchan;
6130  Double_t factor = allchan;
6131  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6132  if (allchan) factor /= allchan;
6133  if (factor == 0) factor = 1;
6134  Hparam.factor = factor;
6135  ymax = factor*ymax;
6136  ymin = factor*ymin;
6137  //just in case the norm factor is negative
6138  // this may happen with a positive norm factor and a negative integral !
6139  if (ymax < ymin) {
6140  Double_t temp = ymax;
6141  ymax = ymin;
6142  ymin = temp;
6143  }
6144 
6145  // For log scales, histogram coordinates are LOG10(ymin) and
6146  // LOG10(ymax). Final adjustment (if not option "Same"
6147  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6148  // Maximum and Minimum are not defined.
6149  if (Hoption.Logy) {
6150  if (ymin <=0 || ymax <=0) {
6151  Error(where, "Cannot set Y axis to log scale");
6152  return 0;
6153  }
6154  ymin = TMath::Log10(ymin);
6155  if (!minimum) ymin += TMath::Log10(0.5);
6156  ymax = TMath::Log10(ymax);
6157  if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
6158  if (!Hoption.Same) {
6159  Hparam.ymin = ymin;
6160  Hparam.ymax = ymax;
6161  }
6162  return 1;
6163  }
6164 
6165  // final adjustment of ymin for linear scale.
6166  // if minimum is not set , then ymin is set to zero if >0
6167  // or to ymin - margin if <0.
6168  if (!minimum) {
6169  if (gStyle->GetHistMinimumZero()) {
6170  if (ymin >= 0) ymin = 0;
6171  else ymin -= yMARGIN*(ymax-ymin);
6172  } else {
6173  Double_t dymin = yMARGIN*(ymax-ymin);
6174  if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
6175  else ymin -= dymin;
6176  }
6177  }
6178 
6179  // final adjustment of YMAXI for linear scale (if not option "Same"):
6180  // decrease histogram height to MAX% of allowed height if HMAXIM
6181  // has not been called.
6182  if (!maximum) {
6183  ymax += yMARGIN*(ymax-ymin);
6184  }
6185 
6186  Hparam.ymin = ymin;
6187  Hparam.ymax = ymax;
6188  return 1;
6189 }
6190 
6191 
6192 ////////////////////////////////////////////////////////////////////////////////
6193 /// Compute histogram parameters used by the drawing routines for a rotated pad.
6194 
6196 {
6197 
6198  static const char *where = "PaintInitH";
6199  Double_t yMARGIN = gStyle->GetHistTopMargin();
6200  Int_t maximum = 0;
6201  Int_t minimum = 0;
6202  if (fH->GetMaximumStored() != -1111) maximum = 1;
6203  if (fH->GetMinimumStored() != -1111) minimum = 1;
6204 
6205  // Compute X axis parameters
6206 
6207  Int_t last = fXaxis->GetLast();
6208  Int_t first = fXaxis->GetFirst();
6209  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6210  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6211  Hparam.xlast = last;
6212  Hparam.xfirst = first;
6213  Hparam.ymin = Hparam.xlowedge;
6214  Hparam.ymax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6215 
6216  // if log scale in Y, replace ymin,max by the log
6217  if (Hoption.Logy) {
6218  if (Hparam.xlowedge <=0 ) {
6219  Hparam.xlowedge = 0.1*Hparam.xbinsize;
6220  Hparam.ymin = Hparam.xlowedge;
6221  }
6222  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
6223  Error(where, "cannot set Y axis to log scale");
6224  return 0;
6225  }
6226  Hparam.xfirst= fXaxis->FindFixBin(Hparam.ymin);
6227  Hparam.xlast = fXaxis->FindFixBin(Hparam.ymax);
6228  Hparam.ymin = TMath::Log10(Hparam.ymin);
6229  Hparam.ymax = TMath::Log10(Hparam.ymax);
6230  if (Hparam.xlast > last) Hparam.xlast = last;
6231  }
6232 
6233  // Compute Y axis parameters
6234  Double_t bigp = TMath::Power(10,32);
6235  Double_t xmax = -bigp;
6236  Double_t xmin = bigp;
6237  Double_t c1, e1;
6238  Double_t xv[1];
6239  Double_t fval;
6240  Int_t i;
6241  TObject *f;
6242  TF1 *f1;
6243  Double_t allchan = 0;
6245  for (i=first; i<=last;i++) {
6246  c1 = fH->GetBinContent(i);
6247  xmax = TMath::Max(xmax,c1);
6248  xmin = TMath::Min(xmin,c1);
6249  if (Hoption.Error) {
6250  e1 = fH->GetBinError(i);
6251  xmax = TMath::Max(xmax,c1+e1);
6252  xmin = TMath::Min(xmin,c1-e1);
6253  }
6254  if (Hoption.Func) {
6255  xv[0] = fXaxis->GetBinCenter(i);
6256  while ((f = (TObject*) next())) {
6257  if (f->IsA() == TF1::Class()) {
6258  f1 = (TF1*)f;
6259  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6260  fval = f1->Eval(xv[0],0,0);
6261  xmax = TMath::Max(xmax,fval);
6262  if (Hoption.Logy) {
6263  if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
6264  }
6265  }
6266  }
6267  next.Reset();
6268  }
6269  allchan += c1;
6270  }
6271 
6272  // Take into account maximum , minimum
6273 
6274  if (Hoption.Logx && xmin <= 0) {
6275  if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
6276  else xmin = 0.001*xmax;
6277  }
6278  Double_t xm = xmin;
6279  if (maximum) xmax = fH->GetMaximumStored();
6280  if (minimum) xm = fH->GetMinimumStored();
6281  if (Hoption.Logx && xm <= 0) {
6282  Error(where, "log scale requested with zero or negative argument (%f)", xm);
6283  return 0;
6284  }
6285  else xmin = xm;
6286  if (xmin >= xmax) {
6287  if (Hoption.Logx) {
6288  if (xmax > 0) xmin = 0.001*xmax;
6289  else {
6290  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
6291  return 0;
6292  }
6293  }
6294  else {
6295  if (xmin > 0) {
6296  xmin = 0;
6297  xmax *= 2;
6298  } else if (xmin < 0) {
6299  xmax = 0;
6300  xmin *= 2;
6301  } else {
6302  xmin = -1;
6303  xmax = 1;
6304  }
6305  }
6306  }
6307 
6308  // take into account normalization factor
6309  Hparam.allchan = allchan;
6310  Double_t factor = allchan;
6311  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6312  if (allchan) factor /= allchan;
6313  if (factor == 0) factor = 1;
6314  Hparam.factor = factor;
6315  xmax = factor*xmax;
6316  xmin = factor*xmin;
6317 
6318  // For log scales, histogram coordinates are LOG10(ymin) and
6319  // LOG10(ymax). Final adjustment (if not option "Same"
6320  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6321  // Maximum and Minimum are not defined.
6322  if (Hoption.Logx) {
6323  if (xmin <=0 || xmax <=0) {
6324  Error(where, "Cannot set Y axis to log scale");
6325  return 0;
6326  }
6327  xmin = TMath::Log10(xmin);
6328  if (!minimum) xmin += TMath::Log10(0.5);
6329  xmax = TMath::Log10(xmax);
6330  if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
6331  if (!Hoption.Same) {
6332  Hparam.xmin = xmin;
6333  Hparam.xmax = xmax;
6334  }
6335  return 1;
6336  }
6337 
6338  // final adjustment of ymin for linear scale.
6339  // if minimum is not set , then ymin is set to zero if >0
6340  // or to ymin - margin if <0.
6341  if (!minimum) {
6342  if (xmin >= 0) xmin = 0;
6343  else xmin -= yMARGIN*(xmax-xmin);
6344  }
6345 
6346  // final adjustment of YMAXI for linear scale (if not option "Same"):
6347  // decrease histogram height to MAX% of allowed height if HMAXIM
6348  // has not been called.
6349  if (!maximum) {
6350  xmax += yMARGIN*(xmax-xmin);
6351  }
6352  Hparam.xmin = xmin;
6353  Hparam.xmax = xmax;
6354  return 1;
6355 }
6356 
6357 
6358 ////////////////////////////////////////////////////////////////////////////////
6359 /// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
6360 
6362 {
6363 
6364  const Double_t ydiff = 1;
6365  const Double_t yligh1 = 10;
6366  const Double_t qa = 0.15;
6367  const Double_t qd = 0.15;
6368  const Double_t qs = 0.8;
6369  Double_t fmin, fmax;
6370  Int_t i, irep;
6371  Int_t nbcol = 28;
6372  Int_t icol1 = 201;
6373  Int_t ic1 = icol1;
6374  Int_t ic2 = ic1+nbcol;
6375  Int_t ic3 = ic2+nbcol;
6376 
6377  TGaxis *axis = new TGaxis();
6378  TAxis *xaxis = fH->GetXaxis();
6379  TAxis *yaxis = fH->GetYaxis();
6380  TAxis *zaxis = fH->GetZaxis();
6381 
6382  Int_t nx = fH->GetNbinsX();
6383  Int_t ny = fH->GetNbinsY();
6384  Int_t nz = fH->GetNbinsZ();
6385 
6386  Double_t *x = new Double_t[nx];
6387  Double_t *y = new Double_t[ny];
6388  Double_t *z = new Double_t[nz];
6389 
6390  for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
6391  for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
6392  for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
6393 
6394  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
6395  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
6396  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
6397  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
6398  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
6399  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
6400 
6401  Double_t s[3];
6402  s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
6403  s[1] = 0.5*s[0];
6404  s[2] = 1.5*s[0];
6405 
6407 
6408  TView *view = gPad->GetView();
6409  if (!view) {
6410  Error("PaintH3Iso", "no TView in current pad");
6411  delete [] x;
6412  delete [] y;
6413  delete [] z;
6414  return;
6415  }
6416  Double_t thedeg = 90 - gPad->GetTheta();
6417  Double_t phideg = -90 - gPad->GetPhi();
6418  Double_t psideg = view->GetPsi();
6419  view->SetView(phideg, thedeg, psideg, irep);
6420 
6421  Int_t backcolor = gPad->GetFrameFillColor();
6422  if (Hoption.System != kCARTESIAN) backcolor = 0;
6423  view->PadRange(backcolor);
6424 
6425  Double_t dcol = 0.5/Double_t(nbcol);
6426  TColor *colref = gROOT->GetColor(fH->GetFillColor());
6427  if (!colref) {
6428  delete [] x;
6429  delete [] y;
6430  delete [] z;
6431  return;
6432  }
6433  Float_t r, g, b, hue, light, satur;
6434  colref->GetRGB(r,g,b);
6435  TColor::RGBtoHLS(r,g,b,hue,light,satur);
6436  TColor *acol;
6437  for (Int_t col=0;col<nbcol;col++) {
6438  acol = gROOT->GetColor(col+icol1);
6439  TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
6440  if (acol) acol->SetRGB(r, g, b);
6441  }
6442 
6443  fLego->InitMoveScreen(-1.1,1.1);
6444 
6445  if (Hoption.BackBox) {
6448  fLego->BackBox(90);
6449  }
6450 
6451  fLego->LightSource(0, ydiff, 0, 0, 0, irep);
6452  fLego->LightSource(1, yligh1, 1, 1, 1, irep);
6453  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
6454  fmin = ydiff*qa;
6455  fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
6456  fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
6457 
6458  fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
6459 
6460  if (Hoption.FrontBox) {
6461  fLego->InitMoveScreen(-1.1,1.1);
6463  fLego->FrontBox(90);
6464  }
6465  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6466 
6467  PaintTitle();
6468 
6469  delete axis;
6470  delete fLego; fLego = 0;
6471  delete [] x;
6472  delete [] y;
6473  delete [] z;
6474 }
6475 
6476 
6477 ////////////////////////////////////////////////////////////////////////////////
6478 /// [Control function to draw a 2D histogram as a lego plot.](#HP17)
6479 
6481 {
6482 
6483  Int_t raster = 1;
6484  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
6485  Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
6486  Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
6487  Double_t zmin = Hparam.zmin;
6488  Double_t zmax = Hparam.zmax;
6489  Double_t xlab1 = Hparam.xmin;
6490  Double_t xlab2 = Hparam.xmax;
6491  Double_t ylab1 = Hparam.ymin;
6492  Double_t ylab2 = Hparam.ymax;
6493  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
6494  Double_t deltaz = TMath::Abs(zmin);
6495  if (deltaz == 0) deltaz = 1;
6496  if (zmin >= zmax) {
6497  zmin -= 0.5*deltaz;
6498  zmax += 0.5*deltaz;
6499  }
6500  Double_t z1c = zmin;
6501  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
6502 
6503  // Compute the lego limits and instantiate a lego object
6504  fXbuf[0] = -1;
6505  fYbuf[0] = 1;
6506  fXbuf[1] = -1;
6507  fYbuf[1] = 1;
6508  if (Hoption.System == kPOLAR) {
6509  fXbuf[2] = z1c;
6510  fYbuf[2] = z2c;
6511  } else if (Hoption.System == kCYLINDRICAL) {
6512  if (Hoption.Logy) {
6513  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
6514  else fXbuf[2] = 0;
6515  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
6516  else fYbuf[2] = 0;
6517  } else {
6518  fXbuf[2] = ylab1;
6519  fYbuf[2] = ylab2;
6520  }
6521  z1c = 0; z2c = 1;
6522  } else if (Hoption.System == kSPHERICAL) {
6523  fXbuf[2] = -1;
6524  fYbuf[2] = 1;
6525  z1c = 0; z2c = 1;
6526  } else if (Hoption.System == kRAPIDITY) {
6527  fXbuf[2] = -1/TMath::Tan(dangle);
6528  fYbuf[2] = 1/TMath::Tan(dangle);
6529  } else {
6530  fXbuf[0] = xlab1;
6531  fYbuf[0] = xlab2;
6532  fXbuf[1] = ylab1;
6533  fYbuf[1] = ylab2;
6534  fXbuf[2] = z1c;
6535  fYbuf[2] = z2c;
6536  raster = 0;
6537  }
6538 
6539  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
6540 
6541  Int_t nids = -1;
6542  TH1 * hid = NULL;
6543  Color_t colormain = -1, colordark = -1;
6544  Bool_t drawShadowsInLego1 = kTRUE;
6545 
6546  // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
6547  if (Hoption.Lego == 13) {
6548  Hoption.Lego = 11;
6549  fLego->SetMesh(0);
6550  }
6551  // LEGO4 is like LEGO1 except no shadows are drawn.
6552  if (Hoption.Lego == 14) {
6553  Hoption.Lego = 11;
6554  drawShadowsInLego1 = kFALSE;
6555  }
6556 
6557  // Create axis object
6558 
6559  TGaxis *axis = new TGaxis();
6560 
6561  // Initialize the levels on the Z axis
6562  Int_t ndiv = fH->GetContour();
6563  if (ndiv == 0 ) {
6564  ndiv = gStyle->GetNumberContours();
6565  fH->SetContour(ndiv);
6566  }
6567  Int_t ndivz = TMath::Abs(ndiv);
6568  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
6569 
6570  // Initialize colors
6571  if (!fStack) {
6573  } else {
6574  for (Int_t id=0;id<=fStack->GetSize();id++) {
6575  hid = (TH1*)fStack->At((id==0)?id:id-1);
6576  fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
6577  }
6578  }
6579 
6580  if (Hoption.Lego == 11) {
6581  nids = 1;
6582  if (fStack) nids = fStack->GetSize();
6583  hid = fH;
6584  for (Int_t id=0;id<=nids;id++) {
6585  if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
6586  colormain = hid->GetFillColor();
6587  if (colormain == 1) colormain = 17; //avoid drawing with black
6588  if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
6589  else colordark = colormain;
6590  fLego->SetColorMain(colormain,id);
6591  fLego->SetColorDark(colordark,id);
6592  if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
6593  if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
6594  }
6595  }
6596 
6597  // Now ready to draw the lego plot
6598  Int_t irep = 0;
6599 
6600  TView *view = gPad->GetView();
6601  if (!view) {
6602  Error("PaintLego", "no TView in current pad");
6603  return;
6604  }
6605 
6606  Double_t thedeg = 90 - gPad->GetTheta();
6607  Double_t phideg = -90 - gPad->GetPhi();
6608  Double_t psideg = view->GetPsi();
6609  view->SetView(phideg, thedeg, psideg, irep);
6610 
6611  fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
6613 
6614  // Set color/style for back box
6615  fLego->SetFillStyle(gPad->GetFrameFillStyle());
6616  fLego->SetFillColor(gPad->GetFrameFillColor());
6617  fLego->TAttFill::Modify();
6618 
6619  Int_t backcolor = gPad->GetFrameFillColor();
6620  if (Hoption.System != kCARTESIAN) backcolor = 0;
6621  view->PadRange(backcolor);
6622 
6625  fLego->TAttFill::Modify();
6626 
6628 
6629  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
6630  else fLego->InitMoveScreen(-1.1,1.1);
6631 
6632  if (Hoption.Lego == 11 || Hoption.Lego == 12) {
6633  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
6635  fLego->BackBox(90);
6636  }
6637  }
6638 
6639  if (Hoption.Lego == 12) DefineColorLevels(ndivz);
6640 
6645  if (Hoption.System == kPOLAR) {
6646  if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
6647  if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
6648  if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
6649  } else if (Hoption.System == kCYLINDRICAL) {
6650  if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
6651  if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
6652  if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
6653  } else if (Hoption.System == kSPHERICAL) {
6654  if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
6655  if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
6656  if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
6657  } else if (Hoption.System == kRAPIDITY) {
6658  if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
6659  if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
6660  if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
6661  } else {
6662  if (Hoption.Lego == 1) {
6664  fLego->LegoCartesian(90,nx,ny,"FB");}
6665  if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
6666  if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
6667  }
6668 
6669  if (Hoption.Lego == 1 || Hoption.Lego == 11) {
6670  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
6672  fLego->BackBox(90);
6673  }
6674  }
6675  if (Hoption.System == kCARTESIAN) {
6676  fLego->InitMoveScreen(-1.1,1.1);
6678  if (Hoption.FrontBox) fLego->FrontBox(90);
6679  }
6680  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6681  if (Hoption.Zscale) PaintPalette();
6682  delete axis;
6683  delete fLego; fLego = 0;
6684 }
6685 
6686 
6687 ////////////////////////////////////////////////////////////////////////////////
6688 /// Draw the axis for legos and surface plots.
6689 
6691 {
6692 
6693  static Double_t epsil = 0.001;
6694 
6695  Double_t cosa, sina;
6696  Double_t bmin, bmax;
6697  Double_t r[24] /* was [3][8] */;
6698  Int_t ndivx, ndivy, ndivz, i;
6699  Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
6700  static char chopax[8], chopay[8], chopaz[8];
6701  Int_t ix1, ix2, iy1, iy2, iz1, iz2;
6702  Double_t rad;
6703 
6704  TView *view = gPad->GetView();
6705  if (!view) {
6706  Error("PaintLegoAxis", "no TView in current pad");
6707  return;
6708  }
6709 
6710  // In polar coordinates, draw a short line going from the external circle
6711  // corresponding to r = 1 up to r = 1.1
6712  if (Hoption.System == kPOLAR) {
6713  r[0] = 1;
6714  r[1] = 0;
6715  r[2] = 0;
6716  view->WCtoNDC(r, x1);
6717  r[0] = 1.1;
6718  r[1] = 0;
6719  r[2] = 0;
6720  view->WCtoNDC(r, x2);
6721  gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
6722  return;
6723  }
6724 
6725  if (Hoption.System != kCARTESIAN) return;
6726 
6727  rad = TMath::ATan(1.) * 4. /180.;
6728  cosa = TMath::Cos(ang*rad);
6729  sina = TMath::Sin(ang*rad);
6730 
6731  view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
6732  for (i = 1; i <= 8; ++i) {
6733  r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
6734  r[i*3 - 2] = av[i*3 - 2]*sina;
6735  r[i*3 - 1] = av[i*3 - 1];
6736  }
6737 
6738  view->WCtoNDC(&r[ix1*3 - 3], x1);
6739  view->WCtoNDC(&r[ix2*3 - 3], x2);
6740  view->WCtoNDC(&r[iy1*3 - 3], y1);
6741  view->WCtoNDC(&r[iy2*3 - 3], y2);
6742  view->WCtoNDC(&r[iz1*3 - 3], z1);
6743  view->WCtoNDC(&r[iz2*3 - 3], z2);
6744 
6745  view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
6746 
6747  Double_t *rmin = view->GetRmin();
6748  Double_t *rmax = view->GetRmax();
6749  if (!rmin || !rmax) return;
6750 
6751  // Initialize the axis options
6752  if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
6753  else strlcpy(chopax, "SDH=-",8);
6754  if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
6755  else strlcpy(chopay, "SDH=-",8);
6756  strlcpy(chopaz, "SDH+=",8);
6757 
6758  // Option LOG is required ?
6759  if (Hoption.Logx) strlcat(chopax,"G",8);
6760  if (Hoption.Logy) strlcat(chopay,"G",8);
6761  if (Hoption.Logz) strlcat(chopaz,"G",8);
6762 
6763  // Initialize the number of divisions. If the
6764  // number of divisions is negative, option 'N' is required.
6765  ndivx = fXaxis->GetNdivisions();
6766  ndivy = fYaxis->GetNdivisions();
6767  ndivz = fZaxis->GetNdivisions();
6768  if (ndivx < 0) {
6769  ndivx = TMath::Abs(ndivx);
6770  strlcat(chopax, "N",8);
6771  }
6772  if (ndivy < 0) {
6773  ndivy = TMath::Abs(ndivy);
6774  strlcat(chopay, "N",8);
6775  }
6776  if (ndivz < 0) {
6777  ndivz = TMath::Abs(ndivz);
6778  strlcat(chopaz, "N",8);
6779  }
6780 
6781  // Set Axis attributes.
6782  // The variable SCALE rescales the VSIZ
6783  // in order to have the same label size for all angles.
6784 
6785  axis->SetLineWidth(1);
6786 
6787  // X axis drawing
6788  if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
6791  if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
6792  bmin = TMath::Power(10, rmin[0]);
6793  bmax = TMath::Power(10, rmax[0]);
6794  } else {
6795  bmin = rmin[0];
6796  bmax = rmax[0];
6797  }
6798  // Option time display is required ?
6799  if (fXaxis->GetTimeDisplay()) {
6800  strlcat(chopax,"t",8);
6801  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
6802  axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
6803  } else {
6805  }
6806  }
6807  axis->SetOption(chopax);
6808  axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
6809  }
6810 
6811  // Y axis drawing
6812  if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
6815 
6816  if (fH->GetDimension() < 2) {
6817  strlcpy(chopay, "V=+UN",8);
6818  ndivy = 0;
6819  }
6820  if (TMath::Abs(y1[0] - y2[0]) < epsil) {
6821  y2[0] = y1[0];
6822  }
6823  if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
6824  bmin = TMath::Power(10, rmin[1]);
6825  bmax = TMath::Power(10, rmax[1]);
6826  } else {
6827  bmin = rmin[1];
6828  bmax = rmax[1];
6829  }
6830  // Option time display is required ?
6831  if (fYaxis->GetTimeDisplay()) {
6832  strlcat(chopay,"t",8);
6833  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
6834  axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
6835  } else {
6837  }
6838  }
6839  axis->SetOption(chopay);
6840  axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
6841  }
6842 
6843  // Z axis drawing
6844  if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
6846  if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
6847  bmin = TMath::Power(10, rmin[2]);
6848  bmax = TMath::Power(10, rmax[2]);
6849  } else {
6850  bmin = rmin[2];
6851  bmax = rmax[2];
6852  }
6853  // Option time display is required ?
6854  if (fZaxis->GetTimeDisplay()) {
6855  strlcat(chopaz,"t",8);
6856  if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
6857  axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
6858  } else {
6860  }
6861  }
6862  axis->SetOption(chopaz);
6863  axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
6864  }
6865 
6866  //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
6867 }
6868 
6869 
6870 ////////////////////////////////////////////////////////////////////////////////
6871 /// [Paint the color palette on the right side of the pad.](#HP22)
6872 
6874 {
6875 
6876  TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
6877  TView *view = gPad->GetView();
6878  if (palette) {
6879  if (view) {
6880  if (!palette->TestBit(TPaletteAxis::kHasView)) {
6881  fFunctions->Remove(palette);
6882  delete palette; palette = 0;
6883  }
6884  } else {
6885  if (palette->TestBit(TPaletteAxis::kHasView)) {
6886  fFunctions->Remove(palette);
6887  delete palette; palette = 0;
6888  }
6889  }
6890  }
6891 
6892  if (!palette) {
6893  Double_t xup = gPad->GetUxmax();
6894  Double_t x2 = gPad->PadtoX(gPad->GetX2());
6895  Double_t ymin = gPad->PadtoY(gPad->GetUymin());
6896  Double_t ymax = gPad->PadtoY(gPad->GetUymax());
6897  Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
6898  Double_t xmin = gPad->PadtoX(xup +0.1*xr);
6899  Double_t xmax = gPad->PadtoX(xup + xr);
6900  if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
6901  palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
6902  fFunctions->AddFirst(palette);
6903  palette->Paint();
6904  }
6905 }
6906 
6907 
6908 ////////////////////////////////////////////////////////////////////////////////
6909 /// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
6910 
6912 {
6913 
6914  fH->TAttMarker::Modify();
6915 
6916  Int_t k, marker;
6917  Double_t dz, z, xk,xstep, yk, ystep;
6918  Double_t scale = 1;
6919  Bool_t ltest = kFALSE;
6920  Double_t zmax = fH->GetMaximum();
6921  Double_t zmin = fH->GetMinimum();
6922  if (zmin == 0 && zmax == 0) return;
6923  if (zmin == zmax) {
6924  zmax += 0.1*TMath::Abs(zmax);
6925  zmin -= 0.1*TMath::Abs(zmin);
6926  }
6927  Int_t ncells = (Hparam.ylast-Hparam.yfirst)*(Hparam.xlast-Hparam.xfirst);
6928  if (Hoption.Logz) {
6929  if (zmin > 0) zmin = TMath::Log10(zmin);
6930  else zmin = 0;
6931  if (zmax > 0) zmax = TMath::Log10(zmax);
6932  else zmax = 0;
6933  if (zmin == 0 && zmax == 0) return;
6934  dz = zmax - zmin;
6935  scale = 100/dz;
6936  if (ncells > 10000) scale /= 5;
6937  ltest = kTRUE;
6938  } else {
6939  dz = zmax - zmin;
6940  if (dz >= kNMAX || zmax < 1) {
6941  scale = (kNMAX-1)/dz;
6942  if (ncells > 10000) scale /= 5;
6943  ltest = kTRUE;
6944  }
6945  }
6946  if (fH->GetMinimumStored() == -1111) {
6947  Double_t yMARGIN = gStyle->GetHistTopMargin();
6948  if (gStyle->GetHistMinimumZero()) {
6949  if (zmin >= 0) zmin = 0;
6950  else zmin -= yMARGIN*(zmax-zmin);
6951  } else {
6952  Double_t dzmin = yMARGIN*(zmax-zmin);
6953  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
6954  else zmin -= dzmin;
6955  }
6956  }
6957 
6958  TString opt = option;
6959  opt.ToLower();
6960  if (opt.Contains("scat=")) {
6961  char optscat[100];
6962  strlcpy(optscat,opt.Data(),100);
6963  char *oscat = strstr(optscat,"scat=");
6964  char *blank = strstr(oscat," "); if (blank) *blank = 0;
6965  sscanf(oscat+5,"%lg",&scale);
6966  }
6967  // use an independent instance of a random generator
6968  // instead of gRandom to avoid conflicts and
6969  // to get same random numbers when drawing the same histogram
6970  TRandom2 random;
6971  marker=0;
6972  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6973  yk = fYaxis->GetBinLowEdge(j);
6974  ystep = fYaxis->GetBinWidth(j);
6975  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6976  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
6977  xk = fXaxis->GetBinLowEdge(i);
6978  xstep = fXaxis->GetBinWidth(i);
6979  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6980  z = fH->GetBinContent(bin);
6981  if (z < zmin) z = zmin;
6982  if (z > zmax) z = zmax;
6983  if (Hoption.Logz) {
6984  if (z > 0) z = TMath::Log10(z) - zmin;
6985  } else {
6986  z -= zmin;
6987  }
6988  if (z <= 0) continue;
6989  k = Int_t(z*scale);
6990  if (ltest) k++;
6991  if (k > 0) {
6992  for (Int_t loop=0; loop<k; loop++) {
6993  if (k+marker >= kNMAX) {
6994  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
6995  marker=0;
6996  }
6997  fXbuf[marker] = (random.Rndm(loop)*xstep) + xk;
6998  fYbuf[marker] = (random.Rndm(loop)*ystep) + yk;
6999  if (Hoption.Logx) {
7000  if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
7001  else break;
7002  }
7003  if (Hoption.Logy) {
7004  if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
7005  else break;
7006  }
7007  if (fXbuf[marker] < gPad->GetUxmin()) break;
7008  if (fYbuf[marker] < gPad->GetUymin()) break;
7009  if (fXbuf[marker] > gPad->GetUxmax()) break;
7010  if (fYbuf[marker] > gPad->GetUymax()) break;
7011  marker++;
7012  }
7013  }
7014  }
7015  }
7016  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7017 
7018  if (Hoption.Zscale) PaintPalette();
7019 }
7020 
7021 
7022 ////////////////////////////////////////////////////////////////////////////////
7023 /// Static function to paint special objects like vectors and matrices.
7024 /// This function is called via `gROOT->ProcessLine` to paint these objects
7025 /// without having a direct dependency of the graphics or histogramming
7026 /// system.
7027 
7028 void THistPainter::PaintSpecialObjects(const TObject *obj, Option_t *option)
7029 {
7030 
7031  if (!obj) return;
7035  if (obj->InheritsFrom(TMatrixFBase::Class())) {
7036  // case TMatrixF
7037  TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
7038  R__TMatrixFBase->SetBit(kCanDelete);
7039  R__TMatrixFBase->Draw(option);
7040 
7041  } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
7042  // case TMatrixD
7043  TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
7044  R__TMatrixDBase->SetBit(kCanDelete);
7045  R__TMatrixDBase->Draw(option);
7046 
7047  } else if (obj->InheritsFrom(TVectorF::Class())) {
7048  //case TVectorF
7049  TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
7050  R__TVectorF->SetBit(kCanDelete);
7051  R__TVectorF->Draw(option);
7052 
7053  } else if (obj->InheritsFrom(TVectorD::Class())) {
7054  //case TVectorD
7055  TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
7056  R__TVectorD->SetBit(kCanDelete);
7057  R__TVectorD->Draw(option);
7058  }
7059 
7060  TH1::AddDirectory(status);
7061 }
7062 
7063 
7064 ////////////////////////////////////////////////////////////////////////////////
7065 /// [Draw the statistics box for 1D and profile histograms.](#HP07)
7066 
7067 void THistPainter::PaintStat(Int_t dostat, TF1 *fit)
7068 {
7069 
7070  static char t[100];
7071  Int_t dofit;
7072  TPaveStats *stats = 0;
7074  TObject *obj;
7075  while ((obj = next())) {
7076  if (obj->InheritsFrom(TPaveStats::Class())) {
7077  stats = (TPaveStats*)obj;
7078  break;
7079  }
7080  }
7081 
7082  if (stats && dostat) {
7083  dofit = stats->GetOptFit();
7084  dostat = stats->GetOptStat();
7085  } else {
7086  dofit = gStyle->GetOptFit();
7087  }
7088  if (!dofit) fit = 0;
7089  if (dofit == 1) dofit = 111;
7090  if (dostat == 1) dostat = 1111;
7091  Int_t print_name = dostat%10;
7092  Int_t print_entries = (dostat/10)%10;
7093  Int_t print_mean = (dostat/100)%10;
7094  Int_t print_stddev = (dostat/1000)%10;
7095  Int_t print_under = (dostat/10000)%10;
7096  Int_t print_over = (dostat/100000)%10;
7097  Int_t print_integral= (dostat/1000000)%10;
7098  Int_t print_skew = (dostat/10000000)%10;
7099  Int_t print_kurt = (dostat/100000000)%10;
7100  Int_t nlines = print_name + print_entries + print_mean + print_stddev +
7101  print_under + print_over + print_integral +
7102  print_skew + print_kurt;
7103  Int_t print_fval = dofit%10;
7104  Int_t print_ferrors = (dofit/10)%10;
7105  Int_t print_fchi2 = (dofit/100)%10;
7106  Int_t print_fprob = (dofit/1000)%10;
7107  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
7108  if (fit) {
7109  if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
7110  else nlinesf += fit->GetNpar();
7111  }
7112  if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
7113 
7114  // Pavetext with statistics
7115  Bool_t done = kFALSE;
7116  if (!dostat && !fit) {
7117  if (stats) { fFunctions->Remove(stats); delete stats;}
7118  return;
7119  }
7120  Double_t statw = gStyle->GetStatW();
7121  if (fit) statw = 1.8*gStyle->GetStatW();
7122  Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
7123  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7124  stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
7125  }
7126  if (stats) {
7127  stats->Clear();
7128  done = kTRUE;
7129  } else {
7130  stats = new TPaveStats(
7131  gStyle->GetStatX()-statw,
7132  gStyle->GetStatY()-stath,
7133  gStyle->GetStatX(),
7134  gStyle->GetStatY(),"brNDC");
7135 
7136  stats->SetParent(fH);
7137  stats->SetOptFit(dofit);
7138  stats->SetOptStat(dostat);
7139  stats->SetFillColor(gStyle->GetStatColor());
7140  stats->SetFillStyle(gStyle->GetStatStyle());
7142  stats->SetTextFont(gStyle->GetStatFont());
7143  if (gStyle->GetStatFont()%10 > 2)
7144  stats->SetTextSize(gStyle->GetStatFontSize());
7145  stats->SetFitFormat(gStyle->GetFitFormat());
7146  stats->SetStatFormat(gStyle->GetStatFormat());
7147  stats->SetName("stats");
7148 
7150  stats->SetTextAlign(12);
7151  stats->SetBit(kCanDelete);
7152  stats->SetBit(kMustCleanup);
7153  }
7154  if (print_name) stats->AddText(fH->GetName());
7155  if (print_entries) {
7156  if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
7157  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
7158  stats->AddText(t);
7159  }
7160  char textstats[50];
7161  if (print_mean) {
7162  if (print_mean == 1) {
7163  snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
7164  snprintf(t,100,textstats,fH->GetMean(1));
7165  } else {
7166  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
7167  ,"%",stats->GetStatFormat());
7168  snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
7169  }
7170  stats->AddText(t);
7171  if (fH->InheritsFrom(TProfile::Class())) {
7172  if (print_mean == 1) {
7173  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7174  snprintf(t,100,textstats,fH->GetMean(2));
7175  } else {
7176  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7177  ,"%",stats->GetStatFormat());
7178  snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
7179  }
7180  stats->AddText(t);
7181  }
7182  }
7183  if (print_stddev) {
7184  if (print_stddev == 1) {
7185  snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
7186  snprintf(t,100,textstats,fH->GetStdDev(1));
7187  } else {
7188  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
7189  ,"%",stats->GetStatFormat());
7190  snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
7191  }
7192  stats->AddText(t);
7193  if (fH->InheritsFrom(TProfile::Class())) {
7194  if (print_stddev == 1) {
7195  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7196  snprintf(t,100,textstats,fH->GetStdDev(2));
7197  } else {
7198  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7199  ,"%",stats->GetStatFormat());
7200  snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
7201  }
7202  stats->AddText(t);
7203  }
7204  }
7205  if (print_under) {
7206  snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
7207  snprintf(t,100,textstats,fH->GetBinContent(0));
7208  stats->AddText(t);
7209  }
7210  if (print_over) {
7211  snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
7212  snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
7213  stats->AddText(t);
7214  }
7215  if (print_integral) {
7216  if (print_integral == 1) {
7217  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7218  snprintf(t,100,textstats,fH->Integral());
7219  } else {
7220  snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
7221  snprintf(t,100,textstats,fH->Integral("width"));
7222  }
7223  stats->AddText(t);
7224  }
7225  if (print_skew) {
7226  if (print_skew == 1) {
7227  snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
7228  snprintf(t,100,textstats,fH->GetSkewness(1));
7229  } else {
7230  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
7231  ,"%",stats->GetStatFormat());
7232  snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
7233  }
7234  stats->AddText(t);
7235  }
7236  if (print_kurt) {
7237  if (print_kurt == 1) {
7238  snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
7239  snprintf(t,100,textstats,fH->GetKurtosis(1));
7240  } else {
7241  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
7242  ,"%",stats->GetStatFormat());
7243  snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
7244  }
7245  stats->AddText(t);
7246  }
7247 
7248  // Draw Fit parameters
7249  if (fit) {
7250  Int_t ndf = fit->GetNDF();
7251  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
7252  snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
7253  if (print_fchi2) stats->AddText(t);
7254  if (print_fprob) {
7255  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
7256  snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
7257  stats->AddText(t);
7258  }
7259  if (print_fval || print_ferrors) {
7260  Double_t parmin,parmax;
7261  Int_t a;
7262  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7263  fit->GetParLimits(ipar,parmin,parmax);
7264  if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
7265  snprintf(t,100,"%-8s ",fit->GetParName(ipar));
7266  a = strlen(t);
7267  if (a>50) a = 50;
7268  if (print_ferrors) {
7269  snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
7270  GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
7271  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar)
7272  ,(Float_t)fit->GetParError(ipar));
7273  } else {
7274  snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
7275  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar));
7276  }
7277  t[63] = 0;
7278  stats->AddText(t);
7279  }
7280  }
7281  }
7282 
7283  if (!done) fFunctions->Add(stats);
7284  stats->Paint();
7285 }
7286 
7287 
7288 ////////////////////////////////////////////////////////////////////////////////
7289 /// [Draw the statistics box for 2D histograms.](#HP07)
7290 
7291 void THistPainter::PaintStat2(Int_t dostat, TF1 *fit)
7292 {
7293 
7294  if (fH->GetDimension() != 2) return;
7295  TH2 *h2 = (TH2*)fH;
7296 
7297  static char t[100];
7298  Int_t dofit;
7299  TPaveStats *stats = 0;
7301  TObject *obj;
7302  while ((obj = next())) {
7303  if (obj->InheritsFrom(TPaveStats::Class())) {
7304  stats = (TPaveStats*)obj;
7305  break;
7306  }
7307  }
7308  if (stats && dostat) {
7309  dofit = stats->GetOptFit();
7310  dostat = stats->GetOptStat();
7311  } else {
7312  dofit = gStyle->GetOptFit();
7313  }
7314  if (dostat == 1) dostat = 1111;
7315  Int_t print_name = dostat%10;
7316  Int_t print_entries = (dostat/10)%10;
7317  Int_t print_mean = (dostat/100)%10;
7318  Int_t print_stddev = (dostat/1000)%10;
7319  Int_t print_under = (dostat/10000)%10;
7320  Int_t print_over = (dostat/100000)%10;
7321  Int_t print_integral= (dostat/1000000)%10;
7322  Int_t print_skew = (dostat/10000000)%10;
7323  Int_t print_kurt = (dostat/100000000)%10;
7324  Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
7325  if (print_under || print_over) nlines += 3;
7326 
7327  // Pavetext with statistics
7328  if (!gStyle->GetOptFit()) fit = 0;
7329  Bool_t done = kFALSE;
7330  if (!dostat && !fit) {
7331  if (stats) { fFunctions->Remove(stats); delete stats;}
7332  return;
7333  }
7334  Double_t statw = gStyle->GetStatW();
7335  if (fit) statw = 1.8*gStyle->GetStatW();
7336  Double_t stath = nlines*gStyle->GetStatFontSize();
7337  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7338  stath = 0.25*nlines*gStyle->GetStatH();
7339  }
7340  if (fit) stath += gStyle->GetStatH();
7341  if (stats) {
7342  stats->Clear();
7343  done = kTRUE;
7344  } else {
7345  stats = new TPaveStats(
7346  gStyle->GetStatX()-statw,
7347  gStyle->GetStatY()-stath,
7348  gStyle->GetStatX(),
7349  gStyle->GetStatY(),"brNDC");
7350 
7351  stats->SetParent(fH);
7352  stats->SetOptFit(dofit);
7353  stats->SetOptStat(dostat);
7354  stats->SetFillColor(gStyle->GetStatColor());
7355  stats->SetFillStyle(gStyle->GetStatStyle());
7357  stats->SetName("stats");
7358 
7360  stats->SetTextAlign(12);
7361  stats->SetTextFont(gStyle->GetStatFont());
7362  if (gStyle->GetStatFont()%10 > 2)
7363  stats->SetTextSize(gStyle->GetStatFontSize());
7364  stats->SetFitFormat(gStyle->GetFitFormat());
7365  stats->SetStatFormat(gStyle->GetStatFormat());
7366  stats->SetBit(kCanDelete);
7367  stats->SetBit(kMustCleanup);
7368  }
7369  if (print_name) stats->AddText(h2->GetName());
7370  if (print_entries) {
7371  if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
7372  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
7373  stats->AddText(t);
7374  }
7375  char textstats[50];
7376  if (print_mean) {
7377  if (print_mean == 1) {
7378  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
7379  snprintf(t,50,textstats,h2->GetMean(1));
7380  stats->AddText(t);
7381  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7382  snprintf(t,100,textstats,h2->GetMean(2));
7383  stats->AddText(t);
7384  } else {
7385  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
7386  ,"%",stats->GetStatFormat());
7387  snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
7388  stats->AddText(t);
7389  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7390  ,"%",stats->GetStatFormat());
7391  snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
7392  stats->AddText(t);
7393  }
7394  }
7395  if (print_stddev) {
7396  if (print_stddev == 1) {
7397  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
7398  snprintf(t,100,textstats,h2->GetStdDev(1));
7399  stats->AddText(t);
7400  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7401  snprintf(t,100,textstats,h2->GetStdDev(2));
7402  stats->AddText(t);
7403  } else {
7404  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
7405  ,"%",stats->GetStatFormat());
7406  snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
7407  stats->AddText(t);
7408  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7409  ,"%",stats->GetStatFormat());
7410  snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
7411  stats->AddText(t);
7412  }
7413  }
7414  if (print_integral) {
7415  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7416  snprintf(t,100,textstats,fH->Integral());
7417  stats->AddText(t);
7418  }
7419  if (print_skew) {
7420  if (print_skew == 1) {
7421  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
7422  snprintf(t,100,textstats,h2->GetSkewness(1));
7423  stats->AddText(t);
7424  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
7425  snprintf(t,100,textstats,h2->GetSkewness(2));
7426  stats->AddText(t);
7427  } else {
7428  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
7429  ,"%",stats->GetStatFormat());
7430  snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
7431  stats->AddText(t);
7432  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
7433  ,"%",stats->GetStatFormat());
7434  snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
7435  stats->AddText(t);
7436  }
7437  }
7438  if (print_kurt) {
7439  if (print_kurt == 1) {
7440  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
7441  snprintf(t,100,textstats,h2->GetKurtosis(1));
7442  stats->AddText(t);
7443  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
7444  snprintf(t,100,textstats,h2->GetKurtosis(2));
7445  stats->AddText(t);
7446  } else {
7447  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
7448  ,"%",stats->GetStatFormat());
7449  snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
7450  stats->AddText(t);
7451  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
7452  ,"%",stats->GetStatFormat());
7453  snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
7454  stats->AddText(t);
7455  }
7456  }
7457  if (print_under || print_over) {
7458  //get 3*3 under/overflows for 2d hist
7459  Double_t unov[9];
7460 
7461  Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
7462  Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
7463  Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
7464  Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
7465  Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
7466  Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
7467 
7468  unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
7469  unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
7470  unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
7471  unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
7472  unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
7473  unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
7474  unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
7475  unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
7476  unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
7477 
7478  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
7479  stats->AddText(t);
7480  if (h2->GetEntries() < 1e7)
7481  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
7482  else
7483  snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
7484  stats->AddText(t);
7485  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
7486  stats->AddText(t);
7487  }
7488 
7489  // Draw Fit parameters
7490  if (fit) {
7491  Int_t ndf = fit->GetNDF();
7492  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
7493  stats->AddText(t);
7494  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7495  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
7496  ,(Float_t)fit->GetParameter(ipar)
7497  ,(Float_t)fit->GetParError(ipar));
7498  t[63] = 0;
7499  stats->AddText(t);
7500  }
7501  }
7502 
7503  if (!done) fFunctions->Add(stats);
7504  stats->Paint();
7505 }
7506 
7507 
7508 ////////////////////////////////////////////////////////////////////////////////
7509 /// [Draw the statistics box for 3D histograms.](#HP07)
7510 
7511 void THistPainter::PaintStat3(Int_t dostat, TF1 *fit)
7512 {
7513 
7514  if (fH->GetDimension() != 3) return;
7515  TH3 *h3 = (TH3*)fH;
7516 
7517  static char t[100];
7518  Int_t dofit;
7519  TPaveStats *stats = 0;
7521  TObject *obj;
7522  while ((obj = next())) {
7523  if (obj->InheritsFrom(TPaveStats::Class())) {
7524  stats = (TPaveStats*)obj;
7525  break;
7526  }
7527  }
7528  if (stats && dostat) {
7529  dofit = stats->GetOptFit();
7530  dostat = stats->GetOptStat();
7531  } else {
7532  dofit = gStyle->GetOptFit();
7533  }
7534  if (dostat == 1) dostat = 1111;
7535  Int_t print_name = dostat%10;
7536  Int_t print_entries = (dostat/10)%10;
7537  Int_t print_mean = (dostat/100)%10;
7538  Int_t print_stddev = (dostat/1000)%10;
7539  Int_t print_under = (dostat/10000)%10;
7540  Int_t print_over = (dostat/100000)%10;
7541  Int_t print_integral= (dostat/1000000)%10;
7542  Int_t print_skew = (dostat/10000000)%10;
7543  Int_t print_kurt = (dostat/100000000)%10;
7544  Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
7545  if (print_under || print_over) nlines += 3;
7546 
7547  // Pavetext with statistics
7548  if (!gStyle->GetOptFit()) fit = 0;
7549  Bool_t done = kFALSE;
7550  if (!dostat && !fit) {
7551  if (stats) { fFunctions->Remove(stats); delete stats;}
7552  return;
7553  }
7554  Double_t statw = gStyle->GetStatW();
7555  if (fit) statw = 1.8*gStyle->GetStatW();
7556  Double_t stath = nlines*gStyle->GetStatFontSize();
7557  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7558  stath = 0.25*nlines*gStyle->GetStatH();
7559  }
7560  if (fit) stath += gStyle->GetStatH();
7561  if (stats) {
7562  stats->Clear();
7563  done = kTRUE;
7564  } else {
7565  stats = new TPaveStats(
7566  gStyle->GetStatX()-statw,
7567  gStyle->GetStatY()-stath,
7568  gStyle->GetStatX(),
7569  gStyle->GetStatY(),"brNDC");
7570 
7571  stats->SetParent(fH);
7572  stats->SetOptFit(dofit);
7573  stats->SetOptStat(dostat);
7574  stats->SetFillColor(gStyle->GetStatColor());
7575  stats->SetFillStyle(gStyle->GetStatStyle());
7577  stats->SetName("stats");
7578 
7580  stats->SetTextAlign(12);
7581  stats->SetTextFont(gStyle->GetStatFont());
7582  stats->SetFitFormat(gStyle->GetFitFormat());
7583  stats->SetStatFormat(gStyle->GetStatFormat());
7584  stats->SetBit(kCanDelete);
7585  stats->SetBit(kMustCleanup);
7586  }
7587  if (print_name) stats->AddText(h3->GetName());
7588  if (print_entries) {
7589  if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
7590  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
7591  stats->AddText(t);
7592  }
7593  char textstats[50];
7594  if (print_mean) {
7595  if (print_mean == 1) {
7596  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
7597  snprintf(t,100,textstats,h3->GetMean(1));
7598  stats->AddText(t);
7599  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7600  snprintf(t,100,textstats,h3->GetMean(2));
7601  stats->AddText(t);
7602  snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
7603  snprintf(t,100,textstats,h3->GetMean(3));
7604  stats->AddText(t);
7605  } else {
7606  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
7607  ,"%",stats->GetStatFormat());
7608  snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
7609  stats->AddText(t);
7610  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7611  ,"%",stats->GetStatFormat());
7612  snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
7613  stats->AddText(t);
7614  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
7615  ,"%",stats->GetStatFormat());
7616  snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
7617  stats->AddText(t);
7618  }
7619  }
7620  if (print_stddev) {
7621  if (print_stddev == 1) {
7622  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
7623  snprintf(t,100,textstats,h3->GetStdDev(1));
7624  stats->AddText(t);
7625  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7626  snprintf(t,100,textstats,h3->GetStdDev(2));
7627  stats->AddText(t);
7628  snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
7629  snprintf(t,100,textstats,h3->GetStdDev(3));
7630  stats->AddText(t);
7631  } else {
7632  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
7633  ,"%",stats->GetStatFormat());
7634  snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
7635  stats->AddText(t);
7636  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7637  ,"%",stats->GetStatFormat());
7638  snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
7639  stats->AddText(t);
7640  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
7641  ,"%",stats->GetStatFormat());
7642  snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
7643  stats->AddText(t);
7644  }
7645  }
7646  if (print_integral) {
7647  snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
7648  stats->AddText(t);
7649  }
7650  if (print_skew) {
7651  if (print_skew == 1) {
7652  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
7653  snprintf(t,100,textstats,h3->GetSkewness(1));
7654  stats->AddText(t);
7655  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
7656  snprintf(t,100,textstats,h3->GetSkewness(2));
7657  stats->AddText(t);
7658  snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
7659  snprintf(t,100,textstats,h3->GetSkewness(3));
7660  stats->AddText(t);
7661  } else {
7662  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
7663  ,"%",stats->GetStatFormat());
7664  snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
7665  stats->AddText(t);
7666  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
7667  ,"%",stats->GetStatFormat());
7668  snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
7669  stats->AddText(t);
7670  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
7671  ,"%",stats->GetStatFormat());
7672  snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
7673  stats->AddText(t);
7674  }
7675  }
7676  if (print_kurt) {
7677  if (print_kurt == 1) {
7678  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
7679  snprintf(t,100,textstats,h3->GetKurtosis(1));
7680  stats->AddText(t);
7681  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
7682  snprintf(t,100,textstats,h3->GetKurtosis(2));
7683  stats->AddText(t);
7684  snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
7685  snprintf(t,100,textstats,h3->GetKurtosis(3));
7686  stats->AddText(t);
7687  } else {
7688  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
7689  ,"%",stats->GetStatFormat());
7690  snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
7691  stats->AddText(t);
7692  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
7693  ,"%",stats->GetStatFormat());
7694  snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
7695  stats->AddText(t);
7696  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
7697  ,"%",stats->GetStatFormat());
7698  snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
7699  stats->AddText(t);
7700  }
7701  }
7702  if (print_under || print_over) {
7703  // no underflow - overflow printing for a 3D histogram
7704  // one would need a 3D table
7705 // //get 3*3 under/overflows for 2d hist
7706 // Double_t unov[9];
7707 
7708 // unov[0] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7709 // unov[1] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7710 // unov[2] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7711 // unov[3] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7712 // unov[4] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7713 // unov[5] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7714 // unov[6] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,0,h3->GetYaxis()->GetFirst()-1);
7715 // unov[7] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),0,h3->GetYaxis()->GetFirst()-1);
7716 // unov[8] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,0,h3->GetYaxis()->GetFirst()-1);
7717 
7718 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
7719 // stats->AddText(t);
7720 // if (h3->GetEntries() < 1e7)
7721 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
7722 // else
7723 // sprintf(t, " %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
7724 // stats->AddText(t);
7725 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
7726 // stats->AddText(t);
7727  }
7728 
7729  // Draw Fit parameters
7730  if (fit) {
7731  Int_t ndf = fit->GetNDF();
7732  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
7733  stats->AddText(t);
7734  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7735  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
7736  ,(Float_t)fit->GetParameter(ipar)
7737  ,(Float_t)fit->GetParError(ipar));
7738  t[32] = 0;
7739  stats->AddText(t);
7740  }
7741  }
7742 
7743  if (!done) fFunctions->Add(stats);
7744  stats->Paint();
7745 }
7746 
7747 
7748 ////////////////////////////////////////////////////////////////////////////////
7749 /// [Control function to draw a 2D histogram as a surface plot.](#HP18)
7750 
7752 {
7753 
7754  const Double_t ydiff = 1;
7755  const Double_t yligh1 = 10;
7756  const Double_t qa = 0.15;
7757  const Double_t qd = 0.15;
7758  const Double_t qs = 0.8;
7759  Double_t fmin, fmax;
7760  Int_t raster = 0;
7761  Int_t irep = 0;
7762 
7763  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7764  Int_t nx = Hparam.xlast - Hparam.xfirst;
7765  Int_t ny = Hparam.ylast - Hparam.yfirst;
7766  Double_t zmin = Hparam.zmin;
7767  Double_t zmax = Hparam.zmax;
7768  Double_t xlab1 = Hparam.xmin;
7769  Double_t xlab2 = Hparam.xmax;
7770  Double_t ylab1 = Hparam.ymin;
7771  Double_t ylab2 = Hparam.ymax;
7772  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7773  Double_t deltaz = TMath::Abs(zmin);
7774  if (deltaz == 0) deltaz = 1;
7775  if (zmin >= zmax) {
7776  zmin -= 0.5*deltaz;
7777  zmax += 0.5*deltaz;
7778  }
7779  Double_t z1c = zmin;
7780  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7781  // Compute the lego limits and instantiate a lego object
7782  fXbuf[0] = -1;
7783  fYbuf[0] = 1;
7784  fXbuf[1] = -1;
7785  fYbuf[1] = 1;
7786  if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
7787  if (Hoption.System == kPOLAR) {
7788  fXbuf[2] = z1c;
7789  fYbuf[2] = z2c;
7790  } else if (Hoption.System == kCYLINDRICAL) {
7791  if (Hoption.Logy) {
7792  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7793  else fXbuf[2] = 0;
7794  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7795  else fYbuf[2] = 0;
7796  } else {
7797  fXbuf[2] = ylab1;
7798  fYbuf[2] = ylab2;
7799  }
7800  z1c = 0; z2c = 1;
7801  } else if (Hoption.System == kSPHERICAL) {
7802  fXbuf[2] = -1;
7803  fYbuf[2] = 1;
7804  z1c = 0; z2c = 1;
7805  } else if (Hoption.System == kRAPIDITY) {
7806  fXbuf[2] = -1/TMath::Tan(dangle);
7807  fYbuf[2] = 1/TMath::Tan(dangle);
7808  } else {
7809  fXbuf[0] = xlab1;
7810  fYbuf[0] = xlab2;
7811  fXbuf[1] = ylab1;
7812  fYbuf[1] = ylab2;
7813  fXbuf[2] = z1c;
7814  fYbuf[2] = z2c;
7815  }
7816 
7817  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
7820 
7821  // Create axis object
7822 
7823  TGaxis *axis = new TGaxis();
7824 
7825  // Initialize the levels on the Z axis
7826  Int_t ndiv = fH->GetContour();
7827  if (ndiv == 0 ) {
7828  ndiv = gStyle->GetNumberContours();
7829  fH->SetContour(ndiv);
7830  }
7831  Int_t ndivz = TMath::Abs(ndiv);
7832  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7833 
7834  if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
7835  if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
7836 
7837  // Close the surface in case of non cartesian coordinates.
7838 
7839  if (Hoption.System != kCARTESIAN) {nx++; ny++;}
7840 
7841  // Now ready to draw the surface plot
7842 
7843  TView *view = gPad->GetView();
7844  if (!view) {
7845  Error("PaintSurface", "no TView in current pad");
7846  return;
7847  }
7848 
7849  Double_t thedeg = 90 - gPad->GetTheta();
7850  Double_t phideg = -90 - gPad->GetPhi();
7851  Double_t psideg = view->GetPsi();
7852  view->SetView(phideg, thedeg, psideg, irep);
7853 
7854  // Set color/style for back box
7855  if (Hoption.Same) {
7856  fLego->SetFillStyle(0);
7857  fLego->SetFillColor(1);
7858  } else {
7859  fLego->SetFillStyle(gPad->GetFrameFillStyle());
7860  fLego->SetFillColor(gPad->GetFrameFillColor());
7861  }
7862  fLego->TAttFill::Modify();
7863 
7864  Int_t backcolor = gPad->GetFrameFillColor();
7865  if (Hoption.System != kCARTESIAN) backcolor = 0;
7866  view->PadRange(backcolor);
7867 
7870  fLego->TAttFill::Modify();
7871 
7872  // Draw the filled contour on top
7873  Int_t icol1 = fH->GetFillColor();
7874 
7875  Int_t hoption35 = Hoption.Surf;
7876  if (Hoption.Surf == 13 || Hoption.Surf == 15) {
7877  DefineColorLevels(ndivz);
7878  Hoption.Surf = 23;
7881  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
7882  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7883  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7884  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7885  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
7886  Hoption.Surf = hoption35;
7887  fLego->SetMesh(1);
7888  }
7889 
7890  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7891  else fLego->InitMoveScreen(-1.1,1.1);
7892 
7893  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
7895  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7897  fLego->BackBox(90);
7898  }
7899  }
7900 
7901  // Gouraud Shading surface
7902  if (Hoption.Surf == 14) {
7903  // Set light sources
7904  fLego->LightSource(0, ydiff, 0,0,0,irep);
7905  fLego->LightSource(1, yligh1 ,1,1,1,irep);
7906  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7907  fmin = ydiff*qa;
7908  fmax = fmin + (yligh1+0.1)*(qd+qs);
7909  Int_t nbcol = 28;
7910  icol1 = 201;
7911  Double_t dcol = 0.5/Double_t(nbcol);
7912  TColor *colref = gROOT->GetColor(fH->GetFillColor());
7913  if (!colref) return;
7914  Float_t r,g,b,hue,light,satur;
7915  colref->GetRGB(r,g,b);
7916  TColor::RGBtoHLS(r,g,b,hue,light,satur);
7917  TColor *acol;
7918  for (Int_t col=0;col<nbcol;col++) {
7919  acol = gROOT->GetColor(col+icol1);
7920  TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
7921  if (acol) acol->SetRGB(r,g,b);
7922  }
7923  fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
7926  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
7927  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7928  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7929  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7930  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
7931  } else if (Hoption.Surf == 15) {
7932  // The surface is not drawn in this case.
7933  } else {
7934  // Draw the surface
7935  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
7936  DefineColorLevels(ndivz);
7937  } else {
7939  }
7941  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceRaster1);
7942  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode2);
7943  if (Hoption.System == kPOLAR) {
7944  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
7945  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
7946  } else if (Hoption.System == kCYLINDRICAL) {
7947  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
7948  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7949  } else if (Hoption.System == kSPHERICAL) {
7950  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
7951  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7952  } else if (Hoption.System == kRAPIDITY) {
7953  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
7954  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7955  } else {
7956  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1);
7958  if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
7959  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
7960  }
7961  }
7962 
7963  // Paint the line contour on top for option SURF7
7964  if (Hoption.Surf == 17) {
7965  fLego->InitMoveScreen(-1.1,1.1);
7967  Hoption.Surf = 23;
7970  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
7971  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
7972  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
7973  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
7974  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
7975  }
7976 
7977  if ((!Hoption.Same) &&
7978  (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
7979  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7981  fLego->BackBox(90);
7982  }
7983  }
7984  if (Hoption.System == kCARTESIAN) {
7985  fLego->InitMoveScreen(-1.1,1.1);
7987  if (Hoption.FrontBox) fLego->FrontBox(90);
7988  }
7989  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7990 
7991  if (Hoption.Zscale) PaintPalette();
7992 
7993  delete axis;
7994  delete fLego; fLego = 0;
7995 }
7996 
7997 
7998 ////////////////////////////////////////////////////////////////////////////////
7999 /// Control function to draw a table using Delaunay triangles.
8000 
8002 {
8003 
8004  TGraphDelaunay2D *dt = nullptr;
8005  TGraphDelaunay *dtOld = nullptr;
8006 
8007  // Check if fH contains a TGraphDelaunay2D
8008  TList *hl = fH->GetListOfFunctions();
8009  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
8010  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
8011  if (!dt && !dtOld) return;
8012 
8013  // If needed, create a TGraph2DPainter
8014  if (!fGraph2DPainter) {
8015  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
8016  else fGraph2DPainter = new TGraph2DPainter(dtOld);
8017  }
8018 
8019  // Define the 3D view
8020  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8021  if (Hoption.Same) {
8022  TView *viewsame = gPad->GetView();
8023  if (!viewsame) {
8024  Error("PaintTriangles", "no TView in current pad, do not use option SAME");
8025  return;
8026  }
8027  Double_t *rmin = viewsame->GetRmin();
8028  Double_t *rmax = viewsame->GetRmax();
8029  if (!rmin || !rmax) return;
8030  fXbuf[0] = rmin[0];
8031  fYbuf[0] = rmax[0];
8032  fXbuf[1] = rmin[1];
8033  fYbuf[1] = rmax[1];
8034  fXbuf[2] = rmin[2];
8035  fYbuf[2] = rmax[2];
8036  } else {
8037  fXbuf[0] = Hparam.xmin;
8038  fYbuf[0] = Hparam.xmax;
8039  fXbuf[1] = Hparam.ymin;
8040  fYbuf[1] = Hparam.ymax;
8041  fXbuf[2] = Hparam.zmin;
8042  fYbuf[2] = Hparam.zmax;
8043  }
8044 
8045  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8046  TView *view = gPad->GetView();
8047  if (!view) {
8048  Error("PaintTriangles", "no TView in current pad");
8049  return;
8050  }
8051  Double_t thedeg = 90 - gPad->GetTheta();
8052  Double_t phideg = -90 - gPad->GetPhi();
8053  Double_t psideg = view->GetPsi();
8054  Int_t irep;
8055  view->SetView(phideg, thedeg, psideg, irep);
8056 
8057  // Set color/style for back box
8058  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8059  fLego->SetFillColor(gPad->GetFrameFillColor());
8060  fLego->TAttFill::Modify();
8061  Int_t backcolor = gPad->GetFrameFillColor();
8062  if (Hoption.System != kCARTESIAN) backcolor = 0;
8063  view->PadRange(backcolor);
8066  fLego->TAttFill::Modify();
8067 
8068  // Paint the Back Box if needed
8069  if (Hoption.BackBox && !Hoption.Same) {
8070  fLego->InitMoveScreen(-1.1,1.1);
8073  fLego->BackBox(90);
8074  }
8075 
8076  // Paint the triangles
8077  fGraph2DPainter->Paint(option);
8078 
8079  // Paint the Front Box if needed
8080  if (Hoption.FrontBox) {
8081  fLego->InitMoveScreen(-1.1,1.1);
8083  fLego->FrontBox(90);
8084  }
8085 
8086  // Paint the Axis if needed
8087  if (!Hoption.Axis && !Hoption.Same) {
8088  TGaxis *axis = new TGaxis();
8089  PaintLegoAxis(axis, 90);
8090  delete axis;
8091  }
8092 
8093  if (Hoption.Zscale) PaintPalette();
8094 
8095  delete fLego; fLego = 0;
8096 }
8097 
8098 
8099 ////////////////////////////////////////////////////////////////////////////////
8100 /// Define the color levels used to paint legos, surfaces etc..
8101 
8103 {
8104 
8105  Int_t i, irep;
8106 
8107  // Initialize the color levels
8108  if (ndivz >= 100) {
8109  Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
8110  ndivz = 8;
8111  }
8112  Double_t *funlevel = new Double_t[ndivz+1];
8113  Int_t *colorlevel = new Int_t[ndivz+1];
8114  Int_t theColor;
8115  Int_t ncolors = gStyle->GetNumberOfColors();
8116  for (i = 0; i < ndivz; ++i) {
8117  funlevel[i] = fH->GetContourLevelPad(i);
8118  theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
8119  colorlevel[i] = gStyle->GetColorPalette(theColor);
8120  }
8121  colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
8122  fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
8123  delete [] colorlevel;
8124  delete [] funlevel;
8125 }
8126 
8127 
8128 ////////////////////////////////////////////////////////////////////////////////
8129 /// [Control function to draw 2D/3D histograms (tables).](#HP01c)
8130 
8131 void THistPainter::PaintTable(Option_t *option)
8132 {
8133 
8134  // Fill Hparam structure with histo parameters
8135  if (!TableInit()) return;
8136 
8137  // Draw histogram frame
8138  PaintFrame();
8139 
8140  // If palette option not specified, delete a possible existing palette
8141  if (!Hoption.Zscale) {
8142  TObject *palette = fFunctions->FindObject("palette");
8143  if (palette) { fFunctions->Remove(palette); delete palette;}
8144  }
8145 
8146  // Do not draw the histogram. Only the attached functions will be drawn.
8147  if (Hoption.Func == 2) {
8148  if (Hoption.Zscale) {
8149  Int_t ndiv = fH->GetContour();
8150  if (ndiv == 0 ) {
8151  ndiv = gStyle->GetNumberContours();
8152  fH->SetContour(ndiv);
8153  }
8154  PaintPalette();
8155  }
8156 
8157  // Draw the histogram according to the option
8158  } else {
8159  if (fH->InheritsFrom(TH2Poly::Class())) {
8160  if (Hoption.Fill) PaintTH2PolyBins("f");
8161  if (Hoption.Color) PaintTH2PolyColorLevels(option);
8162  if (Hoption.Scat) PaintTH2PolyScatterPlot(option);
8163  if (Hoption.Text) PaintTH2PolyText(option);
8164  if (Hoption.Line) PaintTH2PolyBins("l");
8165  if (Hoption.Mark) PaintTH2PolyBins("P");
8166  } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
8167  if (Hoption.Scat) PaintScatterPlot(option);
8168  if (Hoption.Arrow) PaintArrows(option);
8169  if (Hoption.Box) PaintBoxes(option);
8170  if (Hoption.Color) PaintColorLevels(option);
8171  if (Hoption.Contour) PaintContour(option);
8172  if (Hoption.Text) PaintText(option);
8173  if (Hoption.Error >= 100) Paint2DErrors(option);
8174  if (Hoption.Candle) PaintCandlePlot(option);
8175  if (Hoption.Violin) PaintViolinPlot(option);
8176  }
8177  if (Hoption.Lego) PaintLego(option);
8178  if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
8179  if (Hoption.Tri) PaintTriangles(option);
8180  }
8181 
8182  // Draw histogram title
8183  PaintTitle();
8184 
8185  // Draw the axes
8186  if (!Hoption.Lego && !Hoption.Surf &&
8187  !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
8188 
8189  TF1 *fit = 0;
8191  TObject *obj;
8192  while ((obj = next())) {
8193  if (obj->InheritsFrom(TF1::Class())) {
8194  fit = (TF1*)obj;
8195  break;
8196  }
8197  }
8198  if (Hoption.Same != 1) {
8199  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
8200  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
8201  //ALWAYS executed on non-iOS platform.
8202  //On iOS, depends on mode.
8203  PaintStat2(gStyle->GetOptStat(),fit);
8204  }
8205  }
8206  }
8207 }
8208 
8209 
8210 ////////////////////////////////////////////////////////////////////////////////
8211 /// Control function to draw a TH2Poly bins' contours.
8212 ///
8213 /// - option = "F" draw the bins as filled areas.
8214 /// - option = "L" draw the bins as line.
8215 /// - option = "P" draw the bins as markers.
8216 
8218 {
8219 
8220  //Do not highlight the histogram, if its part was picked.
8221  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
8222 
8223  TString opt = option;
8224  opt.ToLower();
8225  Bool_t line = kFALSE;
8226  Bool_t fill = kFALSE;
8227  Bool_t mark = kFALSE;
8228  if (opt.Contains("l")) line = kTRUE;
8229  if (opt.Contains("f")) fill = kTRUE;
8230  if (opt.Contains("p")) mark = kTRUE;
8231 
8232  TH2PolyBin *b;
8233 
8234  TIter next(((TH2Poly*)fH)->GetBins());
8235  TObject *obj, *poly;
8236 
8237  while ((obj=next())) {
8238  b = (TH2PolyBin*)obj;
8239  poly = b->GetPolygon();
8240 
8241  // Paint the TGraph bins.
8242  if (poly->IsA() == TGraph::Class()) {
8243  TGraph *g = (TGraph*)poly;
8244  g->TAttLine::Modify();
8245  g->TAttMarker::Modify();
8246  g->TAttFill::Modify();
8247  if (line) g->Paint("L");
8248  if (fill) g->Paint("F");
8249  if (mark) g->Paint("P");
8250  }
8251 
8252  // Paint the TMultiGraph bins.
8253  if (poly->IsA() == TMultiGraph::Class()) {
8254  TMultiGraph *mg = (TMultiGraph*)poly;
8255  TList *gl = mg->GetListOfGraphs();
8256  if (!gl) return;
8257  TGraph *g;
8258  TIter nextg(gl);
8259  while ((g = (TGraph*) nextg())) {
8260  g->TAttLine::Modify();
8261  g->TAttMarker::Modify();
8262  g->TAttFill::Modify();
8263  if (line) g->Paint("L");
8264  if (fill) g->Paint("F");
8265  if (mark) g->Paint("P");
8266  }
8267  }
8268  }
8269 }
8270 
8271 
8272 ////////////////////////////////////////////////////////////////////////////////
8273 /// [Control function to draw a TH2Poly as a color plot.](#HP20a)
8274 
8276 {
8277 
8278  //Do not highlight the histogram, if its part was picked.
8279  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8280  return;
8282  Int_t ncolors, color, theColor;
8283  Double_t z, zc;
8284  Double_t zmin = fH->GetMinimum();
8285  Double_t zmax = fH->GetMaximum();
8286  if (Hoption.Logz) {
8287  if (zmax > 0) {
8288  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8289  zmin = TMath::Log10(zmin);
8290  zmax = TMath::Log10(zmax);
8291  } else {
8292  return;
8293  }
8294  }
8295  Double_t dz = zmax - zmin;
8296 
8297  // Initialize the levels on the Z axis
8298  ncolors = gStyle->GetNumberOfColors();
8299  Int_t ndiv = fH->GetContour();
8300  if (ndiv == 0 ) {
8301  ndiv = gStyle->GetNumberContours();
8302  fH->SetContour(ndiv);
8303  }
8304  Int_t ndivz = TMath::Abs(ndiv);
8305  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8306  Double_t scale = ndivz/dz;
8307 
8308  TH2PolyBin *b;
8309 
8310  TIter next(((TH2Poly*)fH)->GetBins());
8311  TObject *obj, *poly;
8312 
8313  while ((obj=next())) {
8314  b = (TH2PolyBin*)obj;
8315  poly = b->GetPolygon();
8316 
8317  z = b->GetContent();
8318  if (Hoption.Logz) {
8319  if (z > 0) z = TMath::Log10(z);
8320  else z = zmin;
8321  }
8322  if (z < zmin) continue;
8323 
8324  // Define the bin color.
8325  if (fH->TestBit(TH1::kUserContour)) {
8326  zc = fH->GetContourLevelPad(0);
8327  if (z < zc) continue;
8328  color = -1;
8329  for (Int_t k=0; k<ndiv; k++) {
8330  zc = fH->GetContourLevelPad(k);
8331  if (z < zc) {
8332  continue;
8333  } else {
8334  color++;
8335  }
8336  }
8337  } else {
8338  color = Int_t(0.01+(z-zmin)*scale);
8339  }
8340  theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
8341  if (theColor > ncolors-1) theColor = ncolors-1;
8342 
8343  // Paint the TGraph bins.
8344  if (poly->IsA() == TGraph::Class()) {
8345  TGraph *g = (TGraph*)poly;
8346  g->SetFillColor(gStyle->GetColorPalette(theColor));
8347  g->TAttFill::Modify();
8348  g->Paint("F");
8349  }
8350 
8351  // Paint the TMultiGraph bins.
8352  if (poly->IsA() == TMultiGraph::Class()) {
8353  TMultiGraph *mg = (TMultiGraph*)poly;
8354  TList *gl = mg->GetListOfGraphs();
8355  if (!gl) return;
8356  TGraph *g;
8357  TIter nextg(gl);
8358  while ((g = (TGraph*) nextg())) {
8359  g->SetFillColor(gStyle->GetColorPalette(theColor));
8360  g->TAttFill::Modify();
8361  g->Paint("F");
8362  }
8363  }
8364  }
8365  if (Hoption.Zscale) PaintPalette();
8366 }
8367 
8368 
8369 ////////////////////////////////////////////////////////////////////////////////
8370 /// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
8371 
8373 {
8374 
8375  //Do not highlight the histogram, if its part was selected.
8376  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8377  return;
8379  Int_t k, loop, marker=0;
8380  Double_t z, xk,xstep, yk, ystep, xp, yp;
8381  Double_t scale = 1;
8382  Double_t zmin = fH->GetMinimum();
8383  Double_t zmax = fH->GetMaximum();
8384  if (Hoption.Logz) {
8385  if (zmax > 0) {
8386  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8387  zmin = TMath::Log10(zmin);
8388  zmax = TMath::Log10(zmax);
8389  } else {
8390  return;
8391  }
8392  }
8393  Double_t dz = zmax - zmin;
8394  scale = (kNMAX-1)/dz;
8395 
8396 
8397  // use an independent instance of a random generator
8398  // instead of gRandom to avoid conflicts and
8399  // to get same random numbers when drawing the same histogram
8400  TRandom2 random;
8401 
8402  TH2PolyBin *b;
8403 
8404  TIter next(((TH2Poly*)fH)->GetBins());
8405  TObject *obj, *poly;
8406 
8407  Double_t maxarea = 0, a;
8408  while ((obj=next())) {
8409  b = (TH2PolyBin*)obj;
8410  a = b->GetArea();
8411  if (a>maxarea) maxarea = a;
8412  }
8413 
8414  next.Reset();
8415 
8416  while ((obj=next())) {
8417  b = (TH2PolyBin*)obj;
8418  poly = b->GetPolygon();
8419  z = b->GetContent();
8420  if (z < zmin) z = zmin;
8421  if (z > zmax) z = zmax;
8422  if (Hoption.Logz) {
8423  if (z > 0) z = TMath::Log10(z) - zmin;
8424  } else {
8425  z -= zmin;
8426  }
8427  k = Int_t((z*scale)*(b->GetArea()/maxarea));
8428  xk = b->GetXMin();
8429  yk = b->GetYMin();
8430  xstep = b->GetXMax()-xk;
8431  ystep = b->GetYMax()-yk;
8432 
8433  // Paint the TGraph bins.
8434  if (poly->IsA() == TGraph::Class()) {
8435  TGraph *g = (TGraph*)poly;
8436  if (k <= 0 || z <= 0) continue;
8437  loop = 0;
8438  while (loop<k) {
8439  if (k+marker >= kNMAX) {
8440  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8441  marker=0;
8442  }
8443  xp = (random.Rndm(loop)*xstep) + xk;
8444  yp = (random.Rndm(loop)*ystep) + yk;
8445  if (g->IsInside(xp,yp)) {
8446  fXbuf[marker] = xp;
8447  fYbuf[marker] = yp;
8448  marker++;
8449  loop++;
8450  }
8451  }
8452  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8453  }
8454 
8455  // Paint the TMultiGraph bins.
8456  if (poly->IsA() == TMultiGraph::Class()) {
8457  TMultiGraph *mg = (TMultiGraph*)poly;
8458  TList *gl = mg->GetListOfGraphs();
8459  if (!gl) return;
8460  if (k <= 0 || z <= 0) continue;
8461  loop = 0;
8462  while (loop<k) {
8463  if (k+marker >= kNMAX) {
8464  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8465  marker=0;
8466  }
8467  xp = (random.Rndm(loop)*xstep) + xk;
8468  yp = (random.Rndm(loop)*ystep) + yk;
8469  if (mg->IsInside(xp,yp)) {
8470  fXbuf[marker] = xp;
8471  fYbuf[marker] = yp;
8472  marker++;
8473  loop++;
8474  }
8475  }
8476  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8477  }
8478  }
8479  PaintTH2PolyBins("l");
8480 }
8481 
8482 
8483 ////////////////////////////////////////////////////////////////////////////////
8484 /// [Control function to draw a TH2Poly as a text plot.](#HP20a)
8485 
8487 {
8488 
8489  TLatex text;
8490  text.SetTextFont(gStyle->GetTextFont());
8491  text.SetTextColor(fH->GetMarkerColor());
8493 
8494  Double_t x, y, z, e, angle = 0;
8495  char value[50];
8496  char format[32];
8497  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8498  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8499  Int_t opt = (Int_t)Hoption.Text/1000;
8500 
8501  text.SetTextAlign(22);
8502  if (Hoption.Text == 1) angle = 0;
8503  text.SetTextAngle(angle);
8504  text.TAttText::Modify();
8505 
8506  TH2PolyBin *b;
8507 
8508  TIter next(((TH2Poly*)fH)->GetBins());
8509  TObject *obj, *p;
8510 
8511  while ((obj=next())) {
8512  b = (TH2PolyBin*)obj;
8513  p = b->GetPolygon();
8514  x = (b->GetXMin()+b->GetXMax())/2;
8515  if (Hoption.Logx) {
8516  if (x > 0) x = TMath::Log10(x);
8517  else continue;
8518  }
8519  y = (b->GetYMin()+b->GetYMax())/2;
8520  if (Hoption.Logy) {
8521  if (y > 0) y = TMath::Log10(y);
8522  else continue;
8523  }
8524  z = b->GetContent();
8525  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
8526  if (opt==2) {
8527  e = fH->GetBinError(b->GetBinNumber());
8528  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
8529  "%",gStyle->GetPaintTextFormat(),
8530  "%",gStyle->GetPaintTextFormat());
8531  snprintf(value,50,format,z,e);
8532  } else {
8533  snprintf(value,50,format,z);
8534  }
8535  if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
8536  else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
8537  }
8538 
8539  PaintTH2PolyBins("l");
8540 }
8541 
8542 
8543 ////////////////////////////////////////////////////////////////////////////////
8544 /// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
8545 
8547 {
8548 
8549  TLatex text;
8550  text.SetTextFont(gStyle->GetTextFont());
8551  text.SetTextColor(fH->GetMarkerColor());
8553 
8554  Double_t x, y, z, e, angle = 0;
8555  char value[50];
8556  char format[32];
8557  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8558  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8559 
8560  // 1D histograms
8561  if (fH->GetDimension() == 1) {
8562  Bool_t getentries = kFALSE;
8563  Double_t yt;
8564  TProfile *hp = (TProfile*)fH;
8565  if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
8566  Hoption.Text = Hoption.Text-2000;
8567  getentries = kTRUE;
8568  }
8569  if (Hoption.Text == 1) angle = 90;
8570  text.SetTextAlign(11);
8571  if (angle == 90) text.SetTextAlign(12);
8572  if (angle == 0) text.SetTextAlign(21);
8573  text.TAttText::Modify();
8574  Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
8575  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8576  if (Hoption.Bar) {
8577  x = fH->GetXaxis()->GetBinLowEdge(i)+
8578  fH->GetXaxis()->GetBinWidth(i)*
8579  (fH->GetBarOffset()+0.5*fH->GetBarWidth());
8580  } else {
8581  x = fH->GetXaxis()->GetBinCenter(i);
8582  }
8583  y = fH->GetBinContent(i);
8584  yt = y;
8585  if (gStyle->GetHistMinimumZero() && y<0) y = 0;
8586  if (getentries) yt = hp->GetBinEntries(i);
8587  if (yt == 0.) continue;
8588  snprintf(value,50,format,yt);
8589  if (Hoption.Logx) {
8590  if (x > 0) x = TMath::Log10(x);
8591  else continue;
8592  }
8593  if (Hoption.Logy) {
8594  if (y > 0) y = TMath::Log10(y);
8595  else continue;
8596  }
8597  if (y >= gPad->GetY2()) continue;
8598  if (y <= gPad->GetY1()) continue;
8599  text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
8600  }
8601 
8602  // 2D histograms
8603  } else {
8604  text.SetTextAlign(22);
8605  if (Hoption.Text == 1) angle = 0;
8606  text.SetTextAngle(angle);
8607  text.TAttText::Modify();
8608  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8609  y = fYaxis->GetBinCenter(j);
8610  if (Hoption.Logy) {
8611  if (y > 0) y = TMath::Log10(y);
8612  else continue;
8613  }
8614  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8615  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8616  x = fXaxis->GetBinCenter(i);
8617  if (Hoption.Logx) {
8618  if (x > 0) x = TMath::Log10(x);
8619  else continue;
8620  }
8621  if (!IsInside(x,y)) continue;
8622  z = fH->GetBinContent(bin);
8623  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
8624  if (Hoption.Text>2000) {
8625  e = fH->GetBinError(bin);
8626  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
8627  "%",gStyle->GetPaintTextFormat(),
8628  "%",gStyle->GetPaintTextFormat());
8629  snprintf(value,50,format,z,e);
8630  } else {
8631  snprintf(value,50,format,z);
8632  }
8633  text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
8634  }
8635  }
8636  }
8637 }
8638 
8639 
8640 ////////////////////////////////////////////////////////////////////////////////
8641 /// [Control function to draw a 3D implicit functions.](#HP27)
8642 
8644 {
8645 
8646  Int_t irep;
8647 
8648  TGaxis *axis = new TGaxis();
8649  TAxis *xaxis = fH->GetXaxis();
8650  TAxis *yaxis = fH->GetYaxis();
8651  TAxis *zaxis = fH->GetZaxis();
8652 
8653  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
8654  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
8655  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
8656  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
8657  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
8658  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
8659 
8660  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8661 
8662  TView *view = gPad->GetView();
8663  if (!view) {
8664  Error("PaintTF3", "no TView in current pad");
8665  return;
8666  }
8667  Double_t thedeg = 90 - gPad->GetTheta();
8668  Double_t phideg = -90 - gPad->GetPhi();
8669  Double_t psideg = view->GetPsi();
8670  view->SetView(phideg, thedeg, psideg, irep);
8671 
8672  fLego->InitMoveScreen(-1.1,1.1);
8673 
8674  if (Hoption.BackBox) {
8677  fLego->BackBox(90);
8678  }
8679 
8681 
8682  fLego->ImplicitFunction(fXbuf, fYbuf, fH->GetNbinsX(),
8683  fH->GetNbinsY(),
8684  fH->GetNbinsZ(), "BF");
8685 
8686  if (Hoption.FrontBox) {
8687  fLego->InitMoveScreen(-1.1,1.1);
8689  fLego->FrontBox(90);
8690  }
8691  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8692 
8693  PaintTitle();
8694 
8695  delete axis;
8696  delete fLego; fLego = 0;
8697 }
8698 
8699 
8700 ////////////////////////////////////////////////////////////////////////////////
8701 /// Draw the histogram title
8702 ///
8703 /// The title is drawn according to the title alignment returned by
8704 /// `GetTitleAlign()`. It is a 2 digits integer): hv
8705 ///
8706 /// where `h` is the horizontal alignment and `v` is the
8707 /// vertical alignment.
8708 ///
8709 /// - `h` can get the values 1 2 3 for left, center, and right
8710 /// - `v` can get the values 1 2 3 for bottom, middle and top
8711 ///
8712 /// for instance the default alignment is: 13 (left top)
8713 
8715 {
8716 
8717  if (Hoption.Same) return;
8718  if (fH->TestBit(TH1::kNoTitle)) return;
8719  Int_t nt = strlen(fH->GetTitle());
8720  TPaveText *title = 0;
8721  TObject *obj;
8722  TIter next(gPad->GetListOfPrimitives());
8723  while ((obj = next())) {
8724  if (!obj->InheritsFrom(TPaveText::Class())) continue;
8725  title = (TPaveText*)obj;
8726  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
8727  break;
8728  }
8729  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
8730  if (title) delete title;
8731  return;
8732  }
8733  Double_t ht = gStyle->GetTitleH();
8734  Double_t wt = gStyle->GetTitleW();
8735  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
8736  if (ht <= 0) ht = 0.05;
8737  if (wt <= 0) {
8738  TLatex l;
8739  l.SetTextSize(ht);
8740  l.SetTitle(fH->GetTitle());
8741  // adjustment in case the title has several lines (#splitline)
8742  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
8743  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
8744  wt = TMath::Min(0.7, 0.02+wndc);
8745  }
8746  if (title) {
8747  TText *t0 = (TText*)title->GetLine(0);
8748  if (t0) {
8749  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
8750  t0->SetTitle(fH->GetTitle());
8751  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
8752  }
8753  return;
8754  }
8755 
8756  Int_t talh = gStyle->GetTitleAlign()/10;
8757  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
8758  Int_t talv = gStyle->GetTitleAlign()%10;
8759  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
8760  Double_t xpos, ypos;
8761  xpos = gStyle->GetTitleX();
8762  ypos = gStyle->GetTitleY();
8763  if (talh == 2) xpos = xpos-wt/2.;
8764  if (talh == 3) xpos = xpos-wt;
8765  if (talv == 2) ypos = ypos+ht/2.;
8766  if (talv == 1) ypos = ypos+ht;
8767 
8768  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
8769 
8770  // box with the histogram title
8772  ptitle->SetFillStyle(gStyle->GetTitleStyle());
8773  ptitle->SetName("title");
8776  ptitle->SetTextFont(gStyle->GetTitleFont(""));
8777  if (gStyle->GetTitleFont("")%10 > 2)
8778  ptitle->SetTextSize(gStyle->GetTitleFontSize());
8779  ptitle->AddText(fH->GetTitle());
8780  ptitle->SetBit(kCanDelete);
8781  ptitle->Draw();
8782  ptitle->Paint();
8783 
8784  if(!gPad->IsEditable()) delete ptitle;
8785 }
8786 
8787 
8788 ////////////////////////////////////////////////////////////////////////////////
8789 /// Process message `mess`.
8790 
8791 void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
8792 {
8793 
8794  if (!strcmp(mess,"SetF3")) {
8796  } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
8798  } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
8799  TVectorD &v = (TVectorD&)(*obj);
8800  Double_t xclip = v(0);
8801  Double_t yclip = v(1);
8802  Double_t zclip = v(2);
8803  TPainter3dAlgorithms::SetF3ClippingBoxOn(xclip,yclip,zclip);
8804  }
8805 }
8806 
8807 
8808 ////////////////////////////////////////////////////////////////////////////////
8809 /// Static function.
8810 ///
8811 /// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
8812 /// This procedure can be used to create an all-sky map in Galactic
8813 /// coordinates with an equal-area Aitoff projection. Output map
8814 /// coordinates are zero longitude centered.
8815 /// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
8816 ///
8817 /// source: GMT
8818 ///
8819 /// code from Ernst-Jan Buis
8820 
8822 {
8823 
8824  Double_t x, y;
8825 
8826  Double_t alpha2 = (l/2)*TMath::DegToRad();
8828  Double_t r2 = TMath::Sqrt(2.);
8829  Double_t f = 2*r2/TMath::Pi();
8830  Double_t cdec = TMath::Cos(delta);
8831  Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
8832  x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
8833  y = TMath::Sin(delta)*r2/denom;
8834  x *= TMath::RadToDeg()/f;
8835  y *= TMath::RadToDeg()/f;
8836  // x *= -1.; // for a skymap swap left<->right
8837  Al = x;
8838  Ab = y;
8839 
8840  return 0;
8841 }
8842 
8843 
8844 ////////////////////////////////////////////////////////////////////////////////
8845 /// Static function
8846 ///
8847 /// Probably the most famous of the various map projections, the Mercator projection
8848 /// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
8849 /// with no distortion along the equator.
8850 /// The Mercator projection has been used extensively for world maps in which the distortion towards
8851 /// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
8852 /// Greenland is larger than South America. In reality, the latter is about eight times the size of
8853 /// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
8854 /// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
8855 /// code from Ernst-Jan Buis
8856 
8858 {
8859 
8860  Al = l;
8862  Ab = TMath::Log(aid);
8863  return 0;
8864 }
8865 
8866 
8867 ////////////////////////////////////////////////////////////////////////////////
8868 /// Static function code from Ernst-Jan Buis
8869 
8871 {
8872 
8873  Al = l*cos(b*TMath::DegToRad());
8874  Ab = b;
8875  return 0;
8877 
8878 
8879 ////////////////////////////////////////////////////////////////////////////////
8880 /// Static function code from Ernst-Jan Buis
8881 
8883 {
8884 
8885  Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
8886  Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
8887  return 0;
8889 
8890 
8891 ////////////////////////////////////////////////////////////////////////////////
8892 /// Recompute the histogram range following graphics operations.
8893 
8895 {
8896 
8897  if (Hoption.Same) return;
8898 
8899  // Compute x,y range
8900  Double_t xmin = Hparam.xmin;
8901  Double_t xmax = Hparam.xmax;
8902  Double_t ymin = Hparam.ymin;
8903  Double_t ymax = Hparam.ymax;
8904 
8905  Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
8906  if (Hoption.Proj ==1) {
8907  // TODO : check x range not lower than -180 and not higher than 180
8908  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8909  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8910  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8911  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8912 
8913  if (xmin > xmin_aid) xmin = xmin_aid;
8914  if (ymin > ymin_aid) ymin = ymin_aid;
8915  if (xmax < xmax_aid) xmax = xmax_aid;
8916  if (ymax < ymax_aid) ymax = ymax_aid;
8917  if (Hparam.ymin<0 && Hparam.ymax>0) {
8918  // there is an 'equator', check its range in the plot..
8919  THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
8920  THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
8921  if (xmin >xmin_aid) xmin = xmin_aid;
8922  if (xmax <xmax_aid) xmax = xmax_aid;
8923  }
8924  if (Hparam.xmin<0 && Hparam.xmax>0) {
8925  THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
8926  THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
8927  if (ymin >ymin_aid) ymin = ymin_aid;
8928  if (ymax <ymax_aid) ymax = ymax_aid;
8929  }
8930  } else if ( Hoption.Proj ==2) {
8931  if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
8932  Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
8933  Hoption.Proj = 0;
8934  } else {
8935  THistPainter::ProjectMercator2xy(Hparam.xmin, Hparam.ymin, xmin, ymin);
8936  THistPainter::ProjectMercator2xy(Hparam.xmax, Hparam.ymax, xmax, ymax);
8937  }
8938  } else if (Hoption.Proj == 3) {
8939  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8940  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8941  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8942  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8943 
8944  if (xmin > xmin_aid) xmin = xmin_aid;
8945  if (ymin > ymin_aid) ymin = ymin_aid;
8946  if (xmax < xmax_aid) xmax = xmax_aid;
8947  if (ymax < ymax_aid) ymax = ymax_aid;
8948  if (Hparam.ymin<0 && Hparam.ymax>0) {
8949  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
8950  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
8951  if (xmin >xmin_aid) xmin = xmin_aid;
8952  if (xmax <xmax_aid) xmax = xmax_aid;
8953  }
8954  if (Hparam.xmin<0 && Hparam.xmax>0) {
8955  THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
8956  THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
8957  if (ymin >ymin_aid) ymin = ymin_aid;
8958  if (ymax <ymax_aid) ymax = ymax_aid;
8959  }
8960  } else if (Hoption.Proj == 4) {
8961  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8962  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8963  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8964  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8965 
8966  if (xmin > xmin_aid) xmin = xmin_aid;
8967  if (ymin > ymin_aid) ymin = ymin_aid;
8968  if (xmax < xmax_aid) xmax = xmax_aid;
8969  if (ymax < ymax_aid) ymax = ymax_aid;
8970  if (Hparam.ymin<0 && Hparam.ymax>0) {
8971  THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
8972  THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
8973  if (xmin >xmin_aid) xmin = xmin_aid;
8974  if (xmax <xmax_aid) xmax = xmax_aid;
8975  }
8976  if (Hparam.xmin<0 && Hparam.xmax>0) {
8977  THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
8978  THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
8979  if (ymin >ymin_aid) ymin = ymin_aid;
8980  if (ymax <ymax_aid) ymax = ymax_aid;
8981  }
8982  }
8983  Hparam.xmin= xmin;
8984  Hparam.xmax= xmax;
8985  Hparam.ymin= ymin;
8986  Hparam.ymax= ymax;
8987 
8988  Double_t dx = xmax-xmin;
8989  Double_t dy = ymax-ymin;
8990  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
8991  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
8992 
8993  // Range() could change the size of the pad pixmap and therefore should
8994  // be called before the other paint routines
8995  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
8996  ymin - dyr*gPad->GetBottomMargin(),
8997  xmax + dxr*gPad->GetRightMargin(),
8998  ymax + dyr*gPad->GetTopMargin());
8999  gPad->RangeAxis(xmin, ymin, xmax, ymax);
9000 }
9001 
9002 
9003 ////////////////////////////////////////////////////////////////////////////////
9004 /// Set current histogram to `h`
9005 
9007 {
9008 
9009  if (h == 0) return;
9010  fH = h;
9011  fXaxis = h->GetXaxis();
9013  fZaxis = h->GetZaxis();
9015 }
9016 
9017 
9018 ////////////////////////////////////////////////////////////////////////////////
9019 /// Initialize various options to draw 2D histograms.
9020 
9022 {
9023 
9024  static const char *where = "TableInit";
9025 
9026  Int_t first, last;
9028  Double_t zmin, zmax;
9029  Int_t maximum = 0;
9030  Int_t minimum = 0;
9031  if (fH->GetMaximumStored() != -1111) maximum = 1;
9032  if (fH->GetMinimumStored() != -1111) minimum = 1;
9033 
9034  // ----------------- Compute X axis parameters
9035  first = fXaxis->GetFirst();
9036  last = fXaxis->GetLast();
9037  Hparam.xlast = last;
9038  Hparam.xfirst = first;
9039  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
9040  Hparam.xbinsize = fXaxis->GetBinWidth(first);
9041  Hparam.xmin = Hparam.xlowedge;
9042  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
9043 
9044  // if log scale in X, replace xmin,max by the log
9045  if (Hoption.Logx) {
9046  // find the first edge of a bin that is > 0
9047  if (Hparam.xlowedge <=0 ) {
9048  Hparam.xlowedge = fXaxis->GetBinUpEdge(fXaxis->FindFixBin(0.01*Hparam.xbinsize));
9049  Hparam.xmin = Hparam.xlowedge;
9050  }
9051  if (Hparam.xmin <=0 || Hparam.xmax <=0) {
9052  Error(where, "cannot set X axis to log scale");
9053  return 0;
9054  }
9055  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
9056  if (Hparam.xfirst < first) Hparam.xfirst = first;
9057  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
9058  if (Hparam.xlast > last) Hparam.xlast = last;
9059  Hparam.xmin = TMath::Log10(Hparam.xmin);
9060  Hparam.xmax = TMath::Log10(Hparam.xmax);
9061  }
9062 
9063  // ----------------- Compute Y axis parameters
9064  first = fYaxis->GetFirst();
9065  last = fYaxis->GetLast();
9066  Hparam.ylast = last;
9067  Hparam.yfirst = first;
9068  Hparam.ylowedge = fYaxis->GetBinLowEdge(first);
9069  Hparam.ybinsize = fYaxis->GetBinWidth(first);
9070  if (!Hparam.ybinsize) Hparam.ybinsize = 1;
9071  Hparam.ymin = Hparam.ylowedge;
9072  Hparam.ymax = fYaxis->GetBinLowEdge(last)+fYaxis->GetBinWidth(last);
9073 
9074  // if log scale in Y, replace ymin,max by the log
9075  if (Hoption.Logy) {
9076  if (Hparam.ylowedge <=0 ) {
9077  Hparam.ylowedge = fYaxis->GetBinUpEdge(fYaxis->FindFixBin(0.01*Hparam.ybinsize));
9078  Hparam.ymin = Hparam.ylowedge;
9079  }
9080  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
9081  Error(where, "cannot set Y axis to log scale");
9082  return 0;
9083  }
9084  Hparam.yfirst= fYaxis->FindFixBin(Hparam.ymin);
9085  if (Hparam.yfirst < first) Hparam.yfirst = first;
9086  Hparam.ylast = fYaxis->FindFixBin(Hparam.ymax);
9087  if (Hparam.ylast > last) Hparam.ylast = last;
9088  Hparam.ymin = TMath::Log10(Hparam.ymin);
9089  Hparam.ymax = TMath::Log10(Hparam.ymax);
9090  }
9091 
9092 
9093  // ----------------- Compute Z axis parameters
9094  Double_t bigp = TMath::Power(10,32);
9095  zmax = -bigp;
9096  zmin = bigp;
9097  Double_t c1, e1;
9098  Double_t allchan = 0;
9099  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9100  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9101  c1 = fH->GetBinContent(i,j);
9102  zmax = TMath::Max(zmax,c1);
9103  if (Hoption.Error) {
9104  e1 = fH->GetBinError(i,j);
9105  zmax = TMath::Max(zmax,c1+e1);
9106  }
9107  zmin = TMath::Min(zmin,c1);
9108  allchan += c1;
9109  }
9110  }
9111 
9112  // Take into account maximum , minimum
9113 
9114  if (maximum) zmax = fH->GetMaximumStored();
9115  if (minimum) zmin = fH->GetMinimumStored();
9116  if (Hoption.Logz && zmax < 0) {
9117  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9118  return 0;
9119  } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
9120  zmin = 0.01;
9121  zmax = 10.;
9122  }
9123  if (zmin >= zmax) {
9124  if (Hoption.Logz) {
9125  if (zmax > 0) zmin = 0.001*zmax;
9126  else {
9127  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9128  return 0;
9129  }
9130  }
9131  }
9132 
9133  // take into account normalization factor
9134  Hparam.allchan = allchan;
9135  Double_t factor = allchan;
9136  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
9137  if (allchan) factor /= allchan;
9138  if (factor == 0) factor = 1;
9139  Hparam.factor = factor;
9140  zmax = factor*zmax;
9141  zmin = factor*zmin;
9142  c1 = zmax;
9143  if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
9144 
9145  // For log scales, histogram coordinates are log10(ymin) and
9146  // log10(ymax). Final adjustment (if not option "Same")
9147  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
9148  // Maximum and Minimum are not defined.
9149  if (Hoption.Logz) {
9150  if (zmin <= 0) {
9151  zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9152  fH->SetMinimum(zmin);
9153  }
9154  zmin = TMath::Log10(zmin);
9155  if (!minimum) zmin += TMath::Log10(0.5);
9156  zmax = TMath::Log10(zmax);
9157  if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
9158  goto LZMIN;
9159  }
9160 
9161  // final adjustment of YMAXI for linear scale (if not option "Same"):
9162  // decrease histogram height to MAX% of allowed height if HMAXIM
9163  // has not been called.
9164  // MAX% is the value in percent which has been set in HPLSET
9165  // (default is 90%).
9166  if (!maximum) {
9167  zmax += yMARGIN*(zmax-zmin);
9168  }
9169 
9170  // final adjustment of ymin for linear scale.
9171  // if minimum is not set , then ymin is set to zero if >0
9172  // or to ymin - yMARGIN if <0.
9173  if (!minimum) {
9174  if (gStyle->GetHistMinimumZero()) {
9175  if (zmin >= 0) zmin = 0;
9176  else zmin -= yMARGIN*(zmax-zmin);
9177  } else {
9178  Double_t dzmin = yMARGIN*(zmax-zmin);
9179  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
9180  else zmin -= dzmin;
9181  }
9182  }
9183 
9184 LZMIN:
9185  Hparam.zmin = zmin;
9186  Hparam.zmax = zmax;
9187 
9188  // Set bar offset and width
9189  Hparam.baroffset = fH->GetBarOffset();
9190  Hparam.barwidth = fH->GetBarWidth();
9191 
9192  return 1;
9193 }
9194 
9195 
9196 ////////////////////////////////////////////////////////////////////////////////
9197 /// This function returns the best format to print the error value (e)
9198 /// knowing the parameter value (v) and the format (f) used to print it.
9199 
9200 const char * THistPainter::GetBestFormat(Double_t v, Double_t e, const char *f)
9201 {
9202 
9203  static char ef[20];
9204  char tf[20], tv[64];
9205 
9206  // print v with the format f in tv.
9207  snprintf(tf,20,"%s%s","%",f);
9208  snprintf(tv,64,tf,v);
9209 
9210  // Analyse tv.
9211  TString sv = tv;
9212  int ie = sv.Index("e");
9213  int iE = sv.Index("E");
9214  int id = sv.Index(".");
9215 
9216  // v has been printed with the exponent notation.
9217  // There is 2 cases, the exponent is positive or negative
9218  if (ie >= 0 || iE >= 0) {
9219  if (sv.Index("+") >= 0) {
9220  if (e < 1) {
9221  snprintf(ef,20,"%s.1f","%");
9222  } else {
9223  if (ie >= 0) {
9224  snprintf(ef,20,"%s.%de","%",ie-id-1);
9225  } else {
9226  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9227  }
9228  }
9229  } else {
9230  if (ie >= 0) {
9231  snprintf(ef,20,"%s.%de","%",ie-id-1);
9232  } else {
9233  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9234  }
9235  }
9236 
9237  // There is not '.' in tv. e will be printed with one decimal digit.
9238  } else if (id < 0) {
9239  snprintf(ef,20,"%s.1f","%");
9240 
9241  // There is a '.' in tv and no exponent notation. e's decimal part will
9242  // have the same number of digits as v's one.
9243  } else {
9244  snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
9245  }
9246 
9247  return ef;
9248 }
9249 
9250 
9251 ////////////////////////////////////////////////////////////////////////////////
9252 /// Set projection.
9253 
9254 void THistPainter::SetShowProjection(const char *option,Int_t nbins)
9255 {
9256 
9257  if (fShowProjection) return;
9258  TString opt = option;
9259  opt.ToLower();
9260  Int_t projection = 0;
9261  if (opt.Contains("x")) projection = 1;
9262  if (opt.Contains("y")) projection = 2;
9263  if (opt.Contains("z")) projection = 3;
9264  if (opt.Contains("xy")) projection = 4;
9265  if (opt.Contains("yx")) projection = 5;
9266  if (opt.Contains("xz")) projection = 6;
9267  if (opt.Contains("zx")) projection = 7;
9268  if (opt.Contains("yz")) projection = 8;
9269  if (opt.Contains("zy")) projection = 9;
9270  if (projection < 4) fShowOption = option+1;
9271  else fShowOption = option+2;
9272  fShowProjection = projection+100*nbins;
9273  gROOT->MakeDefCanvas();
9274  gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
9275  gPad->SetGrid();
9276 }
9277 
9278 
9279 ////////////////////////////////////////////////////////////////////////////////
9280 /// Show projection onto X.
9281 
9282 void THistPainter::ShowProjectionX(Int_t /*px*/, Int_t py)
9283 {
9284 
9285  Int_t nbins = (Int_t)fShowProjection/100;
9286  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9287  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9289  // Erase old position and draw a line at current position
9290  static int pyold1 = 0;
9291  static int pyold2 = 0;
9292  float uxmin = gPad->GetUxmin();
9293  float uxmax = gPad->GetUxmax();
9294  int pxmin = gPad->XtoAbsPixel(uxmin);
9295  int pxmax = gPad->XtoAbsPixel(uxmax);
9296  Float_t upy = gPad->AbsPixeltoY(py);
9297  Float_t y = gPad->PadtoY(upy);
9298  Int_t biny1 = fH->GetYaxis()->FindBin(y);
9299  Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
9300  Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
9301  Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
9302 
9303  if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
9304  gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
9305  pyold1 = py1;
9306  pyold2 = py2;
9307 
9308  // Create or set the new canvas proj x
9309  TVirtualPad *padsav = gPad;
9310  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9311  (ULong_t)fH, fShowProjection));
9312  if (c) {
9313  c->Clear();
9314  } else {
9315  fShowProjection = 0;
9316  pyold1 = 0;
9317  pyold2 = 0;
9318  return;
9319  }
9320  c->cd();
9321  c->SetLogy(padsav->GetLogz());
9322  c->SetLogx(padsav->GetLogx());
9323 
9324  // Draw slice corresponding to mouse position
9325  TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
9326  TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
9327  if (hp) {
9328  hp->SetFillColor(38);
9329  // apply a patch from Oliver Freyermuth to set the title in the projection using the range of the projected Y values
9330  if (biny1 == biny2) {
9331  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9332  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
9333  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9334  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9335  if (fH->GetYaxis()->GetLabels() != NULL) {
9336  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
9337  } else {
9338  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
9339  }
9340  } else {
9341  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9342  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
9343  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9344  // biny1 is used here to get equal precision no matter how large the binrange is,
9345  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9346  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
9347  if (fH->GetYaxis()->GetLabels() != NULL) {
9348  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)));
9349  } else {
9350  hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
9351  }
9352  }
9353  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9354  hp->SetYTitle("Number of Entries");
9355  hp->Draw();
9356  c->Update();
9357  padsav->cd();
9358  }
9359 }
9360 
9361 
9362 ////////////////////////////////////////////////////////////////////////////////
9363 /// Show projection onto Y.
9364 
9365 void THistPainter::ShowProjectionY(Int_t px, Int_t /*py*/)
9366 {
9367 
9368  Int_t nbins = (Int_t)fShowProjection/100;
9369  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9370  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9372  // Erase old position and draw a line at current position
9373  static int pxold1 = 0;
9374  static int pxold2 = 0;
9375  float uymin = gPad->GetUymin();
9376  float uymax = gPad->GetUymax();
9377  int pymin = gPad->YtoAbsPixel(uymin);
9378  int pymax = gPad->YtoAbsPixel(uymax);
9379  Float_t upx = gPad->AbsPixeltoX(px);
9380  Float_t x = gPad->PadtoX(upx);
9381  Int_t binx1 = fH->GetXaxis()->FindBin(x);
9382  Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
9383  Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
9384  Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
9385 
9386  if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
9387  gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
9388  pxold1 = px1;
9389  pxold2 = px2;
9390 
9391  // Create or set the new canvas proj y
9392  TVirtualPad *padsav = gPad;
9393  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9394  (ULong_t)fH, fShowProjection));
9395  if (c) {
9396  c->Clear();
9397  } else {
9398  fShowProjection = 0;
9399  pxold1 = 0;
9400  pxold2 = 0;
9401  return;
9402  }
9403  c->cd();
9404  c->SetLogy(padsav->GetLogz());
9405  c->SetLogx(padsav->GetLogy());
9406 
9407  // Draw slice corresponding to mouse position
9408  TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
9409  TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
9410  if (hp) {
9411  hp->SetFillColor(38);
9412  // apply a patch from Oliver Freyermuth to set the title in the projection using the range of the projected X values
9413  if (binx1 == binx2) {
9414  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9415  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
9416  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9417  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9418  if (fH->GetXaxis()->GetLabels() != NULL) {
9419  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
9420  } else {
9421  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
9422  }
9423  } else {
9424  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9425  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
9426  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9427  // binx1 is used here to get equal precision no matter how large the binrange is,
9428  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9429  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
9430  if (fH->GetXaxis()->GetLabels() != NULL) {
9431  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)));
9432  } else {
9433  hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
9434  }
9435  }
9436  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9437  hp->SetYTitle("Number of Entries");
9438  hp->Draw();
9439  c->Update();
9440  padsav->cd();
9441  }
9442 }
9443 
9444 
9445 ////////////////////////////////////////////////////////////////////////////////
9446 /// Show projection (specified by `fShowProjection`) of a `TH3`.
9447 /// The drawing option for the projection is in `fShowOption`.
9448 ///
9449 /// First implementation; R.Brun
9450 ///
9451 /// Full implementation: Tim Tran (timtran@jlab.org) April 2006
9452 
9454 {
9455 
9456  Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
9457  if (fH->GetDimension() < 3) {
9458  if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
9459  if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
9460  }
9461 
9462  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9463  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9464 
9465  // Erase old position and draw a line at current position
9466  TView *view = gPad->GetView();
9467  if (!view) return;
9468  TH3 *h3 = (TH3*)fH;
9469  TAxis *xaxis = h3->GetXaxis();
9470  TAxis *yaxis = h3->GetYaxis();
9471  TAxis *zaxis = h3->GetZaxis();
9472  Double_t u[3],xx[3];
9473 
9474  static TPoint line1[2];//store end points of a line, initialised 0 by default
9475  static TPoint line2[2];// second line when slice thickness > 1 bin thickness
9476  static TPoint line3[2];
9477  static TPoint line4[2];
9478  static TPoint endface1[5];
9479  static TPoint endface2[5];
9480  static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
9481  static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
9482 
9483  Double_t uxmin = gPad->GetUxmin();
9484  Double_t uxmax = gPad->GetUxmax();
9485  Double_t uymin = gPad->GetUymin();
9486  Double_t uymax = gPad->GetUymax();
9487 
9488  int pxmin = gPad->XtoAbsPixel(uxmin);
9489  int pxmax = gPad->XtoAbsPixel(uxmax);
9490  if (pxmin==pxmax) return;
9491  int pymin = gPad->YtoAbsPixel(uymin);
9492  int pymax = gPad->YtoAbsPixel(uymax);
9493  if (pymin==pymax) return;
9494  Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
9495  Double_t cy = (pymax-pymin)/(uymax-uymin);
9496  TVirtualPad *padsav = gPad;
9497  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9498  (ULong_t)fH, fShowProjection));
9499  if (!c) {
9500  fShowProjection = 0;
9501  return;
9502  }
9503 
9504  switch ((Int_t)fShowProjection%100) {
9505  case 1:
9506  // "x"
9507  {
9508  Int_t firstY = yaxis->GetFirst();
9509  Int_t lastY = yaxis->GetLast();
9510  Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
9511  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9512  yaxis->SetRange(biny,biny2);
9513  Int_t firstZ = zaxis->GetFirst();
9514  Int_t lastZ = zaxis->GetLast();
9515  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
9516  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9517  zaxis->SetRange(binz,binz2);
9518  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9519  if (nbins>1 && line1[0].GetX()) {
9520  gVirtualX->DrawPolyLine(2,line2);
9521  gVirtualX->DrawPolyLine(2,line3);
9522  gVirtualX->DrawPolyLine(2,line4);
9523  gVirtualX->DrawPolyLine(5,endface1);
9524  gVirtualX->DrawPolyLine(5,endface2);
9525  }
9526  xx[0] = xaxis->GetXmin();
9527  xx[2] = zaxis->GetBinCenter(binz);
9528  xx[1] = yaxis->GetBinCenter(biny);
9529  view->WCtoNDC(xx,u);
9530  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9531  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9532  xx[0] = xaxis->GetXmax();
9533  view->WCtoNDC(xx,u);
9534  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9535  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9536  gVirtualX->DrawPolyLine(2,line1);
9537  if (nbins>1) {
9538  xx[0] = xaxis->GetXmin();
9539  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9540  xx[1] = yaxis->GetBinCenter(biny);
9541  view->WCtoNDC(xx,u);
9542  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9543  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9544  xx[0] = xaxis->GetXmax();
9545  view->WCtoNDC(xx,u);
9546  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9547  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9548 
9549  xx[0] = xaxis->GetXmin();
9550  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9551  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9552  view->WCtoNDC(xx,u);
9553  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9554  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9555  xx[0] = xaxis->GetXmax();
9556  view->WCtoNDC(xx,u);
9557  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9558  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9559 
9560  xx[0] = xaxis->GetXmin();
9561  xx[2] = zaxis->GetBinCenter(binz);
9562  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9563  view->WCtoNDC(xx,u);
9564  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9565  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9566  xx[0] = xaxis->GetXmax();
9567  view->WCtoNDC(xx,u);
9568  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9569  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9570 
9571  endface1[0].SetX(line1[0].GetX());
9572  endface1[0].SetY(line1[0].GetY());
9573  endface1[1].SetX(line2[0].GetX());
9574  endface1[1].SetY(line2[0].GetY());
9575  endface1[2].SetX(line3[0].GetX());
9576  endface1[2].SetY(line3[0].GetY());
9577  endface1[3].SetX(line4[0].GetX());
9578  endface1[3].SetY(line4[0].GetY());
9579  endface1[4].SetX(line1[0].GetX());
9580  endface1[4].SetY(line1[0].GetY());
9581 
9582  endface2[0].SetX(line1[1].GetX());
9583  endface2[0].SetY(line1[1].GetY());
9584  endface2[1].SetX(line2[1].GetX());
9585  endface2[1].SetY(line2[1].GetY());
9586  endface2[2].SetX(line3[1].GetX());
9587  endface2[2].SetY(line3[1].GetY());
9588  endface2[3].SetX(line4[1].GetX());
9589  endface2[3].SetY(line4[1].GetY());
9590  endface2[4].SetX(line1[1].GetX());
9591  endface2[4].SetY(line1[1].GetY());
9592 
9593  gVirtualX->DrawPolyLine(2,line2);
9594  gVirtualX->DrawPolyLine(2,line3);
9595  gVirtualX->DrawPolyLine(2,line4);
9596  gVirtualX->DrawPolyLine(5,endface1);
9597  gVirtualX->DrawPolyLine(5,endface2);
9598  }
9599  c->Clear();
9600  c->cd();
9601  TH1 *hp = h3->Project3D("x");
9602  yaxis->SetRange(firstY,lastY);
9603  zaxis->SetRange(firstZ,lastZ);
9604  if (hp) {
9605  hp->SetFillColor(38);
9606  if (nbins == 1)
9607  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
9608  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
9609  else {
9610  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),
9611  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
9612  }
9613  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9614  hp->SetYTitle("Number of Entries");
9615  hp->Draw(fShowOption.Data());
9616  }
9617  }
9618  break;
9619 
9620  case 2:
9621  // "y"
9622  {
9623  Int_t firstX = xaxis->GetFirst();
9624  Int_t lastX = xaxis->GetLast();
9625  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
9626  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
9627  xaxis->SetRange(binx,binx2);
9628  Int_t firstZ = zaxis->GetFirst();
9629  Int_t lastZ = zaxis->GetLast();
9630  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
9631  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9632  zaxis->SetRange(binz,binz2);
9633  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9634  if (nbins>1 && line1[0].GetX()) {
9635  gVirtualX->DrawPolyLine(2,line2);
9636  gVirtualX->DrawPolyLine(2,line3);
9637  gVirtualX->DrawPolyLine(2,line4);
9638  gVirtualX->DrawPolyLine(5,endface1);
9639  gVirtualX->DrawPolyLine(5,endface2);
9640  }
9641  xx[0]=xaxis->GetBinCenter(binx);
9642  xx[2] = zaxis->GetBinCenter(binz);
9643  xx[1] = yaxis->GetXmin();
9644  view->WCtoNDC(xx,u);
9645  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9646  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9647  xx[1] = yaxis->GetXmax();
9648  view->WCtoNDC(xx,u);
9649  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9650  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9651  gVirtualX->DrawPolyLine(2,line1);
9652  if (nbins>1) {
9653  xx[1] = yaxis->GetXmin();
9654  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9655  xx[0] = xaxis->GetBinCenter(binx);
9656  view->WCtoNDC(xx,u);
9657  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9658  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9659  xx[1] = yaxis->GetXmax();
9660  view->WCtoNDC(xx,u);
9661  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9662  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9663 
9664  xx[1] = yaxis->GetXmin();
9665  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9666  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9667  view->WCtoNDC(xx,u);
9668  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9669  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9670  xx[1] = yaxis->GetXmax();
9671  view->WCtoNDC(xx,u);
9672  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9673  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9674 
9675  xx[1] = yaxis->GetXmin();
9676  xx[2] = zaxis->GetBinCenter(binz);
9677  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9678  view->WCtoNDC(xx,u);
9679  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9680  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9681  xx[1] = yaxis->GetXmax();
9682  view->WCtoNDC(xx,u);
9683  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9684  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9685 
9686  endface1[0].SetX(line1[0].GetX());
9687  endface1[0].SetY(line1[0].GetY());
9688  endface1[1].SetX(line2[0].GetX());
9689  endface1[1].SetY(line2[0].GetY());
9690  endface1[2].SetX(line3[0].GetX());
9691  endface1[2].SetY(line3[0].GetY());
9692  endface1[3].SetX(line4[0].GetX());
9693  endface1[3].SetY(line4[0].GetY());
9694  endface1[4].SetX(line1[0].GetX());
9695  endface1[4].SetY(line1[0].GetY());
9696 
9697  endface2[0].SetX(line1[1].GetX());
9698  endface2[0].SetY(line1[1].GetY());
9699  endface2[1].SetX(line2[1].GetX());
9700  endface2[1].SetY(line2[1].GetY());
9701  endface2[2].SetX(line3[1].GetX());
9702  endface2[2].SetY(line3[1].GetY());
9703  endface2[3].SetX(line4[1].GetX());
9704  endface2[3].SetY(line4[1].GetY());
9705  endface2[4].SetX(line1[1].GetX());
9706  endface2[4].SetY(line1[1].GetY());
9707 
9708  gVirtualX->DrawPolyLine(2,line2);
9709  gVirtualX->DrawPolyLine(2,line3);
9710  gVirtualX->DrawPolyLine(2,line4);
9711  gVirtualX->DrawPolyLine(5,endface1);
9712  gVirtualX->DrawPolyLine(5,endface2);
9713  }
9714  c->Clear();
9715  c->cd();
9716  TH1 *hp = h3->Project3D("y");
9717  xaxis->SetRange(firstX,lastX);
9718  zaxis->SetRange(firstZ,lastZ);
9719  if (hp) {
9720  hp->SetFillColor(38);
9721  if (nbins == 1)
9722  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
9723  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
9724  else
9725  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),
9726  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
9727  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9728  hp->SetYTitle("Number of Entries");
9729  hp->Draw(fShowOption.Data());
9730  }
9731  }
9732  break;
9733 
9734  case 3:
9735  // "z"
9736  {
9737  Int_t firstX = xaxis->GetFirst();
9738  Int_t lastX = xaxis->GetLast();
9739  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
9740  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
9741  xaxis->SetRange(binx,binx2);
9742  Int_t firstY = yaxis->GetFirst();
9743  Int_t lastY = yaxis->GetLast();
9744  Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
9745  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9746  yaxis->SetRange(biny,biny2);
9747  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9748  if (nbins>1 && line1[0].GetX()) {
9749  gVirtualX->DrawPolyLine(2,line2);
9750  gVirtualX->DrawPolyLine(2,line3);
9751  gVirtualX->DrawPolyLine(2,line4);
9752  gVirtualX->DrawPolyLine(5,endface1);
9753  gVirtualX->DrawPolyLine(5,endface2);
9754  }
9755  xx[0] = xaxis->GetBinCenter(binx);
9756  xx[1] = yaxis->GetBinCenter(biny);
9757  xx[2] = zaxis->GetXmin();
9758  view->WCtoNDC(xx,u);
9759  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9760  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9761  xx[2] = zaxis->GetXmax();
9762  view->WCtoNDC(xx,u);
9763  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9764  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9765  gVirtualX->DrawPolyLine(2,line1);
9766  if (nbins>1) {
9767  xx[2] = zaxis->GetXmin();
9768  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9769  xx[0] = xaxis->GetBinCenter(binx);
9770  view->WCtoNDC(xx,u);
9771  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9772  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9773  xx[2] = zaxis->GetXmax();
9774  view->WCtoNDC(xx,u);
9775  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9776  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9777 
9778  xx[2] = zaxis->GetXmin();
9779  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9780  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9781  view->WCtoNDC(xx,u);
9782  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9783  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9784  xx[2] = zaxis->GetXmax();
9785  view->WCtoNDC(xx,u);
9786  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9787  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9788 
9789  xx[2] = zaxis->GetXmin();
9790  xx[1] = yaxis->GetBinCenter(biny);
9791  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9792  view->WCtoNDC(xx,u);
9793  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9794  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9795  xx[2] = zaxis->GetXmax();
9796  view->WCtoNDC(xx,u);
9797  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9798  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9799 
9800  endface1[0].SetX(line1[0].GetX());
9801  endface1[0].SetY(line1[0].GetY());
9802  endface1[1].SetX(line2[0].GetX());
9803  endface1[1].SetY(line2[0].GetY());
9804  endface1[2].SetX(line3[0].GetX());
9805  endface1[2].SetY(line3[0].GetY());
9806  endface1[3].SetX(line4[0].GetX());
9807  endface1[3].SetY(line4[0].GetY());
9808  endface1[4].SetX(line1[0].GetX());
9809  endface1[4].SetY(line1[0].GetY());
9810 
9811  endface2[0].SetX(line1[1].GetX());
9812  endface2[0].SetY(line1[1].GetY());
9813  endface2[1].SetX(line2[1].GetX());
9814  endface2[1].SetY(line2[1].GetY());
9815  endface2[2].SetX(line3[1].GetX());
9816  endface2[2].SetY(line3[1].GetY());
9817  endface2[3].SetX(line4[1].GetX());
9818  endface2[3].SetY(line4[1].GetY());
9819  endface2[4].SetX(line1[1].GetX());
9820  endface2[4].SetY(line1[1].GetY());
9821 
9822  gVirtualX->DrawPolyLine(2,line2);
9823  gVirtualX->DrawPolyLine(2,line3);
9824  gVirtualX->DrawPolyLine(2,line4);
9825  gVirtualX->DrawPolyLine(5,endface1);
9826  gVirtualX->DrawPolyLine(5,endface2);
9827  }
9828  c->Clear();
9829  c->cd();
9830  TH1 *hp = h3->Project3D("z");
9831  xaxis->SetRange(firstX,lastX);
9832  yaxis->SetRange(firstY,lastY);
9833  if (hp) {
9834  hp->SetFillColor(38);
9835  if (nbins == 1)
9836  hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
9837  biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
9838  else
9839  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),
9840  biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
9841  hp->SetXTitle(fH->GetZaxis()->GetTitle());
9842  hp->SetYTitle("Number of Entries");
9843  hp->Draw(fShowOption.Data());
9844  }
9845  }
9846  break;
9847 
9848  case 4:
9849  // "xy"
9850  {
9851  Int_t first = zaxis->GetFirst();
9852  Int_t last = zaxis->GetLast();
9853  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9854  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9855  zaxis->SetRange(binz,binz2);
9856  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9857  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9858  xx[0] = xaxis->GetXmin();
9859  xx[1] = yaxis->GetXmax();
9860  xx[2] = zaxis->GetBinCenter(binz);
9861  view->WCtoNDC(xx,u);
9862  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9863  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9864  rect1[4].SetX(rect1[0].GetX());
9865  rect1[4].SetY(rect1[0].GetY());
9866  xx[0] = xaxis->GetXmax();
9867  view->WCtoNDC(xx,u);
9868  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9869  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9870  xx[1] = yaxis->GetXmin();
9871  view->WCtoNDC(xx,u);
9872  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9873  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9874  xx[0] = xaxis->GetXmin();
9875  view->WCtoNDC(xx,u);
9876  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9877  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9878  gVirtualX->DrawPolyLine(5,rect1);
9879  if (nbins>1) {
9880  xx[0] = xaxis->GetXmin();
9881  xx[1] = yaxis->GetXmax();
9882  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9883  view->WCtoNDC(xx,u);
9884  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9885  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9886  rect2[4].SetX(rect2[0].GetX());
9887  rect2[4].SetY(rect2[0].GetY());
9888  xx[0] = xaxis->GetXmax();
9889  view->WCtoNDC(xx,u);
9890  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9891  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9892  xx[1] = yaxis->GetXmin();
9893  view->WCtoNDC(xx,u);
9894  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9895  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9896  xx[0] = xaxis->GetXmin();
9897  view->WCtoNDC(xx,u);
9898  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9899  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9900  gVirtualX->DrawPolyLine(5,rect2);
9901  }
9902 
9903  c->Clear();
9904  c->cd();
9905  TH2 *hp = (TH2*)h3->Project3D("xy");
9906  zaxis->SetRange(first,last);
9907  if (hp) {
9908  hp->SetFillColor(38);
9909  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
9910  else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
9911  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9912  hp->SetYTitle(fH->GetXaxis()->GetTitle());
9913  hp->SetZTitle("Number of Entries");
9914  hp->Draw(fShowOption.Data());
9915  }
9916  }
9917  break;
9918 
9919  case 5:
9920  // "yx"
9921  {
9922  Int_t first = zaxis->GetFirst();
9923  Int_t last = zaxis->GetLast();
9924  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9925  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9926  zaxis->SetRange(binz,binz2);
9927  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9928  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9929  xx[0] = xaxis->GetXmin();
9930  xx[1] = yaxis->GetXmax();
9931  xx[2] = zaxis->GetBinCenter(binz);
9932  view->WCtoNDC(xx,u);
9933  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9934  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9935  rect1[4].SetX(rect1[0].GetX());
9936  rect1[4].SetY(rect1[0].GetY());
9937  xx[0] = xaxis->GetXmax();
9938  view->WCtoNDC(xx,u);
9939  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9940  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9941  xx[1] = yaxis->GetXmin();
9942  view->WCtoNDC(xx,u);
9943  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9944  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9945  xx[0] = xaxis->GetXmin();
9946  view->WCtoNDC(xx,u);
9947  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9948  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9949  gVirtualX->DrawPolyLine(5,rect1);
9950  if (nbins>1) {
9951  xx[0] = xaxis->GetXmin();
9952  xx[1] = yaxis->GetXmax();
9953  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9954  view->WCtoNDC(xx,u);
9955  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9956  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9957  rect2[4].SetX(rect2[0].GetX());
9958  rect2[4].SetY(rect2[0].GetY());
9959  xx[0] = xaxis->GetXmax();
9960  view->WCtoNDC(xx,u);
9961  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9962  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9963  xx[1] = yaxis->GetXmin();
9964  view->WCtoNDC(xx,u);
9965  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9966  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9967  xx[0] = xaxis->GetXmin();
9968  view->WCtoNDC(xx,u);
9969  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9970  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9971  gVirtualX->DrawPolyLine(5,rect2);
9972  }
9973  c->Clear();
9974  c->cd();
9975  TH2 *hp = (TH2*)h3->Project3D("yx");
9976  zaxis->SetRange(first,last);
9977  if (hp) {
9978  hp->SetFillColor(38);
9979  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
9980  else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
9981  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9982  hp->SetYTitle(fH->GetYaxis()->GetTitle());
9983  hp->SetZTitle("Number of Entries");
9984  hp->Draw(fShowOption.Data());
9985  }
9986  }
9987  break;
9988 
9989  case 6:
9990  // "xz"
9991  {
9992  Int_t first = yaxis->GetFirst();
9993  Int_t last = yaxis->GetLast();
9994  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9995  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9996  yaxis->SetRange(biny,biny2);
9997  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9998  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9999  xx[0] = xaxis->GetXmin();
10000  xx[2] = zaxis->GetXmax();
10001  xx[1] = yaxis->GetBinCenter(biny);
10002  view->WCtoNDC(xx,u);
10003  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10004  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10005  rect1[4].SetX(rect1[0].GetX());
10006  rect1[4].SetY(rect1[0].GetY());
10007  xx[0] = xaxis->GetXmax();
10008  view->WCtoNDC(xx,u);
10009  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10010  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10011  xx[2] = zaxis->GetXmin();
10012  view->WCtoNDC(xx,u);
10013  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10014  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10015  xx[0] = xaxis->GetXmin();
10016  view->WCtoNDC(xx,u);
10017  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10018  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10019  gVirtualX->DrawPolyLine(5,rect1);
10020  if (nbins>1) {
10021  xx[0] = xaxis->GetXmin();
10022  xx[2] = zaxis->GetXmax();
10023  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10024  view->WCtoNDC(xx,u);
10025  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10026  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10027  rect2[4].SetX(rect2[0].GetX());
10028  rect2[4].SetY(rect2[0].GetY());
10029  xx[0] = xaxis->GetXmax();
10030  view->WCtoNDC(xx,u);
10031  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10032  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10033  xx[2] = zaxis->GetXmin();
10034  view->WCtoNDC(xx,u);
10035  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10036  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10037  xx[0] = xaxis->GetXmin();
10038  view->WCtoNDC(xx,u);
10039  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10040  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10041  gVirtualX->DrawPolyLine(5,rect2);
10042  }
10043  c->Clear();
10044  c->cd();
10045  TH2 *hp = (TH2*)h3->Project3D("xz");
10046  yaxis->SetRange(first,last);
10047  if (hp) {
10048  hp->SetFillColor(38);
10049  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10050  else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10051  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10052  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10053  hp->SetZTitle("Number of Entries");
10054  hp->Draw(fShowOption.Data());
10055  }
10056  }
10057  break;
10058 
10059  case 7:
10060  // "zx"
10061  {
10062  Int_t first = yaxis->GetFirst();
10063  Int_t last = yaxis->GetLast();
10064  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10065  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10066  yaxis->SetRange(biny,biny2);
10067  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10068  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10069  xx[0] = xaxis->GetXmin();
10070  xx[2] = zaxis->GetXmax();
10071  xx[1] = yaxis->GetBinCenter(biny);
10072  view->WCtoNDC(xx,u);
10073  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10074  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10075  rect1[4].SetX(rect1[0].GetX());
10076  rect1[4].SetY(rect1[0].GetY());
10077  xx[0] = xaxis->GetXmax();
10078  view->WCtoNDC(xx,u);
10079  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10080  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10081  xx[2] = zaxis->GetXmin();
10082  view->WCtoNDC(xx,u);
10083  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10084  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10085  xx[0] = xaxis->GetXmin();
10086  view->WCtoNDC(xx,u);
10087  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10088  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10089  gVirtualX->DrawPolyLine(5,rect1);
10090  if (nbins>1) {
10091  xx[0] = xaxis->GetXmin();
10092  xx[2] = zaxis->GetXmax();
10093  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10094  view->WCtoNDC(xx,u);
10095  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10096  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10097  rect2[4].SetX(rect2[0].GetX());
10098  rect2[4].SetY(rect2[0].GetY());
10099  xx[0] = xaxis->GetXmax();
10100  view->WCtoNDC(xx,u);
10101  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10102  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10103  xx[2] = zaxis->GetXmin();
10104  view->WCtoNDC(xx,u);
10105  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10106  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10107  xx[0] = xaxis->GetXmin();
10108  view->WCtoNDC(xx,u);
10109  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10110  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10111  gVirtualX->DrawPolyLine(5,rect2);
10112  }
10113  c->Clear();
10114  c->cd();
10115  TH2 *hp = (TH2*)h3->Project3D("zx");
10116  yaxis->SetRange(first,last);
10117  if (hp) {
10118  hp->SetFillColor(38);
10119  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10120  else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10121  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10122  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10123  hp->SetZTitle("Number of Entries");
10124  hp->Draw(fShowOption.Data());
10125  }
10126  }
10127  break;
10128 
10129  case 8:
10130  // "yz"
10131  {
10132  Int_t first = xaxis->GetFirst();
10133  Int_t last = xaxis->GetLast();
10134  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10135  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10136  xaxis->SetRange(binx,binx2);
10137  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10138  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10139  xx[2] = zaxis->GetXmin();
10140  xx[1] = yaxis->GetXmax();
10141  xx[0] = xaxis->GetBinCenter(binx);
10142  view->WCtoNDC(xx,u);
10143  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10144  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10145  rect1[4].SetX(rect1[0].GetX());
10146  rect1[4].SetY(rect1[0].GetY());
10147  xx[2] = zaxis->GetXmax();
10148  view->WCtoNDC(xx,u);
10149  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10150  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10151  xx[1] = yaxis->GetXmin();
10152  view->WCtoNDC(xx,u);
10153  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10154  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10155  xx[2] = zaxis->GetXmin();
10156  view->WCtoNDC(xx,u);
10157  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10158  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10159  gVirtualX->DrawPolyLine(5,rect1);
10160  if (nbins>1) {
10161  xx[2] = zaxis->GetXmin();
10162  xx[1] = yaxis->GetXmax();
10163  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10164  view->WCtoNDC(xx,u);
10165  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10166  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10167  rect2[4].SetX(rect2[0].GetX());
10168  rect2[4].SetY(rect2[0].GetY());
10169  xx[2] = zaxis->GetXmax();
10170  view->WCtoNDC(xx,u);
10171  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10172  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10173  xx[1] = yaxis->GetXmin();
10174  view->WCtoNDC(xx,u);
10175  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10176  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10177  xx[2] = zaxis->GetXmin();
10178  view->WCtoNDC(xx,u);
10179  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10180  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10181  gVirtualX->DrawPolyLine(5,rect2);
10182  }
10183  c->Clear();
10184  c->cd();
10185  TH2 *hp = (TH2*)h3->Project3D("yz");
10186  xaxis->SetRange(first,last);
10187  if (hp) {
10188  hp->SetFillColor(38);
10189  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10190  else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10191  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10192  hp->SetYTitle(fH->GetYaxis()->GetTitle());
10193  hp->SetZTitle("Number of Entries");
10194  hp->Draw(fShowOption.Data());
10195  }
10196  }
10197  break;
10198 
10199  case 9:
10200  // "zy"
10201  {
10202  Int_t first = xaxis->GetFirst();
10203  Int_t last = xaxis->GetLast();
10204  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10205  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10206  xaxis->SetRange(binx,binx2);
10207  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10208  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10209  xx[2] = zaxis->GetXmin();
10210  xx[1] = yaxis->GetXmax();
10211  xx[0] = xaxis->GetBinCenter(binx);
10212  view->WCtoNDC(xx,u);
10213  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10214  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10215  rect1[4].SetX(rect1[0].GetX());
10216  rect1[4].SetY(rect1[0].GetY());
10217  xx[2] = zaxis->GetXmax();
10218  view->WCtoNDC(xx,u);
10219  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10220  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10221  xx[1] = yaxis->GetXmin();
10222  view->WCtoNDC(xx,u);
10223  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10224  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10225  xx[2] = zaxis->GetXmin();
10226  view->WCtoNDC(xx,u);
10227  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10228  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10229  gVirtualX->DrawPolyLine(5,rect1);
10230  if (nbins>1) {
10231  xx[2] = zaxis->GetXmin();
10232  xx[1] = yaxis->GetXmax();
10233  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10234  view->WCtoNDC(xx,u);
10235  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10236  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10237  rect2[4].SetX(rect2[0].GetX());
10238  rect2[4].SetY(rect2[0].GetY());
10239  xx[2] = zaxis->GetXmax();
10240  view->WCtoNDC(xx,u);
10241  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10242  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10243  xx[1] = yaxis->GetXmin();
10244  view->WCtoNDC(xx,u);
10245  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10246  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10247  xx[2] = zaxis->GetXmin();
10248  view->WCtoNDC(xx,u);
10249  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10250  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10251  gVirtualX->DrawPolyLine(5,rect2);
10252  }
10253  c->Clear();
10254  c->cd();
10255  TH2 *hp = (TH2*)h3->Project3D("zy");
10256  xaxis->SetRange(first,last);
10257  if (hp) {
10258  hp->SetFillColor(38);
10259  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10260  else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10261  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10262  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10263  hp->SetZTitle("Number of Entries");
10264  hp->Draw(fShowOption.Data());
10265  }
10266  }
10267  break;
10268 
10269  }
10270  c->Update();
10271  padsav->cd();
10272 }
const int nx
Definition: kalman.C:16
Double_t * fYbuf
Definition: THistPainter.h:53
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:429
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:1925
virtual void SetZTitle(const char *title)
Definition: TH1.h:410
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Style_t GetLineStyle() const
Definition: TAttLine.h:48
virtual Style_t GetFillStyle() const
Definition: TAttFill.h:44
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Float_t GetEndErrorSize() const
Definition: TStyle.h:195
const Int_t kMAXCONTOUR
static TString gStringKurtosisX
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:6174
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8412
TList * GetListOfFunctions() const
Definition: TH1.h:244
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void PaintFrame()
Calculate range and clear pad (canvas).
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:332
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:30
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:84
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:404
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:521
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:211
Float_t GetTitleW() const
Definition: TStyle.h:290
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
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:717
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
THist< 2, double > TH2D
Definition: THist.h:320
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
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 Int_t GetLogz() const =0
virtual Font_t GetTextFont() const
Definition: TAttText.h:49
short Style_t
Definition: RtypesCore.h:76
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:797
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
const Int_t kMaxCuts
Definition: THistPainter.h:39
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
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:808
Double_t * GetX() const
Definition: TPolyLine.h:69
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:1916
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:45
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
Histogram option structure.
Definition: Hoption.h:24
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:71
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:245
float Float_t
Definition: RtypesCore.h:53
static TString gStringSkewnessX
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1602
THist< 2, float > TH2F
Definition: THist.h:321
static TString gStringSkewnessZ
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
const char Option_t
Definition: RtypesCore.h:62
virtual Double_t * GetRmax()=0
virtual void SetX2NDC(Double_t x2)
Definition: TPave.h:88
void SetIsoSurfaceParameters(Double_t fmin, Double_t fmax, Int_t ncolor, Int_t ic1, Int_t ic2, Int_t ic3)
TCanvas * c1
Definition: legend1.C:2
float ymin
Definition: THbookFile.cxx:93
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:57
Create a Box.
Definition: TBox.h:44
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
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:370
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:1808
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:59
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7863
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
virtual Int_t GetDimension() const
Definition: TH1.h:283
virtual void Update()=0
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:1771
#define mark(osub)
Definition: triangle.c:1206
virtual void PaintViolinPlot(Option_t *option)
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
Double_t GetX2() const
Definition: TBox.h:73
#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...
Color_t GetTitleFillColor() const
Definition: TStyle.h:279
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
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
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:130
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:4182
virtual Double_t Rndm(Int_t i=0)
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:58
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:92
See TView3D.
Definition: TView.h:36
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)
Double_t GetX1NDC() const
Definition: TPave.h:68
void SurfaceFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Service function for Surfaces.
Int_t GetNumberContours() const
Definition: TStyle.h:249
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition: Hoption.h:51
THist< 1, float > TH1F
Definition: THist.h:315
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:489
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
#define gROOT
Definition: TROOT.h:340
virtual void PaintTH2PolyBins(Option_t *option)
Control function to draw a TH2Poly bins' contours.
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2280
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:1818
void ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int_t &irep)
Set correspondance between function and color levels.
Float_t GetTitleX() const
Definition: TStyle.h:288
Basic string class.
Definition: TString.h:137
static Bool_t AddDirectoryStatus()
static function: cannot be inlined on Windows/NT
Definition: TH1.cxx:709
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:570
virtual Int_t PaintInit()
Compute histogram parameters used by the drawing routines.
virtual Double_t GetNormFactor() const
Definition: TH1.h:300
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:655
Float_t GetTitleFontSize() const
Definition: TStyle.h:282
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual void SetYTitle(const char *title)
Definition: TH1.h:409
bool Bool_t
Definition: RtypesCore.h:59
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:331
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
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1631
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:511
Int_t GetOptStat() const
Definition: TStyle.h:253
virtual void SetFillStyle(Style_t fstyle)
Definition: TAttFill.h:52
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
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:28
int nbins[3]
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7105
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
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:3113
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
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)
Double_t zmin
minimum value along Z
Definition: Hparam.h:39
TAxis * fYaxis
Definition: THistPainter.h:46
Double_t ymin
minimum value along y
Definition: Hparam.h:35
Profile Historam.
Definition: TProfile.h:34
virtual void SetX2(Double_t x2)
Definition: TBox.h:84
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
virtual Double_t GetEntries() const
return the current number of entries
Definition: TH1.cxx:4051
void InitMoveScreen(Double_t xmin, Double_t xmax)
Initialize "MOVING SCREEN" method.
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:1591
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:29
virtual Double_t GetXmin() const
Definition: TF1.h:388
void SetY(SCoord_t y)
Definition: TPoint.h:52
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:246
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
Double_t ymax
maximum value along y
Definition: Hparam.h:36
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
THist< 1, double > TH1D
Definition: THist.h:314
double cos(double)
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:2468
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:619
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:732
Width_t GetTitleBorderSize() const
Definition: TStyle.h:283
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:1231
Style_t GetStatFont() const
Definition: TStyle.h:268
static void SetF3(TF3 *f3)
Static function Store pointer to current implicit function.
virtual Double_t GetBinWidth(Int_t bin) const
return bin width for 1D historam Better to use h1.GetXaxis().GetBinWidth(bin)
Definition: TH1.cxx:8492
const char * Data() const
Definition: TString.h:349
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:869
void DefineGridLevels(Int_t ndivz)
Define the grid levels drawn in the background of surface and lego plots.
virtual Double_t GetSkewness(Int_t axis=1) const
For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
Definition: TH1.cxx:7118
virtual void SetTextFont(Font_t tfont=62)
Definition: TAttText.h:59
Int_t GetTitleAlign()
Definition: TStyle.h:278
virtual void PaintPalette()
Paint the color palette on the right side of the pad.
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:7787
virtual Double_t GetPsi()=0
virtual Double_t GetMaximumStored() const
Definition: TF1.h:347
Sequenceable collection abstract base class.
static const double x2[5]
Double_t GetYsize()
Return size of the formula along Y in pad coordinates.
Definition: TLatex.cxx:2568
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:29
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:1907
Double_t * GetY() const
Definition: TPolyLine.h:70
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)
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.
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8441
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:2334
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.
Double_t GetChisquare() const
Definition: TF1.h:336
TCutG * fCuts[kMaxCuts]
Definition: THistPainter.h:56
virtual Double_t GetBinLowEdge(Int_t bin) const
return bin lower edge for 1D historam Better to use h1.GetXaxis().GetBinLowEdge(bin) ...
Definition: TH1.cxx:8481
Float_t GetBarOffset() const
Definition: TStyle.h:192
void Class()
Definition: Class.C:29
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:392
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:399
Color_t GetTitleTextColor() const
Definition: TStyle.h:280
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 Double_t GetMaximumStored() const
Definition: TH1.h:289
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:312
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:273
const int ny
Definition: kalman.C:17
void SetMesh(Int_t mesh=1)
Width_t GetStatBorderSize() const
Definition: TStyle.h:267
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:33
virtual Int_t GetLogx() const =0
Double_t Log10(Double_t x)
Definition: TMath.h:529
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2272
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
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)
Definition: TAttMarker.h:51
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:4535
if(pyself &&pyself!=Py_None)
virtual Int_t MakeChopt(Option_t *option)
Decode string choptin and fill Hoption structure.
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:2513
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
Color_t GetStatColor() const
Definition: TStyle.h:265
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:796
virtual TSeqCollection * GetOutline()=0
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2307
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:42
virtual void PaintColorLevels(Option_t *option)
Double_t GetXMax()
Returns the maximum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1292
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:43
TAxis * fZaxis
Definition: THistPainter.h:47
virtual Bool_t IsInside(Int_t x, Int_t y)
Return kTRUE if the cell ix, iy is inside one of the graphical cuts.
virtual void Show()
Double_t GetYMin()
Returns the minimum value for the y coordinates of the bin.
Definition: TH2Poly.cxx:1400
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...
Float_t GetBarWidth() const
Definition: TStyle.h:193
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:2553
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:1364
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
Int_t xfirst
first bin number along X
Definition: Hparam.h:45
TH1F * h1
Definition: legend1.C:5
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2025
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
Double_t GetXmin() const
Definition: TAxis.h:137
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 Double_t GetXmax() const
Definition: TF1.h:389
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) ...
Int_t GetOptFit() const
Definition: TStyle.h:252
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:118
TList * fFunctions
Definition: THistPainter.h:48
short Color_t
Definition: RtypesCore.h:79
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
static TString gStringKurtosisZ
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
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:2169
Definition: TPoint.h:33
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1641
A doubly linked list.
Definition: TList.h:47
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 const char * GetTimeFormat() const
Definition: TAxis.h:131
Int_t GetOptTitle() const
Definition: TStyle.h:254
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:196
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:542
virtual void SetLogx(Int_t value=1)=0
void SetDrawFace(DrawFaceFunc_t pointer)
Store pointer to current algorithm to draw faces.
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
static TString gStringEntries
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:228
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:1776
Int_t fN
Definition: TArray.h:40
virtual void RecalculateRange()
Recompute the histogram range following graphics operations.
virtual TText * GetLine(Int_t number) const
Get Pointer to line number in this pavetext.
Definition: TPaveText.cxx:252
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:831
virtual Size_t GetMarkerSize() const
Definition: TAttMarker.h:46
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:705
Float_t GetStatY() const
Definition: TStyle.h:273
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.
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:7014
void FrontBox(Double_t ang)
Draw forward faces of surrounding box & axes.
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:114
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7378
virtual Int_t TableInit()
Initialize various options to draw 2D histograms.
ROOT::R::TRInterface & r
Definition: Object.C:4
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:2481
Class to manage histogram axis.
Definition: TAxis.h:36
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2878
Int_t fShowProjection
Definition: THistPainter.h:58
SVector< double, 2 > v
Definition: Dict.h:5
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:33
virtual Double_t GetMinimumStored() const
Definition: TH1.h:293
virtual void SetFillColor(Color_t fcolor)
Definition: TAttFill.h:50
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH3.cxx:1208
Int_t GetNbins() const
Definition: TAxis.h:125
A 3-Dim function with parameters.
Definition: TF3.h:30
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:499
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
void LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots spheric coordinates.
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:256
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
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:674
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
virtual void SetTextAngle(Float_t tangle=0)
Definition: TAttText.h:56
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:8543
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
void SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in cylindrical coordinates.
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:54
virtual void PaintStat3(Int_t dostat, TF1 *fit)
Draw the statistics box for 3D histograms.
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7045
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
const char * GetPaintTextFormat() const
Definition: TStyle.h:258
char * Form(const char *fmt,...)
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
const char * GetBinTitle(Int_t bin) const
Returns the bin title.
Definition: TH2Poly.cxx:756
TString fShowOption
Definition: THistPainter.h:59
virtual void Clear(Option_t *option="")=0
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7354
Double_t E()
Definition: TMath.h:54
Float_t GetStatW() const
Definition: TStyle.h:274
virtual Int_t GetNbinsZ() const
Definition: TH1.h:298
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:1666
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual Int_t GetSumw2N() const
Definition: TH1.h:314
The axis painter class.
Definition: TGaxis.h:39
virtual void SetMarkerStyle(Style_t mstyle=1)
Definition: TAttMarker.h:53
virtual Double_t GetKurtosis(Int_t axis=1) const
For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
Definition: TH1.cxx:7188
TAxis * GetYaxis()
Definition: TH1.h:320
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 void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:286
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
virtual TObjLink * FirstLink() const
Definition: TList.h:101
void SetName(const char *name)
Definition: TCollection.h:116
A 2-Dim function with parameters.
Definition: TF2.h:33
Option_t * GetName() const
Returns name of object.
Definition: TPave.h:65
TObject * GetPolygon() const
Definition: TH2Poly.h:42
Style_t GetTitleStyle() const
Definition: TStyle.h:281
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
virtual Color_t GetLineColor() const
Definition: TAttLine.h:47
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:613
Double_t GetContent() const
Definition: TH2Poly.h:39
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
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)
Definition: TAttMarker.h:54
Float_t GetErrorX() const
Definition: TStyle.h:196
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:46
virtual Double_t * GetRmin()=0
#define gVirtualX
Definition: TVirtualX.h:362
const Double_t * GetBuffer() const
Definition: TH1.h:239
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 Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1174
Double_t Cos(Double_t)
Definition: TMath.h:424
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:730
void SetLegoFunction(LegoFunc_t pointer)
Store pointer to current lego function.
short Width_t
Definition: RtypesCore.h:78
Hoption_t Hoption
The histogram painter class.
Definition: THistPainter.h:41
Double_t Pi()
Definition: TMath.h:44
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:55
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:3100
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
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:86
int Hist
"HIST" Draw only the histogram.
Definition: Hoption.h:45
long Long_t
Definition: RtypesCore.h:50
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Display the histogram info (bin number, contents, integral up to bin corresponding to cursor position...
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:563
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:117
virtual void PaintLegoAxis(TGaxis *axis, Double_t ang)
Draw the axis for legos and surface plots.
virtual Int_t GetSize() const
Definition: TCollection.h:95
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:35
static TString gStringSkewness
double f(double x)
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:62
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
Float_t GetStatFontSize() const
Definition: TStyle.h:269
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:50
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
void fill()
Definition: utils.cpp:314
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
Double_t * fXbuf
Definition: THistPainter.h:52
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
Double_t GetXmax() const
Definition: TAxis.h:138
Double_t y[n]
Definition: legend1.C:17
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:50
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its associated colors.
Definition: TColor.cxx:1605
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...
Double_t ey[n]
Definition: legend1.C:17
Style_t GetStatStyle() const
Definition: TStyle.h:270
The TH1 histogram class.
Definition: TH1.h:80
Int_t xlast
last bin number along X
Definition: Hparam.h:46
ClassImp(THistPainter) THistPainter
Default constructor.
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
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.
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:2881
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.
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Definition: TProfile2D.h:31
virtual void SetLineStyle(Style_t lstyle)
Definition: TAttLine.h:56
virtual void SetShowProjection(const char *option, Int_t nbins)
Set projection.
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
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
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:440
TAxis * GetZaxis()
Definition: TH1.h:321
TList * fStack
Definition: THistPainter.h:57
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:180
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:359
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
TH1 * gCurrentHist
void BackBox(Double_t ang)
Draw back surfaces of surrounding box.
Mother of all ROOT objects.
Definition: TObject.h:58
virtual TList * GetContourList(Double_t contour) const
Get a contour (as a list of TGraphs) using the Delaunay triangulation.
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Float_t GetStatX() const
Definition: TStyle.h:272
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:55
static Int_t ProjectSinusoidal2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
virtual Int_t GetNbinsY() const
Definition: TH1.h:297
static Int_t ProjectParabolic2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
Double_t PiOver2()
Definition: TMath.h:46
else
Definition: TBase64.cxx:55
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.
THashList * GetLabels() const
Definition: TAxis.h:122
virtual Color_t GetMarkerColor() const
Definition: TAttMarker.h:44
virtual void SetXTitle(const char *title)
Definition: TH1.h:408
Double_t GetHistTopMargin() const
Definition: TStyle.h:247
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:49
const char * GetFitFormat() const
Definition: TStyle.h:209
static TString gStringIntegral
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:390
virtual void Add(TObject *obj)
Definition: TList.h:81
Double_t xmin
minimum value along X
Definition: Hparam.h:31
Int_t GetOptStat() const
Return the stat option.
Definition: TPaveStats.cxx:266
static TString gStringStdDevX
double f2(const double *x)
static TString gStringKurtosisY
const UInt_t kCannotRotate
virtual void ShowProjection3(Int_t px, Int_t py)
Show projection (specified by fShowProjection) of a TH3.
Float_t GetTitleY() const
Definition: TStyle.h:289
Double_t GetY1() const
Definition: TBox.h:74
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
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:1262
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:1185
TF1 * f1
Definition: legend1.C:11
const Int_t kRAPIDITY
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:40
Int_t GetBinNumber() const
Definition: TH2Poly.h:41
#define gPad
Definition: TVirtualPad.h:288
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
Double_t GetX1() const
Definition: TBox.h:72
virtual void SetTextColor(Color_t tcolor=1)
Definition: TAttText.h:57
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:167
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1251
virtual void PaintScatterPlot(Option_t *option)
Control function to draw a 2D histogram as a scatter plot.
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
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:838
const TArrayD * GetXbins() const
Definition: TAxis.h:134
The TGraphDelaunay painting class.
Double_t allchan
integrated sum of contents
Definition: Hparam.h:42
void ResetBit(UInt_t f)
Definition: TObject.h:172
void SurfaceCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw surface in cartesian coordinate system.
virtual void SetTitle(const char *title)
Change (i.e.
Definition: TH1.cxx:6268
void SetSurfaceFunction(SurfaceFunc_t pointer)
Store pointer to current surface function.
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7067
Color_t GetStatTextColor() const
Definition: TStyle.h:266
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:55
Double_t GetY2() const
Definition: TBox.h:75
virtual void Paint(Option_t *option="")
Paint the palette.
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
int Same
"S" Histogram is plotted in the current PAD.
Definition: Hoption.h:36
static TString gStringStdDev
static TString gStringSkewnessY
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
int ncx
Definition: THbookFile.cxx:91
const Int_t kCARTESIAN
Histogram parameters structure.
Definition: Hparam.h:28
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8395
virtual Style_t GetMarkerStyle() const
Definition: TAttMarker.h:45
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
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:7921
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Width_t GetLineWidth() const
Definition: TAttLine.h:49
Float_t GetStatH() const
Definition: TStyle.h:275
Double_t GetXMin()
Returns the minimum value for the x coordinates of the bin.
Definition: TH2Poly.cxx:1328
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:58
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
The palette painting class.
Definition: TPaletteAxis.h:33
virtual Float_t GetBarWidth() const
Definition: TH1.h:257
float value
Definition: math.cpp:443
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:257
static TString gStringMeanY
Int_t Nint(T x)
Definition: TMath.h:480
virtual void PadRange(Int_t rback)=0
Double_t ex[n]
Definition: legend1.C:17
Hparam_t Hparam
const Int_t n
Definition: legend1.C:16
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.
virtual Int_t GetNpar() const
Definition: TF1.h:349
Double_t Tan(Double_t)
Definition: TMath.h:427
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:944
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:44
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:8006
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates ie: if the Pad is in log scale along Z ...
Definition: TH1.cxx:7818
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:82
virtual Float_t GetBarOffset() const
Definition: TH1.h:256
TAxis * GetXaxis()
Definition: TH1.h:319
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
TAxis * fXaxis
Definition: THistPainter.h:45
Float_t GetTitleH() const
Definition: TStyle.h:291
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:70
static TString gStringOverflow
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
void SetParent(TObject *obj)
Definition: TPaveStats.h:62
const char * GetStatFormat() const
Definition: TStyle.h:271
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
const Int_t kNMAX
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:54
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:297
Double_t ATan(Double_t)
Definition: TMath.h:451
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904