ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSegmentFittingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
15#include "TrkTrack/Track.h"
16
17namespace {
18 inline double calcChi2 (const Trk::Track& trk) {
19 const Trk::FitQuality* fq = trk.fitQuality();
20 if (!fq || !fq->numberDoF()) { return FLT_MAX;}
21 return fq->chiSquared() / fq->numberDoF();
22 }
23}
24namespace Muon {
25
26 MuonSegmentFittingTool::MuonSegmentFittingTool(const std::string& t, const std::string& n, const IInterface* p) :
27 AthAlgTool(t, n, p), m_magFieldProperties(Trk::NoField) {
28 declareInterface<IMuonSegmentFittingTool>(this);
29 declareProperty("UpdatePrecisionCoordinate", m_updatePrecisionCoordinate = false);
30 }
31
33 ATH_CHECK(m_slPropagator.retrieve());
34 ATH_CHECK(m_slTrackFitter.retrieve());
36 ATH_CHECK(m_trackCleaner.retrieve());
37 return StatusCode::SUCCESS;
38 }
39
41 return fit(segment.globalPosition(), segment.globalDirection(), segment.associatedSurface(), segment.containedMeasurements());
42 }
43
45 const std::vector<const Trk::MeasurementBase*>& rioVec) const {
46 ATH_MSG_VERBOSE(" trying to fit segment ");
47 const EventContext& ctx = Gaudi::Hive::currentContext();
48 Amg::Vector3D gdir = gDir;
49
50 double gdirNorm = gdir.mag();
51 bool isCurvedSegment = (gdirNorm > 1.5);
52 if (isCurvedSegment) {
53 // re-normalize the gdir
54 gdir = Amg::Vector3D(gdir.x() / gdirNorm, gdir.y() / gdirNorm, gdir.z() / gdirNorm);
55 }
56
57 double charge = 0;
58 Trk::AtaPlane segPars(gpos, gdir, charge, surf);
59
60 // extrapolate segment parameters to first measurements
61 const Trk::MeasurementBase* firstMeas = rioVec.front();
62 std::unique_ptr<Trk::TrackParameters> exPars =
63 m_slPropagator->propagate(ctx, segPars, firstMeas->associatedSurface(), Trk::anyDirection, false, m_magFieldProperties);
64 if (!exPars) {
65 ATH_MSG_DEBUG(" Propagation failed!! ");
66 return nullptr;
67 }
68
69 // small shift towards the ip
70 double sign = exPars->position().dot(exPars->momentum()) > 0 ? 1. : -1.;
71 Amg::Vector3D perpos = exPars->position() - sign * exPars->momentum().unit();
72
73 // create start parameter
74 double phi = gdir.phi();
75 double theta = gdir.theta();
76 double qoverp = 0;
77 Trk::PerigeeSurface persurf(perpos);
78 Trk::Perigee startpar(0, 0, phi, theta, qoverp, persurf);
79
80 // copy measurements into new vector
81 std::vector<const Trk::MeasurementBase*> vec2;
82 vec2.reserve(rioVec.size());
83 std::copy(rioVec.begin(), rioVec.end(), std::back_inserter(vec2));
84
85 // fit
86 std::unique_ptr<Trk::Track> newtrack;
87 // use the full fitter if the segment is curved
88 if (isCurvedSegment) {
89 newtrack = m_curvedTrackFitter->fit(ctx, vec2, startpar, false, Trk::ParticleSwitcher::particle[0]);
90 }
91 // else use the straight line fitter
92 else {
93 newtrack = m_slTrackFitter->fit(ctx, vec2, startpar, false, Trk::nonInteracting);
94 }
95
96 if (!newtrack) {
97 ATH_MSG_VERBOSE(" fit failed ");
98 return nullptr;
99 }
100 constexpr double chi2Cut = 10.;
101 std::unique_ptr<Trk::Track> cleanTrack = m_trackCleaner->clean(*newtrack, ctx);
102 if (!cleanTrack && !isCurvedSegment && calcChi2(*newtrack) > chi2Cut) {
103 ATH_MSG_VERBOSE(" lost in cleaner ");
104 return nullptr;
105 }
106
107 if (cleanTrack && !(*cleanTrack->perigeeParameters() == *newtrack->perigeeParameters()) && !isCurvedSegment) {
108 // using release until the entire code can be migrated to use smart pointers
109 newtrack.swap(cleanTrack);
110 }
111
112 // reject fit if larger than cut
113 if (calcChi2(*newtrack) > chi2Cut) {
114 ATH_MSG_VERBOSE(" reduced chi2 to large " << calcChi2(*newtrack) << " cut " << chi2Cut);
115 return nullptr;
116 }
117
118 if (msgLvl(MSG::DEBUG)) {
119 const Trk::Perigee* pp = newtrack->perigeeParameters();
120 if (pp) {
121 ATH_MSG_DEBUG(" pos " << std::setprecision(5) << pp->position() << " phi " << pp->momentum().phi() << " theta "
122 << pp->momentum().theta() << " q*mom " << pp->momentum().mag() * pp->charge() << " pt "
123 << pp->momentum().perp());
124 } else {
125 ATH_MSG_DEBUG(" no perigee ");
126 }
127 }
128 return newtrack.release();
129 }
130
132 Trk::LocalDirection& segLocDir, Amg::MatrixX& locerr) const {
133 ATH_MSG_DEBUG(" old segment parameters: pos (" << segLocPos[Trk::locX] << "," << segLocPos[Trk::locY] << ") dir ("
134 << segLocDir.angleXZ() << "," << segLocDir.angleYZ() << ") ");
135
136 const EventContext& ctx = Gaudi::Hive::currentContext();
137 const Trk::Perigee* pp = track.perigeeParameters();
138 if (!pp) {
139 ATH_MSG_WARNING(" track without perigee ");
140 return;
141 }
142
143 std::unique_ptr<Trk::TrackParameters> exPars =
144 m_slPropagator->propagate(ctx, *pp, surf, Trk::anyDirection, false, m_magFieldProperties);
145 if (!exPars) {
146 ATH_MSG_WARNING(" extrapolation failed, this should not happen ");
147 return;
148 }
149
150 Amg::Vector2D lpos{0., 0.};
151 surf.globalToLocal(exPars->position(), exPars->position(), lpos);
153 surf.globalToLocalDirection(exPars->momentum().unit(), ldir);
154 ATH_MSG_DEBUG(" new segment parameters: pos (" << lpos[Trk::locX] << "," << lpos[Trk::locY] << ") dir (" << ldir.angleXZ() << ","
155 << ldir.angleYZ() << ") ");
156
157 segLocPos[Trk::locX] = lpos[Trk::locX];
158 if (m_updatePrecisionCoordinate) segLocPos[Trk::locY] = lpos[Trk::locY];
159 segLocDir = Trk::LocalDirection(ldir.angleXZ(), m_updatePrecisionCoordinate ? ldir.angleYZ() : segLocDir.angleYZ());
160
161 if (exPars->covariance()) locerr = *exPars->covariance();
162 }
163
164} // namespace Muon
Scalar phi() const
phi method
Scalar theta() const
theta method
#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)
double charge(const T &p)
Definition AtlasPID.h:997
int sign(int a)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
ToolHandle< Muon::IMuonTrackCleaner > m_trackCleaner
void updateSegmentParameters(const Trk::Track &track, const Trk::PlaneSurface &surf, Amg::Vector2D &segLocPos, Trk::LocalDirection &segLocDir, Amg::MatrixX &locerr) const
update the parameters of the segment using the track information
MuonSegmentFittingTool(const std::string &, const std::string &, const IInterface *)
ToolHandle< Trk::IPropagator > m_slPropagator
Trk::MagneticFieldProperties m_magFieldProperties
Trk::Track * fit(const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, const Trk::PlaneSurface &surf, const std::vector< const Trk::MeasurementBase * > &rioVec) const
fit segment parameters + hits producing a track
ToolHandle< Trk::ITrackFitter > m_curvedTrackFitter
ToolHandle< Trk::ITrackFitter > m_slTrackFitter
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
virtual const Trk::PlaneSurface & associatedSurface() const override final
returns the surface for the local to global transformation
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
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.
const Amg::Vector3D & position() const
Access method for the position.
double charge() const
Returns the charge.
Class describing the Line to which the Perigee refers to.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Ensure that the ATLAS eigen extensions are properly loaded.
@ anyDirection
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane