794 state.nscatterers = 0;
795 state.numberOfFlippedMdts = 0;
796 state.numberOfCleanedCompROTs = 0;
799 state.pullSum = ChamberPullInfo();
800 state.pullSumPhi = ChamberPullInfo();
801 state.pullSumTrigEta = ChamberPullInfo();
802 state.chambersToBeRemoved.clear();
803 state.chambersToBeRemovedPhi.clear();
804 state.pullSumPerChamber.clear();
805 state.pullSumPerChamberPhi.clear();
806 state.pullSumPerChamberEta.clear();
807 state.hitsPerChamber.clear();
808 state.outBoundsPerChamber.clear();
809 state.measInfo.clear();
810 state.largePullMeasurements.clear();
811 state.chamberLayerStatistics.clear();
812 state.stations.clear();
813 state.phiLayers.clear();
814 state.hasOfBoundsOutliers =
false;
815 state.hasVertexConstraint =
false;
816 state.hasSmall =
false;
817 state.hasLarge =
false;
819 state.nPseudoMeasurements = 0;
820 state.nPhiConstraints = 0;
825 if (!readHandle.isValid()) {
829 readHandle->getInitializedCache(fieldCache);
843 state.measInfo.reserve(
states->size());
845 std::set<int> rpcLayers;
846 std::set<int> tgcLayers;
848 double largestmdtpull = -999;
853 ATH_MSG_DEBUG(tsit->dumpType() <<
", parameters " << *tsit->trackParameters());
856 state.measInfo.emplace_back(tsit);
875 state.measInfo.emplace_back(tsit);
882 state.measInfo.emplace_back(tsit);
887 bool pseudo = !
id.is_valid();
888 if (pseudo) ++state.nPseudoMeasurements;
891 ATH_MSG_VERBOSE(
" TSOS is not a muon hit, position: r " <<
pars->position().perp() <<
" z " <<
pars->position().z());
895 state.measInfo.emplace_back(tsit);
901 state.hasVertexConstraint =
true;
905 bool measuresPhi = pseudo ? true :
m_idHelperSvc->measuresPhi(
id);
913 bool inBounds =
true;
915 double tol2 = 2 * tol1;
921 const MMClusterOnTrack* mmClusterOnTrack =
dynamic_cast<const MMClusterOnTrack*
>(meas);
926 }
else if (mmClusterOnTrack) {
928 inBounds = mmClusterOnTrack->detectorElement()->insideActiveBounds(
id, locPos, tol1, tol2);
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) {
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;
963 bool flippedIsRecoverable =
965 double innerRadius = 14.6;
967 const MdtDriftCircleOnTrack* mdtdc =
dynamic_cast<const MdtDriftCircleOnTrack*
>(meas);
968 if (mdtdc) innerRadius = mdtdc->detectorElement()->innerTubeRadius();
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;
986 const MdtDriftCircleOnTrack* mdtRot = isMDT ?
dynamic_cast<const MdtDriftCircleOnTrack*
>(meas) :
nullptr;
987 if (mdtRot && mdtRot->prepRawData() && mdtRot->prepRawData()->adc() <
m_adcCut) {
990 isRecoverable =
false;
991 flippedIsRecoverable =
false;
994 if (flippedIsRecoverable) {
999 if (!isNoise && flipSign) {
1001 mdtRotFlipped = std::make_unique<MdtDriftCircleOnTrack>(*mdtRot);
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;
1030 rpcLayers.insert(
layer);
1041 else if (
stName[1] ==
'2')
1043 else if (
stName[1] ==
'3')
1055 tgcLayers.insert(
layer);
1061 const CompetingMuonClustersOnTrack* crot = (measuresPhi && !isMDT &&
m_idHelperSvc->isRpc(
id))
1062 ?
dynamic_cast<const CompetingMuonClustersOnTrack*
>(meas)
1065 ATH_MSG_DEBUG(
" CompetingMuonClustersOnTrack with rots " << crot->numberOfContainedROTs());
1069 double absminres = 0.;
1070 double absmaxres = 0.;
1071 for (
unsigned int i = 0;
i < crot->numberOfContainedROTs(); ++
i) {
1072 const MuonClusterOnTrack* cluster = &crot->rioOnTrack(
i);
1073 if (!cluster)
continue;
1079 minpos = cluster->localParameters()[
Trk::locX];
1082 }
else if (absres < absminres) {
1085 minpos = cluster->localParameters()[
Trk::locX];
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;
1103 for (
unsigned int i = 0;
i < crot->numberOfContainedROTs(); ++
i) {
1104 const MuonClusterOnTrack* cluster = &crot->rioOnTrack(
i);
1105 if (!cluster)
continue;
1110 << cluster->localParameters()[
Trk::locX] <<
" pars "
1112 prdList.push_back(cluster->prepRawData());
1115 if (prdList.empty()) {
1116 ATH_MSG_WARNING(
"No clusters selected during comprot cleaning, keeping old cluster");
1119 ++state.numberOfCleanedCompROTs;
1126 state.measInfo.emplace_back(
id, chId,
chIndex, inBounds,
residual,
pull, tsit, meas,
pars, std::move(resPull),
nullptr);
1127 MCTBCleaningInfo&
info = state.measInfo.back();
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();
1142 state.parsToBeDeleted.emplace_back(std::move(exPars));
1147 ChamberLayerStatistics& chamberStatistics = state.chamberLayerStatistics[
chIndex];
1148 chamberStatistics.chIndex =
chIndex;
1153 ATH_MSG_DEBUG(
" r_drift " << rDrift <<
" r_trk " << rTrack <<
" dr " << std::setw(7)
1160 if (flippedIsRecoverable)
1162 else if (isRecoverable)
1169 state.hasOfBoundsOutliers =
true;
1170 ++chamberStatistics.noutBounds;
1171 }
else if (flippedIsRecoverable || isRecoverable)
1172 ++chamberStatistics.nrecoverableOutliers;
1174 ++chamberStatistics.ndeltas;
1176 ++chamberStatistics.noutliers;
1178 if (!pseudo) ++state.noutliers;
1184 ++chamberStatistics.nhits;
1185 if (!pseudo) ++state.nhits;
1187 if (flipSign) ++state.numberOfFlippedMdts;
1189 std::string idString = pseudo ?
" Pseudomeasurement " :
m_idHelperSvc->toString(
id);
1190 std::string boundCheck = inBounds ?
"inBounds" :
"outBounds";
1197 ATH_MSG_VERBOSE(
" r_drift " << std::setw(8) << rDrift <<
" r_trk " << std::setw(7) << rTrack <<
" dr " << std::setw(7)
1204 const RpcClusterOnTrack* rpc =
dynamic_cast<const RpcClusterOnTrack*
>(meas);
1206 const CompetingMuonClustersOnTrack* crot =
dynamic_cast<const CompetingMuonClustersOnTrack*
>(meas);
1207 if (crot) { rpc =
dynamic_cast<const RpcClusterOnTrack*
>(crot->containedROTs().front()); }
1209 if (rpc)
ATH_MSG_DEBUG(
" time " << rpc->prepRawData()->time() - rpc->globalPosition().mag() / 300.);
1214 if (!isNoise && isOutlier) { state.largePullPseudoMeasurements.insert(meas); }
1219 EtaPhiHits&
hits = state.hitsPerChamber[
info.chId];
1227 EtaPhiHits& outHits = state.outBoundsPerChamber[
info.chId];
1239 ChamberPullInfo& pullInfoHits = measuresPhi ? state.pullSumPhi : state.pullSum;
1240 pullInfoHits.pullSum +=
pull;
1241 ++pullInfoHits.nhits;
1242 if (
pull > pullInfoHits.maxPull) pullInfoHits.maxPull =
pull;
1244 ChamberPullInfo& pullInfoCh = measuresPhi ? state.pullSumPerChamberPhi[
info.chId] : state.pullSumPerChamber[
info.chId];
1245 pullInfoCh.pullSum +=
pull;
1247 if (
pull > pullInfoCh.maxPull) pullInfoCh.maxPull =
pull;
1249 ChamberPullInfo& pullInfoTrig = measuresPhi ? state.pullSumPhi : state.pullSumTrigEta;
1250 if (!measuresPhi) state.pullSumPerChamberEta[
info.chId];
1251 pullInfoTrig.pullSum +=
pull;
1252 ++pullInfoTrig.nhits;
1253 if (
pull > pullInfoTrig.maxPull) pullInfoTrig.maxPull =
pull;
1259 if (mdtmeas) state.largePullMeasurements.insert(mdtmeas);
1262 unsigned int nphiLayers = rpcLayers.size() + tgcLayers.size();
1263 if (state.hasVertexConstraint) { nphiLayers += 1; }
1264 if (state.nIdHits > 0) { nphiLayers += 2; }
1266 if ((nphiLayers > 2) && state.numberOfCleanedCompROTs > 0) {
1267 ATH_MSG_DEBUG(
" Sufficient constraints to clean competing ROTs: trigger layers " << nphiLayers);
1270 state.numberOfCleanedCompROTs = 0;
1274 if (!
m_use_slFit && state.slFit && (state.hasVertexConstraint || state.nIdHits > 0) && fieldCache.
solenoidOn()) {
1275 state.slFit =
false;
1278 if (state.hasVertexConstraint || state.nIdHits) {
1279 if (state.hasVertexConstraint)
ATH_MSG_DEBUG(
" Track has vertex contraint:");
1280 if (state.nIdHits > 0)
ATH_MSG_DEBUG(
" Track has ID Hits: " << state.nIdHits);
1295 std::set<Identifier> chambersToBeRemoved, chambersToBeRemovedPhi, goodEtaLayers, goodPhiLayers;
1307 for (; chit != chit_end; ++chit) {
1308 if (!chit->first.is_valid())
continue;
1314 state.stations.insert(stIndex);
1317 EtaPhiHits& nhits = chit->second;
1318 EtaPhiHits& noutBounds = state.outBoundsPerChamber[chit->first];
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)) {
1327 state.chambersToBeRemoved.emplace_back(fakePull, chit->first);
1328 chambersToBeRemoved.insert(chit->first);
1331 PullChIt pIt = state.chambersToBeRemoved.begin();
1332 PullChIt pIt_end = state.chambersToBeRemoved.end();
1333 for (; pIt != pIt_end; ++pIt) {
1334 if (pIt->second == chit->first && pIt->first < fakePull) {
1335 pIt->first = fakePull;
1341 if (noutBounds.neta != 0)
ATH_MSG_DEBUG(
" --> Some eta hits out of bounds ");
1343 if (isPrec && nhits.neta > 0) {
1345 state.hasSmall =
true;
1347 state.hasLarge =
true;
1350 if (nhits.nphi != 0 && nhits.nphi == noutBounds.nphi) {
1353 double fakePull = 1000. * nhits.nphi;
1354 if (!chambersToBeRemovedPhi.count(chit->first)) {
1356 state.chambersToBeRemovedPhi.emplace_back(fakePull, chit->first);
1357 chambersToBeRemovedPhi.insert(chit->first);
1360 PullChIt pIt = state.chambersToBeRemovedPhi.begin();
1361 PullChIt pIt_end = state.chambersToBeRemovedPhi.end();
1362 for (; pIt != pIt_end; ++pIt) {
1363 if (pIt->second == chit->first) {
1364 pIt->first =
std::max(pIt->first, fakePull);
1370 if (noutBounds.nphi != 0)
ATH_MSG_DEBUG(
" --> Some phi hits out of bounds ");
1371 if (nhits.nphi > 0) {
1372 state.phiLayers.insert(
m_idHelperSvc->phiIndex(chit->first));
1377 state.nPhiConstraints = state.phiLayers.size() + state.nPseudoMeasurements;
1378 if (state.hasLarge && state.hasSmall) ++state.nPhiConstraints;
1379 if (state.stations.size() == 1 && nphiLayers > 1) ++state.nPhiConstraints;
1381 double pull_precisionhits = -1.;
1382 if (state.pullSum.nhits != 0) { pull_precisionhits = state.pullSum.pullSum / state.pullSum.nhits; }
1383 double pull_triggerhits = -1.;
1384 if (state.pullSumTrigEta.nhits != 0) { pull_triggerhits = state.pullSumTrigEta.pullSum / state.pullSumTrigEta.nhits; }
1385 double pull_phihits = -1.;
1386 if (state.pullSumPhi.nhits != 0) { pull_phihits = state.pullSumPhi.pullSum / state.pullSumPhi.nhits; }
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 "
1391 << state.largePullMeasurements.size() <<
" pseudos with large pull " << state.largePullPseudoMeasurements.size()
1392 <<
" chambers to be removed " << state.chambersToBeRemoved.size() <<
" phi " << state.chambersToBeRemovedPhi.size()
1393 <<
" phi lay " << state.phiLayers.size() <<
" phi constr " << state.nPhiConstraints);
1395 if (state.pullSumPhi.nhits != 0) {
1396 double phiPull = state.pullSumPhi.pullSum / state.pullSumPhi.nhits;
1397 if (state.stations.size() == 1 && phiPull > 5.) {
ATH_MSG_DEBUG(
" Single station track with large phi pulls!! "); }