Skip to content

Commit 8912872

Browse files
authored
Merge pull request #4114 from petermic/dedxfitter
dEdxFitter added to TPC calibrations
2 parents 561e967 + 9a19bb9 commit 8912872

File tree

9 files changed

+1240
-0
lines changed

9 files changed

+1240
-0
lines changed
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
#include "GlobaldEdxFitter.h"
2+
3+
#include "bethe_bloch.h"
4+
#include "TF1.h"
5+
#include "TF2.h"
6+
#include "TF3.h"
7+
#include "TChain.h"
8+
#include "TGraph.h"
9+
#include "Math/Minimizer.h"
10+
#include "Math/Functor.h"
11+
#include "Math/Factory.h"
12+
13+
void GlobaldEdxFitter::processResidualData(const std::string& infile, size_t ntracks, size_t skip)
14+
{
15+
std::unique_ptr<TChain> t = std::make_unique<TChain>();
16+
t->Add((infile+"?#residualtree").c_str());
17+
// TFile* f = TFile::Open(infile.c_str());
18+
// TTree* t = (TTree*)f->Get("residualtree");
19+
20+
float px;
21+
float py;
22+
float pz;
23+
float dedx;
24+
float eta;
25+
int nmaps;
26+
int nintt;
27+
int ntpc;
28+
float dcaxy;
29+
30+
t->SetBranchAddress("px",&px);
31+
t->SetBranchAddress("py",&py);
32+
t->SetBranchAddress("pz",&pz);
33+
t->SetBranchAddress("dedx",&dedx);
34+
t->SetBranchAddress("eta",&eta);
35+
t->SetBranchAddress("nmaps",&nmaps);
36+
t->SetBranchAddress("nintt",&nintt);
37+
t->SetBranchAddress("ntpc",&ntpc);
38+
t->SetBranchAddress("dcaxy",&dcaxy);
39+
40+
size_t total_entries = t->GetEntriesFast();
41+
42+
for(size_t entry=skip; entry<(skip+ntracks); entry++)
43+
{
44+
if(entry==total_entries)
45+
{
46+
break;
47+
}
48+
if(entry % 1000 == 0)
49+
{
50+
std::cout << entry << std::endl;
51+
}
52+
t->GetEntry(entry);
53+
if(nmaps>0 && nintt>0 && std::fabs(eta)<1. && dcaxy<0.5 && ntpc>30)
54+
{
55+
p.push_back(std::sqrt(px*px+py*py+pz*pz));
56+
dEdx.push_back(dedx);
57+
}
58+
}
59+
std::cout << "number of good tracks: " << p.size() << std::endl;
60+
//f->Close();
61+
}
62+
63+
void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p)
64+
{
65+
dEdx.push_back(trk_dEdx);
66+
p.push_back(trk_p);
67+
}
68+
69+
double GlobaldEdxFitter::get_fitquality_new(double A)
70+
{
71+
//double chi2 = 0.;
72+
//double ndf = -1.;
73+
74+
double pi_chi2 = 0.;
75+
double K_chi2 = 0.;
76+
double p_chi2 = 0.;
77+
double d_chi2 = 0.;
78+
double pi_ndf = -1.;
79+
double K_ndf = -1.;
80+
double p_ndf = -1.;
81+
double d_ndf = -1.;
82+
83+
for(size_t i=0; i<dEdx.size(); i++)
84+
{
85+
const double dedx_pi = bethe_bloch_new_1D(p[i]/dedx_constants::m_pi,A);
86+
const double dedx_K = bethe_bloch_new_1D(p[i]/dedx_constants::m_K,A);
87+
const double dedx_p = bethe_bloch_new_1D(p[i]/dedx_constants::m_p,A);
88+
const double dedx_d = bethe_bloch_new_1D(p[i]/dedx_constants::m_d,A);
89+
90+
//std::cout << "dedx: (" << dedx_pi << ", " << dedx_K << ", " << dedx_p << ", " << dedx_d << ")" << std::endl;
91+
//std::cout << "measured: " << dEdx[i] << std::endl;
92+
93+
const double pi_dist = fabs(dEdx[i]-dedx_pi);
94+
const double K_dist = fabs(dEdx[i]-dedx_K);
95+
const double p_dist = fabs(dEdx[i]-dedx_p);
96+
const double d_dist = fabs(dEdx[i]-dedx_d);
97+
98+
//std::cout << "dist: (" << pi_dist << ", " << K_dist << ", " << p_dist << ", " << d_dist << ")" << std::endl;
99+
100+
if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist)
101+
{
102+
//std::cout << "pion" << std::endl;
103+
//chi2 += pi_dist*pi_dist;
104+
pi_chi2 += pi_dist*pi_dist;
105+
pi_ndf += 1.;
106+
}
107+
else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist)
108+
{
109+
//std::cout << "K" << std::endl;
110+
//chi2 += K_dist*K_dist;
111+
K_chi2 += K_dist*K_dist;
112+
K_ndf += 1.;
113+
}
114+
else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist)
115+
{
116+
//std::cout << "p" << std::endl;
117+
//chi2 += p_dist*p_dist;
118+
p_chi2 += p_dist*p_dist;
119+
p_ndf += 1.;
120+
}
121+
122+
else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist)
123+
{
124+
//std::cout << "d" << std::endl;
125+
//chi2 += d_dist*d_dist;
126+
d_chi2 += d_dist*d_dist;
127+
d_ndf += 1.;
128+
}
129+
130+
//ndf += 1.;
131+
//std::cout << "chi2: " << chi2 << std::endl;
132+
//std::cout << "ndf: " << ndf << std::endl;
133+
}
134+
135+
if(pi_ndf<1.) {pi_chi2 = 0.; pi_ndf = 1.;}
136+
if(K_ndf<1.) {K_chi2 = 0.; K_ndf = 1.;}
137+
if(p_ndf<1.) {p_chi2 = 0.; p_ndf = 1.;}
138+
if(d_ndf<1.) {d_chi2 = 0.; d_ndf = 1.;}
139+
140+
const double quality = sqrt((pi_chi2*pi_chi2)/(pi_ndf*pi_ndf)+(K_chi2*K_chi2)/(K_ndf*K_ndf)+(p_chi2*p_chi2)/(p_ndf*p_ndf)+(d_chi2*d_chi2)/(d_ndf*d_ndf));
141+
//const double quality = chi2/ndf;
142+
143+
//std::cout << "A: " << A << " quality: " << quality << std::endl;
144+
145+
return quality;
146+
}
147+
148+
double GlobaldEdxFitter::get_fitquality(double norm, double ZS_loss)
149+
{
150+
float pi_chi2 = 0.;
151+
float K_chi2 = 0.;
152+
float p_chi2 = 0.;
153+
float d_chi2 = 0.;
154+
float pi_ndf = -1.;
155+
float K_ndf = -1.;
156+
float p_ndf = -1.;
157+
float d_ndf = -1.;
158+
//float ndf = -1;
159+
160+
for(size_t i=0; i<dEdx.size(); i++)
161+
{
162+
163+
const float dedx_pi = norm*bethe_bloch_total(p[i]/dedx_constants::m_pi) - ZS_loss;
164+
const float dedx_K = norm*bethe_bloch_total(p[i]/dedx_constants::m_K) - ZS_loss;
165+
const float dedx_p = norm*bethe_bloch_total(p[i]/dedx_constants::m_p) - ZS_loss;
166+
const float dedx_d = norm*bethe_bloch_total(p[i]/dedx_constants::m_d) - ZS_loss;
167+
168+
const float pi_dist = fabs(dedx_pi-dEdx[i]);
169+
const float K_dist = fabs(dedx_K-dEdx[i]);
170+
const float p_dist = fabs(dedx_p-dEdx[i]);
171+
const float d_dist = fabs(dedx_d-dEdx[i]);
172+
173+
if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist)
174+
{
175+
pi_chi2 += pi_dist*pi_dist/std::fabs(dedx_pi);
176+
pi_ndf += 2.;
177+
}
178+
else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist)
179+
{
180+
K_chi2 += K_dist*K_dist/std::fabs(dedx_K);
181+
K_ndf += 2.;
182+
}
183+
else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist)
184+
{
185+
p_chi2 += p_dist*p_dist/std::fabs(dedx_p);
186+
p_ndf += 2.;
187+
}
188+
else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist)
189+
{
190+
d_chi2 += d_dist*d_dist/std::fabs(dedx_d);
191+
d_ndf += 2.;
192+
}
193+
//ndf += 2;
194+
}
195+
196+
const double quality = std::sqrt((pi_chi2*pi_chi2)/(pi_ndf*pi_ndf) +
197+
(K_chi2*K_chi2)/(K_ndf*K_ndf) +
198+
(p_chi2*p_chi2)/(p_ndf*p_ndf) +
199+
(d_chi2*d_chi2)/(d_ndf*d_ndf));
200+
201+
/*
202+
const double quality = sqrt((pi_chi2*pi_chi2 +
203+
K_chi2*K_chi2 +
204+
p_chi2*p_chi2)
205+
/(ndf*ndf));
206+
*/
207+
//std::cout << "norm: " << norm << " ZS: " << ZS_loss << std::endl;
208+
//std::cout << "quality: " << quality << std::endl;
209+
210+
return quality;
211+
}
212+
213+
std::vector<double> GlobaldEdxFitter::get_betagamma(double A)
214+
{
215+
std::vector<double> betagamma;
216+
for(size_t i=0; i<dEdx.size(); i++)
217+
{
218+
const double dedx_pi = bethe_bloch_new_1D(p[i]/dedx_constants::m_pi,A);
219+
const double dedx_K = bethe_bloch_new_1D(p[i]/dedx_constants::m_K,A);
220+
const double dedx_p = bethe_bloch_new_1D(p[i]/dedx_constants::m_p,A);
221+
const double dedx_d = bethe_bloch_new_1D(p[i]/dedx_constants::m_d,A);
222+
223+
//std::cout << "dedx: (" << dedx_pi << ", " << dedx_K << ", " << dedx_p << ", " << dedx_d << ")" << std::endl;
224+
//std::cout << "measured: " << dEdx[i] << std::endl;
225+
226+
const double pi_dist = fabs(dEdx[i]-dedx_pi);
227+
const double K_dist = fabs(dEdx[i]-dedx_K);
228+
const double p_dist = fabs(dEdx[i]-dedx_p);
229+
const double d_dist = fabs(dEdx[i]-dedx_d);
230+
231+
if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist)
232+
{
233+
betagamma.push_back(p[i]/dedx_constants::m_pi);
234+
}
235+
else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist)
236+
{
237+
betagamma.push_back(p[i]/dedx_constants::m_K);
238+
}
239+
else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist)
240+
{
241+
betagamma.push_back(p[i]/dedx_constants::m_p);
242+
}
243+
else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist)
244+
{
245+
betagamma.push_back(p[i]/dedx_constants::m_d);
246+
}
247+
}
248+
return betagamma;
249+
}
250+
251+
double GlobaldEdxFitter::get_fitquality_functor(const double* x)
252+
{
253+
return get_fitquality_new(x[0]);
254+
}
255+
256+
double GlobaldEdxFitter::get_fitquality_wrapper(double* x, double* /* par */)
257+
{
258+
return get_fitquality(x[0]);
259+
}
260+
261+
double GlobaldEdxFitter::get_fitquality_wrapper_ZS(double* x, double* /* par */)
262+
{
263+
return get_fitquality(x[0],x[1]);
264+
}
265+
266+
double GlobaldEdxFitter::get_fitquality_wrapper_new(double* x, double* /* par */)
267+
{
268+
return get_fitquality_new(x[0]);
269+
}
270+
271+
TF3* GlobaldEdxFitter::create_TF3_new(const std::string& name)
272+
{
273+
TF3* f = new TF3(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_new,min_norm,max_norm,min_B,max_B,min_ZS,max_ZS,0,"GlobaldEdxFitter","get_fitquality_wrapper_new");
274+
return f;
275+
}
276+
277+
TF1* GlobaldEdxFitter::create_TF1(const std::string& name)
278+
{
279+
TF1* f = new TF1(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_new,min_norm,max_norm,0,"GlobaldEdxFitter","get_fitquality_wrapper");
280+
return f;
281+
}
282+
283+
TF2* GlobaldEdxFitter::create_TF2(const std::string& name)
284+
{
285+
TF2* f = new TF2(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_ZS,min_norm,max_norm,min_ZS,max_ZS,0,"GlobaldEdxFitter","get_fitquality_wrapper_ZS");
286+
return f;
287+
}
288+
289+
double GlobaldEdxFitter::get_minimum_new()
290+
{
291+
/*
292+
TF3* f = create_TF3_new("temp");
293+
double minA;
294+
double minB;
295+
double minC;
296+
f->GetMinimumXYZ(minA,minB,minC);
297+
delete f;
298+
return std::make_tuple(minA,minB,minC);
299+
*/
300+
ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2");
301+
minimizer->SetMaxFunctionCalls(1000000);
302+
minimizer->SetMaxIterations(10000);
303+
minimizer->SetTolerance(0.1);
304+
minimizer->SetPrintLevel(1);
305+
ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1);
306+
double step[1] = {.01};
307+
double variable[1] = {20.};
308+
minimizer->SetFunction(f);
309+
minimizer->SetVariable(0,"A",variable[0],step[0]);
310+
minimizer->Minimize();
311+
const double *xs = minimizer->X();
312+
delete minimizer;
313+
return xs[0];
314+
}
315+
316+
double GlobaldEdxFitter::get_minimum()
317+
{
318+
TF1* f = create_TF1("temp");
319+
f->SetNpx(1000);
320+
double minX = f->GetMinimumX();
321+
delete f;
322+
return minX;
323+
}
324+
325+
std::pair<double,double> GlobaldEdxFitter::get_minimum_ZS()
326+
{
327+
TF2* f = create_TF2("temp");
328+
double minX;
329+
double minY;
330+
f->GetMinimumXY(minX,minY);
331+
delete f;
332+
return std::make_pair(minX,minY);
333+
}
334+
335+
TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A)
336+
{
337+
std::vector<double> betagamma = get_betagamma(A);
338+
TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data());
339+
return g;
340+
}
341+
342+
TGraph* GlobaldEdxFitter::graph_vsp()
343+
{
344+
TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data());
345+
return g;
346+
}

0 commit comments

Comments
 (0)