diff --git a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinder.h b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinder.h index cc577efe0075f..440992c92912c 100644 --- a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinder.h +++ b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinder.h @@ -83,6 +83,7 @@ class TrackFinder void finalize(); void createTrack(const Cluster& cl1, const Cluster& cl2); + std::list::iterator addTrack(const std::list::iterator& pos, const Track& track); bool isAcceptable(const TrackParam& param) const; diff --git a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinderOriginal.h b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinderOriginal.h index 4be32f6260af1..16e24c717bdea 100644 --- a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinderOriginal.h +++ b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackFinderOriginal.h @@ -55,6 +55,7 @@ class TrackFinderOriginal std::list::iterator findTrackCandidates(int ch1, int ch2, bool skipUsedPairs = false); bool areUsed(const Cluster& cl1, const Cluster& cl2); void createTrack(const Cluster& cl1, const Cluster& cl2); + std::list::iterator addTrack(const std::list::iterator& pos, const Track& track); bool isAcceptable(const TrackParam& param) const; void removeDuplicateTracks(); void removeConnectedTracks(int stMin, int stMax); diff --git a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackerParam.h b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackerParam.h index 2decf1c0eb560..202562c583d21 100644 --- a/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackerParam.h +++ b/Detectors/MUON/MCH/Tracking/include/MCHTracking/TrackerParam.h @@ -42,6 +42,8 @@ struct TrackerParam : public o2::conf::ConfigurableParamHelper { bool moreCandidates = false; ///< find more track candidates starting from 1 cluster in each of station (1..) 4 and 5 bool refineTracks = true; ///< refine the tracks in the end using cluster resolution + std::size_t maxCandidates = 100000; ///< maximum number of track candidates above which the tracking abort + O2ParamDef(TrackerParam, "MCHTracking"); }; diff --git a/Detectors/MUON/MCH/Tracking/src/TrackFinder.cxx b/Detectors/MUON/MCH/Tracking/src/TrackFinder.cxx index 3ee2e5fe24254..0026bb9d0dada 100644 --- a/Detectors/MUON/MCH/Tracking/src/TrackFinder.cxx +++ b/Detectors/MUON/MCH/Tracking/src/TrackFinder.cxx @@ -161,38 +161,46 @@ const std::list& TrackFinder::findTracks(const std::unordered_map> excludedClusters{}; + followTrackInChamber(itTrack, 5, 0, false, excludedClusters); + print("findTracks: removing candidate at position #", getTrackIndex(itTrack)); + itTrack = mTracks.erase(itTrack); + } tEnd = std::chrono::high_resolution_clock::now(); - mTimeFindMoreCandidates += tEnd - tStart; - } - mNCandidates += mTracks.size(); - print("------ list of track candidates ------"); - printTracks(); + mTimeFollowTracks += tEnd - tStart; + print("------ list of tracks before improvement and cleaning ------"); + printTracks(); - // track each candidate down to chamber 1 and remove it - tStart = std::chrono::high_resolution_clock::now(); - for (auto itTrack = mTracks.begin(); itTrack != mTracks.end();) { - std::unordered_map> excludedClusters{}; - followTrackInChamber(itTrack, 5, 0, false, excludedClusters); - print("findTracks: removing candidate at position #", getTrackIndex(itTrack)); - itTrack = mTracks.erase(itTrack); + } catch (exception const& e) { + LOG(error) << e.what() << " --> abort"; + mTracks.clear(); + return mTracks; } - tEnd = std::chrono::high_resolution_clock::now(); - mTimeFollowTracks += tEnd - tStart; - print("------ list of tracks before improvement and cleaning ------"); - printTracks(); // improve the reconstructed tracks - tStart = std::chrono::high_resolution_clock::now(); + auto tStart = std::chrono::high_resolution_clock::now(); improveTracks(); - tEnd = std::chrono::high_resolution_clock::now(); + auto tEnd = std::chrono::high_resolution_clock::now(); mTimeImproveTracks += tEnd - tStart; // remove connected tracks in stations(1..) 3, 4 and 5 @@ -746,7 +754,7 @@ std::list::iterator TrackFinder::followTrackInOverlapDE(const std::listgetIdAsString()); itNewTrack->addParamAtCluster(paramAtCluster); @@ -844,7 +852,7 @@ std::list::iterator TrackFinder::followTrackInChamber(std::list::i // or if one reaches station 1 and it is not requested, whether a cluster has been found on it or not if ((!isFirstOnStation && canSkip && excludedClusters.empty()) || (chamber / 2 == 0 && !TrackerParam::Instance().requestStation[0] && (isFirstOnStation || !canSkip))) { - auto itNewTrack = mTracks.emplace(itTrack, *itTrack); + auto itNewTrack = addTrack(itTrack, *itTrack); if (itFirstNewTrack == mTracks.end()) { itFirstNewTrack = itNewTrack; } @@ -1107,7 +1115,7 @@ std::list::iterator TrackFinder::addClustersAndFollowTrack(std::listaddParamAtCluster(paramAtCluster1); if (paramAtCluster2) { itFirstNewTrack->addParamAtCluster(*paramAtCluster2); @@ -1302,6 +1310,11 @@ void TrackFinder::createTrack(const Cluster& cl1, const Cluster& cl2) { /// Create a new track with these 2 clusters and store it at the end of the list of tracks /// Compute the track parameters and covariance matrices at the 2 clusters + /// Throw an exception if the maximum number of tracks is exceeded + + if (mTracks.size() >= TrackerParam::Instance().maxCandidates) { + throw length_error(string("Too many track candidates (") + mTracks.size() + ")"); + } // create the track and the trackParam at each cluster Track& track = mTracks.emplace_back(); @@ -1319,6 +1332,17 @@ void TrackFinder::createTrack(const Cluster& cl1, const Cluster& cl2) } } +//_________________________________________________________________________________________________ +std::list::iterator TrackFinder::addTrack(const std::list::iterator& pos, const Track& track) +{ + /// Add the given track at the requested position in the list of tracks + /// Throw an exception if the maximum number of tracks is exceeded + if (mTracks.size() >= TrackerParam::Instance().maxCandidates) { + throw length_error(string("Too many track candidates (") + mTracks.size() + ")"); + } + return mTracks.emplace(pos, track); +} + //_________________________________________________________________________________________________ bool TrackFinder::isAcceptable(const TrackParam& param) const { diff --git a/Detectors/MUON/MCH/Tracking/src/TrackFinderOriginal.cxx b/Detectors/MUON/MCH/Tracking/src/TrackFinderOriginal.cxx index ee8e537bce2ed..1be406bd77a6c 100644 --- a/Detectors/MUON/MCH/Tracking/src/TrackFinderOriginal.cxx +++ b/Detectors/MUON/MCH/Tracking/src/TrackFinderOriginal.cxx @@ -79,39 +79,47 @@ const std::list& TrackFinderOriginal::findTracks(const std::array Step 1: find track candidates\n"); - auto tStart = std::chrono::high_resolution_clock::now(); - findTrackCandidates(); - auto tEnd = std::chrono::high_resolution_clock::now(); - mTimeFindCandidates += tEnd - tStart; - if (TrackerParam::Instance().moreCandidates) { + try { + + // Look for candidates from clusters in stations(1..) 4 and 5 + print("\n--> Step 1: find track candidates\n"); + auto tStart = std::chrono::high_resolution_clock::now(); + findTrackCandidates(); + auto tEnd = std::chrono::high_resolution_clock::now(); + mTimeFindCandidates += tEnd - tStart; + if (TrackerParam::Instance().moreCandidates) { + tStart = std::chrono::high_resolution_clock::now(); + findMoreTrackCandidates(); + tEnd = std::chrono::high_resolution_clock::now(); + mTimeFindMoreCandidates += tEnd - tStart; + } + mNCandidates += mTracks.size(); + + // Stop tracking if no candidate found + if (mTracks.empty()) { + return mTracks; + } + + // Follow tracks in stations(1..) 3, 2 then 1 + print("\n--> Step 2: Follow track candidates\n"); tStart = std::chrono::high_resolution_clock::now(); - findMoreTrackCandidates(); + followTracks(mTracks.begin(), mTracks.end(), 2); tEnd = std::chrono::high_resolution_clock::now(); - mTimeFindMoreCandidates += tEnd - tStart; - } - mNCandidates += mTracks.size(); + mTimeFollowTracks += tEnd - tStart; - // Stop tracking if no candidate found - if (mTracks.empty()) { + } catch (exception const& e) { + LOG(error) << e.what() << " --> abort"; + mTracks.clear(); return mTracks; } - // Follow tracks in stations(1..) 3, 2 then 1 - print("\n--> Step 2: Follow track candidates\n"); - tStart = std::chrono::high_resolution_clock::now(); - followTracks(mTracks.begin(), mTracks.end(), 2); - tEnd = std::chrono::high_resolution_clock::now(); - mTimeFollowTracks += tEnd - tStart; - // Complete the reconstructed tracks - tStart = std::chrono::high_resolution_clock::now(); + auto tStart = std::chrono::high_resolution_clock::now(); if (completeTracks()) { printTracks(); removeDuplicateTracks(); } - tEnd = std::chrono::high_resolution_clock::now(); + auto tEnd = std::chrono::high_resolution_clock::now(); mTimeCompleteTracks += tEnd - tStart; print("Currently ", mTracks.size(), " candidates"); printTracks(); @@ -388,6 +396,11 @@ void TrackFinderOriginal::createTrack(const Cluster& cl1, const Cluster& cl2) { /// Create a new track with these 2 clusters and store it at the end of the list of tracks /// Compute the track parameters and covariance matrices at the 2 clusters + /// Throw an exception if the maximum number of tracks is exceeded + + if (mTracks.size() >= TrackerParam::Instance().maxCandidates) { + throw length_error(string("Too many track candidates (") + mTracks.size() + ")"); + } print("Creating a new candidate"); @@ -469,6 +482,17 @@ void TrackFinderOriginal::createTrack(const Cluster& cl1, const Cluster& cl2) printTrackParam(param1); } +//_________________________________________________________________________________________________ +std::list::iterator TrackFinderOriginal::addTrack(const std::list::iterator& pos, const Track& track) +{ + /// Add the given track at the requested position in the list of tracks + /// Throw an exception if the maximum number of tracks is exceeded + if (mTracks.size() >= TrackerParam::Instance().maxCandidates) { + throw length_error(string("Too many track candidates (") + mTracks.size() + ")"); + } + return mTracks.emplace(pos, track); +} + //_________________________________________________________________________________________________ bool TrackFinderOriginal::isAcceptable(const TrackParam& param) const { @@ -617,7 +641,7 @@ void TrackFinderOriginal::followTracks(const std::list::iterator& itTrack // Keep the case where no cluster is found as a possible candidate if the next station is not requested if (!TrackerParam::Instance().requestStation[nextStation]) { print("Duplicate original candidate"); - itTrack = mTracks.emplace(itTrack, *itTrack); + itTrack = addTrack(itTrack, *itTrack); } // Try to recover @@ -704,7 +728,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: TrackExtrap::addMCSEffect(extrapTrackParamAtCh, SChamberThicknessInX0[currentChamber], -1.); } - //Extrapolate the track candidate to chamber 2 + // Extrapolate the track candidate to chamber 2 if (!TrackExtrap::extrapToZCov(extrapTrackParamAtCh, SDefaultChamberZ[ch2], mTrackFitter.isSmootherEnabled())) { return mTracks.end(); } @@ -753,7 +777,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: extrapTrackParam.resetPropagator(); } - //Extrapolate the track candidate to chamber 1 + // Extrapolate the track candidate to chamber 1 bool foundSecondCluster(false); if (TrackExtrap::extrapToZCov(extrapTrackParam, SDefaultChamberZ[ch1], mTrackFitter.isSmootherEnabled())) { @@ -794,7 +818,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: // Copy the initial candidate into a new track with these 2 clusters added print("Duplicate the candidate"); - itNewTrack = mTracks.emplace(itNewTrack, *itTrack); + itNewTrack = addTrack(itNewTrack, *itTrack); updateTrack(*itNewTrack, extrapTrackParamAtCluster1, extrapTrackParamAtCluster2); // Tag clusterCh1 as used @@ -806,7 +830,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: // If no clusterCh1 found then copy the initial candidate into a new track with only clusterCh2 added if (!foundSecondCluster) { print("Duplicate the candidate"); - itNewTrack = mTracks.emplace(itNewTrack, *itTrack); + itNewTrack = addTrack(itNewTrack, *itTrack); updateTrack(*itNewTrack, extrapTrackParamAtCluster2); } } @@ -814,7 +838,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: // Add MCS effects in chamber 2 TrackExtrap::addMCSEffect(extrapTrackParamAtCh, SChamberThicknessInX0[ch2], -1.); - //Extrapolate the track candidate to chamber 1 + // Extrapolate the track candidate to chamber 1 if (!TrackExtrap::extrapToZCov(extrapTrackParamAtCh, SDefaultChamberZ[ch1], mTrackFitter.isSmootherEnabled())) { return (itNewTrack == itTrack) ? mTracks.end() : itNewTrack; } @@ -859,7 +883,7 @@ std::list::iterator TrackFinderOriginal::followTrackInStation(const std:: // Copy the initial candidate into a new track with clusterCh1 added print("Duplicate the candidate"); - itNewTrack = mTracks.emplace(itNewTrack, *itTrack); + itNewTrack = addTrack(itNewTrack, *itTrack); updateTrack(*itNewTrack, extrapTrackParamAtCluster1); } @@ -906,7 +930,7 @@ std::list::iterator TrackFinderOriginal::followLinearTrackInChamber(const // Copy the initial candidate into a new track with cluster added print("Duplicate the candidate"); - itNewTrack = mTracks.emplace(itNewTrack, *itTrack); + itNewTrack = addTrack(itNewTrack, *itTrack); updateTrack(*itNewTrack, extrapTrackParamAtCluster); }