2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 ///////////////////////////////////////////////////////////////////
6 // ParametersT.icc, (c) ATLAS Detector software
7 ///////////////////////////////////////////////////////////////////
10 #include "TrkEventPrimitives/ParamDefs.h"
11 #include "CxxUtils/trapping_fp.h"
12 #include "CxxUtils/inline_hints.h"
20 // Constructor with local arguments - uses global <-> local for parameters
21 template<int DIM, class T, class S>
22 ParametersT<DIM, T, S>::ParametersT(double loc1,
28 std::optional<AmgSymMatrix(DIM)> cov)
29 : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), std::move(cov), sgn(qop))
30 , SurfaceUniqHolderImpl<S>(surface)
32 // Tell clang to optimize assuming that FP exceptions can trap.
33 // Otherwise, it can vectorize the division, which can lead to
34 // spurious division-by-zero traps from unused vector lanes.
36 this->m_position = Amg::Vector3D::Zero();
37 this->m_momentum = Amg::Vector3D::Zero();
39 // check qoverp is physical
42 p = std::abs(1. / qop);
44 // qop is unphysical. No momentum measurement.
45 p = InvalidParam::INVALID_P;
46 qop = InvalidParam::INVALID_QOP;
49 // fill the parameters
50 // cppcheck-suppress constStatement
51 this->m_parameters << loc1, loc2, phi, theta, qop;
53 // now calculate the momentum
54 double sinPhi, cosPhi, cosTheta, sinTheta;
55 sincos(phi, &sinPhi, &cosPhi);
56 sincos(theta, &sinTheta, &cosTheta);
58 Amg::Vector3D(p * cosPhi * sinTheta, p * sinPhi * sinTheta, p * cosTheta);
59 this->m_associatedSurface->localToGlobal(this->localPosition(),
60 this->m_momentum, this->m_position);
63 // Constructor with local arguments - uses global <-> local for parameters
64 template<int DIM, class T, class S>
65 ParametersT<DIM, T, S>::ParametersT(const AmgVector(DIM) & parameters,
67 std::optional<AmgSymMatrix(DIM)> cov)
68 : ParametersBase<DIM, T>(parameters,
70 sgn(parameters[Trk::qOverP]))
71 , SurfaceUniqHolderImpl<S>(surface)
73 this->m_position = Amg::Vector3D::Zero();
74 this->m_momentum = Amg::Vector3D::Zero();
75 // decide the sign of the charge
76 double qop = this->m_parameters[Trk::qOverP];
78 // check qoverp is physical
81 p = std::abs(1. / qop);
83 // qop is unphysical. No momentum measurement.
84 p = InvalidParam::INVALID_P;
85 qop = InvalidParam::INVALID_QOP;
88 // fill momentum & then position using the surface
90 Amg::Vector3D(p * std::cos(this->m_parameters[Trk::phi]) *
91 std::sin(this->m_parameters[Trk::theta]),
92 p * std::sin(this->m_parameters[Trk::phi]) *
93 std::sin(this->m_parameters[Trk::theta]),
94 p * std::cos(this->m_parameters[Trk::theta]));
96 this->m_associatedSurface->localToGlobal(this->localPosition(),
97 this->m_momentum, this->m_position);
100 // Constructor with global arguments - uses global <-> local for parameters */
101 template<int DIM, class T, class S>
102 ParametersT<DIM, T, S>::ParametersT(const Amg::Vector3D& pos,
103 const Amg::Vector3D& mom,
106 std::optional<AmgSymMatrix(DIM)> cov)
107 : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), std::move(cov), charge)
108 , SurfaceUniqHolderImpl<S>(surface)
111 this->m_position = pos;
112 this->m_momentum = mom;
114 // get the local parameters via the surface
115 Amg::Vector2D lPosition;
116 const bool ok = this->m_associatedSurface->globalToLocal(
117 this->position(), this->momentum(), lPosition);
119 lPosition = Amg::Vector2D(InvalidParam::INVALID, InvalidParam::INVALID);
122 // For a neutral particle, last parm should be 1/p rather than q/p.
123 double qopnum = this->charge();
128 // fill the vector now
129 this->m_parameters << lPosition[Trk::loc1], lPosition[Trk::loc2],
130 this->momentum().phi(), this->momentum().theta(),
131 qopnum / this->momentum().norm();
134 // Constructor with mixed arguments 1 - uses global <-> local for parameters
135 template<int DIM, class T, class S>
136 Trk::ParametersT<DIM, T, S>::ParametersT(const Amg::Vector3D& pos,
141 std::optional<AmgSymMatrix(DIM)> cov)
142 : ParametersBase<DIM, T>(AmgVector(DIM)::Zero(), std::move(cov), 1.)
143 , SurfaceUniqHolderImpl<S>(surface)
146 this->m_position = pos;
147 this->m_momentum = Amg::Vector3D::Zero();
149 // decide the sign of the charge
151 this->m_chargeDef.setCharge(-1);
154 // fill momentum & then position using the surface
157 p = std::abs(1. / qop);
159 // qop is unphysical. No momentum measurement.
160 p = InvalidParam::INVALID_P;
161 qop = InvalidParam::INVALID_QOP;
163 double sinPhi, cosPhi, cosTheta, sinTheta;
164 sincos(phi, &sinPhi, &cosPhi);
165 sincos(theta, &sinTheta, &cosTheta);
167 Amg::Vector3D(p * cosPhi * sinTheta, p * sinPhi * sinTheta, p * cosTheta);
169 // get the local parameters via the surface
170 Amg::Vector2D lPosition;
171 const bool ok = this->m_associatedSurface->globalToLocal(
172 this->position(), this->momentum(), lPosition);
174 lPosition = Amg::Vector2D(InvalidParam::INVALID, InvalidParam::INVALID);
176 // fill the vector now
177 // cppcheck-suppress constStatement
178 this->m_parameters << lPosition[Trk::loc1], lPosition[Trk::loc2], phi, theta, qop;
181 /** Test to see if there's a surface there. */
182 template<int DIM, class T, class S>
184 ParametersT<DIM, T, S>::hasSurface() const
186 return (this->m_associatedSurface != nullptr);
189 /** Access to the Surface method */
190 template<int DIM, class T, class S>
192 ParametersT<DIM, T, S>::associatedSurface() const
194 if (not this->m_associatedSurface){
195 throw std::runtime_error(
196 "No associated surface in ParametersT::associatedSurface");
198 return *(this->m_associatedSurface);
201 /** equality operator */
202 template<int DIM, class T, class S>
204 ParametersT<DIM, T, S>::operator==(const ParametersBase<DIM, T>& rhs) const
206 // make sure we compare objects of same type
207 decltype(this) pCasted = dynamic_cast<decltype(this)>(&rhs);
212 // comparison to myself?
213 if (pCasted == this) {
218 if (associatedSurface() != pCasted->associatedSurface()) {
222 // return compatibility of base class parts
223 return ParametersBase<DIM, T>::operator==(rhs);
225 template<int DIM, class T, class S>
227 ParametersT<DIM, T, S>::operator==(const ParametersT& rhs) const
229 return *this == static_cast<const ParametersBase<DIM, T>&>(rhs);
232 template<int DIM, class T, class S>
233 ParametersT<DIM, T, S>*
234 ParametersT<DIM, T, S>::clone() const
236 return new ParametersT<DIM, T, S>(*this);
239 /** Return the ParametersType enum */
240 template<int DIM, class T, class S>
241 inline constexpr ParametersType
242 ParametersT<DIM, T, S>::type() const
244 return Trk::AtaSurface;
247 /** Return the Surface Type (check SurfaceType enums)*/
248 template<int DIM, class T, class S>
249 inline constexpr SurfaceType
250 ParametersT<DIM, T, S>::surfaceType() const
252 return S::staticType;
255 // return the measurementFrame
256 template<int DIM, class T, class S>
257 Amg::RotationMatrix3D
258 ParametersT<DIM, T, S>::measurementFrame() const
260 return associatedSurface().measurementFrame(this->position(),
264 // private updateParametersHelper
265 template<int DIM, class T, class S>
268 ParametersT<DIM, T, S>::updateParametersHelper(const AmgVector(DIM) &
271 // valid to use != here, because value is either copied or modified,
272 bool updatePosition =
273 (updatedParameters[Trk::loc1] != this->m_parameters[Trk::loc1]) ||
274 (updatedParameters[Trk::loc2] != this->m_parameters[Trk::loc2]);
276 bool updateMomentum =
277 (updatedParameters[Trk::phi] != this->m_parameters[Trk::phi]) ||
278 (updatedParameters[Trk::theta] != this->m_parameters[Trk::theta]) ||
279 (updatedParameters[qOverP] != this->m_parameters[qOverP]);
281 if constexpr (S::staticType == Trk::SurfaceType::Line ||
282 S::staticType == Trk::SurfaceType::Perigee) {
283 updatePosition |= updateMomentum;
286 // update the parameters vector
287 this->m_parameters = updatedParameters;
289 // momentum update is needed
290 if (updateMomentum) {
291 double phi = this->m_parameters[Trk::phi];
292 double theta = this->m_parameters[Trk::theta];
293 double p = InvalidParam::INVALID_P;
294 if (this->m_parameters[Trk::qOverP] != 0) {
295 this->m_chargeDef = sgn(this->m_parameters[Trk::qOverP]);
296 p = std::abs(1. / this->m_parameters[Trk::qOverP]);
298 double sinPhi, cosPhi, cosTheta, sinTheta;
299 sincos(phi, &sinPhi, &cosPhi);
300 sincos(theta, &sinTheta, &cosTheta);
301 this->m_momentum = Amg::Vector3D(p * cosPhi * sinTheta,
302 p * sinPhi * sinTheta, p * cosTheta);
305 // position or momentum update needed
306 if (updatePosition) {
307 if (this->m_associatedSurface) {
308 this->m_associatedSurface->localToGlobal(
309 this->localPosition(), this->m_momentum, this->m_position);
311 this->m_position.setZero();
316 // Protected Constructor with local arguments - persistency only
317 template<int DIM, class T, class S>
318 ParametersT<DIM, T, S>::ParametersT(const AmgVector(DIM) & pars,
320 std::optional<AmgSymMatrix(DIM)> cov)
321 : ParametersBase<DIM, T>(pars, std::move(cov))
322 , SurfaceUniqHolderImpl<S>(surface)
324 float qop = this->m_parameters[Trk::qOverP];
325 // decide the sign of the charge
327 this->m_chargeDef.setCharge(-1);
331 p = std::abs(1. / qop);
333 // qop is unphysical. No momentum measurement.
334 p = InvalidParam::INVALID_P;
335 qop = InvalidParam::INVALID_QOP;
337 if (this->m_associatedSurface) {
338 // fill momentum & then position using the surface
339 this->m_momentum = Amg::Vector3D(
340 p * std::cos(this->m_parameters[Trk::phi]) * std::sin(this->m_parameters[Trk::theta]),
341 p * std::sin(this->m_parameters[Trk::phi]) * std::sin(this->m_parameters[Trk::theta]),
342 p * std::cos(this->m_parameters[Trk::theta]));
343 this->m_associatedSurface->localToGlobal(
344 this->localPosition(), this->m_momentum, this->m_position);
346 this->m_momentum.setZero();
347 this->m_position.setZero();
351 // Screen output dump
352 template<int DIM, class T, class S>
354 ParametersT<DIM, T, S>::dump(MsgStream& out) const
356 out << "ParametersT parameters " << std::endl;
357 ParametersBase<DIM, T>::dump(out);
362 // Screen output dump
363 template<int DIM, class T, class S>
365 ParametersT<DIM, T, S>::dump(std::ostream& out) const
367 out << "ParametersT parameters:" << std::endl;
368 ParametersBase<DIM, T>::dump(out);
373 } // end of namespace Trk