37 std::unique_ptr<Trk::TrackParameters>
pars{};
38 std::unique_ptr<Muon::MuonClusterOnTrack> clus{};
40 using ClusterLayerMap = std::map<Identifier, PullCluster>;
49 return m_trk.trackStateOnSurfaces()->begin();
52 return m_trk.trackStateOnSurfaces()->end();
55 return m_curr_itr !=
end() ? (*m_curr_itr) :
nullptr;
62 if (m_curr_itr ==
end())
return false;
63 return (++m_curr_itr) !=
end();
66 if (!m_copiedStates.insert(tsos()).
second)
return;
67 if (
target == CopyTarget::GlobalTrkStates) m_newStates.emplace_back(tsos()->
clone());
68 else chamberStates.emplace_back(tsos()->
clone());
71 return chamberStates.empty() ? tsos()->trackParameters() : chamberStates[0]->trackParameters();
74 if (chamberStates.empty())
return;
76 m_newStates.insert(m_newStates.end(), std::make_move_iterator(chamberStates.begin()),
77 std::make_move_iterator(chamberStates.end()));
78 chamberStates.clear();
82 std::unique_ptr<Trk::TrackStates> outVec = std::make_unique<Trk::TrackStates>();
83 for (std::unique_ptr<const Trk::TrackStateOnSurface>& tsos : m_newStates){
91 declareInterface<IMuonHoleRecoveryTool>(
this);
117 return StatusCode::SUCCESS;
125 if (msVol.inside(
pars->position())) {
138 ATH_MSG_VERBOSE(
"The track state does not have an associated measurement");
155 std::set<Identifier> layerIds{};
162 layerIds.insert(measId);
166 if (!
comp) {
continue; }
187 std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), recovState.releaseStates(),
188 track.fitQuality() ?
track.fitQuality()->uniqueClone() :
nullptr);
194 std::set<Identifier> chambInStation{};
218 NewTrackStates& newStates, std::set<Identifier>& knownLayers)
const {
223 if (chHoles.empty())
return;
225 const std::vector<const MdtPrepData*> prdCandidates{loadPrepDataHits<MdtPrepData>(ctx,
m_key_mdt, chHoles)};
226 bool addedState{
false};
241 if (!surf.insideBounds(locPos)) {
242 chHoles.erase(mdtPrd->identify());
248 std::unique_ptr<MdtDriftCircleOnTrack> mdtROT{
m_mdtRotCreator->createRIO_OnTrack(*mdtPrd,
251 if (!mdtROT)
continue;
259 std::optional<const Trk::ResidualPull> resPull{
m_pullCalculator->residualPull(mdtROT.get(),
262 if (!resPull) {
continue; }
264 const double pull = resPull->pull().front();
265 const double radialResidual = std::abs(mdtROT->localParameters()[
Trk::locR]) -
266 std::abs(exPars->parameters()[
Trk::locR]);
268 unsigned int hitFlag = 1;
273 else if (radialResidual > 0.)
284 newStates.emplace_back(std::move(tsos));
288 if (prevDC->
identify() != mdtPrd->identify()) {
289 newStates.emplace_back(std::move(tsos));
291 ATH_MSG_DEBUG(
"Two hits recorded for the same tube "<<std::endl<<
293 " *** previous: "<<
m_printer->print(*prevDC));
294 std::optional<Trk::ResidualPull> prevPullObj{
m_pullCalculator->residualPull(prevDC,
297 const double prevPull = prevPullObj->pull().front();
299 if (std::abs(
pull) < std::abs(prevPull) ||
302 newStates.back() = std::move(tsos);
307 chHoles.erase(mdtPrd->identify());
308 knownLayers.insert(mdtPrd->identify());
339 states.insert(
states.end(), std::make_move_iterator(recovered.begin()),
340 std::make_move_iterator(recovered.end()));
343 const EventContext& ctx,
345 std::set<Identifier>& layIds,
357 ATH_MSG_ERROR(
"Null pointer to the read MuonDetectorManager conditions object");
361 return MuonDetMgr->getMdtReadoutElement(detElId);
363 return MuonDetMgr->getTgcReadoutElement(detElId);
365 return MuonDetMgr->getRpcReadoutElement(detElId);
367 return MuonDetMgr->getCscReadoutElement(detElId);
370 return MuonDetMgr->getsTgcReadoutElement(detElId);
372 return MuonDetMgr->getMMReadoutElement(detElId);
377 const Identifier& chId,
const std::set<Identifier>& tubeIds)
const {
380 if (!interSectSvc.isValid()) {
381 ATH_MSG_ERROR(
"Failed to retrieve chamber intersection service");
382 throw std::runtime_error(
"No chamber intersection service");
389 std::set<Identifier>
holes;
390 for (
unsigned int ii = 0; ii <
intersect.tubeIntersects().
size(); ++ii) {
393 if (tubeIds.count(tint.
tubeId)) {
continue; }
410 const std::set<Identifier>& gasGapIds)
const {
411 std::vector<const Prd*> collectedHits{};
414 return collectedHits;
417 if (!prdContainer.isPresent()) {
419 throw std::runtime_error(
"Invalid prepdata container");
422 std::set<IdentifierHash> chamberIds{};
424 std::inserter(chamberIds, chamberIds.end()),
426 return m_idHelperSvc->moduleHash(id);
430 if (!prdColl)
continue;
431 collectedHits.
reserve(collectedHits.size() + prdColl->
size());
432 for (
const Prd* prd: *prdColl) {
433 bool appendPrd{
false};
435 appendPrd = gasGapIds.count(prd->identify());
437 appendPrd = gasGapIds.count(
m_idHelperSvc->layerId(prd->identify()));
441 collectedHits.push_back(prd);
448 std::sort(collectedHits.begin(), collectedHits.end(), [](
const Prd*
a,
const Prd*
b){
449 return a->identify() < b->identify();
452 return collectedHits;
455 const std::set<Identifier>& knownLayers)
const {
456 std::set<Identifier> holeGaps{};
459 for (
int ml = 1; ml <= idHelper.numberOfMultilayers(detElId); ++ml) {
460 for (
int layer = idHelper.tubeLayerMin(detElId);
461 layer <= idHelper.tubeLayerMax(detElId); ++
layer) {
463 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
468 for (
int ml : {1 ,2}) {
470 const Identifier layerId = idHelper.channelID(detElId, ml,
gap, 1);
471 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
477 for (
int ml : {1, 2}) {
478 for (
const channelType
chType : {channelType::Strip,
484 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
490 const int gapMax{idHelper.
gasGapMax(detElId)};
491 for (
int gasgap = idHelper.
gasGapMin(detElId);
492 gasgap < gapMax; ++gasgap){
493 for (
int measPhi: {0,1}) {
495 if (gapMax == 3 && gasgap ==2 && measPhi == 1)
continue;
497 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
502 const int doubZ{idHelper.
doubletZ(detElId)};
503 const int gapMax{idHelper.
gasGapMax(detElId)};
504 for (
int phiGap = idHelper.
doubletPhi(detElId);
508 for (
int measPhi: {0, 1}) {
510 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
517 for (
bool measPhi: {
false,
true}) {
518 const Identifier layId = idHelper.channelID(detElId, 2,
layer, measPhi, 1);
519 if (!knownLayers.count(layId)) holeGaps.insert(layId);
529 std::set<Identifier>& knownLayers)
const {
531 const std::set<Identifier> missingLayers =
getHoleLayerIds(detElId, knownLayers);
532 std::vector<const Prd*> prdCandidates =
loadPrepDataHits(ctx, prdKey, missingLayers);
534 using LayerParsMap = std::map<Identifier, std::unique_ptr<Trk::TrackParameters>>;
535 LayerParsMap parsAtSurfMap{};
536 for (
const Identifier& holeId : missingLayers) {
539 std::unique_ptr<Trk::TrackParameters>
pars =
m_extrapolator->extrapolateDirectly(ctx, parsInChamb, surf,
551 bool inbounds{
false};
555 inbounds = surf.insideBounds(locExPos, 10., 10.);
560 <<
" is outside of the chamber "<<
Amg::toString(locExPos, 2));
563 parsAtSurfMap[holeId] = std::move(
pars);
565 ClusterLayerMap bestClusterInLay;
567 for (
const Prd* hit : prdCandidates) {
570 LayerParsMap::const_iterator pars_itr = parsAtSurfMap.find(layId);
571 if (pars_itr == parsAtSurfMap.end()) {
574 const std::unique_ptr<Trk::TrackParameters>& parsInLay{pars_itr->second};
575 std::unique_ptr<MuonClusterOnTrack> calibClus{};
578 parsInLay->position(),
579 parsInLay->momentum().unit()));
582 parsInLay->position(),
583 parsInLay->momentum().unit()));
585 if (!calibClus)
continue;
589 if (idHelper.channelType(hit->identify()) == sTgcIdHelper::sTgcChannelTypes::Pad){
603 const double xPull = padDist.x() / xCov;
604 const double yPull = padDist.y() / yCov;
608 <<
" covariance: ("<<xCov<<
", "<<yCov<<
")"
609 <<
" pull: ("<<xPull<<
","<<yPull<<
").");
613 const double pull = std::hypot(xPull, yPull);
616 PullCluster& bestClus = bestClusterInLay[layId];
617 if (bestClus.pull <
pull)
continue;
618 bestClus.pull =
pull;
619 bestClus.clus = std::move(calibClus);
620 bestClus.pars = parsInLay->uniqueClone();
626 std::optional<const Trk::ResidualPull> resPull{
629 if (!resPull || resPull->pull().empty()) {
633 const double pull = std::abs(resPull->pull().front());
636 if (
pull > pullCut)
continue;
638 PullCluster& bestClus = bestClusterInLay[layId];
639 if (bestClus.pull <
pull)
continue;
640 bestClus.pull =
pull;
641 bestClus.clus = std::move(calibClus);
642 bestClus.pars = parsInLay->uniqueClone();
646 for (
auto& [layerId, foundClus]: bestClusterInLay) {
649 std::move(foundClus.pars),
651 recoveredStates.emplace_back(std::move(tsos));
652 knownLayers.insert(layerId);
653 parsAtSurfMap[layerId].reset();
656 for (
auto& [layerId, exPars] : parsAtSurfMap) {
657 if (!exPars)
continue;
661 return recoveredStates;