ATLAS Offline Software
Loading...
Searching...
No Matches
ExtrapolateMuonToIPTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <vector>
8
10
11ExtrapolateMuonToIPTool::ExtrapolateMuonToIPTool(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t, n, p) {
12 declareInterface<Muon::IMuonTrackExtrapolationTool>(this);
13}
14
15// Initialize method:
17 ATH_CHECK(m_extrapolator.retrieve());
18 ATH_CHECK(m_muonExtrapolator.retrieve());
19 if (!m_edmHelperSvc.empty()) {
20 ATH_CHECK(m_edmHelperSvc.retrieve());
21 ATH_MSG_DEBUG("Retrieved helper " << m_edmHelperSvc);
22 }
23 if (!m_printer.empty()) {
24 ATH_CHECK(m_printer.retrieve());
25 ATH_MSG_DEBUG("Retrieved printer " << m_printer);
26 }
27 ATH_CHECK(m_trackSummary.retrieve());
28 return StatusCode::SUCCESS;
29}
30
31// Finalize method:
33 double scale = m_nextrapolations != 0 ? 1. / m_nextrapolations : 1.;
34 ATH_MSG_INFO("Total number of extrapolations " << m_nextrapolations << " good fraction " << scale * m_nextrapolations
35 << " listing failures");
36 ATH_MSG_INFO(" no closest parameters " << scale * m_failedClosestPars);
37 ATH_MSG_INFO(" no extrapolation, low pt " << scale * m_failedExtrapolationLowMom);
38 ATH_MSG_INFO(" no extrapolation, high pt " << scale * m_failedExtrapolationHighMom);
39 ATH_MSG_INFO(" problem with perigee creations " << scale * m_failedPerigeeCreation);
40 return StatusCode::SUCCESS;
41}
42
43std::unique_ptr<TrackCollection> ExtrapolateMuonToIPTool::extrapolate(const TrackCollection& muonTracks, const EventContext& ctx) const {
44 std::unique_ptr<TrackCollection> extrapolateTracks = std::make_unique<TrackCollection>();
45 extrapolateTracks->reserve(muonTracks.size());
46
47 ATH_MSG_DEBUG("Extrapolated tracks: " << muonTracks.size());
48
49 // loop over muon tracks and extrapolate them to the IP
50 for (const Trk::Track* trk : muonTracks) {
51 std::unique_ptr<Trk::Track> extrapolateTrack = extrapolate(*trk, ctx);
52 if (!extrapolateTrack) {
53 ATH_MSG_DEBUG("Extrapolation of muon to IP failed");
54 continue;
55 }
56
57 ATH_MSG_DEBUG("Extrapolated track " << m_printer->print(*extrapolateTrack));
58
59 extrapolateTracks->push_back(std::move(extrapolateTrack));
60 }
61 return extrapolateTracks;
62}
63
64std::unique_ptr<Trk::Track> ExtrapolateMuonToIPTool::extrapolate(const Trk::Track& track, const EventContext& ctx) const {
65 const Trk::TrackInfo& trackInfo = track.info();
68 ATH_MSG_DEBUG("Extrapolating track " << m_printer->print(track) << " type " << particleType << std::endl
69 << m_printer->printStations(track));
70
71 if (!closestPars) {
72 ATH_MSG_WARNING("Failed to find closest parameters ");
74 return nullptr;
75 }
76
77 {
78 // get perigee parameters
79 const Trk::Perigee* perigee = track.perigeeParameters();
80
81 if (!perigee) {
82 ATH_MSG_WARNING("Muon Track without perigee, skipping ");
83 } else {
84 ATH_MSG_DEBUG("Closest parameters " << m_printer->print(*closestPars) << endmsg << " perigee "
85 << m_printer->print(*perigee));
86 }
87 }
88
89 double dirPosProduct = closestPars->position().dot(closestPars->momentum());
90 Trk::PropDirection propDir = dirPosProduct < 0. ? Trk::alongMomentum : Trk::oppositeMomentum;
91
92 if (propDir == Trk::alongMomentum) {
93 ATH_MSG_DEBUG(" scalar product " << dirPosProduct << " extrapolating "
94 << " along momentum");
95 } else {
96 ATH_MSG_DEBUG(" scalar product " << dirPosProduct << " extrapolating "
97 << " opposite momentum");
98 }
99
100 Trk::PerigeeSurface perigeeSurface(Amg::Vector3D(0., 0., 0.));
101 // extrapolate back to IP
102 std::unique_ptr<const Trk::TrackParameters> ipPars{m_extrapolator->extrapolate(ctx, *closestPars, perigeeSurface, propDir, false)};
103 if (!ipPars) {
104 // if extrapolation failed go in other direction
106 ipPars = m_extrapolator->extrapolate(ctx, *closestPars, perigeeSurface, propDir, false, particleType);
107
108 if (propDir == Trk::alongMomentum) {
109 ATH_MSG_DEBUG(" retrying opposite momentum extrapolating "
110 << " along momentum");
111 } else {
112 ATH_MSG_DEBUG(" retrying opposite momentum extrapolating "
113 << " opposite momentum");
114 }
115
116 if (!ipPars) {
117 if (closestPars->momentum().mag() > 5000.)
119 else
121 return nullptr;
122 }
123 }
124
125 // create the new track
126 // create new perigee
127 std::unique_ptr<const Trk::Perigee> ipPerigee_unique;
128 const Trk::Perigee* ipPerigee = dynamic_cast<const Trk::Perigee*>(ipPars.get());
129
130 if (!ipPerigee) {
131 //cppcheck-suppress nullPointerRedundantCheck
132 ipPerigee_unique = createPerigee(*ipPars, ctx);
133 ipPerigee = ipPerigee_unique.get();
134 }
135
136 if (!ipPerigee) {
137 ATH_MSG_WARNING("Failed to create perigee for extrapolate track, skipping ");
139 return nullptr;
140 }
141
142 // create new TSOS DataVector and reserve enough space to fit all old TSOS + one new TSOS
143 const Trk::TrackStates* oldTSOT = track.trackStateOnSurfaces();
144 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
145 unsigned int newSize = oldTSOT->size() + 1;
146 trackStateOnSurfaces->reserve(newSize);
147
148 Amg::Vector3D perDir = ipPerigee->momentum().unit();
149
150 for (const Trk::TrackStateOnSurface* tsit : *oldTSOT) {
151 // remove old perigee if we didn't start from a parameter in the muon system
152 if (tsit->type(Trk::TrackStateOnSurface::Perigee)) continue;
153
154 const Trk::TrackParameters* pars = tsit->trackParameters();
155 if (!pars) continue;
156
157 if (ipPerigee) {
158 double distanceOfPerigeeToCurrent = perDir.dot(pars->position() - ipPerigee->position());
159
160 if (distanceOfPerigeeToCurrent > 0.) {
161 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
162 typePattern.set(Trk::TrackStateOnSurface::Perigee);
163 trackStateOnSurfaces->push_back(
164 new Trk::TrackStateOnSurface(nullptr, ipPerigee->uniqueClone(), nullptr, typePattern));
165 }
166 }
167
168 // copy remainging TSOS
169 trackStateOnSurfaces->push_back(tsit->clone());
170 }
171
172 if (ipPerigee) {
173 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
174 typePattern.set(Trk::TrackStateOnSurface::Perigee);
175 trackStateOnSurfaces->push_back(new Trk::TrackStateOnSurface(nullptr, ipPerigee->uniqueClone(), nullptr, typePattern));
176 }
177 ATH_MSG_DEBUG(" creating new track ");
178
179 Trk::TrackInfo info(track.info().trackFitter(), track.info().particleHypothesis());
180 info.setPatternRecognitionInfo(Trk::TrackInfo::MuidStandAlone);
181 // create new track
182 std::unique_ptr<Trk::Track> extrapolateTrack =
183 std::make_unique<Trk::Track>(info, std::move(trackStateOnSurfaces), track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
184 // create track summary
185 m_trackSummary->updateTrack(ctx, *extrapolateTrack);
186 return extrapolateTrack;
187}
188
190 // create new TSOS DataVector and reserve enough space to fit all old TSOS + one new TSOS
191 const Trk::TrackStates* states = track.trackStateOnSurfaces();
192 if (!states) return nullptr;
193
194 Trk::PerigeeSurface persurf;
195 double rmin{1e9}, rminMeas{1e9};
196 const Trk::TrackParameters* closestPars = nullptr;
197 const Trk::TrackParameters* closestParsMeas = nullptr;
198 for (const Trk::TrackStateOnSurface* tsit : *states) {
199 const Trk::TrackParameters* pars = tsit->trackParameters();
200 if (!pars) continue;
201
202 double rpars = pars->position().perp();
203 if (!closestPars || rpars < rmin) {
204 rmin = rpars;
205 closestPars = pars;
206 }
207
208 if (pars->covariance() && (!closestParsMeas || rpars < rminMeas)) {
209 rminMeas = rpars;
210 closestParsMeas = pars;
211 }
212 }
213
214 if (closestParsMeas) {
215 return closestParsMeas;
216 } else {
217 ATH_MSG_DEBUG(" No measured closest parameters found, using none measured parameters");
218 }
219 return closestPars;
220}
221
222std::unique_ptr<const Trk::Perigee> ExtrapolateMuonToIPTool::createPerigee(const Trk::TrackParameters& pars,
223 const EventContext& ctx) const {
224 std::unique_ptr<const Trk::Perigee> perigee;
225 if (m_muonExtrapolator.empty()) { return perigee; }
226 Trk::PerigeeSurface persurf(pars.position());
227 const Trk::TrackParameters* exPars = m_muonExtrapolator->extrapolateDirectly(ctx, pars, persurf).release();
228 const Trk::Perigee* pp = dynamic_cast<const Trk::Perigee*>(exPars);
229 if (!pp) {
230 ATH_MSG_WARNING(" Extrapolation to Perigee surface did not return a perigee!! ");
231 delete exPars;
232 return perigee;
233 }
234 perigee.reset(pp);
235 return perigee;
236}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
size_type size() const noexcept
Returns the number of elements in the collection.
std::unique_ptr< const Trk::Perigee > createPerigee(const Trk::TrackParameters &pars, const EventContext &ctx) const
const Trk::TrackParameters * findMeasuredParametersClosestToIP(const Trk::Track &track) const
find measured parameters closest to IP to start back extrapolation
std::unique_ptr< TrackCollection > extrapolate(const TrackCollection &muonTracks, const EventContext &ctx) const override
extrapolate all tracks in the track collection to the IP
std::atomic_uint m_failedExtrapolationHighMom
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
muon EDM printer tool
ToolHandle< Trk::ITrackSummaryTool > m_trackSummary
std::atomic_uint m_failedPerigeeCreation
std::atomic_uint m_failedExtrapolationLowMom
ToolHandle< Trk::IExtrapolator > m_extrapolator
Extrapolator.
virtual StatusCode finalize() override
initialize
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
muon EDM helper tool
ExtrapolateMuonToIPTool(const std::string &, const std::string &, const IInterface *)
Constructors.
virtual StatusCode initialize() override
initialize
ToolHandle< Trk::IExtrapolator > m_muonExtrapolator
MuonExtrapolator.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
Class describing the Line to which the Perigee refers to.
Contains information about the 'fitter' of this track.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< TrackParametersDim, Charged > TrackParameters