ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 Histpainter
70 \brief The histogram painter class. Implements all histograms' drawing's options.
71 
72 - [Introduction](#HP00)
73 - [Histograms' plotting options](#HP01)
74  - [Options supported for 1D and 2D histograms](#HP01a)
75  - [Options supported for 1D histograms](#HP01b)
76  - [Options supported for 2D histograms](#HP01c)
77  - [Options supported for 3D histograms](#HP01d)
78  - [Options supported for histograms' stacks (THStack)](#HP01e)
79 - [Setting the Style](#HP02)
80 - [Setting line, fill, marker, and text attributes](#HP03)
81 - [Setting Tick marks on the histogram axis](#HP04)
82 - [Giving titles to the X, Y and Z axis](#HP05)
83 - [The option "SAME"](#HP060)
84  - [Limitations](#HP060a)
85 - [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 
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` (hbars.C).
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 Begin_Macro(source)
750 ../../../tutorials/hist/hbars.C
751 End_Macro
752 
753 To control the bar width (default is the bin width) `TH1::SetBarWidth()`
754 should be used.
755 
756 To control the bar offset (default is 0) `TH1::SetBarOffset()` should
757 be used.
758 
759 These two parameters are useful when several histograms are plotted using
760 the option `SAME`. They allow to plot the histograms next to each other.
761 
762 
763 ### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
764 
765 
766 For each cell (i,j) a number of points proportional to the cell content is
767 drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
768 `kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
769 If option is of the form `scat=ff`, (eg `scat=1.8`,
770 `scat=1e-3`), then `ff` is used as a scale factor to compute the
771 number of dots. `scat=1` is the default.
772 
773 By default the scatter plot is painted with a "dot marker" which not scalable
774 (see the `TAttMarker` documentation). To change the marker size, a scalable marker
775 type should be used. For instance a circle (marker style 20).
776 
777 Begin_Macro(source)
778 {
779  TCanvas *c1 = new TCanvas("c1","c1",600,400);
780  TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
781  Float_t px, py;
782  for (Int_t i = 0; i < 25000; i++) {
783  gRandom->Rannor(px,py);
784  hscat->Fill(px,5*py);
785  hscat->Fill(3+0.5*px,2*py-10.);
786  }
787  hscat->Draw("scat=0.5");
788  return c1;
789 }
790 End_Macro
791 
792 
793 ### <a name="HP12"></a> The ARRow option
794 
795 
796 Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
797 The orientation of the arrow follows the cell gradient.
798 
799 Begin_Macro(source)
800 {
801  TCanvas *c1 = new TCanvas("c1","c1",600,400);
802  TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
803  Float_t px, py;
804  for (Int_t i = 0; i < 25000; i++) {
805  gRandom->Rannor(px,py);
806  harr->Fill(px,5*py);
807  harr->Fill(3+0.5*px,2*py-10.,0.1);
808  }
809  harr->Draw("ARR");
810  return c1;
811 }
812 End_Macro
813 
814 
815 ### <a name="HP13"></a> The BOX option
816 
817 
818 For each cell (i,j) a box is drawn. The size (surface) of the box is
819 proportional to the absolute value of the cell content.
820 The cells with a negative content draw with a `X` on top of the boxes.
821 
822 Begin_Macro(source)
823 {
824  TCanvas *c1 = new TCanvas("c1","c1",600,400);
825  hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
826  hbox->SetFillColor(42);
827  hbox->Fill(0.5, 0.5, 1.);
828  hbox->Fill(0.5, 1.5, 4.);
829  hbox->Fill(0.5, 2.5, 3.);
830  hbox->Fill(1.5, 0.5, 2.);
831  hbox->Fill(1.5, 1.5, 12.);
832  hbox->Fill(1.5, 2.5, -6.);
833  hbox->Fill(2.5, 0.5, -4.);
834  hbox->Fill(2.5, 1.5, 6.);
835  hbox->Fill(2.5, 2.5, 0.5);
836  hbox->Draw("BOX");
837  return c1;
838 }
839 End_Macro
840 
841 With option `BOX1` a button is drawn for each cell with surface
842 proportional to content's absolute value. A sunken button is drawn for
843 negative values a raised one for positive.
844 
845 Begin_Macro(source)
846 {
847  TCanvas *c1 = new TCanvas("c1","c1",600,400);
848  hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
849  hbox1->SetFillColor(42);
850  hbox1->Fill(0.5, 0.5, 1.);
851  hbox1->Fill(0.5, 1.5, 4.);
852  hbox1->Fill(0.5, 2.5, 3.);
853  hbox1->Fill(1.5, 0.5, 2.);
854  hbox1->Fill(1.5, 1.5, 12.);
855  hbox1->Fill(1.5, 2.5, -6.);
856  hbox1->Fill(2.5, 0.5, -4.);
857  hbox1->Fill(2.5, 1.5, 6.);
858  hbox1->Fill(2.5, 2.5, 0.5);
859  hbox1->Draw("BOX1");
860  return c1;
861 }
862 End_Macro
863 
864 When the option `SAME` (or "SAMES") is used with the option `BOX`,
865 the boxes' sizes are computing taking the previous plots into account. The range
866 along the Z axis is imposed by the first plot (the one without option
867 `SAME`); therefore the order in which the plots are done is relevant.
868 
869 Begin_Macro(source)
870 {
871  TCanvas *c1 = new TCanvas("c1","c1",600,400);
872  TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
873  TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
874  TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
875  TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
876  for (Int_t i=0;i<1000;i++) {
877  double x,y;
878  gRandom->Rannor(x,y);
879  if (x>0 && y>0) hb1->Fill(x,y,4);
880  if (x<0 && y<0) hb2->Fill(x,y,3);
881  if (x>0 && y<0) hb3->Fill(x,y,2);
882  if (x<0 && y>0) hb4->Fill(x,y,1);
883  }
884  hb1->SetFillColor(1);
885  hb2->SetFillColor(2);
886  hb3->SetFillColor(3);
887  hb4->SetFillColor(4);
888  hb1->Draw("box");
889  hb2->Draw("box same");
890  hb3->Draw("box same");
891  hb4->Draw("box same");
892  return c1;
893 }
894 End_Macro
895 
896 
897 ### <a name="HP14"></a> The COLor option
898 
899 
900 For each cell (i,j) a box is drawn with a color proportional to the cell
901 content.
902 
903 The color table used is defined in the current style.
904 
905 If the histogram's minimum and maximum are the same (flat histogram), the
906 mapping on colors is not possible, therefore nothing is painted. To paint a
907 flat histogram it is enough to set the histogram minimum
908 (`TH1::SetMinimum()`) different from the bins' content.
909 
910 The default number of color levels used to paint the cells is 20.
911 It can be changed with `TH1::SetContour()` or
912 `TStyle::SetNumberContours()`. The higher this number is, the smoother
913 is the color change between cells.
914 
915 The color palette in TStyle can be modified via `gStyle->SetPalette()`.
916 
917 All the none empty bins are painted. Empty bins are not painted unless
918 some bins have a negative content because in that case the null bins
919 might be not empty.
920 
921 `TProfile2D` histograms are handled differently because, for this type of 2D
922 histograms, it is possible to know if an empty bin has been filled or not. So even
923 if all the bins' contents are positive some empty bins might be painted. And vice versa,
924 if some bins have a negative content some empty bins might be not painted.
925 
926 Combined with the option `COL`, the option `Z` allows to
927 display the color palette defined by `gStyle->SetPalette()`.
928 
929 In the following example, the histogram has only positive bins; the empty
930 bins (containing 0) are not drawn.
931 
932 Begin_Macro(source)
933 {
934  TCanvas *c1 = new TCanvas("c1","c1",600,400);
935  TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
936  Float_t px, py;
937  for (Int_t i = 0; i < 25000; i++) {
938  gRandom->Rannor(px,py);
939  hcol1->Fill(px,5*py);
940  }
941  gStyle->SetPalette(kBird);
942  hcol1->Draw("COLZ");
943  return c1;
944 }
945 End_Macro
946 
947 In the first plot of following example, the histogram has some negative bins;
948 the empty bins (containing 0) are drawn. In some cases one wants to not draw
949 empty bins (containing 0) of histograms having a negative minimum. The option
950 `1`, used to produce the second plot in the following picture, allows to do that.
951 
952 Begin_Macro(source)
953 {
954  TCanvas *c1 = new TCanvas("c1","c1",600,600);
955  c1->Divide(1,2);
956  TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
957  TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
958  Float_t px, py;
959  for (Int_t i = 0; i < 25000; i++) {
960  gRandom->Rannor(px,py);
961  hcol23->Fill(px,5*py);
962  hcol24->Fill(px,5*py);
963  }
964  hcol23->Fill(0.,0.,-200.);
965  hcol24->Fill(0.,0.,-200.);
966  gStyle->SetPalette(kBird);
967  c1->cd(1); hcol23->Draw("COLZ");
968  c1->cd(2); hcol24->Draw("COLZ1");
969  return c1;
970 }
971 End_Macro
972 
973 When the maximum of the histogram is set to a smaller value than the real maximum,
974  the bins having a content between the new maximum and the real maximum are
975 painted with the color corresponding to the new maximum.
976 
977 When the minimum of the histogram is set to a greater value than the real minimum,
978  the bins having a value between the real minimum and the new minimum are not drawn
979  unless the option `0` is set.
980 
981 The following example illustrates the option `0` combined with the option `COL`.
982 
983 Begin_Macro(source)
984 {
985  TCanvas *c1 = new TCanvas("c1","c1",600,600);
986  c1->Divide(1,2);
987  TH2F *hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
988  TH2F *hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
989  Float_t px, py;
990  for (Int_t i = 0; i < 25000; i++) {
991  gRandom->Rannor(px,py);
992  hcol21->Fill(px,5*py);
993  hcol22->Fill(px,5*py);
994  }
995  hcol21->SetBit(TH1::kNoStats);
996  hcol22->SetBit(TH1::kNoStats);
997  gStyle->SetPalette(kBird);
998  c1->cd(1); hcol21->Draw("COLZ");
999  c1->cd(2); hcol22->Draw("COLZ0");
1000  hcol22->SetMaximum(100);
1001  hcol22->SetMinimum(40);
1002  return c1;
1003 }
1004 End_Macro
1005 
1006 The option `COL` can be combined with the option `POL`:
1007 
1008 Begin_Macro(source)
1009 {
1010  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1011  TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1012  Float_t px, py;
1013  for (Int_t i = 0; i < 25000; i++) {
1014  gRandom->Rannor(px,py);
1015  hcol1->Fill(px,py);
1016  }
1017  gStyle->SetPalette(kBird);
1018  hcol1->Draw("COLZPOL");
1019  return c1;
1020 }
1021 End_Macro
1022 
1023 ### <a name="HP140"></a> The CANDLE option
1024 
1025 
1026 <a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1027 a "box-and whisker plot" or simply "box plot") is a convenient way to describe
1028 graphically a data distribution (D) with only five numbers. It was invented
1029 in 1977 by John Tukey.
1030 
1031 With the option CANDLEX five numbers are:
1032 
1033 1. The minimum value of the distribution D (bottom dashed line).
1034 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1035 3. The median (M): 50% of the data points in D are less than M (thick line segment inside the box).
1036 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1037 5. The maximum value of the distribution D (top dashed line).
1038 
1039 
1040 The mean value of the distribution D is also represented as a circle.
1041 
1042 In this implementation a TH2 is considered as a collection of TH1 along
1043 X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1044 Each TH1 is represented as a candle plot.
1045 
1046 Begin_Macro(source)
1047 {
1048  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1049  TH2F *hcandle = new TH2F("hcandle","Option CANDLE example ",40,-4,4,40,-20,20);
1050  Float_t px, py;
1051  for (Int_t i = 0; i < 25000; i++) {
1052  gRandom->Rannor(px,py);
1053  hcandle->Fill(px,5*py);
1054  }
1055  hcandle->SetMarkerSize(0.5);
1056  hcandle->Draw("CANDLE");
1057  return c1;
1058 }
1059 End_Macro
1060 
1061 ### <a name="HP141"></a> The VIOLIN option
1062 
1063 
1064 <a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a box plot
1065 that also encodes the pdf information at each point.
1066 
1067 
1068 Quartiles and mean are also represented at each point, with a marker
1069 and two lines.
1070 
1071 In this implementation a TH2 is considered as a collection of TH1 along
1072 X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1073 
1074 A solid fill style is recommended for this plot (as opposed to a hollow or
1075 hashed style).
1076 
1077 Begin_Macro(source)
1078 {
1079  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1080  Int_t nx(6), ny(40);
1081  Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1082  TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1083  TF1 f1("f1", "gaus", +0,0 +4.0);
1084  Double_t x,y;
1085  for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1086  Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1087  f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1088  for(Int_t i=0; i<10000; ++i){
1089  x = xc;
1090  y = f1.GetRandom();
1091  hviolin->Fill(x, y);
1092  }
1093  }
1094  hviolin->SetFillColor(kGray);
1095  hviolin->SetMarkerStyle(20);
1096  hviolin->SetMarkerSize(0.5);
1097  hviolin->Draw("VIOLIN");
1098  c1->Update();
1099  return c1;
1100 }
1101 End_Macro
1102 
1103 
1104 ### <a name="HP15"></a> The TEXT and TEXTnn Option
1105 
1106 
1107 For each bin the content is printed. The text attributes are:
1108 
1109 - text font = current TStyle font (`gStyle->SetTextFont()`).
1110 - text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1111  with the option `TEXT` the marker size can be changed with
1112  `h->SetMarkerSize(markersize)`).
1113 - text color = marker color.
1114 
1115 By default the format `g` is used. This format can be redefined
1116 by calling `gStyle->SetPaintTextFormat()`.
1117 
1118 It is also possible to use `TEXTnn` in order to draw the text with
1119 the angle `nn` (`0 < nn < 90`).
1120 
1121 For 2D histograms the text is plotted in the center of each non empty cells.
1122 It is possible to plot empty cells by calling gStyle->SetHistMinimumZero().
1123 For 1D histogram the text is plotted at a y position equal to the bin content.
1124 
1125 For 2D histograms when the option "E" (errors) is combined with the option
1126 text ("TEXTE"), the error for each bin is also printed.
1127 
1128 Begin_Macro(source)
1129 {
1130  TCanvas *c01 = new TCanvas("c01","c01",700,400);
1131  c01->Divide(2,1);
1132  TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1133  TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1134  Float_t px, py;
1135  for (Int_t i = 0; i < 25000; i++) {
1136  gRandom->Rannor(px,py);
1137  htext1->Fill(px,0.1);
1138  htext2->Fill(px,5*py,0.1);
1139  }
1140  gStyle->SetPaintTextFormat("4.1f m");
1141  htext2->SetMarkerSize(1.8);
1142  c01->cd(1);
1143  htext2->Draw("TEXT45");
1144  c01->cd(2);
1145  htext1->Draw();
1146  htext1->Draw("HIST TEXT0 SAME");
1147  return c01;
1148 }
1149 End_Macro
1150 
1151 In the case of profile histograms it is possible to print the number
1152 of entries instead of the bin content. It is enough to combine the
1153 option "E" (for entries) with the option "TEXT".
1154 
1155 Begin_Macro(source)
1156 {
1157  TCanvas *c02 = new TCanvas("c02","c02",700,400);
1158  c02->Divide(2,1);
1159  gStyle->SetPaintTextFormat("g");
1160 
1161  TProfile *profile = new TProfile("profile","profile",10,0,10);
1162  profile->SetMarkerSize(2.2);
1163  profile->Fill(0.5,1);
1164  profile->Fill(1.5,2);
1165  profile->Fill(2.5,3);
1166  profile->Fill(3.5,4);
1167  profile->Fill(4.5,5);
1168  profile->Fill(5.5,5);
1169  profile->Fill(6.5,4);
1170  profile->Fill(7.5,3);
1171  profile->Fill(8.5,2);
1172  profile->Fill(9.5,1);
1173  c02->cd(1); profile->Draw("HIST TEXT0");
1174  c02->cd(2); profile->Draw("HIST TEXT0E");
1175 
1176  return c02;
1177 }
1178 End_Macro
1179 
1180 ### <a name="HP16"></a> The CONTour options
1181 
1182 
1183 The following contour options are supported:
1184 
1185 | Option | Description |
1186 |----------|-------------------------------------------------------------------|
1187 | "CONT" | Draw a contour plot (same as CONT0).|
1188 | "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1189 | "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1190 | "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1191 | "CONT3" | Draw a contour plot solid lines for all contours.|
1192 | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1193 | "CONT5" | Draw a contour plot using Delaunay triangles.|
1194 
1195 
1196 
1197 The following example shows a 2D histogram plotted with the option
1198 `CONTZ`. The option `CONT` draws a contour plot using surface
1199 colors to distinguish contours. Combined with the option `CONT` (or
1200 `CONT0`), the option `Z` allows to display the color palette
1201 defined by `gStyle->SetPalette()`.
1202 
1203 Begin_Macro(source)
1204 {
1205  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1206  TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1207  Float_t px, py;
1208  for (Int_t i = 0; i < 25000; i++) {
1209  gRandom->Rannor(px,py);
1210  hcontz->Fill(px-1,5*py);
1211  hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1212  }
1213  gStyle->SetPalette(kBird);
1214  hcontz->Draw("CONTZ");
1215  return c1;
1216 }
1217 End_Macro
1218 
1219 The following example shows a 2D histogram plotted with the option
1220 `CONT1Z`. The option `CONT1` draws a contour plot using the
1221 line colors to distinguish contours. Combined with the option `CONT1`,
1222 the option `Z` allows to display the color palette defined by
1223 `gStyle->SetPalette()`.
1224 
1225 Begin_Macro(source)
1226 {
1227  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1228  TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1229  Float_t px, py;
1230  for (Int_t i = 0; i < 25000; i++) {
1231  gRandom->Rannor(px,py);
1232  hcont1->Fill(px-1,5*py);
1233  hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1234  }
1235  gStyle->SetPalette(kBird);
1236  hcont1->Draw("CONT1Z");
1237  return c1;
1238 }
1239 End_Macro
1240 
1241 The following example shows a 2D histogram plotted with the option
1242 `CONT2`. The option `CONT2` draws a contour plot using the
1243 line styles to distinguish contours.
1244 
1245 Begin_Macro(source)
1246 {
1247  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1248  TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1249  Float_t px, py;
1250  for (Int_t i = 0; i < 25000; i++) {
1251  gRandom->Rannor(px,py);
1252  hcont2->Fill(px-1,5*py);
1253  hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1254  }
1255  hcont2->Draw("CONT2");
1256  return c1;
1257 }
1258 End_Macro
1259 
1260 The following example shows a 2D histogram plotted with the option
1261 `CONT3`. The option `CONT3` draws contour plot solid lines for
1262 all contours.
1263 
1264 Begin_Macro(source)
1265 {
1266  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1267  TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1268  Float_t px, py;
1269  for (Int_t i = 0; i < 25000; i++) {
1270  gRandom->Rannor(px,py);
1271  hcont3->Fill(px-1,5*py);
1272  hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1273  }
1274  hcont3->Draw("CONT3");
1275  return c1;
1276 }
1277 End_Macro
1278 
1279 The following example shows a 2D histogram plotted with the option
1280 `CONT4`. The option `CONT4` draws a contour plot using surface
1281 colors to distinguish contours (`SURF` option at theta = 0). Combined
1282 with the option `CONT` (or `CONT0`), the option `Z`
1283 allows to display the color palette defined by `gStyle->SetPalette()`.
1284 
1285 Begin_Macro(source)
1286 {
1287  TCanvas *c1 = new TCanvas("c1","c1",600,400);
1288  TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1289  Float_t px, py;
1290  for (Int_t i = 0; i < 25000; i++) {
1291  gRandom->Rannor(px,py);
1292  hcont4->Fill(px-1,5*py);
1293  hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1294  }
1295  gStyle->SetPalette(kBird);
1296  hcont4->Draw("CONT4Z");
1297  return c1;
1298 }
1299 End_Macro
1300 
1301 The default number of contour levels is 20 equidistant levels and can be changed
1302 with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1303 
1304 #### <a name="HP16a"></a> The LIST option
1305 
1306 When option `LIST` is specified together with option
1307 `CONT`, the points used to draw the contours are saved in
1308 `TGraph` objects:
1309 
1310  h->Draw("CONT LIST");
1311  gPad->Update();
1312 
1313 The contour are saved in `TGraph` objects once the pad is painted.
1314 Therefore to use this functionnality in a macro, `gPad->Update()`
1315 should be performed after the histogram drawing. Once the list is
1316 built, the contours are accessible in the following way:
1317 
1318  TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1319  Int_t ncontours = contours->GetSize();
1320  TList *list = (TList*)contours->At(i);
1321 
1322 Where `i` is a contour number, and list contains a list of
1323 `TGraph` objects.
1324 For one given contour, more than one disjoint polyline may be generated.
1325 The number of TGraphs per contour is given by:
1326 
1327  list->GetSize();
1328 
1329 To access the first graph in the list one should do:
1330 
1331  TGraph *gr1 = (TGraph*)list->First();
1332 
1333 
1334 The following example (ContourList.C) shows how to use this functionality.
1335 
1336 Begin_Macro(source)
1337 ../../../tutorials/hist/ContourList.C
1338 End_Macro
1339 
1340 The following options select the `CONT4` option and are useful for
1341 sky maps or exposure maps (earth.C).
1342 
1343 | Option | Description |
1344 |--------------|---------------------------------------------------------------|
1345 | "AITOFF" | Draw a contour via an AITOFF projection.|
1346 | "MERCATOR" | Draw a contour via an Mercator projection.|
1347 | "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1348 | "PARABOLIC" | Draw a contour via an Parabolic projection.|
1349 
1350 Begin_Macro(source)
1351 ../../../tutorials/graphics/earth.C
1352 End_Macro
1353 
1354 
1355 ### <a name="HP17"></a> The LEGO options
1356 
1357 
1358 In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1359 is proportional to the cell content. The lego aspect is control with the
1360 following options:
1361 
1362 | Option | Description |
1363 |----------|-------------------------------------------------------------------|
1364 | "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1365 | "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1366 | "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1367 | "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1368 | "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1369 | "0" | When used with any LEGO option, the empty bins are not drawn.|
1370 
1371 
1372 See the limitations with [the option "SAME"](#HP060a).
1373 
1374 Line attributes can be used in lego plots to change the edges' style.
1375 
1376 The following example shows a 2D histogram plotted with the option
1377 `LEGO`. The option `LEGO` draws a lego plot using the hidden
1378 lines removal technique.
1379 
1380 Begin_Macro(source)
1381 {
1382  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1383  TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1384  Float_t px, py;
1385  for (Int_t i = 0; i < 25000; i++) {
1386  gRandom->Rannor(px,py);
1387  hlego->Fill(px-1,5*py);
1388  hlego->Fill(2+0.5*px,2*py-10.,0.1);
1389  }
1390  hlego->Draw("LEGO");
1391  return c2;
1392 }
1393 End_Macro
1394 
1395 The following example shows a 2D histogram plotted with the option
1396 `LEGO1`. The option `LEGO1` draws a lego plot using the
1397 hidden surface removal technique. Combined with any `LEGOn` option, the
1398 option `0` allows to not drawn the empty bins.
1399 
1400 Begin_Macro(source)
1401 {
1402  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1403  TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1404  Float_t px, py;
1405  for (Int_t i = 0; i < 25000; i++) {
1406  gRandom->Rannor(px,py);
1407  hlego1->Fill(px-1,5*py);
1408  hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1409  }
1410  hlego1->SetFillColor(kYellow);
1411  hlego1->Draw("LEGO1 0");
1412  return c2;
1413 }
1414 End_Macro
1415 
1416 The following example shows a 2D histogram plotted with the option
1417 `LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1418 draws a lego plot using the hidden surface removal technique but doesn't draw
1419 the border lines of each individual lego-bar. This is very useful for histograms
1420 having many bins. With such histograms the option `LEGO1` gives a black
1421 image because of the border lines. This option also works with stacked legos.
1422 
1423 Begin_Macro(source)
1424 {
1425  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1426  TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1427  Float_t px, py;
1428  for (Int_t i = 0; i < 25000; i++) {
1429  gRandom->Rannor(px,py);
1430  hlego3->Fill(px-1,5*py);
1431  hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1432  }
1433  hlego3->SetFillColor(kRed);
1434  hlego3->Draw("LEGO3");
1435  return c2;
1436  }
1437 End_Macro
1438 
1439 The following example shows a 2D histogram plotted with the option
1440 `LEGO2`. The option `LEGO2` draws a lego plot using colors to
1441 show the cell contents. Combined with the option `LEGO2`, the option
1442 `Z` allows to display the color palette defined by
1443 `gStyle->SetPalette()`.
1444 
1445 Begin_Macro(source)
1446 {
1447  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1448  TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1449  Float_t px, py;
1450  for (Int_t i = 0; i < 25000; i++) {
1451  gRandom->Rannor(px,py);
1452  hlego2->Fill(px-1,5*py);
1453  hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1454  }
1455  gStyle->SetPalette(kBird);
1456  hlego2->Draw("LEGO2Z");
1457  return c2;
1458 }
1459 End_Macro
1460 
1461 
1462 
1463 ### <a name="HP18"></a> The "SURFace" options
1464 
1465 
1466 In a surface plot, cell contents are represented as a mesh.
1467 The height of the mesh is proportional to the cell content.
1468 
1469 | Option | Description |
1470 |----------|-------------------------------------------------------------------|
1471 | "SURF" | Draw a surface plot using the hidden line removal technique.|
1472 | "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1473 | "SURF2" | Draw a surface plot using colors to show the cell contents.|
1474 | "SURF3" | Same as `SURF` with an additionial filled contour plot on top.|
1475 | "SURF4" | Draw a surface using the Gouraud shading technique.|
1476 | "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1477 | "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.|
1478 | "SURF7" | Same as `SURF2` with an additionial line contour plot on top.|
1479 
1480 
1481 
1482 See the limitations with [the option "SAME"](#HP060a).
1483 
1484 The following example shows a 2D histogram plotted with the option
1485 `SURF`. The option `SURF` draws a lego plot using the hidden
1486 lines removal technique.
1487 
1488 Begin_Macro(source)
1489 {
1490  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1491  TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1492  Float_t px, py;
1493  for (Int_t i = 0; i < 25000; i++) {
1494  gRandom->Rannor(px,py);
1495  hsurf->Fill(px-1,5*py);
1496  hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1497  }
1498  hsurf->Draw("SURF");
1499  return c2;
1500 }
1501 End_Macro
1502 
1503 The following example shows a 2D histogram plotted with the option
1504 `SURF1`. The option `SURF1` draws a surface plot using the
1505 hidden surface removal technique. Combined with the option `SURF1`,
1506 the option `Z` allows to display the color palette defined by
1507 `gStyle->SetPalette()`.
1508 
1509 Begin_Macro(source)
1510 {
1511  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1512  gStyle->SetPalette(kBird);
1513  TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1514  Float_t px, py;
1515  for (Int_t i = 0; i < 25000; i++) {
1516  gRandom->Rannor(px,py);
1517  hsurf1->Fill(px-1,5*py);
1518  hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1519  }
1520  hsurf1->Draw("SURF1");
1521  return c2;
1522 }
1523 End_Macro
1524 
1525 The following example shows a 2D histogram plotted with the option
1526 `SURF2`. The option `SURF2` draws a surface plot using colors
1527 to show the cell contents. Combined with the option `SURF2`, the option
1528 `Z` allows to display the color palette defined by
1529 `gStyle->SetPalette()`.
1530 
1531 Begin_Macro(source)
1532 {
1533  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1534  gStyle->SetPalette(kBird);
1535  TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
1536  Float_t px, py;
1537  for (Int_t i = 0; i < 25000; i++) {
1538  gRandom->Rannor(px,py);
1539  hsurf2->Fill(px-1,5*py);
1540  hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
1541  }
1542  hsurf2->Draw("SURF2");
1543  return c2;
1544 }
1545 End_Macro
1546 
1547 The following example shows a 2D histogram plotted with the option
1548 `SURF3`. The option `SURF3` draws a surface plot using the
1549 hidden line removal technique with, in addition, a filled contour view drawn on the
1550 top. Combined with the option `SURF3`, the option `Z` allows
1551 to display the color palette defined by `gStyle->SetPalette()`.
1552 
1553 Begin_Macro(source)
1554 {
1555  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1556  gStyle->SetPalette(kBird);
1557  TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
1558  Float_t px, py;
1559  for (Int_t i = 0; i < 25000; i++) {
1560  gRandom->Rannor(px,py);
1561  hsurf3->Fill(px-1,5*py);
1562  hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
1563  }
1564  hsurf3->Draw("SURF3");
1565  return c2;
1566 }
1567 End_Macro
1568 
1569 The following example shows a 2D histogram plotted with the option
1570 `SURF4`. The option `SURF4` draws a surface using the Gouraud
1571 shading technique.
1572 
1573 Begin_Macro(source)
1574 {
1575  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1576  TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
1577  Float_t px, py;
1578  for (Int_t i = 0; i < 25000; i++) {
1579  gRandom->Rannor(px,py);
1580  hsurf4->Fill(px-1,5*py);
1581  hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
1582  }
1583  hsurf4->SetFillColor(kOrange);
1584  hsurf4->Draw("SURF4");
1585  return c2;
1586 }
1587 End_Macro
1588 
1589 The following example shows a 2D histogram plotted with the option
1590 `SURF5 CYL`. Combined with the option `SURF5`, the option
1591 `Z` allows to display the color palette defined by `gStyle->SetPalette()`.
1592 
1593 Begin_Macro(source)
1594 {
1595  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1596  gStyle->SetPalette(kBird);
1597  TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
1598  Float_t px, py;
1599  for (Int_t i = 0; i < 25000; i++) {
1600  gRandom->Rannor(px,py);
1601  hsurf5->Fill(px-1,5*py);
1602  hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
1603  }
1604  hsurf5->SetFillColor(kOrange);
1605  hsurf5->Draw("SURF5 CYL");
1606  return c2;
1607 }
1608 End_Macro
1609 
1610 The following example shows a 2D histogram plotted with the option
1611 `SURF7`. The option `SURF7` draws a surface plot using the
1612 hidden surfaces removal technique with, in addition, a line contour view drawn on the
1613 top. Combined with the option `SURF7`, the option `Z` allows
1614 to display the color palette defined by `gStyle->SetPalette()`.
1615 
1616 Begin_Macro(source)
1617 {
1618  TCanvas *c2 = new TCanvas("c2","c2",600,400);
1619  gStyle->SetPalette(kBird);
1620  TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
1621  Float_t px, py;
1622  for (Int_t i = 0; i < 25000; i++) {
1623  gRandom->Rannor(px,py);
1624  hsurf7->Fill(px-1,5*py);
1625  hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
1626  }
1627  hsurf7->Draw("SURF7");
1628  return c2;
1629 }
1630 End_Macro
1631 
1632 As shown in the following example, when a contour plot is painted on top of a
1633 surface plot using the option `SAME`, the contours appear in 3D on the
1634 surface.
1635 
1636 Begin_Macro(source)
1637 {
1638  TCanvas *c20=new TCanvas("c20","c20",600,400);
1639  int NBins = 50;
1640  double d = 2;
1641  TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
1642  for (int bx = 1; bx <= NBins; ++bx) {
1643  for (int by = 1; by <= NBins; ++by) {
1644  double x = hsc->GetXaxis()->GetBinCenter(bx);
1645  double y = hsc->GetYaxis()->GetBinCenter(by);
1646  hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
1647  }
1648  }
1649  gStyle->SetPalette(kBird);
1650  hsc->Draw("surf2");
1651  hsc->Draw("CONT1 SAME");
1652  return c20;
1653 }
1654 End_Macro
1655 
1656 
1657 ### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
1658 
1659 
1660 Legos and surfaces plots are represented by default in Cartesian coordinates.
1661 Combined with any `LEGOn` or `SURFn` options the following
1662 options allow to draw a lego or a surface in other coordinates systems.
1663 
1664 | Option | Description |
1665 |----------|-------------------------------------------------------------------|
1666 | "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
1667 | "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
1668 | "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
1669 | "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
1670 
1671 
1672 
1673 <b>WARNING:</b> Axis are not drawn with these options.
1674 
1675 The following example shows the same histogram as a lego plot is the four
1676 different coordinates systems.
1677 
1678 Begin_Macro(source)
1679 {
1680  TCanvas *c3 = new TCanvas("c3","c3",600,400);
1681  c3->Divide(2,2);
1682  TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
1683  Float_t px, py;
1684  for (Int_t i = 0; i < 25000; i++) {
1685  gRandom->Rannor(px,py);
1686  hlcc->Fill(px-1,5*py);
1687  hlcc->Fill(2+0.5*px,2*py-10.,0.1);
1688  }
1689  hlcc->SetFillColor(kYellow);
1690  c3->cd(1); hlcc->Draw("LEGO1 CYL");
1691  c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
1692  hlpc->SetTitle("Polar coordinates");
1693  c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
1694  hlsc->SetTitle("Spherical coordinates");
1695  c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
1696  hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
1697  return c3;
1698 }
1699 End_Macro
1700 
1701 The following example shows the same histogram as a surface plot is the four different coordinates systems.
1702 
1703 Begin_Macro(source)
1704 {
1705  TCanvas *c4 = new TCanvas("c4","c4",600,400);
1706  c4->Divide(2,2);
1707  TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
1708  Float_t px, py;
1709  for (Int_t i = 0; i < 25000; i++) {
1710  gRandom->Rannor(px,py);
1711  hscc->Fill(px-1,5*py);
1712  hscc->Fill(2+0.5*px,2*py-10.,0.1);
1713  }
1714  gStyle->SetPalette(kBird);
1715  c4->cd(1); hscc->Draw("SURF1 CYL");
1716  c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
1717  hspc->SetTitle("Polar coordinates");
1718  c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
1719  hssc->SetTitle("Spherical coordinates");
1720  c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
1721  hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
1722  return c4;
1723 }
1724 End_Macro
1725 
1726 
1727 ### <a name="HP20"></a> Base line for bar-charts and lego plots
1728 
1729 
1730 By default the base line used to draw the boxes for bar-charts and lego plots is
1731 the histogram minimum. It is possible to force this base line to be 0 with the
1732 command:
1733 
1734  gStyle->SetHistMinimumZero();
1735 
1736 Begin_Macro(source)
1737 {
1738  TCanvas *c5 = new TCanvas("c5","c5",700,400);
1739  c5->Divide(2,1);
1740  gStyle->SetHistMinimumZero(1);
1741  TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
1742  TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
1743  Int_t i;
1744  Double_t x,y;
1745  hz1->SetFillColor(kBlue);
1746  hz2->SetFillColor(kBlue);
1747  for (i=0;i<10000;i++) {
1748  x = gRandom->Gaus(0,1);
1749  y = gRandom->Gaus(0,1);
1750  if (x>0) {
1751  hz1->Fill(x,1);
1752  hz2->Fill(x,y,1);
1753  } else {
1754  hz1->Fill(x,-1);
1755  hz2->Fill(x,y,-2);
1756  }
1757  }
1758  c5->cd(1); hz1->Draw("bar2");
1759  c5->cd(2); hz2->Draw("lego1");
1760  return c5;
1761 }
1762 End_Macro
1763 
1764 This option also works for horizontal plots. The example given in the section
1765 ["The bar chart option"](#HP100) appears as follow:
1766 
1767 Begin_Macro(source)
1768 {
1769  int i;
1770  const Int_t nx = 8;
1771  string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
1772  float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
1773  float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
1774 
1775  TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
1776  cbh->SetGrid();
1777 
1778  gStyle->SetHistMinimumZero();
1779 
1780  TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
1781  h1bh->SetFillColor(4);
1782  h1bh->SetBarWidth(0.4);
1783  h1bh->SetBarOffset(0.1);
1784  h1bh->SetStats(0);
1785  h1bh->SetMinimum(-5);
1786  h1bh->SetMaximum(5);
1787 
1788  for (i=1; i<=nx; i++) {
1789  h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
1790  h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
1791  }
1792 
1793  h1bh->Draw("hbar");
1794 
1795  TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
1796  h2bh->SetFillColor(38);
1797  h2bh->SetBarWidth(0.4);
1798  h2bh->SetBarOffset(0.5);
1799  h2bh->SetStats(0);
1800  for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
1801 
1802  h2bh->Draw("hbar same");
1803 
1804  return cbh;
1805 }
1806 End_Macro
1807 
1808 
1809 ### <a name="HP20a"></a> TH2Poly Drawing
1810 
1811 
1812 The following options are supported:
1813 
1814 | Option | Description |
1815 |----------|-------------------------------------------------------------------|
1816 | "SCAT" | Draw a scatter plot (default).|
1817 | "COL" | Draw a color plot. All the none empty bins are painted. Empty bins are not painted.|
1818 | "COLZ" | Same as "COL". In addition the color palette is also drawn.|
1819 | "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
1820 | "TEXTN" | Draw bin names as text.|
1821 | "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
1822 | "L" | Draw the bins boundaries as lines. The lines attibutes are the TGraphs ones.|
1823 | "P" | Draw the bins boundaries as markers. The markers attibutes are the TGraphs ones.|
1824 | "F" | Draw the bins boundaries as filled polygons. The filled polygons attibutes are the TGraphs ones.|
1825 
1826 
1827 
1828 `TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
1829 shapes. The bins are defined as graphs. The following macro is a very simple
1830 example showing how to book a TH2Poly and draw it.
1831 
1832 Begin_Macro(source)
1833 {
1834  TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
1835  TH2Poly *h2p = new TH2Poly();
1836  h2p->SetName("h2poly_name");
1837  h2p->SetTitle("h2poly_title");
1838  Double_t px1[] = {0, 5, 6};
1839  Double_t py1[] = {0, 0, 5};
1840  Double_t px2[] = {0, -1, -1, 0};
1841  Double_t py2[] = {0, 0, -1, 3};
1842  Double_t px3[] = {4, 3, 0, 1, 2.4};
1843  Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
1844  h2p->AddBin(3, px1, py1);
1845  h2p->AddBin(4, px2, py2);
1846  h2p->AddBin(5, px3, py3);
1847  h2p->Fill(0.1, 0.01, 3);
1848  h2p->Fill(-0.5, -0.5, 7);
1849  h2p->Fill(-0.7, -0.5, 1);
1850  h2p->Fill(1, 3, 1.5);
1851  Double_t fx[] = {0.1, -0.5, -0.7, 1};
1852  Double_t fy[] = {0.01, -0.5, -0.5, 3};
1853  Double_t fw[] = {3, 1, 1, 1.5};
1854  h2p->FillN(4, fx, fy, fw);
1855  gStyle->SetPalette(kBird);
1856  h2p->Draw("col");
1857  return ch2p1;
1858 }
1859 End_Macro
1860 
1861 Rectangular bins are a frequent case. The special version of
1862 the `AddBin` method allows to define them more easily like
1863 shown in the following example (th2polyBoxes.C).
1864 
1865 Begin_Macro(source)
1866 ../../../tutorials/hist/th2polyBoxes.C
1867 End_Macro
1868 
1869 One `TH2Poly` bin can be a list of polygons. Such bins are defined
1870 by calling `AddBin` with a `TMultiGraph`. The following example
1871 shows a such case:
1872 
1873 Begin_Macro(source)
1874 {
1875  TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
1876 
1877  Int_t i, bin;
1878  const Int_t nx = 48;
1879  const char *states [nx] = {
1880  "alabama", "arizona", "arkansas", "california",
1881  "colorado", "connecticut", "delaware", "florida",
1882  "georgia", "idaho", "illinois", "indiana",
1883  "iowa", "kansas", "kentucky", "louisiana",
1884  "maine", "maryland", "massachusetts", "michigan",
1885  "minnesota", "mississippi", "missouri", "montana",
1886  "nebraska", "nevada", "new_hampshire", "new_jersey",
1887  "new_mexico", "new_york", "north_carolina", "north_dakota",
1888  "ohio", "oklahoma", "oregon", "pennsylvania",
1889  "rhode_island", "south_carolina", "south_dakota", "tennessee",
1890  "texas", "utah", "vermont", "virginia",
1891  "washington", "west_virginia", "wisconsin", "wyoming"
1892  };
1893  Double_t pop[nx] = {
1894  4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
1895  9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
1896  1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
1897  1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
1898  11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
1899  24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
1900  };
1901 
1902  Double_t lon1 = -130;
1903  Double_t lon2 = -65;
1904  Double_t lat1 = 24;
1905  Double_t lat2 = 50;
1906  TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
1907 
1908  TFile *f;
1909  f = TFile::Open("http://root.cern.ch/files/usa.root");
1910 
1911  TMultiGraph *mg;
1912  TKey *key;
1913  TIter nextkey(gDirectory->GetListOfKeys());
1914  while ((key = (TKey*)nextkey())) {
1915  TObject *obj = key->ReadObj();
1916  if (obj->InheritsFrom("TMultiGraph")) {
1917  mg = (TMultiGraph*)obj;
1918  bin = p->AddBin(mg);
1919  }
1920  }
1921 
1922  for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
1923 
1924  gStyle->SetOptStat(11);
1925  gStyle->SetPalette(kBird);
1926  p->Draw("COLZ L");
1927  return ch2p2;
1928 }
1929 End_Macro
1930 
1931 `TH2Poly` histograms can also be plotted using the GL interface using
1932 the option "GLLEGO".
1933 
1934 ### <a name="HP21"></a> The SPEC option
1935 
1936 
1937 This option allows to use the `TSpectrum2Painter` tools. See the full
1938 documentation in `TSpectrum2Painter::PaintSpectrum`.
1939 
1940 
1941 ### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
1942 
1943 
1944 When this option is specified, a color palette with an axis indicating the value
1945 of the corresponding color is drawn on the right side of the picture. In case,
1946 not enough space is left, one can increase the size of the right margin by
1947 calling `TPad::SetRightMargin()`. The attributes used to display the
1948 palette axis values are taken from the Z axis of the object. For example, to
1949 set the labels size on the palette axis do:
1950 
1951  hist->GetZaxis()->SetLabelSize().
1952 
1953 <b>WARNING:</b> The palette axis is always drawn vertically.
1954 
1955 
1956 ### <a name="HP23"></a> Setting the color palette
1957 
1958 
1959 To change the color palette `TStyle::SetPalette` should be used, eg:
1960 
1961  gStyle->SetPalette(ncolors,colors);
1962 
1963 For example the option `COL` draws a 2D histogram with cells
1964 represented by a box filled with a color index which is a function
1965 of the cell content.
1966 If the cell content is N, the color index used will be the color number
1967 in `colors[N]`, etc. If the maximum cell content is greater than
1968 `ncolors`, all cell contents are scaled to `ncolors`.
1969 
1970 If ` ncolors <= 0`, a default palette (see below) of 50 colors is
1971 defined. This palette is recommended for pads, labels ...
1972 
1973 `if ncolors == 1 && colors == 0`, then a Pretty Palette with a
1974 Spectrum Violet->Red is created with 50 colors. That's the default rain bow
1975 palette.
1976 
1977 Other prefined palettes with 255 colors are available when `colors == 0`.
1978 The following value of `ncolors` give access to:
1979 
1980 
1981  if ncolors = 51 and colors=0, a Deep Sea palette is used.
1982  if ncolors = 52 and colors=0, a Grey Scale palette is used.
1983  if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
1984  if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
1985  if ncolors = 55 and colors=0, a Rain Bow palette is used.
1986  if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
1987 
1988 
1989 If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
1990 
1991 The default palette defines:
1992 
1993 - index 0 to 9 : shades of grey
1994 - index 10 to 19 : shades of brown
1995 - index 20 to 29 : shades of blue
1996 - index 30 to 39 : shades of red
1997 - index 40 to 49 : basic colors
1998 
1999 The color numbers specified in the palette can be viewed by selecting
2000 the item `colors` in the `VIEW` menu of the canvas tool bar.
2001 The red, green, and blue components of a color can be changed thanks to
2002 `TColor::SetRGB()`.
2003 
2004 
2005 ### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2006 
2007 
2008 Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2009 histogram. One must create a graphical cut (mouse or C++) and specify the name
2010 of the cut between `[]` in the `Draw()` option.
2011 For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2012 
2013  myhist->Draw("surf1 [cutg]");
2014 
2015 To invert the cut, it is enough to put a `-` in front of its name:
2016 
2017  myhist->Draw("surf1 [-cutg]");
2018 
2019 It is possible to apply several cuts (`,` means logical AND):
2020 
2021  myhist->Draw("surf1 [cutg1,cutg2]");
2022 
2023 Begin_Macro(source)
2024 ../../../tutorials/fit/fit2a.C
2025 End_Macro
2026 
2027 ### <a name="HP25"></a> Drawing options for 3D histograms
2028 
2029 
2030 | Option | Description |
2031 |----------|-------------------------------------------------------------------|
2032 | "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)`|
2033 | "BOX" | Draw a for each cell with volume proportional to the content's absolute value.|
2034 
2035 
2036 
2037 By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2038 
2039 The following example shows a 3D histogram plotted as a scatter plot.
2040 
2041 Begin_Macro(source)
2042 {
2043  TCanvas *c06 = new TCanvas("c06","c06",600,400);
2044  gStyle->SetOptStat(kFALSE);
2045  TH3F *h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2046  Double_t x, y, z;
2047  for (Int_t i=0;i<10000;i++) {
2048  gRandom->Rannor(x, y);
2049  z = x*x + y*y;
2050  h3scat->Fill(x,y,z);
2051  }
2052  h3scat->Draw();
2053  return c06;
2054 }
2055 End_Macro
2056 
2057 The following example shows a 3D histogram plotted with the option `BOX`.
2058 
2059 Begin_Macro(source)
2060 {
2061  TCanvas *c16 = new TCanvas("c16","c16",600,400);
2062  gStyle->SetOptStat(kFALSE);
2063  TH3F *h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2064  Double_t x, y, z;
2065  for (Int_t i=0;i<10000;i++) {
2066  gRandom->Rannor(x, y);
2067  z = x*x + y*y;
2068  h3box->Fill(x,y,z);
2069  }
2070  h3box->Draw("BOX");
2071  return c16;
2072 }
2073 End_Macro
2074 
2075 The following example shows a 3D histogram plotted with the option `ISO`.
2076 
2077 Begin_Macro(source)
2078 {
2079  TCanvas *c26 = new TCanvas("c26","c26",600,400);
2080  gStyle->SetOptStat(kFALSE);
2081  TH3F *h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2082  Double_t x, y, z;
2083  for (Int_t i=0;i<10000;i++) {
2084  gRandom->Rannor(x, y);
2085  z = x*x + y*y;
2086  h3iso->Fill(x,y,z);
2087  }
2088  h3iso->SetFillColor(kCyan);
2089  h3iso->Draw("ISO");
2090  return c26;
2091 }
2092 End_Macro
2093 
2094 
2095 ### <a name="HP26"></a> Drawing option for histograms' stacks
2096 
2097 
2098 Stacks of histograms are managed with the `THStack`. A `THStack`
2099 is a collection of `TH1` (or derived) objects. For painting only the
2100 `THStack` containing `TH1` only or
2101 `THStack` containing `TH2` only will be considered.
2102 
2103 By default, histograms are shown stacked:
2104 
2105 1. The first histogram is paint.
2106 2. The the sum of the first and second, etc...
2107 
2108 If the option `NOSTACK` is specified, the histograms are all paint in
2109 the same pad as if the option `SAME` had been specified. This allows to
2110 compute X and Y scales common to all the histograms, like
2111 `TMultiGraph` does for graphs.
2112 
2113 If the option `PADS` is specified, the current pad/canvas is
2114 subdivided into a number of pads equal to the number of histograms and each
2115 histogram is paint into a separate pad.
2116 
2117 The following example shows various types of stacks (hstack.C).
2118 
2119 Begin_Macro(source)
2120 ../../../tutorials/hist/hstack.C
2121 End_Macro
2122 
2123 The option `nostackb` allows to draw the histograms next to each
2124 other as bar charts:
2125 
2126 Begin_Macro(source)
2127 {
2128  TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2129  THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2130 
2131  TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2132  h1->FillRandom("gaus",20000);
2133  h1->SetFillColor(kRed);
2134  hs->Add(h1);
2135 
2136  TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2137  h2->FillRandom("gaus",15000);
2138  h2->SetFillColor(kBlue);
2139  hs->Add(h2);
2140 
2141  TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2142  h3->FillRandom("gaus",10000);
2143  h3->SetFillColor(kGreen);
2144  hs->Add(h3);
2145 
2146  hs->Draw("nostackb");
2147  hs->GetXaxis()->SetNdivisions(-10);
2148  cst0->SetGridx();
2149  return cst0;
2150 }
2151 End_Macro
2152 
2153 If at least one of the histograms in the stack has errors, the whole stack is
2154 visualized by default with error bars. To visualize it without errors the
2155 option `HIST` should be used.
2156 
2157 Begin_Macro(source)
2158 {
2159  TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2160  cst1->Divide(2,1);
2161 
2162  TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2163  hst11->Sumw2();
2164  hst11->FillRandom("gaus", 1000);
2165  hst11->SetFillColor(kViolet);
2166  hst11->SetLineColor(kViolet);
2167 
2168  TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2169  hst12->FillRandom("gaus", 500);
2170  hst12->SetFillColor(kBlue);
2171  hst12->SetLineColor(kBlue);
2172 
2173  THStack st1("st1", "st1");
2174  st1.Add(hst11);
2175  st1.Add(hst12);
2176 
2177  cst1->cd(1); st1.Draw();
2178  cst1->cd(2); st1.Draw("hist");
2179 
2180  return cst1;
2181 }
2182 End_Macro
2183 
2184 ### <a name="HP27"></a> Drawing of 3D implicit functions
2185 
2186 
2187 3D implicit functions (`TF3`) can be drawn as iso-surfaces.
2188 The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2189 In the following example the options "FB" and "BB" suppress the
2190 "Front Box" and "Back Box" around the plot.
2191 
2192 Begin_Macro(source)
2193 {
2194  TCanvas *c2 = new TCanvas("c2","c2",600,400);
2195  TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2196  f3->SetClippingBoxOn(0,0,0);
2197  f3->SetFillColor(30);
2198  f3->SetLineColor(15);
2199  f3->Draw("FBBB");
2200  return c2;
2201 }
2202 End_Macro
2203 
2204 
2205 ### <a name="HP28"></a> Associated functions drawing
2206 
2207 
2208 An associated function is created by `TH1::Fit`. More than on fitted
2209 function can be associated with one histogram (see `TH1::Fit`).
2210 
2211 A `TF1` object `f1` can be added to the list of associated
2212 functions of an histogram `h` without calling `TH1::Fit`
2213 simply doing:
2214 
2215  h->GetListOfFunctions()->Add(f1);
2216 
2217 or
2218 
2219  h->GetListOfFunctions()->Add(f1,someoption);
2220 
2221 To retrieve a function by name from this list, do:
2222 
2223  TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2224 
2225 or
2226 
2227  TF1 *f1 = h->GetFunction(name);
2228 
2229 Associated functions are automatically painted when an histogram is drawn.
2230 To avoid the painting of the associated functions the option `HIST`
2231 should be added to the list of the options used to paint the histogram.
2232 
2233 
2234 ### <a name="HP29"></a> Drawing using OpenGL
2235 
2236 
2237 The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2238 graphics library. The plotting options start with `GL` keyword.
2239 In addition, in order to inform canvases that OpenGL should be used to render
2240 3D representations, the following option should be set:
2241 
2242  gStyle->SetCanvasPreferGL(true);
2243 
2244 
2245 #### <a name="HP29a"></a> General information: plot types and supported options
2246 
2247 The following types of plots are provided:
2248 
2249 For lego plots the supported options are:
2250 
2251 | Option | Description |
2252 |----------|-------------------------------------------------------------------|
2253 | "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2254 | "GLLEGO2"| Bins with color levels.|
2255 | "GLLEGO3"| Cylindrical bars.|
2256 
2257 
2258 
2259 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2260 In polar only Z axis can be logarithmic, in cylindrical only Y.
2261 
2262 For surface plots (`TF2` and `TH2`) the supported options are:
2263 
2264 | Option | Description |
2265 |-----------|------------------------------------------------------------------|
2266 | "GLSURF" | Draw a surface.|
2267 | "GLSURF1" | Surface with color levels|
2268 | "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2269 | "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2270 | "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2271 
2272 
2273 
2274 The surface painting in cartesian coordinates supports logarithmic scales along
2275 X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2276 in cylindrical coordinates only the Y axis.
2277 
2278 Additional options to SURF and LEGO - Coordinate systems:
2279 
2280 | Option | Description |
2281 |----------|-------------------------------------------------------------------|
2282 | " " | Default, cartesian coordinates system.|
2283 | "POL" | Polar coordinates system.|
2284 | "CYL" | Cylindrical coordinates system.|
2285 | "SPH" | Spherical coordinates system.|
2286 
2287 
2288 
2289 #### <a name="HP290"></a> TH3 as color boxes
2290 
2291 The supported option is:
2292 
2293 | Option | Description |
2294 |----------|-------------------------------------------------------------------|
2295 | "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2296 
2297 
2298 
2299 #### <a name="HP29b"></a> TH3 as boxes (spheres)
2300 
2301 The supported options are:
2302 
2303 | Option | Description |
2304 |----------|-------------------------------------------------------------------|
2305 | "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2306 | "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2307 
2308 
2309 
2310 #### <a name="HP29c"></a> TH3 as iso-surface(s)
2311 
2312 The supported option is:
2313 
2314 | Option | Description |
2315 |----------|-------------------------------------------------------------------|
2316 | "GLISO" | TH3 is drawn using iso-surfaces.|
2317 
2318 
2319 
2320 #### <a name="HP29d"></a> TF3 (implicit function)
2321 
2322 The supported option is:
2323 
2324 | Option | Description |
2325 |----------|-------------------------------------------------------------------|
2326 | "GLTF3" | Draw a TF3.|
2327 
2328 
2329 
2330 #### <a name="HP29e"></a> Parametric surfaces
2331 
2332 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2333 equations and visualize the surface.
2334 
2335 #### <a name="HP29f"></a> Interaction with the plots
2336 
2337 All the interactions are implemented via standard methods
2338 `DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2339 interactions with the OpenGL plots are possible only when the mouse cursor is
2340 in the plot's area (the plot's area is the part of a the pad occupied by
2341 gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2342 pad interaction is performed.
2343 
2344 #### <a name="HP29g"></a> Selectable parts
2345 
2346 Different parts of the plot can be selected:
2347 
2348 - xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2349  if the dynamic slicing by this plane is supported, and it's highlighted in red,
2350  if the dynamic slicing is not supported.
2351 - The plot itself:
2352  On surfaces, the selected surface is outlined in red. (TF3 and
2353  ISO are not outlined). On lego plots, the selected bin is
2354  highlighted. The bin number and content are displayed in pad's
2355  status bar. In box plots, the box or sphere is highlighted and
2356  the bin info is displayed in pad's status bar.
2357 
2358 
2359 #### <a name="HP29h"></a> Rotation and zooming
2360 
2361 
2362 - Rotation:
2363  When the plot is selected, it can be rotated by pressing and
2364  holding the left mouse button and move the cursor.
2365 - Zoom/Unzoom:
2366  Mouse wheel or 'j', 'J', 'k', 'K' keys.
2367 
2368 
2369 #### <a name="HP29i"></a> Panning
2370 
2371 The selected plot can be moved in a pad's area by pressing and
2372 holding the left mouse button and the shift key.
2373 
2374 #### <a name="HP29j"></a> Box cut
2375 
2376 Surface, iso, box, TF3 and parametric painters support box cut by
2377 pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2378 area. That will display a transparent box, cutting away part of the
2379 surface (or boxes) in order to show internal part of plot. This box
2380 can be moved inside the plot's area (the full size of the box is
2381 equal to the plot's surrounding box) by selecting one of the box
2382 cut axes and pressing the left mouse button to move it.
2383 
2384 #### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2385 
2386 Currently, all gl-plots support some form of slicing. When back plane
2387 is selected (and if it's highlighted in green) you can press and hold
2388 left mouse button and shift key and move this back plane inside
2389 plot's area, creating the slice. During this "slicing" plot becomes
2390 semi-transparent. To remove all slices (and projected curves for
2391 surfaces) double click with left mouse button in a plot's area.
2392 
2393 #### <a name="HP29l"></a> Surface with option "GLSURF"
2394 
2395 The surface profile is displayed on the slicing plane.
2396 The profile projection is drawn on the back plane
2397 by pressing `'p'` or `'P'` key.
2398 
2399 #### <a name="HP29m"></a> TF3
2400 
2401 The contour plot is drawn on the slicing plane. For TF3 the color
2402 scheme can be changed by pressing 's' or 'S'.
2403 
2404 #### <a name="HP29n"></a> Box
2405 
2406 The contour plot corresponding to slice plane position is drawn in real time.
2407 
2408 #### <a name="HP29o"></a> Iso
2409 
2410 Slicing is similar to "GLBOX" option.
2411 
2412 #### <a name="HP29p"></a> Parametric plot
2413 
2414 No slicing. Additional keys: 's' or 'S' to change color scheme -
2415 about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2416 increase number of polygons ('l' for "level" of details), 'w' or 'W'
2417 to show outlines ('w' for "wireframe").
2418 
2419 */
2420 
2421 TH1 *gCurrentHist = 0;
2422 
2425 
2426 const Int_t kNMAX = 2000;
2428 const Int_t kMAXCONTOUR = 104;
2431 static TString gStringEntries;
2433 static TString gStringMeanX;
2436 static TString gStringStdDev;
2456 ////////////////////////////////////////////////////////////////////////////////
2457 /// Default constructor.
2458 
2460 {
2461 
2462  fH = 0;
2463  fXaxis = 0;
2464  fYaxis = 0;
2465  fZaxis = 0;
2466  fFunctions = 0;
2467  fXbuf = 0;
2468  fYbuf = 0;
2469  fNcuts = 0;
2470  fStack = 0;
2471  fLego = 0;
2472  fPie = 0;
2473  fGraph2DPainter = 0;
2474  fShowProjection = 0;
2475  fShowOption = "";
2476  for (int i=0; i<kMaxCuts; i++) {
2477  fCuts[i] = 0;
2478  fCutsOpt[i] = 0;
2479  }
2480 
2481  gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
2482  gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
2483  gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
2484  gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
2485  gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
2486  gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
2487  gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
2488  gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
2489  gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
2490  gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
2491  gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
2492  gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
2493  gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
2494  gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
2495  gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
2496  gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
2497  gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
2498  gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
2499  gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
2500  gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
2501  gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
2502 }
2503 
2504 
2505 ////////////////////////////////////////////////////////////////////////////////
2506 /// Default destructor.
2507 
2509 {
2510 }
2511 
2512 
2513 ////////////////////////////////////////////////////////////////////////////////
2514 /// Compute the distance from the point px,py to a line.
2515 ///
2516 /// Compute the closest distance of approach from point px,py to elements of
2517 /// an histogram. The distance is computed in pixels units.
2518 ///
2519 /// Algorithm: Currently, this simple model computes the distance from the mouse
2520 /// to the histogram contour only.
2521 
2523 {
2524 
2525 
2526  const Int_t big = 9999;
2527  const Int_t kMaxDiff = 7;
2529  if (fPie) return fPie->DistancetoPrimitive(px, py);
2530 
2531  Double_t x = gPad->AbsPixeltoX(px);
2532  Double_t x1 = gPad->AbsPixeltoX(px+1);
2533 
2534  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
2535  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
2536  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
2537  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
2538  Int_t curdist = big;
2539  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
2540  Bool_t dsame;
2541  TObject *PadPointer = gPad->GetPadPointer();
2542  if (!PadPointer) return 0;
2543  TString doption = PadPointer->GetDrawOption();
2544  Double_t factor = 1;
2545  if (fH->GetNormFactor() != 0) {
2546  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
2547  }
2548  // return if point is not in the histogram area
2549 
2550  // If a 3D view exists, check distance to axis
2551  TView *view = gPad->GetView();
2552  Int_t d1,d2,d3;
2553  if (view && Hoption.Contour != 14) {
2554  Double_t ratio;
2555  d3 = view->GetDistancetoAxis(3, px, py, ratio);
2556  if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
2557  d1 = view->GetDistancetoAxis(1, px, py, ratio);
2558  if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
2559  d2 = view->GetDistancetoAxis(2, px, py, ratio);
2560  if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
2561  if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
2562  goto FUNCTIONS;
2563  }
2564  // check if point is close to an axis
2565  doption.ToLower();
2566  dsame = kFALSE;
2567  if (doption.Contains("same")) dsame = kTRUE;
2568 
2569  dyaxis = Int_t(2*(puymin-puymax)*fYaxis->GetLabelSize());
2570  if (doption.Contains("y+")) {
2571  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2572  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
2573  if (!dsame) {
2574  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2575  else gPad->SetSelected(fXaxis);
2576  return 0;
2577  }
2578  }
2579  } else {
2580  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
2581  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
2582  if (!dsame) {
2583  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
2584  else gPad->SetSelected(fXaxis);
2585  return 0;
2586  }
2587  }
2588  }
2589 
2590  dxaxis = Int_t((puymin-puymax)*fXaxis->GetLabelSize());
2591  if (doption.Contains("x+")) {
2592  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2593  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
2594  if (!dsame) {
2595  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2596  else gPad->SetSelected(fYaxis);
2597  return 0;
2598  }
2599  }
2600  } else {
2601  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
2602  if (yxaxis < puymin) yxaxis = puymin;
2603  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
2604  if (!dsame) {
2605  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
2606  else gPad->SetSelected(fYaxis);
2607  return 0;
2608  }
2609  }
2610  }
2611 
2612  // if object is 2D or 3D return this object
2613  if (fH->GetDimension() == 2) {
2614  if (fH->InheritsFrom(TH2Poly::Class())) {
2615  TH2Poly *th2 = (TH2Poly*)fH;
2616  Double_t xmin, ymin, xmax, ymax;
2617  gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
2618  Double_t pxu = gPad->AbsPixeltoX(px);
2619  Double_t pyu = gPad->AbsPixeltoY(py);
2620  if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
2621  curdist = big;
2622  goto FUNCTIONS;
2623  } else {
2624  Int_t bin = th2->FindBin(pxu, pyu);
2625  if (bin>0) curdist = 1;
2626  else curdist = big;
2627  goto FUNCTIONS;
2628  }
2629  }
2630  Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
2631  if ( px > puxmin + delta2
2632  && px < puxmax - delta2
2633  && py > puymax + delta2
2634  && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
2635  }
2636 
2637  // point is inside histogram area. Find channel number
2638  if (gPad->IsVertical()) {
2639  Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
2640  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
2641  Double_t binval = factor*fH->GetBinContent(bin);
2642  Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
2643  if (binval == 0 && pybin < puymin) pybin = 10000;
2644  // special case if more than one bin for the pixel
2645  if (binsup-bin>1) {
2646  Double_t binvalmin, binvalmax;
2647  binvalmin=binval;
2648  binvalmax=binval;
2649  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2650  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2651  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2652  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2653  }
2654  Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
2655  Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
2656  if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
2657  }
2658  if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
2659  } else {
2660  Double_t y = gPad->AbsPixeltoY(py);
2661  Double_t y1 = gPad->AbsPixeltoY(py+1);
2662  Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
2663  Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
2664  Double_t binval = factor*fH->GetBinContent(bin);
2665  Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
2666  if (binval == 0 && pxbin > puxmin) pxbin = 10000;
2667  // special case if more than one bin for the pixel
2668  if (binsup-bin>1) {
2669  Double_t binvalmin, binvalmax;
2670  binvalmin=binval;
2671  binvalmax=binval;
2672  for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
2673  Double_t binvaltmp = factor*fH->GetBinContent(ibin);
2674  if (binvalmin>binvaltmp) binvalmin=binvaltmp;
2675  if (binvalmax<binvaltmp) binvalmax=binvaltmp;
2676  }
2677  Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
2678  Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
2679  if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
2680  }
2681  if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
2682  }
2683  // Loop on the list of associated functions and user objects
2684 FUNCTIONS:
2685  TObject *f;
2687  while ((f = (TObject*) next())) {
2688  Int_t dist;
2689  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
2690  else dist = f->DistancetoPrimitive(px,py);
2691  if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
2692  }
2693  return curdist;
2694 }
2695 
2696 
2697 ////////////////////////////////////////////////////////////////////////////////
2698 /// Display a panel with all histogram drawing options.
2699 
2701 {
2702 
2703  gCurrentHist = fH;
2704  if (!gPad) {
2705  Error("DrawPanel", "need to draw histogram first");
2706  return;
2707  }
2709  editor->Show();
2710  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
2711  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
2712 }
2713 
2714 
2715 ////////////////////////////////////////////////////////////////////////////////
2716 /// Execute the actions corresponding to `event`.
2717 ///
2718 /// This function is called when a histogram is clicked with the locator at
2719 /// the pixel position px,py.
2720 
2721 void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py)
2722 {
2723 
2724  if (!gPad) return;
2725 
2726  static Int_t bin, px1, py1, px2, py2, pyold;
2727  static TBox *zoombox;
2728  Double_t zbx1,zbx2,zby1,zby2;
2729 
2730  Int_t bin1, bin2;
2731  Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
2732  Bool_t opaque = gPad->OpaqueMoving();
2733 
2734  if (!gPad->IsEditable()) return;
2735 
2736  if (fPie) {
2737  fPie->ExecuteEvent(event, px, py);
2738  return;
2739  }
2740  // come here if we have a lego/surface in the pad
2741  TView *view = gPad->GetView();
2742 
2743  if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
2744  view->ExecuteRotateView(event, px, py);
2745  return;
2746  }
2747 
2748  TAxis *xaxis = fH->GetXaxis();
2749  TAxis *yaxis = fH->GetYaxis();
2750  Int_t dimension = fH->GetDimension();
2751 
2752  Double_t factor = 1;
2753  if (fH->GetNormFactor() != 0) {
2754  factor = fH->GetNormFactor()/fH->GetSumOfWeights();
2755  }
2756 
2757  switch (event) {
2758 
2759  case kButton1Down:
2760 
2761  if (!opaque) gVirtualX->SetLineColor(-1);
2762  fH->TAttLine::Modify();
2763 
2764  if (opaque && dimension ==2) {
2765  zbx1 = gPad->AbsPixeltoX(px);
2766  zbx2 = gPad->AbsPixeltoX(px);
2767  zby1 = gPad->AbsPixeltoY(py);
2768  zby2 = gPad->AbsPixeltoY(py);
2769  px1 = px;
2770  py1 = py;
2771  if (gPad->GetLogx()) {
2772  zbx1 = TMath::Power(10,zbx1);
2773  zbx2 = TMath::Power(10,zbx2);
2774  }
2775  if (gPad->GetLogy()) {
2776  zby1 = TMath::Power(10,zby1);
2777  zby2 = TMath::Power(10,zby2);
2778  }
2779  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
2780  Int_t ci = TColor::GetColor("#7d7dff");
2781  TColor *zoomcolor = gROOT->GetColor(ci);
2782  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
2783  else zoomcolor->SetAlpha(0.5);
2784  zoombox->SetFillColor(ci);
2785  zoombox->Draw();
2786  gPad->Modified();
2787  gPad->Update();
2788  }
2789  // No break !!!
2790 
2791  case kMouseMotion:
2792 
2793  if (fShowProjection) {ShowProjection3(px,py); break;}
2794 
2795  gPad->SetCursor(kPointer);
2796  if (dimension ==1) {
2797  if (Hoption.Bar) {
2798  baroffset = fH->GetBarOffset();
2799  barwidth = fH->GetBarWidth();
2800  } else {
2801  baroffset = 0;
2802  barwidth = 1;
2803  }
2804  x = gPad->AbsPixeltoX(px);
2805  bin = fXaxis->FindFixBin(gPad->PadtoX(x));
2806  binwidth = fXaxis->GetBinWidth(bin);
2807  xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
2808  xup = gPad->XtoPad(xlow + barwidth*binwidth);
2809  ylow = gPad->GetUymin();
2810  px1 = gPad->XtoAbsPixel(xlow);
2811  px2 = gPad->XtoAbsPixel(xup);
2812  py1 = gPad->YtoAbsPixel(ylow);
2813  py2 = py;
2814  pyold = py;
2815  if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
2816  }
2817 
2818  break;
2819 
2820  case kButton1Motion:
2821 
2822  if (dimension ==1) {
2823  if (gROOT->GetEditHistograms()) {
2824  if (!opaque) {
2825  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
2826  py2 += py - pyold;
2827  gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
2828  pyold = py;
2829  } else {
2830  py2 += py - pyold;
2831  pyold = py;
2832  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
2833  fH->SetBinContent(bin,binval);
2834  gPad->Modified(kTRUE);
2835  }
2836  }
2837  }
2838 
2839  if (opaque && dimension ==2) {
2840  if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
2841  zbx2 = gPad->AbsPixeltoX(px);
2842  zby2 = gPad->AbsPixeltoY(py);
2843  if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
2844  if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
2845  zoombox->SetX2(zbx2);
2846  zoombox->SetY2(zby2);
2847  gPad->Modified();
2848  gPad->Update();
2849  }
2850  }
2851 
2852  break;
2853 
2854  case kWheelUp:
2855 
2856  if (dimension ==2) {
2857  bin1 = xaxis->GetFirst()+1;
2858  bin2 = xaxis->GetLast()-1;
2859  bin1 = TMath::Max(bin1, 1);
2860  bin2 = TMath::Min(bin2, xaxis->GetNbins());
2861  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
2862  bin1 = yaxis->GetFirst()+1;
2863  bin2 = yaxis->GetLast()-1;
2864  bin1 = TMath::Max(bin1, 1);
2865  bin2 = TMath::Min(bin2, yaxis->GetNbins());
2866  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
2867  }
2868  gPad->Modified();
2869  gPad->Update();
2870 
2871  break;
2872 
2873  case kWheelDown:
2874 
2875  if (dimension == 2) {
2876  bin1 = xaxis->GetFirst()-1;
2877  bin2 = xaxis->GetLast()+1;
2878  bin1 = TMath::Max(bin1, 1);
2879  bin2 = TMath::Min(bin2, xaxis->GetNbins());
2880  if (bin2>bin1) xaxis->SetRange(bin1,bin2);
2881  bin1 = yaxis->GetFirst()-1;
2882  bin2 = yaxis->GetLast()+1;
2883  bin1 = TMath::Max(bin1, 1);
2884  bin2 = TMath::Min(bin2, yaxis->GetNbins());
2885  if (bin2>bin1) yaxis->SetRange(bin1,bin2);
2886  }
2887  gPad->Modified();
2888  gPad->Update();
2889 
2890  break;
2891 
2892  case kButton1Up:
2893  if (dimension ==1) {
2894  if (gROOT->GetEditHistograms()) {
2895  binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
2896  fH->SetBinContent(bin,binval);
2897  PaintInit(); // recalculate Hparam structure and recalculate range
2898  }
2899 
2900  // might resize pad pixmap so should be called before any paint routine
2901  RecalculateRange();
2902  }
2903  if (opaque && dimension ==2) {
2904  if (zoombox) {
2905  Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
2906  Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
2907  Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
2908  Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
2909  x1 = TMath::Max(x1,xaxis->GetXmin());
2910  x2 = TMath::Min(x2,xaxis->GetXmax());
2911  y1 = TMath::Max(y1,yaxis->GetXmin());
2912  y2 = TMath::Min(y2,yaxis->GetXmax());
2913  if (x1<x2 && y1<y2) {
2914  xaxis->SetRangeUser(x1, x2);
2915  yaxis->SetRangeUser(y1, y2);
2916  }
2917  zoombox->Delete();
2918  zoombox = 0;
2919  }
2920  }
2921  gPad->Modified(kTRUE);
2922  if (opaque) gVirtualX->SetLineColor(-1);
2923 
2924  break;
2925 
2926  case kButton1Locate:
2927 
2928  ExecuteEvent(kButton1Down, px, py);
2929 
2930  while (1) {
2931  px = py = 0;
2932  event = gVirtualX->RequestLocator(1, 1, px, py);
2933 
2934  ExecuteEvent(kButton1Motion, px, py);
2935 
2936  if (event != -1) { // button is released
2937  ExecuteEvent(kButton1Up, px, py);
2938  return;
2939  }
2940  }
2941  }
2942 }
2943 
2944 
2945 ////////////////////////////////////////////////////////////////////////////////
2946 /// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
2947 
2949 {
2950 
2951 
2952 
2953  // Check if fH contains a TGraphDelaunay2D
2955  TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
2956  // try with the old painter
2957  TGraphDelaunay *dtOld = nullptr;
2958  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
2959 
2960  if (!dt && !dtOld) return nullptr;
2961 
2962  gCurrentHist = fH;
2963 
2964  if (!fGraph2DPainter) {
2965  if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
2966  else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
2967  }
2968 
2969  return fGraph2DPainter->GetContourList(contour);
2970 }
2971 
2972 
2973 ////////////////////////////////////////////////////////////////////////////////
2974 /// Display the histogram info (bin number, contents, integral up to bin
2975 /// corresponding to cursor position px,py.
2976 
2977 char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
2978 {
2979 
2980  if (!gPad) return (char*)"";
2981  static char info[200];
2982  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
2983  Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
2984  Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
2985  TString drawOption = fH->GetDrawOption();
2986  drawOption.ToLower();
2987  Double_t xmin, xmax, uxmin,uxmax;
2988  Double_t ymin, ymax, uymin,uymax;
2989  if (fH->GetDimension() == 2) {
2990  if (gPad->GetView() || drawOption.Index("cont") >= 0) {
2991  uxmin=gPad->GetUxmin();
2992  uxmax=gPad->GetUxmax();
2993  xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
2994  xmax = fXaxis->GetBinUpEdge(fXaxis->GetLast());
2995  x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
2996  uymin=gPad->GetUymin();
2997  uymax=gPad->GetUymax();
2998  ymin = fYaxis->GetBinLowEdge(fYaxis->GetFirst());
2999  ymax = fYaxis->GetBinUpEdge(fYaxis->GetLast());
3000  y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3001  }
3002  }
3003  Int_t binx,biny,binmin=0,binx1;
3004  if (gPad->IsVertical()) {
3005  binx = fXaxis->FindFixBin(x);
3006  if (drawOption.Index("same") >= 0) {
3007  TH1 *h1;
3008  TIter next(gPad->GetListOfPrimitives());
3009  while ((h1 = (TH1 *)next())) {
3010  if (!h1->InheritsFrom(TH1::Class())) continue;
3011  binmin = h1->GetXaxis()->GetFirst();
3012  break;
3013  }
3014  } else {
3015  binmin = fXaxis->GetFirst();
3016  }
3017  binx1 = fXaxis->FindFixBin(x1);
3018  // special case if more than 1 bin in x per pixel
3019  if (binx1-binx>1 && fH->GetDimension() == 1) {
3020  Double_t binval=fH->GetBinContent(binx);
3021  Int_t binnear=binx;
3022  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3023  Double_t binvaltmp = fH->GetBinContent(ibin);
3024  if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3025  binval=binvaltmp;
3026  binnear=ibin;
3027  }
3028  }
3029  binx = binnear;
3030  }
3031  } else {
3032  x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3033  binx = fXaxis->FindFixBin(y);
3034  if (drawOption.Index("same") >= 0) {
3035  TH1 *h1;
3036  TIter next(gPad->GetListOfPrimitives());
3037  while ((h1 = (TH1 *)next())) {
3038  if (!h1->InheritsFrom(TH1::Class())) continue;
3039  binmin = h1->GetXaxis()->GetFirst();
3040  break;
3041  }
3042  } else {
3043  binmin = fXaxis->GetFirst();
3044  }
3045  binx1 = fXaxis->FindFixBin(x1);
3046  // special case if more than 1 bin in x per pixel
3047  if (binx1-binx>1 && fH->GetDimension() == 1) {
3048  Double_t binval=fH->GetBinContent(binx);
3049  Int_t binnear=binx;
3050  for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3051  Double_t binvaltmp = fH->GetBinContent(ibin);
3052  if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3053  binval=binvaltmp;
3054  binnear=ibin;
3055  }
3056  }
3057  binx = binnear;
3058  }
3059  }
3060  if (fH->GetDimension() == 1) {
3061  if (fH->InheritsFrom(TProfile::Class())) {
3062  TProfile *tp = (TProfile*)fH;
3063  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3064  x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3065  (Int_t) tp->GetBinEntries(binx));
3066  }
3067  else {
3068  Double_t integ = 0;
3069  for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3070  snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3071  x,y,binx,fH->GetBinContent(binx),integ);
3072  }
3073  } else if (fH->GetDimension() == 2) {
3074  if (fH->InheritsFrom(TH2Poly::Class())) {
3075  TH2Poly *th2 = (TH2Poly*)fH;
3076  biny = th2->FindBin(x,y);
3077  snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3078  th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3079  }
3080  else if (fH->InheritsFrom(TProfile2D::Class())) {
3081  TProfile2D *tp = (TProfile2D*)fH;
3082  biny = fYaxis->FindFixBin(y);
3083  Int_t bin = fH->GetBin(binx,biny);
3084  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3085  x, y, binx, biny, fH->GetBinContent(bin),
3086  fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3087  } else {
3088  biny = fYaxis->FindFixBin(y);
3089  snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3090  x,y,binx,biny,fH->GetBinContent(binx,biny),
3091  fH->GetBinError(binx,biny));
3092  }
3093  } else {
3094  // 3d case: retrieving the x,y,z bin is not yet implemented
3095  // print just the x,y info
3096  snprintf(info,200,"(x=%g, y=%g)",x,y);
3097  }
3098  return info;
3099 }
3100 
3101 
3102 ////////////////////////////////////////////////////////////////////////////////
3103 /// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3104 
3106 {
3107 
3108  for (Int_t i=0;i<fNcuts;i++) {
3109  Double_t x = fXaxis->GetBinCenter(ix);
3110  Double_t y = fYaxis->GetBinCenter(iy);
3111  if (fCutsOpt[i] > 0) {
3112  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3113  } else {
3114  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3115  }
3116  }
3117  return kTRUE;
3118 }
3119 
3120 
3121 ////////////////////////////////////////////////////////////////////////////////
3122 /// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3123 
3125 {
3126 
3127  for (Int_t i=0;i<fNcuts;i++) {
3128  if (fCutsOpt[i] > 0) {
3129  if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3130  } else {
3131  if (fCuts[i]->IsInside(x,y)) return kFALSE;
3132  }
3133  }
3134  return kTRUE;
3135 }
3136 
3137 
3138 ////////////////////////////////////////////////////////////////////////////////
3139 /// Decode string `choptin` and fill Hoption structure.
3140 
3142 {
3143 
3144  char *l;
3145  char chopt[128];
3146  Int_t nch = strlen(choptin);
3147  strlcpy(chopt,choptin,128);
3148  Int_t hdim = fH->GetDimension();
3149 
3150  Hoption.Axis = Hoption.Bar = Hoption.Curve = Hoption.Error = 0;
3151  Hoption.Hist = Hoption.Line = Hoption.Mark = Hoption.Fill = 0;
3152  Hoption.Same = Hoption.Func = Hoption.Scat = 0;
3153  Hoption.Star = Hoption.Arrow = Hoption.Box = Hoption.Text = 0;
3154  Hoption.Char = Hoption.Color = Hoption.Contour = Hoption.Logx = 0;
3155  Hoption.Logy = Hoption.Logz = Hoption.Lego = Hoption.Surf = 0;
3156  Hoption.Off = Hoption.Tri = Hoption.Proj = Hoption.AxisPos = 0;
3157  Hoption.Spec = Hoption.Pie = Hoption.Candle = Hoption.Violin = 0;
3158 
3159  // special 2D options
3160  Hoption.List = 0;
3161  Hoption.Zscale = 0;
3162  Hoption.FrontBox = 1;
3163  Hoption.BackBox = 1;
3164  Hoption.System = kCARTESIAN;
3165 
3166  Hoption.Zero = 0;
3167 
3168  //check for graphical cuts
3169  MakeCuts(chopt);
3170 
3171  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3172  if (hdim > 1) Hoption.Scat = 1;
3173  if (!nch) Hoption.Hist = 1;
3174  if (fFunctions->First()) Hoption.Func = 1;
3175  if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3176 
3177  l = strstr(chopt,"SPEC");
3178  if (l) {
3179  Hoption.Scat = 0;
3180  strncpy(l," ",4);
3181  Int_t bs=0;
3182  l = strstr(chopt,"BF(");
3183  if (l) {
3184  if (sscanf(&l[3],"%d",&bs) > 0) {
3185  Int_t i=0;
3186  while (l[i]!=')') {
3187  l[i] = ' ';
3188  i++;
3189  }
3190  l[i] = ' ';
3191  }
3192  }
3193  Hoption.Spec = TMath::Max(1600,bs);
3194  return 1;
3195  }
3196 
3197  l = strstr(chopt,"GL");
3198  if (l) {
3199  strncpy(l," ",2);
3200  }
3201  l = strstr(chopt,"X+");
3202  if (l) {
3203  Hoption.AxisPos = 10;
3204  strncpy(l," ",2);
3205  }
3206  l = strstr(chopt,"Y+");
3207  if (l) {
3208  Hoption.AxisPos += 1;
3209  strncpy(l," ",2);
3210  }
3211  if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
3212  if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
3213 
3214  l = strstr(chopt,"SAMES");
3215  if (l) {
3216  if (nch == 5) Hoption.Hist = 1;
3217  Hoption.Same = 2;
3218  strncpy(l," ",5);
3219  }
3220  l = strstr(chopt,"SAME");
3221  if (l) {
3222  if (nch == 4) Hoption.Hist = 1;
3223  Hoption.Same = 1;
3224  strncpy(l," ",4);
3225  }
3226 
3227  l = strstr(chopt,"PIE");
3228  if (l) {
3229  Hoption.Pie = 1;
3230  strncpy(l," ",3);
3231  }
3232 
3233  l = strstr(chopt,"CANDLE");
3234  if (l) {
3235  Hoption.Scat = 0;
3236  Hoption.Candle = 1;
3237  strncpy(l," ",6);
3238  if (l[6] == 'X') { Hoption.Candle = 1; l[6] = ' '; }
3239  if (l[6] == 'Y') { Hoption.Candle = 2; l[6] = ' '; }
3240  }
3241 
3242  l = strstr(chopt,"VIOLIN");
3243  if (l) {
3244  Hoption.Scat = 0;
3245  Hoption.Violin = 1;
3246  strncpy(l," ",6);
3247  if (l[6] == 'X') { Hoption.Violin = 1; l[6] = ' '; }
3248  if (l[6] == 'Y') { Hoption.Violin = 2; l[6] = ' '; }
3249  }
3250 
3251  l = strstr(chopt,"LEGO");
3252  if (l) {
3253  Hoption.Scat = 0;
3254  Hoption.Lego = 1; strncpy(l," ",4);
3255  if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
3256  if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
3257  if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
3258  if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
3259  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3260  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3261  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3262  }
3263 
3264  l = strstr(chopt,"SURF");
3265  if (l) {
3266  Hoption.Scat = 0;
3267  Hoption.Surf = 1; strncpy(l," ",4);
3268  if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
3269  if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
3270  if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
3271  if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
3272  if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
3273  if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
3274  if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
3275  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3276  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3277  }
3278 
3279  l = strstr(chopt,"TF3");
3280  if (l) {
3281  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3282  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3283  }
3284 
3285  l = strstr(chopt,"ISO");
3286  if (l) {
3287  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3288  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3289  }
3290 
3291  l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; strncpy(l," ",4);}
3292 
3293  l = strstr(chopt,"CONT");
3294  if (l) {
3295  strncpy(l," ",4);
3296  if (hdim>1) {
3297  Hoption.Scat = 0;
3298  Hoption.Contour = 1;
3299  if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
3300  if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
3301  if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
3302  if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
3303  if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
3304  } else {
3305  Hoption.Hist = 1;
3306  }
3307  }
3308  l = strstr(chopt,"HBAR");
3309  if (l) {
3310  Hoption.Hist = 0;
3311  Hoption.Bar = 20; strncpy(l," ",4);
3312  if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
3313  if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
3314  if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
3315  if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
3316  }
3317  l = strstr(chopt,"BAR");
3318  if (l) {
3319  Hoption.Hist = 0;
3320  Hoption.Bar = 10; strncpy(l," ",3);
3321  if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
3322  if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
3323  if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
3324  if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
3325  }
3326 
3327  l = strstr(chopt,"ARR" );
3328  if (l) {
3329  strncpy(l," ", 3);
3330  if (hdim>1) {
3331  Hoption.Arrow = 1;
3332  Hoption.Scat = 0;
3333  } else {
3334  Hoption.Hist = 1;
3335  }
3336  }
3337  l = strstr(chopt,"BOX" );
3338  if (l) {
3339  strncpy(l," ", 3);
3340  if (hdim>1) {
3341  Hoption.Scat = 0;
3342  Hoption.Box = 1;
3343  if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
3344  } else {
3345  Hoption.Hist = 1;
3346  }
3347  }
3348  l = strstr(chopt,"COLZ");
3349  if (l) {
3350  strncpy(l," ",4);
3351  if (hdim>1) {
3352  Hoption.Color = 1;
3353  Hoption.Scat = 0;
3354  Hoption.Zscale = 1;
3355  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3356  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3357  } else {
3358  Hoption.Hist = 1;
3359  }
3360  }
3361  l = strstr(chopt,"COL" );
3362  if (l) {
3363  strncpy(l," ", 3);
3364  if (hdim>1) {
3365  Hoption.Color = 1;
3366  Hoption.Scat = 0;
3367  l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; strncpy(l," ",1); }
3368  l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; strncpy(l," ",1); }
3369  } else {
3370  Hoption.Hist = 1;
3371  }
3372  }
3373  l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; strncpy(l," ",4); Hoption.Scat = 0; }
3374  l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; strncpy(l," ",4); Hoption.Hist = 0; }
3375  l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; strncpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
3376  l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; strncpy(l," ",4); }
3377  l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; strncpy(l," ",4); }
3378  l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; strncpy(l," ",4); }
3379  l = strstr(chopt,"TEXT");
3380  if (l) {
3381  Int_t angle;
3382  if (sscanf(&l[4],"%d",&angle) > 0) {
3383  if (angle < 0) angle=0;
3384  if (angle > 90) angle=90;
3385  Hoption.Text = 1000+angle;
3386  } else {
3387  Hoption.Text = 1;
3388  }
3389  strncpy(l," ", 4);
3390  l = strstr(chopt,"N");
3391  if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
3392  Hoption.Scat = 0;
3393  }
3394  l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; strncpy(l," ",3); }
3395  l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; strncpy(l," ",3); }
3396  l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; strncpy(l," ",3); }
3397  l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; strncpy(l," ",3); }
3398 
3399  l = strstr(chopt,"TRI");
3400  if (l) {
3401  Hoption.Scat = 0;
3402  Hoption.Color = 0;
3403  Hoption.Tri = 1; strncpy(l," ",3);
3404  l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; strncpy(l," ",2); }
3405  l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; strncpy(l," ",2); }
3406  l = strstr(chopt,"ERR"); if (l) strncpy(l," ",3);
3407  }
3408 
3409  l = strstr(chopt,"AITOFF");
3410  if (l) {
3411  Hoption.Proj = 1; strncpy(l," ",6); //Aitoff projection
3412  }
3413  l = strstr(chopt,"MERCATOR");
3414  if (l) {
3415  Hoption.Proj = 2; strncpy(l," ",8); //Mercator projection
3416  }
3417  l = strstr(chopt,"SINUSOIDAL");
3418  if (l) {
3419  Hoption.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
3420  }
3421  l = strstr(chopt,"PARABOLIC");
3422  if (l) {
3423  Hoption.Proj = 4; strncpy(l," ",9); //Parabolic projection
3424  }
3425  if (Hoption.Proj > 0) {
3426  Hoption.Scat = 0;
3427  Hoption.Contour = 14;
3428  }
3429 
3430  if (strstr(chopt,"A")) Hoption.Axis = -1;
3431  if (strstr(chopt,"B")) Hoption.Bar = 1;
3432  if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
3433  if (strstr(chopt,"F")) Hoption.Fill =1;
3434  if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
3435  if (strstr(chopt,"F2")) Hoption.Fill =2;
3436  if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
3437  if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
3438  if (strstr(chopt,"Z")) Hoption.Zscale =1;
3439  if (strstr(chopt,"*")) Hoption.Star =1;
3440  if (strstr(chopt,"H")) Hoption.Hist =2;
3441  if (strstr(chopt,"P0")) Hoption.Mark =10;
3442 
3443  if (fH->InheritsFrom(TH2Poly::Class())) {
3444  if (Hoption.Fill+Hoption.Line+Hoption.Mark != 0 ) Hoption.Scat = 0;
3445  }
3446 
3447  if (strstr(chopt,"E")) {
3448  if (hdim == 1) {
3449  Hoption.Error = 1;
3450  if (strstr(chopt,"E0")) Hoption.Error = 10;
3451  if (strstr(chopt,"E1")) Hoption.Error = 11;
3452  if (strstr(chopt,"E2")) Hoption.Error = 12;
3453  if (strstr(chopt,"E3")) Hoption.Error = 13;
3454  if (strstr(chopt,"E4")) Hoption.Error = 14;
3455  if (strstr(chopt,"E5")) Hoption.Error = 15;
3456  if (strstr(chopt,"E6")) Hoption.Error = 16;
3457  if (strstr(chopt,"X0")) {
3458  if (Hoption.Error == 1) Hoption.Error += 20;
3459  Hoption.Error += 10;
3460  }
3461  if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
3462  Hoption.Text += 2000;
3463  Hoption.Error = 0;
3464  }
3465  } else {
3466  if (Hoption.Error == 0) {
3467  Hoption.Error = 100;
3468  Hoption.Scat = 0;
3469  }
3470  if (Hoption.Text) {
3471  Hoption.Text += 2000;
3472  Hoption.Error = 0;
3473  }
3474  }
3475  }
3476 
3477  if (Hoption.Surf == 15) {
3478  if (Hoption.System == kPOLAR || Hoption.System == kCARTESIAN) {
3479  Hoption.Surf = 13;
3480  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
3481  }
3482  }
3483 
3484  // Copy options from current style
3485  Hoption.Logx = gPad->GetLogx();
3486  Hoption.Logy = gPad->GetLogy();
3487  Hoption.Logz = gPad->GetLogz();
3488 
3489  // Check options incompatibilities
3490  if (Hoption.Bar == 1) Hoption.Hist = -1;
3491  return 1;
3492 }
3493 
3494 
3495 ////////////////////////////////////////////////////////////////////////////////
3496 /// Decode string `choptin` and fill Graphical cuts structure.
3497 
3498 Int_t THistPainter::MakeCuts(char *choptin)
3499 {
3500 
3501  fNcuts = 0;
3502  char *left = (char*)strchr(choptin,'[');
3503  if (!left) return 0;
3504  char *right = (char*)strchr(choptin,']');
3505  if (!right) return 0;
3506  Int_t nch = right-left;
3507  if (nch < 2) return 0;
3508  char *cuts = left+1;
3509  *right = 0;
3510  char *comma, *minus;
3511  Int_t i;
3512  while (1) {
3513  comma = strchr(cuts,',');
3514  if (comma) *comma = 0;
3515  minus = strchr(cuts,'-');
3516  if (minus) cuts = minus+1;
3517  while (*cuts == ' ') cuts++;
3518  Int_t nc = strlen(cuts);
3519  while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
3520  TIter next(gROOT->GetListOfSpecials());
3521  TCutG *cut=0;
3522  TObject *obj;
3523  while ((obj = next())) {
3524  if (!obj->InheritsFrom(TCutG::Class())) continue;
3525  if (strcmp(obj->GetName(),cuts)) continue;
3526  cut = (TCutG*)obj;
3527  break;
3528  }
3529  if (cut) {
3530  fCuts[fNcuts] = cut;
3531  fCutsOpt[fNcuts] = 1;
3532  if (minus) fCutsOpt[fNcuts] = -1;
3533  fNcuts++;
3534  }
3535  if (!comma) break;
3536  cuts = comma+1;
3537  }
3538  for (i=0;i<=nch;i++) left[i] = ' ';
3539  return fNcuts;
3540 }
3541 
3542 
3543 ////////////////////////////////////////////////////////////////////////////////
3544 /// [Control routine to paint any kind of histograms](#HP00)
3545 
3546 void THistPainter::Paint(Option_t *option)
3547 {
3548 
3549  if (fH->GetBuffer()) fH->BufferEmpty(-1);
3550 
3551  //For iOS: put the histogram on the top of stack of pickable objects.
3552  const TPickerStackGuard topPush(fH);
3553 
3554  gPad->SetVertical(kTRUE);
3555 
3556  TH1 *oldhist = gCurrentHist;
3557  gCurrentHist = fH;
3558  TH1 *hsave = fH;
3559  Double_t minsav = fH->GetMinimumStored();
3560 
3561  if (!MakeChopt(option)) return; //check options and fill Hoption structure
3562 
3563  // Paint using TSpectrum2Painter
3564  if (Hoption.Spec) {
3565  if (!TableInit()) return;
3566  if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
3567  gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
3568  (ULong_t)fH, option, Hoption.Spec));
3569  return;
3570  }
3571 
3572  if (Hoption.Pie) {
3573  if (fH->GetDimension() == 1) {
3574  if (!fPie) fPie = new TPie(fH);
3575  fPie->Paint(option);
3576  } else {
3577  Error("Paint", "Option PIE is for 1D histograms only");
3578  }
3579  return;
3580  } else {
3581  if (fPie) delete fPie;
3582  fPie = 0;
3583  }
3584 
3585  fXbuf = new Double_t[kNMAX];
3586  fYbuf = new Double_t[kNMAX];
3587  if (fH->GetDimension() > 2) {
3588  PaintH3(option);
3589  fH->SetMinimum(minsav);
3590  if (Hoption.Func) {
3591  Hoption_t hoptsave = Hoption;
3592  Hparam_t hparsave = Hparam;
3593  PaintFunction(option);
3594  SetHistogram(hsave);
3595  Hoption = hoptsave;
3596  Hparam = hparsave;
3597  }
3598  gCurrentHist = oldhist;
3599  delete [] fXbuf; delete [] fYbuf;
3600  return;
3601  }
3602  TView *view = gPad->GetView();
3603  if (view) {
3604  if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
3605  delete view;
3606  gPad->SetView(0);
3607  }
3608  }
3609  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
3610  // In case of 1D histogram, Z axis becomes Y axis.
3611  Int_t logysav=0, logzsav=0;
3612  if (fH->GetDimension() == 1) {
3613  logysav = Hoption.Logy;
3614  logzsav = Hoption.Logz;
3615  Hoption.Logz = 0;
3616  if (Hoption.Logy) {
3617  Hoption.Logz = 1;
3618  Hoption.Logy = 0;
3619  }
3620  }
3621  PaintTable(option);
3622  fH->SetMinimum(minsav);
3623  if (Hoption.Func) {
3624  Hoption_t hoptsave = Hoption;
3625  Hparam_t hparsave = Hparam;
3626  PaintFunction(option);
3627  SetHistogram(hsave);
3628  Hoption = hoptsave;
3629  Hparam = hparsave;
3630  }
3631  gCurrentHist = oldhist;
3632  delete [] fXbuf; delete [] fYbuf;
3633  if (fH->GetDimension() == 1) {
3634  Hoption.Logy = logysav;
3635  Hoption.Logz = logzsav;
3636  }
3637  return;
3638  }
3639 
3640  if (Hoption.Bar >= 20) {PaintBarH(option);
3641  delete [] fXbuf; delete [] fYbuf;
3642  return;
3643  }
3644 
3645  // fill Hparam structure with histo parameters
3646  if (!PaintInit()) {
3647  delete [] fXbuf; delete [] fYbuf;
3648  return;
3649  }
3650 
3651  // Picture surround (if new page) and page number (if requested).
3652  // Histogram surround (if not option "Same").
3653  PaintFrame();
3654 
3655  // Paint histogram axis only
3656  Bool_t gridx = gPad->GetGridx();
3657  Bool_t gridy = gPad->GetGridy();
3658  if (Hoption.Axis > 0) {
3659  if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
3660  else {
3661  if (gridx) gPad->SetGridx(0);
3662  if (gridy) gPad->SetGridy(0);
3663  PaintAxis(kFALSE);
3664  if (gridx) gPad->SetGridx(1);
3665  if (gridy) gPad->SetGridy(1);
3666  }
3667  if (Hoption.Same ==1) Hoption.Same = 2;
3668  goto paintstat;
3669  }
3670  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
3671 
3672  // test for options BAR or HBAR
3673  if (Hoption.Bar >= 10) {
3674  PaintBar(option);
3675  }
3676 
3677  // do not draw histogram if error bars required
3678  if (!Hoption.Error) {
3679  if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
3680  }
3681 
3682  // test for error bars or option E
3683  if (Hoption.Error) {
3684  PaintErrors(option);
3685  if (Hoption.Hist == 2) PaintHist(option);
3686  }
3687 
3688  if (Hoption.Text) PaintText(option);
3689 
3690  // test for associated function
3691  if (Hoption.Func) {
3692  Hoption_t hoptsave = Hoption;
3693  Hparam_t hparsave = Hparam;
3694  PaintFunction(option);
3695  SetHistogram(hsave);
3696  Hoption = hoptsave;
3697  Hparam = hparsave;
3698  }
3699 
3700  if (gridx) gPad->SetGridx(0);
3701  if (gridy) gPad->SetGridy(0);
3702  PaintAxis(kFALSE);
3703  if (gridx) gPad->SetGridx(1);
3704  if (gridy) gPad->SetGridy(1);
3705 
3706  PaintTitle(); // Draw histogram title
3707 
3708  // Draw box with histogram statistics and/or fit parameters
3709 paintstat:
3710  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
3712  TObject *obj = 0;
3713  while ((obj = next())) {
3714  if (obj->InheritsFrom(TF1::Class())) break;
3715  obj = 0;
3716  }
3717 
3718  //Stat is painted twice (first, it will be in canvas' list of primitives),
3719  //second, it will be here, this is not required on iOS.
3720  //Condition is ALWAYS true on a platform different from iOS.
3721  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
3722  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
3723  }
3724  fH->SetMinimum(minsav);
3725  gCurrentHist = oldhist;
3726  delete [] fXbuf; fXbuf = 0;
3727  delete [] fYbuf; fYbuf = 0;
3728 
3729 }
3730 
3731 
3732 ////////////////////////////////////////////////////////////////////////////////
3733 /// [Control function to draw a table as an arrow plot](#HP12)
3734 
3736 {
3737 
3738  Style_t linesav = fH->GetLineStyle();
3739  Width_t widthsav = fH->GetLineWidth();
3740  fH->SetLineStyle(1);
3742  fH->TAttLine::Modify();
3743 
3744  Double_t xk, xstep, yk, ystep;
3745  Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
3746  Int_t ncx = Hparam.xlast - Hparam.xfirst + 1;
3747  Int_t ncy = Hparam.ylast - Hparam.yfirst + 1;
3748  Double_t xrg = gPad->GetUxmin();
3749  Double_t yrg = gPad->GetUymin();
3750  Double_t xln = gPad->GetUxmax() - xrg;
3751  Double_t yln = gPad->GetUymax() - yrg;
3752  Double_t cx = (xln/Double_t(ncx) -0.03)/2;
3753  Double_t cy = (yln/Double_t(ncy) -0.03)/2;
3754  Double_t dn = 1.E-30;
3755 
3756  for (Int_t id=1;id<=2;id++) {
3757  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
3758  yk = fYaxis->GetBinLowEdge(j);
3759  ystep = fYaxis->GetBinWidth(j);
3760  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
3761  xk = fXaxis->GetBinLowEdge(i);
3762  xstep = fXaxis->GetBinWidth(i);
3763  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
3764  if (i == Hparam.xfirst) {
3765  dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
3766  } else if (i == Hparam.xlast) {
3767  dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
3768  } else {
3769  dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
3770  }
3771  if (j == Hparam.yfirst) {
3772  dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
3773  } else if (j == Hparam.ylast) {
3774  dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
3775  } else {
3776  dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
3777  }
3778  if (id == 1) {
3779  dn = TMath::Max(dn, TMath::Abs(dx));
3780  dn = TMath::Max(dn, TMath::Abs(dy));
3781  } else if (id == 2) {
3782  xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
3783  dxn = cx*dx/dn;
3784  x1 = xc - dxn;
3785  x2 = xc + dxn;
3786  yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
3787  dyn = cy*dy/dn;
3788  y1 = yc - dyn;
3789  y2 = yc + dyn;
3790  fXbuf[0] = x1;
3791  fXbuf[1] = x2;
3792  fYbuf[0] = y1;
3793  fYbuf[1] = y2;
3794  if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
3795  anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
3796  si = anr*(dxn + dyn);
3797  co = anr*(dxn - dyn);
3798  fXbuf[2] = x2 - si;
3799  fYbuf[2] = y2 + co;
3800  gPad->PaintPolyLine(3, fXbuf, fYbuf);
3801  fXbuf[0] = x2;
3802  fXbuf[1] = x2 - co;
3803  fYbuf[0] = y2;
3804  fYbuf[1] = y2 - si;
3805  gPad->PaintPolyLine(2, fXbuf, fYbuf);
3806  }
3807  else {
3808  gPad->PaintPolyLine(2, fXbuf, fYbuf);
3809  }
3810  }
3811  }
3812  }
3813  }
3814 
3815  if (Hoption.Zscale) PaintPalette();
3816  fH->SetLineStyle(linesav);
3817  fH->SetLineWidth(widthsav);
3818  fH->TAttLine::Modify();
3819 }
3820 
3821 
3822 ////////////////////////////////////////////////////////////////////////////////
3823 /// Draw axis (2D case) of an histogram.
3824 ///
3825 /// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
3826 /// to draw the grid and the axis separately. In `THistPainter::Paint` this
3827 /// feature is used to make sure that the grid is drawn in the background and
3828 /// the axis tick marks in the foreground of the pad.
3829 
3830 void THistPainter::PaintAxis(Bool_t drawGridOnly)
3831 {
3832 
3833  //On iOS, grid should not be picable and can not be highlighted.
3834  //Condition is never true on a platform different from iOS.
3835  if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
3836  return;
3837 
3838  if (Hoption.Axis == -1) return;
3839  if (Hoption.Same && Hoption.Axis <= 0) return;
3840 
3841  // Repainting alphanumeric labels axis on a plot done with
3842  // the option HBAR (horizontal) needs some adjustements.
3843  TAxis *xaxis = 0;
3844  TAxis *yaxis = 0;
3845  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
3846  if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
3847  TIter next(gPad->GetListOfPrimitives());
3848  TObject *obj;
3849  // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
3850  while ((obj = next())) {
3851  if (!obj->InheritsFrom(TH1::Class()) &&
3852  !obj->InheritsFrom(THStack::Class())) continue;
3853  TString opt = obj->GetDrawOption();
3854  opt.ToLower();
3855  // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
3856  if (strstr(opt,"hbar")) {
3857  gPad->SetVertical(kFALSE);
3858  xaxis = fXaxis;
3859  yaxis = fYaxis;
3860  if (!strcmp(xaxis->GetName(),"xaxis")) {
3861  fXaxis = yaxis;
3862  fYaxis = xaxis;
3863  }
3864  }
3865  break;
3866  }
3867  }
3868  }
3869 
3870  static char chopt[10] = "";
3871  Double_t gridl = 0;
3872  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
3873  Int_t useHparam = 0;
3874  Double_t umin, umax, uminsave, umaxsave;
3875  Short_t xAxisPos = Hoption.AxisPos/10;
3876  Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
3877 
3878  Double_t axmin = gPad->GetUxmin();
3879  Double_t axmax = gPad->GetUxmax();
3880  Double_t aymin = gPad->GetUymin();
3881  Double_t aymax = gPad->GetUymax();
3882  char *cw = 0;
3883  TGaxis axis;
3884 
3885  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
3886  // Hparam must be use for the axis limits.
3887  if (Hoption.Contour == 14) useHparam = 1;
3888  if (Hoption.Same) {
3889  TObject *obj;
3890  TIter next(gPad->GetListOfPrimitives());
3891  while ((obj=next())) {
3892  if (strstr(obj->GetDrawOption(),"cont4")) {
3893  useHparam = 1;
3894  break;
3895  }
3896  }
3897  }
3898 
3899  // Paint X axis
3900 
3901  //To make X-axis selectable on iOS device.
3902  if (gPad->PadInSelectionMode())
3903  gPad->PushSelectableObject(fXaxis);
3904 
3905  //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
3906  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
3907  ndivx = fXaxis->GetNdivisions();
3908  if (ndivx > 1000) {
3909  nx2 = ndivx/100;
3910  nx1 = TMath::Max(1, ndivx%100);
3911  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
3912  }
3913  axis.SetTextAngle(0);
3915 
3916  chopt[0] = 0;
3917  strlcat(chopt, "SDH",10);
3918  if (ndivx < 0) strlcat(chopt, "N",10);
3919  if (gPad->GetGridx()) {
3920  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
3921  strlcat(chopt, "W",10);
3922  }
3923 
3924  // Define X-Axis limits
3925  if (Hoption.Logx) {
3926  strlcat(chopt, "G",10);
3927  ndiv = TMath::Abs(ndivx);
3928  if (useHparam) {
3929  umin = TMath::Power(10,Hparam.xmin);
3930  umax = TMath::Power(10,Hparam.xmax);
3931  } else {
3932  umin = TMath::Power(10,axmin);
3933  umax = TMath::Power(10,axmax);
3934  }
3935  } else {
3936  ndiv = TMath::Abs(ndivx);
3937  if (useHparam) {
3938  umin = Hparam.xmin;
3939  umax = Hparam.xmax;
3940  } else {
3941  umin = axmin;
3942  umax = axmax;
3943  }
3944  }
3945 
3946  // Display axis as time
3947  if (fXaxis->GetTimeDisplay()) {
3948  strlcat(chopt,"t",10);
3949  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
3950  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam.xmax-Hparam.xmin));
3951  }
3952  }
3953 
3954  // The main X axis can be on the bottom or on the top of the pad
3955  Double_t xAxisYPos1, xAxisYPos2;
3956  if (xAxisPos == 1) {
3957  // Main X axis top
3958  xAxisYPos1 = aymax;
3959  xAxisYPos2 = aymin;
3960  } else {
3961  // Main X axis bottom
3962  xAxisYPos1 = aymin;
3963  xAxisYPos2 = aymax;
3964  }
3965 
3966  // Paint the main X axis (always)
3967  uminsave = umin;
3968  umaxsave = umax;
3969  ndivsave = ndiv;
3970  axis.SetOption(chopt);
3971  if (xAxisPos) {
3972  strlcat(chopt, "-",10);
3973  gridl = -gridl;
3974  }
3975  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
3976  axis.SetLabelSize(0.);
3977  axis.SetTitle("");
3978  }
3979  axis.PaintAxis(axmin, xAxisYPos1,
3980  axmax, xAxisYPos1,
3981  umin, umax, ndiv, chopt, gridl, drawGridOnly);
3982 
3983  // Paint additional X axis (if needed)
3984  // On iOS, this additional X axis is neither pickable, nor highlighted.
3985  // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
3986  if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
3987  if (xAxisPos) {
3988  cw=strstr(chopt,"-");
3989  *cw='z';
3990  } else {
3991  strlcat(chopt, "-",10);
3992  }
3993  if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
3994  if ((cw=strstr(chopt,"W"))) *cw='z';
3995  axis.SetTitle("");
3996  axis.PaintAxis(axmin, xAxisYPos2,
3997  axmax, xAxisYPos2,
3998  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
3999  }
4000  }//End of "if pad in selection mode etc".
4001 
4002  // Paint Y axis
4003  //On iOS, Y axis must pushed into the stack of selectable objects.
4004  if (gPad->PadInSelectionMode())
4005  gPad->PushSelectableObject(fYaxis);
4006 
4007  //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4008  if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4009  ndivy = fYaxis->GetNdivisions();
4011 
4012  chopt[0] = 0;
4013  strlcat(chopt, "SDH",10);
4014  if (ndivy < 0) strlcat(chopt, "N",10);
4015  if (gPad->GetGridy()) {
4016  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4017  strlcat(chopt, "W",10);
4018  }
4019 
4020  // Define Y-Axis limits
4021  if (Hoption.Logy) {
4022  strlcat(chopt, "G",10);
4023  ndiv = TMath::Abs(ndivy);
4024  if (useHparam) {
4025  umin = TMath::Power(10,Hparam.ymin);
4026  umax = TMath::Power(10,Hparam.ymax);
4027  } else {
4028  umin = TMath::Power(10,aymin);
4029  umax = TMath::Power(10,aymax);
4030  }
4031  } else {
4032  ndiv = TMath::Abs(ndivy);
4033  if (useHparam) {
4034  umin = Hparam.ymin;
4035  umax = Hparam.ymax;
4036  } else {
4037  umin = aymin;
4038  umax = aymax;
4039  }
4040  }
4041 
4042  // Display axis as time
4043  if (fYaxis->GetTimeDisplay()) {
4044  strlcat(chopt,"t",10);
4045  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4046  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam.ymax-Hparam.ymin));
4047  }
4048  }
4049 
4050  // The main Y axis can be on the left or on the right of the pad
4051  Double_t yAxisXPos1, yAxisXPos2;
4052  if (yAxisPos == 1) {
4053  // Main Y axis left
4054  yAxisXPos1 = axmax;
4055  yAxisXPos2 = axmin;
4056  } else {
4057  // Main Y axis right
4058  yAxisXPos1 = axmin;
4059  yAxisXPos2 = axmax;
4060  }
4061 
4062  // Paint the main Y axis (always)
4063  uminsave = umin;
4064  umaxsave = umax;
4065  ndivsave = ndiv;
4066  axis.SetOption(chopt);
4067  if (yAxisPos) {
4068  strlcat(chopt, "+L",10);
4069  gridl = -gridl;
4070  }
4071  if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4072  axis.SetLabelSize(0.);
4073  axis.SetTitle("");
4074  }
4075  axis.PaintAxis(yAxisXPos1, aymin,
4076  yAxisXPos1, aymax,
4077  umin, umax, ndiv, chopt, gridl, drawGridOnly);
4078 
4079  // Paint the additional Y axis (if needed)
4080  // Additional checks for pad mode are required on iOS: this "second" axis is
4081  // neither pickable, nor highlihted. Additional checks have no effect on non-iOS platform.
4082  if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4083  if (gPad->GetTicky() < 2) {
4084  strlcat(chopt, "U",10);
4085  axis.SetTickSize(-fYaxis->GetTickLength());
4086  } else {
4087  strlcat(chopt, "+L",10);
4088  }
4089  if ((cw=strstr(chopt,"W"))) *cw='z';
4090  axis.SetTitle("");
4091  axis.PaintAxis(yAxisXPos2, aymin,
4092  yAxisXPos2, aymax,
4093  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4094  }
4095  }//End of "if pad is in selection mode etc."
4096 
4097  // Reset the axis if they have been inverted in case of option HBAR
4098  if (xaxis) {
4099  fXaxis = xaxis;
4100  fYaxis = yaxis;
4101  }
4102 }
4103 
4104 
4105 ////////////////////////////////////////////////////////////////////////////////
4106 /// [Draw a bar-chart in a normal pad.](#HP10)
4107 
4109 {
4110 
4111  Int_t bar = Hoption.Bar - 10;
4112  Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4115  TBox box;
4116  Int_t hcolor = fH->GetFillColor();
4117  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4118  Int_t hstyle = fH->GetFillStyle();
4119  box.SetFillColor(hcolor);
4120  box.SetFillStyle(hstyle);
4121  for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4122  y = fH->GetBinContent(bin);
4123  xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4124  xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4125  ymin = gPad->GetUymin();
4126  ymax = gPad->YtoPad(y);
4127  if (ymax < gPad->GetUymin()) continue;
4128  if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4129  if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4130  if (gStyle->GetHistMinimumZero() && ymin < 0)
4131  ymin=TMath::Min(0.,gPad->GetUymax());
4132  w = (xmax-xmin)*width;
4133  xmin += offset*(xmax-xmin);
4134  xmax = xmin + w;
4135  if (bar < 1) {
4136  box.PaintBox(xmin,ymin,xmax,ymax);
4137  } else {
4138  umin = xmin + bar*(xmax-xmin)/10.;
4139  umax = xmax - bar*(xmax-xmin)/10.;
4140  //box.SetFillColor(hcolor+150); //bright
4141  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4142  box.PaintBox(xmin,ymin,umin,ymax);
4143  box.SetFillColor(hcolor);
4144  box.PaintBox(umin,ymin,umax,ymax);
4145  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4146  box.PaintBox(umax,ymin,xmax,ymax);
4147  }
4148  }
4149 }
4150 
4151 
4152 ////////////////////////////////////////////////////////////////////////////////
4153 /// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4154 
4156 {
4157 
4158  gPad->SetVertical(kFALSE);
4159 
4160  PaintInitH();
4162  TAxis *xaxis = fXaxis;
4163  TAxis *yaxis = fYaxis;
4164  if (!strcmp(xaxis->GetName(),"xaxis")) {
4165  fXaxis = yaxis;
4166  fYaxis = xaxis;
4167  }
4168 
4169  PaintFrame();
4170 
4171  Int_t bar = Hoption.Bar - 20;
4172  Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4173  Double_t offset = fH->GetBarOffset();
4174  Double_t width = fH->GetBarWidth();
4175  TBox box;
4176  Int_t hcolor = fH->GetFillColor();
4177  if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4178  Int_t hstyle = fH->GetFillStyle();
4179  box.SetFillColor(hcolor);
4180  box.SetFillStyle(hstyle);
4181  for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4182  ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4183  ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4184  xmin = gPad->GetUxmin();
4185  xmax = gPad->XtoPad(fH->GetBinContent(bin));
4186  if (xmax < gPad->GetUxmin()) continue;
4187  if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4188  if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4189  if (gStyle->GetHistMinimumZero() && xmin < 0)
4190  xmin=TMath::Min(0.,gPad->GetUxmax());
4191  w = (ymax-ymin)*width;
4192  ymin += offset*(ymax-ymin);
4193  ymax = ymin + w;
4194  if (bar < 1) {
4195  box.PaintBox(xmin,ymin,xmax,ymax);
4196  } else {
4197  umin = ymin + bar*(ymax-ymin)/10.;
4198  umax = ymax - bar*(ymax-ymin)/10.;
4199  box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4200  box.PaintBox(xmin,ymin,xmax,umin);
4201  box.SetFillColor(hcolor);
4202  box.PaintBox(xmin,umin,xmax,umax);
4203  box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4204  box.PaintBox(xmin,umax,xmax,ymax);
4205  }
4206  }
4207 
4208  PaintTitle();
4209  // Draw box with histogram statistics and/or fit parameters
4210  if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4212  TObject *obj = 0;
4213  while ((obj = next())) {
4214  if (obj->InheritsFrom(TF1::Class())) break;
4215  obj = 0;
4216  }
4217  PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4218  }
4219 
4220  PaintAxis(kFALSE);
4221  fXaxis = xaxis;
4222  fYaxis = yaxis;
4223 }
4224 
4225 
4226 ////////////////////////////////////////////////////////////////////////////////
4227 /// [Control function to draw a 2D histogram as a box plot](#HP13)
4228 
4230 {
4231 
4232  Style_t fillsav = fH->GetFillStyle();
4233  Style_t colsav = fH->GetFillColor();
4234  if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
4235  if (Hoption.Box == 11) fH->SetFillStyle(1001);
4236  fH->TAttLine::Modify();
4237  fH->TAttFill::Modify();
4238 
4239  Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
4240  Double_t ux1 = gPad->PixeltoX(1);
4241  Double_t ux0 = gPad->PixeltoX(0);
4242  Double_t uy1 = gPad->PixeltoY(1);
4243  Double_t uy0 = gPad->PixeltoY(0);
4244  Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
4245  Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
4246 
4247  Double_t zmin = fH->GetMinimum();
4249  TMath::Abs(fH->GetMinimum()));
4250 
4251  // In case of option SAME, zmin and zmax values are taken from the
4252  // first plotted 2D histogram.
4253  if (Hoption.Same) {
4254  TH2 *h2;
4255  TIter next(gPad->GetListOfPrimitives());
4256  while ((h2 = (TH2 *)next())) {
4257  if (!h2->InheritsFrom(TH2::Class())) continue;
4258  zmin = h2->GetMinimum();
4259  zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
4260  TMath::Abs(h2->GetMinimum()));
4261  if (Hoption.Logz) {
4262  zmax = TMath::Log10(zmax);
4263  if (zmin <= 0) {
4264  zmin = TMath::Log10(zmax*0.001);
4265  } else {
4266  zmin = TMath::Log10(zmin);
4267  }
4268  }
4269  break;
4270  }
4271  }
4272 
4273  if (Hoption.Logz) {
4274  if (zmin > 0) {
4275  zmin = TMath::Log10(zmin*0.1);
4276  zmax = TMath::Log10(zmax);
4277  } else {
4278  return;
4279  }
4280  }
4281 
4282  Double_t zratio, dz = zmax - zmin;
4283  Bool_t kZNeg = kFALSE;
4284 
4285  // Define the dark and light colors the "button style" boxes.
4286  Color_t color = fH->GetFillColor();
4287  Color_t light=0, dark=0;
4288  if (Hoption.Box == 11) {
4289  light = TColor::GetColorBright(color);
4290  dark = TColor::GetColorDark(color);
4291  }
4292 
4293  // Loop over all the bins and draw the boxes
4294  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4295  yk = fYaxis->GetBinLowEdge(j);
4296  ystep = fYaxis->GetBinWidth(j);
4297  ycent = 0.5*ystep;
4298  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4299  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4300  xk = fXaxis->GetBinLowEdge(i);
4301  xstep = fXaxis->GetBinWidth(i);
4302  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4303  xcent = 0.5*xstep;
4304  z = Hparam.factor*fH->GetBinContent(bin);
4305  kZNeg = kFALSE;
4306 
4307  if (z < zmin) continue; // Can be the case with
4308  if (z > zmax) z = zmax; // option Same
4309 
4310  if (z < 0) {
4311  if (Hoption.Logz) continue;
4312  z = -z;
4313  kZNeg = kTRUE;
4314  }
4315  if (Hoption.Logz) {
4316  if (z != 0) z = TMath::Log10(z);
4317  else z = zmin;
4318  }
4319 
4320  if (dz == 0) continue;
4321  zratio = TMath::Sqrt((z-zmin)/dz);
4322  if (zratio == 0) continue;
4323 
4324  xup = xcent*zratio + xk + xcent;
4325  xlow = 2*(xk + xcent) - xup;
4326  if (xup-xlow < dxmin) xup = xlow+dxmin;
4327  if (Hoption.Logx) {
4328  if (xup > 0) xup = TMath::Log10(xup);
4329  else continue;
4330  if (xlow > 0) xlow = TMath::Log10(xlow);
4331  else continue;
4332  }
4333 
4334  yup = ycent*zratio + yk + ycent;
4335  ylow = 2*(yk + ycent) - yup;
4336  if (yup-ylow < dymin) yup = ylow+dymin;
4337  if (Hoption.Logy) {
4338  if (yup > 0) yup = TMath::Log10(yup);
4339  else continue;
4340  if (ylow > 0) ylow = TMath::Log10(ylow);
4341  else continue;
4342  }
4343 
4344  xlow = TMath::Max(xlow, gPad->GetUxmin());
4345  ylow = TMath::Max(ylow, gPad->GetUymin());
4346  xup = TMath::Min(xup , gPad->GetUxmax());
4347  yup = TMath::Min(yup , gPad->GetUymax());
4348 
4349  if (xlow >= xup) continue;
4350  if (ylow >= yup) continue;
4351 
4352  if (Hoption.Box == 1) {
4353  fH->SetFillColor(color);
4354  fH->TAttFill::Modify();
4355  gPad->PaintBox(xlow, ylow, xup, yup);
4356  if (kZNeg) {
4357  gPad->PaintLine(xlow, ylow, xup, yup);
4358  gPad->PaintLine(xlow, yup, xup, ylow);
4359  }
4360  } else if (Hoption.Box == 11) {
4361  // Draw the center of the box
4362  fH->SetFillColor(color);
4363  fH->TAttFill::Modify();
4364  gPad->PaintBox(xlow, ylow, xup, yup);
4365 
4366  // Draw top&left part of the box
4367  Double_t x[7], y[7];
4368  Double_t bwidth = 0.1;
4369  x[0] = xlow; y[0] = ylow;
4370  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4371  x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
4372  x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
4373  x[4] = xup; y[4] = yup;
4374  x[5] = xlow; y[5] = yup;
4375  x[6] = xlow; y[6] = ylow;
4376  if (kZNeg) fH->SetFillColor(dark);
4377  else fH->SetFillColor(light);
4378  fH->TAttFill::Modify();
4379  gPad->PaintFillArea(7, x, y);
4380 
4381  // Draw bottom&right part of the box
4382  x[0] = xlow; y[0] = ylow;
4383  x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
4384  x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
4385  x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
4386  x[4] = xup; y[4] = yup;
4387  x[5] = xup; y[5] = ylow;
4388  x[6] = xlow; y[6] = ylow;
4389  if (kZNeg) fH->SetFillColor(light);
4390  else fH->SetFillColor(dark);
4391  fH->TAttFill::Modify();
4392  gPad->PaintFillArea(7, x, y);
4393  }
4394  }
4395  }
4396 
4397  if (Hoption.Zscale) PaintPalette();
4398  fH->SetFillStyle(fillsav);
4399  fH->SetFillColor(colsav);
4400  fH->TAttFill::Modify();
4401 }
4402 
4403 
4404 ////////////////////////////////////////////////////////////////////////////////
4405 /// [Control function to draw a 2D histogram as a candle (box) plot.](#HP14)
4406 
4408 {
4409  Double_t x,y,w;
4410  Double_t m1 = 0.055, m2 = 0.25;
4411  Double_t xpm[1], ypm[1];
4412 
4413  TH1D *hp;
4414  TH2D *h2 = (TH2D*)fH;
4415 
4416  Double_t *quantiles = new Double_t[5];
4417  quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
4418  Double_t *prob = new Double_t[5];
4419  prob[0]=1E-15; prob[1]=0.25; prob[2]=0.5; prob[3]=0.75; prob[4]=1-1E-15;
4420 
4421  Style_t fillsav = h2->GetFillStyle();
4422  Style_t colsav = h2->GetFillColor();
4423  Style_t linesav = h2->GetLineStyle();
4424  Style_t widthsav = h2->GetLineWidth();
4425  Style_t pmssav = h2->GetMarkerStyle();
4426 
4427  if (h2->GetFillColor() == 0) h2->SetFillStyle(0);
4428 
4429  h2->SetMarkerStyle(24);
4430  h2->TAttLine::Modify();
4431  h2->TAttFill::Modify();
4432  h2->TAttMarker::Modify();
4433 
4434  // Candle plot along X
4435  Double_t xb1,xb2,yb1,yb2,xl1,xl2,yl1,yl2,xl3,yl3,xp1,yp1;
4436  if (Hoption.Candle == 1) {
4437  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4438  x = fXaxis->GetBinLowEdge(i);
4439  w = fXaxis->GetBinWidth(i);
4440  hp = h2->ProjectionY("_px", i, i);
4441  if (hp->GetEntries() !=0) {
4442  hp->GetQuantiles(5, quantiles, prob);
4443  yp1 = hp->GetMean();
4444  xb1 = x+m1*w;
4445  xb2 = x+(1-m1)*w;
4446  yb1 = quantiles[1];
4447  yb2 = quantiles[3];
4448  xl1 = x+m2*w;
4449  xl2 = x+(1-m2)*w;
4450  yl1 = quantiles[0];
4451  yl2 = quantiles[4];
4452  yl3 = quantiles[2];
4453  xp1 = x+w/2.;
4454  if (Hoption.Logy) {
4455  if (yb1 > 0) yb1 = TMath::Log10(yb1); else continue;
4456  if (yb2 > 0) yb2 = TMath::Log10(yb2); else continue;
4457  if (yl1 > 0) yl1 = TMath::Log10(yl1); else continue;
4458  if (yl2 > 0) yl2 = TMath::Log10(yl2); else continue;
4459  if (yl3 > 0) yl3 = TMath::Log10(yl3); else continue;
4460  if (yp1 > 0) yp1 = TMath::Log10(yp1); else continue;
4461  }
4462  if (Hoption.Logx) {
4463  if (xb1 > 0) xb1 = TMath::Log10(xb1); else continue;
4464  if (xb2 > 0) xb2 = TMath::Log10(xb2); else continue;
4465  if (xl1 > 0) xl1 = TMath::Log10(xl1); else continue;
4466  if (xl2 > 0) xl2 = TMath::Log10(xl2); else continue;
4467  if (xp1 > 0) xp1 = TMath::Log10(xp1); else continue;
4468  }
4469  ypm[0] = yp1;
4470  h2->SetLineStyle(1);
4471  h2->TAttLine::Modify();
4472  gPad->PaintBox (xb1, yb1, xb2, yb2);
4473  gPad->PaintLine(xl1, yl1, xl2, yl1);
4474  gPad->PaintLine(xl1, yl2, xl2, yl2);
4475  h2->SetLineWidth(3*widthsav);
4476  h2->TAttLine::Modify();
4477  gPad->PaintLine(xb1, yl3, xb2, yl3);
4478  h2->SetLineWidth(widthsav);
4479  h2->TAttLine::Modify();
4480 
4481  h2->SetLineStyle(2);
4482  h2->TAttLine::Modify();
4483  gPad->PaintLine(xp1, yb2, xp1, yl2);
4484  gPad->PaintLine(xp1, yl1, xp1, yb1);
4485 
4486  xpm[0] = xp1;
4487  gPad->PaintPolyMarker(1,xpm,ypm);
4488  }
4489  }
4490  // Candle plot along Y
4491  } else {
4492  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4493  y = fYaxis->GetBinLowEdge(i);
4494  w = fYaxis->GetBinWidth(i);
4495  hp = h2->ProjectionX("_py", i, i);
4496  if (hp->GetEntries() !=0) {
4497  hp->GetQuantiles(5, quantiles, prob);
4498  xp1 = hp->GetMean();
4499  yb1 = y+m1*w;
4500  yb2 = y+(1-m1)*w;
4501  xb1 = quantiles[1];
4502  xb2 = quantiles[3];
4503  yl1 = y+m2*w;
4504  yl2 = y+(1-m2)*w;
4505  xl1 = quantiles[0];
4506  xl2 = quantiles[4];
4507  xl3 = quantiles[2];
4508  yp1 = y+w/2.;
4509  if (Hoption.Logx) {
4510  if (xb1 > 0) xb1 = TMath::Log10(xb1); else continue;
4511  if (xb2 > 0) xb2 = TMath::Log10(xb2); else continue;
4512  if (xl1 > 0) xl1 = TMath::Log10(xl1); else continue;
4513  if (xl2 > 0) xl2 = TMath::Log10(xl2); else continue;
4514  if (xl3 > 0) xl3 = TMath::Log10(xl3); else continue;
4515  if (xp1 > 0) xp1 = TMath::Log10(xp1); else continue;
4516  }
4517  if (Hoption.Logy) {
4518  if (yb1 > 0) yb1 = TMath::Log10(yb1); else continue;
4519  if (yb2 > 0) yb2 = TMath::Log10(yb2); else continue;
4520  if (yl1 > 0) yl1 = TMath::Log10(yl1); else continue;
4521  if (yl2 > 0) yl2 = TMath::Log10(yl2); else continue;
4522  if (yp1 > 0) yp1 = TMath::Log10(yp1); else continue;
4523  }
4524  xpm[0] = xp1;
4525  h2->SetLineStyle(1);
4526  h2->TAttLine::Modify();
4527 
4528  gPad->PaintBox (xb1, yb1, xb2, yb2);
4529  gPad->PaintLine(xl1, yl1, xl1, yl2);
4530  gPad->PaintLine(xl2, yl1, xl2, yl2);
4531 
4532  h2->SetLineWidth(3*widthsav);
4533  h2->TAttLine::Modify();
4534  gPad->PaintLine(xl3, yb1, xl3, yb2);
4535 
4536  h2->SetLineWidth(widthsav);
4537  h2->TAttLine::Modify();
4538 
4539  h2->SetLineStyle(2);
4540  h2->TAttLine::Modify();
4541  gPad->PaintLine(xb2, yp1, xl2, yp1);
4542  gPad->PaintLine(xl1, yp1, xb1, yp1);
4543 
4544  ypm[0] = yp1;
4545  gPad->PaintPolyMarker(1,xpm,ypm);
4546  }
4547  }
4548  }
4549 
4550  h2->SetFillStyle(fillsav);
4551  h2->SetFillColor(colsav);
4552  h2->SetLineStyle(linesav);
4553  h2->SetMarkerStyle(pmssav);
4554  h2->SetLineWidth(widthsav);
4555  h2->TAttFill::Modify();
4556  h2->TAttLine::Modify();
4557  h2->TAttMarker::Modify();
4558 
4559  delete [] prob;
4560  delete [] quantiles;
4561 }
4562 
4563 ////////////////////////////////////////////////////////////////////////////////
4564 /// [Control function to draw a 2D histogram as a violin plot](#HP141)
4565 
4567 {
4568  Double_t x,y,w;
4569  Double_t bw, bcen, bcon;
4570  Double_t xpm[1], ypm[1];
4571 
4572  TH1D *hp;
4573  TH2D *h2 = (TH2D*)fH;
4574 
4575  Double_t *quantiles = new Double_t[5];
4576  quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.;
4577  Double_t *prob = new Double_t[5];
4578  prob[0]=1E-15; prob[1]=0.25; prob[2]=0.5; prob[3]=0.75; prob[4]=1-1E-15;
4579 
4580  Style_t fillsav = h2->GetFillStyle();
4581  Style_t colsav = h2->GetFillColor();
4582  Style_t linesav = h2->GetLineStyle();
4583  Style_t widthsav = h2->GetLineWidth();
4584  Style_t pmssav = h2->GetMarkerStyle();
4585 
4586  if (h2->GetFillColor() == 0) h2->SetFillStyle(0);
4587 
4588  h2->SetMarkerStyle(pmssav);
4589  h2->TAttLine::Modify();
4590  h2->TAttFill::Modify();
4591  h2->TAttMarker::Modify();
4592 
4593  // Violin plot along X
4594  if (Hoption.Violin == 1) {
4595  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
4596  x = fXaxis->GetBinCenter(i);
4597  w = fXaxis->GetBinWidth(i);
4598  hp = h2->ProjectionY("_px", i, i);
4599  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4600  hp->Scale(1.0/hp->Integral());
4601  hp->Scale(w/hp->GetMaximum());
4602  hp->GetQuantiles(5, quantiles, prob);
4603  ypm[0] = hp->GetMean();
4604 
4605  TAxis *ax = hp->GetXaxis();
4606  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4607  bw = ax->GetBinWidth(j);
4608  bcen = ax->GetBinCenter(j);
4609  bcon = hp->GetBinContent(j);
4610  gPad->PaintBox(x-0.5*bcon, bcen-0.5*bw, x+0.5*bcon, bcen+0.5*bw);
4611  }
4612 
4613  h2->SetLineWidth(widthsav);
4614  h2->TAttLine::Modify();
4615 
4616  h2->SetLineStyle(linesav);
4617  h2->TAttLine::Modify();
4618  gPad->PaintLine(x, quantiles[3], x, quantiles[4]);
4619  gPad->PaintLine(x, quantiles[0], x, quantiles[1]);
4620 
4621  xpm[0] = x;
4622  gPad->PaintPolyMarker(1,xpm,ypm);
4623  }
4624  }
4625  // Violin plot along Y
4626  } else {
4627  for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
4628  y = fYaxis->GetBinCenter(i);
4629  w = fYaxis->GetBinWidth(i);
4630  hp = h2->ProjectionX("_py", i, i);
4631  if (hp->GetEntries() !=0 && hp->GetMaximum()!=0) {
4632  hp->Scale(1.0/hp->Integral());
4633  hp->Scale(w/hp->GetMaximum());
4634  hp->GetQuantiles(5, quantiles, prob);
4635  xpm[0] = hp->GetMean();
4636 
4637  h2->SetLineWidth(1);
4638  h2->TAttLine::Modify();
4639  TAxis *ax = hp->GetXaxis();
4640  for(Int_t j=ax->GetFirst(); j<ax->GetLast(); ++j){
4641  bw = ax->GetBinWidth(j);
4642  bcen = ax->GetBinCenter(j);
4643  bcon = hp->GetBinContent(j);
4644  gPad->PaintBox(bcen-0.5*bw, y-0.5*bcon, bcen+0.5*bw, y+0.5*bcon);
4645  }
4646 
4647  hp->GetQuantiles(5, quantiles, prob);
4648  xpm[0] = hp->GetMean();
4649 
4650  h2->SetLineWidth(widthsav);
4651  h2->SetLineStyle(2);
4652  h2->TAttLine::Modify();
4653  gPad->PaintLine(quantiles[3], y, quantiles[4], y);
4654  gPad->PaintLine(quantiles[0], y, quantiles[1], y);
4655 
4656  ypm[0] = y;
4657  gPad->PaintPolyMarker(1,xpm,ypm);
4658  }
4659  }
4660  }
4661 
4662  h2->SetFillStyle(fillsav);
4663  h2->SetFillColor(colsav);
4664  h2->SetLineStyle(linesav);
4665  h2->SetMarkerStyle(pmssav);
4666  h2->SetLineWidth(widthsav);
4667  h2->TAttFill::Modify();
4668  h2->TAttLine::Modify();
4669  h2->TAttMarker::Modify();
4670 
4671  delete [] prob;
4672  delete [] quantiles;
4673 }
4674 
4675 ////////////////////////////////////////////////////////////////////////////////
4676 /// [Control function to draw a 2D histogram as a color plot.](#HP14)
4677 
4679 {
4680  Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
4681 
4682  Double_t zmin = fH->GetMinimum();
4683  Double_t zmax = fH->GetMaximum();
4685  Double_t dz = zmax - zmin;
4686  if (dz <= 0) { // Histogram filled with a constant value
4687  zmax += 0.1*TMath::Abs(zmax);
4688  zmin -= 0.1*TMath::Abs(zmin);
4689  dz = zmax - zmin;
4690  }
4691 
4692  if (Hoption.Logz) {
4693  if (zmin > 0) {
4694  zmin = TMath::Log10(zmin);
4695  zmax = TMath::Log10(zmax);
4696  dz = zmax - zmin;
4697  } else {
4698  return;
4699  }
4700  }
4701 
4702  Style_t fillsav = fH->GetFillStyle();
4703  Style_t colsav = fH->GetFillColor();
4704  fH->SetFillStyle(1001);
4705  fH->TAttFill::Modify();
4706 
4707  // Initialize the levels on the Z axis
4708  Int_t ncolors = gStyle->GetNumberOfColors();
4709  Int_t ndiv = fH->GetContour();
4710  if (ndiv == 0 ) {
4711  ndiv = gStyle->GetNumberContours();
4712  fH->SetContour(ndiv);
4713  }
4714  Int_t ndivz = TMath::Abs(ndiv);
4715  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4716  Double_t scale = ndivz/dz;
4717 
4718  Int_t color;
4719  TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
4720  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4721  yk = fYaxis->GetBinLowEdge(j);
4722  ystep = fYaxis->GetBinWidth(j);
4723  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4724  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
4725  xk = fXaxis->GetBinLowEdge(i);
4726  xstep = fXaxis->GetBinWidth(i);
4727  if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
4728  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4729  z = fH->GetBinContent(bin);
4730  // if fH is a profile histogram do not draw empty bins
4731  if (prof2d) {
4732  const Double_t binEntries = prof2d->GetBinEntries(bin);
4733  if (binEntries == 0)
4734  continue;
4735  } else {
4736  // don't draw the empty bins for non-profile histograms
4737  // with positive content
4738  if (z == 0) {
4739  if (zmin >= 0 || Hoption.Logz) continue;
4740  if (Hoption.Color == 2) continue;
4741  }
4742  }
4743 
4744  if (Hoption.Logz) {
4745  if (z > 0) z = TMath::Log10(z);
4746  else z = zmin;
4747  }
4748  if (z < zmin && !Hoption.Zero) continue;
4749  xup = xk + xstep;
4750  xlow = xk;
4751  if (Hoption.Logx) {
4752  if (xup > 0) xup = TMath::Log10(xup);
4753  else continue;
4754  if (xlow > 0) xlow = TMath::Log10(xlow);
4755  else continue;
4756  }
4757  yup = yk + ystep;
4758  ylow = yk;
4759  if (Hoption.System != kPOLAR) {
4760  if (Hoption.Logy) {
4761  if (yup > 0) yup = TMath::Log10(yup);
4762  else continue;
4763  if (ylow > 0) ylow = TMath::Log10(ylow);
4764  else continue;
4765  }
4766  if (xup < gPad->GetUxmin()) continue;
4767  if (yup < gPad->GetUymin()) continue;
4768  if (xlow > gPad->GetUxmax()) continue;
4769  if (ylow > gPad->GetUymax()) continue;
4770  if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
4771  if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
4772  if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
4773  if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
4774  }
4775 
4776  if (fH->TestBit(TH1::kUserContour)) {
4777  zc = fH->GetContourLevelPad(0);
4778  if (z < zc) continue;
4779  color = -1;
4780  for (Int_t k=0; k<ndiv; k++) {
4781  zc = fH->GetContourLevelPad(k);
4782  if (z < zc) {
4783  continue;
4784  } else {
4785  color++;
4786  }
4787  }
4788  } else {
4789  color = Int_t(0.01+(z-zmin)*scale);
4790  }
4791 
4792  Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4793  if (theColor > ncolors-1) theColor = ncolors-1;
4794  fH->SetFillColor(gStyle->GetColorPalette(theColor));
4795  fH->TAttFill::Modify();
4796  if (Hoption.System != kPOLAR) {
4797  gPad->PaintBox(xlow, ylow, xup, yup);
4798  } else {
4799  TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
4800  crown.SetFillColor(gStyle->GetColorPalette(theColor));
4801  crown.Paint();
4802  }
4803  }
4804  }
4805 
4806  if (Hoption.Zscale) PaintPalette();
4807 
4808  fH->SetFillStyle(fillsav);
4809  fH->SetFillColor(colsav);
4810  fH->TAttFill::Modify();
4811 
4812 }
4813 
4814 
4815 ////////////////////////////////////////////////////////////////////////////////
4816 /// [Control function to draw a 2D histogram as a contour plot.](#HP16)
4817 
4819 {
4820 
4821  Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
4822  Int_t itars, mode, ir[4];
4823  Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
4825  if (Hoption.Contour == 14) {
4826  Hoption.Surf = 12;
4827  Hoption.Axis = 1;
4828  thesave = gPad->GetTheta();
4829  phisave = gPad->GetPhi();
4830  gPad->SetPhi(0.);
4831  gPad->SetTheta(90.);
4832  PaintSurface(option);
4833  gPad->SetPhi(phisave);
4834  gPad->SetTheta(thesave);
4835  TView *view = gPad->GetView();
4836  if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
4837  PaintAxis();
4838  return;
4839  }
4840 
4841  if (Hoption.Same) {
4842  // If the contour is painted on a 3d plot, the contour lines are
4843  // paint in 3d too.
4844  TObject *obj;
4845  TIter next(gPad->GetListOfPrimitives());
4846  while ((obj=next())) {
4847  if (strstr(obj->GetDrawOption(),"surf") ||
4848  strstr(obj->GetDrawOption(),"lego") ||
4849  strstr(obj->GetDrawOption(),"tri")) {
4850  Hoption.Surf = 16;
4851  PaintSurface(option);
4852  return;
4853  }
4854  }
4855  }
4856 
4857  if (Hoption.Contour == 15) {
4858  TGraphDelaunay2D *dt = nullptr;
4859  TGraphDelaunay *dtOld = nullptr;
4860  TList *hl = fH->GetListOfFunctions();
4861  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
4862  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
4863  if (!dt && !dtOld) return;
4864  if (!fGraph2DPainter) {
4865  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
4866  else fGraph2DPainter = new TGraph2DPainter(dtOld);
4867  }
4868  fGraph2DPainter->Paint(option);
4869  return;
4870  }
4871 
4872  gPad->SetBit(TGraph::kClipFrame);
4873 
4874  Double_t *levels = new Double_t[2*kMAXCONTOUR];
4875  Double_t *xarr = new Double_t[2*kMAXCONTOUR];
4876  Double_t *yarr = new Double_t[2*kMAXCONTOUR];
4877  Int_t *itarr = new Int_t[2*kMAXCONTOUR];
4878 
4879  Int_t npmax = 0;
4880  for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
4881 
4882  ncontour = fH->GetContour();
4883  if (ncontour == 0) {
4884  ncontour = gStyle->GetNumberContours();
4885  fH->SetContour(ncontour);
4886  }
4887  if (ncontour > kMAXCONTOUR) {
4888  Warning("PaintContour", "maximum number of contours is %d, asked for %d",
4889  kMAXCONTOUR, ncontour);
4890  ncontour = kMAXCONTOUR-1;
4891  }
4892  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
4893 
4894  for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
4895  //for (i=0;i<ncontour;i++)
4896  // levels[i] = Hparam.zmin+(Hparam.zmax-Hparam.zmin)/ncontour*i;
4897  Int_t linesav = fH->GetLineStyle();
4898  Int_t colorsav = fH->GetLineColor();
4899  Int_t fillsav = fH->GetFillColor();
4900  if (Hoption.Contour == 13) {
4901  fH->TAttLine::Modify();
4902  }
4903 
4904  TPolyLine **polys = 0;
4905  TPolyLine *poly=0;
4906  TObjArray *contours = 0;
4907  TList *list = 0;
4908  TGraph *graph = 0;
4909  Int_t *np = 0;
4910  if (Hoption.Contour == 1) {
4911  np = new Int_t[ncontour];
4912  for (i=0;i<ncontour;i++) np[i] = 0;
4913  polys = new TPolyLine*[ncontour];
4914  for (i=0;i<ncontour;i++) {
4915  polys[i] = new TPolyLine(100);
4916  }
4917  if (Hoption.List == 1) {
4918  contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
4919  if (contours) {
4920  gROOT->GetListOfSpecials()->Remove(contours);
4921  count = contours->GetSize();
4922  for (i=0;i<count;i++) {
4923  list = (TList*)contours->At(i);
4924  if (list) list->Delete();
4925  }
4926  }
4927  contours = new TObjArray(ncontour);
4928  contours->SetName("contours");
4929  gROOT->GetListOfSpecials()->Add(contours);
4930  for (i=0;i<ncontour;i++) {
4931  list = new TList();
4932  contours->Add(list);
4933  }
4934  }
4935  }
4936  Int_t theColor;
4937  Int_t ncolors = gStyle->GetNumberOfColors();
4938  Int_t ndivz = TMath::Abs(ncontour);
4939 
4940  Int_t k,ipoly;
4941  for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
4942  y[0] = fYaxis->GetBinCenter(j);
4943  y[1] = y[0];
4944  y[2] = fYaxis->GetBinCenter(j+1);
4945  y[3] = y[2];
4946  for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
4947  zc[0] = fH->GetBinContent(i, j);
4948  zc[1] = fH->GetBinContent(i+1, j);
4949  zc[2] = fH->GetBinContent(i+1, j+1);
4950  zc[3] = fH->GetBinContent(i, j+1);
4951  if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
4952  if (Hoption.Logz) {
4953  if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
4954  else zc[0] = Hparam.zmin;
4955  if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
4956  else zc[1] = Hparam.zmin;
4957  if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
4958  else zc[2] = Hparam.zmin;
4959  if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
4960  else zc[3] = Hparam.zmin;
4961  }
4962  for (k=0;k<4;k++) {
4963  ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
4964  }
4965  if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
4966  x[0] = fXaxis->GetBinCenter(i);
4967  x[3] = x[0];
4968  x[1] = fXaxis->GetBinCenter(i+1);
4969  x[2] = x[1];
4970  if (zc[0] <= zc[1]) n = 0; else n = 1;
4971  if (zc[2] <= zc[3]) m = 2; else m = 3;
4972  if (zc[n] > zc[m]) n = m;
4973  n++;
4974  lj=1;
4975  for (ix=1;ix<=4;ix++) {
4976  m = n%4 + 1;
4977  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
4978  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
4979  lj += 2*ljfill;
4980  n = m;
4981  }
4982 
4983  if (zc[0] <= zc[1]) n = 0; else n = 1;
4984  if (zc[2] <= zc[3]) m = 2; else m = 3;
4985  if (zc[n] > zc[m]) n = m;
4986  n++;
4987  lj=2;
4988  for (ix=1;ix<=4;ix++) {
4989  if (n == 1) m = 4;
4990  else m = n-1;
4991  ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
4992  ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
4993  lj += 2*ljfill;
4994  n = m;
4995  }
4996 
4997  // Re-order endpoints
4998 
4999  count = 0;
5000  for (ix=1; ix<=lj-5; ix +=2) {
5001  //count = 0;
5002  while (itarr[ix-1] != itarr[ix]) {
5003  xsave = xarr[ix];
5004  ysave = yarr[ix];
5005  itars = itarr[ix];
5006  for (jx=ix; jx<=lj-5; jx +=2) {
5007  xarr[jx] = xarr[jx+2];
5008  yarr[jx] = yarr[jx+2];
5009  itarr[jx] = itarr[jx+2];
5010  }
5011  xarr[lj-3] = xsave;
5012  yarr[lj-3] = ysave;
5013  itarr[lj-3] = itars;
5014  if (count > 100) break;
5015  count++;
5016  }
5017  }
5018 
5019  if (count > 100) continue;
5020  for (ix=1; ix<=lj-2; ix +=2) {
5021  theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5022  icol = gStyle->GetColorPalette(theColor);
5023  if (Hoption.Contour == 11) {
5024  fH->SetLineColor(icol);
5025  }
5026  if (Hoption.Contour == 12) {
5027  mode = icol%5;
5028  if (mode == 0) mode = 5;
5029  fH->SetLineStyle(mode);
5030  }
5031  if (Hoption.Contour != 1) {
5032  fH->TAttLine::Modify();
5033  gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5034  continue;
5035  }
5036 
5037  ipoly = itarr[ix-1];
5038  if (ipoly >=0 && ipoly <ncontour) {
5039  poly = polys[ipoly];
5040  poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5041  poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5042  np[ipoly] += 2;
5043  if (npmax < np[ipoly]) npmax = np[ipoly];
5044  }
5045  }
5046  } // end of if (ir[0]
5047  } //end of for (i
5048  } //end of for (j
5049 
5050  Double_t xmin,ymin;
5051  Double_t *xp, *yp;
5052  Int_t nadd,iminus,iplus;
5053  Double_t *xx, *yy;
5054  Int_t istart;
5055  Int_t first = ncontour;
5056  Int_t *polysort = 0;
5057  Int_t contListNb;
5058  if (Hoption.Contour != 1) goto theEND;
5059 
5060  //The 2 points line generated above are now sorted/merged to generate
5061  //a list of consecutive points.
5062  // If the option "List" has been specified, the list of points is saved
5063  // in the form of TGraph objects in the ROOT list of special objects.
5064  xmin = gPad->GetUxmin();
5065  ymin = gPad->GetUymin();
5066  xp = new Double_t[2*npmax];
5067  yp = new Double_t[2*npmax];
5068  polysort = new Int_t[ncontour];
5069  //find first positive contour
5070  for (ipoly=0;ipoly<ncontour;ipoly++) {
5071  if (levels[ipoly] >= 0) {first = ipoly; break;}
5072  }
5073  //store negative contours from 0 to minimum, then all positive contours
5074  k = 0;
5075  for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
5076  for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
5077  // we can now draw sorted contours
5078  contListNb = 0;
5079  fH->SetFillStyle(1001);
5080  for (k=0;k<ncontour;k++) {
5081  ipoly = polysort[k];
5082  if (np[ipoly] == 0) continue;
5083  if (Hoption.List) list = (TList*)contours->At(contListNb);
5084  contListNb++;
5085  poly = polys[ipoly];
5086  xx = poly->GetX();
5087  yy = poly->GetY();
5088  istart = 0;
5089  while (1) {
5090  iminus = npmax;
5091  iplus = iminus+1;
5092  xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
5093  xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
5094  xx[istart] = xmin; yy[istart] = ymin;
5095  xx[istart+1] = xmin; yy[istart+1] = ymin;
5096  while (1) {
5097  nadd = 0;
5098  for (i=2;i<np[ipoly];i+=2) {
5099  if (xx[i] == xp[iplus] && yy[i] == yp[iplus]) {
5100  iplus++;
5101  xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
5102  xx[i] = xmin; yy[i] = ymin;
5103  xx[i+1] = xmin; yy[i+1] = ymin;
5104  nadd++;
5105  }
5106  if (xx[i+1] == xp[iminus] && yy[i+1] == yp[iminus]) {
5107  iminus--;
5108  xp[iminus] = xx[i]; yp[iminus] = yy[i];
5109  xx[i] = xmin; yy[i] = ymin;
5110  xx[i+1] = xmin; yy[i+1] = ymin;
5111  nadd++;
5112  }
5113  }
5114  if (nadd == 0) break;
5115  }
5116  theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
5117  icol = gStyle->GetColorPalette(theColor);
5118  if (ndivz > 1) fH->SetFillColor(icol);
5119  fH->TAttFill::Modify();
5120  gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5121  if (Hoption.List) {
5122  graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
5123  graph->SetFillColor(icol);
5124  graph->SetLineWidth(fH->GetLineWidth());
5125  list->Add(graph);
5126  }
5127  //check if more points are left
5128  istart = 0;
5129  for (i=2;i<np[ipoly];i+=2) {
5130  if (xx[i] != xmin && yy[i] != ymin) {
5131  istart = i;
5132  break;
5133  }
5134  }
5135  if (istart == 0) break;
5136  }
5137  }
5138 
5139  for (i=0;i<ncontour;i++) delete polys[i];
5140  delete [] polys;
5141  delete [] xp;
5142  delete [] yp;
5143  delete [] polysort;
5144 
5145 theEND:
5146  gPad->ResetBit(TGraph::kClipFrame);
5147  if (Hoption.Zscale) PaintPalette();
5148  fH->SetLineStyle(linesav);
5149  fH->SetLineColor(colorsav);
5150  fH->SetFillColor(fillsav);
5151  if (np) delete [] np;
5152  delete [] xarr;
5153  delete [] yarr;
5154  delete [] itarr;
5155  delete [] levels;
5156 }
5157 
5158 
5159 ////////////////////////////////////////////////////////////////////////////////
5160 /// Fill the matrix `xarr` and `yarr` for Contour Plot.
5161 
5163  Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
5164  Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
5165 {
5166 
5167  Bool_t vert;
5168  Double_t tlen, tdif, elev, diff, pdif, xlen;
5169  Int_t n, i, icount;
5170 
5171  if (x1 == x2) {
5172  vert = kTRUE;
5173  tlen = y2 - y1;
5174  } else {
5175  vert = kFALSE;
5176  tlen = x2 - x1;
5177  }
5178 
5179  n = icont1 +1;
5180  tdif = elev2 - elev1;
5181  i = 0;
5182  icount = 0;
5183  while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
5184  //elev = fH->GetContourLevel(n);
5185  elev = levels[n];
5186  diff = elev - elev1;
5187  pdif = diff/tdif;
5188  xlen = tlen*pdif;
5189  if (vert) {
5190  if (Hoption.Logx)
5191  xarr[i] = TMath::Log10(x1);
5192  else
5193  xarr[i] = x1;
5194  if (Hoption.Logy)
5195  yarr[i] = TMath::Log10(y1 + xlen);
5196  else
5197  yarr[i] = y1 + xlen;
5198  } else {
5199  if (Hoption.Logx)
5200  xarr[i] = TMath::Log10(x1 + xlen);
5201  else
5202  xarr[i] = x1 + xlen;
5203  if (Hoption.Logy)
5204  yarr[i] = TMath::Log10(y1);
5205  else
5206  yarr[i] = y1;
5207  }
5208  itarr[i] = n;
5209  icount++;
5210  i +=2;
5211  n++;
5212  }
5213  return icount;
5214 }
5215 
5216 
5217 ////////////////////////////////////////////////////////////////////////////////
5218 /// [Draw 1D histograms error bars.](#HP09)
5219 
5221 {
5222 
5223  // On iOS, we do not highlight histogram, if it's not picked at the moment
5224  // (but part of histogram (axis or pavestat) was picked, that's why this code
5225  // is called at all. This conditional statement never executes on non-iOS platform.
5226  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
5227 
5228  const Int_t kBASEMARKER=8;
5229  Double_t xp, yp, ex1, ex2, ey1, ey2;
5230  Double_t delta;
5231  Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
5232  Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
5233  Double_t xmin, xmax, ymin, ymax;
5234  Double_t logxmin = 0;
5235  Double_t logymin = 0;
5236  Int_t i, k, npoints, first, last, fixbin;
5237  Int_t if1 = 0;
5238  Int_t if2 = 0;
5239  Int_t drawmarker, errormarker;
5240  Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
5241 
5242  Double_t *xline = 0;
5243  Double_t *yline = 0;
5244  option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
5245  if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
5246  if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
5247  if (Hoption.Error == 10) option0 = 1;
5248  if (Hoption.Error == 11) option1 = 1;
5249  if (Hoption.Error == 12) option2 = 1;
5250  if (Hoption.Error == 13) option3 = 1;
5251  if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
5252  if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
5253  if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
5254  if (option2+option3 == 0) optionE = 1;
5255  if (Hoption.Error == 0) optionE = 0;
5256  if (fXaxis->GetXbins()->fN) fixbin = 0;
5257  else fixbin = 1;
5258 
5259  errormarker = fH->GetMarkerStyle();
5260  if (optionEX0) {
5261  xerror = 0;
5262  } else {
5263  xerror = gStyle->GetErrorX();
5264  }
5265  symbolsize = fH->GetMarkerSize();
5266  if (errormarker == 1) symbolsize = 0.01;
5267  sbase = symbolsize*kBASEMARKER;
5268  // set the graphics attributes
5269 
5270  fH->TAttLine::Modify();
5271  fH->TAttFill::Modify();
5272  fH->TAttMarker::Modify();
5273 
5274  // set the first and last bin
5275 
5276  Double_t factor = Hparam.factor;
5277  first = Hparam.xfirst;
5278  last = Hparam.xlast;
5279  npoints = last - first +1;
5280  xmin = gPad->GetUxmin();
5281  xmax = gPad->GetUxmax();
5282  ymin = gPad->GetUymin();
5283  ymax = gPad->GetUymax();
5284 
5285 
5286  if (option3) {
5287  xline = new Double_t[2*npoints];
5288  yline = new Double_t[2*npoints];
5289  if (!xline || !yline) {
5290  Error("PaintErrors", "too many points, out of memory");
5291  return;
5292  }
5293  if1 = 1;
5294  if2 = 2*npoints;
5295  }
5296 
5297  // compute the offset of the error bars due to the symbol size
5298  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
5299  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
5300 
5301  // compute size of the lines at the end of the error bars
5302  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
5303  bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
5304  bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
5305 
5306 
5307  if (fixbin) {
5308  if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
5309  else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
5310  } else {
5311  delta = fH->GetBinWidth(first);
5312  xp = fH->GetBinLowEdge(first) + 0.5*delta;
5313  }
5314 
5315  // if errormarker = 0 or symbolsize = 0. no symbol is drawn
5316  if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
5317  if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
5318 
5319  // ---------------------- Loop over the points---------------------
5320  for (k=first; k<=last; k++) {
5321 
5322  // get the data
5323  // xp = X position of the current point
5324  // yp = Y position of the current point
5325  // ex1 = Low X error
5326  // ex2 = Up X error
5327  // ey1 = Low Y error
5328  // ey2 = Up Y error
5329  // (xi,yi) = Error bars coordinates
5330 
5331  if (Hoption.Logx) {
5332  if (xp <= 0) goto L30;
5333  if (xp < logxmin) goto L30;
5334  if (xp > TMath::Power(10,xmax)) break;
5335  } else {
5336  if (xp < xmin) goto L30;
5337  if (xp > xmax) break;
5338  }
5339  yp = factor*fH->GetBinContent(k);
5340  if (optionI0 && yp==0) goto L30;
5341  if (fixbin) {
5342  ex1 = xerror*Hparam.xbinsize;
5343  } else {
5344  delta = fH->GetBinWidth(k);
5345  ex1 = xerror*delta;
5346  }
5347  if (fH->GetBinErrorOption() == TH1::kNormal) {
5348  ey1 = factor*fH->GetBinError(k);
5349  ey2 = ey1;
5350  } else {
5351  ey1 = factor*fH->GetBinErrorLow(k);
5352  ey2 = factor*fH->GetBinErrorUp(k);
5353  }
5354  ex2 = ex1;
5355 
5356  xi4 = xp;
5357  xi3 = xp;
5358  xi2 = xp + ex2;
5359  xi1 = xp - ex1;
5360 
5361  yi1 = yp;
5362  yi2 = yp;
5363  yi3 = yp - ey1;
5364  yi4 = yp + ey2;
5365 
5366  // take the LOG if necessary
5367  if (Hoption.Logx) {
5368  xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
5369  xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
5370  xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
5371  xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
5372  }
5373  if (Hoption.Logy) {
5374  yi1 = TMath::Log10(TMath::Max(yi1,logymin));
5375  yi2 = TMath::Log10(TMath::Max(yi2,logymin));
5376  yi3 = TMath::Log10(TMath::Max(yi3,logymin));
5377  yi4 = TMath::Log10(TMath::Max(yi4,logymin));
5378  }
5379 
5380  // test if error bars are not outside the limits
5381  // otherwise they are truncated
5382 
5383  xi1 = TMath::Max(xi1,xmin);
5384  xi2 = TMath::Min(xi2,xmax);
5385  yi3 = TMath::Max(yi3,ymin);
5386  yi4 = TMath::Min(yi4,ymax);
5387 
5388  // test if the marker is on the frame limits. If "Yes", the
5389  // marker will not be drawn and the error bars will be readjusted.
5390 
5391  drawmarker = kTRUE;
5392  if (!option0 && !option3) {
5393  if (Hoption.Logy && yp < logymin) goto L30;
5394  if (yi1 < ymin || yi1 > ymax) goto L30;
5395  if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
5396  }
5397  if (!symbolsize || !errormarker) drawmarker = kFALSE;
5398 
5399  // draw the error rectangles
5400  if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
5401 
5402  // keep points for fill area drawing
5403  if (option3) {
5404  xline[if1-1] = xi3;
5405  xline[if2-1] = xi3;
5406  yline[if1-1] = yi4;
5407  yline[if2-1] = yi3;
5408  if1++;
5409  if2--;
5410  }
5411 
5412  // draw the error bars
5413  if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
5414  if (optionE && drawmarker) {
5415  if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
5416  if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
5417  // don't duplicate the horizontal line
5418  if (Hoption.Hist != 2) {
5419  if (yi1<ymax && yi1>ymin) {
5420  if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
5421  if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
5422  }
5423  }
5424  }
5425  if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
5426  if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
5427  if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,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) gPad->PaintLine(xi1,yi1,xi3,yi2);
5432  if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
5433  }
5434  }
5435  }
5436 
5437  // draw line at the end of the error bars
5438 
5439  if (option1 && drawmarker) {
5440  if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
5441  if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
5442  if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
5443  if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
5444  }
5445 
5446  // draw the marker
5447 
5448  if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
5449 
5450 L30:
5451  if (fixbin) xp += Hparam.xbinsize;
5452  else {
5453  if (k < last) {
5454  delta = fH->GetBinWidth(k+1);
5455  xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
5456  }
5457  }
5458  } //end of for loop
5459 
5460  // draw the filled area
5461 
5462  if (option3) {
5463  TGraph graph;
5464  graph.SetLineStyle(fH->GetLineStyle());
5465  graph.SetLineColor(fH->GetLineColor());
5466  graph.SetLineWidth(fH->GetLineWidth());
5467  graph.SetFillStyle(fH->GetFillStyle());
5468  graph.SetFillColor(fH->GetFillColor());
5469  Int_t logx = gPad->GetLogx();
5470  Int_t logy = gPad->GetLogy();
5471  gPad->SetLogx(0);
5472  gPad->SetLogy(0);
5473 
5474  // In some cases the number of points in the fill area is smaller than
5475  // 2*npoints. In such cases the array xline and yline must be arranged
5476  // before being plotted. The next loop does that.
5477  if (if2 > npoints) {
5478  for (i=1; i<if1; i++) {
5479  xline[if1-2+i] = xline[if2-1+i];
5480  yline[if1-2+i] = yline[if2-1+i];
5481  }
5482  npoints = if1-1;
5483  }
5484  if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
5485  else graph.PaintGraph(2*npoints,xline,yline,"F");
5486  gPad->SetLogx(logx);
5487  gPad->SetLogy(logy);
5488  delete [] xline;
5489  delete [] yline;
5490  }
5491 }
5492 
5493 
5494 ////////////////////////////////////////////////////////////////////////////////
5495 /// Draw 2D histograms errors.
5496 
5498 {
5499 
5500  fH->TAttMarker::Modify();
5501  fH->TAttLine::Modify();
5502 
5503  // Define the 3D view
5504  fXbuf[0] = Hparam.xmin;
5505  fYbuf[0] = Hparam.xmax;
5506  fXbuf[1] = Hparam.ymin;
5507  fYbuf[1] = Hparam.ymax;
5508  fXbuf[2] = Hparam.zmin;
5509  fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
5511  TView *view = gPad->GetView();
5512  if (!view) {
5513  Error("Paint2DErrors", "no TView in current pad");
5514  return;
5515  }
5516  Double_t thedeg = 90 - gPad->GetTheta();
5517  Double_t phideg = -90 - gPad->GetPhi();
5518  Double_t psideg = view->GetPsi();
5519  Int_t irep;
5520  view->SetView(phideg, thedeg, psideg, irep);
5521 
5522  // Set color/style for back box
5523  fLego->SetFillStyle(gPad->GetFrameFillStyle());
5524  fLego->SetFillColor(gPad->GetFrameFillColor());
5525  fLego->TAttFill::Modify();
5526  Int_t backcolor = gPad->GetFrameFillColor();
5527  if (Hoption.System != kCARTESIAN) backcolor = 0;
5528  view->PadRange(backcolor);
5531  fLego->TAttFill::Modify();
5532 
5533  // Paint the Back Box if needed
5534  if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
5535  fLego->InitMoveScreen(-1.1,1.1);
5538  fLego->BackBox(90);
5539  }
5540 
5541  // Paint the Errors
5542  Double_t x, ex, x1, x2;
5543  Double_t y, ey, y1, y2;
5544  Double_t z, ez1, ez2, z1, z2;
5545  Double_t temp1[3],temp2[3];
5546  Double_t xyerror;
5547  if (Hoption.Error == 110) {
5548  xyerror = 0;
5549  } else {
5550  xyerror = gStyle->GetErrorX();
5551  }
5552 
5553  Double_t xk, xstep, yk, ystep;
5554  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5555  y = fYaxis->GetBinCenter(j);
5556  ey = fYaxis->GetBinWidth(j)*xyerror;
5557  y1 = y-ey;
5558  y2 = y+ey;
5559  if (Hoption.Logy) {
5560  if (y > 0) y = TMath::Log10(y);
5561  else continue;
5562  if (y1 > 0) y1 = TMath::Log10(y1);
5563  else y1 = Hparam.ymin;
5564  if (y2 > 0) y2 = TMath::Log10(y2);
5565  else y2 = Hparam.ymin;
5566  }
5567  yk = fYaxis->GetBinLowEdge(j);
5568  ystep = fYaxis->GetBinWidth(j);
5569  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5570  xk = fXaxis->GetBinLowEdge(i);
5571  xstep = fXaxis->GetBinWidth(i);
5572  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5573  Int_t bin = fH->GetBin(i,j);
5574  x = fXaxis->GetBinCenter(i);
5575  ex = fXaxis->GetBinWidth(i)*xyerror;
5576  x1 = x-ex;
5577  x2 = x+ex;
5578  if (Hoption.Logx) {
5579  if (x > 0) x = TMath::Log10(x);
5580  else continue;
5581  if (x1 > 0) x1 = TMath::Log10(x1);
5582  else x1 = Hparam.xmin;
5583  if (x2 > 0) x2 = TMath::Log10(x2);
5584  else x2 = Hparam.xmin;
5585  }
5586  z = fH->GetBinContent(bin);
5587  if (fH->GetBinErrorOption() == TH1::kNormal) {
5588  ez1 = fH->GetBinError(bin);
5589  ez2 = ez1;
5590  }
5591  else {
5592  ez1 = fH->GetBinErrorLow(bin);
5593  ez2 = fH->GetBinErrorUp(bin);
5594  }
5595  z1 = z - ez1;
5596  z2 = z + ez2;
5597  if (Hoption.Logz) {
5598  if (z > 0) z = TMath::Log10(z);
5599  else z = Hparam.zmin;
5600  if (z1 > 0) z1 = TMath::Log10(z1);
5601  else z1 = Hparam.zmin;
5602  if (z2 > 0) z2 = TMath::Log10(z2);
5603  else z2 = Hparam.zmin;
5604 
5605  }
5606  if (z <= Hparam.zmin) continue;
5607  if (z > Hparam.zmax) z = Hparam.zmax;
5608 
5609  temp1[0] = x1;
5610  temp1[1] = y;
5611  temp1[2] = z;
5612  temp2[0] = x2;
5613  temp2[1] = y;
5614  temp2[2] = z;
5615  gPad->PaintLine3D(temp1, temp2);
5616  temp1[0] = x;
5617  temp1[1] = y1;
5618  temp1[2] = z;
5619  temp2[0] = x;
5620  temp2[1] = y2;
5621  temp2[2] = z;
5622  gPad->PaintLine3D(temp1, temp2);
5623  temp1[0] = x;
5624  temp1[1] = y;
5625  temp1[2] = z1;
5626  temp2[0] = x;
5627  temp2[1] = y;
5628  temp2[2] = z2;
5629  gPad->PaintLine3D(temp1, temp2);
5630  temp1[0] = x;
5631  temp1[1] = y;
5632  temp1[2] = z;
5633  view->WCtoNDC(temp1, &temp2[0]);
5634  gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
5635  }
5636  }
5637 
5638  // Paint the Front Box if needed
5639  if (Hoption.FrontBox) {
5640  fLego->InitMoveScreen(-1.1,1.1);
5642  fLego->FrontBox(90);
5643  }
5644 
5645  // Paint the Axis if needed
5646  if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
5647  TGaxis *axis = new TGaxis();
5648  PaintLegoAxis(axis, 90);
5649  delete axis;
5650  }
5651 
5652  delete fLego; fLego = 0;
5653 }
5654 
5655 
5656 ////////////////////////////////////////////////////////////////////////////////
5657 /// Calculate range and clear pad (canvas).
5658 
5660 {
5661 
5662  if (Hoption.Same) return;
5663 
5664  RecalculateRange();
5666  if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
5667  Hoption.Contour == 14 || Hoption.Error >= 100) {
5668  TObject *frame = gPad->FindObject("TFrame");
5669  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
5670  return;
5671  }
5672 
5673  //The next statement is always executed on non-iOS platform,
5674  //on iOS depends on pad mode.
5675  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
5676  gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
5677 }
5678 
5679 
5680 ////////////////////////////////////////////////////////////////////////////////
5681 /// [Paint functions associated to an histogram.](#HP28")
5682 
5684 {
5685 
5687  TObject *obj;
5688 
5689  while (lnk) {
5690  obj = lnk->GetObject();
5691  TVirtualPad *padsave = gPad;
5692  if (obj->InheritsFrom(TF2::Class())) {
5693  if (obj->TestBit(TF2::kNotDraw) == 0) {
5694  if (Hoption.Lego || Hoption.Surf) {
5695  TF2 *f2 = (TF2*)obj;
5696  f2->SetMinimum(fH->GetMinimum());
5697  f2->SetMaximum(fH->GetMaximum());
5698  f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
5699  f2->Paint("surf same");
5700  } else {
5701  obj->Paint("cont3 same");
5702  }
5703  }
5704  } else if (obj->InheritsFrom(TF1::Class())) {
5705  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
5706  } else {
5707  //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
5708  gPad->PushSelectableObject(obj);
5709 
5710  //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
5711  //and picked object.
5712  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
5713  obj->Paint(lnk->GetOption());
5714  }
5715  lnk = (TObjOptLink*)lnk->Next();
5716  padsave->cd();
5717  }
5718 }
5719 
5720 
5721 ////////////////////////////////////////////////////////////////////////////////
5722 /// [Control routine to draw 1D histograms](#HP01b)
5723 
5725 {
5726 
5727  //On iOS: do not highlight hist, if part of it was selected.
5728  //Never executes on non-iOS platform.
5729  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
5730  return;
5731 
5732  static char chopth[17];
5733 
5734  Int_t htype, oldhtype;
5735  Int_t i, j, first, last, nbins, fixbin;
5736  Double_t c1, yb;
5737  yb = 0;
5738 
5739  strlcpy(chopth, " ",17);
5740 
5741  Double_t ymin = Hparam.ymin;
5742  Double_t ymax = Hparam.ymax;
5743  Double_t baroffset = fH->GetBarOffset();
5744  Double_t barwidth = fH->GetBarWidth();
5745  Double_t baroffsetsave = gStyle->GetBarOffset();
5746  Double_t barwidthsave = gStyle->GetBarWidth();
5747  gStyle->SetBarOffset(baroffset);
5748  gStyle->SetBarWidth(barwidth);
5749 
5750  // Create "LIFE" structure to keep current histogram status
5751 
5752  first = Hparam.xfirst;
5753  last = Hparam.xlast;
5754  nbins = last - first + 1;
5755 
5756  Double_t *keepx = 0;
5757  Double_t *keepy = 0;
5758  if (fXaxis->GetXbins()->fN) fixbin = 0;
5759  else fixbin = 1;
5760  if (fixbin) keepx = new Double_t[2];
5761  else keepx = new Double_t[nbins+1];
5762  keepy = new Double_t[nbins];
5763  Double_t logymin = 0;
5764  if (Hoption.Logy) logymin = TMath::Power(10,ymin);
5765 
5766  // Loop on histogram bins
5767 
5768  for (j=first; j<=last;j++) {
5769  c1 = Hparam.factor*fH->GetBinContent(j);
5770  if (TMath::Abs(ymax-ymin) > 0) {
5771  if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
5772  else yb = c1;
5773  }
5774  if (!Hoption.Line) {
5775  yb = TMath::Max(yb, ymin);
5776  yb = TMath::Min(yb, ymax);
5777  }
5778  keepy[j-first] = yb;
5779  }
5780 
5781  // Draw histogram according to value of FillStyle and FillColor
5782 
5783  if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
5784  else {
5785  for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
5786  keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
5787  }
5788 
5789  // Prepare Fill area (systematic with option "Bar").
5790 
5791  oldhtype = fH->GetFillStyle();
5792  htype = oldhtype;
5793  if (Hoption.Bar) {
5794  if (htype == 0 || htype == 1000) htype = 1001;
5795  }
5796 
5797  Width_t lw = (Width_t)fH->GetLineWidth();
5798 
5799  // Code option for GrapHist
5800 
5801  if (Hoption.Line) chopth[0] = 'L';
5802  if (Hoption.Star) chopth[1] = '*';
5803  if (Hoption.Mark) chopth[2] = 'P';
5804  if (Hoption.Mark == 10) chopth[3] = '0';
5805  if (Hoption.Line || Hoption.Curve || Hoption.Hist || Hoption.Bar) {
5806  if (Hoption.Curve) chopth[3] = 'C';
5807  if (Hoption.Hist > 0) chopth[4] = 'H';
5808  else if (Hoption.Bar) chopth[5] = 'B';
5809  if (fH->GetFillColor() && htype) {
5810  if (Hoption.Logy) {
5811  chopth[6] = '1';
5812  }
5813  if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
5814  chopth[7] = 'F';
5815  }
5816  }
5817  }
5818  if (!fixbin && strlen(chopth)) {
5819  chopth[8] = 'N';
5820  }
5821 
5822  if (Hoption.Fill == 2) chopth[13] = '2';
5823 
5824  // Option LOGX
5825 
5826  if (Hoption.Logx) {
5827  chopth[9] = 'G';
5828  chopth[10] = 'X';
5829  if (fixbin) {
5830  keepx[0] = TMath::Power(10,keepx[0]);
5831  keepx[1] = TMath::Power(10,keepx[1]);
5832  }
5833  }
5834 
5835  if (Hoption.Off) {
5836  chopth[11] = ']';
5837  chopth[12] = '[';
5838  }
5839 
5840  // Draw the histogram
5841 
5842  TGraph graph;
5843  graph.SetLineWidth(lw);
5844  graph.SetLineStyle(fH->GetLineStyle());
5845  graph.SetLineColor(fH->GetLineColor());
5846  graph.SetFillStyle(htype);
5847  graph.SetFillColor(fH->GetFillColor());
5848  graph.SetMarkerStyle(fH->GetMarkerStyle());
5849  graph.SetMarkerSize(fH->GetMarkerSize());
5850  graph.SetMarkerColor(fH->GetMarkerColor());
5851  if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
5852 
5853  graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
5854 
5855  delete [] keepx;
5856  delete [] keepy;
5857  gStyle->SetBarOffset(baroffsetsave);
5858  gStyle->SetBarWidth(barwidthsave);
5859 
5860  htype=oldhtype;
5861 }
5862 
5863 
5864 ////////////////////////////////////////////////////////////////////////////////
5865 /// [Control function to draw a 3D histograms.](#HP01d)
5866 
5867 void THistPainter::PaintH3(Option_t *option)
5868 {
5869 
5870  char *cmd;
5871  TString opt = fH->GetDrawOption();
5872  opt.ToLower();
5873  Int_t irep;
5874 
5875  if (fH->GetDrawOption() && (strstr(opt,"box") || strstr(opt,"lego"))) {
5876  cmd = Form("TMarker3DBox::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
5877  } else if (fH->GetDrawOption() && strstr(opt,"iso")) {
5878  PaintH3Iso();
5879  return;
5880  } else if (strstr(option,"tf3")) {
5881  PaintTF3();
5882  return;
5883  } else {
5884  cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
5885  }
5886 
5887  if (strstr(opt,"fb")) Hoption.FrontBox = 0;
5888  if (strstr(opt,"bb")) Hoption.BackBox = 0;
5889 
5890  TView *view = gPad->GetView();
5891  if (!view) return;
5892  Double_t thedeg = 90 - gPad->GetTheta();
5893  Double_t phideg = -90 - gPad->GetPhi();
5894  Double_t psideg = view->GetPsi();
5895  view->SetView(phideg, thedeg, psideg, irep);
5896 
5897  // Paint the data
5898  gROOT->ProcessLine(cmd);
5899 
5900  if (Hoption.Same) return;
5901 
5902  // Draw axis
5903  view->SetOutlineToCube();
5904  TSeqCollection *ol = view->GetOutline();
5905  if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
5906  Hoption.System = kCARTESIAN;
5907  TGaxis *axis = new TGaxis();
5908  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
5909  delete axis;
5910 
5911  // Draw palette. In case of 4D plot with TTree::Draw() the palette should
5912  // be painted with the option colz.
5913  if (fH->GetDrawOption() && strstr(opt,"colz")) {
5914  Int_t ndiv = fH->GetContour();
5915  if (ndiv == 0 ) {
5916  ndiv = gStyle->GetNumberContours();
5917  fH->SetContour(ndiv);
5918  }
5919  PaintPalette();
5920  }
5921 
5922  // Draw title
5923  PaintTitle();
5924 
5925  //Draw stats and fit results
5926  TF1 *fit = 0;
5928  TObject *obj;
5929  while ((obj = next())) {
5930  if (obj->InheritsFrom(TF1::Class())) {
5931  fit = (TF1*)obj;
5932  break;
5933  }
5934  }
5935  if (Hoption.Same != 1) {
5936  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5937  PaintStat3(gStyle->GetOptStat(),fit);
5938  }
5939  }
5940 
5941 }
5942 
5943 
5944 ////////////////////////////////////////////////////////////////////////////////
5945 /// Compute histogram parameters used by the drawing routines.
5946 
5948 {
5949 
5950  if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
5951 
5952  Int_t i;
5953  static const char *where = "PaintInit";
5954  Double_t yMARGIN = gStyle->GetHistTopMargin();
5955  Int_t maximum = 0;
5956  Int_t minimum = 0;
5957  if (fH->GetMaximumStored() != -1111) maximum = 1;
5958  if (fH->GetMinimumStored() != -1111) minimum = 1;
5959 
5960  // Compute X axis parameters
5961 
5962  Int_t last = fXaxis->GetLast();
5963  Int_t first = fXaxis->GetFirst();
5964  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
5965  Hparam.xbinsize = fXaxis->GetBinWidth(first);
5966  Hparam.xlast = last;
5967  Hparam.xfirst = first;
5968  Hparam.xmin = Hparam.xlowedge;
5969  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
5970 
5971  // if log scale in X, replace xmin,max by the log
5972  if (Hoption.Logx) {
5973  if (Hparam.xmax<=0) {
5974  Error(where, "cannot set X axis to log scale");
5975  return 0;
5976  }
5977  if (Hparam.xlowedge <=0 ) {
5978  if (Hoption.Same) {
5979  Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
5980  } else {
5981  for (i=first; i<=last; i++) {
5982  Double_t binLow = fXaxis->GetBinLowEdge(i);
5983  if (binLow>0) {
5984  Hparam.xlowedge = binLow;
5985  break;
5986  }
5987  if (binLow == 0 && fH->GetBinContent(i) !=0) {
5988  Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
5989  break;
5990  }
5991  }
5992  if (Hparam.xlowedge<=0) {
5993  Error(where, "cannot set X axis to log scale");
5994  return 0;
5995  }
5996  }
5997  Hparam.xmin = Hparam.xlowedge;
5998  }
5999  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
6000  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
6001  Hparam.xmin = TMath::Log10(Hparam.xmin);
6002  Hparam.xmax = TMath::Log10(Hparam.xmax);
6003  if (Hparam.xlast > last) Hparam.xlast = last;
6004  if (Hparam.xfirst < first) Hparam.xfirst = first;
6005  }
6006 
6007  // Compute Y axis parameters
6008  Double_t bigp = TMath::Power(10,32);
6009  Double_t ymax = -bigp;
6010  Double_t ymin = bigp;
6011  Double_t c1, e1;
6012  Double_t xv[1];
6013  Double_t fval;
6014  TObject *f;
6015  TF1 *f1;
6016  Double_t allchan = 0;
6017  Int_t nonNullErrors = 0;
6019  for (i=first; i<=last;i++) {
6020  c1 = fH->GetBinContent(i);
6021  ymax = TMath::Max(ymax,c1);
6022  if (Hoption.Logy) {
6023  if (c1 > 0) ymin = TMath::Min(ymin,c1);
6024  } else {
6025  ymin = TMath::Min(ymin,c1);
6026  }
6027  if (Hoption.Error) {
6028  if (fH->GetBinErrorOption() == TH1::kNormal)
6029  e1 = fH->GetBinError(i);
6030  else
6031  e1 = fH->GetBinErrorUp(i);
6032  if (e1 > 0) nonNullErrors++;
6033  ymax = TMath::Max(ymax,c1+e1);
6034  if (fH->GetBinErrorOption() != TH1::kNormal)
6035  e1 = fH->GetBinErrorLow(i);
6036 
6037  if (Hoption.Logy) {
6038  if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6039  } else {
6040  ymin = TMath::Min(ymin,c1-e1);
6041  }
6042  }
6043  if (Hoption.Func) {
6044  xv[0] = fXaxis->GetBinCenter(i);
6045  while ((f = (TObject*) next())) {
6046  if (f->IsA() == TF1::Class()) {
6047  f1 = (TF1*)f;
6048  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6049  fval = f1->Eval(xv[0],0,0);
6050  if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6051  ymax = TMath::Max(ymax,fval);
6052  if (Hoption.Logy) {
6053  if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6054  }
6055  }
6056  }
6057  next.Reset();
6058  }
6059  allchan += c1;
6060  }
6061  if (!nonNullErrors) {
6062  if (Hoption.Error) {
6063  if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
6064  Hoption.Error=0;
6065  }
6066  }
6067 
6068 
6069  // Take into account maximum , minimum
6070 
6071  if (Hoption.Logy && ymin <= 0) {
6072  if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
6073  else ymin = 0.001*ymax;
6074  }
6075 
6076  Double_t xm = ymin;
6077  if (maximum) ymax = fH->GetMaximumStored();
6078  if (minimum) xm = fH->GetMinimumStored();
6079  if (Hoption.Logy && xm < 0) {
6080  Error(where, "log scale requested with a negative argument (%f)", xm);
6081  return 0;
6082  } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
6083  ymin = 0.01;
6084  ymax = 10.;
6085  } else {
6086  ymin = xm;
6087  }
6088 
6089  if (ymin >= ymax) {
6090  if (Hoption.Logy) {
6091  if (ymax > 0) ymin = 0.001*ymax;
6092  else {
6093  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
6094  return 0;
6095  }
6096  }
6097  else {
6098  if (ymin > 0) {
6099  ymin = 0;
6100  ymax *= 2;
6101  } else if (ymin < 0) {
6102  ymax = 0;
6103  ymin *= 2;
6104  } else {
6105  ymin = 0;
6106  ymax = 1;
6107  }
6108  }
6109  }
6110 
6111  // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
6112  if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
6113  ymin = ymin*(1-1E-14);
6114  ymax = ymax*(1+1E-14);
6115  }
6116 
6117  // take into account normalization factor
6118  Hparam.allchan = allchan;
6119  Double_t factor = allchan;
6120  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6121  if (allchan) factor /= allchan;
6122  if (factor == 0) factor = 1;
6123  Hparam.factor = factor;
6124  ymax = factor*ymax;
6125  ymin = factor*ymin;
6126  //just in case the norm factor is negative
6127  // this may happen with a positive norm factor and a negative integral !
6128  if (ymax < ymin) {
6129  Double_t temp = ymax;
6130  ymax = ymin;
6131  ymin = temp;
6132  }
6133 
6134  // For log scales, histogram coordinates are LOG10(ymin) and
6135  // LOG10(ymax). Final adjustment (if not option "Same"
6136  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6137  // Maximum and Minimum are not defined.
6138  if (Hoption.Logy) {
6139  if (ymin <=0 || ymax <=0) {
6140  Error(where, "Cannot set Y axis to log scale");
6141  return 0;
6142  }
6143  ymin = TMath::Log10(ymin);
6144  if (!minimum) ymin += TMath::Log10(0.5);
6145  ymax = TMath::Log10(ymax);
6146  if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
6147  if (!Hoption.Same) {
6148  Hparam.ymin = ymin;
6149  Hparam.ymax = ymax;
6150  }
6151  return 1;
6152  }
6153 
6154  // final adjustment of ymin for linear scale.
6155  // if minimum is not set , then ymin is set to zero if >0
6156  // or to ymin - margin if <0.
6157  if (!minimum) {
6158  if (gStyle->GetHistMinimumZero()) {
6159  if (ymin >= 0) ymin = 0;
6160  else ymin -= yMARGIN*(ymax-ymin);
6161  } else {
6162  Double_t dymin = yMARGIN*(ymax-ymin);
6163  if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
6164  else ymin -= dymin;
6165  }
6166  }
6167 
6168  // final adjustment of YMAXI for linear scale (if not option "Same"):
6169  // decrease histogram height to MAX% of allowed height if HMAXIM
6170  // has not been called.
6171  if (!maximum) {
6172  ymax += yMARGIN*(ymax-ymin);
6173  }
6174 
6175  Hparam.ymin = ymin;
6176  Hparam.ymax = ymax;
6177  return 1;
6178 }
6179 
6180 
6181 ////////////////////////////////////////////////////////////////////////////////
6182 /// Compute histogram parameters used by the drawing routines for a rotated pad.
6183 
6185 {
6186 
6187  static const char *where = "PaintInitH";
6188  Double_t yMARGIN = gStyle->GetHistTopMargin();
6189  Int_t maximum = 0;
6190  Int_t minimum = 0;
6191  if (fH->GetMaximumStored() != -1111) maximum = 1;
6192  if (fH->GetMinimumStored() != -1111) minimum = 1;
6193 
6194  // Compute X axis parameters
6195 
6196  Int_t last = fXaxis->GetLast();
6197  Int_t first = fXaxis->GetFirst();
6198  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
6199  Hparam.xbinsize = fXaxis->GetBinWidth(first);
6200  Hparam.xlast = last;
6201  Hparam.xfirst = first;
6202  Hparam.ymin = Hparam.xlowedge;
6203  Hparam.ymax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
6204 
6205  // if log scale in Y, replace ymin,max by the log
6206  if (Hoption.Logy) {
6207  if (Hparam.xlowedge <=0 ) {
6208  Hparam.xlowedge = 0.1*Hparam.xbinsize;
6209  Hparam.ymin = Hparam.xlowedge;
6210  }
6211  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
6212  Error(where, "cannot set Y axis to log scale");
6213  return 0;
6214  }
6215  Hparam.xfirst= fXaxis->FindFixBin(Hparam.ymin);
6216  Hparam.xlast = fXaxis->FindFixBin(Hparam.ymax);
6217  Hparam.ymin = TMath::Log10(Hparam.ymin);
6218  Hparam.ymax = TMath::Log10(Hparam.ymax);
6219  if (Hparam.xlast > last) Hparam.xlast = last;
6220  }
6221 
6222  // Compute Y axis parameters
6223  Double_t bigp = TMath::Power(10,32);
6224  Double_t xmax = -bigp;
6225  Double_t xmin = bigp;
6226  Double_t c1, e1;
6227  Double_t xv[1];
6228  Double_t fval;
6229  Int_t i;
6230  TObject *f;
6231  TF1 *f1;
6232  Double_t allchan = 0;
6234  for (i=first; i<=last;i++) {
6235  c1 = fH->GetBinContent(i);
6236  xmax = TMath::Max(xmax,c1);
6237  xmin = TMath::Min(xmin,c1);
6238  if (Hoption.Error) {
6239  e1 = fH->GetBinError(i);
6240  xmax = TMath::Max(xmax,c1+e1);
6241  xmin = TMath::Min(xmin,c1-e1);
6242  }
6243  if (Hoption.Func) {
6244  xv[0] = fXaxis->GetBinCenter(i);
6245  while ((f = (TObject*) next())) {
6246  if (f->IsA() == TF1::Class()) {
6247  f1 = (TF1*)f;
6248  if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6249  fval = f1->Eval(xv[0],0,0);
6250  xmax = TMath::Max(xmax,fval);
6251  if (Hoption.Logy) {
6252  if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
6253  }
6254  }
6255  }
6256  next.Reset();
6257  }
6258  allchan += c1;
6259  }
6260 
6261  // Take into account maximum , minimum
6262 
6263  if (Hoption.Logx && xmin <= 0) {
6264  if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
6265  else xmin = 0.001*xmax;
6266  }
6267  Double_t xm = xmin;
6268  if (maximum) xmax = fH->GetMaximumStored();
6269  if (minimum) xm = fH->GetMinimumStored();
6270  if (Hoption.Logx && xm <= 0) {
6271  Error(where, "log scale requested with zero or negative argument (%f)", xm);
6272  return 0;
6273  }
6274  else xmin = xm;
6275  if (xmin >= xmax) {
6276  if (Hoption.Logx) {
6277  if (xmax > 0) xmin = 0.001*xmax;
6278  else {
6279  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
6280  return 0;
6281  }
6282  }
6283  else {
6284  if (xmin > 0) {
6285  xmin = 0;
6286  xmax *= 2;
6287  } else if (xmin < 0) {
6288  xmax = 0;
6289  xmin *= 2;
6290  } else {
6291  xmin = -1;
6292  xmax = 1;
6293  }
6294  }
6295  }
6296 
6297  // take into account normalization factor
6298  Hparam.allchan = allchan;
6299  Double_t factor = allchan;
6300  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
6301  if (allchan) factor /= allchan;
6302  if (factor == 0) factor = 1;
6303  Hparam.factor = factor;
6304  xmax = factor*xmax;
6305  xmin = factor*xmin;
6306 
6307  // For log scales, histogram coordinates are LOG10(ymin) and
6308  // LOG10(ymax). Final adjustment (if not option "Same"
6309  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
6310  // Maximum and Minimum are not defined.
6311  if (Hoption.Logx) {
6312  if (xmin <=0 || xmax <=0) {
6313  Error(where, "Cannot set Y axis to log scale");
6314  return 0;
6315  }
6316  xmin = TMath::Log10(xmin);
6317  if (!minimum) xmin += TMath::Log10(0.5);
6318  xmax = TMath::Log10(xmax);
6319  if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
6320  if (!Hoption.Same) {
6321  Hparam.xmin = xmin;
6322  Hparam.xmax = xmax;
6323  }
6324  return 1;
6325  }
6326 
6327  // final adjustment of ymin for linear scale.
6328  // if minimum is not set , then ymin is set to zero if >0
6329  // or to ymin - margin if <0.
6330  if (!minimum) {
6331  if (xmin >= 0) xmin = 0;
6332  else xmin -= yMARGIN*(xmax-xmin);
6333  }
6334 
6335  // final adjustment of YMAXI for linear scale (if not option "Same"):
6336  // decrease histogram height to MAX% of allowed height if HMAXIM
6337  // has not been called.
6338  if (!maximum) {
6339  xmax += yMARGIN*(xmax-xmin);
6340  }
6341  Hparam.xmin = xmin;
6342  Hparam.xmax = xmax;
6343  return 1;
6344 }
6345 
6346 
6347 ////////////////////////////////////////////////////////////////////////////////
6348 /// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
6349 
6351 {
6352 
6353  const Double_t ydiff = 1;
6354  const Double_t yligh1 = 10;
6355  const Double_t qa = 0.15;
6356  const Double_t qd = 0.15;
6357  const Double_t qs = 0.8;
6358  Double_t fmin, fmax;
6359  Int_t i, irep;
6360  Int_t nbcol = 28;
6361  Int_t icol1 = 201;
6362  Int_t ic1 = icol1;
6363  Int_t ic2 = ic1+nbcol;
6364  Int_t ic3 = ic2+nbcol;
6365 
6366  TGaxis *axis = new TGaxis();
6367  TAxis *xaxis = fH->GetXaxis();
6368  TAxis *yaxis = fH->GetYaxis();
6369  TAxis *zaxis = fH->GetZaxis();
6370 
6371  Int_t nx = fH->GetNbinsX();
6372  Int_t ny = fH->GetNbinsY();
6373  Int_t nz = fH->GetNbinsZ();
6374 
6375  Double_t *x = new Double_t[nx];
6376  Double_t *y = new Double_t[ny];
6377  Double_t *z = new Double_t[nz];
6378 
6379  for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
6380  for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
6381  for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
6382 
6383  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
6384  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
6385  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
6386  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
6387  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
6388  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
6389 
6390  Double_t s[3];
6391  s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
6392  s[1] = 0.5*s[0];
6393  s[2] = 1.5*s[0];
6394 
6396 
6397  TView *view = gPad->GetView();
6398  if (!view) {
6399  Error("PaintH3Iso", "no TView in current pad");
6400  delete [] x;
6401  delete [] y;
6402  delete [] z;
6403  return;
6404  }
6405  Double_t thedeg = 90 - gPad->GetTheta();
6406  Double_t phideg = -90 - gPad->GetPhi();
6407  Double_t psideg = view->GetPsi();
6408  view->SetView(phideg, thedeg, psideg, irep);
6409 
6410  Int_t backcolor = gPad->GetFrameFillColor();
6411  if (Hoption.System != kCARTESIAN) backcolor = 0;
6412  view->PadRange(backcolor);
6413 
6414  Double_t dcol = 0.5/Double_t(nbcol);
6415  TColor *colref = gROOT->GetColor(fH->GetFillColor());
6416  if (!colref) {
6417  delete [] x;
6418  delete [] y;
6419  delete [] z;
6420  return;
6421  }
6422  Float_t r, g, b, hue, light, satur;
6423  colref->GetRGB(r,g,b);
6424  TColor::RGBtoHLS(r,g,b,hue,light,satur);
6425  TColor *acol;
6426  for (Int_t col=0;col<nbcol;col++) {
6427  acol = gROOT->GetColor(col+icol1);
6428  TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
6429  if (acol) acol->SetRGB(r, g, b);
6430  }
6431 
6432  fLego->InitMoveScreen(-1.1,1.1);
6433 
6434  if (Hoption.BackBox) {
6437  fLego->BackBox(90);
6438  }
6439 
6440  fLego->LightSource(0, ydiff, 0, 0, 0, irep);
6441  fLego->LightSource(1, yligh1, 1, 1, 1, irep);
6442  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
6443  fmin = ydiff*qa;
6444  fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
6445  fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
6446 
6447  fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
6448 
6449  if (Hoption.FrontBox) {
6450  fLego->InitMoveScreen(-1.1,1.1);
6452  fLego->FrontBox(90);
6453  }
6454  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6455 
6456  PaintTitle();
6457 
6458  delete axis;
6459  delete fLego; fLego = 0;
6460  delete [] x;
6461  delete [] y;
6462  delete [] z;
6463 }
6464 
6465 
6466 ////////////////////////////////////////////////////////////////////////////////
6467 /// [Control function to draw a 2D histogram as a lego plot.](#HP17)
6468 
6470 {
6471 
6472  Int_t raster = 1;
6473  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
6474  Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
6475  Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
6476  Double_t zmin = Hparam.zmin;
6477  Double_t zmax = Hparam.zmax;
6478  Double_t xlab1 = Hparam.xmin;
6479  Double_t xlab2 = Hparam.xmax;
6480  Double_t ylab1 = Hparam.ymin;
6481  Double_t ylab2 = Hparam.ymax;
6482  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
6483  Double_t deltaz = TMath::Abs(zmin);
6484  if (deltaz == 0) deltaz = 1;
6485  if (zmin >= zmax) {
6486  zmin -= 0.5*deltaz;
6487  zmax += 0.5*deltaz;
6488  }
6489  Double_t z1c = zmin;
6490  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
6491 
6492  // Compute the lego limits and instantiate a lego object
6493  fXbuf[0] = -1;
6494  fYbuf[0] = 1;
6495  fXbuf[1] = -1;
6496  fYbuf[1] = 1;
6497  if (Hoption.System == kPOLAR) {
6498  fXbuf[2] = z1c;
6499  fYbuf[2] = z2c;
6500  } else if (Hoption.System == kCYLINDRICAL) {
6501  if (Hoption.Logy) {
6502  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
6503  else fXbuf[2] = 0;
6504  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
6505  else fYbuf[2] = 0;
6506  } else {
6507  fXbuf[2] = ylab1;
6508  fYbuf[2] = ylab2;
6509  }
6510  z1c = 0; z2c = 1;
6511  } else if (Hoption.System == kSPHERICAL) {
6512  fXbuf[2] = -1;
6513  fYbuf[2] = 1;
6514  z1c = 0; z2c = 1;
6515  } else if (Hoption.System == kRAPIDITY) {
6516  fXbuf[2] = -1/TMath::Tan(dangle);
6517  fYbuf[2] = 1/TMath::Tan(dangle);
6518  } else {
6519  fXbuf[0] = xlab1;
6520  fYbuf[0] = xlab2;
6521  fXbuf[1] = ylab1;
6522  fYbuf[1] = ylab2;
6523  fXbuf[2] = z1c;
6524  fYbuf[2] = z2c;
6525  raster = 0;
6526  }
6527 
6528  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
6529 
6530  Int_t nids = -1;
6531  TH1 * hid = NULL;
6532  Color_t colormain = -1, colordark = -1;
6533  Bool_t drawShadowsInLego1 = kTRUE;
6534 
6535  // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
6536  if (Hoption.Lego == 13) {
6537  Hoption.Lego = 11;
6538  fLego->SetMesh(0);
6539  }
6540  // LEGO4 is like LEGO1 except no shadows are drawn.
6541  if (Hoption.Lego == 14) {
6542  Hoption.Lego = 11;
6543  drawShadowsInLego1 = kFALSE;
6544  }
6545 
6546  // Create axis object
6547 
6548  TGaxis *axis = new TGaxis();
6549 
6550  // Initialize the levels on the Z axis
6551  Int_t ndiv = fH->GetContour();
6552  if (ndiv == 0 ) {
6553  ndiv = gStyle->GetNumberContours();
6554  fH->SetContour(ndiv);
6555  }
6556  Int_t ndivz = TMath::Abs(ndiv);
6557  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
6558 
6559  // Initialize colors
6560  if (!fStack) {
6562  } else {
6563  for (Int_t id=0;id<=fStack->GetSize();id++) {
6564  hid = (TH1*)fStack->At((id==0)?id:id-1);
6565  fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
6566  }
6567  }
6568 
6569  if (Hoption.Lego == 11) {
6570  nids = 1;
6571  if (fStack) nids = fStack->GetSize();
6572  hid = fH;
6573  for (Int_t id=0;id<=nids;id++) {
6574  if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
6575  colormain = hid->GetFillColor();
6576  if (colormain == 1) colormain = 17; //avoid drawing with black
6577  if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
6578  else colordark = colormain;
6579  fLego->SetColorMain(colormain,id);
6580  fLego->SetColorDark(colordark,id);
6581  if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
6582  if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
6583  }
6584  }
6585 
6586  // Now ready to draw the lego plot
6587  Int_t irep = 0;
6588 
6589  TView *view = gPad->GetView();
6590  if (!view) {
6591  Error("PaintLego", "no TView in current pad");
6592  return;
6593  }
6594 
6595  Double_t thedeg = 90 - gPad->GetTheta();
6596  Double_t phideg = -90 - gPad->GetPhi();
6597  Double_t psideg = view->GetPsi();
6598  view->SetView(phideg, thedeg, psideg, irep);
6599 
6600  fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
6602 
6603  // Set color/style for back box
6604  fLego->SetFillStyle(gPad->GetFrameFillStyle());
6605  fLego->SetFillColor(gPad->GetFrameFillColor());
6606  fLego->TAttFill::Modify();
6607 
6608  Int_t backcolor = gPad->GetFrameFillColor();
6609  if (Hoption.System != kCARTESIAN) backcolor = 0;
6610  view->PadRange(backcolor);
6611 
6614  fLego->TAttFill::Modify();
6615 
6617 
6618  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
6619  else fLego->InitMoveScreen(-1.1,1.1);
6620 
6621  if (Hoption.Lego == 11 || Hoption.Lego == 12) {
6622  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
6624  fLego->BackBox(90);
6625  }
6626  }
6627 
6628  if (Hoption.Lego == 12) DefineColorLevels(ndivz);
6629 
6634  if (Hoption.System == kPOLAR) {
6635  if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
6636  if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
6637  if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
6638  } else if (Hoption.System == kCYLINDRICAL) {
6639  if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
6640  if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
6641  if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
6642  } else if (Hoption.System == kSPHERICAL) {
6643  if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
6644  if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
6645  if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
6646  } else if (Hoption.System == kRAPIDITY) {
6647  if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
6648  if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
6649  if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
6650  } else {
6651  if (Hoption.Lego == 1) {
6653  fLego->LegoCartesian(90,nx,ny,"FB");}
6654  if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
6655  if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
6656  }
6657 
6658  if (Hoption.Lego == 1 || Hoption.Lego == 11) {
6659  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
6661  fLego->BackBox(90);
6662  }
6663  }
6664  if (Hoption.System == kCARTESIAN) {
6665  fLego->InitMoveScreen(-1.1,1.1);
6667  if (Hoption.FrontBox) fLego->FrontBox(90);
6668  }
6669  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6670  if (Hoption.Zscale) PaintPalette();
6671  delete axis;
6672  delete fLego; fLego = 0;
6673 }
6674 
6675 
6676 ////////////////////////////////////////////////////////////////////////////////
6677 /// Draw the axis for legos and surface plots.
6678 
6680 {
6681 
6682  static Double_t epsil = 0.001;
6683 
6684  Double_t cosa, sina;
6685  Double_t bmin, bmax;
6686  Double_t r[24] /* was [3][8] */;
6687  Int_t ndivx, ndivy, ndivz, i;
6688  Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
6689  static char chopax[8], chopay[8], chopaz[8];
6690  Int_t ix1, ix2, iy1, iy2, iz1, iz2;
6691  Double_t rad;
6692 
6693  TView *view = gPad->GetView();
6694  if (!view) {
6695  Error("PaintLegoAxis", "no TView in current pad");
6696  return;
6697  }
6698 
6699  // In polar coordinates, draw a short line going from the external circle
6700  // corresponding to r = 1 up to r = 1.1
6701  if (Hoption.System == kPOLAR) {
6702  r[0] = 1;
6703  r[1] = 0;
6704  r[2] = 0;
6705  view->WCtoNDC(r, x1);
6706  r[0] = 1.1;
6707  r[1] = 0;
6708  r[2] = 0;
6709  view->WCtoNDC(r, x2);
6710  gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
6711  return;
6712  }
6713 
6714  if (Hoption.System != kCARTESIAN) return;
6715 
6716  rad = TMath::ATan(1.) * 4. /180.;
6717  cosa = TMath::Cos(ang*rad);
6718  sina = TMath::Sin(ang*rad);
6719 
6720  view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
6721  for (i = 1; i <= 8; ++i) {
6722  r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
6723  r[i*3 - 2] = av[i*3 - 2]*sina;
6724  r[i*3 - 1] = av[i*3 - 1];
6725  }
6726 
6727  view->WCtoNDC(&r[ix1*3 - 3], x1);
6728  view->WCtoNDC(&r[ix2*3 - 3], x2);
6729  view->WCtoNDC(&r[iy1*3 - 3], y1);
6730  view->WCtoNDC(&r[iy2*3 - 3], y2);
6731  view->WCtoNDC(&r[iz1*3 - 3], z1);
6732  view->WCtoNDC(&r[iz2*3 - 3], z2);
6733 
6734  view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
6735 
6736  Double_t *rmin = view->GetRmin();
6737  Double_t *rmax = view->GetRmax();
6738  if (!rmin || !rmax) return;
6739 
6740  // Initialize the axis options
6741  if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
6742  else strlcpy(chopax, "SDH=-",8);
6743  if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
6744  else strlcpy(chopay, "SDH=-",8);
6745  strlcpy(chopaz, "SDH+=",8);
6746 
6747  // Option LOG is required ?
6748  if (Hoption.Logx) strlcat(chopax,"G",8);
6749  if (Hoption.Logy) strlcat(chopay,"G",8);
6750  if (Hoption.Logz) strlcat(chopaz,"G",8);
6751 
6752  // Initialize the number of divisions. If the
6753  // number of divisions is negative, option 'N' is required.
6754  ndivx = fXaxis->GetNdivisions();
6755  ndivy = fYaxis->GetNdivisions();
6756  ndivz = fZaxis->GetNdivisions();
6757  if (ndivx < 0) {
6758  ndivx = TMath::Abs(ndivx);
6759  strlcat(chopax, "N",8);
6760  }
6761  if (ndivy < 0) {
6762  ndivy = TMath::Abs(ndivy);
6763  strlcat(chopay, "N",8);
6764  }
6765  if (ndivz < 0) {
6766  ndivz = TMath::Abs(ndivz);
6767  strlcat(chopaz, "N",8);
6768  }
6769 
6770  // Set Axis attributes.
6771  // The variable SCALE rescales the VSIZ
6772  // in order to have the same label size for all angles.
6773 
6774  axis->SetLineWidth(1);
6775 
6776  // X axis drawing
6777  if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
6780  if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
6781  bmin = TMath::Power(10, rmin[0]);
6782  bmax = TMath::Power(10, rmax[0]);
6783  } else {
6784  bmin = rmin[0];
6785  bmax = rmax[0];
6786  }
6787  // Option time display is required ?
6788  if (fXaxis->GetTimeDisplay()) {
6789  strlcat(chopax,"t",8);
6790  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
6791  axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
6792  } else {
6794  }
6795  }
6796  axis->SetOption(chopax);
6797  axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
6798  }
6799 
6800  // Y axis drawing
6801  if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
6804 
6805  if (fH->GetDimension() < 2) {
6806  strlcpy(chopay, "V=+UN",8);
6807  ndivy = 0;
6808  }
6809  if (TMath::Abs(y1[0] - y2[0]) < epsil) {
6810  y2[0] = y1[0];
6811  }
6812  if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
6813  bmin = TMath::Power(10, rmin[1]);
6814  bmax = TMath::Power(10, rmax[1]);
6815  } else {
6816  bmin = rmin[1];
6817  bmax = rmax[1];
6818  }
6819  // Option time display is required ?
6820  if (fYaxis->GetTimeDisplay()) {
6821  strlcat(chopay,"t",8);
6822  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
6823  axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
6824  } else {
6826  }
6827  }
6828  axis->SetOption(chopay);
6829  axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
6830  }
6831 
6832  // Z axis drawing
6833  if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
6835  if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
6836  bmin = TMath::Power(10, rmin[2]);
6837  bmax = TMath::Power(10, rmax[2]);
6838  } else {
6839  bmin = rmin[2];
6840  bmax = rmax[2];
6841  }
6842  // Option time display is required ?
6843  if (fZaxis->GetTimeDisplay()) {
6844  strlcat(chopaz,"t",8);
6845  if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
6846  axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
6847  } else {
6849  }
6850  }
6851  axis->SetOption(chopaz);
6852  axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
6853  }
6854 
6855  //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
6856 }
6857 
6858 
6859 ////////////////////////////////////////////////////////////////////////////////
6860 /// [Paint the color palette on the right side of the pad.](#HP22)
6861 
6863 {
6864 
6865  TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
6866  TView *view = gPad->GetView();
6867  if (palette) {
6868  if (view) {
6869  if (!palette->TestBit(TPaletteAxis::kHasView)) {
6870  fFunctions->Remove(palette);
6871  delete palette; palette = 0;
6872  }
6873  } else {
6874  if (palette->TestBit(TPaletteAxis::kHasView)) {
6875  fFunctions->Remove(palette);
6876  delete palette; palette = 0;
6877  }
6878  }
6879  }
6880 
6881  if (!palette) {
6882  Double_t xup = gPad->GetUxmax();
6883  Double_t x2 = gPad->PadtoX(gPad->GetX2());
6884  Double_t ymin = gPad->PadtoY(gPad->GetUymin());
6885  Double_t ymax = gPad->PadtoY(gPad->GetUymax());
6886  Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
6887  Double_t xmin = gPad->PadtoX(xup +0.1*xr);
6888  Double_t xmax = gPad->PadtoX(xup + xr);
6889  if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
6890  palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
6891  fFunctions->AddFirst(palette);
6892  palette->Paint();
6893  }
6894 }
6895 
6896 
6897 ////////////////////////////////////////////////////////////////////////////////
6898 /// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
6899 
6901 {
6902 
6903  fH->TAttMarker::Modify();
6904 
6905  Int_t k, marker;
6906  Double_t dz, z, xk,xstep, yk, ystep;
6907  Double_t scale = 1;
6908  Bool_t ltest = kFALSE;
6909  Double_t zmax = fH->GetMaximum();
6910  Double_t zmin = fH->GetMinimum();
6911  if (zmin == 0 && zmax == 0) return;
6912  if (zmin == zmax) {
6913  zmax += 0.1*TMath::Abs(zmax);
6914  zmin -= 0.1*TMath::Abs(zmin);
6915  }
6916  Int_t ncells = (Hparam.ylast-Hparam.yfirst)*(Hparam.xlast-Hparam.xfirst);
6917  if (Hoption.Logz) {
6918  if (zmin > 0) zmin = TMath::Log10(zmin);
6919  else zmin = 0;
6920  if (zmax > 0) zmax = TMath::Log10(zmax);
6921  else zmax = 0;
6922  if (zmin == 0 && zmax == 0) return;
6923  dz = zmax - zmin;
6924  scale = 100/dz;
6925  if (ncells > 10000) scale /= 5;
6926  ltest = kTRUE;
6927  } else {
6928  dz = zmax - zmin;
6929  if (dz >= kNMAX || zmax < 1) {
6930  scale = (kNMAX-1)/dz;
6931  if (ncells > 10000) scale /= 5;
6932  ltest = kTRUE;
6933  }
6934  }
6935  if (fH->GetMinimumStored() == -1111) {
6936  Double_t yMARGIN = gStyle->GetHistTopMargin();
6937  if (gStyle->GetHistMinimumZero()) {
6938  if (zmin >= 0) zmin = 0;
6939  else zmin -= yMARGIN*(zmax-zmin);
6940  } else {
6941  Double_t dzmin = yMARGIN*(zmax-zmin);
6942  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
6943  else zmin -= dzmin;
6944  }
6945  }
6946 
6947  TString opt = option;
6948  opt.ToLower();
6949  if (opt.Contains("scat=")) {
6950  char optscat[100];
6951  strlcpy(optscat,opt.Data(),100);
6952  char *oscat = strstr(optscat,"scat=");
6953  char *blank = strstr(oscat," "); if (blank) *blank = 0;
6954  sscanf(oscat+5,"%lg",&scale);
6955  }
6956  // use an independent instance of a random generator
6957  // instead of gRandom to avoid conflicts and
6958  // to get same random numbers when drawing the same histogram
6959  TRandom2 random;
6960  marker=0;
6961  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6962  yk = fYaxis->GetBinLowEdge(j);
6963  ystep = fYaxis->GetBinWidth(j);
6964  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6965  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
6966  xk = fXaxis->GetBinLowEdge(i);
6967  xstep = fXaxis->GetBinWidth(i);
6968  if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6969  z = fH->GetBinContent(bin);
6970  if (z < zmin) z = zmin;
6971  if (z > zmax) z = zmax;
6972  if (Hoption.Logz) {
6973  if (z > 0) z = TMath::Log10(z) - zmin;
6974  } else {
6975  z -= zmin;
6976  }
6977  if (z <= 0) continue;
6978  k = Int_t(z*scale);
6979  if (ltest) k++;
6980  if (k > 0) {
6981  for (Int_t loop=0; loop<k; loop++) {
6982  if (k+marker >= kNMAX) {
6983  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
6984  marker=0;
6985  }
6986  fXbuf[marker] = (random.Rndm(loop)*xstep) + xk;
6987  fYbuf[marker] = (random.Rndm(loop)*ystep) + yk;
6988  if (Hoption.Logx) {
6989  if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
6990  else break;
6991  }
6992  if (Hoption.Logy) {
6993  if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
6994  else break;
6995  }
6996  if (fXbuf[marker] < gPad->GetUxmin()) break;
6997  if (fYbuf[marker] < gPad->GetUymin()) break;
6998  if (fXbuf[marker] > gPad->GetUxmax()) break;
6999  if (fYbuf[marker] > gPad->GetUymax()) break;
7000  marker++;
7001  }
7002  }
7003  }
7004  }
7005  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
7006 
7007  if (Hoption.Zscale) PaintPalette();
7008 }
7009 
7010 
7011 ////////////////////////////////////////////////////////////////////////////////
7012 /// Static function to paint special objects like vectors and matrices.
7013 /// This function is called via `gROOT->ProcessLine` to paint these objects
7014 /// without having a direct dependency of the graphics or histogramming
7015 /// system.
7016 
7017 void THistPainter::PaintSpecialObjects(const TObject *obj, Option_t *option)
7018 {
7019 
7020  if (!obj) return;
7024  if (obj->InheritsFrom(TMatrixFBase::Class())) {
7025  // case TMatrixF
7026  TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
7027  R__TMatrixFBase->SetBit(kCanDelete);
7028  R__TMatrixFBase->Draw(option);
7029 
7030  } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
7031  // case TMatrixD
7032  TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
7033  R__TMatrixDBase->SetBit(kCanDelete);
7034  R__TMatrixDBase->Draw(option);
7035 
7036  } else if (obj->InheritsFrom(TVectorF::Class())) {
7037  //case TVectorF
7038  TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
7039  R__TVectorF->SetBit(kCanDelete);
7040  R__TVectorF->Draw(option);
7041 
7042  } else if (obj->InheritsFrom(TVectorD::Class())) {
7043  //case TVectorD
7044  TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
7045  R__TVectorD->SetBit(kCanDelete);
7046  R__TVectorD->Draw(option);
7047  }
7048 
7049  TH1::AddDirectory(status);
7050 }
7051 
7052 
7053 ////////////////////////////////////////////////////////////////////////////////
7054 /// [Draw the statistics box for 1D and profile histograms.](#HP07)
7055 
7056 void THistPainter::PaintStat(Int_t dostat, TF1 *fit)
7057 {
7058 
7059  static char t[100];
7060  Int_t dofit;
7061  TPaveStats *stats = 0;
7063  TObject *obj;
7064  while ((obj = next())) {
7065  if (obj->InheritsFrom(TPaveStats::Class())) {
7066  stats = (TPaveStats*)obj;
7067  break;
7068  }
7069  }
7070 
7071  if (stats && dostat) {
7072  dofit = stats->GetOptFit();
7073  dostat = stats->GetOptStat();
7074  } else {
7075  dofit = gStyle->GetOptFit();
7076  }
7077  if (!dofit) fit = 0;
7078  if (dofit == 1) dofit = 111;
7079  if (dostat == 1) dostat = 1111;
7080  Int_t print_name = dostat%10;
7081  Int_t print_entries = (dostat/10)%10;
7082  Int_t print_mean = (dostat/100)%10;
7083  Int_t print_stddev = (dostat/1000)%10;
7084  Int_t print_under = (dostat/10000)%10;
7085  Int_t print_over = (dostat/100000)%10;
7086  Int_t print_integral= (dostat/1000000)%10;
7087  Int_t print_skew = (dostat/10000000)%10;
7088  Int_t print_kurt = (dostat/100000000)%10;
7089  Int_t nlines = print_name + print_entries + print_mean + print_stddev +
7090  print_under + print_over + print_integral +
7091  print_skew + print_kurt;
7092  Int_t print_fval = dofit%10;
7093  Int_t print_ferrors = (dofit/10)%10;
7094  Int_t print_fchi2 = (dofit/100)%10;
7095  Int_t print_fprob = (dofit/1000)%10;
7096  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
7097  if (fit) {
7098  if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
7099  else nlinesf += fit->GetNpar();
7100  }
7101  if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
7102 
7103  // Pavetext with statistics
7104  Bool_t done = kFALSE;
7105  if (!dostat && !fit) {
7106  if (stats) { fFunctions->Remove(stats); delete stats;}
7107  return;
7108  }
7109  Double_t statw = gStyle->GetStatW();
7110  if (fit) statw = 1.8*gStyle->GetStatW();
7111  Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
7112  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7113  stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
7114  }
7115  if (stats) {
7116  stats->Clear();
7117  done = kTRUE;
7118  } else {
7119  stats = new TPaveStats(
7120  gStyle->GetStatX()-statw,
7121  gStyle->GetStatY()-stath,
7122  gStyle->GetStatX(),
7123  gStyle->GetStatY(),"brNDC");
7124 
7125  stats->SetParent(fH);
7126  stats->SetOptFit(dofit);
7127  stats->SetOptStat(dostat);
7128  stats->SetFillColor(gStyle->GetStatColor());
7129  stats->SetFillStyle(gStyle->GetStatStyle());
7131  stats->SetTextFont(gStyle->GetStatFont());
7132  if (gStyle->GetStatFont()%10 > 2)
7133  stats->SetTextSize(gStyle->GetStatFontSize());
7134  stats->SetFitFormat(gStyle->GetFitFormat());
7135  stats->SetStatFormat(gStyle->GetStatFormat());
7136  stats->SetName("stats");
7137 
7139  stats->SetTextAlign(12);
7140  stats->SetBit(kCanDelete);
7141  stats->SetBit(kMustCleanup);
7142  }
7143  if (print_name) stats->AddText(fH->GetName());
7144  if (print_entries) {
7145  if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
7146  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
7147  stats->AddText(t);
7148  }
7149  char textstats[50];
7150  if (print_mean) {
7151  if (print_mean == 1) {
7152  snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
7153  snprintf(t,100,textstats,fH->GetMean(1));
7154  } else {
7155  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
7156  ,"%",stats->GetStatFormat());
7157  snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
7158  }
7159  stats->AddText(t);
7160  if (fH->InheritsFrom(TProfile::Class())) {
7161  if (print_mean == 1) {
7162  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7163  snprintf(t,100,textstats,fH->GetMean(2));
7164  } else {
7165  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7166  ,"%",stats->GetStatFormat());
7167  snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
7168  }
7169  stats->AddText(t);
7170  }
7171  }
7172  if (print_stddev) {
7173  if (print_stddev == 1) {
7174  snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
7175  snprintf(t,100,textstats,fH->GetStdDev(1));
7176  } else {
7177  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
7178  ,"%",stats->GetStatFormat());
7179  snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
7180  }
7181  stats->AddText(t);
7182  if (fH->InheritsFrom(TProfile::Class())) {
7183  if (print_stddev == 1) {
7184  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7185  snprintf(t,100,textstats,fH->GetStdDev(2));
7186  } else {
7187  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7188  ,"%",stats->GetStatFormat());
7189  snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
7190  }
7191  stats->AddText(t);
7192  }
7193  }
7194  if (print_under) {
7195  snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
7196  snprintf(t,100,textstats,fH->GetBinContent(0));
7197  stats->AddText(t);
7198  }
7199  if (print_over) {
7200  snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
7201  snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
7202  stats->AddText(t);
7203  }
7204  if (print_integral) {
7205  if (print_integral == 1) {
7206  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7207  snprintf(t,100,textstats,fH->Integral());
7208  } else {
7209  snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
7210  snprintf(t,100,textstats,fH->Integral("width"));
7211  }
7212  stats->AddText(t);
7213  }
7214  if (print_skew) {
7215  if (print_skew == 1) {
7216  snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
7217  snprintf(t,100,textstats,fH->GetSkewness(1));
7218  } else {
7219  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
7220  ,"%",stats->GetStatFormat());
7221  snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
7222  }
7223  stats->AddText(t);
7224  }
7225  if (print_kurt) {
7226  if (print_kurt == 1) {
7227  snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
7228  snprintf(t,100,textstats,fH->GetKurtosis(1));
7229  } else {
7230  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
7231  ,"%",stats->GetStatFormat());
7232  snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
7233  }
7234  stats->AddText(t);
7235  }
7236 
7237  // Draw Fit parameters
7238  if (fit) {
7239  Int_t ndf = fit->GetNDF();
7240  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
7241  snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
7242  if (print_fchi2) stats->AddText(t);
7243  if (print_fprob) {
7244  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
7245  snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
7246  stats->AddText(t);
7247  }
7248  if (print_fval || print_ferrors) {
7249  Double_t parmin,parmax;
7250  Int_t a;
7251  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7252  fit->GetParLimits(ipar,parmin,parmax);
7253  if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
7254  snprintf(t,100,"%-8s ",fit->GetParName(ipar));
7255  a = strlen(t);
7256  if (a>50) a = 50;
7257  if (print_ferrors) {
7258  snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
7259  GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
7260  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar)
7261  ,(Float_t)fit->GetParError(ipar));
7262  } else {
7263  snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
7264  snprintf(&t[a],100,textstats,(Float_t)fit->GetParameter(ipar));
7265  }
7266  t[63] = 0;
7267  stats->AddText(t);
7268  }
7269  }
7270  }
7271 
7272  if (!done) fFunctions->Add(stats);
7273  stats->Paint();
7274 }
7275 
7276 
7277 ////////////////////////////////////////////////////////////////////////////////
7278 /// [Draw the statistics box for 2D histograms.](#HP07)
7279 
7280 void THistPainter::PaintStat2(Int_t dostat, TF1 *fit)
7281 {
7282 
7283  if (fH->GetDimension() != 2) return;
7284  TH2 *h2 = (TH2*)fH;
7285 
7286  static char t[100];
7287  Int_t dofit;
7288  TPaveStats *stats = 0;
7290  TObject *obj;
7291  while ((obj = next())) {
7292  if (obj->InheritsFrom(TPaveStats::Class())) {
7293  stats = (TPaveStats*)obj;
7294  break;
7295  }
7296  }
7297  if (stats && dostat) {
7298  dofit = stats->GetOptFit();
7299  dostat = stats->GetOptStat();
7300  } else {
7301  dofit = gStyle->GetOptFit();
7302  }
7303  if (dostat == 1) dostat = 1111;
7304  Int_t print_name = dostat%10;
7305  Int_t print_entries = (dostat/10)%10;
7306  Int_t print_mean = (dostat/100)%10;
7307  Int_t print_stddev = (dostat/1000)%10;
7308  Int_t print_under = (dostat/10000)%10;
7309  Int_t print_over = (dostat/100000)%10;
7310  Int_t print_integral= (dostat/1000000)%10;
7311  Int_t print_skew = (dostat/10000000)%10;
7312  Int_t print_kurt = (dostat/100000000)%10;
7313  Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
7314  if (print_under || print_over) nlines += 3;
7315 
7316  // Pavetext with statistics
7317  if (!gStyle->GetOptFit()) fit = 0;
7318  Bool_t done = kFALSE;
7319  if (!dostat && !fit) {
7320  if (stats) { fFunctions->Remove(stats); delete stats;}
7321  return;
7322  }
7323  Double_t statw = gStyle->GetStatW();
7324  if (fit) statw = 1.8*gStyle->GetStatW();
7325  Double_t stath = nlines*gStyle->GetStatFontSize();
7326  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7327  stath = 0.25*nlines*gStyle->GetStatH();
7328  }
7329  if (fit) stath += gStyle->GetStatH();
7330  if (stats) {
7331  stats->Clear();
7332  done = kTRUE;
7333  } else {
7334  stats = new TPaveStats(
7335  gStyle->GetStatX()-statw,
7336  gStyle->GetStatY()-stath,
7337  gStyle->GetStatX(),
7338  gStyle->GetStatY(),"brNDC");
7339 
7340  stats->SetParent(fH);
7341  stats->SetOptFit(dofit);
7342  stats->SetOptStat(dostat);
7343  stats->SetFillColor(gStyle->GetStatColor());
7344  stats->SetFillStyle(gStyle->GetStatStyle());
7346  stats->SetName("stats");
7347 
7349  stats->SetTextAlign(12);
7350  stats->SetTextFont(gStyle->GetStatFont());
7351  if (gStyle->GetStatFont()%10 > 2)
7352  stats->SetTextSize(gStyle->GetStatFontSize());
7353  stats->SetFitFormat(gStyle->GetFitFormat());
7354  stats->SetStatFormat(gStyle->GetStatFormat());
7355  stats->SetBit(kCanDelete);
7356  stats->SetBit(kMustCleanup);
7357  }
7358  if (print_name) stats->AddText(h2->GetName());
7359  if (print_entries) {
7360  if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
7361  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
7362  stats->AddText(t);
7363  }
7364  char textstats[50];
7365  if (print_mean) {
7366  if (print_mean == 1) {
7367  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
7368  snprintf(t,50,textstats,h2->GetMean(1));
7369  stats->AddText(t);
7370  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7371  snprintf(t,100,textstats,h2->GetMean(2));
7372  stats->AddText(t);
7373  } else {
7374  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
7375  ,"%",stats->GetStatFormat());
7376  snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
7377  stats->AddText(t);
7378  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7379  ,"%",stats->GetStatFormat());
7380  snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
7381  stats->AddText(t);
7382  }
7383  }
7384  if (print_stddev) {
7385  if (print_stddev == 1) {
7386  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
7387  snprintf(t,100,textstats,h2->GetStdDev(1));
7388  stats->AddText(t);
7389  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7390  snprintf(t,100,textstats,h2->GetStdDev(2));
7391  stats->AddText(t);
7392  } else {
7393  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
7394  ,"%",stats->GetStatFormat());
7395  snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
7396  stats->AddText(t);
7397  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7398  ,"%",stats->GetStatFormat());
7399  snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
7400  stats->AddText(t);
7401  }
7402  }
7403  if (print_integral) {
7404  snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
7405  snprintf(t,100,textstats,fH->Integral());
7406  stats->AddText(t);
7407  }
7408  if (print_skew) {
7409  if (print_skew == 1) {
7410  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
7411  snprintf(t,100,textstats,h2->GetSkewness(1));
7412  stats->AddText(t);
7413  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
7414  snprintf(t,100,textstats,h2->GetSkewness(2));
7415  stats->AddText(t);
7416  } else {
7417  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
7418  ,"%",stats->GetStatFormat());
7419  snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
7420  stats->AddText(t);
7421  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
7422  ,"%",stats->GetStatFormat());
7423  snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
7424  stats->AddText(t);
7425  }
7426  }
7427  if (print_kurt) {
7428  if (print_kurt == 1) {
7429  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
7430  snprintf(t,100,textstats,h2->GetKurtosis(1));
7431  stats->AddText(t);
7432  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
7433  snprintf(t,100,textstats,h2->GetKurtosis(2));
7434  stats->AddText(t);
7435  } else {
7436  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
7437  ,"%",stats->GetStatFormat());
7438  snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
7439  stats->AddText(t);
7440  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
7441  ,"%",stats->GetStatFormat());
7442  snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
7443  stats->AddText(t);
7444  }
7445  }
7446  if (print_under || print_over) {
7447  //get 3*3 under/overflows for 2d hist
7448  Double_t unov[9];
7449 
7450  Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
7451  Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
7452  Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
7453  Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
7454  Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
7455  Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
7456 
7457  unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
7458  unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
7459  unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
7460  unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
7461  unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
7462  unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
7463  unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
7464  unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
7465  unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
7466 
7467  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
7468  stats->AddText(t);
7469  if (h2->GetEntries() < 1e7)
7470  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
7471  else
7472  snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
7473  stats->AddText(t);
7474  snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
7475  stats->AddText(t);
7476  }
7477 
7478  // Draw Fit parameters
7479  if (fit) {
7480  Int_t ndf = fit->GetNDF();
7481  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
7482  stats->AddText(t);
7483  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7484  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
7485  ,(Float_t)fit->GetParameter(ipar)
7486  ,(Float_t)fit->GetParError(ipar));
7487  t[63] = 0;
7488  stats->AddText(t);
7489  }
7490  }
7491 
7492  if (!done) fFunctions->Add(stats);
7493  stats->Paint();
7494 }
7495 
7496 
7497 ////////////////////////////////////////////////////////////////////////////////
7498 /// [Draw the statistics box for 3D histograms.](#HP07)
7499 
7500 void THistPainter::PaintStat3(Int_t dostat, TF1 *fit)
7501 {
7502 
7503  if (fH->GetDimension() != 3) return;
7504  TH3 *h3 = (TH3*)fH;
7505 
7506  static char t[100];
7507  Int_t dofit;
7508  TPaveStats *stats = 0;
7510  TObject *obj;
7511  while ((obj = next())) {
7512  if (obj->InheritsFrom(TPaveStats::Class())) {
7513  stats = (TPaveStats*)obj;
7514  break;
7515  }
7516  }
7517  if (stats && dostat) {
7518  dofit = stats->GetOptFit();
7519  dostat = stats->GetOptStat();
7520  } else {
7521  dofit = gStyle->GetOptFit();
7522  }
7523  if (dostat == 1) dostat = 1111;
7524  Int_t print_name = dostat%10;
7525  Int_t print_entries = (dostat/10)%10;
7526  Int_t print_mean = (dostat/100)%10;
7527  Int_t print_stddev = (dostat/1000)%10;
7528  Int_t print_under = (dostat/10000)%10;
7529  Int_t print_over = (dostat/100000)%10;
7530  Int_t print_integral= (dostat/1000000)%10;
7531  Int_t print_skew = (dostat/10000000)%10;
7532  Int_t print_kurt = (dostat/100000000)%10;
7533  Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
7534  if (print_under || print_over) nlines += 3;
7535 
7536  // Pavetext with statistics
7537  if (!gStyle->GetOptFit()) fit = 0;
7538  Bool_t done = kFALSE;
7539  if (!dostat && !fit) {
7540  if (stats) { fFunctions->Remove(stats); delete stats;}
7541  return;
7542  }
7543  Double_t statw = gStyle->GetStatW();
7544  if (fit) statw = 1.8*gStyle->GetStatW();
7545  Double_t stath = nlines*gStyle->GetStatFontSize();
7546  if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
7547  stath = 0.25*nlines*gStyle->GetStatH();
7548  }
7549  if (fit) stath += gStyle->GetStatH();
7550  if (stats) {
7551  stats->Clear();
7552  done = kTRUE;
7553  } else {
7554  stats = new TPaveStats(
7555  gStyle->GetStatX()-statw,
7556  gStyle->GetStatY()-stath,
7557  gStyle->GetStatX(),
7558  gStyle->GetStatY(),"brNDC");
7559 
7560  stats->SetParent(fH);
7561  stats->SetOptFit(dofit);
7562  stats->SetOptStat(dostat);
7563  stats->SetFillColor(gStyle->GetStatColor());
7564  stats->SetFillStyle(gStyle->GetStatStyle());
7566  stats->SetName("stats");
7567 
7569  stats->SetTextAlign(12);
7570  stats->SetTextFont(gStyle->GetStatFont());
7571  stats->SetFitFormat(gStyle->GetFitFormat());
7572  stats->SetStatFormat(gStyle->GetStatFormat());
7573  stats->SetBit(kCanDelete);
7574  stats->SetBit(kMustCleanup);
7575  }
7576  if (print_name) stats->AddText(h3->GetName());
7577  if (print_entries) {
7578  if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
7579  else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
7580  stats->AddText(t);
7581  }
7582  char textstats[50];
7583  if (print_mean) {
7584  if (print_mean == 1) {
7585  snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
7586  snprintf(t,100,textstats,h3->GetMean(1));
7587  stats->AddText(t);
7588  snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
7589  snprintf(t,100,textstats,h3->GetMean(2));
7590  stats->AddText(t);
7591  snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
7592  snprintf(t,100,textstats,h3->GetMean(3));
7593  stats->AddText(t);
7594  } else {
7595  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
7596  ,"%",stats->GetStatFormat());
7597  snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
7598  stats->AddText(t);
7599  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
7600  ,"%",stats->GetStatFormat());
7601  snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
7602  stats->AddText(t);
7603  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
7604  ,"%",stats->GetStatFormat());
7605  snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
7606  stats->AddText(t);
7607  }
7608  }
7609  if (print_stddev) {
7610  if (print_stddev == 1) {
7611  snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
7612  snprintf(t,100,textstats,h3->GetStdDev(1));
7613  stats->AddText(t);
7614  snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
7615  snprintf(t,100,textstats,h3->GetStdDev(2));
7616  stats->AddText(t);
7617  snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
7618  snprintf(t,100,textstats,h3->GetStdDev(3));
7619  stats->AddText(t);
7620  } else {
7621  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
7622  ,"%",stats->GetStatFormat());
7623  snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
7624  stats->AddText(t);
7625  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
7626  ,"%",stats->GetStatFormat());
7627  snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
7628  stats->AddText(t);
7629  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
7630  ,"%",stats->GetStatFormat());
7631  snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
7632  stats->AddText(t);
7633  }
7634  }
7635  if (print_integral) {
7636  snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
7637  stats->AddText(t);
7638  }
7639  if (print_skew) {
7640  if (print_skew == 1) {
7641  snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
7642  snprintf(t,100,textstats,h3->GetSkewness(1));
7643  stats->AddText(t);
7644  snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
7645  snprintf(t,100,textstats,h3->GetSkewness(2));
7646  stats->AddText(t);
7647  snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
7648  snprintf(t,100,textstats,h3->GetSkewness(3));
7649  stats->AddText(t);
7650  } else {
7651  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
7652  ,"%",stats->GetStatFormat());
7653  snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
7654  stats->AddText(t);
7655  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
7656  ,"%",stats->GetStatFormat());
7657  snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
7658  stats->AddText(t);
7659  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
7660  ,"%",stats->GetStatFormat());
7661  snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
7662  stats->AddText(t);
7663  }
7664  }
7665  if (print_kurt) {
7666  if (print_kurt == 1) {
7667  snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
7668  snprintf(t,100,textstats,h3->GetKurtosis(1));
7669  stats->AddText(t);
7670  snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
7671  snprintf(t,100,textstats,h3->GetKurtosis(2));
7672  stats->AddText(t);
7673  snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
7674  snprintf(t,100,textstats,h3->GetKurtosis(3));
7675  stats->AddText(t);
7676  } else {
7677  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
7678  ,"%",stats->GetStatFormat());
7679  snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
7680  stats->AddText(t);
7681  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
7682  ,"%",stats->GetStatFormat());
7683  snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
7684  stats->AddText(t);
7685  snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
7686  ,"%",stats->GetStatFormat());
7687  snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
7688  stats->AddText(t);
7689  }
7690  }
7691  if (print_under || print_over) {
7692  // no underflow - overflow printing for a 3D histogram
7693  // one would need a 3D table
7694 // //get 3*3 under/overflows for 2d hist
7695 // Double_t unov[9];
7696 
7697 // unov[0] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7698 // unov[1] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7699 // unov[2] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,h3->GetYaxis()->GetLast()+1,h3->GetYaxis()->GetNbins()+1);
7700 // unov[3] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7701 // unov[4] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7702 // unov[5] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,h3->GetYaxis()->GetFirst(),h3->GetYaxis()->GetLast());
7703 // unov[6] = h3->Integral(0,h3->GetXaxis()->GetFirst()-1,0,h3->GetYaxis()->GetFirst()-1);
7704 // unov[7] = h3->Integral(h3->GetXaxis()->GetFirst(),h3->GetXaxis()->GetLast(),0,h3->GetYaxis()->GetFirst()-1);
7705 // unov[8] = h3->Integral(h3->GetXaxis()->GetLast()+1,h3->GetXaxis()->GetNbins()+1,0,h3->GetYaxis()->GetFirst()-1);
7706 
7707 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
7708 // stats->AddText(t);
7709 // if (h3->GetEntries() < 1e7)
7710 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
7711 // else
7712 // sprintf(t, " %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
7713 // stats->AddText(t);
7714 // sprintf(t, " %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
7715 // stats->AddText(t);
7716  }
7717 
7718  // Draw Fit parameters
7719  if (fit) {
7720  Int_t ndf = fit->GetNDF();
7721  snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
7722  stats->AddText(t);
7723  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
7724  snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
7725  ,(Float_t)fit->GetParameter(ipar)
7726  ,(Float_t)fit->GetParError(ipar));
7727  t[32] = 0;
7728  stats->AddText(t);
7729  }
7730  }
7731 
7732  if (!done) fFunctions->Add(stats);
7733  stats->Paint();
7734 }
7735 
7736 
7737 ////////////////////////////////////////////////////////////////////////////////
7738 /// [Control function to draw a 2D histogram as a surface plot.](#HP18)
7739 
7741 {
7742 
7743  const Double_t ydiff = 1;
7744  const Double_t yligh1 = 10;
7745  const Double_t qa = 0.15;
7746  const Double_t qd = 0.15;
7747  const Double_t qs = 0.8;
7748  Double_t fmin, fmax;
7749  Int_t raster = 0;
7750  Int_t irep = 0;
7751 
7752  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7753  Int_t nx = Hparam.xlast - Hparam.xfirst;
7754  Int_t ny = Hparam.ylast - Hparam.yfirst;
7755  Double_t zmin = Hparam.zmin;
7756  Double_t zmax = Hparam.zmax;
7757  Double_t xlab1 = Hparam.xmin;
7758  Double_t xlab2 = Hparam.xmax;
7759  Double_t ylab1 = Hparam.ymin;
7760  Double_t ylab2 = Hparam.ymax;
7761  Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7762  Double_t deltaz = TMath::Abs(zmin);
7763  if (deltaz == 0) deltaz = 1;
7764  if (zmin >= zmax) {
7765  zmin -= 0.5*deltaz;
7766  zmax += 0.5*deltaz;
7767  }
7768  Double_t z1c = zmin;
7769  Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7770  // Compute the lego limits and instantiate a lego object
7771  fXbuf[0] = -1;
7772  fYbuf[0] = 1;
7773  fXbuf[1] = -1;
7774  fYbuf[1] = 1;
7775  if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
7776  if (Hoption.System == kPOLAR) {
7777  fXbuf[2] = z1c;
7778  fYbuf[2] = z2c;
7779  } else if (Hoption.System == kCYLINDRICAL) {
7780  if (Hoption.Logy) {
7781  if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7782  else fXbuf[2] = 0;
7783  if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7784  else fYbuf[2] = 0;
7785  } else {
7786  fXbuf[2] = ylab1;
7787  fYbuf[2] = ylab2;
7788  }
7789  z1c = 0; z2c = 1;
7790  } else if (Hoption.System == kSPHERICAL) {
7791  fXbuf[2] = -1;
7792  fYbuf[2] = 1;
7793  z1c = 0; z2c = 1;
7794  } else if (Hoption.System == kRAPIDITY) {
7795  fXbuf[2] = -1/TMath::Tan(dangle);
7796  fYbuf[2] = 1/TMath::Tan(dangle);
7797  } else {
7798  fXbuf[0] = xlab1;
7799  fYbuf[0] = xlab2;
7800  fXbuf[1] = ylab1;
7801  fYbuf[1] = ylab2;
7802  fXbuf[2] = z1c;
7803  fYbuf[2] = z2c;
7804  }
7805 
7806  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System);
7809 
7810  // Create axis object
7811 
7812  TGaxis *axis = new TGaxis();
7813 
7814  // Initialize the levels on the Z axis
7815  Int_t ndiv = fH->GetContour();
7816  if (ndiv == 0 ) {
7817  ndiv = gStyle->GetNumberContours();
7818  fH->SetContour(ndiv);
7819  }
7820  Int_t ndivz = TMath::Abs(ndiv);
7821  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7822 
7823  if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
7824  if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
7825 
7826  // Close the surface in case of non cartesian coordinates.
7827 
7828  if (Hoption.System != kCARTESIAN) {nx++; ny++;}
7829 
7830  // Now ready to draw the surface plot
7831 
7832  TView *view = gPad->GetView();
7833  if (!view) {
7834  Error("PaintSurface", "no TView in current pad");
7835  return;
7836  }
7837 
7838  Double_t thedeg = 90 - gPad->GetTheta();
7839  Double_t phideg = -90 - gPad->GetPhi();
7840  Double_t psideg = view->GetPsi();
7841  view->SetView(phideg, thedeg, psideg, irep);
7842 
7843  // Set color/style for back box
7844  if (Hoption.Same) {
7845  fLego->SetFillStyle(0);
7846  fLego->SetFillColor(1);
7847  } else {
7848  fLego->SetFillStyle(gPad->GetFrameFillStyle());
7849  fLego->SetFillColor(gPad->GetFrameFillColor());
7850  }
7851  fLego->TAttFill::Modify();
7852 
7853  Int_t backcolor = gPad->GetFrameFillColor();
7854  if (Hoption.System != kCARTESIAN) backcolor = 0;
7855  view->PadRange(backcolor);
7856 
7859  fLego->TAttFill::Modify();
7860 
7861  // Draw the filled contour on top
7862  Int_t icol1 = fH->GetFillColor();
7863 
7864  Int_t hoption35 = Hoption.Surf;
7865  if (Hoption.Surf == 13 || Hoption.Surf == 15) {
7866  DefineColorLevels(ndivz);
7867  Hoption.Surf = 23;
7870  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
7871  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7872  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7873  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7874  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
7875  Hoption.Surf = hoption35;
7876  fLego->SetMesh(1);
7877  }
7878 
7879  if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7880  else fLego->InitMoveScreen(-1.1,1.1);
7881 
7882  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
7884  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7886  fLego->BackBox(90);
7887  }
7888  }
7889 
7890  // Gouraud Shading surface
7891  if (Hoption.Surf == 14) {
7892  // Set light sources
7893  fLego->LightSource(0, ydiff, 0,0,0,irep);
7894  fLego->LightSource(1, yligh1 ,1,1,1,irep);
7895  fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7896  fmin = ydiff*qa;
7897  fmax = fmin + (yligh1+0.1)*(qd+qs);
7898  Int_t nbcol = 28;
7899  icol1 = 201;
7900  Double_t dcol = 0.5/Double_t(nbcol);
7901  TColor *colref = gROOT->GetColor(fH->GetFillColor());
7902  if (!colref) return;
7903  Float_t r,g,b,hue,light,satur;
7904  colref->GetRGB(r,g,b);
7905  TColor::RGBtoHLS(r,g,b,hue,light,satur);
7906  TColor *acol;
7907  for (Int_t col=0;col<nbcol;col++) {
7908  acol = gROOT->GetColor(col+icol1);
7909  TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
7910  if (acol) acol->SetRGB(r,g,b);
7911  }
7912  fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
7915  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
7916  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7917  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7918  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7919  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
7920  } else if (Hoption.Surf == 15) {
7921  // The surface is not drawn in this case.
7922  } else {
7923  // Draw the surface
7924  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
7925  DefineColorLevels(ndivz);
7926  } else {
7928  }
7930  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceRaster1);
7931  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode2);
7932  if (Hoption.System == kPOLAR) {
7933  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
7934  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
7935  } else if (Hoption.System == kCYLINDRICAL) {
7936  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
7937  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
7938  } else if (Hoption.System == kSPHERICAL) {
7939  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
7940  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
7941  } else if (Hoption.System == kRAPIDITY) {
7942  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
7943  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
7944  } else {
7945  if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1);
7947  if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
7948  if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
7949  }
7950  }
7951 
7952  // Paint the line contour on top for option SURF7
7953  if (Hoption.Surf == 17) {
7954  fLego->InitMoveScreen(-1.1,1.1);
7956  Hoption.Surf = 23;
7959  if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
7960  if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
7961  if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
7962  if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
7963  if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
7964  }
7965 
7966  if ((!Hoption.Same) &&
7967  (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
7968  if (Hoption.System == kCARTESIAN && Hoption.BackBox) {
7970  fLego->BackBox(90);
7971  }
7972  }
7973  if (Hoption.System == kCARTESIAN) {
7974  fLego->InitMoveScreen(-1.1,1.1);
7976  if (Hoption.FrontBox) fLego->FrontBox(90);
7977  }
7978  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7979 
7980  if (Hoption.Zscale) PaintPalette();
7981 
7982  delete axis;
7983  delete fLego; fLego = 0;
7984 }
7985 
7986 
7987 ////////////////////////////////////////////////////////////////////////////////
7988 /// Control function to draw a table using Delaunay triangles.
7989 
7991 {
7992 
7993  TGraphDelaunay2D *dt = nullptr;
7994  TGraphDelaunay *dtOld = nullptr;
7995 
7996  // Check if fH contains a TGraphDelaunay2D
7997  TList *hl = fH->GetListOfFunctions();
7998  dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
7999  if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
8000  if (!dt && !dtOld) return;
8001 
8002  // If needed, create a TGraph2DPainter
8003  if (!fGraph2DPainter) {
8004  if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
8005  else fGraph2DPainter = new TGraph2DPainter(dtOld);
8006  }
8007 
8008  // Define the 3D view
8009  if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
8010  if (Hoption.Same) {
8011  TView *viewsame = gPad->GetView();
8012  if (!viewsame) {
8013  Error("PaintTriangles", "no TView in current pad, do not use option SAME");
8014  return;
8015  }
8016  Double_t *rmin = viewsame->GetRmin();
8017  Double_t *rmax = viewsame->GetRmax();
8018  if (!rmin || !rmax) return;
8019  fXbuf[0] = rmin[0];
8020  fYbuf[0] = rmax[0];
8021  fXbuf[1] = rmin[1];
8022  fYbuf[1] = rmax[1];
8023  fXbuf[2] = rmin[2];
8024  fYbuf[2] = rmax[2];
8025  } else {
8026  fXbuf[0] = Hparam.xmin;
8027  fYbuf[0] = Hparam.xmax;
8028  fXbuf[1] = Hparam.ymin;
8029  fYbuf[1] = Hparam.ymax;
8030  fXbuf[2] = Hparam.zmin;
8031  fYbuf[2] = Hparam.zmax;
8032  }
8033 
8034  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8035  TView *view = gPad->GetView();
8036  if (!view) {
8037  Error("PaintTriangles", "no TView in current pad");
8038  return;
8039  }
8040  Double_t thedeg = 90 - gPad->GetTheta();
8041  Double_t phideg = -90 - gPad->GetPhi();
8042  Double_t psideg = view->GetPsi();
8043  Int_t irep;
8044  view->SetView(phideg, thedeg, psideg, irep);
8045 
8046  // Set color/style for back box
8047  fLego->SetFillStyle(gPad->GetFrameFillStyle());
8048  fLego->SetFillColor(gPad->GetFrameFillColor());
8049  fLego->TAttFill::Modify();
8050  Int_t backcolor = gPad->GetFrameFillColor();
8051  if (Hoption.System != kCARTESIAN) backcolor = 0;
8052  view->PadRange(backcolor);
8055  fLego->TAttFill::Modify();
8056 
8057  // Paint the Back Box if needed
8058  if (Hoption.BackBox && !Hoption.Same) {
8059  fLego->InitMoveScreen(-1.1,1.1);
8062  fLego->BackBox(90);
8063  }
8064 
8065  // Paint the triangles
8066  fGraph2DPainter->Paint(option);
8067 
8068  // Paint the Front Box if needed
8069  if (Hoption.FrontBox) {
8070  fLego->InitMoveScreen(-1.1,1.1);
8072  fLego->FrontBox(90);
8073  }
8074 
8075  // Paint the Axis if needed
8076  if (!Hoption.Axis && !Hoption.Same) {
8077  TGaxis *axis = new TGaxis();
8078  PaintLegoAxis(axis, 90);
8079  delete axis;
8080  }
8081 
8082  if (Hoption.Zscale) PaintPalette();
8083 
8084  delete fLego; fLego = 0;
8085 }
8086 
8087 
8088 ////////////////////////////////////////////////////////////////////////////////
8089 /// Define the color levels used to paint legos, surfaces etc..
8090 
8092 {
8093 
8094  Int_t i, irep;
8095 
8096  // Initialize the color levels
8097  if (ndivz >= 100) {
8098  Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
8099  ndivz = 8;
8100  }
8101  Double_t *funlevel = new Double_t[ndivz+1];
8102  Int_t *colorlevel = new Int_t[ndivz+1];
8103  Int_t theColor;
8104  Int_t ncolors = gStyle->GetNumberOfColors();
8105  for (i = 0; i < ndivz; ++i) {
8106  funlevel[i] = fH->GetContourLevelPad(i);
8107  theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
8108  colorlevel[i] = gStyle->GetColorPalette(theColor);
8109  }
8110  colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
8111  fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
8112  delete [] colorlevel;
8113  delete [] funlevel;
8114 }
8115 
8116 
8117 ////////////////////////////////////////////////////////////////////////////////
8118 /// [Control function to draw 2D/3D histograms (tables).](#HP01c)
8119 
8120 void THistPainter::PaintTable(Option_t *option)
8121 {
8122 
8123  // Fill Hparam structure with histo parameters
8124  if (!TableInit()) return;
8125 
8126  // Draw histogram frame
8127  PaintFrame();
8128 
8129  // If palette option not specified, delete a possible existing palette
8130  if (!Hoption.Zscale) {
8131  TObject *palette = fFunctions->FindObject("palette");
8132  if (palette) { fFunctions->Remove(palette); delete palette;}
8133  }
8134 
8135  // Do not draw the histogram. Only the attached functions will be drawn.
8136  if (Hoption.Func == 2) {
8137  if (Hoption.Zscale) {
8138  Int_t ndiv = fH->GetContour();
8139  if (ndiv == 0 ) {
8140  ndiv = gStyle->GetNumberContours();
8141  fH->SetContour(ndiv);
8142  }
8143  PaintPalette();
8144  }
8145 
8146  // Draw the histogram according to the option
8147  } else {
8148  if (fH->InheritsFrom(TH2Poly::Class())) {
8149  if (Hoption.Fill) PaintTH2PolyBins("f");
8150  if (Hoption.Color) PaintTH2PolyColorLevels(option);
8151  if (Hoption.Scat) PaintTH2PolyScatterPlot(option);
8152  if (Hoption.Text) PaintTH2PolyText(option);
8153  if (Hoption.Line) PaintTH2PolyBins("l");
8154  if (Hoption.Mark) PaintTH2PolyBins("P");
8155  } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
8156  if (Hoption.Scat) PaintScatterPlot(option);
8157  if (Hoption.Arrow) PaintArrows(option);
8158  if (Hoption.Box) PaintBoxes(option);
8159  if (Hoption.Color) PaintColorLevels(option);
8160  if (Hoption.Contour) PaintContour(option);
8161  if (Hoption.Text) PaintText(option);
8162  if (Hoption.Error >= 100) Paint2DErrors(option);
8163  if (Hoption.Candle) PaintCandlePlot(option);
8164  if (Hoption.Violin) PaintViolinPlot(option);
8165  }
8166  if (Hoption.Lego) PaintLego(option);
8167  if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
8168  if (Hoption.Tri) PaintTriangles(option);
8169  }
8170 
8171  // Draw histogram title
8172  PaintTitle();
8173 
8174  // Draw the axes
8175  if (!Hoption.Lego && !Hoption.Surf &&
8176  !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
8177 
8178  TF1 *fit = 0;
8180  TObject *obj;
8181  while ((obj = next())) {
8182  if (obj->InheritsFrom(TF1::Class())) {
8183  fit = (TF1*)obj;
8184  break;
8185  }
8186  }
8187  if (Hoption.Same != 1) {
8188  if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
8189  if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
8190  //ALWAYS executed on non-iOS platform.
8191  //On iOS, depends on mode.
8192  PaintStat2(gStyle->GetOptStat(),fit);
8193  }
8194  }
8195  }
8196 }
8197 
8198 
8199 ////////////////////////////////////////////////////////////////////////////////
8200 /// Control function to draw a TH2Poly bins' contours.
8201 ///
8202 /// - option = "F" draw the bins as filled areas.
8203 /// - option = "L" draw the bins as line.
8204 /// - option = "P" draw the bins as markers.
8205 
8207 {
8208 
8209  //Do not highlight the histogram, if its part was picked.
8210  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
8211 
8212  TString opt = option;
8213  opt.ToLower();
8214  Bool_t line = kFALSE;
8215  Bool_t fill = kFALSE;
8216  Bool_t mark = kFALSE;
8217  if (opt.Contains("l")) line = kTRUE;
8218  if (opt.Contains("f")) fill = kTRUE;
8219  if (opt.Contains("p")) mark = kTRUE;
8220 
8221  TH2PolyBin *b;
8222 
8223  TIter next(((TH2Poly*)fH)->GetBins());
8224  TObject *obj, *poly;
8225 
8226  while ((obj=next())) {
8227  b = (TH2PolyBin*)obj;
8228  poly = b->GetPolygon();
8229 
8230  // Paint the TGraph bins.
8231  if (poly->IsA() == TGraph::Class()) {
8232  TGraph *g = (TGraph*)poly;
8233  g->TAttLine::Modify();
8234  g->TAttMarker::Modify();
8235  g->TAttFill::Modify();
8236  if (line) g->Paint("L");
8237  if (fill) g->Paint("F");
8238  if (mark) g->Paint("P");
8239  }
8240 
8241  // Paint the TMultiGraph bins.
8242  if (poly->IsA() == TMultiGraph::Class()) {
8243  TMultiGraph *mg = (TMultiGraph*)poly;
8244  TList *gl = mg->GetListOfGraphs();
8245  if (!gl) return;
8246  TGraph *g;
8247  TIter nextg(gl);
8248  while ((g = (TGraph*) nextg())) {
8249  g->TAttLine::Modify();
8250  g->TAttMarker::Modify();
8251  g->TAttFill::Modify();
8252  if (line) g->Paint("L");
8253  if (fill) g->Paint("F");
8254  if (mark) g->Paint("P");
8255  }
8256  }
8257  }
8258 }
8259 
8260 
8261 ////////////////////////////////////////////////////////////////////////////////
8262 /// [Control function to draw a TH2Poly as a color plot.](#HP20a)
8263 
8265 {
8266 
8267  //Do not highlight the histogram, if its part was picked.
8268  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8269  return;
8271  Int_t ncolors, color, theColor;
8272  Double_t z, zc;
8273  Double_t zmin = fH->GetMinimum();
8274  Double_t zmax = fH->GetMaximum();
8275  if (Hoption.Logz) {
8276  if (zmax > 0) {
8277  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8278  zmin = TMath::Log10(zmin);
8279  zmax = TMath::Log10(zmax);
8280  } else {
8281  return;
8282  }
8283  }
8284  Double_t dz = zmax - zmin;
8285 
8286  // Initialize the levels on the Z axis
8287  ncolors = gStyle->GetNumberOfColors();
8288  Int_t ndiv = fH->GetContour();
8289  if (ndiv == 0 ) {
8290  ndiv = gStyle->GetNumberContours();
8291  fH->SetContour(ndiv);
8292  }
8293  Int_t ndivz = TMath::Abs(ndiv);
8294  if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8295  Double_t scale = ndivz/dz;
8296 
8297  TH2PolyBin *b;
8298 
8299  TIter next(((TH2Poly*)fH)->GetBins());
8300  TObject *obj, *poly;
8301 
8302  while ((obj=next())) {
8303  b = (TH2PolyBin*)obj;
8304  poly = b->GetPolygon();
8305 
8306  z = b->GetContent();
8307  if (Hoption.Logz) {
8308  if (z > 0) z = TMath::Log10(z);
8309  else z = zmin;
8310  }
8311  if (z < zmin) continue;
8312 
8313  // Define the bin color.
8314  if (fH->TestBit(TH1::kUserContour)) {
8315  zc = fH->GetContourLevelPad(0);
8316  if (z < zc) continue;
8317  color = -1;
8318  for (Int_t k=0; k<ndiv; k++) {
8319  zc = fH->GetContourLevelPad(k);
8320  if (z < zc) {
8321  continue;
8322  } else {
8323  color++;
8324  }
8325  }
8326  } else {
8327  color = Int_t(0.01+(z-zmin)*scale);
8328  }
8329  theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
8330  if (theColor > ncolors-1) theColor = ncolors-1;
8331 
8332  // Paint the TGraph bins.
8333  if (poly->IsA() == TGraph::Class()) {
8334  TGraph *g = (TGraph*)poly;
8335  g->SetFillColor(gStyle->GetColorPalette(theColor));
8336  g->TAttFill::Modify();
8337  g->Paint("F");
8338  }
8339 
8340  // Paint the TMultiGraph bins.
8341  if (poly->IsA() == TMultiGraph::Class()) {
8342  TMultiGraph *mg = (TMultiGraph*)poly;
8343  TList *gl = mg->GetListOfGraphs();
8344  if (!gl) return;
8345  TGraph *g;
8346  TIter nextg(gl);
8347  while ((g = (TGraph*) nextg())) {
8348  g->SetFillColor(gStyle->GetColorPalette(theColor));
8349  g->TAttFill::Modify();
8350  g->Paint("F");
8351  }
8352  }
8353  }
8354  if (Hoption.Zscale) PaintPalette();
8355 }
8356 
8357 
8358 ////////////////////////////////////////////////////////////////////////////////
8359 /// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
8360 
8362 {
8363 
8364  //Do not highlight the histogram, if its part was selected.
8365  if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
8366  return;
8368  Int_t k, loop, marker=0;
8369  Double_t z, xk,xstep, yk, ystep, xp, yp;
8370  Double_t scale = 1;
8371  Double_t zmin = fH->GetMinimum();
8372  Double_t zmax = fH->GetMaximum();
8373  if (Hoption.Logz) {
8374  if (zmax > 0) {
8375  if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
8376  zmin = TMath::Log10(zmin);
8377  zmax = TMath::Log10(zmax);
8378  } else {
8379  return;
8380  }
8381  }
8382  Double_t dz = zmax - zmin;
8383  scale = (kNMAX-1)/dz;
8384 
8385 
8386  // use an independent instance of a random generator
8387  // instead of gRandom to avoid conflicts and
8388  // to get same random numbers when drawing the same histogram
8389  TRandom2 random;
8390 
8391  TH2PolyBin *b;
8392 
8393  TIter next(((TH2Poly*)fH)->GetBins());
8394  TObject *obj, *poly;
8395 
8396  Double_t maxarea = 0, a;
8397  while ((obj=next())) {
8398  b = (TH2PolyBin*)obj;
8399  a = b->GetArea();
8400  if (a>maxarea) maxarea = a;
8401  }
8402 
8403  next.Reset();
8404 
8405  while ((obj=next())) {
8406  b = (TH2PolyBin*)obj;
8407  poly = b->GetPolygon();
8408  z = b->GetContent();
8409  if (z < zmin) z = zmin;
8410  if (z > zmax) z = zmax;
8411  if (Hoption.Logz) {
8412  if (z > 0) z = TMath::Log10(z) - zmin;
8413  } else {
8414  z -= zmin;
8415  }
8416  k = Int_t((z*scale)*(b->GetArea()/maxarea));
8417  xk = b->GetXMin();
8418  yk = b->GetYMin();
8419  xstep = b->GetXMax()-xk;
8420  ystep = b->GetYMax()-yk;
8421 
8422  // Paint the TGraph bins.
8423  if (poly->IsA() == TGraph::Class()) {
8424  TGraph *g = (TGraph*)poly;
8425  if (k <= 0 || z <= 0) continue;
8426  loop = 0;
8427  while (loop<k) {
8428  if (k+marker >= kNMAX) {
8429  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8430  marker=0;
8431  }
8432  xp = (random.Rndm(loop)*xstep) + xk;
8433  yp = (random.Rndm(loop)*ystep) + yk;
8434  if (g->IsInside(xp,yp)) {
8435  fXbuf[marker] = xp;
8436  fYbuf[marker] = yp;
8437  marker++;
8438  loop++;
8439  }
8440  }
8441  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8442  }
8443 
8444  // Paint the TMultiGraph bins.
8445  if (poly->IsA() == TMultiGraph::Class()) {
8446  TMultiGraph *mg = (TMultiGraph*)poly;
8447  TList *gl = mg->GetListOfGraphs();
8448  if (!gl) return;
8449  if (k <= 0 || z <= 0) continue;
8450  loop = 0;
8451  while (loop<k) {
8452  if (k+marker >= kNMAX) {
8453  gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8454  marker=0;
8455  }
8456  xp = (random.Rndm(loop)*xstep) + xk;
8457  yp = (random.Rndm(loop)*ystep) + yk;
8458  if (mg->IsInside(xp,yp)) {
8459  fXbuf[marker] = xp;
8460  fYbuf[marker] = yp;
8461  marker++;
8462  loop++;
8463  }
8464  }
8465  if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8466  }
8467  }
8468  PaintTH2PolyBins("l");
8469 }
8470 
8471 
8472 ////////////////////////////////////////////////////////////////////////////////
8473 /// [Control function to draw a TH2Poly as a text plot.](#HP20a)
8474 
8476 {
8477 
8478  TLatex text;
8479  text.SetTextFont(gStyle->GetTextFont());
8480  text.SetTextColor(fH->GetMarkerColor());
8482 
8483  Double_t x, y, z, e, angle = 0;
8484  char value[50];
8485  char format[32];
8486  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8487  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8488  Int_t opt = (Int_t)Hoption.Text/1000;
8489 
8490  text.SetTextAlign(22);
8491  if (Hoption.Text == 1) angle = 0;
8492  text.SetTextAngle(angle);
8493  text.TAttText::Modify();
8494 
8495  TH2PolyBin *b;
8496 
8497  TIter next(((TH2Poly*)fH)->GetBins());
8498  TObject *obj, *p;
8499 
8500  while ((obj=next())) {
8501  b = (TH2PolyBin*)obj;
8502  p = b->GetPolygon();
8503  x = (b->GetXMin()+b->GetXMax())/2;
8504  if (Hoption.Logx) {
8505  if (x > 0) x = TMath::Log10(x);
8506  else continue;
8507  }
8508  y = (b->GetYMin()+b->GetYMax())/2;
8509  if (Hoption.Logy) {
8510  if (y > 0) y = TMath::Log10(y);
8511  else continue;
8512  }
8513  z = b->GetContent();
8514  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
8515  if (opt==2) {
8516  e = fH->GetBinError(b->GetBinNumber());
8517  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
8518  "%",gStyle->GetPaintTextFormat(),
8519  "%",gStyle->GetPaintTextFormat());
8520  snprintf(value,50,format,z,e);
8521  } else {
8522  snprintf(value,50,format,z);
8523  }
8524  if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
8525  else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
8526  }
8527 
8528  PaintTH2PolyBins("l");
8529 }
8530 
8531 
8532 ////////////////////////////////////////////////////////////////////////////////
8533 /// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
8534 
8536 {
8537 
8538  TLatex text;
8539  text.SetTextFont(gStyle->GetTextFont());
8540  text.SetTextColor(fH->GetMarkerColor());
8542 
8543  Double_t x, y, z, e, angle = 0;
8544  char value[50];
8545  char format[32];
8546  snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
8547  if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
8548 
8549  // 1D histograms
8550  if (fH->GetDimension() == 1) {
8551  Bool_t getentries = kFALSE;
8552  Double_t yt;
8553  TProfile *hp = (TProfile*)fH;
8554  if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
8555  Hoption.Text = Hoption.Text-2000;
8556  getentries = kTRUE;
8557  }
8558  if (Hoption.Text == 1) angle = 90;
8559  text.SetTextAlign(11);
8560  if (angle == 90) text.SetTextAlign(12);
8561  if (angle == 0) text.SetTextAlign(21);
8562  text.TAttText::Modify();
8563  Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
8564  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8565  if (Hoption.Bar) {
8566  x = fH->GetXaxis()->GetBinLowEdge(i)+
8567  fH->GetXaxis()->GetBinWidth(i)*
8568  (fH->GetBarOffset()+0.5*fH->GetBarWidth());
8569  } else {
8570  x = fH->GetXaxis()->GetBinCenter(i);
8571  }
8572  y = fH->GetBinContent(i);
8573  yt = y;
8574  if (gStyle->GetHistMinimumZero() && y<0) y = 0;
8575  if (getentries) yt = hp->GetBinEntries(i);
8576  if (yt == 0.) continue;
8577  snprintf(value,50,format,yt);
8578  if (Hoption.Logx) {
8579  if (x > 0) x = TMath::Log10(x);
8580  else continue;
8581  }
8582  if (Hoption.Logy) {
8583  if (y > 0) y = TMath::Log10(y);
8584  else continue;
8585  }
8586  if (y >= gPad->GetY2()) continue;
8587  if (y <= gPad->GetY1()) continue;
8588  text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
8589  }
8590 
8591  // 2D histograms
8592  } else {
8593  text.SetTextAlign(22);
8594  if (Hoption.Text == 1) angle = 0;
8595  text.SetTextAngle(angle);
8596  text.TAttText::Modify();
8597  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8598  y = fYaxis->GetBinCenter(j);
8599  if (Hoption.Logy) {
8600  if (y > 0) y = TMath::Log10(y);
8601  else continue;
8602  }
8603  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8604  Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8605  x = fXaxis->GetBinCenter(i);
8606  if (Hoption.Logx) {
8607  if (x > 0) x = TMath::Log10(x);
8608  else continue;
8609  }
8610  if (!IsInside(x,y)) continue;
8611  z = fH->GetBinContent(bin);
8612  if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
8613  if (Hoption.Text>2000) {
8614  e = fH->GetBinError(bin);
8615  snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
8616  "%",gStyle->GetPaintTextFormat(),
8617  "%",gStyle->GetPaintTextFormat());
8618  snprintf(value,50,format,z,e);
8619  } else {
8620  snprintf(value,50,format,z);
8621  }
8622  text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
8623  }
8624  }
8625  }
8626 }
8627 
8628 
8629 ////////////////////////////////////////////////////////////////////////////////
8630 /// [Control function to draw a 3D implicit functions.](#HP27)
8631 
8633 {
8634 
8635  Int_t irep;
8636 
8637  TGaxis *axis = new TGaxis();
8638  TAxis *xaxis = fH->GetXaxis();
8639  TAxis *yaxis = fH->GetYaxis();
8640  TAxis *zaxis = fH->GetZaxis();
8641 
8642  fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
8643  fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
8644  fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
8645  fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
8646  fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
8647  fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
8648 
8649  fLego = new TPainter3dAlgorithms(fXbuf, fYbuf);
8650 
8651  TView *view = gPad->GetView();
8652  if (!view) {
8653  Error("PaintTF3", "no TView in current pad");
8654  return;
8655  }
8656  Double_t thedeg = 90 - gPad->GetTheta();
8657  Double_t phideg = -90 - gPad->GetPhi();
8658  Double_t psideg = view->GetPsi();
8659  view->SetView(phideg, thedeg, psideg, irep);
8660 
8661  fLego->InitMoveScreen(-1.1,1.1);
8662 
8663  if (Hoption.BackBox) {
8666  fLego->BackBox(90);
8667  }
8668 
8670 
8671  fLego->ImplicitFunction(fXbuf, fYbuf, fH->GetNbinsX(),
8672  fH->GetNbinsY(),
8673  fH->GetNbinsZ(), "BF");
8674 
8675  if (Hoption.FrontBox) {
8676  fLego->InitMoveScreen(-1.1,1.1);
8678  fLego->FrontBox(90);
8679  }
8680  if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8681 
8682  PaintTitle();
8683 
8684  delete axis;
8685  delete fLego; fLego = 0;
8686 }
8687 
8688 
8689 ////////////////////////////////////////////////////////////////////////////////
8690 /// Draw the histogram title
8691 ///
8692 /// The title is drawn according to the title alignment returned by
8693 /// `GetTitleAlign()`. It is a 2 digits integer): hv
8694 ///
8695 /// where `h` is the horizontal alignment and `v` is the
8696 /// vertical alignment.
8697 ///
8698 /// - `h` can get the values 1 2 3 for left, center, and right
8699 /// - `v` can get the values 1 2 3 for bottom, middle and top
8700 ///
8701 /// for instance the default alignment is: 13 (left top)
8702 
8704 {
8705 
8706  if (Hoption.Same) return;
8707  if (fH->TestBit(TH1::kNoTitle)) return;
8708  Int_t nt = strlen(fH->GetTitle());
8710  TObject *obj;
8711  TIter next(gPad->GetListOfPrimitives());
8712  while ((obj = next())) {
8713  if (!obj->InheritsFrom(TPaveText::Class())) continue;
8714  title = (TPaveText*)obj;
8715  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
8716  break;
8717  }
8718  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
8719  if (title) delete title;
8720  return;
8721  }
8722  Double_t ht = gStyle->GetTitleH();
8723  Double_t wt = gStyle->GetTitleW();
8724  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
8725  if (ht <= 0) ht = 0.05;
8726  if (wt <= 0) {
8727  TLatex l;
8728  l.SetTextSize(ht);
8729  l.SetTitle(fH->GetTitle());
8730  // adjustment in case the title has several lines (#splitline)
8731  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
8732  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
8733  wt = TMath::Min(0.7, 0.02+wndc);
8734  }
8735  if (title) {
8736  TText *t0 = (TText*)title->GetLine(0);
8737  if (t0) {
8738  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
8739  t0->SetTitle(fH->GetTitle());
8740  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
8741  }
8742  return;
8743  }
8744 
8745  Int_t talh = gStyle->GetTitleAlign()/10;
8746  if (talh < 1) talh = 1; if (talh > 3) talh = 3;
8747  Int_t talv = gStyle->GetTitleAlign()%10;
8748  if (talv < 1) talv = 1; if (talv > 3) talv = 3;
8749  Double_t xpos, ypos;
8750  xpos = gStyle->GetTitleX();
8751  ypos = gStyle->GetTitleY();
8752  if (talh == 2) xpos = xpos-wt/2.;
8753  if (talh == 3) xpos = xpos-wt;
8754  if (talv == 2) ypos = ypos+ht/2.;
8755  if (talv == 1) ypos = ypos+ht;
8756 
8757  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
8758 
8759  // box with the histogram title
8761  ptitle->SetFillStyle(gStyle->GetTitleStyle());
8762  ptitle->SetName("title");
8765  ptitle->SetTextFont(gStyle->GetTitleFont(""));
8766  if (gStyle->GetTitleFont("")%10 > 2)
8767  ptitle->SetTextSize(gStyle->GetTitleFontSize());
8768  ptitle->AddText(fH->GetTitle());
8769  ptitle->SetBit(kCanDelete);
8770  ptitle->Draw();
8771  ptitle->Paint();
8772 
8773  if(!gPad->IsEditable()) delete ptitle;
8774 }
8775 
8776 
8777 ////////////////////////////////////////////////////////////////////////////////
8778 /// Process message `mess`.
8779 
8780 void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
8781 {
8782 
8783  if (!strcmp(mess,"SetF3")) {
8785  } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
8787  } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
8788  TVectorD &v = (TVectorD&)(*obj);
8789  Double_t xclip = v(0);
8790  Double_t yclip = v(1);
8791  Double_t zclip = v(2);
8792  TPainter3dAlgorithms::SetF3ClippingBoxOn(xclip,yclip,zclip);
8793  }
8794 }
8795 
8796 
8797 ////////////////////////////////////////////////////////////////////////////////
8798 /// Static function.
8799 ///
8800 /// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
8801 /// This procedure can be used to create an all-sky map in Galactic
8802 /// coordinates with an equal-area Aitoff projection. Output map
8803 /// coordinates are zero longitude centered.
8804 /// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
8805 ///
8806 /// source: GMT
8807 ///
8808 /// code from Ernst-Jan Buis
8809 
8811 {
8812 
8813  Double_t x, y;
8814 
8815  Double_t alpha2 = (l/2)*TMath::DegToRad();
8817  Double_t r2 = TMath::Sqrt(2.);
8818  Double_t f = 2*r2/TMath::Pi();
8819  Double_t cdec = TMath::Cos(delta);
8820  Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
8821  x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
8822  y = TMath::Sin(delta)*r2/denom;
8823  x *= TMath::RadToDeg()/f;
8824  y *= TMath::RadToDeg()/f;
8825  // x *= -1.; // for a skymap swap left<->right
8826  Al = x;
8827  Ab = y;
8828 
8829  return 0;
8830 }
8831 
8832 
8833 ////////////////////////////////////////////////////////////////////////////////
8834 /// Static function
8835 ///
8836 /// Probably the most famous of the various map projections, the Mercator projection
8837 /// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
8838 /// with no distortion along the equator.
8839 /// The Mercator projection has been used extensively for world maps in which the distortion towards
8840 /// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
8841 /// Greenland is larger than South America. In reality, the latter is about eight times the size of
8842 /// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
8843 /// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
8844 /// code from Ernst-Jan Buis
8845 
8847 {
8848 
8849  Al = l;
8851  Ab = TMath::Log(aid);
8852  return 0;
8853 }
8854 
8855 
8856 ////////////////////////////////////////////////////////////////////////////////
8857 /// Static function code from Ernst-Jan Buis
8858 
8860 {
8861 
8862  Al = l*cos(b*TMath::DegToRad());
8863  Ab = b;
8864  return 0;
8866 
8867 
8868 ////////////////////////////////////////////////////////////////////////////////
8869 /// Static function code from Ernst-Jan Buis
8870 
8872 {
8873 
8874  Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
8875  Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
8876  return 0;
8878 
8879 
8880 ////////////////////////////////////////////////////////////////////////////////
8881 /// Recompute the histogram range following graphics operations.
8882 
8884 {
8885 
8886  if (Hoption.Same) return;
8887 
8888  // Compute x,y range
8889  Double_t xmin = Hparam.xmin;
8890  Double_t xmax = Hparam.xmax;
8891  Double_t ymin = Hparam.ymin;
8892  Double_t ymax = Hparam.ymax;
8893 
8894  Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
8895  if (Hoption.Proj ==1) {
8896  // TODO : check x range not lower than -180 and not higher than 180
8897  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8898  THistPainter::ProjectAitoff2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8899  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8900  THistPainter::ProjectAitoff2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8901 
8902  if (xmin > xmin_aid) xmin = xmin_aid;
8903  if (ymin > ymin_aid) ymin = ymin_aid;
8904  if (xmax < xmax_aid) xmax = xmax_aid;
8905  if (ymax < ymax_aid) ymax = ymax_aid;
8906  if (Hparam.ymin<0 && Hparam.ymax>0) {
8907  // there is an 'equator', check its range in the plot..
8908  THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
8909  THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
8910  if (xmin >xmin_aid) xmin = xmin_aid;
8911  if (xmax <xmax_aid) xmax = xmax_aid;
8912  }
8913  if (Hparam.xmin<0 && Hparam.xmax>0) {
8914  THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
8915  THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
8916  if (ymin >ymin_aid) ymin = ymin_aid;
8917  if (ymax <ymax_aid) ymax = ymax_aid;
8918  }
8919  } else if ( Hoption.Proj ==2) {
8920  if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
8921  Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
8922  Hoption.Proj = 0;
8923  } else {
8924  THistPainter::ProjectMercator2xy(Hparam.xmin, Hparam.ymin, xmin, ymin);
8925  THistPainter::ProjectMercator2xy(Hparam.xmax, Hparam.ymax, xmax, ymax);
8926  }
8927  } else if (Hoption.Proj == 3) {
8928  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8929  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8930  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8931  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8932 
8933  if (xmin > xmin_aid) xmin = xmin_aid;
8934  if (ymin > ymin_aid) ymin = ymin_aid;
8935  if (xmax < xmax_aid) xmax = xmax_aid;
8936  if (ymax < ymax_aid) ymax = ymax_aid;
8937  if (Hparam.ymin<0 && Hparam.ymax>0) {
8938  THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
8939  THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
8940  if (xmin >xmin_aid) xmin = xmin_aid;
8941  if (xmax <xmax_aid) xmax = xmax_aid;
8942  }
8943  if (Hparam.xmin<0 && Hparam.xmax>0) {
8944  THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
8945  THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
8946  if (ymin >ymin_aid) ymin = ymin_aid;
8947  if (ymax <ymax_aid) ymax = ymax_aid;
8948  }
8949  } else if (Hoption.Proj == 4) {
8950  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymin, xmin_aid, ymin_aid);
8951  THistPainter::ProjectParabolic2xy(Hparam.xmin, Hparam.ymax, xmin, ymax_aid);
8952  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymax, xmax_aid, ymax);
8953  THistPainter::ProjectParabolic2xy(Hparam.xmax, Hparam.ymin, xmax, ymin);
8954 
8955  if (xmin > xmin_aid) xmin = xmin_aid;
8956  if (ymin > ymin_aid) ymin = ymin_aid;
8957  if (xmax < xmax_aid) xmax = xmax_aid;
8958  if (ymax < ymax_aid) ymax = ymax_aid;
8959  if (Hparam.ymin<0 && Hparam.ymax>0) {
8960  THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
8961  THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
8962  if (xmin >xmin_aid) xmin = xmin_aid;
8963  if (xmax <xmax_aid) xmax = xmax_aid;
8964  }
8965  if (Hparam.xmin<0 && Hparam.xmax>0) {
8966  THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
8967  THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
8968  if (ymin >ymin_aid) ymin = ymin_aid;
8969  if (ymax <ymax_aid) ymax = ymax_aid;
8970  }
8971  }
8972  Hparam.xmin= xmin;
8973  Hparam.xmax= xmax;
8974  Hparam.ymin= ymin;
8975  Hparam.ymax= ymax;
8976 
8977  Double_t dx = xmax-xmin;
8978  Double_t dy = ymax-ymin;
8979  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
8980  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
8981 
8982  // Range() could change the size of the pad pixmap and therefore should
8983  // be called before the other paint routines
8984  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
8985  ymin - dyr*gPad->GetBottomMargin(),
8986  xmax + dxr*gPad->GetRightMargin(),
8987  ymax + dyr*gPad->GetTopMargin());
8988  gPad->RangeAxis(xmin, ymin, xmax, ymax);
8989 }
8990 
8991 
8992 ////////////////////////////////////////////////////////////////////////////////
8993 /// Set current histogram to `h`
8994 
8996 {
8997 
8998  if (h == 0) return;
8999  fH = h;
9000  fXaxis = h->GetXaxis();
9002  fZaxis = h->GetZaxis();
9004 }
9005 
9006 
9007 ////////////////////////////////////////////////////////////////////////////////
9008 /// Initialize various options to draw 2D histograms.
9009 
9011 {
9012 
9013  static const char *where = "TableInit";
9014 
9015  Int_t first, last;
9017  Double_t zmin, zmax;
9018  Int_t maximum = 0;
9019  Int_t minimum = 0;
9020  if (fH->GetMaximumStored() != -1111) maximum = 1;
9021  if (fH->GetMinimumStored() != -1111) minimum = 1;
9022 
9023  // ----------------- Compute X axis parameters
9024  first = fXaxis->GetFirst();
9025  last = fXaxis->GetLast();
9026  Hparam.xlast = last;
9027  Hparam.xfirst = first;
9028  Hparam.xlowedge = fXaxis->GetBinLowEdge(first);
9029  Hparam.xbinsize = fXaxis->GetBinWidth(first);
9030  Hparam.xmin = Hparam.xlowedge;
9031  Hparam.xmax = fXaxis->GetBinLowEdge(last)+fXaxis->GetBinWidth(last);
9032 
9033  // if log scale in X, replace xmin,max by the log
9034  if (Hoption.Logx) {
9035  // find the first edge of a bin that is > 0
9036  if (Hparam.xlowedge <=0 ) {
9037  Hparam.xlowedge = fXaxis->GetBinUpEdge(fXaxis->FindFixBin(0.01*Hparam.xbinsize));
9038  Hparam.xmin = Hparam.xlowedge;
9039  }
9040  if (Hparam.xmin <=0 || Hparam.xmax <=0) {
9041  Error(where, "cannot set X axis to log scale");
9042  return 0;
9043  }
9044  Hparam.xfirst= fXaxis->FindFixBin(Hparam.xmin);
9045  if (Hparam.xfirst < first) Hparam.xfirst = first;
9046  Hparam.xlast = fXaxis->FindFixBin(Hparam.xmax);
9047  if (Hparam.xlast > last) Hparam.xlast = last;
9048  Hparam.xmin = TMath::Log10(Hparam.xmin);
9049  Hparam.xmax = TMath::Log10(Hparam.xmax);
9050  }
9051 
9052  // ----------------- Compute Y axis parameters
9053  first = fYaxis->GetFirst();
9054  last = fYaxis->GetLast();
9055  Hparam.ylast = last;
9056  Hparam.yfirst = first;
9057  Hparam.ylowedge = fYaxis->GetBinLowEdge(first);
9058  Hparam.ybinsize = fYaxis->GetBinWidth(first);
9059  if (!Hparam.ybinsize) Hparam.ybinsize = 1;
9060  Hparam.ymin = Hparam.ylowedge;
9061  Hparam.ymax = fYaxis->GetBinLowEdge(last)+fYaxis->GetBinWidth(last);
9062 
9063  // if log scale in Y, replace ymin,max by the log
9064  if (Hoption.Logy) {
9065  if (Hparam.ylowedge <=0 ) {
9066  Hparam.ylowedge = fYaxis->GetBinUpEdge(fYaxis->FindFixBin(0.01*Hparam.ybinsize));
9067  Hparam.ymin = Hparam.ylowedge;
9068  }
9069  if (Hparam.ymin <=0 || Hparam.ymax <=0) {
9070  Error(where, "cannot set Y axis to log scale");
9071  return 0;
9072  }
9073  Hparam.yfirst= fYaxis->FindFixBin(Hparam.ymin);
9074  if (Hparam.yfirst < first) Hparam.yfirst = first;
9075  Hparam.ylast = fYaxis->FindFixBin(Hparam.ymax);
9076  if (Hparam.ylast > last) Hparam.ylast = last;
9077  Hparam.ymin = TMath::Log10(Hparam.ymin);
9078  Hparam.ymax = TMath::Log10(Hparam.ymax);
9079  }
9080 
9081 
9082  // ----------------- Compute Z axis parameters
9083  Double_t bigp = TMath::Power(10,32);
9084  zmax = -bigp;
9085  zmin = bigp;
9086  Double_t c1, e1;
9087  Double_t allchan = 0;
9088  for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9089  for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9090  c1 = fH->GetBinContent(i,j);
9091  zmax = TMath::Max(zmax,c1);
9092  if (Hoption.Error) {
9093  e1 = fH->GetBinError(i,j);
9094  zmax = TMath::Max(zmax,c1+e1);
9095  }
9096  zmin = TMath::Min(zmin,c1);
9097  allchan += c1;
9098  }
9099  }
9100 
9101  // Take into account maximum , minimum
9102 
9103  if (maximum) zmax = fH->GetMaximumStored();
9104  if (minimum) zmin = fH->GetMinimumStored();
9105  if (Hoption.Logz && zmax < 0) {
9106  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9107  return 0;
9108  } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
9109  zmin = 0.01;
9110  zmax = 10.;
9111  }
9112  if (zmin >= zmax) {
9113  if (Hoption.Logz) {
9114  if (zmax > 0) zmin = 0.001*zmax;
9115  else {
9116  if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
9117  return 0;
9118  }
9119  }
9120  }
9121 
9122  // take into account normalization factor
9123  Hparam.allchan = allchan;
9124  Double_t factor = allchan;
9125  if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
9126  if (allchan) factor /= allchan;
9127  if (factor == 0) factor = 1;
9128  Hparam.factor = factor;
9129  zmax = factor*zmax;
9130  zmin = factor*zmin;
9131  c1 = zmax;
9132  if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
9133 
9134  // For log scales, histogram coordinates are log10(ymin) and
9135  // log10(ymax). Final adjustment (if not option "Same")
9136  // or "+" for ymax) of ymax and ymin for logarithmic scale, if
9137  // Maximum and Minimum are not defined.
9138  if (Hoption.Logz) {
9139  if (zmin <= 0) {
9140  zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9141  fH->SetMinimum(zmin);
9142  }
9143  zmin = TMath::Log10(zmin);
9144  if (!minimum) zmin += TMath::Log10(0.5);
9145  zmax = TMath::Log10(zmax);
9146  if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
9147  goto LZMIN;
9148  }
9149 
9150  // final adjustment of YMAXI for linear scale (if not option "Same"):
9151  // decrease histogram height to MAX% of allowed height if HMAXIM
9152  // has not been called.
9153  // MAX% is the value in percent which has been set in HPLSET
9154  // (default is 90%).
9155  if (!maximum) {
9156  zmax += yMARGIN*(zmax-zmin);
9157  }
9158 
9159  // final adjustment of ymin for linear scale.
9160  // if minimum is not set , then ymin is set to zero if >0
9161  // or to ymin - yMARGIN if <0.
9162  if (!minimum) {
9163  if (gStyle->GetHistMinimumZero()) {
9164  if (zmin >= 0) zmin = 0;
9165  else zmin -= yMARGIN*(zmax-zmin);
9166  } else {
9167  Double_t dzmin = yMARGIN*(zmax-zmin);
9168  if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
9169  else zmin -= dzmin;
9170  }
9171  }
9172 
9173 LZMIN:
9174  Hparam.zmin = zmin;
9175  Hparam.zmax = zmax;
9176 
9177  // Set bar offset and width
9178  Hparam.baroffset = fH->GetBarOffset();
9179  Hparam.barwidth = fH->GetBarWidth();
9180 
9181  return 1;
9182 }
9183 
9184 
9185 ////////////////////////////////////////////////////////////////////////////////
9186 /// This function returns the best format to print the error value (e)
9187 /// knowing the parameter value (v) and the format (f) used to print it.
9188 
9189 const char * THistPainter::GetBestFormat(Double_t v, Double_t e, const char *f)
9190 {
9191 
9192  static char ef[20];
9193  char tf[20], tv[64];
9194 
9195  // print v with the format f in tv.
9196  snprintf(tf,20,"%s%s","%",f);
9197  snprintf(tv,64,tf,v);
9198 
9199  // Analyse tv.
9200  TString sv = tv;
9201  int ie = sv.Index("e");
9202  int iE = sv.Index("E");
9203  int id = sv.Index(".");
9204 
9205  // v has been printed with the exponent notation.
9206  // There is 2 cases, the exponent is positive or negative
9207  if (ie >= 0 || iE >= 0) {
9208  if (sv.Index("+") >= 0) {
9209  if (e < 1) {
9210  snprintf(ef,20,"%s.1f","%");
9211  } else {
9212  if (ie >= 0) {
9213  snprintf(ef,20,"%s.%de","%",ie-id-1);
9214  } else {
9215  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9216  }
9217  }
9218  } else {
9219  if (ie >= 0) {
9220  snprintf(ef,20,"%s.%de","%",ie-id-1);
9221  } else {
9222  snprintf(ef,20,"%s.%dE","%",iE-id-1);
9223  }
9224  }
9225 
9226  // There is not '.' in tv. e will be printed with one decimal digit.
9227  } else if (id < 0) {
9228  snprintf(ef,20,"%s.1f","%");
9229 
9230  // There is a '.' in tv and no exponent notation. e's decimal part will
9231  // have the same number of digits as v's one.
9232  } else {
9233  snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
9234  }
9235 
9236  return ef;
9237 }
9238 
9239 
9240 ////////////////////////////////////////////////////////////////////////////////
9241 /// Set projection.
9242 
9243 void THistPainter::SetShowProjection(const char *option,Int_t nbins)
9244 {
9245 
9246  if (fShowProjection) return;
9247  TString opt = option;
9248  opt.ToLower();
9249  Int_t projection = 0;
9250  if (opt.Contains("x")) projection = 1;
9251  if (opt.Contains("y")) projection = 2;
9252  if (opt.Contains("z")) projection = 3;
9253  if (opt.Contains("xy")) projection = 4;
9254  if (opt.Contains("yx")) projection = 5;
9255  if (opt.Contains("xz")) projection = 6;
9256  if (opt.Contains("zx")) projection = 7;
9257  if (opt.Contains("yz")) projection = 8;
9258  if (opt.Contains("zy")) projection = 9;
9259  if (projection < 4) fShowOption = option+1;
9260  else fShowOption = option+2;
9261  fShowProjection = projection+100*nbins;
9262  gROOT->MakeDefCanvas();
9263  gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
9264  gPad->SetGrid();
9265 }
9266 
9267 
9268 ////////////////////////////////////////////////////////////////////////////////
9269 /// Show projection onto X.
9270 
9271 void THistPainter::ShowProjectionX(Int_t /*px*/, Int_t py)
9272 {
9273 
9274  Int_t nbins = (Int_t)fShowProjection/100;
9275  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9276  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9278  // Erase old position and draw a line at current position
9279  static int pyold1 = 0;
9280  static int pyold2 = 0;
9281  float uxmin = gPad->GetUxmin();
9282  float uxmax = gPad->GetUxmax();
9283  int pxmin = gPad->XtoAbsPixel(uxmin);
9284  int pxmax = gPad->XtoAbsPixel(uxmax);
9285  Float_t upy = gPad->AbsPixeltoY(py);
9286  Float_t y = gPad->PadtoY(upy);
9287  Int_t biny1 = fH->GetYaxis()->FindBin(y);
9288  Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
9289  Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
9290  Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
9291 
9292  if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
9293  gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
9294  pyold1 = py1;
9295  pyold2 = py2;
9296 
9297  // Create or set the new canvas proj x
9298  TVirtualPad *padsav = gPad;
9299  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9300  (ULong_t)fH, fShowProjection));
9301  if (c) {
9302  c->Clear();
9303  } else {
9304  fShowProjection = 0;
9305  pyold1 = 0;
9306  pyold2 = 0;
9307  return;
9308  }
9309  c->cd();
9310  c->SetLogy(padsav->GetLogz());
9311  c->SetLogx(padsav->GetLogx());
9312 
9313  // Draw slice corresponding to mouse position
9314  TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
9315  TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
9316  if (hp) {
9317  hp->SetFillColor(38);
9318  // apply a patch from Oliver Freyermuth to set the title in the projection using the range of the projected Y values
9319  if (biny1 == biny2) {
9320  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9321  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
9322  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9323  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9324  if (fH->GetYaxis()->GetLabels() != NULL) {
9325  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
9326  } else {
9327  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
9328  }
9329  } else {
9330  Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
9331  Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
9332  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9333  // biny1 is used here to get equal precision no matter how large the binrange is,
9334  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9335  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
9336  if (fH->GetYaxis()->GetLabels() != NULL) {
9337  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)));
9338  } else {
9339  hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
9340  }
9341  }
9342  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9343  hp->SetYTitle("Number of Entries");
9344  hp->Draw();
9345  c->Update();
9346  padsav->cd();
9347  }
9348 }
9349 
9350 
9351 ////////////////////////////////////////////////////////////////////////////////
9352 /// Show projection onto Y.
9353 
9354 void THistPainter::ShowProjectionY(Int_t px, Int_t /*py*/)
9355 {
9356 
9357  Int_t nbins = (Int_t)fShowProjection/100;
9358  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9359  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9361  // Erase old position and draw a line at current position
9362  static int pxold1 = 0;
9363  static int pxold2 = 0;
9364  float uymin = gPad->GetUymin();
9365  float uymax = gPad->GetUymax();
9366  int pymin = gPad->YtoAbsPixel(uymin);
9367  int pymax = gPad->YtoAbsPixel(uymax);
9368  Float_t upx = gPad->AbsPixeltoX(px);
9369  Float_t x = gPad->PadtoX(upx);
9370  Int_t binx1 = fH->GetXaxis()->FindBin(x);
9371  Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
9372  Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
9373  Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
9374 
9375  if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
9376  gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
9377  pxold1 = px1;
9378  pxold2 = px2;
9379 
9380  // Create or set the new canvas proj y
9381  TVirtualPad *padsav = gPad;
9382  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9383  (ULong_t)fH, fShowProjection));
9384  if (c) {
9385  c->Clear();
9386  } else {
9387  fShowProjection = 0;
9388  pxold1 = 0;
9389  pxold2 = 0;
9390  return;
9391  }
9392  c->cd();
9393  c->SetLogy(padsav->GetLogz());
9394  c->SetLogx(padsav->GetLogy());
9395 
9396  // Draw slice corresponding to mouse position
9397  TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
9398  TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
9399  if (hp) {
9400  hp->SetFillColor(38);
9401  // apply a patch from Oliver Freyermuth to set the title in the projection using the range of the projected X values
9402  if (binx1 == binx2) {
9403  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9404  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
9405  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9406  Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
9407  if (fH->GetXaxis()->GetLabels() != NULL) {
9408  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
9409  } else {
9410  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
9411  }
9412  } else {
9413  Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
9414  Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
9415  // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
9416  // binx1 is used here to get equal precision no matter how large the binrange is,
9417  // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
9418  Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
9419  if (fH->GetXaxis()->GetLabels() != NULL) {
9420  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)));
9421  } else {
9422  hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
9423  }
9424  }
9425  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9426  hp->SetYTitle("Number of Entries");
9427  hp->Draw();
9428  c->Update();
9429  padsav->cd();
9430  }
9431 }
9432 
9433 
9434 ////////////////////////////////////////////////////////////////////////////////
9435 /// Show projection (specified by `fShowProjection`) of a `TH3`.
9436 /// The drawing option for the projection is in `fShowOption`.
9437 ///
9438 /// First implementation; R.Brun
9439 ///
9440 /// Full implementation: Tim Tran (timtran@jlab.org) April 2006
9441 
9443 {
9444 
9445  Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
9446  if (fH->GetDimension() < 3) {
9447  if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
9448  if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
9449  }
9450 
9451  gPad->SetDoubleBuffer(0); // turn off double buffer mode
9452  gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
9453 
9454  // Erase old position and draw a line at current position
9455  TView *view = gPad->GetView();
9456  if (!view) return;
9457  TH3 *h3 = (TH3*)fH;
9458  TAxis *xaxis = h3->GetXaxis();
9459  TAxis *yaxis = h3->GetYaxis();
9460  TAxis *zaxis = h3->GetZaxis();
9461  Double_t u[3],xx[3];
9462 
9463  static TPoint line1[2];//store end points of a line, initialised 0 by default
9464  static TPoint line2[2];// second line when slice thickness > 1 bin thickness
9465  static TPoint line3[2];
9466  static TPoint line4[2];
9467  static TPoint endface1[5];
9468  static TPoint endface2[5];
9469  static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
9470  static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
9471 
9472  Double_t uxmin = gPad->GetUxmin();
9473  Double_t uxmax = gPad->GetUxmax();
9474  Double_t uymin = gPad->GetUymin();
9475  Double_t uymax = gPad->GetUymax();
9476 
9477  int pxmin = gPad->XtoAbsPixel(uxmin);
9478  int pxmax = gPad->XtoAbsPixel(uxmax);
9479  if (pxmin==pxmax) return;
9480  int pymin = gPad->YtoAbsPixel(uymin);
9481  int pymax = gPad->YtoAbsPixel(uymax);
9482  if (pymin==pymax) return;
9483  Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
9484  Double_t cy = (pymax-pymin)/(uymax-uymin);
9485  TVirtualPad *padsav = gPad;
9486  TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
9487  (ULong_t)fH, fShowProjection));
9488  if (!c) {
9489  fShowProjection = 0;
9490  return;
9491  }
9492 
9493  switch ((Int_t)fShowProjection%100) {
9494  case 1:
9495  // "x"
9496  {
9497  Int_t firstY = yaxis->GetFirst();
9498  Int_t lastY = yaxis->GetLast();
9499  Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
9500  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9501  yaxis->SetRange(biny,biny2);
9502  Int_t firstZ = zaxis->GetFirst();
9503  Int_t lastZ = zaxis->GetLast();
9504  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
9505  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9506  zaxis->SetRange(binz,binz2);
9507  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9508  if (nbins>1 && line1[0].GetX()) {
9509  gVirtualX->DrawPolyLine(2,line2);
9510  gVirtualX->DrawPolyLine(2,line3);
9511  gVirtualX->DrawPolyLine(2,line4);
9512  gVirtualX->DrawPolyLine(5,endface1);
9513  gVirtualX->DrawPolyLine(5,endface2);
9514  }
9515  xx[0] = xaxis->GetXmin();
9516  xx[2] = zaxis->GetBinCenter(binz);
9517  xx[1] = yaxis->GetBinCenter(biny);
9518  view->WCtoNDC(xx,u);
9519  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9520  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9521  xx[0] = xaxis->GetXmax();
9522  view->WCtoNDC(xx,u);
9523  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9524  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9525  gVirtualX->DrawPolyLine(2,line1);
9526  if (nbins>1) {
9527  xx[0] = xaxis->GetXmin();
9528  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9529  xx[1] = yaxis->GetBinCenter(biny);
9530  view->WCtoNDC(xx,u);
9531  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9532  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9533  xx[0] = xaxis->GetXmax();
9534  view->WCtoNDC(xx,u);
9535  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9536  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9537 
9538  xx[0] = xaxis->GetXmin();
9539  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9540  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9541  view->WCtoNDC(xx,u);
9542  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9543  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9544  xx[0] = xaxis->GetXmax();
9545  view->WCtoNDC(xx,u);
9546  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9547  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9548 
9549  xx[0] = xaxis->GetXmin();
9550  xx[2] = zaxis->GetBinCenter(binz);
9551  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9552  view->WCtoNDC(xx,u);
9553  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9554  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9555  xx[0] = xaxis->GetXmax();
9556  view->WCtoNDC(xx,u);
9557  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9558  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9559 
9560  endface1[0].SetX(line1[0].GetX());
9561  endface1[0].SetY(line1[0].GetY());
9562  endface1[1].SetX(line2[0].GetX());
9563  endface1[1].SetY(line2[0].GetY());
9564  endface1[2].SetX(line3[0].GetX());
9565  endface1[2].SetY(line3[0].GetY());
9566  endface1[3].SetX(line4[0].GetX());
9567  endface1[3].SetY(line4[0].GetY());
9568  endface1[4].SetX(line1[0].GetX());
9569  endface1[4].SetY(line1[0].GetY());
9570 
9571  endface2[0].SetX(line1[1].GetX());
9572  endface2[0].SetY(line1[1].GetY());
9573  endface2[1].SetX(line2[1].GetX());
9574  endface2[1].SetY(line2[1].GetY());
9575  endface2[2].SetX(line3[1].GetX());
9576  endface2[2].SetY(line3[1].GetY());
9577  endface2[3].SetX(line4[1].GetX());
9578  endface2[3].SetY(line4[1].GetY());
9579  endface2[4].SetX(line1[1].GetX());
9580  endface2[4].SetY(line1[1].GetY());
9581 
9582  gVirtualX->DrawPolyLine(2,line2);
9583  gVirtualX->DrawPolyLine(2,line3);
9584  gVirtualX->DrawPolyLine(2,line4);
9585  gVirtualX->DrawPolyLine(5,endface1);
9586  gVirtualX->DrawPolyLine(5,endface2);
9587  }
9588  c->Clear();
9589  c->cd();
9590  TH1 *hp = h3->Project3D("x");
9591  yaxis->SetRange(firstY,lastY);
9592  zaxis->SetRange(firstZ,lastZ);
9593  if (hp) {
9594  hp->SetFillColor(38);
9595  if (nbins == 1)
9596  hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
9597  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
9598  else {
9599  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),
9600  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
9601  }
9602  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9603  hp->SetYTitle("Number of Entries");
9604  hp->Draw(fShowOption.Data());
9605  }
9606  }
9607  break;
9608 
9609  case 2:
9610  // "y"
9611  {
9612  Int_t firstX = xaxis->GetFirst();
9613  Int_t lastX = xaxis->GetLast();
9614  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
9615  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
9616  xaxis->SetRange(binx,binx2);
9617  Int_t firstZ = zaxis->GetFirst();
9618  Int_t lastZ = zaxis->GetLast();
9619  Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
9620  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9621  zaxis->SetRange(binz,binz2);
9622  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9623  if (nbins>1 && line1[0].GetX()) {
9624  gVirtualX->DrawPolyLine(2,line2);
9625  gVirtualX->DrawPolyLine(2,line3);
9626  gVirtualX->DrawPolyLine(2,line4);
9627  gVirtualX->DrawPolyLine(5,endface1);
9628  gVirtualX->DrawPolyLine(5,endface2);
9629  }
9630  xx[0]=xaxis->GetBinCenter(binx);
9631  xx[2] = zaxis->GetBinCenter(binz);
9632  xx[1] = yaxis->GetXmin();
9633  view->WCtoNDC(xx,u);
9634  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9635  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9636  xx[1] = yaxis->GetXmax();
9637  view->WCtoNDC(xx,u);
9638  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9639  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9640  gVirtualX->DrawPolyLine(2,line1);
9641  if (nbins>1) {
9642  xx[1] = yaxis->GetXmin();
9643  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9644  xx[0] = xaxis->GetBinCenter(binx);
9645  view->WCtoNDC(xx,u);
9646  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9647  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9648  xx[1] = yaxis->GetXmax();
9649  view->WCtoNDC(xx,u);
9650  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9651  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9652 
9653  xx[1] = yaxis->GetXmin();
9654  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9655  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9656  view->WCtoNDC(xx,u);
9657  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9658  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9659  xx[1] = yaxis->GetXmax();
9660  view->WCtoNDC(xx,u);
9661  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9662  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9663 
9664  xx[1] = yaxis->GetXmin();
9665  xx[2] = zaxis->GetBinCenter(binz);
9666  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9667  view->WCtoNDC(xx,u);
9668  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9669  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9670  xx[1] = yaxis->GetXmax();
9671  view->WCtoNDC(xx,u);
9672  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9673  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9674 
9675  endface1[0].SetX(line1[0].GetX());
9676  endface1[0].SetY(line1[0].GetY());
9677  endface1[1].SetX(line2[0].GetX());
9678  endface1[1].SetY(line2[0].GetY());
9679  endface1[2].SetX(line3[0].GetX());
9680  endface1[2].SetY(line3[0].GetY());
9681  endface1[3].SetX(line4[0].GetX());
9682  endface1[3].SetY(line4[0].GetY());
9683  endface1[4].SetX(line1[0].GetX());
9684  endface1[4].SetY(line1[0].GetY());
9685 
9686  endface2[0].SetX(line1[1].GetX());
9687  endface2[0].SetY(line1[1].GetY());
9688  endface2[1].SetX(line2[1].GetX());
9689  endface2[1].SetY(line2[1].GetY());
9690  endface2[2].SetX(line3[1].GetX());
9691  endface2[2].SetY(line3[1].GetY());
9692  endface2[3].SetX(line4[1].GetX());
9693  endface2[3].SetY(line4[1].GetY());
9694  endface2[4].SetX(line1[1].GetX());
9695  endface2[4].SetY(line1[1].GetY());
9696 
9697  gVirtualX->DrawPolyLine(2,line2);
9698  gVirtualX->DrawPolyLine(2,line3);
9699  gVirtualX->DrawPolyLine(2,line4);
9700  gVirtualX->DrawPolyLine(5,endface1);
9701  gVirtualX->DrawPolyLine(5,endface2);
9702  }
9703  c->Clear();
9704  c->cd();
9705  TH1 *hp = h3->Project3D("y");
9706  xaxis->SetRange(firstX,lastX);
9707  zaxis->SetRange(firstZ,lastZ);
9708  if (hp) {
9709  hp->SetFillColor(38);
9710  if (nbins == 1)
9711  hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
9712  binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
9713  else
9714  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),
9715  binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
9716  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9717  hp->SetYTitle("Number of Entries");
9718  hp->Draw(fShowOption.Data());
9719  }
9720  }
9721  break;
9722 
9723  case 3:
9724  // "z"
9725  {
9726  Int_t firstX = xaxis->GetFirst();
9727  Int_t lastX = xaxis->GetLast();
9728  Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
9729  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
9730  xaxis->SetRange(binx,binx2);
9731  Int_t firstY = yaxis->GetFirst();
9732  Int_t lastY = yaxis->GetLast();
9733  Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
9734  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9735  yaxis->SetRange(biny,biny2);
9736  if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
9737  if (nbins>1 && line1[0].GetX()) {
9738  gVirtualX->DrawPolyLine(2,line2);
9739  gVirtualX->DrawPolyLine(2,line3);
9740  gVirtualX->DrawPolyLine(2,line4);
9741  gVirtualX->DrawPolyLine(5,endface1);
9742  gVirtualX->DrawPolyLine(5,endface2);
9743  }
9744  xx[0] = xaxis->GetBinCenter(binx);
9745  xx[1] = yaxis->GetBinCenter(biny);
9746  xx[2] = zaxis->GetXmin();
9747  view->WCtoNDC(xx,u);
9748  line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9749  line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9750  xx[2] = zaxis->GetXmax();
9751  view->WCtoNDC(xx,u);
9752  line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9753  line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9754  gVirtualX->DrawPolyLine(2,line1);
9755  if (nbins>1) {
9756  xx[2] = zaxis->GetXmin();
9757  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9758  xx[0] = xaxis->GetBinCenter(binx);
9759  view->WCtoNDC(xx,u);
9760  line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9761  line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9762  xx[2] = zaxis->GetXmax();
9763  view->WCtoNDC(xx,u);
9764  line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9765  line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9766 
9767  xx[2] = zaxis->GetXmin();
9768  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
9769  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9770  view->WCtoNDC(xx,u);
9771  line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9772  line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9773  xx[2] = zaxis->GetXmax();
9774  view->WCtoNDC(xx,u);
9775  line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9776  line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9777 
9778  xx[2] = zaxis->GetXmin();
9779  xx[1] = yaxis->GetBinCenter(biny);
9780  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
9781  view->WCtoNDC(xx,u);
9782  line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9783  line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9784  xx[2] = zaxis->GetXmax();
9785  view->WCtoNDC(xx,u);
9786  line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9787  line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9788 
9789  endface1[0].SetX(line1[0].GetX());
9790  endface1[0].SetY(line1[0].GetY());
9791  endface1[1].SetX(line2[0].GetX());
9792  endface1[1].SetY(line2[0].GetY());
9793  endface1[2].SetX(line3[0].GetX());
9794  endface1[2].SetY(line3[0].GetY());
9795  endface1[3].SetX(line4[0].GetX());
9796  endface1[3].SetY(line4[0].GetY());
9797  endface1[4].SetX(line1[0].GetX());
9798  endface1[4].SetY(line1[0].GetY());
9799 
9800  endface2[0].SetX(line1[1].GetX());
9801  endface2[0].SetY(line1[1].GetY());
9802  endface2[1].SetX(line2[1].GetX());
9803  endface2[1].SetY(line2[1].GetY());
9804  endface2[2].SetX(line3[1].GetX());
9805  endface2[2].SetY(line3[1].GetY());
9806  endface2[3].SetX(line4[1].GetX());
9807  endface2[3].SetY(line4[1].GetY());
9808  endface2[4].SetX(line1[1].GetX());
9809  endface2[4].SetY(line1[1].GetY());
9810 
9811  gVirtualX->DrawPolyLine(2,line2);
9812  gVirtualX->DrawPolyLine(2,line3);
9813  gVirtualX->DrawPolyLine(2,line4);
9814  gVirtualX->DrawPolyLine(5,endface1);
9815  gVirtualX->DrawPolyLine(5,endface2);
9816  }
9817  c->Clear();
9818  c->cd();
9819  TH1 *hp = h3->Project3D("z");
9820  xaxis->SetRange(firstX,lastX);
9821  yaxis->SetRange(firstY,lastY);
9822  if (hp) {
9823  hp->SetFillColor(38);
9824  if (nbins == 1)
9825  hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
9826  biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
9827  else
9828  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),
9829  biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
9830  hp->SetXTitle(fH->GetZaxis()->GetTitle());
9831  hp->SetYTitle("Number of Entries");
9832  hp->Draw(fShowOption.Data());
9833  }
9834  }
9835  break;
9836 
9837  case 4:
9838  // "xy"
9839  {
9840  Int_t first = zaxis->GetFirst();
9841  Int_t last = zaxis->GetLast();
9842  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9843  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9844  zaxis->SetRange(binz,binz2);
9845  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9846  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9847  xx[0] = xaxis->GetXmin();
9848  xx[1] = yaxis->GetXmax();
9849  xx[2] = zaxis->GetBinCenter(binz);
9850  view->WCtoNDC(xx,u);
9851  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9852  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9853  rect1[4].SetX(rect1[0].GetX());
9854  rect1[4].SetY(rect1[0].GetY());
9855  xx[0] = xaxis->GetXmax();
9856  view->WCtoNDC(xx,u);
9857  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9858  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9859  xx[1] = yaxis->GetXmin();
9860  view->WCtoNDC(xx,u);
9861  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9862  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9863  xx[0] = xaxis->GetXmin();
9864  view->WCtoNDC(xx,u);
9865  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9866  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9867  gVirtualX->DrawPolyLine(5,rect1);
9868  if (nbins>1) {
9869  xx[0] = xaxis->GetXmin();
9870  xx[1] = yaxis->GetXmax();
9871  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9872  view->WCtoNDC(xx,u);
9873  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9874  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9875  rect2[4].SetX(rect2[0].GetX());
9876  rect2[4].SetY(rect2[0].GetY());
9877  xx[0] = xaxis->GetXmax();
9878  view->WCtoNDC(xx,u);
9879  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9880  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9881  xx[1] = yaxis->GetXmin();
9882  view->WCtoNDC(xx,u);
9883  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9884  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9885  xx[0] = xaxis->GetXmin();
9886  view->WCtoNDC(xx,u);
9887  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9888  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9889  gVirtualX->DrawPolyLine(5,rect2);
9890  }
9891 
9892  c->Clear();
9893  c->cd();
9894  TH2 *hp = (TH2*)h3->Project3D("xy");
9895  zaxis->SetRange(first,last);
9896  if (hp) {
9897  hp->SetFillColor(38);
9898  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
9899  else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
9900  hp->SetXTitle(fH->GetYaxis()->GetTitle());
9901  hp->SetYTitle(fH->GetXaxis()->GetTitle());
9902  hp->SetZTitle("Number of Entries");
9903  hp->Draw(fShowOption.Data());
9904  }
9905  }
9906  break;
9907 
9908  case 5:
9909  // "yx"
9910  {
9911  Int_t first = zaxis->GetFirst();
9912  Int_t last = zaxis->GetLast();
9913  Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9914  Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
9915  zaxis->SetRange(binz,binz2);
9916  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9917  if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9918  xx[0] = xaxis->GetXmin();
9919  xx[1] = yaxis->GetXmax();
9920  xx[2] = zaxis->GetBinCenter(binz);
9921  view->WCtoNDC(xx,u);
9922  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9923  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9924  rect1[4].SetX(rect1[0].GetX());
9925  rect1[4].SetY(rect1[0].GetY());
9926  xx[0] = xaxis->GetXmax();
9927  view->WCtoNDC(xx,u);
9928  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9929  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9930  xx[1] = yaxis->GetXmin();
9931  view->WCtoNDC(xx,u);
9932  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9933  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9934  xx[0] = xaxis->GetXmin();
9935  view->WCtoNDC(xx,u);
9936  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9937  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9938  gVirtualX->DrawPolyLine(5,rect1);
9939  if (nbins>1) {
9940  xx[0] = xaxis->GetXmin();
9941  xx[1] = yaxis->GetXmax();
9942  xx[2] = zaxis->GetBinCenter(binz+nbins-1);
9943  view->WCtoNDC(xx,u);
9944  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9945  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9946  rect2[4].SetX(rect2[0].GetX());
9947  rect2[4].SetY(rect2[0].GetY());
9948  xx[0] = xaxis->GetXmax();
9949  view->WCtoNDC(xx,u);
9950  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9951  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
9952  xx[1] = yaxis->GetXmin();
9953  view->WCtoNDC(xx,u);
9954  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9955  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
9956  xx[0] = xaxis->GetXmin();
9957  view->WCtoNDC(xx,u);
9958  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9959  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
9960  gVirtualX->DrawPolyLine(5,rect2);
9961  }
9962  c->Clear();
9963  c->cd();
9964  TH2 *hp = (TH2*)h3->Project3D("yx");
9965  zaxis->SetRange(first,last);
9966  if (hp) {
9967  hp->SetFillColor(38);
9968  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
9969  else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
9970  hp->SetXTitle(fH->GetXaxis()->GetTitle());
9971  hp->SetYTitle(fH->GetYaxis()->GetTitle());
9972  hp->SetZTitle("Number of Entries");
9973  hp->Draw(fShowOption.Data());
9974  }
9975  }
9976  break;
9977 
9978  case 6:
9979  // "xz"
9980  {
9981  Int_t first = yaxis->GetFirst();
9982  Int_t last = yaxis->GetLast();
9983  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
9984  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
9985  yaxis->SetRange(biny,biny2);
9986  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
9987  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
9988  xx[0] = xaxis->GetXmin();
9989  xx[2] = zaxis->GetXmax();
9990  xx[1] = yaxis->GetBinCenter(biny);
9991  view->WCtoNDC(xx,u);
9992  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9993  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
9994  rect1[4].SetX(rect1[0].GetX());
9995  rect1[4].SetY(rect1[0].GetY());
9996  xx[0] = xaxis->GetXmax();
9997  view->WCtoNDC(xx,u);
9998  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
9999  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10000  xx[2] = zaxis->GetXmin();
10001  view->WCtoNDC(xx,u);
10002  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10003  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10004  xx[0] = xaxis->GetXmin();
10005  view->WCtoNDC(xx,u);
10006  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10007  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10008  gVirtualX->DrawPolyLine(5,rect1);
10009  if (nbins>1) {
10010  xx[0] = xaxis->GetXmin();
10011  xx[2] = zaxis->GetXmax();
10012  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10013  view->WCtoNDC(xx,u);
10014  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10015  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10016  rect2[4].SetX(rect2[0].GetX());
10017  rect2[4].SetY(rect2[0].GetY());
10018  xx[0] = xaxis->GetXmax();
10019  view->WCtoNDC(xx,u);
10020  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10021  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10022  xx[2] = zaxis->GetXmin();
10023  view->WCtoNDC(xx,u);
10024  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10025  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10026  xx[0] = xaxis->GetXmin();
10027  view->WCtoNDC(xx,u);
10028  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10029  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10030  gVirtualX->DrawPolyLine(5,rect2);
10031  }
10032  c->Clear();
10033  c->cd();
10034  TH2 *hp = (TH2*)h3->Project3D("xz");
10035  yaxis->SetRange(first,last);
10036  if (hp) {
10037  hp->SetFillColor(38);
10038  if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10039  else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10040  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10041  hp->SetYTitle(fH->GetXaxis()->GetTitle());
10042  hp->SetZTitle("Number of Entries");
10043  hp->Draw(fShowOption.Data());
10044  }
10045  }
10046  break;
10047 
10048  case 7:
10049  // "zx"
10050  {
10051  Int_t first = yaxis->GetFirst();
10052  Int_t last = yaxis->GetLast();
10053  Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
10054  Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10055  yaxis->SetRange(biny,biny2);
10056  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10057  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10058  xx[0] = xaxis->GetXmin();
10059  xx[2] = zaxis->GetXmax();
10060  xx[1] = yaxis->GetBinCenter(biny);
10061  view->WCtoNDC(xx,u);
10062  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10063  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10064  rect1[4].SetX(rect1[0].GetX());
10065  rect1[4].SetY(rect1[0].GetY());
10066  xx[0] = xaxis->GetXmax();
10067  view->WCtoNDC(xx,u);
10068  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10069  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10070  xx[2] = zaxis->GetXmin();
10071  view->WCtoNDC(xx,u);
10072  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10073  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10074  xx[0] = xaxis->GetXmin();
10075  view->WCtoNDC(xx,u);
10076  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10077  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10078  gVirtualX->DrawPolyLine(5,rect1);
10079  if (nbins>1) {
10080  xx[0] = xaxis->GetXmin();
10081  xx[2] = zaxis->GetXmax();
10082  xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10083  view->WCtoNDC(xx,u);
10084  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10085  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10086  rect2[4].SetX(rect2[0].GetX());
10087  rect2[4].SetY(rect2[0].GetY());
10088  xx[0] = xaxis->GetXmax();
10089  view->WCtoNDC(xx,u);
10090  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10091  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10092  xx[2] = zaxis->GetXmin();
10093  view->WCtoNDC(xx,u);
10094  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10095  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10096  xx[0] = xaxis->GetXmin();
10097  view->WCtoNDC(xx,u);
10098  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10099  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10100  gVirtualX->DrawPolyLine(5,rect2);
10101  }
10102  c->Clear();
10103  c->cd();
10104  TH2 *hp = (TH2*)h3->Project3D("zx");
10105  yaxis->SetRange(first,last);
10106  if (hp) {
10107  hp->SetFillColor(38);
10108  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
10109  else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
10110  hp->SetXTitle(fH->GetXaxis()->GetTitle());
10111  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10112  hp->SetZTitle("Number of Entries");
10113  hp->Draw(fShowOption.Data());
10114  }
10115  }
10116  break;
10117 
10118  case 8:
10119  // "yz"
10120  {
10121  Int_t first = xaxis->GetFirst();
10122  Int_t last = xaxis->GetLast();
10123  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10124  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10125  xaxis->SetRange(binx,binx2);
10126  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10127  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10128  xx[2] = zaxis->GetXmin();
10129  xx[1] = yaxis->GetXmax();
10130  xx[0] = xaxis->GetBinCenter(binx);
10131  view->WCtoNDC(xx,u);
10132  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10133  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10134  rect1[4].SetX(rect1[0].GetX());
10135  rect1[4].SetY(rect1[0].GetY());
10136  xx[2] = zaxis->GetXmax();
10137  view->WCtoNDC(xx,u);
10138  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10139  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10140  xx[1] = yaxis->GetXmin();
10141  view->WCtoNDC(xx,u);
10142  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10143  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10144  xx[2] = zaxis->GetXmin();
10145  view->WCtoNDC(xx,u);
10146  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10147  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10148  gVirtualX->DrawPolyLine(5,rect1);
10149  if (nbins>1) {
10150  xx[2] = zaxis->GetXmin();
10151  xx[1] = yaxis->GetXmax();
10152  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10153  view->WCtoNDC(xx,u);
10154  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10155  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10156  rect2[4].SetX(rect2[0].GetX());
10157  rect2[4].SetY(rect2[0].GetY());
10158  xx[2] = zaxis->GetXmax();
10159  view->WCtoNDC(xx,u);
10160  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10161  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10162  xx[1] = yaxis->GetXmin();
10163  view->WCtoNDC(xx,u);
10164  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10165  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10166  xx[2] = zaxis->GetXmin();
10167  view->WCtoNDC(xx,u);
10168  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10169  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10170  gVirtualX->DrawPolyLine(5,rect2);
10171  }
10172  c->Clear();
10173  c->cd();
10174  TH2 *hp = (TH2*)h3->Project3D("yz");
10175  xaxis->SetRange(first,last);
10176  if (hp) {
10177  hp->SetFillColor(38);
10178  if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10179  else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10180  hp->SetXTitle(fH->GetZaxis()->GetTitle());
10181  hp->SetYTitle(fH->GetYaxis()->GetTitle());
10182  hp->SetZTitle("Number of Entries");
10183  hp->Draw(fShowOption.Data());
10184  }
10185  }
10186  break;
10187 
10188  case 9:
10189  // "zy"
10190  {
10191  Int_t first = xaxis->GetFirst();
10192  Int_t last = xaxis->GetLast();
10193  Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
10194  Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10195  xaxis->SetRange(binx,binx2);
10196  if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
10197  if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
10198  xx[2] = zaxis->GetXmin();
10199  xx[1] = yaxis->GetXmax();
10200  xx[0] = xaxis->GetBinCenter(binx);
10201  view->WCtoNDC(xx,u);
10202  rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10203  rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10204  rect1[4].SetX(rect1[0].GetX());
10205  rect1[4].SetY(rect1[0].GetY());
10206  xx[2] = zaxis->GetXmax();
10207  view->WCtoNDC(xx,u);
10208  rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10209  rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10210  xx[1] = yaxis->GetXmin();
10211  view->WCtoNDC(xx,u);
10212  rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10213  rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10214  xx[2] = zaxis->GetXmin();
10215  view->WCtoNDC(xx,u);
10216  rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10217  rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10218  gVirtualX->DrawPolyLine(5,rect1);
10219  if (nbins>1) {
10220  xx[2] = zaxis->GetXmin();
10221  xx[1] = yaxis->GetXmax();
10222  xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10223  view->WCtoNDC(xx,u);
10224  rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10225  rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10226  rect2[4].SetX(rect2[0].GetX());
10227  rect2[4].SetY(rect2[0].GetY());
10228  xx[2] = zaxis->GetXmax();
10229  view->WCtoNDC(xx,u);
10230  rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10231  rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10232  xx[1] = yaxis->GetXmin();
10233  view->WCtoNDC(xx,u);
10234  rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10235  rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
10236  xx[2] = zaxis->GetXmin();
10237  view->WCtoNDC(xx,u);
10238  rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10239  rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
10240  gVirtualX->DrawPolyLine(5,rect2);
10241  }
10242  c->Clear();
10243  c->cd();
10244  TH2 *hp = (TH2*)h3->Project3D("zy");
10245  xaxis->SetRange(first,last);
10246  if (hp) {
10247  hp->SetFillColor(38);
10248  if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
10249  else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
10250  hp->SetXTitle(fH->GetYaxis()->GetTitle());
10251  hp->SetYTitle(fH->GetZaxis()->GetTitle());
10252  hp->SetZTitle("Number of Entries");
10253  hp->Draw(fShowOption.Data());
10254  }
10255  }
10256  break;
10257 
10258  }
10259  c->Update();
10260  padsav->cd();
10261 }
const int nx
Definition: kalman.C:16
TControlBar * bar
Definition: demos.C:15
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
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
static TString gStringSkewness
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
static TString gStringSkewnessZ
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:95
An array of TObjects.
Definition: TObjArray.h:39
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:405
const Int_t kNMAX
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.
virtual void PaintContour(Option_t *option)
Control function to draw a 2D histogram as a contour plot.
virtual Int_t GetLogy() const =0
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:798
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
tuple random
Definition: hsimple.py:62
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:809
Double_t * GetX() const
Definition: TPolyLine.h:69
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
Hparam_t Hparam
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1579
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
return c
const char Option_t
Definition: RtypesCore.h:62
virtual Double_t * GetRmax()=0
virtual 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
tuple offset
Definition: tree.py:93
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:363
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:1165
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)
Control function to draw a 2D histogram as a violin plot
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
Double_t GetX2() const
Definition: TBox.h:73
tuple f2
Definition: surfaces.py:24
#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
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:93
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
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:344
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:1766
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
static TString gStringUnderflow
virtual void Paint2DErrors(Option_t *option)
Draw 2D histograms errors.
ClassImp(THistPainter) THistPainter
Default constructor.
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:1075
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:101
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1608
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:497
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
static TString gStringMeanZ
static TString gStringKurtosisY
static TString gStringMeanY
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:3090
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
Float_t py
Definition: hprod.C:33
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:1568
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:381
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:311
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.
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
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
TFile * f
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
static TString gStringKurtosisX
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
const UInt_t kCannotRotate
static TString gStringStdDevY
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:340
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:2321
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:329
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
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.
void Class()
Definition: Class.C:29
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.
int d
Definition: tornado.py:11
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:2523
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
tuple np
Definition: multifit.py:30
Base class for several text objects.
Definition: TText.h:42
virtual void PaintColorLevels(Option_t *option)
Control function to draw a 2D histogram as a color plot.
TH2D * h2
Definition: fit2dHist.C:45
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:2563
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)
const Int_t kMAXCONTOUR
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
Float_t z[5]
Definition: Ifit.C:16
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:382
static TString gStringKurtosis
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
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:1618
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:106
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
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:1133
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
TThread * t[5]
Definition: threadsh1.C:13
float ymax
Definition: THbookFile.cxx:93
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:545
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
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
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:675
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:79
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
static TString gStringStdDevX
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
bool first
Definition: line3Dfit.C:48
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
tuple w
Definition: qtexample.py:51
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:1023
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:623
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:1182
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
The histogram painter class.
Definition: THistPainter.h:41
void AddText(TPaveText *pave, const char *datamember, Double_t value, const char *comment)
Definition: csgdemo.C:269
static TString gStringKurtosisZ
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:3077
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
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
static TString gStringEntries
double Double_t
Definition: RtypesCore.h:55
static TString gStringSkewnessX
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:962
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
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
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
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:47
tuple view
Definition: tornado.py:20
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:2801
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
static TString gStringIntegralBinWidth
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:176
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:352
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
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:557
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.
Float_t px
Definition: hprod.C:33
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
static TString gStringOverflow
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
Bool_t axis
Definition: geodemo.C:37
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
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
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
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:1162
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:183
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.
static TString gStringIntegral
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
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
TH1 * gCurrentHist
Int_t Nint(T x)
Definition: TMath.h:480
virtual void PadRange(Int_t rback)=0
Double_t ex[n]
Definition: legend1.C:17
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:342
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
static TString gStringMean
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
Hoption_t Hoption
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
static TString gStringStdDev
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
static TString gStringSkewnessY
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:70
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
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
static TString gStringMeanX
static TString gStringStdDevZ
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