ATLAS Offline Software
Loading...
Searching...
No Matches
EtaHoughTransformAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
15
19
20#include "Acts/Utilities/RangeXD.hpp"
21#include <format>
22
23namespace MuonR4{
24 // helper to check if our trajectory traverses a chamber
25 inline bool passesThrough(const SpacePointBucket::chamberLocation & loc, double y0, double tanBeta){
26 double yCross = (y0 + loc.location().z() * tanBeta);
27 return (loc.minY() < yCross && yCross < loc. maxY());
28 }
29 // determines the local residual when traversing a chamber
30 inline double proximity(const SpacePoint* dc, double y0, double tanBeta) {
32 return std::min(std::abs(HoughHelpers::Eta::houghParamMdtLeft(tanBeta, dc) - y0),
33 std::abs(HoughHelpers::Eta::houghParamMdtRight(tanBeta, dc) - y0));
34 }
35 return std::abs(HoughHelpers::Eta::houghParamStrip(tanBeta, dc) - y0);
36 }
37
43 constexpr double chamberCoverage(const std::array<double,2>& seedEdges,
44 const std::array<double, 2>& chambEdges) {
45 // The seed is full embedded
46 if (chambEdges[0] <= seedEdges[0] && chambEdges[1] >= seedEdges[1]) {
47 return 1.;
48 }
50 else if (chambEdges[0]<= seedEdges[0]) {
51 return (chambEdges[1] - seedEdges[0]) / (seedEdges[1] - seedEdges[0]);
52 }
54 else if (chambEdges[1] >= seedEdges[1]) {
55 return (seedEdges[1] - chambEdges[0]) / (seedEdges[1] - seedEdges[0]);
56 }
58 else if (seedEdges[0] <= chambEdges[0] && seedEdges[1] >= chambEdges[1]) {
59 return (chambEdges[1] - chambEdges[0]) / (seedEdges[1] - seedEdges[0]);
60 }
61 return 0.;
62 }
63
65 ATH_CHECK(m_geoCtxKey.initialize());
66 ATH_CHECK(m_spacePointKey.initialize());
67 ATH_CHECK(m_maxima.initialize());
68 ATH_CHECK(m_idHelperSvc.retrieve());
69 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
70 return StatusCode::SUCCESS;
71}
72StatusCode EtaHoughTransformAlg::execute(const EventContext& ctx) const {
73
75 const SpacePointContainer* spacePoints{nullptr};
76 ATH_CHECK(SG::get(spacePoints, m_spacePointKey, ctx));
77
78 // book the output container
80 ATH_CHECK(writeMaxima.record(std::make_unique<EtaHoughMaxContainer>()));
81
82 const ActsTrk::GeometryContext* gctx{nullptr};
83 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
84
86
88 preProcess(ctx, *gctx, *spacePoints, data);
89
93 for (auto& [station, stationHoughBuckets] : data.houghSetups) {
94 // reset the list of maxima
95 for (auto& bucket : stationHoughBuckets) {
96 processBucket(ctx, data, bucket);
97 }
98 for (HoughMaximum& max : data.maxima) {
99 writeMaxima->push_back(std::make_unique<HoughMaximum>(std::move(max)));
100 }
101 data.maxima.clear();
102 }
103 std::stable_sort(writeMaxima->begin(), writeMaxima->end(),
104 [](const HoughMaximum* a, const HoughMaximum* b){
105 return (*a->parentBucket()) < (*b->parentBucket());
106 });
107 return StatusCode::SUCCESS;
108}
109void EtaHoughTransformAlg::preProcess(const EventContext& ctx,
110 const ActsTrk::GeometryContext& gctx,
111 const SpacePointContainer& spacePoints,
112 HoughEventData& data) const {
113
114 ATH_MSG_DEBUG("Load " << spacePoints.size() << " space point buckets");
115 for (const SpacePointBucket* bucket : spacePoints) {
116 if (m_visionTool.isEnabled()) {
117 m_visionTool->visualizeBucket(ctx, *bucket, "bucket");
118 }
119 std::vector<HoughSetupForBucket>& buckets = data.houghSetups[bucket->front()->msSector()];
120 HoughSetupForBucket& hs{buckets.emplace_back(bucket)};
121 const Amg::Transform3D globToLoc{hs.bucket->msSector()->globalToLocalTrans(gctx)};
122 Amg::Vector3D leftSide = globToLoc.translation() - (hs.bucket->coveredMin() * Amg::Vector3D::UnitY());
123 Amg::Vector3D rightSide = globToLoc.translation() - (hs.bucket->coveredMax() * Amg::Vector3D::UnitY());
124
125 // get the average z of our hits and use it to correct our angle estimate
126 double zmin{1.e9}, zmax{-1.e9};
127 for (const std::shared_ptr<MuonR4::SpacePoint> & sp : *bucket) {
128 zmin = std::min(zmin, sp->localPosition().z());
129 zmax = std::max(zmax, sp->localPosition().z());
130 }
131 const double z = 0.5*(zmin + zmax);
132
133 // estimate the angle, adding extra tolerance based on our target resolution
134 const double tanThetaLeft = (leftSide.y() - m_targetResoIntercept) / (leftSide.z() - z) - m_targetResoTanTheta;
135 const double tanThetaRight = (rightSide.y() + m_targetResoIntercept) / (rightSide.z() - z) + m_targetResoTanTheta;
136 hs.searchWindowTanAngle = {tanThetaLeft, tanThetaRight};
137 double ymin{1e9}, ymax{-1e9};
138
141 for (const std::shared_ptr<MuonR4::SpacePoint> & hit : *bucket){
142 // two estimates: For the two extrema of tan(theta) resulting from the guesstimate
143 double y0l = hit->localPosition().y() - hit->localPosition().z() * tanThetaLeft;
144 double y0r = hit->localPosition().y() - hit->localPosition().z() * tanThetaRight;
145 // pick the widest envelope
146 ymin=std::min(ymin, std::min(y0l, y0r) - m_targetResoIntercept);
147 ymax=std::max(ymax, std::max(y0l, y0r) + m_targetResoIntercept);
148 }
149 hs.searchWindowIntercept = {ymin, ymax};
150 }
151}
153 switch (hit->type()){
155 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->primaryMeasurement());
156 return dc->status() == Muon::MdtDriftCircleStatus::MdtStatusDriftTime;
157 }
159 return hit->measuresEta();
160 }
162 const auto* meas = static_cast<const xAOD::sTgcMeasurement*>(hit->primaryMeasurement());
163 return meas->channelType() == sTgcIdHelper::sTgcChannelTypes::Strip;
164 } default:
165 break;
166 }
167 return false;
168}
169
171 HoughPlaneConfig cfg;
172 cfg.nBinsX = m_nBinsTanTheta;
173 cfg.nBinsY = m_nBinsIntercept;
174 ActsPeakFinderForMuonCfg peakFinderCfg;
175 peakFinderCfg.fractionCutoff = m_peakFractionCutOff;
176 peakFinderCfg.threshold = m_peakThreshold;
177 peakFinderCfg.minSpacingBetweenPeaks = {m_minMaxDistTheta, m_minMaxDistIntercept};
178 data.houghPlane = std::make_unique<HoughPlane>(cfg);
179 data.peakFinder = std::make_unique<ActsPeakFinderForMuon>(peakFinderCfg);
180}
181
182bool EtaHoughTransformAlg::passSeedQuality (const HoughSetupForBucket& currentBucket, const MuonR4::ActsPeakFinderForMuon::Maximum & maximum) const{
183
184 // now we propagate along the seed trajectory and collect crossed volumes
185 int expectedPrecisionChambers{0}, seenPrecisionChambers{0};
186 bool hasTrig = false;
187
188 std::unordered_set<const MuonGMR4::MuonReadoutElement*> seenChambers{};
189 std::set<std::pair<int,int>> seenLayers;
190 const double halfX = currentBucket.bucket->msSector()->halfXLong();
192 std::array<double, 2> tubeExtend{halfX, -halfX};
193
194 auto addSeenHit = [&tubeExtend, &seenLayers, &seenChambers](const SpacePoint& sp,
196 const double sensorL,
197 const int mL, const int layer){
198 seenLayers.emplace(mL, layer);
199 seenChambers.insert(re);
200 tubeExtend[0] = std::min(tubeExtend[0], sp.localPosition().x() - sensorL);
201 tubeExtend[1] = std::max(tubeExtend[1], sp.localPosition().x() + sensorL);
202 };
203 for (const SpacePoint* SP : maximum.hitIdentifiers){
204 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Maximum has associated hit in "
205 << m_idHelperSvc->toStringDetEl(SP->identify()));
206
207 if (isPrecisionHit(SP)) {
209 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(SP->primaryMeasurement());
210 const MuonGMR4::MdtReadoutElement* re = dc->readoutElement();
211 addSeenHit(*SP, re, 0.5*re->activeTubeLength(dc->measurementHash()),
212 re->multilayer(), dc->tubeLayer());
213 } else if(SP->type() == xAOD::UncalibMeasType::MMClusterType){
214 const auto* clust = static_cast<const xAOD::MMCluster*>(SP->primaryMeasurement());
215 const MuonGMR4::MmReadoutElement* re = clust->readoutElement();
216 addSeenHit(*SP, re, 0.5*re->stripLayer(clust->measurementHash()).design().stripLength(clust->channelNumber()),
217 re->multilayer(), clust->gasGap());
218 } else if (SP->type() == xAOD::UncalibMeasType::sTgcStripType) {
219 const auto* clust = static_cast<const xAOD::sTgcMeasurement*>(SP->primaryMeasurement());
220 const MuonGMR4::sTgcReadoutElement* re = clust->readoutElement();
221 addSeenHit(*SP, re, 0.5*re->stripLayer(clust->measurementHash()).design().stripLength(clust->channelNumber()),
222 re->multilayer(), clust->gasGap());
223 }
224 } else {
225 seenChambers.insert(xAOD::muonReadoutElement(SP->primaryMeasurement()));
226 }
227 }
228 // loop over all chambers in the bucket
229 for (const auto & muonChamber : currentBucket.bucket->chamberLocations()){
230 // skip any we don't touch
231 if (!passesThrough(muonChamber, maximum.y, maximum.x)) {
232 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" maximum does not cross "
233 << m_idHelperSvc->toStringDetEl(muonChamber.readoutEle()->identify()));
234 continue;
235 }
236 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" maximum crosses "
237 << m_idHelperSvc->toStringDetEl(muonChamber.readoutEle()->identify())<<", "
238 <<(*muonChamber.bounds())<<", @: "<<Amg::toString(muonChamber.location()));
239 // for MDT multilayers, we increase our expected number of crossed chambers / tubes
240 const ActsTrk::DetectorType type = muonChamber.readoutEle()->detectorType();
241
242 // now we check if we have a compatible measurement on our seed
243 const bool hasHit = seenChambers.count(muonChamber.readoutEle());
244 const bool precTech = (type == ActsTrk::DetectorType::Mdt || type == ActsTrk::DetectorType::Mm ||
246 if (hasHit) {
247 // if we find an MDT hit, we increment the counter for seen chambers
248 if (precTech) {
249 ++seenPrecisionChambers;
250 } else {
251 hasTrig = true;
252 continue;
253 }
254 } else if (precTech) {
257 const double lowL = muonChamber.width(maximum.y + muonChamber.location().z() * maximum.x);
258 const std::array<double, 2> chambEdges{muonChamber.location().x() - lowL,
259 muonChamber.location().x() + lowL};
260
261 const double coverage = chamberCoverage(tubeExtend, chambEdges);
262 if (coverage < 0.95){
263 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Reject chamber due to partial coverage: "<<coverage
264 <<", chamb extend: "<<chambEdges[0]<<"-"<<chambEdges[1]
265 <<", tube extend: "<<tubeExtend[0]<<"-"<<tubeExtend[1]
266 <<", "<<(*muonChamber.readoutEle()->msSector()->bounds()));
267 continue;
268 }
269 } else {
270 continue;
271 }
272 ++expectedPrecisionChambers;
273 }
274 // compute the minimum number of requested precision layers
275 // the integer division will round down (resulting cut: 2 for single-ML, 4 for dual-ML)
276 int minLayers = seenLayers.size() / 2 + 1;
277 // require 2 precision chambers with measurements, except if we only cross one precision multilayer in total
278 int minSeenPrecisionChambers = (expectedPrecisionChambers > 1) + 1;
279 // if we have at least one trigger hit, we loosen the requirements on precision hits and chambers
280 if (hasTrig) {
281 minLayers -= 1;
282 minSeenPrecisionChambers = 1;
283 }
284 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": "<<currentBucket.bucket->msSector()->identString()<<
285 ", seen prec: "<<seenPrecisionChambers<<", required: "<<minSeenPrecisionChambers
286 <<" -- layers: "<<seenLayers.size()<<", required: "<<minLayers);
287 return seenPrecisionChambers >= minSeenPrecisionChambers && (int)seenLayers.size() >= minLayers;
288}
289
290
291void EtaHoughTransformAlg::processBucket(const EventContext& ctx,
293 HoughSetupForBucket& bucket) const {
295
296 double chamberCenter = 0.5 * (bucket.searchWindowIntercept.first +
297 bucket.searchWindowIntercept.second);
298 // build a symmetric window around the (geometric) chamber center so that
299 // the bin width is equivalent to our target resolution
300 double searchStart = chamberCenter - 0.5 * data.houghPlane->nBinsY() * m_targetResoIntercept;
301 double searchEnd = chamberCenter + 0.5 * data.houghPlane->nBinsY() * m_targetResoIntercept;
302 // Protection for very wide buckets - if the search space does not cover all
303 // of the bucket, widen the bin size so that we cover everything
304 searchStart = std::min(searchStart, bucket.searchWindowIntercept.first -
306 searchEnd = std::max(searchEnd, bucket.searchWindowIntercept.second +
308 // also treat tan(theta)
309 double tanThetaMean = 0.5 * (bucket.searchWindowTanAngle.first +
310 bucket.searchWindowTanAngle.second);
311 double searchStartTanTheta = tanThetaMean - 0.5 * data.houghPlane->nBinsX() * m_targetResoTanTheta;
312 double searchEndTanTheta = tanThetaMean + 0.5 * data.houghPlane->nBinsX() * m_targetResoTanTheta;
313 searchStartTanTheta = std::min(searchStartTanTheta, bucket.searchWindowTanAngle.first -
315 searchEndTanTheta = std::max(searchEndTanTheta, bucket.searchWindowTanAngle.second +
317
318 data.currAxisRanges = Acts::HoughTransformUtils::HoughAxisRanges{
319 searchStartTanTheta, searchEndTanTheta, searchStart, searchEnd};
320
321 data.houghPlane->reset();
322 for (const SpacePointBucket::value_type& hit : *(bucket.bucket)) {
323 fillFromSpacePoint(data, hit.get());
324 }
325 auto maxima = data.peakFinder->findPeaks(*(data.houghPlane), data.currAxisRanges);
326 if (m_visionTool.isEnabled()) {
327 m_visionTool->visualizeAccumulator(ctx, *data.houghPlane, data.currAxisRanges, maxima,
328 "#eta Hough accumulator");
329 }
330 if (maxima.empty()) {
331 ATH_MSG_DEBUG("Station "<<bucket.bucket->msSector()->identString()
332 <<":\n Mean tanBeta was "<<tanThetaMean
333 << " and my intercept "<<chamberCenter
334 <<", with hits in the bucket in "<< bucket.bucket->coveredMin()
335 <<" - "<<bucket.bucket->coveredMax()
336 <<". The bucket found a search range of ("
337 <<bucket.searchWindowTanAngle.first<<" - "
338 <<bucket.searchWindowTanAngle.second<<") and ("
339 <<bucket.searchWindowIntercept.first<<" - "
340 <<bucket.searchWindowIntercept.second
341 <<") , and my final search range is ["
342 <<searchStartTanTheta<<" - "<<searchEndTanTheta
343 <<"] and ["<<searchStart<<" - "<<searchEnd
344 <<"] with "<<m_nBinsTanTheta<<" and "
345 <<m_nBinsIntercept<<" bins.");
346 return;
347 }
348
349 // remember used hits - assign only to first maximum when counting
350 // precision hits
351 std::set<HoughHitType> seenHits;
352
353 // now clean up and potentially write the maxima
354 for (const auto& max : maxima) {
355
356 // precision hit cut, using only the measurements on the hough maximum
357 unsigned int nPrec{0};
358 auto toBins = [&data](double x, double y){
359 return std::make_pair(
360 Acts::HoughTransformUtils::binIndex(data.currAxisRanges.xMin, data.currAxisRanges.xMax, data.houghPlane->nBinsX(), x),
361 Acts::HoughTransformUtils::binIndex(data.currAxisRanges.yMin, data.currAxisRanges.yMax, data.houghPlane->nBinsY(), y)
362 );
363 };
364 auto accumulatorBins = toBins(max.x,max.y);
365 for (const HoughHitType& hit : data.houghPlane->hitIds(accumulatorBins.first, accumulatorBins.second)) {
366 auto res = seenHits.emplace(hit);
367 if (res.second){
368 nPrec += isPrecisionHit(hit);
369 }
370 }
371 if (nPrec < m_nPrecHitCut) {
372 ATH_MSG_VERBOSE("The maximum did not pass the precision hit cut");
373 continue;
374 }
375
376 // convert the set of hit identifiers from ACTS to the vector we need later
377 std::vector<HoughHitType> hitList{max.hitIdentifiers.begin(), max.hitIdentifiers.end()};
378
379 // apply a seed quality cut.
380 if (!passSeedQuality(bucket, max)) {
381 // if seed visualisation is enabled, draw the rejected seed
382 if (m_visionTool.isEnabled()) {
383 const HoughMaximum& houghMax{max.x, max.y, 1. *hitList.size(), std::move(hitList), bucket.bucket};
384 const SegmentSeed seed{houghMax};
387 for (auto & chamber : bucket.bucket->chamberLocations()) {
388 primitives.push_back(MuonValR4::drawBox(chamber.minY(), chamber.minZ(),
389 chamber.maxY(), chamber.maxZ(), kGray+2));
390 const Identifier detId{chamber.readoutEle()->identify()};
391 const int eta = m_idHelperSvc->stationEta(detId);
392 std::string chLabel = std::format("{:}{:1d}{:}{:2d}", m_idHelperSvc->stationNameString(detId),
393 std::abs(eta), eta > 0? 'A' : 'C', m_idHelperSvc->stationPhi(detId));
394 switch (chamber.readoutEle()->detectorType()) {
396 chLabel += std::format("M{:1d}", m_idHelperSvc->mdtIdHelper().multilayer(detId));
397 } default:
398 break;
399 }
400 primitives.push_back(MuonValR4::drawLabel(chLabel, chamber.minY(), chamber.maxZ() + 0.02,8));
401 }
402
403 primitives.push_back(MuonValR4::drawLabel(std::format("Missed seed - score {}, layer score {}, comprising {} measurements ",data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size()),0.05,0.03,12));
404
405 primitivesForAcc.push_back(MuonValR4::drawLabel(std::format("Missed seed - score {}, layer score {}, comprising {} measurements ",data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size()),0.05,0.03,12));
406 m_visionTool->visualizeAccumulator(ctx, *data.houghPlane, data.currAxisRanges, {max},
407 "MissedAccumulator", std::move(primitivesForAcc));
408 m_visionTool->visualizeSeed(ctx, seed, "Missed seed",std::move(primitives));
409 }
410 continue;
411 }
412
413 // this seed looks good! Let's finalise it
414 size_t nHits = hitList.size();
415 // add phi measurements - will be filtered for compatibility in separate algorithm
416 extendWithPhiHits(hitList, bucket, max.x, max.y);
417 // sort hits by layer
418 const SpacePointPerLayerSorter sorter{};
419 std::ranges::stable_sort(hitList, sorter);
420 // create hough maximum instance and add it to the event data for later writing!
421 const HoughMaximum& houghMax{data.maxima.emplace_back(max.x, max.y, nHits, std::move(hitList), bucket.bucket)};
422
423 // if desired, visualise the result
424 if (m_visionTool.isEnabled()) {
425 const SegmentSeed seed{houghMax};
428 for (auto & chamber : bucket.bucket->chamberLocations()){
429 primitives.push_back(MuonValR4::drawBox(chamber.minY(), chamber.minZ(), chamber.maxY(), chamber.maxZ(), kGray+2));
430 }
431 primitives.push_back(MuonValR4::drawLabel(std::format("score {}, layer score {}, comprising {} measurements. wx = {:.2f}, wy = {:.1f} ",data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size(), max.wx, max.wy),0.05,0.03,12));
432 primitivesForAcc.push_back(MuonValR4::drawLabel(std::format("score {}, layer score {}, comprising {} measurements. wx = {:.2f}, wy = {:.1f} ",data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size(), max.wx / m_targetResoTanTheta, max.wy / m_targetResoIntercept),0.05,0.03,12));
433
434 m_visionTool->visualizeAccumulator(ctx, *data.houghPlane, data.currAxisRanges, {max},"#eta Hough accumulator", std::move(primitivesForAcc));
435 m_visionTool->visualizeSeed(ctx, seed, "#eta-HoughSeed", std::move(primitives));
436 }
437 }
438}
440
441 using namespace std::placeholders;
442 double w = 1.0;
443 // convert Gaudi::property to double to avoid deep copy in std::bind expression
444 double resolutionTarget = m_targetResoIntercept;
445 // downweight RPC measurements in the barrel relative to MDT
447 w = 0.5;
448 }
450 // if invalid time, do not count this hit towards a potential peak.
451 // The hits will still be included in a potential maximum formed by valid hits,
452 // for later recovery.
453 if (!isPrecisionHit(SP)) w = 0;
454 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(SP->primaryMeasurement());
455 // dummy index for precision layer counting within the hough plane
456 const unsigned precisionLayerIndex = (dc->readoutElement()->multilayer() * 10 + dc->tubeLayer());
457 data.houghPlane->fill<HoughHitType>(SP, data.currAxisRanges, HoughHelpers::Eta::houghParamMdtLeft,
458 std::bind(HoughHelpers::Eta::houghWidthMdt, _1, _2, resolutionTarget), SP, precisionLayerIndex, w);
459 data.houghPlane->fill<HoughHitType>(SP, data.currAxisRanges, HoughHelpers::Eta::houghParamMdtRight,
460 std::bind(HoughHelpers::Eta::houghWidthMdt, _1, _2, resolutionTarget), SP, precisionLayerIndex, w);
461 } else {
462 if (SP->measuresEta()) {
463 data.houghPlane->fill<HoughHitType>(SP, data.currAxisRanges, HoughHelpers::Eta::houghParamStrip,
464 std::bind(HoughHelpers::Eta::houghWidthStrip, _1, _2, resolutionTarget), SP, 0, w * (
465 m_downWeightMultiplePrd ? 1.0 / SP->nEtaInstanceCounts() : 1.));
466 }
467 }
468}
469void EtaHoughTransformAlg::extendWithPhiHits(std::vector<HoughHitType>& hitList,
470 HoughSetupForBucket& bucket,
471 const double tanBeta,
472 const double interceptY) const {
473 const Amg::Vector3D maxPos = interceptY * Amg::Vector3D::UnitY();
474 const Amg::Vector3D maxDir = Acts::makeDirectionFromAxisTangents(0., tanBeta);
475
476 for (const SpacePointBucket::value_type& hit : *bucket.bucket) {
477 if (hit->measuresEta()){
478 continue;
479 }
480 using namespace SegmentFit;
481 const Amg::Vector3D& dir{hit->sensorDirection()};
482 const Amg::Vector3D& pos{hit->localPosition()};
483 const double distAlongStrip = std::abs(dir.dot(SeedingAux::extrapolateToPlane(maxPos,maxDir, *hit) - pos));
484 const double stripL = std::sqrt(hit->covariance()[Acts::toUnderlying(AxisDefs::etaCov)]);
485 if (!hit->measuresEta() && distAlongStrip < stripL + m_phiStripSafety) {
486 hitList.push_back(hit.get());
487 }
488 }
489}
490}
const boost::regex re(r_e)
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
std::pair< std::vector< unsigned int >, bool > res
static Double_t sp
static Double_t a
static const uint32_t nHits
#define y
#define x
#define z
#define max(a, b)
Definition cfImp.cxx:41
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
double halfXLong() const
Long-extend of the chamber in the x-direction at positive Y.
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
void extendWithPhiHits(std::vector< HoughHitType > &hitList, HoughSetupForBucket &bucket, const double tanBeta, const double interceptY) const
extend a maximum with all compatible (pure) phi hits.
void fillFromSpacePoint(HoughEventData &data, const MuonR4::HoughHitType &SP) const
fill the accumulator from a given space point.
void prepareHoughPlane(HoughEventData &data) const
prepare the accumulator and the peak finder once per event
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Handle to the IdHelperSvc.
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
HoughEventData::HoughSetupForBucket HoughSetupForBucket
virtual StatusCode execute(const EventContext &ctx) const override
static bool isPrecisionHit(const HoughHitType &hit)
Returns whether the hit is a precision hit or not.
void preProcess(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const SpacePointContainer &spacePoints, HoughEventData &data) const
pre-processing method called once per event.
void processBucket(const EventContext &ctx, HoughEventData &data, HoughSetupForBucket &currentBucket) const
process a bucket.
bool passSeedQuality(const HoughSetupForBucket &currentBucket, const MuonR4::ActsPeakFinderForMuon::Maximum &maximum) const
apply quality cuts on a given maximum
UnsignedIntegerProperty m_nPrecHitCut
SG::WriteHandleKey< EtaHoughMaxContainer > m_maxima
virtual StatusCode initialize() override
SG::ReadHandleKey< SpacePointContainer > m_spacePointKey
Data class to represent an eta maximum in hough space.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition SegmentSeed.h:14
: The muon space point bucket represents a collection of points that will bre processed together in t...
const MuonGMR4::SpectrometerSector * msSector() const
returns th associated muonChamber
const std::vector< chamberLocation > & chamberLocations() const
returns the list of all tracking chambers in the bucket for fast navigation
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
bool measuresEta() const
: Does the space point contain an eta measurement
unsigned nEtaInstanceCounts() const
How many space points have been built in total with the same eta prd.
const Identifier & identify() const
: Identifier of the primary measurement
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
double ymin
Definition listroot.cxx:63
double ymax
Definition listroot.cxx:64
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
@ Mm
Maybe not needed in the migration.
@ sTgc
Micromegas (NSW)
@ Mdt
MuonSpectrometer.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
double houghWidthStrip(double tanBeta, const MuonR4::HoughHitType &strip, double targetReso)
Uncertainty parametrisation for strip measurements.
double houghParamMdtRight(double tanBeta, const MuonR4::HoughHitType &dc)
right-side straight line parametrisation for drift circles
double houghParamStrip(double tanBeta, const MuonR4::HoughHitType &strip)
straight line parametrisation for strip detector measurements
double houghWidthMdt(double tanBeta, const MuonR4::HoughHitType &dc, double targetReso)
uncertainty parametrisation for drift circles
double houghParamMdtLeft(double tanBeta, const MuonR4::HoughHitType &dc)
left-side straight line parametrisation for drift circles
This header ties the generic definitions in this package.
double proximity(const SpacePoint *dc, double y0, double tanBeta)
constexpr double chamberCoverage(const std::array< double, 2 > &seedEdges, const std::array< double, 2 > &chambEdges)
Calculates how much of the unkknown coordinate along the tube range is covered by the chamber of inte...
bool passesThrough(const SpacePointBucket::chamberLocation &loc, double y0, double tanBeta)
constexpr unsigned minLayers
HoughEventData_impl< ActsPeakFinderForMuon, ActsPeakFinderForMuonCfg > HoughEventData
Acts::HoughTransformUtils::PeakFinders::IslandsAroundMaxConfig ActsPeakFinderForMuonCfg
const SpacePoint * HoughHitType
DataVector< SpacePointBucket > SpacePointContainer
Abrivation of the space point container type.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18)
Create a TLatex label,.
std::unique_ptr< TBox > drawBox(const Amg::Vector3D &boxCenter, const double boxWidth, const double boxHeight, const int color=kGreen+2, const int fillStyle=hollowFilling, const int view=objViewEta)
Creates a box for drawing, e.g strip measurements.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
MdtDriftCircle_v1 MdtDriftCircle
const MuonGMR4::MuonReadoutElement * muonReadoutElement(const UncalibratedMeasurement *meas)
Returns the associated readout element to the measurement.
MMCluster_v1 MMCluster
sTgcMeasurement_v1 sTgcMeasurement
double minY() const
Returns the minimum y covered by the chamber location.
const Amg::Vector3D & location() const
Returns the location.