Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Core/include/Acts/Seeding/CompositeSpacePointLineFitter.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/EventData/CompositeSpacePoint.hpp"
0012 #include "Acts/EventData/CompositeSpacePointCalibrator.hpp"
0013 #include "Acts/Seeding/detail/CompSpacePointAuxiliaries.hpp"
0014 #include "Acts/Seeding/detail/FastStrawLineFitter.hpp"
0015 #include "Acts/Utilities/CalibrationContext.hpp"
0016 #include "Acts/Utilities/Delegate.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 
0019 namespace Acts::Experimental {
0020 /// @brief Generic Implementation to fit a straight line to set of composite space point measurements.
0021 ///        The line is parameterized by x_{0}, y_{0}, theta, phi, where the
0022 ///        first two parameters are the line's intercept at z=0 and the latter
0023 ///        two are the polar and azimuthal angle in the local frame common to
0024 ///        all space points. Optionally, the fitter may also estimate the offset
0025 ///        in the time of arrival at the line's reference plane.
0026 class CompositeSpacePointLineFitter {
0027  public:
0028   /// @brief Abrivation of the line type
0029   using Line_t = detail::CompSpacePointAuxiliaries::Line_t;
0030   /// @brief Abrivation of the carrier object of the chi2 of the measurements w.r.t. the line together
0031   ///        with the corresponding derivatives
0032   using ChiSqCache = detail::CompSpacePointAuxiliaries::ChiSqWithDerivatives;
0033   /// @brief Vector abrivation
0034   using Vector = Line_t::Vector;
0035   /// @brief Assignment of the parameter vector components
0036   using FitParIndex = detail::CompSpacePointAuxiliaries::FitParIndex;
0037   /// @brief Abrivation of the fast fitter
0038   using FastFitter_t = detail::FastStrawLineFitter;
0039 
0040   ///@brief During the repetitive recalibration, single hits may be invalidated
0041   ///       under the track parameters. Define a Delegate to sort out the
0042   ///       invalid hits
0043   template <CompositeSpacePoint Sp_t>
0044   using Selector_t = Delegate<bool(const Sp_t&)>;
0045   /// @brief Abrivation of the underlying space point type
0046   template <CompositeSpacePointContainer Cont_t>
0047   using SpacePoint_t = RemovePointer_t<typename Cont_t::value_type>;
0048 
0049   static constexpr auto s_nPars = toUnderlying(FitParIndex::nPars);
0050   /// @brief Vector containing the 5 straight segment line parameters
0051   using ParamVec_t = std::array<double, s_nPars>;
0052   /// @brief Covariance estimation matrix on the segment line parameters
0053   using CovMat_t = Acts::ActsSquareMatrix<s_nPars>;
0054   /// @brief Fitter configuration object
0055   struct Config {
0056     /// @brief If the parameter change or the gradient's magnitude is below the cutOff the fit is converged
0057     double precCutOff{1.e-7};
0058     /// @brief Gradient decent step size if the Hessian is singular
0059     double gradientStep{1.e-4};
0060     /// @brief Number of iterations
0061     std::size_t maxIter{1000};
0062     /// @brief Fit the time offset if possible
0063     bool fitT0{false};
0064     /// @brief Recalibrate the hits between two iterations
0065     bool recalibrate{false};
0066     /// @brief Switch to use the fast fitter if only straw measurements are passed
0067     bool useFastFitter{false};
0068     /// @brief Threshold on the fast straw chi2 above which the fit is reattempted but with
0069     ///        swapped straw signs.
0070     double badFastChi2SignSwap{5.};
0071     /// @brief Switch to use the fast fitter as pre-fitter. The flag useFastFitter needs to be enabled
0072     bool fastPreFitter{true};
0073     /// @brief Use the second derivative in the residual calculation
0074     bool useHessian{false};
0075     /// @brief Flag toggling whether the along the wire component of straws shall be calculated
0076     ///        if provided by the straw measurement.
0077     bool calcAlongStraw{true};
0078     /// @brief Flag toggling whether the residual along the strip direction
0079     ///        shall be calculated if the space point does not measure both
0080     ///        spatial coordinates on the plane
0081     bool calcAlongStrip{true};
0082     /// @brief  Include the time of flight assuming that the particle travels with the
0083     ///         speed of light in the time residual calculations
0084     bool includeToF{true};
0085     /// @brief Abort the fit as soon as more than n parameters leave the fit range
0086     std::size_t nParsOutOfBounds{1};
0087     /// @brief Allowed parameter ranges. If the lower interval edge is higher than the upper
0088     ///        edge, the parameters are unbound
0089     using RangeArray = std::array<std::array<double, 2>, s_nPars>;
0090     RangeArray ranges{
0091         filledArray<std::array<double, 2>, s_nPars>(std::array{1., -1.})};
0092     /// @brief Overwrite the set of parameters to use, if it's absolutely necessary
0093     std::vector<FitParIndex> parsToUse{};
0094   };
0095   /// @brief Auxiliary object to store the fitted parameters, covariance,
0096   ///        the chi2 / nDoF & the number of required iterations
0097   struct FitParameters {
0098     /// @brief Default constructor
0099     FitParameters() = default;
0100     /// @brief Copy constructor
0101     FitParameters(const FitParameters& other) = default;
0102     /// @brief Move constructor
0103     FitParameters(FitParameters&& other) = default;
0104     /// @brief Copy assignment operator
0105     FitParameters& operator=(const FitParameters& other) = default;
0106     /// @brief Move assignment operator
0107     FitParameters& operator=(FitParameters&& other) = default;
0108     /// @brief Ostream operator
0109     friend std::ostream& operator<<(std::ostream& ostr,
0110                                     const FitParameters& x) {
0111       x.print(ostr);
0112       return ostr;
0113     }
0114     /// @brief Print function
0115     void print(std::ostream& ostr) const;
0116     /// @brief Local straight line parameters
0117     ParamVec_t parameters{filledArray<double, s_nPars>(0)};
0118     /// @brief Covariance on the local line parameters
0119     CovMat_t covariance{CovMat_t::Identity()};
0120     /// @brief Number of degrees of freedom
0121     std::size_t nDoF{0};
0122     /// @brief Fitted chi2
0123     double chi2{0.};
0124     /// @brief Number of iterations to converge
0125     std::size_t nIter{0};
0126     /// @brief Convergence of the fit
0127     bool converged{false};
0128   };
0129   /// @brief  Fit parameters together with the calibrated measurements.
0130   /// @tparam Cont_t Space point container type
0131   template <CompositeSpacePointContainer Cont_t>
0132   struct FitResult : public FitParameters {
0133     /// @param List of measurements post-fit
0134     Cont_t measurements{};
0135   };
0136 
0137   /// @brief Configuration object parsed per each fit. It contains the
0138   ///        measurement container, a pointer to the measurement calibrator +
0139   ///        calibration context, a delegate used to sort out badly calibrated
0140   ///        measurements, and also initial start parameters stemming from an
0141   ///        external seeder.
0142   template <CompositeSpacePointContainer Cont_t,
0143             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0144   struct FitOptions {
0145     /// @brief List of measurements to fit
0146     Cont_t measurements{};
0147     /// @brief Abrivation of the SpacePoint type
0148     using Sp_t = SpacePoint_t<Cont_t>;
0149     /// @brief Good hit selector
0150     Selector_t<Sp_t> selector{};
0151     /// @brief Calibrator
0152     const Calibrator_t* calibrator{nullptr};
0153     /// @brief Experiment specific calibration context
0154     Acts::CalibrationContext calibContext{};
0155     /// @brief Local to global transform
0156     Acts::Transform3 localToGlobal{Acts::Transform3::Identity()};
0157     /// @brief Initial parameter guess
0158     ParamVec_t startParameters{filledArray<double, s_nPars>(0)};
0159     /// @brief Standard constructor
0160     FitOptions() = default;
0161   };
0162 
0163   /// @brief Struct counting the different types of degrees of freedom.
0164   struct DoFcounts {
0165     /// @brief Measurement in the non-bending coordinate
0166     std::size_t nonBending{0u};
0167     /// @brief Measurement in the bending coordinate
0168     std::size_t bending{0u};
0169     /// @brief Time measurement
0170     std::size_t time{0u};
0171     /// @brief Straw measurement
0172     std::size_t straw{0u};
0173   };
0174 
0175   /// @brief Class constructor
0176   /// @param cfg Reference to the fitter configuration object
0177   /// @param logger Logger object used for debug print out
0178   explicit CompositeSpacePointLineFitter(
0179       const Config& cfg,
0180       std::unique_ptr<const Logger> logger = getDefaultLogger(
0181           "CompositeSpacePointLineFitter", Logging::Level::INFO));
0182   /// @brief Returns the instantiated configuration object
0183   const Config& config() const { return m_cfg; }
0184   /// @brief Classify measurements according to whether they measure
0185   ///        loc0, loc1, time or are straw measurements
0186   /// @param measurements: Collection of composite space points of interest
0187   template <CompositeSpacePointContainer Cont_t>
0188   DoFcounts countDoF(const Cont_t& measurements) const;
0189   /// @brief Classify measurements according to whether they measure
0190   ///        loc0, loc1, time or are straw measurements
0191   /// @param measurements: Collection of composite space points of interest
0192   /// @param selector: Delegate to sort out the invalid measurements
0193   template <CompositeSpacePointContainer Cont_t>
0194   DoFcounts countDoF(const Cont_t& measurements,
0195                      const Selector_t<SpacePoint_t<Cont_t>>& selector) const;
0196 
0197   /// @brief Helper function to extract which parameters shall be
0198   ///        extracted from the hit counts.
0199   /// @param hitCounts: Filled array representing the degrees of freedom for
0200   ///                   nonBending, bending, timeStrip, and straw measurement
0201   std::vector<FitParIndex> extractFitablePars(const DoFcounts& hitCounts) const;
0202   /// @brief Fit a line to a set of Composite space point measurements.
0203   /// @param fitOpts: Auxiliary object carrying all necessary input
0204   ///                 needed to execute the fit
0205   template <CompositeSpacePointContainer Cont_t,
0206             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0207   FitResult<Cont_t> fit(FitOptions<Cont_t, Calibrator_t>&& fitOpts) const;
0208 
0209  private:
0210   /// @brief Enumeration to classify the parameter update
0211   enum class UpdateStep : std::uint8_t {
0212     goodStep = 0,     // Good step proceed with fit
0213     converged = 1,    // The fit converged
0214     outOfBounds = 2,  // Too many fit parameters fell out of bounds -> abort
0215   };
0216 
0217   /// @brief Checks whether the parameters from the iteration or the final result parameters
0218   ///        remain within the intervals defined by the user.
0219   /// @param pars: Line parameters to check
0220   /// @param parsToUse: Which parameters are altered by the fit
0221   bool withinRange(const ParamVec_t& pars,
0222                    const std::vector<FitParIndex>& parsToUse) const;
0223   /// @brief Checks whether a parameter value is within the range intreval defined by the user
0224   /// @param parValue: Value of the line parameter to check
0225   /// @param fitPar: Parameter index to which the value corresponds and which interval shall be picked
0226   bool withinRange(const double parValue, const FitParIndex fitPar) const;
0227   /// @brief Abrivation of the fit result returned by the FastStrawLineFitter
0228   using FastFitResult = std::optional<FastFitter_t::FitResult>;
0229   using FastFitResultT0 = std::optional<FastFitter_t::FitResultT0>;
0230 
0231   /// @brief Combine the two return types into a single conditional
0232   template <bool fitTime>
0233   using DelegateRet_t =
0234       std::conditional_t<fitTime, FastFitResultT0, FastFitResult>;
0235   /// @brief Abrivation of the standard function wrapping the call to the precision fitter
0236   template <CompositeSpacePointContainer Cont_t, bool fitTime>
0237   using FastFitDelegate_t = std::function<DelegateRet_t<fitTime>(
0238       const Cont_t& measurements, const std::vector<int>& strawSigns)>;
0239   /// @brief Executes a fast (pre)fit using the FastStrawLineFitter. First the parameters
0240   ///        (theta, y0) are fitted using the straw measurements only, if
0241   ///        present. Otherwise, strips measuring the bending direction are
0242   ///        used. If non-bending information (x0, phi) is also available, a
0243   ///        second strip fit is executed and the directional parameters are
0244   ///        combined, but the covariance ignores a correlation between them.
0245   /// @param measurements: List of measurements to fit
0246   /// @param initialGuess: Line representing the start parameters parsed by the user. Needed to determine
0247   ///                      the L<->R ambiguity of the straws
0248   /// @param parsToUse: List of parameters to fit (y0, theta), (x0, phi) or (y0, theta, x0, phi).
0249   /// @param precFitDelegate: Delegate function to call the fast fitter for to perform the precision fit
0250   template <bool fitStraws, bool fitTime, CompositeSpacePointContainer Cont_t>
0251   FitParameters fastFit(
0252       const Cont_t& measurements, const Line_t& initialGuess,
0253       const std::vector<FitParIndex>& parsToUse,
0254       const FastFitDelegate_t<Cont_t, fitTime>& precFitDelegate) const;
0255 
0256   /// @brief Executes the fast fit in the bending direction.
0257   /// @param measurements: List of measurements to fit
0258   /// @param initialGuess: Line representing the start parameters parsed by the user. Needed to determine
0259   ///                      the L<->R ambiguity of the straws
0260   /// @param delegate: Delegate function to call the fast fitter for to perform the precision fit
0261   template <bool fitStraws, bool fitTime, CompositeSpacePointContainer Cont_t>
0262   DelegateRet_t<fitTime> fastPrecFit(
0263       const Cont_t& measurements, const Line_t& initialGuess,
0264       const FastFitDelegate_t<Cont_t, fitTime>& delegate) const;
0265 
0266   /// @brief Executes the fast fit in the non-bending direction. In case of success, the
0267   ///        fitted angle is overwritten with tanAlpha for an easier combination
0268   ///        with the precision fit
0269   /// @param measurements: List of measurements to fit
0270   template <CompositeSpacePointContainer Cont_t>
0271   FastFitResult fastNonPrecFit(const Cont_t& measurements) const;
0272   /// @brief Update the straight line parameters based on the current chi2 and its
0273   ///        derivatives. Returns whether the parameter update succeeded or was
0274   ///        sufficiently small such that the fit is converged
0275   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0276   ///            both intercepts & angles, all 5 straight line parameters
0277   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0278   ///                  Toggles between x0 + phi vs y0 + theta fits
0279   /// @param cache: Evaluated chi2 & derivatives needed to calculate the update step via
0280   ///               Newton's method
0281   /// @param currentPars: Mutable referebce to the line parameter values at the current iteration
0282   template <unsigned N>
0283   UpdateStep updateParameters(const FitParIndex firstPar, ChiSqCache& cache,
0284                               ParamVec_t& currentPars) const
0285     requires(N >= 2 && N <= s_nPars);
0286 
0287   /// @brief Copies the inverse of the chi2's Hessian
0288   ///        to the covariance matrix of the fit
0289   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0290   ///            both intercepts & angles, all 5 straight line parameters
0291   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0292   ///                  Toggles between x0 + phi vs y0 + theta fits
0293   /// @param hessian: Reference to the Hessian matrix
0294   /// @param covariance: Reference to the covariance matrix
0295   template <unsigned N>
0296   void fillCovariance(const FitParIndex firstPar, const CovMat_t& hessian,
0297                       CovMat_t& covariance) const
0298     requires(N >= 2 && N <= s_nPars);
0299   /// @brief Reference to the logger object
0300   const Logger& logger() const { return *m_logger; }
0301 
0302   /// @brief Configuration object of the fitter
0303   Config m_cfg{};
0304   /// @brief Logger instance
0305   std::unique_ptr<const Logger> m_logger{};
0306   /// @brief Helper function to create the fast fitter configuration object
0307   detail::FastStrawLineFitter::Config fastFitterCfg() const;
0308   /// @brief Instance of the fast line fitter
0309   detail::FastStrawLineFitter m_fastFitter{fastFitterCfg(), logger().clone()};
0310 };
0311 
0312 }  // namespace Acts::Experimental
0313 
0314 #include "Acts/Seeding/CompositeSpacePointLineFitter.ipp"