ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_ClusterOnTrackTool.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// Implementation file for class SCT_ClusterOnTrackTool
8// (c) ATLAS Detector software
10// AlgTool used for SCT_ClusterOnTrack object production
12// started 21/04/2004 I.Gavrilenko -- see ChangeLog
14
16
20
21#include <cmath>
22
23using CLHEP::micrometer;
24using CLHEP::deg;
25
27// Constructor
29
31 (const std::string &t, const std::string &n, const IInterface *p) :
32 AthAlgTool(t, n, p) {
33 declareInterface<IRIO_OnTrackCreator>(this);
34}
35
37// Initialisation
39
40StatusCode
42 StatusCode sc = AlgTool::initialize();
43
44 msg(MSG::INFO) << "A strategy to ";
45 switch (m_option_errorStrategy) {
46 case -1: msg(MSG::INFO) << "keep the PRD errors";
47 break;
48
49 case 0: msg(MSG::INFO) << "apply simple pitch errors";
50 break;
51
52 case 1: msg(MSG::INFO) << "assign tuned SCT errors";
53 break;
54
55 case 2: msg(MSG::INFO) << "assign tuned, angle-dependent SCT errors";
56 break;
57
58 default: msg(MSG::INFO) << " -- NO, UNKNOWN. Pls check jobOptions!";
59 break;
60 }
61 msg(MSG::INFO) << " will be applied during SCT_ClusterOnTrack making" << endmsg;
63 msg(MSG::INFO) << "SCT cluster positions will be corrected" << endmsg;
64 }
65
66 // get the error scaling tool
67 if (!m_sctErrorScalingKey.key().empty()) {
68 ATH_CHECK(m_sctErrorScalingKey.initialize());
69 ATH_MSG_DEBUG("Detected need for scaling sct errors.");
70 }
71
72 ATH_CHECK(m_lorentzAngleTool.retrieve());
73
74 return sc;
75}
76
78// Finalize
80
81StatusCode
83 StatusCode sc = AlgTool::finalize();
84
85 return sc;
86}
87
89// Trk::SCT_ClusterOnTrack production
91
94 (const Trk::PrepRawData &rio, const Trk::TrackParameters &trackPar,const EventContext& ctx) const {
95
97 return nullptr;
98 }
99 const InDet::SCT_Cluster * SC = static_cast<const InDet::SCT_Cluster *> (&rio);
100 const InDet::SiWidth width = SC->width();
101 const Amg::Vector2D &colRow = width.colRow();
102
103 // Get pointer to detector element
104 //
105 const InDetDD::SiDetectorElement *EL = SC->detectorElement();
106 if (!EL) {
107 return nullptr;
108 }
109 IdentifierHash iH = EL->identifyHash();
110
111 // Get local position of track
112 //
113 Amg::Vector2D loct = trackPar.localPosition();
114
115 // Find phi angle of track relative to Lorentz drift direction, if needed
116 //
117 double dphi(0.);
118 double sinAlpha = EL->sinStereoLocal(SC->localPosition());
119 double cosAlpha = std::sqrt(1 - sinAlpha * sinAlpha);
121 double pNormal = trackPar.momentum().dot(EL->normal());
122 double pPhi = trackPar.momentum().dot(Amg::AngleAxis3D(asin(-sinAlpha), Amg::Vector3D::UnitZ()) * EL->phiAxis());
123 dphi = std::atan(pPhi / pNormal) - std::atan(m_lorentzAngleTool->getTanLorentzAngle(iH, ctx));
124 }
125 Amg::Vector3D localstripdir(-sinAlpha, cosAlpha, 0.);
126 Amg::Vector3D globalstripdir = trackPar.associatedSurface().transform().linear() * localstripdir;
127 double distance = (trackPar.position() - SC->globalPosition()).mag();
128 const auto *boundsraw = &trackPar.associatedSurface().bounds();
129
130 const Trk::TrapezoidBounds *tbounds = boundsraw->type() == Trk::SurfaceBounds::Trapezoid ? static_cast<const Trk::TrapezoidBounds *>(boundsraw) : nullptr;
131 const Trk::RectangleBounds *rbounds = boundsraw->type() == Trk::SurfaceBounds::Rectangle ? static_cast<const Trk::RectangleBounds *>(boundsraw) : nullptr;
132
133 if (!tbounds && !rbounds) {
134 return nullptr;
135 }
136
137 double boundsy = rbounds ? rbounds->halflengthY() : tbounds->halflengthY();
138 if (distance * cosAlpha > boundsy) {
139 distance = boundsy / cosAlpha - 1;
140 }
141 // SCT_ClusterOnTrack production
142 //
144 if (loct.y() < 0) {
145 distance = -distance;
146 }
147 Amg::Vector3D glob(SC->globalPosition() + distance * globalstripdir);
148 Amg::MatrixX oldcov = SC->localCovariance();
149 // Local position and error matrix production
150 //
151 // let's start to re-compute cluster error if errorStrategy >=0
152 // These were derived by the studies reported on 25th September 2006
153 // https://indico.cern.ch/event/430391/contributions/1066157/attachments/929942/1317007/SCTSoft_25Sept06_clusters.pdf
154 // and on 4th February 2008
155 // https://indico.cern.ch/event/22934/contributions/485813/attachments/379647/528096/ClusterErrors_04Feb08.pdf
156 if (m_option_errorStrategy > -1) {
157 Amg::MatrixX mat(2, 2);
158 mat.setZero();
159 switch (m_option_errorStrategy) {
160 case 0:
161 mat(0, 0) = std::pow(width.phiR(), 2) /12.;
162 mat(1, 1) = std::pow(width.z(), 2) /12.;
163 break;
164
165 case 1:
166 if (colRow.x() == 1) {
167 mat(0, 0) = std::pow(1.05 * width.phiR(), 2) /12.;
168 } else if (colRow.x() == 2) {
169 mat(0, 0) = std::pow(0.27 * width.phiR(), 2) /12.;
170 } else {
171 mat(0, 0) = std::pow(width.phiR(), 2) /12.;
172 }
173 mat(1, 1) = std::pow(width.z() / colRow.y(), 2) /12.;
174 break;
175
176 case 2:
177 mat(0, 0) = std::pow(getError(dphi, int(colRow.x())) * (EL->phiPitch() / 0.080), 2);
178 mat(1, 1) = std::pow(width.z() / colRow.y(), 2) /12.;
179 break;
180
181 default:
182 // don't do anything....
183 break;
184 }
185 // rotation for endcap SCT
186 if (EL->design().shape() == InDetDD::Trapezoid) {
187 double sn = EL->sinStereoLocal(SC->localPosition());
188 double sn2 = sn * sn;
189 double cs2 = 1. - sn2;
190 double w = EL->phiPitch(SC->localPosition()) / EL->phiPitch();
191 double v0 = mat(0, 0) * w * w;
192 double v1 = mat(1, 1);
193 mat(0, 0) = (cs2 * v0 + sn2 * v1);
194 mat(1, 0) = (sn * std::sqrt(cs2) * (v0 - v1));
195 mat(0, 1) = mat(1, 0);
196 mat(1, 1) = (sn2 * v0 + cs2 * v1);
197 }
198 oldcov = std::move(mat);
199 }
200
201 Amg::MatrixX cov(oldcov);
202 if (EL->design().shape() != InDetDD::Trapezoid) { // barrel
203 Trk::DefinedParameter lpos1dim(SC->localPosition().x(), Trk::locX);
205 Trk::LocalParameters(SC->localPosition()) :// PRDformation does 2-dim
206 Trk::LocalParameters(lpos1dim);
208 cov = Amg::MatrixX(1, 1);
209 cov(0, 0) = oldcov(0, 0);
210 }
211
212 if (!m_sctErrorScalingKey.key().empty()) {
213 //SG::ReadCondHandle<SCTRIO_OnTrackErrorScaling> error_scaling( m_sctErrorScalingKey );
216 ->getScaledCovariance(std::move(cov), false, 0.0);
217 }
218 }else { // endcap
219 locpar = Trk::LocalParameters(SC->localPosition());
220 if (!m_sctErrorScalingKey.key().empty()) {
223 ->getScaledCovariance(std::move(cov), true,
224 EL->sinStereoLocal(SC->localPosition()));
225 }
226 double Sn = EL->sinStereoLocal(SC->localPosition());
227 double Sn2 = Sn * Sn;
228 double Cs2 = (1. - Sn) * (1. + Sn);
229 double SC = Sn * std::sqrt(Cs2);
230 double W = EL->phiPitch(loct) / EL->phiPitch();
231 double dV0 = (Cs2 * cov(0, 0) + Sn2 * cov(1, 1) +
232 2. * SC * cov(1, 0)) * (W * W - 1.);
233 cov(0, 0) += (Cs2 * dV0);
234 cov(1, 0) += (SC * dV0);
235 cov(0, 1) = cov(1, 0);
236 cov(1, 1) += (Sn2 * dV0);
237 }
238
239 // Apply correction for cluster position bias
240 //
242 double correction = getCorrection(dphi, int(colRow.x())) * EL->hitDepthDirection();
243 locpar[Trk::locX] += correction;
244 }
245 bool isbroad = m_option_errorStrategy == 0;
246 return new InDet::SCT_ClusterOnTrack(SC, std::move(locpar), std::move(cov), iH, glob, isbroad);
247}
248
249double
251 constexpr float corr1[30] = {
252 0.3, 0.8, 1.1, 1.5, 1.9, 1.9, 2.1, 2.4, 2.3, 2.6,
253 2.6, 2.7, 2.8, 2.7, 2.5, 2.6, 2.8, 2.6, 2.6, 2.7,
254 2.2, 1.8, 1.8, 1.6, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0
255 };
256 constexpr float corr2[30] = {
257 0.0, 0.0, 0.0, 1.0, 1.5, 1.7, 1.7, 2.3, 2.1, 2.5,
258 2.5, 2.7, 2.7, 2.9, 3.0, 3.0, 3.0, 3.0, 3.4, 3.4,
259 3.0, 3.2, 2.6, 2.6, 3.0, 2.7, 2.5, 2.4, 1.7, 1.3
260 };
261
262 // Phi bins have 1 degree width, and cover 0-30 degrees
263 int phiBin = static_cast<int>(std::abs(phi) / deg);
264
265 float correction(0.);
266
267 if (phiBin < 30) {
268 if (nstrip == 1) {
269 correction = corr1[phiBin];
270 }
271 if (nstrip == 2) {
272 correction = corr2[phiBin];
273 }
274 }
275
276 if (phi > 0.) {
277 correction *= -1.;
278 }
279
280 return correction * micrometer;
281}
282
283double
285 constexpr float sigma1[60] = {
286 22.1, 21.8, 21.4, 21.0, 20.5, 20.0, 19.6, 19.1, 18.5, 18.0,
287 17.4, 17.0, 16.4, 15.8, 15.4, 14.9, 14.4, 14.1, 13.3, 13.1,
288 12.9, 12.4, 12.6, 12.2, 12.3, 12.6, 13.4, 14.2, 15.6, 19.3,
289 22.8, 29.5, 33.2, 41.8, 44.3, 48.4, 49.9, 54.0, 53.0, 56.3,
290 57.5, 56.3, 64.5, 65.7, 66.1, 69.4, 74.8, 78.3, 78.8, 79.8,
291 73.5, 73.8, 75.8, 84.3, 87.0, 99.9, 86.3, 0.0, 0.0, 0.0
292 };
293 constexpr float sigma2[60] = {
294 22.2, 20.3, 18.8, 16.0, 14.6, 13.8, 12.9, 12.9, 12.7, 12.3,
295 12.7, 12.6, 13.0, 13.3, 14.0, 14.6, 15.3, 15.9, 16.6, 17.6,
296 18.4, 19.3, 19.9, 20.5, 21.0, 21.2, 21.5, 21.4, 21.3, 21.3,
297 20.9, 20.8, 20.6, 20.7, 20.3, 20.7, 21.7, 24.4, 26.5, 29.5,
298 34.6, 41.6, 48.5, 52.3, 54.5, 58.4, 61.8, 66.7, 69.9, 72.1,
299 78.9, 79.2, 81.8, 80.9, 87.5, 99.2, 0.0, 0.0, 0.0, 0.0
300 };
301 constexpr float sigma3[60] = {
302 70.1, 73.6, 71.7, 66.9, 68.3, 66.8, 66.2, 64.8, 66.6, 63.3,
303 63.3, 60.4, 59.0, 57.1, 56.4, 54.4, 54.2, 54.4, 50.3, 48.9,
304 48.1, 41.9, 38.0, 31.8, 28.3, 23.1, 23.0, 20.3, 18.5, 17.6,
305 17.7, 16.8, 18.3, 19.3, 19.0, 20.0, 20.9, 21.6, 22.0, 22.2,
306 22.7, 22.4, 24.3, 24.8, 24.6, 27.0, 29.8, 37.0, 47.7, 49.3,
307 58.2, 60.2, 66.8, 70.8, 77.3, 80.6, 0.0, 0.0, 0.0, 0.0
308 };
309 constexpr float sigma4[60] = {
310 103.2, 100.4, 100.7, 101.2, 107.4, 100.6, 100.9, 100.4, 96.3, 98.2,
311 96.7, 94.5, 96.9, 91.7, 90.5, 89.5, 86.3, 90.6, 82.4, 89.3,
312 87.3, 77.6, 75.7, 77.2, 77.3, 84.1, 80.1, 66.9, 73.7, 72.3,
313 58.1, 65.6, 64.2, 54.7, 47.2, 44.4, 34.6, 36.4, 29.1, 25.8,
314 18.8, 21.6, 18.6, 20.3, 22.7, 23.3, 24.1, 22.4, 24.7, 24.7,
315 27.3, 30.4, 37.0, 46.4, 59.4, 62.6, 65.3, 0.0, 0.0, 0.0
316 };
317 constexpr float sigma5[60] = {
318 150.9, 139.7, 133.9, 139.8, 141.4, 134.9, 138.4, 129.3, 137.9, 128.7,
319 132.4, 130.1, 124.2, 115.8, 131.4, 115.2, 128.7, 112.8, 130.7, 129.0,
320 115.8, 101.3, 115.9, 116.1, 121.7, 109.9, 110.0, 97.2, 96.4, 107.3,
321 98.2, 80.0, 73.2, 87.0, 97.0, 88.5, 72.2, 73.9, 80.8, 75.7,
322 69.5, 67.1, 54.1, 58.9, 47.3, 50.6, 29.5, 26.6, 25.8, 20.9,
323 20.6, 21.9, 22.1, 21.1, 27.9, 41.6, 0.0, 0.0, 0.0, 0.0
324 };
325
326 // Phi bins have 1 degree width, and cover 0-60 degrees
327 int phiBin = static_cast<int>(std::abs(phi) / deg);
328
329 float sigma(0.);
330
331 if (phiBin < 60) {
332 if (nstrip == 1) {
333 sigma = sigma1[phiBin];
334 }
335 if (nstrip == 2) {
336 sigma = sigma2[phiBin];
337 }
338 if (nstrip == 3) {
339 sigma = sigma3[phiBin];
340 }
341 if (nstrip == 4) {
342 sigma = sigma4[phiBin];
343 }
344 if (nstrip == 5) {
345 sigma = sigma5[phiBin];
346 }
347 }
348 if (sigma < 0.1) {
349 sigma = std::max(100., float(nstrip) * 80. / std::sqrt(12));
350 }
351
352 return sigma * micrometer;
353}
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
static Double_t sc
#define deg
const double width
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
MsgStream & msg() const
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
SG::ReadCondHandleKey< RIO_OnTrackErrorScaling > m_sctErrorScalingKey
toolhandle for central error scaling
BooleanProperty m_option_make2dimBarrelClusters
job options
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
SCT_ClusterOnTrackTool(const std::string &, const std::string &, const IInterface *)
AlgTool constructor.
static double getCorrection(double phi, int nstrip)
Returns a correction to be applied to the SCT cluster local x position in simulated events to remove ...
virtual InDet::SCT_ClusterOnTrack * correct(const Trk::PrepRawData &, const Trk::TrackParameters &, const EventContext &ctx=Gaudi::Hive::currentContext()) const override
produces an SCT_ClusterOnTrack using the measured SCT_Cluster and the track prediction.
virtual StatusCode initialize() override
AlgTool initialisation.
static double getError(double phi, int nstrip)
Returns the resolution on the reconstructed position (local x) of SCT clusters in simulated events.
virtual StatusCode finalize() override
AlgTool termination.
Specific class to represent the SCT measurements.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Amg::Vector2D localPosition() const
Access method for the local coordinates, local parameter definitions differ for each surface type.
virtual bool type(PrepRawDataType type) const
Interface method checking the type.
Bounds for a rectangular, planar surface.
virtual BoundsType type() const override final
Return the type of the bounds for persistency.
double halflengthY() const
for consitant naming
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
Bounds for a trapezoidal, planar Surface.
virtual BoundsType type() const override
Return the type of the bounds for persistency.
double halflengthY() const
This method returns the halflength in Y (second coordinate of local surface frame)
Eigen::AngleAxisd AngleAxis3D
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
This module defines the arguments passed from the BATCH driver to the BATCH worker.
@ locX
Definition ParamDefs.h:37
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParametersBase< TrackParametersDim, Charged > TrackParameters
const T_res * ErrorScalingCast(const T_src *src)