Skip to content

Commit f55db96

Browse files
authored
Add files via upload
1 parent ce0631b commit f55db96

7 files changed

+1080
-0
lines changed

fit_dmeos/_01_basic_fit.C

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
2+
// this function will be used to set up our TF1 object
3+
double myfunction( double* x, double* par ) {
4+
5+
// it takes in a pointer 'x'
6+
// for example: double x[2] = { 0, 0);
7+
// or double* x = new double [2]
8+
// x[0] = x[1] = 0
9+
10+
11+
12+
double deg = x[0];
13+
14+
double c1 = par[0];
15+
double m = par[1];
16+
17+
double ret = c1 + TMath::Sin( m * deg / 180 * TMath::Pi() );
18+
return ret;
19+
}
20+
21+
22+
23+
// we will assign data for x and y here.
24+
// the x range is from xMin to xMax.
25+
// and we will have dataN points of (x,y)
26+
void generate_data( double* x, double* y, int dataN,
27+
double xMin = 0.,
28+
double xMax = 180. )
29+
{
30+
31+
// the answer.
32+
// and we want the fitting to show c1 and m are close to
33+
// these values.
34+
double c1 = 1.5;
35+
double m = 0.7;
36+
37+
TF1* ftemp = new TF1( "myfunc", myfunction, xMin, xMax, 2 );
38+
39+
ftemp->SetParameters( c1 , m );
40+
41+
for( int i = 0; i < dataN; i++ )
42+
{
43+
44+
x[i] = gRandom->Uniform( xMin, xMax );
45+
46+
y[i] = ftemp->Eval( x[i] ) + gRandom->Uniform(-0.01, 0.01 );
47+
48+
// we use TF1::Eval method to get the y value from
49+
// a given x, with our c1 and m parameters.
50+
// we also add some noise signals.
51+
52+
}
53+
54+
delete ftemp;
55+
}
56+
57+
58+
59+
60+
61+
void _01_basic_fit( )
62+
{
63+
64+
65+
// STEP1:
66+
// build our TF1 ( formula ) object
67+
//
68+
double xMin = 0;
69+
double xMax = 180;
70+
int parN = 2; // the parameter numbers in the TF1.
71+
72+
TF1* f1 = new TF1( "myfunc", myfunction, xMin, xMax, parN );
73+
/*
74+
this is one of the constructor of TF1 class.
75+
it takes in a function with (Double_t*, Double_t*) arguments
76+
and return a Double_t.
77+
78+
*/
79+
80+
81+
// set the names for the two parameters.
82+
f1->SetParNames( "c1", "m") ;
83+
84+
85+
86+
87+
88+
//===============================================================
89+
90+
// STEP2:
91+
// assign some data.
92+
const int dataN = 1000;
93+
double x[dataN] = {0.0};
94+
double y[dataN] = {0.0};
95+
96+
generate_data( x, y, dataN, xMin, xMax );
97+
98+
99+
TGraph* gr = new TGraph( dataN, x, y );
100+
101+
// just for fun, let see what data look like.
102+
TCanvas* c1 = new TCanvas("c1");
103+
gr->Draw("AP*");
104+
105+
106+
107+
108+
109+
110+
//===============================================================
111+
// STEP3:
112+
// do fitting and get results.
113+
114+
// set initial value, important for the fit.
115+
f1->SetParameters( 0.0 , 1.0 );
116+
117+
118+
119+
// some options
120+
//f1->SetParLimits(0, -1, 1 );
121+
// set 0th par to be bounded between -1 and 1.
122+
123+
// f1->FixParameter( 1, 0.8 );
124+
// set the 1th par to be fixed at 0.8
125+
126+
gr->Fit( f1 , "Q" );
127+
// Q = quiet
128+
// N = not draw the fitted curve.
129+
// R = using the range defined in TF1, not those from TGraph (or TH1)
130+
// M = improve algorithm
131+
// more options. goo.gl/odmhGU
132+
133+
134+
135+
cout << "c1 = " << f1->GetParameter(0) << endl;
136+
cout << "m = " << f1->GetParameter(1) << endl;
137+
cout << "Ndf =" << f1->GetNDF() << endl;
138+
cout << "chisqr =" << f1->GetChisquare() << endl;
139+
}

