36 using namespace MuonStationIndex;
47 ATH_CHECK(m_measurementUpdator.retrieve());
48 ATH_CHECK(m_fieldCacheCondObjInputKey.initialize());
50 return StatusCode::SUCCESS;
54 const EventContext& ctx)
const {
62 std::unique_ptr<Trk::Track> cleanedTrack = cleanTrack(ctx, &
track, state);
67 std::unique_ptr<Trk::Track> cleanedTrack = cleanTrack(ctx, &
track, state);
80 unsigned int nstationsInitial = state.
stations.size();
83 std::unique_ptr<Trk::Track> chamberTrack = chamberCleaning(ctx, std::make_unique<Trk::Track>(*
track), state);
88 ATH_MSG_DEBUG(
"after chamber cleaning, track is " << m_printer->print(*chamberTrack));
91 unsigned int nstationsChamberCleaning = state.
stations.size();
92 if (nstationsInitial != nstationsChamberCleaning) {
93 if (!checkStations(state))
return nullptr;
98 if (!checkInnerConstraint(state))
return nullptr;
102 if (!checkPhiConstraint(state))
return nullptr;
105 std::unique_ptr<Trk::Track> cleanCompTrack = cleanCompROTs(ctx, std::move(chamberTrack), state);
106 if (!cleanCompTrack) {
110 ATH_MSG_DEBUG(
"after comp rot cleaning, track is " << m_printer->print(*cleanCompTrack));
113 std::unique_ptr<Trk::Track> flippedTrack = recoverFlippedMdt(ctx, std::move(cleanCompTrack), state);
118 ATH_MSG_DEBUG(
"after flipped mdt recovery, track is " << m_printer->print(*flippedTrack));
120 std::unique_ptr<Trk::Track> hitTrack = hitCleaning(ctx, std::move(flippedTrack), state);
125 ATH_MSG_DEBUG(
"after hit cleaning, track is " << m_printer->print(*hitTrack));
128 std::unique_ptr<Trk::Track> hitTrackClone = std::make_unique<Trk::Track>(*hitTrack);
131 unsigned int nstationsHitCleaning = state.
stations.size();
132 if (nstationsInitial != nstationsHitCleaning) {
133 if (!checkStations(state))
return nullptr;
138 if (!checkInnerConstraint(state))
return nullptr;
142 if (!checkPhiConstraint(state))
return nullptr;
144 std::unique_ptr<Trk::Track> cleanedTrack = outlierRecovery(ctx, std::move(hitTrack), state);
148 init(ctx, *hitTrackClone, state);
150 ATH_MSG_DEBUG(
"Outlier recovery failure unrecoverable, reject track");
153 ATH_MSG_DEBUG(
"Outlier recovery failed but initial track is recoverable");
154 cleanedTrack = std::move(hitTrackClone);
163 unsigned int nstationsFinal = state.
stations.size();
164 if (nstationsInitial != nstationsFinal) {
165 if (!checkStations(state))
return nullptr;
186 auto tsos = std::make_unique<Trk::TrackStates>();
187 tsos->reserve(state.
measInfo.size());
189 unsigned int nmeas = 0;
193 for (; hit != hit_end; ++hit) {
195 if (!hit->useInFit) {
196 ATH_MSG_DEBUG(
" removing hit " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front());
203 if (hit->meas) ++nmeas;
205 if (hit->cleanedCompROT) {
208 ATH_MSG_DEBUG(
" replacing CompROT " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front());
210 tsos->push_back(hit->originalState->clone());
221 std::unique_ptr<Trk::Track> cleanedTrack =
222 std::make_unique<Trk::Track>(
track->info(), std::move(tsos),
track->fitQuality() ?
track->fitQuality()->uniqueClone() :
nullptr);
223 printStates(cleanedTrack.get());
226 std::unique_ptr<Trk::Track> newTrack = fitTrack(ctx, *cleanedTrack,
track->info().particleHypothesis(), state.
slFit);
229 init(ctx, *newTrack, state);
247 auto tsos = std::make_unique<Trk::TrackStates>();
248 tsos->reserve(state.
measInfo.size());
250 unsigned int nmeas = 0;
254 for (; hit != hit_end; ++hit) {
256 if (!hit->useInFit) {
257 ATH_MSG_DEBUG(
" removing hit " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front());
264 if (hit->meas) ++nmeas;
266 if (hit->flippedMdt) {
269 ATH_MSG_DEBUG(
" flipping sign hit " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front());
271 tsos->push_back(hit->originalState->clone());
282 std::unique_ptr<Trk::Track> cleanedTrack =
283 std::make_unique<Trk::Track>(
track->info(), std::move(tsos),
track->fitQuality() ?
track->fitQuality()->uniqueClone() :
nullptr);
284 printStates(cleanedTrack.get());
287 std::unique_ptr<Trk::Track> newTrack = fitTrack(ctx, *cleanedTrack,
track->info().particleHypothesis(), state.
slFit);
290 init(ctx, *newTrack, state);
307 std::unique_ptr<Trk::Track> newTrack;
309 for (
unsigned int n = 0;
n < m_ncycles; ++
n) {
312 ATH_MSG_DEBUG(
" Too many outliers, cannot perform cleaning ");
318 auto tsos = std::make_unique<Trk::TrackStates>();
319 tsos->reserve(state.
measInfo.size());
322 unsigned int nmeas = 0;
323 unsigned int nremovedPhi = 0;
324 bool hasSmall =
false;
325 bool hasLarge =
false;
328 std::map<StIndex, std::pair<bool, bool> > slCountsPerStationLayer;
332 for (; hit != hit_end; ++hit) {
335 if (!hit->useInFit ||
remove) {
339 if (!hit->id.is_valid() || m_idHelperSvc->measuresPhi(hit->id)) ++nremovedPhi;
342 std::string inb = hit->inBounds ?
" inBounds" :
" outBounds";
343 ATH_MSG_DEBUG(
" removing hit " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front()
347 if (hit->cleanedCompROT) {
358 ATH_MSG_DEBUG(
" keeping hit " << m_idHelperSvc->toString(hit->id) <<
" pull " << hit->resPull->pull().front());
362 if (!hit->id.is_valid() || m_idHelperSvc->measuresPhi(hit->id)) {
369 if (hit->id.is_valid() && m_idHelperSvc->isMdt(hit->id)) {
371 bool isSmall = m_idHelperSvc->isSmallChamber(hit->id);
375 slCountsPerStationLayer.find(stIndex);
378 if (
pos == slCountsPerStationLayer.end())
379 slCountsPerStationLayer[stIndex] = std::make_pair(
isSmall, isLarge);
382 if (
isSmall) slCountsPerStationLayer[stIndex].first =
true;
383 if (isLarge) slCountsPerStationLayer[stIndex].second =
true;
387 if (!hit->originalState)
ATH_MSG_DEBUG(
"no original state!");
388 tsos->push_back(hit->originalState->clone());
392 unsigned int noverlaps = 0;
393 for (
auto [
index, slCounts] : slCountsPerStationLayer) {
394 if (!hasSmall && slCounts.first) hasSmall =
true;
395 if (!hasLarge && slCounts.second) hasLarge =
true;
396 if (slCounts.first && slCounts.second) ++noverlaps;
399 if (noverlaps == 0 && hasSmall && hasLarge) ++noverlaps;
406 ATH_MSG_DEBUG(
" nremovedPhi " << nremovedPhi <<
" noverlaps " << noverlaps <<
" nid " << state.
nIdHits);
407 if (firstPhi)
ATH_MSG_DEBUG(
" hasFirstPhi: " << m_idHelperSvc->toString(firstPhi->
id));
408 if (lastPhi)
ATH_MSG_DEBUG(
" hasLastPhi: " << m_idHelperSvc->toString(lastPhi->
id));
411 if (nremovedPhi > 0) {
412 bool hasPhiConstraint =
false;
415 hasPhiConstraint =
true;
416 else if (firstPhi && noverlaps > 0)
417 hasPhiConstraint =
true;
418 else if (noverlaps > 1)
419 hasPhiConstraint =
true;
420 else if (firstPhi && lastPhi && firstPhi->
pars && lastPhi->
pars) {
424 if (
distPhi > 450.) hasPhiConstraint =
true;
426 if (!hasPhiConstraint) {
427 ATH_MSG_DEBUG(
"Lost phi constraint during track cleaning, reject track");
433 std::unique_ptr<Trk::Track> cleanedTrack =
434 std::make_unique<Trk::Track>(
track->info(), std::move(tsos),
track->fitQuality() ?
track->fitQuality()->uniqueClone() :
nullptr);
437 printStates(cleanedTrack.get());
439 newTrack = fitTrack(ctx, *cleanedTrack,
track->info().particleHypothesis(), state.
slFit);
450 init(ctx, *newTrack, state);
473 for (; chit != chit_end; ++chit) {
475 if (m_idHelperSvc->isMdt(chid) || m_idHelperSvc->isCsc(chid)) {
476 ATH_MSG_DEBUG(
" only two precision chambers, cannot remove chamber. ");
483 unsigned int foundChambers = 0;
487 for (; chit != chit_end; ++chit) {
490 ATH_MSG_DEBUG(
" found excluded chamber " << m_idHelperSvc->toStringChamber(chid));
495 if (foundChambers > excludedChambers) {
496 ATH_MSG_WARNING(
" Found more excluded chambers than in list, this should not happen ");
498 }
else if (foundChambers == excludedChambers) {
499 ATH_MSG_DEBUG(
" all excluded chambers in removal list, failing cleaning ");
504 std::vector<ChamberRemovalOutput> cleaningResults;
516 for (; chit != chit_end; ++chit) {
519 ATH_MSG_DEBUG(
" Removed eta hits of " << m_idHelperSvc->toStringChamber(chit->second) <<
", track lost ");
522 ATH_MSG_DEBUG(
" Removed eta hits of " << m_idHelperSvc->toStringChamber(chit->second));
526 if (nchambers > 1) unremoveHits(
result);
528 cleaningResults.push_back(std::move(
result));
536 for (; chit != chit_end; ++chit) {
539 ATH_MSG_DEBUG(
" Removed phi hits of " << m_idHelperSvc->toStringChamber(chit->second) <<
", track lost ");
542 ATH_MSG_DEBUG(
" Removed phi hits of " << m_idHelperSvc->toStringChamber(chit->second));
546 if (nchambers > 1) unremoveHits(
result);
548 cleaningResults.push_back(std::move(
result));
552 if (cleaningResults.empty())
return nullptr;
554 ATH_MSG_DEBUG(
" chamberCleaning Results nr " << cleaningResults.size());
555 for (
auto&
res : cleaningResults) {
ATH_MSG_DEBUG(
" track " << m_printer->print(*
res.track)); }
560 for (
auto* hit : finalResult.
removedHits) hit->useInFit = 0;
567 std::unique_ptr<Trk::Track> finalResultTrackClone = std::make_unique<Trk::Track>(*finalResult.
track);
569 init(ctx, *finalResultTrackClone, state);
572 ChIndex removedChamberIndex = m_idHelperSvc->chamberIndex(finalResult.
chId);
573 std::unique_ptr<Trk::Track> recoveredTrack = outlierRecovery(ctx, std::move(finalResult.
track), state, &removedChamberIndex);
574 if (!recoveredTrack)
return finalResultTrackClone;
575 init(ctx, *recoveredTrack, state);
576 return recoveredTrack;
581 bool removePhi,
bool removeEta,
CleaningState& state)
const {
582 ATH_MSG_DEBUG(
" removing chamber " << m_idHelperSvc->toStringChamber(chId));
593 auto tsos = std::make_unique<Trk::TrackStates>();
594 tsos->reserve(state.
measInfo.size());
596 unsigned int nmeas = 0;
598 std::set<Identifier> stations{};
601 bool measuresPhi = m_idHelperSvc->measuresPhi(hit.
id);
602 bool remove = hit.
chId == chId && ((removePhi && measuresPhi) || (removeEta && !measuresPhi));
605 ATH_MSG_DEBUG(
" removing hit " << m_idHelperSvc->toString(hit.
id) <<
" pull " << hit.
resPull->pull().front());
621 if (m_idHelperSvc->isMdt(hit.
id)) stations.insert(m_idHelperSvc->mdtIdHelper().multilayerID(hit.
id));
623 else if (m_idHelperSvc->isCsc(hit.
id)) stations.insert(m_idHelperSvc->cscIdHelper().elementID(hit.
id));
625 else if (m_idHelperSvc->isMM(hit.
id)) stations.insert(m_idHelperSvc->mmIdHelper().multilayerID(hit.
id));
627 else if (m_idHelperSvc->issTgc(hit.
id)) stations.insert(m_idHelperSvc->stgcIdHelper().multilayerID(hit.
id));
632 if (nmeas < 6 || stations.size() < 2) {
633 ATH_MSG_DEBUG(
" too few hits, cannot perform chamberCleaning ");
638 std::unique_ptr<Trk::Track> cleanedTrack =
639 std::make_unique<Trk::Track>(
track->info(), std::move(tsos),
track->fitQuality() ?
track->fitQuality()->uniqueClone() :
nullptr);
642 printStates(cleanedTrack.get());
646 std::unique_ptr<Trk::Track> newTrack = fitTrack(ctx, *cleanedTrack,
track->info().particleHypothesis(), state.
slFit);
652 result.track = std::move(newTrack);
669 std::set<ChIndex> recoverableLayers;
675 if (currentIndex && *currentIndex != stationIndex)
continue;
678 unsigned int nhits = statistics.
nhits;
679 unsigned int noutliers = statistics.
noutliers;
682 unsigned int noutBounds = statistics.
noutBounds;
684 if (nrecoverableOutliers > 0) {
685 if (nhits + nrecoverableOutliers > 2 &&
686 ((noutBounds == 0 && noutliers == 0) || (nrecoverableOutliers != 0 && noutliers < 2))) {
687 recoverableLayers.insert(stationIndex);
695 bool addedHits =
false;
696 unsigned int removedOutOfBoundsHits(0);
698 auto tsos = std::make_unique<Trk::TrackStates>();
699 tsos->reserve(state.
measInfo.size());
705 if (recoverableLayers.count(hit.chIndex)) {
707 bool recover = !isOutsideOnTrackCut(hit.id, hit.residual, hit.pull, m_associationScaleFactor);
708 if (
recover && m_onlyUseHitErrorInRecovery && hit.pars) {
709 std::optional<const Trk::ResidualPull> resPull{
712 ATH_MSG_DEBUG(
" calculation of residual/pull failed !!!!! ");
715 recover = !isOutsideOnTrackCut(hit.id, resPull->residual().front(), std::abs(resPull->pull().front()),
717 m_associationScaleFactor);
721 ATH_MSG_DEBUG(
" adding outlier " << m_idHelperSvc->toString(hit.id) <<
" pull " << std::setw(7) << hit.pull);
722 if (hit.flippedMdt) {
723 double rDrift = hit.meas->localParameters()[
Trk::locR];
724 double rDriftFlip = hit.flippedMdt->localParameters()[
Trk::locR];
725 double rTrack = hit.pars->parameters()[
Trk::locR];
726 ATH_MSG_DEBUG(
" flipped MDT: r_orig " << rDrift <<
" flip " << rDriftFlip <<
" rTrack " << rTrack);
734 tsos->push_back(hit.originalState->clone());
739 if (m_idHelperSvc->isRpc(hit.id) || m_idHelperSvc->isTgc(hit.id) || m_idHelperSvc->isCsc(hit.id))
742 ++removedOutOfBoundsHits;
744 if (m_idHelperSvc->isRpc(hit.id) || m_idHelperSvc->isTgc(hit.id) || m_idHelperSvc->isCsc(hit.id))
746 ATH_MSG_DEBUG(
" removing out of bounds outlier " << m_idHelperSvc->toString(hit.id) <<
" pull " << std::setw(7)
750 tsos->push_back(hit.originalState->clone());
754 if (!addedHits && removedOutOfBoundsHits == 0) {
759 if (tsos->size() < 6) {
760 ATH_MSG_WARNING(
" too few hits, cannot add hits. This should not happen ");
765 std::unique_ptr<Trk::Track> cleanedTrack =
766 std::make_unique<Trk::Track>(
track->info(), std::move(tsos),
track->fitQuality() ?
track->fitQuality()->uniqueClone() :
nullptr);
769 ATH_MSG_DEBUG(
" only removed out of bound hits, returning track without new fit ");
774 printStates(cleanedTrack.get());
776 std::unique_ptr<Trk::Track> newTrack = fitTrack(ctx, *cleanedTrack,
track->info().particleHypothesis(), state.
slFit);
780 init(ctx, *newTrack, state);
825 if (!readHandle.isValid()) {
826 ATH_MSG_ERROR(
"Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
829 readHandle->getInitializedCache(fieldCache);
832 if (m_use_slFit) state.
slFit =
true;
845 std::set<int> rpcLayers;
846 std::set<int> tgcLayers;
848 double largestmdtpull = -999;
853 ATH_MSG_DEBUG(tsit->dumpType() <<
", parameters " << *tsit->trackParameters());
886 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
887 bool pseudo = !
id.is_valid();
890 if (!pseudo && !m_idHelperSvc->mdtIdHelper().is_muon(
id)) {
891 ATH_MSG_VERBOSE(
" TSOS is not a muon hit, position: r " <<
pars->position().perp() <<
" z " <<
pars->position().z());
904 Identifier chId = pseudo ?
id : m_idHelperSvc->chamberId(
id);
905 bool measuresPhi = pseudo ? true : m_idHelperSvc->measuresPhi(
id);
913 bool inBounds =
true;
915 double tol2 = 2 * tol1;
916 if (!pseudo && m_idHelperSvc->isMdt(
id)) tol1 = 5.;
926 }
else if (mmClusterOnTrack) {
936 std::optional<Trk::ResidualPull> resPull{m_pullCalculator->residualPull(
939 ATH_MSG_DEBUG(
" calculation of residual/pull failed !!!!! ");
942 int pullSize = resPull->pull().size();
943 double residual = resPull->residual().front();
944 double pull = std::abs(resPull->pull().front());
947 if (!pseudo && pullSize != 1) {
948 ATH_MSG_WARNING(
" ResidualPull vector has size " << pullSize <<
" for channel " << m_idHelperSvc->toString(
id));
952 bool isMDT = !pseudo ? m_idHelperSvc->isMdt(
id) :
false;
956 double rTrackAbs = std::abs(rTrack);
957 double flippedResidual = isMDT ? rDrift + rTrack : 1e10;
958 double flippedPull = isMDT ? std::abs(flippedResidual /
error) : 1e10;
960 bool isNoise =
false;
961 bool isOutlier = isOutsideOnTrackCut(
id,
residual,
pull, 1);
962 bool isRecoverable = m_recoverOutliers && !isOutlier && !isOutsideOnTrackCut(
id,
residual,
pull, m_associationScaleFactor);
963 bool flippedIsRecoverable =
964 isMDT && flippedPull <
pull - 0.1 && !isOutsideOnTrackCut(
id, flippedResidual, flippedPull, m_associationScaleFactor);
965 double innerRadius = 14.6;
971 bool isDelta = isOutlier && isMDT && rTrackAbs < innerRadius && rTrackAbs > std::abs(rDrift);
976 if (rTrackAbs > innerRadius) inBounds =
false;
977 }
else if (
pull > 10.) {
982 std::unique_ptr<MdtDriftCircleOnTrack> mdtRotFlipped;
983 std::unique_ptr<const CompetingMuonClustersOnTrack> updatedCompRot;
984 bool flipSign =
false;
990 isRecoverable =
false;
991 flippedIsRecoverable =
false;
994 if (flippedIsRecoverable) {
999 if (!isNoise && flipSign) {
1001 mdtRotFlipped = std::make_unique<MdtDriftCircleOnTrack>(*mdtRot);
1003 m_mdtRotCreator->updateSign(*mdtRotFlipped,
side);
1004 double rDriftFlip = mdtRotFlipped->localParameters()[
Trk::locR];
1005 int signRot = rDrift < 0 ? -1 : 1;
1006 int signRotFlip = rDriftFlip < 0 ? -1 : 1;
1007 if (rDrift != 0. && signRot == signRotFlip) {
1008 ATH_MSG_WARNING(
" failed to flip sign of MDT " << rDrift <<
" flip " << rDriftFlip);
1011 ATH_MSG_WARNING(
" failed to dynamic_cast measurement with MDT Identifier to a MdtDriftCircleOnTrack");
1016 largestmdtpull =
pull;
1022 bool isRpc = m_idHelperSvc->isRpc(
id);
1025 StIndex stIndex = m_idHelperSvc->stationIndex(
id);
1026 if (stIndex ==
StIndex::BM && m_idHelperSvc->rpcIdHelper().doubletR(
id) == 1)
1030 rpcLayers.insert(
layer);
1033 bool isTgc = m_idHelperSvc->isTgc(
id);
1036 StIndex stIndex = m_idHelperSvc->stationIndex(
id);
1038 std::string
stName = m_idHelperSvc->chamberNameString(
id);
1041 else if (
stName[1] ==
'2')
1043 else if (
stName[1] ==
'3')
1046 ATH_MSG_WARNING(
"Unable to calculate TGC layer for " << m_idHelperSvc->toString(
id));
1052 if (m_idHelperSvc->issTgc(
id)) {
1054 if (m_idHelperSvc->stgcIdHelper().multilayer(
id) == 2)
layer = 5;
1055 tgcLayers.insert(
layer);
1060 if (m_cleanCompROTs) {
1069 double absminres = 0.;
1070 double absmaxres = 0.;
1073 if (!cluster)
continue;
1082 }
else if (absres < absminres) {
1086 }
else if (absres > absmaxres) {
1094 ATH_MSG_DEBUG(
" residuals: min " << minres <<
" max " << maxres <<
" diff " << maxres - minres);
1095 bool splitCompRot =
false;
1096 if (std::abs(maxres - minres) > 100 && absmaxres - absminres > 20 && crot->
numberOfContainedROTs() < 20) {
1098 splitCompRot =
true;
1101 std::list<const Trk::PrepRawData*> prdList;
1105 if (!cluster)
continue;
1115 if (prdList.empty()) {
1116 ATH_MSG_WARNING(
"No clusters selected during comprot cleaning, keeping old cluster");
1118 updatedCompRot=m_compRotCreator->createBroadCluster(prdList, 0.);
1126 state.
measInfo.emplace_back(
id, chId,
chIndex, inBounds,
residual,
pull, tsit, meas,
pars, std::move(resPull),
nullptr);
1128 if (flipSign) {
info.flippedMdt = std::move(mdtRotFlipped); }
1129 info.isNoise = isNoise;
1130 if (updatedCompRot) {
1132 info.cleanedCompROT = std::move(updatedCompRot);
1134 std::unique_ptr<Trk::TrackParameters> exPars = m_extrapolator->extrapolate(ctx,
1135 *
pars,
info.cleanedCompROT->associatedSurface(),
1138 ATH_MSG_WARNING(
"Update of comp rot parameters failed, keeping old ones");
1139 info.cleanedCompROT.reset();
1141 info.pars = exPars.get();
1151 ATH_MSG_DEBUG(
" Outlier " << m_idHelperSvc->toString(
id) << m_printer->print(*(
info.resPull)));
1153 ATH_MSG_DEBUG(
" r_drift " << rDrift <<
" r_trk " << rTrack <<
" dr " << std::setw(7)
1160 if (flippedIsRecoverable)
1162 else if (isRecoverable)
1171 }
else if (flippedIsRecoverable || isRecoverable)
1184 ++chamberStatistics.
nhits;
1185 if (!pseudo) ++state.
nhits;
1189 std::string idString = pseudo ?
" Pseudomeasurement " : m_idHelperSvc->toString(
id);
1190 std::string boundCheck = inBounds ?
"inBounds" :
"outBounds";
1191 ATH_MSG_VERBOSE(m_printer->print(*(
info.resPull)) <<
" " << idString <<
" " << boundCheck);
1197 ATH_MSG_VERBOSE(
" r_drift " << std::setw(8) << rDrift <<
" r_trk " << std::setw(7) << rTrack <<
" dr " << std::setw(7)
1238 if (!m_idHelperSvc->isTrigger(
info.chId)) {
1241 ++pullInfoHits.
nhits;
1252 ++pullInfoTrig.
nhits;
1262 unsigned int nphiLayers = rpcLayers.size() + tgcLayers.size();
1264 if (state.
nIdHits > 0) { nphiLayers += 2; }
1267 ATH_MSG_DEBUG(
" Sufficient constraints to clean competing ROTs: trigger layers " << nphiLayers);
1275 state.
slFit =
false;
1295 std::set<Identifier> chambersToBeRemoved, chambersToBeRemovedPhi, goodEtaLayers, goodPhiLayers;
1298 extractChambersToBeRemoved(state, chambersToBeRemoved);
1301 extractChambersToBeRemoved(state, chambersToBeRemovedPhi,
true);
1307 for (; chit != chit_end; ++chit) {
1308 if (!chit->first.is_valid())
continue;
1310 bool isPrec = m_idHelperSvc->isMdt(chit->first) || m_idHelperSvc->isCsc(chit->first) || m_idHelperSvc->isMM(chit->first) ||
1311 m_idHelperSvc->issTgc(chit->first);
1313 StIndex stIndex = m_idHelperSvc->stationIndex(chit->first);
1319 ATH_MSG_DEBUG(
" chamber " << m_idHelperSvc->toStringChamber(chit->first) <<
" eta hits " << nhits.
neta <<
" outBounds "
1320 << noutBounds.
neta <<
" phi hits " << nhits.
nphi <<
" outBounds " << noutBounds.
nphi);
1321 if (nhits.
neta != 0 && nhits.
neta == noutBounds.
neta) {
1324 double fakePull = 1000. * nhits.
neta;
1325 if (!chambersToBeRemoved.count(chit->first)) {
1328 chambersToBeRemoved.insert(chit->first);
1333 for (; pIt != pIt_end; ++pIt) {
1334 if (pIt->second == chit->first && pIt->first < fakePull) {
1335 pIt->first = fakePull;
1343 if (isPrec && nhits.
neta > 0) {
1344 if (m_idHelperSvc->isSmallChamber(chit->first))
1350 if (nhits.
nphi != 0 && nhits.
nphi == noutBounds.
nphi) {
1353 double fakePull = 1000. * nhits.
nphi;
1354 if (!chambersToBeRemovedPhi.count(chit->first)) {
1357 chambersToBeRemovedPhi.insert(chit->first);
1362 for (; pIt != pIt_end; ++pIt) {
1363 if (pIt->second == chit->first) {
1364 pIt->first =
std::max(pIt->first, fakePull);
1371 if (nhits.
nphi > 0) {
1372 state.
phiLayers.insert(m_idHelperSvc->phiIndex(chit->first));
1381 double pull_precisionhits = -1.;
1383 double pull_triggerhits = -1.;
1385 double pull_phihits = -1.;
1388 << pull_precisionhits <<
" trigger eta " << pull_triggerhits <<
" phi " << pull_phihits <<
" measurements "
1389 << state.
measInfo.size() << std::endl
1390 <<
" precision chambers " << state.
pullSumPerChamber.size() <<
" hits with large pull "
1397 if (state.
stations.size() == 1 && phiPull > 5.) {
ATH_MSG_DEBUG(
" Single station track with large phi pulls!! "); }
1403 bool usePhi)
const {
1404 bool doCleaning =
false;
1411 if (!pullSumPerChamber.empty())
msg() <<
MSG::DEBUG <<
"Chamber pulls " << pullSumPerChamber.size() <<
":";
1414 double pulltot = 0.;
1415 for (; cit != cit_end; ++cit) {
1416 double avePull = cit->second.pullSum / cit->second.nhits;
1417 pulltot += cit->second.pullSum;
1418 ndof += cit->second.nhits;
1419 double avePullReduced = cit->second.nhits > 1 ? (cit->second.pullSum - cit->second.maxPull) / (cit->second.nhits - 1) : avePull;
1422 <<
" chamber " << m_idHelperSvc->toStringChamber(cit->first) <<
" pull sum " << cit->second.pullSum <<
" max pull "
1423 << cit->second.maxPull <<
" nhits " << cit->second.nhits <<
" ave pull " << avePull <<
" reduced ave pull "
1425 if (avePull > m_avePullSumPerChamberCut) {
1427 if (cit->second.nhits > 3 && avePullReduced < m_avePullSumPerChamberCut) {
1432 if (!chambersToBeRemovedSet.count(cit->first)) {
1433 chambersToBeRemoved.emplace_back(avePull, cit->first);
1434 chambersToBeRemovedSet.insert(cit->first);
1440 bool dropMore =
false;
1441 if (dropMore && pulltot * pulltot > 2. *
ndof *
ndof) {
1446 if (doCleaning && m_iterate) {
1447 cit = pullSumPerChamber.begin();
1448 for (; cit != cit_end; ++cit) {
1449 double avePull = cit->second.pullSum / cit->second.nhits;
1450 if (!chambersToBeRemovedSet.count(cit->first)) {
1451 chambersToBeRemoved.emplace_back(avePull, cit->first);
1452 chambersToBeRemovedSet.insert(cit->first);
1457 if (dropMore && doCleaning && m_iterate) {
1461 for (; cit != cit_end; ++cit) {
1462 double avePull = cit->second.pullSum / cit->second.nhits;
1463 if (!chambersToBeRemovedSet.count(cit->first)) {
1464 chambersToBeRemoved.emplace_back(avePull, cit->first);
1465 chambersToBeRemovedSet.insert(cit->first);
1474 bool isMdt =
id.is_valid() ? m_idHelperSvc->isMdt(
id) :
false;
1475 bool measuresPhi =
id.is_valid() ? m_idHelperSvc->measuresPhi(
id) :
false;
1478 double pullCut = measuresPhi ? m_pullCutPhi : m_pullCut;
1482 if (m_useMdtResiCut) {
1483 return std::abs(
res) > cutScaleFactor * m_mdtResiCut;
1485 return std::abs(
pull) > cutScaleFactor * pullCut;
1488 return std::abs(
pull) > cutScaleFactor * pullCut;
1493 std::ostringstream sout;
1495 unsigned int nhits = statistics.
nhits;
1496 unsigned int noutliers = statistics.
noutliers;
1497 unsigned int ndeltas = statistics.
ndeltas;
1499 unsigned int noutBounds = statistics.
noutBounds;
1501 sout <<
chName(statistics.
chIndex) <<
" hits " << std::setw(6) << nhits <<
" outliers " << std::setw(6)
1502 << noutliers <<
" deltas " << std::setw(6) << ndeltas <<
" recoverableOutliers " << std::setw(6) << nrecoverableOutliers
1503 <<
" outBounds " << std::setw(6) << noutBounds;
1509 unsigned int nstationsChamberCleaning = state.
stations.size();
1510 ATH_MSG_DEBUG(
" Cleaner removed full station from track: remaining layers " << nstationsChamberCleaning);
1512 if (nstationsChamberCleaning < 2) {
1513 ATH_MSG_DEBUG(
" Cleaner removed all but one station from track!!! ");
1520 unsigned int nstations = state.
stations.size();
1521 if (nstations == 1 ||
1523 ATH_MSG_DEBUG(
" Momentum measurement lost, cleaning given up ");
1539 for (
auto* hit :
result.removedHits) hit->useInFit = 1;
1546 ATH_MSG_DEBUG(
"Calling fit with hits: " << nStates<<std::endl<<m_printer->printMeasurements(*
track));
1551 return slFit ? m_slTrackFitter->fit(ctx,
track,
false, pHyp) : m_trackFitter->fit(ctx,
track,
false, pHyp);