Logo ROOT  
Reference Guide
TMultiGraph.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 12/10/2000
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 "TEnv.h"
14 #include "TBrowser.h"
15 #include "TMultiGraph.h"
16 #include "TGraph.h"
17 #include "TH1.h"
18 #include "TH2.h"
19 #include "TVirtualPad.h"
20 #include "TVirtualFitter.h"
21 #include "TPluginManager.h"
22 #include "TMath.h"
23 #include "TF1.h"
24 #include "strlcpy.h"
25 
26 #include "HFitInterface.h"
27 #include "Fit/DataRange.h"
28 #include "Math/MinimizerOptions.h"
29 
30 #include <iostream>
31 #include <cstdlib>
32 #include <cctype>
33 
34 extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
35 
37 
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 
41 /** \class TMultiGraph
42  \ingroup Hist
43  \brief A TMultiGraph is a collection of TGraph (or derived) objects.
44 
45 - [Introduction](#MG00)
46 - [MultiGraphs' drawing](#MG01)
47  - [Setting drawing options](#MG01a)
48  - [Titles setting](#MG01b)
49  - [The option "3D"](#MG01c)
50  - [Legend drawing](#MG01d)
51  - [Automatic coloring](#MG01e)
52  - [Reverse axis](#MG01f)
53 - [MultiGraphs' fitting](#MG02)
54  - [Fit box position](#MG02a)
55 - [Axis' limits setting](#MG03)
56 
57 
58 ### <a name="MG00"></a> Introduction
59 
60 A TMultiGraph allows to manipulate a set of graphs as a single entity. In particular,
61 when drawn, the X and Y axis ranges are automatically computed such as all the graphs
62 will be visible.
63 
64 `TMultiGraph::Add` should be used to add a new graph to the list.
65 
66 The TMultiGraph owns the objects in the list.
67 
68 The number of graphs in a multigraph can be retrieve with:
69 ~~~ {.cpp}
70 mg->GetListOfGraphs()->GetEntries();
71 ~~~
72 
73 ### <a name="MG00"></a> MultiGraphs' Drawing
74 
75 The drawing options are the same as for TGraph.
76 Like for TGraph, the painting is performed thanks to the TGraphPainter
77 class. All details about the various painting options are given in this class.
78 
79 Example:
80 ~~~ {.cpp}
81  TGraph *gr1 = new TGraph(...
82  TGraphErrors *gr2 = new TGraphErrors(...
83  TMultiGraph *mg = new TMultiGraph();
84  mg->Add(gr1,"lp");
85  mg->Add(gr2,"cp");
86  mg->Draw("a");
87 ~~~
88 
89 #### <a name="MG01a"></a> Setting drawing options
90 
91 The drawing option for each TGraph may be specified as an optional
92 second argument of the `Add` function.
93 
94 If a draw option is specified, it will be used to draw the graph,
95 otherwise the graph will be drawn with the option specified in
96 `TMultiGraph::Draw`
97 
98 #### <a name="MG01b"></a> Titles setting
99 
100 The global title and the axis titles can be modified the following way:
101 
102 ~~~ {.cpp}
103  [...]
104  auto mg = new TMultiGraph;
105  mg->SetTitle("title;xaxis title; yaxis title");
106  mg->Add(g1);
107  mg->Add(g2);
108  mg->Draw("apl");
109 ~~~
110 
111 #### <a name="MG01c"></a> The option "3D"
112 
113 A special option `3D` allows to draw the graphs in a 3D space. See the
114 following example:
115 
116 Begin_Macro(source)
117 {
118  auto c0 = new TCanvas("c1","multigraph L3",200,10,700,500);
119 
120  auto mg = new TMultiGraph();
121 
122  auto gr1 = new TGraph(); gr1->SetLineColor(kBlue);
123  auto gr2 = new TGraph(); gr2->SetLineColor(kRed);
124  auto gr3 = new TGraph(); gr3->SetLineColor(kGreen);
125  auto gr4 = new TGraph(); gr4->SetLineColor(kOrange);
126 
127  Double_t dx = 6.28/1000;
128  Double_t x = -3.14;
129 
130  for (int i=0; i<=1000; i++) {
131  x = x+dx;
132  gr1->SetPoint(i,x,2.*TMath::Sin(x));
133  gr2->SetPoint(i,x,TMath::Cos(x));
134  gr3->SetPoint(i,x,TMath::Cos(x*x));
135  gr4->SetPoint(i,x,TMath::Cos(x*x*x));
136  }
137 
138  mg->Add(gr4); gr4->SetTitle("Cos(x*x*x)"); gr4->SetLineWidth(3);
139  mg->Add(gr3); gr3->SetTitle("Cos(x*x)") ; gr3->SetLineWidth(3);
140  mg->Add(gr2); gr2->SetTitle("Cos(x)") ; gr2->SetLineWidth(3);
141  mg->Add(gr1); gr1->SetTitle("2*Sin(x)") ; gr1->SetLineWidth(3);
142 
143  mg->SetTitle("Multi-graph Title; X-axis Title; Y-axis Title");
144 
145  mg->Draw("a fb l3d");
146 
147  mg->GetHistogram()->GetXaxis()->SetRangeUser(0.,2.5);
148  gPad->Modified();
149  gPad->Update();
150 }
151 End_Macro
152 
153 #### <a name="MG01d"></a> Legend drawing
154 
155 The method TPad::BuildLegend is able to extract the graphs inside a
156 multigraph. The following example demonstrate this.
157 
158 Begin_Macro(source)
159 {
160  auto c3 = new TCanvas("c3","c3",600, 400);
161 
162  auto mg = new TMultiGraph("mg","mg");
163 
164  const Int_t size = 10;
165 
166  double px[size];
167  double py1[size];
168  double py2[size];
169  double py3[size];
170 
171  for ( int i = 0; i < size ; ++i ) {
172  px[i] = i;
173  py1[i] = size - i;
174  py2[i] = size - 0.5 * i;
175  py3[i] = size - 0.6 * i;
176  }
177 
178  auto gr1 = new TGraph( size, px, py1 );
179  gr1->SetName("gr1");
180  gr1->SetTitle("graph 1");
181  gr1->SetMarkerStyle(21);
182  gr1->SetDrawOption("AP");
183  gr1->SetLineColor(2);
184  gr1->SetLineWidth(4);
185  gr1->SetFillStyle(0);
186 
187  auto gr2 = new TGraph( size, px, py2 );
188  gr2->SetName("gr2");
189  gr2->SetTitle("graph 2");
190  gr2->SetMarkerStyle(22);
191  gr2->SetMarkerColor(2);
192  gr2->SetDrawOption("P");
193  gr2->SetLineColor(3);
194  gr2->SetLineWidth(4);
195  gr2->SetFillStyle(0);
196 
197  auto gr3 = new TGraph( size, px, py3 );
198  gr3->SetName("gr3");
199  gr3->SetTitle("graph 3");
200  gr3->SetMarkerStyle(23);
201  gr3->SetLineColor(4);
202  gr3->SetLineWidth(4);
203  gr3->SetFillStyle(0);
204 
205  mg->Add( gr1 );
206  mg->Add( gr2 );
207 
208  gr3->Draw("ALP");
209  mg->Draw("LP");
210  c3->BuildLegend();
211 }
212 End_Macro
213 
214 #### <a name="MG01e"></a> Automatic coloring
215 
216 Automatic coloring according to the current palette is available as shown in the
217 following example:
218 
219 Begin_Macro(source)
220 ../../../tutorials/graphs/multigraphpalettecolor.C
221 End_Macro
222 
223 #### <a name="MG01f"></a> Reverse axis
224 
225 \since **ROOT version 6.19/02**
226 
227 When a TMultiGraph is drawn, the X-axis is drawn with increasing values from left to
228 right and the Y-axis from bottom to top. The two options RX and RY allow to change
229 this order. The option RX allows to draw the X-axis with increasing values from
230 right to left and the RY option allows to draw the Y-axis with increasing values
231 from top to bottom. The following example illustrate how to use these options.
232 
233 Begin_Macro(source)
234 {
235  auto *c = new TCanvas();
236  c->Divide(2,1);
237 
238  auto *g1 = new TGraphErrors();
239  g1->SetPoint(0,-4,-3);
240  g1->SetPoint(1,1,1);
241  g1->SetPoint(2,2,1);
242  g1->SetPoint(3,3,4);
243  g1->SetPoint(4,5,5);
244  g1->SetPointError(0,1.,2.);
245  g1->SetPointError(1,2,1);
246  g1->SetPointError(2,2,3);
247  g1->SetPointError(3,3,2);
248  g1->SetPointError(4,4,5);
249  g1->SetMarkerStyle(21);
250 
251  auto *g2 = new TGraph();
252  g2->SetPoint(0,4,8);
253  g2->SetPoint(1,5,9);
254  g2->SetPoint(2,6,10);
255  g2->SetPoint(3,10,11);
256  g2->SetPoint(4,15,12);
257  g2->SetLineColor(kRed);
258  g2->SetLineWidth(5);
259 
260  auto mg = new TMultiGraph();
261  mg->Add(g1,"P");
262  mg->Add(g2,"L");
263 
264  c->cd(1); gPad->SetGrid(1,1);
265  mg->Draw("A");
266 
267  c->cd(2); gPad->SetGrid(1,1);
268  mg->Draw("A RX RY");
269 }
270 End_Macro
271 
272 ### <a name="MG02"></a> MultiGraphs' fitting
273 
274 The following example shows how to fit a TMultiGraph.
275 
276 Begin_Macro(source)
277 {
278  auto c1 = new TCanvas("c1","c1",600,400);
279 
280  Double_t px1[2] = {2.,4.};
281  Double_t dx1[2] = {0.1,0.1};
282  Double_t py1[2] = {2.1,4.0};
283  Double_t dy1[2] = {0.3,0.2};
284 
285  Double_t px2[2] = {3.,5.};
286  Double_t dx2[2] = {0.1,0.1};
287  Double_t py2[2] = {3.2,4.8};
288  Double_t dy2[2] = {0.3,0.2};
289 
290  gStyle->SetOptFit(0001);
291 
292  auto g1 = new TGraphErrors(2,px1,py1,dx1,dy1);
293  g1->SetMarkerStyle(21);
294  g1->SetMarkerColor(2);
295 
296  auto g2 = new TGraphErrors(2,px2,py2,dx2,dy2);
297  g2->SetMarkerStyle(22);
298  g2->SetMarkerColor(3);
299 
300  auto g = new TMultiGraph();
301  g->Add(g1);
302  g->Add(g2);
303 
304  g->Draw("AP");
305 
306  g->Fit("pol1","FQ");
307 }
308 End_Macro
309 
310 #### <a name="MG02a"></a> Fit box position
311 
312 When the graphs in a TMultiGraph are fitted, the fit parameters boxes
313 overlap. The following example shows how to make them all visible.
314 
315 
316 Begin_Macro(source)
317 ../../../tutorials/graphs/multigraph.C
318 End_Macro
319 
320 ### <a name="MG03"></a> Axis' limits setting
321 
322 The axis limits can be changed the like for TGraph. The same methods apply on
323 the multigraph.
324 Note the two differents ways to change limits on X and Y axis.
325 
326 Begin_Macro(source)
327 {
328  auto c2 = new TCanvas("c2","c2",600,400);
329 
330  TGraph *g[3];
331  Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
332  Double_t y[10] = {1,2,3,4,5,5,4,3,2,1};
333  auto mg = new TMultiGraph();
334  for (int i=0; i<3; i++) {
335  g[i] = new TGraph(10, x, y);
336  g[i]->SetMarkerStyle(20);
337  g[i]->SetMarkerColor(i+2);
338  for (int j=0; j<10; j++) y[j] = y[j]-1;
339  mg->Add(g[i]);
340  }
341  mg->Draw("APL");
342  mg->GetXaxis()->SetTitle("E_{#gamma} (GeV)");
343  mg->GetYaxis()->SetTitle("Coefficients");
344 
345  // Change the axis limits
346  gPad->Modified();
347  mg->GetXaxis()->SetLimits(1.5,7.5);
348  mg->SetMinimum(0.);
349  mg->SetMaximum(10.);
350 }
351 End_Macro
352 */
353 
354 
355 ////////////////////////////////////////////////////////////////////////////////
356 /// TMultiGraph default constructor.
357 
359 {
360  fGraphs = 0;
361  fFunctions = 0;
362  fHistogram = 0;
363  fMaximum = -1111;
364  fMinimum = -1111;
365 }
366 
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// Constructor with name and title.
370 
371 TMultiGraph::TMultiGraph(const char *name, const char *title)
372  : TNamed(name,title)
373 {
374  fGraphs = 0;
375  fFunctions = 0;
376  fHistogram = 0;
377  fMaximum = -1111;
378  fMinimum = -1111;
379 }
380 
381 
382 ////////////////////////////////////////////////////////////////////////////////
383 /// Copy constructor.
384 
386  TNamed (mg),
387  fGraphs(mg.fGraphs),
388  fFunctions(mg.fFunctions),
389  fHistogram(mg.fHistogram),
390  fMaximum(mg.fMaximum),
391  fMinimum(mg.fMinimum)
392 {
393 }
394 
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Assignment operator.
398 
400 {
401  if (this!=&mg) {
403  fGraphs=mg.fGraphs;
404  fFunctions=mg.fFunctions;
405  fHistogram=mg.fHistogram;
406  fMaximum=mg.fMaximum;
407  fMinimum=mg.fMinimum;
408  }
409  return *this;
410 }
411 
412 
413 ////////////////////////////////////////////////////////////////////////////////
414 /// TMultiGraph destructor.
415 
417 {
418  if (!fGraphs) return;
419  TGraph *g;
420  TIter next(fGraphs);
421  while ((g = (TGraph*) next())) {
422  g->ResetBit(kMustCleanup);
423  }
424  fGraphs->Delete();
425  delete fGraphs;
426  fGraphs = 0;
427  delete fHistogram;
428  fHistogram = 0;
429  if (fFunctions) {
431  //special logic to support the case where the same object is
432  //added multiple times in fFunctions.
433  //This case happens when the same object is added with different
434  //drawing modes
435  TObject *obj;
436  while ((obj = fFunctions->First())) {
437  while (fFunctions->Remove(obj)) { }
438  delete obj;
439  }
440  delete fFunctions;
441  }
442 }
443 
444 
445 ////////////////////////////////////////////////////////////////////////////////
446 /// Add a new graph to the list of graphs.
447 /// Note that the graph is now owned by the TMultigraph.
448 /// Deleting the TMultiGraph object will automatically delete the graphs.
449 /// You should not delete the graphs when the TMultigraph is still active.
450 
452 {
453  if (!fGraphs) fGraphs = new TList();
454  graph->SetBit(kMustCleanup);
455  fGraphs->Add(graph,chopt);
456 }
457 
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Add all the graphs in "multigraph" to the list of graphs.
461 ///
462 /// - If "chopt" is defined all the graphs in "multigraph" will be added with
463 /// the "chopt" option.
464 /// - If "chopt" is undefined each graph will be added with the option it had
465 /// in "multigraph".
466 
467 void TMultiGraph::Add(TMultiGraph *multigraph, Option_t *chopt)
468 {
469  TList *graphlist = multigraph->GetListOfGraphs();
470  if (!graphlist) return;
471 
472  if (!fGraphs) fGraphs = new TList();
473 
474  TObjOptLink *lnk = (TObjOptLink*)graphlist->FirstLink();
475  TObject *obj = 0;
476 
477  while (lnk) {
478  obj = lnk->GetObject();
479  if (!strlen(chopt)) fGraphs->Add(obj,lnk->GetOption());
480  else fGraphs->Add(obj,chopt);
481  lnk = (TObjOptLink*)lnk->Next();
482  }
483 }
484 
485 
486 ////////////////////////////////////////////////////////////////////////////////
487 /// Browse multigraph.
488 
490 {
491  TString opt = gEnv->GetValue("TGraph.BrowseOption", "");
492  if (opt.IsNull()) {
493  opt = b ? b->GetDrawOption() : "alp";
494  opt = (opt == "") ? "alp" : opt.Data();
495  }
496  Draw(opt.Data());
497  gPad->Update();
498 }
499 
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 /// Compute distance from point px,py to each graph.
503 
505 {
506  // Are we on the axis?
507  const Int_t kMaxDiff = 10;
508  Int_t distance = 9999;
509  if (fHistogram) {
510  distance = fHistogram->DistancetoPrimitive(px,py);
511  if (distance <= 0) return distance;
512  }
513 
514  // Loop on the list of graphs
515  if (!fGraphs) return distance;
516  TGraph *g;
517  TIter next(fGraphs);
518  while ((g = (TGraph*) next())) {
519  Int_t dist = g->DistancetoPrimitive(px,py);
520  if (dist <= 0) return 0;
521  if (dist < kMaxDiff) {gPad->SetSelected(g); return dist;}
522  }
523  return distance;
524 }
525 
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 /// Draw this multigraph with its current attributes.
529 ///
530 /// Options to draw a graph are described in TGraphPainter.
531 ///
532 /// The drawing option for each TGraph may be specified as an optional
533 /// second argument of the Add function. You can use GetGraphDrawOption
534 /// to return this option.
535 ///
536 /// If a draw option is specified, it will be used to draw the graph,
537 /// otherwise the graph will be drawn with the option specified in
538 /// TMultiGraph::Draw. Use GetDrawOption to return the option specified
539 /// when drawing the TMultiGraph.
540 
542 {
543  TString opt = option;
544  opt.ToLower();
545 
546  if (gPad) {
547  if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
548  if (opt.Contains("a")) gPad->Clear();
549  }
550  AppendPad(option);
551 }
552 
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Fit this graph with function with name fname.
556 ///
557 /// interface to TF1::Fit(TF1 *f1...
558 
560 {
561  char *linear;
562  linear= (char*)strstr(fname, "++");
563  if (linear) {
564  TF1 f1(fname, fname, xmin, xmax);
565  return Fit(&f1,option,"",xmin,xmax);
566  }
567  TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
568  if (!f1) { Printf("Unknown function: %s",fname); return -1; }
569 
570  return Fit(f1,option,"",xmin,xmax);
571 }
572 
573 
574 ////////////////////////////////////////////////////////////////////////////////
575 /// Fit this multigraph with function f1.
576 ///
577 /// In this function all graphs of the multigraph are fitted simultaneously
578 ///
579 /// f1 is an already predefined function created by TF1.
580 /// Predefined functions such as gaus, expo and poln are automatically
581 /// created by ROOT.
582 ///
583 /// The list of fit options is given in parameter `option`which may takes the
584 /// following values:
585 ///
586 /// - "W" Ignore all the point errors
587 /// - "U" Use a User specified fitting algorithm (via SetFCN)
588 /// - "Q" Quiet mode (minimum printing)
589 /// - "V" Verbose mode (default is between Q and V)
590 /// - "B" Use this option when you want to fix one or more parameters
591 /// and the fitting function is like "gaus","expo","poln","landau".
592 /// - "R" Use the Range specified in the function range
593 /// - "N" Do not store the graphics function, do not draw
594 /// - "0" Do not plot the result of the fit. By default the fitted function
595 /// is drawn unless the option"N" above is specified.
596 /// - "+" Add this new fitted function to the list of fitted functions
597 /// (by default, any previous function is deleted)
598 /// - "C" In case of linear fitting, not calculate the chisquare (saves time)
599 /// - "F" If fitting a polN, switch to minuit fitter
600 /// - "ROB" In case of linear fitting, compute the LTS regression
601 /// coefficients (robust(resistant) regression), using
602 /// the default fraction of good points
603 /// - "ROB=0.x" - compute the LTS regression coefficients, using
604 /// 0.x as a fraction of good points
605 ///
606 /// When the fit is drawn (by default), the parameter goption may be used
607 /// to specify a list of graphics options. See TGraph::Paint for a complete
608 /// list of these options.
609 ///
610 /// In order to use the Range option, one must first create a function
611 /// with the expression to be fitted. For example, if your graph
612 /// has a defined range between -4 and 4 and you want to fit a gaussian
613 /// only in the interval 1 to 3, you can do:
614 /// ~~~ {.cpp}
615 /// TF1 *f1 = new TF1("f1","gaus",1,3);
616 /// graph->Fit("f1","R");
617 /// ~~~
618 ///
619 /// ### Who is calling this function ?
620 ///
621 /// Note that this function is called when calling TGraphErrors::Fit
622 /// or TGraphAsymmErrors::Fit ot TGraphBentErrors::Fit
623 /// see the discussion below on the errors calculation.
624 ///
625 /// ### Setting initial conditions
626 ///
627 /// Parameters must be initialized before invoking the Fit function.
628 /// The setting of the parameter initial values is automatic for the
629 /// predefined functions : poln, expo, gaus, landau. One can however disable
630 /// this automatic computation by specifying the option "B".
631 /// You can specify boundary limits for some or all parameters via
632 /// ~~~ {.cpp}
633 /// f1->SetParLimits(p_number, parmin, parmax);
634 /// ~~~
635 /// if `parmin>=parmax`, the parameter is fixed
636 /// Note that you are not forced to fix the limits for all parameters.
637 /// For example, if you fit a function with 6 parameters, you can do:
638 /// ~~~ {.cpp}
639 /// func->SetParameters(0,3.1,1.e-6,0.1,-8,100);
640 /// func->SetParLimits(4,-10,-4);
641 /// func->SetParLimits(5, 1,1);
642 /// ~~~
643 /// With this setup, parameters 0->3 can vary freely
644 /// Parameter 4 has boundaries [-10,-4] with initial value -8
645 /// Parameter 5 is fixed to 100.
646 ///
647 /// ### Fit range
648 ///
649 /// The fit range can be specified in two ways:
650 ///
651 /// - specify rxmax > rxmin (default is rxmin=rxmax=0)
652 /// - specify the option "R". In this case, the function will be taken
653 /// instead of the full graph range.
654 ///
655 /// ### Changing the fitting function
656 ///
657 /// By default a chi2 fitting function is used for fitting the TGraphs's.
658 /// The function is implemented in `FitUtil::EvaluateChi2`.
659 /// In case of TGraphErrors an effective chi2 is used
660 /// (see TGraphErrors fit in TGraph::Fit) and is implemented in
661 /// `FitUtil::EvaluateChi2Effective`
662 /// To specify a User defined fitting function, specify option "U" and
663 /// call the following function:
664 /// ~~~ {.cpp}
665 /// TVirtualFitter::Fitter(mygraph)->SetFCN(MyFittingFunction)
666 /// ~~~
667 /// where MyFittingFunction is of type:
668 /// ~~~ {.cpp}
669 /// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
670 /// ~~~
671 ///
672 /// ### Access to the fit result
673 ///
674 /// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
675 /// By default the TFitResultPtr contains only the status of the fit and it converts
676 /// automatically to an integer. If the option "S" is instead used, TFitResultPtr contains
677 /// the TFitResult and behaves as a smart pointer to it. For example one can do:
678 /// ~~~ {.cpp}
679 /// TFitResultPtr r = graph->Fit("myFunc","S");
680 /// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
681 /// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
682 /// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
683 /// r->Print("V"); // print full information of fit including covariance matrix
684 /// r->Write(); // store the result in a file
685 /// ~~~
686 ///
687 /// The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
688 /// from the fitted function.
689 ///
690 /// ### Associated functions
691 ///
692 /// One or more object (typically a TF1*) can be added to the list
693 /// of functions (fFunctions) associated to each graph.
694 /// When TGraph::Fit is invoked, the fitted function is added to this list.
695 /// Given a graph gr, one can retrieve an associated function
696 /// with:
697 /// ~~~ {.cpp}
698 /// TF1 *myfunc = gr->GetFunction("myfunc");
699 /// ~~~
700 ///
701 /// If the graph is made persistent, the list of
702 /// associated functions is also persistent. Given a pointer (see above)
703 /// to an associated function myfunc, one can retrieve the function/fit
704 /// parameters with calls such as:
705 /// ~~~ {.cpp}
706 /// Double_t chi2 = myfunc->GetChisquare();
707 /// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
708 /// Double_t err0 = myfunc->GetParError(0); //error on first parameter
709 /// ~~~
710 ///
711 /// ### Fit Statistics
712 ///
713 /// You can change the statistics box to display the fit parameters with
714 /// the TStyle::SetOptFit(mode) method. This mode has four digits.
715 /// mode = pcev (default = 0111)
716 ///
717 /// - v = 1; print name/values of parameters
718 /// - e = 1; print errors (if e=1, v must be 1)
719 /// - c = 1; print Chisquare/Number of degrees of freedom
720 /// - p = 1; print Probability
721 ///
722 /// For example: `gStyle->SetOptFit(1011);`
723 /// prints the fit probability, parameter names/values, and errors.
724 /// You can change the position of the statistics box with these lines
725 /// (where g is a pointer to the TGraph):
726 ///
727 /// ~~~ {.cpp}
728 /// Root > TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats")
729 /// Root > st->SetX1NDC(newx1); //new x start position
730 /// Root > st->SetX2NDC(newx2); //new x end position
731 /// ~~~
732 
733 TFitResultPtr TMultiGraph::Fit(TF1 *f1, Option_t *option, Option_t *goption, Axis_t rxmin, Axis_t rxmax)
734 {
735  // internal multigraph fitting methods
736  Foption_t fitOption;
738 
739  // create range and minimizer options with default values
740  ROOT::Fit::DataRange range(rxmin,rxmax);
742  return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
743 
744 }
745 
746 ////////////////////////////////////////////////////////////////////////////////
747 /// Display a panel with all histogram fit options.
748 /// See class TFitPanel for example
749 
751 {
752  if (!gPad)
753  gROOT->MakeDefCanvas();
754 
755  if (!gPad) {
756  Error("FitPanel", "Unable to create a default canvas");
757  return;
758  }
759 
760  // use plugin manager to create instance of TFitEditor
761  TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
762  if (handler && handler->LoadPlugin() != -1) {
763  if (handler->ExecPlugin(2, gPad, this) == 0)
764  Error("FitPanel", "Unable to crate the FitPanel");
765  }
766  else
767  Error("FitPanel", "Unable to find the FitPanel plug-in");
768 }
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 /// Return the draw option for the TGraph `gr` in this TMultiGraph.
772 /// The return option is the one specified when calling TMultiGraph::Add(gr,option).
773 
775 {
776  if (!fGraphs || !gr) return "";
777  TListIter next(fGraphs);
778  TObject *obj;
779  while ((obj = next())) {
780  if (obj == (TObject*)gr) return next.GetOption();
781  }
782  return "";
783 }
784 
785 
786 ////////////////////////////////////////////////////////////////////////////////
787 /// Compute Initial values of parameters for a gaussian.
788 
790 {
791  Double_t allcha, sumx, sumx2, x, val, rms, mean;
792  Int_t bin;
793  const Double_t sqrtpi = 2.506628;
794 
795  // Compute mean value and RMS of the graph in the given range
796  Int_t np = 0;
797  allcha = sumx = sumx2 = 0;
798  TGraph *g;
799  TIter next(fGraphs);
800  Double_t *px, *py;
801  Int_t npp; //number of points in each graph
802  while ((g = (TGraph*) next())) {
803  px=g->GetX();
804  py=g->GetY();
805  npp=g->GetN();
806  for (bin=0; bin<npp; bin++) {
807  x=px[bin];
808  if (x<xmin || x>xmax) continue;
809  np++;
810  val=py[bin];
811  sumx+=val*x;
812  sumx2+=val*x*x;
813  allcha+=val;
814  }
815  }
816  if (np == 0 || allcha == 0) return;
817  mean = sumx/allcha;
818  rms = TMath::Sqrt(sumx2/allcha - mean*mean);
819 
820  Double_t binwidx = TMath::Abs((xmax-xmin)/np);
821  if (rms == 0) rms = 1;
823  TF1 *f1 = (TF1*)grFitter->GetUserFunc();
824  f1->SetParameter(0,binwidx*allcha/(sqrtpi*rms));
825  f1->SetParameter(1,mean);
826  f1->SetParameter(2,rms);
827  f1->SetParLimits(2,0,10*rms);
828 }
829 
830 
831 ////////////////////////////////////////////////////////////////////////////////
832 /// Compute Initial values of parameters for an exponential.
833 
835 {
836  Double_t constant, slope;
837  Int_t ifail;
838 
839  LeastSquareLinearFit(-1, constant, slope, ifail, xmin, xmax);
840 
842  TF1 *f1 = (TF1*)grFitter->GetUserFunc();
843  f1->SetParameter(0,constant);
844  f1->SetParameter(1,slope);
845 }
846 
847 
848 ////////////////////////////////////////////////////////////////////////////////
849 /// Compute Initial values of parameters for a polynom.
850 
852 {
853  Double_t fitpar[25];
854 
856  TF1 *f1 = (TF1*)grFitter->GetUserFunc();
857  Int_t npar = f1->GetNpar();
858 
859  LeastSquareFit(npar, fitpar, xmin, xmax);
860 
861  for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
862 }
863 
864 
865 ////////////////////////////////////////////////////////////////////////////////
866 /// Least squares lpolynomial fitting without weights.
867 ///
868 /// - m number of parameters
869 /// - a array of parameters
870 /// - first 1st point number to fit (default =0)
871 /// - last last point number to fit (default=fNpoints-1)
872 ///
873 /// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
874 
876 {
877  const Double_t zero = 0.;
878  const Double_t one = 1.;
879  const Int_t idim = 20;
880 
881  Double_t b[400] /* was [20][20] */;
882  Int_t i, k, l, ifail, bin;
883  Double_t power;
884  Double_t da[20], xk, yk;
885 
886 
887  //count the total number of points to fit
888  TGraph *g;
889  TIter next(fGraphs);
890  Double_t *px, *py;
891  Int_t n=0;
892  Int_t npp;
893  while ((g = (TGraph*) next())) {
894  px=g->GetX();
895  npp=g->GetN();
896  for (bin=0; bin<npp; bin++) {
897  xk=px[bin];
898  if (xk < xmin || xk > xmax) continue;
899  n++;
900  }
901  }
902  if (m <= 2) {
903  LeastSquareLinearFit(n, a[0], a[1], ifail, xmin, xmax);
904  return;
905  }
906  if (m > idim || m > n) return;
907  da[0] = zero;
908  for (l = 2; l <= m; ++l) {
909  b[l-1] = zero;
910  b[m + l*20 - 21] = zero;
911  da[l-1] = zero;
912  }
913  Int_t np = 0;
914 
915  next.Reset();
916  while ((g = (TGraph*) next())) {
917  px=g->GetX();
918  py=g->GetY();
919  npp=g->GetN();
920 
921  for (k = 0; k <= npp; ++k) {
922  xk = px[k];
923  if (xk < xmin || xk > xmax) continue;
924  np++;
925  yk = py[k];
926  power = one;
927  da[0] += yk;
928  for (l = 2; l <= m; ++l) {
929  power *= xk;
930  b[l-1] += power;
931  da[l-1] += power*yk;
932  }
933  for (l = 2; l <= m; ++l) {
934  power *= xk;
935  b[m + l*20 - 21] += power;
936  }
937  }
938  }
939  b[0] = Double_t(np);
940  for (i = 3; i <= m; ++i) {
941  for (k = i; k <= m; ++k) {
942  b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
943  }
944  }
945  H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
946 
947  if (ifail < 0) {
948  //a[0] = fY[0];
949  py=((TGraph *)fGraphs->First())->GetY();
950  a[0]=py[0];
951  for (i=1; i<m; ++i) a[i] = 0;
952  return;
953  }
954  for (i=0; i<m; ++i) a[i] = da[i];
955 }
956 
957 
958 ////////////////////////////////////////////////////////////////////////////////
959 /// Least square linear fit without weights.
960 ///
961 /// Fit a straight line (a0 + a1*x) to the data in this graph.
962 ///
963 /// - ndata: number of points to fit
964 /// - first: first point number to fit
965 /// - last: last point to fit O(ndata should be last-first
966 /// - ifail: return parameter indicating the status of the fit (ifail=0, fit is OK)
967 ///
968 /// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
969 
971  Int_t &ifail, Double_t xmin, Double_t xmax)
972 {
973  Double_t xbar, ybar, x2bar;
974  Int_t i;
975  Double_t xybar;
976  Double_t fn, xk, yk;
977  Double_t det;
978 
979  ifail = -2;
980  xbar = ybar = x2bar = xybar = 0;
981  Int_t np = 0;
982  TGraph *g;
983  TIter next(fGraphs);
984  Double_t *px, *py;
985  Int_t npp;
986  while ((g = (TGraph*) next())) {
987  px=g->GetX();
988  py=g->GetY();
989  npp=g->GetN();
990  for (i = 0; i < npp; ++i) {
991  xk = px[i];
992  if (xk < xmin || xk > xmax) continue;
993  np++;
994  yk = py[i];
995  if (ndata < 0) {
996  if (yk <= 0) yk = 1e-9;
997  yk = TMath::Log(yk);
998  }
999  xbar += xk;
1000  ybar += yk;
1001  x2bar += xk*xk;
1002  xybar += xk*yk;
1003  }
1004  }
1005  fn = Double_t(np);
1006  det = fn*x2bar - xbar*xbar;
1007  ifail = -1;
1008  if (det <= 0) {
1009  if (fn > 0) a0 = ybar/fn;
1010  else a0 = 0;
1011  a1 = 0;
1012  return;
1013  }
1014  ifail = 0;
1015  a0 = (x2bar*ybar - xbar*xybar) / det;
1016  a1 = (fn*xybar - xbar*ybar) / det;
1017 }
1018 
1019 
1020 ////////////////////////////////////////////////////////////////////////////////
1021 /// Return 1 if the point (x,y) is inside one of the graphs 0 otherwise.
1022 
1024 {
1025  Int_t in = 0;
1026  if (!fGraphs) return in;
1027  TGraph *g;
1028  TIter next(fGraphs);
1029  while ((g = (TGraph*) next())) {
1030  in = g->IsInside(x, y);
1031  if (in) return in;
1032  }
1033  return in;
1034 }
1035 
1036 
1037 ////////////////////////////////////////////////////////////////////////////////
1038 /// Returns a pointer to the histogram used to draw the axis.
1039 /// Takes into account following cases.
1040 ///
1041 /// 1. if `fHistogram` exists it is returned
1042 /// 2. if `fHistogram` doesn't exists and `gPad` exists `gPad` is updated. That
1043 /// may trigger the creation of `fHistogram`. If `fHistogram` still does not
1044 /// exit but `hframe` does (if user called `TPad::DrawFrame`) the pointer to
1045 /// `hframe` histogram is returned
1046 /// 3. after the two previous steps, if `fHistogram` still doesn't exist, then
1047 /// it is created.
1048 
1050 {
1051  if (fHistogram) return fHistogram;
1052 
1053  if (gPad) {
1054  gPad->Modified();
1055  gPad->Update();
1056  if (fHistogram) return fHistogram;
1057  TH1F *h1 = (TH1F*)gPad->FindObject("hframe");
1058  if (h1) return h1;
1059  }
1060 
1061  Bool_t initialrangeset = kFALSE;
1062  Double_t rwxmin = 0.,rwxmax = 0.,rwymin = 0.,rwymax = 0.;
1063  TGraph *g;
1064  Int_t npt = 100 ;
1065  TIter next(fGraphs);
1066  while ((g = (TGraph*) next())) {
1067  if (g->GetN() <= 0) continue;
1068  if (initialrangeset) {
1069  Double_t rx1,ry1,rx2,ry2;
1070  g->ComputeRange(rx1, ry1, rx2, ry2);
1071  if (rx1 < rwxmin) rwxmin = rx1;
1072  if (ry1 < rwymin) rwymin = ry1;
1073  if (rx2 > rwxmax) rwxmax = rx2;
1074  if (ry2 > rwymax) rwymax = ry2;
1075  } else {
1076  g->ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
1077  initialrangeset = kTRUE;
1078  }
1079  if (g->GetN() > npt) npt = g->GetN();
1080  }
1081  if (rwxmin == rwxmax) rwxmax += 1.;
1082  if (rwymin == rwymax) rwymax += 1.;
1083  double dx = 0.05*(rwxmax-rwxmin);
1084  double dy = 0.05*(rwymax-rwymin);
1085  rwxmin = rwxmin - dx;
1086  rwxmax = rwxmax + dx;
1087  rwymin = rwymin - dy;
1088  rwymax = rwymax + dy;
1089  fHistogram = new TH1F(GetName(),GetTitle(),npt,rwxmin,rwxmax);
1090  if (!fHistogram) return 0;
1091  fHistogram->SetMinimum(rwymin);
1093  fHistogram->SetMaximum(rwymax);
1094  fHistogram->GetYaxis()->SetLimits(rwymin,rwymax);
1096  return fHistogram;
1097 }
1098 
1099 
1100 ////////////////////////////////////////////////////////////////////////////////
1101 /// Return pointer to function with name.
1102 ///
1103 /// Functions such as TGraph::Fit store the fitted function in the list of
1104 /// functions of this graph.
1105 
1106 TF1 *TMultiGraph::GetFunction(const char *name) const
1107 {
1108  if (!fFunctions) return 0;
1109  return (TF1*)fFunctions->FindObject(name);
1110 }
1111 
1112 ////////////////////////////////////////////////////////////////////////////////
1113 /// Return pointer to list of functions.
1114 /// If pointer is null create the list
1115 
1117 {
1118  if (!fFunctions) fFunctions = new TList();
1119  return fFunctions;
1120 }
1121 
1122 
1123 ////////////////////////////////////////////////////////////////////////////////
1124 /// Get x axis of the graph.
1125 /// This method returns a valid axis only after the TMultigraph has been drawn.
1126 
1128 {
1129  TH1 *h = GetHistogram();
1130  if (!h) return 0;
1131  return h->GetXaxis();
1132 }
1133 
1134 
1135 ////////////////////////////////////////////////////////////////////////////////
1136 /// Get y axis of the graph.
1137 /// This method returns a valid axis only after the TMultigraph has been drawn.
1138 
1140 {
1141  TH1 *h = GetHistogram();
1142  if (!h) return 0;
1143  return h->GetYaxis();
1144 }
1145 
1146 
1147 ////////////////////////////////////////////////////////////////////////////////
1148 /// Paint all the graphs of this multigraph.
1149 
1151 {
1152  const TPickerStackGuard pushGuard(this);
1153 
1154  if (!fGraphs) return;
1155  if (fGraphs->GetSize() == 0) return;
1156 
1157  char option[128];
1158  strlcpy(option,choptin,128);
1159  Int_t nch = strlen(choptin);
1160  for (Int_t i=0;i<nch;i++) option[i] = toupper(option[i]);
1161 
1162  // Automatic color
1163  char *l1 = strstr(option,"PFC"); // Automatic Fill Color
1164  char *l2 = strstr(option,"PLC"); // Automatic Line Color
1165  char *l3 = strstr(option,"PMC"); // Automatic Marker Color
1166  if (l1 || l2 || l3) {
1167  TString opt1 = option; opt1.ToLower();
1168  if (l1) memcpy(l1," ",3);
1169  if (l2) memcpy(l2," ",3);
1170  if (l3) memcpy(l3," ",3);
1172  TGraph* gAti;
1173  Int_t ngraphs = fGraphs->GetSize();
1174  Int_t ic;
1175  gPad->IncrementPaletteColor(ngraphs, opt1);
1176  for (Int_t i=0;i<ngraphs;i++) {
1177  ic = gPad->NextPaletteColor();
1178  gAti = (TGraph*)(fGraphs->At(i));
1179  if (l1) gAti->SetFillColor(ic);
1180  if (l2) gAti->SetLineColor(ic);
1181  if (l3) gAti->SetMarkerColor(ic);
1182  lnk = (TObjOptLink*)lnk->Next();
1183  }
1184  }
1185 
1186  char *l;
1187 
1188  TString chopt = option;
1189 
1190  l = (char*)strstr(chopt.Data(),"3D");
1191  if (l) {
1192  l = (char*)strstr(chopt.Data(),"L");
1193  if (l) PaintPolyLine3D(chopt.Data());
1194  return;
1195  }
1196 
1197  l = (char*)strstr(chopt.Data(),"PADS");
1198  if (l) {
1199  chopt.ReplaceAll("PADS","");
1200  PaintPads(chopt.Data());
1201  return;
1202  }
1203 
1204  char *lrx = (char *)strstr(chopt.Data(), "RX"); // Reverse graphs along X axis
1205  char *lry = (char *)strstr(chopt.Data(), "RY"); // Reverse graphs along Y axis
1206  if (lrx || lry) {
1207  PaintReverse(chopt.Data());
1208  return;
1209  }
1210 
1211  TGraph *g;
1212 
1213  l = (char*)strstr(chopt.Data(),"A");
1214  if (l) {
1215  *l = ' ';
1216  TIter next(fGraphs);
1217  Int_t npt = 100;
1218  Double_t maximum, minimum, rwxmin, rwxmax, rwymin, rwymax, uxmin, uxmax, dx, dy;
1219  rwxmin = gPad->GetUxmin();
1220  rwxmax = gPad->GetUxmax();
1221  rwymin = gPad->GetUymin();
1222  rwymax = gPad->GetUymax();
1223  char *xtitle = 0;
1224  char *ytitle = 0;
1225  Int_t firstx = 0;
1226  Int_t lastx = 0;
1227  Bool_t timedisplay = kFALSE;
1228  char *timeformat = 0;
1229 
1230  if (fHistogram) {
1231  //cleanup in case of a previous unzoom and in case one of the TGraph has changed
1233  TGraph* gAti;
1234  Int_t ngraphs = fGraphs->GetSize();
1235  Bool_t reset_hist = kFALSE;
1236  for (Int_t i=0;i<ngraphs;i++) {
1237  gAti = (TGraph*)(fGraphs->At(i));
1238  if(gAti->TestBit(TGraph::kResetHisto)) {reset_hist = kTRUE; break;}
1239  lnk = (TObjOptLink*)lnk->Next();
1240  }
1241  if (fHistogram->GetMinimum() >= fHistogram->GetMaximum() || reset_hist) {
1242  nch = strlen(fHistogram->GetXaxis()->GetTitle());
1243  firstx = fHistogram->GetXaxis()->GetFirst();
1244  lastx = fHistogram->GetXaxis()->GetLast();
1245  timedisplay = fHistogram->GetXaxis()->GetTimeDisplay();
1246  if (nch) {
1247  xtitle = new char[nch+1];
1248  strlcpy(xtitle,fHistogram->GetXaxis()->GetTitle(),nch+1);
1249  }
1250  nch = strlen(fHistogram->GetYaxis()->GetTitle());
1251  if (nch) {
1252  ytitle = new char[nch+1];
1253  strlcpy(ytitle,fHistogram->GetYaxis()->GetTitle(),nch+1);
1254  }
1255  nch = strlen(fHistogram->GetXaxis()->GetTimeFormat());
1256  if (nch) {
1257  timeformat = new char[nch+1];
1258  strlcpy(timeformat,fHistogram->GetXaxis()->GetTimeFormat(),nch+1);
1259  }
1260  delete fHistogram;
1261  fHistogram = 0;
1262  }
1263  }
1264  if (fHistogram) {
1265  minimum = fHistogram->GetYaxis()->GetXmin();
1266  maximum = fHistogram->GetYaxis()->GetXmax();
1267  uxmin = gPad->PadtoX(rwxmin);
1268  uxmax = gPad->PadtoX(rwxmax);
1269  } else {
1270  Bool_t initialrangeset = kFALSE;
1271  while ((g = (TGraph*) next())) {
1272  if (g->GetN() <= 0) continue;
1273  if (initialrangeset) {
1274  Double_t rx1,ry1,rx2,ry2;
1275  g->ComputeRange(rx1, ry1, rx2, ry2);
1276  if (rx1 < rwxmin) rwxmin = rx1;
1277  if (ry1 < rwymin) rwymin = ry1;
1278  if (rx2 > rwxmax) rwxmax = rx2;
1279  if (ry2 > rwymax) rwymax = ry2;
1280  } else {
1281  g->ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
1282  initialrangeset = kTRUE;
1283  }
1284  if (g->GetN() > npt) npt = g->GetN();
1285  }
1286  if (rwxmin == rwxmax) rwxmax += 1.;
1287  if (rwymin == rwymax) rwymax += 1.;
1288  dx = 0.05*(rwxmax-rwxmin);
1289  dy = 0.05*(rwymax-rwymin);
1290  uxmin = rwxmin - dx;
1291  uxmax = rwxmax + dx;
1292  if (gPad->GetLogy()) {
1293  if (rwymin <= 0) rwymin = 0.001*rwymax;
1294  minimum = rwymin/(1+0.5*TMath::Log10(rwymax/rwymin));
1295  maximum = rwymax*(1+0.2*TMath::Log10(rwymax/rwymin));
1296  } else {
1297  minimum = rwymin - dy;
1298  maximum = rwymax + dy;
1299  }
1300  if (minimum < 0 && rwymin >= 0) minimum = 0;
1301  if (maximum > 0 && rwymax <= 0) maximum = 0;
1302  }
1303 
1304  if (fMinimum != -1111) rwymin = minimum = fMinimum;
1305  if (fMaximum != -1111) rwymax = maximum = fMaximum;
1306  if (uxmin < 0 && rwxmin >= 0) {
1307  if (gPad->GetLogx()) uxmin = 0.9*rwxmin;
1308  //else uxmin = 0;
1309  }
1310  if (uxmax > 0 && rwxmax <= 0) {
1311  if (gPad->GetLogx()) uxmax = 1.1*rwxmax;
1312  //else uxmax = 0;
1313  }
1314  if (minimum < 0 && rwymin >= 0) {
1315  if (gPad->GetLogy()) minimum = 0.9*rwymin;
1316  //else minimum = 0;
1317  }
1318  if (maximum > 0 && rwymax <= 0) {
1319  if (gPad->GetLogy()) maximum = 1.1*rwymax;
1320  //else maximum = 0;
1321  }
1322  if (minimum <= 0 && gPad->GetLogy()) minimum = 0.001*maximum;
1323  if (uxmin <= 0 && gPad->GetLogx()) {
1324  if (uxmax > 1000) uxmin = 1;
1325  else uxmin = 0.001*uxmax;
1326  }
1327  rwymin = minimum;
1328  rwymax = maximum;
1329  if (fHistogram) {
1330  fHistogram->GetYaxis()->SetLimits(rwymin,rwymax);
1331  }
1332 
1333  // Create a temporary histogram to draw the axis
1334  if (!fHistogram) {
1335  // the graph is created with at least as many channels as there are points
1336  // to permit zooming on the full range
1337  rwxmin = uxmin;
1338  rwxmax = uxmax;
1339  fHistogram = new TH1F(GetName(),GetTitle(),npt,rwxmin,rwxmax);
1340  if (!fHistogram) return;
1341  fHistogram->SetMinimum(rwymin);
1343  fHistogram->SetMaximum(rwymax);
1344  fHistogram->GetYaxis()->SetLimits(rwymin,rwymax);
1346  if (xtitle) {fHistogram->GetXaxis()->SetTitle(xtitle); delete [] xtitle;}
1347  if (ytitle) {fHistogram->GetYaxis()->SetTitle(ytitle); delete [] ytitle;}
1348  if (firstx != lastx) fHistogram->GetXaxis()->SetRange(firstx,lastx);
1349  if (timedisplay) {fHistogram->GetXaxis()->SetTimeDisplay(timedisplay);}
1350  if (timeformat) {fHistogram->GetXaxis()->SetTimeFormat(timeformat); delete [] timeformat;}
1351  }
1352  fHistogram->Paint("0");
1353  }
1354 
1355  TGraph *gfit = nullptr;
1356  if (fGraphs) {
1358  TObject *obj = 0;
1359 
1360  chopt.ReplaceAll("A","");
1361 
1362  while (lnk) {
1363 
1364  obj = lnk->GetObject();
1365 
1366  gPad->PushSelectableObject(obj);
1367 
1368  if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected())) {
1369  TString opt = lnk->GetOption();
1370  if (!opt.IsWhitespace())
1371  obj->Paint(opt.ReplaceAll("A","").Data());
1372  else {
1373  if (!chopt.IsWhitespace()) obj->Paint(chopt.Data());
1374  else obj->Paint("L");
1375  }
1376  }
1377 
1378  lnk = (TObjOptLink*)lnk->Next();
1379  }
1380 
1381  gfit = (TGraph*)obj; // pick one TGraph in the list to paint the fit parameters.
1382  }
1383 
1384  TObject *f;
1385  TF1 *fit = nullptr;
1386  if (fFunctions) {
1387  TIter next(fFunctions);
1388  while ((f = (TObject*) next())) {
1389  if (f->InheritsFrom(TF1::Class())) {
1390  if (f->TestBit(TF1::kNotDraw) == 0) f->Paint("lsame");
1391  fit = (TF1*)f;
1392  } else {
1393  f->Paint();
1394  }
1395  }
1396  }
1397 
1398  if (gfit && fit) gfit->PaintStats(fit);
1399 }
1400 
1401 
1402 ////////////////////////////////////////////////////////////////////////////////
1403 /// Divides the active pad and draws all Graphs in the Multigraph separately.
1404 
1406 {
1407  TIter next(fGraphs);
1408  Int_t neededPads = fGraphs->GetSize();
1409  Int_t existingPads = 0;
1410  TString opt = (TString)option;
1411 
1412  TVirtualPad *curPad = gPad;
1413  TObject *obj;
1414  TIter nextPad(curPad->GetListOfPrimitives());
1415 
1416  while ((obj = nextPad())) {
1417  if (obj->InheritsFrom(TVirtualPad::Class())) existingPads++;
1418  }
1419  if (existingPads < neededPads) {
1420  curPad->Clear();
1421  Int_t nx = (Int_t)TMath::Sqrt((Double_t)neededPads);
1422  if (nx*nx < neededPads) nx++;
1423  Int_t ny = nx;
1424  if (((nx*ny)-nx) >= neededPads) ny--;
1425  curPad->Divide(nx,ny);
1426  }
1427  Int_t i = 0;
1428  TGraph *g;
1429 
1431  obj = 0;
1432 
1433  while (lnk) {
1434  g = (TGraph*)lnk->GetObject();
1435  i++;
1436  curPad->cd(i);
1437  TString apopt = lnk->GetOption();
1438  if (strlen(apopt)) {
1439  g->Draw((apopt.Append("A")).Data());
1440  } else {
1441  if (strlen(opt)) g->Draw(opt.Append("A"));
1442  else g->Draw("LA");
1443  }
1444  lnk = (TObjOptLink*)lnk->Next();
1445  }
1446 
1447  curPad->cd();
1448 }
1449 
1450 
1451 ////////////////////////////////////////////////////////////////////////////////
1452 /// Paint all the graphs of this multigraph as 3D lines.
1453 
1455 {
1456  Int_t i, npt=0;
1457  char *l;
1458  Double_t rwxmin=0., rwxmax=0., rwymin=0., rwymax=0.;
1459  TIter next(fGraphs);
1460  TGraph *g;
1461 
1462  g = (TGraph*) next();
1463  if (g) {
1464  g->ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
1465  npt = g->GetN();
1466  }
1467 
1468  if (!fHistogram) {
1469  fHistogram = new TH1F(GetName(),GetTitle(),npt,rwxmin,rwxmax);
1470  }
1471 
1472  while ((g = (TGraph*) next())) {
1473  Double_t rx1,ry1,rx2,ry2;
1474  g->ComputeRange(rx1, ry1, rx2, ry2);
1475  if (rx1 < rwxmin) rwxmin = rx1;
1476  if (ry1 < rwymin) rwymin = ry1;
1477  if (rx2 > rwxmax) rwxmax = rx2;
1478  if (ry2 > rwymax) rwymax = ry2;
1479  if (g->GetN() > npt) npt = g->GetN();
1480  }
1481 
1482  Int_t ndiv = fGraphs->GetSize();
1483 
1484  TH2F* frame = new TH2F("frame","", ndiv, 0., (Double_t)(ndiv), npt, rwxmin, rwxmax);
1485  if (fHistogram) {
1486  frame->SetTitle(fHistogram->GetTitle());
1487  frame->GetYaxis()->SetTitle(fHistogram->GetXaxis()->GetTitle());
1489  frame->GetZaxis()->SetTitle(fHistogram->GetYaxis()->GetTitle());
1490  }
1491 
1492  TAxis *Xaxis = frame->GetXaxis();
1493  Xaxis->SetNdivisions(-ndiv);
1494  next.Reset();
1495  for (i=ndiv; i>=1; i--) {
1496  g = (TGraph*) next();
1497  Xaxis->SetBinLabel(i, g->GetTitle());
1498  }
1499 
1500  frame->SetStats(kFALSE);
1501  if (fMinimum != -1111) frame->SetMinimum(fMinimum);
1502  else frame->SetMinimum(rwymin);
1503  if (fMaximum != -1111) frame->SetMaximum(fMaximum);
1504  else frame->SetMaximum(rwymax);
1505 
1506  l = (char*)strstr(option,"A");
1507  if (l) frame->Paint("lego9,fb,bb");
1508  l = (char*)strstr(option,"BB");
1509  if (!l) frame->Paint("lego9,fb,a,same");
1510 
1511  Double_t *x, *y;
1512  Double_t xyz1[3], xyz2[3];
1513 
1514  Double_t xl = frame->GetYaxis()->GetBinLowEdge(frame->GetYaxis()->GetFirst());
1515  Double_t xu = frame->GetYaxis()->GetBinUpEdge(frame->GetYaxis()->GetLast());
1516  Double_t yl = frame->GetMinimum();
1517  Double_t yu = frame->GetMaximum();
1518  Double_t xc[2],yc[2];
1519  next.Reset();
1520  Int_t j = ndiv;
1521 
1522  while ((g = (TGraph*) next())) {
1523  npt = g->GetN();
1524  x = g->GetX();
1525  y = g->GetY();
1526  gPad->SetLineColor(g->GetLineColor());
1527  gPad->SetLineWidth(g->GetLineWidth());
1528  gPad->SetLineStyle(g->GetLineStyle());
1529  gPad->TAttLine::Modify();
1530  for (i=0; i<npt-1; i++) {
1531  xc[0] = x[i];
1532  xc[1] = x[i+1];
1533  yc[0] = y[i];
1534  yc[1] = y[i+1];
1535  if (gPad->Clip(&xc[0], &yc[0], xl, yl, xu, yu)<2) {
1536  xyz1[0] = j-0.5;
1537  xyz1[1] = xc[0];
1538  xyz1[2] = yc[0];
1539  xyz2[0] = j-0.5;
1540  xyz2[1] = xc[1];
1541  xyz2[2] = yc[1];
1542  gPad->PaintLine3D(xyz1, xyz2);
1543  }
1544  }
1545  j--;
1546  }
1547 
1548  l = (char*)strstr(option,"FB");
1549  if (!l) frame->Paint("lego9,bb,a,same");
1550  delete frame;
1551 }
1552 
1553 
1554 ////////////////////////////////////////////////////////////////////////////////
1555 /// Paint all the graphs of this multigraph reverting values along X and/or Y axis.
1556 /// New graphs are created.
1557 
1559 {
1560  auto *h = GetHistogram();
1561  TH1F *hg = nullptr;
1562  TGraph *fg = nullptr;
1563  if (!h)
1564  return;
1565  TString mgopt = option;
1566  mgopt.ToLower();
1567 
1568  TIter next(fGraphs);
1569  TGraph *g;
1570  Bool_t first = kTRUE;
1571  TString gopt;
1572  while ((g = (TGraph *)next())) {
1573  gopt = GetGraphDrawOption(g);
1574  gopt.Append(mgopt);
1575  if (first) {
1576  fg = g;
1577  hg = fg->GetHistogram();
1578  fg->SetHistogram(h);
1579  fg->Paint(gopt.Data());
1580  first = kFALSE;
1581  } else {
1582  g->Paint(gopt.ReplaceAll("a", "").Data());
1583  }
1584  }
1585  if (fg)
1586  fg->SetHistogram(hg);
1587 }
1588 
1589 
1590 ////////////////////////////////////////////////////////////////////////////////
1591 /// Print the list of graphs.
1592 
1593 void TMultiGraph::Print(Option_t *option) const
1594 {
1595  TGraph *g;
1596  if (fGraphs) {
1597  TIter next(fGraphs);
1598  while ((g = (TGraph*) next())) {
1599  g->Print(option);
1600  }
1601  }
1602 }
1603 
1604 
1605 ////////////////////////////////////////////////////////////////////////////////
1606 /// Recursively remove this object from a list. Typically implemented
1607 /// by classes that can contain multiple references to a same object.
1608 
1610 {
1611  if (!fGraphs) return;
1612  TObject *objr = fGraphs->Remove(obj);
1613  if (!objr) return;
1614  delete fHistogram; fHistogram = 0;
1615  if (gPad) gPad->Modified();
1616 }
1617 
1618 
1619 ////////////////////////////////////////////////////////////////////////////////
1620 /// Save primitive as a C++ statement(s) on output stream out.
1621 
1622 void TMultiGraph::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1623 {
1624  char quote = '"';
1625  out<<" "<<std::endl;
1626  if (gROOT->ClassSaved(TMultiGraph::Class())) {
1627  out<<" ";
1628  } else {
1629  out<<" TMultiGraph *";
1630  }
1631  out<<"multigraph = new TMultiGraph();"<<std::endl;
1632  out<<" multigraph->SetName("<<quote<<GetName()<<quote<<");"<<std::endl;
1633  out<<" multigraph->SetTitle("<<quote<<GetTitle()<<quote<<");"<<std::endl;
1634 
1635  if (fGraphs) {
1637  TObject *g;
1638 
1639  while (lnk) {
1640  g = lnk->GetObject();
1641  g->SavePrimitive(out, Form("multigraph%s",lnk->GetOption()));
1642  lnk = (TObjOptLink*)lnk->Next();
1643  }
1644  }
1645  const char *l = strstr(option,"th2poly");
1646  if (l) {
1647  out<<" "<<l+7<<"->AddBin(multigraph);"<<std::endl;
1648  } else {
1649  out<<" multigraph->Draw(" <<quote<<option<<quote<<");"<<std::endl;
1650  }
1651  TAxis *xaxis = GetXaxis();
1652  TAxis *yaxis = GetYaxis();
1653 
1654  if (xaxis) {
1655  out<<" multigraph->GetXaxis()->SetLimits("<<xaxis->GetXmin()<<", "<<xaxis->GetXmax()<<");"<<std::endl;
1656  xaxis->SaveAttributes(out, "multigraph","->GetXaxis()");
1657  }
1658  if (yaxis) yaxis->SaveAttributes(out, "multigraph","->GetYaxis()");
1659  if (fMinimum != -1111) out<<" multigraph->SetMinimum("<<fMinimum<<");"<<std::endl;
1660  if (fMaximum != -1111) out<<" multigraph->SetMaximum("<<fMaximum<<");"<<std::endl;
1661 }
1662 
1663 
1664 ////////////////////////////////////////////////////////////////////////////////
1665 /// Set multigraph maximum.
1666 
1668 {
1669  fMaximum = maximum;
1670  if (fHistogram) fHistogram->SetMaximum(maximum);
1671 }
1672 
1673 
1674 ////////////////////////////////////////////////////////////////////////////////
1675 /// Set multigraph minimum.
1676 
1678 {
1679  fMinimum = minimum;
1680  if (fHistogram) fHistogram->SetMinimum(minimum);
1681 }
1682 
1683 
1684 ////////////////////////////////////////////////////////////////////////////////
1685 /// Get iterator over internal graphs list.
1686 
1688 {
1689  return TIter(fGraphs);
1690 }
TGeant4Unit::mg
static constexpr double mg
Definition: TGeant4SystemOfUnits.h:210
TObject::kMustCleanup
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
l
auto * l
Definition: textangle.C:4
m
auto * m
Definition: textangle.C:8
TMultiGraph::fMinimum
Double_t fMinimum
Definition: TMultiGraph.h:43
n
const Int_t n
Definition: legend1.C:16
TMultiGraph::LeastSquareLinearFit
virtual void LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail, Double_t xmin, Double_t xmax)
Least square linear fit without weights.
Definition: TMultiGraph.cxx:970
TAxis
Class to manage histogram axis.
Definition: TAxis.h:30
first
Definition: first.py:1
TBrowser
Definition: TBrowser.h:37
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
e
#define e(i)
Definition: RSha256.hxx:121
TObject::TestBit
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TAxis::GetBinLowEdge
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:518
f
#define f(i)
Definition: RSha256.hxx:122
TAxis::SaveAttributes
virtual void SaveAttributes(std::ostream &out, const char *name, const char *subname)
Save axis attributes as C++ statement(s) on output stream out.
Definition: TAxis.cxx:661
TMultiGraph::InitPolynom
virtual void InitPolynom(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for a polynom.
Definition: TMultiGraph.cxx:851
Foption_t
Definition: Foption.h:24
TMultiGraph::Paint
virtual void Paint(Option_t *chopt="")
Paint all the graphs of this multigraph.
Definition: TMultiGraph.cxx:1150
TMultiGraph::GetGraphDrawOption
virtual Option_t * GetGraphDrawOption(const TGraph *gr) const
Return the draw option for the TGraph gr in this TMultiGraph.
Definition: TMultiGraph.cxx:774
TH1::SetMinimum
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:396
TMultiGraph::RecursiveRemove
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TMultiGraph.cxx:1609
TMultiGraph::PaintReverse
void PaintReverse(Option_t *chopt="")
Paint all the graphs of this multigraph reverting values along X and/or Y axis.
Definition: TMultiGraph.cxx:1558
gEnv
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TH2F
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
TList::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
TAxis::SetLimits
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
TGraph::Paint
virtual void Paint(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:2030
TList::Delete
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
TString::Data
const char * Data() const
Definition: TString.h:369
TNamed::operator=
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
Axis_t
double Axis_t
Definition: RtypesCore.h:76
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:54
TPluginHandler::ExecPlugin
Long_t ExecPlugin(int nargs, const T &... params)
Definition: TPluginManager.h:165
ROOT::Fit::FitOptionsMake
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition: HFitImpl.cxx:684
TF1::GetNpar
virtual Int_t GetNpar() const
Definition: TF1.h:477
TGraph.h
xmax
float xmax
Definition: THbookFile.cxx:95
HFitInterface.h
TMath::Log
Double_t Log(Double_t x)
Definition: TMath.h:760
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
DataRange.h
TAxis::GetFirst
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:458
TVirtualPad::cd
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
Int_t
int Int_t
Definition: RtypesCore.h:45
TListIter::GetOption
Option_t * GetOption() const
Returns the object option stored in the list.
Definition: TList.cxx:1143
TMultiGraph::GetFunction
TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition: TMultiGraph.cxx:1106
TAxis::SetTimeFormat
virtual void SetTimeFormat(const char *format="")
Change the format used for time plotting.
Definition: TAxis.cxx:1020
TBrowser.h
TAxis::GetBinUpEdge
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:528
ROOT::Fit::FitObject
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition: HFitImpl.cxx:971
TObject::AppendPad
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:107
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
x
Double_t x[n]
Definition: legend1.C:17
TEnv::GetValue
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
H1LeastSquareSeqnd
void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
Extracted from CERN Program library routine DSEQN.
Definition: TH1.cxx:4719
TIter::Reset
void Reset()
Definition: TCollection.h:252
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TF1::kNotDraw
@ kNotDraw
Definition: TF1.h:322
TMultiGraph::LeastSquareFit
virtual void LeastSquareFit(Int_t m, Double_t *a, Double_t xmin, Double_t xmax)
Least squares lpolynomial fitting without weights.
Definition: TMultiGraph.cxx:875
TAxis::GetTimeDisplay
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
TAxis::SetTimeDisplay
virtual void SetTimeDisplay(Int_t value)
Definition: TAxis.h:161
TEnv.h
TString
Definition: TString.h:136
TMultiGraph::Draw
virtual void Draw(Option_t *chopt="")
Draw this multigraph with its current attributes.
Definition: TMultiGraph.cxx:541
TVirtualFitter.h
MinimizerOptions.h
TVirtualFitter
Definition: TVirtualFitter.h:29
TH1::GetZaxis
TAxis * GetZaxis()
Definition: TH1.h:319
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
b
#define b(i)
Definition: RSha256.hxx:118
h1
TH1F * h1
Definition: legend1.C:5
TMultiGraph::GetListOfFunctions
TList * GetListOfFunctions()
Return pointer to list of functions.
Definition: TMultiGraph.cxx:1116
TMultiGraph::IsInside
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside one of the graphs 0 otherwise.
Definition: TMultiGraph.cxx:1023
bool
TString::ReplaceAll
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
TListIter
Definition: TList.h:197
TAxis::GetTitle
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
TMultiGraph.h
TROOT.h
TF1::SetParameter
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:630
TH1::SetTitle
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6344
TMultiGraph::~TMultiGraph
virtual ~TMultiGraph()
TMultiGraph destructor.
Definition: TMultiGraph.cxx:416
TList::First
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:658
TPickerStackGuard
Definition: TVirtualPad.h:275
TPluginHandler
Definition: TPluginManager.h:101
ROOT::Math::gv_detail::dist
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:63
TList::At
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:356
TMultiGraph::Print
virtual void Print(Option_t *chopt="") const
Print the list of graphs.
Definition: TMultiGraph.cxx:1593
TMultiGraph::operator=
TMultiGraph & operator=(const TMultiGraph &)
Assignment operator.
Definition: TMultiGraph.cxx:399
TMultiGraph::GetXaxis
TAxis * GetXaxis()
Get x axis of the graph.
Definition: TMultiGraph.cxx:1127
TAxis::SetRange
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition: TAxis.cxx:920
TObject::Paint
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:521
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
TMultiGraph::GetYaxis
TAxis * GetYaxis()
Get y axis of the graph.
Definition: TMultiGraph.cxx:1139
TList::FirstLink
virtual TObjLink * FirstLink() const
Definition: TList.h:108
TMath::Log10
Double_t Log10(Double_t x)
Definition: TMath.h:764
TAxis::GetXmin
Double_t GetXmin() const
Definition: TAxis.h:133
TFitResultPtr
Definition: TFitResultPtr.h:32
TH1::GetYaxis
TAxis * GetYaxis()
Definition: TH1.h:318
TMultiGraph::fFunctions
TList * fFunctions
Definition: TMultiGraph.h:40
xmin
float xmin
Definition: THbookFile.cxx:95
TGraph::GetHistogram
TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases.
Definition: TGraph.cxx:1482
TMultiGraph::InitExpo
virtual void InitExpo(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for an exponential.
Definition: TMultiGraph.cxx:834
h
#define h(i)
Definition: RSha256.hxx:124
TObject::SetBit
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
TMultiGraph::Browse
virtual void Browse(TBrowser *b)
Browse multigraph.
Definition: TMultiGraph.cxx:489
gr
TGraphErrors * gr
Definition: legend1.C:25
a
auto * a
Definition: textangle.C:12
TNamed
Definition: TNamed.h:29
TMultiGraph::GetHistogram
TH1F * GetHistogram()
Returns a pointer to the histogram used to draw the axis.
Definition: TMultiGraph.cxx:1049
TVirtualPad::Clear
virtual void Clear(Option_t *option="")=0
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
TH1::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2735
TVirtualPad::GetListOfPrimitives
virtual TList * GetListOfPrimitives() const =0
TH1::SetMaximum
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:395
ROOT::Fit::DataRange
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:45
TAxis::GetLast
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:469
TH1::GetMinimum
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:8090
ROOT::Math::MinimizerOptions
Minimizer options.
Definition: MinimizerOptions.h:42
TVirtualPad.h
TAxis::GetTimeFormat
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
TH1::SetDirectory
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:8392
y
Double_t y[n]
Definition: legend1.C:17
TVirtualPad::Divide
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)=0
TNamed::SetTitle
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TH1::SetStats
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8445
TH2.h
TObject::kInvalidObject
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
TGraph::SetHistogram
virtual void SetHistogram(TH1F *h)
Definition: TGraph.h:175
TMultiGraph::fGraphs
TList * fGraphs
Definition: TMultiGraph.h:39
Printf
void Printf(const char *fmt,...)
TMultiGraph
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:36
TMultiGraph::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to each graph.
Definition: TMultiGraph.cxx:504
TAxis::SetBinLabel
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition: TAxis.cxx:823
TVirtualFitter::GetUserFunc
virtual TObject * GetUserFunc() const
Definition: TVirtualFitter.h:90
TMultiGraph::GetListOfGraphs
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:70
TPluginHandler::LoadPlugin
Int_t LoadPlugin()
Load the plugin library for this handler.
Definition: TPluginManager.cxx:254
f1
TF1 * f1
Definition: legend1.C:11
TString::IsNull
Bool_t IsNull() const
Definition: TString.h:407
Double_t
double Double_t
Definition: RtypesCore.h:59
TGraph
Definition: TGraph.h:41
TVirtualPad
Definition: TVirtualPad.h:50
TPluginManager.h
TF1.h
TList::Remove
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:821
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
ROOT::Fit::kGraph
@ kGraph
Definition: HFitInterface.h:50
TMultiGraph::TMultiGraph
TMultiGraph()
TMultiGraph default constructor.
Definition: TMultiGraph.cxx:358
TH1F
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:572
graph
Definition: graph.py:1
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TString::IsWhitespace
Bool_t IsWhitespace() const
Definition: TString.h:408
TMultiGraph::fHistogram
TH1F * fHistogram
Definition: TMultiGraph.h:41
TMultiGraph::fMaximum
Double_t fMaximum
Definition: TMultiGraph.h:42
TObject
Definition: TObject.h:37
TMultiGraph::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TMultiGraph.cxx:1622
TMultiGraph::Add
virtual void Add(TGraph *graph, Option_t *chopt="")
Add a new graph to the list of graphs.
Definition: TMultiGraph.cxx:451
TH1
Definition: TH1.h:57
TMultiGraph::PaintPads
void PaintPads(Option_t *chopt="")
Divides the active pad and draws all Graphs in the Multigraph separately.
Definition: TMultiGraph.cxx:1405
name
char name[80]
Definition: TGX11.cxx:110
TMultiGraph::SetMaximum
virtual void SetMaximum(Double_t maximum=-1111)
Set multigraph maximum.
Definition: TMultiGraph.cxx:1667
TAttAxis::SetNdivisions
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition: TAttAxis.cxx:228
gPad
#define gPad
Definition: TVirtualPad.h:287
TIter
Definition: TCollection.h:233
TH1::kNoStats
@ kNoStats
don't draw stats box
Definition: TH1.h:161
TMultiGraph::FitPanel
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition: TMultiGraph.cxx:750
TF1::SetParLimits
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3518
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
TAxis::GetXmax
Double_t GetXmax() const
Definition: TAxis.h:134
TVirtualFitter::GetFitter
static TVirtualFitter * GetFitter()
static: return the current Fitter
Definition: TVirtualFitter.cxx:209
TF1
1-Dim function class
Definition: TF1.h:212
TGraph::kResetHisto
@ kResetHisto
fHistogram must be reset in GetHistogram
Definition: TGraph.h:71
Class
void Class()
Definition: Class.C:29
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
TMultiGraph::InitGaus
virtual void InitGaus(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for a gaussian.
Definition: TMultiGraph.cxx:789
TH1::GetXaxis
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:317
TMultiGraph::SetMinimum
virtual void SetMinimum(Double_t minimum=-1111)
Set multigraph minimum.
Definition: TMultiGraph.cxx:1677
TH1::GetMaximum
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:8005
TH1.h
TGraph::PaintStats
virtual void PaintStats(TF1 *fit)
Draw the stats.
Definition: TGraph.cxx:2057
TMultiGraph::begin
TIter begin() const
Get iterator over internal graphs list.
Definition: TMultiGraph.cxx:1687
TMultiGraph::Fit
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Axis_t xmin=0, Axis_t xmax=0)
Fit this graph with function with name fname.
Definition: TMultiGraph.cxx:559
TH1::Paint
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5836
TList
Definition: TList.h:44
TMath.h
TMultiGraph::PaintPolyLine3D
void PaintPolyLine3D(Option_t *chopt="")
Paint all the graphs of this multigraph as 3D lines.
Definition: TMultiGraph.cxx:1454
gROOT
#define gROOT
Definition: TROOT.h:406
int
g
#define g(i)
Definition: RSha256.hxx:123