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");
391 std::set<Identifier>
holes;
392 for (
unsigned int ii = 0; ii <
intersect.tubeIntersects().
size(); ++ii) {
395 if (tubeIds.count(tint.
tubeId)) {
continue; }
412 const std::set<Identifier>& gasGapIds)
const {
413 std::vector<const Prd*> collectedHits{};
416 return collectedHits;
419 if (!prdContainer.isPresent()) {
421 throw std::runtime_error(
"Invalid prepdata container");
424 std::set<IdentifierHash> chamberIds{};
426 std::inserter(chamberIds, chamberIds.end()),
428 return m_idHelperSvc->moduleHash(id);
432 if (!prdColl)
continue;
433 collectedHits.
reserve(collectedHits.size() + prdColl->
size());
434 for (
const Prd* prd: *prdColl) {
435 bool appendPrd{
false};
437 appendPrd = gasGapIds.count(prd->identify());
439 appendPrd = gasGapIds.count(
m_idHelperSvc->layerId(prd->identify()));
443 collectedHits.push_back(prd);
450 std::sort(collectedHits.begin(), collectedHits.end(), [](
const Prd*
a,
const Prd*
b){
451 return a->identify() < b->identify();
454 return collectedHits;
457 const std::set<Identifier>& knownLayers)
const {
458 std::set<Identifier> holeGaps{};
461 for (
int ml = 1; ml <= idHelper.numberOfMultilayers(detElId); ++ml) {
462 for (
int layer = idHelper.tubeLayerMin(detElId);
463 layer <= idHelper.tubeLayerMax(detElId); ++
layer) {
465 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
470 for (
int ml : {1 ,2}) {
472 const Identifier layerId = idHelper.channelID(detElId, ml,
gap, 1);
473 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
479 for (
int ml : {1, 2}) {
480 for (
const channelType
chType : {channelType::Strip,
486 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
492 const int gapMax{idHelper.
gasGapMax(detElId)};
493 for (
int gasgap = idHelper.
gasGapMin(detElId);
494 gasgap < gapMax; ++gasgap){
495 for (
int measPhi: {0,1}) {
497 if (gapMax == 3 && gasgap ==2 && measPhi == 1)
continue;
499 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
504 const int doubZ{idHelper.
doubletZ(detElId)};
505 const int gapMax{idHelper.
gasGapMax(detElId)};
506 for (
int phiGap = idHelper.
doubletPhi(detElId);
510 for (
int measPhi: {0, 1}) {
512 if (!knownLayers.count(layerId)) holeGaps.insert(layerId);
519 for (
bool measPhi: {
false,
true}) {
520 const Identifier layId = idHelper.channelID(detElId, 2,
layer, measPhi, 1);
521 if (!knownLayers.count(layId)) holeGaps.insert(layId);
531 std::set<Identifier>& knownLayers)
const {
533 const std::set<Identifier> missingLayers =
getHoleLayerIds(detElId, knownLayers);
534 std::vector<const Prd*> prdCandidates =
loadPrepDataHits(ctx, prdKey, missingLayers);
536 using LayerParsMap = std::map<Identifier, std::unique_ptr<Trk::TrackParameters>>;
537 LayerParsMap parsAtSurfMap{};
538 for (
const Identifier& holeId : missingLayers) {
541 std::unique_ptr<Trk::TrackParameters>
pars =
m_extrapolator->extrapolateDirectly(ctx, parsInChamb, surf,
553 bool inbounds{
false};
557 inbounds = surf.insideBounds(locExPos, 10., 10.);
562 <<
" is outside of the chamber "<<
Amg::toString(locExPos, 2));
565 parsAtSurfMap[holeId] = std::move(
pars);
567 ClusterLayerMap bestClusterInLay;
569 for (
const Prd* hit : prdCandidates) {
572 LayerParsMap::const_iterator pars_itr = parsAtSurfMap.find(layId);
573 if (pars_itr == parsAtSurfMap.end()) {
576 const std::unique_ptr<Trk::TrackParameters>& parsInLay{pars_itr->second};
577 std::unique_ptr<MuonClusterOnTrack> calibClus{};
580 parsInLay->position(),
581 parsInLay->momentum().unit()));
584 parsInLay->position(),
585 parsInLay->momentum().unit()));
587 if (!calibClus)
continue;
591 if (idHelper.channelType(hit->identify()) == sTgcIdHelper::sTgcChannelTypes::Pad){
605 const double xPull = padDist.x() / xCov;
606 const double yPull = padDist.y() / yCov;
610 <<
" covariance: ("<<xCov<<
", "<<yCov<<
")"
611 <<
" pull: ("<<xPull<<
","<<yPull<<
").");
615 const double pull = std::hypot(xPull, yPull);
618 PullCluster& bestClus = bestClusterInLay[layId];
619 if (bestClus.pull <
pull)
continue;
620 bestClus.pull =
pull;
621 bestClus.clus = std::move(calibClus);
622 bestClus.pars = parsInLay->uniqueClone();
628 std::optional<const Trk::ResidualPull> resPull{
631 if (!resPull || resPull->pull().empty()) {
635 const double pull = std::abs(resPull->pull().front());
638 if (
pull > pullCut)
continue;
640 PullCluster& bestClus = bestClusterInLay[layId];
641 if (bestClus.pull <
pull)
continue;
642 bestClus.pull =
pull;
643 bestClus.clus = std::move(calibClus);
644 bestClus.pars = parsInLay->uniqueClone();
648 for (
auto& [layerId, foundClus]: bestClusterInLay) {
651 std::move(foundClus.pars),
653 recoveredStates.emplace_back(std::move(tsos));
654 knownLayers.insert(layerId);
655 parsAtSurfMap[layerId].reset();
658 for (
auto& [layerId, exPars] : parsAtSurfMap) {
659 if (!exPars)
continue;
663 return recoveredStates;