31 declareInterface<IMuonSegmentTrackBuilder>(
this);
32 declareInterface<MooTrackBuilder>(
this);
33 declareInterface<IMuonTrackRefiner>(
this);
34 declareInterface<IMuonTrackBuilder>(
this);
57 return StatusCode::SUCCESS;
65 return StatusCode::SUCCESS;
83 fieldCondObj->getInitializedCache(fieldCache);
96 <<
m_printer->print(
track.track().measurementsOnTrack()->stdcont()));
99 if (!finalTrack) {
ATH_MSG_WARNING(
" final track lost, this should not happen "); }
101 <<
m_printer->print(*finalTrack) << std::endl
108 bool recreateCompetingROTs =
true;
109 std::unique_ptr<Trk::Track> recalibratedTrack =
recalibrateHitsOnTrack(ctx, *finalTrack, recalibrateMDTHits, recreateCompetingROTs);
110 if (!recalibratedTrack) {
113 finalTrack.swap(recalibratedTrack);
115 std::unique_ptr<Trk::Track> refittedTrack =
refit(ctx, *finalTrack);
116 if (!refittedTrack) {
118 <<
m_printer->print(*finalTrack) << std::endl
119 <<
m_printer->printStations(*finalTrack));
121 finalTrack.swap(refittedTrack);
125 if (!finalTrackWithHoles) {
126 ATH_MSG_WARNING(
" failed to add holes to final track, this should not happen ");
128 finalTrack.swap(finalTrackWithHoles);
131 if (entryRecordTrack) {
132 finalTrack.swap(entryRecordTrack);
140 std::unique_ptr<Trk::Track>
track =
combine(ctx, seg1, seg2, externalPhiHits);
142 if (!
track)
return nullptr;
152 const PrepVec& externalPhiHits)
const {
156 if (!segInfo1) {
return nullptr; }
158 if (!segInfo2) {
return nullptr; }
161 return combine(ctx, *segInfo1, *segInfo2, externalPhiHits);
165 const PrepVec& externalPhiHits)
const {
167 std::unique_ptr<Trk::Track>
track =
combine(ctx, firstCandidate, secondCandidate, externalPhiHits);
169 if (!
track)
return nullptr;
188 std::set<MuonStationIndex::StIndex> stations = firstCandidate.
stations();
189 stations.insert(secondCandidate.
stations().begin(), secondCandidate.
stations().end());
190 unsigned int nstations = stations.size();
201 fieldCondObj->getInitializedCache(fieldCache);
202 using namespace MuonStationIndex;
203 bool slFit = !fieldCache.
toroidOn() || nstations == 1 ||
208 for (std::set<StIndex>::const_iterator
it = stations.begin();
it != stations.end(); ++
it) {
227 if (trkCan1 && segCan2) {
230 }
else if (trkCan2 && segCan1) {
248 std::set<const MuPatSegment*> segments;
249 if ((segCan1 && segCan2)) {
250 segments.insert(segCan1);
251 segments.insert(segCan2);
255 segments.insert(candidate->
segments().begin(), candidate->
segments().end());
263 std::set<const MuPatSegment*> foundSegments;
264 for (
const MuPatSegment* segOnTrack : assoc_track->segments()) {
265 if (segments.count(segOnTrack)) foundSegments.insert(segOnTrack);
268 if (foundSegments.size() == segments.size()) {
269 ATH_MSG_DEBUG(
"Combination already part of an existing track");
274 if (candidate && !candidate->
excludedSegments().empty() && foundSegments.size() == segments.size() - 1) {
276 std::vector<const MuPatSegment*> unassociatedSegments(segments.size(),
nullptr);
278 segments.begin(), segments.end(), foundSegments.begin(), foundSegments.end(), unassociatedSegments.begin());
280 unassociatedSegments.erase(
std::find(unassociatedSegments.begin(), unassociatedSegments.end(),
zero),
281 unassociatedSegments.end());
284 if (
it != unassociatedSegments.begin()) {
286 if (unassociatedSegments.size() != 1) {
287 ATH_MSG_DEBUG(
"Inconsistent result from set difference: size result "
288 << unassociatedSegments.size() <<
" candidate " << segments.size() <<
" found "
289 << foundSegments.size());
294 if (!segments.count(unassociatedSegments.front())) {
295 ATH_MSG_DEBUG(
"Segment point not part of the original set, aborting!");
300 std::vector<MuPatSegment*>::const_iterator
pos =
std::find(
303 ATH_MSG_DEBUG(
"Segment found in exclusion list, not performing fit");
313 if (slFit)
return std::unique_ptr<Trk::Track>(
m_slFitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits));
315 return m_fitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits);
319 const PrepVec& externalPhiHits)
const {
322 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
324 if (!candidate)
return nullptr;
326 if (!segInfo) {
return nullptr; }
329 return combine(ctx, *candidate, *segInfo, externalPhiHits);
333 const PrepVec& externalPhiHits)
const {
336 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
338 if (!candidate)
return {};
340 if (!segInfo)
return {};
350 double posSeg = isEndcap ?
pos.z() :
pos.perp();
353 double closest = 1e8;
355 bool closestIsMeasured =
false;
367 for (; tsit != tsit_end; ++tsit) {
370 if (!meas) {
continue; }
373 if (!
pars) {
continue; }
376 bool isMeasured =
pars->covariance();
379 if (closestIsMeasured && !isMeasured)
continue;
382 double posPars = isEndcap ?
pars->position().z() :
pars->position().perp();
383 double diffPos = std::abs(posPars - posSeg);
386 if ((isMeasured && !closestIsMeasured) || diffPos < closest) {
388 closestParameters =
pars;
389 closestIsMeasured = isMeasured;
392 if (closest < 100.) {
break; }
397 if (closestParameters)
return closestParameters->
uniqueClone();
417 const std::set<Identifier>& chIds,
418 const PrepVec& patternPhiHits)
const {
420 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
422 if (!
can) {
return {}; }
428 const PrepVec& externalPhiHits)
const {
436 std::vector<std::unique_ptr<Trk::Track> > newTracks;
441 if (chIds.empty())
return newTracks;
446 std::unique_ptr<Trk::Track> newtrack(
m_fitter->fit(ctx, candidate, segInfo, externalPhiHits));
447 if (newtrack) newTracks.push_back(std::move(newtrack));
469 std::unique_ptr<Trk::TrackParameters> exPars(
483 std::vector<const MuonSegment*>& referenceSegments)
const {
484 if (referenceSegments.empty())
return;
486 ATH_MSG_DEBUG(
" Removing duplicates from segment vector of size " << segments->
size() <<
" reference size "
487 << referenceSegments.size());
492 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> > segKeys;
493 segKeys.reserve(segments->
size());
498 for (; sit != sit_end; ++sit) {
505 std::vector<MuonSegmentKey> referenceSegKeys;
506 referenceSegKeys.reserve(referenceSegments.size());
511 for (; vit != vit_end; ++vit) { referenceSegKeys.emplace_back(**vit); }
514 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >
::iterator skit = segKeys.begin();
515 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >
::iterator skit_end = segKeys.end();
516 for (; skit != skit_end; ++skit) {
517 bool isDuplicate =
false;
522 for (; rskit != rskit_end; ++rskit) {
535 if (isDuplicate) segments->
erase(skit->second);
541 const std::set<Identifier>& chIds,
542 const PrepVec& externalPhiHits)
const {
543 std::vector<std::unique_ptr<Trk::Track> > newTracks;
545 if (chIds.empty())
return newTracks;
548 ATH_MSG_WARNING(
"combineWithSegmentFinding called with CSC hits!! retuning zero pointer");
560 if (segments->
empty()) {
565 unsigned int nseg = segments->
size();
567 std::vector<const MuonSegment*> referenceSegments;
568 for (std::vector<MuPatSegment*>::const_iterator esit = candidate.
excludedSegments().begin();
570 if ((*esit)->segment) referenceSegments.push_back((*esit)->segment);
577 <<
" Rejected segments based on exclusion list, number of removed segments: " << nseg - segments->
size()
581 if (!segments->
empty()) {
602 std::unique_ptr<Trk::Track> segTrack =
m_fitter->fit(ctx, candidate, *segInfo, externalPhiHits);
604 if (!segTrack)
continue;
607 newTracks.push_back(std::move(segTrack));
611 if (!newTracks.empty())
ATH_MSG_DEBUG(
" found new tracks for segment " << newTracks.size());
617 bool doCompetingClusters)
const {
628 if (
track.measurementsOnTrack())
636 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> newStates;
637 newStates.reserve(
states->size() + 5);
642 for (; state_itr != end_itr; ++state_itr) {
649 newStates.emplace_back(tsit->
clone());
656 newStates.emplace_back(tsit->
clone());
664 newStates.emplace_back(tsit->
clone());
674 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
683 *tsit, std::move(newMdt),
pars->uniqueClone(),
686 newStates.push_back(std::move(tsos));
689 newStates.emplace_back(tsit->
clone());
693 newStates.emplace_back(tsit->
clone());
696 if (doCompetingClusters) {
699 newStates.emplace_back(tsit->
clone());
703 newStates.emplace_back(tsit->
clone());
709 ATH_MSG_DEBUG(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
712 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
713 trackStateOnSurfaces->reserve(newStates.size());
714 for (std::unique_ptr<const Trk::TrackStateOnSurface>& new_state : newStates) {
716 trackStateOnSurfaces->push_back(std::move(new_state));
718 return std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
719 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
725 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> >&
states)
const {
727 if (tsit == tsit_end) {
728 ATH_MSG_WARNING(
" iterator pointing to end of vector, this should no happen ");
735 if (!meas || !
pars) {
736 ATH_MSG_WARNING(
" iterator pointing to a TSOS without a measurement or TrackParameters ");
737 if (tsit + 1 == tsit_end) --tsit;
745 std::list<const Trk::PrepRawData*> etaPrds;
746 std::list<const Trk::PrepRawData*> phiPrds;
748 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> > newStates;
750 std::vector<std::pair<bool, const Trk::TrackStateOnSurface*> > outlierStates;
751 bool hasPhi {
false}, hasEta{
false};
753 for (; tsit != tsit_end; ++tsit) {
755 if (!in_tsos)
continue;
760 newStates.emplace_back(in_tsos->
clone());
766 if (!
id.is_valid()) {
767 newStates.emplace_back(in_tsos->
clone());
775 if (!hasPhi && measuresPhi) hasPhi =
true;
776 if (!hasEta && !measuresPhi) hasEta =
true;
780 outlierStates.emplace_back(measuresPhi, in_tsos);
788 std::list<const Trk::PrepRawData*>& prdList = measuresPhi ? phiPrds : etaPrds;
792 if (!currentDetEl) currentDetEl = detEl;
793 if (detEl != currentDetEl) {
803 if (
comp->containedROTs().empty()) {
807 detEl =
comp->containedROTs().front()->detectorElement();
808 if (!currentDetEl) currentDetEl = detEl;
809 if (detEl != currentDetEl) {
813 std::vector<const MuonClusterOnTrack*>::const_iterator clit =
comp->containedROTs().begin();
814 std::vector<const MuonClusterOnTrack*>::const_iterator clit_end =
comp->containedROTs().end();
815 for (; clit != clit_end; ++clit) { prdList.push_back((*clit)->prepRawData()); }
825 if (!etaPrds.empty()) {
826 std::unique_ptr<CompetingMuonClustersOnTrack> etaCompRot =
m_compRotCreator->createBroadCluster(etaPrds, 0.);
828 ATH_MSG_WARNING(
" Failed to create CompetingMuonClustersOnTrack for eta hits! ");
830 std::unique_ptr<Trk::TrackParameters> etaPars;;
832 if (etaCompRot->associatedSurface() ==
pars->associatedSurface()) {
833 etaPars =
pars->uniqueClone();
838 etaCompRot->associatedSurface(),
842 ATH_MSG_WARNING(
" Failed to calculate TrackParameters for eta hits! ");
844 std::unique_ptr<Trk::TrackStateOnSurface> tsos =
846 newStates.push_back(std::move(tsos));
851 if (!phiPrds.empty()) {
852 std::unique_ptr<CompetingMuonClustersOnTrack> phiCompRot =
m_compRotCreator->createBroadCluster(phiPrds, 0.);
854 ATH_MSG_WARNING(
" Failed to create CompetingMuonClustersOnTrack for phi hits! ");
856 std::unique_ptr<Trk::TrackParameters> phiPars;
858 if (phiCompRot->associatedSurface() ==
pars->associatedSurface()) {
859 phiPars =
pars->uniqueClone();
867 ATH_MSG_WARNING(
" Failed to calculate TrackParameters for phi hits! ");
869 std::unique_ptr<Trk::TrackStateOnSurface> tsos =
871 newStates.push_back(std::move(tsos));
877 for (
const auto& outlier : outlierStates) {
878 if (hasPhi && outlier.first)
879 newStates.emplace_back(outlier.second->clone());
880 else if (hasEta && !outlier.first)
881 newStates.emplace_back(outlier.second->clone());
890 states.insert(
states.end(), std::make_move_iterator(newStates.begin()),
891 std::make_move_iterator(newStates.end()));
911 fieldCondObj->getInitializedCache(fieldCache);
919 const std::vector<MuPatSegment*>& segVec)
const {
920 std::vector<std::unique_ptr<MuPatTrack> >
candidates;
924 std::set<MuPatSegment*> usedSegments;
925 std::map<MuPatSegment*, MuPatSegment*> slSegments;
928 bool tightQualityCuts =
false;
934 std::vector<std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> > >
extensions;
939 if (usedSegments.count(seg))
continue;
948 ATH_MSG_VERBOSE(
" track/segment combination rejected based on angular matching " << std::endl
956 std::unique_ptr<Trk::Track>
track =
combine(ctx, candidate, *seg, emptyPhiHits);
970 ATH_MSG_VERBOSE(
" rejecting track as new segment results in worse fit");
976 std::set<MuonStationIndex::StIndex> stationLayersOnTrack;
979 if (!
id.is_valid() ||
m_idHelperSvc->isTrigger(
id)) {
continue; }
980 stationLayersOnTrack.insert(
m_idHelperSvc->stationIndex(
id));
983 bool hasAllLayers =
true;
985 if (!stationLayersOnTrack.count(stIdx)) {
987 hasAllLayers =
false;
992 ATH_MSG_VERBOSE(
" rejecting track as one of the chamber layers of the candidate was removed ");
997 if (!
track) {
continue; }
999 usedSegments.insert(seg);
1003 if (!seg->hasSLOverlap()) {
1004 std::unique_ptr<MuPatTrack> newCandidate;
1008 if (seg->chIndex == seg_1->chIndex)
continue;
1010 if (!newCandidate) {
1011 std::unique_ptr<Trk::Track> trkTrkCan = std::make_unique<Trk::Track>(*
track);
1014 newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1016 }
else if (segCan) {
1019 if (!newCandidate)
break;
1022 ATH_MSG_VERBOSE(
"track/segment combination rejected based on angular matching "
1029 std::unique_ptr<Trk::Track> slOverlapTrack =
combine(ctx, *
track, *seg_1->segment, emptyPhiHits);
1030 if (!slOverlapTrack)
continue;
1035 ATH_MSG_VERBOSE(__FILE__<<
":"<<__LINE__<<
" rejecting track as new segment results in worse fit");
1039 <<
m_printer->printStations(*slOverlapTrack));
1041 track.swap(slOverlapTrack);
1042 usedSegments.insert(seg_1);
1043 slSegments[seg] = seg_1;
1066 std::unique_ptr<MuPatTrack> newCandidate;
1069 newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1070 m_candidateHandler->extendWithSegment(*newCandidate, *ext_itr.first, ext_itr.second);
1071 }
else if (segCan) {
1072 newCandidate =
m_candidateHandler->createCandidate(*segCan, *ext_itr.first, ext_itr.second);
1080 std::unique_ptr<Trk::Track> nullTrack;
1081 newCandidate->addSegment(slOverlap, nullTrack);
1083 candidates.push_back(std::move(newCandidate));
1096 if (!parsVec1 || parsVec1->
empty()) {
1102 ATH_MSG_WARNING(
" isSplitTrack::Track without NULL pointer in parameter vector! ");
1107 if (!parsVec2 || parsVec2->
empty()) {
1113 ATH_MSG_WARNING(
" isSplitTrack::Track without NULL pointer in parameter vector! ");
1122 double sinTheta1 =
sin(pars1->
momentum().theta());
1123 double sinTheta2 =
sin(pars2->
momentum().theta());
1124 double deltaSinTheta = sinTheta1 - sinTheta2;
1125 if (std::abs(deltaSinTheta) > 1.) {
1126 ATH_MSG_DEBUG(
" too large opening angle in theta " << deltaSinTheta);
1131 double deltaSinPhi = sinPhi1 - sinPhi2;
1132 if (std::abs(deltaSinPhi) > 1.) {
1133 ATH_MSG_DEBUG(
" too large opening angle in phi " << deltaSinPhi);
1145 if (isSL1 && !isSL2) {
1146 referenceTrack = &track2;
1147 otherTrack = &track1;
1148 }
else if (!isSL1 && isSL2) {
1149 referenceTrack = &track1;
1150 otherTrack = &track2;
1155 referenceTrack = &track1;
1156 otherTrack = &track2;
1158 referenceTrack = &track2;
1159 otherTrack = &track1;
1184 unsigned int nmatching(0);
1185 unsigned int noff(0);
1188 double prevDist = 1e10;
1192 while (refTSOS != refTSOS_end && otherTSOS != otherTSOS_end) {
1205 double dist = distAlongPars(*parsRef, *parsOther);
1214 if (prevPars && std::abs(prevDist) < std::abs(dist)) {
1215 closestPars = prevPars;
1217 closestPars = parsRef;
1225 if (!
id.is_valid()) {
1240 std::optional<Trk::ResidualPull> resPull =
1242 if (resPull && resPull->pull().size() == 1) {
1244 residual = resPull->residual().front();
1245 pull = resPull->pull().front();
1250 bool inBounds =
false;
1272 if (mmClusterOnTrack) {
1288 if (inBounds && (std::abs(
residual) < 20. || std::abs(
pull) < 10.)) {
1297 ATH_MSG_DEBUG(
"failed to extrapolate parameters to surface");
1309 return nmatching > noff;
1314 std::vector<std::pair<bool, std::unique_ptr<Trk::Track> > > goodTracks;
1315 goodTracks.reserve(tracks.
size());
1316 bool foundSplitTracks =
false;
1318 ATH_MSG_DEBUG(
" trying to merge split tracks, collection size " << tracks.
size());
1323 std::unique_ptr<Trk::Track> mergedTrack;
1326 for (std::pair<
bool, std::unique_ptr<Trk::Track>>& good_trk : goodTracks) {
1331 std::unique_ptr<Trk::Track> track1 = std::make_unique<Trk::Track>(*good_trk.second);
1332 std::unique_ptr<Trk::Track> track2 = std::make_unique<Trk::Track>(*in_track);
1335 mergedTrack =
combine(ctx, *can1, *can2, emptyPhiHits);
1341 <<
m_printer->print(*good_trk.second) << std::endl
1342 <<
m_printer->printStations(*good_trk.second) << std::endl
1343 <<
m_printer->print(*in_track) << std::endl
1344 <<
m_printer->printStations(*in_track) << std::endl
1345 <<
" merged track " << std::endl
1346 <<
m_printer->print(*mergedTrack) << std::endl
1347 <<
m_printer->printStations(*mergedTrack));
1348 foundSplitTracks =
true;
1350 good_trk.first =
true;
1351 good_trk.second.swap(mergedTrack);
1355 <<
m_printer->print(*good_trk.second) << std::endl
1356 <<
m_printer->printStations(*good_trk.second) << std::endl
1357 <<
m_printer->print(*in_track) << std::endl
1358 <<
m_printer->printStations(*in_track));
1365 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(*in_track);
1366 goodTracks.emplace_back(
false, std::move(newTrack));
1371 if (!foundSplitTracks)
return nullptr;
1374 newTracks->
reserve(goodTracks.size());
1375 for (std::pair<
bool, std::unique_ptr<Trk::Track>>& good_trk: goodTracks) {
1377 newTracks->
push_back(std::move(good_trk.second));