ATLAS Offline Software
Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
Trk::Extrapolator Class Referencefinal

Extrapolation of track parameters and their associated covariances to destination surfaces. More...

#include <Extrapolator.h>

Inheritance diagram for Trk::Extrapolator:
Collaboration diagram for Trk::Extrapolator:

Public Member Functions

 Extrapolator (const std::string &, const std::string &, const IInterface *)
 Constructor. More...
 
 ~Extrapolator ()
 Destructor. More...
 
virtual StatusCode initialize () override
 AlgTool initailize method. More...
 
virtual StatusCode finalize () override
 AlgTool finalize method. More...
 
virtual std::unique_ptr< TrackParametersextrapolateDirectly (const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const override final
 Extrapolate directly: Forwards directly the call to the configured "Global" propagator. More...
 
virtual std::unique_ptr< NeutralParametersextrapolate (const NeutralParameters &parameters, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true) const override final
 Main extrapolation Interface starting from neutral parameters and aiming at surface. More...
 
virtual std::unique_ptr< TrackParametersextrapolate (const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise, Trk::ExtrapolationCache *cache=nullptr) const override final
 Main extrapolation interface starting from charged parameters and aiming at Surface. More...
 
virtual TrackParametersUVector extrapolateStepwise (const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const override final
 Extrapolation method where a step-wise navigation to the destination surface is performed. More...
 
virtual std::unique_ptr< TrackParametersextrapolateTrack (const EventContext &ctx, const Track &trk, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise, Trk::ExtrapolationCache *cache=nullptr) const override final
 Main extrapolation interface starting from a Trk::Track and aiming at Surface. More...
 
virtual TrackParametersUVector extrapolateBlindly (const EventContext &ctx, const TrackParameters &parm, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, const Volume *boundaryVol=nullptr) const override final
 extrapolateBlindly like step-wise extrapolation, but without a destination surface. More...
 
virtual std::vector< const TrackStateOnSurface * > * extrapolateM (const EventContext &ctx, const TrackParameters &parameters, const Surface &sf, PropDirection dir, const BoundaryCheck &bcheck, ParticleHypothesis particle=pion, Trk::ExtrapolationCache *cache=nullptr) const override final
 Extrapolate to a destination surface, while collecting all the material layers in between. More...
 
virtual std::unique_ptr< std::vector< std::pair< std::unique_ptr< Trk::TrackParameters >, int > > > collectIntersections (const EventContext &ctx, const Trk::TrackParameters &parm, Trk::PropDirection dir, Trk::ParticleHypothesis particle, int destination=3) const override final
 Extrapolation method collecting intersections with subdetector boundaries and active volumes/layers. More...
 
virtual std::pair< std::unique_ptr< TrackParameters >, const Layer * > extrapolateToNextActiveLayerM (const EventContext &ctx, const TrackParameters &parm, PropDirection dir, const BoundaryCheck &bcheck, std::vector< const Trk::TrackStateOnSurface * > &material, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const override final
 Extrapolation to the next active layer with material collection. More...
 
virtual std::unique_ptr< TrackParametersextrapolateToVolume (const EventContext &ctx, const TrackParameters &parm, const Trk::TrackingVolume &vol, PropDirection dir=anyDirection, ParticleHypothesis particle=pion) const override final
 Extrapolation to volume : More...
 
virtual const TrackingGeometrytrackingGeometry () const override final
 Return the TrackingGeometry used by the Extrapolator (forward information from Navigator) More...
 
virtual StatusCode sysInitialize () override
 Perform system initialization for the component. More...
 
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc. More...
 
const ServiceHandle< StoreGateSvc > & evtStore () const
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc. More...
 
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc. More...
 
virtual StatusCode sysStart () override
 Handle START transition. More...
 
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles. More...
 
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles. More...
 
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleKey &hndl, const std::string &doc, const SG::VarHandleKeyType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleBase &hndl, const std::string &doc, const SG::VarHandleType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleKeyArray &hndArr, const std::string &doc, const SG::VarHandleKeyArrayType &)
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, T &property, const std::string &doc, const SG::NotHandleType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, T &property, const std::string &doc="none")
 Declare a new Gaudi property. More...
 
void updateVHKA (Gaudi::Details::PropertyBase &)
 
MsgStream & msg () const
 
MsgStream & msg (const MSG::Level lvl) const
 
bool msgLvl (const MSG::Level lvl) const
 

Static Public Member Functions

static const InterfaceID & interfaceID ()
 AlgTool interface methods. More...
 

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution More...
 
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
 
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed. More...
 

Private Types

typedef std::vector< std::pair< std::unique_ptr< Trk::TrackParameters >, int > > identifiedParameters_t
 
typedef ServiceHandle< StoreGateSvcStoreGateSvc_t
 

Private Member Functions

Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateImpl (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Actual heavy lifting implementation for extrapolate. More...
 
TrackParametersUVector extrapolateStepwiseImpl (const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateImpl (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const std::vector< MaterialEffectsOnTrack > &sfMeff, const TrackingVolume &tvol, PropDirection dir, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Actual heavy lifting implementation for extrapolate. More...
 
virtual Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateImpl (const EventContext &ctx, Cache &cache, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise, Trk::ExtrapolationCache *extrapolationCache=nullptr) const
 Actual heavy lifting implementation for extrapolate. More...
 
std::unique_ptr< TrackParametersextrapolateDirectlyImpl (const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const
 Actual heavy lifting implementation for extrapolateDirectly. More...
 
Trk::TrackParametersUVector extrapolateBlindlyImpl (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, const Volume *boundaryVol=nullptr) const
 Actual heavy lifting implementation for extrapolateBlindly. More...
 
std::pair< std::unique_ptr< TrackParameters >, const Layer * > extrapolateToNextActiveLayerImpl (const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, PropDirection dir, const BoundaryCheck &bcheck, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Actual heavy lifting implementation for extrapolateToNextActiveLayer. More...
 
std::pair< std::unique_ptr< TrackParameters >, const Layer * > extrapolateToNextActiveLayerMImpl (const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, PropDirection dir, const BoundaryCheck &bcheck, std::vector< const Trk::TrackStateOnSurface * > &material, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Actual heavy lifting implementation for extrapolateToNextActiveLayerM. More...
 
std::unique_ptr< TrackParametersextrapolateToVolumeImpl (const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Trk::TrackingVolume &vol, PropDirection dir=anyDirection, ParticleHypothesis particle=pion) const
 Actual heavy lifting implementation for extrapolateToVolume. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateInsideVolume (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Private method for extrapolation in final volume to destination surface. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersinsideVolumeStaticLayers (const EventContext &ctx, Cache &cache, bool toBoundary, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 A) call from extrapolateInsideVolume or toBoundary, if it is to boundary, the return parameters are the parameters at the boundary. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateWithinDetachedVolumes (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 C) call from extrapolateInsideVolume. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateToNextMaterialLayer (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Surface *destSurf, const Trk::TrackingVolume *vol, PropDirection dir, const BoundaryCheck &bcheck, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateInAlignableTV (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Surface *destSurf, const Trk::AlignableTrackingVolume *vol, PropDirection dir, ParticleHypothesis particle=pion) const
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateToVolumeWithPathLimit (const EventContext &ctx, Cache &cache, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, double pathLim, Trk::PropDirection dir, Trk::ParticleHypothesis particle, const Trk::TrackingVolume *destVol, MaterialUpdateMode matupmod=addNoise) const
 
void extrapolateToVolumeBoundary (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Private method for extrapolation in intermediate volume to boundary surface. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateFromLayerToLayer (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const TrackingVolume &tvol, const Layer *nextLayer, const Layer *destinationLayer, Trk::CacheOwnedPtr< Trk::TrackParameters > navParameters, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Private method to step from one to the last layer and stop at last layer (before 0) or before destination layer. More...
 
Trk::CacheOwnedPtr< Trk::TrackParametersextrapolateToDestinationLayer (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const Layer &lay, const TrackingVolume &tvol, const Layer *startLayer, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
 Private to extrapolate to the destination layer + surface. More...
 
std::pair< Trk::CacheOwnedPtr< Trk::TrackParameters >, bool > extrapolateToIntermediateLayer (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer &lay, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise, bool perpendicularCheck=true) const
 Private to extrapolate to the destination layer + surface, special treatment for exit layer. More...
 
void overlapSearch (const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, Trk::CacheOwnedPtr< Trk::TrackParameters > parsOnLayer, const Layer &lay, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, bool startingLayer=false) const
 Private to search for overlap surfaces. More...
 
PropDirection initializeNavigation (const EventContext &ctx, Cache &cache, const Trk::IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > startPars, const Trk::Surface &destSurface, Trk::PropDirection dir, ParticleHypothesis particle, Trk::CacheOwnedPtr< Trk::TrackParameters > &referenceParameters, const Trk::Layer *&associatedLayer, const Trk::TrackingVolume *&associatedVolume, const Trk::TrackingVolume *&destinationVolume) const
 Private method for Initial Extrapolation setup -> overwrites the given pointers for the start and destination parameters -> returns a direction for the Navigation : More...
 
bool radialDirectionCheck (const EventContext &ctx, const IPropagator &prop, const TrackParameters &startParm, const TrackParameters &parsOnLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, ParticleHypothesis particle=pion) const
 Check for punchThrough in case of radial (perpendicular) direction change, returns true if the radial direction change is actually ok (i.e. More...
 
const IPropagatorsubPropagator (const TrackingVolume &tvol) const
 Access the subPropagator to the given volume. More...
 
const IMaterialEffectsUpdatorsubMaterialEffectsUpdator (const TrackingVolume &tvol) const
 Access the subPropagator to the given volume. More...
 
std::string positionOutput (const Amg::Vector3D &pos) const
 For the output - global position. More...
 
void addMaterialEffectsOnTrack (const EventContext &ctx, Cache &cache, const Trk::IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Layer &lay, const Trk::TrackingVolume &vol, Trk::PropDirection propDir, Trk::ParticleHypothesis) const
 helper method for MaterialEffectsOnTrack to be added More...
 
StatusCode isConfigured ()
 Check if component is configured in JobOptionsSvc. More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyArrayType &)
 specialization for handling Gaudi::Property<SG::VarHandleKeyArray> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleType &)
 specialization for handling Gaudi::Property<SG::VarHandleBase> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &t, const SG::NotHandleType &)
 specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray> More...
 

Private Attributes

ToolHandleArray< IPropagatorm_propagators { this, "Propagators", {} }
 Private method for conversion of the synchronized geometry signature to the natural subdetector ordering. More...
 
ToolHandle< IPropagatorm_stepPropagator
 Navigator for TrackingGeometry and magnetic fiels acces. More...
 
ToolHandle< INavigatorm_navigator
 Array of Material updatersc. More...
 
ToolHandleArray< IMaterialEffectsUpdatorm_updaters
 Array of MultipleScattering updaters. More...
 
ToolHandle< IMultipleScatteringUpdatorm_msupdater
 Array of EnergyLoss updaters. More...
 
ToolHandle< IEnergyLossUpdatorm_elossupdater
 
std::vector< const IPropagator * > m_subPropagators
 < Propagators to chose from (steered by signature) More...
 
std::vector< const IMaterialEffectsUpdator * > m_subupdaters
 
StringArrayProperty m_propNames
 
StringArrayProperty m_updatNames
 
BooleanProperty m_includeMaterialEffects
 
BooleanProperty m_stopWithNavigationBreak
 
BooleanProperty m_stopWithUpdateZero
 
BooleanProperty m_skipInitialLayerUpdate
 
BooleanProperty m_resolveActive {this, "ResolveMuonStation", false}
 
BooleanProperty m_resolveMultilayers {this, "ResolveMultilayers", true}
 number of sub valid propagators in the m_subPropagators array More...
 
unsigned int m_numOfValidPropagators
 
UnsignedIntegerProperty m_initialLayerAttempts
 
UnsignedIntegerProperty m_successiveLayerAttempts
 
UnsignedIntegerProperty m_maxMethodSequence {this, "MaximalMethodSequence", 2000}
 
DoubleProperty m_tolerance
 
BooleanProperty m_useMuonMatApprox
 
BooleanProperty m_useDenseVolumeDescription
 
UnsignedIntegerProperty m_maxRecursion {this, "MaxRecursion", 1000}
 
BooleanProperty m_dumpCache {this, "DumpCache", false}
 
BooleanProperty m_fastField {this, "MagneticFieldProperties", false}
 
Trk::MagneticFieldProperties m_fieldProperties
 
std::unique_ptr< Surfacem_referenceSurface = nullptr
 
BooleanProperty m_printRzOutput {this, "positionOutput", true}
 
BooleanProperty m_navigationStatistics
 
BooleanProperty m_navigationBreakDetails
 
Gaudi::Accumulators::Counter m_extrapolateCalls {}
 number of calls: extrapolate() method More...
 
Gaudi::Accumulators::Counter m_extrapolateBlindlyCalls {}
 number of calls: extrapolateBlindly() method More...
 
Gaudi::Accumulators::Counter m_extrapolateDirectlyCalls {}
 number of calls: extrapolateDirectly() method More...
 
Gaudi::Accumulators::Counter m_extrapolateStepwiseCalls {}
 number of calls: extrapolateStepwise() method More...
 
Gaudi::Accumulators::Counter m_startThroughAssociation {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_startThroughRecall {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_startThroughGlobalSearch {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_destinationThroughAssociation {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_destinationThroughRecall {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_destinationThroughGlobalSearch {}
 navigation intialization More...
 
Gaudi::Accumulators::Counter m_layerSwitched {}
 number of layers that have been switched More...
 
Gaudi::Accumulators::Counter m_navigationBreakLoop {}
 number of navigation breaks due to loop More...
 
Gaudi::Accumulators::Counter m_navigationBreakOscillation {}
 number of navigation breaks due to oscillation More...
 
Gaudi::Accumulators::Counter m_navigationBreakNoVolume {}
 number of navigation breaks due no Volume found More...
 
Gaudi::Accumulators::Counter m_navigationBreakDistIncrease {}
 number of navigation breaks due to distance increase More...
 
Gaudi::Accumulators::Counter m_navigationBreakVolumeSignature {}
 number of navigation breaks due to distance increase More...
 
Gaudi::Accumulators::Counter m_overlapSurfaceHit {}
 number of OverlapSurfaces found More...
 
Dbg::PropStat m_propStat ATLAS_THREAD_SAFE
 
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default) More...
 
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default) More...
 
std::vector< SG::VarHandleKeyArray * > m_vhka
 
bool m_varHandleArraysDeclared
 

Static Private Attributes

static const unsigned int m_maxNavigSurf = 1000
 
static const unsigned int m_maxNavigVol = 50
 

Detailed Description

Extrapolation of track parameters and their associated covariances to destination surfaces.

It combines

There are always one Navigator and one STEP_Propagator (forced for muon like workload inside dense volumes)

There are also arrays of Propagators, MaterialEffects updators and possible of EnergyLoss and MultipleScattering Updators. These must have at least one entry [Global] . The default / Global propagator is a RungeKuttaPropator for most typical cases.

Multiple methods are provided for tasks of varying complexity.

As an example: In one side there is ExtrapolateDirectly which is a thinwrapper over the [Global] Propagator call (can be replaced completely by a call to it in client code). In the other side there is an extrapolate overload that allows to find and collect all intersections for a particle (typically muon) traversing the ATLAS calorimeters.

Author
Andre.nosp@m.as.S.nosp@m.alzbu.nosp@m.rger.nosp@m.@cern.nosp@m..ch
Authors
(Athena MT) G. Gaycken, S. Roe , C. Anastopoulos

Definition at line 111 of file Extrapolator.h.

Member Typedef Documentation

◆ identifiedParameters_t

typedef std::vector<std::pair<std::unique_ptr<Trk::TrackParameters>, int> > Trk::Extrapolator::identifiedParameters_t
private

Definition at line 248 of file Extrapolator.h.

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ Extrapolator()

Trk::Extrapolator::Extrapolator ( const std::string &  t,
const std::string &  n,
const IInterface *  p 
)

Constructor.

Definition at line 116 of file Extrapolator.cxx.

120  , m_numOfValidPropagators(INVALIDPROPAGATORS)
121 {
122  declareInterface<IExtrapolator>(this);
123 }

◆ ~Extrapolator()

Trk::Extrapolator::~Extrapolator ( )
default

Destructor.

Member Function Documentation

◆ addMaterialEffectsOnTrack()

void Trk::Extrapolator::addMaterialEffectsOnTrack ( const EventContext &  ctx,
Cache cache,
const Trk::IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Trk::Layer lay,
const Trk::TrackingVolume vol,
Trk::PropDirection  propDir,
Trk::ParticleHypothesis  particle 
) const
private

helper method for MaterialEffectsOnTrack to be added

Definition at line 3965 of file Extrapolator.cxx.

3973 {
3974 
3975  ATH_MSG_VERBOSE(" [+] addMaterialEffectsOnTrack() - at " << positionOutput(parms->position()));
3976  // preparation for the material effects on track
3977  const Trk::MaterialProperties* materialProperties = nullptr;
3978  double pathCorrection = 0.;
3980  // make sure the parameters are on surface
3981  if (parms->associatedSurface() != lay.surfaceRepresentation()) {
3982  parsOnLayer = cache.m_ownedPtrs.push(
3983  prop.propagateParameters(ctx, *parms, lay.surfaceRepresentation(),
3985  } else {
3986  parsOnLayer = parms;
3987  }
3988  // should not really happen
3989  if (!parsOnLayer) {
3990  return;
3991  }
3992  // reference material section:
3993  pathCorrection = pathCorrection > 0. ? pathCorrection
3995  parsOnLayer->position(), parsOnLayer->momentum());
3996 
3997  // material properties are not given by the reference material, get them from the layer
3998  if (!materialProperties) {
3999  materialProperties = lay.fullUpdateMaterialProperties(*parsOnLayer);
4000  }
4001 
4002  if (!materialProperties) {
4003  ATH_MSG_DEBUG(" [!] No MaterialProperties on Layer after intersection.");
4004  return;
4005  }
4006  // pure validation mode
4007  if (!cache.m_matstates) {
4008  if (cache.m_extrapolationCache) {
4009  const double tInX0 = pathCorrection * materialProperties->thicknessInX0();
4010  if (m_dumpCache) {
4011  ATH_MSG_DEBUG(cache.to_string(" addMaterialEffectsOnTrack"));
4012  }
4013  cache.m_extrapolationCache->updateX0(tInX0);
4014  const double currentQoP = parsOnLayer->parameters()[Trk::qOverP];
4015  const Trk::EnergyLoss energyLoss(m_elossupdater->energyLoss(
4016  *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir, particle));
4017  cache.m_extrapolationCache->updateEloss(energyLoss.meanIoni(),
4018  energyLoss.sigmaIoni(),
4019  energyLoss.meanRad(),
4020  energyLoss.sigmaRad());
4021  if (m_dumpCache) {
4022  ATH_MSG_DEBUG(cache.to_string(" After"));
4023  }
4024  }
4025  ATH_MSG_VERBOSE(" [V] Validation mode: MaterialProperties found on this layer.");
4026  } else { // collection mode
4027  // material properties from the layer
4028  const double tInX0 = pathCorrection * materialProperties->thicknessInX0();
4029  // get the q/p for the energyLoss object
4030  const double currentQoP = parsOnLayer->parameters()[Trk::qOverP];
4031  auto energyLoss = m_elossupdater->energyLoss(
4032  *materialProperties, std::abs(1. / currentQoP), pathCorrection, propDir,
4033  particle);
4034  // get the scattering angle
4035  const double sigmaMS = std::sqrt(m_msupdater->sigmaSquare(
4036  *materialProperties, std::abs(1. / currentQoP), pathCorrection, particle));
4037  auto scatAngles =
4038  ScatteringAngles(0, 0, sigmaMS / std::sin(parsOnLayer->parameters()[Trk::theta]), sigmaMS);
4039 
4040  // update cache
4041  if (cache.m_extrapolationCache) {
4042  if (energyLoss.meanIoni() == 0. && tInX0 > 0.) {
4043  ATH_MSG_WARNING(" Extrapolator: the ExtrapolationCache cannot work "
4044  "because the ElossUpdator is wrongly configured: "
4045  "switch joboption DetailedEloss on ");
4046  }
4047  if (m_dumpCache) {
4048  ATH_MSG_DEBUG(cache.to_string(" addMaterialEffectsOnTrack"));
4049  }
4050  cache.m_extrapolationCache->updateX0(tInX0);
4051  cache.m_extrapolationCache->updateEloss(energyLoss.meanIoni(),
4052  energyLoss.sigmaIoni(),
4053  energyLoss.meanRad(),
4054  energyLoss.sigmaRad());
4055  if (m_dumpCache) {
4056  ATH_MSG_DEBUG(cache.to_string(" After"));
4057  }
4058  }
4059  auto meot = std::make_unique<Trk::MaterialEffectsOnTrack>(
4060  tInX0, scatAngles, std::make_unique<Trk::EnergyLoss>(std::move(energyLoss)),
4062  // push it to the material states
4063  cache.m_matstates->push_back(new TrackStateOnSurface(
4064  nullptr, cache.m_ownedPtrs.move(parsOnLayer), std::move(meot)));
4065  }
4066 }

◆ collectIntersections()

std::unique_ptr< std::vector< std::pair< std::unique_ptr< Trk::TrackParameters >, int > > > Trk::Extrapolator::collectIntersections ( const EventContext &  ctx,
const Trk::TrackParameters parm,
Trk::PropDirection  dir,
Trk::ParticleHypothesis  particle,
int  destination = 3 
) const
finaloverridevirtual

Extrapolation method collecting intersections with subdetector boundaries and active volumes/layers.

Destination (subdetector boundary) : geoID (+ entry, -exit) ( default Calo = 3 exit see GeometrySignature.h) Employs the STEP_propagator, used to create ParticleCaloExtensions mainly for muons and Particle Flow.

Implements Trk::IExtrapolator.

Definition at line 511 of file Extrapolator.cxx.

517 {
518  // extrapolation method intended for collection of intersections with active layers/volumes
519  // extrapolation stops at indicated geoID subdetector exit
520  Cache cache(m_propStat);
521  ++cache.m_methodSequence;
522  ATH_MSG_DEBUG("M-[" << cache.m_methodSequence << "] extrapolate(through active volumes), from "
523  << parm.position());
524  // reset the path
525  cache.m_path = 0.;
526  // initialize parameters vector
527  cache.m_identifiedParameters = std::make_unique<identifiedParameters_t>();
528  // dummy input
529  cache.m_currentStatic = nullptr;
530  const Trk::TrackingVolume* boundaryVol = nullptr;
531  // cleanup
532  cache.m_parametersAtBoundary.resetBoundaryInformation();
533  // Material effect updator cache
534  cache.populateMatEffUpdatorCache(m_subupdaters);
535  // extrapolate to subdetector boundary
536  auto *cloneInput = cache.m_ownedPtrs.push(parm.uniqueClone());
538  ctx, cache, cloneInput, -1., dir, particle, boundaryVol);
539 
540  while (subDetBounds) {
541  ATH_MSG_DEBUG(" Identified subdetector boundary crossing saved "
542  << positionOutput(subDetBounds->position()));
543  cache.m_identifiedParameters->push_back(std::pair<std::unique_ptr<Trk::TrackParameters>, int>(
544  subDetBounds->uniqueClone(),
545  cache.m_currentStatic ? cache.m_currentStatic->geometrySignature() : 0));
546  if (cache.m_currentStatic && cache.m_currentStatic->geometrySignature() == destination) {
547  break;
548  }
549  if (!cache.m_parametersAtBoundary.nextVolume) {
550  break; // world boundary
551  }
552  subDetBounds = extrapolateToVolumeWithPathLimit(
553  ctx, cache, subDetBounds, -1., dir, particle, boundaryVol);
554  }
555  if (cache.m_identifiedParameters->empty()) {
556  return nullptr;
557  }
558  return std::move(cache.m_identifiedParameters);
559 }

◆ declareGaudiProperty() [1/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyArrayType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKeyArray>

Definition at line 170 of file AthCommonDataStore.h.

172  {
173  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
174  hndl.value(),
175  hndl.documentation());
176 
177  }

◆ declareGaudiProperty() [2/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158  {
159  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
160  hndl.value(),
161  hndl.documentation());
162 
163  }

◆ declareGaudiProperty() [3/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleBase>

Definition at line 184 of file AthCommonDataStore.h.

186  {
187  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
188  hndl.value(),
189  hndl.documentation());
190  }

◆ declareGaudiProperty() [4/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  t,
const SG::NotHandleType  
)
inlineprivateinherited

specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray>

Definition at line 199 of file AthCommonDataStore.h.

200  {
201  return PBASE::declareProperty(t);
202  }

◆ declareProperty() [1/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleBase hndl,
const std::string &  doc,
const SG::VarHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation string for the property.

This is the version for types that derive from SG::VarHandleBase. The property value object is put on the input and output lists as appropriate; then we forward to the base class.

Definition at line 245 of file AthCommonDataStore.h.

249  {
250  this->declare(hndl.vhKey());
251  hndl.vhKey().setOwner(this);
252 
253  return PBASE::declareProperty(name,hndl,doc);
254  }

◆ declareProperty() [2/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKey hndl,
const std::string &  doc,
const SG::VarHandleKeyType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation string for the property.

This is the version for types that derive from SG::VarHandleKey. The property value object is put on the input and output lists as appropriate; then we forward to the base class.

Definition at line 221 of file AthCommonDataStore.h.

225  {
226  this->declare(hndl);
227  hndl.setOwner(this);
228 
229  return PBASE::declareProperty(name,hndl,doc);
230  }

◆ declareProperty() [3/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKeyArray hndArr,
const std::string &  doc,
const SG::VarHandleKeyArrayType  
)
inlineinherited

Definition at line 259 of file AthCommonDataStore.h.

263  {
264 
265  // std::ostringstream ost;
266  // ost << Algorithm::name() << " VHKA declareProp: " << name
267  // << " size: " << hndArr.keys().size()
268  // << " mode: " << hndArr.mode()
269  // << " vhka size: " << m_vhka.size()
270  // << "\n";
271  // debug() << ost.str() << endmsg;
272 
273  hndArr.setOwner(this);
274  m_vhka.push_back(&hndArr);
275 
276  Gaudi::Details::PropertyBase* p = PBASE::declareProperty(name, hndArr, doc);
277  if (p != 0) {
278  p->declareUpdateHandler(&AthCommonDataStore<PBASE>::updateVHKA, this);
279  } else {
280  ATH_MSG_ERROR("unable to call declareProperty on VarHandleKeyArray "
281  << name);
282  }
283 
284  return p;
285 
286  }

◆ declareProperty() [4/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc,
const SG::NotHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation string for the property.

This is the generic version, for types that do not derive from SG::VarHandleKey. It just forwards to the base class version of declareProperty.

Definition at line 333 of file AthCommonDataStore.h.

337  {
338  return PBASE::declareProperty(name, property, doc);
339  }

◆ declareProperty() [5/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc = "none" 
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation string for the property.

This dispatches to either the generic declareProperty or the one for VarHandle/Key/KeyArray.

Definition at line 352 of file AthCommonDataStore.h.

355  {
356  typedef typename SG::HandleClassifier<T>::type htype;
357  return declareProperty (name, property, doc, htype());
358  }

◆ declareProperty() [6/6]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > &  t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145  {
146  typedef typename SG::HandleClassifier<T>::type htype;
148  }

◆ detStore()

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

95 { return m_detStore; }

◆ evtStore() [1/2]

ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

85 { return m_evtStore; }

◆ evtStore() [2/2]

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( ) const
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 90 of file AthCommonDataStore.h.

90 { return m_evtStore; }

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase &  ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ extrapolate() [1/2]

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolate ( const EventContext &  ctx,
const TrackParameters parm,
const Surface sf,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise,
Trk::ExtrapolationCache cache = nullptr 
) const
finaloverridevirtual

Main extrapolation interface starting from charged parameters and aiming at Surface.

Implements Trk::IExtrapolator.

Definition at line 365 of file Extrapolator.cxx.

373 {
374  Cache cache(m_propStat);
375  // Material effect updator cache
376  Trk::CacheOwnedPtr<Trk::TrackParameters> clonedInput = cache.m_ownedPtrs.push(parm.uniqueClone());
377  cache.populateMatEffUpdatorCache(m_subupdaters);
378  return cache.m_ownedPtrs.move(extrapolateImpl(ctx, cache, clonedInput, sf,
379  dir, bcheck, particle,
380  matupmode, extrapolationCache));
381 }

◆ extrapolate() [2/2]

std::unique_ptr< Trk::NeutralParameters > Trk::Extrapolator::extrapolate ( const NeutralParameters parameters,
const Surface sf,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true 
) const
finaloverridevirtual

Main extrapolation Interface starting from neutral parameters and aiming at surface.

Implements Trk::IExtrapolator.

Definition at line 385 of file Extrapolator.cxx.

389 {
390  const IPropagator* currentPropagator =
391  !m_subPropagators.empty() ? m_subPropagators[Trk::Global] : nullptr;
392  if (currentPropagator) {
393  return currentPropagator->propagate(parameters, sf, dir, bcheck);
394  }
395  ATH_MSG_ERROR("[!] No default Propagator is configured !");
396  return nullptr;
397 }

◆ extrapolateBlindly()

Trk::TrackParametersUVector Trk::Extrapolator::extrapolateBlindly ( const EventContext &  ctx,
const TrackParameters parm,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion,
const Volume boundaryVol = nullptr 
) const
finaloverridevirtual

extrapolateBlindly like step-wise extrapolation, but without a destination surface.

Blind inside the given tracking Volume (boundaryVol). If none is give stops at last boundary surface of the known TrackingGeometry

Implements Trk::IExtrapolator.

Definition at line 447 of file Extrapolator.cxx.

453 {
454  const IPropagator* currentPropagator =
455  !m_subPropagators.empty() ? m_subPropagators[Trk::Global] : nullptr;
456 
457  if (currentPropagator) {
458  Cache cache(m_propStat);
459  Trk::CacheOwnedPtr<Trk::TrackParameters> clonedInput = cache.m_ownedPtrs.push(parm.uniqueClone());
460  cache.populateMatEffUpdatorCache(m_subupdaters);
461  return extrapolateBlindlyImpl(ctx, cache, (*currentPropagator),
462  clonedInput, dir, bcheck, particle,
463  boundaryVol);
464  }
465  ATH_MSG_ERROR(" [!] No default Propagator is configured !");
466  return {};
467 }

◆ extrapolateBlindlyImpl()

Trk::TrackParametersUVector Trk::Extrapolator::extrapolateBlindlyImpl ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion,
const Volume boundaryVol = nullptr 
) const
private

Actual heavy lifting implementation for extrapolateBlindly.

Definition at line 2621 of file Extrapolator.cxx.

2629 {
2630  // statistics && sequence output ----------------------------------------
2632  ++cache.m_methodSequence;
2633  ATH_MSG_DEBUG("F-[" << cache.m_methodSequence << "] extrapolateBlindly() ");
2634  // assign the boundaryVolume
2635  cache.m_boundaryVolume = boundaryVol;
2636  // initialize the return parameters vector
2637  // create a new internal helper vector
2639  //The m_parametersOnDetElements point to it
2640  cache.m_parametersOnDetElements = &tmp;
2641  // run the extrapolation
2642  {
2643  extrapolateImpl(ctx, cache, prop, parm, *m_referenceSurface, dir, bcheck, particle);
2644  }
2645  // reset the .m_parametersOnDetElements to point to nullptr
2646  cache.m_parametersOnDetElements = nullptr;
2647  // reset the boundary Volume
2648  cache.m_boundaryVolume = nullptr;
2649  // return what you have
2650  return tmp;
2651 }

◆ extrapolateDirectly()

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolateDirectly ( const EventContext &  ctx,
const TrackParameters parm,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion 
) const
finaloverridevirtual

Extrapolate directly: Forwards directly the call to the configured "Global" propagator.

No navigation and no material effecs. Useful when we need fast propagation without these.

Implements Trk::IExtrapolator.

Definition at line 346 of file Extrapolator.cxx.

352 {
353  const IPropagator* currentPropagator =
354  !m_subPropagators.empty() ? m_subPropagators[Trk::Global] : nullptr;
355  if (!currentPropagator) {
356  ATH_MSG_ERROR( "[!] No default Propagator is configured !");
357  return nullptr;
358  }
360  ctx, (*currentPropagator), parm, sf, dir, bcheck, particle);
361 }

◆ extrapolateDirectlyImpl()

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolateDirectlyImpl ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters parm,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion 
) const
private

Actual heavy lifting implementation for extrapolateDirectly.

Definition at line 1984 of file Extrapolator.cxx.

1991 {
1992  // statistics && sequence output ----------------------------------------
1994  return prop.propagate(ctx, parm, sf, dir, bcheck, m_fieldProperties, particle);
1995 }

◆ extrapolateFromLayerToLayer()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateFromLayerToLayer ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const TrackingVolume tvol,
const Layer nextLayer,
const Layer destinationLayer,
Trk::CacheOwnedPtr< Trk::TrackParameters navParameters,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Private method to step from one to the last layer and stop at last layer (before 0) or before destination layer.

Definition at line 3265 of file Extrapolator.cxx.

3277 {
3278  // method sequence output ---------------------------------
3279  ++cache.m_methodSequence;
3280  ATH_MSG_DEBUG("S-[" << cache.m_methodSequence << "] extrapolateFromLayerToLayer(...) in '"
3281  << tvol.volumeName() << "'. ");
3282 
3283  // initialize the loop
3284  const Trk::Layer* nextLayer = startLayer;
3285  // avoiding straight loops and oszillations
3286  const Trk::Layer* lastLayer = nullptr;
3287  const Trk::Layer* previousLayer = nullptr;
3288  // pars & fallback
3290  Trk::CacheOwnedPtr<Trk::TrackParameters> navParameters = navParm;
3291  // avoid initial perpendicular check if:
3292  // - navParameters and currPar have different perpendicular direction (resolved in navigaiton)
3293  bool perpCheck = radialDirection(*currPar, dir) * radialDirection(*navParameters, dir) > 0;
3294 
3295  // break conditions: --------- handeled by layerAttempts
3296  unsigned int failedAttempts = 0;
3297 
3298  // get the max attempts from the volume
3299  const unsigned int layersInVolume =
3300  tvol.confinedLayers() ? tvol.confinedLayers()->arrayObjects().size() : 0;
3301  // set the maximal attempts to at least m_initialLayerAttempts
3302  const unsigned int maxAttempts =
3304  static_cast<unsigned int>(layersInVolume * 0.5));
3305 
3306  ATH_MSG_VERBOSE(" [+] Maximum number of failed layer attempts: " << maxAttempts);
3307 
3308  // conditions for the loop are :
3309  // - nextLayer exists
3310  // - nextLayer is not the previous one, Exception : inbound cosmics
3311  // - nextLayer is not the last layer, Exception: formerly inbound cosmics
3312  // - nextLayer is not the destination layer
3313  // - the number of attempts does not exceed a set maximum
3314 
3315  while (nextLayer && nextLayer != previousLayer && nextLayer != lastLayer &&
3316  nextLayer != destinationLayer && failedAttempts < maxAttempts) {
3317  // screen output
3318  ATH_MSG_VERBOSE(" [+] Found next "
3319  << ((nextLayer->layerMaterialProperties() ? "material layer - with "
3320  : "navigation layer with "))
3321  << layerRZoutput(*nextLayer));
3322 
3323  // skip the navigation layers
3324  if (nextLayer->layerMaterialProperties() ||
3325  (cache.m_parametersOnDetElements && nextLayer->surfaceArray())) {
3326  // the next step - do not delete the parameters (garbage collection done by method)
3327  auto [new_track_parm, killed] = extrapolateToIntermediateLayer(
3328  ctx, cache, prop, currPar, *nextLayer, tvol, dir, bcheck, particle,
3329  matupmode, perpCheck);
3331  new_track_parm);
3332  // previous and last layer setting for loop and oscillation protection
3333  previousLayer = lastLayer;
3334  lastLayer = nextLayer;
3335  // the breaking condition ------------------------------------
3336  // check killed first because if killed is true nexPar will be invalid.
3337  if (killed) {
3338  ATH_MSG_VERBOSE(" [+] Material update killed the track parameters - return 0");
3339  // kill the track - Fatras case
3340  return {};
3341  } if (!nextPar) {
3342  ++failedAttempts;
3343  ++m_layerSwitched; // record for statistics output
3344  // reset until break condition is fullfilled
3345  } else if (cache.m_boundaryVolume && !cache.m_boundaryVolume->inside(nextPar->position())) {
3346  ATH_MSG_VERBOSE(" [+] Parameter outside the given boundary/world stopping loop.");
3347  // set the new boundary information
3348  return nextPar;
3349  } else { // reset the failed attempts
3350  ATH_MSG_VERBOSE(" [+] Intersection successful: allowing for " << maxAttempts
3351  << " more failed attempt.");
3352  failedAttempts = 0;
3353  // but a hit sets the max attempts to m_successiveLayerAttempts => navigation machine
3354  // started ! maxAttempts = m_successiveLayerAttempts; new navParameters are currPar
3355  navParameters = nextPar;
3356  currPar = nextPar;
3357  // enforce the perpendicular check
3358  perpCheck = true;
3359  }
3360  }
3361 
3362  // cache of radiatl direction and next layer request
3363  nextLayer =
3364  nextLayer->nextLayer(navParameters->position(), dir * navParameters->momentum().normalized());
3365 
3366  // screen output
3367  if (!nextLayer) {
3368  ATH_MSG_VERBOSE(" [+] No next Layer provided by the previous layer -> stop of layer2layer");
3369  }
3370  }
3371  if (failedAttempts >= maxAttempts) {
3372  ATH_MSG_VERBOSE(" [-] Maximum number of Attempts triggered in '" << tvol.volumeName() << "'.");
3373  }
3374 
3375  // return the result
3376  return currPar;
3377 }

◆ extrapolateImpl() [1/3]

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateImpl ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const std::vector< MaterialEffectsOnTrack > &  sfMeff,
const TrackingVolume tvol,
PropDirection  dir,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Actual heavy lifting implementation for extrapolate.

  • Extrapolation using specific intermediate surfaces and energy loss effects to be accounted for at each surface as specified by the corresponding MaterialEffectsOnTrack -Final boolean only relevant if LandauMode = true for the configured MaterialEffectsUpdator

Definition at line 2527 of file Extrapolator.cxx.

2536 {
2537  // statistics && sequence output ----------------------------------------
2538  if (cache.m_methodSequence) {
2539  ++cache.m_methodSequence;
2540  }
2541  ATH_MSG_DEBUG("D-[" << cache.m_methodSequence
2542  << "] extrapolate with given MaterialEffectsOnTrack in Volume '"
2543  << tvol.volumeName() << "'.");
2544 
2546 
2547  // loop over the provided material effects on track
2548  for (const MaterialEffectsOnTrack& a_sfMeff : sfMeff) {
2549  // first propagate to the given surface
2550  // nextParameters = prop.propagate(*nextParameters, sfMeffI->associatedSurface(),dir,true,tvol,
2551  // particle);
2552  Trk::CacheOwnedPtr<Trk::TrackParameters> nextPar = cache.m_ownedPtrs.push(
2553  prop.propagate(ctx, *currPar, a_sfMeff.associatedSurface(), dir, true,
2554  m_fieldProperties, particle, false, &tvol));
2555  // user might have not calculated well which surfaces are intersected ...
2556  // break if break
2557  if (!nextPar) {
2558  // only return track parameters if at least one iteration was successful
2559  return (currPar!= parm)
2560  ? currPar
2561  : nullptr;
2562  }
2563  currPar = nextPar;
2564  // then update
2565 
2566  const IMaterialEffectsUpdator* currentUpdator = subMaterialEffectsUpdator(tvol);
2567  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
2568  cache.subMaterialEffectsUpdatorCache(tvol);
2569 
2571  if (currentUpdator) {
2572  upNext = cache.m_ownedPtrs.push(currentUpdator->update(
2573  currentUpdatorCache, currPar, a_sfMeff, particle, matupmode));
2574  }
2575  if (!upNext) {
2576  // update killed the track or config problem. Return
2577  ATH_MSG_VERBOSE(" [+] Update killed track.");
2578  break;
2579  }
2580  currPar = upNext;
2581  }
2582  return currPar;
2583 }

◆ extrapolateImpl() [2/3]

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateImpl ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Actual heavy lifting implementation for extrapolate.

Definition at line 2090 of file Extrapolator.cxx.

2099 {
2100 
2101  // reset the destination surface
2102  cache.m_destinationSurface = nullptr;
2103  cache.m_lastValidParameters = nullptr;
2104  // skip rest of navigation if particle hypothesis is nonInteracting
2105  if (particle == Trk::nonInteracting) {
2106  if (cache.m_methodSequence) {
2107  ++cache.m_methodSequence; // extrapolateDirectly does not have the cache and cannot increment
2108  // m_methodSequence therefore do it here
2109  }
2110  return cache.m_ownedPtrs.push(extrapolateDirectlyImpl(ctx, prop, *parm, sf, dir, bcheck, particle));
2111  }
2112 
2113  // set the model action of the material effects updaters
2114  for (unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2115  if(m_subupdaters[imueot]){
2116  m_subupdaters[imueot]->modelAction((cache.m_MaterialUpCache[imueot]));
2117  }
2118  }
2119 
2120  // statistics && sequence output ----------------------------------------
2122  ++cache.m_methodSequence;
2123  // prepare the values for the startup and call the initialization
2124  // ------------------------------------------
2125  const Trk::TrackingVolume* startVolume = nullptr;
2126  const Trk::TrackingVolume* destVolume = nullptr;
2127  const Trk::Layer* nextLayer = nullptr;
2128  const Trk::TrackingVolume* nextVolume = nullptr;
2129  const Trk::TrackingVolume* lastVolume = nullptr;
2130  Trk::TrackParameters* refParameters = nullptr;
2131  Trk::TrackParameters* lastParameters = nullptr;
2132  Trk::TrackParameters* navParameters = nullptr;
2133  Trk::CacheOwnedPtr<Trk::TrackParameters> nextParameters = parm;
2134  // initialize Navigation (calls as well initialize on garbe collection)
2135  // -------------------------------------
2136  Trk::PropDirection const navDir =
2137  initializeNavigation(ctx, cache, prop, nextParameters, sf, dir, particle,
2138  refParameters, nextLayer, nextVolume, destVolume);
2139  // ----------------------------
2140  // if anyDirection has been chosen as a start directive:
2141  // -> overwrite the dir with the navigation direction
2142  dir = (dir == Trk::anyDirection) ? navDir : dir;
2143  // check for consistency
2144  if (dir == Trk::anyDirection || navDir != dir) {
2145  // navigation could not be resolved
2147  " [!] Navigation direction could not be resolved, switching to extrapolateDirectly()");
2148  // the extrapolate directly call
2149  ++cache.m_methodSequence; // extrapolateDirectly does not have the cache and cannot increment
2150  // m_methodSequence
2151  return cache.m_ownedPtrs.push(extrapolateDirectlyImpl(ctx, prop, *parm, sf, navDir, bcheck, particle));
2152  }
2153  // ------------------------------
2154  startVolume = nextVolume;
2155  // fallback setup -------------------------------------
2156  bool fallback = false;
2157  // ------- initial distance estimation ---------------
2158  double currentDistance = 0.;
2159  double previousDistance = 0.;
2160  // reference parameters and distance solution: use consistently one of each
2161  if (refParameters) {
2162  ATH_MSG_VERBOSE(" [+] Reference Parameters - at "
2163  << positionOutput(refParameters->position()));
2164  currentDistance = (refParameters->position() - parm->position()).mag();
2165  } else {
2166  // using fast but accureate sl distance from surface
2167  const Trk::DistanceSolution distSol =
2168  sf.straightLineDistanceEstimate(parm->position(), dir * parm->momentum().normalized());
2169  if (distSol.numberOfSolutions() > 0) {
2170  currentDistance = distSol.absClosest();
2171  } else {
2172  currentDistance = std::abs(distSol.toPointOfClosestApproach());
2173  }
2174  // VERBOSE output
2175  }
2176  ATH_MSG_VERBOSE(" [+] Initial 3D-distance to destination - d3 = " << currentDistance);
2177  // and for oscillation protection ----------------------------------------------------
2178  const Trk::TrackingVolume* previousVolume = nullptr;
2179  // -----------------------------------------------------------------------------------
2180 
2182  " [" << cache.m_methodSequence << "] extrapolate() "
2183  << ((nextVolume) ? nextVolume->volumeName() : "Unknown (ERROR)")
2184  << " -> "
2185  << (destVolume ? destVolume->volumeName()
2186  : "Unknown (blind extrapolation)"));
2187  ATH_MSG_VERBOSE(" [+] Starting position determined - at "
2188  << positionOutput(parm->position()));
2189  if (nextLayer) {
2190  ATH_MSG_VERBOSE(" [+] Starting layer determined - with " << layerRZoutput(*nextLayer));
2191  }
2192 
2193  // -----------------------------------------------------------------------------------
2194  const IPropagator* currentPropagator = nullptr;
2195  // ----------------- extrapolation from One Volume to the next Volume
2196  // -------------------------------------- the loop continues while:
2197  // - nextVolume extists
2198  // - nextVolume is different from lastVolume (prevent infinite loops)
2199  // - nextVolume is different from destinationVolume (change to extrapolateInsideVolume)
2200  // - nextParameters exist
2201  // - lastVolume is different from previousVolume (prevent oscillation loop,
2202  // one-time-punch-through allowed)
2203  // - the reinforced navigation can find destination parameters
2204  // - the maximum method sequence is not met
2205 
2206  // best starting parameters
2207  bool updateLastValid = true;
2208  // one-time-punch-through allows for volume2 - volume1 - volume2 (cosmics)
2209  bool punchThroughDone = false;
2210 
2211  auto navigationBreakOscillation = m_navigationBreakOscillation.buffer();
2212  auto navigationBreakNoVolume = m_navigationBreakNoVolume.buffer();
2213  auto navigationBreakDistIncrease = m_navigationBreakDistIncrease.buffer();
2214  auto navigationBreakVolumeSignature = m_navigationBreakVolumeSignature.buffer();
2215 
2216  while (nextVolume && nextVolume != destVolume && nextVolume != lastVolume && nextParameters &&
2217  cache.m_methodSequence < m_maxMethodSequence) {
2218  // chose the propagtor type
2219  currentPropagator = subPropagator(*nextVolume);
2220  if (!currentPropagator) {
2221  // [0] Navigation break : configuration problem or consistency problem of TrackingGeometry
2222  // output
2223  ATH_MSG_DEBUG(" [X] Navigation break [X]");
2224  ATH_MSG_DEBUG(" - Reason : No Propagator found for Volume '"
2225  << nextVolume->volumeName() << "'");
2226  // debug statistics
2228  // trigger the fallback solution
2229  fallback = true;
2230  break;
2231  }
2232 
2233  // check for the distance to destination
2234  // -------------------------------------------------------------
2235  if (updateLastValid) {
2236  cache.m_lastValidParameters = nextParameters;
2237  }
2238  // avoid the oszillation
2239  previousVolume = lastVolume;
2240  // for the next step to termine if infinite loop occurs
2241  lastVolume = nextVolume;
2242  // for memory cleanup and backup
2243  lastParameters = nextParameters;
2244 
2245  // MS specific code ------------------
2246  // extrapolation within detached volumes - returns parameters on destination surfaces, or
2247  // boundary solution handles also dense volume description in Calo and beam pipe
2248  if (nextVolume->geometrySignature() > 1) {
2249  if (cache.m_parametersAtBoundary.navParameters &&
2250  cache.m_parametersAtBoundary.navParameters !=
2251  cache.m_parametersAtBoundary.nextParameters) {
2252  // extrapolate to volume boundary to avoid navigation break
2254  cache.m_ownedPtrs.push(currentPropagator->propagate(
2255  ctx, *cache.m_parametersAtBoundary.nextParameters,
2256  cache.m_parametersAtBoundary.navParameters->associatedSurface(),
2257  dir, bcheck,
2258  // *previousVolume,
2259  m_fieldProperties, particle, false, previousVolume));
2260  // set boundary and next parameters
2261  cache.m_parametersAtBoundary.boundaryInformation(nextVolume, nextPar, nextPar);
2262  nextParameters = cache.m_parametersAtBoundary.nextParameters;
2263  navParameters = cache.m_parametersAtBoundary.navParameters;
2264  }
2265  // start from the nextParameter (which are at volume boundary)
2266  Trk::CacheOwnedPtr<Trk::TrackParameters> resultParameters = nullptr;
2267  if (nextParameters) {
2268  if (!m_stepPropagator) {
2269  ATH_MSG_ERROR(
2270  "extrapolation in Calo/MS called without configured STEP propagator, aborting");
2271  return {};
2272  }
2273  resultParameters = extrapolateWithinDetachedVolumes(
2274  ctx, cache, *m_stepPropagator, nextParameters, sf,
2275  *nextVolume, dir, bcheck, particle, matupmode);
2276  }
2277  if (resultParameters) {
2278  // destination reached : indicated through result parameters
2279  // set the model action of the material effects updaters
2280  for (unsigned int imueot = 0; imueot < m_subupdaters.size(); ++imueot) {
2281  if(m_subupdaters[imueot]){
2282  m_subupdaters[imueot]->modelAction((cache.m_MaterialUpCache[imueot]));
2283  }
2284  }
2285  // return the parameters at destination
2286  ATH_MSG_DEBUG(" [+] Destination surface successfully hit.");
2287  // return the result (succesful)
2288  return resultParameters;
2289  } if (!cache.m_parametersAtBoundary.nextParameters ||
2290  !cache.m_parametersAtBoundary.nextVolume ||
2291  cache.m_status != Cache::kContinue) {
2292  ATH_MSG_DEBUG(" [-] Destination surface could not be hit.");
2293  return resultParameters;
2294  }
2295  } else {
2296  // -------------------------------------------------------------------------
2297  // standard loop over volumes (but last one)
2298  // extrapolate to volume boundary - void method as 'cache.m_parametersAtBoundary' hold the
2299  // information
2301  cache,
2302  *currentPropagator,
2303  nextParameters,
2304  nextLayer,
2305  *nextVolume,
2306  dir,
2307  bcheck,
2308  particle,
2309  matupmode);
2310  }
2311  // go on with the next volume / get next Volume and Boundary from the private member
2312  nextVolume = cache.m_parametersAtBoundary.nextVolume;
2313  nextParameters = cache.m_parametersAtBoundary.nextParameters;
2314  navParameters = cache.m_parametersAtBoundary.navParameters;
2315  // new distance estimation ( after step to next volume ) -------------------------
2316  previousDistance = currentDistance;
2317  // make it either from the navParmaters (if the exist) or the nextParameters
2318  {
2319  const Trk::TrackParameters* distParameters =
2320  cache.m_parametersAtBoundary.navParameters
2321  ? cache.m_parametersAtBoundary.navParameters
2322  : nextParameters;
2323 
2324  if (distParameters) {
2325  // use consistently either the:
2326  // (A) reference parameters or the
2327  if (refParameters) {
2328  currentDistance = (refParameters->position() - distParameters->position()).mag();
2329  } else {
2330  // (B) distance solution to surface
2331  const Trk::DistanceSolution newDistSol = sf.straightLineDistanceEstimate(
2332  distParameters->position(), dir * distParameters->momentum().normalized());
2333  currentDistance = newDistSol.numberOfSolutions() > 0
2334  ? newDistSol.absClosest()
2335  : std::abs(newDistSol.toPointOfClosestApproach());
2336  }
2337  }
2338  }
2339  ATH_MSG_VERBOSE(" [+] New 3D-distance to destination - d3 = "
2340  << currentDistance << " (from "
2341  << (cache.m_parametersAtBoundary.navParameters
2342  ? "boundary parameters"
2343  : "last parameters within volume ")
2344  << ")");
2345 
2346  // --------------------------------------------------------------------------------
2347  // (1) NAVIGATION BREAK : next Volume is identical to last volume -- LOOP
2348  if (nextVolume == lastVolume && nextVolume) {
2349  // ST false when crossing beam pipe : additional check on step distance
2350  if (nextParameters && lastParameters &&
2351  (nextParameters->position() - lastParameters->position())
2352  .dot(lastParameters->momentum().normalized()) *
2353  dir >
2354  0.001) {
2355  } else {
2356  // output
2357  ATH_MSG_DEBUG(" [X] Navigation break [X]");
2358  if (nextParameters && lastParameters) {
2359  ATH_MSG_DEBUG(
2360  "last step:" << (nextParameters->position() - lastParameters->position()).mag());
2361  }
2362  ATH_MSG_DEBUG("- Reason : Loop detected in TrackingVolume '"
2363  << nextVolume->volumeName() << "'");
2364  // statistics
2366  // fallback flag
2367  fallback = true;
2368  // break it
2369  break;
2370  }
2371  }
2372  // (2) NAVIGATION BREAK : Oscillation
2373  else if (nextVolume == previousVolume && nextVolume) {
2374  // one time the loop oscillation has been allowed already
2375  if (punchThroughDone) {
2376  // output
2377  ATH_MSG_DEBUG(" [X] Navigation break [X]");
2378  ATH_MSG_DEBUG("- Reason : Oscillation detected in TrackingVolume '"
2379  << nextVolume->volumeName() << "'");
2380  // statistics
2381  ++navigationBreakOscillation;
2382  // fallback flag
2383  fallback = true;
2384  // break it
2385  break;
2386  }
2387  // set the punch-through to true
2388  punchThroughDone = true;
2389  ATH_MSG_DEBUG(" [!] One time punch-through a volume done.");
2390 
2391  }
2392  // ------------------- the output interpretationn of the extrapolateToVolumeBoundary
2393  // (3) NAVIGATION BREAK : no nextVolume found - but not in extrapolateBlindly() mode
2394  else if (!nextVolume && !cache.m_parametersOnDetElements && lastVolume &&
2396  // output
2397  ATH_MSG_VERBOSE(" [X] Navigation break [X]");
2398  ATH_MSG_VERBOSE("- Reason : No next volume found of TrackingVolume '"
2399  << lastVolume->volumeName() << "'");
2400  // statistics
2401  ++navigationBreakNoVolume;
2402  // record the "no next" volume -- increase the counter for the (last) volume
2403  // fallback flag
2404  fallback = true;
2405  // break it
2406  break;
2407  }
2408  // ------------------- the output interpretationn of the extrapolateToVolumeBoundary
2409  // (4) NAVIGATION BREAK : // nextParameters found but distance to surface increases
2410  else if (nextParameters && !cache.m_parametersOnDetElements && navParameters && nextVolume &&
2411  currentDistance > s_distIncreaseTolerance + previousDistance) {
2412  // output
2413  ATH_MSG_DEBUG(" [X] Navigation break [X]");
2414  ATH_MSG_DEBUG(" - Reason : Distance increase [ "
2415  << previousDistance << " to " << currentDistance << "] in TrackingVolume '"
2416  << nextVolume->volumeName() << "'");
2417  // statistics
2418  ++navigationBreakDistIncrease;
2419  // record the "dist increase" volume -- increase the counter for the volume
2420  // fallback flag
2421  fallback = true;
2422  break;
2423  }
2424  // ------------------- the output interpretationn of the extrapolateToVolumeBoundary
2425  // (+) update killed track
2426  else if ((!nextParameters && m_stopWithUpdateZero) || !nextVolume) {
2427  ATH_MSG_DEBUG(" [+] Navigation stop : either the update killed the "
2428  "track, or end of detector/boundary volume reached");
2429  return {};
2430  }
2431  // ------------------- the output interpretationn of the extrapolateToVolumeBoundary
2432  // (+) end of extrapolate blindly(volume*)
2433  else if (cache.m_boundaryVolume && navParameters &&
2434  !(cache.m_boundaryVolume->inside(navParameters->position()))) {
2435  ATH_MSG_DEBUG(
2436  " [+] Navigation stop : next navigation step would lead outside given boundary volume");
2437  return {};
2438  }
2439  // ------------------- the output interpretationn of the extrapolateToVolumeBoundary
2440  // (5) NAVIGATION BREAK : // nextParameters found but distance to surface increases
2441  else if (nextVolume) {
2442  ATH_MSG_DEBUG(" [+] next Tracking Volume = " << nextVolume->volumeName());
2443  }
2444  // set validity of last parameters to cache ------------------------------------------
2445  updateLastValid = !nextParameters || cache.m_parametersOnDetElements || !navParameters ||
2446  !nextVolume || currentDistance <= previousDistance;
2447  // reset
2448  if (!nextParameters) {
2449  nextParameters = lastParameters;
2450  }
2451  // one volume step invalidates the nextLayer information
2452  nextLayer = nullptr;
2453  }
2454 
2455  // ------------------- fallback was triggered in volume to volume loop
2456  // --------------------------------------
2457  if (fallback) {
2458  // continue with the output
2459  ATH_MSG_DEBUG(" - Consequence : " << (m_stopWithNavigationBreak
2460  ? "return 0 (configured) "
2461  : "switch to extrapolateDirectly() "));
2462  // stop with navigaiton break or zero update
2464  return {};
2465  }
2466  if (cache.m_lastValidParameters && lastVolume) {
2467  currentPropagator = subPropagator(*lastVolume);
2468  }
2469  if (!currentPropagator) {
2470  return {};
2471  }
2472  // create the result now
2473  Trk::CacheOwnedPtr<Trk::TrackParameters> resultParameters =
2474  cache.m_ownedPtrs.push(currentPropagator->propagate(
2475  ctx, *cache.m_lastValidParameters, sf, Trk::anyDirection, bcheck,
2476  m_fieldProperties, particle, false, lastVolume));
2477  // desperate try
2478  if (!resultParameters) {
2479  resultParameters = cache.m_ownedPtrs.push(currentPropagator->propagate(
2480  ctx, *parm, sf, dir, bcheck, m_fieldProperties, particle, false,
2481  startVolume));
2482  }
2483  return resultParameters;
2484  }
2485 
2486  // ----------------- this is the exit of the extrapolateBlindly() call
2487  // --------------------------------------
2488  if ((&sf) == (m_referenceSurface.get())) {
2489  return {};
2490  }
2491 
2492  // ---------------- extrapolation inside the Volume -----------------------------------
2493  // Trk::CacheOwnedPtr<Trk::TrackParameters> finalNextParameters(cache.trackParmContainer(),nextParameters);
2494  Trk::CacheOwnedPtr<Trk::TrackParameters> finalNextParameters = nextParameters;
2495  ATH_MSG_DEBUG("create finalNextParameters " << *finalNextParameters);
2496  Trk::CacheOwnedPtr<Trk::TrackParameters> resultParameters = nullptr;
2497  if (nextVolume) {
2498  // chose the propagator fromt he geometry signature
2499  currentPropagator = subPropagator(*nextVolume);
2500  // extrapolate inside the volume
2501  if (currentPropagator) {
2502  resultParameters = extrapolateInsideVolume(
2503  ctx, cache, *currentPropagator, nextParameters, sf, nextLayer,
2504  *nextVolume, dir, bcheck, particle, matupmode);
2505  }
2506  }
2507  // -------------------------------------------------------------------------------------
2508  // the final - desperate backup --- just try to hit the surface
2509  if (!resultParameters && !m_stopWithNavigationBreak && !m_stopWithUpdateZero) {
2510  if (finalNextParameters)
2511  ATH_MSG_DEBUG("propagate using parameters " << *finalNextParameters);
2512  else {
2513  ATH_MSG_DEBUG("no finalNextParameters, bailing out of extrapolateDirectly");
2514  return {};
2515  }
2516  ATH_MSG_DEBUG(" [-] Fallback to extrapolateDirectly triggered ! ");
2517  resultParameters = cache.m_ownedPtrs.push(
2518  prop.propagate(ctx, *finalNextParameters, sf, dir, bcheck,
2519  // *startVolume,
2520  m_fieldProperties, particle, false, startVolume));
2521  }
2522  // return whatever you have
2523  return resultParameters;
2524 }

◆ extrapolateImpl() [3/3]

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateImpl ( const EventContext &  ctx,
Cache cache,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Surface sf,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise,
Trk::ExtrapolationCache extrapolationCache = nullptr 
) const
privatevirtual

Actual heavy lifting implementation for extrapolate.

Definition at line 2586 of file Extrapolator.cxx.

2595 {
2596  cache.m_extrapolationCache = extrapolationCache;
2597  cache.m_cacheEloss = extrapolationCache ? extrapolationCache->eloss() : nullptr;
2598 
2599  if (extrapolationCache && m_dumpCache) {
2600  ATH_MSG_DEBUG(" In extrapolate cache pointer input: " << extrapolationCache
2601  << " cache.m_extrapolationCache "
2602  << cache.m_extrapolationCache);
2603  if (cache.m_extrapolationCache) {
2604  ATH_MSG_DEBUG(cache.to_string(" In extrapolate "));
2605  }
2606  }
2607 
2608  // chose the propagator fromt he geometry signature -- start with default
2609  const IPropagator* currentPropagator =
2610  !m_subPropagators.empty() ? m_subPropagators[Trk::Global] : nullptr;
2611  if (currentPropagator) {
2612  return extrapolateImpl(ctx, cache, (*currentPropagator), parm, sf, dir,
2613  bcheck, particle, matupmode);
2614  }
2615  ATH_MSG_ERROR(
2616  " [!] No default Propagator is configured ! Please check jobOptions.");
2617  return {};
2618 }

◆ extrapolateInAlignableTV()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateInAlignableTV ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Trk::Surface destSurf,
const Trk::AlignableTrackingVolume vol,
PropDirection  dir,
ParticleHypothesis  particle = pion 
) const
private

Definition at line 1742 of file Extrapolator.cxx.

1750 {
1751  ++cache.m_methodSequence;
1752  ATH_MSG_DEBUG("M-[" << cache.m_methodSequence << "] extrapolateInAlignableTV(...) ");
1753 
1754  // material loop in sensitive Calo volumes
1755  // extrapolation without target surface returns:
1756  // A) boundary parameters (static volume boundary)
1757  // if target surface:
1758  // B) trPar at target surface
1759  // material collection done by the propagator ( binned material used )
1760 
1761  // initialize the return parameters vector
1763  const Trk::AlignableTrackingVolume* staticVol = nullptr;
1764  const Trk::TrackingVolume* currVol = nullptr;
1765  const Trk::TrackingVolume* nextVol = nullptr;
1766  std::vector<unsigned int> solutions;
1767  const Trk::TrackingVolume* assocVol = nullptr;
1768  // double tol = 0.001;
1769  // double path = 0.;
1770  // set tracking geometry in cache
1771  cache.setTrackingGeometry(*m_navigator,ctx);
1772  if (!cache.m_highestVolume) {
1773  cache.m_highestVolume = m_navigator->highestVolume(ctx);
1774  }
1775 
1776  // verify current position
1777  const Amg::Vector3D gp = parm->position();
1778  if (vol && vol->inside(gp, m_tolerance)) {
1779  staticVol = vol;
1780  } else {
1781  currVol = cache.m_trackingGeometry->lowestStaticTrackingVolume(gp);
1782  const Trk::TrackingVolume* nextStatVol = nullptr;
1783  if (m_navigator->atVolumeBoundary(currPar, currVol, dir, nextStatVol, m_tolerance) &&
1784  nextStatVol != currVol) {
1785  currVol = nextStatVol;
1786  }
1787  if (currVol && currVol != vol) {
1788  if (currVol->isAlignable()) {
1789  const Trk::AlignableTrackingVolume* aliTG =
1790  static_cast<const Trk::AlignableTrackingVolume*>(currVol);
1791  staticVol = aliTG;
1792  }
1793  }
1794  }
1795 
1796  if (!staticVol) {
1797  ATH_MSG_DEBUG(" [!] failing in retrieval of AlignableTV, return 0");
1798  return {};
1799  }
1800 
1801  // save volume entry if collection present
1802  if (cache.m_identifiedParameters) {
1803  const Trk::BinnedMaterial* binMat = staticVol->binnedMaterial();
1804  if (binMat) {
1805  const Trk::IdentifiedMaterial* binIDMat = binMat->material(currPar->position());
1806  if (binIDMat->second > 0) {
1807  std::unique_ptr<Trk::TrackParameters> identified_parm = currPar->uniqueClone();
1808  cache.m_identifiedParameters->push_back(
1809  std::pair<std::unique_ptr<Trk::TrackParameters>, int>(std::move(identified_parm), binIDMat->second));
1810  }
1811  }
1812  }
1813 
1814  // navigation surfaces
1815  if (cache.m_navigSurfs.capacity() > m_maxNavigSurf) {
1816  cache.m_navigSurfs.reserve(m_maxNavigSurf);
1817  }
1818  cache.m_navigSurfs.clear();
1819 
1820  if (destSurf) {
1821  cache.m_navigSurfs.emplace_back(destSurf, false);
1822  }
1823 
1824  // assume new static volume, retrieve boundaries
1825  cache.m_currentStatic = staticVol;
1826  cache.retrieveBoundaries();
1827 
1828  cache.m_navigSurfs.insert(
1829  cache.m_navigSurfs.end(), cache.m_staticBoundaries.begin(), cache.m_staticBoundaries.end());
1830 
1831  // current dense
1832  cache.m_currentDense = staticVol;
1833 
1834  // ready to propagate
1835  // till: A/ static volume boundary(bcheck=true) , B/ destination surface(bcheck=false)
1836 
1837  nextVol = nullptr;
1838  while (currPar) {
1839  double path = 0.;
1840  std::vector<unsigned int> solutions;
1841  // propagate now
1842  ATH_MSG_DEBUG(" [+] Starting propagation at position "
1843  << positionOutput(currPar->position())
1844  << " (current momentum: " << currPar->momentum().mag() << ")");
1845  ATH_MSG_DEBUG(" [+] " << cache.m_navigSurfs.size() << " target surfaces in '"
1846  << cache.m_currentDense->volumeName() << "'.");
1847  // arguments : inputParameters, vector of navigation surfaces, propagation direction, b field
1848  // service, particle
1849  // type, result,
1850  // material collection, intersection collection, path limit, switch for use of path limit,
1851  // switch for curvilinear on return, current TG volume
1852  if (m_dumpCache && cache.m_extrapolationCache) {
1853  ATH_MSG_DEBUG(" prop.propagateM " << cache.m_extrapolationCache);
1854  }
1855  identifiedParameters_t* intersections = cache.m_identifiedParameters.get();
1856  Trk::CacheOwnedPtr<Trk::TrackParameters> nextPar = cache.m_ownedPtrs.push(prop.propagateM(
1857  ctx, *currPar, cache.m_navigSurfs, dir, m_fieldProperties, particle,
1858  solutions, cache.m_matstates, intersections, path, false, false,
1859  cache.m_currentDense, cache.m_extrapolationCache));
1860 
1861  if (nextPar) {
1862  ++cache.m_nPropagations;
1863  ATH_MSG_DEBUG(" [+] Position after propagation - at "
1864  << positionOutput(nextPar->position()));
1865  ATH_MSG_DEBUG(" [+] Number of intersection solutions: " << solutions.size());
1866  // destination surface
1867  if (destSurf && solutions[0] == 0) {
1868  return nextPar;
1869  }
1870  if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1871  return nextPar;
1872  }
1873  // destination surface missed ?
1874  if (destSurf) {
1875  double dist = 0.;
1876  const Trk::DistanceSolution distSol = destSurf->straightLineDistanceEstimate(
1877  nextPar->position(), nextPar->momentum().normalized());
1878  if (distSol.numberOfSolutions() > 0) {
1879  dist = distSol.first();
1880  if (distSol.numberOfSolutions() > 1 && std::abs(dist) < m_tolerance) {
1881  dist = distSol.second();
1882  }
1883  if (distSol.numberOfSolutions() > 1 && dist * dir < 0. && distSol.second() * dir > 0.) {
1884  dist = distSol.second();
1885  }
1886  } else {
1887  dist = distSol.toPointOfClosestApproach();
1888  }
1889  if (dist * dir < 0.) {
1890  ATH_MSG_DEBUG(" [+] Destination surface missed ? " << dist << "," << dir);
1891  cache.m_parametersAtBoundary.resetBoundaryInformation();
1892  return {};
1893  }
1894  ATH_MSG_DEBUG(" [+] New 3D-distance to destinatiion - d3 = " << dist * dir);
1895  }
1896 
1897  int const iDest = destSurf ? 1 : 0;
1898  unsigned int iSol = 0;
1899  while (iSol < solutions.size()) {
1900  if (solutions[iSol] < iDest + cache.m_staticBoundaries.size()) {
1901  // TODO if massive boundary coded, add the material effects here
1902  // static volume boundary; return to the main loop : TODO move from misaligned to static
1903  const unsigned int index = solutions[iSol] - iDest;
1904  // use global coordinates to retrieve attached volume (just for static!)
1905  nextVol = (cache.m_currentStatic->boundarySurfaces())[index]->attachedVolume(
1906  nextPar->position(), nextPar->momentum(), dir);
1907  // double check the next volume
1908  if (nextVol &&
1909  !(nextVol->inside(nextPar->position() + 0.01 * dir * nextPar->momentum().normalized(),
1910  m_tolerance))) {
1911  ATH_MSG_DEBUG(" [!] WARNING: wrongly assigned static volume ?"
1912  << cache.m_currentStatic->volumeName() << "->" << nextVol->volumeName());
1913  nextVol = cache.m_trackingGeometry->lowestStaticTrackingVolume(
1914  nextPar->position() + 0.01 * nextPar->momentum().normalized());
1915  if (nextVol) {
1916  ATH_MSG_DEBUG(" new search yields: " << nextVol->volumeName());
1917  }
1918  }
1919  // end double check - to be removed after validation of the geometry gluing
1920  // lateral exit from calo sample can be handled here
1921  if (cache.m_identifiedParameters) {
1922  const Trk::BinnedMaterial* binMat = staticVol->binnedMaterial();
1923  if (binMat) {
1924  const Trk::IdentifiedMaterial* binIDMat = binMat->material(nextPar->position());
1925  // save only if entry to the sample present, the exit missing and non-zero step in the
1926  // sample
1927  if (binIDMat && binIDMat->second > 0 && !cache.m_identifiedParameters->empty() &&
1928  cache.m_identifiedParameters->back().second == binIDMat->second) {
1929  const double s =
1930  (nextPar->position() - cache.m_identifiedParameters->back().first->position())
1931  .mag();
1932  if (s > 0.001) {
1933  std::unique_ptr<Trk::TrackParameters> identified_parm = nextPar->uniqueClone();
1934  cache.m_identifiedParameters->push_back(
1935  std::pair<std::unique_ptr<Trk::TrackParameters>, int>(std::move(identified_parm),
1936  -binIDMat->second));
1937  }
1938  }
1939  }
1940  }
1941  // end lateral exit handling
1942  if (nextVol != cache.m_currentStatic) {
1943  cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
1944  ATH_MSG_DEBUG(" [+] StaticVol boundary reached of '"
1945  << cache.m_currentStatic->volumeName() << "'.");
1946  if (m_navigator->atVolumeBoundary(
1947  nextPar, cache.m_currentStatic, dir, assocVol, m_tolerance) &&
1948  assocVol != cache.m_currentStatic) {
1949  cache.m_currentDense = m_useMuonMatApprox ? nextVol : cache.m_highestVolume;
1950  }
1951  // no next volume found --- end of the world
1952  if (!nextVol) {
1953  ATH_MSG_DEBUG(" [+] Word boundary reached - at "
1954  << positionOutput(nextPar->position()));
1955  }
1956  // next volume found and parameters are at boundary
1957  if (nextVol && nextPar) {
1958  ATH_MSG_DEBUG(" [+] Crossing to next volume '" << nextVol->volumeName() << "'");
1959  ATH_MSG_DEBUG(" [+] Crossing position is - at "
1960  << positionOutput(nextPar->position()));
1961  if (!destSurf) {
1962  return nextPar; // return value differs between e->surface (cached boundary values
1963  // used)
1964  }
1965  // implicit : parameters at boundary returned
1966  }
1967  return {};
1968  }
1969  }
1970  iSol++;
1971  }
1972  } else {
1973  ATH_MSG_DEBUG(" [!] Propagation failed, return 0");
1974  cache.m_parametersAtBoundary.boundaryInformation(cache.m_currentStatic, nextPar, nextPar);
1975  return {};
1976  }
1977  currPar = nextPar;
1978  }
1979 
1980  return {};
1981 }

◆ extrapolateInsideVolume()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateInsideVolume ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Surface sf,
const Layer associatedLayer,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Private method for extrapolation in final volume to destination surface.

  • Parameters are: IPropagator& prop ... propagator to be used TrackParameters& parm ... starting parameters Surface& sf ... destination surface TrackingVolume& ... the initial volume Layer* associatedLayer ... layer associatiated with starting parameters (steers postupdate) PropDirection dir ... propagation direction const BoundaryCheck& bcheck ... boolean for bounday check ParticleHypothesis particle ... the particle hypothesis std::vector<const TrackParameters*>* dethits ... for blind extrapolation

it will call:

Definition at line 2655 of file Extrapolator.cxx.

2666 {
2667  // ---> C) detached volumes exist
2668  if (!tvol.confinedDetachedVolumes().empty()) {
2670  ctx, cache, prop, parm, sf, tvol, dir, bcheck, particle, matupmode);
2671  }
2672  // ---> A) static layers exist
2673  return insideVolumeStaticLayers(
2674  ctx, cache, false, prop, parm, assocLayer, tvol, dir, bcheck, particle, matupmode);
2675 }

◆ extrapolateM()

std::vector< const Trk::TrackStateOnSurface * > * Trk::Extrapolator::extrapolateM ( const EventContext &  ctx,
const TrackParameters parameters,
const Surface sf,
PropDirection  dir,
const BoundaryCheck bcheck,
ParticleHypothesis  particle = pion,
Trk::ExtrapolationCache cache = nullptr 
) const
finaloverridevirtual

Extrapolate to a destination surface, while collecting all the material layers in between.

Useful for chi2 based tracking.

Implements Trk::IExtrapolator.

Definition at line 471 of file Extrapolator.cxx.

478 {
479 
480  Cache cache(m_propStat);
481  // Material effect updator cache
482  cache.populateMatEffUpdatorCache(m_subupdaters);
483  ATH_MSG_DEBUG("C-[" << cache.m_methodSequence << "] extrapolateM()");
484  // create a new vector for the material to be collected
485  cache.m_matstates = new std::vector<const Trk::TrackStateOnSurface*>;
486  if (m_dumpCache && extrapolationCache) {
487  ATH_MSG_DEBUG(" extrapolateM pointer extrapolationCache " << extrapolationCache << " x0tot "
488  << extrapolationCache->x0tot());
489  }
490  // collect the material
491  Trk::CacheOwnedPtr<Trk::TrackParameters> clonedInput = cache.m_ownedPtrs.push(parm.uniqueClone());
492  Trk::CacheOwnedPtr<Trk::TrackParameters> parameterAtDestination =
493  extrapolateImpl(ctx, cache, clonedInput, sf, dir, bcheck, particle,
494  Trk::addNoise, extrapolationCache);
495  if (parameterAtDestination) {
496  ATH_MSG_VERBOSE(" [+] Adding the destination surface to the TSOS vector in extrapolateM() ");
497  cache.m_matstates->push_back(new TrackStateOnSurface(
498  nullptr, cache.m_ownedPtrs.move(parameterAtDestination), nullptr));
499  } else {
500  ATH_MSG_VERBOSE(" [-] Destination surface was not hit extrapolateM()");
501  }
502  // assign the temporary states
503  std::vector<const Trk::TrackStateOnSurface*>* tmpMatStates = cache.m_matstates;
504  cache.m_matstates = nullptr;
505  // retunr the material states
506  return tmpMatStates;
507 }

◆ extrapolateStepwise()

Trk::TrackParametersUVector Trk::Extrapolator::extrapolateStepwise ( const EventContext &  ctx,
const TrackParameters parm,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion 
) const
finaloverridevirtual

Extrapolation method where a step-wise navigation to the destination surface is performed.

Returns a vector parameters on all detector elements. Used mainly by the hole-search

Implements Trk::IExtrapolator.

Definition at line 401 of file Extrapolator.cxx.

407 {
408 
409  const IPropagator* currentPropagator =
410  !m_subPropagators.empty() ? m_subPropagators[Trk::Global] : nullptr;
411  if (currentPropagator) {
412  return extrapolateStepwiseImpl(ctx, (*currentPropagator), parm, sf, dir,
413  bcheck, particle);
414  }
416  " [!] No default Propagator is configured !");
417  return {};
418 }

◆ extrapolateStepwiseImpl()

Trk::TrackParametersUVector Trk::Extrapolator::extrapolateStepwiseImpl ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters parm,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion 
) const
private
  • Actual heavy lifting implementation for extrapolateStepwise
  • returns a vector of TrackParameters representing the tracking detector elements hit in between and the TrackParameters at the destination Surface (if final extrapolation suceeds), empty if the extrapolation to the destination surface does not suceed

Definition at line 615 of file Extrapolator.cxx.

621  {
622 
623  Cache cache(m_propStat);
624  // statistics && sequence output ----------------------------------------
626  ++cache.m_methodSequence;
627  ATH_MSG_DEBUG("F-[" << cache.m_methodSequence << "] extrapolateStepwise(...) ");
628  // initialize the return parameters vector
629  // create a new internal helper vector
631  //The m_parametersOnDetElements point to it
632  cache.m_parametersOnDetElements = &tmp;
633  // Material effect updator cache
634  cache.populateMatEffUpdatorCache(m_subupdaters);
636  Trk::CacheOwnedPtr<Trk::TrackParameters> clonedInput = cache.m_ownedPtrs.push(parm.uniqueClone());
637  // run the extrapolation
639  ctx, cache, prop, clonedInput, sf, dir, bcheck, particle);
640  // assign the return parameter and set cache.m_parametersOnDetElements = 0;
641  if (parameterOnSf) {
642  tmp.emplace_back(cache.m_ownedPtrs.move(parameterOnSf));
643  } else {
644  tmp.clear();
645  }
646  //m_parametersOnDetElements point to nullptr
647  cache.m_parametersOnDetElements = nullptr;
648  return tmp;
649 }

◆ extrapolateToDestinationLayer()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateToDestinationLayer ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Surface sf,
const Layer lay,
const TrackingVolume tvol,
const Layer startLayer,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Private to extrapolate to the destination layer + surface.

Definition at line 3380 of file Extrapolator.cxx.

3392 {
3393  // method sequence output ---------------------------------
3394  ++cache.m_methodSequence;
3395  ATH_MSG_DEBUG("S-[" << cache.m_methodSequence << "] extrapolateToDestinationLayer(...) in '"
3396  << tvol.volumeName() << "'.");
3397  // start is destination layer -> on layer navigation, take care
3398  const bool startIsDestLayer = startLayer == (&lay);
3399 
3400  // get the Parameters on the destination surface
3401  Trk::CacheOwnedPtr<Trk::TrackParameters> destParameters = cache.m_ownedPtrs.push(prop.propagate(
3402  ctx, *parm, sf, dir, bcheck, MagneticFieldProperties(), particle));
3403  // fallback to anyDirection
3404  if (!destParameters) {
3405  destParameters = cache.m_ownedPtrs.push(
3406  prop.propagate(ctx, *parm, sf, Trk::anyDirection, bcheck,
3408  }
3409 
3410  // return the pre-updated ones
3411  const IMaterialEffectsUpdator* currentUpdator = subMaterialEffectsUpdator(tvol);
3412  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
3413  cache.subMaterialEffectsUpdatorCache(tvol);
3414 
3415  Trk::CacheOwnedPtr<Trk::TrackParameters> preUpdatedParameters = nullptr;
3416  if (currentUpdator && destParameters && !startIsDestLayer) {
3417  preUpdatedParameters = cache.m_ownedPtrs.push(currentUpdator->preUpdate(
3418  currentUpdatorCache, destParameters, lay, dir, particle, matupmode));
3419  } else {
3420  preUpdatedParameters = destParameters;
3421  }
3422 
3423  // collect the material : either for extrapolateM or for the valdiation
3424  if (cache.m_matstates && preUpdatedParameters &&
3425  currentUpdator && !startIsDestLayer &&
3426  lay.preUpdateMaterialFactor(*destParameters, dir) >= 0.01) {
3428  ctx, cache, prop, preUpdatedParameters, lay, tvol, dir, particle);
3429  }
3430 
3431  // call the overlap search on the destination parameters - we are at the surface already
3432  if (cache.m_parametersOnDetElements && preUpdatedParameters && lay.surfaceArray()) {
3433  ATH_MSG_VERBOSE(" [o] Calling overlapSearch() on destination layer.");
3434  // start is destination layer
3435  overlapSearch(ctx, cache, prop, parm, preUpdatedParameters, lay, tvol, dir,
3436  bcheck, particle, startIsDestLayer);
3437  }
3438 
3439  if (preUpdatedParameters) {
3440  ATH_MSG_VERBOSE(" [+] Destination surface successfully hit.");
3441  }
3442 
3443  // return the pre-updated parameters (can be 0 though)
3444  return preUpdatedParameters;
3445 }

◆ extrapolateToIntermediateLayer()

std::pair< Trk::CacheOwnedPtr< Trk::TrackParameters >, bool > Trk::Extrapolator::extrapolateToIntermediateLayer ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Layer lay,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise,
bool  perpendicularCheck = true 
) const
private

Private to extrapolate to the destination layer + surface, special treatment for exit layer.

Returns
valid track parameters or nullptr, as first element and in case of nullptr as second element true to indicate to kill the loop from material update(?)

Definition at line 3448 of file Extrapolator.cxx.

3459 {
3460  // method sequence output ---------------------------------
3461  ++cache.m_methodSequence;
3462  ATH_MSG_DEBUG("S-[" << cache.m_methodSequence << "] to extrapolateToIntermediateLayer(...) layer "
3463  << lay.layerIndex() << " in '" << tvol.volumeName() << "'.");
3464 
3465  // chose the current updator
3466  const IMaterialEffectsUpdator* currentUpdator = subMaterialEffectsUpdator(tvol);
3467  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
3468  cache.subMaterialEffectsUpdatorCache(tvol);
3469  // then go onto the Layer
3470  Trk::CacheOwnedPtr<Trk::TrackParameters> parsOnLayer = nullptr;
3471 
3472  parsOnLayer = cache.m_ownedPtrs.push(
3473  prop.propagate(ctx, *parm, lay.surfaceRepresentation(), dir, true,
3475 
3476  // return if there is nothing to do
3477  if (!parsOnLayer) {
3478  return std::make_pair(nullptr, false);
3479  }
3480  // the layer has been intersected -----------------------------------------------------
3481  // check for radial direction change ----------------------------------------------
3482  int const rDirection = radialDirection(*parm, dir);
3483  int const newrDirection = radialDirection(*parsOnLayer, dir);
3484  if (newrDirection != rDirection && doPerpCheck) {
3485  // it is unfortunate that the cancelling could invalidate the material collection
3486  ATH_MSG_DEBUG(" [!] Perpendicular direction of track has changed -- checking");
3487  // reset the nextParameters if the radial change is not allowed
3488  // resetting is ok - since the parameters are in the garbage bin already
3489  if (!radialDirectionCheck(ctx, prop, *parm, *parsOnLayer, tvol, dir, particle)) {
3490  ATH_MSG_DEBUG(" [+] Perpendicular direction check cancelled this layer intersection.");
3491  return std::make_pair(Trk::CacheOwnedPtr<Trk::TrackParameters>(), false);
3492  }
3493  }
3494  // ----------------------------------------------------------------------------------
3495  ATH_MSG_VERBOSE(" [+] Layer intersection successful at "
3496  << positionOutput(parsOnLayer->position()));
3497  ATH_MSG_VERBOSE(" [+] Layer intersection successful with "
3498  << momentumOutput(parsOnLayer->momentum()));
3499 
3500  // Fatras mode -----------------------------------------------------------------------
3501  if (cache.m_parametersOnDetElements && lay.surfaceArray()) {
3502  // ceck the parameters size before the search
3503  size_t const sizeBeforeSearch = cache.m_parametersOnDetElements->size();
3504  // perform the overlap Search on this layer
3505  ATH_MSG_VERBOSE(" [o] Calling overlapSearch() on intermediate layer.");
3506  overlapSearch(ctx, cache, prop, parm, parsOnLayer, lay, tvol, dir, bcheck, particle);
3507  size_t const sizeAfterSearch = cache.m_parametersOnDetElements->size();
3508  // the Fatras mode was successful -> postUpdate and garbage collection
3509  int const lastElement = (int)cache.m_parametersOnDetElements->size() - 1;
3510  // we have created hits in the vector
3511  if (lastElement >= 0 && sizeBeforeSearch < sizeAfterSearch) {
3512  // get the last element
3513  // it's ok to reassign parOnLayer as the pointer to the first one is in the garbage bin
3514  // already get the latest Fatras hit to start from this one
3515  if (!(*cache.m_parametersOnDetElements)[lastElement]) {
3516  throw std::logic_error("Invalid track parameters on det elements (lastElement)");
3517  }
3518  auto cloneInput = ((*cache.m_parametersOnDetElements)[lastElement])->uniqueClone();
3519  parsOnLayer = ((*cache.m_parametersOnDetElements)[lastElement]
3520  ? cache.m_ownedPtrs.push(std::move(cloneInput))
3521  : nullptr);
3522  ATH_MSG_DEBUG(" [+] Detector element & overlapSearch successful,"
3523  << " call update on last parameter on this layer.");
3524  }
3525  } // -------------------------- Fatras mode off -----------------------------------
3526 
3527  // return the full-updated ones - may create a new object
3528  if (lay.layerMaterialProperties() && currentUpdator) {
3529  parsOnLayer = cache.m_ownedPtrs.push(currentUpdator->update(
3530  currentUpdatorCache, parsOnLayer, lay, dir, particle, matupmode));
3531  }
3532  // there are layers that have a surfaceArray but no material properties
3533  if (parsOnLayer && lay.layerMaterialProperties() && cache.m_matstates) {
3534  addMaterialEffectsOnTrack(ctx, cache, prop, parsOnLayer, lay, tvol, dir, particle);
3535  }
3536  // kill the track if the update killed the track
3537  // ------------------------------------------------
3538  if (!parsOnLayer && m_stopWithUpdateZero) {
3539  return std::make_pair(nullptr, true); // the indicator to kill the loopfrom material update
3540  }
3541  // ------------ the return of the parsOnLayer --- they're in the garbage bin already
3542  return std::make_pair(parsOnLayer, false);
3543 }

◆ extrapolateToNextActiveLayerImpl()

std::pair<std::unique_ptr<TrackParameters>, const Layer*> Trk::Extrapolator::extrapolateToNextActiveLayerImpl ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters parm,
PropDirection  dir,
const BoundaryCheck bcheck,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Actual heavy lifting implementation for extrapolateToNextActiveLayer.

◆ extrapolateToNextActiveLayerM()

std::pair< std::unique_ptr< Trk::TrackParameters >, const Trk::Layer * > Trk::Extrapolator::extrapolateToNextActiveLayerM ( const EventContext &  ctx,
const TrackParameters parm,
PropDirection  dir,
const BoundaryCheck bcheck,
std::vector< const Trk::TrackStateOnSurface * > &  material,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
finaloverridevirtual

Extrapolation to the next active layer with material collection.

Implements Trk::IExtrapolator.

Definition at line 563 of file Extrapolator.cxx.

571 {
572  // set propagator to the MS one - can be reset inside the next method (once
573  // volume information is there)
574  const IPropagator* currentPropagator =
575  !m_subPropagators.empty() ? m_subPropagators[Trk::MS] : nullptr;
576  if (currentPropagator) {
577  return extrapolateToNextActiveLayerMImpl(ctx, (*currentPropagator), parm,
578  dir, bcheck, material, particle,
579  matupmode);
580  }
582  " [!] No default Propagator is configured ! Please check jobOptions.");
583  return {nullptr, nullptr};
584 }

◆ extrapolateToNextActiveLayerMImpl()

std::pair< std::unique_ptr< Trk::TrackParameters >, const Trk::Layer * > Trk::Extrapolator::extrapolateToNextActiveLayerMImpl ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters parm,
PropDirection  dir,
const BoundaryCheck bcheck,
std::vector< const Trk::TrackStateOnSurface * > &  material,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Actual heavy lifting implementation for extrapolateToNextActiveLayerM.

Definition at line 652 of file Extrapolator.cxx.

661 {
662  Cache cache(m_propStat);
663  //This is needed as we need to return a Trk::Layer
664  cache.m_cacheLastMatLayer = true;
665  ++cache.m_methodSequence;
666  ATH_MSG_DEBUG("M-[" << cache.m_methodSequence << "] extrapolateToNextActiveLayerM(...) ");
667  // Material effect updator cache
668  cache.populateMatEffUpdatorCache(m_subupdaters);
669  // initialize the return parameters vector
670  Trk::CacheOwnedPtr<Trk::TrackParameters> currPar = cache.m_ownedPtrs.push(parm.uniqueClone());
671  //
672  const Trk::TrackingVolume* staticVol = nullptr;
673  const Trk::Surface* destSurface = nullptr;
674  const Trk::Layer* assocLayer = nullptr;
675  // initialize material collection
676  cache.m_matstates = &material;
677 
678  while (currPar) {
679  assocLayer = nullptr;
681  extrapolateToNextMaterialLayer(ctx, cache, prop, currPar, destSurface,
682  staticVol, dir, bcheck, particle,
683  matupmode);
684  if (nextPar) {
685  if (cache.m_lastMaterialLayer &&
686  cache.m_lastMaterialLayer->surfaceRepresentation().isOnSurface(
687  nextPar->position(), bcheck, m_tolerance, m_tolerance)) {
688  assocLayer = cache.m_lastMaterialLayer;
689  }
690  if (!assocLayer) {
691  ATH_MSG_ERROR(" [!] No associated layer found - at "
692  << positionOutput(nextPar->position()));
693  }
694  } else {
695  // static volume boundary ?
696  if (cache.m_parametersAtBoundary.nextParameters && cache.m_parametersAtBoundary.nextVolume) {
697  if (cache.m_parametersAtBoundary.nextVolume->geometrySignature() == Trk::MS ||
698  (cache.m_parametersAtBoundary.nextVolume->geometrySignature() == Trk::Calo && m_useDenseVolumeDescription)) {
699  staticVol = cache.m_parametersAtBoundary.nextVolume;
700  nextPar = cache.m_parametersAtBoundary.nextParameters;
701  ATH_MSG_DEBUG(" [+] Static volume boundary: continue loop over active layers in '"
702  << staticVol->volumeName() << "'.");
703  } else { // MSentrance
704  nextPar = cache.m_parametersAtBoundary.nextParameters;
705  cache.m_parametersAtBoundary.resetBoundaryInformation();
706  return {cache.m_ownedPtrs.move(nextPar), nullptr};
707  }
708  } else if (cache.m_parametersAtBoundary.nextParameters) { // outer boundary
709  nextPar = cache.m_parametersAtBoundary.nextParameters;
710  cache.m_parametersAtBoundary.resetBoundaryInformation();
711  return {cache.m_ownedPtrs.move(nextPar), nullptr};
712  }
713  }
714  currPar = nextPar;
715  if (currPar && assocLayer && assocLayer->layerType() != 0) {
716  break;
717  }
718  }
719  // reset the boundary information
720  cache.m_parametersAtBoundary.resetBoundaryInformation();
721  cache.m_matstates = nullptr;
722  return {cache.m_ownedPtrs.move(currPar), assocLayer};
723 }

◆ extrapolateToNextMaterialLayer()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateToNextMaterialLayer ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Trk::Surface destSurf,
const Trk::TrackingVolume vol,
PropDirection  dir,
const BoundaryCheck bcheck,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Definition at line 726 of file Extrapolator.cxx.

736 {
737  RecursionCounter counter(cache.m_recursionCount);
738  if (cache.m_recursionCount[Trk::Cache::kCurrentRecursionCount]>m_maxRecursion) {
739  ATH_MSG_WARNING("Too many recursive calls of extrapolateToNextMaterialLayer: "
740  << cache.m_recursionCount[Trk::Cache::kCurrentRecursionCount]);
741  cache.m_status=Cache::kRecursionCountExceeded;
742  return {};
743  }
744  ++cache.m_methodSequence;
745  ATH_MSG_DEBUG("M-[" << cache.m_methodSequence << "] extrapolateToNextMaterialLayer(...) ");
746  if (cache.m_methodSequence > m_maxMethodSequence) {
747  ATH_MSG_WARNING("Too many method sequence calls of extrapolateToNextMaterialLayer: "
748  << cache.m_methodSequence);
749  cache.m_status=Cache::kRecursionCountExceeded;
750  return {};
751  }
752 
753  // this is the core of the material loop
754  // extrapolation without target surface returns:
755  // A) trPar at next material layer
756  // B) boundary parameters (static volume boundary)
757  // if target surface:
758  // C) trPar at target surface
759  //
760 
761  // initialize the return parameters
763  const Trk::TrackingVolume* staticVol = nullptr;
764  const Trk::TrackingVolume* currVol = nullptr;
765  const Trk::TrackingVolume* nextVol = nullptr;
766  std::vector<unsigned int> solutions;
767  const Trk::TrackingVolume* assocVol = nullptr;
768  // double tol = 0.001;
769  double path = 0.;
770  bool resolveActive = destSurf == nullptr;
771  if (!resolveActive && m_resolveActive) {
772  resolveActive = m_resolveActive;
773  }
774  if (cache.m_lastMaterialLayer && !cache.m_lastMaterialLayer->isOnLayer(parm->position())) {
775  cache.m_lastMaterialLayer = nullptr;
776  }
777  // set tracking geometry in cache
778  cache.setTrackingGeometry(*m_navigator, ctx);
779  if (!cache.m_highestVolume) {
780  cache.m_highestVolume = cache.m_trackingGeometry->highestTrackingVolume();
781  }
782  // resolve current position
783  Amg::Vector3D gp = parm->position();
784  if (vol && vol->inside(gp, m_tolerance)) {
785  staticVol = vol;
786  } else {
787  staticVol = cache.m_trackingGeometry->lowestStaticTrackingVolume(gp);
788  const Trk::TrackingVolume* nextStatVol = nullptr;
789  if (m_navigator->atVolumeBoundary(currPar, staticVol, dir, nextStatVol, m_tolerance) &&
790  nextStatVol != staticVol) {
791  staticVol = nextStatVol;
792  }
793  }
794 
795  // navigation surfaces
796  if (cache.m_navigSurfs.capacity() > m_maxNavigSurf) {
797  cache.m_navigSurfs.reserve(m_maxNavigSurf);
798  }
799  cache.m_navigSurfs.clear();
800  if (destSurf) {
801  cache.m_navigSurfs.emplace_back(destSurf, false);
802  }
803  // alignable frame volume ?
804  if (staticVol && staticVol->geometrySignature() == Trk::Calo) {
805  if (staticVol->isAlignable()) {
806  const Trk::AlignableTrackingVolume* alignTV =
807  static_cast<const Trk::AlignableTrackingVolume*>(staticVol);
808  cache.m_identifiedParameters.reset();
809  return extrapolateInAlignableTV(ctx, cache, prop, currPar, destSurf,
810  alignTV, dir, particle);
811  }
812  }
813 
814  // update if new static volume
815  if (staticVol && (staticVol != cache.m_currentStatic || resolveActive != m_resolveActive)) {
816  // retrieve boundaries
817  cache.m_currentStatic = staticVol;
818  cache.retrieveBoundaries();
819 
820  cache.m_detachedVols.clear();
821  cache.m_detachedBoundaries.clear();
822  cache.m_denseVols.clear();
823  cache.m_denseBoundaries.clear();
824  cache.m_layers.clear();
825  cache.m_navigLays.clear();
826 
828  staticVol->confinedDetachedVolumes();
829  if (!detVols.empty()) {
831  for (; iTer != detVols.end(); ++iTer) {
832  // active station ?
833  const Trk::Layer* layR = (*iTer)->layerRepresentation();
834  const bool active = layR && layR->layerType();
835  const auto detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
836  if (active) {
837  if (resolveActive) {
838  cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
839  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
840  const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
841  cache.m_detachedBoundaries.emplace_back(&surf, true);
842  }
843  } else {
844  if (!m_resolveMultilayers || (*iTer)->multilayerRepresentation().empty()) {
845  cache.addOneNavigationLayer((*iTer)->trackingVolume(), layR);
846 
847  } else {
848  const auto& multi = (*iTer)->multilayerRepresentation();
849  for (const auto *i : multi) {
850  cache.addOneNavigationLayer((*iTer)->trackingVolume(), i);
851  }
852  }
853  }
854  } else if (staticVol->geometrySignature() != Trk::MS ||
856  (*iTer)->name().compare((*iTer)->name().size() - 4, 4, "PERM") ==
857  0) { // retrieve
858  // inert
859  // detached
860  // objects
861  // only if
862  // needed
863  if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
864  ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
865  ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
866  cache.m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
867 
868  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
869  const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
870  cache.m_denseBoundaries.emplace_back(&surf, true);
871  }
872  }
874  (*iTer)->trackingVolume()->confinedArbitraryLayers();
875  if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
876  (confLays.size() > detBounds.size())) {
877  cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
878  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
879  const Trk::Surface& surf =
880  (detBounds[ibb])->surfaceRepresentation();
881  cache.m_detachedBoundaries.emplace_back(&surf, true);
882  }
883  } else if (!confLays.empty()) {
884  for (const Trk::Layer* const lIt : confLays) {
885  cache.addOneNavigationLayer((*iTer)->trackingVolume(), (lIt));
886  }
887  }
888  }
889  }
890  }
891  cache.m_denseResolved = std::pair<unsigned int, unsigned int>(cache.m_denseVols.size(),
892  cache.m_denseBoundaries.size());
893  cache.m_layerResolved = cache.m_layers.size();
894  }
895 
896  cache.m_navigSurfs.insert(
897  cache.m_navigSurfs.end(), cache.m_staticBoundaries.begin(), cache.m_staticBoundaries.end());
898 
899  // resolve the use of dense volumes
900  if (staticVol) {
901  cache.m_dense = (staticVol->geometrySignature() == Trk::MS && m_useMuonMatApprox) ||
903  }
904  while (currPar && staticVol && staticVol->confinedDetachedVolumes().empty()) {
905  // propagate to closest surface
906  solutions.resize(0);
907  const Trk::TrackingVolume* propagVol = cache.m_dense ? staticVol : cache.m_highestVolume;
908  ATH_MSG_DEBUG(" [+] Starting propagation (static) at " << positionOutput(currPar->position())
909  << " in '" << propagVol->volumeName()
910  << "'");
911  // current static may carry non-trivial material properties, their use is optional;
912  // use highest volume as B field source
913  std::unique_ptr<Trk::TrackParameters> pNextPar = prop.propagate(ctx,*currPar,cache.m_navigSurfs,
914  dir,m_fieldProperties,particle,solutions,path,false,
915  false,propagVol);
916  Trk::CacheOwnedPtr<Trk::TrackParameters> nextPar = cache.m_ownedPtrs.push(std::move(pNextPar));
917  if (nextPar) {
918  ++cache.m_nPropagations;
919  ATH_MSG_DEBUG(" [+] Position after propagation - at "
920  << positionOutput(nextPar->position()));
921  }
922  if (!nextPar) {
923  cache.m_parametersAtBoundary.resetBoundaryInformation();
924  return {};
925  }
926  if (nextPar) {
927  // collect material
928  if (propagVol->zOverAtimesRho() != 0. && !cache.m_matstates && cache.m_extrapolationCache) {
929  if (not cache.elossPointerOverwritten()) {
930  if (m_dumpCache) {
931  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer"));
932  }
933  const double dInX0 = std::abs(path) / propagVol->x0();
934  ATH_MSG_DEBUG(" add x0 " << dInX0);
935  cache.m_extrapolationCache->updateX0(dInX0);
936  const Trk::MaterialProperties materialProperties(*propagVol, std::abs(path));
937  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
938  EnergyLoss const eloss = m_elossupdater->energyLoss(
939  materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
940  ATH_MSG_DEBUG(" [M] Energy loss: STEP,EnergyLossUpdator:"
941  << nextPar->momentum().mag() - currPar->momentum().mag() << ","
942  << eloss.deltaE());
943  cache.m_extrapolationCache->updateEloss(
944  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
945  if (m_dumpCache) {
946  ATH_MSG_DEBUG(cache.to_string( " After"));
947  }
948  } else {
949  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
950  }
951  }
952  if (propagVol->zOverAtimesRho() != 0. && cache.m_matstates) {
953  const double dInX0 = std::abs(path) / propagVol->x0();
954  const Trk::MaterialProperties materialProperties(*propagVol, std::abs(path));
955  const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
956  materialProperties, 1. / std::abs(nextPar->parameters()[qOverP]), 1., particle));
957  auto newsa = Trk::ScatteringAngles(
958  0, 0, scatsigma / std::sin(nextPar->parameters()[Trk::theta]), scatsigma);
959  // energy loss
960  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
961  EnergyLoss eloss = m_elossupdater->energyLoss(
962  materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
963  // compare energy loss
964  ATH_MSG_DEBUG(" [M] Energy loss: STEP,EnergyLossUpdator:"
965  << nextPar->momentum().mag() - currPar->momentum().mag() << ","
966  << eloss.deltaE());
967  // use curvilinear TPs to simplify retrieval by fitters
968  std::unique_ptr<Trk::TrackParameters> cvlTP(new Trk::CurvilinearParameters(
969  nextPar->position(), nextPar->momentum(), nextPar->charge()));
970  //
971  if (cache.m_extrapolationCache) {
972  if (m_dumpCache) {
973  ATH_MSG_DEBUG(cache.to_string( " mat states extrapolateToNextMaterialLayer"));
974  }
975  cache.m_extrapolationCache->updateX0(dInX0);
976  cache.m_extrapolationCache->updateEloss(
977  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
978  if (m_dumpCache) {
979  ATH_MSG_DEBUG(cache.to_string( " After"));
980  }
981  }
982  auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
983  dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
984  cvlTP->associatedSurface());
985  cache.m_matstates->push_back(new TrackStateOnSurface(
986  nullptr, std::move(cvlTP), std::move(mefot)));
987  ATH_MSG_DEBUG(" [M] Collecting material from static volume '" << propagVol->volumeName()
988  << "', t/X0 = " << dInX0);
989  }
990  }
991  currPar = nextPar;
992  const unsigned int isurf = destSurf ? 1 : 0;
993  if (destSurf && solutions[0] == 0) {
994  return currPar;
995  }
996  if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
997  return currPar;
998  }
999  if (solutions[0] <= isurf + cache.m_staticBoundaries.size()) { // static volume boundary
1000  // use global coordinates to retrieve attached volume (just for static!)
1001  const Trk::TrackingVolume* nextVol =
1002  cache.m_currentStatic->boundarySurfaces()[solutions[0] - isurf]->attachedVolume(
1003  currPar->position(), currPar->momentum(), dir);
1004  cache.m_parametersAtBoundary.boundaryInformation(nextVol, currPar, currPar);
1005  if (!nextVol) {
1006  ATH_MSG_DEBUG(" [!] World boundary at position R,z: " << currPar->position().perp() << ","
1007  << currPar->position().z());
1008  } else {
1009  ATH_MSG_DEBUG("M-S Crossing to static volume '" << nextVol->volumeName() << "'.'");
1010  }
1011  }
1012  return {};
1013  }
1014 
1015  if (!staticVol || (staticVol->confinedDetachedVolumes().empty()) || !currPar) {
1016  return {};
1017  }
1018 
1019  // reset remaining counters
1020  cache.m_currentDense = cache.m_dense ? cache.m_currentStatic : cache.m_highestVolume;
1021  cache.m_navigBoundaries.clear();
1022  if (cache.m_denseVols.size() > cache.m_denseResolved.first) {
1023  cache.m_denseVols.resize(cache.m_denseResolved.first);
1024  }
1025  while (cache.m_denseBoundaries.size() > cache.m_denseResolved.second) {
1026  cache.m_denseBoundaries.pop_back();
1027  }
1028  if (cache.m_layers.size() > cache.m_layerResolved) {
1029  cache.m_navigLays.resize(cache.m_layerResolved);
1030  }
1031  while (cache.m_layers.size() > cache.m_layerResolved) {
1032  cache.m_layers.pop_back();
1033  }
1034 
1035  // current detached volumes
1036  // collect : subvolume boundaries, ordered/unordered layers, confined dense volumes
1038  // const Trk::DetachedTrackingVolume* currentActive = 0;
1039  if (cache.m_navigVolsInt.capacity() > m_maxNavigVol) {
1040  cache.m_navigVolsInt.reserve(m_maxNavigVol);
1041  }
1042  cache.m_navigVolsInt.clear();
1043 
1044  gp = currPar->position();
1045  std::vector<const Trk::DetachedTrackingVolume*> detVols =
1046  cache.m_trackingGeometry->lowestDetachedTrackingVolumes(gp);
1048  for (; dIter != detVols.end(); ++dIter) {
1049  const Trk::Layer* layR = (*dIter)->layerRepresentation();
1050  const bool active = layR && layR->layerType();
1051  if (active && !resolveActive) {
1052  continue;
1053  }
1054  if (!active && staticVol->geometrySignature() == Trk::MS && m_useMuonMatApprox &&
1055  (*dIter)->name().compare((*dIter)->name().size() - 4, 4, "PERM") != 0) {
1056  continue;
1057  }
1058  const Trk::TrackingVolume* dVol = (*dIter)->trackingVolume();
1059  // detached volume exit ?
1060  const bool dExit =
1061  m_navigator->atVolumeBoundary(currPar, dVol, dir, nextVol, m_tolerance) && !nextVol;
1062  if (dExit) {
1063  continue;
1064  }
1065  // inert material
1066  const auto confinedDense = dVol->confinedDenseVolumes();
1067  const auto confinedLays = dVol->confinedArbitraryLayers();
1068 
1069  if (!active && confinedDense.empty() && confinedLays.empty()) {
1070  continue;
1071  }
1072  const auto bounds = dVol->boundarySurfaces();
1073  if (!active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
1074  continue;
1075  }
1076  if (!confinedDense.empty() || !confinedLays.empty()) {
1077  cache.m_navigVolsInt.emplace_back(dVol, bounds.size());
1078  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
1079  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1080  cache.m_navigBoundaries.emplace_back(&surf, true);
1081  }
1082  // collect dense volume boundary
1083  if (!confinedDense.empty()) {
1084  auto vIter = confinedDense.begin();
1085  for (; vIter != confinedDense.end(); ++vIter) {
1086  const auto bounds = (*vIter)->boundarySurfaces();
1087  cache.m_denseVols.emplace_back(*vIter, bounds.size());
1088  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
1089  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1090  cache.m_denseBoundaries.emplace_back(&surf, true);
1091  }
1092  }
1093  }
1094  // collect unordered layers
1095  if (!confinedLays.empty()) {
1096  for (const auto *confinedLay : confinedLays) {
1097  cache.addOneNavigationLayer(dVol, confinedLay);
1098  }
1099  }
1100  } else { // active material
1101  const Trk::TrackingVolume* detVol = dVol->associatedSubVolume(gp);
1102  if (!detVol && dVol->confinedVolumes()) {
1103  std::span<Trk::TrackingVolume const * const> const subvols = dVol->confinedVolumes()->arrayObjects();
1104  for (const auto *subvol : subvols) {
1105  if (subvol->inside(gp, m_tolerance)) {
1106  detVol = subvol;
1107  break;
1108  }
1109  }
1110  }
1111 
1112  if (!detVol) {
1113  detVol = dVol;
1114  }
1115  bool vExit =
1116  m_navigator->atVolumeBoundary(currPar, detVol, dir, nextVol, m_tolerance) &&
1117  nextVol != detVol;
1118  if (vExit && nextVol && nextVol->inside(gp, m_tolerance)) {
1119  detVol = nextVol;
1120  vExit = false;
1121  }
1122  if (!vExit) {
1123  const auto bounds = detVol->boundarySurfaces();
1124  cache.m_navigVolsInt.emplace_back(detVol, bounds.size());
1125  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
1126  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1127  cache.m_navigBoundaries.emplace_back(&surf, true);
1128  }
1129  if (detVol->zOverAtimesRho() != 0.) {
1130  cache.m_denseVols.emplace_back(detVol, bounds.size());
1131  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
1132  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
1133  cache.m_denseBoundaries.emplace_back(&surf, true);
1134  }
1135  }
1136  // layers ?
1137  if (detVol->confinedLayers()) {
1138  const Trk::Layer* lay = detVol->associatedLayer(gp);
1139 
1140  if (lay) {
1141  cache.addOneNavigationLayer(detVol, lay);
1142 
1143  }
1144  const Trk::Layer* nextLayer =
1145  detVol->nextLayer(currPar->position(), dir * currPar->momentum().unit(), true);
1146  if (nextLayer && nextLayer != lay) {
1147  cache.addOneNavigationLayer(detVol, nextLayer);
1148  }
1149  } else if (!detVol->confinedArbitraryLayers().empty()) {
1151  for (const auto *layer : layers) {
1152  cache.addOneNavigationLayer(detVol, layer);
1153  }
1154  }
1155  }
1156  }
1157  }
1158  cache.copyToNavigationSurfaces();
1159 
1160  // current dense
1161  cache.m_currentDense = cache.m_highestVolume;
1162  if (cache.m_dense && cache.m_denseVols.empty()) {
1163  cache.m_currentDense = cache.m_currentStatic;
1164  } else {
1165  for (unsigned int i = 0; i < cache.m_denseVols.size(); i++) {
1166  const Trk::TrackingVolume* dVol = cache.m_denseVols[i].first;
1167  if (dVol->inside(currPar->position(), m_tolerance) && dVol->zOverAtimesRho() != 0.) {
1168  if (!m_navigator->atVolumeBoundary(currPar, dVol, dir, nextVol, m_tolerance) ||
1169  nextVol == dVol) {
1170  cache.m_currentDense = dVol;
1171  }
1172  }
1173  }
1174  }
1175  // ready to propagate
1176  // till: A/ static volume boundary(bcheck=true) , B/ material layer(bcheck=true), C/ destination
1177  // surface(bcheck=false) update of cache.m_navigSurfs required if I/ entry into new navig volume,
1178  // II/ exit from currentActive without overlaps
1179  nextVol = nullptr;
1180  while (currPar) {
1181  double path = 0.;
1182  std::vector<unsigned int> solutions;
1183  // verify that material input makes sense
1184  const Amg::Vector3D tp =
1185  currPar->position() + 2 * m_tolerance * dir * currPar->momentum().normalized();
1186  if (!(cache.m_currentDense->inside(tp, 0.))) {
1187  cache.m_currentDense = cache.m_highestVolume;
1188  if (cache.m_dense && cache.m_denseVols.empty()) {
1189  cache.m_currentDense = cache.m_currentStatic;
1190  } else {
1191  for (unsigned int i = 0; i < cache.m_denseVols.size(); i++) {
1192  const Trk::TrackingVolume* dVol = cache.m_denseVols[i].first;
1193  if (dVol->inside(tp, 0.) && dVol->zOverAtimesRho() != 0.) {
1194  cache.m_currentDense = dVol;
1195  }
1196  }
1197  }
1198  }
1199  // propagate now
1200  ATH_MSG_DEBUG(" [+] Starting propagation at position "
1201  << positionOutput(currPar->position())
1202  << " (current momentum: " << currPar->momentum().mag() << ")");
1203  ATH_MSG_DEBUG(" [+] " << cache.m_navigSurfs.size() << " target surfaces in '"
1204  << cache.m_currentDense->volumeName() << "'.");
1205  Trk::CacheOwnedPtr<Trk::TrackParameters> nextPar = cache.m_ownedPtrs.push(prop.propagate(
1206  ctx, *currPar, cache.m_navigSurfs, dir, m_fieldProperties, particle,
1207  solutions, path, false, false, cache.m_currentDense));
1208  if (nextPar) {
1209  ++cache.m_nPropagations;
1210  ATH_MSG_DEBUG(" [+] Position after propagation - at "
1211  << positionOutput(nextPar->position()));
1212  }
1213  // check missing volume boundary
1214  if (nextPar && !(cache.m_currentDense->inside(nextPar->position(), m_tolerance) ||
1215  m_navigator->atVolumeBoundary(
1216  nextPar, cache.m_currentDense, dir, assocVol, m_tolerance))) {
1217  ATH_MSG_DEBUG(" [!] ERROR: missing volume boundary for volume"
1218  << cache.m_currentDense->volumeName());
1219  if (cache.m_currentDense->zOverAtimesRho() != 0.) {
1220  ATH_MSG_DEBUG(" [!] ERROR: trying to recover: repeat the propagation step in"
1221  << cache.m_highestVolume->volumeName());
1222  cache.m_currentDense = cache.m_highestVolume;
1223  continue;
1224  }
1225  }
1226  if (nextPar) {
1227  ATH_MSG_DEBUG(" [+] Number of intersection solutions: " << solutions.size());
1228  if (cache.m_currentDense->zOverAtimesRho() != 0. && !cache.m_matstates &&
1229  cache.m_extrapolationCache) {
1230  if (not cache.elossPointerOverwritten()) {
1231  if (m_dumpCache) {
1232  ATH_MSG_DEBUG(cache.to_string( " extrapolateToNextMaterialLayer dense "));
1233  }
1234  const double dInX0 = std::abs(path) / cache.m_currentDense->x0();
1235  cache.m_extrapolationCache->updateX0(dInX0);
1236  const Trk::MaterialProperties materialProperties(*cache.m_currentDense, std::abs(path));
1237  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1238  const Trk::EnergyLoss eloss = m_elossupdater->energyLoss(
1239  materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
1240  cache.m_extrapolationCache->updateEloss(
1241  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
1242  if (m_dumpCache) {
1243  ATH_MSG_DEBUG(cache.to_string(" After"));
1244  }
1245  } else {
1246  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
1247  }
1248  }
1249  // collect material
1250  if (cache.m_currentDense->zOverAtimesRho() != 0. && cache.m_matstates) {
1251  const double dInX0 = std::abs(path) / cache.m_currentDense->x0();
1252  if (path * dir < 0.) {
1253  ATH_MSG_WARNING(" got negative path!! " << path);
1254  }
1255  const Trk::MaterialProperties materialProperties(*cache.m_currentDense, std::abs(path));
1256  const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1257  materialProperties, 1. / std::abs(nextPar->parameters()[qOverP]), 1., particle));
1258  auto newsa = Trk::ScatteringAngles(
1259  0, 0, scatsigma / std::sin(nextPar->parameters()[Trk::theta]), scatsigma);
1260  // energy loss
1261  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1262  EnergyLoss eloss = m_elossupdater->energyLoss(
1263  materialProperties, std::abs(1. / currentqoverp), 1., dir, particle);
1264  // compare energy loss
1265  ATH_MSG_DEBUG(" [M] Energy loss: STEP,EnergyLossUpdator:"
1266  << nextPar->momentum().mag() - currPar->momentum().mag() << ","
1267  << eloss.deltaE());
1268 
1269  // use curvilinear TPs to simplify retrieval by fitters
1270  std::unique_ptr<Trk::TrackParameters> cvlTP(new Trk::CurvilinearParameters(
1271  nextPar->position(), nextPar->momentum(), nextPar->charge()));
1272 
1273  if (cache.m_extrapolationCache) {
1274  if (m_dumpCache) {
1275  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer dense"));
1276  }
1277  cache.m_extrapolationCache->updateX0(dInX0);
1278  cache.m_extrapolationCache->updateEloss(eloss.meanIoni(),
1279  eloss.sigmaIoni(),
1280  eloss.meanRad(),
1281  eloss.sigmaRad());
1282  if (m_dumpCache) {
1283  ATH_MSG_DEBUG(cache.to_string(" After"));
1284  }
1285  }
1286  auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1287  dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->associatedSurface());
1288 
1289  cache.m_matstates->push_back(new TrackStateOnSurface(
1290  nullptr, std::move(cvlTP), std::move(mefot)));
1291 
1292  ATH_MSG_DEBUG(" [M] Collecting material from dense volume '"
1293  << cache.m_currentDense->volumeName() << "', t/X0 = " << dInX0);
1294  }
1295  // destination surface
1296  if (destSurf && solutions[0] == 0) {
1297  return nextPar;
1298  }
1299  if (destSurf && solutions.size() > 1 && solutions[1] == 0) {
1300  return nextPar;
1301  }
1302  // destination surface missed ?
1303  if (destSurf) {
1304  double dist = 0.;
1305  const Trk::DistanceSolution distSol = destSurf->straightLineDistanceEstimate(
1306  nextPar->position(), nextPar->momentum().normalized());
1307  if (distSol.numberOfSolutions() > 0) {
1308  dist = distSol.first();
1309  if (distSol.numberOfSolutions() > 1 && std::abs(dist) < m_tolerance) {
1310  dist = distSol.second();
1311  }
1312  if (distSol.numberOfSolutions() > 1 && dist * dir < 0. && distSol.second() * dir > 0.) {
1313  dist = distSol.second();
1314  }
1315  } else {
1316  dist = distSol.toPointOfClosestApproach();
1317  }
1318  if (dist * dir < 0.) {
1319  ATH_MSG_DEBUG(" [+] Destination surface missed ? " << dist << "," << dir);
1320  cache.m_parametersAtBoundary.resetBoundaryInformation();
1321  return {};
1322  }
1323  ATH_MSG_DEBUG(" [+] New 3D-distance to destinatiion - d3 = " << dist * dir);
1324  }
1325 
1326  int const iDest = destSurf ? 1 : 0;
1327  unsigned int iSol = 0;
1328  while (iSol < solutions.size()) {
1329  if (solutions[iSol] < iDest + cache.m_staticBoundaries.size()) {
1330  // material attached ?
1331  const Trk::Layer* mb = cache.m_navigSurfs[solutions[iSol]].first->materialLayer();
1332  if (mb) {
1333  if (mb->layerMaterialProperties() &&
1334  mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
1335 
1336  const IMaterialEffectsUpdator* currentUpdator =
1337  subMaterialEffectsUpdator(*cache.m_currentStatic);
1338  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
1339  cache.subMaterialEffectsUpdatorCache();
1340 
1341  if (currentUpdator) {
1342  nextPar = cache.m_ownedPtrs.push(
1343  currentUpdator->update(currentUpdatorCache, nextPar,
1344  *mb, dir, particle, matupmode));
1345  }
1346  if (!nextPar) {
1347  cache.m_parametersAtBoundary.resetBoundaryInformation();
1348  return {};
1349  }
1350 
1351  // collect material
1352  const Trk::MaterialProperties* lmat = mb->fullUpdateMaterialProperties(*nextPar);
1353  const double lx0 = lmat->x0();
1354  const double layThick = mb->thickness();
1355 
1356  double thick = 0.;
1357  const double costr =
1358  std::abs(nextPar->momentum().normalized().dot(mb->surfaceRepresentation().normal()));
1359 
1360  if (mb->surfaceRepresentation().isOnSurface(
1361  mb->surfaceRepresentation().center(), false, 0., 0.)) {
1362  thick = fmin(mb->surfaceRepresentation().bounds().r(),
1363  layThick / std::abs(nextPar->momentum().normalized().dot(
1364  mb->surfaceRepresentation().normal())));
1365  } else {
1366  thick = fmin(2 * mb->thickness(), layThick / (1 - costr));
1367  }
1368 
1369  if (!cache.m_matstates && cache.m_extrapolationCache) {
1370  if (not cache.elossPointerOverwritten()) {
1371  const double dInX0 = thick / lx0;
1372  if (m_dumpCache) {
1373  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer thin "));
1374  }
1375  cache.m_extrapolationCache->updateX0(dInX0);
1376  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1377  EnergyLoss const eloss = m_elossupdater->energyLoss(
1378  *lmat, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1379  cache.m_extrapolationCache->updateEloss(
1380  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
1381  if (m_dumpCache) {
1382  ATH_MSG_DEBUG(cache.to_string(" After"));
1383  }
1384  } else {
1385  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
1386  }
1387 
1388  }
1389 
1390  if (cache.m_matstates) {
1391  const double dInX0 = thick / lx0;
1392  const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1393  *lmat, 1. / std::abs(nextPar->parameters()[qOverP]), 1., particle));
1394  auto newsa = Trk::ScatteringAngles(
1395  0, 0, scatsigma / std::sin(nextPar->parameters()[Trk::theta]), scatsigma);
1396  // energy loss
1397  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1398  EnergyLoss eloss = m_elossupdater->energyLoss(
1399  *lmat, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1400 
1401  // use curvilinear TPs to simplify retrieval by fitters
1402  std::unique_ptr<Trk::TrackParameters> cvlTP(new Trk::CurvilinearParameters(
1403  nextPar->position(), nextPar->momentum(), nextPar->charge()));
1404  if (cache.m_extrapolationCache) {
1405  if (not cache.elossPointerOverwritten()) {
1406  if (m_dumpCache) {
1407  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer thin "));
1408  }
1409  cache.m_extrapolationCache->updateX0(dInX0);
1410  cache.m_extrapolationCache->updateEloss(
1411  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
1412  if (m_dumpCache) {
1413  ATH_MSG_DEBUG(cache.to_string(" After"));
1414  }
1415  } else {
1416  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
1417  }
1418  }
1419  auto mefot =
1420  std::make_unique<Trk::MaterialEffectsOnTrack>(
1421  dInX0, newsa,
1422  std::make_unique<Trk::EnergyLoss>(std::move(eloss)),
1423  cvlTP->associatedSurface());
1424  cache.m_matstates->push_back(new TrackStateOnSurface(
1425  nullptr, std::move(cvlTP), std::move(mefot)));
1426  }
1427  }
1428  } // end material update at massive (static volume) boundary
1429 
1430  // static volume boundary; return to the main loop
1431  const unsigned int index = solutions[iSol] - iDest;
1432  // use global coordinates to retrieve attached volume (just for static!)
1433  nextVol = (cache.m_currentStatic->boundarySurfaces())[index]->attachedVolume(
1434  nextPar->position(), nextPar->momentum(), dir);
1435  // double check the next volume
1436  if (nextVol &&
1437  !(nextVol->inside(nextPar->position() + 0.01 * dir * nextPar->momentum().normalized(),
1438  m_tolerance))) {
1439  ATH_MSG_DEBUG(" [!] WARNING: wrongly assigned static volume ?"
1440  << cache.m_currentStatic->volumeName() << "->" << nextVol->volumeName());
1441  nextVol = cache.m_trackingGeometry->lowestStaticTrackingVolume(
1442  nextPar->position() + 0.01 * nextPar->momentum().normalized());
1443  if (nextVol) {
1444  ATH_MSG_DEBUG(" new search yields: " << nextVol->volumeName());
1445  }
1446  }
1447  // end double check - to be removed after validation of the geometry gluing
1448  if (nextVol != cache.m_currentStatic) {
1449  cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
1450  ATH_MSG_DEBUG(" [+] StaticVol boundary reached of '"
1451  << cache.m_currentStatic->volumeName() << "'.");
1452  if (m_navigator->atVolumeBoundary(
1453  nextPar, cache.m_currentStatic, dir, assocVol, m_tolerance) &&
1454  assocVol != cache.m_currentStatic) {
1455  cache.m_currentDense = m_useMuonMatApprox ? nextVol : cache.m_highestVolume;
1456  }
1457  // no next volume found --- end of the world
1458  if (!nextVol) {
1459  ATH_MSG_DEBUG(" [+] Word boundary reached - at "
1460  << positionOutput(nextPar->position()));
1461  }
1462  // next volume found and parameters are at boundary
1463  if (nextVol && nextPar) {
1464  ATH_MSG_DEBUG(" [+] Crossing to next volume '" << nextVol->volumeName() << "'");
1465  ATH_MSG_DEBUG(" [+] Crossing position is - at "
1466  << positionOutput(nextPar->position()));
1467  }
1468  return {};
1469  }
1470  } else if (solutions[iSol] <
1471  iDest + cache.m_staticBoundaries.size() + cache.m_layers.size()) {
1472  // next layer; don't return passive material layers unless required
1473  const unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size();
1474  const Trk::Layer* nextLayer = cache.m_navigLays[index].second;
1475  // material update HERE and NOW (pre/post udpdate ? )
1476  // don't repeat if identical to last update && input parameters on the layer
1477  bool collect = true;
1478  if (nextLayer == cache.m_lastMaterialLayer &&
1480  ATH_MSG_DEBUG(
1481  " [!] This layer is identical to the one with last material update, return layer "
1482  "without repeating the update");
1483  collect = false;
1484  if (!destSurf && (nextLayer->layerType() > 0)) {
1485  return nextPar;
1486  }
1487  }
1488  const double layThick = nextLayer->thickness();
1489  if (collect && layThick > 0.) { // collect material
1490 
1491  // get the right updator
1492  const IMaterialEffectsUpdator* currentUpdator =
1493  subMaterialEffectsUpdator(*cache.m_currentStatic);
1494  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
1495  cache.subMaterialEffectsUpdatorCache();
1496 
1497  if (currentUpdator) {
1498  nextPar = cache.m_ownedPtrs.push(
1499  currentUpdator->update(currentUpdatorCache, nextPar,
1500  *nextLayer, dir, particle, matupmode));
1501  }
1502  if (!nextPar) {
1503  cache.m_parametersAtBoundary.resetBoundaryInformation();
1504  return {};
1505  }
1506 
1507  // collect material
1508  const double lx0 = nextLayer->fullUpdateMaterialProperties(*nextPar)->x0();
1509 
1510  double thick = 0.;
1511  const double costr = std::abs(
1512  nextPar->momentum().normalized().dot(nextLayer->surfaceRepresentation().normal()));
1513 
1514  if (nextLayer->surfaceRepresentation().isOnSurface(
1515  nextLayer->surfaceRepresentation().center(), false, 0., 0.)) {
1516  thick = fmin(nextLayer->surfaceRepresentation().bounds().r(),
1517  layThick / std::abs(nextPar->momentum().normalized().dot(
1518  nextLayer->surfaceRepresentation().normal())));
1519  } else {
1520  thick = fmin(2 * nextLayer->thickness(), layThick / (1 - costr));
1521  }
1522 
1523  if (!cache.m_matstates && cache.m_extrapolationCache) {
1524  if (not cache.elossPointerOverwritten()) {
1525  const double dInX0 = thick / lx0;
1526  if (m_dumpCache) {
1527  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer thin "));
1528  }
1529  cache.m_extrapolationCache->updateX0(dInX0);
1530  const Trk::MaterialProperties materialProperties(
1531  *nextLayer->fullUpdateMaterialProperties(*nextPar)); // !<@TODO check
1532  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1533  EnergyLoss const eloss = m_elossupdater->energyLoss(
1534  materialProperties, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1535  cache.m_extrapolationCache->updateEloss(
1536  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
1537  if (m_dumpCache) {
1538  ATH_MSG_DEBUG(cache.to_string( " After"));
1539  }
1540  } else {
1541  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
1542  }
1543  }
1544 
1545  if (cache.m_matstates) {
1546  const double dInX0 = thick / lx0;
1547  const Trk::MaterialProperties materialProperties(
1548  *nextLayer->fullUpdateMaterialProperties(*nextPar)); // !<@TODOcheck
1549  const double scatsigma = std::sqrt(m_msupdater->sigmaSquare(
1550  materialProperties, 1. / std::abs(nextPar->parameters()[qOverP]), 1., particle));
1551  const double par_theta = std::abs(nextPar->parameters()[Trk::theta]) > FLT_EPSILON
1552  ? nextPar->parameters()[Trk::theta]
1553  : FLT_EPSILON;
1554  Trk::ScatteringAngles newsa(0, 0, scatsigma / std::sin(par_theta), scatsigma);
1555  // energy loss
1556  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
1557  EnergyLoss eloss = m_elossupdater->energyLoss(
1558  materialProperties, std::abs(1. / currentqoverp), 1. / costr, dir, particle);
1559 
1560  // use curvilinear TPs to simplify retrieval by fitters
1561  auto cvlTP = std::make_unique<Trk::CurvilinearParameters>(
1562  nextPar->position(), nextPar->momentum(), nextPar->charge());
1563  if (cache.m_extrapolationCache) {
1564  if (not cache.elossPointerOverwritten()) {
1565  if (m_dumpCache) {
1566  ATH_MSG_DEBUG(cache.to_string(" extrapolateToNextMaterialLayer thin "));
1567  }
1568  cache.m_extrapolationCache->updateX0(dInX0);
1569  cache.m_extrapolationCache->updateEloss(
1570  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
1571  if (m_dumpCache) {
1572  ATH_MSG_DEBUG(cache.to_string( " After"));
1573  }
1574  } else {
1575  ATH_MSG_DEBUG(cache.elossPointerErrorMsg(__LINE__));
1576  }
1577  }
1578  auto mefot = std::make_unique<Trk::MaterialEffectsOnTrack>(
1579  dInX0, newsa, std::make_unique<Trk::EnergyLoss>(std::move(eloss)), cvlTP->associatedSurface());
1580  cache.m_matstates->push_back(new TrackStateOnSurface(
1581  nullptr, std::move(cvlTP), std::move(mefot)));
1582  }
1583  //
1584  if (cache.m_cacheLastMatLayer) {
1585  cache.m_lastMaterialLayer = nextLayer;
1586  }
1587  if (!destSurf && nextLayer->layerType() > 0) {
1588  return nextPar;
1589  }
1590  }
1591  if (resolveActive) {
1592  // if ordered layers, retrieve the next layer and replace the current one in the list
1593  if (cache.m_navigLays[index].first &&
1594  cache.m_navigLays[index].first->confinedLayers()) {
1595  const Trk::Layer* newLayer = cache.m_navigLays[index].first->nextLayer(
1596  nextPar->position(), dir * nextPar->momentum().normalized(), true);
1597  if (newLayer) {
1598  cache.m_navigLays[index].second = newLayer;
1599  cache.m_navigSurfs[solutions[iSol]].first = &(newLayer->surfaceRepresentation());
1600  }
1601  }
1602  }
1603  // not necessary: currPar = nextPar; since done outside the loop and currPar not used
1604  // inside the loop
1605  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() +
1606  cache.m_layers.size() + cache.m_denseBoundaries.size()) {
1607  // dense volume boundary
1608  unsigned int index =
1609  solutions[iSol] - iDest - cache.m_staticBoundaries.size() - cache.m_layers.size();
1610  std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>::iterator dIter =
1611  cache.m_denseVols.begin();
1612  while (dIter != cache.m_denseVols.end() && index >= (*dIter).second) {
1613  index -= (*dIter).second;
1614  ++dIter;
1615  }
1616  if (dIter != cache.m_denseVols.end()) {
1617  currVol = (*dIter).first;
1618  nextVol =
1619  ((*dIter).first->boundarySurfaces())[index]->attachedVolume(*nextPar, dir);
1620  // boundary orientation not reliable
1621  const Amg::Vector3D tp =
1622  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
1623  if (currVol->inside(tp, m_tolerance)) {
1624  cache.m_currentDense = currVol;
1625  } else if (!nextVol || !nextVol->inside(tp, m_tolerance)) { // search for dense volumes
1626  cache.m_currentDense = cache.m_highestVolume;
1627  if (cache.m_dense && cache.m_denseVols.empty()) {
1628  cache.m_currentDense = cache.m_currentStatic;
1629  } else {
1630  for (unsigned int i = 0; i < cache.m_denseVols.size(); i++) {
1631  const Trk::TrackingVolume* dVol = cache.m_denseVols[i].first;
1632  if (dVol->inside(tp, 0.) && dVol->zOverAtimesRho() != 0.) {
1633  cache.m_currentDense = dVol;
1634  ATH_MSG_DEBUG(" [+] Next dense volume found: '"
1635  << cache.m_currentDense->volumeName() << "'.");
1636  break;
1637  }
1638  } // loop over dense volumes
1639  }
1640  } else {
1641  cache.m_currentDense = nextVol;
1642  ATH_MSG_DEBUG(" [+] Next dense volume: '" << cache.m_currentDense->volumeName()
1643  << "'.");
1644  }
1645  }
1646  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() +
1647  cache.m_layers.size() + cache.m_denseBoundaries.size() +
1648  cache.m_navigBoundaries.size()) {
1649  // navig volume boundary
1650  unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size() -
1651  cache.m_layers.size() - cache.m_denseBoundaries.size();
1652  std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>::iterator nIter =
1653  cache.m_navigVolsInt.begin();
1654  while (nIter != cache.m_navigVolsInt.end() && index >= (*nIter).second) {
1655  index -= (*nIter).second;
1656  ++nIter;
1657  }
1658  if (nIter != cache.m_navigVolsInt.end()) {
1659  currVol = (*nIter).first;
1660  nextVol =
1661  ((*nIter).first->boundarySurfaces())[index]->attachedVolume(*nextPar, dir);
1662  // boundary orientation not reliable
1663  const Amg::Vector3D tp =
1664  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
1665  if (nextVol && nextVol->inside(tp, 0.)) {
1666  ATH_MSG_DEBUG(" [+] Navigation volume boundary, entering volume '"
1667  << nextVol->volumeName() << "'.");
1668  } else if (currVol->inside(tp, 0.)) {
1669  nextVol = currVol;
1670  ATH_MSG_DEBUG(" [+] Navigation volume boundary, entering volume '"
1671  << nextVol->volumeName() << "'.");
1672  } else {
1673  nextVol = nullptr;
1674  ATH_MSG_DEBUG(" [+] Navigation volume boundary, leaving volume '"
1675  << currVol->volumeName() << "'.");
1676  }
1677  // not necessary: currPar = nextPar; since done outside the loop and currPar not used
1678  // inside the loop return only if detached volume boundaries not collected
1679  if (nextVol) {
1681  ctx, cache, prop, nextPar, destSurf, cache.m_currentStatic,
1682  dir, bcheck, particle, matupmode);
1683  }
1684  }
1685  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() +
1686  cache.m_layers.size() + cache.m_denseBoundaries.size() +
1687  cache.m_navigBoundaries.size() +
1688  cache.m_detachedBoundaries.size()) {
1689  // detached volume boundary
1690  unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size() -
1691  cache.m_layers.size() - cache.m_denseBoundaries.size() -
1692  cache.m_navigBoundaries.size();
1693  std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>::iterator dIter =
1694  cache.m_detachedVols.begin();
1695  while (dIter != cache.m_detachedVols.end() && index >= (*dIter).second) {
1696  index -= (*dIter).second;
1697  ++dIter;
1698  }
1699  if (dIter != cache.m_detachedVols.end()) {
1700  currVol = (*dIter).first->trackingVolume();
1701  // boundary orientation not reliable
1702  nextVol =
1703  ((*dIter).first->trackingVolume()->boundarySurfaces())[index]->attachedVolume(
1704  *nextPar, dir);
1705  const Amg::Vector3D tp =
1706  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
1707  if (nextVol && nextVol->inside(tp, 0.)) {
1708  ATH_MSG_DEBUG(" [+] Detached volume boundary, entering volume '"
1709  << nextVol->volumeName() << "'.");
1710  } else if (currVol->inside(tp, 0.)) {
1711  nextVol = currVol;
1712  ATH_MSG_DEBUG(" [+] Detached volume boundary, entering volume '"
1713  << nextVol->volumeName() << "'.");
1714  } else {
1715  nextVol = nullptr;
1716  ATH_MSG_DEBUG(" [+] Detached volume boundary, leaving volume '"
1717  << currVol->volumeName() << "'.");
1718  }
1719  // not necessary: currPar = nextPar; since done outside the loop and currPar not used
1720  // inside the loop if ( nextVol || !detachedBoundariesIncluded)
1721  if (nextVol) {
1723  ctx, cache, prop, nextPar, destSurf, cache.m_currentStatic,
1724  dir, bcheck, particle, matupmode);
1725  }
1726  }
1727  }
1728  iSol++;
1729  }
1730  } else {
1731  ATH_MSG_DEBUG(" [!] Propagation failed, return 0");
1732  cache.m_parametersAtBoundary.boundaryInformation(cache.m_currentStatic, nextPar, nextPar);
1733  return {};
1734  }
1735  currPar = nextPar;
1736  }
1737 
1738  return {};
1739 }

◆ extrapolateToVolume()

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolateToVolume ( const EventContext &  ctx,
const TrackParameters parm,
const Trk::TrackingVolume vol,
PropDirection  dir = anyDirection,
ParticleHypothesis  particle = pion 
) const
finaloverridevirtual

Extrapolation to volume :

Implements Trk::IExtrapolator.

Definition at line 588 of file Extrapolator.cxx.

593 {
594  // take the volume signatrue to define the right propagator
595  const IPropagator* currentPropagator =
597  : nullptr;
598  if (currentPropagator) {
599  return (extrapolateToVolumeImpl(ctx, *currentPropagator, parm, vol, dir,
600  particle));
601  }
603  " [!] No default Propagator is configured ! Please check jobOptions.");
604  return nullptr;
605 }

