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);
 
  119         return StatusCode::SUCCESS;
 
  127             if (msVol.inside(
pars->position())) {
 
  140                 ATH_MSG_VERBOSE(
"The track state does not have an associated measurement");
 
  157         std::set<Identifier> layerIds{};
 
  164             layerIds.insert(measId);
 
  168             if (!
comp) { 
continue; }
 
  189         std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(
track.info(), recovState.releaseStates(),
 
  190                                                                             track.fitQuality() ? 
track.fitQuality()->uniqueClone() : 
nullptr);
 
  196         std::set<Identifier> chambInStation{};
 
  220                                                      NewTrackStates& newStates, std::set<Identifier>& knownLayers)
 const {
 
  225         if (chHoles.empty()) 
return;
 
  227         const std::vector<const MdtPrepData*> prdCandidates{loadPrepDataHits<MdtPrepData>(ctx, 
m_key_mdt, chHoles)};
 
  228         bool addedState{
false};
 
  243             if (!surf.insideBounds(locPos)) {
 
  244                 chHoles.erase(mdtPrd->identify());
 
  250             std::unique_ptr<MdtDriftCircleOnTrack> mdtROT{
m_mdtRotCreator->createRIO_OnTrack(*mdtPrd,
 
  253             if (!mdtROT) 
continue;
 
  261             std::optional<const Trk::ResidualPull> resPull{
m_pullCalculator->residualPull(mdtROT.get(),
 
  264             if (!resPull) { 
continue; }
 
  266             const double pull = resPull->pull().front();
 
  267             const double radialResidual = std::abs(mdtROT->localParameters()[
Trk::locR]) -
 
  268                                           std::abs(exPars->parameters()[
Trk::locR]);
 
  270             unsigned int hitFlag = 1;
 
  275             else if (radialResidual > 0.)
 
  286                 newStates.emplace_back(std::move(tsos));
 
  290                 if (prevDC->
identify() != mdtPrd->identify()) {
 
  291                     newStates.emplace_back(std::move(tsos));
 
  293                     ATH_MSG_DEBUG(
"Two hits recorded for the same tube "<<std::endl<<
 
  295                                  " *** previous: "<<
m_printer->print(*prevDC));
 
  296                     std::optional<Trk::ResidualPull> prevPullObj{
m_pullCalculator->residualPull(prevDC,
 
  299                     const double prevPull = prevPullObj->pull().front();
 
  301                     if (std::abs(
pull) < std::abs(prevPull) ||
 
  304                         newStates.back() = std::move(tsos);
 
  309             chHoles.erase(mdtPrd->identify());
 
  310             knownLayers.insert(mdtPrd->identify());
 
  341         states.insert(
states.end(), std::make_move_iterator(recovered.begin()),
 
  342                                     std::make_move_iterator(recovered.end()));
 
  345                                                                       const EventContext& ctx,
 
  347                                                                       std::set<Identifier>& layIds,
 
  359             ATH_MSG_ERROR(
"Null pointer to the read MuonDetectorManager conditions object");
 
  363             return MuonDetMgr->getMdtReadoutElement(detElId);
 
  365             return MuonDetMgr->getTgcReadoutElement(detElId);
 
  367             return MuonDetMgr->getRpcReadoutElement(detElId);
 
  369             return MuonDetMgr->getCscReadoutElement(detElId);
 
  372             return MuonDetMgr->getsTgcReadoutElement(detElId);
 
  374             return MuonDetMgr->getMMReadoutElement(detElId);
 
  379                                                                         const Identifier& chId, 
const std::set<Identifier>& tubeIds)
 const {
 
  382         if (!interSectSvc.isValid())   {
 
  383             ATH_MSG_ERROR(
"Failed to retrieve chamber intersection service");
 
  384             throw std::runtime_error(
"No chamber intersection service");
 
  394         std::set<Identifier> 
holes;
 
  395         for (
unsigned int ii = 0; ii < 
intersect.tubeIntersects().
size(); ++ii) {
 
  398             if (tubeIds.count(tint.
tubeId)) { 
continue; }
 
  415                                                                                                const std::set<Identifier>& gasGapIds)
 const {
 
  416         std::vector<const Prd*> collectedHits{};
 
  419             return collectedHits;
 
  422         if (!prdContainer.isPresent()) {
 
  424             throw std::runtime_error(
"Invalid prepdata container");
 
  427         std::set<IdentifierHash> chamberIds{};
 
  429                             std::inserter(chamberIds, chamberIds.end()),
 
  431                                     return m_idHelperSvc->moduleHash(id);
 
  435             if (!prdColl) 
continue;
 
  436             collectedHits.
reserve(collectedHits.size() + prdColl->
size());
 
  437             for (
const Prd* prd: *prdColl) {
 
  438                 bool appendPrd{
false};
 
  440                     appendPrd = gasGapIds.count(prd->identify());
 
  442                     appendPrd = gasGapIds.count(
m_idHelperSvc->layerId(prd->identify()));
 
  446                     collectedHits.push_back(prd);
 
  453             std::sort(collectedHits.begin(), collectedHits.end(), [](
const Prd* 
a, 
const Prd* 
b){
 
  454                 return a->identify() < b->identify();
 
  457         return collectedHits;
 
  460                                                                       const std::set<Identifier>& knownLayers)
 const {
 
  461          std::set<Identifier> holeGaps{};
 
  464             for (
int ml = 1; ml <= idHelper.numberOfMultilayers(detElId); ++ml) {
 
  465                 for (
int layer = idHelper.tubeLayerMin(detElId);
 
  466                          layer <= idHelper.tubeLayerMax(detElId); ++
layer) {
 
  468                     if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
 
  473             for (
int ml : {1 ,2}) {
 
  475                     const Identifier layerId = idHelper.channelID(detElId, ml, 
gap, 1);
 
  476                     if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
 
  482             for (
int ml : {1, 2}) {
 
  483                 for (
const channelType 
chType : {channelType::Strip,
 
  489                         if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
 
  495             const int gapMax{idHelper.
gasGapMax(detElId)};
 
  496             for (
int gasgap = idHelper.
gasGapMin(detElId);
 
  497                      gasgap < gapMax; ++gasgap){
 
  498                 for (
int measPhi: {0,1}) {
 
  500                     if (gapMax == 3 && gasgap ==2 && measPhi == 1) 
continue;
 
  502                     if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
 
  507             const int doubZ{idHelper.
doubletZ(detElId)};
 
  508             const int gapMax{idHelper.
gasGapMax(detElId)};
 
  509             for (
int phiGap = idHelper.
doubletPhi(detElId);
 
  513                     for (
int measPhi: {0, 1}) {
 
  515                         if (!knownLayers.count(layerId)) holeGaps.insert(layerId);  
 
  522                 for (
bool measPhi: {
false, 
true}) {
 
  523                     const Identifier layId = idHelper.channelID(detElId, 2, 
layer, measPhi, 1);
 
  524                     if (!knownLayers.count(layId)) holeGaps.insert(layId);
 
  534                                                                                             std::set<Identifier>& knownLayers)
 const {
 
  536         const std::set<Identifier> missingLayers = 
getHoleLayerIds(detElId, knownLayers);
 
  537         std::vector<const Prd*> prdCandidates = 
loadPrepDataHits(ctx, prdKey, missingLayers);
 
  539         using LayerParsMap = std::map<Identifier, std::unique_ptr<Trk::TrackParameters>>;
 
  540         LayerParsMap parsAtSurfMap{};
 
  541         for (
const Identifier& holeId : missingLayers) {
 
  544             std::unique_ptr<Trk::TrackParameters> 
pars = 
m_extrapolator->extrapolateDirectly(ctx, parsInChamb, surf,
 
  556             bool inbounds{
false};
 
  560                 inbounds = surf.insideBounds(locExPos, 10., 10.);
 
  565                               <<
" is outside of the chamber "<<
Amg::toString(locExPos, 2));
 
  568             parsAtSurfMap[holeId] = std::move(
pars);
 
  570         ClusterLayerMap bestClusterInLay;
 
  572         for (
const Prd* hit : prdCandidates) {
 
  575             LayerParsMap::const_iterator pars_itr = parsAtSurfMap.find(layId);
 
  576             if (pars_itr == parsAtSurfMap.end()) {
 
  579             const std::unique_ptr<Trk::TrackParameters>& parsInLay{pars_itr->second};
 
  580             std::unique_ptr<MuonClusterOnTrack> calibClus{};
 
  583                                                                    parsInLay->position(),
 
  584                                                                    parsInLay->momentum().unit()));
 
  587                                                                     parsInLay->position(),
 
  588                                                                     parsInLay->momentum().unit()));
 
  590             if (!calibClus) 
continue;
 
  594                 if (idHelper.channelType(hit->identify()) == sTgcIdHelper::sTgcChannelTypes::Pad){
 
  608                     const double xPull = padDist.x() / xCov;
 
  609                     const double yPull = padDist.y() / yCov;
 
  613                                  <<
" covariance: ("<<xCov<<
", "<<yCov<<
")" 
  614                                  <<
" pull: ("<<xPull<<
","<<yPull<<
").");
 
  618                     const double pull = std::hypot(xPull, yPull);
 
  621                     PullCluster& bestClus = bestClusterInLay[layId];
 
  622                     if (bestClus.pull < 
pull) 
continue;
 
  623                     bestClus.pull = 
pull;
 
  624                     bestClus.clus = std::move(calibClus);
 
  625                     bestClus.pars = parsInLay->uniqueClone();
 
  631             std::optional<const Trk::ResidualPull> resPull{
 
  634             if (!resPull || resPull->pull().empty()) {
 
  638             const double pull = std::abs(resPull->pull().front());
 
  641             if (
pull > pullCut) 
continue;
 
  643             PullCluster& bestClus = bestClusterInLay[layId];
 
  644             if (bestClus.pull < 
pull) 
continue;
 
  645             bestClus.pull = 
pull;
 
  646             bestClus.clus = std::move(calibClus);
 
  647             bestClus.pars = parsInLay->uniqueClone();
 
  651         for (
auto& [layerId, foundClus]: bestClusterInLay) {
 
  654                                                                                             std::move(foundClus.pars),
 
  656             recoveredStates.emplace_back(std::move(tsos));
 
  657             knownLayers.insert(layerId);
 
  658             parsAtSurfMap[layerId].reset();
 
  661         for (
auto& [layerId, exPars] : parsAtSurfMap) {
 
  662             if (!exPars) 
continue;
 
  666         return recoveredStates;