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;