◆ extrapolateToVolumeBoundary()

void Trk::Extrapolator::extrapolateToVolumeBoundary ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Layer associatedLayer,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

Private method for extrapolation in intermediate volume to boundary surface.

  • Parameters are: IPropagator& prop ... propagator to be used TrackParameters& parm ... starting parameters Surface& sf ... destination surface TrackingVolume& ... the initial volume Layer* associatedLayer ... layer associatiated with starting parameters (steers postupdate) PropDirection dir ... propagation direction const BoundaryCheck& bcheck ... boolean for bounday check ParticleHypothesis particle ... the particle hypothesis std::vector<const TrackParameters*>* dethits ... for blind extrapolation it will call:
  • A) toVolumeBoundaryStaticLayers() for a TrackingVolume with static layers
  • C) toVolumeBoundaryDetachedVolumes() for a TrackingVolume with detached inner Volumes

Definition at line 2851 of file Extrapolator.cxx.

2861 {
2862  // ---> C) detached volumes exist
2863  if (!tvol.confinedDetachedVolumes().empty()) {
2865  " [!] toVolumeBoundaryDetachedVolumes(...) with confined detached volumes? This should "
2866  "not happen ! volume name and signature: "
2867  << tvol.volumeName() << ":" << tvol.geometrySignature());
2868  }
2869  // ---> A) static layers exist
2871  ctx, cache, true, prop, parm, assocLayer, tvol, dir, bcheck, particle, matupmode));
2872  if (inside_volume_static_layer && cache.m_parametersAtBoundary.navParameters) {
2873  ATH_MSG_VERBOSE(" [+] Boundary intersection - at "
2874  << positionOutput(cache.m_parametersAtBoundary.navParameters->position()));
2875  }
2876 }

◆ extrapolateToVolumeImpl()

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolateToVolumeImpl ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters parm,
const Trk::TrackingVolume vol,
PropDirection  dir = anyDirection,
ParticleHypothesis  particle = pion 
) const
private

Actual heavy lifting implementation for extrapolateToVolume.

Definition at line 1998 of file Extrapolator.cxx.

2004 {
2005  // @TODO in principle the cache should already be created
2006  // here to correctly set cache.m_methodSequence for sub-sequent calls ...
2007  ATH_MSG_DEBUG("V-[?" /*<< cache.m_methodSequence*/
2008  << "] extrapolateToVolume(...) to volume '" << vol.volumeName() << "'.");
2009  std::unique_ptr<TrackParameters> returnParms = nullptr;
2011  double dist = 0.;
2012 
2013  // retrieve boundary surfaces, order them according to distance estimate
2014  const auto& bounds = vol.boundarySurfaces();
2015  std::vector<std::pair<const Trk::Surface*, double>> surfaces;
2016  surfaces.reserve(bounds.size());
2017  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
2018  const Trk::Surface* nextSurface = &((bounds[ib])->surfaceRepresentation());
2019  if (nextSurface) {
2020  const Trk::DistanceSolution distSol = nextSurface->straightLineDistanceEstimate(
2021  parm.position(), propDir * parm.momentum().normalized());
2022  if (distSol.numberOfSolutions() > 0) {
2023  dist = distSol.first();
2024  } else {
2025  dist = distSol.toPointOfClosestApproach();
2026  }
2027  if (!surfaces.empty() && distSol.numberOfSolutions() >= 0 && dist < surfaces.back().second) {
2028  std::vector<std::pair<const Trk::Surface*, double>>::iterator sIter = surfaces.begin();
2029  while (sIter != surfaces.end()) {
2030  if (dist < (*sIter).second) {
2031  break;
2032  }
2033  ++sIter;
2034  }
2035  sIter = surfaces.insert(sIter, (std::pair<const Trk::Surface*, double>(nextSurface, dist)));
2036  } else {
2037  surfaces.emplace_back(nextSurface, dist);
2038  }
2039  }
2040  }
2041 
2042  // solution along path
2043  for (std::pair<const Trk::Surface*, double> const& a_surface : surfaces) {
2044  if (a_surface.second > 0) {
2045  Cache cache(m_propStat);
2046  Trk::CacheOwnedPtr<Trk::TrackParameters> cloneInput = cache.m_ownedPtrs.push(parm.uniqueClone());
2047  // Material effect updator cache
2048  cache.populateMatEffUpdatorCache(m_subupdaters);
2049  returnParms = cache.m_ownedPtrs.move(
2050  extrapolateImpl(ctx, cache, prop, cloneInput, *(a_surface.first),
2051  propDir, true, particle));
2052  if (returnParms.get() == &parm) {
2053  throw std::logic_error("Did not create new track parameters.");
2054  }
2055  if (returnParms) {
2056  break;
2057  }
2058  }
2059  }
2060 
2061  if (!returnParms && dir == anyDirection) {
2062  for (std::vector<std::pair<const Trk::Surface*, double>>::reverse_iterator rsIter =
2063  surfaces.rbegin();
2064  rsIter != surfaces.rend();
2065  ++rsIter) {
2066  if ((*rsIter).second < 0) {
2067  Cache cache(m_propStat);
2068  Trk::CacheOwnedPtr<Trk::TrackParameters> cloneInput = cache.m_ownedPtrs.push(parm.uniqueClone());
2069  // Material effect updator cache
2070  cache.populateMatEffUpdatorCache(m_subupdaters);
2071  returnParms = cache.m_ownedPtrs.move(
2072  extrapolateImpl(ctx, cache, prop, cloneInput, *((*rsIter).first),
2074  if (returnParms.get() == &parm) {
2075  throw std::logic_error("Did not create new track parameters.");
2076  }
2077 
2078  if (returnParms) {
2079  break;
2080  }
2081  }
2082  }
2083  }
2084  // cache.m_methodSequence=0; // originially m_methodSequence was reset here but cache not
2085  // available here
2086  return returnParms;
2087 }

◆ extrapolateToVolumeWithPathLimit()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateToVolumeWithPathLimit ( const EventContext &  ctx,
Cache cache,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
double  pathLim,
Trk::PropDirection  dir,
Trk::ParticleHypothesis  particle,
const Trk::TrackingVolume destVol,
MaterialUpdateMode  matupmod = addNoise 
) const
private

Definition at line 4070 of file Extrapolator.cxx.

4078 {
4079  // returns:
4080  // A) curvilinear track parameters if path limit reached
4081  // B) boundary parameters (at destination volume boundary)
4082  // initialize the return parameters vector
4084  const Trk::TrackingVolume* currVol = nullptr;
4085  const Trk::TrackingVolume* nextVol = nullptr;
4086  const Trk::TrackingVolume* assocVol = nullptr;
4087  unsigned int iDest = 0;
4088 
4089  // set tracking geometry in cache
4090  cache.setTrackingGeometry(*m_navigator, ctx);
4091  // destination volume boundary ?
4092  if (destVol && m_navigator->atVolumeBoundary(currPar, destVol, dir, nextVol, m_tolerance) &&
4093  nextVol != destVol) {
4094  pathLim = cache.m_path;
4095  return currPar;
4096  }
4097 
4098  const bool resolveActive = true;
4099  if (!cache.m_highestVolume) {
4100  cache.m_highestVolume = cache.m_trackingGeometry->highestTrackingVolume();
4101  }
4102 
4103  // navigation surfaces
4104  if (cache.m_navigSurfs.capacity() > m_maxNavigSurf) {
4105  cache.m_navigSurfs.reserve(m_maxNavigSurf);
4106  }
4107  cache.m_navigSurfs.clear();
4108 
4109  // target volume may not be part of tracking geometry
4110  if (destVol) {
4111  const Trk::TrackingVolume* tgVol =
4112  cache.m_trackingGeometry->trackingVolume(destVol->volumeName());
4113  if (!tgVol || tgVol != destVol) {
4114  const auto& bounds = destVol->boundarySurfaces();
4115  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
4116  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4117  cache.m_navigSurfs.emplace_back(&surf, true);
4118  }
4119  iDest = bounds.size();
4120  }
4121  }
4122 
4123  // resolve current position
4124  bool updateStatic = false;
4125  Amg::Vector3D gp = parm->position();
4126  if (!cache.m_currentStatic || !cache.m_currentStatic->inside(gp, m_tolerance)) {
4127  cache.m_currentStatic = cache.m_trackingGeometry->lowestStaticTrackingVolume(gp);
4128  updateStatic = true;
4129  }
4130 
4131  // the navigation sequence may have been evaluated already - check the cache
4132 
4133  bool navigDone = false;
4134  if (cache.m_parametersAtBoundary.nextParameters && cache.m_parametersAtBoundary.nextVolume) {
4135  if ((cache.m_parametersAtBoundary.nextParameters->position() - currPar->position()).mag() <
4136  0.001 &&
4137  cache.m_parametersAtBoundary.nextParameters->momentum().dot(currPar->momentum()) > 0.001) {
4138  nextVol = cache.m_parametersAtBoundary.nextVolume;
4139  navigDone = true;
4140  if (nextVol != cache.m_currentStatic) {
4141  cache.m_currentStatic = nextVol;
4142  updateStatic = true;
4143  }
4144  }
4145  }
4146 
4147  if (!navigDone &&
4148  m_navigator->atVolumeBoundary(
4149  currPar, cache.m_currentStatic, dir, nextVol, m_tolerance) &&
4150  nextVol != cache.m_currentStatic) {
4151  // no next volume found --- end of the world
4152  if (!nextVol) {
4153  ATH_MSG_DEBUG(" [+] Word boundary reached - at "
4154  << positionOutput(currPar->position()));
4155  if (!destVol) {
4156  pathLim = cache.m_path;
4157  }
4158  return currPar;
4159  }
4160  cache.m_currentStatic = nextVol;
4161  updateStatic = true;
4162  }
4163 
4164  // alignable volume ?
4165  if (cache.m_currentStatic && cache.m_currentStatic->geometrySignature() == Trk::Calo) {
4166  if (cache.m_currentStatic->isAlignable()) {
4167  const Trk::AlignableTrackingVolume* alignTV =
4168  static_cast<const Trk::AlignableTrackingVolume*>(cache.m_currentStatic);
4170  ctx, cache, *m_stepPropagator, currPar, nullptr, alignTV, dir, particle));
4171  if (nextPar) {
4173  ctx, cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4174  }
4175  return {};
4176 
4177  }
4178  }
4179 
4180  // update if new static volume
4181  if (updateStatic) { // retrieve boundaries
4182  cache.retrieveBoundaries();
4183  //
4184  cache.m_detachedVols.clear();
4185  cache.m_detachedBoundaries.clear();
4186  cache.m_denseVols.clear();
4187  cache.m_denseBoundaries.clear();
4188  cache.m_layers.clear();
4189  cache.m_navigLays.clear();
4190 
4191  // detached volume boundaries
4193  cache.m_currentStatic->confinedDetachedVolumes();
4194  if (!detVols.empty()) {
4196  for (; iTer != detVols.end(); ++iTer) {
4197  // active station ?
4198  const Trk::Layer* layR = (*iTer)->layerRepresentation();
4199  const bool active = layR && layR->layerType();
4200  const auto& detBounds = (*iTer)->trackingVolume()->boundarySurfaces();
4201  if (active) {
4202  cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
4203  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4204  const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4205  cache.m_detachedBoundaries.emplace_back(&surf, true);
4206  }
4207  } else if (cache.m_currentStatic->geometrySignature() != Trk::MS ||
4208  !m_useMuonMatApprox ||
4209  (*iTer)->name().compare((*iTer)->name().size() - 4, 4, "PERM") ==
4210  0) {
4211  // retrieve inert detached
4212  // objects only if needed
4213  if ((*iTer)->trackingVolume()->zOverAtimesRho() != 0. &&
4214  ((*iTer)->trackingVolume()->confinedDenseVolumes().empty()) &&
4215  ((*iTer)->trackingVolume()->confinedArbitraryLayers().empty())) {
4216  cache.m_denseVols.emplace_back((*iTer)->trackingVolume(), detBounds.size());
4217  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4218  const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4219  cache.m_denseBoundaries.emplace_back(&surf, true);
4220  }
4221  }
4223  (*iTer)->trackingVolume()->confinedArbitraryLayers();
4224  if (!(*iTer)->trackingVolume()->confinedDenseVolumes().empty() ||
4225  (confLays.size() > detBounds.size())) {
4226  cache.m_detachedVols.emplace_back(*iTer, detBounds.size());
4227  for (unsigned int ibb = 0; ibb < detBounds.size(); ibb++) {
4228  const Trk::Surface& surf = (detBounds[ibb])->surfaceRepresentation();
4229  cache.m_detachedBoundaries.emplace_back(&surf, true);
4230  }
4231  } else if (!confLays.empty()) {
4232  for (const Trk::Layer* const lIt : confLays) {
4233  cache.addOneNavigationLayer((*iTer)->trackingVolume(), lIt);
4234  }
4235  }
4236  }
4237  }
4238  }
4239  cache.m_denseResolved = std::pair<unsigned int, unsigned int>(cache.m_denseVols.size(),
4240  cache.m_denseBoundaries.size());
4241  cache.m_layerResolved = cache.m_layers.size();
4242  }
4243 
4244  cache.m_navigSurfs.insert(
4245  cache.m_navigSurfs.end(), cache.m_staticBoundaries.begin(), cache.m_staticBoundaries.end());
4246 
4247  // resolve the use of dense volumes
4248  cache.m_dense =
4249  (cache.m_currentStatic->geometrySignature() == Trk::MS && m_useMuonMatApprox) ||
4250  (cache.m_currentStatic->geometrySignature() != Trk::MS && m_useDenseVolumeDescription);
4251 
4252  // reset remaining counters
4253  cache.m_currentDense = cache.m_dense ? cache.m_currentStatic : cache.m_highestVolume;
4254  cache.m_navigBoundaries.clear();
4255  if (cache.m_denseVols.size() > cache.m_denseResolved.first) {
4256  cache.m_denseVols.resize(cache.m_denseResolved.first);
4257  }
4258  while (cache.m_denseBoundaries.size() > cache.m_denseResolved.second) {
4259  cache.m_denseBoundaries.pop_back();
4260  }
4261 
4262  if (cache.m_layers.size() > cache.m_layerResolved) {
4263  cache.m_navigLays.resize(cache.m_layerResolved);
4264  }
4265  while (cache.m_layers.size() > cache.m_layerResolved) {
4266  cache.m_layers.pop_back();
4267  }
4268 
4269  // current detached volumes
4270  // collect : subvolume boundaries, ordered/unordered layers, confined dense volumes
4272  // const Trk::DetachedTrackingVolume* currentActive = 0;
4273  std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>> navigVols;
4274 
4275  gp = currPar->position();
4276  std::vector<const Trk::DetachedTrackingVolume*> detVols =
4277  cache.m_trackingGeometry->lowestDetachedTrackingVolumes(gp);
4279  for (; dIter != detVols.end(); ++dIter) {
4280  const Trk::Layer* layR = (*dIter)->layerRepresentation();
4281  const bool active = layR && layR->layerType();
4282  if (active && !resolveActive) {
4283  continue;
4284  }
4285  if (!active && cache.m_currentStatic->geometrySignature() == Trk::MS && m_useMuonMatApprox &&
4286  (*dIter)->name().compare((*dIter)->name().size() - 4, 4, "PERM") != 0) {
4287  continue;
4288  }
4289  const Trk::TrackingVolume* dVol = (*dIter)->trackingVolume();
4290  // detached volume exit ?
4291  const bool dExit =
4292  m_navigator->atVolumeBoundary(currPar, dVol, dir, nextVol, m_tolerance) && !nextVol;
4293  if (dExit) {
4294  continue;
4295  }
4296  // inert material
4297  const auto confinedDense = dVol->confinedDenseVolumes();
4298  const auto confinedLays = dVol->confinedArbitraryLayers();
4299 
4300  if (!active && confinedDense.empty() && confinedLays.empty()) {
4301  continue;
4302  }
4303  const auto& bounds = dVol->boundarySurfaces();
4304  if (!active && confinedDense.empty() && confinedLays.size() <= bounds.size()) {
4305  continue;
4306  }
4307  if (!confinedDense.empty() || !confinedLays.empty()) {
4308  navigVols.emplace_back(dVol, bounds.size());
4309  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
4310  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4311  cache.m_navigBoundaries.emplace_back(&surf, true);
4312  }
4313  // collect dense volume boundary
4314  if (!confinedDense.empty()) {
4315  auto vIter = confinedDense.begin();
4316  for (; vIter != confinedDense.end(); ++vIter) {
4317  const auto& bounds = (*vIter)->boundarySurfaces();
4318  cache.m_denseVols.emplace_back(*vIter, bounds.size());
4319  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
4320  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4321  cache.m_denseBoundaries.emplace_back(&surf, true);
4322  }
4323  }
4324  }
4325  // collect unordered layers
4326  if (!confinedLays.empty()) {
4327  for (const auto *confinedLay : confinedLays) {
4328  cache.addOneNavigationLayer(dVol, confinedLay);
4329  }
4330  }
4331  } else { // active material
4332  const Trk::TrackingVolume* detVol = dVol->associatedSubVolume(gp);
4333  if (!detVol && dVol->confinedVolumes()) {
4334  std::span<Trk::TrackingVolume const * const> const subvols = dVol->confinedVolumes()->arrayObjects();
4335  for (const auto *subvol : subvols) {
4336  if (subvol->inside(gp, m_tolerance)) {
4337  detVol = subvol;
4338  break;
4339  }
4340  }
4341  }
4342 
4343  if (!detVol) {
4344  detVol = dVol;
4345  }
4346  bool vExit =
4347  m_navigator->atVolumeBoundary(currPar, detVol, dir, nextVol, m_tolerance) &&
4348  nextVol != detVol;
4349  if (vExit && nextVol && nextVol->inside(gp, m_tolerance)) {
4350  detVol = nextVol;
4351  vExit = false;
4352  }
4353  if (!vExit) {
4354  const auto& bounds = detVol->boundarySurfaces();
4355  navigVols.emplace_back(detVol, bounds.size());
4356  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
4357  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4358  cache.m_navigBoundaries.emplace_back(&surf, true);
4359  }
4360  if (detVol->zOverAtimesRho() != 0.) {
4361  cache.m_denseVols.emplace_back(detVol, bounds.size());
4362  for (unsigned int ib = 0; ib < bounds.size(); ib++) {
4363  const Trk::Surface& surf = (bounds[ib])->surfaceRepresentation();
4364  cache.m_denseBoundaries.emplace_back(&surf, true);
4365  }
4366  }
4367  // layers ?
4368  if (detVol->confinedLayers()) {
4369  std::span<Trk::Layer const* const> const cLays = detVol->confinedLayers()->arrayObjects();
4370  for (const auto* cLay : cLays) {
4371  if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4372  cache.addOneNavigationLayer(cLay);
4373  }
4374  }
4375  } else if (!detVol->confinedArbitraryLayers().empty()) {
4376  for (const auto & pThisLayer: detVol->confinedArbitraryLayers()) {
4377  cache.addOneNavigationLayer(detVol, pThisLayer);
4378  }
4379  }
4380  }
4381  }
4382  }
4383 
4384  // confined layers
4385  if (cache.m_currentStatic->confinedLayers() && updateStatic) {
4386  // if ( cache.m_currentStatic->confinedLayers() ) {
4387  std::span<Trk::Layer const* const> const cLays = cache.m_currentStatic->confinedLayers()->arrayObjects();
4388  for (const auto* cLay : cLays) {
4389  if (cLay->layerType() > 0 || cLay->layerMaterialProperties()) {
4390  cache.addOneNavigationLayer(cLay);
4391  }
4392  }
4393  }
4394  cache.copyToNavigationSurfaces();
4395 
4396  // current dense
4397  cache.m_currentDense = cache.m_highestVolume;
4398  if (cache.m_dense && cache.m_denseVols.empty()) {
4399  cache.m_currentDense = cache.m_currentStatic;
4400  } else {
4401  for (unsigned int i = 0; i < cache.m_denseVols.size(); i++) {
4402  const Trk::TrackingVolume* dVol = cache.m_denseVols[i].first;
4403  if (dVol->inside(currPar->position(), m_tolerance) && dVol->zOverAtimesRho() != 0.) {
4404  if (!m_navigator->atVolumeBoundary(currPar, dVol, dir, nextVol, m_tolerance) ||
4405  nextVol == dVol) {
4406  cache.m_currentDense = dVol;
4407  }
4408  }
4409  }
4410  }
4411 
4412  // ready to propagate
4413  // till: A/ static volume boundary(bcheck=true) , B/ material
4414  // layer(bcheck=true), C/ destination surface(bcheck=false) update of
4415  // cache.m_navigSurfs required if I/ entry into new navig volume, II/ exit
4416  // from currentActive without overlaps
4417  nextVol = nullptr;
4418  while (currPar) {
4419  double path = 0.;
4420  if (pathLim > 0.) {
4421  path = pathLim;
4422  }
4423  std::vector<unsigned int> solutions;
4424  ATH_MSG_DEBUG(" [+] Starting propagation at position "
4425  << positionOutput(currPar->position())
4426  << " (current momentum: " << currPar->momentum().mag() << ")");
4427  ATH_MSG_DEBUG(" [+] " << cache.m_navigSurfs.size() << " target surfaces in '"
4428  << cache.m_currentDense->volumeName()
4429  << "'."); // verify that material input makes sense
4430  ATH_MSG_DEBUG(" [+] "
4431  << " with path limit" << pathLim
4432  << ","); // verify that material input makes sense
4433  ATH_MSG_DEBUG(" [+] "
4434  << " in the direction" << dir << "."); // verify that material input makes sense
4435  if (!(cache.m_currentDense->inside(currPar->position(), m_tolerance) ||
4436  m_navigator->atVolumeBoundary(
4437  currPar, cache.m_currentDense, dir, assocVol, m_tolerance))) {
4438  cache.m_currentDense = cache.m_highestVolume;
4439  }
4440  Trk::CacheOwnedPtr<Trk::TrackParameters> nextPar = cache.m_ownedPtrs.push(m_stepPropagator->propagate(
4441  ctx, *currPar, cache.m_navigSurfs, dir, m_fieldProperties, particle,
4442  solutions, path, true, false, cache.m_currentDense));
4443  if (nextPar) {
4444  ++cache.m_nPropagations;
4445  ATH_MSG_DEBUG(" [+] Position after propagation - at "
4446  << positionOutput(nextPar->position()));
4447  ATH_MSG_DEBUG(" [+] Momentum after propagation - " << nextPar->momentum());
4448  }
4449 
4450  if (pathLim > 0. && cache.m_path + path >= pathLim) {
4451  cache.m_path += path;
4452  return nextPar;
4453  }
4454  // check missing volume boundary
4455  if (nextPar && !(cache.m_currentDense->inside(nextPar->position(), m_tolerance) ||
4456  m_navigator->atVolumeBoundary(
4457  nextPar, cache.m_currentDense, dir, assocVol, m_tolerance))) {
4458  ATH_MSG_DEBUG(" [!] ERROR: missing volume boundary for volume"
4459  << cache.m_currentDense->volumeName());
4460  if (cache.m_currentDense->zOverAtimesRho() != 0.) {
4461  ATH_MSG_DEBUG(" [!] ERROR: trying to recover: repeat the propagation step in"
4462  << cache.m_highestVolume->volumeName());
4463  cache.m_currentDense = cache.m_highestVolume;
4464  continue;
4465  }
4466  }
4467  if (!nextPar) {
4468  ATH_MSG_DEBUG(" [!] Propagation failed, return 0");
4469  cache.m_parametersAtBoundary.boundaryInformation(cache.m_currentStatic, nextPar, nextPar);
4470  // @TODO reset m_parametersAtBoundary ?
4471  return {};
4472  }
4473  cache.m_path += path;
4474  if (pathLim > 0.) {
4475  pathLim -= path;
4476  }
4477  ATH_MSG_DEBUG(" [+] Number of intersection solutions: " << solutions.size());
4478  // Material effects
4479  if (cache.m_currentDense->zOverAtimesRho() != 0.&&
4480  cache.m_extrapolationCache) {
4481  const double dInX0 = std::abs(path) / cache.m_currentDense->x0();
4482  const double currentqoverp = nextPar->parameters()[Trk::qOverP];
4483  const MaterialProperties materialProperties(*cache.m_currentDense, std::abs(path));
4484  const EnergyLoss eloss = (m_elossupdater->energyLoss(
4485  materialProperties, std::abs(1. / currentqoverp), 1., dir, particle));
4486  if (m_dumpCache) {
4487  ATH_MSG_DEBUG(cache.to_string( " extrapolateToVolumeWithPathLimit"));
4488  }
4489  cache.m_extrapolationCache->updateX0(dInX0);
4490  cache.m_extrapolationCache->updateEloss(
4491  eloss.meanIoni(), eloss.sigmaIoni(), eloss.meanRad(), eloss.sigmaRad());
4492  if (m_dumpCache) {
4493  ATH_MSG_DEBUG(cache.to_string(" After"));
4494  }
4495  }
4496 
4497  unsigned int iSol = 0;
4498  while (iSol < solutions.size()) {
4499  if (solutions[iSol] < iDest) {
4500  return nextPar;
4501  } if (solutions[iSol] < iDest + cache.m_staticBoundaries.size()) {
4502  // material attached ?
4503  const Trk::Layer* mb = cache.m_navigSurfs[solutions[iSol]].first->materialLayer();
4504  if (mb) {
4505  if (mb->layerMaterialProperties() &&
4506  mb->layerMaterialProperties()->fullMaterial(nextPar->position())) {
4507  const double pIn = nextPar->momentum().mag();
4508  const IMaterialEffectsUpdator* currentUpdator =
4509  subMaterialEffectsUpdator(*cache.m_currentStatic);
4510  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
4511  cache.subMaterialEffectsUpdatorCache();
4512  if (currentUpdator) {
4513  nextPar = cache.m_ownedPtrs.push(
4514  currentUpdator->update(
4515  currentUpdatorCache, nextPar, *mb, dir, particle, matupmod));
4516  }
4517  if (!nextPar) {
4518  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
4519  cache.m_parametersAtBoundary.resetBoundaryInformation();
4520  return {};
4521  } // the MEOT will be saved at the end
4522  ATH_MSG_VERBOSE(" Updated energy loss:" << nextPar->momentum().mag() - pIn
4523  << "at position:" << nextPar->position());
4524 
4525  }
4526  }
4527  // static volume boundary; return to the main loop
4528  const unsigned int index = solutions[iSol] - iDest;
4529  // use global coordinates to retrieve attached volume (just for static!)
4530  nextVol = (cache.m_currentStatic->boundarySurfaces())[index]->attachedVolume(
4531  nextPar->position(), nextPar->momentum(), dir);
4532  if (nextVol != cache.m_currentStatic) {
4533  cache.m_parametersAtBoundary.boundaryInformation(nextVol, nextPar, nextPar);
4534  ATH_MSG_DEBUG(" [+] StaticVol boundary reached of '"
4535  << cache.m_currentStatic->volumeName()
4536  << "', geoID: " << cache.m_currentStatic->geometrySignature());
4537 
4538  if (m_navigator->atVolumeBoundary(
4539  nextPar, cache.m_currentStatic, dir, assocVol, m_tolerance) &&
4540  assocVol != cache.m_currentStatic) {
4541  cache.m_currentDense = cache.m_dense ? nextVol : cache.m_highestVolume;
4542  }
4543  // no next volume found --- end of the world
4544  if (!nextVol) {
4545  ATH_MSG_DEBUG(" [+] World boundary reached - at "
4546  << positionOutput(nextPar->position()));
4547  if (!destVol) {
4548  pathLim = cache.m_path;
4549  return nextPar;
4550  }
4551  }
4552  // next volume found and parameters are at boundary
4553  if (nextVol /*&& nextPar nextPar is dereferenced after*/) {
4554  ATH_MSG_DEBUG(" [+] Crossing to next volume '"
4555  << nextVol->volumeName()
4556  << "', next geoID: " << nextVol->geometrySignature());
4557  ATH_MSG_DEBUG(" [+] Crossing position is - at "
4558  << positionOutput(nextPar->position()));
4559  if (!destVol &&
4560  cache.m_currentStatic->geometrySignature() != nextVol->geometrySignature()) {
4561  pathLim = cache.m_path;
4562  return nextPar;
4563  }
4564  }
4566  ctx, cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4567  }
4568  } else if (solutions[iSol] <
4569  iDest + cache.m_staticBoundaries.size() + cache.m_layers.size()) {
4570  // next layer; don't return passive material layers unless required
4571  const unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size();
4572  const Trk::Layer* nextLayer = cache.m_navigLays[index].second;
4573  // material update ?
4574  bool matUp = nextLayer->fullUpdateMaterialProperties(*nextPar) &&
4575  m_includeMaterialEffects && nextLayer->isOnLayer(nextPar->position());
4576 
4577  // material update: pre-update
4578  const IMaterialEffectsUpdator* currentUpdator =
4579  subMaterialEffectsUpdator(*cache.m_currentStatic);
4580  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
4581  cache.subMaterialEffectsUpdatorCache();
4582 
4583  if (matUp && nextLayer->surfaceArray()) {
4584  const double pIn = nextPar->momentum().mag();
4585  if (currentUpdator) {
4586  nextPar = cache.m_ownedPtrs.push(
4587  currentUpdator->preUpdate(
4588  currentUpdatorCache, nextPar, *nextLayer, dir, particle, matupmod));
4589  }
4590  if (!nextPar) {
4591  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
4592  cache.m_parametersAtBoundary.resetBoundaryInformation();
4593  return {};
4594  } // the MEOT will be saved at the end
4595  ATH_MSG_VERBOSE(" Pre-update energy loss:"
4596  << nextPar->momentum().mag() - pIn << "at position:"
4597  << nextPar->position() << ", current momentum:" << nextPar->momentum());
4598 
4599  }
4600  // active surface intersections ( Fatras hits ...)
4601  if (cache.m_parametersOnDetElements && particle != Trk::neutron) {
4602  if (nextLayer->surfaceArray()) {
4603  ATH_MSG_VERBOSE(" [o] Calling overlapSearch() on layer.");
4604  overlapSearch(ctx, cache, *m_subPropagators[0], currPar, nextPar,
4605  *nextLayer, *cache.m_currentStatic, dir, true,
4606  particle);
4607  } else if (nextLayer->layerType() > 0 &&
4608  nextLayer->isOnLayer(nextPar->position())) {
4609  ATH_MSG_VERBOSE(" [o] Collecting intersection with active layer.");
4610  cache.m_parametersOnDetElements->emplace_back(nextPar->uniqueClone());
4611  }
4612  } // -------------------------- Fatras mode off -----------------------------------
4613 
4614  if (matUp) {
4615  if (nextLayer->surfaceArray()) {
4616  // verify there is material for postUpdate
4617  const double postFactor = nextLayer->postUpdateMaterialFactor(*nextPar, dir);
4618  if (postFactor > 0.1) {
4619  const double pIn = nextPar->momentum().mag();
4620  if (currentUpdator) {
4621  nextPar = cache.m_ownedPtrs.push(currentUpdator->postUpdate(
4622  currentUpdatorCache, *nextPar, *nextLayer, dir, particle,
4623  matupmod));
4624  }
4625  if (!nextPar) {
4626  ATH_MSG_VERBOSE("postUpdate failed");
4627  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
4628  cache.m_parametersAtBoundary.resetBoundaryInformation();
4629  return {};
4630  } // the MEOT will be saved at the end
4631  ATH_MSG_VERBOSE(" Post-update energy loss:" << nextPar->momentum().mag() - pIn
4632  << "at position:"
4633  << nextPar->position());
4634 
4635  }
4636  } else {
4637  const double pIn = nextPar->momentum().mag();
4638  if (currentUpdator) {
4639  nextPar = cache.m_ownedPtrs.push(
4640  currentUpdator->update(currentUpdatorCache, nextPar,
4641  *nextLayer, dir, particle, matupmod));
4642  }
4643  if (!nextPar) {
4644  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
4645  cache.m_parametersAtBoundary.resetBoundaryInformation();
4646  return {};
4647  } // the MEOT will be saved at the end
4648  ATH_MSG_VERBOSE(" Update energy loss:" << nextPar->momentum().mag() - pIn
4649  << "at position:" << nextPar->position());
4650 
4651  }
4652  }
4653  currPar = nextPar;
4654  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() + cache.m_layers.size() +
4655  cache.m_denseBoundaries.size()) {
4656  // dense volume boundary
4657  unsigned int index =
4658  solutions[iSol] - iDest - cache.m_staticBoundaries.size() - cache.m_layers.size();
4659  std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>::iterator dIter =
4660  cache.m_denseVols.begin();
4661  while (dIter != cache.m_denseVols.end() && index >= (*dIter).second) {
4662  index -= (*dIter).second;
4663  ++dIter;
4664  }
4665  if (dIter != cache.m_denseVols.end()) {
4666  currVol = (*dIter).first;
4667  nextVol =
4668  ((*dIter).first->boundarySurfaces())[index]->attachedVolume(*nextPar, dir);
4669  // the boundary orientation is not reliable
4670  const Amg::Vector3D tp =
4671  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
4672  if (currVol->inside(tp, 0.)) {
4673  cache.m_currentDense = currVol;
4674  } else if (!nextVol || !nextVol->inside(tp, 0.)) { // search for dense volumes
4675  cache.m_currentDense = cache.m_highestVolume;
4676  if (cache.m_dense && cache.m_denseVols.empty()) {
4677  cache.m_currentDense = cache.m_currentStatic;
4678  } else {
4679  for (unsigned int i = 0; i < cache.m_denseVols.size(); i++) {
4680  const Trk::TrackingVolume* dVol = cache.m_denseVols[i].first;
4681  if (dVol->inside(tp, 0.) && dVol->zOverAtimesRho() != 0.) {
4682  cache.m_currentDense = dVol;
4683  ATH_MSG_DEBUG(" [+] Next dense volume found: '"
4684  << cache.m_currentDense->volumeName() << "'.");
4685  break;
4686  }
4687  } // loop over dense volumes
4688  }
4689  } else {
4690  cache.m_currentDense = nextVol;
4691  ATH_MSG_DEBUG(" [+] Next dense volume: '" << cache.m_currentDense->volumeName()
4692  << "'.");
4693  }
4694  }
4695  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() + cache.m_layers.size() +
4696  cache.m_denseBoundaries.size() +
4697  cache.m_navigBoundaries.size()) {
4698  // navig volume boundary
4699  unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size() -
4700  cache.m_layers.size() - cache.m_denseBoundaries.size();
4701  std::vector<std::pair<const Trk::TrackingVolume*, unsigned int>>::iterator nIter =
4702  navigVols.begin();
4703  while (nIter != navigVols.end() && index >= (*nIter).second) {
4704  index -= (*nIter).second;
4705  ++nIter;
4706  }
4707  if (nIter != navigVols.end()) {
4708  currVol = (*nIter).first;
4709  nextVol =
4710  ((*nIter).first->boundarySurfaces())[index]->attachedVolume(*nextPar, dir);
4711  // the boundary orientation is not reliable
4712  const Amg::Vector3D tp =
4713  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
4714  if (nextVol && nextVol->inside(tp, 0.)) {
4715  ATH_MSG_DEBUG(" [+] Navigation volume boundary, entering volume '"
4716  << nextVol->volumeName() << "'.");
4717  } else if (currVol->inside(tp, 0.)) {
4718  nextVol = currVol;
4719  ATH_MSG_DEBUG(" [+] Navigation volume boundary, entering volume '"
4720  << nextVol->volumeName() << "'.");
4721  } else {
4722  nextVol = nullptr;
4723  ATH_MSG_DEBUG(" [+] Navigation volume boundary, leaving volume '"
4724  << currVol->volumeName() << "'.");
4725  }
4726  // return only if detached volume boundaries not collected
4727  // if ( nextVol || !detachedBoundariesIncluded )
4728  if (nextVol) {
4730  ctx, cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4731  }
4732  currPar = nextPar;
4733  }
4734  } else if (solutions[iSol] < iDest + cache.m_staticBoundaries.size() + cache.m_layers.size() +
4735  cache.m_denseBoundaries.size() +
4736  cache.m_navigBoundaries.size() +
4737  cache.m_detachedBoundaries.size()) {
4738  // detached volume boundary
4739  unsigned int index = solutions[iSol] - iDest - cache.m_staticBoundaries.size() -
4740  cache.m_layers.size() - cache.m_denseBoundaries.size() -
4741  cache.m_navigBoundaries.size();
4742  std::vector<std::pair<const Trk::DetachedTrackingVolume*, unsigned int>>::iterator dIter =
4743  cache.m_detachedVols.begin();
4744  while (dIter != cache.m_detachedVols.end() && index >= (*dIter).second) {
4745  index -= (*dIter).second;
4746  ++dIter;
4747  }
4748  if (dIter != cache.m_detachedVols.end()) {
4749  currVol = (*dIter).first->trackingVolume();
4750  nextVol =
4751  ((*dIter).first->trackingVolume()->boundarySurfaces())[index]->attachedVolume(
4752  *nextPar, dir);
4753  // the boundary orientation is not reliable
4754  const Amg::Vector3D tp =
4755  nextPar->position() + 2 * m_tolerance * dir * nextPar->momentum().normalized();
4756  if (nextVol && nextVol->inside(tp, 0.)) {
4757  ATH_MSG_DEBUG(" [+] Detached volume boundary, entering volume '"
4758  << nextVol->volumeName() << "'.");
4759  } else if (currVol->inside(tp, 0.)) {
4760  nextVol = currVol;
4761  ATH_MSG_DEBUG(" [+] Detached volume boundary, entering volume '"
4762  << nextVol->volumeName() << "'.");
4763  } else {
4764  nextVol = nullptr;
4765  ATH_MSG_DEBUG(" [+] Detached volume boundary, leaving volume '"
4766  << currVol->volumeName() << "'.");
4767  }
4768  // if ( nextVol || !detachedBoundariesIncluded)
4769  if (nextVol) {
4771  ctx, cache, nextPar, pathLim, dir, particle, destVol, matupmod);
4772  }
4773  currPar = nextPar;
4774  }
4775  }
4776  iSol++;
4777  }
4778  currPar = nextPar;
4779  }
4780  return {};
4781 }

◆ extrapolateTrack()

std::unique_ptr< Trk::TrackParameters > Trk::Extrapolator::extrapolateTrack ( const EventContext &  ctx,
const Track trk,
const Surface sf,
Trk::PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
Trk::ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise,
Trk::ExtrapolationCache cache = nullptr 
) const
finaloverridevirtual

Main extrapolation interface starting from a Trk::Track and aiming at Surface.

It uses the navigator to find the closest parameters of the track to the surface.

Implements Trk::IExtrapolator.

Definition at line 422 of file Extrapolator.cxx.

431 {
432  const Trk::TrackParameters* closestTrackParameters = m_navigator->closestParameters(trk, sf);
433  if (closestTrackParameters) {
434  return (extrapolate(
435  ctx, *closestTrackParameters, sf, dir, bcheck, particle, matupmode, extrapolationCache));
436  }
437  closestTrackParameters = *(trk.trackParameters()->begin());
438  if (closestTrackParameters) {
439  return (extrapolate(
440  ctx, *closestTrackParameters, sf, dir, bcheck, particle, matupmode, extrapolationCache));
441  }
442  return nullptr;
443 }

◆ extrapolateWithinDetachedVolumes()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::extrapolateWithinDetachedVolumes ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Surface sf,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

C) call from extrapolateInsideVolume.

