CbmRoot
Loading...
Searching...
No Matches
CaTrackFitter.cxx
Go to the documentation of this file.
1/* Copyright (C) 2010-2020 Frankfurt Institute for Advanced Studies, Goethe-Universitaet Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Ivan Kisel, Sergey Gorbunov, Igor Kulakov [committer], Valentina Akishina, Maksym Zyzak */
4
5#include "CaTrackFitter.h"
6
7#include "CaFramework.h"
9#include "KfTrackParam.h"
10
11#include <iostream>
12#include <vector>
13
14
15namespace cbm::algo::ca
16{
17 // -------------------------------------------------------------------------------------------------------------------
18 //
20 : fParameters(pars)
21 , fSetup(fParameters.GetActiveSetup())
22 , fDefaultMass(mass)
23 , fTrackingMode(mode)
24 {
25 }
26
27 // -------------------------------------------------------------------------------------------------------------------
28 //
30
31 // -------------------------------------------------------------------------------------------------------------------
32 //
34 {
35 // LOG(info) << " Start CA Track Fitter ";
36 int start_hit = 0; // for interation in wData.RecoHitIndices()
37
38 // static kf::FieldValue fldB0, fldB1, fldB2 _fvecalignment;
39 // static kf::FieldRegion fld _fvecalignment;
40 kf::FieldValue<fvec> fldB0, fldB1, fldB2 _fvecalignment;
42
43
44 kf::FieldValue<fvec> fldB01, fldB11, fldB21 _fvecalignment;
46
47 const int nStations = fParameters.GetNstationsActive();
48 int nTracks_SIMD = fvec::size();
49
50 kf::TrackKalmanFilter<fvec> fit; // fit parameters coresponding to the current track
51 TrackParamV& tr = fit.Tr();
53 fit.SetDoFitVelocity(true);
54
55 Track* t[fvec::size()]{nullptr};
56
57 const ca::Station<fvec>* sta = fParameters.GetStations().begin();
58
59 // Spatial-time position of a hit vs. station and track in the portion
60
61 fvec x[constants::size::MaxNstations]; // Hit position along the x-axis [cm]
62 fvec y[constants::size::MaxNstations]; // Hit position along the y-axis [cm]
63 kf::MeasurementXy<fvec> mxy[constants::size::MaxNstations]; // Covariance matrix for x,y
64
65 fvec z[constants::size::MaxNstations]; // Hit position along the z-axis (precised) [cm]
66
67 fvec time[constants::size::MaxNstations]; // Hit time [ns]
68 fvec dt2[constants::size::MaxNstations]; // Hit time uncertainty [ns] squared
69
70 fvec x_first;
71 fvec y_first;
73
74 fvec time_first;
75 fvec wtime_first;
76 fvec dt2_first;
77
78 fvec x_last;
79 fvec y_last;
81
82 fvec time_last;
83 fvec wtime_last;
84 fvec dt2_last;
85
89
90 fvec y_temp;
91 fvec x_temp;
92 fvec fldZ0;
93 fvec fldZ1;
94 fvec fldZ2;
95 fvec z_start;
96 fvec z_end;
97
99
100
102 for (int ista = 0; ista < nStations; ista++) {
103 ZSta[ista] = sta[ista].fZ;
104 mxy[ista].SetCov(1., 0., 1.);
105 }
106
107 unsigned short N_vTracks = wData.RecoTracks().size(); // number of tracks processed per one SSE register
108
109 for (unsigned short itrack = 0; itrack < N_vTracks; itrack += fvec::size()) {
110
111 if (N_vTracks - itrack < static_cast<unsigned short>(fvec::size())) nTracks_SIMD = N_vTracks - itrack;
112
113 for (int i = 0; i < nTracks_SIMD; i++) {
114 t[i] = &wData.RecoTrack(itrack + i);
115 }
116
117 // fill the rest of the SIMD vectors with something reasonable
118 for (uint i = nTracks_SIMD; i < fvec::size(); i++) {
119 t[i] = &wData.RecoTrack(itrack);
120 }
121
122 // get hits of current track
123 for (int ista = 0; ista < nStations; ista++) {
124 w[ista] = fmask::Zero();
125 w_time[ista] = fmask::Zero();
126 z[ista] = ZSta[ista];
127 }
128
129 //fmask isFieldPresent = fmask::Zero();
130
131 for (int iVec = 0; iVec < nTracks_SIMD; iVec++) {
132
133 int nHitsTrack = t[iVec]->fNofHits;
135
136 for (int ih = 0; ih < nHitsTrack; ih++) {
137
138 const ca::Hit& hit = input.GetHit(wData.RecoHitIndex(start_hit++));
139 const int ista = hit.Station();
140
141 //if (sta[ista].fieldStatus) { isFieldPresent[iVec] = true; }
142
143 iSta[ih] = ista;
144 w[ista][iVec] = true;
145 if (sta[ista].timeInfo) {
146 w_time[ista][iVec] = true;
147 }
148
149 x[ista][iVec] = hit.X(); //x_temp[iVec];
150 y[ista][iVec] = hit.Y(); //y_temp[iVec];
151 time[ista][iVec] = hit.T();
152 dt2[ista][iVec] = hit.dT2();
153 if (!sta[ista].timeInfo) {
154 dt2[ista][iVec] = 1.e4;
155 }
156 z[ista][iVec] = hit.Z();
157 fB_temp = sta[ista].fieldSlice.GetFieldValue(x[ista], y[ista]);
158 mxy[ista].X()[iVec] = hit.X();
159 mxy[ista].Y()[iVec] = hit.Y();
160 mxy[ista].Dx2()[iVec] = hit.dX2();
161 mxy[ista].Dy2()[iVec] = hit.dY2();
162 mxy[ista].Dxy()[iVec] = hit.dXY();
163 mxy[ista].NdfX()[iVec] = 1.;
164 mxy[ista].NdfY()[iVec] = 1.;
165
166 fB[ista].SetSimdEntry(fB_temp.GetBx()[iVec], fB_temp.GetBy()[iVec], fB_temp.GetBz()[iVec], iVec);
167
168 if (ih == 0) {
169 z_start[iVec] = z[ista][iVec];
170 x_first[iVec] = x[ista][iVec];
171 y_first[iVec] = y[ista][iVec];
172 time_first[iVec] = time[ista][iVec];
173 wtime_first[iVec] = sta[ista].timeInfo ? 1. : 0.;
174 dt2_first[iVec] = dt2[ista][iVec];
175 mxy_first.X()[iVec] = mxy[ista].X()[iVec];
176 mxy_first.Y()[iVec] = mxy[ista].Y()[iVec];
177 mxy_first.Dx2()[iVec] = mxy[ista].Dx2()[iVec];
178 mxy_first.Dy2()[iVec] = mxy[ista].Dy2()[iVec];
179 mxy_first.Dxy()[iVec] = mxy[ista].Dxy()[iVec];
180 mxy_first.NdfX()[iVec] = mxy[ista].NdfX()[iVec];
181 mxy_first.NdfY()[iVec] = mxy[ista].NdfY()[iVec];
182 }
183 else if (ih == nHitsTrack - 1) {
184 z_end[iVec] = z[ista][iVec];
185 x_last[iVec] = x[ista][iVec];
186 y_last[iVec] = y[ista][iVec];
187 mxy_last.X()[iVec] = mxy[ista].X()[iVec];
188 mxy_last.Y()[iVec] = mxy[ista].Y()[iVec];
189 mxy_last.Dx2()[iVec] = mxy[ista].Dx2()[iVec];
190 mxy_last.Dy2()[iVec] = mxy[ista].Dy2()[iVec];
191 mxy_last.Dxy()[iVec] = mxy[ista].Dxy()[iVec];
192 mxy_last.NdfX()[iVec] = mxy[ista].NdfX()[iVec];
193 mxy_last.NdfY()[iVec] = mxy[ista].NdfY()[iVec];
194 time_last[iVec] = time[ista][iVec];
195 dt2_last[iVec] = dt2[ista][iVec];
196 wtime_last[iVec] = sta[ista].timeInfo ? 1. : 0.;
197 }
198 }
199
200 for (int ih = nHitsTrack - 1; ih >= 0; ih--) {
201 const int ista = iSta[ih];
202 const ca::Station<fvec>& st = fParameters.GetStation(ista);
203 By[ista][iVec] = st.fieldSlice.GetFieldValue(0., 0.).GetBy()[0];
204 }
205 }
206
207 fit.GuessTrack(z_end, x, y, z, time, By, w, w_time, nStations);
208
210 tr.Qp() = fvec(1. / 1.1);
211 }
212
213 // tr.Qp() = iif(isFieldPresent, tr.Qp(), fvec(1. / 0.25));
214
215 for (int iter = 0; iter < 2; iter++) { // 1.5 iterations
216
217 fit.SetQp0(tr.Qp());
218
219 // fit backward
220
221 int ista = nStations - 1;
222
223 time_last = iif(w_time[ista], time_last, fvec::Zero());
224 dt2_last = iif(w_time[ista], dt2_last, fvec(1.e6));
225
226 tr.ResetErrors(mxy_last.Dx2(), mxy_last.Dy2(), 0.1, 0.1, 1.0, dt2_last, 1.e-2);
227 tr.C10() = mxy_last.Dxy();
228 tr.X() = mxy_last.X();
229 tr.Y() = mxy_last.Y();
230 tr.Time() = time_last;
232 tr.InitVelocityRange(0.5);
233 tr.Ndf() = fvec(-5.) + fvec(2.);
234 tr.NdfTime() = fvec(-2.) + wtime_last;
235
236 fldZ1 = z[ista];
237
238 fldB1 = sta[ista].fieldSlice.GetFieldValue(tr.X(), tr.Y());
239
240 fldB1.SetSimdEntries(fB[ista], w[ista]);
241
242 fldZ2 = z[ista - 2];
243 fvec dz = fldZ2 - fldZ1;
244 fldB2 = sta[ista].fieldSlice.GetFieldValue(tr.X() + tr.Tx() * dz, tr.Y() + tr.Ty() * dz);
245 fldB2.SetSimdEntries(fB[ista - 2], w[ista - 2]);
246 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
247
248 for (--ista; ista >= 0; ista--) {
249
250 fldZ0 = z[ista];
251 dz = (fldZ1 - fldZ0);
252 fldB0 = sta[ista].fieldSlice.GetFieldValue(tr.X() - tr.Tx() * dz, tr.Y() - tr.Ty() * dz);
253 fldB0.SetSimdEntries(fB[ista], w[ista]);
254 fld.Set(fldB0, fldZ0, fldB1, fldZ1, fldB2, fldZ2);
255
256 fmask initialised = (z[ista] < z_end) & (z_start <= z[ista]);
257
258 fld1 = fld;
259
260 fit.SetMask(initialised);
261 fit.Extrapolate(z[ista], fld1);
262 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(tr.X(), tr.Y());
263 fit.MultipleScattering(radThick);
265
266 fit.SetMask(initialised && w[ista]);
267 fit.FilterXY(mxy[ista]);
268 fit.FilterTime(time[ista], dt2[ista], fmask(sta[ista].timeInfo));
269
270
271 fldB2 = fldB1;
272 fldZ2 = fldZ1;
273 fldB1 = fldB0;
274 fldZ1 = fldZ0;
275 }
276
277 // extrapolate to the PV region
278
279 kf::TrackKalmanFilter fitpv = fit;
280 {
281 fitpv.SetMask(fmask::One());
282
284 vtxInfo.SetDx2(1.e-8);
285 vtxInfo.SetDxy(0.);
286 vtxInfo.SetDy2(1.e-8);
287
290 fitpv.SetMaxExtrapolationStep(1.);
291 for (int vtxIter = 0; vtxIter < 2; vtxIter++) {
292 fitpv.SetQp0(fitpv.Tr().Qp());
293 fitpv.Tr() = fit.Tr();
294 fitpv.Tr().Qp() = fitpv.Qp0();
295 fitpv.Extrapolate(fParameters.GetTargetPositionZ(), fldFull);
296 fitpv.FilterXY(vtxInfo);
297 }
298 }
299 else {
300 fitpv.SetQp0(fitpv.Tr().Qp());
301 fitpv.Extrapolate(fParameters.GetTargetPositionZ(), fld);
302 }
303 }
304
305 //fit.SetQp0(tr.Qp());
306 //fit.SetMask(fmask::One());
307 //fit.MeasureVelocityWithQp();
308 //fit.FilterVi(TrackParamV::kClightNsInv);
309
310 TrackParamV Tf = fit.Tr();
312 Tf.Qp() = fitpv.Tr().Qp();
313 }
314
315 for (int iVec = 0; iVec < nTracks_SIMD; iVec++) {
316 t[iVec]->fParFirst.Set(Tf, iVec);
317 }
318
319 for (int iVec = 0; iVec < nTracks_SIMD; iVec++) {
320 t[iVec]->fParPV.Set(fitpv.Tr(), iVec);
321 }
322
323 if (iter == 1) {
324 break;
325 } // only 1.5 iterations
326
327 // fit forward
328
329 ista = 0;
330
331 tr.ResetErrors(mxy_first.Dx2(), mxy_first.Dy2(), 0.1, 0.1, 1., dt2_first, 1.e-2);
332 tr.C10() = mxy_first.Dxy();
333
334 tr.X() = mxy_first.X();
335 tr.Y() = mxy_first.Y();
336 tr.Time() = time_first;
338 tr.InitVelocityRange(0.5);
339
340 tr.Ndf() = fvec(-5. + 2.);
341 tr.NdfTime() = fvec(-2.) + wtime_first;
342
343 fit.SetQp0(tr.Qp());
344
345 fldZ1 = z[ista];
346 fldB1 = sta[ista].fieldSlice.GetFieldValue(tr.X(), tr.Y());
347 fldB1.SetSimdEntries(fB[ista], w[ista]);
348
349 fldZ2 = z[ista + 2];
350 dz = fldZ2 - fldZ1;
351 fldB2 = sta[ista].fieldSlice.GetFieldValue(tr.X() + tr.Tx() * dz, tr.Y() + tr.Ty() * dz);
352 fldB2.SetSimdEntries(fB[ista + 2], w[ista + 2]);
353 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
354
355 for (++ista; ista < nStations; ista++) {
356 fldZ0 = z[ista];
357 dz = (fldZ1 - fldZ0);
358 fldB0 = sta[ista].fieldSlice.GetFieldValue(tr.X() - tr.Tx() * dz, tr.Y() - tr.Ty() * dz);
359 fldB0.SetSimdEntries(fB[ista], w[ista]);
360 fld.Set(fldB0, fldZ0, fldB1, fldZ1, fldB2, fldZ2);
361
362 fmask initialised = (z[ista] <= z_end) & (z_start < z[ista]);
363
364 fit.SetMask(initialised);
365 fit.Extrapolate(z[ista], fld);
366 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(tr.X(), tr.Y());
367 fit.MultipleScattering(radThick);
369 fit.SetMask(initialised && w[ista]);
370 fit.FilterXY(mxy[ista]);
371 fit.FilterTime(time[ista], dt2[ista], fmask(sta[ista].timeInfo));
372
373 fldB2 = fldB1;
374 fldZ2 = fldZ1;
375 fldB1 = fldB0;
376 fldZ1 = fldZ0;
377 }
378
379 //fit.SetQp0(tr.Qp());
380 //fit.SetMask(fmask::One());
381 //fit.MeasureVelocityWithQp();
382 //fit.FilterVi(TrackParamV::kClightNsInv);
383
384 TrackParamV Tl = fit.Tr();
386 Tl.Qp() = fitpv.Tr().Qp();
387 }
388
389 for (int iVec = 0; iVec < nTracks_SIMD; iVec++) {
390 t[iVec]->fParLast.Set(Tl, iVec);
391 }
392
393 } // iter
394 }
395 }
396} // namespace cbm::algo::ca
friend fvec iif(fmask a, fvec b, fvec c)
Track fit utilities for the CA tracking based on the Kalman filter.
ca::Hit class describes a generic hit for the CA tracker
Definition CaHit.h:32
fscal Z() const
Get the Z coordinate.
Definition CaHit.h:108
fscal dT2() const
Get the uncertainty of time.
Definition CaHit.h:123
fscal dXY() const
Get the X/Y covariance.
Definition CaHit.h:120
fscal dX2() const
Get the uncertainty of X coordinate.
Definition CaHit.h:114
fscal Y() const
Get the Y coordinate.
Definition CaHit.h:105
fscal T() const
Get the time.
Definition CaHit.h:111
fscal X() const
Get the X coordinate.
Definition CaHit.h:102
int Station() const
Get the station index.
Definition CaHit.h:138
fscal dY2() const
Get the uncertainty of Y coordinate.
Definition CaHit.h:117
const Hit & GetHit(HitIndex_t index) const
Gets reference to hit by its index.
Definition CaInputData.h:55
A container for all external parameters of the CA tracking algorithm.
DataT fZ
z position of station [cm]
Definition CaStation.h:29
int timeInfo
flag: if time information can be used
Definition CaStation.h:25
kf::FieldSlice< DataT > fieldSlice
Magnetic field near the station.
Definition CaStation.h:33
ca::TrackingMode fTrackingMode
TrackFitter(const ca::Parameters< fvec > &pars, const fscal mass, const ca::TrackingMode &mode)
Default constructor.
void FitCaTracks(const ca::InputData &input, WindowData &wData)
Fit tracks, found by the CA tracker.
const Parameters< fvec > & fParameters
Object of Framework parameters class.
fscal fDefaultMass
mass of the propagated particle [GeV/c2]
const cbm::algo::kf::Setup< fvec > & fSetup
Setup instance.
Class representing an output track in the CA tracking algorithm.
Container for internal data, processed on a single time window.
Track & RecoTrack(int iTrack)
Accesses reconstructed track by index.
Vector< Track > & RecoTracks()
Accesses reconstructed track container.
HitIndex_t & RecoHitIndex(int iHit)
Accesses index of hit in the input data.
kf::MeasurementXy< fvec > & TargetMeasurement()
Measurement of the target with the uncertainty.
Magnetic field region, corresponding to a hit triplet.
constexpr FieldValue< T > GetFieldValue(const T &x, const T &y) const
Gets field value at a point on the transverse plane.
Magnetic flux density vector.
void SetSimdEntries(const FieldValue &other, const kf::utils::masktype< T > &mask)
Combines the current magnetic field value with another one using a mask.
T GetBy() const
Gets magnetic flux density y-component [kG].
void SetSimdEntry(double bx, double by, double bz, size_t i)
Sets magnetic flux density components to the field function.
static EFieldType fgOriginalFieldType
Global field type.
static FieldFn_t fgOriginalField
Global variable to store the fielf funciton (x,y,z)->(Bx,By,Bz)
The class describes a 2D - measurement (x, y) in XY coordinate system.
void SetCov(DataT dx2, DataT dxy, DataT dy2)
void Extrapolate(DataT z, const kf::FieldRegion< DataT > &F)
void FilterXY(const kf::MeasurementXy< DataT > &m, bool skipUnmeasuredCoordinates=false)
filter the track with the XY measurement
kf::TrackParam< DataT > & Tr()
void MultipleScattering(DataT radThick, DataT tx0, DataT ty0, DataT qp0)
apply multiple scattering correction to the track with the given Qp0
void GuessTrack(const DataT &trackZ, const DataT hitX[], const DataT hitY[], const DataT hitZ[], const DataT hitT[], const DataT By[], const DataTmask hitW[], const DataTmask hitWtime[], int NHits)
fast guess of track parameterts based on its hits
void EnergyLossCorrection(DataT radThick, FitDirection direction)
void FilterTime(DataT t, DataT dt2, const DataTmask &m)
filter the track with the time measurement
void SetParticleMass(DataT mass)
set particle mass for the fit
void SetMaxExtrapolationStep(double step)
set max extrapolation step [cm]
T Ndf() const
Gets NDF of track fit model.
T Vi() const
Gets inverse velocity [ns/cm].
T NdfTime() const
Gets NDF of time measurements.
void ResetErrors(T c00, T c11, T c22, T c33, T c44, T c55, T c66)
Resets variances of track parameters and chi2, ndf values.
T Tx() const
Gets slope along x-axis.
T X() const
Gets x position [cm].
T Y() const
Gets y position [cm].
T Qp() const
Gets charge over momentum [ec/GeV].
void InitVelocityRange(fscal minP)
Initializes inverse velocity range.
T Time() const
Gets time [ns].
T Ty() const
Gets slope along y-axis.
static fmask Zero()
static fmask One()
static constexpr size_t size()
static fvec Zero()
constexpr fscal SpeedOfLightInv
Inverse speed of light [ns/cm].
Definition CaDefs.h:89
constexpr int MaxNstations
Max number of stations, 2^6 = 64.
Definition CaDefs.h:44
TODO: SZh 8.11.2022: add selection of parameterisation.
Definition CaBranch.h:14
class cbm::algo::ca::WindowData _fvecalignment
kf::fscal fscal
Definition CaSimd.h:14
kf::fmask fmask
Definition CaSimd.h:15
kf::fvec fvec
Definition CaSimd.h:13