BOSS 7.0.9
BESIII Offline Software System
Loading...
Searching...
No Matches
KalmanVertexFit.cxx
Go to the documentation of this file.
1//
2// Kalman Vertex fit
3// The algoritm is based on a paper by
4// R. Fruhwirth etc Computer Physics Communications 96(1996) 189-208
5// The formulism for BES3 can be find at BESIII Software Note: No. xx
6// Author: Kanglin He and Min Xu, Apr. 13, 2007 for created
7//
8
9
13#include "math.h"
14
15using namespace std;
16
17KalmanVertexFit * KalmanVertexFit::m_pointer = 0;
18
20 if(m_pointer) return m_pointer;
21 m_pointer = new KalmanVertexFit();
22 return m_pointer;
23}
24
26
27KalmanVertexFit::KalmanVertexFit() {;}
28
30 m_x = HepVector(3, 0);
31 m_C0 = HepSymMatrix(3, 0);
32 m_C = HepSymMatrix(3, 0);
33 m_chisq = 0;
34 m_ndof = -3;
35
36 m_flag.clear();
37 m_p.clear();
38 m_hTrkOrigin.clear();
39 m_hTrkInfit.clear(); //xum
40 //m_wTrkInfit.clear();
41
42 m_G.clear();
43 m_A.clear();
44 m_B.clear();
45 m_c.clear();
46 m_W.clear();
47 m_GB.clear();
48 m_chiF.clear();
49
50 //
51 // chi-square cut, number of iteration etc
52 //
53 m_chisqCutforTrack = 50;
54 m_maxVertexIteration = 3;
55 m_maxTrackIteration = 5;
56 m_chisqCutforTrackIteration = 0.1;
57}
58
60 int ifail;
61 m_x = vtx.Vx();
62 m_C0 = (vtx.Evx()).inverse(ifail);
63 m_C = m_C0;
64}
65
67 int ifail;
69 v.setVx(m_x);
70
71 std::vector<int> trackid;
72 v.setEvx(m_C.inverse(ifail));
73 return v;
74}
75
76HepSymMatrix KalmanVertexFit::Ex() const {
77 int ifail;
78 return m_C.inverse(ifail);
79}
80
82
83 int ifail;
84
85 HepVector p(3, 0);
86 p = htrk.p();
87
88 m_p.push_back(p);
89 m_flag.push_back(0);
90 m_chiF.push_back(999.);
91
92 HepMatrix A(5, 3, 0);
93 HepMatrix B(5, 3, 0);
94 HepSymMatrix G(5, 0);
95
96 G = (htrk.eHel()).inverse(ifail);
97
98 m_hTrkOrigin.push_back(htrk);
99
100 //xum
101 m_hTrkInfit.push_back(htrk);
102 //m_wTrkInfit.push_back(htrk.wTrack());
103
104 m_G.push_back(G);
105 m_A.push_back(A);
106 m_B.push_back(B);
107
108 HepSymMatrix W(3, 0);
109 HepSymMatrix GB(5, 0);
110 HepVector c(5, 0);
111
112 m_W.push_back(W);
113 m_GB.push_back(GB);
114 m_c.push_back(c);
115
116}
117
119 int num = 0;
120 for(int k = 0; k < m_hTrkOrigin.size(); k++)
121 if(m_flag[k] == 0) num = num +1;
122
123 return num;
124}
125
126std::vector<int> KalmanVertexFit::trackIDList() const {
127 std::vector<int> trackid;
128 for(int k = 0; k < m_hTrkOrigin.size(); k++)
129 if(m_flag[k] == 0) trackid.push_back(trackID(k));
130
131 return trackid;
132}
133
134
135int KalmanVertexFit::filter(const int k) {
136 int ifail;
137 double chisq[10];
138 ////////////////////////////////////////////////
139 // start iteration
140 ///////////////////////////////////////////////
141 HepVector pp(3, 0);
142 HepVector xp(3, 0);
143 HepSymMatrix CP(3, 0);
144 xp = m_x;
145 CP = m_C;
146 pp = m_p[k];
147
148 for(int iter = 0; iter < m_maxTrackIteration; iter++) {
149 //
150 // calculate derivative matrices for track k
151 //
152 updateMatrices(k, pp, xp);
153 //
154 // vertex covariance matrix updated
155 //
156 HepSymMatrix CK(3, 0);
157 CK = CP + (m_GB[k].similarity(m_A[k].T()));
158 //
159 // state vector x and p updated
160 //
161 HepVector x(3, 0);
162 HepVector p(3, 0);
163 x = CK.inverse(ifail) * (CP * xp + m_A[k].T() * m_GB[k] *
164 (m_hTrkOrigin[k].hel() - m_c[k]));
165 p = m_W[k] * m_B[k].T() * m_G[k] *(m_hTrkOrigin[k].hel()- m_c[k]-
166 m_A[k]*x);
167 // chi-square of filter
168 HepSymMatrix chif(1, 0);
169 chif = CP.similarity((x-xp).T()) +
170 m_G[k].similarity((m_hTrkOrigin[k].hel()-
171 m_c[k]- m_A[k]*x - m_B[k]*p).T());
172
173 //
174 // save current 3-momentum and vertex for track k
175 //
176 // 3-momentum
177 pp = p;
178 // current vertex and its covaiance matrix
179 xp = x;
180 CP = CK;
181 chisq[iter] = chif[0][0];
182 m_chiF[k] = chif[0][0];
183 // std::cout << "chisq, iter = " <<m_chiF[k] << ", " << iter << ", " << k <<std::endl;
184 if(iter > 0) {
185 double delchi = (chisq[iter]-chisq[iter-1]);
186 if(fabs(delchi) < m_chisqCutforTrackIteration) break;
187 }
188 }
189
190 if(m_chiF[k] > m_chisqCutforTrack) {
191 // do not update vertex if failed
192 m_flag[k]=1;
193 return 1;
194 } else {
195 // update vertex if filter success
196 m_x = xp;
197 m_C = CP;
198 m_p[k] = pp;
199 return 0;
200 }
201}
202
203void KalmanVertexFit::inverse(const int k) {
204 //
205 // inverse kalman filter for track k
206 //
207
208 int ifail;
209 HepVector x(3, 0);
210 HepVector p(3, 0);
211 HepSymMatrix C(3, 0);
212 C = m_C - m_GB[k].similarity(m_A[k].T());
213 x = C.inverse(ifail)*(m_C*m_x-m_A[k].T() * m_GB[k] *
214 (m_hTrkOrigin[k].hel()-m_c[k]));
215 //
216 // update vertex position and its covariance matrix
217 //
218 m_x = x;
219 m_C = C;
220}
222
223 for(int iter = 0; iter < m_maxVertexIteration; iter++) {
224 //
225 // at start of each iteration,
226 // the covariance matrix take the initial values: m_C0
227 // the vertex position take the update value by the last iteration
228 //
229 m_C = m_C0; // covariance matrix of verter --> initial values
230 m_chisq = 0; // total chi-square of smooth
231 m_ndof = -3; // number of degrees of freedom
232
233 for(int k = 0; k < m_hTrkOrigin.size(); k++) {
234 if(m_flag[k]==1) continue;
235 if(filter(k)==0) // filter track k
236 m_ndof += 2;
237
238 }
239 //
240 // check the chi-square of smooth, make decision to remove bad tracks
241 // user may remove more bad track by tight chi-square cut
242 // through the following interface
243 // KalmanVertexFit::remove(k)
244 //
245 for(int k = 0; k < m_hTrkOrigin.size(); k++) {
246 if(m_flag[k]==1) continue;
247 double chi2 = chiS(k);
248 if(chi2 < 0) { // remove track k from vertex
249 remove(k);
250 continue;
251 }
252
253 if(chi2 > m_chisqCutforTrack) { // remove track k from vertex
254 remove(k);
255 continue;
256 }
257 m_chisq += chi2;
258
259 }
260 } // end of iteration
261}
262
263double KalmanVertexFit::chiS(const int k) const {
264 if(m_flag[k]==1) return 999;
265 int ifail;
266 HepVector x(3, 0);
267 HepVector p(3, 0);
268 HepSymMatrix C(3, 0);
269 C = m_C - m_GB[k].similarity(m_A[k].T());
270 x = C.inverse(ifail)*(m_C*m_x-m_A[k].T() * m_GB[k] *
271 (m_hTrkOrigin[k].hel()-m_c[k]));
272 p = m_W[k]* m_B[k].T()*m_G[k]*
273 (m_hTrkOrigin[k].hel()-m_c[k]-m_A[k]*m_x);
274 HepSymMatrix chis(1, 0);
275 chis = C.similarity((x-m_x).T())+
276 m_G[k].similarity((m_hTrkOrigin[k].hel()-m_c[k]-
277 m_A[k]*m_x-m_B[k]*p).T());
278 return chis[0][0];
279}
280
281void KalmanVertexFit::smooth(const int k) {
282 // xum
283 //
284 // update htrk and wtrk parameters
285 //
286 if(m_flag[k] == 1) return;
287 int ifail;
288
289 HepVector pp(3, 0);
290 HepVector xp(3, 0);
291 HepSymMatrix CP(3, 0);
292 xp = m_x;
293 CP = m_C;
294 pp = m_p[k];
295
296 updateMatrices(k, pp, xp);
297 pp = m_W[k] * m_B[k].T() * m_G[k] * (m_hTrkOrigin[k].hel() - m_c[k] - m_A[k] * xp);
298
299 updateMatrices(k, pp, xp);
300 //for htrk
301 HepVector helix(5, 0);
302 helix = m_c[k] + m_A[k] * xp + m_B[k] * pp;
303 HepMatrix E(3, 3, 0);
304 E = -CP.inverse(ifail) * m_A[k].T() * m_G[k] * m_B[k] * m_W[k];
305 HepSymMatrix D(3, 0);
306 D = m_W[k] + CP.similarity(E.T());
307
308 HepMatrix middle(5, 5, 0);
309 HepSymMatrix error(5, 0);
310 middle = (CP.inverse(ifail)).similarity(m_A[k]) + m_A[k] * E * m_B[k].T() +
311 (m_A[k] * E * m_B[k].T()).T() + D.similarity(m_B[k]);
312 error.assign(middle);
313
314 m_hTrkInfit[k].setHel(helix);
315 m_hTrkInfit[k].setEHel(error);
316
317 m_p[k] = pp;
318/*
319 //for wtrk
320 double mass = m_hTrkOrigin[k].xmass(m_hTrkOrigin[k].partID());
321 double Energy = sqrt(pp[0]*pp[0] + pp[1]*pp[1] + pp[2]*pp[2] + mass * mass);
322
323 HepMatrix Awtrk(7, 3, 0), Bwtrk(7, 3, 0);
324 Awtrk[4][0] = Awtrk[5][1] = Awtrk[6][2] = 1;
325 Bwtrk[0][0] = Bwtrk[1][1] = Bwtrk[2][2] = 1;
326 Bwtrk[3][0] = pp[0] / Energy;
327 Bwtrk[3][1] = pp[1] / Energy;
328 Bwtrk[3][2] = pp[2] / Energy;
329
330 HepVector w(7, 0);
331 HepSymMatrix Ew(7, 0);
332 w[0] = pp[0]; w[1] = pp[1]; w[2] = pp[2]; w[3] = Energy;
333 w[4] = xp[0]; w[5] = xp[1]; w[6] = xp[2];
334
335 HepSymMatrix Gwtrk(7, 0);
336 Gwtrk = m_hTrkOrigin[k].wTrack().Ew().inverse(ifail);
337 HepSymMatrix Wwtrk(3, 0);
338 Wwtrk = Gwtrk.similarity(Bwtrk.T()).inverse(ifail);
339
340 HepMatrix Ewtrk(3, 3, 0);
341 Ewtrk = -CP.inverse(ifail) * m_Awtrk[k].T() * m_Gwtrk[k] * m_Bwtrk[k] * m_Wwtrk[k];
342 HepSymMatrix Dwtrk(3, 0);
343 Dwtrk = m_Wwtrk[k] + CP.similarity(Ewtrk.T());
344
345 HepMatrix Ewmiddle(7, 7, 0);
346 Ewmiddle = (CP.inverse(ifail)).similarity(m_Awtrk[k]) + m_Awtrk[k] * Ewtrk * m_Bwtrk[k].T() +
347 (m_Awtrk[k] * Ewtrk * m_Bwtrk[k].T()).T() + Dwtrk.similarity(m_Bwtrk[k]);
348 Ew.assign(Ewmiddle);
349
350 m_wTrkInfit[k].setCharge(m_hTrkOrigin[k].charge());
351 m_wTrkInfit[k].setW(w);
352 m_wTrkInfit[k].setEw(Ew);*/
353}
354
355void KalmanVertexFit::remove(const int k) {
356 //
357 // remove track k from the vertex fit
358 //
359 /*
360 m_hTrkOrigin.erase(m_hTrkOrigin.begin()+k);
361 m_p.erase(m_p.begin()+k);
362 m_flag.erase(m_flag.begin()+k);
363 m_A.erase(m_A.begin()+k);
364 m_B.erase(m_B.begin()+k);
365 m_c.erase(m_c.begin()+k);
366 m_G.erase(m_G.begin()+k);
367 m_GB.erase(m_GB.begin()+k);
368 m_W.erase(m_W.begin()+k);
369 m_chiF.erase(m_chiF.begin()+k);
370 */
371
372 if(m_flag[k]==1) return; // track k already removed
373 inverse(k);
374 m_ndof -= 2;
375 m_flag[k]=1;
376 //xum
377 //m_chisq -=chiS(k);
378}
379
380
382 //add xum
383 //HTrackParameter htrk;
384 //return htrk;
385 return m_hTrkInfit[k];
386}
387
388WTrackParameter KalmanVertexFit::wTrack(const int k, const double mass) const {
389 if(m_flag[k] == 1) return m_hTrkOrigin[k].wTrack();
390 int ifail;
391
392 HepVector pp(3, 0);
393 HepVector xp(3, 0);
394 HepSymMatrix CP(3, 0);
395 xp = m_x;
396 CP = m_C;
397 pp = m_p[k];
398
399 WTrackParameter wtrk;
400 double Energy = sqrt(pp[0]*pp[0] + pp[1]*pp[1] + pp[2]*pp[2] + mass * mass);
401
402 HepMatrix Awtrk(7, 3, 0), Bwtrk(7, 3, 0);
403 Awtrk[4][0] = Awtrk[5][1] = Awtrk[6][2] = 1;
404 Bwtrk[0][0] = Bwtrk[1][1] = Bwtrk[2][2] = 1;
405 Bwtrk[3][0] = pp[0] / Energy;
406 Bwtrk[3][1] = pp[1] / Energy;
407 Bwtrk[3][2] = pp[2] / Energy;
408
409 HepVector w(7, 0);
410 HepSymMatrix Ew(7, 0);
411 w[0] = pp[0]; w[1] = pp[1]; w[2] = pp[2]; w[3] = Energy;
412 w[4] = xp[0]; w[5] = xp[1]; w[6] = xp[2];
413
414 HepSymMatrix Gwtrk(7, 0);
415 Gwtrk = m_hTrkOrigin[k].wTrack().Ew().inverse(ifail);
416 HepSymMatrix Wwtrk(3, 0);
417 Wwtrk = Gwtrk.similarity(Bwtrk.T()).inverse(ifail);
418
419 HepMatrix Ewtrk(3, 3, 0);
420 Ewtrk = -CP.inverse(ifail) * Awtrk.T() * Gwtrk * Bwtrk * Wwtrk;
421 HepSymMatrix Dwtrk(3, 0);
422 Dwtrk = Wwtrk + CP.similarity(Ewtrk.T());
423
424 HepMatrix Ewmiddle(7, 7, 0);
425 Ewmiddle = (CP.inverse(ifail)).similarity(Awtrk) + Awtrk * Ewtrk * Bwtrk.T() +
426 (Awtrk * Ewtrk * Bwtrk.T()).T() + Dwtrk.similarity(Bwtrk);
427 Ew.assign(Ewmiddle);
428
429 wtrk.setCharge(m_hTrkOrigin[k].charge());
430 wtrk.setW(w);
431 wtrk.setEw(Ew);
432
433 return wtrk;
434}
435
436//
437// private functions, update derivative matrices
438//
439void KalmanVertexFit::updateMatrices(const int k, const HepVector p, const HepVector x) {
440
441 int ifail;
442 //
443 // expand measurement equation at (x, p)
444 //
445 HTrackParameter he(m_hTrkOrigin[k].charge(), p, x);
446
447 // derivative matrix
448
449 m_A[k] = he.dHdx(p, x);
450 m_B[k] = he.dHdp(p, x);
451
452 // W, GB, c
453 m_W[k] = (m_G[k].similarity(m_B[k].T())).inverse(ifail);
454 m_GB[k] = m_G[k] - (m_W[k].similarity(m_B[k])).similarity(m_G[k]);
455 m_c[k] = he.hel() - m_A[k] * x - m_B[k] * p;
456}
457
458void KalmanVertexFit::updateMatrices(const int k) {
459
460 int ifail;
461 HepVector p(3, 0);
462 HepVector x(3, 0);
463 p = m_p[k];
464 x = m_x;
465 updateMatrices(k, p, x);
466}
467
468HepVector KalmanVertexFit::pull(const int k) {
469 HepVector n_pull(5, 0);
470 n_pull[0] = n_pull[1] = n_pull[2] = n_pull[3] = n_pull[4] = 999.;
471 if(m_flag[k] == 1) return n_pull;
472 for (int i = 0 ; i < 5; i++) {
473 double cov = m_hTrkOrigin[k].eHel()[i][i] - m_hTrkInfit[k].eHel()[i][i];
474 if (cov == 0.) continue;
475 n_pull[i] = (m_hTrkOrigin[k].hel()[i] - m_hTrkInfit[k].hel()[i]) / sqrt(cov);
476 }
477 return n_pull;
478}
479
480double KalmanVertexFit::pullmomentum(const int k) {
481 double pull = 999.;
482 if(m_flag[k] == 1) return pull;
483
484 double kappa_origin = m_hTrkOrigin[k].kappa();
485 double kappa_infit = m_hTrkInfit[k].kappa();
486 double lamb_origin = m_hTrkOrigin[k].lambda();
487 double lamb_infit = m_hTrkInfit[k].lambda();
488
489 double Vkappa_origin = m_hTrkOrigin[k].eHel()[2][2];
490 double Vkappa_infit = m_hTrkInfit[k].eHel()[2][2];
491 double Vlamb_origin = m_hTrkOrigin[k].eHel()[4][4];
492 double Vlamb_infit = m_hTrkInfit[k].eHel()[4][4];
493 double V_kappa_lamb_origin = m_hTrkOrigin[k].eHel()[4][2];
494 double V_kappa_lamb_infit = m_hTrkInfit[k].eHel()[4][2];
495
496 double P_origin = calculationP(kappa_origin, lamb_origin);
497 //cout << "P_origin = " << P_origin << endl;
498 //P_origin = m_hTrkOrigin[k].p()[0] * m_hTrkOrigin[k].p()[0]
499 // + m_hTrkOrigin[k].p()[1] * m_hTrkOrigin[k].p()[1]
500 // + m_hTrkOrigin[k].p()[2] * m_hTrkOrigin[k].p()[2];
501 //cout << "P = " << P_origin << endl;
502 double P_infit = calculationP(kappa_infit, lamb_infit);
503
504 double SigmaP_origin = calculationSigmaP(kappa_origin, lamb_origin, Vkappa_origin,
505 Vlamb_origin, V_kappa_lamb_origin);
506 double SigmaP_infit = calculationSigmaP(kappa_infit, lamb_infit, Vkappa_infit,
507 Vlamb_infit, V_kappa_lamb_infit);
508 if ((SigmaP_origin - SigmaP_infit) <= 0.) return pull;
509 pull = (P_origin - P_infit) / sqrt (SigmaP_origin - SigmaP_infit);
510
511 return pull;
512}
513
514//====================== sub routine ==================================
515double KalmanVertexFit::calculationP(const double kappa, const double lamb) {
516 double P = 0.0;
517 P = sqrt(1 + lamb * lamb) / kappa;
518 //cout << "P in calculationP = " << P << endl;
519 return P;
520}
521
522double KalmanVertexFit::calculationSigmaP(const double kappa, const double lamb,
523 const double Vkappa, const double Vlamb,
524 const double Vkappa_lamb) {
525 double SigmaP = 0.0;
526 double dp_dkappa = -sqrt(1 + lamb*lamb) /kappa/kappa;
527 double dp_dlamb = lamb / kappa / sqrt(1 + lamb*lamb);
528 SigmaP = dp_dkappa * dp_dkappa * Vkappa + dp_dlamb * dp_dlamb * Vlamb
529 + 2 * dp_dkappa * dp_dlamb * Vkappa_lamb;
530 return SigmaP;
531}
double P(RecMdcKalTrack *trk)
double mass
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
Definition: KarLud.h:35
***************************************************************************************Pseudo Class RRes *****************************************************************************************Parameters and physical constants **Maarten sept ************************************************************************DOUBLE PRECISION xsmu **************************************************************************PARTICLE DATA all others are from PDG *Only resonances with known widths into electron pairs are sept ************************************************************************C Declarations C
Definition: RRes.h:29
EvtStreamInputIterator< typename Generator::result_type > iter(Generator gen, int N=0)
HepVector p() const
HepSymMatrix eHel() const
double pullmomentum(const int k)
HepSymMatrix Ex() const
void addTrack(const HTrackParameter)
int trackID(const int k) const
HTrackParameter hTrack(const int k) const
WTrackParameter wTrack(const int k, const double mass) const
VertexParameter vtx() const
std::vector< int > trackIDList() const
double chiS(const int k) const
void initVertex(const VertexParameter vtx)
HepVector x() const
int numTrack() const
HepVector pull(const int k)
static KalmanVertexFit * instance()
void inverse(const int k)
void remove(const int k)
HepSymMatrix Evx() const
HepVector Vx() const
void setEw(const HepSymMatrix &Ew)
void setCharge(const int charge)
void setW(const HepVector &w)
float charge