Definition at line 2678 of file Extrapolator.cxx.

2688 {
2689  // method sequence output ---------------------------------
2690  ++cache.m_methodSequence;
2691  ATH_MSG_DEBUG("M-[" << cache.m_methodSequence << "] extrapolateWithinDetachedVolumes() inside '"
2692  << tvol.volumeName() << "' to destination surface. ");
2693 
2694  double dist = 0.;
2695  // initialization
2696  Trk::CacheOwnedPtr<Trk::TrackParameters> nextParameters= parm;
2697  const Trk::TrackingVolume* currVol = &tvol;
2698 
2699  // set tracking geometry in cache
2700  cache.setTrackingGeometry(*m_navigator,ctx);
2701  // arbitrary surface or destination layer ?
2702  // bool loopOverLayers = false;
2703  const Trk::Layer* destinationLayer =
2704  cache.m_trackingGeometry->associatedLayer(sf.center());
2705  // if ( destinationLayer ) loopOverLayers = true;
2706 
2707  // initial distance to surface
2708  const Trk::DistanceSolution distSol = sf.straightLineDistanceEstimate(
2709  nextParameters->position(), dir * nextParameters->momentum().normalized());
2710  if (distSol.numberOfSolutions() > 0) {
2711  dist = distSol.first();
2712  } else {
2713  dist = distSol.toPointOfClosestApproach();
2714  }
2715 
2716  if (destinationLayer && destinationLayer->isOnLayer(nextParameters->position())) {
2717  ATH_MSG_DEBUG(" [-] Already at destination layer, distance:" << dist);
2718  Trk::CacheOwnedPtr<Trk::TrackParameters> fwd = cache.m_ownedPtrs.push(
2719  prop.propagate(ctx, *nextParameters, sf, dir, bcheck, m_fieldProperties,
2720  particle, false, currVol));
2721 
2722  if (fwd) {
2723  return fwd;
2724  }
2725  Trk::PropDirection const oppDir =
2727  return cache.m_ownedPtrs.push(
2728  prop.propagate(ctx, *nextParameters, sf, oppDir, bcheck,
2729  m_fieldProperties, particle, false, currVol));
2730  }
2731 
2732  if (std::abs(dist) < m_tolerance) {
2733  ATH_MSG_DEBUG(" [-] Already at the destination surface.");
2734 
2735  if (dist >= 0.) {
2736  return cache.m_ownedPtrs.push(prop.propagate(ctx, *nextParameters, sf, dir,
2737  bcheck, m_fieldProperties,
2738  particle, false, currVol));
2739  }
2740  Trk::PropDirection const oppDir =
2742  return cache.m_ownedPtrs.push(
2743  prop.propagate(ctx, *nextParameters, sf, oppDir, bcheck,
2744  m_fieldProperties, particle, false, currVol));
2745  }
2746  if (dist < 0.) {
2747  ATH_MSG_DEBUG(" [!] Initial 3D-distance to the surface negative ("
2748  << dist << ") -> skip extrapolation.");
2749  cache.m_parametersAtBoundary.resetBoundaryInformation();
2750  return {};
2751  }
2752 
2753  ATH_MSG_DEBUG(" [+] Initial 3D-distance to destination - d3 = " << dist);
2754 
2755  // loop over material layers till
2756  // a/ destination layer found (accept solutions outside surface boundary)
2757  // b/ boundary reached
2758  // c/ negative distance to destination surface( propagate directly to the surface )
2759 
2760  // ---------------------------- main loop over next material layers
2761  // used only to check whether parametersAtBoundary
2762  Trk::TrackParameters* last_boundary_parameters = nullptr;
2763 
2764  while (nextParameters) {
2765  const Trk::BoundaryCheck& bchk = false;
2767  ctx, cache, prop, nextParameters, &sf, currVol, dir, bchk, particle, matupmode);
2768  if (onNextLayer) { // solution with the destination surface ?
2769  // isOnSurface dummy for Perigee, use straightline distance estimate instead
2770  // if ( sf.isOnSurface(onNextLayer->position(),bchk,m_tolerance,m_tolerance) ) {
2771  const Trk::DistanceSolution distSol = sf.straightLineDistanceEstimate(
2772  onNextLayer->position(), dir * onNextLayer->momentum().normalized());
2773  const double currentDistance = (distSol.numberOfSolutions() > 0)
2774  ? distSol.absClosest()
2775  : std::abs(distSol.toPointOfClosestApproach());
2776  if (currentDistance <= m_tolerance &&
2777  sf.isOnSurface(onNextLayer->position(), bchk, m_tolerance, m_tolerance)) {
2778  cache.m_parametersAtBoundary.resetBoundaryInformation();
2779  if (!bcheck || sf.isOnSurface(onNextLayer->position(), bcheck, m_tolerance, m_tolerance)) {
2780  if (sf.type() != onNextLayer->associatedSurface().type()) {
2781  ATH_MSG_DEBUG("mismatch in destination surface type:"
2782  << static_cast<int>(sf.type())
2783  << "," << static_cast<int>(onNextLayer->associatedSurface().type())
2784  << ":distance to the destination surface:" << currentDistance);
2785  Trk::CacheOwnedPtr<Trk::TrackParameters> cParms = cache.m_ownedPtrs.push(prop.propagate(
2786  ctx, *onNextLayer, sf, dir, bchk, m_fieldProperties, particle));
2787  return cParms;
2788  }
2789  return onNextLayer;
2790  }
2791  return {};
2792  }
2793  } else {
2794  // world boundary ?
2795  if (cache.m_parametersAtBoundary.nextParameters && !cache.m_parametersAtBoundary.nextVolume) {
2796  nextParameters = onNextLayer;
2797  break;
2798  }
2799  if (!cache.m_parametersAtBoundary.nextParameters
2800  || cache.m_status != Cache::kContinue) {
2801  return {};
2802  }
2803 
2804  // static volume boundary: check distance to destination
2805  const Trk::DistanceSolution distSol = sf.straightLineDistanceEstimate(
2806  cache.m_parametersAtBoundary.nextParameters->position(),
2807  dir * cache.m_parametersAtBoundary.nextParameters->momentum().normalized());
2808  if (distSol.numberOfSolutions() > 0) {
2809  dist = distSol.first();
2810  } else {
2811  dist = distSol.toPointOfClosestApproach();
2812  }
2813  if (dist < 0.) {
2814  cache.m_parametersAtBoundary.resetBoundaryInformation();
2815  return {};
2816  } if (cache.m_parametersAtBoundary.nextVolume &&
2817  (cache.m_parametersAtBoundary.nextVolume->geometrySignature() == Trk::MS ||
2818  (cache.m_parametersAtBoundary.nextVolume->geometrySignature() == Trk::Calo &&
2820  if (cache.m_parametersAtBoundary.nextParameters) {
2821  if (last_boundary_parameters &&
2822  last_boundary_parameters == cache.m_parametersAtBoundary.nextParameters) {
2824  " [!] Already tried parameters at boundary -> exit: pos="
2825  << positionOutput(cache.m_parametersAtBoundary.nextParameters->position())
2826  << " momentum="
2827  << momentumOutput(cache.m_parametersAtBoundary.nextParameters->momentum()));
2828  cache.m_parametersAtBoundary.resetBoundaryInformation();
2829  return {};
2830  }
2831  onNextLayer = cache.m_parametersAtBoundary.nextParameters;
2832  last_boundary_parameters = cache.m_parametersAtBoundary.nextParameters;
2833  ATH_MSG_DEBUG(" [+] Try parameters at boundary: pos="
2834  << positionOutput(cache.m_parametersAtBoundary.nextParameters->position())
2835  << " momentum="
2836  << momentumOutput(cache.m_parametersAtBoundary.nextParameters->momentum()));
2837  }
2838  currVol = cache.m_parametersAtBoundary.nextVolume;
2839  }
2840  }
2841  nextParameters = onNextLayer;
2842  } // end loop over material layers
2843 
2844  // boundary reached , return to the main loop
2845  ATH_MSG_DEBUG(" [+] extrapolateWithinDetachedVolumes(...) reached static boundary, return to "
2846  "the main loop.");
2847  return nextParameters;
2848 }

