14 #include "Acts/Utilities/Helpers.hpp"
17 constexpr
double resetVal = 1.e10;
22 using namespace SegmentFit;
28 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
30 return StatusCode::SUCCESS;
34 cfg.nBinsX = m_nBinsTanPhi;
35 cfg.nBinsY = m_nBinsIntercept;
39 peakFinderCfg.fractionCutoff = 0.4;
40 peakFinderCfg.threshold = 2;
41 peakFinderCfg.minSpacingBetweenPeaks = {0., 30.};
42 data.houghPlane = std::make_unique<HoughPlane>(
cfg);
43 data.peakFinder = std::make_unique<ActsPeakFinderForMuon>(peakFinderCfg);
48 std::unordered_map<const xAOD::UncalibratedMeasurement*, bool> foundEtas;
51 if (hit->measuresEta() && hit->measuresPhi()) {
52 auto [
iter, added] = foundEtas.emplace(hit->primaryMeasurement(),
false);
56 iter->second |= phiMaximum.hitIdentifiers.count(hit);
60 return std::ranges::count_if(foundEtas,
61 [](
const std::pair<const xAOD::UncalibratedMeasurement*, bool>&
p) {
65 std::unique_ptr<SegmentSeed>
67 const ActsPeakFinderForMuon::Maximum & phiMax)
const {
69 std::vector<HoughHitType> hitsOnMax{};
72 std::back_inserter(hitsOnMax), [](
const HoughHitType &hit){
73 return (hit->measuresEta() && !hit->measuresPhi());
76 hitsOnMax.insert(hitsOnMax.end(), phiMax.hitIdentifiers.begin(), phiMax.hitIdentifiers.end());
79 std::ranges::stable_sort(hitsOnMax,
sorter);
80 return std::make_unique<SegmentSeed>(
etaMax.tanBeta(),
etaMax.interceptY(), phiMax.x, phiMax.y, hitsOnMax.size(), std::move(hitsOnMax),
etaMax.parentBucket());
93 if (!hit->measuresPhi()) {
97 const Amg::Vector3D extrapDir = (hit->localPosition() - hit->msSector()->globalToLocalTrans(gctx).translation()).
unit();
100 std::optional<double> dummyIntercept = Amg::intersect<3>(hit->localPosition(), extrapDir, Amg::Vector3D::UnitZ(),0);
101 double x0 = (hit->localPosition() + dummyIntercept.value_or(0) * extrapDir).
x();
112 double searchStart = chamberCenter - 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
113 double searchEnd = chamberCenter + 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
120 double searchStartTanPhi = tanPhiMean - 0.5 * eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
121 double searchEndTanPhi = tanPhiMean + 0.5* eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
122 searchStartTanPhi =
std::min(searchStartTanPhi, eventData.
searchSpaceTanAngle.first- m_minSigmasSearchTanPhi * m_targetResoTanPhi);
127 Acts::HoughTransformUtils::HoughAxisRanges{searchStartTanPhi, searchEndTanPhi, searchStart, searchEnd};
128 ATH_MSG_VERBOSE(
"Accumulator search window: tanAlpha: ["<<searchStartTanPhi<<
";"<<searchEndTanPhi<<
"], x0: ["
129 <<searchStart<<
";"<<searchEnd<<
"]");
132 std::vector<ActsPeakFinderForMuon::Maximum>
135 std::unordered_map<int, std::vector<ActsPeakFinderForMuon::Maximum>> rankedSeeds;
136 using namespace std::placeholders;
141 if (!hit->measuresPhi()) {
142 ATH_MSG_VERBOSE(
"Hit "<<m_idHelperSvc->toString(hit->identify())<<
" does not have a phi measurement");
152 (hit->measuresEta() ? 2.0 : 1.0) / (m_downWeightMultiplePrd? hit->nPhiInstanceCounts() : 1)
157 if (m_visionTool.isEnabled()) {
162 for (
const auto& solution : foundMaxPhi) {
165 rankedSeeds[countIncompatibleEtaHits(solution, maximum)].push_back(solution);
168 auto best = rankedSeeds.begin();
170 if (
best != rankedSeeds.end() &&
best->first <= m_maxEtaHolesOnMax){
175 std::unique_ptr<SegmentSeed>
183 data.searchSpaceTanAngle.first,
184 data.searchSpaceIntercept.first,
204 prepareHoughPlane(eventData);
208 ATH_CHECK(writeMaxima.record(std::make_unique<SegmentSeedContainer>()));
213 ATH_MSG_VERBOSE(
"Search extra phi hits on maximum "<<
max->msSector()->identString()<<
", tanBeta: "<<
max->tanBeta()
214 <<
", y0: "<<
max->interceptY());
216 for (
const auto& truth : m_visionTool->getLabeledSegments(
max->getHitsInMax())) {
223 preProcessMaximum(*gctx, *
max, eventData);
224 bool foundSolution=
false;
226 if (eventData.phiHitsOnMax > 1){
227 std::vector<ActsPeakFinderForMuon::Maximum> rankedSeeds = findRankedSegmentSeeds(ctx, eventData, *
max);
228 for (
auto & phiSolution : rankedSeeds){
229 foundSolution =
true;
230 const SegmentSeed* seed {writeMaxima->push_back(buildSegmentSeed(*
max, phiSolution))};
231 if (m_visionTool.isEnabled()) {
232 m_visionTool->visualizeSeed(ctx, *seed,
"#phi pattern seed");
243 if (m_recoverSinglePhiWithBS && eventData.phiHitsOnMax == 1){
244 const SegmentSeed* singleMax{writeMaxima->push_back(recoverSinglePhiMax(eventData,*
max))};
245 if (m_visionTool.isEnabled()) {
246 m_visionTool->visualizeSeed(ctx, *singleMax,
"Single #phi hit recovery");
251 writeMaxima->push_back(std::make_unique<SegmentSeed>(*
max));
257 return StatusCode::SUCCESS;