fit_dmeos/_02_setup_TF1.C

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
class gaus_class {
2+
3+
public:
4+
5+
double simple_gaus( double* t, double* par) {
6+
double x = t[0];
7+
double h = par[0]; // hight
8+
double c = par[1]; // center
9+
double w = par[2]; // width
10+
double temp = -0.5* ( (x-c)/w )*( (x-c)/w );
11+
return h*exp(temp);
12+
}
13+
};
14+
15+
TGraph* gr;
16+
17+
void _02_setup_TF1() {
18+
19+
//====================================================================
20+
// to use the built-in function ( gaus, expo, polN )
21+
// (you dont need to specify the parN.)
22+
if( 1 ) {
23+
24+
TCanvas* c1 = new TCanvas("c1");
25+
c1->Divide(1,3, 0, 0 );
26+
27+
TF1* f1a = new TF1( "f1a", "gaus", -3, 3 ); // p0*exp(-0.5*((x-p1)/p2)^2)).
28+
TF1* f1b = new TF1( "f1b", "expo", -3, 3 ); // exp(p0+p1*x).
29+
TF1* f1c = new TF1( "f1c", "pol2", -3, 3 ); // p0 + p1*x +p2*x**2
30+
31+
f1a->SetParameters( 1, 0, 0.5 );
32+
f1b->SetParameters( 0, 1 );
33+
f1c->SetParameters( 1, 1, 1);
34+
35+
c1->cd(1); f1a->Draw();
36+
c1->cd(2); f1b->Draw();
37+
c1->cd(3); f1c->Draw();
38+
39+
40+
41+
42+
43+
//====================================================================
44+
// inline method:
45+
// use [0] as 0th par, [1] as 1th par, etc ...
46+
47+
48+
TCanvas* c2 = new TCanvas("c2");
49+
c2->Divide( 2,1,0,0);
50+
51+
TF1* f2 = new TF1( "f2", "[0]*exp( -0.5* ( (x-[1])/[2] )**2 )", -3, 3 );
52+
53+
54+
f2->SetParameters( 1, 0, 0.5 );
55+
f2->SetLineColor( kBlue );
56+
c2->cd(1); f2->Draw();
57+
c2->cd(2); f1a->Draw();
58+
59+
60+
61+
62+
63+
//====================================================================
64+
// using a method from a class.
65+
// advantage: it can access the member varaibles in the class.
66+
67+
68+
TCanvas* c3 = new TCanvas("c3");
69+
c3->Divide( 3,1,0,0);
70+
gaus_class* myGaus = new gaus_class();
71+
TF1* f3 =
72+
new TF1( "f3", myGaus, &gaus_class::simple_gaus, -3, 3, 3 );
73+
74+
f3->SetParameters( 0.5, 0., 0.5 );
75+
f3->SetLineColor( kGreen );
76+
c3->cd(1); f3->Draw();
77+
c3->cd(2); f2->Draw();
78+
c3->cd(3); f1a->Draw();
79+
}
80+
81+
82+
83+
84+
//====================================================================
85+
// use TGraph as a function.
86+
// we can use a lambda function to access TGraph object.
87+
88+
if( 1 )
89+
{
90+
91+
TCanvas* c4 = new TCanvas("c4", "c4");
92+
93+
// let make some data for our TGraph object.
94+
const int dataN = 100;
95+
double xMin = 1;
96+
double xMax = 10;
97+
double x[dataN];
98+
double y[dataN];
99+
100+
for( int i =0; i<dataN; i++ )
101+
{
102+
x[i] = xMin + (xMax-xMin)/ (dataN-1) * i ;
103+
y[i] = 1/x[i] + 1.0 ;
104+
}
105+
106+
gr = new TGraph( dataN, x, y );
107+
108+
auto lambda_func
109+
= [&] (double*x, double *par){ return par[0]*gr->Eval(x[0]); };
110+
111+
TF1 * f4 = new TF1( "f4", lambda_func, xMin, xMax, 1);
112+
113+
// [] is the symbol for the start of lambda function.
114+
// [&] means this lambda function can access the variables in current scope.
115+
// so we can access gr in our lambda function.
116+
// we have 1 parameters in the lambda function
117+
// which is kind of scaling factor.
118+
119+
f4->SetParameter(0, 0.95 );
120+
121+
122+
123+
// draw the TF1 and TGraph together sometimes tricy
124+
// (and may casue memory issue).
125+
f4->SetLineColor( kRed+1 );
126+
f4->Draw( "" );
127+
gr->Draw("same");
128+
}
129+
130+
}

