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 "Riostream.h"
21#include "TVirtualFitter.h"
22#include "TPluginManager.h"
23#include "TMath.h"
24#include "TSystem.h"
25#include "TF1.h"
26#include <stdlib.h>
27
28#include "HFitInterface.h"
29#include "Fit/DataRange.h"
31
32#include <ctype.h>
33
34extern 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
60A TMultiGraph allows to manipulate a set of graphs as a single entity. In particular,
61when drawn, the X and Y axis ranges are automatically computed such as all the graphs
62will be visible.
63
64`TMultiGraph::Add` should be used to add a new graph to the list.
65
66The TMultiGraph owns the objects in the list.
67
68The number of graphs in a multigraph can be retrieve with:
69~~~ {.cpp}
70mg->GetListOfGraphs()->GetEntries();
71~~~
72
73### <a name="MG00"></a> MultiGraphs' Drawing
74
75The drawing options are the same as for TGraph.
76Like for TGraph, the painting is performed thanks to the TGraphPainter
77class. All details about the various painting options are given in this class.
78
79Example:
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
91The drawing option for each TGraph may be specified as an optional
92second argument of the `Add` function.
93
94If a draw option is specified, it will be used to draw the graph,
95otherwise the graph will be drawn with the option specified in
96`TMultiGraph::Draw`
97
98#### <a name="MG01b"></a> Titles setting
99
100The 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
113A special option `3D` allows to draw the graphs in a 3D space. See the
114following example:
115
116Begin_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}
151End_Macro
152
153#### <a name="MG01d"></a> Legend drawing
154
155The method TPad::BuildLegend is able to extract the graphs inside a
156multigraph. The following example demonstrate this.
157
158Begin_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}
212End_Macro
213
214#### <a name="MG01e"></a> Automatic coloring
215
216Automatic coloring according to the current palette is available as shown in the
217following example:
218
219Begin_Macro(source)
220../../../tutorials/graphs/multigraphpalettecolor.C
221End_Macro
222
223#### <a name="MG01f"></a> Reverse axis
224
225\since **ROOT version 6.19/02**
226
227When a TMultiGraph is drawn, the X-axis is drawn with increasing values from left to
228right and the Y-axis from bottom to top. The two options RX and RY allow to change
229this order. The option RX allows to draw the X-axis with increasing values from
230right to left and the RY option allows to draw the Y-axis with increasing values
231from top to bottom. The following example illustrate how to use these options.
232
233Begin_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}
270End_Macro
271
272### <a name="MG02"></a> MultiGraphs' fitting
273
274The following example shows how to fit a TMultiGraph.
275
276Begin_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}
308End_Macro
309
310#### <a name="MG02a"></a> Fit box position
311
312When the graphs in a TMultiGraph are fitted, the fit parameters boxes
313overlap. The following example shows how to make them all visible.
314
315
316Begin_Macro(source)
317../../../tutorials/graphs/multigraph.C
318End_Macro
319
320### <a name="MG03"></a> Axis' limits setting
321
322The axis limits can be changed the like for TGraph. The same methods apply on
323the multigraph.
324Note the two differents ways to change limits on X and Y axis.
325
326Begin_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}
351End_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
371TMultiGraph::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
467void 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
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
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
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
1593void 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
1622void 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}
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
int Int_t
Definition: RtypesCore.h:43
const Bool_t kFALSE
Definition: RtypesCore.h:90
double Axis_t
Definition: RtypesCore.h:74
double Double_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
char name[80]
Definition: TGX11.cxx:109
float xmin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
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:4720
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
#define gPad
Definition: TVirtualPad.h:287
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:34
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition: TAttAxis.cxx:229
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
Class to manage histogram axis.
Definition: TAxis.h:30
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition: TAxis.cxx:820
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
Double_t GetXmax() const
Definition: TAxis.h:134
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:658
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:515
virtual void SetTimeDisplay(Int_t value)
Definition: TAxis.h:161
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:466
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
Double_t GetXmin() const
Definition: TAxis.h:133
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
virtual void SetTimeFormat(const char *format="")
Change the format used for time plotting.
Definition: TAxis.cxx:1013
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:914
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:455
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
1-Dim function class
Definition: TF1.h:210
virtual Int_t GetNpar() const
Definition: TF1.h:475
@ kNotDraw
Definition: TF1.h:320
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3500
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:628
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
Definition: TFitResultPtr.h:31
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
@ kResetHisto
fHistogram must be reset in GetHistogram
Definition: TGraph.h:71
virtual void Paint(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:2030
virtual void PaintStats(TF1 *fit)
Draw the stats.
Definition: TGraph.cxx:2057
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
virtual void SetHistogram(TH1F *h)
Definition: TGraph.h:175
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
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:8393
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6345
TAxis * GetZaxis()
Definition: TH1.h:318
@ kNoStats
don't draw stats box
Definition: TH1.h:160
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
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:8006
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
TAxis * GetYaxis()
Definition: TH1.h:317
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5837
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:8091
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2736
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8446
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
void Reset()
Definition: TCollection.h:252
Iterator of linked list.
Definition: TList.h:200
Option_t * GetOption() const
Returns the object option stored in the list.
Definition: TList.cxx:1143
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:821
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
virtual TObjLink * FirstLink() const
Definition: TList.h:108
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
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:658
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:36
Double_t fMinimum
Definition: TMultiGraph.h:43
TH1F * fHistogram
Definition: TMultiGraph.h:41
TMultiGraph()
TMultiGraph default constructor.
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.
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:70
TList * fGraphs
Definition: TMultiGraph.h:39
virtual void Add(TGraph *graph, Option_t *chopt="")
Add a new graph to the list of graphs.
Double_t fMaximum
Definition: TMultiGraph.h:42
virtual void SetMinimum(Double_t minimum=-1111)
Set multigraph minimum.
TH1F * GetHistogram()
Returns a pointer to the histogram used to draw the axis.
TF1 * GetFunction(const char *name) const
Return pointer to function with name.
virtual void LeastSquareFit(Int_t m, Double_t *a, Double_t xmin, Double_t xmax)
Least squares lpolynomial fitting without weights.
virtual void InitPolynom(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for a polynom.
void PaintPolyLine3D(Option_t *chopt="")
Paint all the graphs of this multigraph as 3D lines.
virtual void InitExpo(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for an exponential.
virtual void FitPanel()
Display a panel with all histogram fit options.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to each graph.
virtual void Paint(Option_t *chopt="")
Paint all the graphs of this multigraph.
virtual void Draw(Option_t *chopt="")
Draw this multigraph with its current attributes.
TIter begin() const
Get iterator over internal graphs list.
TMultiGraph & operator=(const TMultiGraph &)
Assignment operator.
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.
void PaintPads(Option_t *chopt="")
Divides the active pad and draws all Graphs in the Multigraph separately.
virtual Option_t * GetGraphDrawOption(const TGraph *gr) const
Return the draw option for the TGraph gr in this TMultiGraph.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
TAxis * GetYaxis()
Get y axis of the graph.
virtual void InitGaus(Double_t xmin, Double_t xmax)
Compute Initial values of parameters for a gaussian.
virtual ~TMultiGraph()
TMultiGraph destructor.
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.
TList * GetListOfFunctions()
Return pointer to list of functions.
virtual void Print(Option_t *chopt="") const
Print the list of graphs.
virtual void SetMaximum(Double_t maximum=-1111)
Set multigraph maximum.
virtual void Browse(TBrowser *b)
Browse multigraph.
void PaintReverse(Option_t *chopt="")
Paint all the graphs of this multigraph reverting values along X and/or Y axis.
TList * fFunctions
Definition: TMultiGraph.h:40
TAxis * GetXaxis()
Get x axis of the graph.
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
Long_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
Basic string class.
Definition: TString.h:131
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
Bool_t IsNull() const
Definition: TString.h:402
TString & Append(const char *cs)
Definition: TString.h:559
Bool_t IsWhitespace() const
Definition: TString.h:403
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Abstract Base Class for Fitting.
static TVirtualFitter * GetFitter()
static: return the current Fitter
virtual TObject * GetUserFunc() const
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:51
virtual TList * GetListOfPrimitives() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
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
virtual void Clear(Option_t *option="")=0
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
TGraphErrors * gr
Definition: legend1.C:25
TH1F * h1
Definition: legend1.C:5
TF1 * f1
Definition: legend1.C:11
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:972
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition: HFitImpl.cxx:685
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static constexpr double mg
Double_t Log(Double_t x)
Definition: TMath.h:750
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
Double_t Log10(Double_t x)
Definition: TMath.h:754
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: first.py:1
Definition: graph.py:1
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12