24#include <TGeoGlobalMagField.h>
40constexpr double TrackFinder::SDefaultChamberZ[10];
41constexpr double TrackFinder::SChamberThicknessInX0[10];
42constexpr int TrackFinder::SNDE[10];
52 mTrackFitter.
setChamberResolution(trackerParam.chamberResolutionX, trackerParam.chamberResolutionY);
59 mChamberResolutionX2 = trackerParam.chamberResolutionX * trackerParam.chamberResolutionX;
60 mChamberResolutionY2 = trackerParam.chamberResolutionY * trackerParam.chamberResolutionY;
61 mBendingVertexDispersion2 = trackerParam.bendingVertexDispersion * trackerParam.bendingVertexDispersion;
62 mMaxChi2ForTracking = 2. * trackerParam.sigmaCutForTracking * trackerParam.sigmaCutForTracking;
63 mMaxChi2ForImprovement = 2. * trackerParam.sigmaCutForImprovement * trackerParam.sigmaCutForImprovement;
67 double inverseBendingP = (SMinBendingMomentum > 0.) ? 1. / SMinBendingMomentum : 1.;
68 param.setInverseBendingMomentum(inverseBendingP);
69 for (
int iCh = 0; iCh < 10; ++iCh) {
75 for (
int iCh = 0; iCh < 4; ++iCh) {
76 mClusters[2 * iCh].reserve(2);
77 mClusters[2 * iCh].emplace_back(100 * (iCh + 1) + 1,
nullptr);
78 mClusters[2 * iCh].emplace_back(100 * (iCh + 1) + 3,
nullptr);
79 mClusters[2 * iCh + 1].reserve(2);
80 mClusters[2 * iCh + 1].emplace_back(100 * (iCh + 1),
nullptr);
81 mClusters[2 * iCh + 1].emplace_back(100 * (iCh + 1) + 2,
nullptr);
83 for (
int iCh = 4; iCh < 6; ++iCh) {
84 mClusters[8 + 4 * (iCh - 4)].reserve(5);
85 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1),
nullptr);
86 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 2,
nullptr);
87 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 4,
nullptr);
88 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 14,
nullptr);
89 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 16,
nullptr);
90 mClusters[8 + 4 * (iCh - 4) + 1].reserve(4);
91 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 1,
nullptr);
92 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 3,
nullptr);
93 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 15,
nullptr);
94 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 17,
nullptr);
95 mClusters[8 + 4 * (iCh - 4) + 2].reserve(4);
96 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 6,
nullptr);
97 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 8,
nullptr);
98 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 10,
nullptr);
99 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 12,
nullptr);
100 mClusters[8 + 4 * (iCh - 4) + 3].reserve(5);
101 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 5,
nullptr);
102 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 7,
nullptr);
103 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 9,
nullptr);
104 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 11,
nullptr);
105 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 13,
nullptr);
107 for (
int iCh = 6; iCh < 10; ++iCh) {
108 mClusters[8 + 4 * (iCh - 4)].reserve(7);
109 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1),
nullptr);
110 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 2,
nullptr);
111 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 4,
nullptr);
112 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 6,
nullptr);
113 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 20,
nullptr);
114 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 22,
nullptr);
115 mClusters[8 + 4 * (iCh - 4)].emplace_back(100 * (iCh + 1) + 24,
nullptr);
116 mClusters[8 + 4 * (iCh - 4) + 1].reserve(6);
117 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 1,
nullptr);
118 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 3,
nullptr);
119 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 5,
nullptr);
120 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 21,
nullptr);
121 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 23,
nullptr);
122 mClusters[8 + 4 * (iCh - 4) + 1].emplace_back(100 * (iCh + 1) + 25,
nullptr);
123 mClusters[8 + 4 * (iCh - 4) + 2].reserve(6);
124 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 8,
nullptr);
125 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 10,
nullptr);
126 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 12,
nullptr);
127 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 14,
nullptr);
128 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 16,
nullptr);
129 mClusters[8 + 4 * (iCh - 4) + 2].emplace_back(100 * (iCh + 1) + 18,
nullptr);
130 mClusters[8 + 4 * (iCh - 4) + 3].reserve(7);
131 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 7,
nullptr);
132 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 9,
nullptr);
133 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 11,
nullptr);
134 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 13,
nullptr);
135 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 15,
nullptr);
136 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 17,
nullptr);
137 mClusters[8 + 4 * (iCh - 4) + 3].emplace_back(100 * (iCh + 1) + 19,
nullptr);
145 mTrackFitter.
initField(l3Current, dipoleCurrent);
152 std::unordered_map<int, std::list<const Cluster*>> clustersPerDE{};
153 for (
const auto& cluster :
clusters) {
154 clustersPerDE[cluster.getDEId()].emplace_back(&cluster);
165 mStartTime = std::chrono::steady_clock::now();
168 for (
auto& plane : mClusters) {
169 for (
auto&
de : plane) {
174 de.second = &(itDE->second);
185 auto tStart = std::chrono::high_resolution_clock::now();
186 findTrackCandidates();
187 auto tEnd = std::chrono::high_resolution_clock::now();
188 mTimeFindCandidates += tEnd - tStart;
190 tStart = std::chrono::high_resolution_clock::now();
191 findMoreTrackCandidates();
192 tEnd = std::chrono::high_resolution_clock::now();
193 mTimeFindMoreCandidates += tEnd - tStart;
195 mNCandidates += mTracks.size();
196 print(
"------ list of track candidates ------");
200 tStart = std::chrono::high_resolution_clock::now();
201 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
202 std::unordered_map<int, std::unordered_set<uint32_t>> excludedClusters{};
203 followTrackInChamber(itTrack, 5, 0,
false, excludedClusters);
204 print(
"findTracks: removing candidate at position #", getTrackIndex(itTrack));
205 itTrack = mTracks.erase(itTrack);
207 tEnd = std::chrono::high_resolution_clock::now();
208 mTimeFollowTracks += tEnd - tStart;
209 print(
"------ list of tracks before improvement and cleaning ------");
212 }
catch (exception
const& e) {
213 LOG(warning) << e.what() <<
" --> abort";
219 auto tStart = std::chrono::high_resolution_clock::now();
221 auto tEnd = std::chrono::high_resolution_clock::now();
222 mTimeImproveTracks += tEnd - tStart;
225 tStart = std::chrono::high_resolution_clock::now();
226 removeConnectedTracks(2, 4);
227 tEnd = std::chrono::high_resolution_clock::now();
228 mTimeCleanTracks += tEnd - tStart;
232 tStart = std::chrono::high_resolution_clock::now();
235 tEnd = std::chrono::high_resolution_clock::now();
236 mTimeRefineTracks += tEnd - tStart;
245void TrackFinder::findTrackCandidates()
252 findTrackCandidatesInSt5();
254 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
257 if (!itTrack->hasCurrentParam()) {
258 prepareBackwardTracking(itTrack,
false);
262 std::unordered_map<int, std::unordered_set<uint32_t>> excludedClusters{};
263 auto itNewTrack = followTrackInChamber(itTrack, 7, 6,
false, excludedClusters);
266 if (!
TrackerParam::Instance().requestStation[3] && excludedClusters.empty() && itTrack->areCurrentParamValid()) {
269 print(
"findTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
270 itTrack = mTracks.erase(itTrack);
272 for (; itNewTrack != mTracks.end() && itNewTrack != itTrack; ++itNewTrack) {
273 prepareBackwardTracking(itNewTrack,
false);
279 std::vector<std::array<uint32_t, 8>> usedClusters(mTracks.size());
281 for (
const auto& track : mTracks) {
282 for (
const auto&
param : track) {
283 int iCl = 2 * (
param.getClusterPtr()->getChamberId() - 6) +
param.getClusterPtr()->getDEId() % 2;
284 usedClusters[iTrack][iCl] =
param.getClusterPtr()->uid;
289 auto itLastCandidateFromSt5 = mTracks.empty() ? mTracks.end() : std::prev(mTracks.end());
292 findTrackCandidatesInSt4();
294 auto itFirstCandidateOnSt4 = (itLastCandidateFromSt5 == mTracks.end()) ? mTracks.begin() : std::next(itLastCandidateFromSt5);
295 for (
auto itTrack = itFirstCandidateOnSt4; itTrack != mTracks.end();) {
298 if (!itTrack->hasCurrentParam()) {
300 prepareForwardTracking(itTrack,
true);
301 }
catch (exception
const&) {
302 print(
"findTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
303 itTrack = mTracks.erase(itTrack);
311 std::unordered_map<int, std::unordered_set<uint32_t>> excludedClusters{};
312 if (!usedClusters.empty()) {
313 std::array<uint32_t, 4> currentClusters{};
314 for (
const auto&
param : *itTrack) {
315 int iCl = 2 * (
param.getClusterPtr()->getChamberId() - 6) +
param.getClusterPtr()->getDEId() % 2;
316 currentClusters[iCl] =
param.getClusterPtr()->uid;
318 excludeClustersFromIdenticalTracks(currentClusters, usedClusters, excludedClusters);
320 auto itFirstNewTrack = followTrackInChamber(itTrack, 8, 8,
false, excludedClusters);
321 auto itNewTrack = followTrackInChamber(itTrack, 9, 9,
false, excludedClusters);
322 if (itFirstNewTrack == mTracks.end()) {
323 itFirstNewTrack = itNewTrack;
328 itFirstNewTrack = itTrack;
331 print(
"findTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
332 itTrack = mTracks.erase(itTrack);
336 while (itFirstNewTrack != mTracks.end() && itFirstNewTrack != itTrack) {
338 prepareBackwardTracking(itFirstNewTrack,
true);
340 }
catch (exception
const&) {
341 print(
"findTrackCandidates: removing candidate at position #", getTrackIndex(itFirstNewTrack));
342 itFirstNewTrack = mTracks.erase(itFirstNewTrack);
349void TrackFinder::findTrackCandidatesInSt5()
354 print(
"--- find candidates in station 5 ---");
356 for (
int iPlaneCh9 = 27; iPlaneCh9 > 23; --iPlaneCh9) {
358 for (
int iPlaneCh10 = 28; iPlaneCh10 < 32; ++iPlaneCh10) {
361 bool skipUsedPairs = (iPlaneCh9 == 24 || iPlaneCh9 == 26 || iPlaneCh10 == 29 || iPlaneCh10 == 31);
364 auto itTrack = findTrackCandidates(iPlaneCh9, iPlaneCh10, skipUsedPairs, mTracks.begin());
367 if ((iPlaneCh9 == 24 || iPlaneCh9 == 26) && (iPlaneCh10 == 29 || iPlaneCh10 == 31)) {
371 while (itTrack != mTracks.end()) {
373 auto itNextTrack = std::next(itTrack);
375 if (iPlaneCh10 == 28 || iPlaneCh10 == 30) {
379 prepareForwardTracking(itTrack,
true);
380 }
catch (exception
const&) {
381 print(
"findTrackCandidatesInSt5: removing candidate at position #", getTrackIndex(itTrack));
382 itTrack = mTracks.erase(itTrack);
385 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->last().getClusterPtr()->getDEId(), iPlaneCh10 + 1);
387 if (itNewTrack != mTracks.end()) {
390 print(
"findTrackCandidatesInSt5: removing candidate at position #", getTrackIndex(itTrack));
391 itTrack = mTracks.erase(itTrack);
396 itTrack = std::prev(itTrack);
397 if (itTrack == itNewTrack) {
401 prepareBackwardTracking(itTrack,
true);
402 }
catch (exception
const&) {
403 print(
"findTrackCandidatesInSt5: removing candidate at position #", getTrackIndex(itTrack));
404 itTrack = mTracks.erase(itTrack);
409 prepareBackwardTracking(itTrack,
false);
413 if (iPlaneCh9 == 25 || iPlaneCh9 == 27) {
415 while (itTrack != itNextTrack) {
418 if (!itTrack->hasCurrentParam()) {
419 prepareBackwardTracking(itTrack,
false);
421 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->first().getClusterPtr()->getDEId(), iPlaneCh9 - 1);
424 if (itNewTrack == mTracks.end()) {
427 print(
"findTrackCandidatesInSt5: removing candidate at position #", getTrackIndex(itTrack));
428 itTrack = mTracks.erase(itTrack);
433 itTrack = itNextTrack;
439 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
440 if (itTrack->isRemovable()) {
441 itTrack = mTracks.erase(itTrack);
449void TrackFinder::findTrackCandidatesInSt4()
454 print(
"--- find candidates in station 4 ---");
456 auto itLastCandidateFromSt5 = mTracks.empty() ? mTracks.end() : std::prev(mTracks.end());
458 for (
int iPlaneCh8 = 20; iPlaneCh8 < 24; ++iPlaneCh8) {
460 for (
int iPlaneCh7 = 19; iPlaneCh7 > 15; --iPlaneCh7) {
463 bool skipUsedPairs = (iPlaneCh7 == 18 || iPlaneCh7 == 16 || iPlaneCh8 == 21 || iPlaneCh8 == 23);
466 auto itFirstCandidateOnSt4 = (itLastCandidateFromSt5 == mTracks.end()) ? mTracks.begin() : std::next(itLastCandidateFromSt5);
467 auto itTrack = findTrackCandidates(iPlaneCh7, iPlaneCh8, skipUsedPairs, itFirstCandidateOnSt4);
470 if ((iPlaneCh7 == 18 || iPlaneCh7 == 16) && (iPlaneCh8 == 21 || iPlaneCh8 == 23)) {
474 while (itTrack != mTracks.end()) {
476 auto itNextTrack = std::next(itTrack);
478 if (iPlaneCh7 == 19 || iPlaneCh7 == 17) {
481 prepareBackwardTracking(itTrack,
false);
482 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->first().getClusterPtr()->getDEId(), iPlaneCh7 - 1);
485 if (itNewTrack != mTracks.end()) {
486 print(
"findTrackCandidatesInSt4: removing candidate at position #", getTrackIndex(itTrack));
487 mTracks.erase(itTrack);
488 itTrack = itNewTrack;
492 while (itTrack != itNextTrack) {
496 prepareForwardTracking(itTrack,
true);
497 }
catch (exception
const&) {
498 print(
"findTrackCandidatesInSt4: removing candidate at position #", getTrackIndex(itTrack));
499 itTrack = mTracks.erase(itTrack);
503 if (iPlaneCh8 == 20 || iPlaneCh8 == 22) {
506 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->last().getClusterPtr()->getDEId(), iPlaneCh8 + 1);
509 if (itNewTrack == mTracks.end()) {
513 for (; itNewTrack != itTrack; ++itNewTrack) {
514 prepareForwardTracking(itNewTrack,
false);
516 print(
"findTrackCandidatesInSt4: removing candidate at position #", getTrackIndex(itTrack));
517 itTrack = mTracks.erase(itTrack);
528 auto itTrack = (itLastCandidateFromSt5 == mTracks.end()) ? mTracks.begin() : ++itLastCandidateFromSt5;
529 while (itTrack != mTracks.end()) {
530 if (itTrack->isRemovable()) {
531 itTrack = mTracks.erase(itTrack);
539void TrackFinder::findMoreTrackCandidates()
546 print(
"--- find more candidates ---");
548 auto itLastCandidate = mTracks.empty() ? mTracks.end() : std::prev(mTracks.end());
550 for (
int iPlaneSt4 = 23; iPlaneSt4 > 15; --iPlaneSt4) {
552 for (
int iPlaneSt5 = 24; iPlaneSt5 < 32; ++iPlaneSt5) {
555 auto itTrack = findTrackCandidates(iPlaneSt4, iPlaneSt5,
true, mTracks.begin());
558 if ((iPlaneSt4 % 2 == 0) && (iPlaneSt5 % 2 == 1)) {
562 while (itTrack != mTracks.end()) {
564 auto itNextTrack = std::next(itTrack);
566 if (iPlaneSt5 % 2 == 0) {
570 prepareForwardTracking(itTrack,
true);
571 }
catch (exception
const&) {
572 print(
"findMoreTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
573 itTrack = mTracks.erase(itTrack);
576 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->last().getClusterPtr()->getDEId(), iPlaneSt5 + 1);
578 if (itNewTrack != mTracks.end()) {
581 print(
"findMoreTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
582 itTrack = mTracks.erase(itTrack);
587 itTrack = std::prev(itTrack);
588 if (itTrack == itNewTrack) {
592 prepareBackwardTracking(itTrack,
true);
593 }
catch (exception
const&) {
594 print(
"findMoreTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
595 itTrack = mTracks.erase(itTrack);
600 prepareBackwardTracking(itTrack,
false);
604 if (iPlaneSt4 % 2 == 1) {
606 while (itTrack != itNextTrack) {
609 if (!itTrack->hasCurrentParam()) {
610 prepareBackwardTracking(itTrack,
false);
612 auto itNewTrack = followTrackInOverlapDE(itTrack, itTrack->first().getClusterPtr()->getDEId(), iPlaneSt4 - 1);
615 if (itNewTrack == mTracks.end()) {
618 print(
"findMoreTrackCandidates: removing candidate at position #", getTrackIndex(itTrack));
619 itTrack = mTracks.erase(itTrack);
624 itTrack = itNextTrack;
631 auto itTrack = (itLastCandidate == mTracks.end()) ? mTracks.begin() : ++itLastCandidate;
632 while (itTrack != mTracks.end()) {
633 if (itTrack->isRemovable()) {
634 itTrack = mTracks.erase(itTrack);
636 if (!itTrack->hasCurrentParam()) {
637 prepareBackwardTracking(itTrack,
false);
645std::list<Track>::iterator TrackFinder::findTrackCandidates(
int plane1,
int plane2,
bool skipUsedPairs,
const std::list<Track>::iterator& itFirstTrack)
655 double impactMCS2(0.);
656 int chamber1 = getChamberId(plane1);
657 for (
int iCh = 0; iCh <= chamber1; ++iCh) {
658 impactMCS2 += SDefaultChamberZ[iCh] * SDefaultChamberZ[iCh] * mMaxMCSAngle2[iCh];
662 auto itTrack = mTracks.empty() ? mTracks.end() : std::prev(mTracks.end());
665 int chamber2 = getChamberId(plane2);
666 std::vector<std::array<uint32_t, 4>> usedClusters{};
668 usedClusters.reserve(mTracks.size());
669 for (
auto itTrk = itFirstTrack; itTrk != mTracks.end(); ++itTrk) {
670 usedClusters.push_back({0, 0, 0, 0});
671 for (
const auto&
param : *itTrk) {
672 int ch =
param.getClusterPtr()->getChamberId();
673 if (ch == chamber1) {
674 usedClusters.back()[
param.getClusterPtr()->getDEId() % 2] =
param.getClusterPtr()->uid;
675 }
else if (ch == chamber2) {
676 usedClusters.back()[2 +
param.getClusterPtr()->getDEId() % 2] =
param.getClusterPtr()->uid;
682 for (
auto& de1 : mClusters[plane1]) {
685 if (de1.second ==
nullptr) {
689 for (
const auto cluster1 : *de1.second) {
691 double z1 = cluster1->getZ();
693 for (
auto& de2 : mClusters[plane2]) {
696 if (de2.second ==
nullptr) {
700 for (
const auto cluster2 : *de2.second) {
703 if (skipUsedPairs && areUsed(*cluster1, *cluster2, usedClusters)) {
707 double z2 = cluster2->getZ();
711 double nonBendingSlope = (cluster1->getX() - cluster2->getX()) / dZ;
712 double nonBendingImpactParam = TMath::Abs(cluster1->getX() - cluster1->getZ() * nonBendingSlope);
713 double nonBendingImpactParamErr = TMath::Sqrt((z1 * z1 * mChamberResolutionX2 + z2 * z2 * mChamberResolutionX2) / dZ / dZ + impactMCS2);
714 if ((nonBendingImpactParam - trackerParam.sigmaCutForTracking * nonBendingImpactParamErr) > (3. * trackerParam.nonBendingVertexDispersion)) {
718 double bendingSlope = (cluster1->getY() - cluster2->getY()) / dZ;
721 double bendingImpactParam = cluster1->getY() - cluster1->getZ() * bendingSlope;
722 double bendingImpactParamErr2 = (
z1 *
z1 * mChamberResolutionY2 +
z2 *
z2 * mChamberResolutionY2) / dZ / dZ + impactMCS2;
724 double bendingMomentumErr = TMath::Sqrt((mBendingVertexDispersion2 + bendingImpactParamErr2) / bendingImpactParam / bendingImpactParam + 0.01) * bendingMomentum;
725 if ((bendingMomentum + 3. * bendingMomentumErr) < SMinBendingMomentum) {
730 double bendingImpactParam = TMath::Abs(cluster1->getY() - cluster1->getZ() * bendingSlope);
731 double bendingImpactParamErr = TMath::Sqrt((z1 * z1 * mChamberResolutionY2 + z2 * z2 * mChamberResolutionY2) / dZ / dZ + impactMCS2);
732 if ((bendingImpactParam - trackerParam.sigmaCutForTracking * bendingImpactParamErr) > (3. * trackerParam.bendingVertexDispersion)) {
738 createTrack(*cluster1, *cluster2);
744 return (itTrack == mTracks.end()) ? mTracks.begin() : ++itTrack;
748std::list<Track>::iterator TrackFinder::followTrackInOverlapDE(
const std::list<Track>::iterator& itTrack,
int currentDE,
int plane)
757 print(
"followTrackInOverlapDE: follow track #", getTrackIndex(itTrack),
" currently at DE ", currentDE,
" to plane ", plane);
758 printTrack(*itTrack);
761 assert(itTrack->hasCurrentParam());
763 auto itNewTrack(itTrack);
765 const TrackParam& currentParam = itTrack->getCurrentParam();
766 int currentChamber = itTrack->getCurrentChamber();
769 TrackParam paramAtCluster{};
770 for (
auto&
de : mClusters[plane]) {
773 if (
de.second ==
nullptr) {
778 if (
de.first % 100 != (currentDE % 100 + 1) % SNDE[currentChamber] &&
de.first % 100 != (currentDE % 100 - 1 + SNDE[currentChamber]) % SNDE[currentChamber]) {
783 for (
const auto cluster : *
de.second) {
786 if (!isCompatible(currentParam, *cluster, paramAtCluster)) {
791 itNewTrack = addTrack(itNewTrack, *itTrack);
792 print(
"followTrackInOverlapDE: duplicating candidate at position #", getTrackIndex(itNewTrack),
" to add cluster ", cluster->getIdAsString());
793 itNewTrack->addParamAtCluster(paramAtCluster);
796 if (!itNewTrack->isRemovable() && !isAcceptable(paramAtCluster)) {
797 itNewTrack->removable();
802 return (itNewTrack == itTrack) ? mTracks.end() : itNewTrack;
806std::list<Track>::iterator TrackFinder::followTrackInChamber(std::list<Track>::iterator& itTrack,
807 int chamber,
int lastChamber,
bool canSkip,
808 std::unordered_map<
int, std::unordered_set<uint32_t>>& excludedClusters)
826 static constexpr int plane[10][4] = {{1, 0, -1, -1}, {3, 2, -1, -1}, {5, 4, -1, -1}, {7, 6, -1, -1}, {11, 10, 9, 8}, {15, 14, 13, 12}, {19, 18, 17, 16}, {23, 22, 21, 20}, {24, 25, 26, 27}, {28, 29, 30, 31}};
828 print(
"followTrackInChamber: follow track #", getTrackIndex(itTrack),
" to chamber ", chamber + 1,
" up to chamber ", lastChamber + 1);
831 if (!itTrack->areCurrentParamValid() || chamber == itTrack->getCurrentChamber()) {
832 return mTracks.end();
835 std::chrono::duration<double> currentTrackingDuration = std::chrono::steady_clock::now() - mStartTime;
838 throw length_error(
string(
"Tracking is taking too long (") + std::round(currentTrackingDuration.count()) +
" s)");
842 int currentChamber = itTrack->getCurrentChamber();
843 bool isFirstOnStation = ((
chamber < currentChamber &&
chamber % 2 == 1) || (chamber > currentChamber && chamber % 2 == 0));
846 auto itFirstNewTrack = followTrackInChamber(itTrack, plane[chamber][0], plane[chamber][1], lastChamber, excludedClusters);
848 auto itNewTrack = followTrackInChamber(itTrack, plane[chamber][2], plane[chamber][3], lastChamber, excludedClusters);
849 if (itFirstNewTrack == mTracks.end()) {
850 itFirstNewTrack = itNewTrack;
855 if (itTrack->areCurrentParamValid()) {
858 return itFirstNewTrack;
861 if (chamber != lastChamber) {
864 TrackParam currentParam = itTrack->getCurrentParam();
868 if (isFirstOnStation || (canSkip && excludedClusters.empty())) {
869 int nextChamber = (
chamber > lastChamber) ? chamber - 1 :
chamber + 1;
870 auto itNewTrack = followTrackInChamber(itTrack, nextChamber, lastChamber,
false, excludedClusters);
871 if (itFirstNewTrack == mTracks.end()) {
872 itFirstNewTrack = itNewTrack;
877 if (isFirstOnStation && !
TrackerParam::Instance().requestStation[chamber / 2] && chamber / 2 != lastChamber / 2) {
878 int nextChamber = (
chamber > lastChamber) ? chamber - 2 :
chamber + 2;
879 auto itNewTrack = followTrackInChamber(itTrack, nextChamber, lastChamber,
false, excludedClusters);
880 if (itFirstNewTrack == mTracks.end()) {
881 itFirstNewTrack = itNewTrack;
887 if (itTrack->getCurrentChamber() != chamber) {
888 setCurrentParam(*itTrack, currentParam, chamber);
894 if ((!isFirstOnStation && canSkip && excludedClusters.empty()) ||
896 auto itNewTrack = addTrack(itTrack, *itTrack);
897 if (itFirstNewTrack == mTracks.end()) {
898 itFirstNewTrack = itNewTrack;
900 print(
"followTrackInChamber: duplicating candidate at position #", getTrackIndex(itFirstNewTrack));
904 return itFirstNewTrack;
908std::list<Track>::iterator TrackFinder::followTrackInChamber(std::list<Track>::iterator& itTrack,
909 int plane1,
int plane2,
int lastChamber,
910 std::unordered_map<
int, std::unordered_set<uint32_t>>& excludedClusters)
925 print(
"followTrackInChamber: follow track #", getTrackIndex(itTrack),
" to planes ", plane1,
" and ", plane2,
" up to chamber ", lastChamber + 1);
926 printTrack(*itTrack);
929 if (!itTrack->areCurrentParamValid()) {
930 return mTracks.end();
933 auto itFirstNewTrack(mTracks.end());
936 int chamber = getChamberId(plane1);
937 if ((chamber < itTrack->getCurrentChamber() - 1 || chamber > itTrack->getCurrentChamber() + 1) &&
938 !propagateCurrentParam(*itTrack, (chamber < itTrack->getCurrentChamber()) ? chamber + 1 :
chamber - 1)) {
939 return mTracks.end();
943 TrackParam paramAtChamber = itTrack->getCurrentParam();
944 if (itTrack->getCurrentChamber() != chamber && !
TrackExtrap::extrapToZCov(paramAtChamber, SDefaultChamberZ[chamber],
true)) {
945 itTrack->invalidateCurrentParam();
946 return mTracks.end();
951 if (chamber > lastChamber) {
953 }
else if (chamber < lastChamber) {
958 TrackParam paramAtCluster1{};
959 TrackParam currentParamAtCluster1{};
960 TrackParam paramAtCluster2{};
961 std::unordered_map<int, std::unordered_set<uint32_t>> newExcludedClusters{};
962 for (
auto& de1 : mClusters[plane1]) {
965 if (de1.second ==
nullptr) {
970 auto itExcludedClusters = excludedClusters.find(de1.first);
971 bool hasExcludedClusters = (itExcludedClusters != excludedClusters.end());
974 for (
const auto cluster1 : *de1.second) {
977 if (hasExcludedClusters && itExcludedClusters->second.count(cluster1->uid) > 0) {
982 if (!isCompatible(paramAtChamber, *cluster1, paramAtCluster1)) {
987 excludedClusters[de1.first].emplace(cluster1->uid);
990 bool isAcceptableAtCluster1 = isAcceptable(paramAtCluster1);
993 currentParamAtCluster1 = paramAtCluster1;
994 currentParamAtCluster1.resetPropagator();
998 bool cluster2Found(
false);
999 for (
auto& de2 : mClusters[plane2]) {
1002 if (de2.second ==
nullptr) {
1007 if (de2.first % 100 != (de1.first % 100 + 1) % SNDE[chamber] && de2.first % 100 != (de1.first % 100 - 1 + SNDE[chamber]) % SNDE[chamber]) {
1012 for (
const auto cluster2 : *de2.second) {
1015 if (!isCompatible(currentParamAtCluster1, *cluster2, paramAtCluster2)) {
1019 cluster2Found =
true;
1022 excludedClusters[de2.first].emplace(cluster2->uid);
1025 if (!isAcceptableAtCluster1 || !isAcceptable(paramAtCluster2)) {
1030 auto itNewTrack = addClustersAndFollowTrack(itTrack, paramAtCluster1, ¶mAtCluster2, nextChamber, lastChamber, newExcludedClusters);
1031 if (itFirstNewTrack == mTracks.end()) {
1032 itFirstNewTrack = itNewTrack;
1036 moveClusters(newExcludedClusters, excludedClusters);
1040 if (!cluster2Found && isAcceptableAtCluster1) {
1043 auto itNewTrack = addClustersAndFollowTrack(itTrack, paramAtCluster1,
nullptr, nextChamber, lastChamber, newExcludedClusters);
1044 if (itFirstNewTrack == mTracks.end()) {
1045 itFirstNewTrack = itNewTrack;
1049 moveClusters(newExcludedClusters, excludedClusters);
1055 for (
auto& de2 : mClusters[plane2]) {
1058 if (de2.second ==
nullptr) {
1063 auto itExcludedClusters = excludedClusters.find(de2.first);
1064 bool hasExcludedClusters = (itExcludedClusters != excludedClusters.end());
1067 for (
const auto cluster2 : *de2.second) {
1070 if (hasExcludedClusters && itExcludedClusters->second.count(cluster2->uid) > 0) {
1075 if (!isCompatible(paramAtChamber, *cluster2, paramAtCluster2)) {
1080 excludedClusters[de2.first].emplace(cluster2->uid);
1083 if (!isAcceptable(paramAtCluster2)) {
1088 auto itNewTrack = addClustersAndFollowTrack(itTrack, paramAtCluster2,
nullptr, nextChamber, lastChamber, newExcludedClusters);
1089 if (itFirstNewTrack == mTracks.end()) {
1090 itFirstNewTrack = itNewTrack;
1094 moveClusters(newExcludedClusters, excludedClusters);
1099 if (itTrack->getCurrentChamber() != chamber) {
1100 setCurrentParam(*itTrack, paramAtChamber, chamber);
1103 return itFirstNewTrack;
1107std::list<Track>::iterator TrackFinder::addClustersAndFollowTrack(std::list<Track>::iterator& itTrack,
const TrackParam& paramAtCluster1,
1108 const TrackParam* paramAtCluster2,
int nextChamber,
int lastChamber,
1109 std::unordered_map<
int, std::unordered_set<uint32_t>>& excludedClusters)
1118 assert(excludedClusters.empty());
1120 auto itFirstNewTrack(mTracks.end());
1122 if (nextChamber >= 0) {
1125 if (paramAtCluster2) {
1126 print(
"addClustersAndFollowTrack: 2 clusters found (", paramAtCluster1.getClusterPtr()->getIdAsString(),
" and ",
1127 paramAtCluster2->getClusterPtr()->getIdAsString(),
"). Continuing the tracking of candidate #", getTrackIndex(itTrack));
1128 setCurrentParam(*itTrack, *paramAtCluster2, paramAtCluster2->getClusterPtr()->getChamberId());
1130 print(
"addClustersAndFollowTrack: 1 cluster found (", paramAtCluster1.getClusterPtr()->getIdAsString(),
1131 "). Continuing the tracking of candidate #", getTrackIndex(itTrack));
1132 setCurrentParam(*itTrack, paramAtCluster1, paramAtCluster1.getClusterPtr()->getChamberId());
1136 bool canSkip = (nextChamber / 2 == paramAtCluster1.getClusterPtr()->getChamberId() / 2);
1137 auto itNewTrack = followTrackInChamber(itTrack, nextChamber, lastChamber, canSkip, excludedClusters);
1138 itFirstNewTrack = itNewTrack;
1141 if (itNewTrack != mTracks.end()) {
1142 while (itNewTrack != itTrack) {
1143 itNewTrack->addParamAtCluster(paramAtCluster1);
1144 if (paramAtCluster2) {
1145 itNewTrack->addParamAtCluster(*paramAtCluster2);
1146 print(
"addClustersAndFollowTrack: add to the candidate at position #", getTrackIndex(itNewTrack),
1147 " clusters ", paramAtCluster1.getClusterPtr()->getIdAsString(),
" and ", paramAtCluster2->getClusterPtr()->getIdAsString());
1149 print(
"addClustersAndFollowTrack: add to the candidate at position #", getTrackIndex(itNewTrack),
1150 " cluster ", paramAtCluster1.getClusterPtr()->getIdAsString());
1159 itFirstNewTrack = addTrack(itTrack, *itTrack);
1160 itFirstNewTrack->addParamAtCluster(paramAtCluster1);
1161 if (paramAtCluster2) {
1162 itFirstNewTrack->addParamAtCluster(*paramAtCluster2);
1163 print(
"addClustersAndFollowTrack: duplicating candidate at position #", getTrackIndex(itFirstNewTrack),
" to add 2 clusters (",
1164 paramAtCluster1.getClusterPtr()->getIdAsString(),
" and ", paramAtCluster2->getClusterPtr()->getIdAsString(),
")");
1166 print(
"addClustersAndFollowTrack: duplicating candidate at position #", getTrackIndex(itFirstNewTrack),
1167 " to add 1 cluster (", paramAtCluster1.getClusterPtr()->getIdAsString(),
")");
1171 return itFirstNewTrack;
1175void TrackFinder::improveTracks()
1182 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
1184 bool removeTrack(
false);
1187 auto itStartingParam = std::prev(itTrack->rend());
1193 mTrackFitter.
fit(*itTrack,
true,
false, (itStartingParam == itTrack->rbegin()) ?
nullptr : &itStartingParam);
1194 }
catch (exception
const&) {
1203 double worstLocalChi2(-1.);
1204 auto itWorstParam(itTrack->end());
1205 for (
auto itParam = itTrack->begin(); itParam != itTrack->end(); ++itParam) {
1206 if (itParam->getLocalChi2() > worstLocalChi2) {
1207 worstLocalChi2 = itParam->getLocalChi2();
1208 itWorstParam = itParam;
1213 if (worstLocalChi2 < mMaxChi2ForImprovement) {
1218 if (!itWorstParam->isRemovable()) {
1224 auto itNextParam = itTrack->removeParamAtCluster(itWorstParam);
1228 itStartingParam = itTrack->rbegin();
1229 auto itNextToNextParam = (itNextParam == itTrack->end()) ? itNextParam :
std::next(itNextParam);
1230 while (itNextToNextParam != itTrack->end()) {
1231 if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) {
1232 itStartingParam = std::make_reverse_iterator(++itNextParam);
1235 ++itNextToNextParam;
1241 print(
"improveTracks: removing candidate at position #", getTrackIndex(itTrack));
1242 itTrack = mTracks.erase(itTrack);
1250void TrackFinder::removeConnectedTracks(
int stMin,
int stMax)
1256 if (mTracks.size() < 2) {
1260 int chMin = 2 * stMin;
1261 int chMax = 2 * stMax + 1;
1262 int nPlane = 2 * (chMax - chMin + 1);
1265 std::vector<uint32_t> ClIds(nPlane * mTracks.size());
1266 std::vector<uint8_t> nFiredCh(mTracks.size());
1267 std::vector<double> nChi2(mTracks.size());
1270 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end(); ++itTrack, ++iTrack) {
1271 for (
auto itParam = itTrack->rbegin(); itParam != itTrack->rend(); ++itParam) {
1272 int ch = itParam->getClusterPtr()->getChamberId();
1273 if (ch != previousCh) {
1277 if (ch >= chMin && ch <= chMax) {
1278 ClIds[nPlane * iTrack + 2 * (ch - chMin) + itParam->getClusterPtr()->getDEId() % 2] = itParam->getClusterPtr()->uid;
1281 nChi2[iTrack] = itTrack->first().getTrackChi2() / (itTrack->getNDF() - 1);
1285 std::vector<bool> remove(mTracks.size(),
false);
1286 int iindex = ClIds.size() - 1;
1287 for (
int iTrack1 = mTracks.size() - 1; iTrack1 > -1; --iTrack1, iindex -= nPlane) {
1288 int jindex = iindex - nPlane;
1289 for (
int iTrack2 = iTrack1 - 1; iTrack2 > -1; --iTrack2) {
1290 for (
int iPlane = nPlane; iPlane > 0; --iPlane) {
1291 if (ClIds[iindex] == ClIds[jindex] && ClIds[iindex] > 0) {
1292 if (nFiredCh[iTrack2] > nFiredCh[iTrack1] ||
1293 (nFiredCh[iTrack2] == nFiredCh[iTrack1] && nChi2[iTrack2] < nChi2[iTrack1])) {
1294 remove[iTrack1] =
true;
1296 remove[iTrack2] =
true;
1311 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end(); ++iTrack) {
1312 if (remove[iTrack]) {
1313 print(
"removeConnectedTracks: removing candidate at position #", getTrackIndex(itTrack));
1314 itTrack = mTracks.erase(itTrack);
1322void TrackFinder::refineTracks()
1326 for (
auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
1328 mTrackFitter.
fit(*itTrack);
1330 }
catch (exception
const&) {
1331 print(
"refineTracks: removing candidate at position #", getTrackIndex(itTrack));
1332 itTrack = mTracks.erase(itTrack);
1338void TrackFinder::finalize()
1341 for (
auto& track : mTracks) {
1342 for (
auto&
param : track) {
1343 param.setParameters(
param.getSmoothParameters());
1344 param.setCovariances(
param.getSmoothCovariances());
1350void TrackFinder::createTrack(
const Cluster& cl1,
const Cluster& cl2)
1358 throw length_error(
string(
"Too many track candidates (") + mTracks.size() +
")");
1362 Track& track = mTracks.emplace_back();
1363 track.createParamAtCluster(cl2);
1364 track.createParamAtCluster(cl1);
1365 print(
"createTrack: creating candidate at position #", getTrackIndex(std::prev(mTracks.end())),
1366 " with clusters ", cl1.getIdAsString(),
" and ", cl2.getIdAsString());
1370 mTrackFitter.
fit(track,
false);
1371 }
catch (exception
const&) {
1372 print(
"... fit failed --> removing it");
1373 mTracks.erase(std::prev(mTracks.end()));
1378std::list<Track>::iterator TrackFinder::addTrack(
const std::list<Track>::iterator&
pos,
const Track& track)
1384 throw length_error(
string(
"Too many track candidates (") + mTracks.size() +
")");
1386 return mTracks.emplace(
pos, track);
1390bool TrackFinder::isAcceptable(
const TrackParam&
param)
const
1396 double impactMCS2(0.);
1399 for (
int iCh = 0; iCh <=
chamber; ++iCh) {
1404 for (Int_t iCh = 0; iCh <=
chamber; ++iCh) {
1405 impactMCS2 += SDefaultChamberZ[iCh] * SDefaultChamberZ[iCh] * mMaxMCSAngle2[iCh];
1410 const TMatrixD& paramCov =
param.getCovariances();
1414 double nonBendingImpactParam = TMath::Abs(
param.getNonBendingCoor() -
z *
param.getNonBendingSlope());
1415 double nonBendingImpactParamErr = TMath::Sqrt(paramCov(0, 0) +
z *
z * paramCov(1, 1) - 2. *
z * paramCov(0, 1) + impactMCS2);
1416 if ((nonBendingImpactParam - trackerParam.sigmaCutForTracking * nonBendingImpactParamErr) > (3. * trackerParam.nonBendingVertexDispersion)) {
1422 double bendingMomentum = TMath::Abs(1. /
param.getInverseBendingMomentum());
1423 double bendingMomentumErr = TMath::Sqrt(paramCov(4, 4)) * bendingMomentum * bendingMomentum;
1424 if (chamber < 6 && (bendingMomentum + trackerParam.sigmaCutForTracking * bendingMomentumErr) < SMinBendingMomentum) {
1426 }
else if ((bendingMomentum + 3. * bendingMomentumErr) < SMinBendingMomentum) {
1431 double bendingImpactParam = TMath::Abs(
param.getBendingCoor() -
z *
param.getBendingSlope());
1432 double bendingImpactParamErr = TMath::Sqrt(paramCov(2, 2) +
z *
z * paramCov(3, 3) - 2. *
z * paramCov(2, 3) + impactMCS2);
1433 if ((bendingImpactParam - trackerParam.sigmaCutForTracking * bendingImpactParamErr) > (3. * trackerParam.bendingVertexDispersion)) {
1442void TrackFinder::prepareForwardTracking(std::list<Track>::iterator& itTrack,
bool runSmoother)
1449 auto itStartingParam = std::prev(itTrack->rend());
1450 mTrackFitter.
fit(*itTrack,
true,
false, &itStartingParam,
true);
1453 setCurrentParam(*itTrack, itTrack->last(), itTrack->last().getClusterPtr()->getChamberId(), runSmoother);
1457void TrackFinder::prepareBackwardTracking(std::list<Track>::iterator& itTrack,
bool refit)
1464 mTrackFitter.
fit(*itTrack,
false);
1467 setCurrentParam(*itTrack, itTrack->first(), itTrack->first().getClusterPtr()->getChamberId());
1471void TrackFinder::setCurrentParam(Track& track,
const TrackParam&
param,
int chamber,
bool smoothed)
1476 track.setCurrentParam(
param, chamber);
1479 TrackParam& currentParam = track.getCurrentParam();
1480 currentParam.setParameters(
param.getSmoothParameters());
1481 currentParam.setCovariances(
param.getSmoothCovariances());
1484 if (
param.getClusterPtr()) {
1485 TrackParam& currentParam = track.getCurrentParam();
1486 currentParam.resetPropagator();
1492bool TrackFinder::propagateCurrentParam(Track& track,
int chamber)
1498 TrackParam& currentParam = track.getCurrentParam();
1499 int& currentChamber = track.getCurrentChamber();
1500 while (currentChamber != chamber) {
1502 currentChamber += (
chamber < currentChamber) ? -1 : 1;
1505 track.invalidateCurrentParam();
1516bool TrackFinder::areUsed(
const Cluster& cl1,
const Cluster& cl2,
const std::vector<std::array<uint32_t, 4>>& usedClusters)
1519 int iCl1 = cl1.getDEId() % 2;
1520 int iCl2 = 2 + cl2.getDEId() % 2;
1521 for (
const auto&
clusters : usedClusters) {
1530void TrackFinder::excludeClustersFromIdenticalTracks(
const std::array<uint32_t, 4>& currentClusters,
1531 const std::vector<std::array<uint32_t, 8>>& usedClusters,
1532 std::unordered_map<
int, std::unordered_set<uint32_t>>& excludedClusters)
1537 for (
const auto&
clusters : usedClusters) {
1539 bool identicalTrack(
true);
1540 for (
int iCl = 0; iCl < 4; ++iCl) {
1541 if (
clusters[iCl] != currentClusters[iCl] && currentClusters[iCl] > 0) {
1542 identicalTrack =
false;
1547 if (identicalTrack) {
1548 for (
int iCl = 4; iCl < 8; ++iCl) {
1558void TrackFinder::moveClusters(std::unordered_map<
int, std::unordered_set<uint32_t>>&
source, std::unordered_map<
int, std::unordered_set<uint32_t>>& destination)
1561 for (
auto& sourceDE :
source) {
1562 destination[sourceDE.first].insert(sourceDE.second.begin(), sourceDE.second.end());
1568bool TrackFinder::isCompatible(
const TrackParam&
param,
const Cluster& cluster, TrackParam& paramAtCluster)
1574 if (!tryOneClusterFast(
param, cluster)) {
1579 if (tryOneCluster(
param, cluster, paramAtCluster) >= mMaxChi2ForTracking) {
1584 paramAtCluster.setExtrapParameters(paramAtCluster.getParameters());
1585 paramAtCluster.setExtrapCovariances(paramAtCluster.getCovariances());
1590 }
catch (exception
const&) {
1598bool TrackFinder::tryOneClusterFast(
const TrackParam&
param,
const Cluster& cluster)
1605 ++mNCallTryOneClusterFast;
1607 double dZ = cluster.getZ() -
param.getZ();
1608 double dX = cluster.getX() - (
param.getNonBendingCoor() +
param.getNonBendingSlope() * dZ);
1609 double dY = cluster.getY() - (
param.getBendingCoor() +
param.getBendingSlope() * dZ);
1610 const TMatrixD& paramCov =
param.getCovariances();
1611 double errX2 = paramCov(0, 0) + dZ * dZ * paramCov(1, 1) + 2. * dZ * paramCov(0, 1) + mChamberResolutionX2;
1612 double errY2 = paramCov(2, 2) + dZ * dZ * paramCov(3, 3) + 2. * dZ * paramCov(2, 3) + mChamberResolutionY2;
1614 double dXmax =
TrackerParam::Instance().sigmaCutForTracking * TMath::Sqrt(2. * errX2) + SMaxNonBendingDistanceToTrack;
1615 double dYmax =
TrackerParam::Instance().sigmaCutForTracking * TMath::Sqrt(2. * errY2) + SMaxBendingDistanceToTrack;
1617 if (TMath::Abs(dX) > dXmax || TMath::Abs(dY) > dYmax) {
1624double TrackFinder::tryOneCluster(
const TrackParam&
param,
const Cluster& cluster, TrackParam& paramAtCluster)
1631 ++mNCallTryOneCluster;
1634 paramAtCluster =
param;
1635 paramAtCluster.setClusterPtr(&cluster);
1641 double dX = cluster.getX() - paramAtCluster.getNonBendingCoor();
1642 double dY = cluster.getY() - paramAtCluster.getBendingCoor();
1645 const TMatrixD& paramCov = paramAtCluster.getCovariances();
1646 double sigmaX2 = paramCov(0, 0) + mChamberResolutionX2;
1647 double sigmaY2 = paramCov(2, 2) + mChamberResolutionY2;
1648 double covXY = paramCov(0, 2);
1649 double det = sigmaX2 * sigmaY2 - covXY * covXY;
1655 return (dX * dX * sigmaY2 + dY * dY * sigmaX2 - 2. * dX * dY * covXY) / det;
1659uint8_t TrackFinder::requestedStationMask()
const
1664 for (
int i = 0;
i < 5; ++
i) {
1673int TrackFinder::getTrackIndex(
const std::list<Track>::iterator& itCurrentTrack)
const
1680 if (mDebugLevel < 1) {
1684 if (itCurrentTrack == mTracks.end()) {
1689 for (
auto itTrack = mTracks.begin(); itTrack != itCurrentTrack; ++itTrack) {
1690 if (itTrack == mTracks.end()) {
1700void TrackFinder::printTracks()
const
1703 if (mDebugLevel > 1) {
1704 for (
const auto& track : mTracks) {
1711void TrackFinder::printTrack(
const Track& track)
const
1714 if (mDebugLevel > 1) {
1720void TrackFinder::printTrackParam(
const TrackParam& trackParam)
const
1723 if (mDebugLevel > 1) {
1729template <
class... Args>
1730void TrackFinder::print(Args... args)
const
1733 if (mDebugLevel > 0) {
1734 (
cout << ... << args) <<
"\n";
1742 LOG(info) <<
"number of candidates tracked = " << mNCandidates;
1744 LOG(info) <<
"number of times tryOneClusterFast() is called = " << mNCallTryOneClusterFast;
1745 LOG(info) <<
"number of times tryOneCluster() is called = " << mNCallTryOneCluster;
1752 LOG(info) <<
"findTrackCandidates duration = " << mTimeFindCandidates.count() <<
" s";
1753 LOG(info) <<
"findMoreTrackCandidates duration = " << mTimeFindMoreCandidates.count() <<
" s";
1754 LOG(info) <<
"followTracks duration = " << mTimeFollowTracks.count() <<
" s";
1755 LOG(info) <<
"improveTracks duration = " << mTimeImproveTracks.count() <<
" s";
1756 LOG(info) <<
"removeConnectedTracks duration = " << mTimeCleanTracks.count() <<
" s";
1757 LOG(info) <<
"refineTracks duration = " << mTimeRefineTracks.count() <<
" s";
definition of the MCH processing errors
Configurable parameters for MCH tracking.
Definition of the MagF class.
Definition of a class to reconstruct tracks.
static const TrackerParam & Instance()
HMPID cluster implementation.
void add(ErrorType errorType, uint32_t id0, uint32_t id1, uint64_t n=1)
const std::list< Track > & findTracks(gsl::span< const Cluster > clusters)
void initField(float l3Current, float dipoleCurrent)
void setChamberResolution(double ex, double ey)
void useChamberResolution()
Use the chamber resolution instead of cluster resolution during the fit.
void initField(float l3Current, float dipoleCurrent)
void useClusterResolution()
Use the own resolution of each cluster during the fit (default)
void setBendingVertexDispersion(double ey)
Set the vertex dispersion in y direction used for the track covariance seed.
void smoothTracks(bool smooth)
Enable/disable the smoother (and the saving of related parameters)
static constexpr double getMaxChi2()
Return the maximum chi2 above which the track can be considered as abnormal.
void fit(Track &track, bool smooth=true, bool finalize=true, std::list< TrackParam >::reverse_iterator *itStartingParam=nullptr, bool skipLocalChi2Calculation=false)
void runKalmanFilter(TrackParam &trackParam)
track parameters for internal use
GLsizei GLsizei GLchar * source
GLdouble GLdouble GLdouble z
uint8_t itsSharedClusterMap uint8_t
float float float float float z2
float float float float z1
o2::track::TrackParCov Track
std::optional< Chamber > chamber(int chamberId)
@ Tracking_TooManyCandidates
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters