diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..1ce41acc943f6b058fb5778d12b257fd10aa69d0 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h @@ -0,0 +1,130 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ExtrapolationEngine.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRKEXINTERFACES_EXTRAPOLATIONENGINE_H +#define TRKEXINTERFACES_EXTRAPOLATIONENGINE_H + +// Gaudi +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +// Trk +#include "TrkDetDescrInterfaces/ITrackingGeometrySvc.h" +#include "TrkExInterfaces/IExtrapolationEngine.h" +#include "TrkExEngine/ExtrapolationMacros.h" +#include "TrkExUtils/ExtrapolationCell.h" +#include "TrkParameters/TrackParameters.h" +#include "TrkNeutralParameters/NeutralParameters.h" +// throw GaudiExceptions where necessary +#include "GaudiKernel/GaudiException.h" + +namespace Trk { + + class TrackingGeometry; + + /** @class ExtrapolationEngine + + Master extrapolation engine for extrapolation through the TrackingGeometry, + it delegates the extrapolation to optimised engines, handing over the ExtrapolationCell + as internal cache. + + There are identical interfaces for charged and neutral track parameters. + Providing a destination surface is optional, if no destination surface is given the extrapolation + process can be stopped by other directives, e.g. stopping at a certain path limit, material limit + or with a change of detector signature. + + @author Andreas.Salzburger -at- cern.ch + */ + class ExtrapolationEngine : public AthAlgTool, virtual public IExtrapolationEngine { + + friend class NavigationInitTest; + + public: + /** Constructor */ + ExtrapolationEngine(const std::string&,const std::string&,const IInterface*); + + /** Destructor */ + ~ExtrapolationEngine(); + + /** AlgTool initialize method */ + StatusCode initialize(); + + /** AlgTool finalize method */ + StatusCode finalize(); + + using IExtrapolationEngine::extrapolate; + + /** charged extrapolation - public interface */ + virtual ExtrapolationCode extrapolate(ExCellCharged& ecCharged, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** neutral extrapolation - public interface */ + virtual ExtrapolationCode extrapolate(ExCellNeutral& ecNeutral, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + + /** define for which GeometrySignature this extrapolator is valid - this is GLOBAL */ + GeometryType geometryType() const; + + private: + /** main loop extrapolation method */ + template <class T> ExtrapolationCode extrapolateT(ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** initialization method */ + template <class T> ExtrapolationCode initNavigation(ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum) const throw (GaudiException); + + + //!< retrieve TrackingGeometry + StatusCode updateTrackingGeometry() const; + + //!< return and retrieve + const TrackingGeometry& trackingGeometry() const throw (GaudiException); + + mutable const TrackingGeometry* m_trackingGeometry; //!< the tracking geometry owned by the navigator + ServiceHandle<ITrackingGeometrySvc> m_trackingGeometrySvc; //!< ToolHandle to the TrackingGeometrySvc + std::string m_trackingGeometryName; //!< Name of the TrackingGeometry as given in Detector Store + + //!< the tool handle array for static / dense / detached + ToolHandleArray<IExtrapolationEngine> m_extrapolationEngines; + std::vector<const IExtrapolationEngine*> m_eeAccessor; + + //!< forces a global search for the initialization, allows to switch TrackingGeometries in one job + bool m_forceSearchInit; + + }; + + inline GeometryType ExtrapolationEngine::geometryType() const + { return Trk::Master; } + + + inline const Trk::TrackingGeometry& ExtrapolationEngine::trackingGeometry() const throw (GaudiException) { + if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){ + ATH_MSG_ERROR("Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." ); + throw GaudiException("ExtrapolationEngine", "Problem with TrackingGeometry loading.", StatusCode::FAILURE); + } + return (*m_trackingGeometry); + } + + + +} // end of namespace + +//!< define the templated function +#include "ExtrapolationEngine.icc" + +#endif // TRKEXINTERFACES_IEXTRAPOLATIONENGINE_H + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc new file mode 100644 index 0000000000000000000000000000000000000000..5eb5ce6b79255edfacaecd2693cd3442e80cd921 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc @@ -0,0 +1,106 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ExtrapolationEngine.icc, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#include "TrkSurfaces/Surface.h" +#include "TrkVolumes/BoundarySurface.h" +#include "TrkGeometry/TrackingGeometry.h" +#include "TrkGeometry/TrackingVolume.h" +#include "TrkGeometry/Layer.h" +#include <iostream> +#include <iomanip> + +template <class T> Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolateT(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection dir, + Trk::BoundaryCheck bcheck) const +{ + + EX_MSG_DEBUG(++eCell.navigationStep, "starting extrapolation sequence."); + // initialize the navigation + Trk::ExtrapolationCode eCode = initNavigation<T>(eCell,sf,dir); + EX_MSG_VERBOSE(eCell.navigationStep, "initialize navigation return code : " << eCode.toString() ); + // main loop over volumes + while (eCell.leadVolume && eCode == Trk::ExtrapolationCode::InProgress ){ + // get the appropriate IExtrapolationEngine + const Trk::IExtrapolationEngine* iee = m_eeAccessor[eCell.leadVolume->geometryType()]; + eCode = iee ? iee->extrapolate(eCell, sf, dir, bcheck) : Trk::ExtrapolationCode::FailureConfiguration; + // give a message about what you have + EX_MSG_VERBOSE(eCell.navigationStep, "returned from volume return code : " << eCode.toString() ); + } + EX_MSG_DEBUG(eCell.navigationStep, "extrapolation finished return code : " << eCode.toString() ); + // before you return, finalize: sets the leadParameters to endParameters and empties the garbage bin + eCell.finalize(eCode); + // return the code + return eCode; +} + + +template <class T> Trk::ExtrapolationCode Trk::ExtrapolationEngine::initNavigation(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection dir) const throw (GaudiException) +{ + // initialize the Navigation stream ---------------------------------------------------------------------------------------- + // + // this is the global initialization, it only associated direct objects + // detailed navigation search needs to be done by the sub engines (since they know best) + EX_MSG_DEBUG(++eCell.navigationStep, "initialize the navigation stream."); + if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){ + EX_MSG_WARNING(eCell.navigationStep, "could not retrieve TrackingGeometry. Stopping."); + return Trk::ExtrapolationCode::FailureConfiguration; + } else + EX_MSG_DEBUG("navi", "successfully retrieved TrackingGeometry."); + // ---------- START initialization ----------------------------------------------------------------------------------------- + // initialize the start parameters - try association first + eCell.startLayer = eCell.startLayer ? eCell.startLayer : eCell.leadParameters->associatedSurface().associatedLayer(); + eCell.startVolume = eCell.startVolume ? eCell.startVolume : + ( eCell.startLayer ? eCell.startLayer->enclosingTrackingVolume() : m_trackingGeometry->lowestTrackingVolume(eCell.leadParameters->position()) ); + // bail out of the start volume can not be resolved + if (!eCell.startVolume) return Trk::ExtrapolationCode::FailureNavigation; + // screen output + EX_MSG_VERBOSE( eCell.navigationStep, "start volume termined as '" << eCell.startVolume->volumeName() << "'." ); + // check if the parameters are on a volume boundary - @TODO identify this case by something like eCell.leadParameters->associatedSurface().isBoundary() + if ( eCell.startVolume->onVolumeBoundary(*eCell.startParameters) ){ + // re-evaluate the volume by stepping out of the volume + EX_MSG_VERBOSE( eCell.navigationStep, "parameters are on volume boundary, stepping out of this TrackingVolume." ); + // stepping by one unit out of the volume + eCell.startVolume = m_trackingGeometry->lowestTrackingVolume(eCell.leadParameters->position()+dir*eCell.leadParameters->momentum().unit()); + // + EX_MSG_VERBOSE( eCell.navigationStep, "start volume re-evaluated as '" << eCell.startVolume->volumeName() << "'." ); + } + eCell.startLayer = eCell.startLayer ? eCell.startLayer : eCell.startVolume->associatedLayer(eCell.leadParameters->position()); + // now you can assign the lead volume + eCell.leadVolume = eCell.startVolume; + // ---------- END initialization ----------------------------------------------------------------------------------------- + if (sf){ + // keep track of the end surface + eCell.endSurface = sf; + // trying association via the layer : associated layer of material layer + eCell.endLayer = sf ? ( sf->associatedLayer() ? sf->associatedLayer() : sf->materialLayer() ) : 0; + eCell.endVolume = eCell.endLayer ? eCell.endLayer->enclosingTrackingVolume() : 0; + // check if you found layer and volume + if (!eCell.endVolume){ + EX_MSG_VERBOSE( eCell.navigationStep, "end volume needs to be determinded by surface intersection." ); + // make a straight line intersection + Trk::Intersection sfI = (dir == Trk::alongMomentum) ? + sf->straightLineIntersection(eCell.leadParameters->position(), eCell.leadParameters->momentum().unit(), true) : + sf->straightLineIntersection(eCell.leadParameters->position(), -1*(eCell.leadParameters->momentum().unit()), true); + // use this to find endVolume and endLayer + eCell.endVolume = trackingGeometry().lowestTrackingVolume(sfI.position); + eCell.endLayer = eCell.endLayer ? eCell.endLayer : trackingGeometry().associatedLayer(sfI.position); + } + // check the final end volume configuraiton - screen output + if (eCell.endVolume) + EX_MSG_VERBOSE( eCell.navigationStep, "end volume termined as '" << eCell.endVolume->volumeName() << "'." ); + } else + EX_MSG_VERBOSE( eCell.navigationStep, "no destination surface nor end volume provided, extrapolaiton has to stop on other means." ); + // return the progress call + return Trk::ExtrapolationCode::InProgress; + +} + + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h new file mode 100644 index 0000000000000000000000000000000000000000..bf1ab8d5e550368895dcbf18be0dfa06011fea7c --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// IExtrapolationMacros.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef EXSCREENOUTPUTDEFS +#define EXSCREENOUTPUTDEFS 1 +#define EX_MSG_INFO(nav, x) ATH_MSG_INFO(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x) +#define EX_MSG_DEBUG(nav, x) ATH_MSG_DEBUG(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x) +#define EX_MSG_VERBOSE(nav, x) ATH_MSG_VERBOSE(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x) +#define EX_MSG_WARNING(nav, x) ATH_MSG_WARNING(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x) +#define EX_MSG_FATAL(nav, x) ATH_MSG_FATAL(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x) +#endif + +#ifndef TRKEXENINGE_OUTPUTHELPER +#define TRKEXENINGE_OUTPUTHELPER +#define OH_CHECKFOUND(object) ( object ? "found" : "not found") +#endif + +#ifndef TRKEXENGINE_EXCODECHECKS +#define TRKEXENGINE_EXCODECHECKS +#define CHECK_ECODE_CONTINUE(ecell, ecode) if (!ecode.inProgress()) { EX_MSG_VERBOSE(ecell.navigationStep, ecode.toString() << " triggers return."); return ecode; } +#define CHECK_ECODE_SUCCESS(ecell, ecode) if (ecode.isSuccess()) { EX_MSG_VERBOSE(ecell.navigationStep, ecode.toString() << " stops extrapolation sequence."); return ecode; } +#endif + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..11c2e70402f3fae2455112c482dc49051369bb7e --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// MaterialEffectsEngine.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRKEXINTERFACES_MATERIAKEFFECTSENGINE_H +#define TRKEXINTERFACES_MATERIAKEFFECTSENGINE_H + +// Gaudi +#include "AthenaBaseComps/AthAlgTool.h" +// Trk +#include "TrkExInterfaces/IMaterialEffectsEngine.h" +#include "TrkExEngine/ExtrapolationMacros.h" +#include "TrkExUtils/ExtrapolationCell.h" +#include "TrkExUtils/MaterialInteraction.h" +#include "TrkExUtils/MaterialUpdateMode.h" +#include "TrkEventPrimitives/PropDirection.h" +#include "TrkParameters/TrackParameters.h" +#include "TrkNeutralParameters/NeutralParameters.h" + +namespace Trk { + + class Layer; + + /** @class MaterialEffectsEngine + + Material effects engine interface for charged and neutral (fast track simulation) , + the update is alwyas on the: + - eCell.leadParmaeters && eCell.leadLayer + - if eCell.leadPameters == eCell.startParamters clone to new parameters + else : update the new parameters + + @author Andreas Salzburger -at - cern.ch + */ + class MaterialEffectsEngine : public AthAlgTool, virtual public IMaterialEffectsEngine { + public: + + /** Constructor */ + MaterialEffectsEngine(const std::string&,const std::string&,const IInterface*); + + /** Destructor */ + ~MaterialEffectsEngine(); + + /** AlgTool initialize method */ + StatusCode initialize(); + + /** AlgTool finalize method */ + StatusCode finalize(); + + /** charged extrapolation */ + virtual ExtrapolationCode handleMaterial(ExCellCharged& ecCharged, + PropDirection dir=alongMomentum, + MaterialUpdateStage matupstage=fullUpdate) const; + + /** neutral extrapolation - only for Fatras, dummy implementation here */ + virtual ExtrapolationCode handleMaterial(ExCellNeutral&, + PropDirection, + MaterialUpdateStage) const {return Trk::ExtrapolationCode::InProgress; } + + protected: + /** charged extrapolation */ + const TrackParameters* updateTrackParameters(const Trk::TrackParameters& parameters, + Trk::ExCellCharged& eCell, + Trk::PropDirection dir, + Trk::MaterialUpdateStage matupstage) const; + + MaterialInteraction m_interactionFormulae; //!< the formulas concentrated + ParticleMasses m_particleMasses; //!< struct of Particle masses + + + }; + + +} // end of namespace + +#endif // TRKEXINTERFACES_MATERIAKEFFECTSENGINE_H + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..73fe210878dba10d75ede5bc3da0ea1a4af9cc71 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PropagationEngine.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRKEXENGINE_PROPAGATIONENGINE_H +#define TRKEXENGINE_PROPAGATIONENGINE_H + +// Gaudi +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +// Trk +#include "TrkExInterfaces/IPropagationEngine.h" +#include "TrkExEngine/ExtrapolationMacros.h" +#include "TrkExUtils/ExtrapolationCell.h" +#include "TrkEventPrimitives/PropDirection.h" +#include "TrkParameters/TrackParameters.h" +#include "TrkNeutralParameters/NeutralParameters.h" + +namespace Trk { + + class Surface; + class IPropagator; + + /** @class PropagationEngine + + Wrapper around the IPropagator interface, + the neutral propagation is solved by using the surface::straightLineIntersection + mehtod. + + @author Andreas Salzburger -at - cern.ch + */ + class PropagationEngine : public AthAlgTool, virtual public IPropagationEngine { + public: + + /** Constructor */ + PropagationEngine(const std::string&,const std::string&,const IInterface*); + + /** Destructor */ + ~PropagationEngine(); + + /** AlgTool initialize method */ + StatusCode initialize(); + + /** AlgTool finalize method */ + StatusCode finalize(); + + /** Avoid shaddowing */ + using IPropagationEngine::propagate; + + /** resolve the boundary situation - for charged particles */ + virtual ExtrapolationCode propagate(ExCellCharged& ecCell, + const Surface& sf, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true, + bool returnCurvilinear = true) const; + + /** resolve the boundary situation - for neutral particles */ + virtual ExtrapolationCode propagate(ExCellNeutral& enCell, + const Surface& sf, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true, + bool returnCurvilinear = true) const; + + protected: + + ToolHandle<IPropagator> m_propagator; + double m_pathLimitTolerance; + + + }; + + +} // end of namespace + +#endif // TRKEXINTERFACES_INAVIGATIONENGINE_H + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..bc81f5102f4b3060fe0e630f755f3f6074820315 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h @@ -0,0 +1,144 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticEngine.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRKEXENINGE_STATICENGINE_H +#define TRKEXENINGE_STATICENGINE_H + +#ifndef TRKEXENINGE_OUTPUTHELPER +#define TRKEXENINGE_OUTPUTHELPER +#define OH_CHECKFOUND(object) ( object ? "found" : "not found") +#endif + +// Gaudi +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +// Trk +#include "TrkExInterfaces/IExtrapolationEngine.h" +#include "TrkExUtils/ExtrapolationCell.h" +#include "TrkExEngine/ExtrapolationMacros.h" +#include "TrkParameters/TrackParameters.h" +#include "TrkNeutralParameters/NeutralParameters.h" + +namespace Trk { + + class IPropagationEngine; + class IMaterialEffectsEngine; + class INavigationEngine; + + + /** @class StaticEngine + + Extrapolation engine for static layer & volume setup. + + This engine relies on the fact that every position in a static layer setup can be uniquely associated to a layer (NavigationLayer or real physical layer), + and thus to a voume at navigation level. The extrapolation process within a fully static setup is then realised as a step from layer to layer within a volume, + and from volume to volume at a higher level. + + The entire code is written as a template in either charged or neutral parameters. + + @author Andreas.Salzburger -at- cern.ch + + */ + class StaticEngine : public AthAlgTool, virtual public IExtrapolationEngine { + + public: + + /** @enum ResolveLayerType + - use for code readability + */ + enum ResolveLayerType { + StartLayer = 0, + NavigationLayer = 1, + PassThroughLayer = 2, + SubStructureLayer = 3, + DestinationLayer = 4, + StartAndDestinationLayer = 6, + UndefinedLayer = 5 + }; + + /** Constructor */ + StaticEngine(const std::string&,const std::string&,const IInterface*); + + /** Destructor */ + ~StaticEngine(); + + /** AlgTool initialize method */ + StatusCode initialize(); + + /** AlgTool finalize method */ + StatusCode finalize(); + + using IExtrapolationEngine::extrapolate; + + /** charged extrapolation - public interface */ + virtual ExtrapolationCode extrapolate(ExCellCharged& ecCharged, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + + /** neutral extrapolation - public interface */ + virtual ExtrapolationCode extrapolate(ExCellNeutral& ecNeutral, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** define for which GeometrySignature this extrapolator is valid - this is GLOBAL */ + GeometryType geometryType() const; + + private: + /** main loop extrapolation method */ + template <class T> ExtrapolationCode extrapolateT(ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** init Navigation for static setup */ + template <class T> ExtrapolationCode initNavigationT(ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** main static layer handling */ + template <class T> ExtrapolationCode handleLayerT(ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + /** main sub structure layer handling */ + template <class T> ExtrapolationCode resolveLayerT(ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true, + bool hasSubStructure = false, + bool isStartLayer = false, + bool isDestinationLayer =false) const; + /** handle the failure - as configured */ + template <class T> ExtrapolationCode handleReturnT(ExtrapolationCode eCode, + ExtrapolationCell<T>& eCell, + const Surface* sf = 0, + PropDirection dir=alongMomentum, + BoundaryCheck bcheck = true) const; + + ToolHandle<IPropagationEngine> m_propagationEngine; //!< the used propagation engine + ToolHandle<INavigationEngine> m_navigationEngine; //!< the navigation engine to resolve the boundary + ToolHandle<IMaterialEffectsEngine> m_materialEffectsEngine; //!< the material effects updated + + }; + + inline GeometryType StaticEngine::geometryType() const + { return Trk::Static; } + + +} // end of namespace + +//!< define the templated function +#include "StaticEngine.icc" + +#endif // TRKEXINTERFACES_IStaticEngine_H + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc new file mode 100644 index 0000000000000000000000000000000000000000..f41651fbac1f9a3a9cc471606ad545f7af2aea34 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc @@ -0,0 +1,385 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticEngine.icc, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#include "TrkExInterfaces/INavigationEngine.h" +#include "TrkExInterfaces/IPropagationEngine.h" +#include "TrkExInterfaces/IMaterialEffectsEngine.h" +#include "TrkSurfaces/Surface.h" +#include "TrkGeometry/TrackingGeometry.h" +#include "TrkGeometry/TrackingVolume.h" +#include "TrkGeometry/Layer.h" +#include <iostream> +#include <iomanip> + +template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck) const +{ + + Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress; + // ---- [0] check the direct propagation exit + // + // obviously need a surface to exercise the fallback & need to be configured to do so + if (sf && eCell.checkConfigurationMode(Trk::ExtrapolationMode::Direct)){ + EX_MSG_DEBUG(++eCell.navigationStep, "direct extapolation in volume " << eCell.leadVolume->volumeName()); + // propagate to the surface, possible return codes are : SuccessPathLimit, SucessDestination, FailureDestination + eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear); + // eCode can be directly returned + return eCode; + } + EX_MSG_DEBUG(++eCell.navigationStep, "extrapolation in static environment in volume " << eCell.leadVolume->volumeName()); + // evoke or finish the navigation initialization, possible return codes are: + // - InProgress : everything is fine, extrapolation in static volume is in progress + // - FailureNavigation : navigation setup could not be resolved, but reovery was not configured + // - Recovered : navigation setup could not be resolved, recovery by fallback to directly kicked in (and worked) + eCode = initNavigationT<T>(eCell,sf,pDir,bcheck); + CHECK_ECODE_CONTINUE(eCell, eCode); + // ----- [1] handle the ( leadLayer == endLayer )case : + // + // - this case does not need a layer to layer loop + if (sf && eCell.leadLayer == eCell.endLayer && eCell.initialVolume()){ + // screen output for startLayer == endLayer + EX_MSG_VERBOSE(eCell.navigationStep, "start and destination layer are identical -> jumping to final propagation."); + // set the leadLayerSurface to the parameters surface + eCell.leadLayerSurface = &(eCell.leadParameters->associatedSurface()); + // resolve the layer, it is the final extrapolation + // - InProgress : layer resolving went without problem + // - SuccessPathLimit : path limit reached & configured to stop (rather unlikely within a layer) + // - SuccessMaterialLimit : material limit reached & configured to stop there + // if the lead layer is also the startLayer found by initialization -> no material handling + eCode = resolveLayerT<T>(eCell, + sf, + pDir, + bcheck, + eCell.leadLayer->hasSubStructure(eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive)), + (eCell.leadLayer == eCell.startLayer && eCell.leadVolume == eCell.startVolume), + true); + // Success triggers a return + CHECK_ECODE_SUCCESS(eCell, eCode); + // extrapolation to destination was not successful + // - handle the return as configured (e.g. fallback) + return handleReturnT<T>(eCode, eCell, sf, pDir, bcheck); + } + // ----- [2] now do the layer-to-layer loop + // + // the volume returns the layers ordered by distance : + // - give potential start and end layer (latter only for the final volume) + // - start and end layer will be part of the loop + const Trk::Layer* fLayer = eCell.finalVolumeReached() ? eCell.endLayer : 0; + auto layerIntersections = eCell.leadVolume->materialLayersOrdered(eCell.leadLayer, fLayer, + *eCell.leadParameters, + pDir, + true, + eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive)); + EX_MSG_VERBOSE(eCell.navigationStep, "found a total of " << layerIntersections.size() << " layers for the layer-to-layer loop."); + // layer-to-layer loop starts here + for (auto& layerCandidate : layerIntersections ) { + // assign the leadLayer + eCell.leadLayer = layerCandidate.object; + // screen output for layer-to-layer loop + EX_MSG_VERBOSE(eCell.navigationStep, "layer-to-layer loop - processing layer with index : " << eCell.leadLayer->layerIndex().value()); + // assign also the leadLayer surface + // - it is the approaching surface for all layers but the very first one (where it's the parameter surface) + eCell.leadLayerSurface = (eCell.leadLayer == eCell.startLayer) ? &(eCell.leadParameters->associatedSurface()) : layerCandidate.representation; + // handle the layer, possible returns are : + // - InProgress : fine, whatever happened on the lead layer, may also be missed + // - SuccessWithPathLimit : propagation towards layer exceeded path limit + // - SuccessWithMaterialLimit : material interaction killed track + // - FailureDestination : destination was not hit appropriately + eCode = handleLayerT<T>(eCell, sf, pDir, bcheck); + EX_MSG_VERBOSE(eCell.navigationStep, "handleLayerT returned extrapolation code " << eCode.toString()); + // Possibilities are: + // - SuccessX -> return (via handleReturnT) + // - FailureX -> return (via handleReturnT that might evoke a fallback) + // - InProgess -> continue layer-to-layer loop + if (!eCode.inProgress()) return handleReturnT<T>(eCode, eCell, sf, pDir, bcheck); + } + // the layer 2 layer loop is done, the lead parameters are at the last valid option + // ----- [3] now resolve the boundary situation, call includes information wheather one is alreay at a boundary + // + // the navigaiton engine ca trigger different return codes + // - InProgress : fine, boundary surface has been found + // - SuccessWithPathLimit : propagation towards boundary surface exceeded path limit + // - FailureLoop/Navigation : problem in boundary resolving + eCode = m_navigationEngine->resolveBoundary(eCell, pDir); + // SuccessX and FailureX trigger a return + CHECK_ECODE_SUCCESS(eCell, eCode); + // handle the return of the boudnary resolving + return handleReturnT<T>(eCode, eCell, sf, pDir, bcheck); +} + +template <class T> Trk::ExtrapolationCode Trk::StaticEngine::initNavigationT(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck) const +{ + // initialize the Navigation stream ---------------------------------------------------------------------------------------- + // + // this is the global initialization, it only associated direct objects + // detailed navigation search needs to be done by the sub engines (since they know best) + EX_MSG_DEBUG(++eCell.navigationStep, "complete navigation initialization for static environment."); + // [1] the initial volume + if (eCell.startVolume == eCell.leadVolume && eCell.startLayer) { + // - found the initial start layer through association + EX_MSG_VERBOSE(eCell.navigationStep, "initial volume, everything set up already."); + // assigning it to the leadLayer + eCell.leadLayer = eCell.startLayer; + // return progress + return Trk::ExtrapolationCode::InProgress; + } + // [2] any volume if we don't have a leadLayer + if (!eCell.leadLayer){ + // - finding it through global search, never a boundary layer ... convention says that you update by exit + eCell.leadLayer = eCell.leadVolume->associatedLayer(eCell.leadParameters->position()); + EX_MSG_VERBOSE(eCell.navigationStep, "no start layer found yet, looking for it ..." << OH_CHECKFOUND(eCell.leadLayer) ); + } + // [3] the final volume - everything's fine + if (eCell.leadVolume == eCell.endVolume && sf) { + if (eCell.endLayer) { + // the end layer had been found already by association + EX_MSG_VERBOSE(eCell.navigationStep, "final volume, everything set up already."); + return Trk::ExtrapolationCode::InProgress; + } else { + // make a straight line intersection + Trk::Intersection sfI = sf->straightLineIntersection(eCell.leadParameters->position(), pDir*eCell.leadParameters->momentum(), true); + // use this to find endVolume and endLayer + eCell.endLayer = eCell.leadVolume->associatedLayer(sfI.position); + // if you have a surface you need to require an end layer for the validation, otherwise you need to do a fallbac + return eCell.endLayer ? Trk::ExtrapolationCode::InProgress : handleReturnT<T>(Trk::ExtrapolationCode::FailureNavigation, eCell, sf, pDir, bcheck); + } + } + // return that you're in progress + return Trk::ExtrapolationCode::InProgress; +} + +/** handle the layer */ +template <class T> Trk::ExtrapolationCode Trk::StaticEngine::handleLayerT(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck) const +{ + Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress; + EX_MSG_DEBUG(++eCell.navigationStep, "handle a new layer with layer index " << eCell.leadLayer->layerIndex().value()); + // layer has sub structure - this can be (and the layer will tell you): + // - sensitive surface which should be tried to hit + // - material sub structure to be resolved (independent of sensitive surface) + bool hasSubStructure = eCell.leadLayer->hasSubStructure(eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive)); + // [A] layer is a pure navigation layer and has no sub structure -> skip it, but only if it is not the final layer + if (!hasSubStructure && !eCell.leadLayer->layerIndex().value() && eCell.leadLayer != eCell.endLayer){ + EX_MSG_VERBOSE(eCell.navigationStep, "this layer is a navigation layer -> skipping it ..."); + return Trk::ExtrapolationCode::InProgress; + } + // [B] layer resolving is necessary -> resolve it + // - (a) layer has sub structure - this can be (and the layer will tell you): + // - sensitive surface which should be tried to hit + // - material sub structure to be resolved (independent of sensitive surface) + // - (b) layer is start layer (can not be if there was a volume switch) + bool isStartLayer = eCell.initialVolume() && eCell.leadLayer->onLayer(*eCell.leadParameters); + // - (c) layer is destination layer + // - final propagation to the layer and update if necessary + bool isDestinationLayer = (sf && eCell.leadLayer == eCell.endLayer); + // - postUpdate if necessary + if (hasSubStructure || isStartLayer || isDestinationLayer ){ + // screen output for sub strucutred layer + EX_MSG_VERBOSE(eCell.navigationStep, "this layer has sub structure, is start layer, or destination layer -> resolving it ..." ); + // resolve the layer, it handles all possible return types and gives them directly to extrapolateT<T> + // - InProgress : layer resolving went without problem + // - SuccessPathLimit : path limit reached & configured to stop + // - SuccessMaterialLimit : material limit reached & configured to stop there + return resolveLayerT<T>(eCell,sf,pDir,bcheck,hasSubStructure,isStartLayer,isDestinationLayer); + } + // [C] layer is a material layer without sub structure but material -> pass through + // no resolving ob sub structure to be done, an intermediate layer to be crossed + EX_MSG_VERBOSE(eCell.navigationStep, "this layer is an intermediate layer without sub structure -> passing through ..."); + // propagate to it, possible return codes ( with the default of finalPropagation = false): + // - SuccessPathLimit : propagation to layer exceeded path limit + // - InProgress : layer was hit successfuly, try to handle the material and sub structure, these are new parameters + // - Recovered : layer was not hit, so can be ignored in the layer to layer loop + eCode = m_propagationEngine->propagate(eCell,*eCell.leadLayerSurface,pDir,true,eCell.navigationCurvilinear); + // check if success was triggered through path limit reached on the way to the layer + CHECK_ECODE_SUCCESS(eCell, eCode); + // check if the layer was actually hit + if (eCode.inProgress()){ + // successful layer hit + EX_MSG_VERBOSE(eCell.navigationStep, "the layer has been succesful hit "); + // layer has no sub-structure : it is an intermediate layer that just needs pass-throgh + // return possbilities: + // - InProgress : material update performed or not (depending on material) + // - SuccessMaterialLimit : material limit reached & configured to stop there + eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate); + // check if success was triggered through material limit reached when updating + CHECK_ECODE_CONTINUE(eCell, eCode); + // record the passive parameters + eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectPassive); + // return the progress eCode back to the extrapolateT + return eCode; + } + // hit or not hit ... it's always in progress since we are in the layer to layer loop + return Trk::ExtrapolationCode::InProgress; +} + + +/** main sub structure layer handling */ +template <class T> Trk::ExtrapolationCode Trk::StaticEngine::resolveLayerT(Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck, + bool hasSubStructure, + bool isStartLayer, + bool isDestinationLayer) const +{ + Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress; + EX_MSG_DEBUG(++eCell.navigationStep, "resolve layer with" << (hasSubStructure ? " " : "out ") << "sub structure" + << (isDestinationLayer ? " -> destination layer." : "") ); + + // cache the leadLayer - needed for the layer-to-layer loop not to be broken + const Trk::Layer* initialLayer = eCell.leadLayer; + + // [A] the sub structure of the layer needs to be resolved: + // - either for sensitive parameters + // - or for material substructure + if (hasSubStructure){ + // if the layer is not the start layer - let us propagate to it + // - the surfaceOnApproach() call should have sorted out that this is actually an approaching representation + if (!isStartLayer){ + EX_MSG_VERBOSE(eCell.navigationStep, "this is not the start layer, propagate to it."); + // propagate to the representing surface of this layer + // - InProgress : propagation to approaching surface worked - check material update + // - SuccessPathLimit : propagation to approaching surface reached the path limit + // - Recovered : layer was not hit, so can be ignored in the layer to layer loop + eCode = m_propagationEngine->propagate(eCell,*eCell.leadLayerSurface,pDir,true,eCell.sensitiveCurvilinear); + CHECK_ECODE_SUCCESS(eCell,eCode); + // the extrapolation to the initial layer did not succeed - skip this layer in the layer-to-layer loop + if (eCode == Trk::ExtrapolationCode::Recovered) return Trk::ExtrapolationCode::InProgress; + // fill the corresponding parameters, the material effects updator can attach material to them + eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectPassive); + // the correct material layer needs to be assigned + if (eCell.leadLayerSurface->materialLayer()){ + eCell.leadLayer = eCell.leadLayerSurface->materialLayer(); + // now handle the material, return codes are: + // - SuccessMaterialLimit : material limit reached, return back + // - InProgress : material update done or not (depending on the material description) + eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate); + CHECK_ECODE_CONTINUE(eCell, eCode); + } + } // @TODO check postUpdate for start surface in sub structure environment + // resolve the substructure - the surfaces given by the layer, needs to be searched for with anyDirection + std::vector<Trk::SurfaceIntersection> cSurfaces; + // this will give you the compatible up to the endSurface (without the endSurface (sf) if given) + // - leadParameters->associatedSurface() are included or not, depending if it is the startLayer or not + size_t ncSurfaces = eCell.leadLayer->compatibleSurfaces(cSurfaces, + *eCell.leadParameters, + pDir, + bcheck, + (!isStartLayer ? eCell.leadLayerSurface : 0), + (isDestinationLayer ? sf : 0) ); + + EX_MSG_VERBOSE(eCell.navigationStep, "found " << ncSurfaces << " candidate sensitive surfaces to test."); + // check if you have to do something + if (ncSurfaces){ + // now loop over the surfaces: + // the surfaces will be sorted @TODO integrate pathLength propagation into this + for (auto& csf : cSurfaces ) { + EX_MSG_VERBOSE(eCell.navigationStep, "trying candidate surfaces with straight line path length " << csf.intersection.pathLength); + // propagate to the compatible surface, return types are (pathLimit failure is excluded by Trk::anyDirection for the moment): + // - InProgress : propagation to compatible surface worked + // - Recovered : propagation to compatible surface did not work, leadParameters stay the same + // eCode = m_propagationEngine->propagate(eCell,*(csf.object),pDir,true,eCell.sensitiveCurvilinear); + eCode = m_propagationEngine->propagate(eCell,*(csf.object),pDir,true,eCell.sensitiveCurvilinear); + + // check if the propagation was successful + if (eCode.inProgress()){ + EX_MSG_VERBOSE(eCell.navigationStep, "successfully hit sub structure surface."); + // record the parameters as sensitive or passive depending on the surface + Trk::ExtrapolationMode::eMode emode = csf.object->isActive() ? Trk::ExtrapolationMode::CollectSensitive : Trk::ExtrapolationMode::CollectPassive; + // fill the corresponding parameters, the material effects updator can attach material to them + eCell.stepParameters(eCell.leadParameters, emode); + // check if the surface holds a material layer + // - yes : it is a sub surface that has a material layer attached + // - no 1 : it is a sub surface and has no material attached + // - no 2 : it is the representing layer for the material integration (this case can be caught by surface pointer comparison) + if (csf.object->materialLayer() || ( csf.object->associatedLayer() && csf.object == &(csf.object->associatedLayer()->surfaceRepresentation()) ) ) { + // the resolved surface has material, set the leadLayer to + // - the materialLayer ( has higher priority than the associatedLayer() ) + // - the associatedLayer ( it is the representing layer ) + eCell.leadLayer = csf.object->materialLayer() ? csf.object->materialLayer() : csf.object->associatedLayer(); + // now handle the material, return codes are: + // - SuccessMaterialLimit : material limit reached,return back + // - InProgress : material update done or not (depending on the material description) + eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate); + CHECK_ECODE_CONTINUE(eCell, eCode); + } + } + } // loop over test surfaces done + } // there are compatible surfaces + } + + // the layer is a destination layer + // - the final propagation call is indepenent of whether sub structure was resolved or not + // - the eCell.leadParameters are at the last possible parameters + if (sf && isDestinationLayer) { + // [B] the layer is start and destination layer but has no sub-structure + // -> propagation to destination surface + // (a) the starting layer is the same layer : + // - neither preUpdate nore postUpdate to be done, this is old-style within-layer extrapolation + // - material will be taken into account either when the layer was reached from another layer + // or when the layer is left to another destination + // (b) the starting layer is not the same layer : + // - apply the preUpdate on the parameters whein they reached the surface + // Possible return types: + // - SuccessDestion : great, desintation surface hit + // - SuccessPathLimit : pathlimit was reached on the way to the destination surface + eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear); + EX_MSG_VERBOSE(eCell.navigationStep, "attempt to hit destination surface resulted in " << eCode.toString() ); + // preUpdate needed when the layer is NOT the startLayer - or if sub structure resolving happened + if ( (!isStartLayer || hasSubStructure) && (eCode != Trk::ExtrapolationCode::SuccessPathLimit) ){ + // the resolved surface has material, set the leadLayer to + // - the materialLayer ( has higher priority than the associatedLayer() ) + // - the associatedLayer ( if no materialLayer is not there ) + eCell.leadLayer = sf->materialLayer() ? sf->materialLayer() : sf->associatedLayer(); + // finally do the material update + // - this is the final call, no need to check for SuccessMaterialLimit + // - however only do the preUpdate if the destination was successfully hit (and no path limit kicked in) + // the material effects updator usually returns inProgress, this needs to be ingored + m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::preUpdate); + } + // return what you have handleLayerT or extrapolateT will resolve that + return eCode; + } + // reset the lead layer to ensure the layer-to-layer loop + eCell.leadLayer = initialLayer; + // return the code: + // - if it came until here, return InProgress to not break the layer-to-layer loop + return Trk::ExtrapolationCode::InProgress; +} + +/** handle the failure - as configured */ +template <class T> Trk::ExtrapolationCode Trk::StaticEngine::handleReturnT(Trk::ExtrapolationCode eCode, + Trk::ExtrapolationCell<T>& eCell, + const Trk::Surface* sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck) const +{ + EX_MSG_DEBUG(++eCell.navigationStep, "handleReturnT with code " << eCode.toString() << " called." ); + if (eCode.isSuccessOrRecovered() || eCode.inProgress() ){ + EX_MSG_VERBOSE(eCell.navigationStep, "leaving static extrapolator successfully with code " << eCode.toString()); + return eCode; + } + EX_MSG_VERBOSE(eCell.navigationStep, "failure detected as " << eCode.toString() << " - checking fallback configuration."); + // obviously we need a surface to exercise the fallback + if (sf && !eCell.checkConfigurationMode(Trk::ExtrapolationMode::AvoidFallback)){ + EX_MSG_VERBOSE(eCell.navigationStep, "fallback configured. Trying to hit destination surface from last valid parameters."); + // check if you hit the surface, could still be stopped by PathLimit, but would also count as recovered + eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear); + } + // nothing to try anynore + return eCode; +} + + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..ddbf4b3ef1fba9f1d2a8c5e9fdd1d6985db4e41a --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticNavigationEngine.h, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRKEXENGINE_STATICNAVIGATIONENGINE_H +#define TRKEXENGINE_STATICNAVIGATIONENGINE_H + +// Gaudi +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +// Trk +#include "TrkExInterfaces/INavigationEngine.h" +#include "TrkExEngine/ExtrapolationMacros.h" +#include "TrkExUtils/ExtrapolationCell.h" +#include "TrkParameters/TrackParameters.h" +#include "TrkNeutralParameters/NeutralParameters.h" +#include "TrkVolumes/BoundarySurface.h" +// throw GaudiExceptions where necessary +#include "GaudiKernel/GaudiException.h" + + +namespace Trk { + + class IPropagationEngine; + class IMaterialEffectsEngine; + class TrackingGeometry; + + /** @class StaticNavigationEntine + + The static navigation engine for finding the next volume, + propagate to the boundary, can be shared with other engines that have a static frame. + + @author Andreas.Salzburger -at- cern.ch + */ + class StaticNavigationEngine : public AthAlgTool, virtual public INavigationEngine { + + public: + /** Constructor */ + StaticNavigationEngine(const std::string&,const std::string&,const IInterface*); + + /** Destructor */ + ~StaticNavigationEngine(); + + /** AlgTool initialize method */ + StatusCode initialize(); + + /** AlgTool finalize method */ + StatusCode finalize(); + + /** avoid method shaddowing */ + using INavigationEngine::resolveBoundary; + + /** resolve the boundary situation - for charged particles */ + virtual ExtrapolationCode resolveBoundary(Trk::ExCellCharged& eCell, PropDirection dir=alongMomentum) const; + + /** resolve the boundary situation - for neutral particles */ + virtual ExtrapolationCode resolveBoundary(Trk::ExCellNeutral& eCelll, PropDirection dir=alongMomentum) const; + + private: + /** resolve the boundary situation */ + template <class T> ExtrapolationCode resolveBoundaryT(ExtrapolationCell<T>& eCell, + PropDirection dir=alongMomentum) const; + + /** deal with the boundary Surface - called by resolveBoundary */ + template <class T> ExtrapolationCode handleBoundaryT(ExtrapolationCell<T>& eCell, + const BoundarySurface<TrackingVolume>& bSurfaceTV, + PropDirection dir=alongMomentum, + bool stepout=false) const; + + + //!< retrieve TrackingGeometry + StatusCode updateTrackingGeometry() const; + + //!< return and retrieve + const TrackingGeometry& trackingGeometry() const throw (GaudiException); + + ToolHandle<IPropagationEngine> m_propagationEngine; //!< the used propagation engine + ToolHandle<IMaterialEffectsEngine> m_materialEffectsEngine; //!< the material effects updated + + mutable const TrackingGeometry* m_trackingGeometry; //!< the tracking geometry owned by the navigator + std::string m_trackingGeometryName; //!< Name of the TrackingGeometry as given in Detector Store + + }; + +inline const Trk::TrackingGeometry& StaticNavigationEngine::trackingGeometry() const throw (GaudiException) { + if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){ + ATH_MSG_ERROR("Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." ); + throw GaudiException("StaticNavigationEngine", "Problem with TrackingGeometry loading.", StatusCode::FAILURE); + } + return (*m_trackingGeometry); +} + +} // end of namespace + +//!< define the templated function +#include "StaticNavigationEngine.icc" + +#endif // TRKEXENGINE_STATICNAVIGATIONENGINE_H + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc new file mode 100644 index 0000000000000000000000000000000000000000..0924e1bcb678f77d0dea6d8fcef5d92a4f580c52 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc @@ -0,0 +1,184 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticNavigationEngine.icc, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#include "TrkExInterfaces/IPropagationEngine.h" +#include "TrkExInterfaces/IMaterialEffectsEngine.h" +#include "TrkGeometry/TrackingVolume.h" +#include "TrkGeometry/TrackingGeometry.h" +#include "TrkVolumes/BoundarySurface.h" +#include "GeoPrimitives/GeoPrimitives.h" + +/** handle the failure - as configured */ +template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBoundaryT(Trk::ExtrapolationCell<T>& eCell, + Trk::PropDirection pDir) const +{ + EX_MSG_DEBUG(++eCell.navigationStep, "resolve boundary situation leaving '"<< eCell.leadVolume->volumeName() + << (int(pDir) > 0 ? "' along momentum." : "' opposite momentum.") ); + // initialize the extrapolation code to progress + Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress; + // [1] ------------------------ fast boundary access : take straight line estimates as navigation guide -------------- + auto boundaryIntersections = eCell.leadVolume->boundarySurfacesOrdered(*eCell.leadParameters, + pDir, + eCell.onLastBoundary() ); + EX_MSG_VERBOSE(eCell.navigationStep, "found " << boundaryIntersections.size() << " boundary surfaces to try" + << ( eCell.onLastBoundary() ? " - starting from last boundary." : "." ) ); + // remember them for the slow acces + std::map< const Trk::BoundarySurface<Trk::TrackingVolume>*, bool > bSurfacesTried; + for (auto& boundaryCandidate : boundaryIntersections){ + // the surface of the + const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryCandidate.object; + // skip if it's the last boundary surface + if (eCell.onLastBoundary() && &bSurfaceTV->surfaceRepresentation() == eCell.lastBoundarySurface ) continue; + // check this boudnary, possible return codes are: + // - SuccessPathLimit : propagation to boundary caused PathLimit to be fail @TODO implement protection againg far of tries + // - SuccessMaterialLimit : boundary was reached and material update on boundary reached limit + // - InProgress : boundary was reached and ready for continueing the navigation + // - UnSet : boundary was not reached, try the next one + // - FailureLoop : next Volume was previous Volume + eCode = handleBoundaryT<T>(eCell,*bSurfaceTV,pDir); + CHECK_ECODE_SUCCESS(eCell, eCode); + // Failure or Unset are not triggering a return, try more sophisticated navigation + if (!eCode.inProgress()){ + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping."); + // book keeping for the slow access not to try again the same stuff + bSurfacesTried[bSurfaceTV] = false; + // skip to the next surface if there's one + continue; + } + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString()); + // set that this was the last boundary surface + eCell.lastBoundarySurface = &bSurfaceTV->surfaceRepresentation(); + // and return the code yielded by the handleBoundaryT + return eCode; + } + // [2] ------------------------ slow boundary access : take all boundary surfaces and simply try -------------- + EX_MSG_VERBOSE(eCell.navigationStep, "fast boundary navigation did not succeeed - trying slow navigation now."); + // ignore the ones you have tried already + for (auto& bSurface : eCell.leadVolume->boundarySurfaces() ){ + // we tried this one already, no point to do it again + if ( bSurfacesTried.size() && bSurfacesTried.find(bSurface.getPtr()) != bSurfacesTried.end() ) continue; + // skip if it's the last boundary surface + if ( &bSurface->surfaceRepresentation() == eCell.lastBoundarySurface ) continue; + EX_MSG_VERBOSE(eCell.navigationStep, "trying a boundary surface."); + // there is now loop protection in the slow access, needs to be done by hand + // check this boudnary, possible return codes are: + // - SuccessPathLimit : propagation to boundary caused PathLimit to be fail @TODO implement protection againg far of tries + // - SuccessMaterialLimit : boundary was reached and material update on boundary reached limit + // - InProgress : boundary was reached and ready for continueing the navigation + // - UnSet : boundary was not reached, try the next one + eCode = handleBoundaryT<T>(eCell,*bSurface.getPtr(),pDir); + CHECK_ECODE_SUCCESS(eCell, eCode); + // Failure or Unset are not triggering a return, try more sophisticated navigation + if (!eCode.inProgress()){ + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping."); + // skip to the next surface if there's one + continue; + } + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString()); + // set that this was the last boundary surface + eCell.lastBoundarySurface = &bSurface->surfaceRepresentation(); + // and return the code yielded by the handleBoundaryT + return eCode; + } + // [3] ------------------------ slowest boundary access : step-out-of-volume approach ------------------------- + EX_MSG_VERBOSE(eCell.navigationStep, "slow boundary navigation did not succeeed - trying step-out-of-volume approach now"); + for (auto& boundaryCandidate : boundaryIntersections){ + // the surface of the + const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryCandidate.object; + // check this boudnary, possible return codes are: + // - SuccessPathLimit : propagation to boundary caused PathLimit to be fail @TODO implement protection againg far of tries + // - SuccessMaterialLimit : boundary was reached and material update on boundary reached limit + // - InProgress : boundary was reached and ready for continueing the navigation + // - UnSet : boundary was not reached, try the next one + // - FailureLoop : next Volume was previous Volume + eCode = handleBoundaryT<T>(eCell,*bSurfaceTV,pDir,true); + CHECK_ECODE_SUCCESS(eCell, eCode); + // Failure or Unset are not triggering a return, try more sophisticated navigation + if (!eCode.inProgress()){ + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping."); + // skip to the next surface if there's one + continue; + } + EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString()); + // set that this was the last boundary surface + eCell.lastBoundarySurface = &bSurfaceTV->surfaceRepresentation(); + // and return the code yielded by the handleBoundaryT + return eCode; + } + // return it back + EX_MSG_DEBUG(eCell.navigationStep, "could not resolve the boundary situation. Exiting."); + return Trk::ExtrapolationCode::FailureNavigation; +} + +/** handle the failure - as configured */ +template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::handleBoundaryT(Trk::ExtrapolationCell<T>& eCell, + const Trk::BoundarySurface<Trk::TrackingVolume>& bSurfaceTV, + Trk::PropDirection pDir, + bool stepout) const +{ + // get the bondary surface and compare with last one to prevent loops + const Trk::Surface& bSurface = bSurfaceTV.surfaceRepresentation(); + // propagate the parameters to the boundary (force boundaryCheck to true in case it is not a step-out trial), possible return codes : + // - SuccessPathLimit : pathLimit reached during propagation + // - InProgress : boundary reached + // - Recovered : boundary not reached + Trk::ExtrapolationCode eCode = m_propagationEngine->propagate(eCell,bSurface,pDir,!stepout,eCell.destinationCurvilinear); + CHECK_ECODE_SUCCESS(eCell, eCode); + // check for progress + if (eCode.inProgress()){ + EX_MSG_VERBOSE(eCell.navigationStep, "parameters on boundary surface created, moving to next volume."); + // get the nextVolume - modify the position in case you have a step out trial, take attachment otherwise + const Trk::TrackingVolume* nextVolume = stepout ? + trackingGeometry().lowestTrackingVolume(Amg::Vector3D(eCell.leadParameters->position()+pDir*eCell.leadParameters->momentum().unit())) : + bSurfaceTV.attachedVolume(eCell.leadParameters->position(), eCell.leadParameters->momentum(), pDir); + // check if it is a boundary reached case + // - geometrySignature change and configuration to stop then triggers a Success + bool stopAtThisBoundary = eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopAtBoundary) + && (nextVolume->geometrySignature() != eCell.leadVolume->geometrySignature()); + // fill the boundary into the cache if successfully hit boundary surface + // - only cache if those are not the final parameters caused by a StopAtBoundary + if (!stopAtThisBoundary) + eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectBoundary); + // loop protection - relaxed for the cases where you start from the boundary + if (eCell.leadVolume == nextVolume ) { + // the start parameters where on the boundary already give a relaxed return code + if (&bSurface == eCell.lastBoundarySurface) return Trk::ExtrapolationCode::Unset; + // give some screen output as of why this happens + EX_MSG_VERBOSE(eCell.navigationStep, "loop detected while trying to leave TrackingVolume '" << nextVolume->volumeName() << "."); + // return a loop failure, parameter deletion will be done by cache + return Trk::ExtrapolationCode::FailureLoop; + } + // update the with the information of the layer material - will change the leadParameters + if (bSurface.materialLayer()) { + // assign the new lead layer for material inclusion + eCell.leadLayer = bSurface.materialLayer(); + // now handle the material, possible return codes: + // - InProgress : material update performed or not (depending on material) + // - SuccessMaterialLimit : material limit reached & configured to stop there + eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate); + CHECK_ECODE_SUCCESS(eCell, eCode); + } + // break if configured to break at volume boundary and signature change + if (stopAtThisBoundary){ + EX_MSG_VERBOSE(eCell.navigationStep, "geometry signature change from " << eCell.leadVolume->geometrySignature() << " to " << nextVolume->geometrySignature()); + // return the boundary reached + return Trk::ExtrapolationCode::SuccessBoundaryReached; + } + // remember the last boundary surface for loop protection + eCell.lastBoundarySurface = &bSurface; + eCell.lastBoundaryParameters = eCell.leadParameters; + // set next volume and reset lead layer + eCell.leadVolume = nextVolume; + eCell.leadLayer = 0; + // we have bParameters -> break the loop over boundaryIntersections + return Trk::ExtrapolationCode::InProgress; + } + + // you need to keep on trying + return Trk::ExtrapolationCode::Unset; + } diff --git a/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements b/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..97ff8ce49994fe8cbe5fbdcd629acc74c0a6a38b --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements @@ -0,0 +1,36 @@ +package TrkExEngine + +manager Andreas Salzburger <Andreas.Salzburger@cern.ch> +author Andreas Salzburger <Andreas.Salzburger@cern.ch> + +################################################################# +# public use statements +use AtlasPolicy AtlasPolicy-* +use GeoPrimitives GeoPrimitives-* DetectorDescription +use GaudiInterface GaudiInterface-* External +use AthenaBaseComps AthenaBaseComps-* Control +use TrkExInterfaces TrkExInterfaces-* Tracking/TrkExtrapolation +use TrkExUtils TrkExUtils-* Tracking/TrkExtrapolation +use TrkParameters TrkParameters-* Tracking/TrkEvent +use TrkNeutralParameters TrkNeutralParameters-* Tracking/TrkEvent +use TrkEventPrimitives TrkEventPrimitives-* Tracking/TrkEvent +use TrkVolumes TrkVolumes-* Tracking/TrkDetDescr +use TrkSurfaces TrkSurfaces-* Tracking/TrkDetDescr +use TrkGeometry TrkGeometry-* Tracking/TrkDetDescr +use TrkDetDescrInterfaces TrkDetDescrInterfaces-* Tracking/TrkDetDescr + + +################################################################# +# private use statements +private +use TrkDetDescrUtils TrkDetDescrUtils-* Tracking/TrkDetDescr + +public +library TrkExEngine *.cxx components/*.cxx +apply_pattern declare_python_modules files="*.py" +apply_pattern component_library + +private +#macro cppdebugflags '$(cppdebugflags_s)' +#macro_remove componentshr_linkopts "-Wl,-s" +macro DOXYGEN_IMAGE_PATH "../doc/images" \ No newline at end of file diff --git a/Tracking/TrkExtrapolation/TrkExEngine/doc/mainpage.h b/Tracking/TrkExtrapolation/TrkExEngine/doc/mainpage.h new file mode 100644 index 0000000000000000000000000000000000000000..d58f97cb9f88e3f6f50f0ee3c891958db425cfc2 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/doc/mainpage.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + + <i>This page has been automatically generated by the tool. Please remove this line when you start creating your own mainpage</i> + +@mainpage + +New Extrapolation package +========================= + +The TrkExEngine package was created to eventually repace the TrkExTools package by redefining and centralising the interface of all extrapolation operations needed for reconstruction and fast track simulation. +It has been re-designed in accordance to the updated track parameterisation (TrkParametersBase). + +Design concepts and implementation +================================== + +Data Flow +--------- + +The major design choice of the new TrkExEngine package is a division into optimised engines for the given geometry setup. +The tracking geometry (TrkGeometry) supports the following different geometyr types: +- static : a layer based setup that is interlinked and pre-ordered at the tracking geometry building +- dense : a dense volume description, especially made for the STEP propagator (TrkExSTEP_Propagator) +- detached : a mixed setup of freely based volumes, especially made fort the STEP propagator + +One single master engine (Trk::ExtrapolationEngine) steers the dataflow and the navigation through the high level tracking volumes, +calling the optimised sub engine for the different tracking volumes. The type of the tracking volume is provided by the node itself via an enumaration object. + +The extrapolation, navigation and eventually needed material or jacobian collection is done using a cache object (Trk::ExtrapolationCell) which is handed over from engine to engine. + + +The ExtrapolationCell +--------------------- + +The key object of the extrapolation engine is the Trk::ExtrapolationCell class, which is used to start, configure and steer the extrapolation process. +This class is a templated object and can be used with charged (TrkParameters) and neutral (TrkNeutralParameters) parameters. +The ExtrapolationEngine itself thus supports the exact same interface for charged and neutral parameters. + +The ExtrapolationCell is the single cache allowed in the new ExtrapolationEngine and --- since it is the input/output object --- turns the master engine into a thread -safe component. + + +The ExtrapolationCode +--------------------- + +The main return class of the ExtrapolationEngine package is a ExtrapolationCode class, which carries the current status of the extrapoaltion. +During the extrapolation process, the code forwarded between the different components is usually Trk::ExtrapolationCode::InProgress, +while success and failure codes are used to indicate different destination parameters or eventual failures during the extrapolation progress. + + +@htmlinclude used_packages.html + +@include requirements + +*/ diff --git a/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py b/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py new file mode 100644 index 0000000000000000000000000000000000000000..881ec2941d03e6abf10158d40bca99ce339222ad --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py @@ -0,0 +1,106 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +###################################################### +# AtlasExtrapolationEngine module +# +# it inherits from Trk__Extrapolator and uses +# the AtlasTrackingGeometrySvc +# +###################################################### + +# import the include statement +from AthenaCommon.Include import Include, IncludeError, include + +# import the ExtrapolationEngine configurable +from TrkExEngine.TrkExEngineConf import Trk__ExtrapolationEngine as ExEngine + +# define the class +class AtlasExtrapolationEngine( ExEngine ): + # constructor + def __init__(self,name = 'Extrapolation', nameprefix = 'Atlas', ToolOutputLevel = None, TrackingGeometrySvc = None): + + # get the correct TrackingGeometry setup + if not TrackingGeometrySvc : + from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc + from AthenaCommon.AppMgr import ServiceMgr as svcMgr + AtlasTrackingGeometrySvc = svcMgr.AtlasTrackingGeometrySvc + else : + AtlasTrackingGeometrySvc = TrackingGeometrySvc + + # import the ToolSvc + from AthenaCommon.AppMgr import ToolSvc + if 'ToolSvc' not in dir() : + ToolSvc = ToolSvc() + + # load the RungeKutta Propagator + from TrkExRungeKuttaPropagator.TrkExRungeKuttaPropagatorConf import Trk__RungeKuttaPropagator + RungeKuttaPropagator = Trk__RungeKuttaPropagator(name = nameprefix+'RungeKuttaPropagator') + if ToolOutputLevel : + RungeKuttaPropagator.OutputLevel = ToolOutputLevel + ToolSvc += RungeKuttaPropagator + + # from the Propagator create a Propagation engine to handle path length + from TrkExEngine.TrkExEngineConf import Trk__PropagationEngine + StaticPropagator = Trk__PropagationEngine(name = nameprefix+'StaticPropagation') + # give the tools it needs + StaticPropagator.Propagator = RungeKuttaPropagator + # configure output formatting + StaticPropagator.OutputPrefix = '[SP] - ' + StaticPropagator.OutputPostfix = ' - ' + if ToolOutputLevel : + StaticPropagator.OutputLevel = ToolOutputLevel + # add to tool service + ToolSvc += StaticPropagator + + # load the material effects engine + from TrkExEngine.TrkExEngineConf import Trk__MaterialEffectsEngine + MaterialEffectsEngine = Trk__MaterialEffectsEngine(name = nameprefix+'MaterialEffects') + # configure output formatting + MaterialEffectsEngine.OutputPrefix = '[ME] - ' + MaterialEffectsEngine.OutputPostfix = ' - ' + if ToolOutputLevel : + MaterialEffectsEngine.OutputLevel = ToolOutputLevel + # add to tool service + ToolSvc += MaterialEffectsEngine + + # load the static navigation engine + from TrkExEngine.TrkExEngineConf import Trk__StaticNavigationEngine + StaticNavigator = Trk__StaticNavigationEngine(name = nameprefix+'StaticNavigation') + # give the tools it needs + StaticNavigator.PropagationEngine = StaticPropagator + StaticNavigator.MaterialEffectsEngine = MaterialEffectsEngine + # Geometry name + StaticNavigator.TrackingGeometry = AtlasTrackingGeometrySvc.TrackingGeometryName + # configure output formatting + StaticNavigator.OutputPrefix = '[SN] - ' + StaticNavigator.OutputPostfix = ' - ' + if ToolOutputLevel : + StaticNavigator.OutputLevel = ToolOutputLevel + # add to tool service + ToolSvc += StaticNavigator + + + # load the Static ExtrapolationEngine + from TrkExEngine.TrkExEngineConf import Trk__StaticEngine + StaticExtrapolator = Trk__StaticEngine(name = nameprefix+'StaticExtrapolation') + # give the tools it needs + StaticExtrapolator.PropagationEngine = StaticPropagator + StaticExtrapolator.MaterialEffectsEngine = MaterialEffectsEngine + StaticExtrapolator.NavigationEngine = StaticNavigator + # configure output formatting + StaticExtrapolator.OutputPrefix = '[SE] - ' + StaticExtrapolator.OutputPostfix = ' - ' + if ToolOutputLevel : + StaticExtrapolator.OutputLevel = ToolOutputLevel + # add to tool service + ToolSvc += StaticExtrapolator + + # call the base class constructor + ExEngine.__init__(self, name=nameprefix+'Extrapolation',\ + ExtrapolationEngines = [ StaticExtrapolator ], \ + TrackingGeometrySvc = AtlasTrackingGeometrySvc, \ + OutputPrefix = '[ME] - ', \ + OutputPostfix = ' - ') + # set the output level + if ToolOutputLevel : + self.OutputLevel = ToolOutputLevel diff --git a/Tracking/TrkExtrapolation/TrkExEngine/python/__init__.py b/Tracking/TrkExtrapolation/TrkExEngine/python/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74583d364ec2ca794156596c7254d9b234a940c6 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/python/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d8d583f569c02f95eff87752059d52a76600d351 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx @@ -0,0 +1,111 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ExtrapolationEngine.cxx, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +// STL +#include <sstream> +// Trk include +#include "TrkExEngine/ExtrapolationEngine.h" +#include "TrkDetDescrUtils/GeometrySignature.h" + +// constructor +Trk::ExtrapolationEngine::ExtrapolationEngine(const std::string& t, const std::string& n, const IInterface* p) +: AthAlgTool(t,n,p), + m_trackingGeometry(0), + m_trackingGeometrySvc("AtlasTrackingGeometrySvc", n), + m_trackingGeometryName("AtlasTrackingGeometry"), + m_forceSearchInit(false) +{ + declareInterface<Trk::IExtrapolationEngine>(this); + + // Geometry retrieval + declareProperty("TrackingGeometrySvc" , m_trackingGeometrySvc); + // Extrapolation Engine retrieval + declareProperty("ExtrapolationEngines" , m_extrapolationEngines); + // Material Updator Engine retrival + + // steering of the screen outoput (SOP) + declareProperty("OutputPrefix" , m_sopPrefix); + declareProperty("OutputPostfix" , m_sopPostfix); + // the properties to be given + declareProperty("ForceSearchAtInit" , m_forceSearchInit); +} + +// destructor +Trk::ExtrapolationEngine::~ExtrapolationEngine() +{} + + +// the interface method initialize +StatusCode Trk::ExtrapolationEngine::initialize() +{ + + + EX_MSG_INFO( "init", " starting initialize()" ); + + // get the TrackingGeometrySvc + if (m_trackingGeometrySvc.retrieve().isSuccess()){ + EX_MSG_INFO( "init", "Successfully retrieved " << m_trackingGeometrySvc ); + m_trackingGeometryName = m_trackingGeometrySvc->trackingGeometryName(); + } else { + EX_MSG_WARNING( "init", "Couldn't retrieve " << m_trackingGeometrySvc << ". " ); + EX_MSG_WARNING( "init", " -> Trying to retrieve default '" << m_trackingGeometryName << "' from DetectorStore. Abort." ); + return StatusCode::FAILURE; + } + + // retrieve the ExtrapolationEngines + if (m_extrapolationEngines.retrieve().isFailure()){ + + } else { + EX_MSG_INFO( "init", "Successfully retrieved " << m_extrapolationEngines.size() << " ExtrapolationEngines. Ordering them now." ); + m_eeAccessor = std::vector<const Trk::IExtrapolationEngine*>(int(Trk::NumberOfGeometryTypes), (const Trk::IExtrapolationEngine*)NULL); + for (auto& ee : m_extrapolationEngines){ + EX_MSG_DEBUG( "init", "Registering " << ee->name() << " - for GeometryType : " << ee->geometryType() ); + m_eeAccessor[ee->geometryType()] = (&*ee); + } + } + + + + return StatusCode::SUCCESS; +} + +// the interface method finalize +StatusCode Trk::ExtrapolationEngine::finalize() +{ + EX_MSG_INFO( "fini", "finalize() successful" ); + return StatusCode::SUCCESS; +} + + +/** charged extrapolation */ +Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolate(ExCellCharged& ecCharged, + const Surface* sf, + PropDirection dir, + BoundaryCheck bcheck) const +{ return extrapolateT<TrackParameters>(ecCharged,sf,dir,bcheck); } + + +/** neutral extrapolation */ +Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolate(ExCellNeutral& ecNeutral, + const Surface* sf, + PropDirection dir, + BoundaryCheck bcheck) const +{ return extrapolateT<NeutralParameters>(ecNeutral,sf,dir,bcheck); } + + +StatusCode Trk::ExtrapolationEngine::updateTrackingGeometry() const { + // retrieve the TrackingGeometry from the detector store + if (detStore()->retrieve(m_trackingGeometry, m_trackingGeometryName).isFailure()){ + EX_MSG_FATAL( "tgeo", "Could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." ); + EX_MSG_FATAL( "tgeo", " - probably the chosen layout is not supported / no cool tag exists. " ); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..158cd4dc8a71457b49dac7f470b55af3b11734cb --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx @@ -0,0 +1,145 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// MaterialEffectsEngine.cxx, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +// STL +#include <sstream> +// Trk include +#include "TrkExEngine/MaterialEffectsEngine.h" +#include "TrkGeometry/Layer.h" + +// constructor +Trk::MaterialEffectsEngine::MaterialEffectsEngine(const std::string& t, const std::string& n, const IInterface* p) +: AthAlgTool(t,n,p) +{ + declareInterface<Trk::IMaterialEffectsEngine>(this); + // steering of the screen outoput (SOP) + declareProperty("OutputPrefix" , m_sopPrefix); + declareProperty("OutputPostfix" , m_sopPostfix); +} + +// destructor +Trk::MaterialEffectsEngine::~MaterialEffectsEngine() +{} + + +// the interface method initialize +StatusCode Trk::MaterialEffectsEngine::initialize() +{ + EX_MSG_INFO( "init", " starting initialize()" ); + return StatusCode::SUCCESS; +} + +// the interface method finalize +StatusCode Trk::MaterialEffectsEngine::finalize() +{ + EX_MSG_INFO( "fini", "finalize() successful" ); + return StatusCode::SUCCESS; +} + + +/** charged extrapolation */ +Trk::ExtrapolationCode Trk::MaterialEffectsEngine::handleMaterial(Trk::ExCellCharged& eCell, + Trk::PropDirection dir, + Trk::MaterialUpdateStage matupstage) const +{ + + // the Extrapolator made sure that the layer is the lead layer && the parameters are the lead parameters + if (eCell.leadLayer && eCell.leadLayer->layerMaterialProperties()){ + EX_MSG_DEBUG(++eCell.navigationStep, "handleMaterial for charged TrackParameters called."); + // update the track parameters + eCell.leadParameters = updateTrackParameters(*eCell.leadParameters,eCell,dir,matupstage); + } + return Trk::ExtrapolationCode::InProgress; +} + +/** charged extrapolation */ +const Trk::TrackParameters* Trk::MaterialEffectsEngine::updateTrackParameters(const Trk::TrackParameters& parameters, + Trk::ExCellCharged& eCell, + Trk::PropDirection dir, + Trk::MaterialUpdateStage matupstage) const +{ + // now calculate the pathCorrection from the layer surface - it is signed, gives you the relative direction to the layer + const Trk::Layer* layer = eCell.leadLayer; + // path correction + double pathCorrection = layer->surfaceRepresentation().pathCorrection(parameters.position(),dir*(parameters.momentum())); + // the relative direction wrt with the layer + Trk::PropDirection rlDir = (pathCorrection > 0. ? Trk::alongMomentum : Trk::oppositeMomentum); + // multiply by the pre-and post-update factor + double mFactor = layer->layerMaterialProperties()->factor(rlDir, matupstage); + if (mFactor == 0.){ + EX_MSG_VERBOSE(eCell.navigationStep, "material update with pre/post update factor 0. No update done."); + // return the parameters untouched - + return (¶meters); + } + pathCorrection = mFactor*pathCorrection; + // screen output + EX_MSG_VERBOSE(eCell.navigationStep, "material update on layer with index " << layer->layerIndex().value() << " - corr factor = " << pathCorrection); + // get the actual material bin + const Trk::MaterialProperties* materialProperties = layer->layerMaterialProperties()->fullMaterial(parameters.position()); + // and let's check if there's acutally something to do + if (materialProperties){ + // a simple cross-check if the parameters are the initial ones + AmgVector(5) uParameters = parameters.parameters(); + AmgSymMatrix(5)* uCovariance = parameters.covariance() ? new AmgSymMatrix(5)(*parameters.covariance()) : 0; + // get the material itself & its parameters + const Trk::Material& material = materialProperties->material(); + double thicknessInX0 = materialProperties->thicknessInX0(); + double thickness = materialProperties->thickness(); + // calculate energy loss and multiple scattering + double p = parameters.momentum().mag(); + double m = m_particleMasses.mass[eCell.pHypothesis]; + double E = sqrt(p*p+m*m); + double beta = p/E; + double sigmaP = 0.; + double kazL = 0.; + /** dE/dl ionization energy loss per path unit */ + double dEdX = m_interactionFormulae.dEdl_ionization(p, &material, eCell.pHypothesis, sigmaP, kazL); + double dE = dEdX*thickness*pathCorrection; + // calcuate the new momentum + double newP = sqrt((E+dE)*(E+dE)-m*m); + uParameters[Trk::qOverP] = parameters.charge()/newP; + // @TODO add straggling + + // update the covariance if needed + if (uCovariance){ + /** multiple scattering as function of dInX0 */ + double sigmaMS = m_interactionFormulae.sigmaMS(thicknessInX0*pathCorrection, p, beta); + double sinTheta = sin(parameters.parameters()[Trk::theta]); + double sigmaDeltaPhiSq = sigmaMS*sigmaMS/(sinTheta*sinTheta); + double sigmaDeltaThetaSq = sigmaMS*sigmaMS; + // and add them + int sign = int(eCell.materialUpdateMode); + // add or remove @TODO implement check for covariance matrix -> 0 + (*uCovariance)(Trk::phi,Trk::phi) += sign*sigmaDeltaPhiSq; + (*uCovariance)(Trk::theta, Trk::theta) += sign*sigmaDeltaThetaSq; + } + // check if material filling was requested + if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectMaterial)){ + EX_MSG_VERBOSE(eCell.navigationStep, "collecting material at layer " << layer->layerIndex().value() << " of - t/X0 = " << thicknessInX0); + eCell.stepMaterial(parameters.associatedSurface(), layer, parameters.position(), pathCorrection, materialProperties); + } + // now either create new ones or update - only start parameters can not be updated + if (eCell.leadParameters != eCell.startParameters ){ + EX_MSG_VERBOSE(eCell.navigationStep, "material update on non-initial parameters."); + parameters.updateParameters(uParameters,uCovariance); + } else { + EX_MSG_VERBOSE(eCell.navigationStep, "material update on initial parameters, creating new ones."); + // create new parameters + const Trk::Surface& tSurface = parameters.associatedSurface(); + const Trk::TrackParameters* tParameters = tSurface.createTrackParameters(uParameters[Trk::loc1], + uParameters[Trk::loc2], + uParameters[Trk::phi], + uParameters[Trk::theta], + uParameters[Trk::qOverP], + uCovariance); + // these are newly created + return tParameters; + } + } + return (¶meters); +} diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..87973d6a19e9ee0eff9aed4e95f6fd818bacb65f --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx @@ -0,0 +1,164 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PropagationEngine.cxx, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +// STL +#include <sstream> +// Trk include +#include "TrkExEngine/PropagationEngine.h" +#include "TrkExInterfaces/IPropagator.h" +#include "TrkSurfaces/Surface.h" + +// constructor +Trk::PropagationEngine::PropagationEngine(const std::string& t, const std::string& n, const IInterface* p) +: AthAlgTool(t,n,p), + m_propagator(""), + m_pathLimitTolerance(0.01) +{ + declareInterface<Trk::IPropagationEngine>(this); + // configure the Propagator + declareProperty("Propagator" , m_propagator); + // steering of the screen outoput (SOP) + declareProperty("OutputPrefix" , m_sopPrefix); + declareProperty("OutputPostfix" , m_sopPostfix); + // the path limit tolerance + declareProperty("PathLimitTolerance" , m_pathLimitTolerance); +} + +// destructor +Trk::PropagationEngine::~PropagationEngine() +{} + + +// the interface method initialize +StatusCode Trk::PropagationEngine::initialize() +{ + + if (m_propagator.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve propagator '"<< m_propagator << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully retrieved '" << m_propagator << "'." ); + + EX_MSG_INFO( "init", "initialize() successful" ); + return StatusCode::SUCCESS; +} + +// the interface method finalize +StatusCode Trk::PropagationEngine::finalize() +{ + EX_MSG_INFO( "fini", "finalize() successful" ); + return StatusCode::SUCCESS; +} + + +/** resolve the boundary situation - for charged particles */ +Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellCharged& eCell, + const Trk::Surface& sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck, + bool returnCurvilinear) const +{ + EX_MSG_DEBUG(++eCell.navigationStep, "propagation engine called with charged parameters with propagation direciton " << pDir ); + + double propLength = -1.; + if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopWithPathLimit)){ + // the path limit + propLength = eCell.pathLimit > 0 ? (eCell.pathLimit-eCell.pathLength) : eCell.pathLimit; + EX_MSG_VERBOSE(eCell.navigationStep, "available step length for this propagation " << propLength ); + } + // it is the final propagation if it is the endSurface + bool finalPropagation = (eCell.endSurface == (&sf)); + // + Trk::TransportJacobian* tjac = 0; + // we need to first fill the propagation parameters in order to be able to updates & fallbacks + const Trk::TrackParameters* pParameters = m_propagator->propagate(*eCell.leadParameters, + sf, + pDir, + bcheck, + eCell.mFieldMode, + tjac, + propLength, + eCell.pHypothesis, + returnCurvilinear); + // set the return type according to how the propagation went + if (pParameters){ + // assign the lead and end parameters + eCell.leadParameters = pParameters; + // check what to do with the path Length + if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopWithPathLimit) || propLength > 0){ + // add the new propagation length to the path length + eCell.pathLength += propLength; + // check if Limit reached + if (eCell.pathLimitReached(m_pathLimitTolerance)){ + EX_MSG_VERBOSE(eCell.navigationStep, "path limit of " << eCell.pathLimit << " successfully reached -> stopping." ); + return Trk::ExtrapolationCode::SuccessPathLimit; + } + } + // return Success only if it is the final propagation - the extrapolation engine knows that + return (finalPropagation ? Trk::ExtrapolationCode::SuccessDestination : Trk::ExtrapolationCode::InProgress); + } + // return - recovered means that the leadParameters are the input ones + return (finalPropagation ? Trk::ExtrapolationCode::FailureDestination : Trk::ExtrapolationCode::Recovered) ; +} + +/** resolve the boundary situation - for neutral particles */ +Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellNeutral& eCell, + const Trk::Surface& sf, + Trk::PropDirection pDir, + Trk::BoundaryCheck bcheck, + bool returnCurvilinear) const +{ + EX_MSG_DEBUG(++eCell.navigationStep, "propagation engine called with neutral parameters with propagation direciton " << pDir ); + // leave this for the moment, can re replaced by an appropriate propagator call later + if (eCell.leadParameters->covariance()){ + EX_MSG_VERBOSE(eCell.navigationStep, "propagation of neutral parameters with covariances requested. This is not supported for the moment."); + } + // the pathLimit cache so far + double cPath = eCell.pathLength; + // it is the final propagation if it is the endSurface + bool finalPropagation = (eCell.endSurface == (&sf)); + // intersect the surface + Trk::Intersection sfIntersection = pDir ? sf.straightLineIntersection(eCell.leadParameters->position(), + pDir*eCell.leadParameters->momentum().unit(), + true, bcheck) : + sf.straightLineIntersection(eCell.leadParameters->position(), + eCell.leadParameters->momentum().unit(), + false, bcheck); + // we have a valid intersection + if (sfIntersection.valid){ + // fill the transport information - only if the propation direction is not 0 + if (pDir){ + double pLength = (sfIntersection.position-eCell.leadParameters->position()).mag(); + EX_MSG_VERBOSE(eCell.navigationStep, "Path length of " << pLength << " added to the extrapolation cell (limit = " << eCell.pathLimit << ")" ); + eCell.stepTransport(sf,pLength); + } + // now check if it is valud it's further away than the pathLimit + if (eCell.pathLimitReached(m_pathLimitTolerance)){ + // create new neutral curvilinear parameters at the path limit reached + double pDiff = eCell.pathLimit - cPath; + eCell.leadParameters = new Trk::NeutralCurvilinearParameters(eCell.leadParameters->position()+pDiff*eCell.leadParameters->momentum().unit(), + eCell.leadParameters->momentum(), + 0.); + EX_MSG_VERBOSE(eCell.navigationStep, "path limit of " << eCell.pathLimit << " reached. Stopping extrapolation."); + return Trk::ExtrapolationCode::SuccessPathLimit; + } + // now exchange the lead parameters + // create the new curvilinear paramters at the surface intersection -> if so, trigger the success + eCell.leadParameters = returnCurvilinear ? new Trk::NeutralCurvilinearParameters(sfIntersection.position, eCell.leadParameters->momentum(), 0.) : + sf.createNeutralParameters(sfIntersection.position, eCell.leadParameters->momentum(), 0.); + + // return success for the final destination or in progress + return (finalPropagation ? Trk::ExtrapolationCode::SuccessDestination : Trk::ExtrapolationCode::InProgress); + + } else { + // give some screen output + EX_MSG_VERBOSE(eCell.navigationStep, "intersection with the surface did not succeed."); + } + // return - recovered means that the leadParameters are the input ones + return (finalPropagation ? Trk::ExtrapolationCode::FailureDestination : Trk::ExtrapolationCode::Recovered) ; +} diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7a8b90113f05c1f65a4361505a10238435f78a99 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx @@ -0,0 +1,84 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticEngine.cxx, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +// STL +#include <sstream> +// Trk include +#include "TrkExEngine/StaticEngine.h" + +// constructor +Trk::StaticEngine::StaticEngine(const std::string& t, const std::string& n, const IInterface* p) +: AthAlgTool(t,n,p), + m_propagationEngine(""), + m_navigationEngine(""), + m_materialEffectsEngine("") +{ + declareInterface<Trk::IExtrapolationEngine>(this); + // The Tools needed + declareProperty("PropagationEngine" , m_propagationEngine); + declareProperty("NavigationEngine" , m_navigationEngine); + declareProperty("MaterialEffectsEngine" , m_materialEffectsEngine); + // steering of the screen outoput (SOP) + declareProperty("OutputPrefix" , m_sopPrefix); + declareProperty("OutputPostfix" , m_sopPostfix); +} + +// destructor +Trk::StaticEngine::~StaticEngine() +{} + + +// the interface method initialize +StatusCode Trk::StaticEngine::initialize() +{ + EX_MSG_INFO( "init", "initialize()" ); + + if (m_propagationEngine.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully propagation engine '" << m_propagationEngine << "'." ); + + if (m_navigationEngine.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve navigation engine '"<< m_navigationEngine << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully retrieved '" << m_navigationEngine << "'." ); + + if (m_materialEffectsEngine.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully retrieved '" << m_materialEffectsEngine << "'." ); + + return StatusCode::SUCCESS; +} + +// the interface method finalize +StatusCode Trk::StaticEngine::finalize() +{ + ATH_MSG_INFO( "finalize() successful" ); + return StatusCode::SUCCESS; +} + + +/** charged extrapolation */ +Trk::ExtrapolationCode Trk::StaticEngine::extrapolate(ExCellCharged& ecCharged, + const Surface* sf, + PropDirection dir, + BoundaryCheck bcheck) const +{ return extrapolateT<TrackParameters>(ecCharged,sf,dir,bcheck); } + + +/** neutral extrapolation */ +Trk::ExtrapolationCode Trk::StaticEngine::extrapolate(ExCellNeutral& ecNeutral, + const Surface* sf, + PropDirection dir, + BoundaryCheck bcheck) const +{ return extrapolateT<NeutralParameters>(ecNeutral,sf,dir,bcheck); } + \ No newline at end of file diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..685aa5ccc6549a7a3769d2602ed03e1532160d2b --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx @@ -0,0 +1,82 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// StaticNavigationEngine.cxx, (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +// STL +#include <sstream> +// Trk include +#include "TrkExEngine/StaticNavigationEngine.h" + +// constructor +Trk::StaticNavigationEngine::StaticNavigationEngine(const std::string& t, const std::string& n, const IInterface* p) +: AthAlgTool(t,n,p), + m_propagationEngine(""), + m_materialEffectsEngine(""), + m_trackingGeometry(0), + m_trackingGeometryName("AtlasTrackingGeometry") + +{ + declareInterface<Trk::INavigationEngine>(this); + // Tools needed + declareProperty("PropagationEngine" , m_propagationEngine); + declareProperty("MaterialEffectsEngine" , m_materialEffectsEngine); + // The TrackingGeometry + declareProperty("TrackingGeometry" , m_trackingGeometryName); + // steering of the screen outoput (SOP) + declareProperty("OutputPrefix" , m_sopPrefix); + declareProperty("OutputPostfix" , m_sopPostfix); +} + +// destructor +Trk::StaticNavigationEngine::~StaticNavigationEngine() +{} + +// the interface method initialize +StatusCode Trk::StaticNavigationEngine::initialize() +{ + EX_MSG_INFO( "init", "initialize()" ); + + if (m_propagationEngine.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully retrieved '" << m_propagationEngine << "'." ); + + if (m_materialEffectsEngine.retrieve().isFailure()){ + EX_MSG_FATAL( "init", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." ); + return StatusCode::FAILURE; + } else + EX_MSG_INFO( "init", "successfully retrieved '" << m_materialEffectsEngine << "'." ); + + return StatusCode::SUCCESS; +} + +// the interface method finalize +StatusCode Trk::StaticNavigationEngine::finalize() +{ + ATH_MSG_INFO( "finalize() successful" ); + return StatusCode::SUCCESS; +} + +/** charged situation */ +Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBoundary(Trk::ExCellCharged& ecCharged, PropDirection dir) const +{ return resolveBoundaryT<Trk::TrackParameters>(ecCharged,dir); } + +/** charged situation */ +Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBoundary(Trk::ExCellNeutral& ecNeutral, PropDirection dir) const +{ return resolveBoundaryT<Trk::NeutralParameters>(ecNeutral,dir); } + +StatusCode Trk::StaticNavigationEngine::updateTrackingGeometry() const { + // retrieve the TrackingGeometry from the detector store + if (detStore()->retrieve(m_trackingGeometry, m_trackingGeometryName).isFailure()){ + EX_MSG_FATAL( "tgeo", "Could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." ); + EX_MSG_FATAL( "tgeo", " - probably the chosen layout is not supported / no cool tag exists. " ); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_entries.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..315bf68aaa445b3b6e890031898bdef6b327acb3 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_entries.cxx @@ -0,0 +1,26 @@ +#include "GaudiKernel/DeclareFactoryEntries.h" +#include "TrkExEngine/ExtrapolationEngine.h" +#include "TrkExEngine/StaticEngine.h" +#include "TrkExEngine/StaticNavigationEngine.h" +#include "TrkExEngine/MaterialEffectsEngine.h" +#include "TrkExEngine/PropagationEngine.h" + +using namespace Trk; + +DECLARE_TOOL_FACTORY( ExtrapolationEngine ) +DECLARE_TOOL_FACTORY( MaterialEffectsEngine ) +DECLARE_TOOL_FACTORY( StaticEngine ) +DECLARE_TOOL_FACTORY( StaticNavigationEngine ) +DECLARE_TOOL_FACTORY( PropagationEngine ) + +/** factory entries need to have the name of the package */ +DECLARE_FACTORY_ENTRIES( TrkExEngine ) +{ + DECLARE_TOOL( ExtrapolationEngine ) + DECLARE_TOOL( MaterialEffectsEngine ) + DECLARE_TOOL( StaticEngine ) + DECLARE_TOOL( StaticNavigationEngine ) + DECLARE_TOOL( PropagationEngine ) +} + + diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_load.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_load.cxx new file mode 100755 index 0000000000000000000000000000000000000000..563e2d8a5549da993596bbb0c212d350ff499269 --- /dev/null +++ b/Tracking/TrkExtrapolation/TrkExEngine/src/components/TrkExEngine_load.cxx @@ -0,0 +1,4 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES( TrkExEngine ) +