17 constexpr
double resetVal = 1.e10;
22 using namespace SegmentFit;
28 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
29 return StatusCode::SUCCESS;
33 cfg.nBinsX = m_nBinsTanPhi;
34 cfg.nBinsY = m_nBinsIntercept;
38 peakFinderCfg.fractionCutoff = 0.4;
39 peakFinderCfg.threshold = 2;
40 peakFinderCfg.minSpacingBetweenPeaks = {0., 30.};
41 data.houghPlane = std::make_unique<HoughPlane>(
cfg);
42 data.peakFinder = std::make_unique<ActsPeakFinderForMuon>(peakFinderCfg);
47 std::unordered_map<const xAOD::UncalibratedMeasurement*, bool> foundEtas;
50 if (hit->measuresEta() && hit->measuresPhi()) {
51 auto [
iter, added] = foundEtas.emplace(hit->primaryMeasurement(),
false);
55 iter->second |= phiMaximum.hitIdentifiers.count(hit);
59 return std::ranges::count_if(foundEtas,
60 [](
const std::pair<const xAOD::UncalibratedMeasurement*, bool>&
p) {
64 std::unique_ptr<SegmentSeed>
66 const ActsPeakFinderForMuon::Maximum & phiMax)
const {
68 std::vector<HoughHitType> hitsOnMax{};
71 std::back_inserter(hitsOnMax), [](
const HoughHitType &hit){
72 return (hit->measuresEta() && !hit->measuresPhi());
75 hitsOnMax.insert(hitsOnMax.end(), phiMax.hitIdentifiers.begin(), phiMax.hitIdentifiers.end());
78 std::ranges::stable_sort(hitsOnMax,
sorter);
79 return std::make_unique<SegmentSeed>(
etaMax.tanTheta(),
etaMax.interceptY(), phiMax.x, phiMax.y, hitsOnMax.size(), std::move(hitsOnMax),
etaMax.parentBucket());
92 if (!hit->measuresPhi()) {
96 const Amg::Vector3D extrapDir = (hit->positionInChamber() - hit->msSector()->globalToLocalTrans(gctx).translation()).
unit();
99 std::optional<double> dummyIntercept = Amg::intersect<3>(hit->positionInChamber(), extrapDir, Amg::Vector3D::UnitZ(),0);
100 double x0 = (hit->positionInChamber() + dummyIntercept.value_or(0) * extrapDir).
x();
111 double searchStart = chamberCenter - 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
112 double searchEnd = chamberCenter + 0.5 * eventData.
houghPlane->nBinsY() * m_targetResoIntercept;
119 double searchStartTanPhi = tanPhiMean - 0.5 * eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
120 double searchEndTanPhi = tanPhiMean + 0.5* eventData.
houghPlane->nBinsX() * m_targetResoTanPhi;
121 searchStartTanPhi =
std::min(searchStartTanPhi, eventData.
searchSpaceTanAngle.first- m_minSigmasSearchTanPhi * m_targetResoTanPhi);
126 Acts::HoughTransformUtils::HoughAxisRanges{searchStartTanPhi, searchEndTanPhi, searchStart, searchEnd};
127 ATH_MSG_VERBOSE(
"Accumulator search window: tanPhi: ["<<searchStartTanPhi<<
";"<<searchEndTanPhi<<
"], x0: ["
128 <<searchStart<<
";"<<searchEnd<<
"]");
131 std::vector<ActsPeakFinderForMuon::Maximum>
134 std::unordered_map<int, std::vector<ActsPeakFinderForMuon::Maximum>> rankedSeeds;
135 using namespace std::placeholders;
140 if (!hit->measuresPhi()) {
141 ATH_MSG_VERBOSE(
"Hit "<<hit->msSector()->idHelperSvc()->toString(hit->identify())<<
" does not have a phi measurement");
151 (hit->measuresEta() ? 2.0 : 1.0) / (m_downWeightMultiplePrd? hit->nPhiInstanceCounts() : 1)
156 if (m_visionTool.isEnabled()) {
161 for (
const auto& solution : foundMaxPhi) {
164 rankedSeeds[countIncompatibleEtaHits(solution, maximum)].push_back(solution);
167 auto best = rankedSeeds.begin();
169 if (
best != rankedSeeds.end() &&
best->first <= m_maxEtaHolesOnMax){
174 std::unique_ptr<SegmentSeed>
182 data.searchSpaceTanAngle.first,
183 data.searchSpaceIntercept.first,
203 prepareHoughPlane(eventData);
207 ATH_CHECK(writeMaxima.record(std::make_unique<SegmentSeedContainer>()));
212 ATH_MSG_VERBOSE(
"Search extra phi hits on maximum "<<
max->msSector()->identString()<<
", tanTheta: "<<
max->tanTheta()
213 <<
", y0: "<<
max->interceptY());
215 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;