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);
226 if (trkCan1 && segCan2) {
229 }
else if (trkCan2 && segCan1) {
247 std::set<const MuPatSegment*> segments;
248 if ((segCan1 && segCan2)) {
249 segments.insert(segCan1);
250 segments.insert(segCan2);
254 segments.insert(candidate->
segments().begin(), candidate->
segments().end());
262 std::set<const MuPatSegment*> foundSegments;
263 for (
const MuPatSegment* segOnTrack : assoc_track->segments()) {
264 if (segments.count(segOnTrack)) foundSegments.insert(segOnTrack);
267 if (foundSegments.size() == segments.size()) {
268 ATH_MSG_DEBUG(
"Combination already part of an existing track");
273 if (candidate && !candidate->
excludedSegments().empty() && foundSegments.size() == segments.size() - 1) {
275 std::vector<const MuPatSegment*> unassociatedSegments(segments.size(),
nullptr);
277 segments.begin(), segments.end(), foundSegments.begin(), foundSegments.end(), unassociatedSegments.begin());
279 unassociatedSegments.erase(
std::find(unassociatedSegments.begin(), unassociatedSegments.end(),
zero),
280 unassociatedSegments.end());
283 if (
it != unassociatedSegments.begin()) {
285 if (unassociatedSegments.size() != 1) {
286 ATH_MSG_DEBUG(
"Inconsistent result from set difference: size result "
287 << unassociatedSegments.size() <<
" candidate " << segments.size() <<
" found "
288 << foundSegments.size());
293 if (!segments.count(unassociatedSegments.front())) {
294 ATH_MSG_DEBUG(
"Segment point not part of the original set, aborting!");
299 std::vector<MuPatSegment*>::const_iterator
pos =
std::find(
302 ATH_MSG_DEBUG(
"Segment found in exclusion list, not performing fit");
312 if (slFit)
return std::unique_ptr<Trk::Track>(
m_slFitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits));
314 return m_fitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits);
318 const PrepVec& externalPhiHits)
const {
321 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
323 if (!candidate)
return nullptr;
325 if (!segInfo) {
return nullptr; }
328 return combine(ctx, *candidate, *segInfo, externalPhiHits);
332 const PrepVec& externalPhiHits)
const {
335 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
337 if (!candidate)
return {};
339 if (!segInfo)
return {};
349 double posSeg = isEndcap ?
pos.z() :
pos.perp();
352 double closest = 1e8;
354 bool closestIsMeasured =
false;
366 for (; tsit != tsit_end; ++tsit) {
369 if (!meas) {
continue; }
372 if (!
pars) {
continue; }
375 bool isMeasured =
pars->covariance();
378 if (closestIsMeasured && !isMeasured)
continue;
381 double posPars = isEndcap ?
pars->position().z() :
pars->position().perp();
382 double diffPos = std::abs(posPars - posSeg);
385 if ((isMeasured && !closestIsMeasured) || diffPos < closest) {
387 closestParameters =
pars;
388 closestIsMeasured = isMeasured;
391 if (closest < 100.) {
break; }
396 if (closestParameters)
return closestParameters->
uniqueClone();
416 const std::set<Identifier>& chIds,
417 const PrepVec& patternPhiHits)
const {
419 std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(
track);
421 if (!
can) {
return {}; }
427 const PrepVec& externalPhiHits)
const {
435 std::vector<std::unique_ptr<Trk::Track> > newTracks;
440 if (chIds.empty())
return newTracks;
445 std::unique_ptr<Trk::Track> newtrack(
m_fitter->fit(ctx, candidate, segInfo, externalPhiHits));
446 if (newtrack) newTracks.push_back(std::move(newtrack));
468 std::unique_ptr<Trk::TrackParameters> exPars(
482 std::vector<const MuonSegment*>& referenceSegments)
const {
483 if (referenceSegments.empty())
return;
485 ATH_MSG_DEBUG(
" Removing duplicates from segment vector of size " << segments->
size() <<
" reference size "
486 << referenceSegments.size());
491 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> > segKeys;
492 segKeys.reserve(segments->
size());
497 for (; sit != sit_end; ++sit) {
504 std::vector<MuonSegmentKey> referenceSegKeys;
505 referenceSegKeys.reserve(referenceSegments.size());
510 for (; vit != vit_end; ++vit) { referenceSegKeys.emplace_back(**vit); }
513 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >
::iterator skit = segKeys.begin();
514 std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >
::iterator skit_end = segKeys.end();
515 for (; skit != skit_end; ++skit) {
516 bool isDuplicate =
false;
521 for (; rskit != rskit_end; ++rskit) {
534 if (isDuplicate) segments->
erase(skit->second);
540 const std::set<Identifier>& chIds,
541 const PrepVec& externalPhiHits)
const {
542 std::vector<std::unique_ptr<Trk::Track> > newTracks;
544 if (chIds.empty())
return newTracks;
547 ATH_MSG_WARNING(
"combineWithSegmentFinding called with CSC hits!! retuning zero pointer");
559 if (segments->
empty()) {
564 unsigned int nseg = segments->
size();
566 std::vector<const MuonSegment*> referenceSegments;
567 for (std::vector<MuPatSegment*>::const_iterator esit = candidate.
excludedSegments().begin();
569 if ((*esit)->segment) referenceSegments.push_back((*esit)->segment);
576 <<
" Rejected segments based on exclusion list, number of removed segments: " << nseg - segments->
size()
580 if (!segments->
empty()) {
601 std::unique_ptr<Trk::Track> segTrack =
m_fitter->fit(ctx, candidate, *segInfo, externalPhiHits);
603 if (!segTrack)
continue;
606 newTracks.push_back(std::move(segTrack));
610 if (!newTracks.empty())
ATH_MSG_DEBUG(
" found new tracks for segment " << newTracks.size());
616 bool doCompetingClusters)
const {
627 if (
track.measurementsOnTrack())
635 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> newStates;
636 newStates.reserve(
states->size() + 5);
641 for (; state_itr != end_itr; ++state_itr) {
648 newStates.emplace_back(tsit->
clone());
655 newStates.emplace_back(tsit->
clone());
663 newStates.emplace_back(tsit->
clone());
673 ATH_MSG_WARNING(
" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
682 *tsit, std::move(newMdt),
pars->uniqueClone(),
685 newStates.push_back(std::move(tsos));
688 newStates.emplace_back(tsit->
clone());
692 newStates.emplace_back(tsit->
clone());
695 if (doCompetingClusters) {
698 newStates.emplace_back(tsit->
clone());
702 newStates.emplace_back(tsit->
clone());
708 ATH_MSG_DEBUG(
" original track had " <<
states->size() <<
" TSOS, adding " << newStates.size() -
states->size() <<
" new TSOS ");
711 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
712 trackStateOnSurfaces->reserve(newStates.size());
713 for (std::unique_ptr<const Trk::TrackStateOnSurface>& new_state : newStates) {
715 trackStateOnSurfaces->push_back(std::move(new_state));
717 return std::make_unique<Trk::Track>(
track.info(), std::move(trackStateOnSurfaces),
718 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
724 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> >&
states)
const {
726 if (tsit == tsit_end) {
727 ATH_MSG_WARNING(
" iterator pointing to end of vector, this should no happen ");
734 if (!meas || !
pars) {
735 ATH_MSG_WARNING(
" iterator pointing to a TSOS without a measurement or TrackParameters ");
736 if (tsit + 1 == tsit_end) --tsit;
744 std::list<const Trk::PrepRawData*> etaPrds;
745 std::list<const Trk::PrepRawData*> phiPrds;
747 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> > newStates;
749 std::vector<std::pair<bool, const Trk::TrackStateOnSurface*> > outlierStates;
750 bool hasPhi {
false}, hasEta{
false};
752 for (; tsit != tsit_end; ++tsit) {
754 if (!in_tsos)
continue;
759 newStates.emplace_back(in_tsos->
clone());
765 if (!
id.is_valid()) {
766 newStates.emplace_back(in_tsos->
clone());
774 if (!hasPhi && measuresPhi) hasPhi =
true;
775 if (!hasEta && !measuresPhi) hasEta =
true;
779 outlierStates.emplace_back(measuresPhi, in_tsos);
787 std::list<const Trk::PrepRawData*>& prdList = measuresPhi ? phiPrds : etaPrds;
791 if (!currentDetEl) currentDetEl = detEl;
792 if (detEl != currentDetEl) {
802 if (
comp->containedROTs().empty()) {
806 detEl =
comp->containedROTs().front()->detectorElement();
807 if (!currentDetEl) currentDetEl = detEl;
808 if (detEl != currentDetEl) {
812 std::vector<const MuonClusterOnTrack*>::const_iterator clit =
comp->containedROTs().begin();
813 std::vector<const MuonClusterOnTrack*>::const_iterator clit_end =
comp->containedROTs().end();
814 for (; clit != clit_end; ++clit) { prdList.push_back((*clit)->prepRawData()); }
824 if (!etaPrds.empty()) {
825 std::unique_ptr<CompetingMuonClustersOnTrack> etaCompRot =
m_compRotCreator->createBroadCluster(etaPrds, 0.);
827 ATH_MSG_WARNING(
" Failed to create CompetingMuonClustersOnTrack for eta hits! ");
829 std::unique_ptr<Trk::TrackParameters> etaPars;;
831 if (etaCompRot->associatedSurface() ==
pars->associatedSurface()) {
832 etaPars =
pars->uniqueClone();
837 etaCompRot->associatedSurface(),
841 ATH_MSG_WARNING(
" Failed to calculate TrackParameters for eta hits! ");
843 std::unique_ptr<Trk::TrackStateOnSurface> tsos =
845 newStates.push_back(std::move(tsos));
850 if (!phiPrds.empty()) {
851 std::unique_ptr<CompetingMuonClustersOnTrack> phiCompRot =
m_compRotCreator->createBroadCluster(phiPrds, 0.);
853 ATH_MSG_WARNING(
" Failed to create CompetingMuonClustersOnTrack for phi hits! ");
855 std::unique_ptr<Trk::TrackParameters> phiPars;
857 if (phiCompRot->associatedSurface() ==
pars->associatedSurface()) {
858 phiPars =
pars->uniqueClone();
866 ATH_MSG_WARNING(
" Failed to calculate TrackParameters for phi hits! ");
868 std::unique_ptr<Trk::TrackStateOnSurface> tsos =
870 newStates.push_back(std::move(tsos));
876 for (
const auto& outlier : outlierStates) {
877 if (hasPhi && outlier.first)
878 newStates.emplace_back(outlier.second->clone());
879 else if (hasEta && !outlier.first)
880 newStates.emplace_back(outlier.second->clone());
889 states.insert(
states.end(), std::make_move_iterator(newStates.begin()),
890 std::make_move_iterator(newStates.end()));
910 fieldCondObj->getInitializedCache(fieldCache);
918 const std::vector<MuPatSegment*>& segVec)
const {
919 std::vector<std::unique_ptr<MuPatTrack> >
candidates;
923 std::set<MuPatSegment*> usedSegments;
924 std::map<MuPatSegment*, MuPatSegment*> slSegments;
927 bool tightQualityCuts =
false;
933 std::vector<std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> > >
extensions;
938 if (usedSegments.count(seg))
continue;
947 ATH_MSG_VERBOSE(
" track/segment combination rejected based on angular matching " << std::endl
955 std::unique_ptr<Trk::Track>
track =
combine(ctx, candidate, *seg, emptyPhiHits);
969 ATH_MSG_VERBOSE(
" rejecting track as new segment results in worse fit");
975 std::set<MuonStationIndex::StIndex> stationLayersOnTrack;
978 if (!
id.is_valid() ||
m_idHelperSvc->isTrigger(
id)) {
continue; }
979 stationLayersOnTrack.insert(
m_idHelperSvc->stationIndex(
id));
982 bool hasAllLayers =
true;
984 if (!stationLayersOnTrack.count(stIdx)) {
986 hasAllLayers =
false;
991 ATH_MSG_VERBOSE(
" rejecting track as one of the chamber layers of the candidate was removed ");
996 if (!
track) {
continue; }
998 usedSegments.insert(seg);
1002 if (!seg->hasSLOverlap()) {
1003 std::unique_ptr<MuPatTrack> newCandidate;
1007 if (seg->chIndex == seg_1->chIndex)
continue;
1009 if (!newCandidate) {
1010 std::unique_ptr<Trk::Track> trkTrkCan = std::make_unique<Trk::Track>(*
track);
1013 newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1015 }
else if (segCan) {
1018 if (!newCandidate)
break;
1021 ATH_MSG_VERBOSE(
"track/segment combination rejected based on angular matching "
1028 std::unique_ptr<Trk::Track> slOverlapTrack =
combine(ctx, *
track, *seg_1->segment, emptyPhiHits);
1029 if (!slOverlapTrack)
continue;
1034 ATH_MSG_VERBOSE(__FILE__<<
":"<<__LINE__<<
" rejecting track as new segment results in worse fit");
1038 <<
m_printer->printStations(*slOverlapTrack));
1040 track.swap(slOverlapTrack);
1041 usedSegments.insert(seg_1);
1042 slSegments[seg] = seg_1;
1065 std::unique_ptr<MuPatTrack> newCandidate;
1068 newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1069 m_candidateHandler->extendWithSegment(*newCandidate, *ext_itr.first, ext_itr.second);
1070 }
else if (segCan) {
1071 newCandidate =
m_candidateHandler->createCandidate(*segCan, *ext_itr.first, ext_itr.second);
1079 std::unique_ptr<Trk::Track> nullTrack;
1080 newCandidate->addSegment(slOverlap, nullTrack);
1082 candidates.push_back(std::move(newCandidate));
1095 if (!parsVec1 || parsVec1->
empty()) {
1101 ATH_MSG_WARNING(
" isSplitTrack::Track without NULL pointer in parameter vector! ");
1106 if (!parsVec2 || parsVec2->
empty()) {
1112 ATH_MSG_WARNING(
" isSplitTrack::Track without NULL pointer in parameter vector! ");
1121 double sinTheta1 =
sin(pars1->
momentum().theta());
1122 double sinTheta2 =
sin(pars2->
momentum().theta());
1123 double deltaSinTheta = sinTheta1 - sinTheta2;
1124 if (std::abs(deltaSinTheta) > 1.) {
1125 ATH_MSG_DEBUG(
" too large opening angle in theta " << deltaSinTheta);
1130 double deltaSinPhi = sinPhi1 - sinPhi2;
1131 if (std::abs(deltaSinPhi) > 1.) {
1132 ATH_MSG_DEBUG(
" too large opening angle in phi " << deltaSinPhi);
1144 if (isSL1 && !isSL2) {
1145 referenceTrack = &track2;
1146 otherTrack = &track1;
1147 }
else if (!isSL1 && isSL2) {
1148 referenceTrack = &track1;
1149 otherTrack = &track2;
1154 referenceTrack = &track1;
1155 otherTrack = &track2;
1157 referenceTrack = &track2;
1158 otherTrack = &track1;
1183 unsigned int nmatching(0);
1184 unsigned int noff(0);
1187 double prevDist = 1e10;
1191 while (refTSOS != refTSOS_end && otherTSOS != otherTSOS_end) {
1204 double dist = distAlongPars(*parsRef, *parsOther);
1213 if (prevPars && std::abs(prevDist) < std::abs(dist)) {
1214 closestPars = prevPars;
1216 closestPars = parsRef;
1224 if (!
id.is_valid()) {
1239 std::optional<Trk::ResidualPull> resPull =
1241 if (resPull && resPull->pull().size() == 1) {
1243 residual = resPull->residual().front();
1244 pull = resPull->pull().front();
1249 bool inBounds =
false;
1271 if (mmClusterOnTrack) {
1287 if (inBounds && (std::abs(
residual) < 20. || std::abs(
pull) < 10.)) {
1296 ATH_MSG_DEBUG(
"failed to extrapolate parameters to surface");
1308 return nmatching > noff;
1313 std::vector<std::pair<bool, std::unique_ptr<Trk::Track> > > goodTracks;
1314 goodTracks.reserve(tracks.
size());
1315 bool foundSplitTracks =
false;
1317 ATH_MSG_DEBUG(
" trying to merge split tracks, collection size " << tracks.
size());
1322 std::unique_ptr<Trk::Track> mergedTrack;
1325 for (std::pair<
bool, std::unique_ptr<Trk::Track>>& good_trk : goodTracks) {
1330 std::unique_ptr<Trk::Track> track1 = std::make_unique<Trk::Track>(*good_trk.second);
1331 std::unique_ptr<Trk::Track> track2 = std::make_unique<Trk::Track>(*in_track);
1334 mergedTrack =
combine(ctx, *can1, *can2, emptyPhiHits);
1340 <<
m_printer->print(*good_trk.second) << std::endl
1341 <<
m_printer->printStations(*good_trk.second) << std::endl
1342 <<
m_printer->print(*in_track) << std::endl
1343 <<
m_printer->printStations(*in_track) << std::endl
1344 <<
" merged track " << std::endl
1345 <<
m_printer->print(*mergedTrack) << std::endl
1346 <<
m_printer->printStations(*mergedTrack));
1347 foundSplitTracks =
true;
1349 good_trk.first =
true;
1350 good_trk.second.swap(mergedTrack);
1354 <<
m_printer->print(*good_trk.second) << std::endl
1355 <<
m_printer->printStations(*good_trk.second) << std::endl
1356 <<
m_printer->print(*in_track) << std::endl
1357 <<
m_printer->printStations(*in_track));
1364 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(*in_track);
1365 goodTracks.emplace_back(
false, std::move(newTrack));
1370 if (!foundSplitTracks)
return nullptr;
1373 newTracks->
reserve(goodTracks.size());
1374 for (std::pair<
bool, std::unique_ptr<Trk::Track>>& good_trk: goodTracks) {
1376 newTracks->
push_back(std::move(good_trk.second));