ATLAS Offline Software
Loading...
Searching...
No Matches
SegmentFittingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "SegmentFittingAlg.h"
5
8
13#include "ActsInterop/Logger.h"
14
16
18#include "Acts/Definitions/Units.hpp"
19
20#include <format>
21
22using namespace Acts;
23using namespace Acts::UnitLiterals;
24
25namespace MuonR4 {
26 using namespace SegmentFit;
27 using namespace MuonValR4;
28
37 const SegmentSeed& seed,
38 double etaEdgeTolerance = 25. * Gaudi::Units::mm,
39 double phiEdgeTolerance = 0.){
40
41 // eta projection
42 const double z = loc.location().z();
43 const double yCross = seed.interceptY() + (z * seed.tanBeta());
44 if (loc.minY() - etaEdgeTolerance > yCross || yCross > loc.maxY() + etaEdgeTolerance) {
45 return false;
46 }
47
48 // No reliable second coordinate available.
49 if (!seed.hasPhiExtension()) {
50 return true;
51 }
52
53 // phi projection
54 const double xCross = seed.interceptX() + (z * seed.tanAlpha());
55
56 // Chamber half-width in x depends on y.
57 const double halfWidthX = loc.width(yCross);
58
59 return ((loc.location().x() - halfWidthX) + phiEdgeTolerance) < xCross && xCross < ((loc.location().x() + halfWidthX) - phiEdgeTolerance);
60
61 }
62
64
67 ATH_CHECK(m_geoCtxKey.initialize());
68 ATH_CHECK(m_seedKey.initialize());
69 ATH_CHECK(m_outSegments.initialize());
70 ATH_CHECK(m_calibTool.retrieve());
71 ATH_CHECK(m_idHelperSvc.retrieve());
72 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
74 m_ambiSolver = std::make_unique<SegmentAmbiSolver>(name(), std::move(cfg));
75
77 fitCfg.calibrator = m_calibTool.get();
78 fitCfg.visionTool = m_visionTool.get();
79 fitCfg.idHelperSvc = m_idHelperSvc.get();
80 fitCfg.fitT0 = m_doT0Fit;
81 fitCfg.recalibrate = m_recalibInFit;
82 fitCfg.useFastFitter = m_useFastFitter;
83 fitCfg.fastPreFitter = m_fastPreFitter;
84 fitCfg.ignoreFailedPreFit = m_ignoreFailedPreFit;
85 fitCfg.useHessian = m_hessianResidual;
86
90
92 for (const auto* prop :{&m_seedMaxBsR, &m_seedMaxBsL}) {
93 if (prop->value().size() != s_stIdxMax ||
94 std::ranges::min(prop->value()) < 0.) {
95 ATH_MSG_ERROR("Invalid configuratnon of "<<(prop));
96 return StatusCode::FAILURE;
97 }
98 ATH_MSG_DEBUG("Configured "<<(*prop));
99 }
100 }
103 fitCfg.nPrecHitCut = m_precHitCut;
104 fitCfg.maxIter = m_maxIter;
105 ATH_MSG_DEBUG("Fitter configuration: \n -- "<<m_doT0Fit<<"\n -- "<<m_recalibInFit<<"\n -- "<<m_useFastFitter
106 <<"\n -- "<<m_fastPreFitter<<"\n -- "<<m_ignoreFailedPreFit<<"\n -- "<<m_hessianResidual
107 <<"\n -- "<<m_doBeamspotConstraint<<"\n -- "<<m_beamSpotR<<"\n -- "<<m_beamSpotL<<"\n -- "<<m_outlierRemovalCut
108 <<"\n -- "<<m_recoveryPull<<"\n -- "<<m_precHitCut<<"\n -- "<<m_maxIter);
109
110 m_fitter = std::make_unique<SegmentFit::SegmentLineFitter>(name(), std::move(fitCfg));
111
112 MdtSegmentSeedGenerator::Config genCfg{};
113 genCfg.hitPullCut = m_seedHitChi2;
114 genCfg.busyLayerLimit = m_busyLayerLimit;
115 genCfg.startWithPattern = m_tryPatternPars;
116 ATH_MSG_DEBUG("Seeder configuration: \n - "<<m_tryPatternPars
117 <<"\n - "<<m_seedHitChi2
118 <<"\n - "<<m_busyLayerLimit);
119 m_seeder = std::make_unique<SegmentFit::MdtSegmentSeedGenerator>(genCfg, makeActsAthenaLogger(this, name()));
120
121 //Cache station indices for quick access
122 const auto& mdtHelper = m_idHelperSvc->mdtIdHelper();
123 m_bilStation = mdtHelper.stationNameIndex("BIL");
124 m_bimStation = mdtHelper.stationNameIndex("BIM");
125 m_birStation = mdtHelper.stationNameIndex("BIR");
126
127 return StatusCode::SUCCESS;
128 }
129 StatusCode SegmentFittingAlg::execute(const EventContext& ctx) const {
130 const ActsTrk::GeometryContext* gctx{nullptr};
131 const SegmentSeedContainer* segmentSeeds{nullptr};
132
133 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
134 ATH_CHECK(SG::get(segmentSeeds, m_seedKey, ctx));
135
136 SG::WriteHandle writeSegments{m_outSegments, ctx};
137 ATH_CHECK(writeSegments.record(std::make_unique<SegmentContainer>()));
138 SegmentVec_t allSegments{};
139 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - execute() - Start processing " << segmentSeeds->size() << " pattern seeds.");
140 for (const SegmentSeed* seed : *segmentSeeds) {
141 SegmentVec_t segments = fitSegmentSeed(ctx, *gctx, seed);
142 if (m_visionTool.isEnabled() && segments.size() > 1) {
143 auto drawFinalReco = [this, &segments, &gctx, &ctx,&seed](const std::string& nameTag) {
144 PrimitiveVec segmentLines{};
145 double yLegend{0.85};
146 segmentLines.push_back(drawLabel(std::format("# segments: {:d}", segments.size()), 0.2, yLegend, 14));
147 yLegend-=0.04;
148 for (const std::unique_ptr<Segment>& seg : segments) {
149 const Parameters pars = localSegmentPars(*gctx, *seg);
150 const auto [pos, dir] = makeLine(pars);
151 segmentLines.emplace_back(drawLine(pars, -Gaudi::Units::m, Gaudi::Units::m, kRed));
152 std::stringstream signStream{};
153 const auto& cov = seg->covariance();
154 signStream<<std::format("#chi^{{2}}/nDoF: {:.2f} ({:}), ", seg->chi2() / seg->nDoF(), seg->nDoF());
155 signStream<<std::format("y_{{0}}={:.2f}#pm{:.2f}",
156 pars[toUnderlying(ParamDefs::y0)],
157 Amg::error(cov, toUnderlying(ParamDefs::y0)))<<", ";
158 signStream<<std::format("#theta={:.2f}#pm{:.2f}^{{#circ}}",
159 pars[toUnderlying(ParamDefs::theta)]/ 1._degree,
160 Amg::error(cov, toUnderlying(ParamDefs::theta)) / 1._degree )<<", ";
161 for (const Segment::MeasType& m : seg->measurements()) {
163 m->fitState() == CalibratedSpacePoint::State::Valid) {
164 signStream<<(SeedingAux::strawSign(pos, dir, *m) == -1 ? "L" : "R");
165 }
166 }
167 segmentLines.push_back(drawLabel(signStream.str(), 0.2, yLegend, 13));
168 yLegend-=0.03;
169 }
170
171 m_visionTool->visualizeBucket(ctx, *seed->parentBucket(), nameTag, std::move(segmentLines));
172 };
173 drawFinalReco("all segments");
174 const unsigned int nBeforeAmbi = segments.size();
175 segments = m_ambiSolver->resolveAmbiguity(*gctx, std::move(segments));
176 if (nBeforeAmbi != segments.size()) {
177 drawFinalReco("post ambiguity");
178 }
179 } else if (m_visionTool.isEnabled() && segments.empty() &&
180 std::ranges::any_of(seed->getHitsInMax(),[this](const SpacePoint* hit){
181 return m_visionTool->isLabeled(*hit);
182 })) {
183 m_visionTool->visualizeSeed(ctx, *seed, "Failed fit");
184 }
185 allSegments.insert(allSegments.end(), std::make_move_iterator(segments.begin()),
186 std::make_move_iterator(segments.end()));
187 }
188 resolveAmbiguities(*gctx, allSegments);
189 writeSegments->insert(writeSegments->end(),
190 std::make_move_iterator(allSegments.begin()),
191 std::make_move_iterator(allSegments.end()));
192 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Found in total "<<writeSegments->size()<<" segments. ");
193 return StatusCode::SUCCESS;
194 }
195
197 SegmentFittingAlg::fitSegmentSeed(const EventContext& ctx,
198 const ActsTrk::GeometryContext& gctx,
199 const SegmentSeed* patternSeed) const {
200
201 const Acts::Transform3& locToGlob{patternSeed->msSector()->localToGlobalTransform(gctx)};
202 std::vector<std::unique_ptr<Segment>> segments{};
203
204 const Acts::CalibrationContext cctx = ActsTrk::getCalibrationContext(ctx);
205
206 using namespace Muon::MuonStationIndex;
207 using State_t = MdtSegmentSeedGenerator::State_t;
208
209
210 auto seedSelector = [&](const Amg::Vector3D& tangentSeedPos,
211 const Amg::Vector3D& tangentSeedDir) {
213 return true;
214 }
215 const Amg::Vector3D globPos{locToGlob*tangentSeedPos};
216 const Amg::Vector3D globDir{locToGlob.linear()*tangentSeedDir};
217
220 const StIndex stIdx = toStationIndex(patternSeed->msSector()->chamberIndex());
221 switch (stIdx) {
222 using enum StIndex;
223 case EM: {
224 if (std::abs(globPos.eta()) > 2.35 &&
225 std::abs(globPos.theta() - globDir.theta()) < 5.8_degree) {
226 return true;
227 }
228 break;
229 }
230 case EO: {
231 if (std::abs(globPos.eta()) > 2.35 &&
232 std::abs(globPos.theta() - globDir.theta()) < 3._degree) {
233 return true;
234 }
235 break;
236 }
237 default:
238 break;
239 }
240 using namespace Acts::detail::LineHelper;
241 const Acts::Intersection3D bsExtp = lineIntersect<3>(Amg::Vector3D::Zero(),
242 Amg::Vector3D::UnitZ(),
243 globPos, globDir);
244 const Amg::Vector3D closePoint = bsExtp.position();
245 const auto rawStIdx = Acts::toUnderlying(stIdx);
246 //coverity[NEGATIVE_RETURNS]
247 if (closePoint.perp() > m_seedMaxBsR.value().at(rawStIdx) * m_beamSpotR ||
248 std::abs(closePoint.z()) > m_seedMaxBsL.value().at(rawStIdx) * m_beamSpotL){
249 ATH_MSG_DEBUG("fitSegmentSeed() - Reject parameters "<<Amg::toString(tangentSeedPos)
250 <<" + "<<Amg::toString(tangentSeedDir)
251 <<" as extrapolation to beamspot is too far "<<Amg::toString(closePoint)
252 <<", r: "<<closePoint.perp());
253 return false;
254 }
255 return true;
256 };
257
258 // Make sure patternSeed->parameters() are in ACTS units!
259 State_t seedState{patternSeed->parameters(), patternSeed, m_calibTool.get(), m_recalibSeed, seedSelector};
260
261 auto visualizeSegmentSeeds = [&](State_t& state, const std::string_view label) {
262 if (m_visionTool.isEnabled()) {
263 PrimitiveVec seedLines{};
264 State_t drawMe{state};
265 while(auto s = m_seeder->nextSeed(cctx, drawMe)) {
266 seedLines.push_back(drawLine(s->parameters, -Gaudi::Units::m, Gaudi::Units::m, kViolet));
267 }
268 seedLines.push_back(drawLabel(std::format("{} possible seeds: {:d}", label, drawMe.nGenSeeds()), 0.2, 0.85, 14));
269 m_visionTool->visualizeSeed(ctx, *patternSeed, std::format("pattern_{:}{:}{:}",
270 patternSeed->msSector()->chamberIndex(),
271 patternSeed->msSector()->side() ? 'A' : 'C' ,
272 patternSeed->msSector()->sector()), std::move(seedLines));
273 }
274 };
275
276 auto runSeeder = [&](State_t&& state) {
277 while (auto seed = m_seeder->nextSeed(cctx, state)) {
278 seed->parameters[toUnderlying(ParamDefs::t0)] = ActsTrk::timeToAthena( seed->parameters[toUnderlying(ParamDefs::t0)]);
279 auto segment = m_fitter->fitSegment(ctx, patternSeed, seed->parameters, locToGlob, std::move(seed->hits));
280 if (segment) {
281 segments.push_back(std::move(segment));
282 }
283 }
284 };
285
286 visualizeSegmentSeeds(seedState, "Nominal Seeds");
287 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - fitSegmentHits() - Start segment seed search");
288 runSeeder(std::move(seedState));
289
290 //----------------------------------------------------------------------------------------
292 /* Trying to recover certain cases where we either have only one multilayer or where the chambers are not overlapping and there are no hits in the other (e.g. BIM & BIR)*/
293 //----------------------------------------------------------------------------------------
295 segments.empty() && (patternSeed->msSector()->chamberIndex() == ChIndex::BIL) ) {
296 // Implement fallback logic here
297 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - fitSegmentSeed() - Standard MDT seeding failed. " "Trying ML fallback.");
298
299 //For recovery seeding we will have smaller hit collection
300 std::optional<SpacePointPerLayerSplitter::HitVec> recoveryHits{};
301
302 // First try the very restrictive BIL single-ML recovery.
303 recoveryHits = makeBilRecoveryHits(*patternSeed);
304
305 if (!recoveryHits) {
306 ATH_MSG_VERBOSE(__func__<< ":" <<__LINE__<< "- BIL recovery did not succeed. Try BIM/BIR.");
307 recoveryHits = makeBimBirRecoveryHits(*patternSeed);
308 }
309
310 // Both recovery modes ultimately use exactly the same nominal MDT seeder. Only their input hits differ.
311 if (recoveryHits) {
312 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - fitSegmentSeed() - ML seeding fallback has " << recoveryHits->size() << " hits.");
313 State_t fallbackState{patternSeed->parameters(), patternSeed, m_calibTool.get(), m_recalibSeed, *recoveryHits, seedSelector};
314 visualizeSegmentSeeds(fallbackState , "Fallback Seeds");
315 runSeeder(std::move(fallbackState));
316 }
317 }
318 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - fitSegmentHits() - In total "<<segments.size()<<" segment were constructed ");
319 return segments;
320
321 }
322
324 SegmentVec_t& segmentCandidates) const {
325 if (segmentCandidates.empty()) {
326 return;
327 }
328 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - resolveAmbiguities() - Resolve ambiguities amongst "
329 <<segmentCandidates.size()<<" segment candidates.");
332
333 for (std::unique_ptr<Segment>& sortMe : segmentCandidates) {
334 const MuonGMR4::SpectrometerSector* chamb = sortMe->msSector();
335 candidatesPerChamber[chamb].push_back(std::move(sortMe));
336 }
337 segmentCandidates.clear();
338 for (auto& [chamber, resolveMe] : candidatesPerChamber) {
339 const std::size_t nBefore = resolveMe.size();
340 SegmentVec_t resolvedSegments = m_ambiSolver->resolveAmbiguity(gctx, std::move(resolveMe));
341 ATH_MSG_DEBUG("resolveAmbiguities() - "<<resolvedSegments.size()<<"/"<<nBefore
342 <<" segments survived ambiguity solving in "<<chamber->identString()<<".");
343 segmentCandidates.insert(segmentCandidates.end(),
344 std::make_move_iterator(resolvedSegments.begin()),
345 std::make_move_iterator(resolvedSegments.end()));
346 }
347 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Ambiguity solving done "<<segmentCandidates.size()<<" survived.");
348 }
349
350
351std::optional<SpacePointPerLayerSplitter::HitVec>
353
354 const auto& mdtHelper = m_idHelperSvc->mdtIdHelper();
355
356 const MuonGMR4::MuonReadoutElement* crossedRE{nullptr};
357
358 // Find BIL readout elements crossed by the Hough trajectory.
359 for (const auto& chamber : seed.parentBucket()->chamberLocations()) {
360
361 const auto* readoutEle = chamber.readoutEle();
362 if (readoutEle->detectorType() != ActsTrk::DetectorType::Mdt) {
363 continue;
364 }
365 const Identifier id = readoutEle->identify();
366 //For now do this only for BIL stations (technically could be even more specific, BIL eta 3 or 4), choose int comparison instead?
367 if (mdtHelper.stationName(id) != m_bilStation) {
368 continue;
369 }
370
372 continue;
373 }
374
375 crossedRE = readoutEle;
376
377 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIL recovery: Hough trajectory crosses "
378 << m_idHelperSvc->toStringDetEl(id));
379 }
380
381 // BIL recovery is strictly a single crossed-ML recovery.
382 if (!crossedRE) {
383 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIL recovery rejected: trajectory crosses no BIL readout elements.");
384 return std::nullopt;
385 }
386
388 recoveryHits.reserve(seed.getHitsInMax().size());
389
390 std::size_t nMdtHits{0};
391
392 for (const SpacePoint* hit : seed.getHitsInMax()) {
393
394 // Preserve non-MDT hits.
396 recoveryHits.push_back(hit);
397 continue;
398 }
399 // Only MDT hits from the single geometrically crossed BIL RE.
400 if (hit->primaryMeasurement()->readoutElement() != crossedRE) {
401 continue;
402 }
403 recoveryHits.push_back(hit);
404 ++nMdtHits;
405 }
406
407 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIL recovery: keeping " << nMdtHits << " MDT hits from " << m_idHelperSvc->toStringDetEl( crossedRE->identify()));
408 return recoveryHits;
409}
410
411
412std::optional<SpacePointPerLayerSplitter::HitVec> SegmentFittingAlg::makeBimBirRecoveryHits( const SegmentSeed& seed) const {
413
414 // For BIM/BIR we rely on the phi extension to distinguish
415 // readout elements which overlap in the eta projection.
416 if (!seed.hasPhiExtension()) {
417 ATH_MSG_VERBOSE("BIM/BIR recovery rejected: seed has no phi extension.");
418 return std::nullopt;
419 }
420
421 const auto& mdtHelper = m_idHelperSvc->mdtIdHelper();
422 /*
423 * Use the geometrical crossing only to identify the recovery
424 * station family (BIM/BIR) and stationPhi.
425 *
426 * Do NOT use the crossed REs themselves for hit filtering:
427 * the Hough trajectory can be biased in eta by high occupancy.
428 */
429 std::optional<int> recoveryStation{};
430
431 for (const auto& chamber : seed.parentBucket()->chamberLocations()) {
432
433 const auto* readoutEle = chamber.readoutEle();
434 if (readoutEle->detectorType() != ActsTrk::DetectorType::Mdt) {
435 continue;
436 }
437
438 const Identifier id = readoutEle->identify();
439 const int station = mdtHelper.stationName(id);
440
441 //Don't care about other stations for now
442 if (station != m_bimStation && station != m_birStation) {
443 continue;
444 }
445 //Don't need any tolerance here
446 if (!trajectoryPassesThroughChamber(chamber, seed, 0., 0.)) {
447 continue;
448 }
449
450 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIM/BIR recovery: Hough trajectory crosses " << m_idHelperSvc->toStringDetEl(id));
451
452 // First crossed BIM/BIR RE defines the recovery region.
453 if (!recoveryStation) {
454 recoveryStation = station;
455 continue;
456 }
457
458 /*
459 * All geometrically crossed BIM/BIR REs must be compatible
460 * with the same station family
461 * Different eta and multilayer are explicitly allowed.
462 */
463 if (*recoveryStation != station){
464 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIM/BIR recovery rejected: crossed readout " "elements belong to different station/phi regions.");
465 return std::nullopt;
466 }
467 }
468 // No geometrically compatible BIM/BIR region.
469 if (!recoveryStation) {
470 return std::nullopt;
471 }
472
473 /*
474 * Now construct the recovery collection.
475 * Selection:
476 * - same BIM/BIR station family
477 * - ANY stationEta
478 * - ANY multilayer
479 * Only hits already belonging to this Hough seed are considered.
480 */
482 recoveryHits.reserve(seed.getHitsInMax().size());
483
484 std::size_t nMdtHits{0};
485 for (const SpacePoint* hit : seed.getHitsInMax()) {
486 //Preserve the non-MDT content of the original seed.
488 recoveryHits.push_back(hit);
489 continue;
490 }
491
492 const Identifier hitId = hit->identify();
493 if (mdtHelper.stationName(hitId) != *recoveryStation) {
494 continue;
495 }
496 recoveryHits.push_back(hit);
497 ++nMdtHits;
498
499 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIM/BIR recovery keeps MDT hit " << m_idHelperSvc->toString(hitId));
500 }
501
502 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - BIM/BIR recovery selected " << nMdtHits << " MDT hits from station " << mdtHelper.stationNameString(*recoveryStation));
503
504 if (nMdtHits == 0) {
505 return std::nullopt;
506 }
507
508 return recoveryHits;
509}
510
511
512}
513
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_VERBOSE(x,...)
bool hit(const Container &ids, int pdgId)
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition Logger.cxx:64
#define x
#define z
size_type size() const noexcept
Returns the number of elements in the collection.
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
Identifier identify() const override final
Return the ATLAS identifier.
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
int8_t side() const
Returns the side of the MS-sector 1 -> A side ; -1 -> C side.
const Acts::Transform3 & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
int sector() const
Returns the sector of the MS-sector.
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index scheme.
SeedingState< HitVec_t, CalibCont_t, SeederStateBase > State_t
Define the state holder object.
std::unique_ptr< SegmentFit::SegmentAmbiSolver > m_ambiSolver
Pointer to the ambiguity reosolution.
Gaudi::Property< unsigned > m_precHitCut
Minimum number of precision hits to accept the segment.
Gaudi::Property< bool > m_hessianResidual
Use the expliciit Hessian in the residual calculation.
virtual StatusCode initialize() override
Gaudi::Property< bool > m_recalibSeed
Toggle seed recalibration.
Gaudi::Property< double > m_seedHitChi2
Two mdt seeds are the same if their defining parameters match wihin.
Gaudi::Property< bool > m_useFastFitter
Use the fast Mdt fitter where possible.
std::optional< SpacePointPerLayerSplitter::HitVec > makeBimBirRecoveryHits(const SegmentSeed &seed) const
BIM/BIR chambers are treated as the same sector, however, they don't overlap in many instances.
int m_birStation
Cached BIR station index for quick access.
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
Gaudi::Property< double > m_beamSpotL
Longitudinal covariance on the beam spo measurement.
Gaudi::Property< bool > m_recalibInFit
SG::WriteHandleKey< SegmentContainer > m_outSegments
SegmentVec_t fitSegmentSeed(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const SegmentSeed *seed) const
Fit the hits from the pattern seed to segment candidates.
int m_bimStation
Cached BIM station index for quick access.
int m_bilStation
Cached BIL station index for quick access.
Gaudi::Property< bool > m_allowSegmentSeedingFallback
Allow single multilayer fallback when standard segment reconstruction fails.
Gaudi::Property< bool > m_fastPreFitter
The fast fitter is treated as a pre fitter.
void resolveAmbiguities(const ActsTrk::GeometryContext &gctx, SegmentVec_t &segmentCandidates) const
Resolve the ambiguity amongst the segment candidates within a spectrometer sector.
std::unique_ptr< SegmentFit::MdtSegmentSeedGenerator > m_seeder
Pointer to the L-R segment seeder.
Gaudi::Property< double > m_singleMlEdgeTolerance
Tolerance for the single multilayer edge crossing test, if the trajectory only slighty nicks the seco...
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc.
Gaudi::Property< bool > m_doBeamspotConstraint
Add beamline constraint.
Gaudi::Property< double > m_singleMlPhiEdgeTolerance
Tolerance for the single multilayer edge crossing test in the phi projection in case the trajectory o...
ToolHandle< ISpacePointCalibrator > m_calibTool
Handle to the space point calibrator.
std::unique_ptr< SegmentFit::SegmentLineFitter > m_fitter
Pointer to the actual segment fitter.
std::vector< std::unique_ptr< Segment > > SegmentVec_t
std::optional< SpacePointPerLayerSplitter::HitVec > makeBilRecoveryHits(const SegmentSeed &seed) const
For BIL (specifically around eta3 chambers), there are cases where only a single multilayer is crosse...
Gaudi::Property< std::vector< double > > m_seedMaxBsL
Gaudi::Property< bool > m_ignoreFailedPreFit
Switch to try the full fit when the fast pre-fitter fails.
SegmentFit::Parameters Parameters
Gaudi::Property< bool > m_doT0Fit
static constexpr auto s_stIdxMax
SG::ReadHandleKey< SegmentSeedContainer > m_seedKey
ReadHandle of the seeds.
Gaudi::Property< std::vector< double > > m_seedMaxBsR
Maximum allowed distance of the segment seed line to the beam spot measurement expressed in relative ...
Gaudi::Property< double > m_recoveryPull
Gaudi::Property< double > m_beamSpotR
Radial covariance on th beam spot measurment.
Gaudi::Property< unsigned > m_maxIter
Tune the number of iterations.
virtual StatusCode execute(const EventContext &ctx) const override
ActsTrk::GeoContextReadKey_t m_geoCtxKey
Gaudi::Property< unsigned > m_busyLayerLimit
Cut on the number of hits per layer to use the layer for seeding.
Gaudi::Property< double > m_outlierRemovalCut
Cut on the segment chi2 / nDoF to launch the outlier removal.
Gaudi::Property< bool > m_tryPatternPars
Try first to fit the pattern parameters. Then proceed with the straw line tangents.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition SegmentSeed.h:14
const Parameters & parameters() const
Returns the parameter array.
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated chamber.
Acts::CloneablePtr< CalibratedSpacePoint > MeasType
Calibrated space point type.
std::vector< const SpacePoint * > HitVec
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
std::string label(const std::string &format, int i)
Definition label.h:19
@ Mdt
MuonSpectrometer.
constexpr double timeToAthena(T actsT)
Converts a time unit from Acts to Athena units.
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
This header ties the generic definitions in this package.
bool trajectoryPassesThroughChamber(const SpacePointBucket::chamberLocation &loc, const SegmentSeed &seed, double etaEdgeTolerance=25. *Gaudi::Units::mm, double phiEdgeTolerance=0.)
brief checks if the trajectory passes through the given chamber in local y,z plane if phiExtension is...
MuonValR4::IPatternVisualizationTool::PrimitiveVec PrimitiveVec
DataVector< SegmentSeed > SegmentSeedContainer
std::unique_ptr< TLine > drawLine(const MuonR4::SegmentFit::Parameters &pars, const double lowEnd, const double highEnd, const int color=kRed+1, const int lineStyle=kDashed, const int view=objViewEta)
Draws a line from the segment fit parameters.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const double textSize=18, const bool useNDC=true, const int color=kBlack)
Create a TLatex label,.
StIndex
enum to classify the different station layers in the muon spectrometer
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
double width(const double y0) const
Calculate the strip / tube length at a given position in the y-z plane.
double maxY() const
Returns the maximum u covered by the chamber location.
double minY() const
Returns the minimum y covered by the chamber location.
const Amg::Vector3D & location() const
Returns the location.
Configuration object to stree the ambiguties.
const ISpacePointCalibrator * calibrator
Pointer to the calibrator.
bool doBeamSpot
Switch to insert a beamspot constraint if possible.
const Muon::IMuonIdHelperSvc * idHelperSvc
Pointer to the idHelperSvc.
unsigned nPrecHitCut
Minimum number of precision hits.
double outlierRemovalCut
Cut on the segment chi2 / nDoF to launch the outlier removal.
const MuonValR4::IPatternVisualizationTool * visionTool
Pointer to the visualization tool.
double recoveryPull
Maximum pull on a measurement to add it back on the line.
double beamSpotRadius
Parameters of the beamspot measurement.