ATLAS Offline Software
Loading...
Searching...
No Matches
TGC_ResidualPullCalculator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
11
12//================ Initialisation =================================================
13
15{
16 ATH_CHECK(m_idHelperSvc.retrieve());
17 ATH_MSG_DEBUG ("initialize() successful in " << name());
18 return StatusCode::SUCCESS;
19}
20
21//================ calculate residuals for TGC ==================================
22std::array<double,5>
24 const Trk::MeasurementBase* measurement,
25 const Trk::TrackParameters* trkPar,
26 const Trk::ResidualPull::ResidualType /*resType*/,
28 std::array<double,5> residuals{};
29 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(measurement);
30 if (!rot) {
31 const Muon::CompetingMuonClustersOnTrack* muonCompClusters =
32 dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(measurement);
33 if (muonCompClusters) rot = muonCompClusters->containedROTs().empty() ? nullptr : &muonCompClusters->rioOnTrack(0);
34 }
35 if (!trkPar || !rot) {
36 if( !trkPar ) ATH_MSG_WARNING ("No TrackParameters, cannot calculate residual/pull ");
37 if( !rot ) ATH_MSG_WARNING ("No ROT, cannot calculate residual/pull ");
38 return residuals;
39 }
40 Identifier ID = rot->identify();
41
42 if( m_idHelperSvc->isTgc(ID) ) {
43
44 double sinAlpha = 0.0;
45
46 bool isStrip = m_idHelperSvc->tgcIdHelper().isStrip(ID);
47
48 // calculate residual
49 if (isStrip) {
50 // consistency check that Muon EDM is as expected
51 if (measurement->localParameters().parameterKey() !=3) {
52 ATH_MSG_WARNING ( "TGC ClusterOnTrack does not carry the expected "
53 << "LocalParameters structure!");
54 return residuals;
55 }
56 // get orientation angle of strip to rotate back from local frame to strip
57 const Amg::MatrixX &covmat=measurement->localCovariance();
58 double v0=0.5*(covmat(0,0)+covmat(1,1)-sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
59 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
60 double v1=0.5*(covmat(0,0)+covmat(1,1)+sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
61 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
62 sinAlpha=std::sin(0.5*std::asin(2*covmat(0,1)/(v0-v1)));
63
64 double cosAlpha = std::sqrt(1 - sinAlpha*sinAlpha);
65
66 // Calculate Residual for hit: res = (vec(x_hit) - vec(x_track)) * vec(n_perpendicular)
68 (measurement->localParameters()[Trk::locX] - trkPar->parameters()[Trk::locX]) * cosAlpha
69 + (measurement->localParameters()[Trk::locY] - trkPar->parameters()[Trk::locY]) * sinAlpha;
70
71 } else {
72 if (measurement->localParameters().parameterKey() != 1) {
73 ATH_MSG_WARNING ("TGC ClusterOnTrack does not carry the expected "
74 << "LocalParameters structure!" );
75 return residuals;
76 } else {
77 // convention to be interpreted by TrkValTools: 2nd coordinate codes orientation of TGC
79 - trkPar->parameters()[Trk::loc1];
80 }
81 }
82 } else {
83 ATH_MSG_DEBUG ( "Input problem measurement is not TGC." );
84 return residuals;
85 }
86 return residuals;
87}
88
89//================ calculate residuals and pulls for TGC ==================================
90std::optional<Trk::ResidualPull> Muon::TGC_ResidualPullCalculator::residualPull(
91 const Trk::MeasurementBase* measurement,
92 const Trk::TrackParameters* trkPar,
95
96 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(measurement);
97 if (!rot) {
98 const Muon::CompetingMuonClustersOnTrack* muonCompClusters =
99 dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(measurement);
100 if (muonCompClusters) rot = muonCompClusters->containedROTs().empty() ? nullptr :
101 muonCompClusters->containedROTs().front().get();
102 }
103 if (!trkPar || !rot) {
104 if( !trkPar ) ATH_MSG_WARNING ("No TrackParameters, cannot calculate residual/pull ");
105 if( !rot ) ATH_MSG_WARNING ("No ROT, cannot calculate residual/pull ");
106 return std::nullopt;
107 }
108 Identifier ID = rot->identify();
109
110 if( m_idHelperSvc->isTgc(ID) ) {
111
112 // try to cast the track parameters to measured ones
113 const AmgSymMatrix(5)* trkCov = trkPar->covariance();
114 bool pullIsValid = (trkCov);
115
116 double sinAlpha = 0.0;
117
118 bool isStrip = m_idHelperSvc->tgcIdHelper().isStrip(ID);
119
120 // calculate residual
121 std::vector<double> residual(1);
122 std::vector<double> pull(1);
123 if (isStrip) {
124 // consistency check that Muon EDM is as expected
125 if (measurement->localParameters().parameterKey() !=3) {
126 ATH_MSG_WARNING ( "TGC ClusterOnTrack does not carry the expected "
127 << "LocalParameters structure!");
128 return std::nullopt;
129 }
130 // get orientation angle of strip to rotate back from local frame to strip
131 const Amg::MatrixX &covmat=measurement->localCovariance();
132 double v0=0.5*(covmat(0,0)+covmat(1,1)-sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
133 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
134 double v1=0.5*(covmat(0,0)+covmat(1,1)+sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
135 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
136 sinAlpha=std::sin(0.5*std::asin(2*covmat(0,1)/(v0-v1)));
137
138 const MuonGM::TgcReadoutElement *ele =
139 dynamic_cast<const MuonGM::TgcReadoutElement*>(rot->detectorElement());
140 if (!ele) {
141 ATH_MSG_WARNING ("Could not obtain TGC detEl from TGC ROT, this is a bug!" );
142 return std::nullopt;
143 }
144
145 double cosAlpha = std::sqrt(1 - sinAlpha*sinAlpha);
146
147 // Calculate Residual for hit: res = (vec(x_hit) - vec(x_track)) * vec(n_perpendicular)
148 residual[Trk::loc1] =
149 (measurement->localParameters()[Trk::locX] - trkPar->parameters()[Trk::locX]) * cosAlpha
150 + (measurement->localParameters()[Trk::locY] - trkPar->parameters()[Trk::locY]) * sinAlpha;
151
152 // Fill transformation matrix to transform covariance matrices
153 Amg::MatrixX RotMat(2,2);
154 RotMat(0,0) = cosAlpha;
155 RotMat(0,1) = sinAlpha;
156 RotMat(1,0) = -sinAlpha;
157 RotMat(1,1) = cosAlpha;
158 // get the covariance matrix of the ROT and rotate it by stereo angle
159 Amg::MatrixX transformedROTCov = measurement->localCovariance().similarity(RotMat);
160
161 if (pullIsValid) {
162 // Get local error matrix for track to calc pull
163 // Just use first local coordinates
164 // and rotate by the stereo angle
165 Amg::MatrixX subm = trkCov->block<2,2>(0,0);
166 Amg::MatrixX transformedTrkCov = subm.similarity(RotMat);
167 // calc pull now
168 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
169 transformedROTCov(0,0),
170 transformedTrkCov(0,0),
171 resType);
172 } else {
173 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
174 transformedROTCov(0,0),
175 0.,
176 resType);
177 }
178
179 } else {
180 if (measurement->localParameters().parameterKey() != 1) {
181 ATH_MSG_WARNING ("TGC ClusterOnTrack does not carry the expected "
182 << "LocalParameters structure!" );
183 return std::nullopt;
184 } else {
185 // convention to be interpreted by TrkValTools: 2nd coordinate codes orientation of TGC
186 residual[Trk::loc1] = measurement->localParameters()[Trk::loc1]
187 - trkPar->parameters()[Trk::loc1];
188 // calculate pull
189 if (pullIsValid)
190 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
191 measurement->localCovariance()(Trk::loc1,Trk::loc1),
192 (*trkCov)(Trk::loc1,Trk::loc1),
193 resType);
194 else
195 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
196 measurement->localCovariance()(Trk::loc1,Trk::loc1),
197 0,
198 resType);
199 }
200 }
201 // create the Trk::ResidualPull.
202 ATH_MSG_VERBOSE ( "Calculating Pull for channel " << m_idHelperSvc->toString(ID) << " residual " << residual[Trk::loc1] << " pull " << pull[Trk::loc1] );
203
204 return std::make_optional<Trk::ResidualPull>(std::move(residual), std::move(pull), pullIsValid, resType, 1, sinAlpha);
205
206 } else {
207 ATH_MSG_DEBUG ( "Input problem measurement is not TGC." );
208 return std::nullopt;
209 }
210}
211
216 const double residual,
217 const double locMesCov,
218 const double locTrkCov,
219 const Trk::ResidualPull::ResidualType& resType ) const {
220 if( locMesCov < 0 ) {
221 ATH_MSG_DEBUG("Bad error " << locMesCov << " " << locTrkCov << " using measured error ");
222 return 0;
223 }
224 double ErrorSum;
225 if (resType == Trk::ResidualPull::Unbiased) {
226 if( locMesCov + locTrkCov > 0 ) ErrorSum = std::sqrt(locMesCov + locTrkCov);
227 else{
228 ATH_MSG_DEBUG("Bad error measurement " << locMesCov << " from track " << locTrkCov << ", using measured error ");
229 ErrorSum = std::sqrt(locMesCov);
230 }
231 } else if (resType == Trk::ResidualPull::Biased) {
232 if ((locMesCov - locTrkCov) < 0.) {
233 return 0;
234 }
235 ErrorSum = std::sqrt(locMesCov - locTrkCov);
236 } else ErrorSum = std::sqrt(locMesCov);
237 if (ErrorSum != 0) return residual/ErrorSum;
238 return 0;
239}
#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)
#define AmgSymMatrix(dim)
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< std::unique_ptr< const MuonClusterOnTrack > > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
const MuonClusterOnTrack & rioOnTrack(unsigned int) const
returns the RIO_OnTrack (also known as ROT) objects depending on the integer
virtual std::array< double, 5 > residuals(const Trk::MeasurementBase *measurement, const Trk::TrackParameters *trkPar, const Trk::ResidualPull::ResidualType, const Trk::TrackState::MeasurementType) const override
This function is a light-weight version of the function above, designed for track fitters where speed...
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
virtual std::optional< Trk::ResidualPull > residualPull(const Trk::MeasurementBase *measurement, const Trk::TrackParameters *trkPar, const Trk::ResidualPull::ResidualType, const Trk::TrackState::MeasurementType) const override
This function returns (creates!) a Trk::ResidualPull object, which contains the values of residual an...
double calcPull(const double residual, const double locMesCov, const double locTrkCov, const Trk::ResidualPull::ResidualType &) const
internal structuring: common code for calculating hit pulls
int parameterKey() const
Identifier key for matrix expansion/reduction.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const TrkDetElementBase * detectorElement() const =0
returns the detector element, assoicated with the PRD of this class
Identifier identify() const
return the identifier -extends MeasurementBase
@ Biased
RP with track state including the hit.
@ Unbiased
RP with track state that has measurement not included.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
MeasurementType
enum describing the flavour of MeasurementBase
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ loc1
Definition ParamDefs.h:34
ParametersBase< TrackParametersDim, Charged > TrackParameters