◆ finalize()

StatusCode Trk::Extrapolator::finalize ( )
overridevirtual

AlgTool finalize method.

Definition at line 277 of file Extrapolator.cxx.

278 {
279  if (m_propStat.m_maxRecursionCount>0) {
280  ATH_MSG_INFO("ExtrapolatorStat: maximum-recursion-depth = " << m_propStat.m_maxRecursionCount);
281  }
282  if (m_propStat.m_maxPropagations>0) {
283  ATH_MSG_INFO("ExtrapolatorStat: maximum-number-of-propagations = " << m_propStat.m_maxPropagations);
284  }
285  if (m_propStat.m_maxMethodSequence>0) {
286  ATH_MSG_INFO("ExtrapolatorStat: maximum-method-sequence-number = " << m_propStat.m_maxMethodSequence);
287  }
289  ATH_MSG_INFO(" Perfomance Statistics : ");
290  ATH_MSG_INFO(" [P] Method Statistics ------- ------------------------------------");
291  ATH_MSG_INFO(" -> Number of extrapolate() calls : " << m_extrapolateCalls);
292  ATH_MSG_INFO(
293  " -> Number of extrapolateBlindly() calls : " << m_extrapolateBlindlyCalls);
294  ATH_MSG_INFO(
295  " -> Number of extrapolateDirectly() calls : " << m_extrapolateDirectlyCalls);
296  ATH_MSG_INFO(
297  " -> Number of extrapolateStepwise() calls : " << m_extrapolateStepwiseCalls);
298  ATH_MSG_INFO(" -> Number of layers switched in layer2layer : " << m_layerSwitched);
299  ATH_MSG_INFO("[P] Navigation Initialization -------------------------------------");
300  ATH_MSG_INFO(
301  " -> Number of start associations : " << m_startThroughAssociation);
302  ATH_MSG_INFO(" -> Number of start recalls : " << m_startThroughRecall);
303  ATH_MSG_INFO(
304  " -> Number of start global searches : " << m_startThroughGlobalSearch);
305  ATH_MSG_INFO(
306  " -> Number of destination associations : " << m_destinationThroughAssociation);
307  ATH_MSG_INFO(
308  " -> Number of destination recalls : " << m_destinationThroughRecall);
309  ATH_MSG_INFO(" -> Number of destination global searches : "
311  ATH_MSG_INFO("[P] Navigation Breaks ---------------------------------------------");
312  ATH_MSG_INFO(
313  " -> Number of navigation breaks: loop : " << m_navigationBreakLoop);
314  ATH_MSG_INFO(
315  " -> Number of navigation breaks: oscillation : " << m_navigationBreakOscillation);
316  ATH_MSG_INFO(
317  " -> Number of navigation breaks: no volume found : " << m_navigationBreakNoVolume);
318  ATH_MSG_INFO(
319  " -> Number of navigation breaks: dist. increase : " << m_navigationBreakDistIncrease);
320  ATH_MSG_INFO(" -> Number of navigation breaks: dist. increase : "
323  ATH_MSG_DEBUG(" Detailed output for Navigation breaks : ");
325  << " loops occured in the following volumes: ");
327  << " oscillations occured in following volumes: ");
329  << " times no next volume found of volumes: ");
331  << " distance increases detected at volumes: ");
333  << " no propagator configured for volumes: ");
334  }
335  // validation of the overlap search
336  ATH_MSG_INFO("[P] Overlaps found ------------------------------------------------");
337  ATH_MSG_INFO(" -> Number of overlap Surface hit : " << m_overlapSurfaceHit);
338  ATH_MSG_INFO(" ------------------------------------------------------------------");
339  }
340 
341  return StatusCode::SUCCESS;
342 }

◆ initialize()

StatusCode Trk::Extrapolator::initialize ( )
overridevirtual

AlgTool initailize method.

Definition at line 131 of file Extrapolator.cxx.

132 {
133 
134  m_referenceSurface = std::make_unique<Trk::PlaneSurface>(Amg::Transform3D(Trk::s_idTransform), 0., 0.);
135  m_referenceSurface->setOwner(Trk::userOwn); //this is owned by an instance of this class
136 
138  : Trk::MagneticFieldProperties(Trk::FullField);
139 
140  // before we start messing around, how many of these updaters were actually passed in?
141  const auto numberOfSubPropagatorsGiven = m_propNames.size();
142  const auto numberOfSubMatEffUpdatersGiven = m_updatNames.size();
143  //
144  if (m_propagators.empty()) {
145  m_propagators.push_back("Trk::RungeKuttaPropagator/DefaultPropagator");
146  }
147  if (m_updaters.empty()) {
148  m_updaters.push_back("Trk::MaterialEffectsUpdator/DefaultMaterialEffectsUpdator");
149  }
150 
151 
152  if (!m_propagators.empty()) {
153  ATH_CHECK(m_propagators.retrieve());
154  }
155 
156  // from the number of retrieved propagators set the configurationLevel
157  const unsigned int validprop = m_propagators.size();
158 
159  if (!validprop) {
160  ATH_MSG_WARNING("None of the defined propagators could be retrieved!");
161  ATH_MSG_WARNING("Extrapolator unconfigured");
162  } else {
163  m_numOfValidPropagators = validprop ;
164  ATH_MSG_VERBOSE("Number of Valid Propagators " << m_numOfValidPropagators);
165  }
166 
167  // Get the Navigation AlgTools
168  ATH_CHECK(m_navigator.retrieve());
169 
170  // Get the Material Updator
171  if (m_includeMaterialEffects && not m_updaters.empty()) {
172  ATH_CHECK(m_updaters.retrieve());
173  for (auto& tool : m_updaters) {
174  // @TODO tools, that are already used, should not be disabled. Those are
175  // currently disabled to silence the warning issued by the tool usage
176  // detection, which is circumvented in case of the m_updaters.
177  tool.disable();
178  }
179  }
180 
181  // from the number of retrieved propagators set the configurationLevel
182  const unsigned int validmeuts = m_updaters.size();
183  std::vector<std::string> fullPropagatorNames(m_propagators.size());
184  std::vector<std::string> fullUpdatorNames(m_updaters.size());
185  auto extractNameFromTool = [](const auto& toolHndl) { return toolHndl->name(); };
187  m_propagators.begin(), m_propagators.end(), fullPropagatorNames.begin(), extractNameFromTool);
189  m_updaters.begin(), m_updaters.end(), fullUpdatorNames.begin(), extractNameFromTool);
190 
191  // ------------------------------------
192  // Sanity check 1
193  if (m_propNames.empty() && not m_propagators.empty()) {
195  "Inconsistent setup of Extrapolator, no sub-propagators configured, doing it for you. ");
196  m_propNames.value().push_back(TrkExTools::getToolSuffix(fullPropagatorNames[0]));
198  TrkExTools::numberOfUniqueEntries(fullPropagatorNames)) {
199  ATH_MSG_ERROR("Some configured propagators have same name but different owners");
200  }
201  if (const auto& errMsg = TrkExTools::possibleToolNameError(m_propNames); not errMsg.empty()) {
202  ATH_MSG_ERROR(errMsg);
203  }
204  }
205 
206  if (m_updatNames.empty() && not m_updaters.empty()) {
207  ATH_MSG_DEBUG("Inconsistent setup of Extrapolator, no sub-material updaters configured, doing "
208  "it for you. ");
209  m_updatNames.value().push_back(TrkExTools::getToolSuffix(fullUpdatorNames[0]));
211  TrkExTools::numberOfUniqueEntries(fullUpdatorNames)) {
212  ATH_MSG_ERROR("Some configured material updaters have same name but different owners");
213  }
214  if (const auto& errMsg = TrkExTools::possibleToolNameError(m_updatNames); not errMsg.empty()) {
215  ATH_MSG_ERROR(errMsg);
216  }
217  }
218 
219  // ------------------------------------
220  // Sanity check 2
221  // fill the number of propagator names and updator names up with first one
222  m_propNames.value().resize(static_cast<int>(Trk::NumberOfSignatures), m_propNames[0]);
223  m_updatNames.value().resize(static_cast<int>(Trk::NumberOfSignatures), m_updatNames[0]);
224 
225  if (validprop && validmeuts) {
226  // Per definition: if configured not found, take the lowest one
227  for (unsigned int isign = 0; int(isign) < int(Trk::NumberOfSignatures); ++isign) {
228  unsigned int index = 0;
229  for (unsigned int iProp = 0; iProp < m_propagators.size(); iProp++) {
230  const std::string pname = TrkExTools::getToolSuffix(m_propagators[iProp]->name());
231  if (m_propNames[isign] == pname) {
232  index = iProp;
233  }
234  }
236  " subPropagator:" << isign << " pointing to propagator: " << m_propagators[index]->name());
237  m_subPropagators[isign] =
238  (index < validprop) ? &(*m_propagators[index]) : &(*m_propagators[Trk::Global]);
239 
240  index = 0;
241  for (unsigned int iUp = 0; iUp < m_updaters.size(); iUp++) {
242  const std::string uname = TrkExTools::getToolSuffix(m_updaters[iUp]->name());
243  if (m_updatNames[isign] == uname) {
244  index = iUp;
245  }
246  }
247  ATH_MSG_DEBUG(" subMEUpdator:" << isign
248  << " pointing to updator: " << m_updaters[index]->name());
249  m_subupdaters[isign] =
250  (index < validmeuts) ? &(*m_updaters[index]) : &(*m_updaters[Trk::Global]);
251  }
252  } else {
254  "Configuration Problem of Extrapolator: "
255  << " -- At least one IPropagator and IMaterialUpdator instance have to be given.! ");
256  }
257  const std::string propStr = std::to_string(numberOfSubPropagatorsGiven) + " propagator" +
258  std::string((numberOfSubPropagatorsGiven == 1) ? "" : "s");
259  const std::string updStr = std::to_string(numberOfSubMatEffUpdatersGiven) + " updater" +
260  std::string((numberOfSubMatEffUpdatersGiven == 1) ? "" : "s");
261  std::string msgString{ "\nThe extrapolator uses six sub-propagators and "
262  "sub-material effects updaters:\n" };
263  msgString += propStr + " and " + updStr + " were given in the configuration,\n";
264  msgString += "the extrapolator sub-tools have been defined as follows: \n";
265  for (int i(0); i != int(Trk::NumberOfSignatures); ++i) {
266  msgString += std::to_string(i) + ") propagator: " + m_subPropagators[i]->name() +
267  ", updater: " + m_subupdaters[i]->name() + "\n";
268  }
269  ATH_MSG_VERBOSE(msgString);
270  ATH_CHECK(m_stepPropagator.retrieve());
271  ATH_MSG_DEBUG("initialize() successful");
272  return StatusCode::SUCCESS;
273 }

◆ initializeNavigation()

Trk::PropDirection Trk::Extrapolator::initializeNavigation ( const EventContext &  ctx,
Cache cache,
const Trk::IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters startPars,
const Trk::Surface destSurface,
Trk::PropDirection  dir,
ParticleHypothesis  particle,
Trk::CacheOwnedPtr< Trk::TrackParameters > &  referenceParameters,
const Trk::Layer *&  associatedLayer,
const Trk::TrackingVolume *&  associatedVolume,
const Trk::TrackingVolume *&  destinationVolume 
) const
private

Private method for Initial Extrapolation setup -> overwrites the given pointers for the start and destination parameters -> returns a direction for the Navigation :

Definition at line 3717 of file Extrapolator.cxx.

3728 {
3729  cache.setTrackingGeometry(*m_navigator, ctx);
3730  // output for initializeNavigation should be an eye-catcher
3731  if (!cache.m_destinationSurface) {
3732  ATH_MSG_DEBUG(" [I] initializeNaviagtion() -------------------------- ");
3733  cache.m_methodSequence = 0;
3734  } else {
3735  ATH_MSG_DEBUG(" [I] (re)initializeNaviagtion() ---------------------- ");
3736  }
3737 
3738  Trk::PropDirection navigationDirection = dir;
3739  // only for the initial and not for the redoNavigation - give back the navigation direction
3740  if (!cache.m_destinationSurface) {
3742  " [I] Starting with Start Layer/Volume search: ------------------------------");
3743  ATH_MSG_VERBOSE(" [I] Destination surface : " << sf);
3744  // reset the boundary information
3745  cache.m_parametersAtBoundary.resetBoundaryInformation();
3746  // and set the destination surface
3747  cache.m_destinationSurface = (&sf);
3748  // prepare for screen output
3749  const char* startSearchType = "association";
3750 
3751  // ---------------------------------- ASSOCIATED VOLUME ----------------------------------
3752  // 1 - TRY the association method
3753  const Trk::Surface* associatedSurface = &parm->associatedSurface();
3754  associatedLayer = (associatedSurface) ? associatedSurface->associatedLayer() : associatedLayer;
3755  associatedVolume =
3756  associatedLayer ? associatedLayer->enclosingTrackingVolume() : associatedVolume;
3757  // 2 - TRY the recall method -> only if association method didn't work
3758  // only if associated detector element exists to protect against dynamic surfaces
3759  if (!associatedVolume && associatedSurface && associatedSurface == cache.m_recallSurface &&
3760  associatedSurface->associatedDetectorElement()) {
3761  // statistics output
3763  associatedVolume = cache.m_recallTrackingVolume;
3764  associatedLayer = cache.m_recallLayer;
3765  // change the association type
3766  startSearchType = "recall";
3767  } else if (!associatedVolume) {
3768  // 3 - GLOBAL SEARCH METHOD
3770  // non-perigee surface
3771  cache.resetRecallInformation();
3772  associatedVolume = cache.volume(ctx,parm->position());
3773 
3774  associatedLayer =
3775  (associatedVolume) ? associatedVolume->associatedLayer(parm->position()) : nullptr;
3776 
3777  // change the association type
3778  startSearchType = "global search";
3779 
3780  // ---------------------------------- ASSOCIATED STATIC VOLUME
3781  // -------------------------------------- this is not necessary for ( association & recall )
3782  const Trk::TrackingVolume* lowestStaticVol =
3783  cache.m_trackingGeometry->lowestStaticTrackingVolume(parm->position());
3784 
3785  if (lowestStaticVol && lowestStaticVol != associatedVolume) {
3786  associatedVolume = lowestStaticVol;
3787  }
3788  // ---------------------------------------------------------------------------
3789  } else {
3791  }
3792 
3793  // verify if not exit point from associated volume
3794  if (associatedVolume && navigationDirection != Trk::anyDirection) {
3795  const Trk::TrackingVolume* nextAssVol = nullptr;
3796  if (m_navigator->atVolumeBoundary(parm, associatedVolume, dir, nextAssVol,
3797  m_tolerance) &&
3798  nextAssVol != associatedVolume) {
3799  if (nextAssVol) {
3800  associatedVolume = nextAssVol;
3801  } else {
3802  ATH_MSG_WARNING(" [X] Navigation break occurs in volume "
3803  << associatedVolume->volumeName() << " no action taken");
3804  }
3805  }
3806  }
3807  // ---------------- anyDirection given : navigation direction has to be estimated ---------
3808  if (navigationDirection == Trk::anyDirection) {
3810  " [I] 'AnyDirection' has been chosen: approaching direction must be determined.");
3811 
3812  // refParameters = prop.propagateParameters(parm,sf,dir,false,*associatedVolume);
3813  refParameters = cache.m_ownedPtrs.push(prop.propagateParameters(
3814  ctx, *parm, sf, dir, false, m_fieldProperties, particle, false,
3815  associatedVolume));
3816  // chose on projective method
3817  if (refParameters) {
3818  // check the direction on basis of a vector projection
3819  const Amg::Vector3D surfaceDir(refParameters->position() - parm->position());
3820  if (surfaceDir.dot(parm->momentum()) > 0.) {
3821  navigationDirection = Trk::alongMomentum;
3822  } else {
3823  navigationDirection = Trk::oppositeMomentum;
3824  }
3825 
3826  // really verbose statement, but needed for debugging
3827  ATH_MSG_VERBOSE(" [+] Approaching direction determined as: "
3828  << ((navigationDirection < 0) ? "oppositeMomentum." : "alongMomentum"));
3829  } else {
3831  " [+] Approaching direction could not be determined, they remain: anyDirection.");
3832  }
3833  }
3834  ATH_MSG_VERBOSE(" [I] Starting Information gathered through : " << startSearchType << ".");
3835  }
3836  // -----------------------------------------------------------------
3837 
3838  // ---------------------------------- DESTINATION VOLUME ----------------------------------
3839  // only do it if sf is not the reference Surface
3840  ATH_MSG_VERBOSE(" [I] Starting with destination Volume search: -----------------------------");
3841 
3842  if ((&sf) != (m_referenceSurface.get())) {
3843  // (1) - TRY the association method
3844  destVolume = (sf.associatedLayer()) ? sf.associatedLayer()->enclosingTrackingVolume() : nullptr;
3845  // for the summary output
3846  std::string destinationSearchType = "association";
3847  if (destVolume) {
3849  }
3850  // (2) - RECALL
3851  // only if associated detector element exists to protect against dynamic surfaces
3852  if (!destVolume && ((&sf) == cache.m_recallSurface) && sf.associatedDetectorElement()) {
3853  destVolume = cache.m_recallTrackingVolume;
3854  destinationSearchType = "recall";
3855  // the recal case ----------
3857  } else if (!destVolume) {
3858  // (3) GLOBAL SEARCH
3859  destinationSearchType = "global search";
3861  // if the propagation has not been done already (for direction estimation)
3862  // do the global search always with a reference propagation
3863  if (!refParameters && associatedVolume) {
3864  refParameters = cache.m_ownedPtrs.push(prop.propagateParameters(
3865  ctx, *parm, sf, dir, false, m_fieldProperties, particle, false,
3866  associatedVolume));
3867  }
3868  // get the destination Volume
3869  if (refParameters) {
3870  destVolume = cache.volume(ctx,refParameters->position());
3871  }
3872  // ------ the last chance : associate to the globalReferencePoint
3873  // std::cout << "destVolume: " << destVolume << " ref par: " << refParameters << "
3874  // associatedVolume: "
3875  // << associatedVolume << std::endl;
3876  if (!destVolume) {
3877  destVolume = cache.volume(ctx,sf.globalReferencePoint());
3878  }
3879  }
3880  ATH_MSG_VERBOSE(" [I] Destination Information gathered through : " << destinationSearchType
3881  << ".");
3882  }
3883  // screen output summary -----------------------------------------------------------
3884  if (msgLvl(MSG::VERBOSE)) {
3885  ATH_MSG_VERBOSE(" [+] Association Volume search ...... "
3886  << (associatedVolume ? "ok." : "failed."));
3887  ATH_MSG_VERBOSE(" [+] Association Layer search ...... "
3888  << (associatedLayer ? "ok." : "failed."));
3889  ATH_MSG_VERBOSE(" [+] Destinaiton Volume search ...... " << (destVolume ? "ok." : "failed."));
3890  // give a line of output when start volume is destination volume
3891  if (destVolume == associatedVolume) {
3892  ATH_MSG_VERBOSE(" [+] Start volume is destination volume.");
3893  }
3894  const std::string navDirString =
3895  ((navigationDirection < 0) ? "oppositeMomentum"
3896  : (navigationDirection > 0) ? "alongMomentum" : "undefined");
3897  ATH_MSG_VERBOSE(" [+] NavigationDirection is : " << navDirString);
3898  ATH_MSG_VERBOSE(" [I] initializeNaviagtion() end ---------------------- ");
3899  }
3900 
3901  // ----------------------------------------------------------------------------
3902  return navigationDirection;
3903 }

◆ inputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ insideVolumeStaticLayers()

Trk::CacheOwnedPtr< Trk::TrackParameters > Trk::Extrapolator::insideVolumeStaticLayers ( const EventContext &  ctx,
Cache cache,
bool  toBoundary,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
const Layer associatedLayer,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
MaterialUpdateMode  matupmode = addNoise 
) const
private

A) call from extrapolateInsideVolume or toBoundary, if it is to boundary, the return parameters are the parameters at the boundary.

Definition at line 2879 of file Extrapolator.cxx.

2890 {
2891  // method sequence output ---------------------------------
2892  ++cache.m_methodSequence;
2893  // the next volume as given from the navigator
2894  const Trk::TrackingVolume* nextVolume = nullptr;
2895  // initialization
2896  // nextParameters : parameters to be used for the extrapolation stream
2897  Trk::CacheOwnedPtr<Trk::TrackParameters> nextParameters(parm);
2898  // navParameters : parameters to be used for the navigation stream (if possible, start from
2899  // boundary parameters)
2900  Trk::CacheOwnedPtr<Trk::TrackParameters> navParameters(cache.m_parametersAtBoundary.navParameters
2901  ? cache.m_parametersAtBoundary.navParameters
2902  : nextParameters);
2903 
2904  // adjust the radial scaling for the layer search, this is for inwards vs. outwards moving
2905  const double rPos = parm->position().perp();
2906  double rComponent = parm->momentum().normalized().perp();
2907  // numerical stability
2908  rComponent = rComponent < 10e-5 ? 10e-5 : rComponent;
2909  // a special case for closed cylinders, check if rScalor is not below numerical tolerance
2910  double rScalor = (toBoundary && tvol.boundarySurfaces().size() == 3) ? 2. * rPos / rComponent
2911  : 0.5 * rPos / rComponent;
2912  rScalor = rScalor * rScalor < 10e-10 ? 0.1 : rScalor;
2913 
2914  // output and fast exit if the volume does not have confined layers
2915  if (toBoundary) {
2916  ATH_MSG_VERBOSE("S-[" << cache.m_methodSequence
2917  << "] insideVolumeStaticLayers(...) to volume boundary of '"
2918  << tvol.volumeName() << "'");
2919  } else { // to destination surface
2920  ATH_MSG_VERBOSE("S-[" << cache.m_methodSequence
2921  << "] insideVolumeStaticLayers(...) to destination surface in '"
2922  << tvol.volumeName() << "'");
2923  // no layer case - just do the extrapolation to the destination surface
2924  if (!tvol.confinedLayers()) {
2926  " [+] Volume does not contain layers, just propagate to destination surface.");
2927  // the final extrapolation to the destinationLayer
2928  nextParameters = cache.m_ownedPtrs.push(
2929  prop.propagate(ctx, *parm, *cache.m_destinationSurface, dir, bcheck,
2931  if (!nextParameters) {
2932  nextParameters = cache.m_ownedPtrs.push(prop.propagate(
2933  ctx, *parm, *cache.m_destinationSurface, Trk::anyDirection, bcheck,
2935  }
2936  return nextParameters;
2937  }
2938  }
2939 
2940  // print out the perpendicular direction best guess parameters
2942  " [+] Perpendicular direction of the track : " << radialDirection(*navParameters, dir));
2943  // check whether to do a postupdate with the assoicated Layer
2944  const Trk::Layer* associatedLayer = assocLayer;
2945  // chache the assocLayer given, because this may be needed for the destination layer
2946  const Trk::Layer* assocLayerReference = assocLayer;
2947 
2948  // the exit face of the last volume
2950 
2951  // ============================ RESOLVE DESTINATION / STARTPOINT ============================
2952  // (1) ASSOCIATION
2953  const Trk::Layer* destinationLayer = nullptr;
2954  // will be only executed if directive is not to go to the boundary
2955  if (!toBoundary) {
2956  destinationLayer = cache.m_destinationSurface->associatedLayer();
2957  if (!destinationLayer) { // (2) RECALL (very unlikely) // (3) GLOBAL SEARCH
2958  destinationLayer =
2959  (cache.m_recallSurface == cache.m_destinationSurface &&
2960  cache.m_destinationSurface->associatedDetectorElement())
2961  ? cache.m_recallLayer
2962  : tvol.associatedLayer(cache.m_destinationSurface->globalReferencePoint());
2963  }
2964  if (destinationLayer) {
2965  ATH_MSG_VERBOSE(" [+] Destination layer found - with "
2966  << layerRZoutput(*destinationLayer));
2967  }
2968  } // destination layer only gather if extrapolation does not go to boundary
2969 
2970  // The update on the starting layer if necessary ----------------------------------
2971  // - only done in static volume setup
2972  // - only done if required
2973  // - only done if the parameter is on the layer
2974  // - only if no volume skip has been done
2975  // - only if associated layer is not destination layer (and both exist)
2976  if (!m_skipInitialLayerUpdate && associatedLayer && associatedLayer != destinationLayer &&
2977  associatedLayer->layerMaterialProperties() && tvol.confinedLayers()) {
2979  " [+] In starting volume: check for eventual necessary postUpdate and overlapSearch.");
2980 
2981  // check if the parameter is on the layer
2982  const Trk::Layer* parsLayer = nextParameters->associatedSurface().associatedLayer();
2983  if ((parsLayer && parsLayer == associatedLayer) ||
2984  associatedLayer->surfaceRepresentation().isOnSurface(parm->position(),
2985  false,
2986  0.5 * associatedLayer->thickness(),
2987  0.5 * associatedLayer->thickness())) {
2988  // call the overlap search for the starting layer if asked for
2989  if (cache.m_parametersOnDetElements && associatedLayer->surfaceArray()) {
2990  ATH_MSG_VERBOSE(" [o] Calling overlapSearch() on start layer.");
2991  overlapSearch(ctx, cache, prop, parm, nextParameters, *associatedLayer,
2992  tvol, dir, bcheck, particle, true);
2993  }
2994 
2995  // the post-update is valid
2996  ATH_MSG_VERBOSE(" [+] Calling postUpdate on inital track parameters.");
2997  // do the post-update according to the associated Layer - parameters are
2998  // either (&parm) or newly created ones chose current updator
2999 
3000  const IMaterialEffectsUpdator* currentUpdator = subMaterialEffectsUpdator(tvol);
3001  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
3002  cache.subMaterialEffectsUpdatorCache(tvol);
3003 
3004  if (currentUpdator) {
3005  nextParameters = cache.m_ownedPtrs.push(currentUpdator->postUpdate(
3006  currentUpdatorCache, *nextParameters, *associatedLayer, dir,
3007  particle, matupmode));
3008  }
3009  // collect the material : either for extrapolateM or for the valdiation
3010  if (nextParameters && cache.m_matstates) {
3012  ctx, cache, prop, nextParameters, *associatedLayer, tvol, dir, particle);
3013  }
3014  if (nextParameters && nextParameters != parm) {
3015  } else if (!m_stopWithUpdateZero) { // re-assign the start parameters
3016  // @TODO condition correct ?
3017  nextParameters = parm;
3018  } else {
3019  ATH_MSG_VERBOSE(" [-] Initial postUpdate killed track.");
3020  cache.m_parametersAtBoundary.resetBoundaryInformation();
3021  cache.resetRecallInformation();
3022  return {};
3023  }
3024  }
3025  } else {
3026  assocLayer = nullptr; // reset the provided Layer in case no postUpdate happened: search a new one
3027  // for layer2layer start
3028  }
3029  // ============================ RESOLVE STARTPOINT =============================
3030  // only if you do not have an input associated Layer
3031  // - this means that a volume step has been done
3032 
3033  if (!associatedLayer) {
3034  ATH_MSG_VERBOSE(" [+] Volume switch has happened, searching for entry layers.");
3035  // reset the exitFace
3036  exitFace = cache.m_parametersAtBoundary.exitFace;
3037  // Step [1] Check for entry layers --------------------------
3038  associatedLayer = tvol.associatedLayer(navParameters->position());
3039  if (associatedLayer && associatedLayer->layerMaterialProperties()) {
3040  // --------------------------------------------------------
3041  ATH_MSG_VERBOSE(" [+] Entry layer to volume found with "
3042  << layerRZoutput(*associatedLayer));
3043  // try to go to the entry Layer first - do not delete the parameters (garbage collection done
3044  // by method)
3045  // - set entry flag
3046  auto [new_track_parm, killed] = extrapolateToIntermediateLayer(
3047  ctx, cache, prop, parm, *associatedLayer, tvol, dir, bcheck, particle, matupmode);
3048  nextParameters = new_track_parm;
3049  // -------------------------------------------------------
3050  if (m_stopWithUpdateZero && killed) {
3051  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
3052  // set the new boundary information
3053  cache.m_parametersAtBoundary.resetBoundaryInformation();
3054  cache.resetRecallInformation();
3055  return {};
3056  } if (cache.m_boundaryVolume && nextParameters &&
3057  !cache.m_boundaryVolume->inside(nextParameters->position())) {
3058  ATH_MSG_VERBOSE(" [+] Parameter outside the given boundary/world stopping loop.");
3059  // set the new boundary information
3060  cache.m_parametersAtBoundary.resetBoundaryInformation();
3061  cache.resetRecallInformation();
3062  return {};
3063  }
3064  // --------------------------------------------------------
3065  if (nextParameters) {
3066  ATH_MSG_VERBOSE(" [+] Entry layer successfully hit - at "
3067  << positionOutput(nextParameters->position()));
3068  }
3069  // --------------------------------------------------------
3070  // check whether it worked or not
3071  if (!nextParameters) {
3072  nextParameters = parm;
3073  }
3074  }
3075  }
3076 
3077  // Step [2] Associate the starting point to the layer ------------------------------------------
3078  // if an action has been taken, the nextParameters are not identical with the provided parameters
3079  // anymore
3080  if (nextParameters != parm) {
3081  navParameters = nextParameters;
3082  }
3083  // only associate the layer if the destination layer is not the assigned reference
3084  if (destinationLayer != assocLayerReference || toBoundary) {
3085  // get the starting layer for the layer - layer loop
3086  associatedLayer = assocLayer ? assocLayer : tvol.associatedLayer(navParameters->position());
3087  // ignore closest material layer if it is equal to the initially given layer (has been handled
3088  // by the post update )
3089  associatedLayer =
3090  (associatedLayer && associatedLayer == assocLayerReference)
3091  ? associatedLayer->nextLayer(navParameters->position(),
3092  dir * rScalor * navParameters->momentum().normalized())
3093  : associatedLayer;
3094  }
3095 
3096  if (associatedLayer) {
3097  ATH_MSG_VERBOSE(" [+] Associated layer at start with " << layerRZoutput(*associatedLayer));
3098  }
3099 
3100  // the layer to layer step and the final destination layer step can be done
3101  if (destinationLayer || toBoundary) {
3102  // the layer to layer step only makes sense here
3103  if (associatedLayer && associatedLayer != destinationLayer) {
3104  // screen output
3105  ATH_MSG_VERBOSE(" [+] First layer for layer2layer with "
3106  << layerRZoutput(*associatedLayer));
3107 
3108  // now do the loop from the associatedLayer to one before the destinationLayer
3110  ctx, cache, prop, nextParameters, tvol, associatedLayer,
3111  destinationLayer, navParameters, dir, bcheck, particle,
3112  matupmode);
3113  // kill the track when the update ----------------------
3114  if (m_stopWithUpdateZero && !updateNext) {
3115  ATH_MSG_VERBOSE(" [+] Update may have killed track - return.");
3116  // set the new boundary information
3117  cache.m_parametersAtBoundary.resetBoundaryInformation();
3118  cache.resetRecallInformation();
3119  return {};
3120  } if (cache.m_boundaryVolume && updateNext &&
3121  !cache.m_boundaryVolume->inside(updateNext->position())) {
3122  ATH_MSG_VERBOSE(" [+] Parameter outside the given boundary/world stopping loop.");
3123  // set the new boundary information
3124  cache.m_parametersAtBoundary.resetBoundaryInformation();
3125  cache.resetRecallInformation();
3126  return {};
3127  }
3128  // the fallback if only one step was done - solve cleaner
3129  if (updateNext) {
3130  nextParameters = updateNext;
3131  }
3132  }
3133  // Case Ia: To Destination after LayerToLayer sequence
3134  if (!toBoundary) {
3135  // the final extrapolation to the destinationLayer
3136  nextParameters = extrapolateToDestinationLayer(
3137  ctx, cache, prop, nextParameters, *cache.m_destinationSurface,
3138  *destinationLayer, tvol, assocLayerReference, dir, bcheck, particle,
3139  matupmode);
3140 
3141  // set the recallInformation <- everything went fine
3142  cache.setRecallInformation( *cache.m_destinationSurface, *destinationLayer, tvol);
3143  // done
3144  return nextParameters;
3145  }
3146  // -----------------------------------------------------------------------------------
3147  // Case Ib: To Destination directly since no destination layer has been found
3148  } else if (!toBoundary) {
3149  nextParameters = cache.m_ownedPtrs.push(
3150  prop.propagate(ctx, *nextParameters, *cache.m_destinationSurface, dir,
3151  bcheck, m_fieldProperties, particle));
3152  // job done: cleanup and go home
3153  // reset the recallInformation
3154  cache.resetRecallInformation();
3155  // return the directly extrapolated ones
3156  return nextParameters;
3157  }
3158 
3159  // the reset to the initial in case the extrapolationFromLayerToLayer
3160  if (!nextParameters) {
3161  nextParameters = parm;
3162  }
3163 
3164  // start the search with the simplest possible propagator
3165  unsigned int navprop = 0;
3166 
3167  Trk::CacheOwnedPtr<Trk::TrackParameters> bParameters= nullptr;
3168  if (m_numOfValidPropagators != INVALIDPROPAGATORS) {
3169  // loop over propagators to do the search
3170  while (navprop < m_numOfValidPropagators) {
3171  const IPropagator* navPropagator = &(*m_propagators[navprop]);
3172 
3173  // we veto the navigaiton parameters for calo-volumes with calo dynamic
3174  const bool vetoNavParameters = false; //
3175  // the next Parameters are usually better, because they're closer to the
3176  // boundary
3177  // --- in the initial volume (assocLayerReference!=0), the parm are good if
3178  // no action taken
3179  if (nextParameters != parm || assocLayerReference) {
3180  navParameters = nextParameters;
3181  } else {
3182  navParameters = (cache.m_parametersAtBoundary.navParameters && !vetoNavParameters)
3183  ? cache.m_parametersAtBoundary.navParameters
3184  : nextParameters;
3185  }
3186 
3187  ATH_MSG_VERBOSE(" [+] Starting next boundary search from "
3188  << positionOutput(navParameters->position()));
3189  ATH_MSG_VERBOSE(" [+] Starting next boundary search with "
3190  << momentumOutput(navParameters->momentum()));
3191 
3192  // get the new navigaiton cell from the Navigator
3193  Trk::NavigationCell nextNavCell =
3194  m_navigator->nextTrackingVolume(ctx, *navPropagator, *navParameters, dir, tvol);
3195  nextVolume = nextNavCell.nextVolume;
3196 
3197  navParameters =
3198  cache.m_ownedPtrs.push(std::move(nextNavCell.parametersOnBoundary));
3199  bParameters = navParameters;
3200  // set the new exit Cell
3201  exitFace = nextNavCell.exitFace;
3202  navprop++;
3203  if (nextVolume) {
3204  break;
3205  }
3206  }
3207  } else {
3208  Trk::NavigationCell nextNavCell =
3209  m_navigator->nextTrackingVolume(ctx, prop, *navParameters, dir, tvol);
3210 
3211  nextVolume = nextNavCell.nextVolume;
3212  navParameters = cache.m_ownedPtrs.push(std::move(nextNavCell.parametersOnBoundary));
3213  bParameters = navParameters;
3214  // set the new exit Cell
3215  exitFace = nextNavCell.exitFace;
3216  }
3217 
3218  if (!nextVolume && !cache.m_parametersOnDetElements) {
3219  ATH_MSG_DEBUG(" [-] Cannot find nextVolume of TrackingVolume: " << tvol.volumeName());
3220  if (navParameters) {
3221  ATH_MSG_VERBOSE(" Starting Parameters : " << navParameters);
3222  } else {
3223  ATH_MSG_VERBOSE(" Starting Parameters not defined.");
3224  }
3225  // reset the recall information as it is invalid
3226  cache.resetRecallInformation();
3227  }
3228 
3229  if (bParameters && bParameters->associatedSurface().materialLayer()) {
3230  ATH_MSG_VERBOSE(" [+] parameters on BoundarySurface with material.");
3232 
3233  const IMaterialEffectsUpdator* currentUpdator = m_subupdaters[tvol.geometrySignature()];
3234  IMaterialEffectsUpdator::ICache& currentUpdatorCache =
3235  cache.subMaterialEffectsUpdatorCache(tvol);
3236 
3237  if (currentUpdator) {
3238  bParameters = cache.m_ownedPtrs.push(currentUpdator->update(
3239  currentUpdatorCache, bParameters,
3240  *(bParameters->associatedSurface().materialLayer()), dir, particle,
3241  matupmode));
3242  }
3243  // collect the material
3244  if (bParameters && cache.m_matstates) {
3246  ctx, cache, prop, bParameters,
3247  *(bParameters->associatedSurface().materialLayer()), tvol, dir,
3248  particle);
3249  }
3250  navParameters = bParameters;
3251  }
3252  }
3253 
3254  // set the new boundary information
3255  cache.m_parametersAtBoundary.boundaryInformation(
3256  nextVolume, nextParameters, navParameters, exitFace);
3257 
3258  // return the navParameters
3259  return navParameters;
3260 }

◆ interfaceID()

static const InterfaceID& Trk::IExtrapolator::interfaceID ( )
inlinestaticinherited

AlgTool interface methods.

Definition at line 68 of file IExtrapolator.h.

68 { return IID_IExtrapolator; }

◆ isConfigured()

StatusCode AthCheckedComponent< AthAlgTool >::isConfigured ( )
privateinherited

Check if component is configured in JobOptionsSvc.

Checks if at least one property of the component is configured in the JobOptionsSvc. Can be used to detect if a component is missing its python configuration.

