ATLAS Offline Software
Loading...
Searching...
No Matches
MsTrackFindingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MsTrackFindingAlg.h"
6
7#include "Acts/Surfaces/PerigeeSurface.hpp"
8#include "Acts/Surfaces/PlaneSurface.hpp"
9#include "Acts/Surfaces/detail/PlanarHelper.hpp"
10
11
15
16#include "GaudiKernel/PhysicalConstants.h"
20
22
24#include "GaudiKernel/PhysicalConstants.h"
27
28#include <system_error>
29
30using namespace Acts::UnitLiterals;
31using namespace Acts::PlanarHelper;
32
33namespace MuonR4{
35 ATH_CHECK(m_idHelperSvc.retrieve());
36 ATH_CHECK(detStore()->retrieve(m_detMgr));
38
39 ATH_CHECK(m_visualizationTool.retrieve(EnableTool{!m_visualizationTool.empty()}));
40 ATH_CHECK(m_trackFitTool.retrieve());
41 ATH_CHECK(m_calibTool.retrieve());
42 ATH_CHECK(m_writeKey.initialize());
43 ATH_CHECK(m_summaryTool.retrieve());
44 ATH_CHECK(m_seedingTool.retrieve());
45 ATH_CHECK(m_extrapolationTool.retrieve(EnableTool{m_expressAtMsEntrance}));
47
48 ATH_CHECK(m_ctxProvider.initialize());
49 return StatusCode::SUCCESS;
50 }
51
53
54 StatusCode MsTrackFindingAlg::execute(const EventContext& ctx) const {
55 ATH_MSG_VERBOSE("Run track finding in event "<<ctx.eventID().event_number());
56
57
58 auto seedContainer = std::make_unique<MsTrackSeedContainer>();
59
60 ATH_CHECK(m_seedingTool->findTrackSeeds(ctx, *seedContainer));
61
62 if (!m_visualizationTool.empty()) {
63 m_visualizationTool->displaySeeds(ctx, *seedContainer);
64 }
65 const Acts::GeometryContext tgContext = m_ctxProvider.getGeometryContext(ctx);
66 const Acts::MagneticFieldContext mfContext = m_ctxProvider.getMagneticFieldContext(ctx);
67 const Acts::CalibrationContext calContext{m_ctxProvider.getCalibrationContext(ctx)};
68
69
70 Acts::VectorTrackContainer trackBackend{};
71 Acts::VectorMultiTrajectory trackStateBackend{};
72 ActsTrk::MutableTrackContainer cacheTrkContainer{std::move(trackBackend),
73 std::move(trackStateBackend)};
75 cacheTrkContainer.addColumn<std::size_t>("parentSeed");
76 unsigned seedIdx{0};
77 for (const MsTrackSeed& seed : *seedContainer) {
78 if (!fitSeedCandidate(tgContext, mfContext, calContext, seed,
79 cacheTrkContainer)) {
80 ++seedIdx;
81 continue;
82 }
83 auto lastTrack = cacheTrkContainer.getTrack(cacheTrkContainer.size() -1);
84 lastTrack.component<std::size_t, Acts::hashString("parentSeed")>() = seedIdx;
85 ++seedIdx;
86 }
87 if (!m_msTrkSeedKey.empty()) {
88 SG::WriteHandle writeHandleSeed{m_msTrkSeedKey, ctx};
89 ATH_CHECK(writeHandleSeed.record(std::move(seedContainer)));
90 }
91
92 // Constant declination
93 Acts::ConstVectorTrackContainer ctrackBackend{std::move(cacheTrkContainer.container())};
94 Acts::ConstVectorMultiTrajectory ctrackStateBackend{std::move(cacheTrkContainer.trackStateContainer())};
95 auto ctc = std::make_unique<ActsTrk::TrackContainer>(std::move(ctrackBackend),
96 std::move(ctrackStateBackend));
97
98 SG::WriteHandle writeHandle{m_writeKey, ctx};
99 ATH_CHECK(writeHandle.record(std::move(ctc)));
100 return StatusCode::SUCCESS;
101 }
102
105 MsTrackFindingAlg::prepareFit(const Acts::GeometryContext& tgContext,
106 const Acts::CalibrationContext& calContext,
107 const MsTrackSeed& seed) const {
108 const EventContext& ctx{*calContext.get<const EventContext*>()};
109
110 auto initialPars = m_seedingTool->estimateStartParameters(ctx, seed);
111 if (!initialPars.ok()) {
112 ATH_MSG_WARNING(__func__<<"() "<<__LINE__
113 <<" - Start parameter creation failed. ");
114 return std::make_pair(OptBoundPars_t::failure(std::make_error_code(std::errc::invalid_argument)),
115 std::vector<const xAOD::UncalibratedMeasurement_v1*>{});
116 }
117
118 MeasVec_t measurements{};
119 measurements.reserve(100);
120 for (const xAOD::MuonSegment* segment : seed.segments()) {
122 m_calibTool->stampSignsOnMeasurements(*segment);
123 MeasVec_t segMeasurements = collectMeasurements(*segment, /*skipOutlier:*/ true);
124 if (msgLvl(MSG::VERBOSE)) {
125 std::stringstream sstr{};
126 for (const xAOD::UncalibratedMeasurement* m : segMeasurements) {
127 const Acts::Surface& surf{xAOD::muonSurface(m)};
128 sstr<<" *** "<<m_idHelperSvc->toString(xAOD::identify(m))
129 <<", "<<m->numDimensions()<<", "
130 <<", "<<surf.geometryId()<<" @ "<<Amg::toString(surf.localToGlobalTransform(tgContext))<<std::endl;
131 }
132 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Fetch measurements from segment: "<<Amg::toString(segment->position())
133 <<", direction: "<<Amg::toString(segment->direction()) << " eta " << segment->direction().eta() << " phi " << segment->direction().phi() <<"\n"<<sstr.str());
134 }
135 measurements.insert(measurements.end(),
136 std::make_move_iterator(segMeasurements.begin()),
137 std::make_move_iterator(segMeasurements.end()));
138 }
139
140 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - "<<measurements.size()<<" measurements");
141 if (measurements.empty()) {
142 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - No measurements were associated with seed "<<seed);
143 return std::make_pair(OptBoundPars_t::failure(std::make_error_code(std::errc::invalid_argument)),
144 std::vector<const xAOD::UncalibratedMeasurement_v1*>{});
145 }
146 return std::make_pair(std::move(initialPars), std::move(measurements));
147
148 }
149 bool MsTrackFindingAlg::fitSeedCandidate(const Acts::GeometryContext& tgContext,
150 const Acts::MagneticFieldContext& mfContext,
151 const Acts::CalibrationContext& calContext,
152 const MsTrackSeed& seed,
153 ActsTrk::MutableTrackContainer& outContainer) const {
154
155 ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Attempt to fit a new track seed \n"<<seed);
156 const EventContext& ctx{*calContext.get<const EventContext*>()};
157 const auto [initialPars, measurements] = prepareFit(tgContext, calContext, seed);
158
159 if (!initialPars.ok()) {
160 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Failed to construct valid parameters for seed \n"<<seed);
161 if (m_visualizationTool.isEnabled()) {
162 m_visualizationTool->displayTrackSeedObj(ctx, seed, initialPars, "FailedStartPars");
163 }
164 return false;
165 }
166 auto fitTraject = m_trackFitTool->fit(measurements, *initialPars,
167 tgContext, mfContext, calContext,
168 &(*initialPars).referenceSurface());
169 if (!fitTraject || fitTraject->size() == 0) {
170 ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Fit failed. Seed was \n"<<seed);
171 if (m_visualizationTool.isEnabled()) {
172 m_visualizationTool->displayTrackSeedObj(ctx, seed, initialPars, "FailedFit");
173 }
174 return false;
175 }
176
177 ActsTrk::MutableTrackContainer::TrackProxy track = fitTraject->getTrack(0);
178 // Check the hit counts on track post fit and if we only have one station on track discard track
179 // Eventually we should implement some recovery mechanism for track where we loose too many stations
180 MuonR4::HitSummary summary = m_summaryTool->makeSummary(ctx, track);
181 ATH_MSG_DEBUG("Track has " << static_cast<std::uint32_t>(summary.nPrecisionStations()) << " precision layers with summary "<< summary);
182 if(summary.nPrecisionStations()<2) {
183 ATH_MSG_DEBUG("rejecting single station track");
184 return false;
185 }
186 if (!expressAtCaloExit(ctx, track)) {
187
188 return false;
189 }
190
195 {
196 fitTraject->addColumn<std::vector<const xAOD::MuonSegment*>>("muonSegLinks");
197 auto appendMe = seed.segments();
198 auto& toAppend = track.component<std::vector<const xAOD::MuonSegment*>>("muonSegLinks");
199 toAppend.insert(toAppend.end(), appendMe.begin(), appendMe.end());
200 }
201 outContainer.ensureDynamicColumns(*fitTraject);
202 auto destProxy = outContainer.getTrack(outContainer.addTrack());
203 destProxy.copyFrom(track);
204 ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Good track fit...");
205 if (m_visualizationTool.isEnabled()) {
206 m_visualizationTool->displayTrackSeedObj(ctx, seed,
207 destProxy.createParametersAtReference(), "GoodFit");
208 }
209 return true;
210 }
211 bool MsTrackFindingAlg::expressAtCaloExit(const EventContext& ctx,
212 ActsTrk::MutableTrackContainer::TrackProxy track) const {
214 return true;
215 }
216 const Acts::BoundTrackParameters startPars = track.createParametersAtReference();
217 const Acts::TrackingVolume* msEntrance = m_trackingGeometrySvc->getEnvelope(ActsTrk::SystemEnvelope::CaloExit);
218 const Acts::GeometryContext tgContext = m_ctxProvider.getGeometryContext(ctx);
219 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Extrapolate "<<startPars<<", "
220 <<startPars.referenceSurface().toString(tgContext)<<" to MS entrance: "<<msEntrance->volumeBounds());
221
222 auto parsAtEntrance = m_extrapolationTool->propagate(ctx, startPars, *msEntrance,
224 Acts::Direction::Backward());
225
226 if (!parsAtEntrance.ok()) {
227 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Failed to extrapolate "<<startPars<<" to MS entrance");
229 }
230 if (parsAtEntrance->referenceSurface().geometryId().withBoundary(0) != msEntrance->geometryId()) {
231 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Parameter extrapolation to "<<(*parsAtEntrance)<<", @"
232 << Amg::toString(parsAtEntrance->referenceSurface().localToGlobalTransform(tgContext))
233 <<" did not end up at "<<msEntrance->geometryId()<<".");
235 }
236 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Extrapolated start parameters to "<<(*parsAtEntrance)
237 <<", "<<parsAtEntrance->referenceSurface().toString(tgContext));
238 track.setReferenceSurface(parsAtEntrance->referenceSurface().getSharedPtr());
239 track.parameters() = parsAtEntrance->parameters();
240 track.covariance() = (*parsAtEntrance->covariance());
241 return true;
242 }
243
244}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ATLAS-specific HepMC functions.
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
bool fitSeedCandidate(const Acts::GeometryContext &tgContext, const Acts::MagneticFieldContext &mfContext, const Acts::CalibrationContext &calContext, const MsTrackSeed &seed, ActsTrk::MutableTrackContainer &outContainer) const
Attempts to fit the track seed candidate to a full track and returns whether the fit succeeded.
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
Service handle to the tracking geometry service.
bool expressAtCaloExit(const EventContext &ctx, ActsTrk::MutableTrackContainer::TrackProxy track) const
ToolHandle< ITrackSeedingTool > m_seedingTool
The track seeding tool to construct the seed candidates and to estimate the initial parameters.
Acts::Result< Acts::BoundTrackParameters > OptBoundPars_t
std::vector< const xAOD::UncalibratedMeasurement * > MeasVec_t
SG::WriteHandleKey< ActsTrk::TrackContainer > m_writeKey
Key to the output track container.
SG::WriteHandleKey< MsTrackSeedContainer > m_msTrkSeedKey
Temporary container write handle to push the seeds to store gate for later efficiency analysis.
virtual StatusCode execute(const EventContext &ctx) const override final
Standard algorithm execution hook.
std::pair< OptBoundPars_t, MeasVec_t > prepareFit(const Acts::GeometryContext &tgContext, const Acts::CalibrationContext &calContext, const MsTrackSeed &seed) const
Prepares the input to the fit by collecting the measurements on the segment &.
ToolHandle< ISpacePointCalibrator > m_calibTool
Calibration tool to fill the track states.
ToolHandle< MuonValR4::ITrackVisualizationTool > m_visualizationTool
Visualization tool to debug the track finding.
const MuonGMR4::MuonDetectorManager * m_detMgr
Pointer to the MuonDetectorManager.
ToolHandle< ActsTrk::IFitterTool > m_trackFitTool
Track fitting tool.
virtual StatusCode initialize() override final
Standard algorithm hook to setup the extrapolator, retrieve the tools and declare algorithm's data de...
ToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
Track extrapolation tool.
Gaudi::Property< bool > m_expressAtMsEntrance
Propagate the track at the MS entry and express its parameters.
ActsTrk::ContextUtility m_ctxProvider
Utility to fetch the geometry, magnetic field and calibration context in the event.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc to decode the Identifiers.
Gaudi::Property< bool > m_ignoreFailedMsEntrance
Ignore failed track extrapolations to the entrance.
ToolHandle< MuonR4::ITrackSummaryTool > m_summaryTool
Handle to the muon summary tool.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Acts::TrackContainer< MutableTrackBackend, MutableTrackStateBackend, Acts::detail::ValueHolder > MutableTrackContainer
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
This header ties the generic definitions in this package.
std::vector< const xAOD::UncalibratedMeasurement * > collectMeasurements(const xAOD::MuonSegment &segment, bool skipOutlier=true)
Helper function to extract the measurements from the segment.
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
MuonSegment_v1 MuonSegment
Reference the current persistent version:
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
Summary struct to hold the hit counts on the track per MS layer.
Definition HitSummary.h:23