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