CbmRoot
Loading...
Searching...
No Matches
CaTrackExtender.cxx
Go to the documentation of this file.
1/* Copyright (C) 2010-2021 Frankfurt Institute for Advanced Studies, Goethe-Universität Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Igor Kulakov [committer], Maksym Zyzak, Valentina Akishina */
4
5#include "CaTrackExtender.h"
6
8#include "CaBranch.h"
9#include "CaDefines.h"
10#include "CaFramework.h"
11#include "CaGridArea.h"
12#include "CaInputData.h"
13#include "CaTrack.h"
14#include "CaUtils.h"
15#include "CaVector.h"
16#include "KfTrackKalmanFilter.h"
17#include "KfTrackParam.h"
18
19#include <iostream>
20
21
22namespace cbm::algo::ca
23{
24 // -------------------------------------------------------------------------------------------------------------------
25 //
27 : fParameters(pars)
28 , fSetup(fParameters.GetActiveSetup())
29 , fDefaultMass(mass)
30 {
31 }
32
33
34 // -------------------------------------------------------------------------------------------------------------------
35 //
37
38 // -------------------------------------------------------------------------------------------------------------------
39 //
40
42 const fvec qp0, const bool initParams)
43 {
44 CBMCA_DEBUG_ASSERT(t.NHits >= 3);
45
48 fit.SetMask(fmask::One());
49 fit.SetTrack(Tout);
50 TrackParamV& T = fit.Tr();
51
52 // get hits of current track
53 const Vector<ca::HitIndex_t>& hits = t.Hits(); // array of indeses of hits of current track
54 const int nHits = t.NofHits();
55
56 const signed short int step = (direction == kf::FitDirection::kUpstream ? -1 : 1); // increment for station index
57 const int iFirstHit = (direction == kf::FitDirection::kUpstream) ? nHits - 1 : 0;
58 const int iLastHit = (direction == kf::FitDirection::kUpstream) ? 0 : nHits - 1;
59
60 const ca::Hit& hit0 = frWData->Hit(hits[iFirstHit]);
61 const ca::Hit& hit1 = frWData->Hit(hits[iFirstHit + step]);
62 const ca::Hit& hit2 = frWData->Hit(hits[iFirstHit + 2 * step]);
63
64 int ista0 = hit0.Station();
65 int ista1 = hit1.Station();
66 int ista2 = hit2.Station();
67
68 const ca::Station<fvec>& sta0 = fParameters.GetStation(ista0);
69 const ca::Station<fvec>& sta1 = fParameters.GetStation(ista1);
70 const ca::Station<fvec>& sta2 = fParameters.GetStation(ista2);
71
72 fvec x0 = hit0.X();
73 fvec y0 = hit0.Y();
74 fvec z0 = hit0.Z();
75
76 fvec x1 = hit1.X();
77 fvec y1 = hit1.Y();
78 fvec z1 = hit1.Z();
79
80 fvec x2 = hit2.X();
81 fvec y2 = hit2.Y();
82
83 T.X() = x0;
84 T.Y() = y0;
85 if (initParams) {
86 fvec dzi = fvec(1.) / (z1 - z0);
87 T.Tx() = (x1 - x0) * dzi;
88 T.Ty() = (y1 - y0) * dzi;
89 T.Qp() = qp0;
90 }
91 fit.SetQp0(qp0);
92
93 T.Z() = z0;
94 T.Time() = hit0.T();
95 T.Vi() = 0.;
96
97 T.ResetErrors(1., 1., .1, .1, 1., (sta0.timeInfo ? hit0.dT2() : 1.e6), 1.e6);
98 T.Ndf() = fvec(2.);
99 T.NdfTime() = sta0.timeInfo ? fvec(-1.) : fvec(-2.);
100
101 T.C00() = hit0.dX2();
102 T.C10() = hit0.dXY();
103 T.C11() = hit0.dY2();
104
106 fvec fldZ0 = sta1.fZ; // suppose field is smoth
107 fvec fldZ1 = sta2.fZ;
108 fvec fldZ2 = sta0.fZ;
109
110
111 kf::FieldValue fldB0 = sta1.fieldSlice.GetFieldValue(x1, y1);
112 kf::FieldValue fldB1 = sta2.fieldSlice.GetFieldValue(x2, y2);
113 kf::FieldValue fldB2 = sta0.fieldSlice.GetFieldValue(x0, y0);
114
115 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
116
117 for (int i = iFirstHit + step; step * i <= step * iLastHit; i += step) {
118 const ca::Hit& hit = frWData->Hit(hits[i]);
119 int ista = hit.Station();
120 const ca::Station<fvec>& sta = fParameters.GetStation(ista);
121
122 fit.Extrapolate(hit.Z(), fld);
123 ca::utils::FilterHit(fit, hit, fmask(sta.timeInfo));
124 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(T.X(), T.Y());
125 fit.MultipleScattering(radThick);
126 fit.EnergyLossCorrection(radThick, direction);
127
128 fldB0 = fldB1;
129 fldB1 = fldB2;
130 fldZ0 = fldZ1;
131 fldZ1 = fldZ2;
132 fldB2 = sta.fieldSlice.GetFieldValue(hit.X(), hit.Y());
133 fldZ2 = sta.fZ;
134 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
135 } // i
136
137 Tout = T;
138 } // void ca::Framework::BranchFitterFast
139
141 void TrackExtender::FitBranch(const ca::Branch& t, TrackParamV& T, const kf::FitDirection direction, const fvec qp0,
142 const bool initParams)
143 {
144 FitBranchFast(t, T, direction, qp0, initParams);
145 for (int i = 0; i < 1; i++) {
146 FitBranchFast(t, T, !direction, T.Qp(), false);
147 FitBranchFast(t, T, direction, T.Qp(), false);
148 }
149 } // void ca::Framework::BranchFitter
150
151
152 void TrackExtender::FindMoreHits(ca::Branch& t, TrackParamV& Tout, const kf::FitDirection direction, const fvec qp0)
153 {
154 Vector<ca::HitIndex_t> newHits{"ca::TrackExtender::newHits"};
155 newHits.reserve(fParameters.GetNstationsActive());
156
159 fit.SetMask(fmask::One());
160 fit.SetTrack(Tout);
161 fit.SetQp0(qp0);
162
163 const signed short int step = (direction == kf::FitDirection::kUpstream) ? -1 : 1; // increment for station index
164 const int iFirstHit = (direction == kf::FitDirection::kUpstream) ? 2 : t.NofHits() - 3;
165 // int ista = fInputData->GetHit(t.Hits[iFirstHit]).iSt + 2 * step; // current station. set to the end of track
166
167 const ca::Hit& hit0 = frWData->Hit(t.Hits()[iFirstHit]); // optimize
168 const ca::Hit& hit1 = frWData->Hit(t.Hits()[iFirstHit + step]);
169 const ca::Hit& hit2 = frWData->Hit(t.Hits()[iFirstHit + 2 * step]);
170
171 const int ista0 = hit0.Station();
172 const int ista1 = hit1.Station();
173 const int ista2 = hit2.Station();
174
175 const ca::Station<fvec>& sta0 = fParameters.GetStation(ista0);
176 const ca::Station<fvec>& sta1 = fParameters.GetStation(ista1);
177 const ca::Station<fvec>& sta2 = fParameters.GetStation(ista2);
178
179 fvec x0 = hit0.X();
180 fvec y0 = hit0.Y();
181
182 fvec x1 = hit1.X();
183 fvec y1 = hit1.Y();
184
185 fvec x2 = hit2.X();
186 fvec y2 = hit2.Y();
187
189 fvec fldZ0 = sta1.fZ;
190 fvec fldZ1 = sta2.fZ;
191 fvec fldZ2 = sta0.fZ;
192
193 kf::FieldValue fldB0 = sta1.fieldSlice.GetFieldValue(x1, y1);
194 kf::FieldValue fldB1 = sta2.fieldSlice.GetFieldValue(x2, y2);
195 kf::FieldValue fldB2 = sta0.fieldSlice.GetFieldValue(x0, y0);
196
197 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
198
199 int ista = ista2 + 2 * step; // skip one station. if there would be hit it has to be found on previous stap
200
201 if (ista2 == frWData->CurrentIteration()->GetFirstStationIndex()) ista = ista2 + step;
202
203 const fscal pickGather = frWData->CurrentIteration()->GetPickGather();
204 const fvec pickGather2 = pickGather * pickGather;
205 const fvec maxDZ = frWData->CurrentIteration()->GetMaxDZ();
206 for (; (ista < fParameters.GetNstationsActive()) && (ista >= 0); ista += step) { // CHECKME why ista2?
207
208 const ca::Station<fvec>& sta = fParameters.GetStation(ista);
209
210 fit.Extrapolate(sta.fZ, fld);
211
212 fscal r2_best = 1e8; // best distance to hit
213 int iHit_best = -1; // index of the best hit
214
215 TrackParamV& tr = fit.Tr();
216
217 const auto& grid = frWData->Grid(ista);
218 ca::GridArea area(grid, tr.X()[0], tr.Y()[0],
219 (sqrt(pickGather * tr.C00()) + grid.GetMaxRangeX() + maxDZ * kf::utils::fabs(tr.Tx()))[0],
220 (sqrt(pickGather * tr.C11()) + grid.GetMaxRangeY() + maxDZ * kf::utils::fabs(tr.Ty()))[0]);
221
222 if (fParameters.DevIsIgnoreHitSearchAreas()) {
224 }
225
226 ca::HitIndex_t ih = 0;
227
228 while (area.GetNextObjectId(ih)) { // loop over the hits in the area
229
230 if (frWData->IsHitSuppressed(ih)) {
231 continue;
232 }
233 const ca::Hit& hit = frWData->Hit(ih);
234
235 if (sta.timeInfo && tr.NdfTime()[0] > -2.) {
236 fscal dt = hit.T() - tr.Time()[0];
237 if (fabs(dt) > sqrt(25. * tr.C55()[0]) + hit.RangeT()) continue;
238 }
239
240 //if (GetFUsed((*fStripFlag)[hit.f] | (*fStripFlag)[hit.b])) continue; // if used
241
242 if (frWData->IsHitKeyUsed(hit.FrontKey()) || frWData->IsHitKeyUsed(hit.BackKey())) {
243 continue;
244 }
245
246 auto [y, C11] = fit.ExtrapolateLineYdY2(hit.Z());
247
248 // fscal dym_est = ( fPickGather * sqrt(fabs(C11[0]+sta.XYInfo.C11[0])) );
249 // fscal y_minus_new = y[0] - dym_est;
250 // if (yh < y_minus_new) continue; // CHECKME take into account overlaping?
251
252 auto [x, C00] = fit.ExtrapolateLineXdX2(hit.Z());
253
254 fscal d_x = hit.X() - x[0];
255 fscal d_y = hit.Y() - y[0];
256 fscal d2 = d_x * d_x + d_y * d_y;
257 if (d2 > r2_best) continue;
258 fscal dxm_est = sqrt(pickGather2 * C00)[0] + grid.GetMaxRangeX();
259 if (fabs(d_x) > dxm_est) continue;
260
261 fscal dym_est = sqrt(pickGather2 * C11)[0] + grid.GetMaxRangeY();
262 if (fabs(d_y) > dym_est) continue;
263
264 r2_best = d2;
265 iHit_best = ih;
266 }
267
268 if (iHit_best < 0) break;
269
270
271 const ca::Hit& hit = frWData->Hit(iHit_best);
272 newHits.push_back(iHit_best);
273
274 fit.Extrapolate(hit.Z(), fld);
275 ca::utils::FilterHit(fit, hit, fmask(sta.timeInfo));
276 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(tr.X(), tr.Y());
277 fit.MultipleScattering(radThick);
278 fit.EnergyLossCorrection(radThick, direction);
279
280 fldB0 = fldB1;
281 fldB1 = fldB2;
282 fldZ0 = fldZ1;
283 fldZ1 = fldZ2;
284 fldB2 = sta.fieldSlice.GetFieldValue(hit.X(), hit.Y());
285 fldZ2 = sta.fZ;
286 fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0);
287 }
288
289 // save hits
290 const unsigned int NOldHits = t.NofHits();
291 const unsigned int NNewHits = newHits.size();
292 t.RefHits().enlarge(NNewHits + NOldHits);
293
294 if (direction == kf::FitDirection::kUpstream) {
295 for (int i = NOldHits - 1; i >= 0; i--) {
296 t.RefHits()[NNewHits + i] = t.RefHits()[i];
297 }
298 for (unsigned int i = 0, ii = NNewHits - 1; i < NNewHits; i++, ii--) {
299 t.RefHits()[i] = newHits[ii];
300 }
301 }
302 else { // downstream
303 for (unsigned int i = 0; i < newHits.size(); i++) {
304 t.RefHits()[NOldHits + i] = newHits[i];
305 }
306 }
307
308 Tout = fit.Tr();
309
310 } // void ca::Framework::FindMoreHits
311
314 {
315 frWData = &wData;
316 // const unsigned int minNHits = 3;
317
318 TrackParamV T;
319
320 // downstream
321
324
325 // upstream
326
327 FitBranchFast(t, T, kf::FitDirection::kUpstream, T.Qp(), false);
329
330 return T.GetChiSq()[0];
331 }
332} // namespace cbm::algo::ca
Macros for the CA tracking algorithm.
#define CBMCA_DEBUG_ASSERT(v)
Definition CaDefines.h:40
Structure for input data to the L1 tracking algorithm (declaration)
source file for the ca::Track class
Compile-time constants definition for the CA tracking algorithm.
static vector< vector< QAHit > > hits
friend fvec sqrt(const fvec &a)
Track fit utilities for the CA tracking based on the Kalman filter.
Vector< ca::HitIndex_t > & RefHits()
Definition CaBranch.h:41
const Vector< ca::HitIndex_t > & Hits() const
Definition CaBranch.h:39
int NofHits() const
Definition CaBranch.h:34
Class for accessing objects in the 2D area that are stored in ca::Grid.
Definition CaGridArea.h:17
bool GetNextObjectId(ca::HitIndex_t &objectId)
look up the next object id in the requested area
Definition CaGridArea.h:92
void DoLoopOverEntireGrid()
debug mode: loop over the entire GetEntries() vector ignoring the search area
Definition CaGridArea.h:103
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
HitKeyIndex_t BackKey() const
Get the back key index.
Definition CaHit.h:99
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 RangeT() const
Get the +/- range of uncertainty of time.
Definition CaHit.h:132
HitKeyIndex_t FrontKey() const
Get the front key index.
Definition CaHit.h:96
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
float GetPickGather() const
Gets size of region [TODO: units??] to attach new hits to the created track.
Definition CaIteration.h:97
float GetMaxDZ() const
Gets correction for accounting overlaping and iff z.
Definition CaIteration.h:76
int GetFirstStationIndex() const
Gets station index of the first station used in tracking.
Definition CaIteration.h:70
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
void FitBranch(const ca::Branch &t, TrackParamV &T, const kf::FitDirection direction, const fvec qp0, const bool initParams=true)
like BranchFitterFast but more precise
void FindMoreHits(ca::Branch &t, TrackParamV &T, const kf::FitDirection direction, const fvec qp0)
TrackExtender(const ca::Parameters< fvec > &pars, const fscal mass)
Default constructor.
void FitBranchFast(const ca::Branch &t, TrackParamV &T, const kf::FitDirection direction, const fvec qp0, const bool initParams=true)
const Parameters< fvec > & fParameters
Object of Framework parameters class.
fscal ExtendBranch(ca::Branch &t, WindowData &wData)
Try to extrapolate and find additional hits on other stations.
fscal fDefaultMass
mass of the propagated particle [GeV/c2]
const cbm::algo::kf::Setup< fvec > & fSetup
void enlarge(std::size_t count, Tinput... value)
Enlarges the vector to the new size.
Definition CaVector.h:133
void reserve(std::size_t count)
Reserves a new size for the vector.
Definition CaVector.h:162
Container for internal data, processed on a single time window.
ca::Grid & Grid(int iStation)
Gets grid for station index.
const Iteration * CurrentIteration() const
Accesses current iteration.
uint8_t IsHitSuppressed(int iHit) const
Gets hit suppression flag.
unsigned char IsHitKeyUsed(HitKeyIndex_t iKey) const
Hit key flag: if this hit or cluster was already used.
ca::Hit & Hit(int iHit)
Gets hit by index.
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 Set(const I &bx, const I &by, const I &bz)
Constructor from components.
void Extrapolate(DataT z, const kf::FieldRegion< DataT > &F)
std::pair< DataT, DataT > ExtrapolateLineYdY2(DataT z_out) const
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 EnergyLossCorrection(DataT radThick, FitDirection direction)
std::pair< DataT, DataT > ExtrapolateLineXdX2(DataT z_out) const
void SetParticleMass(DataT mass)
set particle mass for the fit
void SetTrack(const kf::TrackParam< T > &t)
T C00() const
Individual getters for covariance matrix elements.
T NdfTime() const
Gets NDF of time measurements.
T Tx() const
Gets slope along x-axis.
T X() const
Gets x position [cm].
T Y() const
Gets y position [cm].
T Time() const
Gets time [ns].
T Ty() const
Gets slope along y-axis.
static fmask One()
void FilterHit(kf::TrackKalmanFilter< T > &fit, const ca::Hit &hit, const kf::utils::masktype< T > &timeInfo)
Definition CaUtils.h:24
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
unsigned int HitIndex_t
Index of ca::Hit.
Definition CaHit.h:27
kf::fvec fvec
Definition CaSimd.h:13
fvec fabs(const fvec &v)
Definition KfUtils.h:30