CbmRoot
Loading...
Searching...
No Matches
CbmKFPrimaryVertexFinder.cxx
Go to the documentation of this file.
1/* Copyright (C) 2006-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergey Gorbunov, Alex Bercuci, Ivan Kisel, Denis Bertini [committer] */
4
13
14#include "CbmKF.h"
15#include "CbmKFTrack.h"
16
17#include <vector>
18
19using std::vector;
20
22
23 void CbmKFPrimaryVertexFinder::Clear(Option_t* /*opt*/)
24{
25 Tracks.clear();
26}
27
29{
30 Tracks.push_back(std::make_tuple(Track, idx, true));
31}
32
33void CbmKFPrimaryVertexFinder::SetTracks(vector<CbmKFTrackInterface*>& vTr)
34{
35 for (auto& trk : vTr)
36 Tracks.push_back(std::make_tuple(trk, -1, true));
37}
38
40{
41 //* Constants
42 const Double_t CutChi2 = 3.5 * 3.5;
43 const Int_t MaxIter = 3;
44
45 //* Vertex state vector and the covariance matrix
46
47 Double_t r[3], *C = vtx.GetCovMatrix();
48
49 //* Initialize the vertex
50
51 for (Int_t i = 0; i < 6; i++) {
52 C[i] = 0;
53 }
54
55 if (CbmKF::Instance()->vTargets.empty()) {
56 r[0] = r[1] = r[2] = 0.;
57 C[0] = C[2] = 5.;
58 C[5] = 0.25;
59 }
60 else {
62 r[0] = r[1] = 0.;
63 r[2] = t.z;
64 C[0] = C[2] = t.RR / 3.5 / 3.5;
65 C[5] = (t.dz / 2 / 3.5) * (t.dz / 2 / 3.5);
66 }
67
68 int fitIterSuccess = 0; // no. of successful calculations of the vertex position out of requested MaxIter.
69 //* Iteratively fit vertex - number of iterations fixed at MaxIter
70 for (Int_t iteration = 0; iteration < MaxIter; ++iteration) {
71
72 //* Store vertex from previous iteration
73
74 Double_t r0[3], C0[6];
75
76 for (Int_t i = 0; i < 3; i++) {
77 r0[i] = r[i];
78 }
79 for (Int_t i = 0; i < 6; i++) {
80 C0[i] = C[i];
81 }
82
83 //* Initialize the vertex covariance, Chi^2 & NDF
84
85 C[0] = 100.;
86 C[1] = 0.;
87 C[2] = 100.;
88 C[3] = 0.;
89 C[4] = 0.;
90 C[5] = 100.;
91
92 vtx.GetRefNDF() = -3;
93 vtx.GetRefChi2() = 0.;
94 vtx.GetRefNTracks() = 0;
95 for (auto& trk : Tracks) {
96 // convert track to internal KF representation and reset used flag
97 auto itr = std::get<0>(trk);
98 std::get<2>(trk) = true;
99 CbmKFTrack T(*itr);
100
101 Bool_t err = T.Extrapolate(r0[2]);
102 if (err) {
103 std::get<2>(trk) = false;
104 continue;
105 }
106
107 Double_t* m = T.GetTrack();
108 Double_t* V = T.GetCovMatrix();
109 Double_t a = 0, b = 0;
110 {
111 Double_t zeta[2] = {r0[0] - m[0], r0[1] - m[1]};
112
113 //* Check track Chi^2 deviation from the r0 vertex estimate
114
115 Double_t S[3] = {(C0[2] + V[2]), -(C0[1] + V[1]), (C0[0] + V[0])};
116 Double_t s = S[2] * S[0] - S[1] * S[1];
117 Double_t chi2 = zeta[0] * zeta[0] * S[0] + 2 * zeta[0] * zeta[1] * S[1] + zeta[1] * zeta[1] * S[2];
118 if (chi2 > s * CutChi2) {
119 std::get<2>(trk) = false;
120 continue;
121 }
122 //* Fit of vertex track slopes (a,b) to r0 vertex
123
124 s = V[0] * V[2] - V[1] * V[1];
125 if (s < 1.E-20) {
126 std::get<2>(trk) = false;
127 continue;
128 }
129 s = 1. / s;
130 a = m[2] + s * ((V[3] * V[2] - V[4] * V[1]) * zeta[0] + (-V[3] * V[1] + V[4] * V[0]) * zeta[1]);
131 b = m[3] + s * ((V[6] * V[2] - V[7] * V[1]) * zeta[0] + (-V[6] * V[1] + V[7] * V[0]) * zeta[1]);
132 }
133
134 //** Update the vertex (r,C) with the track estimate (m,V) :
135
136 //* Linearized measurement matrix H = { { 1, 0, -a}, { 0, 1, -b} };
137
138 //* Residual (measured - estimated)
139
140 Double_t zeta[2] = {m[0] - (r[0] - a * (r[2] - r0[2])), m[1] - (r[1] - b * (r[2] - r0[2]))};
141
142 //* CHt = CH'
143
144 Double_t CHt[3][2] = {{C[0] - a * C[3], C[1] - b * C[3]},
145 {C[1] - a * C[4], C[2] - b * C[4]},
146 {C[3] - a * C[5], C[4] - b * C[5]}};
147
148 //* S = (H*C*H' + V )^{-1}
149
150 Double_t S[3] = {V[0] + CHt[0][0] - a * CHt[2][0], V[1] + CHt[1][0] - b * CHt[2][0],
151 V[2] + CHt[1][1] - b * CHt[2][1]};
152
153 //* Invert S
154 {
155 Double_t w = S[0] * S[2] - S[1] * S[1];
156 if (w < 1.E-200) {
157 std::get<2>(trk) = false;
158 continue;
159 }
160 w = 1. / w;
161 Double_t S0 = S[0];
162 S[0] = w * S[2];
163 S[1] = -w * S[1];
164 S[2] = w * S0;
165 }
166
167 //* Calculate Chi^2
168
169 vtx.GetRefChi2() +=
170 zeta[0] * zeta[0] * S[0] + 2 * zeta[0] * zeta[1] * S[1] + zeta[1] * zeta[1] * S[2] + T.GetRefChi2();
171 vtx.GetRefNDF() += 2 + T.GetRefNDF();
172 vtx.GetRefNTracks()++;
173
174 //* Kalman gain K = CH'*S
175
176 Double_t K[3][2];
177
178 for (Int_t i = 0; i < 3; ++i) {
179 K[i][0] = CHt[i][0] * S[0] + CHt[i][1] * S[1];
180 K[i][1] = CHt[i][0] * S[1] + CHt[i][1] * S[2];
181 }
182
183 //* New estimation of the vertex position r += K*zeta
184
185 for (Int_t i = 0; i < 3; ++i) {
186 r[i] += K[i][0] * zeta[0] + K[i][1] * zeta[1];
187 }
188
189 //* New covariance matrix C -= K*(CH')'
190
191 C[0] -= K[0][0] * CHt[0][0] + K[0][1] * CHt[0][1];
192 C[1] -= K[1][0] * CHt[0][0] + K[1][1] * CHt[0][1];
193 C[2] -= K[1][0] * CHt[1][0] + K[1][1] * CHt[1][1];
194 C[3] -= K[2][0] * CHt[0][0] + K[2][1] * CHt[0][1];
195 C[4] -= K[2][0] * CHt[1][0] + K[2][1] * CHt[1][1];
196 C[5] -= K[2][0] * CHt[2][0] + K[2][1] * CHt[2][1];
197 } //* itr
198 if (vtx.GetRefNTracks()) fitIterSuccess++; // mark success of this iteration for vertex calculation
199 } //* finished iterations
200
201 //* Copy state vector to output (covariance matrix was used directly )
202 if (fitIterSuccess) { // store successful PV calculation. May include also a reference to MaxIter (AB 17.10.2024)
203 vtx.GetRefX() = r[0];
204 vtx.GetRefY() = r[1];
205 vtx.GetRefZ() = r[2];
206 }
207 else {
208 vtx.GetRefX() = -999;
209 vtx.GetRefY() = -999;
210 vtx.GetRefZ() = -999;
211 }
212}
213
214int CbmKFPrimaryVertexFinder::GetUsedTracks(std::vector<uint32_t>& idx) const
215{
216 idx.clear();
217 for (auto& trk : Tracks) {
218 if (!std::get<2>(trk)) continue;
219 if (std::get<1>(trk) < 0) continue;
220 idx.push_back(std::get<1>(trk));
221 }
222 return (int) idx.size();
223}
ClassImp(CbmKFPrimaryVertexFinder) void CbmKFPrimaryVertexFinder
int GetUsedTracks(std::vector< uint32_t > &idx) const
void SetTracks(std::vector< CbmKFTrackInterface * > &vTracks)
void AddTrack(CbmKFTrackInterface *Track, int32_t idx=-1)
virtual void Clear(Option_t *opt="")
std::vector< std::tuple< CbmKFTrackInterface *, int32_t, bool > > Tracks
void Fit(CbmKFVertexInterface &vtx)
Double_t RR
Double_t dz
Double_t z
virtual Double_t & GetRefY()
virtual Double_t & GetRefX()
virtual Int_t & GetRefNTracks()
Number of Degrees of Freedom after fit.
virtual Double_t & GetRefZ()
virtual Double_t & GetRefChi2()
Array[6] of covariance matrix.
virtual Int_t & GetRefNDF()
Chi^2 after fit.
virtual Double_t * GetCovMatrix()
static CbmKF * Instance()
Definition CbmKF.h:40
std::vector< CbmKFTube > vTargets
Definition CbmKF.h:71