ATLAS Offline Software
Loading...
Searching...
No Matches
SegmentFittingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SegmentFittingAlg.h"
6
8
11
15
16#include <format>
17
18using namespace Acts;
19namespace MuonR4 {
20 using namespace SegmentFit;
21 using namespace MuonValR4;
22
23
25
28 ATH_CHECK(m_geoCtxKey.initialize());
29 ATH_CHECK(m_seedKey.initialize());
30 ATH_CHECK(m_outSegments.initialize());
31 ATH_CHECK(m_calibTool.retrieve());
32 ATH_CHECK(m_idHelperSvc.retrieve());
33 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
35 m_ambiSolver = std::make_unique<SegmentAmbiSolver>(name(), std::move(cfg));
36
38 fitCfg.calibrator = m_calibTool.get();
39 fitCfg.visionTool = m_visionTool.get();
40 fitCfg.idHelperSvc = m_idHelperSvc.get();
41 fitCfg.fitT0 = m_doT0Fit;
42 fitCfg.recalibrate = m_recalibInFit;
43 fitCfg.useFastFitter = m_useFastFitter;
44 fitCfg.fastPreFitter = m_fastPreFitter;
45 fitCfg.useHessian = m_hessianResidual;
46
50
54 fitCfg.maxIter = m_maxIter;
55
56 m_fitter = std::make_unique<SegmentFit::SegmentLineFitter>(name(), std::move(fitCfg));
57
58 return StatusCode::SUCCESS;
59 }
60 StatusCode SegmentFittingAlg::execute(const EventContext& ctx) const {
61 const ActsTrk::GeometryContext* gctx{nullptr};
62 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
63 const SegmentSeedContainer* segmentSeeds=nullptr;
64 ATH_CHECK(SG::get(segmentSeeds, m_seedKey, ctx));
65
66 SG::WriteHandle writeSegments{m_outSegments, ctx};
67 ATH_CHECK(writeSegments.record(std::make_unique<SegmentContainer>()));
68 std::vector<std::unique_ptr<Segment>> allSegments{};
69 for (const SegmentSeed* seed : *segmentSeeds) {
70 std::vector<std::unique_ptr<Segment>> segments = fitSegmentSeed(ctx, *gctx, seed);
71 if (m_visionTool.isEnabled() && segments.size() > 1) {
72 auto drawFinalReco = [this, &segments, &gctx, &ctx,&seed](const std::string& nameTag) {
73 PrimitiveVec segmentLines{};
74 double yLegend{0.85};
75 segmentLines.push_back(drawLabel(std::format("# segments: {:d}", segments.size()), 0.2, yLegend, 14));
76 yLegend-=0.04;
77 for (const std::unique_ptr<Segment>& seg : segments) {
78 const Parameters pars = localSegmentPars(*gctx, *seg);
79 const auto [pos, dir] = makeLine(pars);
80 segmentLines.emplace_back(drawLine(pars, -Gaudi::Units::m, Gaudi::Units::m, kRed));
81 std::stringstream signStream{};
82 signStream<<std::format("#chi^{{2}}/nDoF: {:.2f} ({:}), ", seg->chi2() / seg->nDoF(), seg->nDoF());
83 signStream<<std::format("y_{{0}}={:.2f}",pars[toUnderlying(ParamDefs::y0)])<<", ";
84 signStream<<std::format("#theta={:.2f}^{{#circ}}", pars[toUnderlying(ParamDefs::theta)]/ Gaudi::Units::deg )<<", ";
85 for (const Segment::MeasType& m : seg->measurements()) {
86 if (m->type() == xAOD::UncalibMeasType::MdtDriftCircleType && m->fitState() == CalibratedSpacePoint::State::Valid) {
87 signStream<<(SeedingAux::strawSign(pos, dir, *m) == -1 ? "L" : "R");
88 }
89 }
90 segmentLines.push_back(drawLabel(signStream.str(), 0.2, yLegend, 13));
91 yLegend-=0.03;
92 }
93
94 m_visionTool->visualizeBucket(ctx, *seed->parentBucket(), nameTag, std::move(segmentLines));
95 };
96 drawFinalReco("all segments");
97 const unsigned int nBeforeAmbi = segments.size();
98 segments = m_ambiSolver->resolveAmbiguity(*gctx, std::move(segments));
99 if (nBeforeAmbi != segments.size()) {
100 drawFinalReco("post ambiguity");
101 }
102 } else if (m_visionTool.isEnabled() && segments.empty() &&
103 std::ranges::count_if(seed->getHitsInMax(),[this](const SpacePoint* hit){
104 return m_visionTool->isLabeled(*hit);
105 })) {
106 m_visionTool->visualizeSeed(ctx, *seed, "Failed fit");
107 }
108 allSegments.insert(allSegments.end(), std::make_move_iterator(segments.begin()),
109 std::make_move_iterator(segments.end()));
110 }
111 resolveAmbiguities(*gctx, allSegments);
112 writeSegments->insert(writeSegments->end(),
113 std::make_move_iterator(allSegments.begin()),
114 std::make_move_iterator(allSegments.end()));
115 ATH_MSG_VERBOSE("Found in total "<<writeSegments->size()<<" segments. ");
116 return StatusCode::SUCCESS;
117 }
118
119 std::vector<std::unique_ptr<Segment>>
120 SegmentFittingAlg::fitSegmentSeed(const EventContext& ctx,
121 const ActsTrk::GeometryContext& gctx,
122 const SegmentSeed* patternSeed) const {
123
124 const Amg::Transform3D& locToGlob{patternSeed->msSector()->localToGlobalTrans(gctx)};
125 std::vector<std::unique_ptr<Segment>> segments{};
126
128 genCfg.hitPullCut = m_seedHitChi2;
130 genCfg.calibrator = m_calibTool.get();
132
134 genCfg.busyLayerLimit = 2 + 2*(patternSeed->parameters()[toUnderlying(ParamDefs::theta)] > 50 * Gaudi::Units::deg);
136 if (m_visionTool.isEnabled()) {
137 PrimitiveVec seedLines{};
138 MdtSegmentSeedGenerator drawMe{name(), patternSeed, genCfg};
139 while(auto s = drawMe.nextSeed(ctx)) {
140 seedLines.push_back(drawLine(s->parameters, -Gaudi::Units::m, Gaudi::Units::m, kViolet));
141 }
142 seedLines.push_back(drawLabel(std::format("possible seeds: {:d}", drawMe.numGenerated()), 0.2, 0.85, 14));
143 m_visionTool->visualizeSeed(ctx, *patternSeed, "pattern", std::move(seedLines));
144 }
145
146 MdtSegmentSeedGenerator seedGen{name(), patternSeed, std::move(genCfg)};
147 ATH_MSG_VERBOSE("fitSegmentHits() - Start segment seed search");
148 while (auto seed = seedGen.nextSeed(ctx)) {
149 auto segment = m_fitter->fitSegment(ctx, patternSeed, seed->parameters,
150 locToGlob, std::move(seed->measurements));
151 if (segment) {
152 segments.push_back(std::move(segment));
153 }
154 }
155 ATH_MSG_VERBOSE("fitSegmentHits() - In total "<<segments.size()<<" segment were constructed ");
156 return segments;
157 }
158
160 std::vector<std::unique_ptr<Segment>>& segmentCandidates) const {
161 if (segmentCandidates.empty()) {
162 return;
163 }
164 using SegmentVec = std::vector<std::unique_ptr<Segment>>;
165 ATH_MSG_VERBOSE("Resolve ambiguities amongst "<<segmentCandidates.size()<<" segment candidates. ");
166 std::unordered_map<const MuonGMR4::SpectrometerSector*, SegmentVec> candidatesPerChamber{};
167
168 for (std::unique_ptr<Segment>& sortMe : segmentCandidates) {
169 const MuonGMR4::SpectrometerSector* chamb = sortMe->msSector();
170 candidatesPerChamber[chamb].push_back(std::move(sortMe));
171 }
172 segmentCandidates.clear();
173 for (auto& [chamber, resolveMe] : candidatesPerChamber) {
174 SegmentVec resolvedSegments = m_ambiSolver->resolveAmbiguity(gctx, std::move(resolveMe));
175 segmentCandidates.insert(segmentCandidates.end(),
176 std::make_move_iterator(resolvedSegments.begin()),
177 std::make_move_iterator(resolvedSegments.end()));
178 }
179 }
180}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Helper class to generate valid seeds for the segment fit.
unsigned int numGenerated() const
Returns how many seeds have been generated.
std::optional< DriftCircleSeed > nextSeed(const EventContext &ctx)
returns the next seed in the row
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.
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
Gaudi::Property< double > m_beamSpotL
Gaudi::Property< bool > m_recalibInFit
SG::WriteHandleKey< SegmentContainer > m_outSegments
Gaudi::Property< bool > m_fastPreFitter
The fast fitter is treated as a pre fitter.
std::vector< std::unique_ptr< Segment > > fitSegmentSeed(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const SegmentSeed *seed) const
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc.
Gaudi::Property< bool > m_doBeamspotConstraint
Add beamline constraint.
ToolHandle< ISpacePointCalibrator > m_calibTool
Handle to the space point calibrator.
std::unique_ptr< SegmentFit::SegmentLineFitter > m_fitter
Pointer to the actual segment fitter.
SegmentFit::Parameters Parameters
Gaudi::Property< bool > m_doT0Fit
SG::ReadHandleKey< SegmentSeedContainer > m_seedKey
ReadHandle of the seeds.
Gaudi::Property< double > m_recoveryPull
void resolveAmbiguities(const ActsTrk::GeometryContext &gctx, std::vector< std::unique_ptr< Segment > > &segmentCandidates) const
Gaudi::Property< double > m_beamSpotR
Gaudi::Property< unsigned > m_maxIter
Tune the number of iterations.
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
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.
std::unique_ptr< CalibratedSpacePoint > MeasType
Calibrated space point type.
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.
Eigen::Affine3d Transform3D
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.
SegmentAmbiSolver::SegmentVec SegmentVec
This header ties the generic definitions in this package.
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 unsigned int fontSize=18)
Create a TLatex label,.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
bool startWithPattern
Try at the first time the pattern seed as candidate.
bool recalibSeedCircles
Recalibrate the seed drift circles from the initial estimate.
const MuonR4::ISpacePointCalibrator * calibrator
Pointer to the space point calibrator.
unsigned int busyLayerLimit
How many drift circles may be on a layer to be used for seeding.
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.