ATLAS Offline Software
Loading...
Searching...
No Matches
MuidMuonRecovery.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MuidMuonRecovery
7// AlgTool performing MS hit reallocation for a likely spectrometer-indet
8// match which has given combined fit problems.
9// Extrapolates indet track to MS.
10// Returns a combined track with full track fit.
11//
13
14#include "MuidMuonRecovery.h"
15
16#include <cmath>
17#include <iomanip>
18#include <vector>
19
20#include "GaudiKernel/ServiceHandle.h"
21#include "GaudiKernel/SystemOfUnits.h"
31#include "TrkTrack/Track.h"
33
34namespace Rec {
35
36 MuidMuonRecovery::MuidMuonRecovery(const std::string& type, const std::string& name, const IInterface* parent) :
37 AthAlgTool(type, name, parent){
38 declareInterface<IMuidMuonRecovery>(this);
39 }
40
41 //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS >>>>>>
42
44 ATH_MSG_INFO("Initializing MuidMuonRecovery");
45
46 // get the Tools
47 ATH_CHECK(m_extrapolator.retrieve());
48 ATH_MSG_INFO("Retrieved tool " << m_extrapolator);
49 ATH_CHECK(m_edmHelperSvc.retrieve());
50 ATH_MSG_INFO("Retrieved tool " << m_edmHelperSvc);
51 ATH_CHECK(m_idHelperSvc.retrieve());
52 ATH_MSG_INFO("Retrieved tool " << m_idHelperSvc);
53 ATH_CHECK(m_printer.retrieve());
54 ATH_MSG_INFO("Retrieved tool " << m_printer);
56 ATH_MSG_INFO("Retrieved tool " << m_residualCalculator);
57
58 if (!m_trackBuilder.empty()) {
59 ATH_CHECK(m_trackBuilder.retrieve());
60 ATH_MSG_INFO("Retrieved tool " << m_trackBuilder);
61 }
62
63 return StatusCode::SUCCESS;
64 }
65
67 ATH_MSG_INFO("Recovery attempts " << m_recoveryAttempts << ", failedFit " << m_recoveryFitFailure << ", success "
69
70 return StatusCode::SUCCESS;
71 }
72 std::unique_ptr<Trk::Track> MuidMuonRecovery::recoverableMatch(const Trk::Track& indetTrack, const Trk::Track& spectrometerTrack,
73 const EventContext& ctx) const {
74 // skip low pt ID tracks
75 if (!indetTrack.perigeeParameters() || indetTrack.perigeeParameters()->momentum().mag() < m_minP ||
76 indetTrack.perigeeParameters()->momentum().perp() < m_minPt) {
77 return nullptr;
78 }
79
81
82 ATH_MSG_DEBUG("Entering new recovery" << std::endl
83 << " ID track " << m_printer->print(indetTrack) << std::endl
84 << " MS track " << m_printer->print(spectrometerTrack) << std::endl
85 << m_printer->printStations(spectrometerTrack));
86
87 const Trk::TrackParameters* lastIndetPars = nullptr;
88 int index = static_cast<int>(indetTrack.trackParameters()->size());
89
90 while (!lastIndetPars && index > 0) {
91 --index;
92 lastIndetPars = (*indetTrack.trackParameters())[index] ? (*indetTrack.trackParameters())[index] : nullptr;
93 }
94
95 if (!lastIndetPars) {
96 ATH_MSG_WARNING("ID track parameters don't have error matrix!");
97 return nullptr;
98 }
99
100 // track builder prefers estimate of inner, middle and outer spectrometer track parameters
101 std::unique_ptr<Trk::TrackParameters> innerParameters, middleParameters, outerParameters;
102 std::unique_ptr<Trk::TrackParameters> lastPars = lastIndetPars->uniqueClone();
103 bool innerParsSet{false};
104
105 std::vector<const Trk::TrackStateOnSurface*> stations;
106 std::set<Muon::MuonStationIndex::StIndex> etaIndices, phiIndices, badEtaIndices, badPhiIndices;
107
108 unsigned int nmeas = 0;
109
110 for (const Trk::TrackStateOnSurface* tsosit : *spectrometerTrack.trackStateOnSurfaces()) {
111 const Trk::MeasurementBase* meas = tsosit->measurementOnTrack();
112 if (!meas) continue;
113
114 if (tsosit->type(Trk::TrackStateOnSurface::Outlier)) continue;
115
116 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
117 if (!id.is_valid()) continue;
118
120 bool measuresPhi = m_idHelperSvc->measuresPhi(id);
121 ++nmeas;
122
123 if (measuresPhi) {
124 if (phiIndices.count(index)) continue;
125 ATH_MSG_DEBUG("Adding phi station " << m_idHelperSvc->toString(id));
126 phiIndices.insert(index);
127 } else if (m_idHelperSvc->isMdt(id) || (m_idHelperSvc->isCsc(id))) {
128 if (etaIndices.count(index)) continue;
129
130 ATH_MSG_DEBUG("Adding eta station " << m_idHelperSvc->toString(id));
131 etaIndices.insert(index);
132 } else {
133 continue;
134 }
135
136 std::unique_ptr<Trk::TrackParameters> exPars{};
137 if (lastPars->associatedSurface() == meas->associatedSurface()) {
138 ATH_MSG_DEBUG("Using existing pars");
139 exPars = std::move(lastPars);
140 } else {
141 exPars = m_extrapolator->extrapolate(ctx, *lastPars, meas->associatedSurface(), Trk::alongMomentum, false, Trk::muon);
142 }
143
144 if (!exPars) {
145 ATH_MSG_DEBUG("Failed to extrapolate to station" << m_idHelperSvc->toStringChamber(id));
146 continue;
147 }
148
149 std::optional<Trk::ResidualPull> res {m_residualCalculator->residualPull(meas, exPars.get(), Trk::ResidualPull::Unbiased)};
150
151 ATH_MSG_DEBUG(" " << m_idHelperSvc->toStringChamber(id) << " residual " << m_printer->print(*res));
152
153 if (std::abs(res->pull().front()) > m_pullCut) {
154 if (measuresPhi) {
155 badPhiIndices.insert(index);
156 } else {
157 badEtaIndices.insert(index);
158 }
159 }
160
161
162 if (msgLvl(MSG::DEBUG)) {
163 if (!m_idHelperSvc->measuresPhi(id)) {
164 const MuonGM::MuonReadoutElement* detEl = nullptr;
165 if (m_idHelperSvc->isMdt(id)) {
166 const Muon::MdtDriftCircleOnTrack* mdt = dynamic_cast<const Muon::MdtDriftCircleOnTrack*>(meas);
167 if (mdt) { detEl = mdt->detectorElement(); }
168 } else if (m_idHelperSvc->isCsc(id)) {
169 const Muon::CscClusterOnTrack* csc = dynamic_cast<const Muon::CscClusterOnTrack*>(meas);
170 if (csc) { detEl = csc->detectorElement(); }
171 }
172
173 if (detEl) {
174 const Trk::PlaneSurface* detSurf = dynamic_cast<const Trk::PlaneSurface*>(&detEl->surface());
175 if (detSurf) {
176 Trk::LocalDirection idDir{};
177 detSurf->globalToLocalDirection(exPars->momentum(), idDir);
178
179 const Trk::TrackParameters* pars = tsosit->trackParameters();
180 Trk::LocalDirection msDir{};
181 detSurf->globalToLocalDirection(pars->momentum(), msDir);
182 ATH_MSG_DEBUG(" local Angles: id (" << idDir.angleXZ() << "," << idDir.angleYZ() << ") ms ("
183 << msDir.angleXZ() << "," << msDir.angleYZ() << ")");
184 }
185 }
186 }
187 } // end DEBUG toggle
188
189 if (!innerParsSet && !innerParameters && exPars && lastPars) {
190 innerParameters = std::move(exPars);
191 } else if (exPars && innerParameters && !middleParameters ) {
192 middleParameters = std::move(exPars);
193 } else {
194 lastPars = std::move(exPars);
195 }
196 innerParsSet = true;
197 }
198
199 if (middleParameters) {
200 outerParameters = std::move(lastPars);
201 } else {
202 middleParameters = std::move(innerParameters);
203 if (!middleParameters) {
204 ATH_MSG_DEBUG("parameter extrapolation failed");
205 return nullptr;
206 }
207 }
208
209 bool cleanEta = badEtaIndices.size() == 1 && etaIndices.size() > 1;
210 bool cleanPhi = badPhiIndices.size() == 1;
211
212 if (!cleanPhi && !cleanEta) {
213 ATH_MSG_DEBUG("No layers removed");
214 return nullptr;
215 }
216
217 if (badEtaIndices.size() == etaIndices.size()) {
218 ATH_MSG_DEBUG("All layers removed");
219 return nullptr;
220 }
221
222 Trk::MeasurementSet spectrometerMeasurements;
223 for (const Trk::TrackStateOnSurface* tsosit : *spectrometerTrack.trackStateOnSurfaces()) {
224 const Trk::MeasurementBase* meas = tsosit->measurementOnTrack();
225 if (!meas) continue;
226 if (tsosit->type(Trk::TrackStateOnSurface::Outlier)) continue;
227
228 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
229 if (!id.is_valid()) continue;
230
232 bool measuresPhi = m_idHelperSvc->measuresPhi(id);
233 if (cleanEta && !measuresPhi && badEtaIndices.count(index)) continue;
234 if (cleanPhi && measuresPhi && badPhiIndices.count(index)) continue;
235 spectrometerMeasurements.push_back(meas);
236 }
237
238 ATH_MSG_DEBUG("Number of measurements before cleaning " << nmeas << " after cleaning " << spectrometerMeasurements.size());
239
240 if (spectrometerMeasurements.size() < 6) {
241 ATH_MSG_DEBUG("Too few hits left - discarding fit");
242 return nullptr;
243 }
244
245 // fit the combined track
246 std::unique_ptr<Trk::Track> combinedTrack;
247 if (!m_trackBuilder.empty()) {
248 combinedTrack = m_trackBuilder->indetExtension(ctx, indetTrack, spectrometerMeasurements, std::move(innerParameters), std::move(middleParameters),
249 std::move(outerParameters));
250 }
251 if (combinedTrack) {
253 combinedTrack->info().setPatternRecognitionInfo(Trk::TrackInfo::MuidMuonRecoveryTool);
254
255 ATH_MSG_DEBUG("Recovered track " << std::endl
256 << m_printer->print(*combinedTrack) << std::endl
257 << m_printer->printStations(*combinedTrack));
258 } else {
260 ATH_MSG_DEBUG("track fit failure ");
261 }
262 return combinedTrack;
263 }
264
265} // namespace Rec
#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)
std::pair< std::vector< unsigned int >, bool > res
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
Base class for the XxxReadoutElement, with Xxx = Mdt, Rpc, Tgc, Csc.
Class to represent the calibrated clusters created from CSC strips.
virtual const MuonGM::CscReadoutElement * detectorElement() const override final
Returns the detector element, associated with the PRD of this class.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
virtual const MuonGM::MdtReadoutElement * detectorElement() const override final
Returns the detector element, assoicated with the PRD of this class.
StatusCode initialize() override
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
MuidMuonRecovery(const std::string &type, const std::string &name, const IInterface *parent)
ToolHandle< ICombinedMuonTrackBuilder > m_trackBuilder
StatusCode finalize() override
std::unique_ptr< Trk::Track > recoverableMatch(const Trk::Track &indetTrack, const Trk::Track &spectrometerTrack, const EventContext &ctx) const override
IMuidMuonRecovery interface: algorithmic code for recovering muon spectrometer using the inner detect...
std::atomic< unsigned int > m_recoveryAttempts
ToolHandle< Trk::IExtrapolator > m_extrapolator
Gaudi::Property< double > m_minP
ToolHandle< Trk::IResidualPullCalculator > m_residualCalculator
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
Gaudi::Property< double > m_minPt
std::atomic< unsigned int > m_recoveryFitFailure
std::atomic< unsigned int > m_recoverySuccess
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< double > m_pullCut
represents the three-dimensional global direction with respect to a planar surface frame.
double angleXZ() const
access method for angle of local XZ projection
double angleYZ() const
access method for angle of local YZ projection
This class is the pure abstract base class for all fittable tracking measurements.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
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 for a planaer rectangular or trapezoidal surface in the ATLAS detector.
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
@ Unbiased
RP with track state that has measurement not included.
@ MuidMuonRecoveryTool
Muons found by the ID seeded muon recovery.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
const Perigee * perigeeParameters() const
return Perigee.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
StIndex
enum to classify the different station layers in the muon spectrometer
Gaudi Tools.
@ alongMomentum
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition FitterTypes.h:30
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1