Logo ROOT   6.14/05
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 }
539 
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Destructor.
543 
545 {
546 }
547 
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 
560 {
561 
562 
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 
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 
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  // Paint the fit parameters if needed.
1028  TF1 *fit = 0;
1029  TList *functions = theGraph->GetListOfFunctions();
1030  TObject *f;
1031  if (functions) {
1032  f = (TF1*)functions->First();
1033  if (f) {
1034  if (f->InheritsFrom(TF1::Class())) fit = (TF1*)f;
1035  }
1036  TIter next(functions);
1037  while ((f = (TObject*) next())) {
1038  if (f->InheritsFrom(TF1::Class())) {
1039  fit = (TF1*)f;
1040  break;
1041  }
1042  }
1043  }
1044  if (fit) PaintStats(theGraph, fit);
1045 
1046  }
1047 }
1048 
1049 
1050 ////////////////////////////////////////////////////////////////////////////////
1051 /// [Control function to draw a graph.]($GP01)
1052 
1053 void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
1054 {
1055 
1056  if (theGraph->InheritsFrom("TGraphPolar"))
1057  gPad->PushSelectableObject(theGraph);
1058 
1059  Int_t optionLine , optionAxis , optionCurve , optionStar , optionMark;
1060  Int_t optionBar , optionR , optionOne , optionE;
1061  Int_t optionFill , optionZ , optionCurveFill, optionIAxis;
1062  Int_t i, npt, nloop;
1063  Int_t drawtype=0;
1064  Double_t xlow, xhigh, ylow, yhigh;
1065  Double_t barxmin, barxmax, barymin, barymax;
1066  Double_t uxmin, uxmax;
1067  Double_t x1, xn, y1, yn;
1068  Double_t dbar, bdelta;
1069  Int_t theNpoints = theGraph->GetN();
1070 
1071  if (npoints <= 0) {
1072  Error("PaintGraph", "illegal number of points (%d)", npoints);
1073  return;
1074  }
1075  TString opt = chopt;
1076  opt.ToUpper();
1077  opt.ReplaceAll("SAME","");
1078 
1079  if (opt.Contains("L")) optionLine = 1; else optionLine = 0;
1080  if (opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
1081  if (opt.Contains("C")) optionCurve = 1; else optionCurve = 0;
1082  if (opt.Contains("*")) optionStar = 1; else optionStar = 0;
1083  if (opt.Contains("P")) optionMark = 1; else optionMark = 0;
1084  if (opt.Contains("B")) optionBar = 1; else optionBar = 0;
1085  if (opt.Contains("R")) optionR = 1; else optionR = 0;
1086  if (opt.Contains("1")) optionOne = 1; else optionOne = 0;
1087  if (opt.Contains("F")) optionFill = 1; else optionFill = 0;
1088  if (opt.Contains("I")) optionIAxis = 1; else optionIAxis = 0;
1089  if (opt.Contains("2") || opt.Contains("3") ||
1090  opt.Contains("4") || opt.Contains("5")) optionE = 1; else optionE = 0;
1091  optionZ = 0;
1092 
1093  // If no "drawing" option is selected and if chopt<>' ' nothing is done.
1094  if (optionLine+optionFill+optionCurve+optionStar+optionMark+optionBar+optionE == 0) {
1095  if (!chopt[0]) optionLine=1;
1096  else return;
1097  }
1098 
1099  if (optionStar) theGraph->SetMarkerStyle(3);
1100 
1101  optionCurveFill = 0;
1102  if (optionCurve && optionFill) {
1103  optionCurveFill = 1;
1104  optionFill = 0;
1105  }
1106 
1107  // Draw the Axis.
1108  Double_t rwxmin,rwxmax, rwymin, rwymax, maximum, minimum, dx, dy;
1109  if (optionAxis) {
1110  if (theGraph->GetHistogram()) {
1111  rwxmin = gPad->GetUxmin();
1112  rwxmax = gPad->GetUxmax();
1113  rwymin = gPad->GetUymin();
1114  rwymax = gPad->GetUymax();
1115  minimum = theGraph->GetHistogram()->GetMinimumStored();
1116  maximum = theGraph->GetHistogram()->GetMaximumStored();
1117  if (minimum == -1111) { //this can happen after unzooming
1118  minimum = theGraph->GetHistogram()->GetYaxis()->GetXmin();
1119  theGraph->GetHistogram()->SetMinimum(minimum);
1120  }
1121  if (maximum == -1111) {
1122  maximum = theGraph->GetHistogram()->GetYaxis()->GetXmax();
1123  theGraph->GetHistogram()->SetMaximum(maximum);
1124  }
1125  uxmin = gPad->PadtoX(rwxmin);
1126  uxmax = gPad->PadtoX(rwxmax);
1127  } else {
1128 
1129  theGraph->ComputeRange(rwxmin, rwymin, rwxmax, rwymax); //this is redefined in TGraphErrors
1130 
1131  if (rwxmin == rwxmax) rwxmax += 1.;
1132  if (rwymin == rwymax) rwymax += 1.;
1133  dx = 0.1*(rwxmax-rwxmin);
1134  dy = 0.1*(rwymax-rwymin);
1135  uxmin = rwxmin - dx;
1136  uxmax = rwxmax + dx;
1137  minimum = rwymin - dy;
1138  maximum = rwymax + dy;
1139  }
1140  if (theGraph->GetMinimum() != -1111) rwymin = minimum = theGraph->GetMinimum();
1141  if (theGraph->GetMaximum() != -1111) rwymax = maximum = theGraph->GetMaximum();
1142  if (uxmin < 0 && rwxmin >= 0) uxmin = 0.9*rwxmin;
1143  if (uxmax > 0 && rwxmax <= 0) {
1144  if (gPad->GetLogx()) uxmax = 1.1*rwxmax;
1145  else uxmax = 0;
1146  }
1147  if (minimum < 0 && rwymin >= 0) minimum = 0.9*rwymin;
1148  if (maximum > 0 && rwymax <= 0) {
1149  //if(gPad->GetLogy()) maximum = 1.1*rwymax;
1150  //else maximum = 0;
1151  }
1152  if (minimum <= 0 && gPad->GetLogy()) minimum = 0.001*maximum;
1153  if (uxmin <= 0 && gPad->GetLogx()) {
1154  if (uxmax > 1000) uxmin = 1;
1155  else uxmin = 0.001*uxmax;
1156  }
1157  rwymin = minimum;
1158  rwymax = maximum;
1159 
1160  // Create a temporary histogram and fill each bin with the
1161  // function value.
1162  char chopth[8] = " ";
1163  if (strstr(chopt,"x+")) strncat(chopth, "x+",2);
1164  if (strstr(chopt,"y+")) strncat(chopth, "y+",2);
1165  if (optionIAxis) strncat(chopth, "A",1);
1166  if (!theGraph->GetHistogram()) {
1167  // the graph is created with at least as many bins as there are
1168  // points to permit zooming on the full range.
1169  rwxmin = uxmin;
1170  rwxmax = uxmax;
1171  npt = 100;
1172  if (theNpoints > npt) npt = theNpoints;
1173  TH1F *h = new TH1F(Form("%s_h",GetName()),GetTitle(),npt,rwxmin,rwxmax);
1174  theGraph->SetHistogram(h);
1175  if (!theGraph->GetHistogram()) return;
1176  theGraph->GetHistogram()->SetMinimum(rwymin);
1177  theGraph->GetHistogram()->SetMaximum(rwymax);
1178  theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
1179  theGraph->GetHistogram()->SetBit(TH1::kNoStats);
1180  theGraph->GetHistogram()->SetDirectory(0);
1181  theGraph->GetHistogram()->Paint(chopth); // Draw histogram axis, title and grid
1182  } else {
1183  if (gPad->GetLogy()) {
1184  theGraph->GetHistogram()->SetMinimum(rwymin);
1185  theGraph->GetHistogram()->SetMaximum(rwymax);
1186  theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
1187  }
1188  theGraph->GetHistogram()->Paint(chopth); // Draw histogram axis, title and grid
1189  }
1190  }
1191 
1192  // Set Clipping option
1193  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
1194 
1195  rwxmin = gPad->GetUxmin();
1196  rwxmax = gPad->GetUxmax();
1197  rwymin = gPad->GetUymin();
1198  rwymax = gPad->GetUymax();
1199  uxmin = gPad->PadtoX(rwxmin);
1200  uxmax = gPad->PadtoX(rwxmax);
1201  if (theGraph->GetHistogram() && !theGraph->InheritsFrom("TGraphPolar")) {
1202  maximum = theGraph->GetHistogram()->GetMaximum();
1203  minimum = theGraph->GetHistogram()->GetMinimum();
1204  } else {
1205  maximum = gPad->PadtoY(rwymax);
1206  minimum = gPad->PadtoY(rwymin);
1207  }
1208 
1209  // Set attributes
1210  theGraph->TAttLine::Modify();
1211  theGraph->TAttFill::Modify();
1212  theGraph->TAttMarker::Modify();
1213 
1214  // Draw the graph with a polyline or a fill area
1215  gxwork = new Double_t[2*npoints+10];
1216  gywork = new Double_t[2*npoints+10];
1217  gxworkl = new Double_t[2*npoints+10];
1218  gyworkl = new Double_t[2*npoints+10];
1219 
1220  if (optionLine || optionFill) {
1221  x1 = x[0];
1222  xn = x[npoints-1];
1223  y1 = y[0];
1224  yn = y[npoints-1];
1225  nloop = npoints;
1226  if (optionFill && (xn != x1 || yn != y1)) nloop++;
1227  npt = 0;
1228  for (i=1;i<=nloop;i++) {
1229  if (i > npoints) {
1230  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1231  } else {
1232  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1233  npt++;
1234  }
1235  if (i == nloop) {
1236  ComputeLogs(npt, optionZ);
1237  Int_t bord = gStyle->GetDrawBorder();
1238  if (optionR) {
1239  if (optionFill) {
1240  gPad->PaintFillArea(npt,gyworkl,gxworkl);
1241  if (bord) gPad->PaintPolyLine(npt,gyworkl,gxworkl);
1242  }
1243  if (optionLine) {
1244  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gyworkl, gxworkl);
1245  gPad->PaintPolyLine(npt,gyworkl,gxworkl);
1246  }
1247  } else {
1248  if (optionFill) {
1249  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1250  if (bord) gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1251  }
1252  if (optionLine) {
1253  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gxworkl, gyworkl);
1254  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1255  }
1256  }
1257  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1258  npt = 1;
1259  }
1260  }
1261  }
1262 
1263  // Draw the graph with a smooth Curve. Smoothing via Smooth
1264  if (optionCurve) {
1265  x1 = x[0];
1266  xn = x[npoints-1];
1267  y1 = y[0];
1268  yn = y[npoints-1];
1269  drawtype = 1;
1270  nloop = npoints;
1271  if (optionCurveFill) {
1272  drawtype += 1000;
1273  if (xn != x1 || yn != y1) nloop++;
1274  }
1275  if (!optionR) {
1276  npt = 0;
1277  for (i=1;i<=nloop;i++) {
1278  if (i > npoints) {
1279  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1280  } else {
1281  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1282  npt++;
1283  }
1284  ComputeLogs(npt, optionZ);
1285  if (gyworkl[npt-1] < rwymin || gyworkl[npt-1] > rwymax) {
1286  if (npt > 2) {
1287  ComputeLogs(npt, optionZ);
1288  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1289  }
1290  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1291  npt=1;
1292  continue;
1293  }
1294  }
1295  if (npt > 1) {
1296  ComputeLogs(npt, optionZ);
1297  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1298  }
1299  } else {
1300  drawtype += 10;
1301  npt = 0;
1302  for (i=1;i<=nloop;i++) {
1303  if (i > npoints) {
1304  gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
1305  } else {
1306  if (y[i-1] < minimum || y[i-1] > maximum) continue;
1307  if (x[i-1] < uxmin || x[i-1] > uxmax) continue;
1308  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1309  npt++;
1310  }
1311  ComputeLogs(npt, optionZ);
1312  if (gxworkl[npt-1] < rwxmin || gxworkl[npt-1] > rwxmax) {
1313  if (npt > 2) {
1314  ComputeLogs(npt, optionZ);
1315  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1316  }
1317  gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
1318  npt=1;
1319  continue;
1320  }
1321  }
1322  if (npt > 1) {
1323  ComputeLogs(npt, optionZ);
1324  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1325  }
1326  }
1327  }
1328 
1329  // Draw the graph with a '*' on every points
1330  if (optionStar) {
1331  theGraph->SetMarkerStyle(3);
1332  npt = 0;
1333  for (i=1;i<=npoints;i++) {
1334  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1335  npt++;
1336  if (i == npoints) {
1337  ComputeLogs(npt, optionZ);
1338  if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
1339  else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
1340  npt = 0;
1341  }
1342  }
1343  }
1344 
1345  // Draw the graph with the current polymarker on every points
1346  if (optionMark) {
1347  npt = 0;
1348  for (i=1;i<=npoints;i++) {
1349  gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
1350  npt++;
1351  if (i == npoints) {
1352  ComputeLogs(npt, optionZ);
1353  if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
1354  else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
1355  npt = 0;
1356  }
1357  }
1358  }
1359 
1360  // Draw the graph as a bar chart
1361  if (optionBar) {
1362  if (!optionR) {
1363  barxmin = x[0];
1364  barxmax = x[0];
1365  for (i=1;i<npoints;i++) {
1366  if (x[i] < barxmin) barxmin = x[i];
1367  if (x[i] > barxmax) barxmax = x[i];
1368  }
1369  bdelta = (barxmax-barxmin)/Double_t(npoints);
1370  } else {
1371  barymin = y[0];
1372  barymax = y[0];
1373  for (i=1;i<npoints;i++) {
1374  if (y[i] < barymin) barymin = y[i];
1375  if (y[i] > barymax) barymax = y[i];
1376  }
1377  bdelta = (barymax-barymin)/Double_t(npoints);
1378  }
1379  dbar = 0.5*bdelta*gStyle->GetBarWidth();
1380  if (!optionR) {
1381  for (i=1;i<=npoints;i++) {
1382  xlow = x[i-1] - dbar;
1383  xhigh = x[i-1] + dbar;
1384  yhigh = y[i-1];
1385  if (xlow < uxmin && xhigh < uxmin) continue;
1386  if (xhigh > uxmax && xlow > uxmax) continue;
1387  if (xlow < uxmin) xlow = uxmin;
1388  if (xhigh > uxmax) xhigh = uxmax;
1389  if (!optionOne) ylow = TMath::Max((Double_t)0,gPad->GetUymin());
1390  else ylow = gPad->GetUymin();
1391  gxwork[0] = xlow;
1392  gywork[0] = ylow;
1393  gxwork[1] = xhigh;
1394  gywork[1] = yhigh;
1395  ComputeLogs(2, optionZ);
1396  if (gyworkl[0] < gPad->GetUymin()) gyworkl[0] = gPad->GetUymin();
1397  if (gyworkl[1] < gPad->GetUymin()) continue;
1398  if (gyworkl[1] > gPad->GetUymax()) gyworkl[1] = gPad->GetUymax();
1399  if (gyworkl[0] > gPad->GetUymax()) continue;
1400 
1401  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
1402  }
1403  } else {
1404  for (i=1;i<=npoints;i++) {
1405  xhigh = x[i-1];
1406  ylow = y[i-1] - dbar;
1407  yhigh = y[i-1] + dbar;
1408  xlow = TMath::Max((Double_t)0, gPad->GetUxmin());
1409  gxwork[0] = xlow;
1410  gywork[0] = ylow;
1411  gxwork[1] = xhigh;
1412  gywork[1] = yhigh;
1413  ComputeLogs(2, optionZ);
1414  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
1415  }
1416  }
1417  }
1418  gPad->ResetBit(TGraph::kClipFrame);
1419 
1420  delete [] gxwork;
1421  delete [] gywork;
1422  delete [] gxworkl;
1423  delete [] gyworkl;
1424 }
1425 
1426 
1427 ////////////////////////////////////////////////////////////////////////////////
1428 /// This is a service method used by `THistPainter`
1429 /// to paint 1D histograms. It is not used to paint TGraph.
1430 ///
1431 /// Input parameters:
1432 ///
1433 /// - npoints : Number of points in X or in Y.
1434 /// - x[npoints] or x[0] : x coordinates or (xmin,xmax).
1435 /// - y[npoints] or y[0] : y coordinates or (ymin,ymax).
1436 /// - chopt : Option.
1437 ///
1438 /// The aspect of the histogram is done according to the value of the chopt.
1439 ///
1440 /// | Option | Description |
1441 /// |--------|-----------------------------------------------------------------|
1442 /// |"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) |
1443 /// |"L" | A simple polyline between every points is drawn.|
1444 /// |"H" | An Histogram with equidistant bins is drawn as a polyline.|
1445 /// |"F" | An histogram with equidistant bins is drawn as a fill area. Contour is not drawn unless chopt='H' is also selected..|
1446 /// |"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 |
1447 /// |"F1" | Idem as 'F' except that fill area base line is the minimum of the pad instead of Y=0.|
1448 /// |"F2" | Draw a Fill area polyline connecting the center of bins|
1449 /// |"C" | A smooth Curve is drawn.|
1450 /// |"*" | A Star is plotted at the center of each bin.|
1451 /// |"P" | Idem with the current marker.|
1452 /// |"P0" | Idem with the current marker. Empty bins also drawn.|
1453 /// |"B" | A Bar chart with equidistant bins is drawn as fill areas (Contours are drawn).|
1454 /// |"][" | "Cutoff" style. When this option is selected together with H option, the first and last vertical lines of the histogram are not drawn.|
1455 
1456 void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_t *x,
1457  const Double_t *y, Option_t *chopt)
1458 {
1459 
1460  const char *where = "PaintGrapHist";
1461 
1462  Int_t optionLine , optionAxis , optionCurve, optionStar, optionMark;
1463  Int_t optionBar , optionRot , optionOne , optionOff ;
1464  Int_t optionFill , optionZ;
1465  Int_t optionHist , optionBins , optionMarker;
1466  Int_t i, j, npt;
1467  Int_t drawtype=0, drawborder, drawbordersav;
1468  Double_t xlow, xhigh, ylow, yhigh;
1469  Double_t wmin, wmax;
1470  Double_t dbar, offset, wminstep;
1471  Double_t delta = 0;
1472  Double_t ylast = 0;
1473  Double_t xi, xi1, xj, xj1, yi1, yi, yj, yj1, xwmin, ywmin;
1474  Int_t first, last, nbins;
1475  Int_t fillarea;
1476 
1477  char choptaxis[10] = " ";
1478 
1479  if (npoints <= 0) {
1480  Error(where, "illegal number of points (%d)", npoints);
1481  return;
1482  }
1483  TString opt = chopt;
1484  opt.ToUpper();
1485  if (opt.Contains("H")) optionHist = 1; else optionHist = 0;
1486  if (opt.Contains("F")) optionFill = 1; else optionFill = 0;
1487  if (opt.Contains("C")) optionCurve= 1; else optionCurve= 0;
1488  if (opt.Contains("*")) optionStar = 1; else optionStar = 0;
1489  if (opt.Contains("R")) optionRot = 1; else optionRot = 0;
1490  if (opt.Contains("1")) optionOne = 1; else optionOne = 0;
1491  if (opt.Contains("B")) optionBar = 1; else optionBar = 0;
1492  if (opt.Contains("N")) optionBins = 1; else optionBins = 0;
1493  if (opt.Contains("L")) optionLine = 1; else optionLine = 0;
1494  if (opt.Contains("P")) optionMark = 1; else optionMark = 0;
1495  if (opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
1496  if (opt.Contains("][")) optionOff = 1; else optionOff = 0;
1497  if (opt.Contains("P0")) optionMark = 10;
1498 
1499  Int_t optionFill2 = 0;
1500  if (opt.Contains("F") && opt.Contains("2")) {
1501  optionFill = 0; optionFill2 = 1;
1502  }
1503 
1504  // Set Clipping option
1505  Option_t *noClip;
1506  if (theGraph->TestBit(TGraph::kClipFrame)) noClip = "";
1507  else noClip = "C";
1508  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
1509 
1510  optionZ = 1;
1511 
1512  if (optionStar) theGraph->SetMarkerStyle(3);
1513 
1514  first = 1;
1515  last = npoints;
1516  nbins = last - first + 1;
1517 
1518  // Draw the Axis with a fixed number of division: 510
1519 
1520  Double_t baroffset = gStyle->GetBarOffset();
1521  Double_t barwidth = gStyle->GetBarWidth();
1522  Double_t rwxmin = gPad->GetUxmin();
1523  Double_t rwxmax = gPad->GetUxmax();
1524  Double_t rwymin = gPad->GetUymin();
1525  Double_t rwymax = gPad->GetUymax();
1526  Double_t uxmin = gPad->PadtoX(rwxmin);
1527  Double_t uxmax = gPad->PadtoX(rwxmax);
1528  Double_t rounding = (uxmax-uxmin)*1.e-5;
1529  drawborder = gStyle->GetDrawBorder();
1530  if (optionAxis) {
1531  Int_t nx1, nx2, ndivx, ndivy, ndiv;
1532  choptaxis[0] = 0;
1533  Double_t rwmin = rwxmin;
1534  Double_t rwmax = rwxmax;
1535  ndivx = gStyle->GetNdivisions("X");
1536  ndivy = gStyle->GetNdivisions("Y");
1537  if (ndivx > 1000) {
1538  nx2 = ndivx/100;
1539  nx1 = TMath::Max(1, ndivx%100);
1540  ndivx = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
1541  }
1542  ndiv =TMath::Abs(ndivx);
1543  // coverity [Calling risky function]
1544  if (ndivx < 0) strlcat(choptaxis, "N",10);
1545  if (gPad->GetGridx()) {
1546  // coverity [Calling risky function]
1547  strlcat(choptaxis, "W",10);
1548  }
1549  if (gPad->GetLogx()) {
1550  rwmin = TMath::Power(10,rwxmin);
1551  rwmax = TMath::Power(10,rwxmax);
1552  // coverity [Calling risky function]
1553  strlcat(choptaxis, "G",10);
1554  }
1555  TGaxis *axis = new TGaxis();
1556  axis->SetLineColor(gStyle->GetAxisColor("X"));
1557  axis->SetTextColor(gStyle->GetLabelColor("X"));
1558  axis->SetTextFont(gStyle->GetLabelFont("X"));
1559  axis->SetLabelSize(gStyle->GetLabelSize("X"));
1560  axis->SetLabelOffset(gStyle->GetLabelOffset("X"));
1561  axis->SetTickSize(gStyle->GetTickLength("X"));
1562 
1563  axis->PaintAxis(rwxmin,rwymin,rwxmax,rwymin,rwmin,rwmax,ndiv,choptaxis);
1564 
1565  choptaxis[0] = 0;
1566  rwmin = rwymin;
1567  rwmax = rwymax;
1568  if (ndivy < 0) {
1569  nx2 = ndivy/100;
1570  nx1 = TMath::Max(1, ndivy%100);
1571  ndivy = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsHNDC());
1572  // coverity [Calling risky function]
1573  strlcat(choptaxis, "N",10);
1574  }
1575  ndiv =TMath::Abs(ndivy);
1576  if (gPad->GetGridy()) {
1577  // coverity [Calling risky function]
1578  strlcat(choptaxis, "W",10);
1579  }
1580  if (gPad->GetLogy()) {
1581  rwmin = TMath::Power(10,rwymin);
1582  rwmax = TMath::Power(10,rwymax);
1583  // coverity [Calling risky function]
1584  strlcat(choptaxis,"G",10);
1585  }
1586  axis->SetLineColor(gStyle->GetAxisColor("Y"));
1587  axis->SetTextColor(gStyle->GetLabelColor("Y"));
1588  axis->SetTextFont(gStyle->GetLabelFont("Y"));
1589  axis->SetLabelSize(gStyle->GetLabelSize("Y"));
1590  axis->SetLabelOffset(gStyle->GetLabelOffset("Y"));
1591  axis->SetTickSize(gStyle->GetTickLength("Y"));
1592 
1593  axis->PaintAxis(rwxmin,rwymin,rwxmin,rwymax,rwmin,rwmax,ndiv,choptaxis);
1594  delete axis;
1595  }
1596 
1597 
1598  // Set attributes
1599  theGraph->TAttLine::Modify();
1600  theGraph->TAttFill::Modify();
1601  theGraph->TAttMarker::Modify();
1602 
1603  // Min-Max scope
1604 
1605  if (!optionRot) {wmin = x[0]; wmax = x[1];}
1606  else {wmin = y[0]; wmax = y[1];}
1607 
1608  if (!optionBins) delta = (wmax - wmin)/ Double_t(nbins);
1609 
1610  Int_t fwidth = gPad->GetFrameLineWidth();
1611  TFrame *frame = gPad->GetFrame();
1612  if (frame) fwidth = frame->GetLineWidth();
1613  if (optionOff) fwidth = 1;
1614  Double_t dxframe = gPad->AbsPixeltoX(fwidth/2) - gPad->AbsPixeltoX(0);
1615  Double_t vxmin = gPad->PadtoX(gPad->GetUxmin() + dxframe);
1616  Double_t vxmax = gPad->PadtoX(gPad->GetUxmax() - dxframe);
1617  Double_t dyframe = -gPad->AbsPixeltoY(fwidth/2) + gPad->AbsPixeltoY(0);
1618  Double_t vymin = gPad->GetUymin() + dyframe; //y already in log scale
1619  vxmin = TMath::Max(vxmin,wmin);
1620  vxmax = TMath::Min(vxmax,wmax);
1621 
1622  // Draw the histogram with a fill area
1623 
1624  gxwork = new Double_t[2*npoints+10];
1625  gywork = new Double_t[2*npoints+10];
1626  gxworkl = new Double_t[2*npoints+10];
1627  gyworkl = new Double_t[2*npoints+10];
1628 
1629  if (optionFill && !optionCurve) {
1630  fillarea = kTRUE;
1631  if (!optionRot) {
1632  gxwork[0] = vxmin;
1633  if (!optionOne) gywork[0] = TMath::Min(TMath::Max((Double_t)0,gPad->GetUymin())
1634  ,gPad->GetUymax());
1635  else gywork[0] = gPad->GetUymin();
1636  npt = 2;
1637  for (j=first; j<=last;j++) {
1638  if (!optionBins) {
1639  gxwork[npt-1] = gxwork[npt-2];
1640  gxwork[npt] = wmin+((j-first+1)*delta);
1641  if (gxwork[npt] < gxwork[0]) gxwork[npt] = gxwork[0];
1642 
1643  } else {
1644  xj1 = x[j]; xj = x[j-1];
1645  if (xj1 < xj) {
1646  if (j != last) Error(where, "X must be in increasing order");
1647  else Error(where, "X must have N+1 values with option N");
1648  return;
1649  }
1650  gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j];
1651  }
1652  gywork[npt-1] = y[j-1];
1653  gywork[npt] = y[j-1];
1654  if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
1655  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1656  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1657  if (j == last) {
1658  gxwork[npt-1] = gxwork[npt-2];
1659  gywork[npt-1] = gywork[0];
1660  //make sure that the fill area does not overwrite the frame
1661  //take into account the frame line width
1662  if (gxwork[0 ] < vxmin) {gxwork[0 ] = vxmin; gxwork[1 ] = vxmin;}
1663  if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
1664 
1665  //transform to log ?
1666  ComputeLogs(npt, optionZ);
1667  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1668  if (drawborder) {
1669  if (!fillarea) gyworkl[0] = ylast;
1670  gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
1671  }
1672  continue;
1673  }
1674  } //endfor (j=first; j<=last;j++) {
1675  } else {
1676  gywork[0] = wmin;
1677  if (!optionOne) gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
1678  else gxwork[0] = gPad->GetUxmin();
1679  npt = 2;
1680  for (j=first; j<=last;j++) {
1681  if (!optionBins) {
1682  gywork[npt-1] = gywork[npt-2];
1683  gywork[npt] = wmin+((j-first+1)*delta);
1684  } else {
1685  yj1 = y[j]; yj = y[j-1];
1686  if (yj1 < yj) {
1687  if (j != last) Error(where, "Y must be in increasing order");
1688  else Error(where, "Y must have N+1 values with option N");
1689  return;
1690  }
1691  gywork[npt-1] = y[j-1]; gywork[npt] = y[j];
1692  }
1693  gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j-1];
1694  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1695  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1696  if (j == last) {
1697  gywork[npt-1] = gywork[npt-2];
1698  gxwork[npt-1] = gxwork[0];
1699  ComputeLogs(npt, optionZ);
1700  gPad->PaintFillArea(npt,gxworkl,gyworkl);
1701  if (drawborder) {
1702  if (!fillarea) gyworkl[0] = ylast;
1703  gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
1704  }
1705  continue;
1706  }
1707  } //endfor (j=first; j<=last;j++)
1708  }
1709  theGraph->TAttLine::Modify();
1710  theGraph->TAttFill::Modify();
1711  }
1712 
1713  // Draw a standard Histogram (default)
1714 
1715  if ((optionHist) || !chopt[0]) {
1716  if (!optionRot) {
1717  gxwork[0] = wmin;
1718  gywork[0] = gPad->GetUymin();
1719  ywmin = gywork[0];
1720  npt = 2;
1721  for (i=first; i<=last;i++) {
1722  if (!optionBins) {
1723  gxwork[npt-1] = gxwork[npt-2];
1724  gxwork[npt] = wmin+((i-first+1)*delta);
1725  } else {
1726  xi1 = x[i]; xi = x[i-1];
1727  if (xi1 < xi) {
1728  if (i != last) Error(where, "X must be in increasing order");
1729  else Error(where, "X must have N+1 values with option N");
1730  return;
1731  }
1732  gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i];
1733  }
1734  gywork[npt-1] = y[i-1];
1735  gywork[npt] = y[i-1];
1736  if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
1737  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1738  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1739  if (i == last) {
1740  gxwork[npt-1] = gxwork[npt-2];
1741  gywork[npt-1] = gywork[0];
1742  //make sure that the fill area does not overwrite the frame
1743  //take into account the frame line width
1744  if (gxwork[0] < vxmin) {gxwork[0] = vxmin; gxwork[1 ] = vxmin;}
1745  if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
1746 
1747  ComputeLogs(npt, optionZ);
1748 
1749  // do not draw the two vertical lines on the edges
1750  Int_t nbpoints = npt-2;
1751  Int_t point1 = 1;
1752 
1753  if (optionOff) {
1754  // remove points before the low cutoff
1755  Int_t ip;
1756  for (ip=point1; ip<=nbpoints; ip++) {
1757  if (gyworkl[ip] != ywmin) {
1758  point1 = ip;
1759  break;
1760  }
1761  }
1762  // remove points after the high cutoff
1763  Int_t point2 = nbpoints;
1764  for (ip=point2; ip>=point1; ip--) {
1765  if (gyworkl[ip] != ywmin) {
1766  point2 = ip;
1767  break;
1768  }
1769  }
1770  nbpoints = point2-point1+1;
1771  } else {
1772  // if the 1st or last bin are not on the pad limits the
1773  // the two vertical lines on the edges are added.
1774  if (gxwork[0] > gPad->GetUxmin()) { nbpoints++; point1 = 0; }
1775  if (gxwork[nbpoints] < gPad->GetUxmax()) nbpoints++;
1776  }
1777 
1778  gPad->PaintPolyLine(nbpoints,&gxworkl[point1],&gyworkl[point1],noClip);
1779  continue;
1780  }
1781  } //endfor (i=first; i<=last;i++)
1782  } else {
1783  gywork[0] = wmin;
1784  gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
1785  xwmin = gxwork[0];
1786  npt = 2;
1787  for (i=first; i<=last;i++) {
1788  if (!optionBins) {
1789  gywork[npt-1] = gywork[npt-2];
1790  gywork[npt] = wmin+((i-first+1)*delta);
1791  } else {
1792  yi1 = y[i]; yi = y[i-1];
1793  if (yi1 < yi) {
1794  if (i != last) Error(where, "Y must be in increasing order");
1795  else Error(where, "Y must have N+1 values with option N");
1796  return;
1797  }
1798  gywork[npt-1] = y[i-1]; gywork[npt] = y[i];
1799  }
1800  gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i-1];
1801  if ((gxwork[npt-1] >= uxmin-rounding && gxwork[npt-1] <= uxmax+rounding) ||
1802  (gxwork[npt] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding)) npt += 2;
1803  if (i == last) {
1804  gywork[npt-1] = gywork[npt-2];
1805  gxwork[npt-1] = xwmin;
1806  ComputeLogs(npt, optionZ);
1807  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1808  continue;
1809  }
1810  } //endfor (i=first; i<=last;i++)
1811  }
1812  }
1813 
1814  // Draw the histogram with a smooth Curve.
1815  // The smoothing is done by the method Smooth()
1816 
1817  if (optionCurve) {
1818  if (!optionFill) {
1819  drawtype = 1;
1820  } else {
1821  if (!optionOne) drawtype = 2;
1822  else drawtype = 3;
1823  }
1824  if (!optionRot) {
1825  npt = 0;
1826  for (i=first; i<=last;i++) {
1827  npt++;
1828  if (!optionBins) {
1829  gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1830  } else {
1831  xi1 = x[i]; xi = x[i-1];
1832  if (xi1 < xi) {
1833  if (i != last) Error(where, "X must be in increasing order");
1834  else Error(where, "X must have N+1 values with option N");
1835  return;
1836  }
1837  gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
1838  }
1839  if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) {
1840  npt--;
1841  continue;
1842  }
1843  gywork[npt-1] = y[i-1];
1844  ComputeLogs(npt, optionZ);
1845  if ((gyworkl[npt-1] < rwymin) || (gyworkl[npt-1] > rwymax)) {
1846  if (npt > 2) {
1847  ComputeLogs(npt, optionZ);
1848  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1849  }
1850  gxwork[0] = gxwork[npt-1];
1851  gywork[0] = gywork[npt-1];
1852  npt = 1;
1853  continue;
1854  }
1855  if (npt >= fgMaxPointsPerLine) {
1856  ComputeLogs(fgMaxPointsPerLine, optionZ);
1857  Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype);
1858  gxwork[0] = gxwork[npt-1];
1859  gywork[0] = gywork[npt-1];
1860  npt = 1;
1861  }
1862  } //endfor (i=first; i<=last;i++)
1863  if (npt > 1) {
1864  ComputeLogs(npt, optionZ);
1865  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1866  }
1867  } else {
1868  drawtype = drawtype+10;
1869  npt = 0;
1870  for (i=first; i<=last;i++) {
1871  npt++;
1872  if (!optionBins) {
1873  gywork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1874  } else {
1875  yi1 = y[i]; yi = y[i-1];
1876  if (yi1 < yi) {
1877  if (i != last) Error(where, "Y must be in increasing order");
1878  else Error(where, "Y must have N+1 values with option N");
1879  return;
1880  }
1881  gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
1882  }
1883  gxwork[npt-1] = x[i-1];
1884  ComputeLogs(npt, optionZ);
1885  if ((gxworkl[npt] < uxmin) || (gxworkl[npt] > uxmax)) {
1886  if (npt > 2) {
1887  ComputeLogs(npt, optionZ);
1888  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1889  }
1890  gxwork[0] = gxwork[npt-1];
1891  gywork[0] = gywork[npt-1];
1892  npt = 1;
1893  continue;
1894  }
1895  if (npt >= fgMaxPointsPerLine) {
1896  ComputeLogs(fgMaxPointsPerLine, optionZ);
1897  Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype);
1898  gxwork[0] = gxwork[npt-1];
1899  gywork[0] = gywork[npt-1];
1900  npt = 1;
1901  }
1902  } //endfor (i=first; i<=last;i++)
1903  if (npt > 1) {
1904  ComputeLogs(npt, optionZ);
1905  Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
1906  }
1907  }
1908  }
1909 
1910  // Draw the histogram with a simple line
1911 
1912  if (optionLine) {
1913  wminstep = wmin + 0.5*delta;
1914  Axis_t ax1,ax2,ay1,ay2;
1915  gPad->GetRangeAxis(ax1,ay1,ax2,ay2);
1916 
1917  if (!optionRot) {
1918  npt = 0;
1919  for (i=first; i<=last;i++) {
1920  npt++;
1921  if (!optionBins) {
1922  gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
1923  } else {
1924  xi1 = x[i]; xi = x[i-1];
1925  if (xi1 < xi) {
1926  if (i != last) Error(where, "X must be in increasing order");
1927  else Error(where, "X must have N+1 values with option N");
1928  return;
1929  }
1930  gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
1931  }
1932  if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) { npt--; continue;}
1933  gywork[npt-1] = y[i-1];
1934  gywork[npt] = y[i-1]; //new
1935  if ((gywork[npt-1] < rwymin) || ((gywork[npt-1] > rwymax) && !optionFill2)) {
1936  if ((gywork[npt-1] < rwymin)) gywork[npt-1] = rwymin;
1937  if ((gywork[npt-1] > rwymax)) gywork[npt-1] = rwymax;
1938  if (npt > 2) {
1939  ComputeLogs(npt, optionZ);
1940  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1941  }
1942  gxwork[0] = gxwork[npt-1];
1943  gywork[0] = gywork[npt-1];
1944  npt = 1;
1945  continue;
1946  }
1947 
1948  if (npt >= fgMaxPointsPerLine) {
1949  if (optionLine) {
1950  ComputeLogs(fgMaxPointsPerLine, optionZ);
1951  if (optionFill2) {
1952  gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
1953  gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
1954  gPad->PaintFillArea(fgMaxPointsPerLine+2,gxworkl,gyworkl);
1955  }
1956  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1957  }
1958  gxwork[0] = gxwork[npt-1];
1959  gywork[0] = gywork[npt-1];
1960  npt = 1;
1961  }
1962  } //endfor (i=first; i<=last;i++)
1963  if (npt > 1) {
1964  ComputeLogs(npt, optionZ);
1965  if (optionFill2) {
1966  gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
1967  gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
1968  gPad->PaintFillArea(npt+2,gxworkl,gyworkl);
1969  }
1970  gPad->PaintPolyLine(npt,gxworkl,gyworkl);
1971  }
1972  } else {
1973  npt = 0;
1974  for (i=first; i<=last;i++) {
1975  npt++;
1976  if (!optionBins) {
1977  gywork[npt-1] = wminstep+(i-first)*delta+0.5*delta;
1978  } else {
1979  yi1 = y[i]; yi = y[i-1];
1980  if (yi1 < yi) {
1981  if (i != last) Error(where, "Y must be in increasing order");
1982  else Error(where, "Y must have N+1 values with option N");
1983  return;
1984  }
1985  gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
1986  }
1987  gxwork[npt-1] = x[i-1];
1988  if ((gxwork[npt-1] < uxmin) || (gxwork[npt-1] > uxmax)) {
1989  if (npt > 2) {
1990  if (optionLine) {
1991  ComputeLogs(npt, optionZ);
1992  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
1993  }
1994  }
1995  gxwork[0] = gxwork[npt-1];
1996  gywork[0] = gywork[npt-1];
1997  npt = 1;
1998  continue;
1999  }
2000  if (npt >= fgMaxPointsPerLine) {
2001  if (optionLine) {
2002  ComputeLogs(fgMaxPointsPerLine, optionZ);
2003  gPad->PaintPolyLine(fgMaxPointsPerLine,gxworkl,gyworkl);
2004  }
2005  gxwork[0] = gxwork[npt-1];
2006  gywork[0] = gywork[npt-1];
2007  npt = 1;
2008  }
2009  } //endfor (i=first; i<=last;i++)
2010  if (optionLine != 0 && npt > 1) {
2011  ComputeLogs(npt, optionZ);
2012  gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
2013  }
2014  }
2015  }
2016 
2017  // Draw the histogram as a bar chart
2018 
2019  if (optionBar) {
2020  if (!optionBins) {
2021  offset = delta*baroffset; dbar = delta*barwidth;
2022  } else {
2023  if (!optionRot) {
2024  offset = (x[1]-x[0])*baroffset;
2025  dbar = (x[1]-x[0])*barwidth;
2026  } else {
2027  offset = (y[1]-y[0])*baroffset;
2028  dbar = (y[1]-y[0])*barwidth;
2029  }
2030  }
2031  drawbordersav = drawborder;
2032  gStyle->SetDrawBorder(1);
2033  if (!optionRot) {
2034  xlow = wmin+offset;
2035  xhigh = wmin+offset+dbar;
2036  if (!optionOne) ylow = TMath::Min(TMath::Max((Double_t)0,gPad->GetUymin())
2037  ,gPad->GetUymax());
2038  else ylow = gPad->GetUymin();
2039 
2040  for (i=first; i<=last;i++) {
2041  yhigh = y[i-1];
2042  gxwork[0] = xlow;
2043  gywork[0] = ylow;
2044  gxwork[1] = xhigh;
2045  gywork[1] = yhigh;
2046  ComputeLogs(2, optionZ);
2047  if (xlow < rwxmax && xhigh > rwxmin)
2048  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
2049  if (!optionBins) {
2050  xlow = xlow+delta;
2051  xhigh = xhigh+delta;
2052  } else {
2053  if (i < last) {
2054  xi1 = x[i]; xi = x[i-1];
2055  if (xi1 < xi) {
2056  Error(where, "X must be in increasing order");
2057  return;
2058  }
2059  offset = (x[i+1]-x[i])*baroffset;
2060  dbar = (x[i+1]-x[i])*barwidth;
2061  xlow = x[i] + offset;
2062  xhigh = x[i] + offset + dbar;
2063  }
2064  }
2065  } //endfor (i=first; i<=last;i++)
2066  } else {
2067  ylow = wmin + offset;
2068  yhigh = wmin + offset + dbar;
2069  if (!optionOne) xlow = TMath::Max((Double_t)0,gPad->GetUxmin());
2070  else xlow = gPad->GetUxmin();
2071  for (i=first; i<=last;i++) {
2072  xhigh = x[i-1];
2073  gxwork[0] = xlow;
2074  gywork[0] = ylow;
2075  gxwork[1] = xhigh;
2076  gywork[1] = yhigh;
2077  ComputeLogs(2, optionZ);
2078  gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
2079  gPad->PaintBox(xlow,ylow,xhigh,yhigh);
2080  if (!optionBins) {
2081  ylow = ylow + delta;
2082  yhigh = yhigh + delta;
2083  } else {
2084  if (i < last) {
2085  yi1 = y[i]; yi = y[i-1];
2086  if (yi1 < yi) {
2087  Error(where, "Y must be in increasing order");
2088  return;
2089  }
2090  offset = (y[i+1]-y[i])*baroffset;
2091  dbar = (y[i+1]-y[i])*barwidth;
2092  ylow = y[i] + offset;
2093  yhigh = y[i] + offset + dbar;
2094  }
2095  }
2096  } //endfor (i=first; i<=last;i++)
2097  }
2098  gStyle->SetDrawBorder(drawbordersav);
2099  }
2100 
2101  // Draw the histogram with a simple marker
2102 
2103  optionMarker = 0;
2104  if ((optionStar) || (optionMark)) optionMarker=1;
2105 
2106  if (optionMarker) {
2107  Double_t xm,ym;
2108  npt = 0;
2109  if (!optionRot) {
2110  for (i=first; i<=last;i++) {
2111  if (!optionBins) xm = wmin+(i-first)*delta+0.5*delta;
2112  else xm = x[i-1] + 0.5*(x[i]-x[i-1]);
2113  ym = y[i-1];
2114  if (optionMark != 10) {
2115  if (ym<rwymax && ym > rwymin) {
2116  npt++;
2117  gxwork[npt-1] = xm;
2118  gywork[npt-1] = ym;
2119  }
2120  } else {
2121  if (ym<rwymax && ym >= rwymin) {
2122  npt++;
2123  gxwork[npt-1] = xm;
2124  gywork[npt-1] = ym;
2125  }
2126  }
2127  if (npt >= fgMaxPointsPerLine) {
2128  ComputeLogs(npt, optionZ);
2129  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2130  npt = 0;
2131  }
2132  }
2133  if (npt > 0) {
2134  ComputeLogs(npt, optionZ);
2135  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2136  }
2137  } else {
2138  wminstep = wmin + 0.5*delta;
2139  for (i=first; i<=last;i++) {
2140  if (!optionBins) ym = wminstep+(i-first)*delta+0.5*delta;
2141  else ym = y[i-1] + 0.5*(y[i]-y[i-1]);
2142  xm = x[i-1];
2143  if (optionMark != 10) {
2144  if (xm<rwxmax && xm > rwxmin) {
2145  npt++;
2146  gxwork[npt-1] = xm;
2147  gywork[npt-1] = ym;
2148  }
2149  } else {
2150  if (xm<rwxmax && xm >= rwxmin) {
2151  npt++;
2152  gxwork[npt-1] = xm;
2153  gywork[npt-1] = ym;
2154  }
2155  }
2156  if (npt >= fgMaxPointsPerLine) {
2157  ComputeLogs(npt, optionZ);
2158  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2159  npt = 0;
2160  }
2161  }
2162  if (npt > 0) {
2163  ComputeLogs(npt, optionZ);
2164  gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
2165  }
2166  }
2167  }
2168 
2169  gPad->ResetBit(TGraph::kClipFrame);
2170 
2171  delete [] gxwork;
2172  delete [] gywork;
2173  delete [] gxworkl;
2174  delete [] gyworkl;
2175 }
2176 
2177 
2178 ////////////////////////////////////////////////////////////////////////////////
2179 /// [Paint this TGraphAsymmErrors with its current attributes.](#GP03)
2180 
2182 {
2183 
2184  Double_t *xline = 0;
2185  Double_t *yline = 0;
2186  Int_t if1 = 0;
2187  Int_t if2 = 0;
2188  Double_t xb[4], yb[4];
2189 
2190  const Int_t kBASEMARKER=8;
2191  Double_t s2x, s2y, symbolsize, sbase;
2192  Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2193  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};
2194  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2195  Int_t theNpoints = theGraph->GetN();
2196  Double_t *theX = theGraph->GetX();
2197  Double_t *theY = theGraph->GetY();
2198  Double_t *theEXlow = theGraph->GetEXlow(); if (!theEXlow) return;
2199  Double_t *theEYlow = theGraph->GetEYlow(); if (!theEYlow) return;
2200  Double_t *theEXhigh = theGraph->GetEXhigh(); if (!theEXhigh) return;
2201  Double_t *theEYhigh = theGraph->GetEYhigh(); if (!theEYhigh) return;
2202 
2203  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2204  Bool_t brackets = kFALSE;
2205  Bool_t braticks = kFALSE;
2206  if (strstr(option,"||") || strstr(option,"[]")) {
2207  brackets = kTRUE;
2208  if (strstr(option,"[]")) braticks = kTRUE;
2209  }
2210  Bool_t endLines = kTRUE;
2211  if (strchr(option,'z')) endLines = kFALSE;
2212  if (strchr(option,'Z')) endLines = kFALSE;
2213  const char *arrowOpt = 0;
2214  if (strchr(option,'>')) arrowOpt = ">";
2215  if (strstr(option,"|>")) arrowOpt = "|>";
2216 
2217  Bool_t axis = kFALSE;
2218  if (strchr(option,'a')) axis = kTRUE;
2219  if (strchr(option,'A')) axis = kTRUE;
2220  if (axis) PaintGraphSimple(theGraph, option);
2221 
2222  Bool_t option0 = kFALSE;
2223  Bool_t option2 = kFALSE;
2224  Bool_t option3 = kFALSE;
2225  Bool_t option4 = kFALSE;
2226  Bool_t option5 = kFALSE;
2227  if (strchr(option,'0')) option0 = kTRUE;
2228  if (strchr(option,'2')) option2 = kTRUE;
2229  if (strchr(option,'3')) option3 = kTRUE;
2230  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2231  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2232 
2233  if (option3) {
2234  xline = new Double_t[2*theNpoints];
2235  yline = new Double_t[2*theNpoints];
2236  if (!xline || !yline) {
2237  Error("Paint", "too many points, out of memory");
2238  return;
2239  }
2240  if1 = 1;
2241  if2 = 2*theNpoints;
2242  }
2243 
2244  theGraph->TAttLine::Modify();
2245 
2246  TArrow arrow;
2247  arrow.SetLineWidth(theGraph->GetLineWidth());
2248  arrow.SetLineColor(theGraph->GetLineColor());
2249  arrow.SetFillColor(theGraph->GetFillColor());
2250 
2251  TBox box;
2252  Double_t x1b,y1b,x2b,y2b;
2253  box.SetLineWidth(theGraph->GetLineWidth());
2254  box.SetLineColor(theGraph->GetLineColor());
2255  box.SetFillColor(theGraph->GetFillColor());
2256  box.SetFillStyle(theGraph->GetFillStyle());
2257 
2258  symbolsize = theGraph->GetMarkerSize();
2259  sbase = symbolsize*kBASEMARKER;
2260  Int_t mark = theGraph->GetMarkerStyle();
2261  Double_t cx = 0;
2262  Double_t cy = 0;
2263  if (mark >= 20 && mark <= 34) {
2264  cx = cxx[mark-20];
2265  cy = cyy[mark-20];
2266  }
2267 
2268  // Define the offset of the error bars due to the symbol size
2269  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2270  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2271  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2272  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2273  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2274  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2275 
2276  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2277  for (Int_t i=0;i<theNpoints;i++) {
2278  x = gPad->XtoPad(theX[i]);
2279  y = gPad->YtoPad(theY[i]);
2280  if (!option0) {
2281  if (option3) {
2282  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2283  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2284  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2285  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2286  } else {
2287  if (x < gPad->GetUxmin()) continue;
2288  if (x > gPad->GetUxmax()) continue;
2289  if (y < gPad->GetUymin()) continue;
2290  if (y > gPad->GetUymax()) continue;
2291  }
2292  }
2293  xl1 = x - s2x*cx;
2294  xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
2295 
2296  // draw the error rectangles
2297  if (option2) {
2298  x1b = gPad->XtoPad(theX[i] - theEXlow[i]);
2299  y1b = gPad->YtoPad(theY[i] - theEYlow[i]);
2300  x2b = gPad->XtoPad(theX[i] + theEXhigh[i]);
2301  y2b = gPad->YtoPad(theY[i] + theEYhigh[i]);
2302  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2303  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2304  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2305  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2306  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2307  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2308  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2309  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2310  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2311  else box.PaintBox(x1b, y1b, x2b, y2b);
2312  continue;
2313  }
2314 
2315  // keep points for fill area drawing
2316  if (option3) {
2317  xline[if1-1] = x;
2318  xline[if2-1] = x;
2319  yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
2320  yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
2321  if1++;
2322  if2--;
2323  continue;
2324  }
2325 
2326  if (xl1 > xl2) {
2327  if (arrowOpt) {
2328  arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
2329  } else {
2330  if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
2331  if (endLines) {
2332  if (braticks) {
2333  xb[0] = xl2+tx; yb[0] = y-ty;
2334  xb[1] = xl2; yb[1] = y-ty;
2335  xb[2] = xl2; yb[2] = y+ty;
2336  xb[3] = xl2+tx; yb[3] = y+ty;
2337  gPad->PaintPolyLine(4, xb, yb);
2338  } else {
2339  gPad->PaintLine(xl2,y-ty,xl2,y+ty);
2340  }
2341  }
2342  }
2343  }
2344  xr1 = x + s2x*cx;
2345  xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
2346  if (xr1 < xr2) {
2347  if (arrowOpt) {
2348  arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
2349  } else {
2350  if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
2351  if (endLines) {
2352  if (braticks) {
2353  xb[0] = xr2-tx; yb[0] = y-ty;
2354  xb[1] = xr2; yb[1] = y-ty;
2355  xb[2] = xr2; yb[2] = y+ty;
2356  xb[3] = xr2-tx; yb[3] = y+ty;
2357  gPad->PaintPolyLine(4, xb, yb);
2358  } else {
2359  gPad->PaintLine(xr2,y-ty,xr2,y+ty);
2360  }
2361  }
2362  }
2363  }
2364  yup1 = y + s2y*cy;
2365  yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
2366  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2367  if (yup2 > yup1) {
2368  if (arrowOpt) {
2369  arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
2370  } else {
2371  if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
2372  if (endLines) {
2373  if (braticks) {
2374  xb[0] = x-tx; yb[0] = yup2-ty;
2375  xb[1] = x-tx; yb[1] = yup2;
2376  xb[2] = x+tx; yb[2] = yup2;
2377  xb[3] = x+tx; yb[3] = yup2-ty;
2378  gPad->PaintPolyLine(4, xb, yb);
2379  } else {
2380  gPad->PaintLine(x-tx,yup2,x+tx,yup2);
2381  }
2382  }
2383  }
2384  }
2385  ylow1 = y - s2y*cy;
2386  ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
2387  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2388  if (ylow2 < ylow1) {
2389  if (arrowOpt) {
2390  arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
2391  } else {
2392  if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
2393  if (endLines) {
2394  if (braticks) {
2395  xb[0] = x-tx; yb[0] = ylow2+ty;
2396  xb[1] = x-tx; yb[1] = ylow2;
2397  xb[2] = x+tx; yb[2] = ylow2;
2398  xb[3] = x+tx; yb[3] = ylow2+ty;
2399  gPad->PaintPolyLine(4, xb, yb);
2400  } else {
2401  gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
2402  }
2403  }
2404  }
2405  }
2406  }
2407  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2408  gPad->ResetBit(TGraph::kClipFrame);
2409 
2410  if (option3) {
2411  Int_t logx = gPad->GetLogx();
2412  Int_t logy = gPad->GetLogy();
2413  gPad->SetLogx(0);
2414  gPad->SetLogy(0);
2415  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2416  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2417  gPad->SetLogx(logx);
2418  gPad->SetLogy(logy);
2419  delete [] xline;
2420  delete [] yline;
2421  }
2422 }
2423 
2424 
2425 ////////////////////////////////////////////////////////////////////////////////
2426 /// [Paint this TGraphBentErrors with its current attributes.]($GP03)
2427 
2429 {
2430 
2431  Double_t *xline = 0;
2432  Double_t *yline = 0;
2433  Int_t if1 = 0;
2434  Int_t if2 = 0;
2435  Double_t xb[4], yb[4];
2436 
2437  const Int_t kBASEMARKER=8;
2438  Double_t s2x, s2y, symbolsize, sbase;
2439  Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2440  Double_t bxl, bxh, byl, byh;
2441  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};
2442  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2443  Int_t theNpoints = theGraph->GetN();
2444  Double_t *theX = theGraph->GetX();
2445  Double_t *theY = theGraph->GetY();
2446  Double_t *theEXlow = theGraph->GetEXlow(); if (!theEXlow) return;
2447  Double_t *theEYlow = theGraph->GetEYlow(); if (!theEYlow) return;
2448  Double_t *theEXhigh = theGraph->GetEXhigh(); if (!theEXhigh) return;
2449  Double_t *theEYhigh = theGraph->GetEYhigh(); if (!theEYhigh) return;
2450  Double_t *theEXlowd = theGraph->GetEXlowd(); if (!theEXlowd) return;
2451  Double_t *theEXhighd = theGraph->GetEXhighd(); if (!theEXhighd) return;
2452  Double_t *theEYlowd = theGraph->GetEYlowd(); if (!theEYlowd) return;
2453  Double_t *theEYhighd = theGraph->GetEYhighd(); if (!theEYhighd) return;
2454 
2455  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2456  Bool_t brackets = kFALSE;
2457  Bool_t braticks = kFALSE;
2458  if (strstr(option,"||") || strstr(option,"[]")) {
2459  brackets = kTRUE;
2460  if (strstr(option,"[]")) braticks = kTRUE;
2461  }
2462  Bool_t endLines = kTRUE;
2463  if (strchr(option,'z')) endLines = kFALSE;
2464  if (strchr(option,'Z')) endLines = kFALSE;
2465  const char *arrowOpt = 0;
2466  if (strchr(option,'>')) arrowOpt = ">";
2467  if (strstr(option,"|>")) arrowOpt = "|>";
2468 
2469  Bool_t axis = kFALSE;
2470  if (strchr(option,'a')) axis = kTRUE;
2471  if (strchr(option,'A')) axis = kTRUE;
2472  if (axis) PaintGraphSimple(theGraph,option);
2473 
2474  Bool_t option0 = kFALSE;
2475  Bool_t option2 = kFALSE;
2476  Bool_t option3 = kFALSE;
2477  Bool_t option4 = kFALSE;
2478  Bool_t option5 = kFALSE;
2479  if (strchr(option,'0')) option0 = kTRUE;
2480  if (strchr(option,'2')) option2 = kTRUE;
2481  if (strchr(option,'3')) option3 = kTRUE;
2482  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2483  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2484 
2485  if (option3) {
2486  xline = new Double_t[2*theNpoints];
2487  yline = new Double_t[2*theNpoints];
2488  if (!xline || !yline) {
2489  Error("Paint", "too many points, out of memory");
2490  return;
2491  }
2492  if1 = 1;
2493  if2 = 2*theNpoints;
2494  }
2495 
2496  theGraph->TAttLine::Modify();
2497 
2498  TArrow arrow;
2499  arrow.SetLineWidth(theGraph->GetLineWidth());
2500  arrow.SetLineColor(theGraph->GetLineColor());
2501  arrow.SetFillColor(theGraph->GetFillColor());
2502 
2503  TBox box;
2504  Double_t x1b,y1b,x2b,y2b;
2505  box.SetLineWidth(theGraph->GetLineWidth());
2506  box.SetLineColor(theGraph->GetLineColor());
2507  box.SetFillColor(theGraph->GetFillColor());
2508  box.SetFillStyle(theGraph->GetFillStyle());
2509 
2510  symbolsize = theGraph->GetMarkerSize();
2511  sbase = symbolsize*kBASEMARKER;
2512  Int_t mark = theGraph->GetMarkerStyle();
2513  Double_t cx = 0;
2514  Double_t cy = 0;
2515  if (mark >= 20 && mark <= 34) {
2516  cx = cxx[mark-20];
2517  cy = cyy[mark-20];
2518  }
2519 
2520  // define the offset of the error bars due to the symbol size
2521  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2522  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2523  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2524  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2525  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2526  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2527 
2528  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2529  for (Int_t i=0;i<theNpoints;i++) {
2530  x = gPad->XtoPad(theX[i]);
2531  y = gPad->YtoPad(theY[i]);
2532  bxl = gPad->YtoPad(theY[i]+theEXlowd[i]);
2533  bxh = gPad->YtoPad(theY[i]+theEXhighd[i]);
2534  byl = gPad->XtoPad(theX[i]+theEYlowd[i]);
2535  byh = gPad->XtoPad(theX[i]+theEYhighd[i]);
2536  if (!option0) {
2537  if (option3) {
2538  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2539  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2540  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2541  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2542  } else {
2543  if (x < gPad->GetUxmin()) continue;
2544  if (x > gPad->GetUxmax()) continue;
2545  if (y < gPad->GetUymin()) continue;
2546  if (y > gPad->GetUymax()) continue;
2547  }
2548  }
2549 
2550  // draw the error rectangles
2551  if (option2) {
2552  x1b = gPad->XtoPad(theX[i] - theEXlow[i]);
2553  y1b = gPad->YtoPad(theY[i] - theEYlow[i]);
2554  x2b = gPad->XtoPad(theX[i] + theEXhigh[i]);
2555  y2b = gPad->YtoPad(theY[i] + theEYhigh[i]);
2556  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2557  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2558  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2559  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2560  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2561  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2562  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2563  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2564  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2565  else box.PaintBox(x1b, y1b, x2b, y2b);
2566  continue;
2567  }
2568 
2569  // keep points for fill area drawing
2570  if (option3) {
2571  xline[if1-1] = byh;
2572  xline[if2-1] = byl;
2573  yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
2574  yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
2575  if1++;
2576  if2--;
2577  continue;
2578  }
2579 
2580  xl1 = x - s2x*cx;
2581  xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
2582  if (xl1 > xl2) {
2583  if (arrowOpt) {
2584  arrow.PaintArrow(xl1,y,xl2,bxl,asize,arrowOpt);
2585  } else {
2586  if (!brackets) gPad->PaintLine(xl1,y,xl2,bxl);
2587  if (endLines) {
2588  if (braticks) {
2589  xb[0] = xl2+tx; yb[0] = bxl-ty;
2590  xb[1] = xl2; yb[1] = bxl-ty;
2591  xb[2] = xl2; yb[2] = bxl+ty;
2592  xb[3] = xl2+tx; yb[3] = bxl+ty;
2593  gPad->PaintPolyLine(4, xb, yb);
2594  } else {
2595  gPad->PaintLine(xl2,bxl-ty,xl2,bxl+ty);
2596  }
2597  }
2598  }
2599  }
2600  xr1 = x + s2x*cx;
2601  xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
2602  if (xr1 < xr2) {
2603  if (arrowOpt) {
2604  arrow.PaintArrow(xr1,y,xr2,bxh,asize,arrowOpt);
2605  } else {
2606  if (!brackets) gPad->PaintLine(xr1,y,xr2,bxh);
2607  if (endLines) {
2608  if (braticks) {
2609  xb[0] = xr2-tx; yb[0] = bxh-ty;
2610  xb[1] = xr2; yb[1] = bxh-ty;
2611  xb[2] = xr2; yb[2] = bxh+ty;
2612  xb[3] = xr2-tx; yb[3] = bxh+ty;
2613  gPad->PaintPolyLine(4, xb, yb);
2614  } else {
2615  gPad->PaintLine(xr2,bxh-ty,xr2,bxh+ty);
2616  }
2617  }
2618  }
2619  }
2620  yup1 = y + s2y*cy;
2621  yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
2622  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2623  if (yup2 > yup1) {
2624  if (arrowOpt) {
2625  arrow.PaintArrow(x,yup1,byh,yup2,asize,arrowOpt);
2626  } else {
2627  if (!brackets) gPad->PaintLine(x,yup1,byh,yup2);
2628  if (endLines) {
2629  if (braticks) {
2630  xb[0] = byh-tx; yb[0] = yup2-ty;
2631  xb[1] = byh-tx; yb[1] = yup2;
2632  xb[2] = byh+tx; yb[2] = yup2;
2633  xb[3] = byh+tx; yb[3] = yup2-ty;
2634  gPad->PaintPolyLine(4, xb, yb);
2635  } else {
2636  gPad->PaintLine(byh-tx,yup2,byh+tx,yup2);
2637  }
2638  }
2639  }
2640  }
2641  ylow1 = y - s2y*cy;
2642  ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
2643  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2644  if (ylow2 < ylow1) {
2645  if (arrowOpt) {
2646  arrow.PaintArrow(x,ylow1,byl,ylow2,asize,arrowOpt);
2647  } else {
2648  if (!brackets) gPad->PaintLine(x,ylow1,byl,ylow2);
2649  if (endLines) {
2650  if (braticks) {
2651  xb[0] = byl-tx; yb[0] = ylow2+ty;
2652  xb[1] = byl-tx; yb[1] = ylow2;
2653  xb[2] = byl+tx; yb[2] = ylow2;
2654  xb[3] = byl+tx; yb[3] = ylow2+ty;
2655  gPad->PaintPolyLine(4, xb, yb);
2656  } else {
2657  gPad->PaintLine(byl-tx,ylow2,byl+tx,ylow2);
2658  }
2659  }
2660  }
2661  }
2662  }
2663  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2664  gPad->ResetBit(TGraph::kClipFrame);
2665 
2666  if (option3) {
2667  Int_t logx = gPad->GetLogx();
2668  Int_t logy = gPad->GetLogy();
2669  gPad->SetLogx(0);
2670  gPad->SetLogy(0);
2671  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2672  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2673  gPad->SetLogx(logx);
2674  gPad->SetLogy(logy);
2675  delete [] xline;
2676  delete [] yline;
2677  }
2678 }
2679 
2680 
2681 ////////////////////////////////////////////////////////////////////////////////
2682 /// [Paint this TGraphErrors with its current attributes.]($GP03)
2683 
2685 {
2686 
2687  Double_t *xline = 0;
2688  Double_t *yline = 0;
2689  Int_t if1 = 0;
2690  Int_t if2 = 0;
2691  Double_t xb[4], yb[4];
2692 
2693  const Int_t kBASEMARKER=8;
2694  Double_t s2x, s2y, symbolsize, sbase;
2695  Double_t x, y, ex, ey, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
2696  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};
2697  static Float_t cyy[15] = {1,1,1,1,1,1,1,1,1,0.5,0.6,1,1,1,1};
2698  Int_t theNpoints = theGraph->GetN();
2699  Double_t *theX = theGraph->GetX();
2700  Double_t *theY = theGraph->GetY();
2701  Double_t *theEX = theGraph->GetEX(); if (!theEX) return;
2702  Double_t *theEY = theGraph->GetEY(); if (!theEY) return;
2703 
2704  if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
2705  Bool_t brackets = kFALSE;
2706  Bool_t braticks = kFALSE;
2707  if (strstr(option,"||") || strstr(option,"[]")) {
2708  brackets = kTRUE;
2709  if (strstr(option,"[]")) braticks = kTRUE;
2710  }
2711  Bool_t endLines = kTRUE;
2712  if (strchr(option,'z')) endLines = kFALSE;
2713  if (strchr(option,'Z')) endLines = kFALSE;
2714  const char *arrowOpt = 0;
2715  if (strchr(option,'>')) arrowOpt = ">";
2716  if (strstr(option,"|>")) arrowOpt = "|>";
2717 
2718  Bool_t axis = kFALSE;
2719  if (strchr(option,'a')) axis = kTRUE;
2720  if (strchr(option,'A')) axis = kTRUE;
2721  if (axis) PaintGraphSimple(theGraph, option);
2722 
2723  Bool_t option0 = kFALSE;
2724  Bool_t option2 = kFALSE;
2725  Bool_t option3 = kFALSE;
2726  Bool_t option4 = kFALSE;
2727  Bool_t option5 = kFALSE;
2728  if (strchr(option,'0')) option0 = kTRUE;
2729  if (strchr(option,'2')) option2 = kTRUE;
2730  if (strchr(option,'3')) option3 = kTRUE;
2731  if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
2732  if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;}
2733 
2734  if (option3) {
2735  xline = new Double_t[2*theNpoints];
2736  yline = new Double_t[2*theNpoints];
2737  if (!xline || !yline) {
2738  Error("Paint", "too many points, out of memory");
2739  return;
2740  }
2741  if1 = 1;
2742  if2 = 2*theNpoints;
2743  }
2744 
2745  theGraph->TAttLine::Modify();
2746 
2747  TArrow arrow;
2748  arrow.SetLineWidth(theGraph->GetLineWidth());
2749  arrow.SetLineColor(theGraph->GetLineColor());
2750  arrow.SetFillColor(theGraph->GetFillColor());
2751 
2752  TBox box;
2753  Double_t x1b,y1b,x2b,y2b;
2754  box.SetLineWidth(theGraph->GetLineWidth());
2755  box.SetLineColor(theGraph->GetLineColor());
2756  box.SetFillColor(theGraph->GetFillColor());
2757  box.SetFillStyle(theGraph->GetFillStyle());
2758 
2759  symbolsize = theGraph->GetMarkerSize();
2760  sbase = symbolsize*kBASEMARKER;
2761  Int_t mark = theGraph->GetMarkerStyle();
2762  Double_t cx = 0;
2763  Double_t cy = 0;
2764  if (mark >= 20 && mark <= 34) {
2765  cx = cxx[mark-20];
2766  cy = cyy[mark-20];
2767  }
2768 
2769  // define the offset of the error bars due to the symbol size
2770  s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
2771  s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
2772  Int_t dxend = Int_t(gStyle->GetEndErrorSize());
2773  tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
2774  ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
2775  Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
2776 
2777  gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
2778  for (Int_t i=0;i<theNpoints;i++) {
2779  x = gPad->XtoPad(theX[i]);
2780  y = gPad->YtoPad(theY[i]);
2781  if (!option0) {
2782  if (option3) {
2783  if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
2784  if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
2785  if (y < gPad->GetUymin()) y = gPad->GetUymin();
2786  if (y > gPad->GetUymax()) y = gPad->GetUymax();
2787  } else {
2788  if (x < gPad->GetUxmin()) continue;
2789  if (x > gPad->GetUxmax()) continue;
2790  if (y < gPad->GetUymin()) continue;
2791  if (y > gPad->GetUymax()) continue;
2792  }
2793  }
2794  ex = theEX[i];
2795  ey = theEY[i];
2796 
2797  // draw the error rectangles
2798  if (option2) {
2799  x1b = gPad->XtoPad(theX[i] - ex);
2800  y1b = gPad->YtoPad(theY[i] - ey);
2801  x2b = gPad->XtoPad(theX[i] + ex);
2802  y2b = gPad->YtoPad(theY[i] + ey);
2803  if (x1b < gPad->GetUxmin()) x1b = gPad->GetUxmin();
2804  if (x1b > gPad->GetUxmax()) x1b = gPad->GetUxmax();
2805  if (y1b < gPad->GetUymin()) y1b = gPad->GetUymin();
2806  if (y1b > gPad->GetUymax()) y1b = gPad->GetUymax();
2807  if (x2b < gPad->GetUxmin()) x2b = gPad->GetUxmin();
2808  if (x2b > gPad->GetUxmax()) x2b = gPad->GetUxmax();
2809  if (y2b < gPad->GetUymin()) y2b = gPad->GetUymin();
2810  if (y2b > gPad->GetUymax()) y2b = gPad->GetUymax();
2811  if (option5) box.PaintBox(x1b, y1b, x2b, y2b, "l");
2812  else box.PaintBox(x1b, y1b, x2b, y2b);
2813  continue;
2814  }
2815 
2816  // keep points for fill area drawing
2817  if (option3) {
2818  xline[if1-1] = x;
2819  xline[if2-1] = x;
2820  yline[if1-1] = gPad->YtoPad(theY[i] + ey);
2821  yline[if2-1] = gPad->YtoPad(theY[i] - ey);
2822  if1++;
2823  if2--;
2824  continue;
2825  }
2826 
2827  xl1 = x - s2x*cx;
2828  xl2 = gPad->XtoPad(theX[i] - ex);
2829  if (xl1 > xl2) {
2830  if (arrowOpt) {
2831  arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
2832  } else {
2833  if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
2834  if (endLines) {
2835  if (braticks) {
2836  xb[0] = xl2+tx; yb[0] = y-ty;
2837  xb[1] = xl2; yb[1] = y-ty;
2838  xb[2] = xl2; yb[2] = y+ty;
2839  xb[3] = xl2+tx; yb[3] = y+ty;
2840  gPad->PaintPolyLine(4, xb, yb);
2841  } else {
2842  gPad->PaintLine(xl2,y-ty,xl2,y+ty);
2843  }
2844  }
2845  }
2846  }
2847  xr1 = x + s2x*cx;
2848  xr2 = gPad->XtoPad(theX[i] + ex);
2849  if (xr1 < xr2) {
2850  if (arrowOpt) {
2851  arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
2852  } else {
2853  if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
2854  if (endLines) {
2855  if (braticks) {
2856  xb[0] = xr2-tx; yb[0] = y-ty;
2857  xb[1] = xr2; yb[1] = y-ty;
2858  xb[2] = xr2; yb[2] = y+ty;
2859  xb[3] = xr2-tx; yb[3] = y+ty;
2860  gPad->PaintPolyLine(4, xb, yb);
2861  } else {
2862  gPad->PaintLine(xr2,y-ty,xr2,y+ty);
2863  }
2864  }
2865  }
2866  }
2867  yup1 = y + s2y*cy;
2868  yup2 = gPad->YtoPad(theY[i] + ey);
2869  if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
2870  if (yup2 > yup1) {
2871  if (arrowOpt) {
2872  arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
2873  } else {
2874  if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
2875  if (endLines) {
2876  if (braticks) {
2877  xb[0] = x-tx; yb[0] = yup2-ty;
2878  xb[1] = x-tx; yb[1] = yup2;
2879  xb[2] = x+tx; yb[2] = yup2;
2880  xb[3] = x+tx; yb[3] = yup2-ty;
2881  gPad->PaintPolyLine(4, xb, yb);
2882  } else {
2883  gPad->PaintLine(x-tx,yup2,x+tx,yup2);
2884  }
2885  }
2886  }
2887  }
2888  ylow1 = y - s2y*cy;
2889  ylow2 = gPad->YtoPad(theY[i] - ey);
2890  if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
2891  if (ylow2 < ylow1) {
2892  if (arrowOpt) {
2893  arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
2894  } else {
2895  if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
2896  if (endLines) {
2897  if (braticks) {
2898  xb[0] = x-tx; yb[0] = ylow2+ty;
2899  xb[1] = x-tx; yb[1] = ylow2;
2900  xb[2] = x+tx; yb[2] = ylow2;
2901  xb[3] = x+tx; yb[3] = ylow2+ty;
2902  gPad->PaintPolyLine(4, xb, yb);
2903  } else {
2904  gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
2905  }
2906  }
2907  }
2908  }
2909  }
2910  if (!brackets && !axis) PaintGraphSimple(theGraph, option);
2911  gPad->ResetBit(TGraph::kClipFrame);
2912 
2913  if (option3) {
2914  Int_t logx = gPad->GetLogx();
2915  Int_t logy = gPad->GetLogy();
2916  gPad->SetLogx(0);
2917  gPad->SetLogy(0);
2918  if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
2919  else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
2920  gPad->SetLogx(logx);
2921  gPad->SetLogy(logy);
2922  delete [] xline;
2923  delete [] yline;
2924  }
2925 }
2926 
2927 
2928 ////////////////////////////////////////////////////////////////////////////////
2929 /// [Paint this TGraphPolar with its current attributes.]($GP04)
2930 
2932 {
2933 
2934  Int_t ipt, i;
2935  Double_t rwrmin, rwrmax, rwtmin, rwtmax;
2936 
2937  TGraphPolar *theGraphPolar = (TGraphPolar*) theGraph;
2938 
2939  Int_t theNpoints = theGraphPolar->GetN();
2940  Double_t *theX = theGraphPolar->GetX();
2941  Double_t *theY = theGraphPolar->GetY();
2942  Double_t *theEX = theGraphPolar->GetEX();
2943  Double_t *theEY = theGraphPolar->GetEY();
2944 
2945  if (theNpoints<1) return;
2946  TString opt = options;
2947  opt.ToUpper();
2948 
2949  Bool_t nolabel = kFALSE;
2950  if (opt.Contains("N")){
2951  nolabel = kTRUE;
2952  opt.ReplaceAll("N","");
2953  }
2954 
2955  TGraphPolargram *thePolargram = theGraphPolar->GetPolargram();
2956 
2957  // Check for existing TGraphPolargram in the Pad
2958  if (gPad) {
2959  // Existing polargram
2960  if (thePolargram) if (!gPad->FindObject(thePolargram->GetName())) thePolargram=0;
2961  if (!thePolargram) {
2962  // Find any other Polargram in the Pad
2963  TListIter padObjIter(gPad->GetListOfPrimitives());
2964  while (TObject* AnyObj = padObjIter.Next()) {
2965  if (TString(AnyObj->ClassName()).CompareTo("TGraphPolargram",
2966  TString::kExact)==0)
2967  thePolargram = (TGraphPolargram*)AnyObj;
2968  theGraphPolar->SetPolargram(thePolargram);
2969  }
2970  }
2971  }
2972 
2973  // Get new polargram range if necessary.
2974  if (!thePolargram) {
2975  // Get range, initialize with first/last value
2976  rwrmin = theY[0]; rwrmax = theY[theNpoints-1];
2977  rwtmin = theX[0]; rwtmax = theX[theNpoints-1];
2978 
2979  for (ipt = 0; ipt < theNpoints; ipt++) {
2980  // Check for errors if available
2981  if (theEX) {
2982  if (theX[ipt] -theEX[ipt] < rwtmin) rwtmin = theX[ipt]-theEX[ipt];
2983  if (theX[ipt] +theEX[ipt] > rwtmax) rwtmax = theX[ipt]+theEX[ipt];
2984  } else {
2985  if (theX[ipt] < rwtmin) rwtmin=theX[ipt];
2986  if (theX[ipt] > rwtmax) rwtmax=theX[ipt];
2987  }
2988  if (theEY) {
2989  if (theY[ipt] -theEY[ipt] < rwrmin) rwrmin = theY[ipt]-theEY[ipt];
2990  if (theY[ipt] +theEY[ipt] > rwrmax) rwrmax = theY[ipt]+theEY[ipt];
2991  } else {
2992  if (theY[ipt] < rwrmin) rwrmin=theY[ipt];
2993  if (theY[ipt] > rwrmax) rwrmax=theY[ipt];
2994  }
2995  }
2996  // Add radial and Polar margins.
2997  if (rwrmin == rwrmax) rwrmax += 1.;
2998  if (rwtmin == rwtmax) rwtmax += 1.;
2999  Double_t dr = (rwrmax-rwrmin);
3000  Double_t dt = (rwtmax-rwtmin);
3001  rwrmax += 0.1*dr;
3002  rwrmin -= 0.1*dr;
3003 
3004  // Assume equally spaced points for full 2*Pi.
3005  rwtmax += dt/theNpoints;
3006  } else {
3007  rwrmin = thePolargram->GetRMin();
3008  rwrmax = thePolargram->GetRMax();
3009  rwtmin = thePolargram->GetTMin();
3010  rwtmax = thePolargram->GetTMax();
3011  }
3012 
3013  if ((!thePolargram) || theGraphPolar->GetOptionAxis()) {
3014  // Draw Polar coord system
3015  thePolargram = new TGraphPolargram("Polargram",rwrmin,rwrmax,rwtmin,rwtmax);
3016  theGraphPolar->SetPolargram(thePolargram);
3017  if (opt.Contains("O")) thePolargram->SetBit(TGraphPolargram::kLabelOrtho);
3018  else thePolargram->ResetBit(TGraphPolargram::kLabelOrtho);
3019  if (nolabel) thePolargram->Draw("N");
3020  else thePolargram->Draw("");
3021  theGraphPolar->SetOptionAxis(kFALSE); //Prevent redrawing
3022  }
3023 
3024  // Convert points to polar.
3025  Double_t *theXpol = theGraphPolar->GetXpol();
3026  Double_t *theYpol = theGraphPolar->GetYpol();
3027 
3028  // Project theta in [0,2*Pi] and radius in [0,1].
3029  Double_t radiusNDC = rwrmax-rwrmin;
3030  Double_t thetaNDC = (rwtmax-rwtmin)/(2*TMath::Pi());
3031 
3032  // Draw the error bars.
3033  // Y errors are lines, but X errors are pieces of circles.
3034  if (opt.Contains("E")) {
3035  Double_t c=1;
3036  if (thePolargram->IsDegree()) {c=180/TMath::Pi();}
3037  if (thePolargram->IsGrad()) {c=100/TMath::Pi();}
3038  if (theEY) {
3039  for (i=0; i<theNpoints; i++) {
3040  Double_t eymin, eymax, exmin,exmax;
3041  exmin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
3042  TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3043  eymin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
3044  TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3045  exmax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
3046  TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3047  eymax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
3048  TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3049  theGraphPolar->TAttLine::Modify();
3050  if (exmin != exmax || eymin != eymax) gPad->PaintLine(exmin,eymin,exmax,eymax);
3051  }
3052  }
3053  if (theEX) {
3054  for (i=0; i<theNpoints; i++) {
3055  Double_t rad = (theY[i]-rwrmin)/radiusNDC;
3056  Double_t phimin = c*(theX[i]-theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
3057  Double_t phimax = c*(theX[i]+theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
3058  theGraphPolar->TAttLine::Modify();
3059  if (phimin != phimax) thePolargram->PaintCircle(0,0,rad,phimin,phimax,0);
3060  }
3061  }
3062  }
3063 
3064  // Draw the graph itself.
3065  if (!(gPad->GetLogx()) && !(gPad->GetLogy())) {
3066  Double_t a, b, c=1, x1, x2, y1, y2, discr, norm1, norm2, xts, yts;
3067  Bool_t previouspointin = kFALSE;
3068  Double_t norm = 0;
3069  Double_t xt = 0;
3070  Double_t yt = 0 ;
3071  Int_t j = -1;
3072  if (thePolargram->IsDegree()) {c=180/TMath::Pi();}
3073  if (thePolargram->IsGrad()) {c=100/TMath::Pi();}
3074  for (i=0; i<theNpoints; i++) {
3075  xts = xt;
3076  yts = yt;
3077  xt = (theY[i]-rwrmin)/radiusNDC*TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
3078  yt = (theY[i]-rwrmin)/radiusNDC*TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
3079  norm = sqrt(xt*xt+yt*yt);
3080  // Check if points are in the main circle.
3081  if ( norm <= 1) {
3082  // We check that the previous point was in the circle too.
3083  // We record new point position.
3084  if (!previouspointin) {
3085  j++;
3086  theXpol[j] = xt;
3087  theYpol[j] = yt;
3088  } else {
3089  a = (yt-yts)/(xt-xts);
3090  b = yts-a*xts;
3091  discr = 4*(a*a-b*b+1);
3092  x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
3093  x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
3094  y1 = a*x1+b;
3095  y2 = a*x2+b;
3096  norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
3097  norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
3098  previouspointin = kFALSE;
3099  j = 0;
3100  if (norm1 < norm2) {
3101  theXpol[j] = x1;
3102  theYpol[j] = y1;
3103  } else {
3104  theXpol[j] = x2;
3105  theYpol[j] = y2;
3106  }
3107  j++;
3108  theXpol[j] = xt;
3109  theYpol[j] = yt;
3110  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3111  }
3112  } else {
3113  // We check that the previous point was in the circle.
3114  // We record new point position
3115  if (j>=1 && !previouspointin) {
3116  a = (yt-theYpol[j])/(xt-theXpol[j]);
3117  b = theYpol[j]-a*theXpol[j];
3118  previouspointin = kTRUE;
3119  discr = 4*(a*a-b*b+1);
3120  x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
3121  x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
3122  y1 = a*x1+b;
3123  y2 = a*x2+b;
3124  norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
3125  norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
3126  j++;
3127  if (norm1 < norm2) {
3128  theXpol[j] = x1;
3129  theYpol[j] = y1;
3130  } else {
3131  theXpol[j] = x2;
3132  theYpol[j] = y2;
3133  }
3134  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3135  }
3136  j=-1;
3137  }
3138  }
3139  if (j>=1) {
3140  // If the last point is in the circle, we draw the last serie of point.
3141  PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
3142  }
3143  } else {
3144  for (i=0; i<theNpoints; i++) {
3145  theXpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Cos((theX[i]-rwtmin)/thetaNDC)+1);
3146  theYpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Sin((theX[i]-rwtmin)/thetaNDC)+1);
3147  }
3148  PaintGraph(theGraphPolar, theNpoints, theXpol, theYpol,opt);
3149  }
3150 
3151  // Paint the title.
3152 
3153  if (TestBit(TH1::kNoTitle)) return;
3154  Int_t nt = strlen(theGraph->GetTitle());
3155  TPaveText *title = 0;
3156  TObject *obj;
3157  TIter next(gPad->GetListOfPrimitives());
3158  while ((obj = next())) {
3159  if (!obj->InheritsFrom(TPaveText::Class())) continue;
3160  title = (TPaveText*)obj;
3161  if (title->GetName())
3162  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
3163  break;
3164  }
3165  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
3166  if (title) delete title;
3167  return;
3168  }
3169  Double_t ht = gStyle->GetTitleH();
3170  Double_t wt = gStyle->GetTitleW();
3171  if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
3172  if (ht <= 0) ht = 0.05;
3173  if (wt <= 0) {
3174  TLatex l;
3175  l.SetTextSize(ht);
3176  l.SetTitle(theGraph->GetTitle());
3177  // Adjustment in case the title has several lines (#splitline)
3178  ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
3179  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
3180  wt = TMath::Min(0.7, 0.02+wndc);
3181  }
3182  if (title) {
3183  TText *t0 = (TText*)title->GetLine(0);
3184  if (t0) {
3185  if (!strcmp(t0->GetTitle(),theGraph->GetTitle())) return;
3186  t0->SetTitle(theGraph->GetTitle());
3187  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
3188  }
3189  return;
3190  }
3191 
3192  Int_t talh = gStyle->GetTitleAlign()/10;
3193  if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
3194  Int_t talv = gStyle->GetTitleAlign()%10;
3195  if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
3196 
3197  Double_t xpos, ypos;
3198  xpos = gStyle->GetTitleX();
3199  ypos = gStyle->GetTitleY();
3200 
3201  if (talh == 2) xpos = xpos-wt/2.;
3202  if (talh == 3) xpos = xpos-wt;
3203  if (talv == 2) ypos = ypos+ht/2.;
3204  if (talv == 1) ypos = ypos+ht;
3205 
3206  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
3207 
3208  // Box with the histogram title.
3210  ptitle->SetFillStyle(gStyle->GetTitleStyle());
3211  ptitle->SetName("title");
3214  ptitle->SetTextFont(gStyle->GetTitleFont(""));
3215  if (gStyle->GetTitleFont("")%10 > 2)
3216  ptitle->SetTextSize(gStyle->GetTitleFontSize());
3217  ptitle->AddText(theGraph->GetTitle());
3218  ptitle->SetBit(kCanDelete);
3219  ptitle->Draw();
3220  ptitle->Paint();
3221 }
3222 
3223 
3224 ////////////////////////////////////////////////////////////////////////////////
3225 /// Paint this graphQQ. No options for the time being.
3226 
3228 {
3229 
3230  TGraphQQ *theGraphQQ = (TGraphQQ*) theGraph;
3231 
3232  Double_t *theX = theGraphQQ->GetX();
3233  Double_t theXq1 = theGraphQQ->GetXq1();
3234  Double_t theXq2 = theGraphQQ->GetXq2();
3235  Double_t theYq1 = theGraphQQ->GetYq1();
3236  Double_t theYq2 = theGraphQQ->GetYq2();
3237  TF1 *theF = theGraphQQ->GetF();
3238 
3239  if (!theX){
3240  Error("TGraphQQ::Paint", "2nd dataset or theoretical function not specified");
3241  return;
3242  }
3243 
3244  if (theF){
3245  theGraphQQ->GetXaxis()->SetTitle("theoretical quantiles");
3246  theGraphQQ->GetYaxis()->SetTitle("data quantiles");
3247  }
3248 
3249  PaintGraphSimple(theGraph,option);
3250 
3251  Double_t xmin = gPad->GetUxmin();
3252  Double_t xmax = gPad->GetUxmax();
3253  Double_t ymin = gPad->GetUymin();
3254  Double_t ymax = gPad->GetUymax();
3255  Double_t yxmin, xymin, yxmax, xymax;
3256  Double_t xqmin = TMath::Max(xmin, theXq1);
3257  Double_t xqmax = TMath::Min(xmax, theXq2);
3258  Double_t yqmin = TMath::Max(ymin, theYq1);
3259  Double_t yqmax = TMath::Min(ymax, theYq2);
3260 
3261  TLine line1, line2, line3;
3262  line1.SetLineStyle(2);
3263  line3.SetLineStyle(2);
3264  yxmin = (theYq2-theYq1)*(xmin-theXq1)/(theXq2-theXq1) + theYq1;
3265  if (yxmin < ymin){
3266  xymin = (theXq2-theXq1)*(ymin-theYq1)/(theYq2-theYq1) + theXq1;
3267  line1.PaintLine(xymin, ymin, xqmin, yqmin);
3268  }
3269  else
3270  line1.PaintLine(xmin, yxmin, xqmin, yqmin);
3271 
3272  line2.PaintLine(xqmin, yqmin, xqmax, yqmax);
3273 
3274  yxmax = (theYq2-theYq1)*(xmax-theXq1)/(theXq2-theXq1) + theYq1;
3275  if (yxmax > ymax){
3276  xymax = (theXq2-theXq1)*(ymax-theYq1)/(theYq2-theYq1) + theXq1;
3277  line3.PaintLine(xqmax, yqmax, xymax, ymax);
3278  }
3279  else
3280  line3.PaintLine(xqmax, yqmax, xmax, yxmax);
3281 }
3282 
3283 
3284 ////////////////////////////////////////////////////////////////////////////////
3285 /// Paint theGraph reverting values along X and/or Y axis. a new graph is created.
3286 
3288 {
3289  TString opt = option;
3290  opt.ToLower();
3291  TH1F *theHist = (TH1F *)theGraph->GetHistogram();
3292 
3293  Bool_t lrx = opt.Contains("rx");
3294  Bool_t lry = opt.Contains("ry");
3295 
3296  Double_t LOX = theHist->GetXaxis()->GetLabelOffset();
3297  Double_t TLX = theHist->GetXaxis()->GetTickLength();
3298  Double_t LOY = theHist->GetYaxis()->GetLabelOffset();
3299  Double_t TLY = theHist->GetYaxis()->GetTickLength();
3300  Int_t XACOL = theHist->GetXaxis()->GetAxisColor();
3301  Int_t YACOL = theHist->GetYaxis()->GetAxisColor();
3302 
3303  if (opt.Contains("a")) {
3304  if (lrx) {
3305  theHist->GetXaxis()->SetTickLength(0.);
3306  theHist->GetXaxis()->SetLabelOffset(999.);
3307  theHist->GetXaxis()->SetAxisColor(gPad->GetFrameFillColor());
3308  }
3309  if (lry) {
3310  theHist->GetYaxis()->SetTickLength(0.);
3311  theHist->GetYaxis()->SetLabelOffset(999.);
3312  theHist->GetYaxis()->SetAxisColor(gPad->GetFrameFillColor());
3313  }
3314  theHist->Paint("0");
3315  opt.ReplaceAll("a", "");
3316  }
3317 
3318  Int_t N = theGraph->GetN();
3319  Double_t *X = theGraph->GetX();
3320  Double_t *Y = theGraph->GetY();
3321  Double_t XA1 = theGraph->GetXaxis()->GetXmin();
3322  Double_t XA2 = theGraph->GetXaxis()->GetXmax();
3323  Double_t YA1 = theGraph->GetYaxis()->GetXmin();
3324  Double_t YA2 = theGraph->GetYaxis()->GetXmax();
3325  Double_t dX = XA1+XA2;
3326  Double_t dY = YA1+YA2;
3327  std::vector<Double_t> newX(N);
3328  std::vector<Double_t> newY(N);
3329 
3330  if (lrx) {
3331  opt.ReplaceAll("rx", "");
3332 
3333  Double_t GL = 0.;
3334  theHist->GetXaxis()->SetTickLength(0.);
3335  theHist->GetXaxis()->SetLabelOffset(999.);
3336 
3337  // Redraw the new X axis
3338  gPad->Update();
3339  TString optax = "-SDH";
3340  if (gPad->GetGridx()) {
3341  GL = (YA2-YA1)/(gPad->GetY2() - gPad->GetY1());
3342  optax.Append("W");
3343  }
3344  TGaxis *theNewAxis = new TGaxis(gPad->GetUxmax(),
3345  gPad->GetUymin(),
3346  gPad->GetUxmin(),
3347  gPad->GetUymin(),
3348  theGraph->GetXaxis()->GetXmin(),
3349  theGraph->GetXaxis()->GetXmax(),
3350  theHist->GetNdivisions("X"),
3351  optax.Data(), -GL);
3352  theNewAxis->SetLabelFont(theGraph->GetXaxis()->GetLabelFont());
3353  theNewAxis->SetLabelSize(theGraph->GetXaxis()->GetLabelSize());
3354  theNewAxis->SetLabelColor(theGraph->GetXaxis()->GetLabelColor());
3355  theNewAxis->SetTickLength(TLX);
3356  theNewAxis->SetLabelOffset(LOX-theGraph->GetXaxis()->GetLabelSize());
3357  theNewAxis->Paint();
3358 
3359  // Reverse X coordinates
3360  for (Int_t i=0; i<N; i++) newX[i] = dX-X[i];
3361  } else {
3362  for (Int_t i=0; i<N; i++) newX[i] = X[i];
3363  }
3364 
3365  if (lry) {
3366  opt.ReplaceAll("ry", "");
3367  Double_t GL = 0.;
3368 
3369  // Redraw the new Y axis
3370  gPad->Update();
3371  TString optax = "-SDH";
3372 
3373  if (gPad->GetGridy()) {
3374  GL = (XA2-XA1)/(gPad->GetX2() - gPad->GetX1());
3375  optax.Append("W");
3376  }
3377  TGaxis *theNewAxis = new TGaxis(gPad->GetUxmin(),
3378  gPad->GetUymax(),
3379  gPad->GetUxmin(),
3380  gPad->GetUymin(),
3381  theGraph->GetYaxis()->GetXmin(),
3382  theGraph->GetYaxis()->GetXmax(),
3383  theHist->GetNdivisions("Y"),
3384  optax.Data(), GL);
3385  theNewAxis->SetLabelFont(theGraph->GetYaxis()->GetLabelFont());
3386  theNewAxis->SetLabelSize(theGraph->GetYaxis()->GetLabelSize());
3387  theNewAxis->SetLabelColor(theGraph->GetYaxis()->GetLabelColor());
3388  theNewAxis->SetTickLength(-TLY);
3389  theNewAxis->SetLabelOffset(LOY-TLY);
3390  theNewAxis->Paint();
3391 
3392  // Reverse Y coordinates
3393  for (Int_t i=0; i<N; i++) newY[i] = dY-Y[i];
3394  } else {
3395  for (Int_t i=0; i<N; i++) newY[i] = Y[i];
3396  }
3397 
3398  // Create the new reversed graph
3399  TGraph *theNewGraph = (TGraph*)theGraph->Clone();
3400  for (Int_t i=0; i<N; i++) theNewGraph->SetPoint(i, newX[i], newY[i]);
3401  theNewGraph->SetMarkerStyle(theGraph->GetMarkerStyle());
3402  theNewGraph->SetMarkerColor(theGraph->GetMarkerColor());
3403  theNewGraph->SetLineStyle(theGraph->GetLineStyle());
3404  theNewGraph->SetLineColor(theGraph->GetLineColor());
3405 
3406  PaintHelper(theNewGraph,opt.Data());
3407 
3408  theHist->GetXaxis()->SetLabelOffset(LOX);
3409  theHist->GetXaxis()->SetTickLength(TLX);
3410  theHist->GetYaxis()->SetLabelOffset(LOY);
3411  theHist->GetYaxis()->SetTickLength(TLY);
3412  theHist->GetXaxis()->SetAxisColor(XACOL);
3413  theHist->GetYaxis()->SetAxisColor(YACOL);
3414 }
3415 
3416 
3417 ////////////////////////////////////////////////////////////////////////////////
3418 /// Paint a simple graph, without errors bars.
3419 
3421 {
3422 
3423  if (strstr(option,"H") || strstr(option,"h")) {
3424  PaintGrapHist(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
3425  } else {
3426  PaintGraph(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
3427  }
3428 
3429  // Paint associated objects in the list of functions (for instance
3430  // the fit function).
3431  TList *functions = theGraph->GetListOfFunctions();
3432  if (!functions) return;
3433  TObjOptLink *lnk = (TObjOptLink*)functions->FirstLink();
3434  TObject *obj;
3435 
3436  while (lnk) {
3437  obj = lnk->GetObject();
3438  TVirtualPad *padsave = gPad;
3439  if (obj->InheritsFrom(TF1::Class())) {
3440  if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
3441  } else {
3442  obj->Paint(lnk->GetOption());
3443  }
3444  lnk = (TObjOptLink*)lnk->Next();
3445  padsave->cd();
3446  }
3447  return;
3448 }
3449 
3450 
3451 ////////////////////////////////////////////////////////////////////////////////
3452 /// Paint a polyline with hatches on one side showing an exclusion zone. x and y
3453 /// are the the vectors holding the polyline and n the number of points in the
3454 /// polyline and `w` the width of the hatches. `w` can be negative.
3455 /// This method is not meant to be used directly. It is called automatically
3456 /// according to the line style convention.
3457 
3459 {
3460 
3461  Int_t i,j,nf;
3462  Double_t w = (theGraph->GetLineWidth()/100)*0.005;
3463 
3464  Double_t *xf = new Double_t[2*n];
3465  Double_t *yf = new Double_t[2*n];
3466  Double_t *xt = new Double_t[n];
3467  Double_t *yt = new Double_t[n];
3468  Double_t x1, x2, y1, y2, x3, y3, xm, ym, a, a1, a2, a3;
3469 
3470  // Compute the gPad coordinates in TRUE normalized space (NDC)
3471  Int_t ix1,iy1,ix2,iy2;
3472  Int_t iw = gPad->GetWw();
3473  Int_t ih = gPad->GetWh();
3474  Double_t x1p,y1p,x2p,y2p;
3475  gPad->GetPadPar(x1p,y1p,x2p,y2p);
3476  ix1 = (Int_t)(iw*x1p);
3477  iy1 = (Int_t)(ih*y1p);
3478  ix2 = (Int_t)(iw*x2p);
3479  iy2 = (Int_t)(ih*y2p);
3480  Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
3481  Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
3482  Double_t rh = hndc/(Double_t)ih;
3483  Double_t rw = wndc/(Double_t)iw;
3484  Double_t x1ndc = (Double_t)ix1*rw;
3485  Double_t y1ndc = (Double_t)iy1*rh;
3486  Double_t x2ndc = (Double_t)ix2*rw;
3487  Double_t y2ndc = (Double_t)iy2*rh;
3488 
3489  // Ratios to convert user space in TRUE normalized space (NDC)
3490  Double_t rx1,ry1,rx2,ry2;
3491  gPad->GetRange(rx1,ry1,rx2,ry2);
3492  Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
3493  Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
3494 
3495  // The first part of the filled area is made of the graph points.
3496  // Make sure that two adjacent points are different.
3497  xf[0] = rx*(x[0]-rx1)+x1ndc;
3498  yf[0] = ry*(y[0]-ry1)+y1ndc;
3499  nf = 0;
3500  for (i=1; i<n; i++) {
3501  if (x[i]==x[i-1] && y[i]==y[i-1]) continue;
3502  nf++;
3503  xf[nf] = rx*(x[i]-rx1)+x1ndc;
3504  if (xf[i]==xf[i-1]) xf[i] += 0.000001; // add an epsilon to avoid exact vertical lines.
3505  yf[nf] = ry*(y[i]-ry1)+y1ndc;
3506  }
3507 
3508  // For each graph points a shifted points is computed to build up
3509  // the second part of the filled area. First and last points are
3510  // treated as special cases, outside of the loop.
3511  if (xf[1]==xf[0]) {
3512  a = TMath::PiOver2();
3513  } else {
3514  a = TMath::ATan((yf[1]-yf[0])/(xf[1]-xf[0]));
3515  }
3516  if (xf[0]<=xf[1]) {
3517  xt[0] = xf[0]-w*TMath::Sin(a);
3518  yt[0] = yf[0]+w*TMath::Cos(a);
3519  } else {
3520  xt[0] = xf[0]+w*TMath::Sin(a);
3521  yt[0] = yf[0]-w*TMath::Cos(a);
3522  }
3523 
3524  if (xf[nf]==xf[nf-1]) {
3525  a = TMath::PiOver2();
3526  } else {
3527  a = TMath::ATan((yf[nf]-yf[nf-1])/(xf[nf]-xf[nf-1]));
3528  }
3529  if (xf[nf]>=xf[nf-1]) {
3530  xt[nf] = xf[nf]-w*TMath::Sin(a);
3531  yt[nf] = yf[nf]+w*TMath::Cos(a);
3532  } else {
3533  xt[nf] = xf[nf]+w*TMath::Sin(a);
3534  yt[nf] = yf[nf]-w*TMath::Cos(a);
3535  }
3536 
3537  Double_t xi0,yi0,xi1,yi1,xi2,yi2;
3538  for (i=1; i<nf; i++) {
3539  xi0 = xf[i];
3540  yi0 = yf[i];
3541  xi1 = xf[i+1];
3542  yi1 = yf[i+1];
3543  xi2 = xf[i-1];
3544  yi2 = yf[i-1];
3545  if (xi1==xi0) {
3546  a1 = TMath::PiOver2();
3547  } else {
3548  a1 = TMath::ATan((yi1-yi0)/(xi1-xi0));
3549  }
3550  if (xi1<xi0) a1 = a1+3.14159;
3551  if (xi2==xi0) {
3552  a2 = TMath::PiOver2();
3553  } else {
3554  a2 = TMath::ATan((yi0-yi2)/(xi0-xi2));
3555  }
3556  if (xi0<xi2) a2 = a2+3.14159;
3557  x1 = xi0-w*TMath::Sin(a1);
3558  y1 = yi0+w*TMath::Cos(a1);
3559  x2 = xi0-w*TMath::Sin(a2);
3560  y2 = yi0+w*TMath::Cos(a2);
3561  xm = (x1+x2)*0.5;
3562  ym = (y1+y2)*0.5;
3563  if (xm==xi0) {
3564  a3 = TMath::PiOver2();
3565  } else {
3566  a3 = TMath::ATan((ym-yi0)/(xm-xi0));
3567  }
3568  x3 = xi0-w*TMath::Sin(a3+1.57079);
3569  y3 = yi0+w*TMath::Cos(a3+1.57079);
3570  // Rotate (x3,y3) by PI around (xi0,yi0) if it is not on the (xm,ym) side.
3571  if ((xm-xi0)*(x3-xi0)<0 && (ym-yi0)*(y3-yi0)<0) {
3572  x3 = 2*xi0-x3;
3573  y3 = 2*yi0-y3;
3574  }
3575  if ((xm==x1) && (ym==y1)) {
3576  x3 = xm;
3577  y3 = ym;
3578  }
3579  xt[i] = x3;
3580  yt[i] = y3;
3581  }
3582 
3583  // Close the polygon if the first and last points are the same
3584  if (xf[nf]==xf[0] && yf[nf]==yf[0]) {
3585  xm = (xt[nf]+xt[0])*0.5;
3586  ym = (yt[nf]+yt[0])*0.5;
3587  if (xm==xf[0]) {
3588  a3 = TMath::PiOver2();
3589  } else {
3590  a3 = TMath::ATan((ym-yf[0])/(xm-xf[0]));
3591  }
3592  x3 = xf[0]+w*TMath::Sin(a3+1.57079);
3593  y3 = yf[0]-w*TMath::Cos(a3+1.57079);
3594  if ((xm-xf[0])*(x3-xf[0])<0 && (ym-yf[0])*(y3-yf[0])<0) {
3595  x3 = 2*xf[0]-x3;
3596  y3 = 2*yf[0]-y3;
3597  }
3598  xt[nf] = x3;
3599  xt[0] = x3;
3600  yt[nf] = y3;
3601  yt[0] = y3;
3602  }
3603 
3604  // Find the crossing segments and remove the useless ones
3605  Double_t xc, yc, c1, b1, c2, b2;
3606  Bool_t cross = kFALSE;
3607  Int_t nf2 = nf;
3608  for (i=nf2; i>0; i--) {
3609  for (j=i-1; j>0; j--) {
3610  if (xt[i-1]==xt[i] || xt[j-1]==xt[j]) continue;
3611  c1 = (yt[i-1]-yt[i])/(xt[i-1]-xt[i]);
3612  b1 = yt[i]-c1*xt[i];
3613  c2 = (yt[j-1]-yt[j])/(xt[j-1]-xt[j]);
3614  b2 = yt[j]-c2*xt[j];
3615  if (c1 != c2) {
3616  xc = (b2-b1)/(c1-c2);
3617  yc = c1*xc+b1;
3618  if (xc>TMath::Min(xt[i],xt[i-1]) && xc<TMath::Max(xt[i],xt[i-1]) &&
3619  xc>TMath::Min(xt[j],xt[j-1]) && xc<TMath::Max(xt[j],xt[j-1]) &&
3620  yc>TMath::Min(yt[i],yt[i-1]) && yc<TMath::Max(yt[i],yt[i-1]) &&
3621  yc>TMath::Min(yt[j],yt[j-1]) && yc<TMath::Max(yt[j],yt[j-1])) {
3622  nf++; xf[nf] = xt[i]; yf[nf] = yt[i];
3623  nf++; xf[nf] = xc ; yf[nf] = yc;
3624  i = j;
3625  cross = kTRUE;
3626  break;
3627  } else {
3628  continue;
3629  }
3630  } else {
3631  continue;
3632  }
3633  }
3634  if (!cross) {
3635  nf++;
3636  xf[nf] = xt[i];
3637  yf[nf] = yt[i];
3638  }
3639  cross = kFALSE;
3640  }
3641  nf++; xf[nf] = xt[0]; yf[nf] = yt[0];
3642 
3643  // NDC to user coordinates
3644  for (i=0; i<nf+1; i++) {
3645  xf[i] = (1/rx)*(xf[i]-x1ndc)+rx1;
3646  yf[i] = (1/ry)*(yf[i]-y1ndc)+ry1;
3647  }
3648 
3649  // Draw filled area
3650  gPad->PaintFillArea(nf+1,xf,yf);
3651  theGraph->TAttLine::Modify(); // In case of PaintFillAreaHatches
3652 
3653  delete [] xf;
3654  delete [] yf;
3655  delete [] xt;
3656  delete [] yt;
3657 }
3658 
3659 
3660 ////////////////////////////////////////////////////////////////////////////////
3661 /// Paint the statistics box with the fit info.
3662 
3663 void TGraphPainter::PaintStats(TGraph *theGraph, TF1 *fit)
3664 {
3665 
3666  Int_t dofit;
3667  TPaveStats *stats = 0;
3668  TList *functions = theGraph->GetListOfFunctions();
3669  TIter next(functions);
3670  TObject *obj;
3671  while ((obj = next())) {
3672  if (obj->InheritsFrom(TPaveStats::Class())) {
3673  stats = (TPaveStats*)obj;
3674  break;
3675  }
3676  }
3677 
3678  if (stats) dofit = stats->GetOptFit();
3679  else dofit = gStyle->GetOptFit();
3680 
3681  if (!dofit) fit = 0;
3682  if (!fit) return;
3683  if (dofit == 1) dofit = 111;
3684  Int_t nlines = 0;
3685  Int_t print_fval = dofit%10;
3686  Int_t print_ferrors = (dofit/10)%10;
3687  Int_t print_fchi2 = (dofit/100)%10;
3688  Int_t print_fprob = (dofit/1000)%10;
3689  Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
3690  if (fit) nlinesf += fit->GetNpar();
3691  Bool_t done = kFALSE;
3692  Double_t statw = 1.8*gStyle->GetStatW();
3693  Double_t stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
3694  if (stats) {
3695  stats->Clear();
3696  done = kTRUE;
3697  } else {
3698  stats = new TPaveStats(
3699  gStyle->GetStatX()-statw,
3700  gStyle->GetStatY()-stath,
3701  gStyle->GetStatX(),
3702  gStyle->GetStatY(),"brNDC");
3703 
3704  stats->SetParent(functions);
3705  stats->SetOptFit(dofit);
3706  stats->SetOptStat(0);
3707  stats->SetFillColor(gStyle->GetStatColor());
3708  stats->SetFillStyle(gStyle->GetStatStyle());
3710  stats->SetTextFont(gStyle->GetStatFont());
3711  if (gStyle->GetStatFont()%10 > 2)
3712  stats->SetTextSize(gStyle->GetStatFontSize());
3713  stats->SetFitFormat(gStyle->GetFitFormat());
3714  stats->SetStatFormat(gStyle->GetStatFormat());
3715  stats->SetName("stats");
3716 
3718  stats->SetTextAlign(12);
3719  stats->SetBit(kCanDelete);
3720  stats->SetBit(kMustCleanup);
3721  }
3722 
3723  char t[64];
3724  char textstats[50];
3725  Int_t ndf = fit->GetNDF();
3726  snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
3727  snprintf(t,64,textstats,(Float_t)fit->GetChisquare());
3728  if (print_fchi2) stats->AddText(t);
3729  if (print_fprob) {
3730  snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
3731  snprintf(t,64,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
3732  stats->AddText(t);
3733  }
3734  if (print_fval || print_ferrors) {
3735  for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
3736  if (print_ferrors) {
3737  snprintf(textstats,50,"%-8s = %s%s #pm %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat(),"%",stats->GetFitFormat());
3738  snprintf(t,64,textstats,(Float_t)fit->GetParameter(ipar)
3739  ,(Float_t)fit->GetParError(ipar));
3740  } else {
3741  snprintf(textstats,50,"%-8s = %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat());
3742  snprintf(t,64,textstats,(Float_t)fit->GetParameter(ipar));
3743  }
3744  t[63] = 0;
3745  stats->AddText(t);
3746  }
3747  }
3748 
3749  if (!done) functions->Add(stats);
3750  stats->Paint();
3751 }
3752 
3753 
3754 ////////////////////////////////////////////////////////////////////////////////
3755 /// Smooth a curve given by N points.
3756 ///
3757 /// The original code is from an underlaying routine for Draw based on the
3758 /// CERN GD3 routine TVIPTE:
3759 ///
3760 /// Author - Marlow etc. Modified by - P. Ward Date - 3.10.1973
3761 ///
3762 /// This method draws a smooth tangentially continuous curve through
3763 /// the sequence of data points P(I) I=1,N where P(I)=(X(I),Y(I)).
3764 /// The curve is approximated by a polygonal arc of short vectors.
3765 /// The data points can represent open curves, P(1) != P(N) or closed
3766 /// curves P(2) == P(N). If a tangential discontinuity at P(I) is
3767 /// required, then set P(I)=P(I+1). Loops are also allowed.
3768 ///
3769 /// Reference Marlow and Powell, Harwell report No.R.7092.1972
3770 /// MCCONALOGUE, Computer Journal VOL.13, NO4, NOV1970P p392 6
3771 ///
3772 /// - npoints : Number of data points.
3773 /// - x : Abscissa
3774 /// - y : Ordinate
3775 
3776 void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_t *y, Int_t drawtype)
3777 {
3778 
3779  Int_t i, k, kp, km, npointsMax, banksize, n2, npt;
3780  Int_t maxiterations, finished;
3781  Int_t jtype, ktype, closed;
3782  Double_t sxmin, sxmax, symin, symax;
3783  Double_t delta;
3784  Double_t xorg, yorg;
3785  Double_t ratio_signs, xratio, yratio;
3786  Int_t flgic, flgis;
3787  Int_t iw, loptx;
3788  Double_t p1, p2, p3, p4, p5, p6;
3789  Double_t w1, w2, w3;
3790  Double_t a, b, c, r, s=0.0, t, z;
3791  Double_t co, so, ct, st, ctu, stu, xnt;
3792  Double_t dx1, dy1, dx2, dy2, dk1, dk2;
3793  Double_t xo, yo, dx, dy, xt, yt;
3794  Double_t xa, xb, ya, yb;
3795  Double_t u1, u2, u3, tj;
3796  Double_t cc, err;
3797  Double_t sb, sth;
3798  Double_t wsign, tsquare, tcube;
3799  c = t = co = so = ct = st = ctu = stu = dx1 = dy1 = dx2 = dy2 = 0;
3800  xt = yt = xa = xb = ya = yb = u1 = u2 = u3 = tj = sb = 0;
3801 
3802  npointsMax = npoints*10;
3803  n2 = npointsMax-2;
3804  banksize = n2;
3805 
3806  Double_t *qlx = new Double_t[npointsMax];
3807  Double_t *qly = new Double_t[npointsMax];
3808  if (!qlx || !qly) {
3809  Error("Smooth", "not enough space in memory");
3810  return;
3811  }
3812 
3813  // Decode the type of curve (draw type).
3814 
3815  loptx = kFALSE;
3816  jtype = (drawtype%1000)-10;
3817  if (jtype > 0) { ktype = jtype; loptx = kTRUE; }
3818  else ktype = drawtype%1000;
3819 
3820  Double_t ruxmin = gPad->GetUxmin();
3821  Double_t ruymin = gPad->GetUymin();
3822  if (ktype == 3) {
3823  xorg = ruxmin;
3824  yorg = ruymin;
3825  } else {
3826  xorg = TMath::Max((Double_t)0,ruxmin);
3827  yorg = TMath::Min(TMath::Max((Double_t)0,ruymin),gPad->GetUymax());
3828  }
3829 
3830  // delta is the accuracy required in constructing the curve.
3831  // If it is zero then the routine calculates a value otherwise
3832  // it uses this value. (default is 0.0)
3833 
3834  delta = 0.00055;
3835  maxiterations = 20;
3836 
3837  // Scale data to the range 0-ratio_signs in X, 0-1 in Y
3838  // where ratio_signs is the ratio between the number of changes
3839  // of sign in Y divided by the number of changes of sign in X
3840 
3841  sxmin = x[0];
3842  sxmax = x[0];
3843  symin = y[0];
3844  symax = y[0];
3845  Double_t six = 1;
3846  Double_t siy = 1;
3847  for (i=1;i<npoints;i++) {
3848  if (i > 1) {
3849  if ((x[i]-x[i-1])*(x[i-1]-x[i-2]) < 0) six++;
3850  if ((y[i]-y[i-1])*(y[i-1]-y[i-2]) < 0) siy++;
3851  }
3852  if (x[i] < sxmin) sxmin = x[i];
3853  if (x[i] > sxmax) sxmax = x[i];
3854  if (y[i] < symin) symin = y[i];
3855  if (y[i] > symax) symax = y[i];
3856  }
3857  closed = 0;
3858  Double_t dx1n = TMath::Abs(x[npoints-1]-x[0]);
3859  Double_t dy1n = TMath::Abs(y[npoints-1]-y[0]);
3860  if (dx1n < 0.01*(sxmax-sxmin) && dy1n < 0.01*(symax-symin)) closed = 1;
3861  if (sxmin == sxmax) {
3862  xratio = 1;
3863  } else {
3864  if (six > 1) ratio_signs = siy/six;
3865  else ratio_signs = 20;
3866  xratio = ratio_signs/(sxmax-sxmin);
3867  }
3868  if (symin == symax) yratio = 1;
3869  else yratio = 1/(symax-symin);
3870 
3871  qlx[0] = x[0];
3872  qly[0] = y[0];
3873  for (i=0;i<npoints;i++) {
3874  x[i] = (x[i]-sxmin)*xratio;
3875  y[i] = (y[i]-symin)*yratio;
3876  }
3877 
3878  // "finished" is minus one if we must draw a straight line from P(k-1)
3879  // to P(k). "finished" is one if the last call to PaintPolyLine has < n2
3880  // points. "finished" is zero otherwise. npt counts the X and Y
3881  // coordinates in work . When npt=n2 a call to IPL is made.
3882 
3883  finished = 0;
3884  npt = 1;
3885  k = 1;
3886 
3887  // Convert coordinates back to original system
3888 
3889  // Separate the set of data points into arcs P(k-1),P(k).
3890  // Calculate the direction cosines. first consider whether
3891  // there is a continuous tangent at the endpoints.
3892 
3893  if (!closed) {
3894  if (x[0] != x[npoints-1] || y[0] != y[npoints-1]) goto L40;
3895  if (x[npoints-2] == x[npoints-1] && y[npoints-2] == y[npoints-1]) goto L40;
3896  if (x[0] == x[1] && y[0] == y[1]) goto L40;
3897  }
3898  flgic = kFALSE;
3899  flgis = kTRUE;
3900 
3901  // flgic is true if the curve is open and false if it is closed.
3902  // flgis is true in the main loop, but is false if there is
3903  // a deviation from the main loop.
3904 
3905  km = npoints - 1;
3906 
3907  // Calculate direction cosines at P(1) using P(N-1),P(1),P(2).
3908 
3909  goto L100;
3910 L40:
3911  flgic = kTRUE;
3912  flgis = kFALSE;
3913 
3914  // Skip excessive consecutive equal points.
3915 
3916 L50:
3917  if (k >= npoints) {
3918  finished = 1; // Prepare to clear out remaining short vectors before returning
3919  if (npt > 1) goto L310;
3920  goto L390;
3921  }
3922  k++;
3923  if (x[k-1] == x[k-2] && y[k-1] == y[k-2]) goto L50;
3924 L60:
3925  km = k-1;
3926  if (k > npoints) {
3927  finished = 1; // Prepare to clear out remaining short vectors before returning
3928  if (npt > 1) goto L310;
3929  goto L390;
3930  }
3931  if (k < npoints) goto L90;
3932  if (!flgic) { kp = 2; goto L130;}
3933 
3934 L80:
3935  if (flgis) goto L150;
3936 
3937  // Draw a straight line from P(k-1) to P(k).
3938 
3939  finished = -1;
3940  goto L170;
3941 
3942  // Test whether P(k) is a cusp.
3943 
3944 L90:
3945  if (x[k-1] == x[k] && y[k-1] == y[k]) goto L80;
3946 L100:
3947  kp = k+1;
3948  goto L130;
3949 
3950  // Branch if the next section of the curve begins at a cusp.
3951 
3952 L110:
3953  if (!flgis) goto L50;
3954 
3955  // Carry forward the direction cosines from the previous arc.
3956 
3957 L120:
3958  co = ct;
3959  so = st;
3960  k++;
3961  goto L60;
3962 
3963  // Calculate the direction cosines at P(k). If k=1 then
3964  // N-1 is used for k-1. If k=N then 2 is used for k+1.
3965  // direction cosines at P(k) obtained from P(k-1),P(k),P(k+1).
3966 
3967 L130:
3968  dx1 = x[k-1] - x[km-1];
3969  dy1 = y[k-1] - y[km-1];
3970  dk1 = dx1*dx1 + dy1*dy1;
3971  dx2 = x[kp-1] - x[k-1];
3972  dy2 = y[kp-1] - y[k-1];
3973  dk2 = dx2*dx2 + dy2*dy2;
3974  ctu = dx1*dk2 + dx2*dk1;
3975  stu = dy1*dk2 + dy2*dk1;
3976  xnt = ctu*ctu + stu*stu;
3977 
3978  // If both ctu and stu are zero,then default.This can
3979  // occur when P(k)=P(k+1). I.E. A loop.
3980 
3981  if (xnt < 1.E-25) {
3982  ctu = dy1;
3983  stu =-dx1;
3984  xnt = dk1;
3985  }
3986  // Normalise direction cosines.
3987 
3988  ct = ctu/TMath::Sqrt(xnt);
3989  st = stu/TMath::Sqrt(xnt);
3990  if (flgis) goto L160;
3991 
3992  // Direction cosines at P(k-1) obtained from P(k-1),P(k),P(k+1).
3993 
3994  w3 = 2*(dx1*dy2-dx2*dy1);
3995  co = ctu+w3*dy1;
3996  so = stu-w3*dx1;
3997  xnt = 1/TMath::Sqrt(co*co+so*so);
3998  co = co*xnt;
3999  so = so*xnt;
4000  flgis = kTRUE;
4001  goto L170;
4002 
4003  // Direction cosines at P(k) obtained from P(k-2),P(k-1),P(k).
4004 
4005 L150:
4006  w3 = 2*(dx1*dy2-dx2*dy1);
4007  ct = ctu-w3*dy2;
4008  st = stu+w3*dx2;
4009  xnt = 1/TMath::Sqrt(ct*ct+st*st);
4010  ct = ct*xnt;
4011  st = st*xnt;
4012  flgis = kFALSE;
4013  goto L170;
4014 L160:
4015  if (k <= 1) goto L120;
4016 
4017  // For the arc between P(k-1) and P(k) with direction cosines co,
4018  // so and ct,st respectively, calculate the coefficients of the
4019  // parametric cubic represented by X(t) and Y(t) where
4020  // X(t)=xa*t**3 + xb*t**2 + co*t + xo
4021  // Y(t)=ya*t**3 + yb*t**2 + so*t + yo
4022 
4023 L170:
4024  xo = x[k-2];
4025  yo = y[k-2];
4026  dx = x[k-1] - xo;
4027  dy = y[k-1] - yo;
4028 
4029  // Initialise the values of X(TI),Y(TI) in xt and yt respectively.
4030 
4031  xt = xo;
4032  yt = yo;
4033  if (finished < 0) { // Draw a straight line between (xo,yo) and (xt,yt)
4034  xt += dx;
4035  yt += dy;
4036  goto L300;
4037  }
4038  c = dx*dx+dy*dy;
4039  a = co+ct;
4040  b = so+st;
4041  r = dx*a+dy*b;
4042  t = c*6/(TMath::Sqrt(r*r+2*(7-co*ct-so*st)*c)+r);
4043  tsquare = t*t;
4044  tcube = t*tsquare;
4045  xa = (a*t-2*dx)/tcube;
4046  xb = (3*dx-(co+a)*t)/tsquare;
4047  ya = (b*t-2*dy)/tcube;
4048  yb = (3*dy-(so+b)*t)/tsquare;
4049 
4050  // If the curve is close to a straight line then use a straight
4051  // line between (xo,yo) and (xt,yt).
4052 
4053  if (.75*TMath::Max(TMath::Abs(dx*so-dy*co),TMath::Abs(dx*st-dy*ct)) <= delta) {
4054  finished = -1;
4055  xt += dx;
4056  yt += dy;
4057  goto L300;
4058  }
4059 
4060  // Calculate a set of values 0 == t(0).LTCT(1) < ... < t(M)=TC
4061  // such that polygonal arc joining X(t(J)),Y(t(J)) (J=0,1,..M)
4062  // is within the required accuracy of the curve
4063 
4064  tj = 0;
4065  u1 = ya*xb-yb*xa;
4066  u2 = yb*co-xb*so;
4067  u3 = so*xa-ya*co;
4068 
4069  // Given t(J), calculate t(J+1). The values of X(t(J)),
4070  // Y(t(J)) t(J) are contained in xt,yt and tj respectively.
4071 
4072 L180:
4073  s = t - tj;
4074  iw = -2;
4075 
4076  // Define iw here later.
4077 
4078  p1 = (2*u1)*tj-u3;
4079  p2 = (u1*tj-u3)*3*tj+u2;
4080  p3 = 3*tj*ya+yb;
4081  p4 = (p3+yb)*tj+so;
4082  p5 = 3*tj*xa+xb;
4083  p6 = (p5+xb)*tj+co;
4084 
4085  // Test D(tj,THETA). A is set to (Y(tj+s)-Y(tj))/s.b is
4086  // set to (X(tj+s)-X(tj))/s.
4087 
4088  cc = 0.8209285;
4089  err = 0.1209835;
4090 L190:
4091  iw -= 2;
4092 L200:
4093  a = (s*ya+p3)*s+p4;
4094  b = (s*xa+p5)*s+p6;
4095 
4096  // Set z to PSI(D/delta)-cc.
4097 
4098  w1 = -s*(s*u1+p1);
4099  w2 = s*s*u1-p2;
4100  w3 = 1.5*w1+w2;
4101 
4102  // Set the estimate of (THETA-tj)/s.Then set the numerator
4103  // of the expression (EQUATION 4.4)/s. Then set the square
4104  // of D(tj,tj+s)/delta. Then replace z by PSI(D/delta)-cc.
4105 
4106  if (w3 > 0) wsign = TMath::Abs(w1);
4107  else wsign = -TMath::Abs(w1);
4108  sth = 0.5+wsign/(3.4*TMath::Abs(w1)+5.2*TMath::Abs(w3));
4109  z = s*sth*(s-s*sth)*(w1*sth+w1+w2);
4110  z = z*z/((a*a+b*b)*(delta*delta));
4111  z = (z+2.642937)*z/((.3715652*z+3.063444)*z+.2441889)-cc;
4112 
4113  // Branch if z has been calculated
4114 
4115  if (iw > 0) goto L250;
4116  if (z > err) goto L240;
4117  goto L220;
4118 L210:
4119  iw -= 2;
4120 L220:
4121  if (iw+2 == 0) goto L190;
4122  if (iw+2 > 0) goto L290;
4123 
4124  // Last part of arc.
4125 
4126 L230:
4127  xt = x[k-1];
4128  yt = y[k-1];
4129  s = 0;
4130  goto L300;
4131 
4132  // z(s). find a value of s where 0 <= s <= sb such that
4133  // TMath::Abs(z(s)) < err
4134 
4135 L240:
4136  kp = 0;
4137  c = z;
4138  sb = s;
4139 L250:
4140  theGraph->Zero(kp,0,sb,err,s,z,maxiterations);
4141  if (kp == 2) goto L210;
4142  if (kp > 2) {
4143  Error("Smooth", "Attempt to plot outside plot limits");
4144  goto L230;
4145  }
4146  if (iw > 0) goto L200;
4147 
4148  // Set z=z(s) for s=0.
4149 
4150  if (iw < 0) {
4151  z = -cc;
4152  iw = 0;
4153  goto L250;
4154  }
4155 
4156  // Set z=z(s) for s=sb.
4157 
4158  z = c;
4159  iw = 1;
4160  goto L250;
4161 
4162  // Update tj,xt and yt.
4163 
4164 L290:
4165  xt = xt + s*b;
4166  yt = yt + s*a;
4167  tj = s + tj;
4168 
4169  // Convert coordinates to original system
4170 
4171 L300:
4172  qlx[npt] = sxmin + xt/xratio;
4173  qly[npt] = symin + yt/yratio;
4174  npt++;
4175 
4176  // If a fill area must be drawn and if the banks LX and
4177  // LY are too small they are enlarged in order to draw
4178  // the filled area in one go.
4179 
4180  if (npt < banksize) goto L320;
4181  if (drawtype >= 1000 || ktype > 1) {
4182  Int_t newsize = banksize + n2;
4183  Double_t *qtemp = new Double_t[banksize];
4184  for (i=0;i<banksize;i++) qtemp[i] = qlx[i];
4185  delete [] qlx;
4186  qlx = new Double_t[newsize];
4187  for (i=0;i<banksize;i++) qlx[i] = qtemp[i];
4188  for (i=0;i<banksize;i++) qtemp[i] = qly[i];
4189  delete [] qly;
4190  qly = new Double_t[newsize];
4191  for (i=0;i<banksize;i++) qly[i] = qtemp[i];
4192  delete [] qtemp;
4193  banksize = newsize;
4194  goto L320;
4195  }
4196 
4197  // Draw the graph
4198 
4199 L310:
4200  if (drawtype >= 1000) {
4201  gPad->PaintFillArea(npt,qlx,qly, "B");
4202  } else {
4203  if (ktype > 1) {
4204  if (!loptx) {
4205  qlx[npt] = qlx[npt-1];
4206  qlx[npt+1] = qlx[0];
4207  qly[npt] = yorg;
4208  qly[npt+1] = yorg;
4209  } else {
4210  qlx[npt] = xorg;
4211  qlx[npt+1] = xorg;
4212  qly[npt] = qly[npt-1];
4213  qly[npt+1] = qly[0];
4214  }
4215  gPad->PaintFillArea(npt+2,qlx,qly);
4216  }
4217  if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, qlx, qly);
4218  gPad->PaintPolyLine(npt,qlx,qly);
4219  }
4220  npt = 1;
4221  qlx[0] = sxmin + xt/xratio;
4222  qly[0] = symin + yt/yratio;
4223 L320:
4224  if (finished > 0) goto L390;
4225  if (finished < 0) { finished = 0; goto L110;}
4226  if (s > 0) goto L180;
4227  goto L110;
4228 
4229  // Convert coordinates back to original system
4230 
4231 L390:
4232  for (i=0;i<npoints;i++) {
4233  x[i] = sxmin + x[i]/xratio;
4234  y[i] = symin + y[i]/yratio;
4235  }
4236 
4237  delete [] qlx;
4238  delete [] qly;
4239 }
4240 
4241 ////////////////////////////////////////////////////////////////////////////////
4242 /// Static function to set `fgMaxPointsPerLine` for graph painting. When graphs
4243 /// are painted with lines, they are split into chunks of length `fgMaxPointsPerLine`.
4244 /// This allows to paint line with an "infinite" number of points. In some case
4245 /// this "chunks painting" technic may create artefacts at the chunk's boundaries.
4246 /// For instance when zooming deeply in a PDF file. To avoid this effect it might
4247 /// be necessary to increase the chunks' size using this function:
4248 /// `TGraphPainter::SetMaxPointsPerLine(20000)`.
4249 
4251 {
4252  fgMaxPointsPerLine = maxp;
4253  if (maxp < 50) fgMaxPointsPerLine = 50;
4254 }
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:244
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:7844
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1021
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5692
Color_t GetLabelColor(Option_t *axis="X") const
Return the label color number in the axis.
Definition: TStyle.cxx:921
float xmin
Definition: THbookFile.cxx:93
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:293
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:233
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:957
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:259
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:8231
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:901
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:687
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
#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
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:182
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1113
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:410
Float_t GetEndErrorSize() const
Definition: TStyle.h:173
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Basic string class.
Definition: TString.h:131
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.
#define f(i)
Definition: RSha256.hxx:104
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1100
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:1817
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:268
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:187
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:933
don&#39;t draw stats box
Definition: TH1.h:160
Double_t Prob(Double_t chi2, Int_t ndf)
Iterator of linked list.
Definition: TList.h:197
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:734
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:256
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:257
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:1776
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:2597
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:261
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:410
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:311
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:231
Double_t Log10(Double_t x)
Definition: TMath.h:763
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:2460
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:559
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:208
Base class for several text objects.
Definition: TText.h:23
Float_t GetStatX() const
Definition: TStyle.h:251
Float_t GetTitleX() const
Definition: TStyle.h:267
virtual void Show()
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
Function which returns kTRUE if point xp,yp lies inside the polygon defined by the np points in array...
Definition: TMath.h:1329
Float_t GetBarWidth() const
Definition: TStyle.h:171
constexpr Double_t Pi()
Definition: TMath.h:38
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
Style_t GetStatStyle() const
Definition: TStyle.h:249
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:2712
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:956
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:2510
Float_t GetTitleH() const
Definition: TStyle.h:270
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:247
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:252
Float_t GetStatW() const
Definition: TStyle.h:253
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:172
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:285
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()
Base of natural log: .
Definition: TMath.h:97
#define h(i)
Definition: RSha256.hxx:106
Define a Frame.
Definition: TFrame.h:19
Double_t Cos(Double_t)
Definition: TMath.h:640
Color_t GetTitleFillColor() const
Definition: TStyle.h:258
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:7929
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:262
Float_t GetTitleW() const
Definition: TStyle.h:269
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
#define d(i)
Definition: RSha256.hxx:102
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:320
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:172
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:198
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
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:246
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:248
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:935
Double_t * GetY() const
Definition: TGraph.h:130
Float_t GetTickLength(Option_t *axis="X") const
Return tick length.
Definition: TStyle.cxx:997
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:254
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:636
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:945
#define snprintf
Definition: civetweb.c:1351
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
#define c(i)
Definition: RSha256.hxx:101
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:319
Float_t GetBarOffset() const
Definition: TStyle.h:170
Style_t GetTitleStyle() const
Definition: TStyle.h:260
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:690
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:245
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:889
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:52
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:250
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:302
Int_t GetOptTitle() const
Definition: TStyle.h:233
static const double x3[11]
const char * Data() const
Definition: TString.h:364
Double_t ATan(Double_t)
Definition: TMath.h:674
void SetPolargram(TGraphPolargram *p)
Definition: TGraphPolar.h:50