diff --git a/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py b/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py index 433a8c7a9ed6628e9f9c126cab646262aaf6abe2..99383e9fc4691910df6388e9598cc7969e0a9354 100644 --- a/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py +++ b/InnerDetector/InDetExample/InDetRecExample/python/TrackingCommon.py @@ -654,8 +654,8 @@ def getInDetGsfMaterialUpdator(name='InDetGsfMaterialUpdator', **kwargs) : if 'MaximumNumberOfComponents' not in kwargs : kwargs=setDefaults(kwargs, MaximumNumberOfComponents = 12) - from TrkGaussianSumFilter.TrkGaussianSumFilterConf import Trk__GsfMaterialMixtureConvolution - return Trk__GsfMaterialMixtureConvolution (name = the_name, **kwargs) + from TrkGaussianSumFilter.TrkGaussianSumFilterConf import Trk__GsfMaterialMixtureConvolutionLM + return Trk__GsfMaterialMixtureConvolutionLM (name = the_name, **kwargs) @makePublicTool diff --git a/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py b/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py index 7987f21044b4cdb9b945dc5e4612f937d221445b..38558de3029b17ce906dfb2b75175ed733496a56 100755 --- a/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py +++ b/InnerDetector/InDetExample/InDetRecExample/share/InDetRec_jobOptions.py @@ -928,19 +928,20 @@ else: # InDetTruthTrackCreation.OutputLevel = VERBOSE topSequence += InDetTruthTrackCreation - # --- add the truth to the truth tracks ;-) - include ("InDetRecExample/ConfiguredInDetTrackTruth.py") - InDetTracksTruth = ConfiguredInDetTrackTruth(InDetKeys.PseudoTracks(), + if InDetFlags.doSplitReco() : + # --- add the truth to the truth tracks ;-) + include ("InDetRecExample/ConfiguredInDetTrackTruth.py") + InDetTracksTruth = ConfiguredInDetTrackTruth(InDetKeys.PseudoTracks(), InDetKeys.PseudoDetailedTracksTruth(), InDetKeys.PseudoTracksTruth(), PixelClusterTruth, SCT_ClusterTruth, TRT_DriftCircleTruth) - from TrkTruthToTrack.TrkTruthToTrackConf import Trk__TruthToTrack - InDetTruthToTrack = Trk__TruthToTrack(name = "InDetTruthToTrack", + from TrkTruthToTrack.TrkTruthToTrackConf import Trk__TruthToTrack + InDetTruthToTrack = Trk__TruthToTrack(name = "InDetTruthToTrack", Extrapolator = TrackingCommon.getInDetExtrapolator()) - ToolSvc += InDetTruthToTrack + ToolSvc += InDetTruthToTrack # Register the track collections for further processing - only if new tracking has not been running if not InDetFlags.doNewTracking(): diff --git a/InnerDetector/InDetTruth/InDetTruthTools/src/PRD_TruthTrajectorySelectorID.cxx b/InnerDetector/InDetTruth/InDetTruthTools/src/PRD_TruthTrajectorySelectorID.cxx index 80e7bb29a1c0a517aae60229a2d15455b44c5244..b3ab20ab83ed414a798e9c53a1a7451e46491208 100644 --- a/InnerDetector/InDetTruth/InDetTruthTools/src/PRD_TruthTrajectorySelectorID.cxx +++ b/InnerDetector/InDetTruth/InDetTruthTools/src/PRD_TruthTrajectorySelectorID.cxx @@ -140,16 +140,24 @@ bool InDet::PRD_TruthTrajectorySelectorID::pass( const Trk::PRD_TruthTrajectory for ( int i = 0; i < 3 && prdIter != prdIterE; ++ prdIter ){ if( m_atlasId->is_pixel((*prdIter)->identify()) ){ const InDet::PixelCluster* pixclus=dynamic_cast<const InDet::PixelCluster*>(*prdIter); - if (pixclus) pos.push_back (pixclus->globalPosition()); + if (pixclus) { + if(!pos.empty() && (pos.back()-pixclus->globalPosition()).squaredNorm() < 9) + continue; + pos.push_back (pixclus->globalPosition()); + } } else if( m_atlasId->is_sct((*prdIter)->identify()) ){ - const InDet::SCT_Cluster* sctclus=dynamic_cast<const InDet::SCT_Cluster*>(*prdIter); - if (sctclus) pos.push_back (sctclus->globalPosition()); + const InDet::SCT_Cluster* sctclus=dynamic_cast<const InDet::SCT_Cluster*>(*prdIter); + if (sctclus) { + if(!pos.empty() && (pos.back()-sctclus->globalPosition()).squaredNorm() < 9) + continue; + pos.push_back (sctclus->globalPosition()); + } } else if( m_atlasId->is_trt((*prdIter)->identify()) ){ - continue; + continue; } - i++; + i++; } // only take trajectory if enough hits diff --git a/Reconstruction/egamma/egammaRec/python/EMCommonRefitter.py b/Reconstruction/egamma/egammaRec/python/EMCommonRefitter.py index da9368ef829acb9f176dcbe44ebb57fa003aeaa6..e4188ae5d8794c62b881eff6846aca05607bafad 100644 --- a/Reconstruction/egamma/egammaRec/python/EMCommonRefitter.py +++ b/Reconstruction/egamma/egammaRec/python/EMCommonRefitter.py @@ -32,9 +32,9 @@ def getGSFTrackFitter(): # Set up the GSF from TrkGaussianSumFilter.TrkGaussianSumFilterConf import ( - Trk__GsfMaterialMixtureConvolution) + Trk__GsfMaterialMixtureConvolutionLM) - GsfMaterialUpdator = Trk__GsfMaterialMixtureConvolution(name='GsfMaterialUpdator',MaximumNumberOfComponents=12) + GsfMaterialUpdator = Trk__GsfMaterialMixtureConvolutionLM(name='GsfMaterialUpdator',MaximumNumberOfComponents=12) from TrkGaussianSumFilter.TrkGaussianSumFilterConf import ( Trk__GsfExtrapolator) diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/AlignedDynArray.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/AlignedDynArray.h index 5809bbd07bcaac4f9a2d9c8e223f21bfb71949e8..a833fe39d9a1ccb6765c5bb640fc67ea7682567a 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/AlignedDynArray.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/AlignedDynArray.h @@ -61,6 +61,12 @@ public: /// size of allocated buffer std::size_t size() const noexcept; + + typedef T* iterator; + typedef const T* const_iterator; + iterator begin() { return &m_buffer[0]; } + iterator end() { return &m_buffer[m_size]; } + private: void cleanup() noexcept; T* m_buffer = nullptr; diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/ForwardGsfFitter.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/ForwardGsfFitter.h index 38c10489cb58010da2a3a679283feff3a239cce1..c7c912a05008a0e92f6e259e95ede834a2e75cad 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/ForwardGsfFitter.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/ForwardGsfFitter.h @@ -15,6 +15,7 @@ #include "TrkEventPrimitives/ParticleHypothesis.h" #include "TrkFitterUtils/FitterTypes.h" #include "TrkGaussianSumFilter/IForwardGsfFitter.h" +#include "TrkGaussianSumFilter/IMultiStateExtrapolator.h" #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" #include "TrkParameters/TrackParameters.h" @@ -24,7 +25,6 @@ namespace Trk { class IMultiStateMeasurementUpdator; -class IMultiStateExtrapolator; class IRIO_OnTrackCreator; class Surface; @@ -58,6 +58,7 @@ public: /** Forward GSF fit using PrepRawData */ virtual std::unique_ptr<ForwardTrajectory> fitPRD( const EventContext& ctx, + IMultiStateExtrapolator::Cache&, const PrepRawDataSet&, const TrackParameters&, const ParticleHypothesis particleHypothesis = @@ -66,6 +67,7 @@ public: /** Forward GSF fit using MeasurementSet */ virtual std::unique_ptr<ForwardTrajectory> fitMeasurements( const EventContext& ctx, + IMultiStateExtrapolator::Cache&, const MeasurementSet&, const TrackParameters&, const ParticleHypothesis particleHypothesis = @@ -78,6 +80,7 @@ private: /** Progress one step along the fit */ bool stepForwardFit( const EventContext& ctx, + IMultiStateExtrapolator::Cache&, ForwardTrajectory*, const PrepRawData*, const MeasurementBase*, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GaussianSumFitter.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GaussianSumFitter.h index 160dcea5aa5e442f31e82db531a4a802871c9989..6fc9d21ce6e9c1c2f8b08f2f2d9a419529028a4a 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GaussianSumFitter.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GaussianSumFitter.h @@ -12,6 +12,7 @@ #include "TrkEventPrimitives/PropDirection.h" #include "TrkEventUtils/TrkParametersComparisonFunction.h" #include "TrkFitterInterfaces/ITrackFitter.h" +#include "TrkGaussianSumFilter/IMultiStateExtrapolator.h" #include "TrkFitterUtils/FitterTypes.h" #include "TrkParameters/TrackParameters.h" #include "TrkFitterUtils/TrackFitInputPreparator.h" @@ -28,7 +29,6 @@ namespace Trk { class IMultiStateMeasurementUpdator; class MultiComponentStateOnSurface; -class IMultiStateExtrapolator; class IForwardGsfFitter; class IGsfSmoother; class FitQuality; @@ -115,6 +115,7 @@ private: /** Produces a perigee from a smoothed trajectory */ const MultiComponentStateOnSurface* makePerigee( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache&, const SmoothedTrajectory*, const ParticleHypothesis particleHypothesis = nonInteracting) const; @@ -150,7 +151,14 @@ private: "GsfSmoother", "Trk::GsfSmoother/GsfSmoother", "" }; - + + Gaudi::Property<bool> m_StoreMCSOS{ + this, + "StoreMCSOS", + false, + "Store multicomponent state or single state in final trajectory" + }; + bool m_reintegrateOutliers; bool m_makePerigee; bool m_refitOnMeasurementBase; @@ -173,6 +181,10 @@ private: mutable std::atomic<int> m_PerigeeFailure; // Number of Tracks that fail fit Quailty test mutable std::atomic<int> m_fitQualityFailure; + // Number of Tracks that are successfull + mutable std::atomic<int> m_fitSuccess; + + }; } // end Trk namespace diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfExtrapolator.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfExtrapolator.h index 350e84992f3e16b8bc0299d7cf7a4b39ea44fc84..8db31e2430a36034a5fa861ef841bc2f2ec40fa9 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfExtrapolator.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfExtrapolator.h @@ -19,6 +19,7 @@ #include "TrkExInterfaces/INavigator.h" #include "TrkExInterfaces/IPropagator.h" #include "TrkGaussianSumFilter/IMultiStateExtrapolator.h" +#include "TrkGaussianSumFilter/IMultiStateMaterialEffects.h" #include "AthenaBaseComps/AthAlgTool.h" #include "GaudiKernel/IChronoStatSvc.h" @@ -45,37 +46,6 @@ class MaterialProperties; class IMultiComponentStateMerger; class IMaterialMixtureConvolution; class IMultipleScatteringUpdator; -/** @struct StateAtBoundarySurface - - Structure to contain information about a state at the interface between - tracking volumes - */ - -struct StateAtBoundarySurface -{ - - /** Data members */ - const MultiComponentState* stateAtBoundary; - const TrackParameters* navigationParameters; - const TrackingVolume* trackingVolume; - - /** Default constructor */ - StateAtBoundarySurface() - : stateAtBoundary(nullptr) - , navigationParameters(nullptr) - , trackingVolume(nullptr) - {} - - /** Update State at Boundary Surface Information */ - void updateBoundaryInformation(const MultiComponentState* boundaryState, - const TrackParameters* navParameters, - const TrackingVolume* nextVolume) - { - stateAtBoundary = boundaryState; - navigationParameters = navParameters; - trackingVolume = nextVolume; - } -}; - /** @class GsfExtrapolator */ class GsfExtrapolator @@ -99,6 +69,7 @@ public: /** Configured AlgTool extrapolation method (1) */ virtual MultiComponentState extrapolate( const EventContext& ctx, + Cache&, const MultiComponentState&, const Surface&, PropDirection direction = anyDirection, @@ -125,33 +96,6 @@ public: ParticleHypothesis particle) const override final; private: - struct Cache - { - bool m_recall; //!< Flag the recall solution - const Surface* m_recallSurface; //!< Surface for recall - const Layer* m_recallLayer; //!< Layer for recall - const TrackingVolume* - m_recallTrackingVolume; //!< Tracking volume for recall - StateAtBoundarySurface - m_stateAtBoundarySurface; //!< Instance of structure describing the state - //!< at a boundary of tracking volumes - std::unique_ptr<std::vector<const Trk::TrackStateOnSurface*>> m_matstates; - std::vector<std::unique_ptr<const MultiComponentState>> - m_mcsGarbageBin; //!< Garbage bin for MultiComponentState objects - std::vector<std::unique_ptr<const TrackParameters>> - m_tpGarbageBin; //!< Garbage bin for TrackParameter objects - - Cache() - : m_recall(false) - , m_recallSurface(nullptr) - , m_recallLayer(nullptr) - , m_recallTrackingVolume(nullptr) - , m_stateAtBoundarySurface() - , m_matstates(nullptr) - , m_mcsGarbageBin() - , m_tpGarbageBin() - {} - }; /** These are the methods that do the actual heavy lifting when extrapolating * with a cache */ diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolution.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolution.h index 0c32a8a0c66221808eba97fb06c2371d76ef2415..65d4e5296cd14e1e7615df4077ffd23404a5b792 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolution.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolution.h @@ -44,21 +44,24 @@ public: virtual StatusCode finalize() override; //!< Convolution with full material properties - virtual MultiComponentState update(const MultiComponentState&, + virtual MultiComponentState update(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, ParticleHypothesis particleHypothesis = nonInteracting) const override final; //!< Convolution with pre-measurement-update material properties - virtual MultiComponentState preUpdate(const MultiComponentState&, + virtual MultiComponentState preUpdate(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, ParticleHypothesis particleHypothesis = nonInteracting) const override final; //!< Convolution with post-measurement-update material properties - virtual MultiComponentState postUpdate(const MultiComponentState&, + virtual MultiComponentState postUpdate(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, ParticleHypothesis particleHypothesis = diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolutionLM.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolutionLM.h new file mode 100644 index 0000000000000000000000000000000000000000..4611856669cdf962b39a5f1f664ba9b1fa9037d5 --- /dev/null +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfMaterialMixtureConvolutionLM.h @@ -0,0 +1,138 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @file GsfMaterialMixtureConvolutionLM.h + * @date Thursday 7th September 2006 + * @author Tom Athkinson, Anthony Morley, Christos Anastopoulos + * @brief Class description for convolution of GSF material mixture + */ + +#ifndef TrkGsfMaterialMixtureConvolutionLM_H +#define TrkGsfMaterialMixtureConvolutionLM_H + +#include "TrkGaussianSumFilter/IMaterialMixtureConvolution.h" +#include "TrkMultiComponentStateOnSurface/MultiComponentState.h" + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" + +namespace Trk { + +class IMultiStateMaterialEffectsUpdator; +class IMultiStateMaterialEffects; +class Layer; +class MaterialProperties; + +class GsfMaterialMixtureConvolutionLM + : public AthAlgTool + , virtual public IMaterialMixtureConvolution +{ + +public: + + enum MaterialUpdateType{ Normal = 0, Preupdate=1, Postupdate=2 }; + + //!< Constructor with AlgTool parameters + GsfMaterialMixtureConvolutionLM(const std::string&, + const std::string&, + const IInterface*); + + //!< Destructor + virtual ~GsfMaterialMixtureConvolutionLM(); + + //!< AlgTool initialise method + virtual StatusCode initialize() override; + + //!< AlgTool finalize method + virtual StatusCode finalize() override; + + //!< Convolution with full material properties + virtual MultiComponentState update(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, + const Layer&, + PropDirection direction = anyDirection, + ParticleHypothesis particleHypothesis = + nonInteracting) const override final; + + //!< Convolution with pre-measurement-update material properties + virtual MultiComponentState preUpdate(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, + const Layer&, + PropDirection direction = anyDirection, + ParticleHypothesis particleHypothesis = + nonInteracting) const override final; + + //!< Convolution with post-measurement-update material properties + virtual MultiComponentState postUpdate(std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const MultiComponentState&, + const Layer&, + PropDirection direction = anyDirection, + ParticleHypothesis particleHypothesis = + nonInteracting) const override final; + + //!< Retain for now redundant simplified material effects + virtual MultiComponentState simplifiedMaterialUpdate( + const MultiComponentState& , + PropDirection, + ParticleHypothesis) const override final { return {}; }; + + + private: + Gaudi::Property<unsigned int> m_maximumNumberOfComponents{ + this, + "MaximumNumberOfComponents", + 12, + "Maximum number of components" + }; + + ToolHandle<IMultiStateMaterialEffectsUpdator> m_updator{ + this, + "MaterialEffectsUpdator", + "Trk::GsfMaterialEffectsUpdator/GsfMaterialEffectsUpdator", + "" + }; + + ToolHandle<IMultiStateMaterialEffects> m_materialEffects{ + this, + "MaterialEffects", + "Trk::GsfCombinedMaterialEffects/GsfCombinedMaterialEffects", + "" + }; + + Gaudi::Property<bool> m_useReferenceMaterial{ + this, + "UseReferenceMaterial", + false, + "" + }; + + Gaudi::Property<double> m_momentumCut{ + this, + "MinimalMomentum", + 250. * Gaudi::Units::MeV, + "" + }; + + + Trk::MultiComponentState update( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, + const Trk::MultiComponentState& inputState, + const Trk::Layer& layer, + Trk::PropDirection direction, + Trk::ParticleHypothesis particleHypothesis, + MaterialUpdateType updateType) const; + + bool updateP(double& qOverP, double deltaP) const; + + std::pair< const Trk::MaterialProperties*, double > getMaterialProperties( + const Trk::TrackParameters* trackParameters, + const Trk::Layer& layer ) const; + + +}; + +} // end Trk namespace + +#endif diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfSmoother.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfSmoother.h index f7a363901c464eb4d9df90c6bbe09791d36783ac..615054c82b7fbf2d162d313f26cd53d1bc6c6e7c 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfSmoother.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/GsfSmoother.h @@ -54,6 +54,7 @@ public: /** Gsf smoother method */ virtual SmoothedTrajectory* fit( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache&, const ForwardTrajectory&, const ParticleHypothesis particleHypothesis = nonInteracting, const CaloCluster_OnTrack* ccot = nullptr) const; diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IForwardGsfFitter.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IForwardGsfFitter.h index ebc4bbd4c79144dd3670c40c46a966ac6ab82965..f514deb5402bd767c625b094b299494007814235 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IForwardGsfFitter.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IForwardGsfFitter.h @@ -18,6 +18,7 @@ #include "TrkEventPrimitives/ParticleHypothesis.h" #include "TrkFitterUtils/FitterTypes.h" #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" +#include "TrkGaussianSumFilter/IMultiStateExtrapolator.h" #include "TrkParameters/TrackParameters.h" #include "GaudiKernel/EventContext.h" @@ -25,7 +26,6 @@ namespace Trk { class IMultiStateMeasurementUpdator; -class IMultiStateExtrapolator; class IRIO_OnTrackCreator; class Surface; @@ -56,6 +56,7 @@ public: /** Forward GSF fit using PrepRawData */ virtual std::unique_ptr<ForwardTrajectory> fitPRD( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache&, const PrepRawDataSet&, const TrackParameters&, const ParticleHypothesis particleHypothesis = nonInteracting) const = 0; @@ -63,6 +64,7 @@ public: /** Forward GSF fit using MeasurementSet */ virtual std::unique_ptr<ForwardTrajectory> fitMeasurements( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache&, const MeasurementSet&, const TrackParameters&, const ParticleHypothesis particleHypothesis = nonInteracting) const = 0; diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IGsfSmoother.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IGsfSmoother.h index 2dbf97f0af0fd275c95e24983298a5174fb6d4ec..11ae1e16db27e39c95f90bd4cf7c9a80bd2643c0 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IGsfSmoother.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IGsfSmoother.h @@ -15,6 +15,7 @@ #include "TrkEventPrimitives/ParticleHypothesis.h" #include "TrkFitterUtils/FitterTypes.h" #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" +#include "TrkGaussianSumFilter/IMultiStateExtrapolator.h" #include "GaudiKernel/EventContext.h" #include "GaudiKernel/IAlgTool.h" @@ -23,7 +24,6 @@ namespace Trk { class IMultiStateMeasurementUpdator; -class IMultiStateExtrapolator; class CaloCluster_OnTrack; static const InterfaceID InterfaceID_GsfSmoother("GsfSmoother", 1, 0); @@ -48,6 +48,7 @@ public: /** Gsf smoother method */ virtual SmoothedTrajectory* fit( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache&, const ForwardTrajectory&, const ParticleHypothesis particleHypothesis = nonInteracting, const CaloCluster_OnTrack* ccot = nullptr) const = 0; diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMaterialMixtureConvolution.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMaterialMixtureConvolution.h index 10aa90246091ea06c7bc9e960995c57c660732c0..469b19c66019630148af1f0d72a00cad1739350b 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMaterialMixtureConvolution.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMaterialMixtureConvolution.h @@ -16,6 +16,7 @@ #include "TrkEventPrimitives/ParticleHypothesis.h" #include "TrkEventPrimitives/PropDirection.h" #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" +#include "TrkGaussianSumFilter/IMultiStateMaterialEffects.h" namespace Trk { class Layer; @@ -37,6 +38,7 @@ public: //!< Convolution with full material properties virtual MultiComponentState update( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, @@ -44,6 +46,7 @@ public: //!< Convolution with pre-measurement-update material properties virtual MultiComponentState preUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, @@ -51,6 +54,7 @@ public: //!< Convolution with post-measurement-update material properties virtual MultiComponentState postUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const MultiComponentState&, const Layer&, PropDirection direction = anyDirection, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateExtrapolator.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateExtrapolator.h index 42d6af11468a19e08fe38af862c45f7d12be79b3..d7e0a75b14615ed3233ec68643e91279fddb49f9 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateExtrapolator.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateExtrapolator.h @@ -14,6 +14,7 @@ #define TrkIMultiStateExtrapolator_H #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" +#include "TrkGaussianSumFilter/IMultiStateMaterialEffects.h" #include "TrkEventPrimitives/ParticleHypothesis.h" #include "TrkEventPrimitives/PropDirection.h" @@ -35,6 +36,32 @@ class Track; class TrackingVolume; class TrackStateOnSurface; +/** @struct StateAtBoundarySurface + - Structure to contain information about a state at the interface between + tracking volumes + */ + +struct StateAtBoundarySurface +{ + + /** Data members */ + const MultiComponentState* stateAtBoundary = nullptr; + const TrackParameters* navigationParameters = nullptr; + const TrackingVolume* trackingVolume = nullptr; + + + /** Update State at Boundary Surface Information */ + void updateBoundaryInformation(const MultiComponentState* boundaryState, + const TrackParameters* navParameters, + const TrackingVolume* nextVolume) + { + stateAtBoundary = boundaryState; + navigationParameters = navParameters; + trackingVolume = nextVolume; + } +}; + + static const InterfaceID IID_IMultiStateExtrapolator("IMultiStateExtrapolator", 1, 0); @@ -42,7 +69,52 @@ static const InterfaceID IID_IMultiStateExtrapolator("IMultiStateExtrapolator", class IMultiStateExtrapolator : virtual public IAlgTool { public: - /** Virtual destructor */ + /** @brief MultiStateExtrapolator cache class. + * This object holds information regarding the state of the extrpolation process + * as well as a large store for material effects properties. + * + * The is owned by the tools that call the extrapolatator (Currently the GSFSmoother or Forward fitter) + * and it not exposed to the caller of the track fitter. + * */ + struct Cache + { + bool m_recall = false; //!< Flag the recall solution + const Surface* m_recallSurface = nullptr; //!< Surface for recall + const Layer* m_recallLayer = nullptr; //!< Layer for recall + const TrackingVolume* + m_recallTrackingVolume = nullptr; //!< Tracking volume for recall + StateAtBoundarySurface + m_stateAtBoundarySurface; //!< Instance of structure describing the state + //!< at a boundary of tracking volumes + std::unique_ptr<std::vector<const Trk::TrackStateOnSurface*>> m_matstates; + std::vector<std::unique_ptr<const MultiComponentState>> + m_mcsGarbageBin; //!< Garbage bin for MultiComponentState objects + std::vector<std::unique_ptr<const TrackParameters>> + m_tpGarbageBin; //!< Garbage bin for TrackParameter objects + + std::vector<Trk::IMultiStateMaterialEffects::Cache> + m_materialEffectsCaches; //!< Large cache for material effects + + + Cache() + { + m_materialEffectsCaches.reserve(72); + } + + void reset(){ + m_recall = false; + m_recallSurface = nullptr; + m_recallLayer = nullptr; + m_recallTrackingVolume = nullptr; + m_matstates.reset(nullptr); + m_stateAtBoundarySurface.updateBoundaryInformation(nullptr,nullptr,nullptr); + m_mcsGarbageBin.clear(); + m_tpGarbageBin.clear(); + m_materialEffectsCaches.clear(); + }; + }; + + /** Virtual destructor */ virtual ~IMultiStateExtrapolator() = default; /** AlgTool interface method */ @@ -54,6 +126,7 @@ public: /** Configured AlgTool extrapolation method (1) */ virtual MultiComponentState extrapolate( const EventContext& ctx, + Cache&, const MultiComponentState&, const Surface&, PropDirection direction = anyDirection, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateMaterialEffects.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateMaterialEffects.h index 1d235b978b8dc370681aace97f95aad0e539e2e6..870ee67246dd40e7cba3c32a92608f3de439fb6b 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateMaterialEffects.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/IMultiStateMaterialEffects.h @@ -44,6 +44,7 @@ public: { weights.reserve(6); deltaPs.reserve(6); + deltaParameters.reserve(6); deltaCovariances.reserve(6); } Cache(Cache&&) = default; @@ -60,14 +61,29 @@ public: * "you must use the Eigen::aligned_allocator (not another aligned * allocator), and #include <Eigen/StdVector>." */ + std::vector<AmgVector(5),Eigen::aligned_allocator<AmgVector(5)>> + deltaParameters; std::vector<AmgSymMatrix(5), Eigen::aligned_allocator<AmgSymMatrix(5)>> deltaCovariances; void reset() { weights.clear(); deltaPs.clear(); + deltaParameters.clear(); deltaCovariances.clear(); } + void resetAndAddDummyValues() + { + reset(); + weights.push_back(1); + deltaPs.push_back(0); + AmgVector(5) newParameters; + newParameters.setZero(); + deltaParameters.push_back( std::move(newParameters) ); + AmgSymMatrix(5) newCovarianceMatrix; + newCovarianceMatrix.setZero(); + deltaCovariances.push_back( std::move(newCovarianceMatrix) ); + } }; /** Alg tool and IAlgTool interface method */ diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/MultiComponentStateCombiner.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/MultiComponentStateCombiner.h index d18a5aee90fa99f9e93538c75bb9cb0f31a6a7ad..95cd0d23d8a861652448da81a774ab4350f29a9d 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/MultiComponentStateCombiner.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/MultiComponentStateCombiner.h @@ -31,6 +31,26 @@ void combineWithWeight(Trk::ComponentParameters& mergeTo, const Trk::ComponentParameters& addThis); +/** @brief Combined/merge a component to the parts of another */ +void +combineWithWeight( Trk::ComponentParameters& mergeTo, + const AmgVector(5)& secondParameters, + const AmgSymMatrix(5)* secondMeasuredCov, + const double secondWeight ); + + +/** @brief Update first parameters */ +void combineParametersWithWeight( + AmgVector(5)& firstParameters, double& firstWeight, + const AmgVector(5)& secondParameters, const double secondWeight ); + +/** @brief Update cov matrix */ +void combineCovWithWeight( + const AmgVector(5)& firstParameters, AmgSymMatrix(5)& firstMeasuredCov, const double firstWeight, + const AmgVector(5)& secondParameters, const AmgSymMatrix(5)& secondMeasuredCov, const double secondWeight ); + + + /** @brief Calculate combined state and weight of many components */ std::unique_ptr<Trk::ComponentParameters> combineWithWeight(const MultiComponentState&, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/ForwardGsfFitter.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/ForwardGsfFitter.cxx index 12ab02457be411564eac4fe1300c78af4ee5336b..f317764a29d4be26782b557a60498cc62d6948e0 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/ForwardGsfFitter.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/ForwardGsfFitter.cxx @@ -91,6 +91,7 @@ Trk::ForwardGsfFitter::configureTools( std::unique_ptr<Trk::ForwardTrajectory> Trk::ForwardGsfFitter::fitPRD( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache& extrapolatorCache, const Trk::PrepRawDataSet& inputPrepRawDataSet, const Trk::TrackParameters& estimatedTrackParametersNearOrigin, const Trk::ParticleHypothesis particleHypothesis) const @@ -149,6 +150,7 @@ Trk::ForwardGsfFitter::fitPRD( // stepForwardFit method is updated bool stepIsValid = stepForwardFit( ctx, + extrapolatorCache, forwardTrajectory.get(), *prepRawData, nullptr, @@ -172,6 +174,7 @@ Trk::ForwardGsfFitter::fitPRD( std::unique_ptr<Trk::ForwardTrajectory> Trk::ForwardGsfFitter::fitMeasurements( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache& extrapolatorCache, const Trk::MeasurementSet& inputMeasurementSet, const Trk::TrackParameters& estimatedTrackParametersNearOrigin, const Trk::ParticleHypothesis particleHypothesis) const @@ -230,6 +233,7 @@ Trk::ForwardGsfFitter::fitMeasurements( for (; measurement != inputMeasurementSet.end(); ++measurement) { bool stepIsValid = stepForwardFit(ctx, + extrapolatorCache, forwardTrajectory.get(), nullptr, *measurement, @@ -252,6 +256,7 @@ Trk::ForwardGsfFitter::fitMeasurements( bool Trk::ForwardGsfFitter::stepForwardFit( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache& extrapolatorCache, ForwardTrajectory* forwardTrajectory, const Trk::PrepRawData* originalPrepRawData, const Trk::MeasurementBase* originalMeasurement, @@ -276,6 +281,7 @@ Trk::ForwardGsfFitter::stepForwardFit( // ================================================================= Trk::MultiComponentState extrapolatedState = m_extrapolator->extrapolate(ctx, + extrapolatorCache, updatedState, surface, Trk::alongMomentum, @@ -284,6 +290,8 @@ Trk::ForwardGsfFitter::stepForwardFit( if (extrapolatedState.empty()) { ATH_MSG_DEBUG("Extrapolation failed... returning false"); return false; + } else { + ATH_MSG_DEBUG("Extrapolation worked... state size: "<< extrapolatedState.size() ); } // ======================= // Measurement Preparation @@ -321,6 +329,8 @@ Trk::ForwardGsfFitter::stepForwardFit( if (updatedState.empty()) { ATH_MSG_DEBUG("Measurement update of the state failed... Exiting!"); return false; + } else { + ATH_MSG_DEBUG("Measurement update of the state worked : " << updatedState.size() ); } // Bail if the fit quality is not defined: if (!fitQuality) { diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GaussianSumFitter.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GaussianSumFitter.cxx index 618c26e733a173422b4b9232762e0a1275b14aa1..b2654163bd4876b21e864738fd70861272ddb338 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GaussianSumFitter.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GaussianSumFitter.cxx @@ -55,6 +55,7 @@ Trk::GaussianSumFitter::GaussianSumFitter(const std::string& type, , m_SmootherFailure{ 0 } , m_PerigeeFailure{ 0 } , m_fitQualityFailure{ 0 } + , m_fitSuccess{ 0 } { declareInterface<ITrackFitter>(this); @@ -162,6 +163,8 @@ Trk::GaussianSumFitter::finalize() << "Number of MakePerigee Failures: " << m_PerigeeFailure << '\n' << "Number of Trks that fail fitquality test: " << m_fitQualityFailure << '\n' + << "Number of successful fits: " << m_fitSuccess << '\n' + << '\n' << "-----------------------------------------------" << '\n' << "Finalisation of " << name() << " was successful"); return StatusCode::SUCCESS; @@ -323,11 +326,15 @@ Trk::GaussianSumFitter::fit( sortedPrepRawDataSet.end(), prdComparisonFunction); } + // Create Extrapolator cache that holds material effects cache; + Trk::IMultiStateExtrapolator::Cache extrapolatorCache; + // Perform GSF forwards fit ForwardTrajectory* forwardTrajectory = m_forwardGsfFitter ->fitPRD(ctx, + extrapolatorCache, sortedPrepRawDataSet, estimatedParametersNearOrigin, particleHypothesis) @@ -348,7 +355,7 @@ Trk::GaussianSumFitter::fit( // Perform GSF smoother operation SmoothedTrajectory* smoothedTrajectory = - m_gsfSmoother->fit(ctx,*forwardTrajectory, particleHypothesis); + m_gsfSmoother->fit(ctx, extrapolatorCache, *forwardTrajectory, particleHypothesis); // Protect against failed smoother fit if (!smoothedTrajectory) { @@ -370,7 +377,7 @@ Trk::GaussianSumFitter::fit( if (m_makePerigee) { const Trk::MultiComponentStateOnSurface* perigeeMultiStateOnSurface = - this->makePerigee(ctx,smoothedTrajectory, particleHypothesis); + makePerigee(ctx, extrapolatorCache, smoothedTrajectory, particleHypothesis); ATH_MSG_DEBUG( "perigeeMultiStateOnSurface :" << perigeeMultiStateOnSurface); if (perigeeMultiStateOnSurface) { @@ -389,11 +396,28 @@ Trk::GaussianSumFitter::fit( delete forwardTrajectory; // Reverse the order of the TSOS's to make be order flow from inside to out std::reverse(smoothedTrajectory->begin(), smoothedTrajectory->end()); + + // Store only TSOS in tracks instead of MCSOS + if( !m_StoreMCSOS ){ + auto slimmedSmoothedTrajectory = std::make_unique<Trk::SmoothedTrajectory>(); + for( const Trk::TrackStateOnSurface* tsos : *smoothedTrajectory ){ + slimmedSmoothedTrajectory->push_back( new Trk::TrackStateOnSurface( *tsos ) ); + } + delete smoothedTrajectory; + // Create new track + Trk::TrackInfo info(Trk::TrackInfo::GaussianSumFilter, particleHypothesis); + info.setTrackProperties(TrackInfo::BremFit); + info.setTrackProperties(TrackInfo::BremFitSuccessful); + ++m_fitSuccess; + return std::make_unique<Track>(info, slimmedSmoothedTrajectory.release(), fitQuality); + } + // Create new track Trk::TrackInfo info(Trk::TrackInfo::GaussianSumFilter, particleHypothesis); info.setTrackProperties(TrackInfo::BremFit); info.setTrackProperties(TrackInfo::BremFitSuccessful); + ++m_fitSuccess; return std::make_unique<Track>(info, smoothedTrajectory, fitQuality); } @@ -465,10 +489,17 @@ Trk::GaussianSumFitter::fit( measurementBaseComparisonFunction); } + + // Create Extrapolator cache that holds material effects cache; + Trk::IMultiStateExtrapolator::Cache extrapolatorCache; + + + // Perform GSF forwards fit - new memory allocated in forwards fitter ForwardTrajectory* forwardTrajectory = m_forwardGsfFitter ->fitMeasurements(ctx, + extrapolatorCache, sortedMeasurementSet, estimatedParametersNearOrigin, particleHypothesis) @@ -490,7 +521,7 @@ Trk::GaussianSumFitter::fit( // Perform GSF smoother operation SmoothedTrajectory* smoothedTrajectory = - m_gsfSmoother->fit(ctx, *forwardTrajectory, particleHypothesis, ccot); + m_gsfSmoother->fit(ctx, extrapolatorCache, *forwardTrajectory, particleHypothesis, ccot); // Protect against failed smoother fit if (!smoothedTrajectory) { @@ -513,7 +544,7 @@ Trk::GaussianSumFitter::fit( if (m_makePerigee) { const Trk::MultiComponentStateOnSurface* perigeeMultiStateOnSurface = - this->makePerigee(ctx,smoothedTrajectory, particleHypothesis); + makePerigee(ctx, extrapolatorCache, smoothedTrajectory, particleHypothesis); ATH_MSG_DEBUG( "perigeeMultiStateOnSurface :" << perigeeMultiStateOnSurface); @@ -535,10 +566,27 @@ Trk::GaussianSumFitter::fit( // Reverse the order of the TSOS's to make be order flow from inside to out std::reverse(smoothedTrajectory->begin(), smoothedTrajectory->end()); + + // Store only TSOS in tracks instead of MCSOS + if( !m_StoreMCSOS ){ + auto slimmedSmoothedTrajectory = std::make_unique<Trk::SmoothedTrajectory>(); + for( const Trk::TrackStateOnSurface* tsos : *smoothedTrajectory ){ + slimmedSmoothedTrajectory->push_back( new Trk::TrackStateOnSurface(*tsos) ); + } + delete smoothedTrajectory; + // Create new track + Trk::TrackInfo info(Trk::TrackInfo::GaussianSumFilter, particleHypothesis); + info.setTrackProperties(TrackInfo::BremFit); + info.setTrackProperties(TrackInfo::BremFitSuccessful); + ++m_fitSuccess; + return std::make_unique<Track>(info, slimmedSmoothedTrajectory.release(), fitQuality); + } + // Create new track Trk::TrackInfo info(Trk::TrackInfo::GaussianSumFilter, particleHypothesis); info.setTrackProperties(TrackInfo::BremFit); info.setTrackProperties(TrackInfo::BremFitSuccessful); + ++m_fitSuccess; return std::make_unique<Track>(info, smoothedTrajectory, fitQuality); } @@ -698,6 +746,7 @@ Trk::GaussianSumFitter::fit(const EventContext& ctx, const Trk::MultiComponentStateOnSurface* Trk::GaussianSumFitter::makePerigee( const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache& extrapolatorCache, const Trk::SmoothedTrajectory* smoothedTrajectory, const Trk::ParticleHypothesis particleHypothesis) const { @@ -733,6 +782,7 @@ Trk::GaussianSumFitter::makePerigee( // Extrapolate to perigee, taking material effects considerations into account Trk::MultiComponentState stateExtrapolatedToPerigee = m_extrapolator->extrapolate(ctx, + extrapolatorCache, *multiComponentState, perigeeSurface, m_directionToPerigee, @@ -763,7 +813,7 @@ Trk::GaussianSumFitter::makePerigee( pattern(0); pattern.set(Trk::TrackStateOnSurface::Perigee); - if (fabs(combinedPerigee->parameters()[Trk::qOverP]) > 1e8) { + if (std::abs(combinedPerigee->parameters()[Trk::qOverP]) > 1e8) { // Protection against 0-momentum track .. this check should NEVER be needed. //actual cutoff is 0.01eV track ATH_MSG_ERROR( diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfCombinedMaterialEffects.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfCombinedMaterialEffects.cxx index c5b2735ab7536d41f3b4db68959c1bbb94b2ade6..b53ae153a282b0f8ff72761696eaaa9746eb3f2d 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfCombinedMaterialEffects.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfCombinedMaterialEffects.cxx @@ -72,7 +72,7 @@ Trk::GsfCombinedMaterialEffects::compute( Trk::ParticleHypothesis particleHypothesis) const { - ATH_MSG_DEBUG("Computing combined material effects"); + ATH_MSG_DEBUG("Computing combined material effects, P : " << componentParameters.first->momentum().norm() << " W " << componentParameters.second ); // Reset everything before computation cache.reset(); @@ -163,7 +163,6 @@ Trk::GsfCombinedMaterialEffects::compute( (*multipleScatter_weightsIterator) * (*energyLoss_weightsIterator); double combinedDeltaP = (*multipleScatter_deltaPsIterator) + (*energyLoss_deltaPsIterator); - cache.weights.push_back(combinedWeight); cache.deltaPs.push_back(combinedDeltaP); diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfExtrapolator.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfExtrapolator.cxx index 0dfb08aefafa805c97f66a89de89ec7343c3b7e0..251154f86a8996fae6eb3031eb7ece63562786c1 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfExtrapolator.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfExtrapolator.cxx @@ -145,6 +145,7 @@ Trk::GsfExtrapolator::extrapolateImpl( const Trk::BoundaryCheck& boundaryCheck, Trk::ParticleHypothesis particleHypothesis) const { + ATH_MSG_DEBUG("Calling extrpolate: " << multiComponentState.size() ); auto buff_extrapolateCalls = m_extrapolateCalls.buffer(); // If the extrapolation is to be without material effects simply revert to the @@ -312,7 +313,7 @@ Trk::GsfExtrapolator::extrapolateImpl( double revisedDistance = (referenceParameters->position() - newDestination).mag(); - double distanceChange = fabs(revisedDistance - initialDistance); + double distanceChange = std::abs(revisedDistance - initialDistance); if (revisedDistance > initialDistance && distanceChange > 0.01) { ATH_MSG_DEBUG("Navigation break. Initial separation: " @@ -432,6 +433,7 @@ Trk::GsfExtrapolator::extrapolateImpl( return {}; } // After successful extrapolation return the state + ATH_MSG_DEBUG("extrapolateInsideVolume() successful: " << destinationState.size() ); return destinationState; } /* @@ -469,17 +471,19 @@ Trk::GsfExtrapolator::extrapolateDirectlyImpl( Trk::MultiComponentState Trk::GsfExtrapolator::extrapolate( const EventContext& ctx, + Cache& cache, const Trk::MultiComponentState& multiComponentState, const Trk::Surface& surface, Trk::PropDirection direction, const Trk::BoundaryCheck& boundaryCheck, Trk::ParticleHypothesis particleHypothesis) const { - Cache cache{}; if (multiComponentState.empty()) { ATH_MSG_DEBUG("MultiComponentState is empty..."); return {}; } + + cache.reset(); // Set the propagator to that one corresponding to the configuration level const Trk::IPropagator* currentPropagator = @@ -629,7 +633,7 @@ Trk::GsfExtrapolator::extrapolateToVolumeBoundary( else if (trackingVolume.confinedLayers() && associatedLayer->layerMaterialProperties()) { Trk::MultiComponentState updatedState = m_materialUpdator->postUpdate( - *currentState, *layer, direction, particleHypothesis); + cache.m_materialEffectsCaches, *currentState, *layer, direction, particleHypothesis); if (!updatedState.empty()) { addMaterialtoVector(cache, layer, currentState->begin()->first.get()); @@ -752,7 +756,7 @@ Trk::GsfExtrapolator::extrapolateToVolumeBoundary( ATH_MSG_DEBUG("Boundary surface has material - updating properties"); assert(currentState); matUpdatedState = m_materialUpdator->postUpdate( - *currentState, *layerAtBoundary, direction, particleHypothesis); + cache.m_materialEffectsCaches, *currentState, *layerAtBoundary, direction, particleHypothesis); } } @@ -809,7 +813,7 @@ Trk::GsfExtrapolator::extrapolateInsideVolume( { ATH_MSG_DEBUG("GSF extrapolateInsideVolume() in tracking volume: " - << trackingVolume.volumeName()); + << trackingVolume.volumeName() << " with " << multiComponentState.size() << " components" ); /* * We use current State to track where we are @@ -856,7 +860,7 @@ Trk::GsfExtrapolator::extrapolateInsideVolume( associatedLayer->layerMaterialProperties()) { updatedState = m_materialUpdator->postUpdate( - *currentState, *associatedLayer, direction, particleHypothesis); + cache.m_materialEffectsCaches, *currentState, *associatedLayer, direction, particleHypothesis); if (!updatedState.empty()) { addMaterialtoVector( @@ -1090,7 +1094,7 @@ Trk::GsfExtrapolator::extrapolateToIntermediateLayer( ------------------------------------- */ Trk::MultiComponentState updatedState = m_materialUpdator->update( - destinationState, layer, direction, particleHypothesis); + cache.m_materialEffectsCaches, destinationState, layer, direction, particleHypothesis); if (updatedState.empty()) { return destinationState; @@ -1166,9 +1170,11 @@ Trk::GsfExtrapolator::extrapolateToDestinationLayer( Trk::MultiComponentState updatedState{}; if (startLayer != &layer) { updatedState = m_materialUpdator->preUpdate( - destinationState, layer, direction, particleHypothesis); + cache.m_materialEffectsCaches, destinationState, layer, direction, particleHypothesis); } + ATH_MSG_DEBUG( "State size after preUpdate: " << updatedState.size() ); + if (updatedState.empty()) { return destinationState; } @@ -1201,7 +1207,7 @@ Trk::GsfExtrapolator::extrapolateSurfaceBasedMaterialEffects( // Check the multi-component state is populated if (multiComponentState.empty()) { - ATH_MSG_WARNING("Multi component state passed to extrapolateInsideVolume " + ATH_MSG_WARNING("Multi component state passed to extrapolateSurfaceBasedMaterialEffects " "is not populated... returning 0"); return {}; } @@ -1288,7 +1294,7 @@ Trk::GsfExtrapolator::multiStatePropagate( } ATH_MSG_DEBUG("GSF multiStatePropagate() propagated " - << propagatedState.size() << "components"); + << propagatedState.size() << " components"); // Protect against empty propagation if (propagatedState.empty() || sumw < 0.1) { ATH_MSG_DEBUG("multiStatePropagate failed... "); @@ -1320,7 +1326,7 @@ Trk::GsfExtrapolator::propagatorType( // field and material properties ST : the following check may fail as the dEdX // is often dummy for dense volumes - switch to rho or zOverAtimesRho ? unsigned int propagatorMode = - (magneticFieldMode > 1 && fabs(trackingVolume.dEdX) < 10e-2) ? 2 : 3; + (magneticFieldMode > 1 && std::abs(trackingVolume.dEdX) < 10e-2) ? 2 : 3; unsigned int returnType = (propagatorMode > m_propagatorConfigurationLevel) ? m_propagatorConfigurationLevel @@ -1352,7 +1358,7 @@ Trk::GsfExtrapolator::initialiseNavigation( Trk::PropDirection direction) const { - ATH_MSG_DEBUG("initialiseNavigation !!!"); + ATH_MSG_DEBUG("initialiseNavigation !!! : " << multiComponentState.size() ); // Empty the garbage bin ATH_MSG_DEBUG("Destination to surface [r,z] [" << surface.center().perp() << ",\t" << surface.center().z() @@ -1505,7 +1511,7 @@ Trk::GsfExtrapolator::addMaterialtoVector(Cache& cache, // Determine the pathCorrection if the material properties exist pathcorr = materialProperties - ? 1. / fabs(surface->normal().dot(nextPar->momentum().unit())) + ? 1. / std::abs(surface->normal().dot(nextPar->momentum().unit())) : 0.; } @@ -1527,7 +1533,7 @@ Trk::GsfExtrapolator::addMaterialtoVector(Cache& cache, nextPar->position(), nextPar->momentum()); double thick = pathcorr * materialProperties->thickness(); double dInX0 = thick / materialProperties->x0(); - double absP = 1 / fabs(nextPar->parameters()[Trk::qOverP]); + double absP = 1 / std::abs(nextPar->parameters()[Trk::qOverP]); double scatsigma = sqrt( m_msupdators->sigmaSquare(*materialProperties, absP, pathcorr, particle)); Trk::ScatteringAngles* newsa = new Trk::ScatteringAngles( diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialEffectsUpdator.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialEffectsUpdator.cxx index 9657a682b8513f15c507950d39186a9ba9f1e9f8..16c18501e86bf97244cb50a0a593fc66e978b04a 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialEffectsUpdator.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialEffectsUpdator.cxx @@ -98,7 +98,7 @@ Trk::GsfMaterialEffectsUpdator::updateState( // Determine the pathCorrection if the material properties exist pathCorrection = materialProperties - ? 1. / fabs(surface->normal().dot(trackParameters->momentum().unit())) + ? 1. / std::abs(surface->normal().dot(trackParameters->momentum().unit())) : 0.; } } @@ -216,7 +216,7 @@ Trk::GsfMaterialEffectsUpdator::preUpdateState( // Determine the pathCorrection if the material properties exist pathCorrection = materialProperties - ? 1. / fabs(surface->normal().dot(trackParameters->momentum().unit())) + ? 1. / std::abs(surface->normal().dot(trackParameters->momentum().unit())) : 0.; } } @@ -316,7 +316,7 @@ Trk::GsfMaterialEffectsUpdator::postUpdateState( // Determine the pathCorrection if the material properties exist pathCorrection = materialProperties - ? 1. / fabs(surface->normal().dot(trackParameters->momentum().unit())) + ? 1. / std::abs(surface->normal().dot(trackParameters->momentum().unit())) : 0.; } } @@ -446,7 +446,7 @@ bool Trk::GsfMaterialEffectsUpdator::updateP(AmgVector(5) & stateVector, double deltaP) const { - double p = 1. / fabs(stateVector[Trk::qOverP]); + double p = 1. / std::abs(stateVector[Trk::qOverP]); p += deltaP; if (p <= 0.) { return false; diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolution.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolution.cxx index 438bb317b845b090869ba45e02fbd2a9f18af03d..eabd4ae974bf1d4644bf7deab9d3d72928749d5b 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolution.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolution.cxx @@ -58,6 +58,7 @@ Trk::GsfMaterialMixtureConvolution::finalize() Trk::MultiComponentState Trk::GsfMaterialMixtureConvolution::update( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const Trk::MultiComponentState& multiComponentState, const Trk::Layer& layer, Trk::PropDirection direction, @@ -113,6 +114,7 @@ Trk::GsfMaterialMixtureConvolution::update( QuickCloseComponentsMultiStateMerger::merge( std::move(cache.multiComponentState), m_maximumNumberOfComponents); + ATH_MSG_DEBUG("UPDATE update N in: " << multiComponentState.size() <<" N out: "<< mergedState.size() ); if (mergedState.empty()) { return {}; } @@ -128,6 +130,7 @@ Trk::GsfMaterialMixtureConvolution::update( Trk::MultiComponentState Trk::GsfMaterialMixtureConvolution::preUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const Trk::MultiComponentState& multiComponentState, const Trk::Layer& layer, Trk::PropDirection direction, @@ -159,7 +162,7 @@ Trk::GsfMaterialMixtureConvolution::preUpdate( Trk::MultiComponentState updatedState = m_updator->preUpdateState( *component, layer, direction, particleHypothesis); - + ATH_MSG_DEBUG("PREUPDATE update component result size: " << updatedState.size() ); if (updatedState.empty()) { continue; } @@ -172,11 +175,12 @@ Trk::GsfMaterialMixtureConvolution::preUpdate( "Component could not be added to the state in the assembler"); } } - + ATH_MSG_DEBUG("PREUPDATE before merge N: " << cache.multiComponentState.size() ); Trk::MultiComponentState mergedState = QuickCloseComponentsMultiStateMerger::merge( std::move(cache.multiComponentState), m_maximumNumberOfComponents); + ATH_MSG_DEBUG("PREUPDATE update N in: " << multiComponentState.size() <<" N out: "<< mergedState.size() ); if (mergedState.empty()) { return {}; } @@ -192,6 +196,7 @@ Trk::GsfMaterialMixtureConvolution::preUpdate( Trk::MultiComponentState Trk::GsfMaterialMixtureConvolution::postUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>&, const Trk::MultiComponentState& multiComponentState, const Trk::Layer& layer, Trk::PropDirection direction, @@ -243,6 +248,7 @@ Trk::GsfMaterialMixtureConvolution::postUpdate( QuickCloseComponentsMultiStateMerger::merge( std::move(cache.multiComponentState), m_maximumNumberOfComponents); + ATH_MSG_DEBUG("POSTUPDATE update N in: " << multiComponentState.size() <<" N out: "<< mergedState.size() ); if (mergedState.empty()) { return {}; } diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolutionLM.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolutionLM.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3f8405742c5811a5d415ed0fcc7d8097ba3fd43f --- /dev/null +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMaterialMixtureConvolutionLM.cxx @@ -0,0 +1,503 @@ +/* + Copyright (C) 2020-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/************************************************************************************* + GsfMaterialMixtureConvolutionLM.cxx - description + ------------------------------------------------- +author : amorley +email : amorley@cern.ch +decription : Implementation code for GSF material mixture convolution that uses less mem +************************************************************************************/ + +#include "TrkGaussianSumFilter/GsfMaterialMixtureConvolutionLM.h" +#include "TrkGaussianSumFilter/IMultiStateMaterialEffectsUpdator.h" +#include "TrkGaussianSumFilter/IMultiStateMaterialEffects.h" +#include "TrkGaussianSumFilter/MultiComponentStateAssembler.h" +#include "TrkGaussianSumFilter/MultiComponentStateCombiner.h" +#include "TrkGaussianSumFilter/QuickCloseComponentsMultiStateMerger.h" +#include "TrkGeometry/Layer.h" +#include "TrkGeometry/MaterialProperties.h" +#include "TrkGaussianSumFilter/AlignedDynArray.h" +#include "TrkGaussianSumFilter/KLGaussianMixtureReduction.h" + +#include "TrkMultiComponentStateOnSurface/MultiComponentState.h" +#include "TrkSurfaces/PerigeeSurface.h" + +Trk::GsfMaterialMixtureConvolutionLM::GsfMaterialMixtureConvolutionLM( + const std::string& type, + const std::string& name, + const IInterface* parent) + : AthAlgTool(type, name, parent) +{ + declareInterface<IMaterialMixtureConvolution>(this); +} + +Trk::GsfMaterialMixtureConvolutionLM::~GsfMaterialMixtureConvolutionLM() = default; + +StatusCode +Trk::GsfMaterialMixtureConvolutionLM::initialize() +{ + + ATH_CHECK( m_updator.retrieve() ); + + ATH_CHECK( m_materialEffects.retrieve() ); + + return StatusCode::SUCCESS; +} + +StatusCode +Trk::GsfMaterialMixtureConvolutionLM::finalize() +{ + return StatusCode::SUCCESS; +} + +/* ========================================== + Update with full material effects + ========================================== */ + +Trk::MultiComponentState +Trk::GsfMaterialMixtureConvolutionLM::update( + std::vector<Trk::IMultiStateMaterialEffects::Cache>& caches, + const Trk::MultiComponentState& multiComponentState, + const Trk::Layer& layer, + Trk::PropDirection direction, + Trk::ParticleHypothesis particleHypothesis) const +{ + + const Trk::MaterialProperties* materialProperties = + layer.fullUpdateMaterialProperties(*(multiComponentState.begin()->first)); + + if (!materialProperties) { + ATH_MSG_DEBUG("UPDATE but no material properties!!!"); + } + + Trk::MultiComponentState updatedMergedState = update( caches, + multiComponentState, + layer, + direction, + particleHypothesis, + Normal ); + ATH_MSG_DEBUG("UPDATE update N in: " << multiComponentState.size() <<" N out: "<< updatedMergedState.size() ); + if (updatedMergedState.empty()) { + return {}; + } + // Renormalise state + MultiComponentStateHelpers::renormaliseState(updatedMergedState); + + return updatedMergedState; +} + +/* ========================================== + Update with pre-update material effects +========================================== */ + +Trk::MultiComponentState +Trk::GsfMaterialMixtureConvolutionLM::preUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>& caches, + const Trk::MultiComponentState& multiComponentState, + const Trk::Layer& layer, + Trk::PropDirection direction, + Trk::ParticleHypothesis particleHypothesis) const +{ + const Trk::MaterialProperties* materialProperties = + layer.fullUpdateMaterialProperties(*(multiComponentState.begin()->first)); + if (!materialProperties) { + ATH_MSG_DEBUG("PREUPDATE but no material properties!!!"); + } + /* ------------------------------------- + Preliminary checks + ------------------------------------- */ + Trk::MultiComponentState updatedMergedState = update( caches, + multiComponentState, + layer, + direction, + particleHypothesis, + Preupdate ); + ATH_MSG_DEBUG("PREUPDATE update N in: " << multiComponentState.size() <<" N out: "<< updatedMergedState.size() ); + if (updatedMergedState.empty()) { + return {}; + } + // Renormalise state + MultiComponentStateHelpers::renormaliseState(updatedMergedState); + + return updatedMergedState; +} + +/* ========================================== + Update with post-update material effects + ========================================== */ + +Trk::MultiComponentState +Trk::GsfMaterialMixtureConvolutionLM::postUpdate( + std::vector<Trk::IMultiStateMaterialEffects::Cache>& caches, + const Trk::MultiComponentState& multiComponentState, + const Trk::Layer& layer, + Trk::PropDirection direction, + Trk::ParticleHypothesis particleHypothesis) const +{ + + const Trk::MaterialProperties* materialProperties = + layer.fullUpdateMaterialProperties(*(multiComponentState.begin()->first)); + if (!materialProperties) { + ATH_MSG_DEBUG("POSTUPDATE but no material properties!!!"); + } + /* ------------------------------------- + Preliminary checks + ------------------------------------- */ + + Trk::MultiComponentState updatedMergedState = update( caches, + multiComponentState, + layer, + direction, + particleHypothesis, + Postupdate ); + + + ATH_MSG_DEBUG("POSTUPDATE update N in: " << multiComponentState.size() <<" N out: "<< updatedMergedState.size() ); + if (updatedMergedState.empty()) { + return {}; + } + // Renormalise state + MultiComponentStateHelpers::renormaliseState(updatedMergedState); + + + return updatedMergedState; +} + + + +Trk::MultiComponentState Trk::GsfMaterialMixtureConvolutionLM::update( + std::vector<Trk::IMultiStateMaterialEffects::Cache>& caches, + const Trk::MultiComponentState& inputState, + const Trk::Layer& layer, + Trk::PropDirection direction, + Trk::ParticleHypothesis particleHypothesis, + MaterialUpdateType updateType) const +{ + + + // Check the multi-component state is populated + if (inputState.empty()) { + ATH_MSG_DEBUG("Multi component state passed to update is " + "not populated... returning 0"); + return {}; + } + + + double updateFactor(1.); + // Full method does this for each component which i don't think this is needed + if( updateType == Preupdate ){ + updateFactor = layer.preUpdateMaterialFactor(*inputState.front().first, direction); + ATH_MSG_DEBUG("Material effects update prior to propagation using layer " + "information and particle hypothesis: " + << particleHypothesis); + } else if ( updateType == Postupdate) { + updateFactor = layer.postUpdateMaterialFactor( *inputState.front().first, direction); + ATH_MSG_DEBUG("Material effects update after propagation using layer " + "information and particle hypothesis: " + << particleHypothesis); + } + + if( updateFactor < 0.01 ){ + //Bail out as factor is too small to bother about + return {}; + } + + + caches.resize( inputState.size() ); + + // Fill cache and work out how many final components there should be + size_t n(0); + for( size_t i(0) ; i < inputState.size(); ++i){ + const AmgSymMatrix(5)* measuredCov = inputState[i].first->covariance(); + //If the momentum is too dont apply material effects + if( inputState[i].first->momentum().mag() <= m_momentumCut ){ + ATH_MSG_DEBUG("Ignoring material effects... Momentum too low"); + caches[i].resetAndAddDummyValues(); + caches[i].deltaParameters[0] = inputState[i].first->parameters(); + caches[i].weights[0] = inputState[i].second; + if (measuredCov) { + caches[i].deltaCovariances[0] += *measuredCov; + } + n += caches[i].weights.size(); + continue; + } + + // Get the material effects and store them in the cache + std::pair< const Trk::MaterialProperties*, double > matPropPair = + getMaterialProperties( inputState[i].first.get(), layer ); + + if( !matPropPair.first ) { + ATH_MSG_DEBUG("No material properties .. dont apply material effects"); + caches[i].resetAndAddDummyValues(); + caches[i].deltaParameters[0] = inputState[i].first->parameters(); + caches[i].weights[0] = inputState[i].second; + if (measuredCov) { + caches[i].deltaCovariances[0] += *measuredCov; + } + n += caches[i].weights.size(); + continue; + } + + // Apply the update factor + matPropPair.second *= updateFactor; + + m_materialEffects->compute(caches[i], + inputState[i], + *matPropPair.first, + matPropPair.second, + direction, + particleHypothesis); + + // check all vectors have the same size + if (caches[i].weights.size() != caches[i].deltaPs.size()) { + ATH_MSG_ERROR("Inconsistent number of components in the updator!!! no material effect will be applied"); + caches[i].resetAndAddDummyValues(); + } + + for( size_t j(0); j < caches[i].weights.size(); ++j){ + if (measuredCov) { + caches[i].deltaCovariances[j] += *measuredCov; + } else { + caches[i].deltaCovariances[j].setZero(); + } + caches[i].deltaParameters[j] = inputState[i].first->parameters(); + // Adjust the momentum of the component's parameters vector here. Check to + // make sure update is good. + if (!updateP(caches[i].deltaParameters[j][Trk::qOverP], caches[i].deltaPs[j])) { + ATH_MSG_ERROR("Cannot update state vector momentum!!! return nullptr"); + return {}; + } + // Store component weight + caches[i].weights[j] *= inputState[i].second; + } + + n += caches[i].weights.size(); + } + + + // Fill information for to calculate which components to merge + // Inaddition scan all components for covariance matrices. If one or more component + // is missing an error matrix, component reduction is impossible. + bool componentWithoutMeasurement = false; + + GSFUtils::AlignedDynArray<GSFUtils::Component1D, GSFUtils::alignment> components(n); + size_t k(0); + std::vector< std::pair<size_t,size_t> > indices(n); + for( size_t i(0) ; i < inputState.size(); ++i){ + for( size_t j(0); j < caches[i].weights.size(); ++j ){ + const AmgSymMatrix(5)* measuredCov = inputState[i].first->covariance(); + // Fill in infomation + const double cov = + measuredCov ? caches[i].deltaCovariances[j](Trk::qOverP, Trk::qOverP) : -1.; + if( !measuredCov ){ + componentWithoutMeasurement = true; + } + components[k].mean = caches[i].deltaParameters[j][Trk::qOverP]; + components[k].cov = cov; + components[k].invCov = cov > 0 ? 1. / cov : 1e10; + components[k].weight = caches[i].weights[j] ; + indices[k] = {i,j}; + ++k; + } + } + + + if(componentWithoutMeasurement){ + auto result = std::max_element(components.begin(), + components.end(), + [](const auto& a, const auto& b){ + return a.weight < b.weight; + }); + auto index = std::distance(components.begin(), result); + + // Build the first TP + size_t stateIndex = indices[index].first; + size_t materialIndex = indices[index].second; + + AmgVector(5)& updatedStateVector = caches[stateIndex].deltaParameters[materialIndex]; + const AmgSymMatrix(5)* measuredCov = inputState[stateIndex].first->covariance(); + AmgSymMatrix(5)* updatedCovariance = nullptr; + if (measuredCov && caches[stateIndex].deltaCovariances.size() > materialIndex) { + updatedCovariance = new AmgSymMatrix(5)( + caches[stateIndex].deltaCovariances[materialIndex] ); + } + Trk::TrackParameters* updatedTrackParameters = + inputState[stateIndex].first->associatedSurface().createTrackParameters( + updatedStateVector[Trk::loc1], + updatedStateVector[Trk::loc2], + updatedStateVector[Trk::phi], + updatedStateVector[Trk::theta], + updatedStateVector[Trk::qOverP], + updatedCovariance); + + Trk::ComponentParameters dummyCompParams( updatedTrackParameters, 1.); + Trk::MultiComponentState returnMultiState; + returnMultiState.push_back(std::move(dummyCompParams)); + return returnMultiState; + } + + + // Gather the merges -- order is important -- RHS is smaller than LHS + std::vector<std::pair<int32_t, int32_t>> merges; + if (n > m_maximumNumberOfComponents) + merges = findMerges(components.buffer(), n, m_maximumNumberOfComponents); + + //Merge components + MultiComponentStateAssembler::Cache assemblerCache; + int nMerges(0); + std::vector<bool> isMerged( n, false); + for (const auto& mergePair : merges) { + const int32_t mini = mergePair.first; + const int32_t minj = mergePair.second; + + + + // Build the first TP + size_t stateIndex = indices[mini].first; + size_t materialIndex = indices[mini].second; + AmgVector(5)& stateVector = caches[stateIndex].deltaParameters[materialIndex]; + AmgSymMatrix(5)& measuredCov = caches[stateIndex].deltaCovariances[materialIndex]; + + // Build the second TP + size_t stateIndex2 = indices[minj].first; + size_t materialIndex2 = indices[minj].second; + + ++nMerges; + + const AmgVector(5) firstParameters = stateVector; + const double firstWeight = caches[stateIndex].weights[materialIndex]; + + Trk::MultiComponentStateCombiner::combineParametersWithWeight( caches[stateIndex].deltaParameters[materialIndex], + caches[stateIndex].weights[materialIndex], + caches[stateIndex2].deltaParameters[materialIndex2], + caches[stateIndex2].weights[materialIndex2] ); + + Trk::MultiComponentStateCombiner::combineCovWithWeight( firstParameters, + measuredCov, + firstWeight, + caches[stateIndex2].deltaParameters[materialIndex2], + caches[stateIndex2].deltaCovariances[materialIndex2], + caches[stateIndex2].weights[materialIndex2] ); + + isMerged[minj] = true; + caches[stateIndex2].deltaParameters[materialIndex2].setZero(); + caches[stateIndex2].deltaCovariances[materialIndex2].setZero(); + + } + + for( size_t i(0); i < n; ++i ){ + if( isMerged[i] ) + continue; + + // Build the TP + size_t stateIndex = indices[i].first; + size_t materialIndex = indices[i].second; + AmgVector(5)& stateVector = caches[stateIndex].deltaParameters[materialIndex]; + AmgSymMatrix(5)& measuredCov = caches[stateIndex].deltaCovariances[materialIndex]; + + Trk::TrackParameters* updatedTrackParameters = + inputState[stateIndex].first->associatedSurface().createTrackParameters( + stateVector[Trk::loc1], + stateVector[Trk::loc2], + stateVector[Trk::phi], + stateVector[Trk::theta], + stateVector[Trk::qOverP], + new AmgSymMatrix(5)( measuredCov ) ); + + double updatedWeight = caches[stateIndex].weights[materialIndex]; + + assemblerCache.multiComponentState.emplace_back( updatedTrackParameters, updatedWeight); + assemblerCache.validWeightSum += updatedWeight; + } + + if( nMerges + assemblerCache.multiComponentState.size() != n ){ + ATH_MSG_ERROR("Combining complete but merger size is incompatible: " << n << " " << nMerges << " " << assemblerCache.multiComponentState.size() ); + } + + // Check all weights + Trk::MultiComponentState mergedState = + MultiComponentStateAssembler::assembledState(assemblerCache); + + if(mergedState.size() > m_maximumNumberOfComponents) + ATH_MSG_ERROR("Merging failed, target size: " << m_maximumNumberOfComponents << " final size: " << mergedState.size()); + return mergedState; +} + + +bool Trk::GsfMaterialMixtureConvolutionLM::updateP(double& qOverP, double deltaP) const +{ + double p = 1. / std::abs(qOverP); + p += deltaP; + if (p <= 0.) { + return false; + } + qOverP = qOverP > 0. ? 1. / p : -1. / p; + return true; +} + + + +std::pair< const Trk::MaterialProperties*, double > + Trk::GsfMaterialMixtureConvolutionLM::getMaterialProperties( + const Trk::TrackParameters* trackParameters, + const Trk::Layer& layer) const +{ + + const Trk::MaterialProperties* materialProperties(nullptr); + double pathCorrection(0.); + + // Incorporate the reference material + + if (m_useReferenceMaterial) { + + // Get the surface associated with the parameters + const Trk::Surface* surface = &(trackParameters->associatedSurface()); + + // Only utilise the reference material if an associated detector element + // exists + if (surface && surface->associatedDetectorElement()) { + + // Get the layer material properties + const Trk::LayerMaterialProperties* layerMaterial = + layer.layerMaterialProperties(); + + // Assign the material properties + materialProperties = + layerMaterial ? layerMaterial->fullMaterial(trackParameters->position()) + : nullptr; + + // Determine the pathCorrection if the material properties exist + pathCorrection = + materialProperties + ? 1. / std::abs(surface->normal().dot(trackParameters->momentum().unit())) + : 0.; + } + } + + // Check that the material properties have been defined - if not define them + // from the layer information + materialProperties = materialProperties + ? materialProperties + : layer.fullUpdateMaterialProperties(*trackParameters); + + // Bail out if still no material properties can be found + if (!materialProperties) { + return {nullptr,0}; + } + + // Define the path correction + pathCorrection = + pathCorrection > 0. + ? pathCorrection + : layer.surfaceRepresentation().pathCorrection( + trackParameters->position(), trackParameters->momentum()); + + + // The pathlength ( in mm ) is the path correction * the thickness of the + // material + double pathLength = pathCorrection * materialProperties->thickness(); + + return {materialProperties,pathLength}; +} diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx index 5300da13fe4504ecf5598e5616d0ecc36bbe5d88..5ffb33af9b5b74fbfde643566eaa7e59c37514df 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfMeasurementUpdator.cxx @@ -291,6 +291,8 @@ Trk::GsfMeasurementUpdator::calculateFilterStep( if (stateBeforeUpdate.empty()) { ATH_MSG_WARNING("Cannot update multi-state with no components!"); return {}; + } else { + ATH_MSG_DEBUG("calculateFilterStep() starting with : " << stateBeforeUpdate.size() ); } // Calculate the weight of each component after the measurement @@ -301,6 +303,8 @@ Trk::GsfMeasurementUpdator::calculateFilterStep( if (stateWithNewWeights.empty()) { ATH_MSG_DEBUG("Cacluation of state posterior weights failed... Exiting!"); return {}; + } else { + ATH_MSG_DEBUG("calculateFilterStep() after new weights : " << stateWithNewWeights.size() ); } // Update each component using the specified updator @@ -312,9 +316,10 @@ Trk::GsfMeasurementUpdator::calculateFilterStep( for (; component != stateWithNewWeights.end(); ++component) { - if (fabs((*component).first->parameters()[Trk::qOverP]) > 0.033333) { + if ( stateWithNewWeights.size() > 1 && + std::abs((*component).first->parameters()[Trk::qOverP]) > 0.033333) { ATH_MSG_DEBUG( - "About to update component with p<30MeV...skipping component! (2)"); + "About to update component with p<30 MeV...skipping component! (2)"); continue; } Trk::FitQualityOnSurface* componentFitQuality = nullptr; @@ -381,11 +386,15 @@ Trk::GsfMeasurementUpdator::calculateFilterStep( } } + ATH_MSG_DEBUG("Assembeler cache size : " << cache.multiComponentState.size() ); + Trk::MultiComponentState assembledUpdatedState = MultiComponentStateAssembler::assembledState(cache); if (assembledUpdatedState.empty()) { return {}; + } else { + ATH_MSG_DEBUG("Assembeled size : " << assembledUpdatedState.size() ); } fitQoS = std::make_unique<FitQualityOnSurface>(chiSquared, degreesOfFreedom); diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfSmoother.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfSmoother.cxx index 5ca92fd3350321ac255d8c5535147013f0dd49c5..4dba395e60173c65ce479704856e22a5ed34b18c 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfSmoother.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/GsfSmoother.cxx @@ -65,6 +65,7 @@ Trk::GsfSmoother::configureTools( Trk::SmoothedTrajectory* Trk::GsfSmoother::fit(const EventContext& ctx, + Trk::IMultiStateExtrapolator::Cache& extrapolatorCache, const ForwardTrajectory& forwardTrajectory, const ParticleHypothesis particleHypothesis, const Trk::CaloCluster_OnTrack* ccot) const @@ -249,6 +250,7 @@ Trk::GsfSmoother::fit(const EventContext& ctx, Trk::MultiComponentState extrapolatedState = m_extrapolator->extrapolate(ctx, + extrapolatorCache, updatedState, measurement->associatedSurface(), Trk::oppositeMomentum, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateCombiner.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateCombiner.cxx index cd299aa50059cbf21d3ca271a9c2a553d4b0c4a9..801690c53a60a8a87205bdceb90076194522e17b 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateCombiner.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateCombiner.cxx @@ -14,6 +14,7 @@ #include "TrkGaussianSumFilter/MultiComponentStateModeCalculator.h" #include "TrkParameters/TrackParameters.h" #include "TrkSurfaces/Surface.h" +#include "CxxUtils/phihelper.h" std::unique_ptr<Trk::TrackParameters> Trk::MultiComponentStateCombiner::combine( @@ -41,76 +42,91 @@ Trk::MultiComponentStateCombiner::combineWithWeight( Trk::ComponentParameters& mergeTo, const Trk::ComponentParameters& addThis) { + const Trk::TrackParameters* secondParameters = addThis.first.get(); + combineWithWeight( mergeTo, secondParameters->parameters(), secondParameters->covariance(), addThis.second ); +} - const Trk::TrackParameters* firstParameters = mergeTo.first.get(); - // Check to see if first track parameters are measured or not - const AmgSymMatrix(5)* firstMeasuredCov = firstParameters->covariance(); +void +Trk::MultiComponentStateCombiner::combineWithWeight( + Trk::ComponentParameters& mergeTo, + const AmgVector(5)& secondParameters, const AmgSymMatrix(5)* secondMeasuredCov, const double secondWeight ) +{ double firstWeight = mergeTo.second; - - const Trk::TrackParameters* secondParameters = addThis.first.get(); + auto trackParameters = mergeTo.first.get(); + const AmgVector(5)& firstParameters = trackParameters->parameters(); + AmgVector(5) finalParameters( firstParameters ); // Check to see if first track parameters are measured or not - const AmgSymMatrix(5)* secondMeasuredCov = secondParameters->covariance(); - double secondWeight = addThis.second; - double totalWeight = firstWeight + secondWeight; + double finalWeight = firstWeight; + combineParametersWithWeight( finalParameters, finalWeight, + secondParameters, secondWeight ); + + + if( trackParameters->covariance() && secondMeasuredCov ) + { + AmgSymMatrix(5) finalMeasuredCov( *trackParameters->covariance() ); + combineCovWithWeight( firstParameters, finalMeasuredCov, firstWeight, + secondParameters, *secondMeasuredCov, secondWeight ); + + mergeTo.first->updateParameters(finalParameters, finalMeasuredCov); + mergeTo.second = finalWeight; + } else { + mergeTo.first->updateParameters(finalParameters, nullptr); + mergeTo.second = finalWeight; + } + +} + - AmgVector(5) mean; - mean.setZero(); - AmgVector(5) parameters = secondParameters->parameters(); + +void Trk::MultiComponentStateCombiner::combineParametersWithWeight( + AmgVector(5)& firstParameters, double& firstWeight, + const AmgVector(5)& secondParameters, const double secondWeight ) +{ + + double totalWeight = firstWeight + secondWeight; // Ensure that we don't have any problems with the cyclical nature of phi // Use first state as reference poin - double deltaPhi = firstParameters->parameters()[2] - parameters[2]; - + double deltaPhi = firstParameters[2] - secondParameters[2]; if (deltaPhi > M_PI) { - parameters[2] += 2 * M_PI; + firstParameters[2] -= 2 * M_PI; } else if (deltaPhi < -M_PI) { - parameters[2] -= 2 * M_PI; + firstParameters[2] += 2 * M_PI; } - mean = - firstWeight * firstParameters->parameters() + secondWeight * parameters; - mean /= totalWeight; + + firstParameters = + firstWeight * firstParameters + secondWeight * secondParameters; + firstParameters /= totalWeight; // Ensure that phi is between -pi and pi // - if (mean[2] > M_PI) { - mean[2] -= 2 * M_PI; - } else if (mean[2] < -M_PI) { - mean[2] += 2 * M_PI; - } + firstParameters[2] = CxxUtils::wrapToPi( firstParameters[2] ); + firstWeight = totalWeight; +} + + + +void Trk::MultiComponentStateCombiner::combineCovWithWeight( + const AmgVector(5)& firstParameters, AmgSymMatrix(5)& firstMeasuredCov, const double firstWeight, + const AmgVector(5)& secondParameters, const AmgSymMatrix(5)& secondMeasuredCov, const double secondWeight ) +{ + + double totalWeight = firstWeight + secondWeight; // Extract local error matrix: Must make sure track parameters are measured, // ie have an associated error matrix. - if (firstMeasuredCov && secondMeasuredCov) { - AmgSymMatrix(5) covariance; - AmgSymMatrix(5) covariancePart1; - covariancePart1.setZero(); - AmgSymMatrix(5) covariancePart2; - covariancePart2.setZero(); - - covariancePart1 = - firstWeight * (*firstMeasuredCov) + secondWeight * (*secondMeasuredCov); - AmgVector(5) parameterDifference = - firstParameters->parameters() - parameters; - - if (parameterDifference[2] > M_PI) { - parameterDifference[2] -= 2 * M_PI; - } else if (parameterDifference[2] < -M_PI) { - parameterDifference[2] += 2 * M_PI; - } - covariancePart2 = firstWeight * secondWeight * parameterDifference * - parameterDifference.transpose(); - covariance = covariancePart1 / totalWeight + - covariancePart2 / (totalWeight * totalWeight); - - mergeTo.first->updateParameters(mean, covariance); - mergeTo.second = totalWeight; - } else { - mergeTo.first->updateParameters(mean, nullptr); - mergeTo.second = totalWeight; - } + AmgVector(5) parameterDifference = firstParameters - secondParameters; + parameterDifference[2] = CxxUtils::wrapToPi( parameterDifference[2] ); + parameterDifference /= totalWeight; + + firstMeasuredCov *= firstWeight; + firstMeasuredCov += secondWeight * secondMeasuredCov; + firstMeasuredCov /= totalWeight; + firstMeasuredCov += firstWeight * secondWeight * parameterDifference * parameterDifference.transpose(); + } std::unique_ptr<Trk::ComponentParameters> @@ -227,11 +243,7 @@ Trk::MultiComponentStateCombiner::compute( // Ensure that phi is between -pi and pi // - if (mean[2] > M_PI) { - mean[2] -= 2 * M_PI; - } else if (mean[2] < -M_PI) { - mean[2] += 2 * M_PI; - } + mean[2] = CxxUtils::wrapToPi( mean[2] ); (*covariance) = covariancePart1 / sumW + covariancePart2 / (sumW * sumW); diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateModeCalculator.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateModeCalculator.cxx index 6a7df3538a3181e8e1d5a6b71e940b1d7c319e27..ef97513d3e1bd25ee144eb1e35125a9104733437 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateModeCalculator.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/MultiComponentStateModeCalculator.cxx @@ -13,9 +13,10 @@ #include "TrkGaussianSumFilter/MultiComponentStateModeCalculator.h" #include "TrkMultiComponentStateOnSurface/MultiComponentState.h" #include "TrkParameters/TrackParameters.h" +#include "CxxUtils/phihelper.h" namespace { -const double invsqrt2PI = 1. / sqrt(2. * M_PI); +constexpr double invsqrt2PI = 1. / sqrt(2. * M_PI); /** bried method to determine the value of the a gaussian distribution at a * given value */ @@ -165,11 +166,7 @@ Trk::MultiComponentStateModeCalculator::calculateMode( } // Ensure that phi is between -pi and pi if (i == 2) { - if (modes[i] > M_PI) { - modes[i] -= 2 * M_PI; - } else if (modes[i] < -M_PI) { - modes[i] += 2 * M_PI; - } + modes[i] = CxxUtils::wrapToPi( modes[i] ) ; } } } @@ -205,9 +202,9 @@ Trk::MultiComponentStateModeCalculator::fillMixture( // d0=0, z0=1, phi0=2, theta=3, qOverP=4, double weight = component->second; double mean = componentParameters->parameters()[parameter[i]]; - // FIXME ATLASRECTS-598 this fabs() should not be necessary... for some + // FIXME ATLASRECTS-598 this std::abs() should not be necessary... for some // reason cov(qOverP,qOverP) can be negative - double sigma = sqrt(fabs((*measuredCov)(parameter[i], parameter[i]))); + double sigma = sqrt(std::abs((*measuredCov)(parameter[i], parameter[i]))); // Ensure that we don't have any problems with the cyclical nature of phi // Use first state as reference point @@ -254,7 +251,7 @@ Trk::MultiComponentStateModeCalculator::findMode( double pdfPreviousMode = pdf(previousMode, i, mixture); if ((pdfMode + pdfPreviousMode) != 0.0) { - tolerance = fabs(pdfMode - pdfPreviousMode) / (pdfMode + pdfPreviousMode); + tolerance = std::abs(pdfMode - pdfPreviousMode) / (pdfMode + pdfPreviousMode); } else { return xStart; } @@ -288,7 +285,7 @@ Trk::MultiComponentStateModeCalculator::findModeGlobal( double mode(0); double maximum(-1); - double iterate(fabs(mean / 1000)); + double iterate(std::abs(mean / 1000)); for (double counter(start); counter < end; counter += iterate) { double value(pdf(counter, i, mixture)); @@ -342,7 +339,7 @@ Trk::MultiComponentStateModeCalculator::findRoot( e = b - a; } - if (fabs(fc) < fabs(fb)) { + if (std::abs(fc) < std::abs(fb)) { ac_equal = true; a = b; b = c; @@ -352,15 +349,15 @@ Trk::MultiComponentStateModeCalculator::findRoot( fc = fa; } - double tol = 0.5 * tolerance * fabs(b); + double tol = 0.5 * tolerance * std::abs(b); double m = 0.5 * (c - b); - if (fb == 0 || fabs(m) <= tol) { + if (fb == 0 || std::abs(m) <= tol) { result = b; return true; } - if (fabs(e) < tol || fabs(fa) <= fabs(fb)) { + if (std::abs(e) < tol || std::abs(fa) <= std::abs(fb)) { // Bounds decreasing too slowly: use bisection d = m; e = m; @@ -387,8 +384,8 @@ Trk::MultiComponentStateModeCalculator::findRoot( p = -p; } - double min1 = 3 * m * q - fabs(tol * q); - double min2 = fabs(e * q); + double min1 = 3 * m * q - std::abs(tol * q); + double min2 = std::abs(e * q); if (2 * p < (min1 < min2 ? min1 : min2)) { // Accept the interpolation e = d; @@ -403,7 +400,7 @@ Trk::MultiComponentStateModeCalculator::findRoot( a = b; fa = fb; // Evaluate new trial root - if (fabs(d) > tol) { + if (std::abs(d) > tol) { b += d; } else { b += (m > 0 ? +tol : -tol); diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/components/TrkGaussianSumFilter_entries.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/components/TrkGaussianSumFilter_entries.cxx index 86bd37996bb9a33d5164599b62c9fd34442ab1fe..f53ef90ca49b278f379b7e42a9d7c5a82e9e0e70 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/components/TrkGaussianSumFilter_entries.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/components/TrkGaussianSumFilter_entries.cxx @@ -1,3 +1,4 @@ +#include "TrkGaussianSumFilter/GsfMaterialMixtureConvolutionLM.h" #include "TrkGaussianSumFilter/GsfMaterialMixtureConvolution.h" #include "TrkGaussianSumFilter/GsfCombinedMaterialEffects.h" #include "TrkGaussianSumFilter/GsfMaterialEffectsUpdator.h" @@ -8,6 +9,7 @@ #include "TrkGaussianSumFilter/GsfExtrapolator.h" #include "TrkGaussianSumFilter/GsfSmoother.h" +DECLARE_COMPONENT( Trk::GsfMaterialMixtureConvolutionLM ) DECLARE_COMPONENT( Trk::GsfMaterialMixtureConvolution ) DECLARE_COMPONENT( Trk::GsfCombinedMaterialEffects ) DECLARE_COMPONENT( Trk::GsfMaterialEffectsUpdator ) diff --git a/Tracking/TrkTruthTracks/TrkTruthTrackTools/src/TruthTrackBuilder.cxx b/Tracking/TrkTruthTracks/TrkTruthTrackTools/src/TruthTrackBuilder.cxx index d3635339af1c596aaa9e2a97dd37d102f29fee72..b17fa2e045bb4a786da8a7935032b3079cd2d9db 100644 --- a/Tracking/TrkTruthTracks/TrkTruthTrackTools/src/TruthTrackBuilder.cxx +++ b/Tracking/TrkTruthTracks/TrkTruthTrackTools/src/TruthTrackBuilder.cxx @@ -237,7 +237,7 @@ Trk::Track* Trk::TruthTrackBuilder::createTrack(const PRD_TruthTrajectory& prdTr Trk::Track *refittedtrack=m_trackFitter->fit(track,false,materialInteractions); - //!< @todo : add documentation & find out why we need the fit twice ? + //!< Refit a second time to add TRT hits Trk::Track *refittedtrack2=nullptr; if (refittedtrack && (int)clusters.size()-i>=9){ Trk::MeasurementSet measset; @@ -263,7 +263,7 @@ Trk::Track* Trk::TruthTrackBuilder::createTrack(const PRD_TruthTrajectory& prdTr refittedtrack2=new Trk::Track(refittedtrack->info(),traj2,refittedtrack->fitQuality()->clone()); } else for (int j=0;j<(int)measset.size();j++) delete measset[j]; - } else { + } else if(!refittedtrack){ ATH_MSG_VERBOSE("Track fit of truth trajectory NOT successful, NO track created. "); return nullptr; } @@ -272,7 +272,7 @@ Trk::Track* Trk::TruthTrackBuilder::createTrack(const PRD_TruthTrajectory& prdTr if (!refittedtrack2 && refittedtrack) refittedtrack2=refittedtrack; // - ATH_MSG_WARNING("Track fit of truth trajectory successful, track created. "); + ATH_MSG_DEBUG("Track fit of truth trajectory successful, track created. "); // return what you have // Before returning, fix the creator refittedtrack2->info().setPatternRecognitionInfo( Trk::TrackInfo::Pseudotracking);