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