ATLAS Offline Software
Loading...
Searching...
No Matches
MuonTGMeasurementTool.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
27#include "TrkGeometry/Layer.h"
32
33// Constructor with parameters:
34Muon::MuonTGMeasurementTool::MuonTGMeasurementTool(const std::string& type, const std::string& name, const IInterface* parent) :
35 AthAlgTool(type, name, parent), m_muonDetMgr(nullptr) {
36 declareInterface<Muon::IMuonTGMeasTool>(this);
37}
38
39// Initialize method:
41 // Get the messaging service, print where you are
42 ATH_MSG_INFO("MuonTGMeasurementTool::initialize()");
43
44 ATH_CHECK(m_idHelperSvc.retrieve());
46 if (m_useDSManager) { ATH_CHECK(detStore()->retrieve(m_muonDetMgr)); }
47
48 // define projection matrices
49 m_tgcProjEta = std::make_unique<AmgMatrix(5, 5)>();
50 m_tgcProjEta->setIdentity();
51 (*m_tgcProjEta)(0, 0) = 0.;
52 (*m_tgcProjEta)(1, 1) = 0.;
53 (*m_tgcProjEta)(0, 1) = 1.;
54 (*m_tgcProjEta)(1, 0) = -1.;
55 m_tgcProjPhi = std::make_unique<AmgMatrix(5, 5)>();
56 m_tgcProjPhi->setIdentity();
57
58 m_rpcProjEta = std::make_unique<AmgMatrix(5, 5)>();
59 m_rpcProjEta->setIdentity();
60 (*m_rpcProjEta)(0, 0) = 0.;
61 (*m_rpcProjEta)(1, 1) = 0.;
62 (*m_rpcProjEta)(0, 1) = 1.;
63 (*m_rpcProjEta)(1, 0) = 1.;
64 m_rpcProjPhi = std::make_unique<AmgMatrix(5, 5)>();
65 m_rpcProjPhi->setIdentity();
66
67 if (!m_trackingGeometryReadKey.empty()) {
69 } else {
71 }
72 return StatusCode::SUCCESS;
73}
75 Identifier id) const {
76 const MuonGM::MuonDetectorManager* MuonDetMgr = m_muonDetMgr;
77 if (!m_useDSManager) {
79 MuonDetMgr = DetectorManagerHandle.cptr();
80 if (MuonDetMgr == nullptr) {
81 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
82 // return StatusCode::FAILURE;
83 }
84 }
85
86 // Get the messaging service, print where you are
87 ATH_MSG_DEBUG("MuonTGMeasurementTool::layerToDetEl");
88 const Trk::TrackParameters* projPar = nullptr;
89 // const Amg::Vector2D* locPos = 0;
90 // check input
91 if (!lay || !parm || !id.get_identifier32().get_compact()) return projPar;
92
93 // get tracking geometry
94
95 // check compatibility of layer info and required id ? this was already done when associating !
96 if (!lay->layerType()) return projPar;
97 Identifier layId(lay->layerType());
98
99 unsigned int hitType = 0;
100 if (m_idHelperSvc->isMdt(id)) hitType = 1;
101 if (m_idHelperSvc->isRpc(id)) hitType = 2;
102 if (m_idHelperSvc->isCsc(id)) hitType = 3;
103 if (m_idHelperSvc->isTgc(id)) hitType = 4;
104
105 unsigned int layType = 0;
106 if (m_idHelperSvc->isMdt(layId)) layType = 1;
107 if (m_idHelperSvc->isRpc(layId)) layType = 2;
108 if (m_idHelperSvc->isCsc(layId)) layType = 3;
109 if (m_idHelperSvc->isTgc(layId)) layType = 4;
110
111 if (layType != hitType) return projPar;
112
113 if (hitType == 0) {
114 ATH_MSG_ERROR("unknown hit technology");
115 return projPar;
116 } else {
117 ATH_MSG_DEBUG("hit technology:" << hitType);
118 }
119
120 ATH_MSG_DEBUG("extrapolated covariance:" << parm->covariance());
121
122 if (hitType == 1) {
123 const MuonGM::MdtReadoutElement* mdtROE = MuonDetMgr->getMdtReadoutElement(id);
124 if (!mdtROE) {
125 ATH_MSG_WARNING(name() << "MDT readout element not found");
126 return projPar;
127 }
128 // local position of tube
129 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
130 Amg::Vector2D locWire(0., lay->getRef() + (tube - 1) * 30.035);
131 if (fabs(lay->getRef()) > 10e6) {
132 double sign = (lay->getRef() > 0) ? 1. : -1.;
133 int dec = int(lay->getRef() / 1.e5);
134 double ref0 = dec / 1.e5;
135 double ref1 = lay->getRef() - dec * 1e5 - 0.5 * (sign + 1) * 1e5;
136 locWire[0] = ref0;
137 locWire[1] = ref1;
138 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
139 int tubeMax = m_idHelperSvc->mdtIdHelper().tubeMax(id);
140 if (tube > 6 && tubeMax - tube > 5) locWire[0] = 0.;
141 }
142 if (sqrt(locWire[0] * locWire[0] + locWire[1] * locWire[1]) > 2000.) {
143 ATH_MSG_WARNING(name() << " wire shift out bounds for MDT tube :" << m_idHelperSvc->mdtIdHelper().stationName(id) << ","
144 << m_idHelperSvc->mdtIdHelper().stationEta(id) << "," << m_idHelperSvc->mdtIdHelper().stationPhi(id)
145 << ": abandon projection");
146 return projPar;
147 }
148 // direction at the layer
149 Amg::Vector3D dir = parm->momentum().unit();
150 Amg::Vector3D locDir = (lay->surfaceRepresentation().transform().inverse()) * dir;
151 Amg::Vector3D wireDir(1., 0., 0.);
152 //
153 double ND = dir.dot(lay->surfaceRepresentation().normal());
154 double DL = locDir.dot(wireDir);
155 double A = sqrt(1. - DL * DL);
156 AmgMatrix(5, 5) mdtProj;
157 mdtProj.setIdentity();
158 //
159 const Trk::StraightLineSurface* tubeSurf = dynamic_cast<const Trk::StraightLineSurface*>(&(mdtROE->surface(id)));
160 double ori = (lay->surfaceRepresentation().transform().inverse() * tubeSurf->transform()).rotation()(1, 1) > 0. ? -1. : 1.;
161 if (A > 10e-6) {
162 mdtProj(0, 1) = ND / A;
163 mdtProj(1, 0) = ori;
164 mdtProj(1, 1) = DL / A * sqrt(A * A - ND * ND) / A;
165 mdtProj(0, 0) = 0.;
166 } else {
167 mdtProj(0, 1) = 1.;
168 mdtProj(1, 0) = ori;
169 mdtProj(1, 1) = 0.;
170 mdtProj(0, 0) = 0.;
171 }
172 //
173 Amg::VectorX locPar = parm->parameters();
174 locPar[0] -= locWire[0];
175 locPar[1] -= locWire[1];
176 Amg::VectorX pPar = mdtProj * locPar;
177 ATH_MSG_DEBUG("projected parameters(layer->MDT):" << pPar);
178
179 if (parm->covariance()) {
180 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarity(mdtProj);
181 ATH_MSG_DEBUG("projected covariance(layer->MDT):" << (*projEM));
182 projPar = new Trk::AtaStraightLine(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *tubeSurf, projEM);
183
184 } else {
185 projPar = new Trk::AtaStraightLine(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *tubeSurf);
186 }
187 }
188
189 if (hitType == 2) {
190 //
191 const MuonGM::RpcReadoutElement* rpcROE = MuonDetMgr->getRpcReadoutElement(id);
192 if (!rpcROE) return projPar;
193 const Trk::PlaneSurface* stripSurf = dynamic_cast<const Trk::PlaneSurface*>(&(rpcROE->surface(id)));
194 if (!stripSurf) return projPar;
195 // decode ref position
196 Amg::VectorX locPar = parm->parameters();
197 // projection matrix
198 AmgMatrix(5, 5)* pMx = nullptr;
199 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
200 pMx = m_rpcProjPhi.get();
201 else
202 pMx = m_rpcProjEta.get();
203 // projected parameters
204 double eta = 1.;
205 double sign = (m_idHelperSvc->rpcIdHelper().measuresPhi(id) && m_idHelperSvc->rpcIdHelper().doubletPhi(id) == 2) ? -1. : 1.;
206 double zswap = (lay->getRef() > 10000.) ? -1. : 1.;
207 double ref = (zswap < 0.) ? lay->getRef() - 20000. : lay->getRef();
208 locPar[0] -= sign * ref;
209 Amg::VectorX pPar = (*pMx) * locPar;
210 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
211 pPar[0] *= eta;
212 else
213 pPar[1] *= -eta;
214 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
215 pPar[1] *= zswap;
216 else
217 pPar[0] *= zswap;
218
219 std::optional<AmgMatrix(5, 5)> projEM;
220 projEM.emplace();
221 if (parm->covariance()) {
222 projEM = parm->covariance()->similarity(*pMx);
223 projPar = new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *stripSurf, projEM);
224
225 } else {
226 projPar = new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *stripSurf);
227 projEM = std::nullopt;
228 }
229
230 if (m_alignedMode && (parm->position() - projPar->position()).mag() > 0.001) {
231 ATH_MSG_DEBUG("geometrical RPC projection (layerToDetEl) for hit : "
232 << m_idHelperSvc->rpcIdHelper().measuresPhi(id) << "," << m_idHelperSvc->rpcIdHelper().stationName(id) << ","
233 << m_idHelperSvc->rpcIdHelper().stationEta(id) << "," << m_idHelperSvc->rpcIdHelper().stationPhi(id) << ","
234 << m_idHelperSvc->rpcIdHelper().doubletPhi(id) << "," << m_idHelperSvc->rpcIdHelper().doubletR(id) << ","
235 << m_idHelperSvc->rpcIdHelper().doubletZ(id));
236 Amg::Vector2D locPos;
237 const Amg::Vector3D& globPos = parm->position();
238 bool onSurface = stripSurf->globalToLocal(globPos, globPos, locPos);
239 if (onSurface) {
240 pPar[0] = locPos[0];
241 pPar[1] = locPos[1];
242 delete projPar;
243 projPar = nullptr;
244 projPar = projEM ? new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *stripSurf, projEM)
245 : new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *stripSurf);
246 } else {
247 delete projPar;
248 return nullptr;
249 }
250 }
251 }
252
253 if (hitType == 3) {
254 // local position of detEl
255 const MuonGM::CscReadoutElement* cscROE = MuonDetMgr->getCscReadoutElement(id);
256 if (!cscROE) {
257 ATH_MSG_WARNING(name() << "CSC readout element not found");
258 return projPar;
259 }
260
261 const Trk::PlaneSurface* stripSurf = dynamic_cast<const Trk::PlaneSurface*>(&(cscROE->surface(id)));
262 if (!stripSurf) return projPar;
263 // dealing with displaced planes, possibly sligthly displaced
264 double diff = m_idHelperSvc->cscIdHelper().measuresPhi(id) ? 1.55 : -1.55;
265 // distance between planes (assuming parallel planes)
266 Amg::Vector3D layNormal = lay->surfaceRepresentation().normal();
267 double DN = parm->momentum().dot(layNormal);
268 double t = diff / DN;
269 // displacement ( as projection of strip surface center on the layer )
270 const Amg::Vector2D csc_shift(0., lay->getRef());
271 // correct local position due to plane distance : use method independent on misalignment
272 Amg::Vector3D corrLocPos = parm->position() - t * parm->momentum() + t * DN * layNormal;
273 Amg::Vector2D locCorrLay;
274 bool onSurface = lay->surfaceRepresentation().globalToLocal(corrLocPos, corrLocPos, locCorrLay);
275
276 if (!onSurface) {
277 ATH_MSG_WARNING(name() << ": misplaced CSC " << id);
278 return projPar;
279 }
280
281 Amg::VectorX parProj(5);
282 parProj[0] = locCorrLay[Trk::locX] - csc_shift[Trk::locX];
283 parProj[1] = locCorrLay[Trk::locY] - csc_shift[Trk::locY];
284 parProj[2] = parm->parameters()[Trk::phi];
285 parProj[3] = parm->parameters()[Trk::theta];
286 parProj[4] = parm->parameters()[Trk::qOverP];
287 //
288 AmgMatrix(5, 5)* pMx = nullptr;
289 if (m_idHelperSvc->cscIdHelper().measuresPhi(id))
290 pMx = m_tgcProjPhi.get();
291 else
292 pMx = m_tgcProjEta.get();
293 Amg::VectorX locPar = (*pMx) * parProj;
294 ATH_MSG_DEBUG("projected parameters (layer->CSC):" << m_idHelperSvc->cscIdHelper().measuresPhi(id) << "," << locPar);
295
296 if (parm->covariance()) {
297 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarity(*pMx);
298
299 ATH_MSG_DEBUG("projected covariance (layer->CSC):" << *projEM);
300
301 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf, projEM);
302
303 } else
304 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf);
305
306 ATH_MSG_DEBUG("test CSC projection:layerToDetEl:" << parm->position() << "," << projPar->position());
307 }
308
309 if (hitType == 4) {
310 // local position at layer
311 const MuonGM::TgcReadoutElement* tgcROE = MuonDetMgr->getTgcReadoutElement(id);
312 if (!tgcROE) {
313 ATH_MSG_WARNING(name() << "TGC readout element not found");
314 return projPar;
315 }
316 const Trk::PlaneSurface* stripSurf = dynamic_cast<const Trk::PlaneSurface*>(&(tgcROE->surface(id)));
317 if (!stripSurf) return projPar;
318 //
319 AmgMatrix(5, 5)* pMx = nullptr;
320 if (m_idHelperSvc->tgcIdHelper().isStrip(id))
321 pMx = m_tgcProjPhi.get();
322 else
323 pMx = m_tgcProjEta.get();
324 Amg::VectorX locPar = (*pMx) * parm->parameters();
325 ATH_MSG_DEBUG("projected parameters (layer->TGC):" << m_idHelperSvc->tgcIdHelper().isStrip(id) << "," << locPar << ","
326 << stripSurf);
327
328 std::optional<AmgMatrix(5, 5)> projEM = std::nullopt;
329 bool bcov = false;
330
331 if (parm->covariance()) {
332 projEM = parm->covariance()->similarity(*pMx);
333 bcov = true;
334 ATH_MSG_DEBUG("projected covariance (layer->TGC):" << (*projEM));
335 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf, projEM);
336
337 } else {
338 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf);
339 }
340
341 // verify
342 if (m_alignedMode && (parm->position() - projPar->position()).mag() > 0.001) {
343 ATH_MSG_DEBUG("geometrical TGC projection ( layer2detEl ):"
344 << m_idHelperSvc->tgcIdHelper().stationName(id) << "," << m_idHelperSvc->tgcIdHelper().stationEta(id) << ","
345 << m_idHelperSvc->tgcIdHelper().stationPhi(id) << "," << m_idHelperSvc->tgcIdHelper().isStrip(id));
346 Amg::Vector2D locPos;
347 const Amg::Vector3D& globPos = parm->position();
348 bool onSurface = stripSurf->globalToLocal(globPos, globPos, locPos);
349 if (onSurface) {
350 locPar[0] = locPos[0];
351 locPar[1] = locPos[1];
352 delete projPar;
353 projPar = nullptr;
354 projPar = bcov ? new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf, projEM)
355 : new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *stripSurf);
356 } else {
357 delete projPar;
358 return nullptr;
359 }
360 }
361 }
362
363 return projPar;
364}
365
367 Identifier id) const {
368 // Get the messaging service, print where you are
369 ATH_MSG_DEBUG("MuonTGMeasurementTool::detElToLayer");
370 const Trk::TrackParameters* projPar = nullptr;
371
372 // check input
373 if (!lay || !parm || !(id.get_identifier32().get_compact() > 0)) return projPar;
374
375 // check compatibility of layer info and required id ? this was already done when associating !
376 if (!lay->layerType()) return projPar;
377 Identifier layId(lay->layerType());
378
379 ATH_MSG_DEBUG("MuonTGMeasurementTool::input ok");
380
381 unsigned int hitType = 0;
382 if (m_idHelperSvc->isMdt(id)) hitType = 1;
383 if (m_idHelperSvc->isRpc(id)) hitType = 2;
384 if (m_idHelperSvc->isCsc(id)) hitType = 3;
385 if (m_idHelperSvc->isTgc(id)) hitType = 4;
386
387 unsigned int layType = 0;
388 if (m_idHelperSvc->isMdt(layId)) layType = 1;
389 if (m_idHelperSvc->isRpc(layId)) layType = 2;
390 if (m_idHelperSvc->isCsc(layId)) layType = 3;
391 if (m_idHelperSvc->isTgc(layId)) layType = 4;
392
393 if (layType != hitType) return projPar;
394
395 if (hitType == 0) {
396 ATH_MSG_DEBUG("unknown hit technology");
397 return projPar;
398 }
399
400 if (hitType == 1) {
401 // local position of the tube
402 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
403 Amg::Vector2D locWire(0., lay->getRef() + (tube - 1) * 30.035);
404 if (fabs(lay->getRef()) > 10e6) {
405 double sign = (lay->getRef() > 0) ? 1. : -1.;
406 int dec = int(lay->getRef() / 1.e5);
407 double ref0 = dec / 1.e5;
408 double ref1 = lay->getRef() - dec * 1e5 - 0.5 * (sign + 1) * 1e5;
409 locWire[0] = ref0;
410 locWire[1] = ref1;
411 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
412 int tubeMax = m_idHelperSvc->mdtIdHelper().tubeMax(id);
413 if (tube > 6 && tubeMax - tube > 5) locWire[0] = 0.;
414 }
415 if (sqrt(locWire[0] * locWire[0] + locWire[1] * locWire[1]) > 2000.) {
416 ATH_MSG_WARNING(name() << " wire shift out bounds for MDT tube :" << m_idHelperSvc->mdtIdHelper().stationName(id) << ","
417 << m_idHelperSvc->mdtIdHelper().stationEta(id) << "," << m_idHelperSvc->mdtIdHelper().stationPhi(id)
418 << ": abandon projection");
419 return projPar;
420 }
421 // local position (tube)
422 // const Amg::Vector2D locPos = parm->localPosition();
423 // direction at the layer
424 Amg::Vector3D dir = parm->momentum().unit();
425 Amg::Vector3D locDir = (lay->surfaceRepresentation().transform().inverse()) * dir;
427 Amg::Vector3D wireDir(1., 0., 0.);
428 const Trk::PlaneSurface* laySurf = dynamic_cast<const Trk::PlaneSurface*>(&(lay->surfaceRepresentation()));
429 if (!laySurf) return projPar;
430 //
431 double ND = dir.dot(normal);
432 double DL = locDir.dot(wireDir);
433 double A = sqrt(1. - DL * DL);
434 AmgMatrix(5, 5) mdtProj;
435 mdtProj.setIdentity();
436 //
437 double ori = (laySurf->transform().inverse() * parm->associatedSurface().transform()).rotation()(1, 1) > 0. ? -1. : 1.;
438 if (A > 10e-6) {
439 mdtProj(0, 1) = ND / A;
440 mdtProj(1, 0) = ori;
441 mdtProj(1, 1) = DL / A * sqrt(A * A - ND * ND) / A;
442 mdtProj(0, 0) = 0.;
443 } else {
444 mdtProj(0, 1) = 1.;
445 mdtProj(1, 0) = ori;
446 mdtProj(1, 1) = 0.;
447 mdtProj(0, 0) = 0.;
448 }
449 Amg::VectorX locPar = parm->parameters();
450 AmgMatrix(5, 5) mdtProjInv = mdtProj.inverse();
451 Amg::VectorX pPar = mdtProjInv * locPar;
452 pPar[0] += locWire[0];
453 pPar[1] += locWire[1];
454 ATH_MSG_DEBUG("back projected parameters(MDT->layer):" << pPar);
455
456 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarity(mdtProjInv);
457
458 ATH_MSG_DEBUG("back projected covariance(MDT->layer):" << (*projEM));
459 projPar = new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *laySurf, projEM);
460 // delete projEM;
461 }
462
463 if (hitType == 2) {
464 // local position at detEl
465 // const Amg::Vector2D locPos = parm->localPosition();
466 const Trk::PlaneSurface* laySurf = dynamic_cast<const Trk::PlaneSurface*>(&(lay->surfaceRepresentation()));
467 if (!laySurf) return projPar;
468 //
469 Amg::VectorX locPar = parm->parameters();
470 AmgMatrix(5, 5)* pMx = nullptr;
471 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
472 pMx = m_rpcProjPhi.get();
473 else
474 pMx = m_rpcProjEta.get();
475
476 double eta = 1.;
477 double sign = (m_idHelperSvc->rpcIdHelper().measuresPhi(id) && m_idHelperSvc->rpcIdHelper().doubletPhi(id) == 2) ? -1. : 1.;
478
479 double ref = (lay->getRef() > 10000.) ? lay->getRef() - 20000. : lay->getRef();
480 double zswap = (lay->getRef() > 10000.) ? -1. : 1.;
481
482 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
483 locPar[0] *= eta;
484 else
485 locPar[1] *= -eta;
486 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
487 locPar[1] *= zswap;
488 else
489 locPar[0] *= zswap;
490
491 Amg::VectorX pPar = (*pMx) * locPar;
492 pPar[0] += sign * ref;
493
494 //
495 ATH_MSG_DEBUG("back projected parameters(RPC->layer):" << m_idHelperSvc->rpcIdHelper().measuresPhi(id) << "," << pPar);
496
497 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarityT(*pMx);
498
499 ATH_MSG_DEBUG("back projected covariance(RPC->layer):" << (*projEM));
500 projPar = new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *laySurf, projEM);
501 // delete projEM;
502
503 if ((parm->position() - projPar->position()).mag() > 0.001) {
504 ATH_MSG_DEBUG("geometrical RPC projection (detElToLayer) for hit : "
505 << m_idHelperSvc->rpcIdHelper().measuresPhi(id) << "," << m_idHelperSvc->rpcIdHelper().stationName(id) << ","
506 << m_idHelperSvc->rpcIdHelper().stationEta(id) << "," << m_idHelperSvc->rpcIdHelper().stationPhi(id) << ","
507 << m_idHelperSvc->rpcIdHelper().doubletPhi(id) << "," << m_idHelperSvc->rpcIdHelper().doubletR(id) << ","
508 << m_idHelperSvc->rpcIdHelper().doubletZ(id));
509 Amg::Vector2D locPos;
510 const Amg::Vector3D& globPos = parm->position();
511 bool onSurface = laySurf->globalToLocal(globPos, globPos, locPos);
512 if (onSurface) {
513 pPar[0] = locPos[0];
514 pPar[1] = locPos[1];
515 delete projPar;
516 projPar = new Trk::AtaPlane(pPar[0], pPar[1], pPar[2], pPar[3], pPar[4], *laySurf, projEM);
517 // delete projEM;
518 } else {
519 delete projPar;
520 return nullptr;
521 }
522 }
523 }
524
525 if (hitType == 3) {
526 // local position of detEl
527 // const Amg::Vector2D locPos = parm->localPosition();
528 const Trk::PlaneSurface* laySurf = dynamic_cast<const Trk::PlaneSurface*>(&(lay->surfaceRepresentation()));
529 if (!laySurf) return projPar;
530 // dealing with parallel displaced planes
531 double diff = m_idHelperSvc->cscIdHelper().measuresPhi(id) ? 1.55 : -1.55;
532 //
533 Amg::Vector3D layNormal = lay->surfaceRepresentation().normal();
534 double DN = parm->momentum().dot(layNormal);
535 double t = diff / DN;
536 // displacement of planes
537 const Amg::Vector2D csc_shift(0., lay->getRef());
538 // projection : take into account possible misalignment ;
539 AmgMatrix(5, 5)* pMx = nullptr;
540 if (m_idHelperSvc->cscIdHelper().measuresPhi(id))
541 pMx = m_tgcProjPhi.get();
542 else
543 pMx = m_tgcProjEta.get();
544 AmgMatrix(5, 5) pMxInv = pMx->inverse();
545 Amg::VectorX parProj = pMxInv * parm->parameters();
546 Amg::Vector3D corrLocPos = lay->surfaceRepresentation().center() - t * parm->momentum() + t * DN * layNormal;
547 Amg::Vector2D locCorrLay;
548 bool onSurface = lay->surfaceRepresentation().globalToLocal(corrLocPos, corrLocPos, locCorrLay);
549 if (onSurface && locCorrLay.size() > 0) {
550 parProj[0] += locCorrLay[Trk::locX] + csc_shift[Trk::locX];
551 parProj[1] += locCorrLay[Trk::locY] + csc_shift[Trk::locY];
552 ATH_MSG_DEBUG("back projected parameters(CSC->layer):" << m_idHelperSvc->cscIdHelper().measuresPhi(id) << "," << parProj);
553 }
554 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarity(pMxInv);
555
556 ATH_MSG_DEBUG("back projected covariance(CSC->layer):" << (*projEM));
557 projPar = new Trk::AtaPlane(parProj[0], parProj[1], parProj[2], parProj[3], parProj[4], *laySurf, projEM);
558
559 ATH_MSG_DEBUG("test CSC projection:detElToLayer:" << parm->position() << "," << projPar->position());
560 }
561
562 if (hitType == 4) {
563 const Trk::PlaneSurface* laySurf = dynamic_cast<const Trk::PlaneSurface*>(&(lay->surfaceRepresentation()));
564 if (!laySurf) { return projPar; }
565
566 AmgMatrix(5, 5)* pMx = nullptr;
567 if (m_idHelperSvc->tgcIdHelper().isStrip(id))
568 pMx = m_tgcProjPhi.get();
569 else
570 pMx = m_tgcProjEta.get();
571 AmgMatrix(5, 5) pMxInv = pMx->inverse();
572 Amg::VectorX locPar = pMxInv * parm->parameters();
573 ATH_MSG_DEBUG("back projected parameters(TGC->layer):" << m_idHelperSvc->tgcIdHelper().isStrip(id) << "," << locPar);
574
575 std::optional<AmgMatrix(5, 5)> projEM = parm->covariance()->similarity(pMxInv);
576
577 ATH_MSG_DEBUG("back projected covariance(TGC->layer):" << (*projEM));
578 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *laySurf, projEM);
579
580 // verify
581 if (m_alignedMode && (parm->position() - projPar->position()).mag() > 0.001) {
582 ATH_MSG_DEBUG("geometrical TGC projection ( detEl2Layer ):"
583 << m_idHelperSvc->tgcIdHelper().stationName(id) << "," << m_idHelperSvc->tgcIdHelper().stationEta(id) << ","
584 << m_idHelperSvc->tgcIdHelper().stationPhi(id) << "," << m_idHelperSvc->tgcIdHelper().isStrip(id));
585 Amg::Vector2D locPos;
586 const Amg::Vector3D& globPos = parm->position();
587 bool onSurface = laySurf->globalToLocal(globPos, globPos, locPos);
588 if (onSurface) {
589 locPar[0] = locPos[0];
590 locPar[1] = locPos[1];
591 delete projPar;
592 projPar = nullptr;
593 projPar = new Trk::AtaPlane(locPar[0], locPar[1], locPar[2], locPar[3], locPar[4], *laySurf, projEM);
594 } else {
595 delete projPar;
596 return nullptr;
597 }
598 }
599 }
600 return projPar;
601}
602
604 const Trk::RIO_OnTrack* rio) const {
605 const MuonGM::MuonDetectorManager* MuonDetMgr = m_muonDetMgr;
606 if (!m_useDSManager) {
608 MuonDetMgr = DetectorManagerHandle.cptr();
609 if (MuonDetMgr == nullptr) {
610 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
611 // return StatusCode::FAILURE;
612 }
613 }
614 // Get the messaging service, print where you are
615 ATH_MSG_DEBUG("MuonTGMeasurementTool::measToLayer");
616 const Trk::RIO_OnTrack* projRIO = nullptr;
617
618 // check input
619 if (!lay || !parm || !rio) return projRIO;
620
621 // check compatibility of layer info and required id ? this was already done when associating !
622 Identifier id = rio->identify();
623
624 ATH_MSG_DEBUG("MuonTGMeasurementTool::input ok");
625
626 unsigned int hitType = 0;
627 if (m_idHelperSvc->isMdt(id)) hitType = 1;
628 if (m_idHelperSvc->isRpc(id)) hitType = 2;
629 if (m_idHelperSvc->isCsc(id)) hitType = 3;
630 if (m_idHelperSvc->isTgc(id)) hitType = 4;
631
632 if (hitType == 1) {
633 // local position of the tube
634 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
635 Amg::Vector2D locWire(0., lay->getRef() + (tube - 1) * 30.035);
636 if (fabs(lay->getRef()) > 10e6) {
637 double sign = (lay->getRef() > 0) ? 1. : -1.;
638 int dec = int(lay->getRef() / 1.e5);
639 double ref0 = dec / 1.e5;
640 double ref1 = lay->getRef() - dec * 1e5 - 0.5 * (sign + 1) * 1e5;
641 locWire[0] = ref0;
642 locWire[1] = ref1;
643 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
644 int tubeMax = m_idHelperSvc->mdtIdHelper().tubeMax(id);
645 if (tube > 6 && tubeMax - tube > 5) locWire[0] = 0.;
646 }
647 // direction at the layer
648 Amg::Vector3D dir = parm->momentum().unit();
649 Amg::Vector3D locDir = (lay->surfaceRepresentation().transform().inverse()) * dir;
651 Amg::Vector3D wireDir(1., 0., 0.);
652 //
653 double ND = dir.dot(normal);
654 double DL = locDir.dot(wireDir);
655 double A = sqrt(1. - DL * DL);
656 double A_ND = A / ND;
657 //
658 double locLay = A_ND * rio->localParameters()[Trk::locR] + locWire[1];
659 // create (fake!) rio ( rio image on TG layer )
660 IdentifierHash idHash(0);
661 const MuonGM::MdtReadoutElement* mdtROE = MuonDetMgr->getMdtReadoutElement(id);
662 auto cov = Amg::MatrixX();
663 cov = A_ND * A_ND * rio->localCovariance();
665 const Muon::MdtPrepData* mdtPrd =
666 new Muon::MdtPrepData(id,
667 Amg::Vector2D(locLay, 0.),
668 cov,
669 mdtROE,
670 0,
671 0,
672 status);
675 Muon::MuonDriftCircleErrorStrategy strat(stratbits);
676 const Muon::MdtDriftCircleOnTrack* mdtRio =
678 Amg::MatrixX(mdtPrd->localCovariance()), 0., Trk::DECIDED, 0.0, strat);
679 return mdtRio;
680 }
681
682 else if (hitType == 2) {
683 //
684 double eta = (m_idHelperSvc->rpcIdHelper().stationEta(id) < 0) ? -1. : 1.;
685 double sign = (m_idHelperSvc->rpcIdHelper().measuresPhi(id) && m_idHelperSvc->rpcIdHelper().doubletPhi(id) == 2) ? -1. : 1.;
686
687 double locPos = rio->localParameters()[Trk::locX];
688
689 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id)) locPos *= eta;
690
691 double ref = (lay->getRef() > 10000.) ? lay->getRef() - 20000. : lay->getRef();
692 double zswap = (lay->getRef() > 10000.) ? -1. : 1.;
693
694 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
695 locPos += sign * ref;
696 else
697 locPos *= zswap;
698 //
699 const MuonGM::RpcReadoutElement* rpcROE = MuonDetMgr->getRpcReadoutElement(id);
700 const IdentifierHash idHash(0);
701 std::vector<Identifier> rdoList;
702 rdoList.push_back(id);
703 const Muon::RpcPrepData* rpcPrd = new Muon::RpcPrepData(id, idHash, Amg::Vector2D(locPos, 0.), rdoList,
704 Amg::MatrixX(rio->localCovariance()), rpcROE, float(0.), 0, 0);
705 const Muon::RpcClusterOnTrack* rpcRio = nullptr;
706 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
709 else
712 return rpcRio;
713 }
714
715 else if (hitType == 3) {
716 // dealing with parallel displaced planes
717 double diff = m_idHelperSvc->cscIdHelper().measuresPhi(id) ? 1.55 : -1.55;
718 //
719 Amg::Vector3D layNormal = lay->surfaceRepresentation().normal();
720 double DN = parm->momentum().dot(layNormal);
721 double t = diff / DN;
722 // displacement of planes
723 const Amg::Vector2D csc_shift(0., lay->getRef());
724 Amg::Vector3D corrLocPos = lay->surfaceRepresentation().center() - t * parm->momentum() + t * DN * layNormal;
725 Amg::Vector2D locCorrLay;
726 bool onSurface = lay->surfaceRepresentation().globalToLocal(corrLocPos, corrLocPos, locCorrLay);
727 //
728 // if( !locCorrLay.size()==2) { ??
729 if (!onSurface) { return projRIO; }
730 double locPos;
731 if (m_idHelperSvc->cscIdHelper().measuresPhi(id)) {
732 locPos = rio->localParameters()[Trk::locX] + locCorrLay[Trk::locX] + csc_shift[Trk::locX];
733 } else {
734 locPos = rio->localParameters()[Trk::locX] + locCorrLay[Trk::locY] + csc_shift[Trk::locY];
735 }
736 //
737 const MuonGM::CscReadoutElement* cscROE = MuonDetMgr->getCscReadoutElement(id);
738 IdentifierHash idHash(0);
739 std::vector<Identifier> rdoList;
740 rdoList.push_back(id);
742 const Muon::CscPrepData* cscPrd =
743 new Muon::CscPrepData(id,
744 idHash,
745 Amg::Vector2D(locPos, 0.),
746 rdoList,
748 cscROE,
749 0,
750 0.,
751 status);
752 const Muon::CscClusterOnTrack* cscRio = nullptr;
753 if (m_idHelperSvc->cscIdHelper().measuresPhi(id))
755 Amg::MatrixX(cscPrd->localCovariance()), parm->localPosition()[Trk::locY], cscPrd->status());
756 else
758 Amg::MatrixX(cscPrd->localCovariance()), parm->localPosition()[Trk::locX], cscPrd->status());
759 return cscRio;
760 }
761
762 else if (hitType == 4) {
763 //
764 double locPos = rio->localParameters()[Trk::locX];
765 //
766 const MuonGM::TgcReadoutElement* tgcROE = MuonDetMgr->getTgcReadoutElement(id);
767 IdentifierHash idHash(0);
768 std::vector<Identifier> rdoList;
769 rdoList.push_back(id);
770 const Muon::TgcPrepData* tgcPrd =
771 new Muon::TgcPrepData(id,
772 idHash,
773 Amg::Vector2D(locPos, 0.),
774 rdoList,
776 tgcROE);
777 const Muon::TgcClusterOnTrack* tgcRio = nullptr;
778 if (m_idHelperSvc->tgcIdHelper().isStrip(id)) {
779 Amg::Vector2D loc(locPos, parm->localPosition()[Trk::locY]);
782 } else {
785 }
786 return tgcRio;
787 }
788
789 ATH_MSG_DEBUG("unknown hit technology");
790 return projRIO;
791}
792
794 double& pitch) const {
795 const MuonGM::MuonDetectorManager* MuonDetMgr = m_muonDetMgr;
796 if (!m_useDSManager) {
798 MuonDetMgr = DetectorManagerHandle.cptr();
799 if (MuonDetMgr == nullptr) { ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object"); }
800 }
801 // Get the messaging service, print where you are
802 ATH_MSG_DEBUG("MuonTGMeasurementTool::nearestDetEl");
803 Identifier nid(0);
804 // check input
805 if (!lay || !parm || !lay->layerType()) return nid;
806
807 // check compatibility of layer info and required id ? this was already done when associating !
808 Identifier layId(lay->layerType());
809
810 unsigned int hitType = 0;
811 if (m_idHelperSvc->isMdt(layId)) hitType = 1;
812 if (m_idHelperSvc->isRpc(layId)) hitType = 2;
813 if (m_idHelperSvc->isCsc(layId)) hitType = 3;
814 if (m_idHelperSvc->isTgc(layId)) hitType = 4;
815
816 if (hitType == 0) {
817 ATH_MSG_DEBUG("unknown hit technology");
818 return nid;
819 }
820
821 if (hitType == 1) {
822 const MuonGM::MdtReadoutElement* mdtROE = MuonDetMgr->getMdtReadoutElement(layId);
823 if (!mdtROE) return nid;
824 int tMax = mdtROE->getNtubesperlayer();
825 // local position at layer
826 Amg::Vector2D locLay;
827 const Amg::Vector3D& globPos = parm->position();
828 bool onSurface = lay->surfaceRepresentation().globalToLocal(globPos, globPos, locLay);
829 if (!onSurface || measPhi) { return nid; }
830 // nearest tube index
831 double refL = lay->getRef();
832 if (fabs(refL) > 10e6) {
833 double sign = (lay->getRef() > 0) ? 1. : -1.;
834 int dec = int(lay->getRef() / 1.e5);
835 refL = lay->getRef() - dec * 1e5 - 0.5 * (sign + 1) * 1e5;
836 }
837 double dloc = locLay[Trk::locY] - refL + 15.0175;
838 int itube = int(dloc / 30.035) + 1;
839 if (itube < 1 || itube > tMax || dloc < 0.) { return nid; }
840 // tube id
841 Identifier nearId = m_idHelperSvc->mdtIdHelper().channelID(
842 m_idHelperSvc->mdtIdHelper().stationName(layId), m_idHelperSvc->mdtIdHelper().stationEta(layId),
843 m_idHelperSvc->mdtIdHelper().stationPhi(layId), m_idHelperSvc->mdtIdHelper().multilayer(layId),
844 m_idHelperSvc->mdtIdHelper().tubeLayer(layId), itube);
845 // check if position within active volume
846 if (fabs(locLay[Trk::locX]) > 0.5 * mdtROE->getActiveTubeLength(m_idHelperSvc->mdtIdHelper().tubeLayer(layId), itube)) {
847 return nid;
848 }
849 //
850 if (m_idHelperSvc->mdtIdHelper().valid(nearId))
851 return nearId;
852 else
853 return nid;
854 }
855
856 if (hitType == 2) {
857 // identify phi doublet first
858 Identifier phiId(0);
859 // both phi and eta needs to be within bounds !!!
860 int doubletPhi = 1;
861 bool foundDoubletPhi = false;
862 const MuonGM::RpcReadoutElement* rpcROE = nullptr;
863 while (!foundDoubletPhi && doubletPhi < 3) {
864 Identifier refPhi1 = m_idHelperSvc->rpcIdHelper().channelID(
865 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
866 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId),
867 m_idHelperSvc->rpcIdHelper().doubletZ(layId), doubletPhi, m_idHelperSvc->rpcIdHelper().gasGap(layId), 1, 1);
868 rpcROE = MuonDetMgr->getRpcReadoutElement(refPhi1);
869 if (!rpcROE) return nid;
870 if (!m_idHelperSvc->rpcIdHelper().valid(refPhi1)) return nid;
871 int nStripPhi = rpcROE->Nstrips(1);
872
873 Identifier refPhiN = m_idHelperSvc->rpcIdHelper().channelID(
874 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
875 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId),
876 m_idHelperSvc->rpcIdHelper().doubletZ(layId), doubletPhi, m_idHelperSvc->rpcIdHelper().gasGap(layId), 1, nStripPhi);
877 //
878 Amg::Vector2D loc1;
879 const Amg::Vector3D globPos1 = rpcROE->stripPos(refPhi1);
880 bool onSurface1 = rpcROE->surface(refPhi1).globalToLocal(globPos1, globPos1, loc1);
881 Amg::Vector2D locN;
882 const Amg::Vector3D globPosN = rpcROE->stripPos(refPhiN);
883 bool onSurfaceN = rpcROE->surface(refPhiN).globalToLocal(globPosN, globPosN, locN);
884 Amg::Vector2D loc;
885 const Amg::Vector3D& glob = parm->position();
886 bool onSurface = rpcROE->surface(refPhiN).globalToLocal(glob, glob, loc);
887
888 int strip = 0;
889 if (onSurface1 && onSurfaceN && onSurface) {
890 pitch = (locN[Trk::locX] - loc1[Trk::locX]) / fmax(1, nStripPhi - 1);
891 double dstrip = (loc[Trk::locX] - loc1[Trk::locX]) / pitch + 0.5;
892 strip = dstrip >= 0. ? int(dstrip) + 1 : 0;
893
894 if (strip > 0 && strip <= nStripPhi) {
895 // correct doublet
896 phiId = m_idHelperSvc->rpcIdHelper().channelID(
897 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
898 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId),
899 m_idHelperSvc->rpcIdHelper().doubletZ(layId), doubletPhi, m_idHelperSvc->rpcIdHelper().gasGap(layId), 1, strip);
900 foundDoubletPhi = true;
901
902 } else {
903 doubletPhi += 1;
904 }
905 } else
906 doubletPhi += 1;
907 }
908 // no valid phi strip - skip search
909 if (!foundDoubletPhi) return nid;
910
911 // eta strip
912 Identifier etaId(0);
913 int doubletZ = 1;
914 while (doubletZ < 4) {
915 Identifier refEta1 = m_idHelperSvc->rpcIdHelper().channelID(
916 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
917 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId), doubletZ, doubletPhi,
918 m_idHelperSvc->rpcIdHelper().gasGap(layId), 0, 1);
919 rpcROE = MuonDetMgr->getRpcReadoutElement(refEta1);
920 if (!rpcROE) return nid;
921 if (!m_idHelperSvc->rpcIdHelper().valid(refEta1)) return nid;
922 int nStrips = rpcROE->Nstrips(0);
923
924 Identifier refEtaN = m_idHelperSvc->rpcIdHelper().channelID(
925 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
926 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId), doubletZ, doubletPhi,
927 m_idHelperSvc->rpcIdHelper().gasGap(layId), 0, nStrips);
928 //
929
930 Amg::Vector2D loc1;
931 const Amg::Vector3D globPos1 = rpcROE->stripPos(refEta1);
932 bool onSurface1 = rpcROE->surface(refEta1).globalToLocal(globPos1, globPos1, loc1);
933 Amg::Vector2D locN;
934 const Amg::Vector3D globPosN = rpcROE->stripPos(refEtaN);
935 bool onSurfaceN = rpcROE->surface(refEtaN).globalToLocal(globPosN, globPosN, locN);
936 Amg::Vector2D loc;
937 const Amg::Vector3D& glob = parm->position();
938 bool onSurface = rpcROE->surface(refEtaN).globalToLocal(glob, glob, loc);
939
940 int strip = 0;
941 if (onSurface && onSurface1 && onSurfaceN) {
942 pitch = (locN[Trk::locX] - loc1[Trk::locX]) / fmax(1, nStrips - 1);
943 // strip = int( (refPar->localPosition()[Trk::locX]-loc1[Trk::locX])/pitch+0.5 )+1;
944 double dstrip = (loc[Trk::locX] - loc1[Trk::locX]) / pitch + 0.5;
945 strip = dstrip >= 0. ? int(dstrip) + 1 : 0;
946
947 if (strip > 0 && strip <= nStrips) {
948 etaId = m_idHelperSvc->rpcIdHelper().channelID(
949 m_idHelperSvc->rpcIdHelper().stationName(layId), m_idHelperSvc->rpcIdHelper().stationEta(layId),
950 m_idHelperSvc->rpcIdHelper().stationPhi(layId), m_idHelperSvc->rpcIdHelper().doubletR(layId), doubletZ, doubletPhi,
951 m_idHelperSvc->rpcIdHelper().gasGap(layId), 0, strip);
952 if (measPhi)
953 return phiId;
954 else
955 return etaId;
956 }
957 }
958 doubletZ += 1;
959 }
960
961 return nid;
962 }
963
964 if (hitType == 3) {
965 // ref id
966 Identifier refId = m_idHelperSvc->cscIdHelper().channelID(
967 m_idHelperSvc->cscIdHelper().stationName(layId), m_idHelperSvc->cscIdHelper().stationEta(layId),
968 m_idHelperSvc->cscIdHelper().stationPhi(layId), m_idHelperSvc->cscIdHelper().chamberLayer(layId),
969 m_idHelperSvc->cscIdHelper().wireLayer(layId), measPhi, 1);
970 if (!m_idHelperSvc->cscIdHelper().valid(refId)) return nid;
971 // residual in ref frame
972 const Trk::TrackParameters* refPar = layerToDetEl(lay, parm, refId);
973 if (!refPar) return nid;
974 //
975 const MuonGM::CscReadoutElement* cscROE = MuonDetMgr->getCscReadoutElement(refId);
976 if (!cscROE) {
977 delete refPar;
978 return nid;
979 }
980 pitch = cscROE->StripPitch(measPhi);
981 int nStrips = m_idHelperSvc->cscIdHelper().stripMax(refId);
982 if (nStrips < 1) {
983 delete refPar;
984 return nid;
985 }
986
987 Identifier refIdN = m_idHelperSvc->cscIdHelper().channelID(
988 m_idHelperSvc->cscIdHelper().stationName(refId), m_idHelperSvc->cscIdHelper().stationEta(refId),
989 m_idHelperSvc->cscIdHelper().stationPhi(refId), m_idHelperSvc->cscIdHelper().chamberLayer(refId),
990 m_idHelperSvc->cscIdHelper().wireLayer(refId), measPhi, nStrips);
991 //
992 Amg::Vector3D loc1 = cscROE->surface(refId).transform().inverse() * cscROE->stripPos(refId);
993 Amg::Vector3D locN = cscROE->surface(refIdN).transform().inverse() * cscROE->stripPos(refIdN);
994 int strip = 0;
995
996 pitch = (locN[0] - loc1[0]) / fmax(1, nStrips - 1);
997 strip = int((refPar->localPosition()[Trk::locX] - loc1[0]) / pitch + 0.5) + 1;
998
999 delete refPar;
1000 refPar = nullptr;
1001 if (strip > 0 && strip <= nStrips) {
1002 // strip id
1003 Identifier nearId = m_idHelperSvc->cscIdHelper().channelID(
1004 m_idHelperSvc->cscIdHelper().stationName(layId), m_idHelperSvc->cscIdHelper().stationEta(layId),
1005 m_idHelperSvc->cscIdHelper().stationPhi(layId), m_idHelperSvc->cscIdHelper().chamberLayer(layId),
1006 m_idHelperSvc->cscIdHelper().wireLayer(layId), measPhi, strip);
1007 if (fabs(residual(parm, nearId)) > 0.5 * pitch)
1008 ATH_MSG_DEBUG("nearest CSC channel residual too large: " << residual(parm, nearId));
1009 return nearId;
1010 }
1011 }
1012
1013 if (hitType == 4) { // ref id
1014 if (measPhi && m_idHelperSvc->tgcIdHelper().gasGap(layId) == 2 && m_idHelperSvc->tgcIdHelper().gasGapMax(layId) == 3)
1015 return nid; // no phi strips here
1016 // ref id
1017 Identifier refId = layId;
1018 if (measPhi)
1019 refId = m_idHelperSvc->tgcIdHelper().channelID(
1020 m_idHelperSvc->tgcIdHelper().stationName(layId), m_idHelperSvc->tgcIdHelper().stationEta(layId),
1021 m_idHelperSvc->tgcIdHelper().stationPhi(layId), m_idHelperSvc->tgcIdHelper().gasGap(layId), measPhi, 1);
1022 if (!m_idHelperSvc->tgcIdHelper().valid(refId)) return nid;
1023 // residual in ref frame
1024 const Trk::TrackParameters* refPar = layerToDetEl(lay, parm, refId);
1025 if (!refPar) return nid;
1026 //
1027 const MuonGM::TgcReadoutElement* tgcROE = MuonDetMgr->getTgcReadoutElement(layId);
1028 if (!tgcROE) {
1029 delete refPar;
1030 return nid;
1031 }
1032 int nStrips = m_idHelperSvc->tgcIdHelper().channelMax(refId);
1033
1034 if (nStrips < 1) {
1035 delete refPar;
1036 return nid;
1037 }
1038
1039 Identifier refIdN = m_idHelperSvc->tgcIdHelper().channelID(
1040 m_idHelperSvc->tgcIdHelper().stationName(layId), m_idHelperSvc->tgcIdHelper().stationEta(layId),
1041 m_idHelperSvc->tgcIdHelper().stationPhi(layId), m_idHelperSvc->tgcIdHelper().gasGap(layId), measPhi, nStrips);
1042 //
1043 Amg::Vector2D loc1;
1044 const Amg::Vector3D glob1 = tgcROE->channelPos(refId);
1045 bool onSurface1 = tgcROE->surface(refId).globalToLocal(glob1, glob1, loc1);
1046 Amg::Vector2D locN;
1047 const Amg::Vector3D globN = tgcROE->channelPos(refIdN);
1048 bool onSurfaceN = tgcROE->surface(refIdN).globalToLocal(globN, globN, locN);
1049
1050 int strip = 0;
1051 if (onSurface1 && onSurfaceN) {
1052 pitch = (locN[Trk::locX] - loc1[Trk::locX]) / fmax(1, nStrips - 1);
1053 strip = int((refPar->localPosition()[Trk::locX] - loc1[Trk::locX]) / pitch + 0.5) + 1;
1054 } else {
1055 ATH_MSG_DEBUG("local position of boundary elements not retrieved, return 0 ");
1056 delete refPar;
1057 return nid;
1058 }
1059
1060 if (strip > 0 && strip <= nStrips) {
1061 // check second coordinate for active volume
1062 if (!measPhi && fabs(refPar->localPosition()[Trk::locY]) >
1063 tgcROE->gangCentralWidth(m_idHelperSvc->tgcIdHelper().gasGap(layId), strip)) {
1064 delete refPar;
1065 return nid;
1066 }
1067 Identifier nearId = m_idHelperSvc->tgcIdHelper().channelID(
1068 m_idHelperSvc->tgcIdHelper().stationName(layId), m_idHelperSvc->tgcIdHelper().stationEta(layId),
1069 m_idHelperSvc->tgcIdHelper().stationPhi(layId), m_idHelperSvc->tgcIdHelper().gasGap(layId), measPhi, strip);
1070 Amg::Vector3D stripposition = tgcROE->surface(nearId).transform().inverse() * tgcROE->channelPos(nearId);
1071 Amg::Vector3D localhit = tgcROE->surface(nearId).transform().inverse() * parm->position();
1072
1073 int plane = m_idHelperSvc->tgcIdHelper().gasGap(nearId);
1074 if (m_idHelperSvc->tgcIdHelper().isStrip(nearId))
1075 pitch = tgcROE->stripPitch(plane, m_idHelperSvc->tgcIdHelper().channel(nearId), localhit[1]);
1076 int last = 0;
1077 while (fabs(stripposition[0] - localhit[0]) > 0.5 * pitch) {
1078 if (stripposition[0] < localhit[0]) {
1079 if (last != -1) {
1080 strip += 1;
1081 last = 1;
1082 } else
1083 break;
1084 } else {
1085 if (last != 1) {
1086 strip -= 1;
1087 last = -1;
1088 } else
1089 break;
1090 }
1091 if (strip < 1 || strip > nStrips) break;
1092 nearId = m_idHelperSvc->tgcIdHelper().channelID(
1093 m_idHelperSvc->tgcIdHelper().stationName(layId), m_idHelperSvc->tgcIdHelper().stationEta(layId),
1094 m_idHelperSvc->tgcIdHelper().stationPhi(layId), m_idHelperSvc->tgcIdHelper().gasGap(layId), measPhi, strip);
1095 stripposition = tgcROE->surface(nearId).transform().inverse() * tgcROE->channelPos(nearId);
1096 localhit = tgcROE->surface(nearId).transform().inverse() * parm->position();
1097 if (m_idHelperSvc->tgcIdHelper().isStrip(nearId))
1098 pitch = tgcROE->stripPitch(plane, m_idHelperSvc->tgcIdHelper().channel(nearId), localhit[1]);
1099 }
1100 delete refPar;
1101 if (strip < 1 || strip > nStrips) return nid;
1102 if (m_idHelperSvc->tgcIdHelper().valid(nearId))
1103 return nearId;
1104 else
1105 return nid;
1106 }
1107 delete refPar;
1108 }
1109 return nid;
1110}
1111
1113 // Get the messaging service, print where you are
1114 ATH_MSG_DEBUG("MuonTGMeasurementTool::associatedLayer");
1115 const Trk::Layer* lay = nullptr;
1116 // check input
1117 if (!id.get_identifier32().get_compact()) return lay;
1118
1119 // rely on having misalignment uncertainty covered by span safety marge ( don't loose station from static volume
1120 // when misaligned
1121 const Trk::TrackingVolume* staticVol = getGeometry()->lowestStaticTrackingVolume(gp);
1122 const Trk::DetachedTrackingVolume* station = nullptr;
1123 if (staticVol && !staticVol->confinedDetachedVolumes().empty()) {
1125 for (const auto *i : detTV) {
1126 if (i->layerRepresentation() && i->layerRepresentation()->layerType() > 0) {
1127 Identifier stId(i->layerRepresentation()->layerType());
1128 if (m_idHelperSvc->mdtIdHelper().stationName(stId) == m_idHelperSvc->mdtIdHelper().stationName(id) &&
1129 m_idHelperSvc->mdtIdHelper().stationEta(stId) == m_idHelperSvc->mdtIdHelper().stationEta(id) &&
1130 m_idHelperSvc->mdtIdHelper().stationPhi(stId) == m_idHelperSvc->mdtIdHelper().stationPhi(id)) {
1131 station = i;
1132 break;
1133 }
1134 }
1135 }
1136 }
1137
1138 if (station) lay = associatedLayer(id, station->trackingVolume());
1139
1140 return lay;
1141}
1142
1144 const Trk::Layer* lay = nullptr;
1145 // check input
1146 if (!vol) return lay;
1147
1148 if (vol->confinedVolumes()) {
1149 std::span<Trk::TrackingVolume const * const > subVols = vol->confinedVolumes()->arrayObjects();
1150 std::span<Trk::TrackingVolume const * const >::iterator iter = subVols.begin();
1151 while (!lay && iter != subVols.end()) {
1152 lay = associatedLayer(id, *iter);
1153 if (lay) break;
1154 ++iter;
1155 }
1156 if (lay) return lay;
1157 }
1158
1159 if (vol->confinedLayers()) {
1160 std::span<Trk::Layer const * const > ordLay = vol->confinedLayers()->arrayObjects();
1161 std::span<Trk::Layer const * const >::iterator iter = ordLay.begin();
1162 while (!lay && iter != ordLay.end()) {
1163 lay = match(id, *iter);
1164 if (lay) break;
1165 ++iter;
1166 }
1167 if (lay) return lay;
1168 }
1169
1170 if (!vol->confinedArbitraryLayers().empty()) {
1172 Trk::ArraySpan<const Trk::Layer* const>::iterator iter = unOrdLay.begin();
1173 while (!lay && iter != unOrdLay.end()) {
1174 lay = match(id, *iter);
1175 if (lay) break;
1176 ++iter;
1177 }
1178 if (lay) return lay;
1179 }
1180
1181 return lay;
1182}
1183
1185 const Trk::Layer* mLay = nullptr;
1186 if (!id.get_identifier32().get_compact() || !lay || !lay->layerType()) return mLay;
1187
1188 Identifier layId(lay->layerType());
1189
1190 if (m_idHelperSvc->isMdt(id) && m_idHelperSvc->isMdt(layId)) {
1191 if (m_idHelperSvc->mdtIdHelper().multilayer(layId) == m_idHelperSvc->mdtIdHelper().multilayer(id) &&
1192 m_idHelperSvc->mdtIdHelper().tubeLayer(layId) == m_idHelperSvc->mdtIdHelper().tubeLayer(id))
1193 return lay;
1194 }
1195
1196 if (m_idHelperSvc->isRpc(id) && m_idHelperSvc->isRpc(layId)) {
1197 if (m_idHelperSvc->rpcIdHelper().doubletR(layId) == m_idHelperSvc->rpcIdHelper().doubletR(id) &&
1198 m_idHelperSvc->rpcIdHelper().doubletZ(layId) == m_idHelperSvc->rpcIdHelper().doubletZ(id) &&
1199 m_idHelperSvc->rpcIdHelper().gasGap(layId) == m_idHelperSvc->rpcIdHelper().gasGap(id))
1200 return lay;
1201 }
1202
1203 if (m_idHelperSvc->isTgc(id) && m_idHelperSvc->isTgc(layId)) {
1204 if (m_idHelperSvc->tgcIdHelper().gasGap(layId) == m_idHelperSvc->tgcIdHelper().gasGap(id)) return lay;
1205 }
1206
1207 if (m_idHelperSvc->isCsc(id) && m_idHelperSvc->isCsc(layId)) {
1208 if (m_idHelperSvc->cscIdHelper().chamberLayer(layId) == m_idHelperSvc->cscIdHelper().chamberLayer(id) &&
1209 m_idHelperSvc->cscIdHelper().wireLayer(layId) == m_idHelperSvc->cscIdHelper().wireLayer(id))
1210 return lay;
1211 }
1212
1213 return mLay;
1214}
1215
1217 double res = 10000.;
1218 if (!layPar || !rio) return res;
1219
1220 Amg::Vector3D gp = layPar->position();
1221 const Trk::Layer* layer = associatedLayer(rio->identify(), gp);
1222 if (!layer) return res;
1223
1224 return residual(layer, layPar, rio);
1225}
1226
1228 double res = 10000.;
1229 if (!layPar || !id.get_identifier32().get_compact()) return res;
1230
1231 Amg::Vector3D gp = layPar->position();
1232 const Trk::Layer* layer = associatedLayer(id, gp);
1233 if (!layer) return res;
1234
1235 return residual(layer, layPar, id);
1236}
1237
1239 const Trk::RIO_OnTrack* rio) const {
1240 double res = 10000.;
1241 if (!layer || !layPar || !rio) return res;
1242
1243 const Trk::TrackParameters* detElPar = layerToDetEl(layer, layPar, rio->identify());
1244 if (!detElPar) return res;
1245 if (m_idHelperSvc->isMdt(rio->identify())) {
1246 res = fabs(detElPar->localPosition()[Trk::locR] - rio->localParameters()[Trk::locR]);
1247 } else {
1248 res = fabs(detElPar->localPosition()[Trk::locX] - rio->localParameters()[Trk::locX]);
1249 }
1250 delete detElPar;
1251 return res;
1252}
1253
1255 const MuonGM::MuonDetectorManager* MuonDetMgr = m_muonDetMgr;
1256 if (!m_useDSManager) {
1258 MuonDetMgr = DetectorManagerHandle.cptr();
1259 if (MuonDetMgr == nullptr) {
1260 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
1261 // return StatusCode::FAILURE;
1262 }
1263 }
1264
1265 double res = 10000.;
1266 if (!layer || !layPar || !id.get_identifier32().get_compact()) return res;
1267
1268 const Trk::TrackParameters* detElPar = layerToDetEl(layer, layPar, id);
1269 if (!detElPar) return res;
1270 if (m_idHelperSvc->isMdt(id)) {
1271 res = detElPar->localPosition()[Trk::locR];
1272 } else if (m_idHelperSvc->isRpc(id)) {
1273 const MuonGM::RpcReadoutElement* rpcROE = MuonDetMgr->getRpcReadoutElement(id);
1274 if (rpcROE)
1275 res = detElPar->localPosition()[Trk::locX] -
1276 (detElPar->associatedSurface().transform().inverse() * (rpcROE->stripPos(id)))[Trk::locX];
1277 } else if (m_idHelperSvc->isCsc(id)) {
1278 const MuonGM::CscReadoutElement* cscROE = MuonDetMgr->getCscReadoutElement(id);
1279 if (cscROE)
1280 res = detElPar->localPosition()[Trk::locX] - (detElPar->associatedSurface().transform().inverse() * (cscROE->stripPos(id)))[0];
1281 } else if (m_idHelperSvc->isTgc(id)) {
1282 if (m_idHelperSvc->tgcIdHelper().isStrip(id) && m_idHelperSvc->tgcIdHelper().gasGap(id) == 2 &&
1283 m_idHelperSvc->tgcIdHelper().gasGapMax(id) == 3) {
1284 delete detElPar;
1285 return res; // no phi strips here
1286 }
1287 const MuonGM::TgcReadoutElement* tgcROE = MuonDetMgr->getTgcReadoutElement(id);
1288 if (tgcROE) {
1289 Amg::Vector2D locPos;
1290 const Amg::Vector3D globPos = tgcROE->channelPos(id);
1291 bool onSurface = detElPar->associatedSurface().globalToLocal(globPos, globPos, locPos);
1292 if (onSurface) res = detElPar->localPosition()[Trk::locX] - locPos[Trk::locX];
1293 }
1294 }
1295 delete detElPar;
1296 return res;
1297}
const boost::regex ref(r_ef)
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgMatrix(rows, cols)
std::pair< std::vector< unsigned int >, bool > res
double tubeMax
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
int sign(int a)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
This is a "hash" representation of an Identifier.
double StripPitch(int chlayer, int measphi) const
Amg::Vector3D stripPos(const Identifier &id) const
takes into account internal alignment parameters, hence gives accurate answer
double getActiveTubeLength(const int tubeLayer, const int tube) const
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const RpcReadoutElement * getRpcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const CscReadoutElement * getCscReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
int Nstrips(bool measphi) const
returns the number of strips for the phi or eta plane
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Amg::Vector3D channelPos(const Identifier &id) const
Returns the position of the active channel (wireGang or strip)
double stripPitch(int gasGap, int strip) const
Returns the pitch of the given strip in gasGap i.
double gangCentralWidth(int gasGap, int gang) const
Returns the length of the central wire in the gang.
Class to represent the calibrated clusters created from CSC strips.
Class representing clusters from the CSC.
Definition CscPrepData.h:39
CscClusterStatus status() const
Returns the Csc status (position measurement) flag.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
Gaudi::Property< bool > m_useDSManager
std::unique_ptr< AmgMatrix(5, 5)> m_rpcProjEta
const Trk::TrackParameters * layerToDetEl(const Trk::Layer *, const Trk::TrackParameters *, Identifier) const override
const Trk::RIO_OnTrack * measToLayer(const Trk::Layer *, const Trk::TrackParameters *, const Trk::RIO_OnTrack *) const override
MuonTGMeasurementTool(const std::string &type, const std::string &name, const IInterface *)
Constructor with AlgTool parameters.
SG::ReadCondHandleKey< Trk::TrackingGeometry > m_trackingGeometryReadKey
const Identifier nearestDetEl(const Trk::Layer *, const Trk::TrackParameters *, bool measPhi, double &pitch) const override
const MuonGM::MuonDetectorManager * m_muonDetMgr
virtual StatusCode initialize() override
Gaudi::Property< bool > m_alignedMode
std::unique_ptr< AmgMatrix(5, 5)> m_rpcProjPhi
const Trk::Layer * match(Identifier id, const Trk::Layer *lay) const override
const Trk::TrackingGeometry * getGeometry() const
double residual(const Trk::Layer *, const Trk::TrackParameters *, const Trk::RIO_OnTrack *) const override
ServiceHandle< Trk::ITrackingGeometrySvc > m_trackingGeometrySvc
const Trk::Layer * associatedLayer(Identifier id, Amg::Vector3D &gp) const override
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
std::unique_ptr< AmgMatrix(5, 5)> m_tgcProjPhi
const Trk::TrackParameters * detElToLayer(const Trk::Layer *, const Trk::TrackParameters *, Identifier) const override
std::unique_ptr< AmgMatrix(5, 5)> m_tgcProjEta
Class to represent calibrated clusters formed from RPC strips.
Class to represent RPC measurements.
Definition RpcPrepData.h:35
Class to represent calibrated clusters formed from TGC strips.
Class to represent TGC measurements.
Definition TgcPrepData.h:32
const_pointer_type cptr()
virtual std::span< T *const > arrayObjects()=0
Return all objects of the Array non-const we can still modify the T.
Base Class for a navigation object (active/passive) in the Tracking realm.
const TrackingVolume * trackingVolume() const
returns the TrackingVolume
Base Class for a Detector Layer in the Tracking realm.
Definition Layer.h:72
int layerType() const
get the Layer coding
virtual const Surface & surfaceRepresentation() const =0
Transforms the layer into a Surface representation for extrapolation.
double getRef() const
get the reference measure
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
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.
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...
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
const LayerArray * confinedLayers() const
Return the subLayer array.
const TrackingVolumeArray * confinedVolumes() const
Return the subLayer array.
ArraySpan< DetachedTrackingVolume const *const > confinedDetachedVolumes() const
Return detached subVolumes - not the ownership.
ArraySpan< Layer const *const > confinedArbitraryLayers() const
Return the confined subLayer array.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
MdtDriftCircleStatus
Enum to represent the 'status' of Mdt measurements e.g.
@ MdtStatusDriftTime
The tube produced a vaild measurement.
std::bitset< 23 > MuonDriftCircleErrorStrategyInput
CscClusterStatus
Enum to represent the cluster status - see the specific enum values for more details.
@ CscStatusSimple
Cluster with non-precision fit.
std::span< T > ArraySpan
ParametersT< TrackParametersDim, Charged, StraightLineSurface > AtaStraightLine
@ DECIDED
sign of drift radius has been determined
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ locR
Definition ParamDefs.h:44
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
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
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane
hold the test vectors and ease the comparison