CbmRoot
Loading...
Searching...
No Matches
LitTrackFinderNNVecMuon.cxx
Go to the documentation of this file.
1/* Copyright (C) 2009-2012 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Andrey Lebedev [committer] */
4
11
12#include "../LitAddMaterial.h"
13#include "../LitExtrapolation.h"
14#include "../LitFieldGrid.h"
15#include "../LitFiltration.h"
16#include "../LitHit.h"
17#include "../LitMath.h"
19#include "../LitTypes.h"
20#include "../LitVecPack.h"
22#include "LitHitDataMuon.h"
23
24#include <algorithm>
25#include <iostream>
26#include <limits>
27#include <vector>
28
30 : fTracks()
31 , fLayout()
32 , fHitData()
33 , fMaxNofMissingHits(3)
34 , fIsProcessSubstationsTogether(true)
35 , fSigmaCoef(3.5)
36 , fMaxCovSq(20. * 20.)
37 , fChiSqPixelHitCut(25)
38{
39}
40
42
43void lit::parallel::LitTrackFinderNNVecMuon::DoFind(const PixelHitArray& hits, const TrackArray& trackSeeds,
44 TrackArray& tracks)
45{
46 ArrangeHits(hits);
47 InitTrackSeeds(trackSeeds);
48 FollowTracks();
49
50 DoTrackSelectionMuon(fTracks.begin(), fTracks.end());
51
52 // std::cout << "NOF TRACKS = " << fTracks.size() << std::endl;
53 // Copy tracks to output
54 for (unsigned int iTrack = 0; iTrack < fTracks.size(); iTrack++) {
55 LitScalTrack* track = fTracks[iTrack];
56 // std::cout << "BEFORE " << *track;
57 if (!track->IsGood()) {
58 continue;
59 }
60 // std::cout << "AFTER " << *track;
61 tracks.push_back(new LitScalTrack(*track));
62 }
63
64 // for (unsigned int i = 0; i < tracks.size(); i++)
65 // std::cout << *tracks[i];
66
67 for_each(fTracks.begin(), fTracks.end(), DeleteObject());
68 fTracks.clear();
69 fHitData.Clear();
70}
71
73{
74 for (unsigned int iHit = 0; iHit < hits.size(); iHit++) {
75 LitScalPixelHit* hit = hits[iHit];
76 // if (fUsedHitsSet.find(hit->GetRefId()) != fUsedHitsSet.end()) continue;
77 fHitData.AddHit(hit->planeId, hit);
78 }
79 fHitData.SortHits();
80 // std::cout << fHitData;
81}
82
84{
85 fscal QpCut = 1. / 1.5;
86 for (unsigned int iTrack = 0; iTrack < trackSeeds.size(); iTrack++) {
87 LitScalTrack* track = trackSeeds[iTrack];
88 if (fabs(track->GetParamLast().Qp) > QpCut) {
89 continue;
90 }
91 track->SetPreviousTrackId(iTrack);
92 LitScalTrack* newTrack = new LitScalTrack(*track);
93 newTrack->SetParamLast(newTrack->GetParamFirst());
94 fTracks.push_back(newTrack);
95 }
96}
97
99{
100 // Temporary arrays to store track indices from the fTracks array
101 std::vector<unsigned int> tracksId1;
102 std::vector<unsigned int> tracksId2;
103
104 // Initially use all tracks from fTracks array
105 for (unsigned int i = 0; i < fTracks.size(); i++) {
106 tracksId1.push_back(i);
107 }
108
109 // Main loop over station groups for track following
110 unsigned char nofStationGroups = fLayout.GetNofStationGroups();
111 for (unsigned char iStationGroup = 0; iStationGroup < nofStationGroups;
112 iStationGroup++) { // loop over station groups
113 const LitStationGroupMuon<fvec>& stg = fLayout.GetStationGroup(iStationGroup);
114
115 // First propagate all tracks through absorber
116 PropagateThroughAbsorber(tracksId1, stg.GetAbsorber());
117
118 // Loop over stations, and propagate tracks from station to station
119 unsigned char nofStations = stg.GetNofStations();
120 for (unsigned char iStation = 0; iStation < nofStations; iStation++) { // loop over stations
121
122 // Process station for each track
123 ProcessStation(tracksId1, iStationGroup, iStation);
124
125 // Check missing hits in each track.
126 // Propagate further only tracks which pass the cut.
127 for (unsigned int iTrack = 0; iTrack < tracksId1.size(); iTrack++) {
128 unsigned int id = tracksId1[iTrack];
129 if (fTracks[id]->GetNofMissingHits() <= fMaxNofMissingHits) {
130 tracksId2.push_back(id);
131 }
132 }
133 tracksId1.assign(tracksId2.begin(), tracksId2.end());
134 tracksId2.clear();
135 } // loop over stations
136 } // loop over station groups
137}
138
139void lit::parallel::LitTrackFinderNNVecMuon::PropagateThroughAbsorber(const std::vector<unsigned int>& tracksId1,
140 const LitAbsorber<fvec>& absorber)
141{
142 unsigned int nofTracks = tracksId1.size(); // number of tracks
143 unsigned int nofTracksVec = nofTracks / fvecLen; // number of tracks grouped in vectors
144 unsigned int dTracks = nofTracks - fvecLen * nofTracksVec; // number of tracks remained after grouping in vectors
145
146 // loop over fTracks, pack data and propagate through the absorber
147 for (unsigned int iTrack = 0; iTrack < nofTracksVec; iTrack++) {
148 unsigned int start = fvecLen * iTrack;
149 // Collect track group
150 std::vector<LitScalTrack*> tracks(fvecLen);
151 for (unsigned int i = 0; i < fvecLen; i++) {
152 tracks[i] = fTracks[tracksId1[start + i]];
153 }
154 PropagateThroughAbsorber(tracks, absorber);
155 } // loop over tracks
156
157 // Propagate remaining dTracks through the absorber
158 if (dTracks > 0) {
159 std::vector<LitScalTrack*> tracks(fvecLen);
160 std::vector<LitScalTrack> dummyTracks(fvecLen - dTracks);
161 unsigned int start = fvecLen * nofTracksVec;
162 for (unsigned int i = 0; i < dTracks; i++) {
163 tracks[i] = fTracks[tracksId1[start + i]];
164 }
165 // Check if the number of remaining tracks is less than fvecLen.
166 if (dTracks < fvecLen) {
167 for (unsigned int i = 0; i < fvecLen - dTracks; i++) {
168 tracks[dTracks + i] = &dummyTracks[i];
169 } //tracks[dTracks-1];
170 }
171 PropagateThroughAbsorber(tracks, absorber);
172 }
173}
174
176 const LitAbsorber<fvec>& absorber)
177{
178 // Pack track parameters
179 LitTrackParamScal par[fvecLen];
180 for (unsigned int i = 0; i < fvecLen; i++) {
181 par[i] = tracks[i]->GetParamLast();
182 }
184 PackTrackParam(par, lpar);
185
186 // Propagate through the absorber
187 // LitFieldValue<fvec> v1, v2, v3;
188 // absorber.GetFieldSliceFront().GetFieldValue(lpar.X, lpar.Y, v1);
189 // absorber.GetFieldSliceMiddle().GetFieldValue(lpar.X, lpar.Y, v2);
190 // absorber.GetFieldSliceBack().GetFieldValue(lpar.X, lpar.Y, v3);
191 LitRK4Extrapolation(lpar, absorber.GetZ(), absorber.GetFieldGridFront(), absorber.GetFieldGridMiddle(),
192 absorber.GetFieldGridBack());
193 LitAddMaterial(lpar, absorber.GetMaterial());
194
195 // std::cout << "absorber:" << absorber.GetZ() << " " << lpar;
196
197 // Unpack track parameters
198 UnpackTrackParam(lpar, par);
199 for (unsigned int i = 0; i < fvecLen; i++) {
200 tracks[i]->SetParamLast(par[i]);
201 }
202}
203
204void lit::parallel::LitTrackFinderNNVecMuon::ProcessStation(const std::vector<unsigned int>& tracksId1,
205 unsigned char stationGroup, unsigned char station)
206{
207 unsigned int nofTracks = tracksId1.size(); // number of tracks
208 unsigned int nofTracksVec = nofTracks / fvecLen; // number of tracks grouped in vectors
209 unsigned int dTracks = nofTracks - fvecLen * nofTracksVec; // number of tracks remained after grouping in vectors
210
211 for (unsigned int iTrack = 0; iTrack < nofTracksVec; iTrack++) { // loop over tracks
212 unsigned int start = fvecLen * iTrack;
213 // Collect track group
214 std::vector<LitScalTrack*> tracks(fvecLen);
215 for (unsigned int i = 0; i < fvecLen; i++) {
216 tracks[i] = fTracks[tracksId1[start + i]];
217 }
218 ProcessStation(tracks, stationGroup, station);
219 } // loop over tracks
220
221 // Propagate remaining dTracks
222 if (dTracks > 0) {
223 std::vector<LitScalTrack*> tracks(fvecLen);
224 std::vector<LitScalTrack> dummyTracks(fvecLen - dTracks);
225 unsigned int start = fvecLen * nofTracksVec;
226 for (unsigned int i = 0; i < dTracks; i++) {
227 tracks[i] = fTracks[tracksId1[start + i]];
228 }
229 // Check if the number of remaining tracks is less than fvecLen.
230 if (dTracks < fvecLen) {
231 for (unsigned int i = 0; i < fvecLen - dTracks; i++) {
232 tracks[dTracks + i] = &dummyTracks[i];
233 } //tracks[dTracks-1];
234 }
235 ProcessStation(tracks, stationGroup, station);
236 }
237}
238
239void lit::parallel::LitTrackFinderNNVecMuon::ProcessStation(const TrackArray& tracks, unsigned char stationGroup,
240 unsigned char station)
241{
242 const LitStationGroupMuon<fvec>& stg = fLayout.GetStationGroup(stationGroup);
243 const LitStationMuon<fvec>& sta = stg.GetStation(station);
244 unsigned char nofSubstations = sta.GetNofSubstations();
245
246 // Pack track parameters
247 std::vector<std::vector<LitTrackParamScal>> par(nofSubstations, std::vector<LitTrackParamScal>(fvecLen));
248 for (unsigned int i = 0; i < fvecLen; i++) {
249 par[0][i] = tracks[i]->GetParamLast();
250 }
251 std::vector<LitTrackParam<fvec>> lpar(nofSubstations);
252 PackTrackParam(&par[0][0], lpar[0]);
253
254 //Approximate the field between the absorbers
255 // TODO: Do not need to recalculate it for each station??
257 stg.GetFieldRegion(lpar[0].X, lpar[0].Y, field);
258
259 // Propagate to each of the substations
260 for (unsigned char iSubstation = 0; iSubstation < nofSubstations; iSubstation++) { // loop over substations
261 const LitSubstationMuon<fvec>& substation = sta.GetSubstation(iSubstation);
262 // Propagation through station
263 // LitRK4Extrapolation(lpar[iSubstation], substation.GetZ(), field);
264 LitLineExtrapolation(lpar[iSubstation], substation.GetZ());
265 LitAddMaterial(lpar[iSubstation], substation.GetMaterial());
266 if (iSubstation < nofSubstations - 1) {
267 lpar[iSubstation + 1] = lpar[iSubstation];
268 }
269 } // loop over substations
270
271 for (unsigned char iSubstation = 0; iSubstation < nofSubstations; iSubstation++) {
272 UnpackTrackParam(lpar[iSubstation], &par[iSubstation][0]);
273 }
274 for (unsigned int i = 0; i < fvecLen; i++) {
275 std::vector<LitTrackParamScal> spar(nofSubstations);
276 for (unsigned char iSubstation = 0; iSubstation < nofSubstations; iSubstation++) {
277 spar[iSubstation] = par[iSubstation][i];
278 }
279
280 CollectHits(spar, tracks[i], stationGroup, station, nofSubstations);
281 }
282}
283
284void lit::parallel::LitTrackFinderNNVecMuon::CollectHits(std::vector<LitTrackParamScal>& par, LitScalTrack* track,
285 unsigned char stationGroup, unsigned char station,
286 unsigned char nofSubstations)
287{
288 std::vector<PixelHitConstIteratorPair> hits(nofSubstations);
289 unsigned int nofHits = 0;
290
291 // TODO implement multithreading for this loop
292 for (unsigned char iSubstation = 0; iSubstation < nofSubstations; iSubstation++) { // loop over substations
293 track->SetParamLast(par[iSubstation]);
294
295 const PixelHitArray& hitvec = fHitData.GetHits(stationGroup, station, iSubstation);
296 fscal err = fHitData.GetMaxErr(stationGroup, station, iSubstation);
297
298 MinMaxIndex(&par[iSubstation], hitvec, err, hits[iSubstation].first, hits[iSubstation].second);
299 nofHits += std::distance(hits[iSubstation].first, hits[iSubstation].second);
300 } // loop over substations
301
302
303 bool hitAdded = false;
304 PixelHitArray ahits(nofHits);
305 std::vector<LitTrackParamScal*> apars(nofHits);
306 unsigned int cnt = 0;
307 for (unsigned char iss = 0; iss < nofSubstations; iss++) {
308 for (PixelHitConstIterator j = hits[iss].first; j != hits[iss].second; j++) {
309 ahits[cnt] = *j;
310 apars[cnt] = &par[iss];
311 cnt++;
312 }
313 }
314
315 if (AddNearestHit(track, ahits, apars, nofHits)) {
316 hitAdded = true;
317 }
318 // Check if hit was added, if not than increase number of missing hits
319 if (!hitAdded) {
320 track->IncNofMissingHits();
321 }
322}
323
325 const std::vector<LitTrackParamScal*>& pars,
326 unsigned int nofHits)
327{
328 bool hitAdded = false;
329 LitScalPixelHit* hita = NULL;
330 LitTrackParamScal param;
331 fscal chiSq = std::numeric_limits<fscal>::max();
332
333 unsigned int nofHitsVec = nofHits / fvecLen; // number of hits grouped in vectors
334 unsigned int dHits = nofHits - fvecLen * nofHitsVec; // number of hits remained after grouping in vectors
335 for (unsigned int iHit = 0; iHit < nofHitsVec; iHit++) {
336 unsigned int start = fvecLen * iHit;
337
338 // Pack hit
339 LitScalPixelHit hit[fvecLen];
340 for (unsigned int i = 0; i < fvecLen; i++) {
341 hit[i] = *hits[start + i];
342 }
344 PackPixelHit(hit, lhit);
345 // Pack track parameters
346 LitTrackParamScal par[fvecLen];
347 for (unsigned int i = 0; i < fvecLen; i++) {
348 par[i] = *pars[start + i];
349 }
351 PackTrackParam(par, lpar);
352
353 //First update track parameters with KF, than check whether the hit is in the validation gate.
354 fvec chisq = 0;
355 LitFiltration(lpar, lhit, chisq);
356
357 // Unpack track parameters
358 UnpackTrackParam(lpar, par);
359 for (unsigned int i = 0; i < fvecLen; i++) {
360 if (chisq[i] < fChiSqPixelHitCut[i] && chisq[i] < chiSq) {
361 chiSq = chisq[i];
362 hita = hits[start + i];
363 param = par[i];
364 }
365 }
366 }
367 if (dHits > 0) {
368 unsigned int start = fvecLen * nofHitsVec;
369 LitScalPixelHit hit[fvecLen];
371 LitTrackParamScal par[fvecLen];
373 for (unsigned int i = 0; i < dHits; i++) {
374 hit[i] = *hits[start + i];
375 par[i] = *pars[start + i];
376 }
377 // Check if the number of remaining tracks is less than fvecLen.
378 if (dHits < fvecLen) {
379 for (unsigned int i = 0; i < fvecLen - dHits; i++) {
380 hit[dHits + i] = *hits[nofHits - 1];
381 par[dHits + i] = *pars[nofHits - 1];
382 }
383 }
384 PackPixelHit(hit, lhit);
385 PackTrackParam(par, lpar);
386
387 //First update track parameters with KF, than check whether the hit is in the validation gate.
388 fvec chisq = 0;
389 LitFiltration(lpar, lhit, chisq);
390
391 // Unpack track parameters
392 UnpackTrackParam(lpar, par);
393 for (unsigned int i = 0; i < fvecLen; i++) {
394 if (chisq[i] < fChiSqPixelHitCut[i] && chisq[i] < chiSq) {
395 chiSq = chisq[i];
396 hita = hits[start + i];
397 param = par[i];
398 }
399 }
400 }
401
402 // if hit was attached than change track information
403 if (hita != NULL) {
404 track->AddHit(hita);
405 track->SetParamLast(param);
406 track->IncChiSq(chiSq);
407 track->SetNDF(NDF(*track));
408 hitAdded = true;
409 }
410 return hitAdded;
411}
412
414 fscal maxErr, PixelHitConstIterator& first,
415 PixelHitConstIterator& last)
416{
417 first = hits.begin();
418 last = hits.begin();
419 LitScalPixelHit hit;
420 fscal C0 = par->C0;
421 if (C0 > fMaxCovSq || C0 < 0.) {
422 return;
423 }
424 fscal devX = fSigmaCoef * (std::sqrt(C0) + maxErr);
425 hit.X = par->X - devX;
426 first = std::lower_bound(hits.begin(), hits.end(), &hit, ComparePixelHitXLess());
427 hit.X = par->X + devX;
428 last = std::lower_bound(hits.begin(), hits.end(), &hit, ComparePixelHitXLess());
429}
TClonesArray * tracks
static vector< vector< QAHit > > hits
bool first
Functions for calculation of the material effects.
Classes for muon geometry description of CBM.
Functions for track parameters extrapolation.
Class stores a grid of magnetic field values in XY slice at Z position.
Class for accessing hits in the track reconstruction.
Useful math functions.
Parallel implementation of MUCH tracking.
Implementation of the track selection algorithms.
Header files for SSE operations.
Functions to pack and unpack vector data classes.
Functor class for convenient memory release.
Definition LitUtils.h:58
Absorber in muon detector layout.
Definition LitAbsorber.h:29
const LitFieldGrid & GetFieldGridFront() const
Return magnetic field grid in front of the absorber.
Definition LitAbsorber.h:69
const LitFieldGrid & GetFieldGridMiddle() const
Return magnetic field grid in the middle of the absorber.
Definition LitAbsorber.h:81
const T & GetZ() const
Return Z position of absorber.
Definition LitAbsorber.h:45
const LitMaterialInfo< T > & GetMaterial() const
Return absorber material.
Definition LitAbsorber.h:57
const LitFieldGrid & GetFieldGridBack() const
Return magnetic field grid in the back of the absorber.
Definition LitAbsorber.h:93
Storage for field approximation along Z.
Base class for pixel hits.
Definition LitPixelHit.h:35
Base class for scalar pixel hits.
Scalar track data class.
void IncChiSq(fscal dChiSq)
Increases chi square by dChiSq.
void SetPreviousTrackId(unsigned short previousTrackId)
Sets previous trackId.
const LitTrackParamScal & GetParamFirst() const
Returns first parameter of the track.
void SetNDF(unsigned short NDF)
Sets number of degrees of freedom.
const LitTrackParamScal & GetParamLast() const
Returns last parameter of the track.
bool IsGood() const
Returns true if track is good.
void SetParamLast(const LitTrackParamScal &param)
Sets last track parameter.
void IncNofMissingHits(unsigned short dNofMissingHits=1)
Increases number of missing hits by dNofMissingHits.
void AddHit(const LitScalPixelHit *hit)
Adds hit to track.
void GetFieldRegion(T x, T y, LitFieldRegion< T > &field) const
Calculate field region for the group of stations.
unsigned char GetNofStations() const
Return number of stations in this station group.
const LitStationMuon< T > & GetStation(unsigned short index) const
Return station by index.
const LitAbsorber< T > & GetAbsorber() const
Return absorber.
Station in muon detector layout.
const LitSubstationMuon< T > & GetSubstation(unsigned short index) const
Return substation by index.
unsigned char GetNofSubstations() const
Return number of substations in station.
Substation in muon detector layout.
const T & GetZ() const
Return Z position of substation.
const LitMaterialInfo< T > & GetMaterial() const
Return material of substation.
void InitTrackSeeds(const TrackArray &trackSeeds)
void MinMaxIndex(const LitTrackParamScal *par, const PixelHitArray &hits, fscal maxErr, PixelHitConstIterator &first, PixelHitConstIterator &last)
void CollectHits(std::vector< LitTrackParamScal > &par, LitScalTrack *track, unsigned char stationGroup, unsigned char station, unsigned char nofSubstations)
void PropagateThroughAbsorber(const std::vector< unsigned int > &tracksId1, const LitAbsorber< fvec > &absorber)
bool AddNearestHit(LitScalTrack *track, const PixelHitArray &hits, const std::vector< LitTrackParamScal * > &pars, unsigned int nofHits)
void ProcessStation(const std::vector< unsigned int > &tracksId1, unsigned char stationGroup, unsigned char station)
virtual void DoFind(const PixelHitArray &hits, const TrackArray &trackSeeds, TrackArray &tracks)
Main function for tracking.
void ArrangeHits(const PixelHitArray &hits)
void PackPixelHit(const LitScalPixelHit hit[], LitPixelHit< fvec > &lhit)
Packs LitPixelHit.
Definition LitVecPack.h:151
void UnpackTrackParam(const LitTrackParam< fvec > &lpar, LitTrackParam< fscal > par[])
Unpacks LitTrackParam.
Definition LitVecPack.h:83
void LitRK4Extrapolation(LitTrackParam< T > &par, T zOut, const LitFieldGrid &field1, const LitFieldGrid &field2, const LitFieldGrid &field3)
void LitFiltration(LitTrackParam< T > &par, const LitPixelHit< T > &hit, T &chiSq)
Function implements Kalman filter update step for pixel hit.
void LitLineExtrapolation(LitTrackParam< T > &par, T zOut)
Line track extrapolation for the field free regions.
void PackTrackParam(const LitTrackParam< fscal > par[], LitTrackParam< fvec > &lpar)
Packs LitTrackParam.
Definition LitVecPack.h:49
void LitAddMaterial(LitTrackParam< T > &par, T siliconThickness)
unsigned short NDF(const LitScalTrack &track)
Returns number of degrees of freedom for the track.
Definition LitMath.h:56