Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MCH] add protection against too many track candidates #8635

Merged
merged 1 commit into from
Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class TrackFinder
void finalize();

void createTrack(const Cluster& cl1, const Cluster& cl2);
std::list<Track>::iterator addTrack(const std::list<Track>::iterator& pos, const Track& track);

bool isAcceptable(const TrackParam& param) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class TrackFinderOriginal
std::list<Track>::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<Track>::iterator addTrack(const std::list<Track>::iterator& pos, const Track& track);
bool isAcceptable(const TrackParam& param) const;
void removeDuplicateTracks();
void removeConnectedTracks(int stMin, int stMax);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct TrackerParam : public o2::conf::ConfigurableParamHelper<TrackerParam> {
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");
};

Expand Down
80 changes: 52 additions & 28 deletions Detectors/MUON/MCH/Tracking/src/TrackFinder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -161,38 +161,46 @@ const std::list<Track>& TrackFinder::findTracks(const std::unordered_map<int, st
// use the chamber resolution when fitting the tracks during the tracking
mTrackFitter.useChamberResolution();

// find track candidates on stations 4 and 5
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 {

// find track candidates on stations 4 and 5
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();
print("------ list of track candidates ------");
printTracks();

// track each candidate down to chamber 1 and remove it
tStart = std::chrono::high_resolution_clock::now();
findMoreTrackCandidates();
for (auto itTrack = mTracks.begin(); itTrack != mTracks.end();) {
std::unordered_map<int, std::unordered_set<uint32_t>> 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<int, std::unordered_set<uint32_t>> 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
Expand Down Expand Up @@ -746,7 +754,7 @@ std::list<Track>::iterator TrackFinder::followTrackInOverlapDE(const std::list<T
}

// duplicate the track and add the new cluster
itNewTrack = mTracks.emplace(itNewTrack, *itTrack);
itNewTrack = addTrack(itNewTrack, *itTrack);
print("followTrackInOverlapDE: duplicating candidate at position #", getTrackIndex(itNewTrack), " to add cluster ", cluster->getIdAsString());
itNewTrack->addParamAtCluster(paramAtCluster);

Expand Down Expand Up @@ -844,7 +852,7 @@ std::list<Track>::iterator TrackFinder::followTrackInChamber(std::list<Track>::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;
}
Expand Down Expand Up @@ -1107,7 +1115,7 @@ std::list<Track>::iterator TrackFinder::addClustersAndFollowTrack(std::list<Trac
} else {

// or duplicate the track and add the new cluster(s)
itFirstNewTrack = mTracks.emplace(itTrack, *itTrack);
itFirstNewTrack = addTrack(itTrack, *itTrack);
itFirstNewTrack->addParamAtCluster(paramAtCluster1);
if (paramAtCluster2) {
itFirstNewTrack->addParamAtCluster(*paramAtCluster2);
Expand Down Expand Up @@ -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();
Expand All @@ -1319,6 +1332,17 @@ void TrackFinder::createTrack(const Cluster& cl1, const Cluster& cl2)
}
}

//_________________________________________________________________________________________________
std::list<Track>::iterator TrackFinder::addTrack(const std::list<Track>::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
{
Expand Down
84 changes: 54 additions & 30 deletions Detectors/MUON/MCH/Tracking/src/TrackFinderOriginal.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -79,39 +79,47 @@ const std::list<Track>& TrackFinderOriginal::findTracks(const std::array<std::li
// Use the chamber resolution when fitting the tracks during the tracking
mTrackFitter.useChamberResolution();

// 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) {
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();
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -469,6 +482,17 @@ void TrackFinderOriginal::createTrack(const Cluster& cl1, const Cluster& cl2)
printTrackParam(param1);
}

//_________________________________________________________________________________________________
std::list<Track>::iterator TrackFinderOriginal::addTrack(const std::list<Track>::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
{
Expand Down Expand Up @@ -617,7 +641,7 @@ void TrackFinderOriginal::followTracks(const std::list<Track>::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
Expand Down Expand Up @@ -704,7 +728,7 @@ std::list<Track>::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();
}
Expand Down Expand Up @@ -753,7 +777,7 @@ std::list<Track>::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())) {

Expand Down Expand Up @@ -794,7 +818,7 @@ std::list<Track>::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
Expand All @@ -806,15 +830,15 @@ std::list<Track>::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);
}
}

// 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;
}
Expand Down Expand Up @@ -859,7 +883,7 @@ std::list<Track>::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);
}

Expand Down Expand Up @@ -906,7 +930,7 @@ std::list<Track>::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);
}

Expand Down