Logo ROOT   6.12/07
Reference Guide
TGraphPainter.cxx
Go to the documentation of this file.
1 // @(#)root/histpainter:$Id: TGraphPainter.cxx,v 1.00
2 // Author: Olivier Couet
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "TGraphPainter.h"
14 #include "TMath.h"
15 #include "TGraph.h"
16 #include "TPolyLine.h"
17 #include "TPolyMarker.h"
18 #include "TVirtualPad.h"
19 #include "TView.h"
20 #include "TStyle.h"
21 #include "TH1.h"
22 #include "TF1.h"
23 #include "TPaveStats.h"
24 #include "TGaxis.h"
25 #include "TGraphAsymmErrors.h"
26 #include "TGraphBentErrors.h"
27 #include "TGraphPolargram.h"
28 #include "TGraphPolar.h"
29 #include "TGraphQQ.h"
30 #include "TLatex.h"
31 #include "TArrow.h"
32 #include "TFrame.h"
33 #include "TVirtualPadEditor.h"
34 
37 
39 
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 
43 /*! \class TGraphPainter
44  \ingroup Histpainter
45  \brief The graph painter class. Implements all graphs' drawing's options.
46 
47 - [Introduction](#GP00)
48 - [Graphs' plotting options](#GP01)
49 - [Exclusion graphs](#GP02)
50 - [Graphs with error bars](#GP03)
51  - [TGraphErrors](#GP03a)
52  - [TGraphAsymmErrors](#GP03b)
53  - [TGraphBentErrors](#GP03c)
54 - [TGraphPolar options](#GP04)
55 - [Colors automatically picked in palette](#GP05)
56 - [Reverse graphs' axis](#GP06)
57 - [Graphs in logarithmic scale](#GP07)
58 
59 
60 ### <a name="GP00"></a> Introduction
61 
62 Graphs are drawn via the painter `TGraphPainter` class. This class
63 implements techniques needed to display the various kind of
64 graphs i.e.: `TGraph`, `TGraphErrors`, `TGraphBentErrors` and `TGraphAsymmErrors`.
65 
66 To draw a graph `graph` it's enough to do:
67 
68  graph->Draw("AL");
69 
70 The option `AL` in the `Draw()` method means:
71 
72 1. The axis should be drawn (option `A`),
73 2. The graph should be drawn as a simple line (option `L`).
74 
75  By default a graph is drawn in the current pad in the current coordinate system.
76 To define a suitable coordinate system and draw the axis the option
77 `A` must be specified.
78 
79 `TGraphPainter` offers many options to paint the various kind of graphs.
80 
81 It is separated from the graph classes so that one can have graphs without the
82 graphics overhead, for example in a batch program.
83 
84 When a displayed graph is modified, there is no need to call `Draw()` again; the
85 image will be refreshed the next time the pad will be updated. A pad is updated
86 after one of these three actions:
87 
88 1. a carriage return on the ROOT command line,
89 2. a click inside the pad,
90 3. a call to `TPad::Update`.
91 
92 ### <a name="GP01"></a> Graphs' plotting options
93 Graphs can be drawn with the following options:
94 
95 | Option | Description |
96 |----------|-------------------------------------------------------------------|
97 | "A" | Axis are drawn around the graph |
98 | "I" | Combine with option 'A' it draws invisible axis |
99 | "L" | A simple polyline is drawn |
100 | "F" | A fill area is drawn ('CF' draw a smoothed fill area) |
101 | "C" | A smooth Curve is drawn |
102 | "*" | A Star is plotted at each point |
103 | "P" | The current marker is plotted at each point |
104 | "B" | A Bar chart is drawn |
105 | "1" | When a graph is drawn as a bar chart, this option makes the bars start from the bottom of the pad. By default they start at 0. |
106 | "X+" | The X-axis is drawn on the top side of the plot. |
107 | "Y+" | The Y-axis is drawn on the right side of the plot. |
108 | "PFC" | Palette Fill Color: graph's fill color is taken in the current palette. |
109 | "PLC" | Palette Line Color: graph's line color is taken in the current palette. |
110 | "PMC" | Palette Marker Color: graph's marker color is taken in the current palette. |
111 | "RX" | Reverse the X axis. |
112 | "RY" | Reverse the Y axis. |
113 
114 Drawing options can be combined. In the following example the graph
115 is drawn as a smooth curve (option "C") with markers (option "P") and
116 with axes (option "A").
117 
118 Begin_Macro(source)
119 {
120  auto c1 = new TCanvas("c1","c1",200,10,600,400);
121 
122  c1->SetFillColor(42);
123  c1->SetGrid();
124 
125  const Int_t n = 20;
126  Double_t x[n], y[n];
127  for (Int_t i=0;i<n;i++) {
128  x[i] = i*0.1;
129  y[i] = 10*sin(x[i]+0.2);
130  }
131  gr = new TGraph(n,x,y);
132  gr->SetLineColor(2);
133  gr->SetLineWidth(4);
134  gr->SetMarkerColor(4);
135  gr->SetMarkerSize(1.5);
136  gr->SetMarkerStyle(21);
137  gr->SetTitle("Option ACP example");
138  gr->GetXaxis()->SetTitle("X title");
139  gr->GetYaxis()->SetTitle("Y title");
140  gr->Draw("ACP");
141 
142  // TCanvas::Update() draws the frame, after which one can change it
143  c1->Update();
144  c1->GetFrame()->SetFillColor(21);
145  c1->GetFrame()->SetBorderSize(12);
146  c1->Modified();
147 }
148 End_Macro
149 
150 The following macro shows the option "B" usage. It can be combined with the
151 option "1".
152 
153 Begin_Macro(source)
154 {
155  auto c47 = new TCanvas("c47","c47",200,10,600,400);
156  c47->Divide(1,2);
157  const Int_t n = 20;
158  Double_t x[n], y[n];
159  for (Int_t i=0;i<n;i++) {
160  x[i] = i*0.1;
161  y[i] = 10*sin(x[i]+0.2)-6;
162  }
163  gr = new TGraph(n,x,y);
164  gr->SetFillColor(38);
165  c47->cd(1); gr->Draw("AB");
166  c47->cd(2); gr->Draw("AB1");
167 }
168 End_Macro
169 
170 ### <a name="GP02"></a> Exclusion graphs
171 
172 When a graph is painted with the option `C` or `L` it is
173 possible to draw a filled area on one side of the line. This is useful to show
174 exclusion zones.
175 
176 This drawing mode is activated when the absolute value of the graph line
177 width (set by `SetLineWidth()`) is greater than 99. In that
178 case the line width number is interpreted as:
179 
180  100*ff+ll = ffll
181 
182 - The two digits number `ll` represent the normal line width
183 - The two digits number `ff` represent the filled area width.
184 - The sign of "ffll" allows to flip the filled area from one side of the line to the other.
185 
186 The current fill area attributes are used to draw the hatched zone.
187 
188 Begin_Macro(source)
189 ../../../tutorials/graphs/exclusiongraph.C
190 End_Macro
191 
192 ### <a name="GP03"></a> Graphs with error bars
193 Three classes are available to handle graphs with error bars:
194 `TGraphErrors`, `TGraphAsymmErrors` and `TGraphBentErrors`.
195 The following drawing options are specific to graphs with error bars:
196 
197 | Option | Description |
198 |----------|-------------------------------------------------------------------|
199 | "Z" | Do not draw small horizontal and vertical lines the end of the error bars. Without "Z", the default is to draw these. |
200 | ">" | An arrow is drawn at the end of the error bars. The size of the arrow is set to 2/3 of the marker size. |
201 | \"\|>\" | A filled arrow is drawn at the end of the error bars. The size of the arrow is set to 2/3 of the marker size. |
202 | "X" | Do not draw error bars. By default, graph classes that have errors are drawn with the errors (TGraph itself has no errors, and so this option has no effect.) |
203 | \"\|\|\" | Draw only the small vertical/horizontal lines at the ends of the error bars, without drawing the bars themselves. This option is interesting to superimpose statistical-only errors on top of a graph with statistical+systematic errors. |
204 | "[]" | Does the same as option \"\|\|\" except that it draws additional marks at the ends of the small vertical/horizontal lines. It makes plots less ambiguous in case several graphs are drawn on the same picture. |
205 | "0" | By default, when a data point is outside the visible range along the Y axis, the error bars are not drawn. This option forces error bars' drawing for the data points outside the visible range along the Y axis (see example below). |
206 | "2" | Error rectangles are drawn. |
207 | "3" | A filled area is drawn through the end points of the vertical error bars. |
208 | "4" | A smoothed filled area is drawn through the end points of the vertical error bars. |
209 | "5" | Error rectangles are drawn like option "2". In addition the contour line around the boxes is drawn. This can be useful when boxes' fill colors are very light or in gray scale mode. |
210 
211 
212 `gStyle->SetErrorX(dx)` controls the size of the error along x.
213 `dx = 0` removes the error along x.
214 
215 `gStyle->SetEndErrorSize(np)` controls the size of the lines
216 at the end of the error bars (when option 1 is used).
217 By default `np=1`. (np represents the number of pixels).
218 
219 #### <a name="GP03a"></a> TGraphErrors
220 
221 A `TGraphErrors` is a `TGraph` with error bars. The errors are
222 defined along X and Y and are symmetric: The left and right errors are the same
223 along X and the bottom and up errors are the same along Y.
224 
225 Begin_Macro(source)
226 {
227  auto c4 = new TCanvas("c4","c4",200,10,600,400);
228  double x[] = {0, 1, 2, 3, 4};
229  double y[] = {0, 2, 4, 1, 3};
230  double ex[] = {0.1, 0.2, 0.3, 0.4, 0.5};
231  double ey[] = {1, 0.5, 1, 0.5, 1};
232  TGraphErrors* ge = new TGraphErrors(5, x, y, ex, ey);
233  ge->Draw("ap");
234 }
235 End_Macro
236 
237 The option "0" shows the error bars for data points outside range.
238 
239 Begin_Macro(source)
240 {
241  auto c48 = new TCanvas("c48","c48",200,10,600,400);
242  float x[] = {1,2,3};
243  float err_x[] = {0,0,0};
244  float err_y[] = {5,5,5};
245  float y[] = {1,4,9};
246  TGraphErrors tg(3,x,y,err_x,err_y);
247  c48->Divide(2,1);
248  c48->cd(1); gPad->DrawFrame(0,0,4,8); tg.Draw("PC");
249  c48->cd(2); gPad->DrawFrame(0,0,4,8); tg.Draw("0PC");
250 }
251 End_Macro
252 
253 The option "3" shows the errors as a band.
254 
255 Begin_Macro(source)
256 {
257  auto c41 = new TCanvas("c41","c41",200,10,600,400);
258  double x[] = {0, 1, 2, 3, 4};
259  double y[] = {0, 2, 4, 1, 3};
260  double ex[] = {0.1, 0.2, 0.3, 0.4, 0.5};
261  double ey[] = {1, 0.5, 1, 0.5, 1};
262  TGraphErrors* ge = new TGraphErrors(5, x, y, ex, ey);
263  ge->SetFillColor(4);
264  ge->SetFillStyle(3010);
265  ge->Draw("a3");
266 }
267 End_Macro
268 
269 The option "4" is similar to the option "3" except that the band
270 is smoothed. As the following picture shows, this option should be
271 used carefully because the smoothing algorithm may show some (huge)
272 "bouncing" effects. In some cases it looks nicer than option "3"
273 (because it is smooth) but it can be misleading.
274 
275 Begin_Macro(source)
276 {
277  auto c42 = new TCanvas("c42","c42",200,10,600,400);
278  double x[] = {0, 1, 2, 3, 4};
279  double y[] = {0, 2, 4, 1, 3};
280  double ex[] = {0.1, 0.2, 0.3, 0.4, 0.5};
281  double ey[] = {1, 0.5, 1, 0.5, 1};
282  TGraphErrors* ge = new TGraphErrors(5, x, y, ex, ey);
283  ge->SetFillColor(6);
284  ge->SetFillStyle(3005);
285  ge->Draw("a4");
286 }
287 End_Macro
288 
289 The following example shows how the option "[]" can be used to superimpose
290 systematic errors on top of a graph with statistical errors.
291 
292 Begin_Macro(source)
293 {
294  auto c43 = new TCanvas("c43","c43",200,10,600,400);
295  c43->DrawFrame(0., -0.5, 6., 2);
296 
297  double x[5] = {1, 2, 3, 4, 5};
298  double zero[5] = {0, 0, 0, 0, 0};
299 
300  // data set (1) with stat and sys errors
301  double py1[5] = {1.2, 1.15, 1.19, 0.9, 1.4};
302  double ey_stat1[5] = {0.2, 0.18, 0.17, 0.2, 0.4};
303  double ey_sys1[5] = {0.5, 0.71, 0.76, 0.5, 0.45};
304 
305  // data set (2) with stat and sys errors
306  double y2[5] = {0.25, 0.18, 0.29, 0.2, 0.21};
307  double ey_stat2[5] = {0.2, 0.18, 0.17, 0.2, 0.4};
308  double ey_sys2[5] = {0.63, 0.19, 0.7, 0.2, 0.7};
309 
310  // Now draw data set (1)
311 
312  // We first have to draw it only with the stat errors
313  TGraphErrors *graph1 = new TGraphErrors(5, x, py1, zero, ey_stat1);
314  graph1->SetMarkerStyle(20);
315  graph1->Draw("P");
316 
317  // Now we have to somehow depict the sys errors
318 
319  TGraphErrors *graph1_sys = new TGraphErrors(5, x, py1, zero, ey_sys1);
320  graph1_sys->Draw("[]");
321 
322  // Now draw data set (2)
323 
324  // We first have to draw it only with the stat errors
325  TGraphErrors *graph2 = new TGraphErrors(5, x, y2, zero, ey_stat2);
326  graph2->SetMarkerStyle(24);
327  graph2->Draw("P");
328 
329  // Now we have to somehow depict the sys errors
330 
331  TGraphErrors *graph2_sys = new TGraphErrors(5, x, y2, zero, ey_sys2);
332  graph2_sys->Draw("[]");
333 }
334 End_Macro
335 
336 #### <a name="GP03b"></a> TGraphAsymmErrors
337 A `TGraphAsymmErrors` is like a `TGraphErrors` but the errors
338 defined along X and Y are not symmetric: The left and right errors are
339 different along X and the bottom and up errors are different along Y.
340 
341 Begin_Macro(source)
342 {
343  auto c44 = new TCanvas("c44","c44",200,10,600,400);
344  double ax[] = {0, 1, 2, 3, 4};
345  double ay[] = {0, 2, 4, 1, 3};
346  double aexl[] = {0.1, 0.2, 0.3, 0.4, 0.5};
347  double aexh[] = {0.5, 0.4, 0.3, 0.2, 0.1};
348  double aeyl[] = {1, 0.5, 1, 0.5, 1};
349  double aeyh[] = {0.5, 1, 0.5, 1, 0.5};
350  TGraphAsymmErrors* gae = new TGraphAsymmErrors(5, ax, ay, aexl, aexh, aeyl, aeyh);
351  gae->SetFillColor(2);
352  gae->SetFillStyle(3001);
353  gae->Draw("a2");
354  gae->Draw("p");
355 }
356 End_Macro
357 
358 
359 #### <a name="GP03c"></a> TGraphBentErrors
360 A `TGraphBentErrors` is like a `TGraphAsymmErrors`.
361 An extra parameter allows to bend the error bars to better see them
362 when several graphs are drawn on the same plot.
363 
364 Begin_Macro(source)
365 {
366  auto c45 = new TCanvas("c45","c45",200,10,600,400);
367  const Int_t n = 10;
368  Double_t x[n] = {-0.22, 0.05, 0.25, 0.35, 0.5, 0.61,0.7,0.85,0.89,0.95};
369  Double_t y[n] = {1,2.9,5.6,7.4,9,9.6,8.7,6.3,4.5,1};
370  Double_t exl[n] = {.05,.1,.07,.07,.04,.05,.06,.07,.08,.05};
371  Double_t eyl[n] = {.8,.7,.6,.5,.4,.4,.5,.6,.7,.8};
372  Double_t exh[n] = {.02,.08,.05,.05,.03,.03,.04,.05,.06,.03};
373  Double_t eyh[n] = {.6,.5,.4,.3,.2,.2,.3,.4,.5,.6};
374  Double_t exld[n] = {.0,.0,.0,.0,.0,.0,.0,.0,.0,.0};
375  Double_t eyld[n] = {.0,.0,.05,.0,.0,.0,.0,.0,.0,.0};
376  Double_t exhd[n] = {.0,.0,.0,.0,.0,.0,.0,.0,.0,.0};
377  Double_t eyhd[n] = {.0,.0,.0,.0,.0,.0,.0,.0,.05,.0};
378  TGraphBentErrors *gr = new TGraphBentErrors(n,x,y,exl,exh,eyl,eyh,exld,exhd,eyld,eyhd);
379  gr->SetTitle("TGraphBentErrors Example");
380  gr->SetMarkerColor(4);
381  gr->SetMarkerStyle(21);
382  gr->Draw("ALP");
383 }
384 End_Macro
385 
386 
387 ### <a name="GP04"></a> TGraphPolar options
388 
389 The drawing options for the polar graphs are the following:
390 
391 | Option | Description |
392 |----------|-------------------------------------------------------------------|
393 | "O" | Polar labels are drawn orthogonally to the polargram radius. |
394 | "P" | Polymarker are drawn at each point position. |
395 | "E" | Draw error bars. |
396 | "F" | Draw fill area (closed polygon). |
397 | "A" | Force axis redrawing even if a polargram already exists. |
398 | "N" | Disable the display of the polar labels. |
399 
400 
401 Begin_Macro(source)
402 {
403  auto c46 = new TCanvas("c46","c46",500,500);
404  TGraphPolar * grP1 = new TGraphPolar();
405  grP1->SetTitle("TGraphPolar example");
406 
407  grP1->SetPoint(0, (1*TMath::Pi())/4., 0.05);
408  grP1->SetPoint(1, (2*TMath::Pi())/4., 0.10);
409  grP1->SetPoint(2, (3*TMath::Pi())/4., 0.15);
410  grP1->SetPoint(3, (4*TMath::Pi())/4., 0.20);
411  grP1->SetPoint(4, (5*TMath::Pi())/4., 0.25);
412  grP1->SetPoint(5, (6*TMath::Pi())/4., 0.30);
413  grP1->SetPoint(6, (7*TMath::Pi())/4., 0.35);
414  grP1->SetPoint(7, (8*TMath::Pi())/4., 0.40);
415 
416  grP1->SetMarkerStyle(20);
417  grP1->SetMarkerSize(1.);
418  grP1->SetMarkerColor(4);
419  grP1->SetLineColor(4);
420  grP1->Draw("ALP");
421 
422  // Update, otherwise GetPolargram returns 0
423  c46->Update();
424  grP1->GetPolargram()->SetToRadian();
425 }
426 End_Macro
427 
428 ### <a name="GP05"></a> Colors automatically picked in palette
429 
430 \since **ROOT version 6.09/01**
431 
432 When several graphs are painted in the same canvas or when a multi-graph is drawn,
433 it might be useful to have an easy and automatic way to choose
434 their color. The simplest way is to pick colors in the current active color
435 palette. Palette coloring for histogram is activated thanks to the options `PFC`
436 (Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
437 When one of these options is given to `TGraph::Draw` the graph get its color
438 from the current color palette defined by `gStyle->SetPalette(…)`. The color
439 is determined according to the number of objects having palette coloring in
440 the current pad.
441 
442 Begin_Macro(source)
443 ../../../tutorials/graphs/graphpalettecolor.C
444 End_Macro
445 
446 Begin_Macro(source)
447 ../../../tutorials/graphs/multigraphpalettecolor.C
448 End_Macro
449 
450 ### <a name="GP06"></a> Reverse graphs' axis
451 
452 \since **ROOT version 6.09/03**
453 
454 When a TGraph is drawn, the X-axis is drawn with increasing values from left to
455 right and the Y-axis from bottom to top. The two options `RX` and `RY` allow to
456 change this order. The option `RX` allows to draw the X-axis with increasing values
457 from right to left and the `RY` option allows to draw the Y-axis with increasing
458 values from top to bottom. The following example illustrate how to use these options.
459 
460 Begin_Macro(source)
461 {
462  auto *c = new TCanvas();
463  c->Divide(2,1);
464  auto *g = new TGraphErrors();
465  g->SetTitle("Simple Graph");
466 
467  g->SetPoint(0,-4,-3);
468  g->SetPoint(1,1,1);
469  g->SetPoint(2,2,1);
470  g->SetPoint(3,3,4);
471  g->SetPoint(4,5,5);
472 
473  g->SetPointError(0,1.,2.);
474  g->SetPointError(1,2,1);
475  g->SetPointError(2,2,3);
476  g->SetPointError(3,3,2);
477  g->SetPointError(4,4,5);
478 
479  g->GetXaxis()->SetNdivisions(520);
480 
481  g->SetMarkerStyle(21);
482  c->cd(1); gPad->SetGrid(1,1);
483  g->Draw("APL");
484 
485  c->cd(2); gPad->SetGrid(1,1);
486  g->Draw("A RX RY PL");
487 }
488 End_Macro
489 
490 ### <a name="GP07"></a> Graphs in logarithmic scale
491 
492 Like histograms, graphs can be drawn in logarithmic scale along X and Y. When
493 a pad is set to logarithmic scale with TPad::SetLogx() and/or with TPad::SetLogy()
494 the points building the graph are converted into logarithmic scale. But **only** the
495 points not the lines connecting them which stay linear. This can be clearly seen
496 on the following example:
497 
498 Begin_Macro(source)
499 {
500  // A graph with 3 points
501  Double_t xmin = 750.;
502  Double_t xmax = 1000;
503  auto g = new TGraph(3);
504  g->SetPoint(0,xmin,0.1);
505  g->SetPoint(1,845,0.06504);
506  g->SetPoint(2,xmax,0.008);
507 
508  // The same graph with n points
509  Int_t n = 10000;
510  Double_t dx = (xmax-xmin)/n;
511  Double_t x = xmin;
512  TGraph*g2 = new TGraph();
513  for (Int_t i=0; i<n; i++) {
514  g2->SetPoint(i, x, g->Eval(x));
515  x = x + dx;
516  }
517 
518  auto cv = new TCanvas("cv","cv",800,600);
519  cv->SetLogy();
520  cv->SetGridx();
521  cv->SetGridy();
522  g->Draw("AL*");
523 
524  g2->SetMarkerColor(kRed);
525  g2->SetMarkerStyle(1);
526  g2->Draw("P");
527 }
528 
529 End_Macro
530 */
531 
532 
533 ////////////////////////////////////////////////////////////////////////////////
534 /// Default constructor
535 
537 {
538 }
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Destructor.
543 
545 {
546 }
548 
549 ////////////////////////////////////////////////////////////////////////////////
550 /// Compute the logarithm of global variables `gxwork` and `gywork`
551 /// according to the value of Options and put the results in the global
552 /// variables `gxworkl` and `gyworkl`.
553 ///
554 /// npoints : Number of points in gxwork and in gywork.
555 ///
556 /// - opt = 1 ComputeLogs is called from PaintGrapHist
557 /// - opt = 0 ComputeLogs is called from PaintGraph
558 
559 void TGraphPainter::ComputeLogs(Int_t npoints, Int_t opt)
560 {
561 
563  Int_t i;
564  memcpy(gxworkl,gxwork,npoints*8);
565  memcpy(gyworkl,gywork,npoints*8);
566  if (gPad->GetLogx()) {
567  for (i=0;i<npoints;i++) {
568  if (gxworkl[i] > 0) gxworkl[i] = TMath::Log10(gxworkl[i]);
569  else gxworkl[i] = gPad->GetX1();
570  }
571  }
572  if (!opt && gPad->GetLogy()) {
573  for (i=0;i<npoints;i++) {
574  if (gyworkl[i] > 0) gyworkl[i] = TMath::Log10(gyworkl[i]);
575  else gyworkl[i] = gPad->GetY1();
576  }
577  }
578 }
579 
580 
581 ////////////////////////////////////////////////////////////////////////////////
582 /// Compute distance from point px,py to a graph.
583 ///
584 /// Compute the closest distance of approach from point px,py to this line.
585 /// The distance is computed in pixels units.
586 
588 {
589 
590  // Are we on the axis?
591  Int_t distance;
592  if (theGraph->GetHistogram()) {
593  distance = theGraph->GetHistogram()->DistancetoPrimitive(px,py);
594  if (distance <= 5) return distance;
595  }
596 
597  // Somewhere on the graph points?
598  const Int_t big = 9999;
599  const Int_t kMaxDiff = 10;
600  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
601  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
602  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
603  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
604 
605  // return if point is not in the graph area
606  if (px <= puxmin) return big;
607  if (py >= puymin) return big;
608  if (px >= puxmax) return big;
609  if (py <= puymax) return big;
610 
611  // check if point is near one of the graph points
612  Int_t i, pxp, pyp, d;
613  distance = big;
614 
615  Int_t theNpoints = theGraph->GetN();
616  Double_t *theX, *theY;
617  if (theGraph->InheritsFrom(TGraphPolar::Class())) {
618  TGraphPolar *theGraphPolar = (TGraphPolar*) theGraph;
619  theX = theGraphPolar->GetXpol();
620  theY = theGraphPolar->GetYpol();
621  } else {
622  theX = theGraph->GetX();
623  theY = theGraph->GetY();
624  }
625 
626  for (i=0;i<theNpoints;i++) {
627  pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
628  pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
629  d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
630  if (d < distance) distance = d;
631  }
632  if (distance < kMaxDiff) return distance;
633 
634  for (i=0;i<theNpoints-1;i++) {
635  TAttLine l;
636  d = l.DistancetoLine(px, py, gPad->XtoPad(theX[i]), gPad->YtoPad(theY[i]), gPad->XtoPad(theX[i+1]), gPad->YtoPad(theY[i+1]));
637  if (d < distance) distance = d;
638  }
639 
640  // If graph has been drawn with the fill area option, check if we are inside
641  TString drawOption = theGraph->GetDrawOption();
642  drawOption.ToLower();
643  if (drawOption.Contains("f")) {
644  Double_t xp = gPad->AbsPixeltoX(px); xp = gPad->PadtoX(xp);
645  Double_t yp = gPad->AbsPixeltoY(py); yp = gPad->PadtoY(yp);
646  if (TMath::IsInside(xp,yp,theNpoints,theX,theY) != 0) distance = 1;
647  }
648 
649  // Loop on the list of associated functions and user objects
650  TObject *f;
651  TList *functions = theGraph->GetListOfFunctions();
652  TIter next(functions);
653  while ((f = (TObject*) next())) {
654  Int_t dist;
655  if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
656  else dist = f->DistancetoPrimitive(px,py);
657  if (dist < kMaxDiff) {
658  gPad->SetSelected(f);
659  return 0; //must be o and not dist in case of TMultiGraph
660  }
661  }
662 
663  return distance;
664 }
665 
666 
667 ////////////////////////////////////////////////////////////////////////////////
668 /// Display a panel with all histogram drawing options.
669 
671 {
672 
673  if (!gPad) {
674  Error("DrawPanel", "need to draw graph first");
675  return;
676  }
678  editor->Show();
679  gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
680  (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)theGraph));
681 }
682 
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Execute action corresponding to one event.
686 ///
687 /// This member function is called when a graph is clicked with the locator.
688 ///
689 /// If the left mouse button is clicked on one of the line end points, this point
690 /// follows the cursor until button is released.
691 ///
692 /// If the middle mouse button clicked, the line is moved parallel to itself
693 /// until the button is released.
694 
695 void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, Int_t py)
696 {
697 
698  if (!gPad) return;
699 
700  Int_t i, d;
701  Double_t xmin, xmax, ymin, ymax, dx, dy, dxr, dyr;
702  const Int_t kMaxDiff = 10;//3;
703  static Bool_t middle, badcase;
704  static Int_t ipoint, pxp, pyp;
705  static Int_t px1,px2,py1,py2;
706  static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
707  static Int_t dpx, dpy;
708  static Int_t *x=0, *y=0;
709  Bool_t opaque = gPad->OpaqueMoving();
710 
711  if (!theGraph->IsEditable() || theGraph->InheritsFrom(TGraphPolar::Class())) {
712  gPad->SetCursor(kHand);
713  return;
714  }
715  if (!gPad->IsEditable()) return;
716  Int_t theNpoints = theGraph->GetN();
717  Double_t *theX = theGraph->GetX();
718  Double_t *theY = theGraph->GetY();
719 
720  switch (event) {
721 
722  case kButton1Down:
723  badcase = kFALSE;
724  gVirtualX->SetLineColor(-1);
725  theGraph->TAttLine::Modify(); //Change line attributes only if necessary
726  px1 = gPad->XtoAbsPixel(gPad->GetX1());
727  py1 = gPad->YtoAbsPixel(gPad->GetY1());
728  px2 = gPad->XtoAbsPixel(gPad->GetX2());
729  py2 = gPad->YtoAbsPixel(gPad->GetY2());
730  ipoint = -1;
731 
732 
733  if (x || y) break;
734  x = new Int_t[theNpoints+1];
735  y = new Int_t[theNpoints+1];
736  for (i=0;i<theNpoints;i++) {
737  pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
738  pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
739  if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
740  pyp < -kMaxPixel || pyp >= kMaxPixel) {
741  badcase = kTRUE;
742  continue;
743  }
744  if (!opaque) {
745  gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
746  gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
747  gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
748  gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
749  }
750  x[i] = pxp;
751  y[i] = pyp;
752  d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
753  if (d < kMaxDiff) ipoint =i;
754  }
755  dpx = 0;
756  dpy = 0;
757  pxold = px;
758  pyold = py;
759  if (ipoint < 0) return;
760  if (ipoint == 0) {
761  px1old = 0;
762  py1old = 0;
763  px2old = gPad->XtoAbsPixel(theX[1]);
764  py2old = gPad->YtoAbsPixel(theY[1]);
765  } else if (ipoint == theNpoints-1) {
766  px1old = gPad->XtoAbsPixel(gPad->XtoPad(theX[theNpoints-2]));
767  py1old = gPad->YtoAbsPixel(gPad->YtoPad(theY[theNpoints-2]));
768  px2old = 0;
769  py2old = 0;
770  } else {
771  px1old = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint-1]));
772  py1old = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint-1]));
773  px2old = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint+1]));
774  py2old = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint+1]));
775  }
776  pxold = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint]));
777  pyold = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint]));
778 
779  break;
780 
781 
782  case kMouseMotion:
783 
784  middle = kTRUE;
785  for (i=0;i<theNpoints;i++) {
786  pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
787  pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
788  d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
789  if (d < kMaxDiff) middle = kFALSE;
790  }
791 
792 
793  // check if point is close to an axis
794  if (middle) gPad->SetCursor(kMove);
795  else gPad->SetCursor(kHand);
796  break;
797 
798  case kButton1Motion:
799  if (!opaque) {
800  if (middle) {
801  for(i=0;i<theNpoints-1;i++) {
802  gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy);
803  pxp = x[i]+dpx;
804  pyp = y[i]+dpy;
805  if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
806  pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
807  gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
808  gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
809  gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
810  gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
811  }
812  pxp = x[theNpoints-1]+dpx;
813  pyp = y[theNpoints-1]+dpy;
814  gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
815  gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
816  gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
817  gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
818  dpx += px - pxold;
819  dpy += py - pyold;
820  pxold = px;
821  pyold = py;
822  for(i=0;i<theNpoints-1;i++) {
823  gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy);
824  pxp = x[i]+dpx;
825  pyp = y[i]+dpy;
826  if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
827  pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
828  gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
829  gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
830  gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
831  gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
832  }
833  pxp = x[theNpoints-1]+dpx;
834  pyp = y[theNpoints-1]+dpy;
835  gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
836  gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
837  gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
838  gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
839  } else {
840  if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold);
841  if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old);
842  gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4);
843  gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4);
844  gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4);
845  gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4);
846  pxold = px;
847  pxold = TMath::Max(pxold, px1);
848  pxold = TMath::Min(pxold, px2);
849  pyold = py;
850  pyold = TMath::Max(pyold, py2);
851  pyold = TMath::Min(pyold, py1);
852  if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold);
853  if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old);
854  gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4);
855  gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4);
856  gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4);
857  gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4);
858  }
859  } else {
860  xmin = gPad->GetUxmin();
861  xmax = gPad->GetUxmax();
862  ymin = gPad->GetUymin();
863  ymax = gPad->GetUymax();
864  dx = xmax-xmin;
865  dy = ymax-ymin;
866  dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
867  dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
868 
869  if (theGraph->GetHistogram()) {
870  // Range() could change the size of the pad pixmap and therefore should
871  // be called before the other paint routines
872  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
873  ymin - dyr*gPad->GetBottomMargin(),
874  xmax + dxr*gPad->GetRightMargin(),
875  ymax + dyr*gPad->GetTopMargin());
876  gPad->RangeAxis(xmin, ymin, xmax, ymax);
877  }
878  if (middle) {
879  dpx += px - pxold;
880  dpy += py - pyold;
881  pxold = px;
882  pyold = py;
883  for(i=0;i<theNpoints;i++) {
884  if (badcase) continue; //do not update if big zoom and points moved
885  if (x) theX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx));
886  if (y) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy));
887  }
888  } else {
889  pxold = px;
890  pxold = TMath::Max(pxold, px1);
891  pxold = TMath::Min(pxold, px2);
892  pyold = py;
893  pyold = TMath::Max(pyold, py2);
894  pyold = TMath::Min(pyold, py1);
895  theX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold));
896  theY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold));
897  if (theGraph->InheritsFrom("TCutG")) {
898  //make sure first and last point are the same
899  if (ipoint == 0) {
900  theX[theNpoints-1] = theX[0];
901  theY[theNpoints-1] = theY[0];
902  }
903  if (ipoint == theNpoints-1) {
904  theX[0] = theX[theNpoints-1];
905  theY[0] = theY[theNpoints-1];
906  }
907  }
908  }
909  badcase = kFALSE;
910  gPad->Modified(kTRUE);
911  //gPad->Update();
912  }
913  break;
914 
915  case kButton1Up:
916 
917  if (gROOT->IsEscaped()) {
918  gROOT->SetEscape(kFALSE);
919  delete [] x; x = 0;
920  delete [] y; y = 0;
921  break;
922  }
923 
924  // Compute x,y range
925  xmin = gPad->GetUxmin();
926  xmax = gPad->GetUxmax();
927  ymin = gPad->GetUymin();
928  ymax = gPad->GetUymax();
929  dx = xmax-xmin;
930  dy = ymax-ymin;
931  dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
932  dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
933 
934  if (theGraph->GetHistogram()) {
935  // Range() could change the size of the pad pixmap and therefore should
936  // be called before the other paint routines
937  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
938  ymin - dyr*gPad->GetBottomMargin(),
939  xmax + dxr*gPad->GetRightMargin(),
940  ymax + dyr*gPad->GetTopMargin());
941  gPad->RangeAxis(xmin, ymin, xmax, ymax);
942  }
943  if (middle) {
944  for(i=0;i<theNpoints;i++) {
945  if (badcase) continue; //do not update if big zoom and points moved
946  if (x) theX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx));
947  if (y) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy));
948  }
949  } else {
950  theX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold));
951  theY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold));
952  if (theGraph->InheritsFrom("TCutG")) {
953  //make sure first and last point are the same
954  if (ipoint == 0) {
955  theX[theNpoints-1] = theX[0];
956  theY[theNpoints-1] = theY[0];
957  }
958  if (ipoint == theNpoints-1) {
959  theX[0] = theX[theNpoints-1];
960  theY[0] = theY[theNpoints-1];
961  }
962  }
963  }
964  badcase = kFALSE;
965  delete [] x; x = 0;
966  delete [] y; y = 0;
967  gPad->Modified(kTRUE);
968  gVirtualX->SetLineColor(-1);
969  }
970 }
971 
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 
975 char *TGraphPainter::GetObjectInfoHelper(TGraph * /*theGraph*/, Int_t /*px*/, Int_t /*py*/) const
976 {
977  return (char*)"";
978 }
979 
980 
981 ////////////////////////////////////////////////////////////////////////////////
982 /// Paint a any kind of TGraph
983 
984 void TGraphPainter::PaintHelper(TGraph *theGraph, Option_t *option)
985 {
986 
987  char chopt[80];
988  strlcpy(chopt,option,80);
989 
990  if (theGraph) {
991  char *l1 = strstr(chopt,"pfc"); // Automatic Fill Color
992  char *l2 = strstr(chopt,"plc"); // Automatic Line Color
993  char *l3 = strstr(chopt,"pmc"); // Automatic Marker Color
994  if (l1 || l2 || l3) {
995  Int_t i = gPad->NextPaletteColor();
996  if (l1) {strncpy(l1," ",3); theGraph->SetFillColor(i);}
997  if (l2) {strncpy(l2," ",3); theGraph->SetLineColor(i);}
998  if (l3) {strncpy(l3," ",3); theGraph->SetMarkerColor(i);}
999  }
1000 
1002 
1003  char *l4 = strstr(chopt,"rx"); // Reverse graph along X axis
1004  char *l5 = strstr(chopt,"ry"); // Reverse graph along Y axis
1005 
1006  if (l4 || l5) {
1007  PaintGraphReverse(theGraph,chopt);
1008  return;
1009  }
1010 
1011  if (theGraph->InheritsFrom(TGraphBentErrors::Class())) {
1012  PaintGraphBentErrors(theGraph,chopt);
1013  } else if (theGraph->InheritsFrom(TGraphQQ::Class())) {
1014  PaintGraphQQ(theGraph,chopt);
1015  } else if (theGraph->InheritsFrom(TGraphAsymmErrors::Class())) {
1016  PaintGraphAsymmErrors(theGraph,chopt);
1017  } else if (theGraph->InheritsFrom(TGraphErrors::Class())) {
1018  if (theGraph->InheritsFrom(TGraphPolar::Class())) {
1019  PaintGraphPolar(theGraph,chopt);
1020  } else {
1021  PaintGraphErrors(theGraph,chopt);
1022  }
1023  } else {
1024  PaintGraphSimple(theGraph,chopt);
1025  }
1026  }
1027 }
1028 
1029 
1030 ////////////////////////////////////////////////////////////////////////////////
1031 /// [Control function to draw a graph.]($GP01)
1032 
1033 void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
1034 {
1035 
1036  if (theGraph->InheritsFrom("TGraphPolar"))
1037  gPad->PushSelectableObject(theGraph);
1038 
1039  Int_t optionLine , optionAxis , optionCurve , optionStar , optionMark;
1040  Int_t optionBar , optionR , optionOne , optionE;
1041  Int_t optionFill , optionZ , optionCurveFill, optionIAxis;
1042  Int_t i, npt, nloop;
1043  Int_t drawtype=0;
1044  Double_t xlow, xhigh, ylow, yhigh;
1045  Double_t barxmin, barxmax, barymin, barymax;
1046  Double_t uxmin, uxmax;
1047  Double_t x1, xn, y1, yn;
1048  Double_t dbar, bdelta;
1049  Int_t theNpoints = theGraph->GetN();
1050 
1051  if (npoints <= 0) {
1052  Error("PaintGraph", "illegal number of points (%d)", npoints);
1053  return;
1054  }
1055  TString opt = chopt;
1056  opt.ToUpper();
1057  opt.ReplaceAll("SAME","");
1058 
1059  if (opt.Contains("L")) optionLine = 1; else optionLine = 0;
1060  if (opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
1061  if (opt.Contains("C")) optionCurve = 1; else optionCurve = 0;
1062  if (opt.Contains("*")) optionStar = 1; else optionStar = 0;
1063  if (opt.Contains("P")) optionMark = 1; else optionMark = 0;
1064  if (opt.Contains("B")) optionBar = 1; else optionBar = 0;
1065  if (opt.Contains("R")) optionR = 1; else optionR = 0;
1066  if (opt.Contains("1")) optionOne = 1; else optionOne = 0;
1067  if (opt.Contains("F")) optionFill = 1; else optionFill = 0;
1068  if (opt.Contains("I")) optionIAxis = 1; else optionIAxis = 0;
1069  if (opt.Contains("2") || opt.Contains("3") ||
1070  opt.Contains("4") || opt.Contains("5")) optionE = 1; else optionE = 0;
1071  optionZ = 0;
1072 
1073  // If no "drawing" option is selected and if chopt<>' ' nothing is done.
1074  if (optionLine+optionFill+optionCurve+optionStar+optionMark+optionBar+optionE == 0) {
1075  if (!chopt[0]) optionLine=1;
1076  else return;
1077  }
1078 
1079  if (optionStar) theGraph->SetMarkerStyle(3);
1080 
1081  optionCurveFill = 0;
1082  if (optionCurve && optionFill) {
1083  optionCurveFill = 1;
1084  optionFill = 0;
1085  }
1086 
1087  // Draw the Axis.
1088  Double_t rwxmin,rwxmax, rwymin, rwymax, maximum, minimum, dx, dy;
1089  if (optionAxis) {
1090  if (theGraph->GetHistogram()) {
1091  rwxmin = gPad->GetUxmin();
1092  rwxmax = gPad->GetUxmax();
1093  rwymin = gPad->GetUymin();
1094  rwymax = gPad->GetUymax();
1095  minimum = theGraph->GetHistogram()->GetMinimumStored();
1096  maximum = theGraph->GetHistogram()->GetMaximumStored();
1097  if (minimum == -1111) { //this can happen after unzooming
1098  minimum = theGraph->GetHistogram()->GetYaxis()->GetXmin();
1099  theGraph->GetHistogram()->SetMinimum(minimum);
1100  }
1101  if (maximum == -1111) {
1102  maximum = theGraph->GetHistogram()->GetYaxis()->GetXmax();
1103  theGraph->GetHistogram()->SetMaximum(maximum);
1104  }
1105  uxmin = gPad->PadtoX(rwxmin);
1106  uxmax = gPad->PadtoX(rwxmax);
1107  } else {
1108 
1109  theGraph->ComputeRange(rwxmin, rwymin, rwxmax, rwymax); //this is redefined in TGraphErrors
1110 
1111  if (rwxmin == rwxmax) rwxmax += 1.;
1112  if (rwymin == rwymax) rwymax += 1.;
1113  dx = 0.1*(rwxmax-rwxmin);
1114  dy = 0.1*(rwymax-rwymin);
1115  uxmin = rwxmin - dx;
1116  uxmax = rwxmax + dx;
1117  minimum = rwymin - dy;
1118  maximum = rwymax + dy;
1119  }
1120  if (theGraph->GetMinimum() != -1111) rwymin = minimum = theGraph->GetMinimum();
1121  if (theGraph->GetMaximum() != -1111) rwymax = maximum = theGraph->GetMaximum();
1122  if (uxmin < 0 && rwxmin >= 0) uxmin = 0.9*rwxmin;
1123  if (uxmax > 0 && rwxmax <= 0) {
1124  if (gPad->GetLogx()) uxmax = 1.1*rwxmax;
1125  else uxmax = 0;
1126  }
1127  if (minimum < 0 && rwymin >= 0) minimum = 0.9*rwymin;
1128  if (maximum > 0 && rwymax <= 0) {
1129  //if(gPad->GetLogy()) maximum = 1.1*rwymax;
1130  //else maximum = 0;
1131  }
1132  if (minimum <= 0 && gPad->GetLogy()) minimum = 0.001*maximum;
1133  if (uxmin <= 0 && gPad->GetLogx()) {
1134  if (uxmax > 1000) uxmin = 1;
1135  else uxmin = 0.001*uxmax;
1136  }
1137  rwymin = minimum;
1138  rwymax = maximum;
1139 
1140  // Create a temporary histogram and fill each bin with the
1141  // function value.
1142  char chopth[8] = " ";
1143  if (strstr(chopt,"x+")) strncat(chopth, "x+",2);
1144  if (strstr(chopt,"y+")) strncat(chopth, "y+",2);
1145  if (optionIAxis) strncat(chopth, "A",1);
1146  if (!theGraph->GetHistogram()) {
1147  // the graph is created with at least as many bins as there are
1148  // points to permit zooming on the full range.
1149  rwxmin = uxmin;
1150  rwxmax = uxmax;
1151  npt = 100;
1152  if (theNpoints > npt) npt = theNpoints;
1153  TH1F *h = new TH1F(Form("%s_h",GetName()),GetTitle(),npt,rwxmin,rwxmax);
1154  theGraph->SetHistogram(h);
1155  if (!theGraph->GetHistogram()) return;
1156  theGraph->GetHistogram()->SetMinimum(rwymin);
1157  theGraph->GetHistogram()->SetMaximum(rwymax);
1158  theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
1159  theGraph->GetHistogram()->SetBit(TH1::kNoStats);
1160  theGraph->GetHistogram()->SetDirectory(0);
1161  theGraph->GetHistogram()->Paint(chopth); // Draw histogram axis, title and grid
1162  } else {
1163  if (gPad->GetLogy()) {
1164  theGraph->GetHistogram()->SetMinimum(rwymin);
1165  theGraph->GetHistogram()->SetMaximum(rwymax);
1166  theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
1167  }
1168  theGraph->GetHistogram()->Paint(chopth); // Draw histogram axis, title and grid
1169  }
1170  }
1171 
1172  // Set Clipping option
1173  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
1174 
1175  TF1 *fit = 0;
1176  TList *functions = theGraph->GetListOfFunctions();
1177  TObject *f;
1178  if (functions) {
1179  f = (TF1*)functions->First();
1180  if (f) {
1181  if (f->InheritsFrom(TF1::Class())) fit = (TF1*)f;
1182  }
1183  TIter next(functions);
1184  while ((f = (TObject*) next())) {
1185  if (f->InheritsFrom(TF1::Class())) {
1186  fit = (TF1*)f;
1187  break;
1188  }
1189  }
1190  }
1191  if (fit) PaintStats(theGraph, fit);
1192 
1193  rwxmin = gPad->GetUxmin();
1194  rwxmax = gPad->GetUxmax();
1195  rwymin = gPad->GetUymin();
1196  rwymax = gPad->GetUymax();
1197  uxmin = gPad->PadtoX(rwxmin);
1198  uxmax = gPad->PadtoX(rwxmax);
1199  if (theGraph->GetHistogram() && !theGraph->InheritsFrom("TGraphPolar")) {
1200  maximum = theGraph->GetHistogram()->GetMaximum();
1201  minimum = theGraph->GetHistogram()->GetMinimum();
1202  } else {
1203  maximum = gPad->PadtoY(rwymax);
1204  minimum = gPad->PadtoY(rwymin);
1205  }
1206 
1207  // Set attributes
1208  theGraph->TAttLine::Modify();
1209  theGraph->TAttFill::Modify();
1210  theGraph->TAttMarker::Modify();
1211 
1212  // Draw the graph with a polyline or a fill area
1213  gxwork = new Double_t[2*npoints+10];
1214  gywork = new Double_t[2*npoints+10];
1215  gxworkl = new Double_t[2*npoints+10];
1216  gyworkl = new Double_t[2*npoints+10];
1217 
1218  if (optionLine || optionFill) {
1219  x1 = x[0];
1220  xn = x[npoints-1];
1221  y1 = y[0];
1222  yn = y[npoints-1];
1223  nloop = npoints;
1224  if (optionFill && (xn != x1 || yn != y1)) nloop++;
1225  npt = 0;
1226  for (i=1;i<=nloop;i++) {
1227  if (i > npoints) {
1228  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1229  } else {
1230  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1231  npt++;
1232  }
1233  if (i == nloop) {
1234  ComputeLogs(npt, optionZ);
1235  Int_t bord = gStyle->GetDrawBorder();
1236  if (optionR) {
1237  if (optionFill) {
1238  gPad->PaintFillArea(npt,gyworkl,gxworkl);
1239  if (bord) gPad->PaintPolyLine(npt,gyworkl,gxworkl);
1240  }
1241  if (optionLine) {
1242  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gyworkl, gxworkl);
1243  gPad->PaintPolyLine(npt,gyworkl,gxworkl);
1244  }
1245  } else {
1246  if (optionFill) {
1247  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1248  if (bord) gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1249  }
1250  if (optionLine) {
1251  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gxworkl, gyworkl);
1252  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1253  }
1254  }
1255  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1256  npt = 1;
1257  }
1258  }
1259  }
1260 
1261  // Draw the graph with a smooth Curve. Smoothing via Smooth
1262  if (optionCurve) {
1263  x1 = x[0];
1264  xn = x[npoints-1];
1265  y1 = y[0];
1266  yn = y[npoints-1];
1267  drawtype = 1;
1268  nloop = npoints;
1269  if (optionCurveFill) {
1270  drawtype += 1000;
1271  if (xn != x1 || yn != y1) nloop++;
1272  }
1273  if (!optionR) {
1274  npt = 0;
1275  for (i=1;i<=nloop;i++) {
1276  if (i > npoints) {
1277  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1278  } else {
1279  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1280  npt++;
1281  }
1282  ComputeLogs(npt, optionZ);
1283  if (gyworkl[npt-1] < rwymin || gyworkl[npt-1] > rwymax) {
1284  if (npt > 2) {
1285  ComputeLogs(npt, optionZ);
1286  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1287  }
1288  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1289  npt=1;
1290  continue;
1291  }
1292  }
1293  if (npt > 1) {
1294  ComputeLogs(npt, optionZ);
1295  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1296  }
1297  } else {
1298  drawtype += 10;
1299  npt = 0;
1300  for (i=1;i<=nloop;i++) {
1301  if (i > npoints) {
1302  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1303  } else {
1304  if (y[i-1] < minimum || y[i-1] > maximum) continue;
1305  if (x[i-1] < uxmin || x[i-1] > uxmax) continue;
1306  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1307  npt++;
1308  }
1309  ComputeLogs(npt, optionZ);
1310  if (gxworkl[npt-1] < rwxmin || gxworkl[npt-1] > rwxmax) {
1311  if (npt > 2) {
1312  ComputeLogs(npt, optionZ);
1313  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1314  }
1315  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1316  npt=1;
1317  continue;
1318  }
1319  }
1320  if (npt > 1) {
1321  ComputeLogs(npt, optionZ);
1322  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1323  }
1324  }
1325  }
1326 
1327  // Draw the graph with a '*' on every points
1328  if (optionStar) {
1329  theGraph->SetMarkerStyle(3);
1330  npt = 0;
1331  for (i=1;i<=npoints;i++) {
1332  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1333  npt++;
1334  if (i == npoints) {
1335  ComputeLogs(npt, optionZ);
1336  if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
1337  else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
1338  npt = 0;
1339  }
1340  }
1341  }
1342 
1343  // Draw the graph with the current polymarker on every points
1344  if (optionMark) {
1345  npt = 0;
1346  for (i=1;i<=npoints;i++) {
1347  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1348  npt++;
1349  if (i == npoints) {
1350  ComputeLogs(npt, optionZ);
1351  if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
1352  else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
1353  npt = 0;
1354  }
1355  }
1356  }
1357 
1358  // Draw the graph as a bar chart
1359  if (optionBar) {
1360  if (!optionR) {
1361  barxmin = x[0];
1362  barxmax = x[0];
1363  for (i=1;i<npoints;i++) {
1364  if (x[i] < barxmin) barxmin = x[i];
1365  if (x[i] > barxmax) barxmax = x[i];
1366  }
1367  bdelta = (barxmax-barxmin)/Double_t(npoints);
1368  } else {
1369  barymin = y[0];
1370  barymax = y[0];
1371  for (i=1;i<npoints;i++) {
1372  if (y[i] < barymin) barymin = y[i];
1373  if (y[i] > barymax) barymax = y[i];
1374  }
1375  bdelta = (barymax-barymin)/Double_t(npoints);
1376  }
1377  dbar = 0.5*bdelta*gStyle->GetBarWidth();
1378  if (!optionR) {
1379  for (i=1;i<=npoints;i++) {
1380  xlow = x[i-1] - dbar;
1381  xhigh = x[i-1] + dbar;
1382  yhigh = y[i-1];
1383  if (xlow < uxmin) xlow = uxmin;
1384  if (xhigh > uxmax) xhigh = uxmax;
1385  if (!optionOne) ylow = TMath::Max((Double_t)0,gPad->GetUymin());
1386  else ylow = gPad->GetUymin();
1387  gxwork[0] = xlow;
1388  gywork[0] = ylow;
1389  gxwork[1] = xhigh;
1390  gywork[1] = yhigh;
1391  ComputeLogs(2, optionZ);
1392  if (gyworkl[0] < gPad->GetUymin()) gyworkl[0] = gPad->GetUymin();
1393  if (gyworkl[1] < gPad->GetUymin()) continue;
1394  if (gyworkl[1] > gPad->GetUymax()) gyworkl[1] = gPad->GetUymax();
1395  if (gyworkl[0] > gPad->GetUymax()) continue;
1396 
1397  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
1398  }
1399  } else {
1400  for (i=1;i<=npoints;i++) {
1401  xhigh = x[i-1];
1402  ylow = y[i-1] - dbar;
1403  yhigh = y[i-1] + dbar;
1404  xlow = TMath::Max((Double_t)0, gPad->GetUxmin());
1405  gxwork[0] = xlow;
1406  gywork[0] = ylow;
1407  gxwork[1] = xhigh;
1408  gywork[1] = yhigh;
1409  ComputeLogs(2, optionZ);
1410  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
1411  }
1412  }
1413  }
1414  gPad->ResetBit(TGraph::kClipFrame);
1415 
1416  delete [] gxwork;
1417  delete [] gywork;
1418  delete [] gxworkl;
1419  delete [] gyworkl;
1420 }
1421 
1422 
1423 ////////////////////////////////////////////////////////////////////////////////
1424 /// This is a service method used by `THistPainter`
1425 /// to paint 1D histograms. It is not used to paint TGraph.
1426 ///
1427 /// Input parameters:
1428 ///
1429 /// - npoints : Number of points in X or in Y.
1430 /// - x[npoints] or x[0] : x coordinates or (xmin,xmax).
1431 /// - y[npoints] or y[0] : y coordinates or (ymin,ymax).
1432 /// - chopt : Option.
1433 ///
1434 /// The aspect of the histogram is done according to the value of the chopt.
1435 ///
1436 /// | Option | Description |
1437 /// |--------|-----------------------------------------------------------------|
1438 /// |"R" | Graph is drawn horizontally, parallel to X axis. (default is vertically, parallel to Y axis).If option R is selected the user must give 2 values for Y (y[0]=YMIN and y[1]=YMAX) or N values for X, one for each channel. Otherwise the user must give, N values for Y, one for each channel or 2 values for X (x[0]=XMIN and x[1]=XMAX) |
1439 /// |"L" | A simple polyline between every points is drawn.|
1440 /// |"H" | An Histogram with equidistant bins is drawn as a polyline.|
1441 /// |"F" | An histogram with equidistant bins is drawn as a fill area. Contour is not drawn unless chopt='H' is also selected..|
1442 /// |"N" | Non equidistant bins (default is equidistant). If N is the number of channels array X and Y must be dimensioned as follow: If option R is not selected (default) then the user must give (N+1) values for X (limits of channels) or N values for Y, one for each channel. Otherwise the user must give (N+1) values for Y (limits of channels). or N values for X, one for each channel |
1443 /// |"F1" | Idem as 'F' except that fill area base line is the minimum of the pad instead of Y=0.|
1444 /// |"F2" | Draw a Fill area polyline connecting the center of bins|
1445 /// |"C" | A smooth Curve is drawn.|
1446 /// |"*" | A Star is plotted at the center of each bin.|
1447 /// |"P" | Idem with the current marker.|
1448 /// |"P0" | Idem with the current marker. Empty bins also drawn.|
1449 /// |"B" | A Bar chart with equidistant bins is drawn as fill areas (Contours are drawn).|
1450 /// |"][" | "Cutoff" style. When this option is selected together with H option, the first and last vertical lines of the histogram are not drawn.|
1451 
1452 void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_t *x,
1453  const Double_t *y, Option_t *chopt)
1454 {
1456  const char *where = "PaintGrapHist";
1457 
1458  Int_t optionLine , optionAxis , optionCurve, optionStar, optionMark;
1459  Int_t optionBar , optionRot , optionOne , optionOff ;
1460  Int_t optionFill , optionZ;
1461  Int_t optionHist , optionBins , optionMarker;
1462  Int_t i, j, npt;
1463  Int_t drawtype=0, drawborder, drawbordersav;
1464  Double_t xlow, xhigh, ylow, yhigh;
1465  Double_t wmin, wmax;
1466  Double_t dbar, offset, wminstep;
1467  Double_t delta = 0;
1468  Double_t ylast = 0;
1469  Double_t xi, xi1, xj, xj1, yi1, yi, yj, yj1, xwmin, ywmin;
1470  Int_t first, last, nbins;
1471  Int_t fillarea;
1472 
1473  char choptaxis[10] = " ";
1474 
1475  if (npoints <= 0) {
1476  Error(where, "illegal number of points (%d)", npoints);
1477  return;
1478  }
1479  TString opt = chopt;
1480  opt.ToUpper();
1481  if (opt.Contains("H")) optionHist = 1; else optionHist = 0;
1482  if (opt.Contains("F")) optionFill = 1; else optionFill = 0;
1483  if (opt.Contains("C")) optionCurve= 1; else optionCurve= 0;
1484  if (opt.Contains("*")) optionStar = 1; else optionStar = 0;
1485  if (opt.Contains("R")) optionRot = 1; else optionRot = 0;
1486  if (opt.Contains("1")) optionOne = 1; else optionOne = 0;
1487  if (opt.Contains("B")) optionBar = 1; else optionBar = 0;
1488  if (opt.Contains("N")) optionBins = 1; else optionBins = 0;
1489  if (opt.Contains("L")) optionLine = 1; else optionLine = 0;
1490  if (opt.Contains("P")) optionMark = 1; else optionMark = 0;
1491  if (opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
1492  if (opt.Contains("][")) optionOff = 1; else optionOff = 0;
1493  if (opt.Contains("P0")) optionMark = 10;
1494 
1495  Int_t optionFill2 = 0;
1496  if (opt.Contains("F") && opt.Contains("2")) {
1497  optionFill = 0; optionFill2 = 1;
1498  }
1499 
1500  // Set Clipping option
1501  Option_t *noClip;
1502  if (theGraph->TestBit(TGraph::kClipFrame)) noClip = "";
1503  else noClip = "C";
1504  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
1505 
1506  optionZ = 1;
1507 
1508  if (optionStar) theGraph->SetMarkerStyle(3);
1509 
1510  first = 1;
1511  last = npoints;
1512  nbins = last - first + 1;
1513 
1514  // Draw the Axis with a fixed number of division: 510
1515 
1516  Double_t baroffset = gStyle->GetBarOffset();
1517  Double_t barwidth = gStyle->GetBarWidth();
1518  Double_t rwxmin = gPad->GetUxmin();
1519  Double_t rwxmax = gPad->GetUxmax();
1520  Double_t rwymin = gPad->GetUymin();
1521  Double_t rwymax = gPad->GetUymax();
1522  Double_t uxmin = gPad->PadtoX(rwxmin);
1523  Double_t uxmax = gPad->PadtoX(rwxmax);
1524  Double_t rounding = (uxmax-uxmin)*1.e-5;
1525  drawborder = gStyle->GetDrawBorder();
1526  if (optionAxis) {
1527  Int_t nx1, nx2, ndivx, ndivy, ndiv;
1528  choptaxis[0] = 0;
1529  Double_t rwmin = rwxmin;
1530  Double_t rwmax = rwxmax;
1531  ndivx = gStyle->GetNdivisions("X");
1532  ndivy = gStyle->GetNdivisions("Y");
1533  if (ndivx > 1000) {
1534  nx2 = ndivx/100;
1535  nx1 = TMath::Max(1, ndivx%100);
1536  ndivx = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
1537  }
1538  ndiv =TMath::Abs(ndivx);
1539  // coverity [Calling risky function]
1540  if (ndivx < 0) strlcat(choptaxis, "N",10);
1541  if (gPad->GetGridx()) {
1542  // coverity [Calling risky function]
1543  strlcat(choptaxis, "W",10);
1544  }
1545  if (gPad->GetLogx()) {
1546  rwmin = TMath::Power(10,rwxmin);
1547  rwmax = TMath::Power(10,rwxmax);
1548  // coverity [Calling risky function]
1549  strlcat(choptaxis, "G",10);
1550  }
1551  TGaxis *axis = new TGaxis();
1552  axis->SetLineColor(gStyle->GetAxisColor("X"));
1553  axis->SetTextColor(gStyle->GetLabelColor("X"));
1554  axis->SetTextFont(gStyle->GetLabelFont("X"));
1555  axis->SetLabelSize(gStyle->GetLabelSize("X"));
1556  axis->SetLabelOffset(gStyle->GetLabelOffset("X"));
1557  axis->SetTickSize(gStyle->GetTickLength("X"));
1558 
1559  axis->PaintAxis(rwxmin,rwymin,rwxmax,rwymin,rwmin,rwmax,ndiv,choptaxis);
1560 
1561  choptaxis[0] = 0;
1562  rwmin = rwymin;
1563  rwmax = rwymax;
1564  if (ndivy < 0) {
1565  nx2 = ndivy/100;
1566  nx1 = TMath::Max(1, ndivy%100);
1567  ndivy = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsHNDC());
1568  // coverity [Calling risky function]
1569  strlcat(choptaxis, "N",10);
1570  }
1571  ndiv =TMath::Abs(ndivy);
1572  if (gPad->GetGridy()) {
1573  // coverity [Calling risky function]
1574  strlcat(choptaxis, "W",10);
1575  }
1576  if (gPad->GetLogy()) {
1577  rwmin = TMath::Power(10,rwymin);
1578  rwmax = TMath::Power(10,rwymax);
1579  // coverity [Calling risky function]
1580  strlcat(choptaxis,"G",10);
1581  }
1582  axis->SetLineColor(gStyle->GetAxisColor("Y"));
1583  axis->SetTextColor(gStyle->GetLabelColor("Y"));
1584  axis->SetTextFont(gStyle->GetLabelFont("Y"));
1585  axis->SetLabelSize(gStyle->GetLabelSize("Y"));
1586  axis->SetLabelOffset(gStyle->GetLabelOffset("Y"));
1587  axis->SetTickSize(gStyle->GetTickLength("Y"));
1588 
1589  axis->PaintAxis(rwxmin,rwymin,rwxmin,rwymax,rwmin,rwmax,ndiv,choptaxis);
1590  delete axis;
1591  }
1592 
1593 
1594  // Set attributes
1595  theGraph->TAttLine::Modify();
1596  theGraph->TAttFill::Modify();
1597  theGraph->TAttMarker::Modify();
1598 
1599  // Min-Max scope
1600 
1601  if (!optionRot) {wmin = x[0]; wmax = x[1];}
1602  else {wmin = y[0]; wmax = y[1];}
1603 
1604  if (!optionBins) delta = (wmax - wmin)/ Double_t(nbins);
1605 
1606  Int_t fwidth = gPad->GetFrameLineWidth();
1607  TFrame *frame = gPad->GetFrame();
1608  if (frame) fwidth = frame->GetLineWidth();
1609  if (optionOff) fwidth = 1;
1610  Double_t dxframe = gPad->AbsPixeltoX(fwidth/2) - gPad->AbsPixeltoX(0);
1611  Double_t vxmin = gPad->PadtoX(gPad->GetUxmin() + dxframe);
1612  Double_t vxmax = gPad->PadtoX(gPad->GetUxmax() - dxframe);
1613  Double_t dyframe = -gPad->AbsPixeltoY(fwidth/2) + gPad->AbsPixeltoY(0);
1614  Double_t vymin = gPad->GetUymin() + dyframe; //y already in log scale
1615  vxmin = TMath::Max(vxmin,wmin);
1616  vxmax = TMath::Min(vxmax,wmax);
1617 
1618  // Draw the histogram with a fill area
1619 
1620  gxwork = new Double_t[2*npoints+10];
1621  gywork = new Double_t[2*npoints+10];
1622  gxworkl = new Double_t[2*npoints+10];
1623  gyworkl = new Double_t[2*npoints+10];
1624 
1625  if (optionFill && !optionCurve) {
1626  fillarea = kTRUE;
1627  if (!optionRot) {
1628  gxwork[0] = vxmin;
1629  if (!optionOne) gywork[0] = TMath::Min(TMath::Max((Double_t)0,gPad->GetUymin())
1630  ,gPad->GetUymax());
1631  else gywork[0] = gPad->GetUymin();
1632  npt = 2;
1633  for (j=first; j<=last;j++) {
1634  if (!optionBins) {
1635  gxwork[npt-1] = gxwork[npt-2];
1636  gxwork[npt] = wmin+((j-first+1)*delta);
1637  if (gxwork[npt] < gxwork[0]) gxwork[npt] = gxwork[0];
1638 
1639  } else {
1640  xj1 = x[j]; xj = x[j-1];
1641  if (xj1 < xj) {
1642  if (j != last) Error(where, "X must be in increasing order");
1643  else Error(where, "X must have N+1 values with option N");
1644  return;
1645  }
1646  gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j];
1647  }
1648  gywork[npt-1] = y[j-1];
1649  gywork[npt] = y[j-1];
1650  if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
1651  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1652  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1653  if (j == last) {
1654  gxwork[npt-1] = gxwork[npt-2];
1655  gywork[npt-1] = gywork[0];
1656  //make sure that the fill area does not overwrite the frame
1657  //take into account the frame line width
1658  if (gxwork[0 ] < vxmin) {gxwork[0 ] = vxmin; gxwork[1 ] = vxmin;}
1659  if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
1660 
1661  //transform to log ?
1662  ComputeLogs(npt, optionZ);
1663  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1664  if (drawborder) {
1665  if (!fillarea) gyworkl[0] = ylast;
1666  gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
1667  }
1668  continue;
1669  }
1670  } //endfor (j=first; j<=last;j++) {
1671  } else {
1672  gywork[0] = wmin;
1673  if (!optionOne) gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
1674  else gxwork[0] = gPad->GetUxmin();
1675  npt = 2;
1676  for (j=first; j<=last;j++) {
1677  if (!optionBins) {
1678  gywork[npt-1] = gywork[npt-2];
1679  gywork[npt] = wmin+((j-first+1)*delta);
1680  } else {
1681  yj1 = y[j]; yj = y[j-1];
1682  if (yj1 < yj) {
1683  if (j != last) Error(where, "Y must be in increasing order");
1684  else Error(where, "Y must have N+1 values with option N");
1685  return;
1686  }
1687  gywork[npt-1] = y[j-1]; gywork[npt] = y[j];
1688  }
1689  gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j-1];
1690  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1691  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1692  if (j == last) {
1693  gywork[npt-1] = gywork[npt-2];
1694  gxwork[npt-1] = gxwork[0];
1695  ComputeLogs(npt, optionZ);
1696  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1697  if (drawborder) {
1698  if (!fillarea) gyworkl[0] = ylast;
1699  gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
1700  }
1701  continue;
1702  }
1703  } //endfor (j=first; j<=last;j++)
1704  }
1705  theGraph->TAttLine::Modify();
1706  theGraph->TAttFill::Modify();
1707  }
1708 
1709  // Draw a standard Histogram (default)
1710 
1711  if ((optionHist) || !chopt[0]) {
1712  if (!optionRot) {
1713  gxwork[0] = wmin;
1714  gywork[0] = gPad->GetUymin();
1715  ywmin = gywork[0];
1716  npt = 2;
1717  for (i=first; i<=last;i++) {
1718  if (!optionBins) {
1719  gxwork[npt-1] = gxwork[npt-2];
1720  gxwork[npt] = wmin+((i-first+1)*delta);
1721  } else {
1722  xi1 = x[i]; xi = x[i-1];
1723  if (xi1 < xi) {
1724  if (i != last) Error(where, "X must be in increasing order");
1725  else Error(where, "X must have N+1 values with option N");
1726  return;
1727  }
1728  gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i];
1729  }
1730  gywork[npt-1] = y[i-1];
1731  gywork[npt] = y[i-1];
1732  if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
1733  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1734  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1735  if (i == last) {
1736  gxwork[npt-1] = gxwork[npt-2];
1737  gywork[npt-1] = gywork[0];
1738  //make sure that the fill area does not overwrite the frame
1739  //take into account the frame line width
1740  if (gxwork[0] < vxmin) {gxwork[0] = vxmin; gxwork[1 ] = vxmin;}
1741  if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
1742 
1743  ComputeLogs(npt, optionZ);
1744 
1745  // do not draw the two vertical lines on the edges
1746  Int_t nbpoints = npt-2;
1747  Int_t point1 = 1;
1748 
1749  if (optionOff) {
1750  // remove points before the low cutoff
1751  Int_t ip;
1752  for (ip=point1; ip<=nbpoints; ip++) {
1753  if (gyworkl[ip] != ywmin) {
1754  point1 = ip;
1755  break;
1756  }
1757  }
1758  // remove points after the high cutoff
1759  Int_t point2 = nbpoints;
1760  for (ip=point2; ip>=point1; ip--) {
1761  if (gyworkl[ip] != ywmin) {
1762  point2 = ip;
1763  break;
1764  }
1765  }
1766  nbpoints = point2-point1+1;
1767  } else {
1768  // if the 1st or last bin are not on the pad limits the
1769  // the two vertical lines on the edges are added.
1770  if (gxwork[0] > gPad->GetUxmin()) { nbpoints++; point1 = 0; }
1771  if (gxwork[nbpoints] < gPad->GetUxmax()) nbpoints++;
1772  }
1773 
1774  gPad->PaintPolyLine(nbpoints,&gxworkl[point1],&gyworkl[point1],noClip);
1775  continue;
1776  }
1777  } //endfor (i=first; i<=last;i++)
1778  } else {
1779  gywork[0] = wmin;
1780  gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
1781  xwmin = gxwork[0];
1782  npt = 2;
1783  for (i=first; i<=last;i++) {
1784  if (!optionBins) {
1785  gywork[npt-1] = gywork[npt-2];
1786  gywork[npt] = wmin+((i-first+1)*delta);
1787  } else {
1788  yi1 = y[i]; yi = y[i-1];
1789  if (yi1 < yi) {
1790  if (i != last) Error(where, "Y must be in increasing order");
1791  else Error(where, "Y must have N+1 values with option N");
1792  return;
1793  }
1794  gywork[npt-1] = y[i-1]; gywork[npt] = y[i];
1795  }
1796  gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i-1];
1797  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1798  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1799  if (i == last) {
1800  gywork[npt-1] = gywork[npt-2];
1801  gxwork[npt-1] = xwmin;
1802  ComputeLogs(npt, optionZ);
1803  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1804  continue;
1805  }
1806  } //endfor (i=first; i<=last;i++)
1807  }
1808  }
1809 
1810  // Draw the histogram with a smooth Curve.
1811  // The smoothing is done by the method Smooth()
1812 
1813  if (optionCurve) {
1814  if (!optionFill) {
1815  drawtype = 1;
1816  } else {
1817  if (!optionOne) drawtype = 2;
1818  else drawtype = 3;
1819  }
1820  if (!optionRot) {
1821  npt = 0;
1822  for (i=first; i<=last;i++) {
1823  npt++;
1824  if (!optionBins) {
1825  gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1826  } else {
1827  xi1 = x[i]; xi = x[i-1];
1828  if (xi1 < xi) {
1829  if (i != last) Error(where, "X must be in increasing order");
1830  else Error(where, "X must have N+1 values with option N");
1831  return;
1832  }
1833  gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
1834  }
1835  if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) {
1836  npt--;
1837  continue;
1838  }
1839  gywork[npt-1] = y[i-1];
1840  ComputeLogs(npt, optionZ);
1841  if ((gyworkl[npt-1] < rwymin) || (gyworkl[npt-1] > rwymax)) {
1842  if (npt > 2) {
1843  ComputeLogs(npt, optionZ);
1844  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1845  }
1846  gxwork[0] = gxwork[npt-1];
1847  gywork[0] = gywork[npt-1];
1848  npt = 1;
1849  continue;
1850  }
1851  if (npt >= fgMaxPointsPerLine) {
1852  ComputeLogs(fgMaxPointsPerLine, optionZ);
1853  Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype);
1854  gxwork[0] = gxwork[npt-1];
1855  gywork[0] = gywork[npt-1];
1856  npt = 1;
1857  }
1858  } //endfor (i=first; i<=last;i++)
1859  if (npt > 1) {
1860  ComputeLogs(npt, optionZ);
1861  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1862  }
1863  } else {
1864  drawtype = drawtype+10;
1865  npt = 0;
1866  for (i=first; i<=last;i++) {
1867  npt++;
1868  if (!optionBins) {
1869  gywork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1870  } else {
1871  yi1 = y[i]; yi = y[i-1];
1872  if (yi1 < yi) {
1873  if (i != last) Error(where, "Y must be in increasing order");
1874  else Error(where, "Y must have N+1 values with option N");
1875  return;
1876  }
1877  gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
1878  }
1879  gxwork[npt-1] = x[i-1];
1880  ComputeLogs(npt, optionZ);
1881  if ((gxworkl[npt] < uxmin) || (gxworkl[npt] > uxmax)) {
1882  if (npt > 2) {
1883  ComputeLogs(npt, optionZ);
1884  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1885  }
1886  gxwork[0] = gxwork[npt-1];
1887  gywork[0] = gywork[npt-1];
1888  npt = 1;
1889  continue;
1890  }
1891  if (npt >= fgMaxPointsPerLine) {
1892  ComputeLogs(fgMaxPointsPerLine, optionZ);
1893  Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype);
1894  gxwork[0] = gxwork[npt-1];
1895  gywork[0] = gywork[npt-1];
1896  npt = 1;
1897  }
1898  } //endfor (i=first; i<=last;i++)
1899  if (npt > 1) {
1900  ComputeLogs(npt, optionZ);
1901  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1902  }
1903  }
1904  }
1905 
1906  // Draw the histogram with a simple line
1907 
1908  if (optionLine) {
1909  wminstep = wmin + 0.5*delta;
1910  Axis_t ax1,ax2,ay1,ay2;
1911  gPad->GetRangeAxis(ax1,ay1,ax2,ay2);
1912 
1913  if (!optionRot) {
1914  npt = 0;
1915  for (i=first; i<=last;i++) {
1916  npt++;
1917  if (!optionBins) {
1918  gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1919  } else {
1920  xi1 = x[i]; xi = x[i-1];
1921  if (xi1 < xi) {
1922  if (i != last) Error(where, "X must be in increasing order");
1923  else Error(where, "X must have N+1 values with option N");
1924  return;
1925  }
1926  gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
1927  }
1928  if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) { npt--; continue;}
1929  gywork[npt-1] = y[i-1];
1930  gywork[npt] = y[i-1]; //new
1931  if ((gywork[npt-1] < rwymin) || ((gywork[npt-1] > rwymax) && !optionFill2)) {
1932  if ((gywork[npt-1] < rwymin)) gywork[npt-1] = rwymin;
1933  if ((gywork[npt-1] > rwymax)) gywork[npt-1] = rwymax;
1934  if (npt > 2) {
1935  ComputeLogs(npt, optionZ);
1936  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1937  }
1938  gxwork[0] = gxwork[npt-1];
1939  gywork[0] = gywork[npt-1];
1940  npt = 1;
1941  continue;
1942  }
1943 
1944  if (npt >= fgMaxPointsPerLine) {
1945  if (optionLine) {
1946  ComputeLogs(fgMaxPointsPerLine, optionZ);
1947  if (optionFill2) {
1948  gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
1949  gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
1950  gPad->PaintFillArea(fgMaxPointsPerLine+2,gxworkl,gyworkl);
1951  }
1952  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1953  }
1954  gxwork[0] = gxwork[npt-1];
1955  gywork[0] = gywork[npt-1];
1956  npt = 1;
1957  }
1958  } //endfor (i=first; i<=last;i++)
1959  if (npt > 1) {
1960  ComputeLogs(npt, optionZ);
1961  if (optionFill2) {
1962  gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
1963  gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
1964  gPad->PaintFillArea(npt+2,gxworkl,gyworkl);
1965  }
1966  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1967  }
1968  } else {
1969  npt = 0;
1970  for (i=first; i<=last;i++) {
1971  npt++;
1972  if (!optionBins) {
1973  gywork[npt-1] = wminstep+(i-first)*delta+0.5*delta;
1974  } else {
1975  yi1 = y[i]; yi = y[i-1];
1976  if (yi1 < yi) {
1977  if (i != last) Error(where, "Y must be in increasing order");
1978  else Error(where, "Y must have N+1 values with option N");
1979  return;
1980  }
1981  gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
1982  }
1983  gxwork[npt-1] = x[i-1];
1984  if ((gxwork[npt-1] < uxmin) || (gxwork[npt-1] > uxmax)) {
1985  if (npt > 2) {
1986  if (optionLine) {
1987  ComputeLogs(npt, optionZ);
1988  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1989  }
1990  }
1991  gxwork[0] = gxwork[npt-1];
1992  gywork[0] = gywork[npt-1];
1993  npt = 1;
1994  continue;
1995  }
1996  if (npt >= fgMaxPointsPerLine) {
1997  if (optionLine) {
1998  ComputeLogs(fgMaxPointsPerLine, optionZ);
1999  gPad->PaintPolyLine(fgMaxPointsPerLine,gxworkl,gyworkl);
2000  }
2001  gxwork[0] = gxwork[npt-1];
2002  gywork[0] = gywork[npt-1];
2003  npt = 1;
2004  }
2005  } //endfor (i=first; i<=last;i++)
2006  if (optionLine != 0 && npt > 1) {
2007  ComputeLogs(npt, optionZ);
2008  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
2009  }
2010  }
2011  }
2012 
2013  // Draw the histogram as a bar chart
2014 
2015  if (optionBar) {
2016  if (!optionBins) {
2017  offset = delta*baroffset; dbar = delta*barwidth;
2018  } else {
2019  if (!optionRot) {
2020  offset = (x[1]-x[0])*baroffset;
2021  dbar = (x[1]-x[0])*barwidth;
2022  } else {
2023  offset = (y[1]-y[0])*baroffset;
2024  dbar = (y[1]-y[0])*barwidth;
2025  }
2026  }
2027  drawbordersav = drawborder;
2028  gStyle->SetDrawBorder(1);
2029  if (!optionRot) {
2030  xlow = wmin+offset;
2031  xhigh = wmin+offset+dbar;
2032  if (!optionOne) ylow = TMath::Min(TMath::Max((Double_t)0,gPad->GetUymin())
2033  ,gPad->GetUymax());
2034  else ylow = gPad->GetUymin();
2035 
2036  for (i=first; i<=last;i++) {
2037  yhigh = y[i-1];
2038  gxwork[0] = xlow;
2039  gywork[0] = ylow;
2040  gxwork[1] = xhigh;
2041  gywork[1] = yhigh;
2042  ComputeLogs(2, optionZ);
2043  if (xlow < rwxmax && xhigh > rwxmin)
2044  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
2045  if (!optionBins) {
2046  xlow = xlow+delta;
2047  xhigh = xhigh+delta;
2048  } else {
2049  if (i < last) {
2050  xi1 = x[i]; xi = x[i-1];
2051  if (xi1 < xi) {
2052  Error(where, "X must be in increasing order");
2053  return;
2054  }
2055  offset = (x[i+1]-x[i])*baroffset;
2056  dbar = (x[i+1]-x[i])*barwidth;
2057  xlow = x[i] + offset;
2058  xhigh = x[i] + offset + dbar;
2059  }
2060  }
2061  } //endfor (i=first; i<=last;i++)
2062  } else {
2063  ylow = wmin + offset;
2064  yhigh = wmin + offset + dbar;
2065  if (!optionOne) xlow = TMath::Max((Double_t)0,gPad->GetUxmin());
2066  else xlow = gPad->GetUxmin();
2067  for (i=first; i<=last;i++) {
2068  xhigh = x[i-1];
2069  gxwork[0] = xlow;
2070  gywork[0] = ylow;
2071  gxwork[1] = xhigh;
2072  gywork[1] = yhigh;
2073  ComputeLogs(2, optionZ);
2074  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
2075  gPad->PaintBox(xlow,ylow,xhigh,yhigh);
2076  if (!optionBins) {
2077  ylow = ylow + delta;
2078  yhigh = yhigh + delta;
2079  } else {
2080  if (i < last) {
2081  yi1 = y[i]; yi = y[i-1];
2082  if (yi1 < yi) {
2083  Error(where, "Y must be in increasing order");
2084  return;
2085  }
2086  offset = (y[i+1]-y[i])*baroffset;
2087  dbar = (y[i+1]-y[i])*barwidth;
2088  ylow = y[i] + offset;
2089  yhigh = y[i] + offset + dbar;
2090  }
2091  }
2092  } //endfor (i=first; i<=last;i++)
2093  }
2094  gStyle->SetDrawBorder(drawbordersav);
2095  }
2096 
2097  // Draw the histogram with a simple marker
2098 
2099  optionMarker = 0;
2100  if ((optionStar) || (optionMark)) optionMarker=1;
2101 
2102  if (optionMarker) {
2103  Double_t xm,ym;
2104  npt = 0;
2105  if (!optionRot) {
2106  for (i=first; i<=last;i++) {
2107  if (!optionBins) xm = wmin+(i-first)*delta+0.5*delta;
2108  else xm = x[i-1] + 0.5*(x[i]-x[i-1]);
2109  ym = y[i-1];
2110  if (optionMark != 10) {
2111  if (ym<rwymax && ym > rwymin) {
2112  npt++;
2113  gxwork[npt-1] = xm;
2114  gywork[npt-1] = ym;
2115  }
2116  } else {
2117  if (ym<rwymax && ym >= rwymin) {
2118  npt++;
2119  gxwork[npt-1] = xm;
2120  gywork[npt-1] = ym;
2121  }
2122  }
2123  if (npt >= fgMaxPointsPerLine) {
2124  ComputeLogs(npt, optionZ);
2125  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2126  npt = 0;
2127  }
2128  }
2129  if (npt > 0) {
2130  ComputeLogs(npt, optionZ);
2131  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2132  }
2133  } else {
2134  wminstep = wmin + 0.5*delta;
2135  for (i=first; i<=last;i++) {
2136  if (!optionBins) ym = wminstep+(i-first)*delta+0.5*delta;
2137  else ym = y[i-1] + 0.5*(y[i]-y[i-1]);
2138  xm = x[i-1];
2139  if (optionMark != 10) {
2140  if (xm<rwxmax && xm > rwxmin) {
2141  npt++;
2142  gxwork[npt-1] = xm;
2143  gywork[npt-1] = ym;
2144  }
2145  } else {
2146  if (xm<rwxmax && xm >= rwxmin) {
2147  npt++;
2148  gxwork[npt-1] = xm;
2149  gywork[npt-1] = ym;
2150  }
2151  }
2152  if (npt >= fgMaxPointsPerLine) {
2153  ComputeLogs(npt, optionZ);
2154  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2155  npt = 0;
2156  }
2157  }
2158  if (npt > 0) {
2159  ComputeLogs(npt, optionZ);
2160  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2161  }
2162  }
2163  }
2164 
2165  gPad->ResetBit(TGraph::kClipFrame);
2166 
2167  delete [] gxwork;
2168  delete [] gywork;
2169  delete [] gxworkl;
2170  delete [] gyworkl;
2171 }
2172 
2173 
2174 ////////////////////////////////////////////////////////////////////////////////
2175 /// [Paint this TGraphAsymmErrors with its current attributes.](#GP03)
2176 
2177 void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option)
2178 {
2179 
2180  Double_t *xline = 0;
2181  Double_t *yline = 0;
2182  Int_t if1 = 0;
2183  Int_t if2 = 0;
2184  Double_t xb[4], yb[4];
2185 
2186  const Int_t kBASEMARKER=8;
2187  Double_t s2x, s2y, symbolsize, sbase;
2188  Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2189  static Float_t cxx[15] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6,1,0.6,1,1};
2190  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2191  Int_t theNpoints = theGraph->GetN();
2192  Double_t *theX = theGraph->GetX();
2193  Double_t *theY = theGraph->GetY();
2194  Double_t *theEXlow = theGraph->GetEXlow(); if (!theEXlow) return;
2195  Double_t *theEYlow = theGraph->GetEYlow(); if (!theEYlow) return;
2196  Double_t *theEXhigh = theGraph->GetEXhigh(); if (!theEXhigh) return;
2197  Double_t *theEYhigh = theGraph->GetEYhigh(); if (!theEYhigh) return;
2198 
2199  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2200  Bool_t brackets = kFALSE;
2201  Bool_t braticks = kFALSE;
2202  if (strstr(option,"||") || strstr(option,"[]")) {
2203  brackets = kTRUE;
2204  if (strstr(option,"[]")) braticks = kTRUE;
2205  }
2206  Bool_t endLines = kTRUE;
2207  if (strchr(option,'z')) endLines = kFALSE;
2208  if (strchr(option,'Z')) endLines = kFALSE;
2209  const char *arrowOpt = 0;
2210  if (strchr(option,'>')) arrowOpt = ">";
2211  if (strstr(option,"|>")) arrowOpt = "|>";
2212 
2213  Bool_t axis = kFALSE;
2214  if (strchr(option,'a')) axis = kTRUE;
2215  if (strchr(option,'A')) axis = kTRUE;
2216  if (axis) PaintGraphSimple(theGraph, option);
2217 
2218  Bool_t option0 = kFALSE;
2219  Bool_t option2 = kFALSE;
2220  Bool_t option3 = kFALSE;
2221  Bool_t option4 = kFALSE;
2222  Bool_t option5 = kFALSE;
2223  if (strchr(option,'0')) option0 = kTRUE;
2224  if (strchr(option,'2')) option2 = kTRUE;
2225  if (strchr(option,'3')) option3 = kTRUE;
2226  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2227  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2228 
2229  if (option3) {
2230  xline = new Double_t[2*theNpoints];
2231  yline = new Double_t[2*theNpoints];
2232  if (!xline || !yline) {
2233  Error("Paint", "too many points, out of memory");
2234  return;
2235  }
2236  if1 = 1;
2237  if2 = 2*theNpoints;
2238  }
2239 
2240  theGraph->TAttLine::Modify();
2241 
2242  TArrow arrow;
2243  arrow.SetLineWidth(theGraph->GetLineWidth());
2244  arrow.SetLineColor(theGraph->GetLineColor());
2245  arrow.SetFillColor(theGraph->GetFillColor());
2246 
2247  TBox box;
2248  Double_t x1b,y1b,x2b,y2b;
2249  box.SetLineWidth(theGraph->GetLineWidth());
2250  box.SetLineColor(theGraph->GetLineColor());
2251  box.SetFillColor(theGraph->GetFillColor());
2252  box.SetFillStyle(theGraph->GetFillStyle());
2253 
2254  symbolsize = theGraph->GetMarkerSize();
2255  sbase = symbolsize*kBASEMARKER;
2256  Int_t mark = theGraph->GetMarkerStyle();
2257  Double_t cx = 0;
2258  Double_t cy = 0;
2259  if (mark >= 20 && mark <= 34) {
2260  cx = cxx[mark-20];
2261  cy = cyy[mark-20];
2262  }
2263 
2264  // Define the offset of the error bars due to the symbol size
2265  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2266  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2267  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2268  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2269  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2270  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2271 
2272  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2273  for (Int_t i=0;i<theNpoints;i++) {
2274  x = gPad->XtoPad(theX[i]);
2275  y = gPad->YtoPad(theY[i]);
2276  if (!option0) {
2277  if (option3) {
2278  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2279  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2280  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2281  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2282  } else {
2283  if (x < gPad->GetUxmin()) continue;
2284  if (x > gPad->GetUxmax()) continue;
2285  if (y < gPad->GetUymin()) continue;
2286  if (y > gPad->GetUymax()) continue;
2287  }
2288  }
2289  xl1 = x - s2x*cx;
2290  xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
2291 
2292  // draw the error rectangles
2293  if (option2) {
2294  x1b = gPad->XtoPad(theX[i] - theEXlow[i]);
2295  y1b = gPad->YtoPad(theY[i] - theEYlow[i]);
2296  x2b = gPad->XtoPad(theX[i] + theEXhigh[i]);
2297  y2b = gPad->YtoPad(theY[i] + theEYhigh[i]);
2298  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2299  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2300  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2301  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2302  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2303  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2304  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2305  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2306  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2307  else box.PaintBox(x1b, y1b, x2b, y2b);
2308  continue;
2309  }
2310 
2311  // keep points for fill area drawing
2312  if (option3) {
2313  xline[if1-1] = x;
2314  xline[if2-1] = x;
2315  yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
2316  yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
2317  if1++;
2318  if2--;
2319  continue;
2320  }
2321 
2322  if (xl1 > xl2) {
2323  if (arrowOpt) {
2324  arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
2325  } else {
2326  if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
2327  if (endLines) {
2328  if (braticks) {
2329  xb[0] = xl2+tx; yb[0] = y-ty;
2330  xb[1] = xl2; yb[1] = y-ty;
2331  xb[2] = xl2; yb[2] = y+ty;
2332  xb[3] = xl2+tx; yb[3] = y+ty;
2333  gPad->PaintPolyLine(4, xb, yb);
2334  } else {
2335  gPad->PaintLine(xl2,y-ty,xl2,y+ty);
2336  }
2337  }
2338  }
2339  }
2340  xr1 = x + s2x*cx;
2341  xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
2342  if (xr1 < xr2) {
2343  if (arrowOpt) {
2344  arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
2345  } else {
2346  if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
2347  if (endLines) {
2348  if (braticks) {
2349  xb[0] = xr2-tx; yb[0] = y-ty;
2350  xb[1] = xr2; yb[1] = y-ty;
2351  xb[2] = xr2; yb[2] = y+ty;
2352  xb[3] = xr2-tx; yb[3] = y+ty;
2353  gPad->PaintPolyLine(4, xb, yb);
2354  } else {
2355  gPad->PaintLine(xr2,y-ty,xr2,y+ty);
2356  }
2357  }
2358  }
2359  }
2360  yup1 = y + s2y*cy;
2361  yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
2362  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2363  if (yup2 > yup1) {
2364  if (arrowOpt) {
2365  arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
2366  } else {
2367  if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
2368  if (endLines) {
2369  if (braticks) {
2370  xb[0] = x-tx; yb[0] = yup2-ty;
2371  xb[1] = x-tx; yb[1] = yup2;
2372  xb[2] = x+tx; yb[2] = yup2;
2373  xb[3] = x+tx; yb[3] = yup2-ty;
2374  gPad->PaintPolyLine(4, xb, yb);
2375  } else {
2376  gPad->PaintLine(x-tx,yup2,x+tx,yup2);
2377  }
2378  }
2379  }
2380  }
2381  ylow1 = y - s2y*cy;
2382  ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
2383  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2384  if (ylow2 < ylow1) {
2385  if (arrowOpt) {
2386  arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
2387  } else {
2388  if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
2389  if (endLines) {
2390  if (braticks) {
2391  xb[0] = x-tx; yb[0] = ylow2+ty;
2392  xb[1] = x-tx; yb[1] = ylow2;
2393  xb[2] = x+tx; yb[2] = ylow2;
2394  xb[3] = x+tx; yb[3] = ylow2+ty;
2395  gPad->PaintPolyLine(4, xb, yb);
2396  } else {
2397  gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
2398  }
2399  }
2400  }
2401  }
2402  }
2403  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2404  gPad->ResetBit(TGraph::kClipFrame);
2405 
2406  if (option3) {
2407  Int_t logx = gPad->GetLogx();
2408  Int_t logy = gPad->GetLogy();
2409  gPad->SetLogx(0);
2410  gPad->SetLogy(0);
2411  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2412  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2413  gPad->SetLogx(logx);
2414  gPad->SetLogy(logy);
2415  delete [] xline;
2416  delete [] yline;
2417  }
2418 }
2419 
2420 
2421 ////////////////////////////////////////////////////////////////////////////////
2422 /// [Paint this TGraphBentErrors with its current attributes.]($GP03)
2423 
2424 void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option)
2425 {
2426 
2427  Double_t *xline = 0;
2428  Double_t *yline = 0;
2429  Int_t if1 = 0;
2430  Int_t if2 = 0;
2431  Double_t xb[4], yb[4];
2432 
2433  const Int_t kBASEMARKER=8;
2434  Double_t s2x, s2y, symbolsize, sbase;
2435  Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2436  Double_t bxl, bxh, byl, byh;
2437  static Float_t cxx[15] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6,1,0.6,1,1};
2438  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2439  Int_t theNpoints = theGraph->GetN();
2440  Double_t *theX = theGraph->GetX();
2441  Double_t *theY = theGraph->GetY();
2442  Double_t *theEXlow = theGraph->GetEXlow(); if (!theEXlow) return;
2443  Double_t *theEYlow = theGraph->GetEYlow(); if (!theEYlow) return;
2444  Double_t *theEXhigh = theGraph->GetEXhigh(); if (!theEXhigh) return;
2445  Double_t *theEYhigh = theGraph->GetEYhigh(); if (!theEYhigh) return;
2446  Double_t *theEXlowd = theGraph->GetEXlowd(); if (!theEXlowd) return;
2447  Double_t *theEXhighd = theGraph->GetEXhighd(); if (!theEXhighd) return;
2448  Double_t *theEYlowd = theGraph->GetEYlowd(); if (!theEYlowd) return;
2449  Double_t *theEYhighd = theGraph->GetEYhighd(); if (!theEYhighd) return;
2450 
2451  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2452  Bool_t brackets = kFALSE;
2453  Bool_t braticks = kFALSE;
2454  if (strstr(option,"||") || strstr(option,"[]")) {
2455  brackets = kTRUE;
2456  if (strstr(option,"[]")) braticks = kTRUE;
2457  }
2458  Bool_t endLines = kTRUE;
2459  if (strchr(option,'z')) endLines = kFALSE;
2460  if (strchr(option,'Z')) endLines = kFALSE;
2461  const char *arrowOpt = 0;
2462  if (strchr(option,'>')) arrowOpt = ">";
2463  if (strstr(option,"|>")) arrowOpt = "|>";
2464 
2465  Bool_t axis = kFALSE;
2466  if (strchr(option,'a')) axis = kTRUE;
2467  if (strchr(option,'A')) axis = kTRUE;
2468  if (axis) PaintGraphSimple(theGraph,option);
2469 
2470  Bool_t option0 = kFALSE;
2471  Bool_t option2 = kFALSE;
2472  Bool_t option3 = kFALSE;
2473  Bool_t option4 = kFALSE;
2474  Bool_t option5 = kFALSE;
2475  if (strchr(option,'0')) option0 = kTRUE;
2476  if (strchr(option,'2')) option2 = kTRUE;
2477  if (strchr(option,'3')) option3 = kTRUE;
2478  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2479  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2480 
2481  if (option3) {
2482  xline = new Double_t[2*theNpoints];
2483  yline = new Double_t[2*theNpoints];
2484  if (!xline || !yline) {
2485  Error("Paint", "too many points, out of memory");
2486  return;
2487  }
2488  if1 = 1;
2489  if2 = 2*theNpoints;
2490  }
2491 
2492  theGraph->TAttLine::Modify();
2493 
2494  TArrow arrow;
2495  arrow.SetLineWidth(theGraph->GetLineWidth());
2496  arrow.SetLineColor(theGraph->GetLineColor());
2497  arrow.SetFillColor(theGraph->GetFillColor());
2498 
2499  TBox box;
2500  Double_t x1b,y1b,x2b,y2b;
2501  box.SetLineWidth(theGraph->GetLineWidth());
2502  box.SetLineColor(theGraph->GetLineColor());
2503  box.SetFillColor(theGraph->GetFillColor());
2504  box.SetFillStyle(theGraph->GetFillStyle());
2505 
2506  symbolsize = theGraph->GetMarkerSize();
2507  sbase = symbolsize*kBASEMARKER;
2508  Int_t mark = theGraph->GetMarkerStyle();
2509  Double_t cx = 0;
2510  Double_t cy = 0;
2511  if (mark >= 20 && mark <= 34) {
2512  cx = cxx[mark-20];
2513  cy = cyy[mark-20];
2514  }
2515 
2516  // define the offset of the error bars due to the symbol size
2517  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2518  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2519  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2520  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2521  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2522  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2523 
2524  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2525  for (Int_t i=0;i<theNpoints;i++) {
2526  x = gPad->XtoPad(theX[i]);
2527  y = gPad->YtoPad(theY[i]);
2528  bxl = gPad->YtoPad(theY[i]+theEXlowd[i]);
2529  bxh = gPad->YtoPad(theY[i]+theEXhighd[i]);
2530  byl = gPad->XtoPad(theX[i]+theEYlowd[i]);
2531  byh = gPad->XtoPad(theX[i]+theEYhighd[i]);
2532  if (!option0) {
2533  if (option3) {
2534  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2535  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2536  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2537  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2538  } else {
2539  if (x < gPad->GetUxmin()) continue;
2540  if (x > gPad->GetUxmax()) continue;
2541  if (y < gPad->GetUymin()) continue;
2542  if (y > gPad->GetUymax()) continue;
2543  }
2544  }
2545 
2546  // draw the error rectangles
2547  if (option2) {
2548  x1b = gPad->XtoPad(theX[i] - theEXlow[i]);
2549  y1b = gPad->YtoPad(theY[i] - theEYlow[i]);
2550  x2b = gPad->XtoPad(theX[i] + theEXhigh[i]);
2551  y2b = gPad->YtoPad(theY[i] + theEYhigh[i]);
2552  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2553  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2554  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2555  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2556  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2557  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2558  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2559  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2560  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2561  else box.PaintBox(x1b, y1b, x2b, y2b);
2562  continue;
2563  }
2564 
2565  // keep points for fill area drawing
2566  if (option3) {
2567  xline[if1-1] = byh;
2568  xline[if2-1] = byl;
2569  yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
2570  yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
2571  if1++;
2572  if2--;
2573  continue;
2574  }
2575 
2576  xl1 = x - s2x*cx;
2577  xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
2578  if (xl1 > xl2) {
2579  if (arrowOpt) {
2580  arrow.PaintArrow(xl1,y,xl2,bxl,asize,arrowOpt);
2581  } else {
2582  if (!brackets) gPad->PaintLine(xl1,y,xl2,bxl);
2583  if (endLines) {
2584  if (braticks) {
2585  xb[0] = xl2+tx; yb[0] = bxl-ty;
2586  xb[1] = xl2; yb[1] = bxl-ty;
2587  xb[2] = xl2; yb[2] = bxl+ty;
2588  xb[3] = xl2+tx; yb[3] = bxl+ty;
2589  gPad->PaintPolyLine(4, xb, yb);
2590  } else {
2591  gPad->PaintLine(xl2,bxl-ty,xl2,bxl+ty);
2592  }
2593  }
2594  }
2595  }
2596  xr1 = x + s2x*cx;
2597  xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
2598  if (xr1 < xr2) {
2599  if (arrowOpt) {
2600  arrow.PaintArrow(xr1,y,xr2,bxh,asize,arrowOpt);
2601  } else {
2602  if (!brackets) gPad->PaintLine(xr1,y,xr2,bxh);
2603  if (endLines) {
2604  if (braticks) {
2605  xb[0] = xr2-tx; yb[0] = bxh-ty;
2606  xb[1] = xr2; yb[1] = bxh-ty;
2607  xb[2] = xr2; yb[2] = bxh+ty;
2608  xb[3] = xr2-tx; yb[3] = bxh+ty;
2609  gPad->PaintPolyLine(4, xb, yb);
2610  } else {
2611  gPad->PaintLine(xr2,bxh-ty,xr2,bxh+ty);
2612  }
2613  }
2614  }
2615  }
2616  yup1 = y + s2y*cy;
2617  yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
2618  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2619  if (yup2 > yup1) {
2620  if (arrowOpt) {
2621  arrow.PaintArrow(x,yup1,byh,yup2,asize,arrowOpt);
2622  } else {
2623  if (!brackets) gPad->PaintLine(x,yup1,byh,yup2);
2624  if (endLines) {
2625  if (braticks) {
2626  xb[0] = byh-tx; yb[0] = yup2-ty;
2627  xb[1] = byh-tx; yb[1] = yup2;
2628  xb[2] = byh+tx; yb[2] = yup2;
2629  xb[3] = byh+tx; yb[3] = yup2-ty;
2630  gPad->PaintPolyLine(4, xb, yb);
2631  } else {
2632  gPad->PaintLine(byh-tx,yup2,byh+tx,yup2);
2633  }
2634  }
2635  }
2636  }
2637  ylow1 = y - s2y*cy;
2638  ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
2639  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2640  if (ylow2 < ylow1) {
2641  if (arrowOpt) {
2642  arrow.PaintArrow(x,ylow1,byl,ylow2,asize,arrowOpt);
2643  } else {
2644  if (!brackets) gPad->PaintLine(x,ylow1,byl,ylow2);
2645  if (endLines) {
2646  if (braticks) {
2647  xb[0] = byl-tx; yb[0] = ylow2+ty;
2648  xb[1] = byl-tx; yb[1] = ylow2;
2649  xb[2] = byl+tx; yb[2] = ylow2;
2650  xb[3] = byl+tx; yb[3] = ylow2+ty;
2651  gPad->PaintPolyLine(4, xb, yb);
2652  } else {
2653  gPad->PaintLine(byl-tx,ylow2,byl+tx,ylow2);
2654  }
2655  }
2656  }
2657  }
2658  }
2659  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2660  gPad->ResetBit(TGraph::kClipFrame);
2661 
2662  if (option3) {
2663  Int_t logx = gPad->GetLogx();
2664  Int_t logy = gPad->GetLogy();
2665  gPad->SetLogx(0);
2666  gPad->SetLogy(0);
2667  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2668  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2669  gPad->SetLogx(logx);
2670  gPad->SetLogy(logy);
2671  delete [] xline;
2672  delete [] yline;
2673  }
2674 }
2675 
2676 
2677 ////////////////////////////////////////////////////////////////////////////////
2678 /// [Paint this TGraphErrors with its current attributes.]($GP03)
2679 
2680 void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option)
2681 {
2682 
2683  Double_t *xline = 0;
2684  Double_t *yline = 0;
2685  Int_t if1 = 0;
2686  Int_t if2 = 0;
2687  Double_t xb[4], yb[4];
2688 
2689  const Int_t kBASEMARKER=8;
2690  Double_t s2x, s2y, symbolsize, sbase;
2691  Double_t x, y, ex, ey, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2692  static Float_t cxx[15] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6,1,0.6,1,1};
2693  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2694  Int_t theNpoints = theGraph->GetN();
2695  Double_t *theX = theGraph->GetX();
2696  Double_t *theY = theGraph->GetY();
2697  Double_t *theEX = theGraph->GetEX(); if (!theEX) return;
2698  Double_t *theEY = theGraph->GetEY(); if (!theEY) return;
2699 
2700  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2701  Bool_t brackets = kFALSE;
2702  Bool_t braticks = kFALSE;
2703  if (strstr(option,"||") || strstr(option,"[]")) {
2704  brackets = kTRUE;
2705  if (strstr(option,"[]")) braticks = kTRUE;
2706  }
2707  Bool_t endLines = kTRUE;
2708  if (strchr(option,'z')) endLines = kFALSE;
2709  if (strchr(option,'Z')) endLines = kFALSE;
2710  const char *arrowOpt = 0;
2711  if (strchr(option,'>')) arrowOpt = ">";
2712  if (strstr(option,"|>")) arrowOpt = "|>";
2713 
2714  Bool_t axis = kFALSE;
2715  if (strchr(option,'a')) axis = kTRUE;
2716  if (strchr(option,'A')) axis = kTRUE;
2717  if (axis) PaintGraphSimple(theGraph, option);
2718 
2719  Bool_t option0 = kFALSE;
2720  Bool_t option2 = kFALSE;
2721  Bool_t option3 = kFALSE;
2722  Bool_t option4 = kFALSE;
2723  Bool_t option5 = kFALSE;
2724  if (strchr(option,'0')) option0 = kTRUE;
2725  if (strchr(option,'2')) option2 = kTRUE;
2726  if (strchr(option,'3')) option3 = kTRUE;
2727  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2728  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2729 
2730  if (option3) {
2731  xline = new Double_t[2*theNpoints];
2732  yline = new Double_t[2*theNpoints];
2733  if (!xline || !yline) {
2734  Error("Paint", "too many points, out of memory");
2735  return;
2736  }
2737  if1 = 1;
2738  if2 = 2*theNpoints;
2739  }
2740 
2741  theGraph->TAttLine::Modify();
2742 
2743  TArrow arrow;
2744  arrow.SetLineWidth(theGraph->GetLineWidth());
2745  arrow.SetLineColor(theGraph->GetLineColor());
2746  arrow.SetFillColor(theGraph->GetFillColor());
2747 
2748  TBox box;
2749  Double_t x1b,y1b,x2b,y2b;
2750  box.SetLineWidth(theGraph->GetLineWidth());
2751  box.SetLineColor(theGraph->GetLineColor());
2752  box.SetFillColor(theGraph->GetFillColor());
2753  box.SetFillStyle(theGraph->GetFillStyle());
2754 
2755  symbolsize = theGraph->GetMarkerSize();
2756  sbase = symbolsize*kBASEMARKER;
2757  Int_t mark = theGraph->GetMarkerStyle();
2758  Double_t cx = 0;
2759  Double_t cy = 0;
2760  if (mark >= 20 && mark <= 34) {
2761  cx = cxx[mark-20];
2762  cy = cyy[mark-20];
2763  }
2764 
2765  // define the offset of the error bars due to the symbol size
2766  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2767  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2768  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2769  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2770  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2771  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2772 
2773  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2774  for (Int_t i=0;i<theNpoints;i++) {
2775  x = gPad->XtoPad(theX[i]);
2776  y = gPad->YtoPad(theY[i]);
2777  if (!option0) {
2778  if (option3) {
2779  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2780  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2781  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2782  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2783  } else {
2784  if (x < gPad->GetUxmin()) continue;
2785  if (x > gPad->GetUxmax()) continue;
2786  if (y < gPad->GetUymin()) continue;
2787  if (y > gPad->GetUymax()) continue;
2788  }
2789  }
2790  ex = theEX[i];
2791  ey = theEY[i];
2792 
2793  // draw the error rectangles
2794  if (option2) {
2795  x1b = gPad->XtoPad(theX[i] - ex);
2796  y1b = gPad->YtoPad(theY[i] - ey);
2797  x2b = gPad->XtoPad(theX[i] + ex);
2798  y2b = gPad->YtoPad(theY[i] + ey);
2799  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2800  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2801  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2802  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2803  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2804  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2805  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2806  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2807  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2808  else box.PaintBox(x1b, y1b, x2b, y2b);
2809  continue;
2810  }
2811 
2812  // keep points for fill area drawing
2813  if (option3) {
2814  xline[if1-1] = x;
2815  xline[if2-1] = x;
2816  yline[if1-1] = gPad->YtoPad(theY[i] + ey);
2817  yline[if2-1] = gPad->YtoPad(theY[i] - ey);
2818  if1++;
2819  if2--;
2820  continue;
2821  }
2822 
2823  xl1 = x - s2x*cx;
2824  xl2 = gPad->XtoPad(theX[i] - ex);
2825  if (xl1 > xl2) {
2826  if (arrowOpt) {
2827  arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
2828  } else {
2829  if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
2830  if (endLines) {
2831  if (braticks) {
2832  xb[0] = xl2+tx; yb[0] = y-ty;
2833  xb[1] = xl2; yb[1] = y-ty;
2834  xb[2] = xl2; yb[2] = y+ty;
2835  xb[3] = xl2+tx; yb[3] = y+ty;
2836  gPad->PaintPolyLine(4, xb, yb);
2837  } else {
2838  gPad->PaintLine(xl2,y-ty,xl2,y+ty);
2839  }
2840  }
2841  }
2842  }
2843  xr1 = x + s2x*cx;
2844  xr2 = gPad->XtoPad(theX[i] + ex);
2845  if (xr1 < xr2) {
2846  if (arrowOpt) {
2847  arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
2848  } else {
2849  if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
2850  if (endLines) {
2851  if (braticks) {
2852  xb[0] = xr2-tx; yb[0] = y-ty;
2853  xb[1] = xr2; yb[1] = y-ty;
2854  xb[2] = xr2; yb[2] = y+ty;
2855  xb[3] = xr2-tx; yb[3] = y+ty;
2856  gPad->PaintPolyLine(4, xb, yb);
2857  } else {
2858  gPad->PaintLine(xr2,y-ty,xr2,y+ty);
2859  }
2860  }
2861  }
2862  }
2863  yup1 = y + s2y*cy;
2864  yup2 = gPad->YtoPad(theY[i] + ey);
2865  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2866  if (yup2 > yup1) {
2867  if (arrowOpt) {
2868  arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
2869  } else {
2870  if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
2871  if (endLines) {
2872  if (braticks) {
2873  xb[0] = x-tx; yb[0] = yup2-ty;
2874  xb[1] = x-tx; yb[1] = yup2;
2875  xb[2] = x+tx; yb[2] = yup2;
2876  xb[3] = x+tx; yb[3] = yup2-ty;
2877  gPad->PaintPolyLine(4, xb, yb);
2878  } else {
2879  gPad->PaintLine(x-tx,yup2,x+tx,yup2);
2880  }
2881  }
2882  }
2883  }
2884  ylow1 = y - s2y*cy;
2885  ylow2 = gPad->YtoPad(theY[i] - ey);
2886  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2887  if (ylow2 < ylow1) {
2888  if (arrowOpt) {
2889  arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
2890  } else {
2891  if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
2892  if (endLines) {
2893  if (braticks) {
2894  xb[0] = x-tx; yb[0] = ylow2+ty;
2895  xb[1] = x-tx; yb[1] = ylow2;
2896  xb[2] = x+tx; yb[2] = ylow2;
2897  xb[3] = x+tx; yb[3] = ylow2+ty;
2898  gPad->PaintPolyLine(4, xb, yb);
2899  } else {
2900  gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
2901  }
2902  }
2903  }
2904  }
2905  }
2906  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2907  gPad->ResetBit(TGraph::kClipFrame);
2908 
2909  if (option3) {
2910  Int_t logx = gPad->GetLogx();
2911  Int_t logy = gPad->GetLogy();
2912  gPad->SetLogx(0);
2913  gPad->SetLogy(0);
2914  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2915  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2916  gPad->SetLogx(logx);
2917  gPad->SetLogy(logy);
2918  delete [] xline;
2919  delete [] yline;
2920  }
2921 }
2922 
2923 
2924 ////////////////////////////////////////////////////////////////////////////////
2925 /// [Paint this TGraphPolar with its current attributes.]($GP04)
2926 
2927 void TGraphPainter::PaintGraphPolar(TGraph *theGraph, Option_t* options)
2928 {
2929 
2930  Int_t ipt, i;
2931  Double_t rwrmin, rwrmax, rwtmin, rwtmax;
2932 
2933  TGraphPolar *theGraphPolar = (TGraphPolar*) theGraph;
2934 
2935  Int_t theNpoints = theGraphPolar->GetN();
2936  Double_t *theX = theGraphPolar->GetX();
2937  Double_t *theY = theGraphPolar->GetY();
2938  Double_t *theEX = theGraphPolar->GetEX();
2939  Double_t *theEY = theGraphPolar->GetEY();
2940 
2941  if (theNpoints<1) return;
2942  TString opt = options;
2943  opt.ToUpper();
2944 
2945  Bool_t nolabel = kFALSE;
2946  if (opt.Contains("N")){
2947  nolabel = kTRUE;
2948  opt.ReplaceAll("N","");
2949  }
2950 
2951  TGraphPolargram *thePolargram = theGraphPolar->GetPolargram();
2952 
2953  // Check for existing TGraphPolargram in the Pad
2954  if (gPad) {
2955  // Existing polargram
2956  if (thePolargram) if (!gPad->FindObject(thePolargram->GetName())) thePolargram=0;
2957  if (!thePolargram) {
2958  // Find any other Polargram in the Pad
2959  TListIter padObjIter(gPad->GetListOfPrimitives());
2960  while (TObject* AnyObj = padObjIter.Next()) {
2961  if (TString(AnyObj->ClassName()).CompareTo("TGraphPolargram",
2962  TString::kExact)==0)
2963  thePolargram = (TGraphPolargram*)AnyObj;
2964  theGraphPolar->SetPolargram(thePolargram);
2965  }
2966  }
2967  }
2968 
2969  // Get new polargram range if necessary.
2970  if (!thePolargram) {
2971  // Get range, initialize with first/last value
2972  rwrmin = theY[0]; rwrmax = theY[theNpoints-1];
2973  rwtmin = theX[0]; rwtmax = theX[theNpoints-1];
2974 
2975  for (ipt = 0; ipt < theNpoints; ipt++) {
2976  // Check for errors if available
2977  if (theEX) {
2978  if (theX[ipt] -theEX[ipt] < rwtmin) rwtmin = theX[ipt]-theEX[ipt];
2979  if (theX[ipt] +theEX[ipt] > rwtmax) rwtmax = theX[ipt]+theEX[ipt];
2980  } else {
2981  if (theX[ipt] < rwtmin) rwtmin=theX[ipt];
2982  if (theX[ipt] > rwtmax) rwtmax=theX[ipt];
2983  }
2984  if (theEY) {
2985  if (theY[ipt] -theEY[ipt] < rwrmin) rwrmin = theY[ipt]-theEY[ipt];
2986  if (theY[ipt] +theEY[ipt] > rwrmax) rwrmax = theY[ipt]+theEY[ipt];
2987  } else {
2988  if (theY[ipt] < rwrmin) rwrmin=theY[ipt];
2989  if (theY[ipt] > rwrmax) rwrmax=theY[ipt];
2990  }
2991  }
2992  // Add radial and Polar margins.
2993  if (rwrmin == rwrmax) rwrmax += 1.;
2994  if (rwtmin == rwtmax) rwtmax += 1.;
2995  Double_t dr = (rwrmax-rwrmin);
2996  Double_t dt = (rwtmax-rwtmin);
2997  rwrmax += 0.1*dr;
2998  rwrmin -= 0.1*dr;
2999 
3000  // Assume equally spaced points for full 2*Pi.
3001  rwtmax += dt/theNpoints;
3002  } else {
3003  rwrmin = thePolargram->GetRMin();
3004  rwrmax = thePolargram->GetRMax();
3005  rwtmin = thePolargram->GetTMin();
3006  rwtmax = thePolargram->GetTMax();
3007  }
3008 
3009  if ((!thePolargram) || theGraphPolar->GetOptionAxis()) {
3010  // Draw Polar coord system
3011  thePolargram = new TGraphPolargram("Polargram",rwrmin,rwrmax,rwtmin,rwtmax);
3012  theGraphPolar->SetPolargram(thePolargram);
3013  if (opt.Contains("O")) thePolargram->SetBit(TGraphPolargram::kLabelOrtho);
3014  else thePolargram->ResetBit(TGraphPolargram::kLabelOrtho);
3015  if (nolabel) thePolargram->Draw("N");
3016  else thePolargram->Draw("");
3017  theGraphPolar->SetOptionAxis(kFALSE); //Prevent redrawing
3018  }
3019 
3020  // Convert points to polar.
3021  Double_t *theXpol = theGraphPolar->GetXpol();
3022  Double_t *theYpol = theGraphPolar->GetYpol();
3023 
3024  // Project theta in [0,2*Pi] and radius in [0,1].
3025  Double_t radiusNDC = rwrmax-rwrmin;
3026  Double_t thetaNDC = (rwtmax-rwtmin)/(2*TMath::Pi());
3027 
3028  // Draw the error bars.
3029  // Y errors are lines, but X errors are pieces of circles.
3030  if (opt.Contains("E")) {
3031  Double_t c=1;
3032  if (thePolargram->IsDegree()) {c=180/TMath::Pi();}
3033  if (thePolargram->IsGrad()) {c=100/TMath::Pi();}
3034  if (theEY) {
3035  for (i=0; i<theNpoints; i++) {
3036  Double_t eymin, eymax, exmin,exmax;
3037  exmin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
3038  TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3039  eymin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
3040  TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3041  exmax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
3042  TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3043  eymax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
3044  TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3045  theGraphPolar->TAttLine::Modify();
3046  if (exmin != exmax || eymin != eymax) gPad->PaintLine(exmin,eymin,exmax,eymax);
3047  }
3048  }
3049  if (theEX) {
3050  for (i=0; i<theNpoints; i++) {
3051  Double_t rad = c*(theY[i]-rwrmin)/radiusNDC;
3052  Double_t phimin = c*(theX[i]-theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
3053  Double_t phimax = c*(theX[i]+theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
3054  theGraphPolar->TAttLine::Modify();
3055  if (phimin != phimax) thePolargram->PaintCircle(0,0,rad,phimin,phimax,0);
3056  }
3057  }
3058  }
3059 
3060  // Draw the graph itself.
3061  if (!(gPad->GetLogx()) && !(gPad->GetLogy())) {
3062  Double_t a, b, c=1, x1, x2, y1, y2, discr, norm1, norm2, xts, yts;
3063  Bool_t previouspointin = kFALSE;
3064  Double_t norm = 0;
3065  Double_t xt = 0;
3066  Double_t yt = 0 ;
3067  Int_t j = -1;
3068  if (thePolargram->IsDegree()) {c=180/TMath::Pi();}
3069  if (thePolargram->IsGrad()) {c=100/TMath::Pi();}
3070  for (i=0; i<theNpoints; i++) {
3071  xts = xt;
3072  yts = yt;
3073  xt = (theY[i]-rwrmin)/radiusNDC*TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3074  yt = (theY[i]-rwrmin)/radiusNDC*TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3075  norm = sqrt(xt*xt+yt*yt);
3076  // Check if points are in the main circle.
3077  if ( norm <= 1) {
3078  // We check that the previous point was in the circle too.
3079  // We record new point position.
3080  if (!previouspointin) {
3081  j++;
3082  theXpol[j] = xt;
3083  theYpol[j] = yt;
3084  } else {
3085  a = (yt-yts)/(xt-xts);
3086  b = yts-a*xts;
3087  discr = 4*(a*a-b*b+1);
3088  x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
3089  x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
3090  y1 = a*x1+b;
3091  y2 = a*x2+b;
3092  norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
3093  norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
3094  previouspointin = kFALSE;
3095  j = 0;
3096  if (norm1 < norm2) {
3097  theXpol[j] = x1;
3098  theYpol[j] = y1;
3099  } else {
3100  theXpol[j] = x2;
3101  theYpol[j] = y2;
3102  }
3103  j++;
3104  theXpol[j] = xt;
3105  theYpol[j] = yt;
3106  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3107  }
3108  } else {
3109  // We check that the previous point was in the circle.
3110  // We record new point position
3111  if (j>=1 && !previouspointin) {
3112  a = (yt-theYpol[j])/(xt-theXpol[j]);
3113  b = theYpol[j]-a*theXpol[j];
3114  previouspointin = kTRUE;
3115  discr = 4*(a*a-b*b+1);
3116  x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
3117  x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
3118  y1 = a*x1+b;
3119  y2 = a*x2+b;
3120  norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
3121  norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
3122  j++;
3123  if (norm1 < norm2) {
3124  theXpol[j] = x1;
3125  theYpol[j] = y1;
3126  } else {
3127  theXpol[j] = x2;
3128  theYpol[j] = y2;
3129  }
3130  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3131  }
3132  j=-1;
3133  }
3134  }
3135  if (j>=1) {
3136  // If the last point is in the circle, we draw the last serie of point.
3137  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3138  }
3139  } else {
3140  for (i=0; i<theNpoints; i++) {
3141  theXpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Cos((theX[i]-rwtmin)/thetaNDC)+1);
3142  theYpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Sin((theX[i]-rwtmin)/thetaNDC)+1);
3143  }
3144  PaintGraph(theGraphPolar, theNpoints, theXpol, theYpol,opt);
3145  }
3146 
3147  // Paint the title.
3148 
3149  if (TestBit(TH1::kNoTitle)) return;
3150  Int_t nt = strlen(theGraph->GetTitle());
3151  TPaveText *title = 0;
3152  TObject *obj;
3153  TIter next(gPad->GetListOfPrimitives());
3154  while ((obj = next())) {
3155  if (!obj->InheritsFrom(TPaveText::Class())) continue;
3156  title = (TPaveText*)obj;
3157  if (title->GetName())
3158  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
3159  break;
3160  }
3161  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
3162  if (title) delete title;
3163  return;
3164  }
3165  Double_t ht = gStyle->GetTitleH();
3166  Double_t wt = gStyle->GetTitleW();
3167  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
3168  if (ht <= 0) ht = 0.05;
3169  if (wt <= 0) {
3170  TLatex l;
3171  l.SetTextSize(ht);
3172  l.SetTitle(theGraph->GetTitle());
3173  // Adjustment in case the title has several lines (#splitline)
3174  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
3175  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
3176  wt = TMath::Min(0.7, 0.02+wndc);
3177  }
3178  if (title) {
3179  TText *t0 = (TText*)title->GetLine(0);
3180  if (t0) {
3181  if (!strcmp(t0->GetTitle(),theGraph->GetTitle())) return;
3182  t0->SetTitle(theGraph->GetTitle());
3183  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
3184  }
3185  return;
3186  }
3187 
3188  Int_t talh = gStyle->GetTitleAlign()/10;
3189  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
3190  Int_t talv = gStyle->GetTitleAlign()%10;
3191  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
3192 
3193  Double_t xpos, ypos;
3194  xpos = gStyle->GetTitleX();
3195  ypos = gStyle->GetTitleY();
3196 
3197  if (talh == 2) xpos = xpos-wt/2.;
3198  if (talh == 3) xpos = xpos-wt;
3199  if (talv == 2) ypos = ypos+ht/2.;
3200  if (talv == 1) ypos = ypos+ht;
3201 
3202  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
3203 
3204  // Box with the histogram title.
3206  ptitle->SetFillStyle(gStyle->GetTitleStyle());
3207  ptitle->SetName("title");
3210  ptitle->SetTextFont(gStyle->GetTitleFont(""));
3211  if (gStyle->GetTitleFont("")%10 > 2)
3212  ptitle->SetTextSize(gStyle->GetTitleFontSize());
3213  ptitle->AddText(theGraph->GetTitle());
3214  ptitle->SetBit(kCanDelete);
3215  ptitle->Draw();
3216  ptitle->Paint();
3217 }
3218 
3219 
3220 ////////////////////////////////////////////////////////////////////////////////
3221 /// Paint this graphQQ. No options for the time being.
3222 
3223 void TGraphPainter::PaintGraphQQ(TGraph *theGraph, Option_t *option)
3224 {
3225 
3226  TGraphQQ *theGraphQQ = (TGraphQQ*) theGraph;
3227 
3228  Double_t *theX = theGraphQQ->GetX();
3229  Double_t theXq1 = theGraphQQ->GetXq1();
3230  Double_t theXq2 = theGraphQQ->GetXq2();
3231  Double_t theYq1 = theGraphQQ->GetYq1();
3232  Double_t theYq2 = theGraphQQ->GetYq2();
3233  TF1 *theF = theGraphQQ->GetF();
3234 
3235  if (!theX){
3236  Error("TGraphQQ::Paint", "2nd dataset or theoretical function not specified");
3237  return;
3238  }
3239 
3240  if (theF){
3241  theGraphQQ->GetXaxis()->SetTitle("theoretical quantiles");
3242  theGraphQQ->GetYaxis()->SetTitle("data quantiles");
3243  }
3244 
3245  PaintGraphSimple(theGraph,option);
3246 
3247  Double_t xmin = gPad->GetUxmin();
3248  Double_t xmax = gPad->GetUxmax();
3249  Double_t ymin = gPad->GetUymin();
3250  Double_t ymax = gPad->GetUymax();
3251  Double_t yxmin, xymin, yxmax, xymax;
3252  Double_t xqmin = TMath::Max(xmin, theXq1);
3253  Double_t xqmax = TMath::Min(xmax, theXq2);
3254  Double_t yqmin = TMath::Max(ymin, theYq1);
3255  Double_t yqmax = TMath::Min(ymax, theYq2);
3256 
3257  TLine line1, line2, line3;
3258  line1.SetLineStyle(2);
3259  line3.SetLineStyle(2);
3260  yxmin = (theYq2-theYq1)*(xmin-theXq1)/(theXq2-theXq1) + theYq1;
3261  if (yxmin < ymin){
3262  xymin = (theXq2-theXq1)*(ymin-theYq1)/(theYq2-theYq1) + theXq1;
3263  line1.PaintLine(xymin, ymin, xqmin, yqmin);
3264  }
3265  else
3266  line1.PaintLine(xmin, yxmin, xqmin, yqmin);
3267 
3268  line2.PaintLine(xqmin, yqmin, xqmax, yqmax);
3269 
3270  yxmax = (theYq2-theYq1)*(xmax-theXq1)/(theXq2-theXq1) + theYq1;
3271  if (yxmax > ymax){
3272  xymax = (theXq2-theXq1)*(ymax-theYq1)/(theYq2-theYq1) + theXq1;
3273  line3.PaintLine(xqmax, yqmax, xymax, ymax);
3274  }
3275  else
3276  line3.PaintLine(xqmax, yqmax, xmax, yxmax);
3277 }
3278 
3279 
3280 ////////////////////////////////////////////////////////////////////////////////
3281 /// Paint theGraph reverting values along X and/or Y axis. a new graph is created.
3282 
3283 void TGraphPainter::PaintGraphReverse(TGraph *theGraph, Option_t *option)
3284 {
3285  TString opt = option;
3286  opt.ToLower();
3287  TH1F *theHist = (TH1F *)theGraph->GetHistogram();
3288 
3289  Bool_t lrx = opt.Contains("rx");
3290  Bool_t lry = opt.Contains("ry");
3291 
3292  Double_t LOX = theHist->GetXaxis()->GetLabelOffset();
3293  Double_t TLX = theHist->GetXaxis()->GetTickLength();
3294  Double_t LOY = theHist->GetYaxis()->GetLabelOffset();
3295  Double_t TLY = theHist->GetYaxis()->GetTickLength();
3296  Int_t XACOL = theHist->GetXaxis()->GetAxisColor();
3297  Int_t YACOL = theHist->GetYaxis()->GetAxisColor();
3298 
3299  if (opt.Contains("a")) {
3300  if (lrx) {
3301  theHist->GetXaxis()->SetTickLength(0.);
3302  theHist->GetXaxis()->SetLabelOffset(999.);
3303  theHist->GetXaxis()->SetAxisColor(gPad->GetFrameFillColor());
3304  }
3305  if (lry) {
3306  theHist->GetYaxis()->SetTickLength(0.);
3307  theHist->GetYaxis()->SetLabelOffset(999.);
3308  theHist->GetYaxis()->SetAxisColor(gPad->GetFrameFillColor());
3309  }
3310  theHist->Paint("0");
3311  opt.ReplaceAll("a", "");
3312  }
3313 
3314  Int_t N = theGraph->GetN();
3315  Double_t *X = theGraph->GetX();
3316  Double_t *Y = theGraph->GetY();
3317  Double_t XA1 = theGraph->GetXaxis()->GetXmin();
3318  Double_t XA2 = theGraph->GetXaxis()->GetXmax();
3319  Double_t YA1 = theGraph->GetYaxis()->GetXmin();
3320  Double_t YA2 = theGraph->GetYaxis()->GetXmax();
3321  Double_t dX = XA1+XA2;
3322  Double_t dY = YA1+YA2;
3323  std::vector<Double_t> newX(N);
3324  std::vector<Double_t> newY(N);
3325 
3326  if (lrx) {
3327  opt.ReplaceAll("rx", "");
3328 
3329  Double_t GL = 0.;
3330  theHist->GetXaxis()->SetTickLength(0.);
3331  theHist->GetXaxis()->SetLabelOffset(999.);
3332 
3333  // Redraw the new X axis
3334  gPad->Update();
3335  TString optax = "-SDH";
3336  if (gPad->GetGridx()) {
3337  GL = (YA2-YA1)/(gPad->GetY2() - gPad->GetY1());
3338  optax.Append("W");
3339  }
3340  TGaxis *theNewAxis = new TGaxis(gPad->GetUxmax(),
3341  gPad->GetUymin(),
3342  gPad->GetUxmin(),
3343  gPad->GetUymin(),
3344  theGraph->GetXaxis()->GetXmin(),
3345  theGraph->GetXaxis()->GetXmax(),
3346  theHist->GetNdivisions("X"),
3347  optax.Data(), -GL);
3348  theNewAxis->SetLabelFont(theGraph->GetXaxis()->GetLabelFont());
3349  theNewAxis->SetLabelSize(theGraph->GetXaxis()->GetLabelSize());
3350  theNewAxis->SetLabelColor(theGraph->GetXaxis()->GetLabelColor());
3351  theNewAxis->SetTickLength(TLX);
3352  theNewAxis->SetLabelOffset(LOX-theGraph->GetXaxis()->GetLabelSize());
3353  theNewAxis->Paint();
3354 
3355  // Reverse X coordinates
3356  for (Int_t i=0; i<N; i++) newX[i] = dX-X[i];
3357  } else {
3358  for (Int_t i=0; i<N; i++) newX[i] = X[i];
3359  }
3360 
3361  if (lry) {
3362  opt.ReplaceAll("ry", "");
3363  Double_t GL = 0.;
3364 
3365  // Redraw the new Y axis
3366  gPad->Update();
3367  TString optax = "-SDH";
3368 
3369  if (gPad->GetGridy()) {
3370  GL = (XA2-XA1)/(gPad->GetX2() - gPad->GetX1());
3371  optax.Append("W");
3372  }
3373  TGaxis *theNewAxis = new TGaxis(gPad->GetUxmin(),
3374  gPad->GetUymax(),
3375  gPad->GetUxmin(),
3376  gPad->GetUymin(),
3377  theGraph->GetYaxis()->GetXmin(),
3378  theGraph->GetYaxis()->GetXmax(),
3379  theHist->GetNdivisions("Y"),
3380  optax.Data(), GL);
3381  theNewAxis->SetLabelFont(theGraph->GetYaxis()->GetLabelFont());
3382  theNewAxis->SetLabelSize(theGraph->GetYaxis()->GetLabelSize());
3383  theNewAxis->SetLabelColor(theGraph->GetYaxis()->GetLabelColor());
3384  theNewAxis->SetTickLength(-TLY);
3385  theNewAxis->SetLabelOffset(LOY-TLY);
3386  theNewAxis->Paint();
3387 
3388  // Reverse Y coordinates
3389  for (Int_t i=0; i<N; i++) newY[i] = dY-Y[i];
3390  } else {
3391  for (Int_t i=0; i<N; i++) newY[i] = Y[i];
3392  }
3393 
3394  // Create the new reversed graph
3395  TGraph *theNewGraph = (TGraph*)theGraph->Clone();
3396  for (Int_t i=0; i<N; i++) theNewGraph->SetPoint(i, newX[i], newY[i]);
3397  theNewGraph->SetMarkerStyle(theGraph->GetMarkerStyle());
3398  theNewGraph->SetMarkerColor(theGraph->GetMarkerColor());
3399  theNewGraph->SetLineStyle(theGraph->GetLineStyle());
3400  theNewGraph->SetLineColor(theGraph->GetLineColor());
3401 
3402  PaintHelper(theNewGraph,opt.Data());
3403 
3404  theHist->GetXaxis()->SetLabelOffset(LOX);
3405  theHist->GetXaxis()->SetTickLength(TLX);
3406  theHist->GetYaxis()->SetLabelOffset(LOY);
3407  theHist->GetYaxis()->SetTickLength(TLY);
3408  theHist->GetXaxis()->SetAxisColor(XACOL);
3409  theHist->GetYaxis()->SetAxisColor(YACOL);
3410 }
3411 
3412 
3413 ////////////////////////////////////////////////////////////////////////////////
3414 /// Paint a simple graph, without errors bars.
3415 
3416 void TGraphPainter::PaintGraphSimple(TGraph *theGraph, Option_t *option)
3417 {
3418 
3419  if (strstr(option,"H") || strstr(option,"h")) {
3420  PaintGrapHist(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
3421  } else {
3422  PaintGraph(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
3423  }
3424 
3425  // Paint associated objects in the list of functions (for instance
3426  // the fit function).
3427  TList *functions = theGraph->GetListOfFunctions();
3428  if (!functions) return;
3429  TObjOptLink *lnk = (TObjOptLink*)functions->FirstLink();
3430  TObject *obj;
3431 
3432  while (lnk) {
3433  obj = lnk->GetObject();
3434  TVirtualPad *padsave = gPad;
3435  if (obj->InheritsFrom(TF1::Class())) {
3436  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
3437  } else {
3438  obj->Paint(lnk->GetOption());
3439  }
3440  lnk = (TObjOptLink*)lnk->Next();
3441  padsave->cd();
3442  }
3443  return;
3444 }
3445 
3446 
3447 ////////////////////////////////////////////////////////////////////////////////
3448 /// Paint a polyline with hatches on one side showing an exclusion zone. x and y
3449 /// are the the vectors holding the polyline and n the number of points in the
3450 /// polyline and `w` the width of the hatches. `w` can be negative.
3451 /// This method is not meant to be used directly. It is called automatically
3452 /// according to the line style convention.
3453 
3454 void TGraphPainter::PaintPolyLineHatches(TGraph *theGraph, Int_t n, const Double_t *x, const Double_t *y)
3455 {
3456 
3457  Int_t i,j,nf;
3458  Double_t w = (theGraph->GetLineWidth()/100)*0.005;
3459 
3460  Double_t *xf = new Double_t[2*n];
3461  Double_t *yf = new Double_t[2*n];
3462  Double_t *xt = new Double_t[n];
3463  Double_t *yt = new Double_t[n];
3464  Double_t x1, x2, y1, y2, x3, y3, xm, ym, a, a1, a2, a3;
3465 
3466  // Compute the gPad coordinates in TRUE normalized space (NDC)
3467  Int_t ix1,iy1,ix2,iy2;
3468  Int_t iw = gPad->GetWw();
3469  Int_t ih = gPad->GetWh();
3470  Double_t x1p,y1p,x2p,y2p;
3471  gPad->GetPadPar(x1p,y1p,x2p,y2p);
3472  ix1 = (Int_t)(iw*x1p);
3473  iy1 = (Int_t)(ih*y1p);
3474  ix2 = (Int_t)(iw*x2p);
3475  iy2 = (Int_t)(ih*y2p);
3476  Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
3477  Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
3478  Double_t rh = hndc/(Double_t)ih;
3479  Double_t rw = wndc/(Double_t)iw;
3480  Double_t x1ndc = (Double_t)ix1*rw;
3481  Double_t y1ndc = (Double_t)iy1*rh;
3482  Double_t x2ndc = (Double_t)ix2*rw;
3483  Double_t y2ndc = (Double_t)iy2*rh;
3484 
3485  // Ratios to convert user space in TRUE normalized space (NDC)
3486  Double_t rx1,ry1,rx2,ry2;
3487  gPad->GetRange(rx1,ry1,rx2,ry2);
3488  Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
3489  Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
3490 
3491  // The first part of the filled area is made of the graph points.
3492  // Make sure that two adjacent points are different.
3493  xf[0] = rx*(x[0]-rx1)+x1ndc;
3494  yf[0] = ry*(y[0]-ry1)+y1ndc;
3495  nf = 0;
3496  for (i=1; i<n; i++) {
3497  if (x[i]==x[i-1] && y[i]==y[i-1]) continue;
3498  nf++;
3499  xf[nf] = rx*(x[i]-rx1)+x1ndc;
3500  if (xf[i]==xf[i-1]) xf[i] += 0.000001; // add an epsilon to avoid exact vertical lines.
3501  yf[nf] = ry*(y[i]-ry1)+y1ndc;
3502  }
3503 
3504  // For each graph points a shifted points is computed to build up
3505  // the second part of the filled area. First and last points are
3506  // treated as special cases, outside of the loop.
3507  if (xf[1]==xf[0]) {
3508  a = TMath::PiOver2();
3509  } else {
3510  a = TMath::ATan((yf[1]-yf[0])/(xf[1]-xf[0]));
3511  }
3512  if (xf[0]<=xf[1]) {
3513  xt[0] = xf[0]-w*TMath::Sin(a);
3514  yt[0] = yf[0]+w*TMath::Cos(a);
3515  } else {
3516  xt[0] = xf[0]+w*TMath::Sin(a);
3517  yt[0] = yf[0]-w*TMath::Cos(a);
3518  }
3519 
3520  if (xf[nf]==xf[nf-1]) {
3521  a = TMath::PiOver2();
3522  } else {
3523  a = TMath::ATan((yf[nf]-yf[nf-1])/(xf[nf]-xf[nf-1]));
3524  }
3525  if (xf[nf]>=xf[nf-1]) {
3526  xt[nf] = xf[nf]-w*TMath::Sin(a);
3527  yt[nf] = yf[nf]+w*TMath::Cos(a);
3528  } else {
3529  xt[nf] = xf[nf]+w*TMath::Sin(a);
3530  yt[nf] = yf[nf]-w*TMath::Cos(a);
3531  }
3532 
3533  Double_t xi0,yi0,xi1,yi1,xi2,yi2;
3534  for (i=1; i<nf; i++) {
3535  xi0 = xf[i];
3536  yi0 = yf[i];
3537  xi1 = xf[i+1];
3538  yi1 = yf[i+1];
3539  xi2 = xf[i-1];
3540  yi2 = yf[i-1];
3541  if (xi1==xi0) {
3542  a1 = TMath::PiOver2();
3543  } else {
3544  a1 = TMath::ATan((yi1-yi0)/(xi1-xi0));
3545  }
3546  if (xi1<xi0) a1 = a1+3.14159;
3547  if (xi2==xi0) {
3548  a2 = TMath::PiOver2();
3549  } else {
3550  a2 = TMath::ATan((yi0-yi2)/(xi0-xi2));
3551  }
3552  if (xi0<xi2) a2 = a2+3.14159;
3553  x1 = xi0-w*TMath::Sin(a1);
3554  y1 = yi0+w*TMath::Cos(a1);
3555  x2 = xi0-w*TMath::Sin(a2);
3556  y2 = yi0+w*TMath::Cos(a2);
3557  xm = (x1+x2)*0.5;
3558  ym = (y1+y2)*0.5;
3559  if (xm==xi0) {
3560  a3 = TMath::PiOver2();
3561  } else {
3562  a3 = TMath::ATan((ym-yi0)/(xm-xi0));
3563  }
3564  x3 = xi0-w*TMath::Sin(a3+1.57079);
3565  y3 = yi0+w*TMath::Cos(a3+1.57079);
3566  // Rotate (x3,y3) by PI around (xi0,yi0) if it is not on the (xm,ym) side.
3567  if ((xm-xi0)*(x3-xi0)<0 && (ym-yi0)*(y3-yi0)<0) {
3568  x3 = 2*xi0-x3;
3569  y3 = 2*yi0-y3;
3570  }
3571  if ((xm==x1) && (ym==y1)) {
3572  x3 = xm;
3573  y3 = ym;
3574  }
3575  xt[i] = x3;
3576  yt[i] = y3;
3577  }
3578 
3579  // Close the polygon if the first and last points are the same
3580  if (xf[nf]==xf[0] && yf[nf]==yf[0]) {
3581  xm = (xt[nf]+xt[0])*0.5;
3582  ym = (yt[nf]+yt[0])*0.5;
3583  if (xm==xf[0]) {
3584  a3 = TMath::PiOver2();
3585  } else {
3586  a3 = TMath::ATan((ym-yf[0])/(xm-xf[0]));
3587  }
3588  x3 = xf[0]+w*TMath::Sin(a3+1.57079);
3589  y3 = yf[0]-w*TMath::Cos(a3+1.57079);
3590  if ((xm-xf[0])*(x3-xf[0])<0 && (ym-yf[0])*(y3-yf[0])<0) {
3591  x3 = 2*xf[0]-x3;
3592  y3 = 2*yf[0]-y3;
3593  }
3594  xt[nf] = x3;
3595  xt[0] = x3;
3596  yt[nf] = y3;
3597  yt[0] = y3;
3598  }
3599 
3600  // Find the crossing segments and remove the useless ones
3601  Double_t xc, yc, c1, b1, c2, b2;
3602  Bool_t cross = kFALSE;
3603  Int_t nf2 = nf;
3604  for (i=nf2; i>0; i--) {
3605  for (j=i-1; j>0; j--) {
3606  if (xt[i-1]==xt[i] || xt[j-1]==xt[j]) continue;
3607  c1 = (yt[i-1]-yt[i])/(xt[i-1]-xt[i]);
3608  b1 = yt[i]-c1*xt[i];
3609  c2 = (yt[j-1]-yt[j])/(xt[j-1]-xt[j]);
3610  b2 = yt[j]-c2*xt[j];
3611  if (c1 != c2) {
3612  xc = (b2-b1)/(c1-c2);
3613  yc = c1*xc+b1;
3614  if (xc>TMath::Min(xt[i],xt[i-1]) && xc<TMath::Max(xt[i],xt[i-1]) &&
3615  xc>TMath::Min(xt[j],xt[j-1]) && xc<TMath::Max(xt[j],xt[j-1]) &&
3616  yc>TMath::Min(yt[i],yt[i-1]) && yc<TMath::Max(yt[i],yt[i-1]) &&
3617  yc>TMath::Min(yt[j],yt[j-1]) && yc<TMath::Max(yt[j],yt[j-1])) {
3618  nf++; xf[nf] = xt[i]; yf[nf] = yt[i];
3619  nf++; xf[nf] = xc ; yf[nf] = yc;
3620  i = j;
3621  cross = kTRUE;
3622  break;
3623  } else {
3624  continue;
3625  }
3626  } else {
3627  continue;
3628  }
3629  }
3630  if (!cross) {
3631  nf++;
3632  xf[nf] = xt[i];
3633  yf[nf] = yt[i];
3634  }
3635  cross = kFALSE;
3636  }
3637  nf++; xf[nf] = xt[0]; yf[nf] = yt[0];
3638 
3639  // NDC to user coordinates
3640  for (i=0; i<nf+1; i++) {
3641  xf[i] = (1/rx)*(xf[i]-x1ndc)+rx1;
3642  yf[i] = (1/ry)*(yf[i]-y1ndc)+ry1;
3643  }
3644 
3645  // Draw filled area
3646  gPad->PaintFillArea(nf+1,xf,yf);
3647  theGraph->TAttLine::Modify(); // In case of PaintFillAreaHatches
3648 
3649  delete [] xf;
3650  delete [] yf;
3651  delete [] xt;
3652  delete [] yt;
3653 }
3654 
3655 
3656 ////////////////////////////////////////////////////////////////////////////////
3657 /// Paint the statistics box with the fit info.
3658 
3659 void TGraphPainter::PaintStats(TGraph *theGraph, TF1 *fit)
3660 {
3661 
3662  Int_t dofit;
3663  TPaveStats *stats = 0;
3664  TList *functions = theGraph->GetListOfFunctions();
3665  TIter next(functions);
3666  TObject *obj;
3667  while ((obj = next())) {
3668  if (obj->InheritsFrom(TPaveStats::Class())) {
3669  stats = (TPaveStats*)obj;
3670  break;
3671  }
3672  }
3673 
3674  if (stats) dofit = stats->GetOptFit();
3675  else dofit = gStyle->GetOptFit();
3676 
3677  if (!dofit) fit = 0;
3678  if (!fit) return;
3679  if (dofit == 1) dofit = 111;
3680  Int_t nlines = 0;
3681  Int_t print_fval = dofit%10;
3682  Int_t print_ferrors = (dofit/10)%10;
3683  Int_t print_fchi2 = (dofit/100)%10;
3684  Int_t print_fprob = (dofit/1000)%10;
3685  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
3686  if (fit) nlinesf += fit->GetNpar();
3687  Bool_t done = kFALSE;
3688  Double_t statw = 1.8*gStyle->GetStatW();
3689  Double_t stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
3690  if (stats) {
3691  stats->Clear();
3692  done = kTRUE;
3693  } else {
3694  stats = new TPaveStats(
3695  gStyle->GetStatX()-statw,
3696  gStyle->GetStatY()-stath,
3697  gStyle->GetStatX(),
3698  gStyle->GetStatY(),"brNDC");
3699 
3700  stats->SetParent(functions);
3701  stats->SetOptFit(dofit);
3702  stats->SetOptStat(0);
3703  stats->SetFillColor(gStyle->GetStatColor());
3704  stats->SetFillStyle(gStyle->GetStatStyle());
3706  stats->SetTextFont(gStyle->GetStatFont());
3707  if (gStyle->GetStatFont()%10 > 2)
3708  stats->SetTextSize(gStyle->GetStatFontSize());
3709  stats->SetFitFormat(gStyle->GetFitFormat());
3710  stats->SetStatFormat(gStyle->GetStatFormat());
3711  stats->SetName("stats");
3712 
3714  stats->SetTextAlign(12);
3715  stats->SetBit(kCanDelete);
3716  stats->SetBit(kMustCleanup);
3717  }
3718 
3719  char t[64];
3720  char textstats[50];
3721  Int_t ndf = fit->GetNDF();
3722  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
3723  snprintf(t,64,textstats,(Float_t)fit->GetChisquare());
3724  if (print_fchi2) stats->AddText(t);
3725  if (print_fprob) {
3726  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
3727  snprintf(t,64,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
3728  stats->AddText(t);
3729  }
3730  if (print_fval || print_ferrors) {
3731  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
3732  if (print_ferrors) {
3733  snprintf(textstats,50,"%-8s = %s%s #pm %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat(),"%",stats->GetFitFormat());
3734  snprintf(t,64,textstats,(Float_t)fit->GetParameter(ipar)
3735  ,(Float_t)fit->GetParError(ipar));
3736  } else {
3737  snprintf(textstats,50,"%-8s = %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat());
3738  snprintf(t,64,textstats,(Float_t)fit->GetParameter(ipar));
3739  }
3740  t[63] = 0;
3741  stats->AddText(t);
3742  }
3743  }
3744 
3745  if (!done) functions->Add(stats);
3746  stats->Paint();
3747 }
3748 
3749 
3750 ////////////////////////////////////////////////////////////////////////////////
3751 /// Smooth a curve given by N points.
3752 ///
3753 /// The original code is from an underlaying routine for Draw based on the
3754 /// CERN GD3 routine TVIPTE:
3755 ///
3756 /// Author - Marlow etc. Modified by - P. Ward Date - 3.10.1973
3757 ///
3758 /// This method draws a smooth tangentially continuous curve through
3759 /// the sequence of data points P(I) I=1,N where P(I)=(X(I),Y(I)).
3760 /// The curve is approximated by a polygonal arc of short vectors.
3761 /// The data points can represent open curves, P(1) != P(N) or closed
3762 /// curves P(2) == P(N). If a tangential discontinuity at P(I) is
3763 /// required, then set P(I)=P(I+1). Loops are also allowed.
3764 ///
3765 /// Reference Marlow and Powell, Harwell report No.R.7092.1972
3766 /// MCCONALOGUE, Computer Journal VOL.13, NO4, NOV1970P p392 6
3767 ///
3768 /// - npoints : Number of data points.
3769 /// - x : Abscissa
3770 /// - y : Ordinate
3771 
3772 void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_t *y, Int_t drawtype)
3773 {
3774 
3775  Int_t i, k, kp, km, npointsMax, banksize, n2, npt;
3776  Int_t maxiterations, finished;
3777  Int_t jtype, ktype, closed;
3778  Double_t sxmin, sxmax, symin, symax;
3779  Double_t delta;
3780  Double_t xorg, yorg;
3781  Double_t ratio_signs, xratio, yratio;
3782  Int_t flgic, flgis;
3783  Int_t iw, loptx;
3784  Double_t p1, p2, p3, p4, p5, p6;
3785  Double_t w1, w2, w3;
3786  Double_t a, b, c, r, s=0.0, t, z;
3787  Double_t co, so, ct, st, ctu, stu, xnt;
3788  Double_t dx1, dy1, dx2, dy2, dk1, dk2;
3789  Double_t xo, yo, dx, dy, xt, yt;
3790  Double_t xa, xb, ya, yb;
3791  Double_t u1, u2, u3, tj;
3792  Double_t cc, err;
3793  Double_t sb, sth;
3794  Double_t wsign, tsquare, tcube;
3795  c = t = co = so = ct = st = ctu = stu = dx1 = dy1 = dx2 = dy2 = 0;
3796  xt = yt = xa = xb = ya = yb = u1 = u2 = u3 = tj = sb = 0;
3797 
3798  npointsMax = npoints*10;
3799  n2 = npointsMax-2;
3800  banksize = n2;
3801 
3802  Double_t *qlx = new Double_t[npointsMax];
3803  Double_t *qly = new Double_t[npointsMax];
3804  if (!qlx || !qly) {
3805  Error("Smooth", "not enough space in memory");
3806  return;
3807  }
3808 
3809  // Decode the type of curve (draw type).
3810 
3811  loptx = kFALSE;
3812  jtype = (drawtype%1000)-10;
3813  if (jtype > 0) { ktype = jtype; loptx = kTRUE; }
3814  else ktype = drawtype%1000;
3815 
3816  Double_t ruxmin = gPad->GetUxmin();
3817  Double_t ruymin = gPad->GetUymin();
3818  if (ktype == 3) {
3819  xorg = ruxmin;
3820  yorg = ruymin;
3821  } else {
3822  xorg = TMath::Max((Double_t)0,ruxmin);
3823  yorg = TMath::Min(TMath::Max((Double_t)0,ruymin),gPad->GetUymax());
3824  }
3825 
3826  // delta is the accuracy required in constructing the curve.
3827  // If it is zero then the routine calculates a value otherwise
3828  // it uses this value. (default is 0.0)
3829 
3830  delta = 0.00055;
3831  maxiterations = 20;
3832 
3833  // Scale data to the range 0-ratio_signs in X, 0-1 in Y
3834  // where ratio_signs is the ratio between the number of changes
3835  // of sign in Y divided by the number of changes of sign in X
3836 
3837  sxmin = x[0];
3838  sxmax = x[0];
3839  symin = y[0];
3840  symax = y[0];
3841  Double_t six = 1;
3842  Double_t siy = 1;
3843  for (i=1;i<npoints;i++) {
3844  if (i > 1) {
3845  if ((x[i]-x[i-1])*(x[i-1]-x[i-2]) < 0) six++;
3846  if ((y[i]-y[i-1])*(y[i-1]-y[i-2]) < 0) siy++;
3847  }
3848  if (x[i] < sxmin) sxmin = x[i];
3849  if (x[i] > sxmax) sxmax = x[i];
3850  if (y[i] < symin) symin = y[i];
3851  if (y[i] > symax) symax = y[i];
3852  }
3853  closed = 0;
3854  Double_t dx1n = TMath::Abs(x[npoints-1]-x[0]);
3855  Double_t dy1n = TMath::Abs(y[npoints-1]-y[0]);
3856  if (dx1n < 0.01*(sxmax-sxmin) && dy1n < 0.01*(symax-symin)) closed = 1;
3857  if (sxmin == sxmax) {
3858  xratio = 1;
3859  } else {
3860  if (six > 1) ratio_signs = siy/six;
3861  else ratio_signs = 20;
3862  xratio = ratio_signs/(sxmax-sxmin);
3863  }
3864  if (symin == symax) yratio = 1;
3865  else yratio = 1/(symax-symin);
3866 
3867  qlx[0] = x[0];
3868  qly[0] = y[0];
3869  for (i=0;i<npoints;i++) {
3870  x[i] = (x[i]-sxmin)*xratio;
3871  y[i] = (y[i]-symin)*yratio;
3872  }
3873 
3874  // "finished" is minus one if we must draw a straight line from P(k-1)
3875  // to P(k). "finished" is one if the last call to PaintPolyLine has < n2
3876  // points. "finished" is zero otherwise. npt counts the X and Y
3877  // coordinates in work . When npt=n2 a call to IPL is made.
3878 
3879  finished = 0;
3880  npt = 1;
3881  k = 1;
3882 
3883  // Convert coordinates back to original system
3884 
3885  // Separate the set of data points into arcs P(k-1),P(k).
3886  // Calculate the direction cosines. first consider whether
3887  // there is a continuous tangent at the endpoints.
3888 
3889  if (!closed) {
3890  if (x[0] != x[npoints-1] || y[0] != y[npoints-1]) goto L40;
3891  if (x[npoints-2] == x[npoints-1] && y[npoints-2] == y[npoints-1]) goto L40;
3892  if (x[0] == x[1] && y[0] == y[1]) goto L40;
3893  }
3894  flgic = kFALSE;
3895  flgis = kTRUE;
3896 
3897  // flgic is true if the curve is open and false if it is closed.
3898  // flgis is true in the main loop, but is false if there is
3899  // a deviation from the main loop.
3900 
3901  km = npoints - 1;
3902 
3903  // Calculate direction cosines at P(1) using P(N-1),P(1),P(2).
3904 
3905  goto L100;
3906 L40:
3907  flgic = kTRUE;
3908  flgis = kFALSE;
3909 
3910  // Skip excessive consecutive equal points.
3911 
3912 L50:
3913  if (k >= npoints) {
3914  finished = 1; // Prepare to clear out remaining short vectors before returning
3915  if (npt > 1) goto L310;
3916  goto L390;
3917  }
3918  k++;
3919  if (x[k-1] == x[k-2] && y[k-1] == y[k-2]) goto L50;
3920 L60:
3921  km = k-1;
3922  if (k > npoints) {
3923  finished = 1; // Prepare to clear out remaining short vectors before returning
3924  if (npt > 1) goto L310;
3925  goto L390;
3926  }
3927  if (k < npoints) goto L90;
3928  if (!flgic) { kp = 2; goto L130;}
3929 
3930 L80:
3931  if (flgis) goto L150;
3932 
3933  // Draw a straight line from P(k-1) to P(k).
3934 
3935  finished = -1;
3936  goto L170;
3937 
3938  // Test whether P(k) is a cusp.
3939 
3940 L90:
3941  if (x[k-1] == x[k] && y[k-1] == y[k]) goto L80;
3942 L100:
3943  kp = k+1;
3944  goto L130;
3945 
3946  // Branch if the next section of the curve begins at a cusp.
3947 
3948 L110:
3949  if (!flgis) goto L50;
3950 
3951  // Carry forward the direction cosines from the previous arc.
3952 
3953 L120:
3954  co = ct;
3955  so = st;
3956  k++;
3957  goto L60;
3958 
3959  // Calculate the direction cosines at P(k). If k=1 then
3960  // N-1 is used for k-1. If k=N then 2 is used for k+1.
3961  // direction cosines at P(k) obtained from P(k-1),P(k),P(k+1).
3962 
3963 L130:
3964  dx1 = x[k-1] - x[km-1];
3965  dy1 = y[k-1] - y[km-1];
3966  dk1 = dx1*dx1 + dy1*dy1;
3967  dx2 = x[kp-1] - x[k-1];
3968  dy2 = y[kp-1] - y[k-1];
3969  dk2 = dx2*dx2 + dy2*dy2;
3970  ctu = dx1*dk2 + dx2*dk1;
3971  stu = dy1*dk2 + dy2*dk1;
3972  xnt = ctu*ctu + stu*stu;
3973 
3974  // If both ctu and stu are zero,then default.This can
3975  // occur when P(k)=P(k+1). I.E. A loop.
3976 
3977  if (xnt < 1.E-25) {
3978  ctu = dy1;
3979  stu =-dx1;
3980  xnt = dk1;
3981  }
3982  // Normalise direction cosines.
3983 
3984  ct = ctu/TMath::Sqrt(xnt);
3985  st = stu/TMath::Sqrt(xnt);
3986  if (flgis) goto L160;
3987 
3988  // Direction cosines at P(k-1) obtained from P(k-1),P(k),P(k+1).
3989 
3990  w3 = 2*(dx1*dy2-dx2*dy1);
3991  co = ctu+w3*dy1;
3992  so = stu-w3*dx1;
3993  xnt = 1/TMath::Sqrt(co*co+so*so);
3994  co = co*xnt;
3995  so = so*xnt;
3996  flgis = kTRUE;
3997  goto L170;
3998 
3999  // Direction cosines at P(k) obtained from P(k-2),P(k-1),P(k).
4000 
4001 L150:
4002  w3 = 2*(dx1*dy2-dx2*dy1);
4003  ct = ctu-w3*dy2;
4004  st = stu+w3*dx2;
4005  xnt = 1/TMath::Sqrt(ct*ct+st*st);
4006  ct = ct*xnt;
4007  st = st*xnt;
4008  flgis = kFALSE;
4009  goto L170;
4010 L160:
4011  if (k <= 1) goto L120;
4012 
4013  // For the arc between P(k-1) and P(k) with direction cosines co,
4014  // so and ct,st respectively, calculate the coefficients of the
4015  // parametric cubic represented by X(t) and Y(t) where
4016  // X(t)=xa*t**3 + xb*t**2 + co*t + xo
4017  // Y(t)=ya*t**3 + yb*t**2 + so*t + yo
4018 
4019 L170:
4020  xo = x[k-2];
4021  yo = y[k-2];
4022  dx = x[k-1] - xo;
4023  dy = y[k-1] - yo;
4024 
4025  // Initialise the values of X(TI),Y(TI) in xt and yt respectively.
4026 
4027  xt = xo;
4028  yt = yo;
4029  if (finished < 0) { // Draw a straight line between (xo,yo) and (xt,yt)
4030  xt += dx;
4031  yt += dy;
4032  goto L300;
4033  }
4034  c = dx*dx+dy*dy;
4035  a = co+ct;
4036  b = so+st;
4037  r = dx*a+dy*b;
4038  t = c*6/(TMath::Sqrt(r*r+2*(7-co*ct-so*st)*c)+r);
4039  tsquare = t*t;
4040  tcube = t*tsquare;
4041  xa = (a*t-2*dx)/tcube;
4042  xb = (3*dx-(co+a)*t)/tsquare;
4043  ya = (b*t-2*dy)/tcube;
4044  yb = (3*dy-(so+b)*t)/tsquare;
4045 
4046  // If the curve is close to a straight line then use a straight
4047  // line between (xo,yo) and (xt,yt).
4048 
4049  if (.75*TMath::Max(TMath::Abs(dx*so-dy*co),TMath::Abs(dx*st-dy*ct)) <= delta) {
4050  finished = -1;
4051  xt += dx;
4052  yt += dy;
4053  goto L300;
4054  }
4055 
4056  // Calculate a set of values 0 == t(0).LTCT(1) < ... < t(M)=TC
4057  // such that polygonal arc joining X(t(J)),Y(t(J)) (J=0,1,..M)
4058  // is within the required accuracy of the curve
4059 
4060  tj = 0;
4061  u1 = ya*xb-yb*xa;
4062  u2 = yb*co-xb*so;
4063  u3 = so*xa-ya*co;
4064 
4065  // Given t(J), calculate t(J+1). The values of X(t(J)),
4066  // Y(t(J)) t(J) are contained in xt,yt and tj respectively.
4067 
4068 L180:
4069  s = t - tj;
4070  iw = -2;
4071 
4072  // Define iw here later.
4073 
4074  p1 = (2*u1)*tj-u3;
4075  p2 = (u1*tj-u3)*3*tj+u2;
4076  p3 = 3*tj*ya+yb;
4077  p4 = (p3+yb)*tj+so;
4078  p5 = 3*tj*xa+xb;
4079  p6 = (p5+xb)*tj+co;
4080 
4081  // Test D(tj,THETA). A is set to (Y(tj+s)-Y(tj))/s.b is
4082  // set to (X(tj+s)-X(tj))/s.
4083 
4084  cc = 0.8209285;
4085  err = 0.1209835;
4086 L190:
4087  iw -= 2;
4088 L200:
4089  a = (s*ya+p3)*s+p4;
4090  b = (s*xa+p5)*s+p6;
4091 
4092  // Set z to PSI(D/delta)-cc.
4093 
4094  w1 = -s*(s*u1+p1);
4095  w2 = s*s*u1-p2;
4096  w3 = 1.5*w1+w2;
4097 
4098  // Set the estimate of (THETA-tj)/s.Then set the numerator
4099  // of the expression (EQUATION 4.4)/s. Then set the square
4100  // of D(tj,tj+s)/delta. Then replace z by PSI(D/delta)-cc.
4101 
4102  if (w3 > 0) wsign = TMath::Abs(w1);
4103  else wsign = -TMath::Abs(w1);
4104  sth = 0.5+wsign/(3.4*TMath::Abs(w1)+5.2*TMath::Abs(w3));
4105  z = s*sth*(s-s*sth)*(w1*sth+w1+w2);
4106  z = z*z/((a*a+b*b)*(delta*delta));
4107  z = (z+2.642937)*z/((.3715652*z+3.063444)*z+.2441889)-cc;
4108 
4109  // Branch if z has been calculated
4110 
4111  if (iw > 0) goto L250;
4112  if (z > err) goto L240;
4113  goto L220;
4114 L210:
4115  iw -= 2;
4116 L220:
4117  if (iw+2 == 0) goto L190;
4118  if (iw+2 > 0) goto L290;
4119 
4120  // Last part of arc.
4121 
4122 L230:
4123  xt = x[k-1];
4124  yt = y[k-1];
4125  s = 0;
4126  goto L300;
4127 
4128  // z(s). find a value of s where 0 <= s <= sb such that
4129  // TMath::Abs(z(s)) < err
4130 
4131 L240:
4132  kp = 0;
4133  c = z;
4134  sb = s;
4135 L250:
4136  theGraph->Zero(kp,0,sb,err,s,z,maxiterations);
4137  if (kp == 2) goto L210;
4138  if (kp > 2) {
4139  Error("Smooth", "Attempt to plot outside plot limits");
4140  goto L230;
4141  }
4142  if (iw > 0) goto L200;
4143 
4144  // Set z=z(s) for s=0.
4145 
4146  if (iw < 0) {
4147  z = -cc;
4148  iw = 0;
4149  goto L250;
4150  }
4151 
4152  // Set z=z(s) for s=sb.
4153 
4154  z = c;
4155  iw = 1;
4156  goto L250;
4157 
4158  // Update tj,xt and yt.
4159 
4160 L290:
4161  xt = xt + s*b;
4162  yt = yt + s*a;
4163  tj = s + tj;
4164 
4165  // Convert coordinates to original system
4166 
4167 L300:
4168  qlx[npt] = sxmin + xt/xratio;
4169  qly[npt] = symin + yt/yratio;
4170  npt++;
4171 
4172  // If a fill area must be drawn and if the banks LX and
4173  // LY are too small they are enlarged in order to draw
4174  // the filled area in one go.
4175 
4176  if (npt < banksize) goto L320;
4177  if (drawtype >= 1000 || ktype > 1) {
4178  Int_t newsize = banksize + n2;
4179  Double_t *qtemp = new Double_t[banksize];
4180  for (i=0;i<banksize;i++) qtemp[i] = qlx[i];
4181  delete [] qlx;
4182  qlx = new Double_t[newsize];
4183  for (i=0;i<banksize;i++) qlx[i] = qtemp[i];
4184  for (i=0;i<banksize;i++) qtemp[i] = qly[i];
4185  delete [] qly;
4186  qly = new Double_t[newsize];
4187  for (i=0;i<banksize;i++) qly[i] = qtemp[i];
4188  delete [] qtemp;
4189  banksize = newsize;
4190  goto L320;
4191  }
4192 
4193  // Draw the graph
4194 
4195 L310:
4196  if (drawtype >= 1000) {
4197  gPad->PaintFillArea(npt,qlx,qly, "B");
4198  } else {
4199  if (ktype > 1) {
4200  if (!loptx) {
4201  qlx[npt] = qlx[npt-1];
4202  qlx[npt+1] = qlx[0];
4203  qly[npt] = yorg;
4204  qly[npt+1] = yorg;
4205  } else {
4206  qlx[npt] = xorg;
4207  qlx[npt+1] = xorg;
4208  qly[npt] = qly[npt-1];
4209  qly[npt+1] = qly[0];
4210  }
4211  gPad->PaintFillArea(npt+2,qlx,qly);
4212  }
4213  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, qlx, qly);
4214  gPad->PaintPolyLine(npt,qlx,qly);
4215  }
4216  npt = 1;
4217  qlx[0] = sxmin + xt/xratio;
4218  qly[0] = symin + yt/yratio;
4219 L320:
4220  if (finished > 0) goto L390;
4221  if (finished < 0) { finished = 0; goto L110;}
4222  if (s > 0) goto L180;
4223  goto L110;
4224 
4225  // Convert coordinates back to original system
4226 
4227 L390:
4228  for (i=0;i<npoints;i++) {
4229  x[i] = sxmin + x[i]/xratio;
4230  y[i] = symin + y[i]/yratio;
4231  }
4232 
4233  delete [] qlx;
4234  delete [] qly;
4235 }
4236 
4237 ////////////////////////////////////////////////////////////////////////////////
4238 /// Static function to set `fgMaxPointsPerLine` for graph painting. When graphs
4239 /// are painted with lines, they are split into chunks of length `fgMaxPointsPerLine`.
4240 /// This allows to paint line with an "infinite" number of points. In some case
4241 /// this "chunks painting" technic may create artefacts at the chunk's boundaries.
4242 /// For instance when zooming deeply in a PDF file. To avoid this effect it might
4243 /// be necessary to increase the chunks' size using this function:
4244 /// `TGraphPainter::SetMaxPointsPerLine(20000)`.
4245 
4247 {
4248  fgMaxPointsPerLine = maxp;
4249  if (maxp < 50) fgMaxPointsPerLine = 50;
4250 }
virtual Bool_t IsEditable() const
Definition: TGraph.h:153
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Double_t GetYq2() const
Definition: TGraphQQ.h:43
virtual Double_t GetMaximumStored() const
Definition: TH1.h:283
void SetTickLength(Float_t ticklength)
Definition: TGaxis.h:120
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:44
Color_t GetStatColor() const
Definition: TStyle.h:241
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7807
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:843
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5663
Color_t GetLabelColor(Option_t *axis="X") const
Return the label color number in the axis.
Definition: TStyle.cxx:743
float xmin
Definition: THbookFile.cxx:93
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:294
Double_t * GetEX() const
Definition: TGraphErrors.h:66
virtual void SetName(const char *name="")
Definition: TPave.h:72
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:234
virtual Double_t * GetEX() const
Definition: TGraph.h:131
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:390
Float_t GetLabelSize(Option_t *axis="X") const
Return label size.
Definition: TStyle.cxx:779
static double p3(double t, double a, double b, double c, double d)
virtual Int_t DistancetoPrimitiveHelper(TGraph *theGraph, Int_t px, Int_t py)
Compute distance from point px,py to a graph.
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
virtual void ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Double_t GetRMin()
Color_t GetTitleTextColor() const
Definition: TStyle.h:256
void PaintPolyLineHatches(TGraph *theGraph, Int_t n, const Double_t *x, const Double_t *y)
Paint a polyline with hatches on one side showing an exclusion zone.
void Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_t *y, Int_t drawtype)
Smooth a curve given by N points.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes distance from point (px,py) to the object.
Definition: TObject.cxx:186
float Float_t
Definition: RtypesCore.h:53
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8194
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
const char Option_t
Definition: RtypesCore.h:62
static Int_t fgMaxPointsPerLine
Definition: TGraphPainter.h:59
Color_t GetAxisColor(Option_t *axis="X") const
Return the axis color number in the axis.
Definition: TStyle.cxx:723
return c1
Definition: legend1.C:41
float ymin
Definition: THbookFile.cxx:93
void PaintCircle(Double_t x, Double_t y, Double_t r, Double_t phimin, Double_t phimax, Double_t theta)
This is simplified from TEllipse::PaintEllipse.
virtual Double_t * GetEYlow() const
Definition: TGraph.h:136
Create a Box.
Definition: TBox.h:24
double Axis_t
Definition: RtypesCore.h:72
virtual Double_t GetMinimumStored() const
Definition: TH1.h:287
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:638
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
#define mark(osub)
Definition: triangle.c:1206
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:285
virtual Color_t GetAxisColor() const
Definition: TAttAxis.h:37
TH1 * h
Definition: legend2.C:5
static constexpr double km
virtual Double_t * GetEXhighd() const
Definition: TGraph.h:138
void Draw(Option_t *options="")
Draw Polargram.
TList * GetListOfFunctions() const
Definition: TGraph.h:116
TAxis * GetYaxis() const
Get y axis of the graph.
Definition: TGraph.cxx:1602
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:183
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1112
virtual Double_t * GetEY() const
Definition: TGraph.h:132
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:391
#define N
#define gROOT
Definition: TROOT.h:402
Float_t GetEndErrorSize() const
Definition: TStyle.h:171
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Basic string class.
Definition: TString.h:125
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:567
void PaintStats(TGraph *theGraph, TF1 *fit)
Paint the statistics box with the fit info.
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
void SetOptionAxis(Bool_t opt)
Definition: TGraphPolar.h:49
The histogram statistics painter class.
Definition: TPaveStats.h:18
virtual Int_t GetNdivisions(Option_t *axis="X") const
Return the number of divisions for "axis".
Definition: Haxis.cxx:27
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1815
void PaintGraphPolar(TGraph *theGraph, Option_t *option)
[Paint this TGraphPolar with its current attributes.]($GP04)
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
Float_t GetTitleY() const
Definition: TStyle.h:265
static void SetMaxPointsPerLine(Int_t maxp=50)
Static function to set fgMaxPointsPerLine for graph painting.
virtual ~TGraphPainter()
Destructor.
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
static constexpr double rad
Double_t * gxworkl
don&#39;t draw the histogram title
Definition: TH1.h:165
const char * GetFitFormat() const
Definition: TStyle.h:185
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels The distance is expressed in per cent of the pad width...
Definition: TAttAxis.cxx:193
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
Style_t GetLabelFont(Option_t *axis="X") const
Return label font.
Definition: TStyle.cxx:755
don&#39;t draw stats box
Definition: TH1.h:160
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:624
Iterator of linked list.
Definition: TList.h:197
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:627
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:257
if object in a list can be deleted
Definition: TObject.h:58
This class allows to draw quantile-quantile plots.
Definition: TGraphQQ.h:18
TGraphPainter()
Default constructor.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
Double_t GetTMin()
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
Int_t GetTitleAlign()
Definition: TStyle.h:254
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
double sqrt(double)
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:1774
Double_t GetXmin() const
Definition: TAxis.h:133
static const double x2[5]
Double_t GetYsize()
Return size of the formula along Y in pad coordinates.
Definition: TLatex.cxx:2601
void PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option)
Paint this TGraphAsymmErrors with its current attributes.
virtual void DrawPanelHelper(TGraph *theGraph)
Display a panel with all histogram drawing options.
Double_t x[n]
Definition: legend1.C:17
Float_t GetTitleFontSize() const
Definition: TStyle.h:258
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
void Class()
Definition: Class.C:29
TArrow * arrow
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:411
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:312
Double_t GetXq2() const
Definition: TGraphQQ.h:41
Double_t GetXq1() const
Definition: TGraphQQ.h:40
To draw Mathematical Formula.
Definition: TLatex.h:18
Int_t GetOptFit() const
Definition: TStyle.h:228
Double_t Log10(Double_t x)
Definition: TMath.h:651
void Zero(Int_t &k, Double_t AZ, Double_t BZ, Double_t E2, Double_t &X, Double_t &Y, Int_t maxiterations)
Find zero of a continuous function.
Definition: TGraph.cxx:2443
const Int_t kMaxPixel
Definition: GuiTypes.h:368
static double p2(double t, double a, double b, double c)
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
TString & Append(const char *cs)
Definition: TString.h:495
TGraphPolargram * GetPolargram()
Definition: TGraphPolar.h:39
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:209
Base class for several text objects.
Definition: TText.h:23
Float_t GetStatX() const
Definition: TStyle.h:248
Float_t GetTitleX() const
Definition: TStyle.h:264
virtual void Show()
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
Definition: TMath.h:1204
Float_t GetBarWidth() const
Definition: TStyle.h:169
constexpr Double_t Pi()
Definition: TMath.h:40
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
Style_t GetStatStyle() const
Definition: TStyle.h:246
virtual Color_t GetLabelColor() const
Definition: TAttAxis.h:38
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:108
Bool_t GetOptionAxis()
Definition: TGraphPolar.h:42
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual void PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
This is a service method used by THistPainter to paint 1D histograms.
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
virtual char * GetObjectInfoHelper(TGraph *theGraph, Int_t px, Int_t py) const
A doubly linked list.
Definition: TList.h:44
virtual void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition: TLine.cxx:380
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:513
void PaintHelper(TGraph *theGraph, Option_t *option)
Paint a any kind of TGraph.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2707
virtual Double_t * GetEYhighd() const
Definition: TGraph.h:140
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
To draw a polar graph.
Definition: TGraphPolar.h:22
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:738
void PaintGraphErrors(TGraph *theGraph, Option_t *option)
[Paint this TGraphErrors with its current attributes.]($GP03)
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
ROOT::R::TRInterface & r
Definition: Object.C:4
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2514
Float_t GetTitleH() const
Definition: TStyle.h:267
void PaintGraphQQ(TGraph *theGraph, Option_t *option)
Paint this graphQQ. No options for the time being.
Double_t * gywork
Style_t GetStatFont() const
Definition: TStyle.h:244
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
auto * a
Definition: textangle.C:12
Float_t GetStatY() const
Definition: TStyle.h:249
Float_t GetStatW() const
Definition: TStyle.h:250
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
void PaintGraphBentErrors(TGraph *theGraph, Option_t *option)
[Paint this TGraphBentErrors with its current attributes.]($GP03)
virtual void PaintArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Float_t arrowsize=0.05, Option_t *option=">")
Draw this arrow.
Definition: TArrow.cxx:173
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
A simple line.
Definition: TLine.h:23
Int_t GetN() const
Definition: TGraph.h:122
To draw polar axis.
The axis painter class.
Definition: TGaxis.h:24
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
TAxis * GetYaxis()
Definition: TH1.h:316
Double_t * GetEY() const
Definition: TGraphErrors.h:67
Double_t * gyworkl
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:286
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
Double_t GetTMax()
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition: TAttAxis.cxx:163
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
virtual void PaintBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Option_t *option="")
Draw this box with new coordinates.
Definition: TBox.cxx:627
Double_t GetMaximum() const
Definition: TGraph.h:141
#define gVirtualX
Definition: TVirtualX.h:350
constexpr Double_t E()
Definition: TMath.h:74
Define a Frame.
Definition: TFrame.h:19
Double_t Cos(Double_t)
Definition: TMath.h:550
Color_t GetTitleFillColor() const
Definition: TStyle.h:255
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:7892
TAxis * GetXaxis() const
Get x axis of the graph.
Definition: TGraph.cxx:1592
const Bool_t kFALSE
Definition: RtypesCore.h:88
Double_t * GetX() const
Definition: TGraph.h:129
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual Double_t * GetEXlowd() const
Definition: TGraph.h:137
void ComputeLogs(Int_t npoints, Int_t opt)
Compute the logarithm of global variables gxwork and gywork according to the value of Options and put...
Width_t GetTitleBorderSize() const
Definition: TStyle.h:259
Float_t GetTitleW() const
Definition: TStyle.h:266
Double_t GetChisquare() const
Definition: TF1.h:428
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
virtual Double_t * GetEYlowd() const
Definition: TGraph.h:139
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:107
return c2
Definition: legend2.C:14
static const double x1[5]
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
#define ClassImp(name)
Definition: Rtypes.h:359
TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases...
Definition: TGraph.cxx:1469
void SetDrawBorder(Int_t drawborder=1)
Definition: TStyle.h:317
Double_t * gxwork
double Double_t
Definition: RtypesCore.h:55
virtual Double_t * GetEXlow() const
Definition: TGraph.h:134
unsigned long ULong_t
Definition: RtypesCore.h:51
Int_t GetDrawBorder() const
Definition: TStyle.h:170
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Double_t ey[n]
Definition: legend1.C:17
void SetLabelFont(Int_t labelfont)
Definition: TGaxis.h:106
Int_t DistancetoLine(Int_t px, Int_t py, Double_t xp1, Double_t yp1, Double_t xp2, Double_t yp2)
Compute distance from point px,py to a line.
Definition: TAttLine.cxx:196
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:570
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Abstract base class used by ROOT graphics editor.
virtual void PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
[Control function to draw a graph.]($GP01)
Width_t GetStatBorderSize() const
Definition: TStyle.h:243
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
Double_t GetRMax()
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
Float_t GetStatFontSize() const
Definition: TStyle.h:245
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual Int_t GetNpar() const
Definition: TF1.h:465
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2184
virtual void Paint(Option_t *chopt="")
Draw this axis with its current attributes.
Definition: TGaxis.cxx:717
Double_t * GetY() const
Definition: TGraph.h:130
Float_t GetTickLength(Option_t *axis="X") const
Return tick length.
Definition: TStyle.cxx:819
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:496
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
Float_t GetStatH() const
Definition: TStyle.h:251
1-Dim function class
Definition: TF1.h:211
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Double_t Sin(Double_t)
Definition: TMath.h:547
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:119
Float_t GetLabelOffset(Option_t *axis="X") const
Return label offset.
Definition: TStyle.cxx:767
#define snprintf
Definition: civetweb.c:822
Double_t * GetXpol()
Return points in polar coordinates.
void SetLabelColor(Int_t labelcolor)
Definition: TGaxis.h:105
#define gPad
Definition: TVirtualPad.h:285
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length The length is expressed in per cent of the pad width.
Definition: TAttAxis.cxx:280
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
The graph painter class.
Definition: TGraphPainter.h:29
virtual void SetHistogram(TH1F *h)
Definition: TGraph.h:168
virtual void Paint(Option_t *option="")
Paint the pave stat.
Definition: TPaveStats.cxx:320
Float_t GetBarOffset() const
Definition: TStyle.h:168
Style_t GetTitleStyle() const
Definition: TStyle.h:257
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
Definition: first.py:1
Double_t GetYq1() const
Definition: TGraphQQ.h:42
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
Color_t GetStatTextColor() const
Definition: TStyle.h:242
virtual Double_t * GetEYhigh() const
Definition: TGraph.h:135
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
Compute the x/y range of the points in this graph.
Definition: TGraph.cxx:645
Int_t GetNdivisions(Option_t *axis="X") const
Return number of divisions.
Definition: TStyle.cxx:711
Draw all kinds of Arrows.
Definition: TArrow.h:29
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
Double_t * GetYpol()
Return points in polar coordinates.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
Double_t GetMinimum() const
Definition: TGraph.h:142
const Bool_t kTRUE
Definition: RtypesCore.h:87
TF1 * GetF() const
Definition: TGraphQQ.h:44
Double_t GetXmax() const
Definition: TAxis.h:134
Double_t ex[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
Line Attributes class.
Definition: TAttLine.h:18
clip to the frame boundary
Definition: TGraph.h:70
constexpr Double_t PiOver2()
Definition: TMath.h:48
virtual Double_t * GetEXhigh() const
Definition: TGraph.h:133
void PaintGraphSimple(TGraph *theGraph, Option_t *option)
Paint a simple graph, without errors bars.
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:70
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
virtual Style_t GetLabelFont() const
Definition: TAttAxis.h:39
const char * GetStatFormat() const
Definition: TStyle.h:247
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
void PaintGraphReverse(TGraph *theGraph, Option_t *option)
Paint theGraph reverting values along X and/or Y axis. a new graph is created.
void SetParent(TObject *obj)
Definition: TPaveStats.h:52
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:303
Int_t GetOptTitle() const
Definition: TStyle.h:230
static const double x3[11]
const char * Data() const
Definition: TString.h:345
Double_t ATan(Double_t)
Definition: TMath.h:577
void SetPolargram(TGraphPolargram *p)
Definition: TGraphPolar.h:50