ATLAS Offline Software
MsTrackFindingAlg.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 "MsTrackFindingAlg.h"
6 
7 #include "Acts/Surfaces/PerigeeSurface.hpp"
8 #include "Acts/Surfaces/PlaneSurface.hpp"
9 #include "Acts/Surfaces/detail/PlanarHelper.hpp"
10 
11 
16 
17 #include "GaudiKernel/PhysicalConstants.h"
20 
22 #include "GaudiKernel/PhysicalConstants.h"
23 #include "TruthUtils/AtlasPID.h"
25 
26 using namespace Acts::UnitLiterals;
27 using namespace Acts::PlanarHelper;
28 
29 namespace MuonR4{
31  ATH_CHECK(m_segmentKey.initialize());
32  ATH_CHECK(m_idHelperSvc.retrieve());
33  ATH_CHECK(detStore()->retrieve(m_detMgr));
34  ATH_CHECK(m_segSelector.retrieve());
35  ATH_CHECK(m_msTrkSeedKey.initialize());
36 
37  ATH_CHECK(m_visualizationTool.retrieve(EnableTool{!m_visualizationTool.empty()}));
38 
39  ATH_CHECK(m_trackingGeometryTool.retrieve());
40  ATH_CHECK(m_extrapolationTool.retrieve());
41  ATH_CHECK(m_trackFitTool.retrieve());
42  ATH_CHECK(m_calibTool.retrieve());
43  ATH_CHECK(m_writeKey.initialize());
44 
45 
46  MsTrackSeeder::Config seederCfg{};
47  seederCfg.seedHalfLength = m_seedHalfLength;
48  seederCfg.selector = m_segSelector.get();
49  seederCfg.detMgr = m_detMgr;
50 
51  m_seeder = std::make_unique<MsTrackSeeder>(name(), std::move(seederCfg));
52  return StatusCode::SUCCESS;
53  }
54 
55  MsTrackFindingAlg::~MsTrackFindingAlg() = default;
56 
57  StatusCode MsTrackFindingAlg::execute(const EventContext& ctx) const {
58  ATH_MSG_VERBOSE("Run track finding in event "<<ctx.eventID().event_number());
59 
60  const xAOD::MuonSegmentContainer* allEventSegs{nullptr};
61  ATH_CHECK(SG::get(allEventSegs, m_segmentKey, ctx));
62 
63  auto seedContainer = findTrackSeeds(ctx, *allEventSegs);
64 
65  const Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
66  const Acts::MagneticFieldContext mfContext = m_extrapolationTool->getMagneticFieldContext(ctx);
67  const Acts::CalibrationContext calContext{ActsTrk::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  SG::WriteHandle writeHandleSeed{m_msTrkSeedKey, ctx};
88  ATH_CHECK(writeHandleSeed.record(std::move(seedContainer)));
89 
90  // Constant declination
91  Acts::ConstVectorTrackContainer ctrackBackend{std::move(cacheTrkContainer.container())};
92  Acts::ConstVectorMultiTrajectory ctrackStateBackend{std::move(cacheTrkContainer.trackStateContainer())};
93  auto ctc = std::make_unique<ActsTrk::TrackContainer>(std::move(ctrackBackend),
94  std::move(ctrackStateBackend));
95 
96  SG::WriteHandle writeHandle{m_writeKey, ctx};
97  ATH_CHECK(writeHandle.record(std::move(ctc)));
98  return StatusCode::SUCCESS;
99  }
100 
101  std::unique_ptr<MsTrackSeedContainer>
102  MsTrackFindingAlg::findTrackSeeds(const EventContext& ctx,
103  const xAOD::MuonSegmentContainer& segments) const {
104 
105  auto seedContainer = m_seeder->findTrackSeeds(ctx, m_trackingGeometryTool->getGeometryContext(ctx), segments);
106 
107  if (!m_visualizationTool.empty()) {
108  m_visualizationTool->displaySeeds(ctx, *m_seeder, segments, *seedContainer, "all seeds");
109  }
110  return seedContainer;
111  }
114  MsTrackFindingAlg::prepareFit(const Acts::GeometryContext& tgContext,
115  const Acts::MagneticFieldContext& mfContext,
116  const Acts::CalibrationContext& calContext,
117  const MsTrackSeed& seed) const {
118  const EventContext& ctx{*calContext.get<const EventContext*>()};
119  MeasVec_t measurements{};
120  measurements.reserve(100);
122  const xAOD::MuonSegment* refSeg{nullptr};
123  for (const xAOD::MuonSegment* segment : seed.segments()) {
125  m_calibTool->stampSignsOnMeasurements(*segment);
126  MeasVec_t segMeasurements = collectMeasurements(*segment, /*skipOutlier:*/ true);
127  if (msgLvl(MSG::VERBOSE)) {
128  std::stringstream sstr{};
129  for (const xAOD::UncalibratedMeasurement* m : segMeasurements) {
130  const Acts::Surface& surf{xAOD::muonSurface(m)};
131  sstr<<" *** "<<m_idHelperSvc->toString(xAOD::identify(m))
132  <<", "<<m->numDimensions()<<", "
133  <<", "<<surf.geometryId()<<" @ "<<Amg::toString(surf.transform(tgContext))<<std::endl;
134  }
135  ATH_MSG_VERBOSE("Fetch measurements from segment: "<<Amg::toString(segment->position())
136  <<", direction: "<<Amg::toString(segment->direction())<<"\n"<<sstr.str());
137  }
138  measurements.insert(measurements.end(),
139  std::make_move_iterator(segMeasurements.begin()),
140  std::make_move_iterator(segMeasurements.end()));
141 
142  if (!refSeg && m_segSelector->passSeedingQuality(ctx, *detailedSegment(*segment))) {
143  refSeg = segment;
144  }
145  }
146  Amg::Vector3D seedPos{refSeg->position()};
147  Amg::Vector3D seedDir{refSeg->direction()};
151  if (false && refSeg != seed.segments().front()) {
152  const MuonGMR4::SpectrometerSector* innerPlane = m_seeder->envelope(*seed.segments().front());
153  const Acts::PlaneSurface& surf = innerPlane->surface();
154  const Amg::Transform3D toInnerPlane = surf.transform(tgContext).inverse();
155  const Amg::Vector3D locSeedPos = toInnerPlane * seedPos;
156  const Amg::Vector3D locSeedDir = toInnerPlane.linear() * seedDir;
157 
158  auto seedOnInner = Acts::PlanarHelper::intersectPlane(locSeedPos, locSeedDir,
159  Amg::Vector3D::UnitZ(), 0.);
160 
161  using enum SegmentFit::ParamDefs;
162  SegmentFit::Parameters innerPars = SegmentFit::localSegmentPars(*seed.segments().front());
163  innerPars[Acts::toUnderlying(x0)] = seedOnInner.position().x();
164  const Amg::Vector3D innerSegDir =
165  Acts::makeDirectionFromPhiTheta(innerPars[Acts::toUnderlying(phi)],
166  innerPars[Acts::toUnderlying(theta)]);
167  const Amg::Vector3D combSegDir =
168  Acts::makeDirectionFromAxisTangents(houghTanAlpha(locSeedDir),
169  houghTanBeta(innerSegDir));
170  seedPos = surf.transform(tgContext) * Amg::Vector3D{innerPars[Acts::toUnderlying(x0)],
171  innerPars[Acts::toUnderlying(y0)], 0};
172  seedDir = surf.transform(tgContext).linear() * combSegDir;
173  }
175  const double propDistance = (xAOD::muonSurface(measurements[0]).center(tgContext) -
176  seedPos).dot(seedDir) - 1.*Gaudi::Units::cm;
177  const Amg::Vector3D refPos = seedPos + propDistance * seedDir;
178  auto target = Acts::Surface::makeShared<Acts::PerigeeSurface>(refPos);
179 
180  auto fourPos = ActsTrk::convertPosToActs(refPos, refPos.mag() / Gaudi::Units::c_light);
181  const double qOverP = 1./ m_seeder->estimateQtimesP(*tgContext.get<const ActsTrk::GeometryContext*>(),
182  *mfContext.get<const AtlasFieldCacheCondObj*>(), seed);
183  auto initialPars = Acts::BoundTrackParameters::create(tgContext, target, fourPos,
184  seedDir,
186  Acts::BoundSquareMatrix::Identity(),
188  return std::make_pair(std::move(initialPars), std::move(measurements));
189 
190  }
191  void MsTrackFindingAlg::visualizeObj(const Acts::GeometryContext& tgContext,
192  const Acts::CalibrationContext& calContext,
193  const MsTrackSeed& seed,
194  const OptBoundPars_t& parsToExt) const {
195  if (!m_drawEvent) {
196  return;
197  }
198  const EventContext& ctx {*calContext.get<const EventContext*>()};
199  const ActsTrk::GeometryContext& gctx{*tgContext.get<const ActsTrk::GeometryContext*>()};
200  Acts::ObjVisualization3D visualHelper{};
201  if (parsToExt.ok()) {
202  MuonValR4::drawPropagation(m_extrapolationTool->propagationSteps(ctx, *parsToExt).first,
203  visualHelper);
204  }
205  std::string saveStr = std::format("MsTrackFinding_{:}", ctx.eventID().event_number());
206  for (const xAOD::MuonSegment* seg : seed.segments()) {
207  MuonValR4::drawSegmentMeasurements(gctx,* seg, visualHelper);
208  MuonValR4::drawSegmentLine(gctx,*seg, visualHelper);
209  saveStr += std::format("_{:}_{:}", printID(*seg), seg->index());
210  }
211  saveStr+=".obj";
212  visualHelper.write(saveStr);
213  }
214 
215 
216  bool MsTrackFindingAlg::fitSeedCandidate(const Acts::GeometryContext& tgContext,
217  const Acts::MagneticFieldContext& mfContext,
218  const Acts::CalibrationContext& calContext,
219  const MsTrackSeed& seed,
220  ActsTrk::MutableTrackContainer& outContainer) const {
221 
222  ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Attempt to fit a new track seed \n"<<seed);
223 
224  const auto [initialPars, measurements] = prepareFit(tgContext, mfContext, calContext, seed);
225 
226  if (!initialPars.ok()) {
227  ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Failed to construct valid parameters for seed \n"<<seed);
228  visualizeObj(tgContext, calContext, seed, initialPars);
229  return false;
230  }
231  auto fitTraject = m_trackFitTool->fit(measurements, *initialPars,
232  tgContext, mfContext, calContext,
233  &(*initialPars).referenceSurface());
234  if (!fitTraject || fitTraject->size() == 0) {
235  ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Fit failed ");
236  visualizeObj(tgContext, calContext, seed, initialPars);
237  return false;
238  }
239  outContainer.ensureDynamicColumns(*fitTraject);
240  auto destProxy = outContainer.getTrack(outContainer.addTrack());
241  destProxy.copyFrom(fitTraject->getTrack(0));
242  ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Good track fit...");
243  for (const auto state : destProxy.trackStates()) {
244  if (!state.hasUncalibratedSourceLink()){
245  continue;
246  }
247  auto meas = ActsTrk::detail::xAODUncalibMeasCalibrator::unpack(state.getUncalibratedSourceLink());
248  ATH_MSG_DEBUG("Accepted measurement "<<m_idHelperSvc->toString(xAOD::identify(meas))
249  <<", "<<xAOD::muonSurface(meas).geometryId());
250  }
251  return true;
252  }
253 
254 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MuonR4::collectMeasurements
std::vector< const xAOD::UncalibratedMeasurement * > collectMeasurements(const Segment &seg, bool skipOutlier=true)
Helper function to extract the measurements from the segment.
Definition: TrackingHelpers.cxx:33
MuonR4::printID
std::string printID(const xAOD::MuonSegment &seg)
Print the chamber ID of a segment, e.g.
Definition: TrackingHelpers.cxx:15
ActsTrk::getCalibrationContext
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
Definition: CalibrationContext.h:15
MuonSimHitHelpers.h
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:196
xAOD::identify
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:95
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:40
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
vtune_athena.format
format
Definition: vtune_athena.py:14
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
MuonR4::MsTrackSeed
Definition: MsTrackSeed.h:18
initialize
void initialize()
Definition: run_EoverP.cxx:894
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
MsTrackSeeder.h
ActsTrk::energyToActs
constexpr double energyToActs(const double athenaE)
Converts an energy scalar from Athena to Acts units.
Definition: UnitConverters.h:21
ActsTrk::MutableTrackContainer
Acts::TrackContainer< MutableTrackBackend, MutableTrackStateBackend, Acts::detail::ValueHolder > MutableTrackContainer
Definition: TrackContainer.h:27
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
xAODUncalibMeasCalibrator.h
ActsTrk::convertPosToActs
Acts::Vector4 convertPosToActs(const Amg::Vector3D &athenaPos, const double athenaTime=0.)
Converts a position vector & time from Athena units into Acts units.
Definition: UnitConverters.h:74
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
InDetAccessor::qOverP
@ qOverP
perigee
Definition: InDetAccessor.h:35
MatrixUtils.h
MuonValR4::drawSegmentLine
void drawSegmentLine(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=1.*Gaudi::Units::m)
Draw a segment line inside the obj file.
Definition: ObjVisualizationHelpers.cxx:46
ActsTrk::detail::xAODUncalibMeasCalibrator::unpack
static const xAOD::UncalibratedMeasurement * unpack(const Acts::SourceLink &sl)
Helper method to unpack an Acts source link to an uncalibrated measurement.
Definition: xAODUncalibMeasCalibrator.cxx:12
MuonR4::MsTrackFindingAlg::MeasVec_t
std::vector< const xAOD::UncalibratedMeasurement * > MeasVec_t
Definition: MsTrackFindingAlg.h:50
MuonR4::detailedSegment
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Definition: TrackingHelpers.cxx:22
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
MuonR4::houghTanBeta
double houghTanBeta(const Amg::Vector3D &v)
Returns the hough tanBeta [y] / [z].
Definition: SegmentFitterEventData.cxx:26
CalibrationContext.h
xAOD::UncalibratedMeasurement_v1
Definition: UncalibratedMeasurement_v1.h:13
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:283
UnitConverters.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonValR4::drawPropagation
void drawPropagation(const std::vector< Acts::detail::Step > &steps, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine)
Definition: ObjVisualizationHelpers.cxx:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ObjVisualizationHelpers.h
MuonR4::SegmentFit::Parameters
Acts::Experimental::CompositeSpacePointLineFitter::ParamVec_t Parameters
Definition: MuonHoughDefs.h:46
MuonGMR4::SpectrometerSector::surface
const Acts::PlaneSurface & surface() const
Returns the associated surface.
Definition: SpectrometerSector.cxx:72
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
TrackingHelpers.h
MuonR4::MsTrackFindingAlg::OptBoundPars_t
Acts::Result< Acts::BoundTrackParameters > OptBoundPars_t
Definition: MsTrackFindingAlg.h:49
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
MsTrackFindingAlg.h
MuonR4::MsTrackSeeder::Config::seedHalfLength
double seedHalfLength
Maximum separation of point on the cylinder to be picked up onto a seed.
Definition: MsTrackSeeder.h:44
MuonValR4::drawSegmentMeasurements
void drawSegmentMeasurements(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw all uncalibrated measurements associated to the segment.
Definition: ObjVisualizationHelpers.cxx:81
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:73
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
xAOD::muonSurface
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:68
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
copySelective.target
string target
Definition: copySelective.py:36
MuonR4::SegmentFit::localSegmentPars
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
Definition: SegmentFitterEventData.cxx:42
MuonR4::MsTrackSeeder::Config
Configuration object.
Definition: MsTrackSeeder.h:32
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Pmt::ParamDefs
ParamDefs
This file defines the parameter enums in the Trk namespace.
Definition: PoorMansIpAugmenterAlg.cxx:26
MuonR4::houghTanAlpha
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
Definition: SegmentFitterEventData.cxx:30
AtlasPID.h
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106