48 int nTracks = extTracks.size();
50 assert(nTracks < std::numeric_limits<unsigned short>::max());
52 constexpr unsigned short kNoNeighbour = std::numeric_limits<unsigned short>::max();
59 firstStation.
reset(nTracks);
60 lastStation.
reset(nTracks);
61 firstHit.
reset(nTracks);
62 lastHit.
reset(nTracks);
63 isStored.
reset(nTracks);
64 trackChi2.
reset(nTracks);
65 neighbour.
reset(nTracks);
66 isDownstreamNeighbour.
reset(nTracks);
70 for (
int iTr = 0; iTr < nTracks; iTr++) {
71 firstHit[iTr] = start_hit;
72 firstStation[iTr] = input.
GetHit(extRecoHits[start_hit]).
Station();
73 start_hit += extTracks[iTr].fNofHits - 1;
74 lastHit[iTr] = start_hit;
75 lastStation[iTr] = input.
GetHit(extRecoHits[start_hit]).
Station();
78 isStored[iTr] =
false;
79 neighbour[iTr] = kNoNeighbour;
80 trackChi2[iTr] = 100000.;
81 isDownstreamNeighbour[iTr] =
false;
100 unsigned char maxLengthForMerge =
static_cast<unsigned char>(
fParameters.GetNstationsActive() - 3);
102 for (
int iTr = 0; iTr < nTracks; iTr++) {
103 if (extTracks[iTr].fNofHits > maxLengthForMerge)
continue;
104 for (
int jTr = 0; jTr < nTracks; jTr++) {
105 if (extTracks[jTr].fNofHits > maxLengthForMerge)
continue;
106 if (iTr == jTr)
continue;
107 if (firstStation[iTr] <= lastStation[jTr])
continue;
109 unsigned short stab = firstStation[iTr];
111 Tb.
Set(extTracks[iTr].fParFirst);
115 unsigned short staf = lastStation[jTr];
117 Tf.
Set(extTracks[jTr].fParLast);
126 fBf =
fParameters.GetStation(staf).fieldSlice.GetFieldValue(Tf.
X(), Tf.
Y());
127 fBb =
fParameters.GetStation(stab).fieldSlice.GetFieldValue(Tb.
X(), Tb.
Y());
129 unsigned short dist = firstStation[iTr] - lastStation[jTr];
138 fvec ym =
fvec(0.5) * (Tf.
Y() + Tf.
Ty() * (zm - Tf.
Z()) + Tb.
Y() + Tb.
Ty() * (zm - Tb.
Z()));
139 fBm =
fParameters.GetStation(stam).fieldSlice.GetFieldValue(xm, ym);
140 fld.
Set(fBb, Tb.
Z(), fBm, zm, fBf, Tf.
Z());
149 if (Chi2Tracks[0] > 50)
continue;
151 if (Chi2Tracks[0] < trackChi2[iTr] || Chi2Tracks[0] < trackChi2[jTr]) {
152 if (neighbour[iTr] < kNoNeighbour) {
153 neighbour[neighbour[iTr]] = kNoNeighbour;
154 trackChi2[neighbour[iTr]] = 100000.;
155 isDownstreamNeighbour[neighbour[iTr]] =
false;
157 if (neighbour[jTr] < kNoNeighbour) {
158 neighbour[neighbour[jTr]] = kNoNeighbour;
159 trackChi2[neighbour[jTr]] = 100000.;
160 isDownstreamNeighbour[neighbour[jTr]] =
false;
162 neighbour[iTr] = jTr;
163 neighbour[jTr] = iTr;
164 trackChi2[iTr] = Chi2Tracks[0];
165 trackChi2[jTr] = Chi2Tracks[0];
166 isDownstreamNeighbour[iTr] =
true;
167 isDownstreamNeighbour[jTr] =
false;
172 for (
int iTr = 0; iTr < nTracks; iTr++) {
173 if (isStored[iTr])
continue;
176 if (!isDownstreamNeighbour[iTr]) {
177 for (
ca::HitIndex_t HI = firstHit[iTr]; HI <= lastHit[iTr]; HI++) {
182 if (neighbour[iTr] < kNoNeighbour) {
183 isStored[neighbour[iTr]] =
true;
185 for (
ca::HitIndex_t HI = firstHit[neighbour[iTr]]; HI <= lastHit[neighbour[iTr]]; HI++)
189 if (isDownstreamNeighbour[iTr]) {
190 for (
ca::HitIndex_t HI = firstHit[iTr]; HI <= lastHit[iTr]; HI++) {
207 for (
int i = 0; i < 15; i++) {
216 for (
int i = 0; i < 5; i++)
217 dzeta[i] = m[i] - r[i];
220 for (
int i = 0; i < 5; i++)
228 for (
int i = 0; i < 15; i++)
232 for (
int i = 0; i < 5; i++) {
234 for (
int j = 0; j < 5; j++)
235 kd += K[i][j] * dzeta[j];
242 *chi2 = dzeta[0] * S_dzeta[0] + dzeta[1] * S_dzeta[1] + dzeta[2] * S_dzeta[2] + dzeta[3] * S_dzeta[3]
243 + dzeta[4] * S_dzeta[4];
251 fvec d[5], uud, u[5][5];
252 for (
int i = 0; i < 5; i++) {
254 for (
int j = 0; j < 5; j++)
258 for (
int i = 0; i < 5; i++) {
260 for (
int j = 0; j < i; j++)
261 uud += u[j][i] * u[j][i] * d[j];
262 uud = a[i * (i + 3) / 2] - uud;
264 fvec smallval(1.e-12);
265 uud =
iif(uud >= smallval, uud, smallval);
270 for (
int j = i + 1; j < 5; j++) {
272 for (
int k = 0; k < i; k++)
273 uud += u[k][i] * u[k][j] * d[k];
274 uud = a[j * (j + 1) / 2 + i] - uud;
275 u[i][j] = d[i] / u[i][i] * uud;
281 for (
int i = 0; i < 5; i++) {
283 u[i][i] = 1.f / u[i][i];
285 for (
int i = 0; i < 4; i++) {
286 u[i][i + 1] = -u[i][i + 1] * u[i][i] * u[i + 1][i + 1];
288 for (
int i = 0; i < 3; i++) {
289 u[i][i + 2] = u[i][i + 1] * u1[i + 1] * u[i + 1][i + 2] - u[i][i + 2] * u[i][i] * u[i + 2][i + 2];
291 for (
int i = 0; i < 2; i++) {
292 u[i][i + 3] = u[i][i + 2] * u1[i + 2] * u[i + 2][i + 3] - u[i][i + 3] * u[i][i] * u[i + 3][i + 3];
293 u[i][i + 3] -= u[i][i + 1] * u1[i + 1] * (u[i + 1][i + 2] * u1[i + 2] * u[i + 2][i + 3] - u[i + 1][i + 3]);
295 u[0][4] = u[0][2] * u1[2] * u[2][4] - u[0][4] * u[0][0] * u[4][4];
296 u[0][4] += u[0][1] * u1[1] * (u[1][4] - u[1][3] * u1[3] * u[3][4] - u[1][2] * u1[2] * u[2][4]);
297 u[0][4] += u[3][4] * u1[3] * (u[0][3] - u1[2] * u[2][3] * (u[0][2] - u[0][1] * u1[1] * u[1][2]));
299 for (
int i = 0; i < 5; i++)
300 a[i + 10] = u[i][4] * d[4] * u[4][4];
301 for (
int i = 0; i < 4; i++)
302 a[i + 6] = u[i][3] * u[3][3] * d[3] + u[i][4] * u[3][4] * d[4];
303 for (
int i = 0; i < 3; i++)
304 a[i + 3] = u[i][2] * u[2][2] * d[2] + u[i][3] * u[2][3] * d[3] + u[i][4] * u[2][4] * d[4];
305 for (
int i = 0; i < 2; i++)
307 u[i][1] * u[1][1] * d[1] + u[i][2] * u[1][2] * d[2] + u[i][3] * u[1][3] * d[3] + u[i][4] * u[1][4] * d[4];
308 a[0] = u[0][0] * u[0][0] * d[0] + u[0][1] * u[0][1] * d[1] + u[0][2] * u[0][2] * d[2] + u[0][3] * u[0][3] * d[3]
309 + u[0][4] * u[0][4] * d[4];
316 K[0] = C[0][0] * V[0] + C[0][1] * V[1] + C[0][2] * V[3] + C[0][3] * V[6] + C[0][4] * V[10];
318 K[1] = C[1][0] * V[0] + C[1][1] * V[1] + C[1][2] * V[3] + C[1][3] * V[6] + C[1][4] * V[10];
319 K[2] = C[1][0] * V[1] + C[1][1] * V[2] + C[1][2] * V[4] + C[1][3] * V[7] + C[1][4] * V[11];
321 K[3] = C[2][0] * V[0] + C[2][1] * V[1] + C[2][2] * V[3] + C[2][3] * V[6] + C[2][4] * V[10];
322 K[4] = C[2][0] * V[1] + C[2][1] * V[2] + C[2][2] * V[4] + C[2][3] * V[7] + C[2][4] * V[11];
323 K[5] = C[2][0] * V[3] + C[2][1] * V[4] + C[2][2] * V[5] + C[2][3] * V[8] + C[2][4] * V[12];
325 K[6] = C[3][0] * V[0] + C[3][1] * V[1] + C[3][2] * V[3] + C[3][3] * V[6] + C[3][4] * V[10];
326 K[7] = C[3][0] * V[1] + C[3][1] * V[2] + C[3][2] * V[4] + C[3][3] * V[7] + C[3][4] * V[11];
327 K[8] = C[3][0] * V[3] + C[3][1] * V[4] + C[3][2] * V[5] + C[3][3] * V[8] + C[3][4] * V[12];
328 K[9] = C[3][0] * V[6] + C[3][1] * V[7] + C[3][2] * V[8] + C[3][3] * V[9] + C[3][4] * V[13];
330 K[10] = C[4][0] * V[0] + C[4][1] * V[1] + C[4][2] * V[3] + C[4][3] * V[6] + C[4][4] * V[10];
331 K[11] = C[4][0] * V[1] + C[4][1] * V[2] + C[4][2] * V[4] + C[4][3] * V[7] + C[4][4] * V[11];
332 K[12] = C[4][0] * V[3] + C[4][1] * V[4] + C[4][2] * V[5] + C[4][3] * V[8] + C[4][4] * V[12];
333 K[13] = C[4][0] * V[6] + C[4][1] * V[7] + C[4][2] * V[8] + C[4][3] * V[9] + C[4][4] * V[13];
334 K[14] = C[4][0] * V[10] + C[4][1] * V[11] + C[4][2] * V[12] + C[4][3] * V[13] + C[4][4] * V[14];
341 r_out[0] = r_in[0] * C[0] + r_in[1] * C[1] + r_in[2] * C[3] + r_in[3] * C[6] + r_in[4] * C[10];
342 r_out[1] = r_in[0] * C[1] + r_in[1] * C[2] + r_in[2] * C[4] + r_in[3] * C[7] + r_in[4] * C[11];
343 r_out[2] = r_in[0] * C[3] + r_in[1] * C[4] + r_in[2] * C[5] + r_in[3] * C[8] + r_in[4] * C[12];
344 r_out[3] = r_in[0] * C[6] + r_in[1] * C[7] + r_in[2] * C[8] + r_in[3] * C[9] + r_in[4] * C[13];
345 r_out[4] = r_in[0] * C[10] + r_in[1] * C[11] + r_in[2] * C[12] + r_in[3] * C[13] + r_in[4] * C[14];
352 K[0][0] = C[0] * V[0] + C[1] * V[1] + C[3] * V[3] + C[6] * V[6] + C[10] * V[10];
353 K[0][1] = C[0] * V[1] + C[1] * V[2] + C[3] * V[4] + C[6] * V[7] + C[10] * V[11];
354 K[0][2] = C[0] * V[3] + C[1] * V[4] + C[3] * V[5] + C[6] * V[8] + C[10] * V[12];
355 K[0][3] = C[0] * V[6] + C[1] * V[7] + C[3] * V[8] + C[6] * V[9] + C[10] * V[13];
356 K[0][4] = C[0] * V[10] + C[1] * V[11] + C[3] * V[12] + C[6] * V[13] + C[10] * V[14];
358 K[1][0] = C[1] * V[0] + C[2] * V[1] + C[4] * V[3] + C[7] * V[6] + C[11] * V[10];
359 K[1][1] = C[1] * V[1] + C[2] * V[2] + C[4] * V[4] + C[7] * V[7] + C[11] * V[11];
360 K[1][2] = C[1] * V[3] + C[2] * V[4] + C[4] * V[5] + C[7] * V[8] + C[11] * V[12];
361 K[1][3] = C[1] * V[6] + C[2] * V[7] + C[4] * V[8] + C[7] * V[9] + C[11] * V[13];
362 K[1][4] = C[1] * V[10] + C[2] * V[11] + C[4] * V[12] + C[7] * V[13] + C[11] * V[14];
364 K[2][0] = C[3] * V[0] + C[4] * V[1] + C[5] * V[3] + C[8] * V[6] + C[12] * V[10];
365 K[2][1] = C[3] * V[1] + C[4] * V[2] + C[5] * V[4] + C[8] * V[7] + C[12] * V[11];
366 K[2][2] = C[3] * V[3] + C[4] * V[4] + C[5] * V[5] + C[8] * V[8] + C[12] * V[12];
367 K[2][3] = C[3] * V[6] + C[4] * V[7] + C[5] * V[8] + C[8] * V[9] + C[12] * V[13];
368 K[2][4] = C[3] * V[10] + C[4] * V[11] + C[5] * V[12] + C[8] * V[13] + C[12] * V[14];
370 K[3][0] = C[6] * V[0] + C[7] * V[1] + C[8] * V[3] + C[9] * V[6] + C[13] * V[10];
371 K[3][1] = C[6] * V[1] + C[7] * V[2] + C[8] * V[4] + C[9] * V[7] + C[13] * V[11];
372 K[3][2] = C[6] * V[3] + C[7] * V[4] + C[8] * V[5] + C[9] * V[8] + C[13] * V[12];
373 K[3][3] = C[6] * V[6] + C[7] * V[7] + C[8] * V[8] + C[9] * V[9] + C[13] * V[13];
374 K[3][4] = C[6] * V[10] + C[7] * V[11] + C[8] * V[12] + C[9] * V[13] + C[13] * V[14];
376 K[4][0] = C[10] * V[0] + C[11] * V[1] + C[12] * V[3] + C[13] * V[6] + C[14] * V[10];
377 K[4][1] = C[10] * V[1] + C[11] * V[2] + C[12] * V[4] + C[13] * V[7] + C[14] * V[11];
378 K[4][2] = C[10] * V[3] + C[11] * V[4] + C[12] * V[5] + C[13] * V[8] + C[14] * V[12];
379 K[4][3] = C[10] * V[6] + C[11] * V[7] + C[12] * V[8] + C[13] * V[9] + C[14] * V[13];
380 K[4][4] = C[10] * V[10] + C[11] * V[11] + C[12] * V[12] + C[13] * V[13] + C[14] * V[14];
source file for the ca::Track class
friend fvec sqrt(const fvec &a)
friend fvec iif(fmask a, fvec b, fvec c)
Track fit utilities for the CA tracking based on the Kalman filter.
Vector< unsigned short > fTrackLastStation
Last station of a track.
static void MultiplySS(fvec const C[15], fvec const V[15], fvec K[5][5])
Vector< char > fTrackIsDownstreamNeighbour
Flag: is the track a downstream neighbour of another track.
fscal fDefaultMass
mass of the propagated particle [GeV/c2]
~CloneMerger()
Destructor.
CloneMerger(const ca::Parameters< fvec > &pars, const fscal mass)
Default constructor.
Vector< Track > fTracksNew
vector of tracks after the merge
const Parameters< fvec > & fParameters
Object of Framework parameters class.
Vector< unsigned short > fTrackNeighbour
Index (TODO:??) of a track that can be merge with the given track.
Vector< ca::HitIndex_t > fRecoHitsNew
vector of track hits after the merge
static void MultiplyMS(fvec const C[5][5], fvec const V[15], fvec K[15])
void Exec(const ca::InputData &input, WindowData &wData)
Registers.
static void MultiplySR(fvec const C[15], fvec const r_in[5], fvec r_out[5])
Vector< char > fTrackIsStored
Flag: is the given track already stored to the output.
Vector< unsigned short > fTrackFirstStation
First station of a track.
Vector< fscal > fTrackChi2
Chi2 value of the track merging procedure.
Vector< ca::HitIndex_t > fTrackFirstHit
Index of the first hit of a track.
static void FilterTracks(fvec const r[5], fvec const C[15], fvec const m[5], fvec const V[15], fvec R[5], fvec W[15], fvec *chi2)
Vector< ca::HitIndex_t > fTrackLastHit
Index of the last hit of a track.
static void InvertCholesky(fvec a[15])
int Station() const
Get the station index.
A container for all external parameters of the CA tracking algorithm.
void push_back(Tinput value)
Pushes back a value to the vector.
T & back()
Mutable access to the last element of the vector.
void reserve(std::size_t count)
Reserves a new size for the vector.
void reset(std::size_t count, Tinput... value)
Clears vector and resizes it to the selected size with selected values.
Container for internal data, processed on a single time window.
Vector< Track > & RecoTracks()
Accesses reconstructed track container.
Vector< HitIndex_t > & RecoHitIndices()
Accesses indices of hits, used by reconstructed tracks.
Magnetic field region, corresponding to a hit triplet.
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)
void SetMask(const DataTmask &m)
kf::TrackParam< DataT > & Tr()
void SetParticleMass(DataT mass)
set particle mass for the fit
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 GetTime() const
Gets time [ns].
T X() const
Gets x position [cm].
T GetQp() const
Gets charge over momentum [ec/GeV].
T Y() const
Gets y position [cm].
T Z() const
Gets z position [cm].
void Set(const TrackParamBase< T1 > &Tb)
T Ty() const
Gets slope along y-axis.
T GetX() const
Gets x position [cm].
TODO: SZh 8.11.2022: add selection of parameterisation.
class cbm::algo::ca::WindowData _fvecalignment
unsigned int HitIndex_t
Index of ca::Hit.