Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-13 08:15:51

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 
0038   ///@brief During the repetitive recalibration, single hits may be invalidated
0039   ///       under the track parameters. Define a Delegate to sort out the
0040   ///       invalid hits
0041   template <CompositeSpacePoint Sp_t>
0042   using Selector_t = Delegate<bool(const Sp_t&)>;
0043   /// @brief Abrivation of the underlying space point type
0044   template <CompositeSpacePointContainer Cont_t>
0045   using SpacePoint_t = RemovePointer_t<typename Cont_t::value_type>;
0046 
0047   static constexpr auto s_nPars = toUnderlying(FitParIndex::nPars);
0048   /// @brief Vector containing the 5 straight segment line parameters
0049   using ParamVec_t = std::array<double, s_nPars>;
0050   /// @brief Covariance estimation matrix on the segment line parameters
0051   using CovMat_t = Acts::ActsSquareMatrix<s_nPars>;
0052   /// @brief Fitter configuration object
0053   struct Config {
0054     /// @brief If the parameter change or the gradient's magnitude is below the cutOff the fit is converged
0055     double precCutOff{1.e-7};
0056     /// @brief Gradient decent step size if the Hessian is singular
0057     double gradientStep{1.e-4};
0058     /// @brief Number of iterations
0059     std::size_t maxIter{1000};
0060     /// @brief Fit the time offset if possible
0061     bool fitT0{false};
0062     /// @brief Recalibrate the hits between two iterations
0063     bool recalibrate{false};
0064     /// @brief Switch to use the fast fitter if only straw measurements are passed
0065     bool useFastFitter{false};
0066     /// @brief Threshold on the fast straw chi2 above which the fit is reattempted but with
0067     ///        swapped straw signs.
0068     double badFastChi2SignSwap{5.};
0069     /// @brief Switch to use the fast fitter as pre-fitter. The flag useFastFitter needs to be enabled
0070     bool fastPreFitter{true};
0071     /// @brief Use the second derivative in the residual calculation
0072     bool useHessian{false};
0073     /// @brief Flag toggling whether the along the wire component of straws shall be calculated
0074     ///        if provided by the straw measurement.
0075     bool calcAlongStraw{true};
0076     /// @brief Flag toggling whether the residual along the strip direction
0077     ///        shall be calculated if the space point does not measure both
0078     ///        spatial coordinates on the plane
0079     bool calcAlongStrip{true};
0080     /// @brief  Include the time of flight assuming that the particle travels with the
0081     ///         speed of light in the time residual calculations
0082     bool includeToF{true};
0083     /// @brief Abort the fit as soon as more than n parameters leave the fit range
0084     std::size_t nParsOutOfBounds{1};
0085     /// @brief Allowed parameter ranges
0086     using RangeArray = std::array<std::array<double, 2>, s_nPars>;
0087     RangeArray ranges{};
0088   };
0089 
0090   /// @brief Class constructor
0091   /// @param cfg Reference to the fitter configuration object
0092   /// @param logger
0093   explicit CompositeSpacePointLineFitter(
0094       const Config& cfg,
0095       std::unique_ptr<const Logger> logger = getDefaultLogger(
0096           "CompositeSpacePointLineFitter", Logging::Level::INFO));
0097 
0098   /// @brief Auxiliary object to store the fitted parameters, covariance,
0099   ///        the chi2 / nDoF & the number of required iterations
0100   struct FitParameters {
0101     /// @brief Default constructor
0102     FitParameters() = default;
0103     /// @brief Copy constructor
0104     FitParameters(const FitParameters& other) = default;
0105     /// @brief Move constructor
0106     FitParameters(FitParameters&& other) = default;
0107     /// @brief Copy assignment operator
0108     FitParameters& operator=(const FitParameters& other) = default;
0109     /// @brief Move assignment operator
0110     FitParameters& operator=(FitParameters&& other) = default;
0111     /// @brief Ostream operator
0112     friend std::ostream& operator<<(std::ostream& ostr,
0113                                     const FitParameters& x) {
0114       x.print(ostr);
0115       return ostr;
0116     }
0117     /// @brief Print function
0118     void print(std::ostream& ostr) const;
0119     /// @brief Local straight line parameters
0120     ParamVec_t parameters{filledArray<double, s_nPars>(0)};
0121     /// @brief Covariance on the local line parameters
0122     CovMat_t covariance{CovMat_t::Identity()};
0123     /// @brief Number of degrees of freedom
0124     std::size_t nDoF{0};
0125     /// @brief Fitted chi2
0126     double chi2{0.};
0127     /// @brief Number of iterations to converge
0128     std::size_t nIter{0};
0129     /// @brief Convergence of the fit
0130     bool converged{false};
0131   };
0132   /// @brief  Fit parameters together with the calibrated measurements.
0133   /// @tparam Cont_t Space point container type
0134   template <CompositeSpacePointContainer Cont_t>
0135   struct FitResult : public FitParameters {
0136     /// @param List of measurements post-fit
0137     Cont_t measurements{};
0138   };
0139 
0140   /// @brief Configuration object parsed per each fit. It contains the
0141   ///        measurement container, a pointer to the measurement calibrator +
0142   ///        calibration context, a delegate used to sort out badly calibrated
0143   ///        measurements, and also initial start parameters stemming from an
0144   ///        external seeder.
0145   template <CompositeSpacePointContainer Cont_t,
0146             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0147   struct FitOptions {
0148     /// @brief List of measurements to fit
0149     Cont_t measurements{};
0150     /// @brief Abrivation of the SpacePoint type
0151     using Sp_t = SpacePoint_t<Cont_t>;
0152     /// @brief Good hit selector
0153     Selector_t<Sp_t> selector{};
0154     /// @brief Calibrator
0155     const Calibrator_t* calibrator{nullptr};
0156     /// @brief Experiment specific calibration context
0157     Acts::CalibrationContext calibContext{};
0158     /// @brief Local to global transform
0159     Acts::Transform3 localToGlobal{Acts::Transform3::Identity()};
0160     /// @brief Initial parameter guess
0161     ParamVec_t startParameters{filledArray<double, s_nPars>(0)};
0162     /// @brief Standard constructor
0163     FitOptions() = default;
0164   };
0165   /// @brief Counts how many measurements measure loc0, loc1 & time
0166   /// @param measurements: Collection of composite space points of interest
0167   template <CompositeSpacePointContainer Cont_t>
0168   std::array<std::size_t, 3> countDoF(const Cont_t& measurements) const;
0169   /// @brief Counts how many measurements measure loc0, loc1 & time
0170   /// @param measurements: Collection of composite space points of interest
0171   /// @param selector: Delegate to sort out the invalid measurements
0172   template <CompositeSpacePointContainer Cont_t>
0173   std::array<std::size_t, 3> countDoF(
0174       const Cont_t& measurements,
0175       const Selector_t<SpacePoint_t<Cont_t>>& selector) const;
0176 
0177   /// @brief Helper function to extract which parameters shall be
0178   ///        extracted from the hit counts.
0179   /// @param hitCounts: Filled array representing the degrees of freedom for
0180   ///                    nonBending, bending & time
0181   static std::vector<FitParIndex> extractFitablePars(
0182       const std::array<std::size_t, 3>& hitCounts);
0183 
0184   template <CompositeSpacePointContainer Cont_t,
0185             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0186   FitResult<Cont_t> fit(FitOptions<Cont_t, Calibrator_t>&& fitOpts) const;
0187 
0188  private:
0189   /// @brief Enumeration to classify the parameter update
0190   enum class UpdateStep : std::uint8_t {
0191     goodStep = 0,     // Good step proceed with fit
0192     converged = 1,    // The fit converged
0193     outOfBounds = 2,  // Too many fit parameters fell out of bounds -> abort
0194   };
0195 
0196   /// @brief Executes a fast (pre)fit using the FastStrawLineFitter. First the parameters
0197   ///        (theta, y0) are fitted using the straw measurements only, if
0198   ///        present. Otherwise, strips measuring the bending direction are
0199   ///        used. If non-bending information (x0, phi) is also available, a
0200   ///        second strip fit is executed and the directional parameters are
0201   ///        combined, but the covariance ignores a correlation between them.
0202   /// @param measurements: List of measurements to fit
0203   /// @param initialGuess: Line representing the start parameters parsed by the user. Needed to determine
0204   ///                      the L<->R ambiguity of the straws
0205   /// @param parsToUse: List of parameters to fit (y0, theta), (x0, phi) or (y0, theta, x0, phi).
0206   template <CompositeSpacePointContainer Cont_t>
0207   FitParameters fastFit(const Cont_t& measurements, const Line_t& initialGuess,
0208                         const std::vector<FitParIndex>& parsToUse) const;
0209 
0210   using FastFitResult = std::optional<detail::FastStrawLineFitter::FitResult>;
0211 
0212   /// @brief Executes the fast line fit in the bending direction. Returns
0213   ///        the result containing the chi2 and the parameters from the fast
0214   ///        fitter if succeeds otherwise a nullopt
0215   /// @param measurements: List of measurements to be fitted. Only the ones with measuresLoc1() are
0216   ///                       considered by the fast fitter
0217   /// @param initialGuess: Instantiated line from the start parameters needed for the L<->R ambiguity
0218   /// @param parsToUse: List of parameters to fit. Used as an initial check to ensure that there're
0219   ///                   at least enough measurements parsed for the fit.
0220   template <CompositeSpacePointContainer Cont_t>
0221   FastFitResult fastPrecFit(const Cont_t& measurements,
0222                             const Line_t& initialGuess,
0223                             const std::vector<FitParIndex>& parsToUse) const;
0224 
0225   /// @brief Update the straight line parameters based on the current chi2 and its
0226   ///        derivatives. Returns whether the parameter update succeeded or was
0227   ///        sufficiently small such that the fit is converged
0228   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0229   ///            both intercepts & angles, all 5 straight line parameters
0230   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0231   ///                  Toggles between x0 + phi vs y0 + theta fits
0232   /// @param cache: Evaluated chi2 & derivatives needed to calculate the update step via
0233   ///               Newton's method
0234   /// @param currentPars: Mutable referebce to the line parameter values at the current iteration
0235   template <unsigned N>
0236   UpdateStep updateParameters(const FitParIndex firstPar,
0237                               const ChiSqCache& cache,
0238                               ParamVec_t& currentPars) const
0239     requires(N >= 2 && N <= s_nPars);
0240   /// @brief Copies the inverse of the chi2's Hessian
0241   ///        to the covariance matrix of the fit
0242   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0243   ///            both intercepts & angles, all 5 straight line parameters
0244   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0245   ///                  Toggles between x0 + phi vs y0 + theta fits
0246   /// @param hessian: Reference to the Hessian matrix
0247   /// @param covariance: Reference to the covariance matrix
0248   template <unsigned N>
0249   void fillCovariance(const FitParIndex firstPar, const CovMat_t& hessian,
0250                       CovMat_t& covariance) const
0251     requires(N >= 2 && N <= s_nPars);
0252   /// @brief Reference to the logger object
0253   const Logger& logger() const { return *m_logger; }
0254 
0255   /// @brief Configuration object of the fitter
0256   Config m_cfg{};
0257   /// @brief Logger instance
0258   std::unique_ptr<const Logger> m_logger{};
0259   /// @brief Helper function to create the fast fitter configuration object
0260   detail::FastStrawLineFitter::Config fastFitterCfg() const;
0261   /// @brief Instance of the fast line fitter
0262   detail::FastStrawLineFitter m_fastFitter{fastFitterCfg(), logger().clone()};
0263 };
0264 
0265 }  // namespace Acts::Experimental
0266 
0267 #include "Acts/Seeding/CompositeSpacePointLineFitter.ipp"