2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5///////////////////////////////////////////////////////////////////
6// CurvilinearParametersT.icc, (c) ATLAS Detector software
7///////////////////////////////////////////////////////////////////
10#include "GaudiKernel/MsgStream.h"
12#include "TrkEventPrimitives/ParamDefs.h"
16// Constructor with TP arguments
17template<int DIM, class T, class S>
18CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
19 const AmgVector(DIM + 2) & parameters,
20 std::optional<AmgSymMatrix(DIM)> covariance,
21 unsigned int cIdentifier)
22 : ParametersBase<DIM, T>(std::move(covariance))
23 , m_cIdentifier(cIdentifier)
25 this->m_position = Amg::Vector3D(parameters[x], parameters[y], parameters[z]);
26 this->m_momentum = Amg::Vector3D(parameters[3], parameters[4], parameters[5]);
28 // flip the charge according to qOverP
29 if (parameters[6] < 0.) {
30 this->m_chargeDef.setCharge(-1);
31 // cppcheck-suppress missingReturn; false positive
33 // assign the parameters
34 this->m_parameters[locX] = 0.;
35 this->m_parameters[locY] = 0.;
36 // get phi & theta from the momentum vector
37 this->m_parameters[phi] = this->momentum().phi();
38 this->m_parameters[theta] = this->momentum().theta();
39 this->m_parameters[qOverP] = parameters[6] / this->momentum().mag();
41 /* we need all the above to be there for the surfac*/
42 this->m_surface = S(this->m_position, curvilinearFrame());
45// Constructor with TP arguments
46template<int DIM, class T, class S>
47CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
48 const Amg::Vector3D& pos,
52 std::optional<AmgSymMatrix(DIM)> cov,
53 unsigned int cIdentifier)
54 : ParametersBase<DIM, T>(std::move(cov))
55 , m_cIdentifier(cIdentifier)
57 this->m_position = pos;
58 // flip the charge according to qOverP
60 this->m_chargeDef.setCharge(-1.);
62 this->m_chargeDef.setCharge(1.);
65 // assign the parameters
66 this->m_parameters[Trk::locX] = 0.;
67 this->m_parameters[Trk::locY] = 0.;
68 this->m_parameters[Trk::phi] = tphi;
69 this->m_parameters[Trk::theta] = ttheta;
70 this->m_parameters[Trk::qOverP] = tqOverP;
72 // make sure that the position & momentum are calculated
73 double p = std::abs(1. / tqOverP);
74 this->m_momentum = Amg::Vector3D(p * std::cos(tphi) * std::sin(ttheta),
75 p * std::sin(tphi) * std::sin(ttheta),
76 p * std::cos(ttheta));
78 /* we need all the above for the surface*/
79 this->m_surface = S(this->m_position, curvilinearFrame());
82// full global constructor
83template<int DIM, class T, class S>
84CurvilinearParametersT<DIM, T, S>::CurvilinearParametersT(
85 const Amg::Vector3D& pos,
86 const Amg::Vector3D& mom,
88 std::optional<AmgSymMatrix(DIM)> cov,
89 unsigned int cIdentifier)
90 : ParametersBase<DIM, T>(std::move(cov))
91 , m_cIdentifier(cIdentifier)
93 this->m_chargeDef.setCharge(charge);
94 // assign the parameters
95 this->m_parameters[Trk::locX] = 0.;
96 this->m_parameters[Trk::locY] = 0.;
97 this->m_parameters[Trk::phi] = mom.phi();
98 this->m_parameters[Trk::theta] = mom.theta();
101 charge = 1.; // such that below is 1./mom.mag()
104 this->m_parameters[Trk::qOverP] = charge / mom.mag();
105 this->m_position = pos;
106 this->m_momentum = mom;
108 // we need all the above to create the surface
109 m_surface = S(this->m_position, curvilinearFrame());
112/** the curvilinear parameters identifier */
113template<int DIM, class T, class S>
115CurvilinearParametersT<DIM, T, S>::cIdentifier() const
117 return m_cIdentifier;
120template<int DIM, class T, class S>
122CurvilinearParametersT<DIM, T, S>::setcIdentifier(unsigned int cIdentifier)
124 m_cIdentifier = cIdentifier;
127/** Test to see if there's a surface there. */
128template<int DIM, class T, class S>
130CurvilinearParametersT<DIM, T, S>::hasSurface() const
135/** Access to the Surface method */
136template<int DIM, class T, class S>
138CurvilinearParametersT<DIM, T, S>::associatedSurface() const
144template<int DIM, class T, class S>
146CurvilinearParametersT<DIM, T, S>::operator==(
147 const ParametersBase<DIM, T>& rhs) const
149 // tolerance for comparing matrices
150 constexpr double tolerance = 1e-8;
152 // make sure we compare objects of same type
153 if (this->type() != rhs.type()){
156 const auto pCasted = static_cast<decltype(this)>(&rhs);
157 // comparison to myself?
158 if (pCasted == this) {
162 // compare identifier
163 if (cIdentifier() != pCasted->cIdentifier()) {
168 CurvilinearUVT local_curvilinearFrame = curvilinearFrame();
169 CurvilinearUVT casted_curvilinearFrame = pCasted->curvilinearFrame();
170 if (!local_curvilinearFrame.curvU().isApprox(casted_curvilinearFrame.curvU(),
174 if (!local_curvilinearFrame.curvV().isApprox(casted_curvilinearFrame.curvV(),
178 if (!local_curvilinearFrame.curvT().isApprox(casted_curvilinearFrame.curvT(),
183 if (associatedSurface() != pCasted->associatedSurface()) {
187 // return compatibility of base class parts
188 return ParametersBase<DIM, T>::operator==(rhs);
192template<int DIM, class T, class S>
193CurvilinearParametersT<DIM, T, S>*
194CurvilinearParametersT<DIM, T, S>::clone() const
196 return new CurvilinearParametersT<DIM, T, S>(*this);
199/** Return the ParametersType enum */
200template<int DIM, class T, class S>
201inline constexpr ParametersType
202CurvilinearParametersT<DIM, T, S>::type() const
204 return Trk::Curvilinear;
207/** Return the Surface Type (check SurfaceType enums)*/
208template<int DIM, class T, class S>
209inline constexpr SurfaceType
210CurvilinearParametersT<DIM, T, S>::surfaceType() const
212 return S::staticType;
215// Surface return (with on demand construction)
216template<int DIM, class T, class S>
218CurvilinearParametersT<DIM, T, S>::measurementFrame() const
220 Amg::RotationMatrix3D mFrame;
222 CurvilinearUVT local_curvilinearFrame = curvilinearFrame();
223 mFrame.col(0) = local_curvilinearFrame.curvU();
224 mFrame.col(1) = local_curvilinearFrame.curvV();
225 mFrame.col(2) = local_curvilinearFrame.curvT();
227 // return the rotation matrix that defines the curvilinear parameters
231template<int DIM, class T, class S>
233CurvilinearParametersT<DIM, T, S>::curvilinearFrame() const
235 CurvilinearUVT curvilinFrame(this->momentum().unit());
236 return curvilinFrame;
240template<int DIM, class T, class S>
242CurvilinearParametersT<DIM, T, S>::dump(MsgStream& out) const
244 out << "CurvilinearParametersT parameters:" << std::endl;
245 ParametersBase<DIM, T>::dump(out);
251template<int DIM, class T, class S>
253CurvilinearParametersT<DIM, T, S>::dump(std::ostream& out) const
255 out << "CurvilinearParametersT parameters:" << std::endl;
256 ParametersBase<DIM, T>::dump(out);
261// private updateParametersHelper
262template<int DIM, class T, class S>
264CurvilinearParametersT<DIM, T, S>::updateParametersHelper(
265 const AmgVector(DIM) & updatedParameters)
267 // valid to use != here, because value is either copied or modified,
268 bool updateMomentum =
269 (updatedParameters[Trk::phi] != this->m_parameters[Trk::phi]) ||
270 (updatedParameters[Trk::theta] != this->m_parameters[Trk::theta]) ||
271 (updatedParameters[Trk::qOverP] != this->m_parameters[Trk::qOverP]);
273 // momentum update is needed
274 if (updateMomentum) {
275 double phi = updatedParameters[Trk::phi];
276 double theta = updatedParameters[Trk::theta];
277 double p = std::abs(1. / updatedParameters[Trk::qOverP]);
278 this->m_chargeDef.setCharge(sgn(updatedParameters[Trk::qOverP]));
279 // assign them and update the momentum 3 vector
280 this->m_parameters[Trk::phi] = phi;
281 this->m_parameters[Trk::theta] = theta;
282 this->m_parameters[Trk::qOverP] = updatedParameters[Trk::qOverP];
283 this->m_momentum = Amg::Vector3D(p * std::cos(phi) * std::sin(theta),
284 p * std::sin(phi) * std::sin(theta),
285 p * std::cos(theta));
288 // position update if needed - loc1
289 if (updatedParameters[Trk::loc1] != 0.) {
291 updatedParameters[Trk::loc1] * curvilinearFrame().curvU();
293 // position update if needed - loc2
294 if (updatedParameters[Trk::loc2] != 0.) {
296 updatedParameters[Trk::loc2] * curvilinearFrame().curvV();
298 // Reset also the surface
299 m_surface = S(this->m_position, curvilinearFrame());
302} // end of namespace Trk