ATLAS Offline Software
Loading...
Searching...
No Matches
MuidCaloTrackStateOnSurface.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MuidCaloTrackStateOnSurface
7// AlgTool to allocate 3 scattering centres as TrackStateOnSurface objects
8// to represent the Coulomb scattering and energy deposit between the InDet
9// and MuonSpectrometer entrance.
10//
11// This tool retrieves the appropriate parametrized scattering centres and
12// hybrid (measured + parametrized) energy deposit evaluation
13// using the IMuidCaloMaterialParam and IMuidCaloEnergy interfaces
14//
16
17//<<<<<< INCLUDES >>>>>>
18
20
21#include <cmath>
22#include <iomanip>
23
25#include "GaudiKernel/SystemOfUnits.h"
34//<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>>
35
36namespace Rec {
37
38 MuidCaloTrackStateOnSurface::MuidCaloTrackStateOnSurface(const std::string& type, const std::string& name, const IInterface* parent) :
39 AthAlgTool(type, name, parent),
40 m_minCaloRadius(0.4 * Gaudi::Units::meter),
42 m_paramPtCut(15.0 * Gaudi::Units::GeV) {
43 declareInterface<IMuidCaloTrackStateOnSurface>(this);
44 declareProperty("MinCaloRadius", m_minCaloRadius);
45 declareProperty("MinRemainingEnergy", m_minRemainingEnergy);
46 declareProperty("ParamPtCut", m_paramPtCut);
47 }
48
49 //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS >>>>>>
50
52 ATH_MSG_DEBUG("Initializing CombinedMuonTrackStateOnSurface");
53
54 // get the Tools
56 ATH_MSG_DEBUG("Retrieved tool " << m_caloEnergyDeposit);
57
58 ATH_CHECK(m_caloEnergyParam.retrieve());
59 ATH_MSG_DEBUG("Retrieved tool " << m_caloEnergyParam);
60
62 ATH_MSG_DEBUG("Retrieved tool " << m_caloMaterialParam);
63
66
67 ATH_CHECK(m_propagator.retrieve());
68 ATH_MSG_DEBUG("Retrieved tool " << m_propagator);
69
70 return StatusCode::SUCCESS;
71 }
72
74 ATH_MSG_INFO("finalized with " << m_count << " muons asking for calo association, out of which: " << endmsg << " "
75 << m_countInnerFailure << " failed to find the inner calo scattering plane," << endmsg << " "
76 << m_countOuterFailure << " failed to find the outer calo scattering plane," << endmsg
77 << " while another " << m_countCompleteFailure
78 << " completely failed to intersect the calorimeter." << endmsg << " "
79 << m_countArbitrarySolution << " with oscillation resolved by taking an arbitrary solution");
80
81 return StatusCode::SUCCESS;
82 }
83
84 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> MuidCaloTrackStateOnSurface::caloTSOS(
85 const EventContext& ctx, const Trk::TrackParameters& parameters) const {
86 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> caloTSOS;
87 caloTSOS.reserve(3);
88
89 std::unique_ptr<Trk::TrackStateOnSurface> innerTS, middleTS, outerTS;
90 std::unique_ptr<const Trk::TrackParameters> inParams, midParams;
91 const Trk::TrackParameters* innerParams = nullptr;
92 const Trk::TrackParameters* middleParams = nullptr;
93 const Trk::TrackParameters* outerParams = nullptr;
94
96 // Get field cache object
98 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
99
100 if (!fieldCondObj) {
101 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
102 return caloTSOS;
103 }
104 fieldCondObj->getInitializedCache(fieldCache);
105
106 // track to calo surfaces - first decide in or outwards
107 bool trackOutwards = true;
108 if (dynamic_cast<const Trk::PerigeeSurface*>(&parameters.associatedSurface())) {
109 if (parameters.associatedSurface().center().perp() > 0.5 * Gaudi::Units::meter) trackOutwards = false;
110 } else if (std::abs(parameters.position().z()) > 4.0 * Gaudi::Units::meter ||
111 parameters.position().perp() > 1.2 * Gaudi::Units::meter) {
112 trackOutwards = false;
113 }
114
115 if (trackOutwards) // forward tracking
116 {
117 innerTS = innerTSOS(ctx, parameters);
118 if (innerTS) {
119 innerParams = innerTS->trackParameters();
120 if (innerParams->momentum().dot(innerParams->position()) > 0.) {
121 midParams = getExtrapolatedParameters(ctx, *innerParams, SurfaceLayer::Middle);
122 middleParams = midParams.get();
123 } else {
124 ATH_MSG_VERBOSE(" quit as looper " << innerParams);
125 }
126 if (middleParams) {
127 // get calo energy deposit
128 middleTS = m_caloEnergyParam->trackStateOnSurface(ctx, *midParams, innerParams, outerParams);
129 if (!middleTS) { middleParams = nullptr; }
130 }
131
132 if (middleParams) {
133 // apply energy deposit to give outgoing middleParams,
134 // note the iteration required to get optimum energy correction
135 std::unique_ptr<const Trk::TrackParameters> params;
136 for (int iterate = 0; iterate != 2; ++iterate) {
137 if (!middleTS) break;
138
139 const Trk::MaterialEffectsOnTrack* meot =
140 dynamic_cast<const Trk::MaterialEffectsOnTrack*>(middleTS->materialEffectsOnTrack());
141 const double energyDeposit = meot ? meot->energyLoss()->deltaE() : 0.;
142 middleParams = middleTS->trackParameters();
143 Amg::Vector3D momentum = middleParams->momentum();
144 double correctedEnergy = innerParams->momentum().mag() - energyDeposit;
145
146 // fail potential loopers
147 if (fieldCache.toroidOn() && correctedEnergy < m_minRemainingEnergy) {
148 middleTS.reset();
149 ATH_MSG_VERBOSE(" fail tracking outwards: momentum " << momentum.mag() / Gaudi::Units::GeV
150 << " energyDeposit " << energyDeposit / Gaudi::Units::GeV
151 << " correctedEnergy "
152 << correctedEnergy / Gaudi::Units::GeV << " (GeV units)");
153 break;
154 }
155 // toroid off: set floor for remaining energy
156 if (correctedEnergy < m_minRemainingEnergy) {
157 momentum *= m_minRemainingEnergy / momentum.mag();
158 } else {
159 momentum *= correctedEnergy / momentum.mag();
160 }
161
162 const Trk::CylinderSurface* cylinder =
163 dynamic_cast<const Trk::CylinderSurface*>(&middleParams->associatedSurface());
164 if (cylinder) {
165 params =
166 std::make_unique<Trk::AtaCylinder>(middleParams->position(), momentum, middleParams->charge(), *cylinder);
167 } else {
168 const Trk::DiscSurface* disc = dynamic_cast<const Trk::DiscSurface*>(&middleParams->associatedSurface());
169 if (disc) {
170 params = std::make_unique<Trk::AtaDisc>(middleParams->position(), momentum, middleParams->charge(), *disc);
171 } else {
172 ATH_MSG_WARNING(" caloTSOS: unexpected TrackParameters type ");
173 }
174 }
175
176 // delete middle and outer,
177 // then recompute with parameters as for backwards tracking
178 if (!params) {
179 middleTS.reset();
180 } else if (params->momentum().perp() > m_paramPtCut) {
181 middleTS = m_caloEnergyDeposit->trackStateOnSurface(ctx, *params, innerParams, outerParams);
182 } else {
183 middleTS = m_caloEnergyParam->trackStateOnSurface(ctx, *params, innerParams, outerParams);
184 }
186 if (middleTS) { outerTS = outerTSOS(ctx, *params); }
187 }
188 if (!middleTS) { ATH_MSG_VERBOSE(" fail tracking outwards: no intersect at middle surface"); }
189 }
190 } else {
191 ATH_MSG_VERBOSE(" fail tracking ouwards: no intersect at inner surface");
192 }
193 } else // backward tracking
194 {
195 outerTS = outerTSOS(ctx, parameters);
196 if (outerTS) {
197 outerParams = outerTS->trackParameters();
198 midParams = getExtrapolatedParameters(ctx, *outerParams, SurfaceLayer::Middle);
199 middleParams = midParams.get();
200 if (middleParams) {
201 inParams = getExtrapolatedParameters(ctx, *midParams, SurfaceLayer::Inner);
202 innerParams = inParams.get();
203 if (inParams) {
204 // get calo energy deposit
205 if (middleParams->momentum().perp() > m_paramPtCut) {
206 middleTS = m_caloEnergyDeposit->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
207 } else {
208 middleTS = m_caloEnergyParam->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
209 }
210 // apply energy deposit
211 const Trk::MaterialEffectsOnTrack* meot =
212 middleTS ? dynamic_cast<const Trk::MaterialEffectsOnTrack*>(middleTS->materialEffectsOnTrack()) : nullptr;
213 const double energyDeposit = meot ? meot->energyLoss()->deltaE() : 0.;
214 Amg::Vector3D momentum = middleParams->momentum();
215 double correctedEnergy = momentum.mag() + energyDeposit;
216
217 // fail potential loopers
218 if (correctedEnergy < 0.5 * Gaudi::Units::GeV) {
219 middleTS.reset();
220 ATH_MSG_VERBOSE(" fail tracking inwards: momentum " << momentum.mag() / Gaudi::Units::GeV << " energyDeposit "
221 << energyDeposit / Gaudi::Units::GeV
222 << " correctedEnergy "
223 << correctedEnergy / Gaudi::Units::GeV << " (GeV units)");
224 } else {
225 momentum *= 1. + energyDeposit / momentum.mag();
226 std::unique_ptr<const Trk::TrackParameters> params;
227 const Trk::CylinderSurface* cylinder =
228 dynamic_cast<const Trk::CylinderSurface*>(&middleParams->associatedSurface());
229 std::optional<AmgSymMatrix(5)> cov =
230 middleParams->covariance() ? std::optional<AmgSymMatrix(5)>(*middleParams->covariance()) : std::nullopt;
231 if (cylinder) {
232 params = std::make_unique<Trk::AtaCylinder>(middleParams->position(), momentum, middleParams->charge(),
233 *cylinder, cov);
234 } else {
235 const Trk::DiscSurface* disc = dynamic_cast<const Trk::DiscSurface*>(&middleParams->associatedSurface());
236 if (disc) {
237 params = std::make_unique<Trk::AtaDisc>(middleParams->position(), momentum, middleParams->charge(),
238 *disc, cov);
239 } else {
240 ATH_MSG_WARNING(" caloTSOS: unexpected TrackParameters type ");
241 }
242 }
243 if (params && middleTS) { innerTS = innerTSOS(ctx, *params); }
244 }
245 } else {
246 ATH_MSG_VERBOSE(" fail tracking inwards: no intersect at inner surface");
247 }
248 } else {
249 ATH_MSG_VERBOSE(" fail tracking inwards: no intersect at middle surface");
250 }
251 }
252 }
253
254 if (innerTS)
255 caloTSOS.push_back(std::move(innerTS));
256 else
258 if (middleTS) caloTSOS.push_back(std::move(middleTS));
259 if (outerTS)
260 caloTSOS.push_back(std::move(outerTS));
261 else
263
264 // keep some statistics
265 ++m_count;
266
267 if (caloTSOS.empty()) { ++m_countCompleteFailure; }
268 return caloTSOS;
269 }
270 std::unique_ptr<Trk::TrackStateOnSurface> MuidCaloTrackStateOnSurface::innerTSOS(const EventContext& ctx,
271 const Trk::TrackParameters& parameters) const {
272 std::unique_ptr<const Trk::TrackParameters> extrapolation = getExtrapolatedParameters(ctx, parameters, SurfaceLayer::Inner);
273 if (!extrapolation || extrapolation->position().perp() < m_minCaloRadius) {
274 ATH_MSG_DEBUG(" innerTSOS: extrapolation fails ");
275 return nullptr;
276 }
277 return m_caloMaterialParam->trackStateOnSurface(*extrapolation);
278 }
279 std::unique_ptr<Trk::TrackStateOnSurface> MuidCaloTrackStateOnSurface::outerTSOS(const EventContext& ctx,
280 const Trk::TrackParameters& parameters) const {
281 std::unique_ptr<const Trk::TrackParameters> extrapolation = getExtrapolatedParameters(ctx, parameters, SurfaceLayer::Outer);
282 if (!extrapolation || extrapolation->position().perp() < m_minCaloRadius) {
283 ATH_MSG_DEBUG(" outerTSOS: extrapolation fails ");
284 return nullptr;
285 }
286 return m_caloMaterialParam->trackStateOnSurface(*extrapolation);
287 }
288 std::unique_ptr<Trk::TrackStateOnSurface> MuidCaloTrackStateOnSurface::middleTSOS(const EventContext& ctx,
289 const Trk::TrackParameters& middleParams,
290 const Trk::TrackParameters* innerParams,
291 const Trk::TrackParameters* outerParams) const {
292 std::unique_ptr<const Trk::TrackParameters> extrapolation = getExtrapolatedParameters(ctx, middleParams, SurfaceLayer::Middle);
293
294 if (!extrapolation || extrapolation->position().perp() < m_minCaloRadius) {
295 ATH_MSG_DEBUG(" middleTSOS: extrapolation fails ");
296 return nullptr;
297 }
298 std::unique_ptr<Trk::TrackStateOnSurface> TSOS;
299 if (extrapolation->momentum().perp() > m_paramPtCut) {
300 TSOS = m_caloEnergyDeposit->trackStateOnSurface(ctx, *extrapolation, innerParams, outerParams);
301 } else {
302 TSOS = m_caloEnergyParam->trackStateOnSurface(ctx, *extrapolation, innerParams, outerParams);
303 }
304 return TSOS;
305 }
306
307 //<<<<<< PRIVATE MEMBER FUNCTION DEFINITIONS >>>>>>
308
309 const Trk::Surface* MuidCaloTrackStateOnSurface::getCaloSurface(const double eta, const short layer) const {
310 if (layer == SurfaceLayer::Inner) return m_caloMaterialParam->innerSurface(eta);
311 if (layer == SurfaceLayer::Middle) return m_caloMaterialParam->middleSurface(eta);
312 if (layer == SurfaceLayer::Outer) return m_caloMaterialParam->outerSurface(eta);
313 ATH_MSG_WARNING("Invalid layer id given " << layer);
314 return nullptr;
315 }
316 std::unique_ptr<const Trk::TrackParameters> MuidCaloTrackStateOnSurface::getExtrapolatedParameters(
317 const EventContext& ctx, const Trk::TrackParameters& parameters, const short layer) const {
318 // will need to know whether forward or back tracking
319 Trk::PropDirection momentumDirection = Trk::alongMomentum;
320 Trk::PropDirection oppositeDirection = Trk::oppositeMomentum;
322 const std::string surf_layer_str = layer == SurfaceLayer::Inner ? "Inner" : (layer == SurfaceLayer::Middle ? "Middle" : "Outer");
323 // initial surface at track eta -
324 // using position or direction according to distance from origin
325 double startingPhi = 0.;
326 const Trk::Surface* surface = nullptr;
327 if (useEtaPhiFromDirection(parameters)) {
328 startingPhi = parameters.momentum().phi();
329 surface = getCaloSurface(parameters.momentum().eta(), layer);
330 } else {
331 startingPhi = parameters.position().phi();
332 surface = getCaloSurface(parameters.position().eta(), layer);
333 if (parameters.momentum().dot(parameters.position()) < 0.) {
334 momentumDirection = Trk::oppositeMomentum;
335 oppositeDirection = Trk::alongMomentum;
336 }
337 }
338 if (!surface) return nullptr;
339
340 // extrapolate to calo surface (take care to get correct cylinder intersect)
341 unsigned extrapolations = 0;
342 if (surface->type() == Trk::SurfaceType::Cylinder) {
343 if (parameters.position().perp() < surface->globalReferencePoint().perp()) {
344 propDirection = momentumDirection;
345 } else {
346 propDirection = oppositeDirection;
347 }
348 }
349 // tidy up ownership later
350 std::unique_ptr<const Trk::TrackParameters> extrapolation{
351 m_propagator->propagate(ctx, parameters, *surface, propDirection, false, m_magFieldProperties, Trk::nonInteracting)};
352 if (!extrapolation) return nullptr;
353
354 // phi flip means track has crossed beam-axis (so quit)
355 double deltaPhi = xAOD::P4Helpers::deltaPhi(extrapolation->position().phi(), startingPhi);
356 if (std::abs(deltaPhi) > M_PI_2) { return nullptr; }
357
358 // also quit wrong rz-direction in endcap
359 if (surface->type() != Trk::SurfaceType::Cylinder) {
360 double signRZ = (extrapolation->position().perp() - parameters.position().perp()) *
361 (extrapolation->position().z() - parameters.position().z());
362 if (signRZ * extrapolation->position().z() < 0.) {
363 ATH_MSG_VERBOSE(" wrong way in endcap ");
364 return nullptr;
365 }
366 }
367
368 // iterate if extrapolated surface is different
369 bool restart = false;
370 const Trk::Surface* oldSurface = surface;
371 const Trk::Surface* extrapolatedSurface = getCaloSurface(extrapolation->position().eta(), layer);
375 std::unique_ptr<const Trk::Surface> reset_surface;
376 while (++extrapolations < 5 && extrapolatedSurface != oldSurface) {
377 // take care to get correct solution for cylinder when starting from inside
378 if (surface->type() == Trk::SurfaceType::Cylinder) {
379 if (extrapolation->position().perp() < surface->globalReferencePoint().perp()) {
380 propDirection = momentumDirection;
381 } else {
382 propDirection = oppositeDirection;
383 }
384 } else {
385 propDirection = Trk::anyDirection;
386 }
387 std::unique_ptr<const Trk::TrackParameters> oldParameters = std::move(extrapolation);
388 extrapolation = m_propagator->propagate(ctx, *oldParameters, *extrapolatedSurface, propDirection, false, m_magFieldProperties,
390 if (!extrapolation) {
391 // restart from input parameters (if not already done)
392 // trap no solution after restart
393 if ((*oldParameters) == parameters) {
394 ATH_MSG_VERBOSE(" innerParameters: extrap fails ");
395 return nullptr;
396 }
397 if (restart) {
398 ATH_MSG_DEBUG(surf_layer_str << " Parameters: oscillating => arbitrary solution chosen");
400 extrapolation = std::move(oldParameters);
401 reset_surface.reset(extrapolation->associatedSurface().clone());
402 extrapolatedSurface = reset_surface.get();
403 surface = extrapolatedSurface;
404 restart = false;
405 } else {
406 ATH_MSG_VERBOSE(surf_layer_str << " Parameters: restart extrap after " << extrapolations << " extrapolations");
407 restart = true;
408 extrapolations -= 2;
409 extrapolation = parameters.uniqueClone();
410 surface = oldSurface;
411 }
412 } else {
413 // update surface
414 ATH_MSG_DEBUG(surf_layer_str << " Parameters: Extrapolation succeeded go to next iteration");
415 oldSurface = surface;
416 surface = extrapolatedSurface;
417 extrapolatedSurface = getCaloSurface(extrapolation->position().eta(), layer);
418 }
419 }
420
421 // final check for phi flip
422 deltaPhi = xAOD::P4Helpers::deltaPhi(extrapolation->position().phi(), startingPhi);
423 if (std::abs(deltaPhi) > M_PI_2) { return nullptr; }
424
425 ATH_MSG_VERBOSE(surf_layer_str << " Parameters: success after " << extrapolations << " extrapolation step(s). "
426 << std::setiosflags(std::ios::fixed) << " Intersection at: r,phi,z " << std::setw(7)
427 << std::setprecision(1) << extrapolation->position().perp() << std::setw(7) << std::setprecision(3)
428 << extrapolation->position().phi() << std::setw(8) << std::setprecision(1)
429 << extrapolation->position().z() << " Direction: eta,phi " << std::setw(7) << std::setprecision(3)
430 << extrapolation->momentum().eta() << std::setw(7) << std::setprecision(3)
431 << extrapolation->momentum().phi());
432
433 return extrapolation;
434 }
435
437 // estimate eta,phi for the track intersect with the calo from the track direction when the
438 // parameters are expressed near the beam-line, further out it's better to use the track position
439 double parameterDistance = parameters.position().mag();
440 if (dynamic_cast<const Trk::PerigeeSurface*>(&parameters.associatedSurface()))
441 parameterDistance = parameters.associatedSurface().center().perp();
442
443 return parameterDistance < 0.5 * Gaudi::Units::meter;
444 }
445
446} // namespace Rec
Scalar eta() const
pseudorapidity method
Scalar perp() const
perp method - perpendicular length
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
#define z
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
std::vector< std::unique_ptr< const Trk::TrackStateOnSurface > > caloTSOS(const EventContext &ctx, const Trk::TrackParameters &parameters) const override
IMuidCaloTrackStateOnSurface interface: to get the 3 scattering and energy deposit TSOS'es representi...
std::unique_ptr< Trk::TrackStateOnSurface > middleTSOS(const EventContext &ctx, const Trk::TrackParameters &middleParameters, const Trk::TrackParameters *innerParameters, const Trk::TrackParameters *outerParameters) const override
IMuidCaloTrackStateOnSurface interface: to get the energy deposit TSOS representing the calorimeter.
MuidCaloTrackStateOnSurface(const std::string &type, const std::string &name, const IInterface *parent)
const Trk::Surface * getCaloSurface(const double eta, const short layer) const
std::unique_ptr< Trk::TrackStateOnSurface > outerTSOS(const EventContext &ctx, const Trk::TrackParameters &parameters) const override
ToolHandle< Rec::IMuidCaloEnergy > m_caloEnergyDeposit
Trk::MagneticFieldProperties m_magFieldProperties
static bool useEtaPhiFromDirection(const Trk::TrackParameters &parameters)
std::unique_ptr< const Trk::TrackParameters > getExtrapolatedParameters(const EventContext &ctx, const Trk::TrackParameters &parameters, const short layer) const
std::unique_ptr< Trk::TrackStateOnSurface > innerTSOS(const EventContext &ctx, const Trk::TrackParameters &parameters) const override
IMuidCaloTrackStateOnSurface interface: to get individually the scattering TSOS'es representing the c...
ToolHandle< Rec::IMuidCaloEnergy > m_caloEnergyParam
ToolHandle< Trk::IPropagator > m_propagator
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
ToolHandle< Rec::IMuidCaloMaterialParam > m_caloMaterialParam
Class for a CylinderSurface in the ATLAS detector.
Class for a DiscSurface in the ATLAS detector.
Definition DiscSurface.h:54
double deltaE() const
returns the
represents the full description of deflection and e-loss of a track in material.
const EnergyLoss * energyLoss() const
returns the energy loss object.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
double charge() const
Returns the charge.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Class describing the Line to which the Perigee refers to.
Abstract Base Class for tracking surfaces.
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
virtual const Amg::Vector3D & globalReferencePoint() const
Returns a global reference point on the surface, for PlaneSurface, StraightLineSurface,...
Eigen::Matrix< double, 3, 1 > Vector3D
=============================================================================
Gaudi Tools.
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
@ anyDirection
ParametersBase< TrackParametersDim, Charged > TrackParameters
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[