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-Universitaet 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 , fField(fSetup.GetField())
30 , fDefaultMass(mass)
31 {
32 }
33
34
35 // -------------------------------------------------------------------------------------------------------------------
36 //
38
39 // -------------------------------------------------------------------------------------------------------------------
40 //
41
43 const fvec qp0, const bool initParams)
44 {
45 CBMCA_DEBUG_ASSERT(t.NHits >= 3);
46
49 fit.SetMask(fmask::One());
50 fit.SetTrack(Tout);
51 TrackParamV& T = fit.Tr();
52
53 // get hits of current track
54 const Vector<ca::HitIndex_t>& hits = t.Hits(); // array of indeses of hits of current track
55 const int nHits = t.NofHits();
56
57 const signed short int step = (direction == kf::FitDirection::kUpstream ? -1 : 1); // increment for station index
58 const int iFirstHit = (direction == kf::FitDirection::kUpstream) ? nHits - 1 : 0;
59 const int iLastHit = (direction == kf::FitDirection::kUpstream) ? 0 : nHits - 1;
60
61 const ca::Hit& hit0 = frWData->Hit(hits[iFirstHit]);
62 const ca::Hit& hit1 = frWData->Hit(hits[iFirstHit + step]);
63 const ca::Hit& hit2 = frWData->Hit(hits[iFirstHit + 2 * step]);
64
65 int ista0 = hit0.Station();
66 int ista1 = hit1.Station();
67 int ista2 = hit2.Station();
68
69
70 fvec x0 = hit0.X();
71 fvec y0 = hit0.Y();
72 fvec z0 = hit0.Z();
73
74 fvec x1 = hit1.X();
75 fvec y1 = hit1.Y();
76 fvec z1 = hit1.Z();
77
78 fvec x2 = hit2.X();
79 fvec y2 = hit2.Y();
80
81 T.X() = x0;
82 T.Y() = y0;
83 if (initParams) {
84 fvec dzi = fvec(1.) / (z1 - z0);
85 T.Tx() = (x1 - x0) * dzi;
86 T.Ty() = (y1 - y0) * dzi;
87 T.Qp() = qp0;
88 }
89 fit.Linearization().qp = qp0;
90
91 T.Z() = z0;
92 T.Time() = hit0.T();
93 T.Vi() = 0.;
94
95 const auto& sta0 = fSetup.GetActiveLayer(ista0);
96 T.ResetErrors(1., 1., .1, .1, 1., (sta0.IsTimeMeasured() ? hit0.dT2() : 1.e6), 1.e6);
97 T.Ndf() = fvec(2.);
98 T.NdfTime() = sta0.IsTimeMeasured() ? fvec(-1.) : fvec(-2.);
99
100 T.C00() = hit0.dX2();
101 T.C10() = hit0.dXY();
102 T.C11() = hit0.dY2();
103
105
106 kf::FieldValue fldB0 = fField.GetFieldValue(ista1, x1, y1);
107 kf::FieldValue fldB1 = fField.GetFieldValue(ista2, x2, y2);
108 kf::FieldValue fldB2 = fField.GetFieldValue(ista0, x0, y0);
109
110 fld.Set(fldB2, fldB1, fldB0);
111
112 for (int i = iFirstHit + step; step * i <= step * iLastHit; i += step) {
113 const ca::Hit& hit = frWData->Hit(hits[i]);
114 int ista = hit.Station();
115 const auto& sta = fSetup.GetActiveLayer(ista);
116
117 fit.Extrapolate(hit.Z(), fld);
118 ca::utils::FilterHit(fit, hit, fmask(sta.IsTimeMeasured()));
119 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(T.X(), T.Y());
120 fit.MultipleScattering(radThick);
121 fit.EnergyLossCorrection(radThick, direction);
122
123 fldB0 = fldB1;
124 fldB1 = fldB2;
125 fldB2 = fField.GetFieldValue(ista, hit.X(), hit.Y());
126 fld.Set(fldB2, fldB1, fldB0);
127 } // i
128
129 Tout = T;
130 } // void ca::Framework::BranchFitterFast
131
133 void TrackExtender::FitBranch(const ca::Branch& t, TrackParamV& T, const kf::FitDirection direction, const fvec qp0,
134 const bool initParams)
135 {
136 FitBranchFast(t, T, direction, qp0, initParams);
137 for (int i = 0; i < 1; i++) {
138 FitBranchFast(t, T, !direction, T.Qp(), false);
139 FitBranchFast(t, T, direction, T.Qp(), false);
140 }
141 } // void ca::Framework::BranchFitter
142
143
144 void TrackExtender::FindMoreHits(ca::Branch& t, TrackParamV& Tout, const kf::FitDirection direction, const fvec qp0)
145 {
146 Vector<ca::HitIndex_t> newHits{"ca::TrackExtender::newHits"};
147 newHits.reserve(fParameters.GetNstationsActive());
148
151 fit.SetMask(fmask::One());
152 fit.SetTrack(Tout);
153 fit.Linearization().qp = qp0;
154
155 const signed short int step = (direction == kf::FitDirection::kUpstream) ? -1 : 1; // increment for station index
156 const int iFirstHit = (direction == kf::FitDirection::kUpstream) ? 2 : t.NofHits() - 3;
157 // int ista = fInputData->GetHit(t.Hits[iFirstHit]).iSt + 2 * step; // current station. set to the end of track
158
159 const ca::Hit& hit0 = frWData->Hit(t.Hits()[iFirstHit]); // optimize
160 const ca::Hit& hit1 = frWData->Hit(t.Hits()[iFirstHit + step]);
161 const ca::Hit& hit2 = frWData->Hit(t.Hits()[iFirstHit + 2 * step]);
162
163 const int ista0 = hit0.Station();
164 const int ista1 = hit1.Station();
165 const int ista2 = hit2.Station();
166
167 fvec x0 = hit0.X();
168 fvec y0 = hit0.Y();
169
170 fvec x1 = hit1.X();
171 fvec y1 = hit1.Y();
172
173 fvec x2 = hit2.X();
174 fvec y2 = hit2.Y();
175
177 kf::FieldValue fldB0 = fField.GetFieldValue(ista1, x1, y1);
178 kf::FieldValue fldB1 = fField.GetFieldValue(ista2, x2, y2);
179 kf::FieldValue fldB2 = fField.GetFieldValue(ista0, x0, y0);
180 fld.Set(fldB2, fldB1, fldB0);
181
182 int ista = ista2 + 2 * step; // skip one station. if there would be hit it has to be found on previous stap
183
184 if (ista2 == frWData->CurrentIteration()->GetFirstStationIndex()) ista = ista2 + step;
185
186 const fscal pickGather = frWData->CurrentIteration()->GetPickGather();
187 const fvec pickGather2 = pickGather * pickGather;
188 const fvec maxDZ = frWData->CurrentIteration()->GetMaxDZ();
189 for (; (ista < fParameters.GetNstationsActive()) && (ista >= 0); ista += step) { // CHECKME why ista2?
190
191 const auto& sta = fSetup.GetActiveLayer(ista);
192
193 fit.Extrapolate(sta.GetZref(), fld);
194
195 fscal r2_best = 1e8; // best distance to hit
196 int iHit_best = -1; // index of the best hit
197
198 TrackParamV& tr = fit.Tr();
199
200 const auto& grid = frWData->Grid(ista);
201 ca::GridArea area(grid, tr.X()[0], tr.Y()[0],
202 (sqrt(pickGather * tr.C00()) + grid.GetMaxRangeX() + maxDZ * kf::utils::fabs(tr.Tx()))[0],
203 (sqrt(pickGather * tr.C11()) + grid.GetMaxRangeY() + maxDZ * kf::utils::fabs(tr.Ty()))[0]);
204
205 if (fParameters.GetConfig().DevIgnoreHitSearchAreas()) {
207 }
208
209 ca::HitIndex_t ih = 0;
210
211 while (area.GetNextObjectId(ih)) { // loop over the hits in the area
212
213 if (frWData->IsHitSuppressed(ih)) {
214 continue;
215 }
216 const ca::Hit& hit = frWData->Hit(ih);
217
218 if (sta.IsTimeMeasured() && tr.NdfTime()[0] > -2.) {
219 fscal dt = hit.T() - tr.Time()[0];
220 if (fabs(dt) > sqrt(25. * tr.C55()[0]) + hit.RangeT()) continue;
221 }
222
223 //if (GetFUsed((*fStripFlag)[hit.f] | (*fStripFlag)[hit.b])) continue; // if used
224
225 if (frWData->IsHitKeyUsed(hit.FrontKey()) || frWData->IsHitKeyUsed(hit.BackKey())) {
226 continue;
227 }
228
229 auto [y, C11] = fit.ExtrapolateLineYdY2(hit.Z());
230
231 // fscal dym_est = ( fPickGather * sqrt(fabs(C11[0]+sta.XYInfo.C11[0])) );
232 // fscal y_minus_new = y[0] - dym_est;
233 // if (yh < y_minus_new) continue; // CHECKME take into account overlaping?
234
235 auto [x, C00] = fit.ExtrapolateLineXdX2(hit.Z());
236
237 fscal d_x = hit.X() - x[0];
238 fscal d_y = hit.Y() - y[0];
239 fscal d2 = d_x * d_x + d_y * d_y;
240 if (d2 > r2_best) continue;
241 fscal dxm_est = sqrt(pickGather2 * C00)[0] + grid.GetMaxRangeX();
242 if (fabs(d_x) > dxm_est) continue;
243
244 fscal dym_est = sqrt(pickGather2 * C11)[0] + grid.GetMaxRangeY();
245 if (fabs(d_y) > dym_est) continue;
246
247 r2_best = d2;
248 iHit_best = ih;
249 }
250
251 if (iHit_best < 0) break;
252
253
254 const ca::Hit& hit = frWData->Hit(iHit_best);
255 newHits.push_back(iHit_best);
256
257 fit.Extrapolate(hit.Z(), fld);
258 ca::utils::FilterHit(fit, hit, fmask(sta.IsTimeMeasured()));
259 auto radThick = fSetup.GetMaterial(ista).GetThicknessX0(tr.X(), tr.Y());
260 fit.MultipleScattering(radThick);
261 fit.EnergyLossCorrection(radThick, direction);
262
263 fldB0 = fldB1;
264 fldB1 = fldB2;
265 fldB2 = fField.GetFieldValue(ista, hit.X(), hit.Y());
266 fld.Set(fldB2, fldB1, fldB0);
267 }
268
269 // save hits
270 const unsigned int NOldHits = t.NofHits();
271 const unsigned int NNewHits = newHits.size();
272 t.RefHits().enlarge(NNewHits + NOldHits);
273
274 if (direction == kf::FitDirection::kUpstream) {
275 for (int i = NOldHits - 1; i >= 0; i--) {
276 t.RefHits()[NNewHits + i] = t.RefHits()[i];
277 }
278 for (unsigned int i = 0, ii = NNewHits - 1; i < NNewHits; i++, ii--) {
279 t.RefHits()[i] = newHits[ii];
280 }
281 }
282 else { // downstream
283 for (unsigned int i = 0; i < newHits.size(); i++) {
284 t.RefHits()[NOldHits + i] = newHits[i];
285 }
286 }
287
288 Tout = fit.Tr();
289
290 } // void ca::Framework::FindMoreHits
291
294 {
295 frWData = &wData;
296 // const unsigned int minNHits = 3;
297
298 TrackParamV T;
299
300 // downstream
301
304
305 // upstream
306
307 FitBranchFast(t, T, kf::FitDirection::kUpstream, T.Qp(), false);
309
310 return T.GetChiSq()[0];
311 }
312} // 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
A container for all external parameters of the CA tracking algorithm.
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
const cbm::algo::kf::Field< fvec > & fField
void enlarge(std::size_t count, Tinput... value)
Enlarges the vector to the new size.
Definition CaVector.h:147
void reserve(std::size_t count)
Reserves a new size for the vector.
Definition CaVector.h:176
Container for internal data, processed on a single time window.
Magnetic field region, corresponding to a hit triplet.
Magnetic flux density vector.
void EnergyLossCorrection(DataT radThick, FitDirection direction)
void Extrapolate(DataT z, const kf::FieldRegion< DataT > &F)
void MultipleScattering(DataT radThick, DataT tx0, DataT ty0, DataT qp0)
apply multiple scattering correction to the track with the given Qp0
void SetParticleMass(DataT mass)
set particle mass for the fit
kf::TrackParam< DataT > & Tr()
void SetTrack(const kf::TrackParam< T > &t)
std::pair< DataT, DataT > ExtrapolateLineXdX2(DataT z_out) const
std::pair< DataT, DataT > ExtrapolateLineYdY2(DataT z_out) const
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
TrackParam< fvec > TrackParamV