25#include "GaudiKernel/SystemOfUnits.h"
43 declareInterface<IMuidCaloTrackStateOnSurface>(
this);
52 ATH_MSG_DEBUG(
"Initializing CombinedMuonTrackStateOnSurface");
70 return StatusCode::SUCCESS;
78 <<
" completely failed to intersect the calorimeter." <<
endmsg <<
" "
81 return StatusCode::SUCCESS;
86 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>>
caloTSOS;
89 std::unique_ptr<Trk::TrackStateOnSurface> innerTS, middleTS, outerTS;
90 std::unique_ptr<const Trk::TrackParameters> inParams, midParams;
107 bool trackOutwards =
true;
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;
119 innerParams = innerTS->trackParameters();
122 middleParams = midParams.get();
128 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *midParams, innerParams, outerParams);
129 if (!middleTS) { middleParams =
nullptr; }
135 std::unique_ptr<const Trk::TrackParameters> params;
136 for (
int iterate = 0; iterate != 2; ++iterate) {
137 if (!middleTS)
break;
142 middleParams = middleTS->trackParameters();
144 double correctedEnergy = innerParams->
momentum().mag() - energyDeposit;
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)");
159 momentum *= correctedEnergy / momentum.mag();
166 std::make_unique<Trk::AtaCylinder>(middleParams->
position(), momentum, middleParams->
charge(), *cylinder);
170 params = std::make_unique<Trk::AtaDisc>(middleParams->
position(), momentum, middleParams->
charge(), *disc);
181 middleTS =
m_caloEnergyDeposit->trackStateOnSurface(ctx, *params, innerParams, outerParams);
183 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *params, innerParams, outerParams);
186 if (middleTS) { outerTS =
outerTSOS(ctx, *params); }
188 if (!middleTS) {
ATH_MSG_VERBOSE(
" fail tracking outwards: no intersect at middle surface"); }
191 ATH_MSG_VERBOSE(
" fail tracking ouwards: no intersect at inner surface");
197 outerParams = outerTS->trackParameters();
199 middleParams = midParams.get();
202 innerParams = inParams.get();
206 middleTS =
m_caloEnergyDeposit->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
208 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
215 double correctedEnergy = momentum.mag() + energyDeposit;
218 if (correctedEnergy < 0.5 * Gaudi::Units::GeV) {
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)");
225 momentum *= 1. + energyDeposit / momentum.mag();
226 std::unique_ptr<const Trk::TrackParameters> params;
230 middleParams->covariance() ? std::optional<AmgSymMatrix(5)>(*middleParams->covariance()) : std::nullopt;
232 params = std::make_unique<Trk::AtaCylinder>(middleParams->
position(), momentum, middleParams->
charge(),
237 params = std::make_unique<Trk::AtaDisc>(middleParams->
position(), momentum, middleParams->
charge(),
243 if (params && middleTS) { innerTS =
innerTSOS(ctx, *params); }
246 ATH_MSG_VERBOSE(
" fail tracking inwards: no intersect at inner surface");
249 ATH_MSG_VERBOSE(
" fail tracking inwards: no intersect at middle surface");
255 caloTSOS.push_back(std::move(innerTS));
258 if (middleTS)
caloTSOS.push_back(std::move(middleTS));
260 caloTSOS.push_back(std::move(outerTS));
273 if (!extrapolation || extrapolation->position().perp() <
m_minCaloRadius) {
282 if (!extrapolation || extrapolation->position().perp() <
m_minCaloRadius) {
294 if (!extrapolation || extrapolation->position().perp() <
m_minCaloRadius) {
298 std::unique_ptr<Trk::TrackStateOnSurface> TSOS;
300 TSOS =
m_caloEnergyDeposit->trackStateOnSurface(ctx, *extrapolation, innerParams, outerParams);
302 TSOS =
m_caloEnergyParam->trackStateOnSurface(ctx, *extrapolation, innerParams, outerParams);
325 double startingPhi = 0.;
328 startingPhi = parameters.momentum().phi();
331 startingPhi = parameters.position().phi();
333 if (parameters.momentum().dot(parameters.position()) < 0.) {
338 if (!surface)
return nullptr;
341 unsigned extrapolations = 0;
344 propDirection = momentumDirection;
346 propDirection = oppositeDirection;
350 std::unique_ptr<const Trk::TrackParameters> extrapolation{
352 if (!extrapolation)
return nullptr;
356 if (std::abs(
deltaPhi) > M_PI_2) {
return nullptr; }
360 double signRZ = (extrapolation->position().
perp() - parameters.position().perp()) *
361 (extrapolation->position().
z() - parameters.position().z());
362 if (signRZ * extrapolation->position().z() < 0.) {
369 bool restart =
false;
375 std::unique_ptr<const Trk::Surface> reset_surface;
376 while (++extrapolations < 5 && extrapolatedSurface != oldSurface) {
380 propDirection = momentumDirection;
382 propDirection = oppositeDirection;
387 std::unique_ptr<const Trk::TrackParameters> oldParameters = std::move(extrapolation);
390 if (!extrapolation) {
393 if ((*oldParameters) == parameters) {
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;
406 ATH_MSG_VERBOSE(surf_layer_str <<
" Parameters: restart extrap after " << extrapolations <<
" extrapolations");
409 extrapolation = parameters.uniqueClone();
410 surface = oldSurface;
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);
423 if (std::abs(
deltaPhi) > M_PI_2) {
return nullptr; }
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());
433 return extrapolation;
439 double parameterDistance = parameters.position().mag();
441 parameterDistance = parameters.associatedSurface().center().perp();
443 return parameterDistance < 0.5 * Gaudi::Units::meter;
Scalar eta() const
pseudorapidity method
Scalar perp() const
perp method - perpendicular length
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define AmgSymMatrix(dim)
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 ¶meters) 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)
std::atomic_int m_countInnerFailure
const Trk::Surface * getCaloSurface(const double eta, const short layer) const
std::unique_ptr< Trk::TrackStateOnSurface > outerTSOS(const EventContext &ctx, const Trk::TrackParameters ¶meters) const override
StatusCode initialize() override
double m_minRemainingEnergy
StatusCode finalize() override
ToolHandle< Rec::IMuidCaloEnergy > m_caloEnergyDeposit
Trk::MagneticFieldProperties m_magFieldProperties
static bool useEtaPhiFromDirection(const Trk::TrackParameters ¶meters)
std::atomic_int m_countCompleteFailure
std::unique_ptr< const Trk::TrackParameters > getExtrapolatedParameters(const EventContext &ctx, const Trk::TrackParameters ¶meters, const short layer) const
std::unique_ptr< Trk::TrackStateOnSurface > innerTSOS(const EventContext &ctx, const Trk::TrackParameters ¶meters) const override
IMuidCaloTrackStateOnSurface interface: to get individually the scattering TSOS'es representing the c...
ToolHandle< Rec::IMuidCaloEnergy > m_caloEnergyParam
ToolHandle< Trk::IPropagator > m_propagator
std::atomic_int m_countOuterFailure
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
ToolHandle< Rec::IMuidCaloMaterialParam > m_caloMaterialParam
std::atomic_int m_countArbitrarySolution
Class for a CylinderSurface in the ATLAS detector.
Class for a DiscSurface in the ATLAS detector.
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 =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
=============================================================================
namespace for combined reconstruction tools and interfaces
PropDirection
PropDirection, enum for direction of the propagation.
ParametersBase< TrackParametersDim, Charged > TrackParameters
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[