◆ msg() [1/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24  {
25  return this->msgStream();
26  }

◆ msg() [2/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( const MSG::Level  lvl) const
inlineinherited

Definition at line 27 of file AthCommonMsg.h.

27  {
28  return this->msgStream(lvl);
29  }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30  {
31  return this->msgLevel(lvl);
32  }

◆ outputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ overlapSearch()

void Trk::Extrapolator::overlapSearch ( const EventContext &  ctx,
Cache cache,
const IPropagator prop,
Trk::CacheOwnedPtr< Trk::TrackParameters parm,
Trk::CacheOwnedPtr< Trk::TrackParameters parsOnLayer,
const Layer lay,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
const BoundaryCheck bcheck = true,
ParticleHypothesis  particle = pion,
bool  startingLayer = false 
) const
private

Private to search for overlap surfaces.

Definition at line 3546 of file Extrapolator.cxx.

3557 {
3558  // indicate destination layer
3559  const bool isDestinationLayer = (&parsOnLayer->associatedSurface() == cache.m_destinationSurface);
3560  // start and end surface for on-layer navigation
3561  // -> take the start surface if ther parameter surface is owned by detector element
3562  const Trk::Surface* startSurface =
3563  ((parm->associatedSurface()).associatedDetectorElement() && startingLayer)
3564  ? &(parm->associatedSurface())
3565  : nullptr;
3566  const Trk::Surface* endSurface = isDestinationLayer ? cache.m_destinationSurface : nullptr;
3567  // - the best detSurface to start from is the one associated to the detector element
3568  const Trk::Surface* detSurface = (parsOnLayer->associatedSurface()).associatedDetectorElement()
3569  ? &parsOnLayer->associatedSurface()
3570  : nullptr;
3571 
3572  ATH_MSG_VERBOSE(" [o] OverlapSearch called " << (startSurface ? "with " : "w/o ") << "start, "
3573  << (endSurface ? "with " : "w/o ")
3574  << "end surface.");
3575 
3576  if (!detSurface) {
3577  // of parsOnLayer are different from parm, then local position is safe, because the
3578  // extrapolation
3579  // to the detector surface has been done !
3580  detSurface = isDestinationLayer ? lay.subSurface(parsOnLayer->localPosition())
3581  : lay.subSurface(parsOnLayer->position());
3582  if (detSurface) {
3583  ATH_MSG_VERBOSE(" [o] Detector surface found through subSurface() call");
3584  } else {
3585  ATH_MSG_VERBOSE(" [o] No Detector surface found on this layer.");
3586  }
3587  } else {
3588  ATH_MSG_VERBOSE(" [o] Detector surface found through parameter on layer association");
3589  }
3590 
3591  // indicate the start layer
3592  const bool isStartLayer = (detSurface && detSurface == startSurface);
3593 
3594  // the temporary vector (might have to be ordered)
3595  TrackParametersUVector detParametersOnLayer;
3596  bool reorderDetParametersOnLayer = false;
3597  // the first test for the detector surface to be hit (false test)
3598  // - only do this if the parameters aren't on the surface
3599  // (i.e. search on the start layer or end layer)
3600  Trk::CacheOwnedPtr<Trk::TrackParameters> detParameters = nullptr;
3601  if (isDestinationLayer) {
3602  detParameters = parsOnLayer;
3603  } else if (isStartLayer) {
3604  detParameters = parm;
3605  } else if (detSurface) {
3606  detParameters = cache.m_ownedPtrs.push(
3607  prop.propagate(ctx, *parm, *detSurface, dir, false, m_fieldProperties, particle));
3608  }
3609 
3610  // set the surface hit to true, it is anyway overruled
3611  bool surfaceHit = true;
3612  // circumvents pointer management
3613  // to allow using detParameters after detParameters.release()
3614  Trk::CacheOwnedPtr<Trk::TrackParameters> track_parm_for_overlap(detParameters);
3615  if (detParameters && !isStartLayer && !isDestinationLayer) {
3616  ATH_MSG_VERBOSE(" [o] First intersection with Detector surface: " << *detParameters);
3617  // for the later use in the overlapSearch
3618  surfaceHit = detParameters && detSurface ? detSurface->isOnSurface(detParameters->position())
3619  : 0; // ,bcheck) -creates problems on start layer;
3620  // check also for start/endSurface on this level
3621  surfaceHit = (surfaceHit && startSurface)
3622  ? ((detParameters->position() - parm->position())
3623  .dot(dir * parm->momentum().normalized()) > 0)
3624  : surfaceHit;
3625  surfaceHit =(surfaceHit && endSurface)
3626  ? ((detParameters->position() - parsOnLayer->position())
3627  .dot(dir * parsOnLayer->momentum().normalized()) < 0)
3628  : surfaceHit;
3629  // surface is hit within bounds (or at least with given boundary check
3630  // directive) -> it counts surface hit also survived start/endsurface search
3631  //
3632  // Convention for Fatras: always apply the full update on the last
3633  // parameters
3634  // of the gathered vector (no pre/post schema)
3635  // don't record a hit on the destination surface
3636  if (surfaceHit && detSurface != startSurface && detSurface != cache.m_destinationSurface) {
3637  ATH_MSG_VERBOSE(" [H] Hit with detector surface recorded ! ");
3638  // push into the temporary vector
3639  detParametersOnLayer.emplace_back(cache.m_ownedPtrs.move(detParameters));
3640  } else if (detParameters) {
3641  // no hit -> fill into the garbage bin
3643  " [-] Detector surface hit cancelled through bounds check or start/end surface check.");
3644  }
3645  }
3646 
3647  // search for the overlap -------------------------------------------------
3648  if (track_parm_for_overlap) {
3649  // retrive compatible subsurfaces
3650  std::vector<Trk::SurfaceIntersection> cSurfaces;
3651  size_t const ncSurfaces =
3652  lay.compatibleSurfaces(cSurfaces, *track_parm_for_overlap, Trk::anyDirection, bcheck, false);
3653 
3654  // import from StaticEngine.icc
3655  if (ncSurfaces) {
3656  ATH_MSG_VERBOSE("found " << ncSurfaces << " candidate sensitive surfaces to test.");
3657  // now loop over the surfaces:
3658  // the surfaces will be sorted @TODO integrate pathLength propagation into this
3659 
3660  auto overlapSurfaceHit = m_overlapSurfaceHit.buffer();
3661  for (auto& csf : cSurfaces) {
3662  // propagate to the compatible surface, return types are (pathLimit
3663  // failure is excluded by Trk::anyDirection for the moment):
3664  Trk::CacheOwnedPtr<Trk::TrackParameters> overlapParameters = cache.m_ownedPtrs.push(
3665  prop.propagate(ctx, *parm, *(csf.object), Trk::anyDirection, true,
3667 
3668  if (overlapParameters) {
3669  ATH_MSG_VERBOSE(" [+] Overlap surface was hit, checking start/end surface condition.");
3670  // check on start / end surface for on-layer navigaiton action
3671 
3672  surfaceHit = (startSurface) ? ((overlapParameters->position() - parm->position())
3673  .dot(dir * parm->momentum().normalized()) > 0)
3674  : true;
3675 
3676  surfaceHit = (surfaceHit && endSurface)
3677  ? ((overlapParameters->position() - parsOnLayer->position())
3678  .dot(dir * parsOnLayer->momentum().normalized()) < 0)
3679  : surfaceHit;
3680 
3681  if (surfaceHit) {
3682  ATH_MSG_VERBOSE(" [H] Hit with detector surface recorded !");
3683  // count the overlap Surfaces hit
3684  ++overlapSurfaceHit;
3685  // distinguish whether sorting is needed or not
3686  reorderDetParametersOnLayer = true;
3687  // push back into the temporary vector
3688  detParametersOnLayer.emplace_back(cache.m_ownedPtrs.move(overlapParameters));
3689  } else { // the parameters have been cancelled by start/end surface
3690  // no hit -> fill into the garbage bin
3692  " [-] Detector surface hit cancelled through start/end surface check.");
3693  }
3694  }
3695  } // loop over test surfaces done
3696  } // there are compatible surfaces
3697  } // ----------------------------------------------------------------------
3698 
3699  // reorder the track parameters if neccessary, the overlap descriptor did not provide the ordered
3700  // surfaces
3701  if (reorderDetParametersOnLayer) {
3702  // sort to reference of incoming parameters
3703  Trk::TrkParametersComparisonFunction const parameterSorter(parm->position());
3704  sort(detParametersOnLayer.begin(), detParametersOnLayer.end(), parameterSorter);
3705  }
3706  assert(cache.m_parametersOnDetElements);
3707  if (cache.m_parametersOnDetElements->empty()) {
3708  *(cache.m_parametersOnDetElements) = std::move(detParametersOnLayer);
3709  } else {
3710  std::move(detParametersOnLayer.begin(), detParametersOnLayer.end(),
3711  std::back_inserter(*(cache.m_parametersOnDetElements)));
3712  }
3713 }

◆ positionOutput()

std::string Trk::Extrapolator::positionOutput ( const Amg::Vector3D pos) const
private

For the output - global position.

Definition at line 3952 of file Extrapolator.cxx.

3953 {
3954  std::stringstream outStream;
3955 
3956  if (m_printRzOutput) {
3957  outStream << "[r,phi,z] = [ " << pos.perp() << ", " << pos.phi() << ", " << pos.z() << " ]";
3958  } else {
3959  outStream << "[xyz] = [ " << pos.x() << ", " << pos.y() << ", " << pos.z() << " ]";
3960  }
3961  return outStream.str();
3962 }

◆ radialDirectionCheck()

bool Trk::Extrapolator::radialDirectionCheck ( const EventContext &  ctx,
const IPropagator prop,
const TrackParameters startParm,
const TrackParameters parsOnLayer,
const TrackingVolume tvol,
PropDirection  dir = anyDirection,
ParticleHypothesis  particle = pion 
) const
private

Check for punchThrough in case of radial (perpendicular) direction change, returns true if the radial direction change is actually ok (i.e.

punch-through allowed)

Definition at line 3906 of file Extrapolator.cxx.

3913 {
3914 
3915  const Amg::Vector3D& startPosition = startParm.position();
3916  const Amg::Vector3D& onLayerPosition = parsOnLayer.position();
3917 
3918  // the 3D distance to the layer intersection
3919  const double distToLayer = (startPosition - onLayerPosition).mag();
3920  // get the innermost contained surface for crosscheck
3921  const auto& boundarySurfaces = tvol.boundarySurfaces();
3922 
3923  // only for tubes the crossing makes sense to check for validity
3924  if (boundarySurfaces.size() == 4) {
3925  // it can be either the next layer from the initial point, or the inner tube boundary surface
3926  const Trk::Surface& insideSurface =
3927  (boundarySurfaces[Trk::tubeInnerCover])->surfaceRepresentation();
3928  // const Trk::TrackParameters* parsOnInsideSurface =
3929  std::unique_ptr<const Trk::TrackParameters> const parsOnInsideSurface(prop.propagateParameters(
3930  ctx, startParm, insideSurface, dir, true, m_fieldProperties, particle));
3931 
3932  const double distToInsideSurface =
3933  parsOnInsideSurface ? (startPosition - (parsOnInsideSurface->position())).mag() : 10e10;
3934 
3935  ATH_MSG_VERBOSE(" [+] Radial direction check start - at " << positionOutput(startPosition));
3936  ATH_MSG_VERBOSE(" [+] Radial direction check layer - at " << positionOutput(onLayerPosition));
3937  if (parsOnInsideSurface) {
3938  ATH_MSG_VERBOSE(" [+] Radial direction check inner - at "
3939  << positionOutput(parsOnInsideSurface->position()));
3940  }
3941 
3942  // memory cleanup (no garbage bin, this is faster)
3943  ATH_MSG_VERBOSE(" [+] Check radial direction: distance layer / boundary = "
3944  << distToLayer << " / " << distToInsideSurface);
3945  // the intersection with the original layer is valid if it is before the inside surface
3946  return distToLayer < distToInsideSurface;
3947  }
3948  return true;
3949 }

◆ renounce()

std::enable_if_t<std::is_void_v<std::result_of_t<decltype(&T::renounce)(T)> > && !std::is_base_of_v<SG::VarHandleKeyArray, T> && std::is_base_of_v<Gaudi::DataHandle, T>, void> AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T &  h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381  {
382  h.renounce();
383  PBASE::renounce (h);
384  }

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364  {
365  handlesArray.renounce();
366  }

◆ subMaterialEffectsUpdator()

const IMaterialEffectsUpdator* Trk::Extrapolator::subMaterialEffectsUpdator ( const TrackingVolume tvol) const
private

Access the subPropagator to the given volume.

◆ subPropagator()

const IPropagator* Trk::Extrapolator::subPropagator ( const TrackingVolume tvol) const
private

Access the subPropagator to the given volume.

◆ sysInitialize()

virtual StatusCode AthCheckedComponent< AthAlgTool >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for the component.

We overwrite this to call the additional checkers below.

Reimplemented from AthCommonDataStore< AthCommonMsg< AlgTool > >.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ trackingGeometry()

virtual const TrackingGeometry* Trk::Extrapolator::trackingGeometry ( ) const
finaloverridevirtual

Return the TrackingGeometry used by the Extrapolator (forward information from Navigator)

Implements Trk::IExtrapolator.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase &  )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308  {
309  // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310  // << " size: " << m_vhka.size() << endmsg;
311  for (auto &a : m_vhka) {
312  std::vector<SG::VarHandleKey*> keys = a->keys();
313  for (auto k : keys) {
314  k->setOwner(this);
315  }
316  }
317  }

Member Data Documentation

◆ ATLAS_THREAD_SAFE

Dbg::PropStat m_propStat Trk::Extrapolator::ATLAS_THREAD_SAFE
mutableprivate

Definition at line 714 of file Extrapolator.h.

◆ m_destinationThroughAssociation

Gaudi::Accumulators::Counter Trk::Extrapolator::m_destinationThroughAssociation {}
mutableprivate

navigation intialization

Definition at line 701 of file Extrapolator.h.

◆ m_destinationThroughGlobalSearch

Gaudi::Accumulators::Counter Trk::Extrapolator::m_destinationThroughGlobalSearch {}
mutableprivate

navigation intialization

Definition at line 703 of file Extrapolator.h.

◆ m_destinationThroughRecall

Gaudi::Accumulators::Counter Trk::Extrapolator::m_destinationThroughRecall {}
mutableprivate

navigation intialization

Definition at line 702 of file Extrapolator.h.

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_dumpCache

BooleanProperty Trk::Extrapolator::m_dumpCache {this, "DumpCache", false}
private

Definition at line 675 of file Extrapolator.h.

◆ m_elossupdater

ToolHandle<IEnergyLossUpdator> Trk::Extrapolator::m_elossupdater
private
Initial value:
{ this,
"EnergyLossUpdater",
"Trk::EnergyLossUpdator/AtlasEnergyLossUpdator" }

Definition at line 621 of file Extrapolator.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_extrapolateBlindlyCalls

Gaudi::Accumulators::Counter Trk::Extrapolator::m_extrapolateBlindlyCalls {}
mutableprivate

number of calls: extrapolateBlindly() method

Definition at line 694 of file Extrapolator.h.

◆ m_extrapolateCalls

Gaudi::Accumulators::Counter Trk::Extrapolator::m_extrapolateCalls {}
mutableprivate

number of calls: extrapolate() method

Definition at line 693 of file Extrapolator.h.

◆ m_extrapolateDirectlyCalls

Gaudi::Accumulators::Counter Trk::Extrapolator::m_extrapolateDirectlyCalls {}
mutableprivate

number of calls: extrapolateDirectly() method

Definition at line 695 of file Extrapolator.h.

◆ m_extrapolateStepwiseCalls

Gaudi::Accumulators::Counter Trk::Extrapolator::m_extrapolateStepwiseCalls {}
mutableprivate

number of calls: extrapolateStepwise() method

Definition at line 696 of file Extrapolator.h.

◆ m_fastField

BooleanProperty Trk::Extrapolator::m_fastField {this, "MagneticFieldProperties", false}
private

Definition at line 677 of file Extrapolator.h.

◆ m_fieldProperties

Trk::MagneticFieldProperties Trk::Extrapolator::m_fieldProperties
private

Definition at line 678 of file Extrapolator.h.

◆ m_includeMaterialEffects

BooleanProperty Trk::Extrapolator::m_includeMaterialEffects
private
Initial value:
{this, "ApplyMaterialEffects", true,
"boolean to switch on/off material effects"}

Definition at line 641 of file Extrapolator.h.

◆ m_initialLayerAttempts

UnsignedIntegerProperty Trk::Extrapolator::m_initialLayerAttempts
private
Initial value:
{this, "InitialLayerAttempts", 3,
"allowed layer intersection attempts at the start of a volume"}

Definition at line 655 of file Extrapolator.h.

◆ m_layerSwitched

Gaudi::Accumulators::Counter Trk::Extrapolator::m_layerSwitched {}
mutableprivate

number of layers that have been switched

Definition at line 704 of file Extrapolator.h.

◆ m_maxMethodSequence

UnsignedIntegerProperty Trk::Extrapolator::m_maxMethodSequence {this, "MaximalMethodSequence", 2000}
private

Definition at line 661 of file Extrapolator.h.

◆ m_maxNavigSurf

const unsigned int Trk::Extrapolator::m_maxNavigSurf = 1000
staticprivate

Definition at line 673 of file Extrapolator.h.

◆ m_maxNavigVol

const unsigned int Trk::Extrapolator::m_maxNavigVol = 50
staticprivate

Definition at line 674 of file Extrapolator.h.

◆ m_maxRecursion

UnsignedIntegerProperty Trk::Extrapolator::m_maxRecursion {this, "MaxRecursion", 1000}
private

Definition at line 671 of file Extrapolator.h.

◆ m_msupdater

ToolHandle<IMultipleScatteringUpdator> Trk::Extrapolator::m_msupdater
private
Initial value:
{
this,
"MultipleScatteringUpdater",
"Trk::MultipleScatteringUpdator/AtlasMultipleScatteringUpdator"
}

Array of EnergyLoss updaters.

Definition at line 615 of file Extrapolator.h.

◆ m_navigationBreakDetails

BooleanProperty Trk::Extrapolator::m_navigationBreakDetails
private
Initial value:
{this, "DetailedNavigationOutput", false,
"steer the output for the navigation break details"}

Definition at line 688 of file Extrapolator.h.

◆ m_navigationBreakDistIncrease

Gaudi::Accumulators::Counter Trk::Extrapolator::m_navigationBreakDistIncrease {}
mutableprivate

number of navigation breaks due to distance increase

Definition at line 710 of file Extrapolator.h.

◆ m_navigationBreakLoop

Gaudi::Accumulators::Counter Trk::Extrapolator::m_navigationBreakLoop {}
mutableprivate

number of navigation breaks due to loop

Definition at line 707 of file Extrapolator.h.

◆ m_navigationBreakNoVolume

Gaudi::Accumulators::Counter Trk::Extrapolator::m_navigationBreakNoVolume {}
mutableprivate

number of navigation breaks due no Volume found

Definition at line 709 of file Extrapolator.h.

◆ m_navigationBreakOscillation

Gaudi::Accumulators::Counter Trk::Extrapolator::m_navigationBreakOscillation {}
mutableprivate

number of navigation breaks due to oscillation

Definition at line 708 of file Extrapolator.h.

◆ m_navigationBreakVolumeSignature

Gaudi::Accumulators::Counter Trk::Extrapolator::m_navigationBreakVolumeSignature {}
mutableprivate

number of navigation breaks due to distance increase

Definition at line 711 of file Extrapolator.h.

◆ m_navigationStatistics

BooleanProperty Trk::Extrapolator::m_navigationStatistics
private
Initial value:
{this, "NavigationStatisticsOutput", false,
"steer the output for the navigation statistics"}

Definition at line 685 of file Extrapolator.h.

◆ m_navigator

ToolHandle<INavigator> Trk::Extrapolator::m_navigator
private
Initial value:
{ this,
"Navigator",
"Trk::Navigator/AtlasNavigator" }

Array of Material updatersc.

Definition at line 605 of file Extrapolator.h.

◆ m_numOfValidPropagators

unsigned int Trk::Extrapolator::m_numOfValidPropagators
private

Definition at line 654 of file Extrapolator.h.

◆ m_overlapSurfaceHit

Gaudi::Accumulators::Counter Trk::Extrapolator::m_overlapSurfaceHit {}
mutableprivate

number of OverlapSurfaces found

Definition at line 712 of file Extrapolator.h.

◆ m_printRzOutput

BooleanProperty Trk::Extrapolator::m_printRzOutput {this, "positionOutput", true}
private

Definition at line 682 of file Extrapolator.h.

◆ m_propagators

ToolHandleArray<IPropagator> Trk::Extrapolator::m_propagators { this, "Propagators", {} }
private

Private method for conversion of the synchronized geometry signature to the natural subdetector ordering.

< Array of Propagators Steo Propagator

Definition at line 597 of file Extrapolator.h.

◆ m_propNames

StringArrayProperty Trk::Extrapolator::m_propNames
private
Initial value:
{this, "SubPropagators", {},
"configuration of subPropagators"}

Definition at line 634 of file Extrapolator.h.

◆ m_referenceSurface

std::unique_ptr<Surface> Trk::Extrapolator::m_referenceSurface = nullptr
private

Definition at line 680 of file Extrapolator.h.

◆ m_resolveActive

BooleanProperty Trk::Extrapolator::m_resolveActive {this, "ResolveMuonStation", false}
private

Definition at line 650 of file Extrapolator.h.

◆ m_resolveMultilayers

BooleanProperty Trk::Extrapolator::m_resolveMultilayers {this, "ResolveMultilayers", true}
private

number of sub valid propagators in the m_subPropagators array

Definition at line 651 of file Extrapolator.h.

◆ m_skipInitialLayerUpdate

BooleanProperty Trk::Extrapolator::m_skipInitialLayerUpdate
private
Initial value:
{this, "SkipInitialPostUpdate", false,
"skip the initial post-Update at the layer [Fatras conversion mode]"}

Definition at line 648 of file Extrapolator.h.

◆ m_startThroughAssociation

Gaudi::Accumulators::Counter Trk::Extrapolator::m_startThroughAssociation {}
mutableprivate

navigation intialization

Definition at line 698 of file Extrapolator.h.

◆ m_startThroughGlobalSearch

Gaudi::Accumulators::Counter Trk::Extrapolator::m_startThroughGlobalSearch {}
mutableprivate

navigation intialization

Definition at line 700 of file Extrapolator.h.

◆ m_startThroughRecall

Gaudi::Accumulators::Counter Trk::Extrapolator::m_startThroughRecall {}
mutableprivate

navigation intialization

Definition at line 699 of file Extrapolator.h.

◆ m_stepPropagator

ToolHandle<IPropagator> Trk::Extrapolator::m_stepPropagator
private
Initial value:
{
this,
"STEP_Propagator",
"Trk::STEP_Propagator/AtlasSTEP_Propagator"
}

Navigator for TrackingGeometry and magnetic fiels acces.

Definition at line 599 of file Extrapolator.h.

◆ m_stopWithNavigationBreak

BooleanProperty Trk::Extrapolator::m_stopWithNavigationBreak
private
Initial value:
{this, "StopWithNavigationBreak", false,
"return 0 if navigation breaks - for validation reasons"}

Definition at line 643 of file Extrapolator.h.

◆ m_stopWithUpdateZero

BooleanProperty Trk::Extrapolator::m_stopWithUpdateZero
private
Initial value:
{this, "StopWithUpdateKill", false,
"return 0 if update kills the trajectory"}

Definition at line 646 of file Extrapolator.h.

◆ m_subPropagators

std::vector<const IPropagator*> Trk::Extrapolator::m_subPropagators
private

< Propagators to chose from (steered by signature)

updaters to chose from (steered by signature)

Definition at line 628 of file Extrapolator.h.

◆ m_subupdaters

std::vector<const IMaterialEffectsUpdator*> Trk::Extrapolator::m_subupdaters
private

Definition at line 630 of file Extrapolator.h.

◆ m_successiveLayerAttempts

UnsignedIntegerProperty Trk::Extrapolator::m_successiveLayerAttempts
private
Initial value:
{this, "SuccessiveLayerAttempts", 1,
"layer intersection attemps after one layer has been hit sucessfully"}

Definition at line 658 of file Extrapolator.h.

◆ m_tolerance

DoubleProperty Trk::Extrapolator::m_tolerance
private
Initial value:
{this, "Tolerance", 0.002,
"surface & volume tolerance"}

Definition at line 663 of file Extrapolator.h.

◆ m_updaters

ToolHandleArray<IMaterialEffectsUpdator> Trk::Extrapolator::m_updaters
private
Initial value:
{
this,
"MaterialEffectsUpdators",
{}
}

Array of MultipleScattering updaters.

Definition at line 609 of file Extrapolator.h.

◆ m_updatNames

StringArrayProperty Trk::Extrapolator::m_updatNames
private
Initial value:
{this, "SubMEUpdators", {},
"configuration of subupdaters"}

Definition at line 636 of file Extrapolator.h.

◆ m_useDenseVolumeDescription

BooleanProperty Trk::Extrapolator::m_useDenseVolumeDescription
private
Initial value:
{this, "UseDenseVolumeDescription", true,
"use dense volume description when available in ID/Calo"}

Definition at line 668 of file Extrapolator.h.

◆ m_useMuonMatApprox

BooleanProperty Trk::Extrapolator::m_useMuonMatApprox
private
Initial value:
{this, "UseMuonMatApproximation", false,
"use approximative MS inert material"}

Definition at line 666 of file Extrapolator.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files:
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trk::Layer::isOnLayer
virtual bool isOnLayer(const Amg::Vector3D &gp, const BoundaryCheck &bcheck=BoundaryCheck(true)) const
isOnLayer() method, using isOnSurface() with Layer specific tolerance
Definition: Layer.cxx:135
Trk::Extrapolator::overlapSearch
void overlapSearch(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, Trk::CacheOwnedPtr< Trk::TrackParameters > parsOnLayer, const Layer &lay, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, bool startingLayer=false) const
Private to search for overlap surfaces.
Definition: Extrapolator.cxx:3546
Trk::Layer::postUpdateMaterialFactor
virtual double postUpdateMaterialFactor(const TrackParameters &, PropDirection) const
getting the MaterialProperties back - for pre-update
Definition: Layer.h:150
Trk::Surface::pathCorrection
virtual double pathCorrection(const Amg::Vector3D &pos, const Amg::Vector3D &mom) const
the pathCorrection for derived classes with thickness - it reflects if the direction projection is po...
Trk::Extrapolator::m_propNames
StringArrayProperty m_propNames
Definition: Extrapolator.h:634
TrkExTools::getToolSuffix
std::string getToolSuffix(const std::string &fullToolName)
Return the name suffix, e.g. return 'myNiceTool' from 'ToolSvc.myNiceTool'.
Definition: TrkExToolsStringUtility.cxx:14
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::Layer::fullUpdateMaterialProperties
const MaterialProperties * fullUpdateMaterialProperties(const TrackParameters &par) const
getting the MaterialProperties back - for full update
Definition: Layer.cxx:169
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:79
Trk::Extrapolator::m_resolveMultilayers
BooleanProperty m_resolveMultilayers
number of sub valid propagators in the m_subPropagators array
Definition: Extrapolator.h:651
Trk::TrackingVolume::nextLayer
const Layer * nextLayer(const Amg::Vector3D &gp, const Amg::Vector3D &mom, bool asres=true, bool skipNavLayer=false) const
Return the next Layer if existing, NULL if no next layer corresponds.
Definition: TrackingVolume.cxx:418
Trk::Surface::associatedDetectorElement
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
TrkExTools::numberOfUniqueEntries
unsigned int numberOfUniqueEntries(const std::vector< std::string > &nameVector)
Give the number of unique entries in a vector.
Definition: TrkExToolsStringUtility.cxx:45
Trk::NavigationCell::nextVolume
const TrackingVolume * nextVolume
Definition: INavigator.h:40
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
Trk::NavigationCell::parametersOnBoundary
std::unique_ptr< TrackParameters > parametersOnBoundary
Definition: INavigator.h:42
Trk::Extrapolator::m_navigationBreakDetails
BooleanProperty m_navigationBreakDetails
Definition: Extrapolator.h:689
Trk::DistanceSolution::toPointOfClosestApproach
double toPointOfClosestApproach() const
Distance to point of closest approach along direction.
Trk::MagneticFieldProperties
Definition: MagneticFieldProperties.h:31
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::Extrapolator::m_elossupdater
ToolHandle< IEnergyLossUpdator > m_elossupdater
Definition: Extrapolator.h:621
Trk::Extrapolator::m_extrapolateDirectlyCalls
Gaudi::Accumulators::Counter m_extrapolateDirectlyCalls
number of calls: extrapolateDirectly() method
Definition: Extrapolator.h:695
Trk::Extrapolator::m_extrapolateBlindlyCalls
Gaudi::Accumulators::Counter m_extrapolateBlindlyCalls
number of calls: extrapolateBlindly() method
Definition: Extrapolator.h:694
Trk::DistanceSolution
Definition: DistanceSolution.h:25
Trk::Volume::inside
bool inside(const Amg::Vector3D &gp, double tol=0.) const
Inside() method for checks.
Definition: Volume.cxx:72
Trk::Extrapolator::m_navigationBreakNoVolume
Gaudi::Accumulators::Counter m_navigationBreakNoVolume
number of navigation breaks due no Volume found
Definition: Extrapolator.h:709
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Trk::oppositeMomentum
@ oppositeMomentum
Definition: PropDirection.h:21
Trk::TrackingVolume::geometrySignature
GeometrySignature geometrySignature() const
return the Signature
Trk::DistanceSolution::numberOfSolutions
int numberOfSolutions() const
Number of intersection solutions.
index
Definition: index.py:1
Trk::Surface::straightLineDistanceEstimate
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const =0
fast straight line distance evaluation to Surface
Trk::ParametersBase::uniqueClone
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
Definition: ParametersBase.h:97
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
Trk::Extrapolator::m_includeMaterialEffects
BooleanProperty m_includeMaterialEffects
Definition: Extrapolator.h:641
Trk::MaterialProperties::thicknessInX0
float thicknessInX0() const
Return the radiationlength fraction.
Trk::Extrapolator::addMaterialEffectsOnTrack
void addMaterialEffectsOnTrack(const EventContext &ctx, Cache &cache, const Trk::IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Layer &lay, const Trk::TrackingVolume &vol, Trk::PropDirection propDir, Trk::ParticleHypothesis) const
helper method for MaterialEffectsOnTrack to be added
Definition: Extrapolator.cxx:3965
Trk::BinnedMaterial
Definition: BinnedMaterial.h:31
Trk::TrackingVolume::associatedSubVolume
const TrackingVolume * associatedSubVolume(const Amg::Vector3D &gp) const
Return the associated sub Volume, returns THIS if no subVolume exists.
Definition: TrackingVolume.cxx:530
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:113
Trk::Extrapolator::m_numOfValidPropagators
unsigned int m_numOfValidPropagators
Definition: Extrapolator.h:654
Trk::Extrapolator::m_navigationBreakLoop
Gaudi::Accumulators::Counter m_navigationBreakLoop
number of navigation breaks due to loop
Definition: Extrapolator.h:707
Trk::Material::zOverAtimesRho
float zOverAtimesRho() const
access to members
Definition: Material.h:226
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
StoreGateSvc_t m_evtStore
Pointer to StoreGate (event store by default)
Definition: AthCommonDataStore.h:390
PlotCalibFromCool.ib
ib
Definition: PlotCalibFromCool.py:419
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
std::vector< SG::VarHandleKeyArray * > m_vhka
Definition: AthCommonDataStore.h:398
Trk::Extrapolator::insideVolumeStaticLayers
Trk::CacheOwnedPtr< Trk::TrackParameters > insideVolumeStaticLayers(const EventContext &ctx, Cache &cache, bool toBoundary, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
A) call from extrapolateInsideVolume or toBoundary, if it is to boundary, the return parameters are t...
Definition: Extrapolator.cxx:2879
ParticleTest.tp
tp
Definition: ParticleTest.py:25
Trk::TrackingVolume::confinedDetachedVolumes
ArraySpan< DetachedTrackingVolume const *const > confinedDetachedVolumes() const
Return detached subVolumes - not the ownership.
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Trk::ScatteringAngles
represents a deflection of the track caused through multiple scattering in material.
Definition: ScatteringAngles.h:26
Trk::Extrapolator::extrapolateDirectlyImpl
std::unique_ptr< TrackParameters > extrapolateDirectlyImpl(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const
Actual heavy lifting implementation for extrapolateDirectly.
Definition: Extrapolator.cxx:1984
Trk::Extrapolator::m_fastField
BooleanProperty m_fastField
Definition: Extrapolator.h:677
Trk::Extrapolator::m_referenceSurface
std::unique_ptr< Surface > m_referenceSurface
Definition: Extrapolator.h:680
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
Trk::MaterialProperties::x0
float x0() const
Return the radiation length.
Trk::Extrapolator::extrapolateBlindlyImpl
Trk::TrackParametersUVector extrapolateBlindlyImpl(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, const Volume *boundaryVol=nullptr) const
Actual heavy lifting implementation for extrapolateBlindly.
Definition: Extrapolator.cxx:2621
Trk::EnergyLoss::sigmaRad
double sigmaRad() const
Trk::Extrapolator::m_destinationThroughRecall
Gaudi::Accumulators::Counter m_destinationThroughRecall
navigation intialization
Definition: Extrapolator.h:702
Trk::Extrapolator::extrapolateImpl
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateImpl(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Actual heavy lifting implementation for extrapolate.
Definition: Extrapolator.cxx:2090
Trk::Extrapolator::m_overlapSurfaceHit
Gaudi::Accumulators::Counter m_overlapSurfaceHit
number of OverlapSurfaces found
Definition: Extrapolator.h:712
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Trk::DistanceSolution::first
double first() const
Distance to first intersection solution along direction.
PlotCalibFromCool.multi
multi
Definition: PlotCalibFromCool.py:99
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::Extrapolator::m_maxNavigVol
static const unsigned int m_maxNavigVol
Definition: Extrapolator.h:674
Trk::EnergyLoss::meanIoni
double meanIoni() const
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Trk::Extrapolator::m_extrapolateStepwiseCalls
Gaudi::Accumulators::Counter m_extrapolateStepwiseCalls
number of calls: extrapolateStepwise() method
Definition: Extrapolator.h:696
Trk::Extrapolator::m_extrapolateCalls
Gaudi::Accumulators::Counter m_extrapolateCalls
number of calls: extrapolate() method
Definition: Extrapolator.h:693
Trk::Calo
@ Calo
Definition: GeometrySignature.h:28
Trk::Extrapolator::m_maxMethodSequence
UnsignedIntegerProperty m_maxMethodSequence
Definition: Extrapolator.h:662
Trk::Cache::kContinue
@ kContinue
Definition: LocalExtrapolatorCache.h:103
Trk::AlignableTrackingVolume::binnedMaterial
const BinnedMaterial * binnedMaterial() const
access to binned material
Definition: AlignableTrackingVolume.h:68
TrkExTools::possibleToolNameError
std::string possibleToolNameError(const std::vector< std::string > &toolNameVector)
Give an error message if tool names are invalid; empty string if good.
Definition: TrkExToolsStringUtility.cxx:34
Trk::Extrapolator::m_tolerance
DoubleProperty m_tolerance
Definition: Extrapolator.h:663
Trk::Extrapolator::m_subupdaters
std::vector< const IMaterialEffectsUpdator * > m_subupdaters
Definition: Extrapolator.h:630
Trk::NumberOfSignatures
@ NumberOfSignatures
Definition: GeometrySignature.h:32
Trk::BoundarySurfaceFace
BoundarySurfaceFace
Definition: BoundarySurfaceFace.h:31
std::sort
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:554
Trk::Extrapolator::m_startThroughGlobalSearch
Gaudi::Accumulators::Counter m_startThroughGlobalSearch
navigation intialization
Definition: Extrapolator.h:700
Trk::Layer::layerType
int layerType() const
get the Layer coding
Trk::Cache::kRecursionCountExceeded
@ kRecursionCountExceeded
Definition: LocalExtrapolatorCache.h:103
Trk::Extrapolator::extrapolateToVolumeImpl
std::unique_ptr< TrackParameters > extrapolateToVolumeImpl(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Trk::TrackingVolume &vol, PropDirection dir=anyDirection, ParticleHypothesis particle=pion) const
Actual heavy lifting implementation for extrapolateToVolume.
Definition: Extrapolator.cxx:1998
Trk::Extrapolator::m_updatNames
StringArrayProperty m_updatNames
Definition: Extrapolator.h:636
Trk::Extrapolator::m_initialLayerAttempts
UnsignedIntegerProperty m_initialLayerAttempts
Definition: Extrapolator.h:656
Trk::Extrapolator::m_fieldProperties
Trk::MagneticFieldProperties m_fieldProperties
Definition: Extrapolator.h:678
SG::VarHandleKeyArray::setOwner
virtual void setOwner(IDataHandleHolder *o)=0
Trk::Surface::baseSurface
virtual const Trk::Surface * baseSurface() const
return the base surface (simplified for persistification)
IDTPMcnv.htype
htype
Definition: IDTPMcnv.py:29
Trk::Extrapolator::m_useDenseVolumeDescription
BooleanProperty m_useDenseVolumeDescription
Definition: Extrapolator.h:669
Trk::MS
@ MS
Definition: GeometrySignature.h:29
Trk::TrackingVolume::confinedLayers
const LayerArray * confinedLayers() const
Return the subLayer array.
Trk::Layer::surfaceArray
const SurfaceArray * surfaceArray() const
Return the entire SurfaceArray, returns nullptr if no SurfaceArray.
Trk::FastField
@ FastField
call the fast field access method of the FieldSvc
Definition: MagneticFieldMode.h:20
AthCommonDataStore::declareGaudiProperty
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>
Definition: AthCommonDataStore.h:156
Trk::PropDirection
PropDirection
Definition: PropDirection.h:19
Trk::Surface::isOnSurface
virtual bool isOnSurface(const Amg::Vector3D &glopo, const BoundaryCheck &bchk=true, double tol1=0., double tol2=0.) const
This method returns true if the GlobalPosition is on the Surface for both, within or without check of...
Definition: Surface.cxx:123
Trk::Material::x0
float x0() const
Definition: Material.h:227
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
AthCommonDataStore
Definition: AthCommonDataStore.h:52
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::Layer::surfaceRepresentation
virtual const Surface & surfaceRepresentation() const =0
Transforms the layer into a Surface representation for extrapolation.
Trk::Extrapolator::m_navigationBreakDistIncrease
Gaudi::Accumulators::Counter m_navigationBreakDistIncrease
number of navigation breaks due to distance increase
Definition: Extrapolator.h:710
Trk::Extrapolator::extrapolateStepwiseImpl
TrackParametersUVector extrapolateStepwiseImpl(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const
Definition: Extrapolator.cxx:615
Trk::active
@ active
Definition: Layer.h:47
AthCheckedComponent< AthAlgTool >
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::Extrapolator::m_stopWithNavigationBreak
BooleanProperty m_stopWithNavigationBreak
Definition: Extrapolator.h:644
Trk::Extrapolator::extrapolateToIntermediateLayer
std::pair< Trk::CacheOwnedPtr< Trk::TrackParameters >, bool > extrapolateToIntermediateLayer(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer &lay, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise, bool perpendicularCheck=true) const
Private to extrapolate to the destination layer + surface, special treatment for exit layer.
Definition: Extrapolator.cxx:3448
Trk::ArraySpan
std::span< T > ArraySpan
Definition: TrackingVolume.h:59
Trk::Extrapolator::m_navigationBreakOscillation
Gaudi::Accumulators::Counter m_navigationBreakOscillation
number of navigation breaks due to oscillation
Definition: Extrapolator.h:708
beamspotman.n
n
Definition: beamspotman.py:727
Trk::TrackingVolume::confinedArbitraryLayers
ArraySpan< Layer const *const > confinedArbitraryLayers() const
Return the confined subLayer array.
Trk::theta
@ theta
Definition: ParamDefs.h:66
Trk::Extrapolator::m_navigator
ToolHandle< INavigator > m_navigator
Array of Material updatersc.
Definition: Extrapolator.h:605
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trk::Extrapolator::extrapolateInAlignableTV
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateInAlignableTV(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Surface *destSurf, const Trk::AlignableTrackingVolume *vol, PropDirection dir, ParticleHypothesis particle=pion) const
Definition: Extrapolator.cxx:1742
AthCommonDataStore::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
Trk::Extrapolator::m_navigationBreakVolumeSignature
Gaudi::Accumulators::Counter m_navigationBreakVolumeSignature
number of navigation breaks due to distance increase
Definition: Extrapolator.h:711
Trk::TrackingVolume::confinedDenseVolumes
ArraySpan< TrackingVolume const *const > confinedDenseVolumes() const
Return unordered subVolumes - not the ownership.
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Trk::DistanceSolution::second
double second() const
Distance to second intersection solution along direction (for a cylinder surface)
Trk::Extrapolator::radialDirectionCheck
bool radialDirectionCheck(const EventContext &ctx, const IPropagator &prop, const TrackParameters &startParm, const TrackParameters &parsOnLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, ParticleHypothesis particle=pion) const
Check for punchThrough in case of radial (perpendicular) direction change, returns true if the radial...
Definition: Extrapolator.cxx:3906
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::Extrapolator::extrapolateToVolumeWithPathLimit
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateToVolumeWithPathLimit(const EventContext &ctx, Cache &cache, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, double pathLim, Trk::PropDirection dir, Trk::ParticleHypothesis particle, const Trk::TrackingVolume *destVol, MaterialUpdateMode matupmod=addNoise) const
Definition: Extrapolator.cxx:4070
Trk::Extrapolator::identifiedParameters_t
std::vector< std::pair< std::unique_ptr< Trk::TrackParameters >, int > > identifiedParameters_t
Definition: Extrapolator.h:248
Trk::Extrapolator::m_dumpCache
BooleanProperty m_dumpCache
Definition: Extrapolator.h:675
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Trk::NavigationCell::exitFace
BoundarySurfaceFace exitFace
Definition: INavigator.h:43
Trk::Surface::normal
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
Trk::Layer::nextLayer
const Layer * nextLayer(const Amg::Vector3D &gp, const Amg::Vector3D &udir) const
getting the next/previous Layer if registered - unit for direction vector required
Definition: Layer.cxx:161
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::Extrapolator::m_navigationStatistics
BooleanProperty m_navigationStatistics
Definition: Extrapolator.h:686
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
StoreGateSvc_t m_detStore
Pointer to StoreGate (detector store by default)
Definition: AthCommonDataStore.h:393
Trk::ParametersBase
Definition: ParametersBase.h:55
Trk::TrackingVolume::boundarySurfaces
std::vector< std::shared_ptr< BoundarySurface< TrackingVolume > > > & boundarySurfaces()
Method to return the BoundarySurfaces.
Definition: TrackingVolume.cxx:809
Trk::CurvilinearParametersT
Definition: CurvilinearParametersT.h:48
Trk::Extrapolator::subMaterialEffectsUpdator
const IMaterialEffectsUpdator * subMaterialEffectsUpdator(const TrackingVolume &tvol) const
Access the subPropagator to the given volume.
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
Trk::Extrapolator::m_printRzOutput
BooleanProperty m_printRzOutput
Definition: Extrapolator.h:682
Trk::neutron
@ neutron
Definition: ParticleHypothesis.h:36
Trk::Extrapolator::positionOutput
std::string positionOutput(const Amg::Vector3D &pos) const
For the output - global position.
Definition: Extrapolator.cxx:3952
Trk::TrackParametersUVector
std::vector< std::unique_ptr< Trk::TrackParameters > > TrackParametersUVector
Definition: Extrapolator.h:62
Trk::Extrapolator::subPropagator
const IPropagator * subPropagator(const TrackingVolume &tvol) const
Access the subPropagator to the given volume.
Trk::EnergyLoss::meanRad
double meanRad() const
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
Trk::BinnedArray::arrayObjects
virtual std::span< T *const > arrayObjects()=0
Return all objects of the Array non-const we can still modify the T.
Trk::FullField
@ FullField
Field is set to be realistic, but within a given Volume.
Definition: MagneticFieldMode.h:21
Trk::Extrapolator::m_destinationThroughAssociation
Gaudi::Accumulators::Counter m_destinationThroughAssociation
navigation intialization
Definition: Extrapolator.h:701
beamspotman.dir
string dir
Definition: beamspotman.py:619
Trk::IPropagator::propagateParameters
virtual std::unique_ptr< TrackParameters > propagateParameters(const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir, const BoundaryCheck &bcheck, const MagneticFieldProperties &mprop, ParticleHypothesis particle=pion, bool returnCurv=false, const TrackingVolume *tVol=nullptr) const =0
Main propagation method for parameters only.
SG::VarHandleKeyArray::renounce
virtual void renounce()=0
Trk::Extrapolator::extrapolateFromLayerToLayer
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateFromLayerToLayer(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const TrackingVolume &tvol, const Layer *nextLayer, const Layer *destinationLayer, Trk::CacheOwnedPtr< Trk::TrackParameters > navParameters, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Private method to step from one to the last layer and stop at last layer (before 0) or before destina...
Definition: Extrapolator.cxx:3265
Trk::Extrapolator::m_useMuonMatApprox
BooleanProperty m_useMuonMatApprox
Definition: Extrapolator.h:666
SG::HandleClassifier::type
std::conditional< std::is_base_of< SG::VarHandleKeyArray, T >::value, VarHandleKeyArrayType, type2 >::type type
Definition: HandleClassifier.h:54
Trk::Global
@ Global
Definition: GeometrySignature.h:25
Trk::Extrapolator::m_resolveActive
BooleanProperty m_resolveActive
Definition: Extrapolator.h:650
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::TrackingVolume::volumeName
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
Trk::Extrapolator::extrapolateToDestinationLayer
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateToDestinationLayer(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const Layer &lay, const TrackingVolume &tvol, const Layer *startLayer, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Private to extrapolate to the destination layer + surface.
Definition: Extrapolator.cxx:3380
Trk::Surface::bounds
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
Trk::Extrapolator::m_stopWithUpdateZero
BooleanProperty m_stopWithUpdateZero
Definition: Extrapolator.h:646
Trk::Extrapolator::extrapolate
virtual std::unique_ptr< NeutralParameters > extrapolate(const NeutralParameters &parameters, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true) const override final
Main extrapolation Interface starting from neutral parameters and aiming at surface.
Definition: Extrapolator.cxx:385
Trk::nonInteracting
@ nonInteracting
Definition: ParticleHypothesis.h:28
Trk::EnergyLoss
This class describes energy loss material effects in the ATLAS tracking EDM.
Definition: EnergyLoss.h:34
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:452
Trk::DistanceSolution::absClosest
double absClosest() const
Absolute Distance to closest solution.
Trk::Extrapolator::extrapolateWithinDetachedVolumes
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateWithinDetachedVolumes(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
C) call from extrapolateInsideVolume.
Definition: Extrapolator.cxx:2678
Trk::IdentifiedMaterial
std::pair< std::shared_ptr< Material >, int > IdentifiedMaterial
Definition: BinnedMaterial.h:23
Trk::Extrapolator::m_updaters
ToolHandleArray< IMaterialEffectsUpdator > m_updaters
Array of MultipleScattering updaters.
Definition: Extrapolator.h:609
Trk::Extrapolator::m_maxRecursion
UnsignedIntegerProperty m_maxRecursion
Definition: Extrapolator.h:671
Trk::Layer::thickness
double thickness() const
Return the Thickness of the Layer.
Trk::Extrapolator::m_maxNavigSurf
static const unsigned int m_maxNavigSurf
Definition: Extrapolator.h:673
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::Extrapolator::initializeNavigation
PropDirection initializeNavigation(const EventContext &ctx, Cache &cache, const Trk::IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > startPars, const Trk::Surface &destSurface, Trk::PropDirection dir, ParticleHypothesis particle, Trk::CacheOwnedPtr< Trk::TrackParameters > &referenceParameters, const Trk::Layer *&associatedLayer, const Trk::TrackingVolume *&associatedVolume, const Trk::TrackingVolume *&destinationVolume) const
Private method for Initial Extrapolation setup -> overwrites the given pointers for the start and des...
Definition: Extrapolator.cxx:3717
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
Trk::NavigationCell
useful struct for a single navigation cell
Definition: INavigator.h:38
Trk::Surface::associatedLayer
const Trk::Layer * associatedLayer() const
return the associated Layer
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
DeMoScan.index
string index
Definition: DeMoScan.py:362
Trk::MaterialProperties
Definition: MaterialProperties.h:40
a
TList * a
Definition: liststreamerinfos.cxx:10
h
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::Extrapolator::m_startThroughAssociation
Gaudi::Accumulators::Counter m_startThroughAssociation
navigation intialization
Definition: Extrapolator.h:698
TRT_PAI_physicsConstants::mb
const double mb
1mb to cm2
Definition: TRT_PAI_physicsConstants.h:17
Trk::TrackingVolume::nextVolume
const TrackingVolume * nextVolume(const Amg::Vector3D &gp, const Amg::Vector3D &dir, PropDirection pDir=alongMomentum) const
Return the next volume along the navigation stream.
Definition: TrackingVolume.cxx:583
Trk::userOwn
@ userOwn
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:61
Trk::BoundaryCheck
Definition: BoundaryCheck.h:51
Trk::BinnedMaterial::material
const IdentifiedMaterial * material(const Amg::Vector3D &position) const
access to material/id per bin
Definition: BinnedMaterial.cxx:58
Trk::addNoise
@ addNoise
Definition: MaterialUpdateMode.h:19
Trk::TrackingVolume::confinedVolumes
const TrackingVolumeArray * confinedVolumes() const
Return the subLayer array.
Trk::Extrapolator::extrapolateToNextMaterialLayer
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateToNextMaterialLayer(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Trk::Surface *destSurf, const Trk::TrackingVolume *vol, PropDirection dir, const BoundaryCheck &bcheck, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Definition: Extrapolator.cxx:726
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:67
Trk::Layer::enclosingTrackingVolume
const TrackingVolume * enclosingTrackingVolume() const
get the confining TrackingVolume
Trk::SurfaceType::Cylinder
@ Cylinder
Trk::Layer::layerMaterialProperties
const LayerMaterialProperties * layerMaterialProperties() const
getting the LayerMaterialProperties including full/pre/post update
Trig::FeatureAccessImpl::collect
void collect(const HLT::TriggerElement *te, std::vector< Trig::Feature< T > > &data, const std::string &label, unsigned int condition, const std::string &teName, const HLT::TrigNavStructure *navstructure)
actual feature acceess implementation It has (thanks to the ClassTraits) functionality to flatten con...
Definition: FeatureCollectAthena.h:299
Trk::Extrapolator::extrapolateToVolumeBoundary
void extrapolateToVolumeBoundary(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Private method for extrapolation in intermediate volume to boundary surface.
Definition: Extrapolator.cxx:2851
SG::VarHandleBase::vhKey
SG::VarHandleKey & vhKey()
Return a non-const reference to the HandleKey.
Definition: StoreGate/src/VarHandleBase.cxx:629
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
Trk::Extrapolator::m_startThroughRecall
Gaudi::Accumulators::Counter m_startThroughRecall
navigation intialization
Definition: Extrapolator.h:699
Trk::TrackingVolume::isAlignable
virtual bool isAlignable() const
Trk::Extrapolator::m_layerSwitched
Gaudi::Accumulators::Counter m_layerSwitched
number of layers that have been switched
Definition: Extrapolator.h:704
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Trk::Cache::kCurrentRecursionCount
@ kCurrentRecursionCount
Definition: LocalExtrapolatorCache.h:100
Trk::Extrapolator::m_destinationThroughGlobalSearch
Gaudi::Accumulators::Counter m_destinationThroughGlobalSearch
navigation intialization
Definition: Extrapolator.h:703
Trk::undefinedFace
@ undefinedFace
Definition: BoundarySurfaceFace.h:59
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801
Trk::Extrapolator::m_subPropagators
std::vector< const IPropagator * > m_subPropagators
< Propagators to chose from (steered by signature)
Definition: Extrapolator.h:628
Trk::tubeInnerCover
@ tubeInnerCover
Definition: BoundarySurfaceFace.h:39
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Trk::CacheOwnedPtr
T * CacheOwnedPtr
Definition: ExtrUniquePtrHolder.h:28
Trk::ComparisonFunction< TrackParameters >
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::Extrapolator::extrapolateInsideVolume
Trk::CacheOwnedPtr< Trk::TrackParameters > extrapolateInsideVolume(const EventContext &ctx, Cache &cache, const IPropagator &prop, Trk::CacheOwnedPtr< Trk::TrackParameters > parm, const Surface &sf, const Layer *associatedLayer, const TrackingVolume &tvol, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Private method for extrapolation in final volume to destination surface.
Definition: Extrapolator.cxx:2655
test_pyathena.counter
counter
Definition: test_pyathena.py:15
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
Trk::TrackingVolume
Definition: TrackingVolume.h:119
Trk::TrackingVolume::associatedLayer
const Layer * associatedLayer(const Amg::Vector3D &gp) const
Return the associated Layer.
Definition: TrackingVolume.cxx:382
Trk::Extrapolator::extrapolateToNextActiveLayerMImpl
std::pair< std::unique_ptr< TrackParameters >, const Layer * > extrapolateToNextActiveLayerMImpl(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parm, PropDirection dir, const BoundaryCheck &bcheck, std::vector< const Trk::TrackStateOnSurface * > &material, ParticleHypothesis particle=pion, MaterialUpdateMode matupmode=addNoise) const
Actual heavy lifting implementation for extrapolateToNextActiveLayerM.
Definition: Extrapolator.cxx:652
Trk::Surface::type
constexpr virtual SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:26
Trk::Extrapolator::m_msupdater
ToolHandle< IMultipleScatteringUpdator > m_msupdater
Array of EnergyLoss updaters.
Definition: Extrapolator.h:615
Trk::Extrapolator::m_skipInitialLayerUpdate
BooleanProperty m_skipInitialLayerUpdate
Definition: Extrapolator.h:648
fitman.k
k
Definition: fitman.py:528
Trk::ExtrapolationCache::eloss
const EnergyLoss * eloss() const
Trk::EnergyLoss::sigmaIoni
double sigmaIoni() const
Trk::Extrapolator::m_propagators
ToolHandleArray< IPropagator > m_propagators
Private method for conversion of the synchronized geometry signature to the natural subdetector order...
Definition: Extrapolator.h:597
Trk::Extrapolator::m_stepPropagator
ToolHandle< IPropagator > m_stepPropagator
Navigator for TrackingGeometry and magnetic fiels acces.
Definition: Extrapolator.h:599
Trk::Layer
Definition: Layer.h:72
Trk::AlignableTrackingVolume
Definition: AlignableTrackingVolume.h:36
Trk::SurfaceBounds::r
virtual double r() const =0
Interface method for the maximal extension or the radius.