16 constexpr
double resetVal = 1.e10;
21 using namespace SegmentFit;
27 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
28 return StatusCode::SUCCESS;
32 cfg.nBinsX = m_nBinsTanPhi;
33 cfg.nBinsY = m_nBinsIntercept;
37 peakFinderCfg.fractionCutoff = 0.4;
38 peakFinderCfg.threshold = 2;
39 peakFinderCfg.minSpacingBetweenPeaks = {0., 30.};
40 data.houghPlane = std::make_unique<HoughPlane>(
cfg);
41 data.peakFinder = std::make_unique<ActsPeakFinderForMuon>(peakFinderCfg);
46 std::unordered_map<const xAOD::UncalibratedMeasurement*, bool> foundEtas;
49 if (hit->measuresEta() && hit->measuresPhi()) {
50 auto [
iter, added] = foundEtas.emplace(hit->primaryMeasurement(),
false);
54 iter->second |= phiMaximum.hitIdentifiers.count(hit);
58 return std::ranges::count_if(foundEtas,
59 [](
const std::pair<const xAOD::UncalibratedMeasurement*, bool>&
p) {
63 std::unique_ptr<SegmentSeed>
65 const ActsPeakFinderForMuon::Maximum & phiMax)
const {
67 std::vector<HoughHitType> hitsOnMax{};
70 std::back_inserter(hitsOnMax), [](
const HoughHitType &hit){
71 return (hit->measuresEta() && !hit->measuresPhi());
74 hitsOnMax.insert(hitsOnMax.end(), phiMax.hitIdentifiers.begin(), phiMax.hitIdentifiers.end());
77 std::ranges::stable_sort(hitsOnMax,
sorter);
78 return std::make_unique<SegmentSeed>(
etaMax.tanTheta(),
etaMax.interceptY(), phiMax.x, phiMax.y, hitsOnMax.size(), std::move(hitsOnMax),
etaMax.parentBucket());
91 if (!hit->measuresPhi()) {
95 const Amg::Vector3D extrapDir = (hit->localPosition() - hit->msSector()->globalToLocalTrans(gctx).translation()).
unit();
98 std::optional<double> dummyIntercept = Amg::intersect<3>(hit->localPosition(), extrapDir, Amg::Vector3D::UnitZ(),0);
99 double x0 = (hit->localPosition() + dummyIntercept.value_or(0) * extrapDir).
x();
110 double searchStart = chamberCenter - 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
111 double searchEnd = chamberCenter + 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
118 double searchStartTanPhi = tanPhiMean - 0.5 * eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
119 double searchEndTanPhi = tanPhiMean + 0.5* eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
120 searchStartTanPhi =
std::min(searchStartTanPhi, eventData.
searchSpaceTanAngle.first- m_minSigmasSearchTanPhi * m_targetResoTanPhi);
125 Acts::HoughTransformUtils::HoughAxisRanges{searchStartTanPhi, searchEndTanPhi, searchStart, searchEnd};
126 ATH_MSG_VERBOSE(
"Accumulator search window: tanPhi: ["<<searchStartTanPhi<<
";"<<searchEndTanPhi<<
"], x0: ["
127 <<searchStart<<
";"<<searchEnd<<
"]");
130 std::vector<ActsPeakFinderForMuon::Maximum>
133 std::unordered_map<int, std::vector<ActsPeakFinderForMuon::Maximum>> rankedSeeds;
134 using namespace std::placeholders;
139 if (!hit->measuresPhi()) {
140 ATH_MSG_VERBOSE(
"Hit "<<hit->msSector()->idHelperSvc()->toString(hit->identify())<<
" does not have a phi measurement");
150 (hit->measuresEta() ? 2.0 : 1.0) / (m_downWeightMultiplePrd? hit->nPhiInstanceCounts() : 1)
155 if (m_visionTool.isEnabled()) {
160 for (
const auto& solution : foundMaxPhi) {
163 rankedSeeds[countIncompatibleEtaHits(solution, maximum)].push_back(solution);
166 auto best = rankedSeeds.begin();
168 if (
best != rankedSeeds.end() &&
best->first <= m_maxEtaHolesOnMax){
173 std::unique_ptr<SegmentSeed>
181 data.searchSpaceTanAngle.first,
182 data.searchSpaceIntercept.first,
202 prepareHoughPlane(eventData);
206 ATH_CHECK(writeMaxima.record(std::make_unique<SegmentSeedContainer>()));
211 ATH_MSG_VERBOSE(
"Search extra phi hits on maximum "<<
max->msSector()->identString()<<
", tanTheta: "<<
max->tanTheta()
212 <<
", y0: "<<
max->interceptY());
214 for (
const auto& truth : m_visionTool->getLabeledSegments(
max->getHitsInMax())) {
221 preProcessMaximum(*gctx, *
max, eventData);
222 bool foundSolution=
false;
224 if (eventData.phiHitsOnMax > 1){
225 std::vector<ActsPeakFinderForMuon::Maximum> rankedSeeds = findRankedSegmentSeeds(ctx, eventData, *
max);
226 for (
auto & phiSolution : rankedSeeds){
227 foundSolution =
true;
228 const SegmentSeed* seed {writeMaxima->push_back(buildSegmentSeed(*
max, phiSolution))};
229 if (m_visionTool.isEnabled()) {
230 m_visionTool->visualizeSeed(ctx, *seed,
"#phi pattern seed");
241 if (m_recoverSinglePhiWithBS && eventData.phiHitsOnMax == 1){
242 const SegmentSeed* singleMax{writeMaxima->push_back(recoverSinglePhiMax(eventData,*
max))};
243 if (m_visionTool.isEnabled()) {
244 m_visionTool->visualizeSeed(ctx, *singleMax,
"Single #phi hit recovery");
249 writeMaxima->push_back(std::make_unique<SegmentSeed>(*
max));
255 return StatusCode::SUCCESS;