fit_dmeos/_03_fit_2D.C

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
2+
// gaus2d is for 2d gaussian function.
3+
Double_t gaus2d( Double_t* t, Double_t* par ) {
4+
5+
double x = t[0];
6+
double y = t[1];
7+
8+
double a_x = par[0];
9+
double c_x = par[1];
10+
double s_x = par[2];
11+
12+
double a_y = par[3];
13+
double c_y = par[4];
14+
double s_y = par[5];
15+
16+
17+
double termx = a_x * TMath::Exp( -0.5*(x-c_x)*(x-c_x) /s_x /s_x );
18+
double termy = a_y * TMath::Exp( -0.5*(y-c_y)*(y-c_y) /s_y /s_y );
19+
return termx * termy;
20+
21+
}
22+
23+
24+
25+
26+
27+
void _03_fit_2D() {
28+
29+
//======================================================
30+
// Step 1
31+
// prepare a TH2F histo for source data.
32+
//
33+
TH2F* histo2D = new TH2F( "histo2D", "histo2D",
34+
200, 0, 200,
35+
200, 0, 200 );
36+
double width_x[3], width_y[3];
37+
double center_x[3], center_y[3];
38+
39+
for( int i=0; i<10000; i++) {
40+
41+
histo2D->Fill( gRandom->Gaus( 100, 5),
42+
gRandom->Gaus( 150, 3) );
43+
}
44+
45+
// let's visualize the data
46+
TCanvas* c1 = new TCanvas("c1","c1", 500, 375);
47+
histo2D->Draw( "colz" );
48+
49+
50+
51+
52+
53+
//======================================================
54+
// Step 2
55+
// prepare a TF2 for the fitting.
56+
57+
58+
59+
TF2* f2 = new TF2( "f2", gaus2d, 50, 150, 50, 200, 6 );
60+
// the syntax is very similar
61+
// xMin, xMax, yMin, yMax, parN
62+
63+
// it is important to set inital values for fitting.
64+
f2->SetParameters( 1000, 80, 8, 1000, 120, 3 );
65+
f2->SetParLimits( 2, 0, 10); // for sigma_x
66+
f2->SetParLimits( 5, 0, 10); // for sigma_y
67+
68+
f2->SetParNames( "height_x", "center_x", "sigma_x",
69+
"height_y", "center_y", "sigma_y" );
70+
71+
72+
73+
74+
// show the fit results.
75+
histo2D->Fit( f2, "MN" );
76+
// "R" for using the range defined in TF2
77+
78+
cout << "==================\n" << endl;
79+
80+
printf( "center is at x=%6.3f, y=%6.3f\n",
81+
f2->GetParameter(1), f2->GetParameter(4));
82+
83+
printf( "sigma_x = %6.3f, sigma_y = %6.3f\n",
84+
f2->GetParameter(2), f2->GetParameter(5) );
85+
86+
histo2D->Draw();
87+
f2->Draw( "same");
88+
89+
}

0 commit comments

Comments
 (0)