ATLAS Offline Software
Loading...
Searching...
No Matches
TGC_ResidualPullCalculator.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
11
12//================ Constructor =================================================
13
14Muon::TGC_ResidualPullCalculator::TGC_ResidualPullCalculator(const std::string& t, const std::string& n, const IInterface* p) :
15 AthAlgTool(t,n,p) {
16 declareInterface<IResidualPullCalculator>(this);
17}
18
19//================ Initialisation =================================================
20
22{
23 ATH_CHECK(m_idHelperSvc.retrieve());
24 ATH_MSG_DEBUG ("initialize() successful in " << name());
25 return StatusCode::SUCCESS;
26}
27
28//================ calculate residuals for TGC ==================================
29std::array<double,5>
31 const Trk::MeasurementBase* measurement,
32 const Trk::TrackParameters* trkPar,
33 const Trk::ResidualPull::ResidualType /*resType*/,
35 std::array<double,5> residuals{};
36 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(measurement);
37 if (!rot) {
38 const Muon::CompetingMuonClustersOnTrack* muonCompClusters =
39 dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(measurement);
40 if (muonCompClusters) rot = muonCompClusters->containedROTs().empty() ? nullptr :
41 muonCompClusters->containedROTs().front();
42 }
43 if (!trkPar || !rot) {
44 if( !trkPar ) ATH_MSG_WARNING ("No TrackParameters, cannot calculate residual/pull ");
45 if( !rot ) ATH_MSG_WARNING ("No ROT, cannot calculate residual/pull ");
46 return residuals;
47 }
48 Identifier ID = rot->identify();
49
50 if( m_idHelperSvc->isTgc(ID) ) {
51
52 double sinAlpha = 0.0;
53
54 bool isStrip = m_idHelperSvc->tgcIdHelper().isStrip(ID);
55
56 // calculate residual
57 if (isStrip) {
58 // consistency check that Muon EDM is as expected
59 if (measurement->localParameters().parameterKey() !=3) {
60 ATH_MSG_WARNING ( "TGC ClusterOnTrack does not carry the expected "
61 << "LocalParameters structure!");
62 return residuals;
63 }
64 // get orientation angle of strip to rotate back from local frame to strip
65 const Amg::MatrixX &covmat=measurement->localCovariance();
66 double v0=0.5*(covmat(0,0)+covmat(1,1)-sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
67 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
68 double v1=0.5*(covmat(0,0)+covmat(1,1)+sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
69 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
70 sinAlpha=std::sin(0.5*std::asin(2*covmat(0,1)/(v0-v1)));
71
72 double cosAlpha = std::sqrt(1 - sinAlpha*sinAlpha);
73
74 // Calculate Residual for hit: res = (vec(x_hit) - vec(x_track)) * vec(n_perpendicular)
76 (measurement->localParameters()[Trk::locX] - trkPar->parameters()[Trk::locX]) * cosAlpha
77 + (measurement->localParameters()[Trk::locY] - trkPar->parameters()[Trk::locY]) * sinAlpha;
78
79 } else {
80 if (measurement->localParameters().parameterKey() != 1) {
81 ATH_MSG_WARNING ("TGC ClusterOnTrack does not carry the expected "
82 << "LocalParameters structure!" );
83 return residuals;
84 } else {
85 // convention to be interpreted by TrkValTools: 2nd coordinate codes orientation of TGC
87 - trkPar->parameters()[Trk::loc1];
88 }
89 }
90 } else {
91 ATH_MSG_DEBUG ( "Input problem measurement is not TGC." );
92 return residuals;
93 }
94 return residuals;
95}
96
97//================ calculate residuals and pulls for TGC ==================================
98std::optional<Trk::ResidualPull> Muon::TGC_ResidualPullCalculator::residualPull(
99 const Trk::MeasurementBase* measurement,
100 const Trk::TrackParameters* trkPar,
103
104 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(measurement);
105 if (!rot) {
106 const Muon::CompetingMuonClustersOnTrack* muonCompClusters =
107 dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(measurement);
108 if (muonCompClusters) rot = muonCompClusters->containedROTs().empty() ? nullptr :
109 muonCompClusters->containedROTs().front();
110 }
111 if (!trkPar || !rot) {
112 if( !trkPar ) ATH_MSG_WARNING ("No TrackParameters, cannot calculate residual/pull ");
113 if( !rot ) ATH_MSG_WARNING ("No ROT, cannot calculate residual/pull ");
114 return std::nullopt;
115 }
116 Identifier ID = rot->identify();
117
118 if( m_idHelperSvc->isTgc(ID) ) {
119
120 // try to cast the track parameters to measured ones
121 const AmgSymMatrix(5)* trkCov = trkPar->covariance();
122 bool pullIsValid = (trkCov);
123
124 double sinAlpha = 0.0;
125
126 bool isStrip = m_idHelperSvc->tgcIdHelper().isStrip(ID);
127
128 // calculate residual
129 std::vector<double> residual(1);
130 std::vector<double> pull(1);
131 if (isStrip) {
132 // consistency check that Muon EDM is as expected
133 if (measurement->localParameters().parameterKey() !=3) {
134 ATH_MSG_WARNING ( "TGC ClusterOnTrack does not carry the expected "
135 << "LocalParameters structure!");
136 return std::nullopt;
137 }
138 // get orientation angle of strip to rotate back from local frame to strip
139 const Amg::MatrixX &covmat=measurement->localCovariance();
140 double v0=0.5*(covmat(0,0)+covmat(1,1)-sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
141 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
142 double v1=0.5*(covmat(0,0)+covmat(1,1)+sqrt((covmat(0,0)+covmat(1,1))*(covmat(0,0)+covmat(1,1))-
143 4*(covmat(0,0)*covmat(1,1)-covmat(0,1)*covmat(0,1))));
144 sinAlpha=std::sin(0.5*std::asin(2*covmat(0,1)/(v0-v1)));
145
146 const MuonGM::TgcReadoutElement *ele =
147 dynamic_cast<const MuonGM::TgcReadoutElement*>(rot->detectorElement());
148 if (!ele) {
149 ATH_MSG_WARNING ("Could not obtain TGC detEl from TGC ROT, this is a bug!" );
150 return std::nullopt;
151 }
152
153 double cosAlpha = std::sqrt(1 - sinAlpha*sinAlpha);
154
155 // Calculate Residual for hit: res = (vec(x_hit) - vec(x_track)) * vec(n_perpendicular)
156 residual[Trk::loc1] =
157 (measurement->localParameters()[Trk::locX] - trkPar->parameters()[Trk::locX]) * cosAlpha
158 + (measurement->localParameters()[Trk::locY] - trkPar->parameters()[Trk::locY]) * sinAlpha;
159
160 // Fill transformation matrix to transform covariance matrices
161 Amg::MatrixX RotMat(2,2);
162 RotMat(0,0) = cosAlpha;
163 RotMat(0,1) = sinAlpha;
164 RotMat(1,0) = -sinAlpha;
165 RotMat(1,1) = cosAlpha;
166 // get the covariance matrix of the ROT and rotate it by stereo angle
167 Amg::MatrixX transformedROTCov = measurement->localCovariance().similarity(RotMat);
168
169 if (pullIsValid) {
170 // Get local error matrix for track to calc pull
171 // Just use first local coordinates
172 // and rotate by the stereo angle
173 Amg::MatrixX subm = trkCov->block<2,2>(0,0);
174 Amg::MatrixX transformedTrkCov = subm.similarity(RotMat);
175 // calc pull now
176 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
177 transformedROTCov(0,0),
178 transformedTrkCov(0,0),
179 resType);
180 } else {
181 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
182 transformedROTCov(0,0),
183 0.,
184 resType);
185 }
186
187 } else {
188 if (measurement->localParameters().parameterKey() != 1) {
189 ATH_MSG_WARNING ("TGC ClusterOnTrack does not carry the expected "
190 << "LocalParameters structure!" );
191 return std::nullopt;
192 } else {
193 // convention to be interpreted by TrkValTools: 2nd coordinate codes orientation of TGC
194 residual[Trk::loc1] = measurement->localParameters()[Trk::loc1]
195 - trkPar->parameters()[Trk::loc1];
196 // calculate pull
197 if (pullIsValid)
198 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
199 measurement->localCovariance()(Trk::loc1,Trk::loc1),
200 (*trkCov)(Trk::loc1,Trk::loc1),
201 resType);
202 else
203 pull[Trk::loc1] = calcPull(residual[Trk::loc1],
204 measurement->localCovariance()(Trk::loc1,Trk::loc1),
205 0,
206 resType);
207 }
208 }
209 // create the Trk::ResidualPull.
210 ATH_MSG_VERBOSE ( "Calculating Pull for channel " << m_idHelperSvc->toString(ID) << " residual " << residual[Trk::loc1] << " pull " << pull[Trk::loc1] );
211
212 return std::make_optional<Trk::ResidualPull>(std::move(residual), std::move(pull), pullIsValid, resType, 1, sinAlpha);
213
214 } else {
215 ATH_MSG_DEBUG ( "Input problem measurement is not TGC." );
216 return std::nullopt;
217 }
218}
219
224 const double residual,
225 const double locMesCov,
226 const double locTrkCov,
227 const Trk::ResidualPull::ResidualType& resType ) const {
228 if( locMesCov < 0 ) {
229 ATH_MSG_DEBUG("Bad error " << locMesCov << " " << locTrkCov << " using measured error ");
230 return 0;
231 }
232 double ErrorSum;
233 if (resType == Trk::ResidualPull::Unbiased) {
234 if( locMesCov + locTrkCov > 0 ) ErrorSum = std::sqrt(locMesCov + locTrkCov);
235 else{
236 ATH_MSG_DEBUG("Bad error measurement " << locMesCov << " from track " << locTrkCov << ", using measured error ");
237 ErrorSum = std::sqrt(locMesCov);
238 }
239 } else if (resType == Trk::ResidualPull::Biased) {
240 if ((locMesCov - locTrkCov) < 0.) {
241 return 0;
242 }
243 ErrorSum = std::sqrt(locMesCov - locTrkCov);
244 } else ErrorSum = std::sqrt(locMesCov);
245 if (ErrorSum != 0) return residual/ErrorSum;
246 return 0;
247}
#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)
std::vector< Identifier > ID
#define AmgSymMatrix(dim)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
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< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
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
TGC_ResidualPullCalculator(const std::string &, const std::string &, const IInterface *)
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