Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-14 09:39:38

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   /// @brief Auxiliary object to store the fitted parameters, covariance,
0090   ///        the chi2 / nDoF & the number of required iterations
0091   struct FitParameters {
0092     /// @brief Default constructor
0093     FitParameters() = default;
0094     /// @brief Copy constructor
0095     FitParameters(const FitParameters& other) = default;
0096     /// @brief Move constructor
0097     FitParameters(FitParameters&& other) = default;
0098     /// @brief Copy assignment operator
0099     FitParameters& operator=(const FitParameters& other) = default;
0100     /// @brief Move assignment operator
0101     FitParameters& operator=(FitParameters&& other) = default;
0102     /// @brief Ostream operator
0103     friend std::ostream& operator<<(std::ostream& ostr,
0104                                     const FitParameters& x) {
0105       x.print(ostr);
0106       return ostr;
0107     }
0108     /// @brief Print function
0109     void print(std::ostream& ostr) const;
0110     /// @brief Local straight line parameters
0111     ParamVec_t parameters{filledArray<double, s_nPars>(0)};
0112     /// @brief Covariance on the local line parameters
0113     CovMat_t covariance{CovMat_t::Identity()};
0114     /// @brief Number of degrees of freedom
0115     std::size_t nDoF{0};
0116     /// @brief Fitted chi2
0117     double chi2{0.};
0118     /// @brief Number of iterations to converge
0119     std::size_t nIter{0};
0120     /// @brief Convergence of the fit
0121     bool converged{false};
0122   };
0123   /// @brief  Fit parameters together with the calibrated measurements.
0124   /// @tparam Cont_t Space point container type
0125   template <CompositeSpacePointContainer Cont_t>
0126   struct FitResult : public FitParameters {
0127     /// @param List of measurements post-fit
0128     Cont_t measurements{};
0129   };
0130 
0131   /// @brief Configuration object parsed per each fit. It contains the
0132   ///        measurement container, a pointer to the measurement calibrator +
0133   ///        calibration context, a delegate used to sort out badly calibrated
0134   ///        measurements, and also initial start parameters stemming from an
0135   ///        external seeder.
0136   template <CompositeSpacePointContainer Cont_t,
0137             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0138   struct FitOptions {
0139     /// @brief List of measurements to fit
0140     Cont_t measurements{};
0141     /// @brief Abrivation of the SpacePoint type
0142     using Sp_t = SpacePoint_t<Cont_t>;
0143     /// @brief Good hit selector
0144     Selector_t<Sp_t> selector{};
0145     /// @brief Calibrator
0146     const Calibrator_t* calibrator{nullptr};
0147     /// @brief Experiment specific calibration context
0148     Acts::CalibrationContext calibContext{};
0149     /// @brief Local to global transform
0150     Acts::Transform3 localToGlobal{Acts::Transform3::Identity()};
0151     /// @brief Initial parameter guess
0152     ParamVec_t startParameters{filledArray<double, s_nPars>(0)};
0153     /// @brief Standard constructor
0154     FitOptions() = default;
0155   };
0156 
0157   /// @brief Struct counting the different types of degrees of freedom.
0158   struct DoFcounts {
0159     /// @brief Measurement in the non-bending coordinate
0160     std::size_t nonBending{0u};
0161     /// @brief Measurement in the bending coordinate
0162     std::size_t bending{0u};
0163     /// @brief Time measurement
0164     std::size_t time{0u};
0165     /// @brief Straw measurement
0166     std::size_t straw{0u};
0167   };
0168 
0169   /// @brief Class constructor
0170   /// @param cfg Reference to the fitter configuration object
0171   /// @param logger Logger object used for debug print out
0172   explicit CompositeSpacePointLineFitter(
0173       const Config& cfg,
0174       std::unique_ptr<const Logger> logger = getDefaultLogger(
0175           "CompositeSpacePointLineFitter", Logging::Level::INFO));
0176   /// @brief Returns the instantiated configuration object
0177   const Config& config() const { return m_cfg; }
0178   /// @brief Classify measurements according to whether they measure
0179   ///        loc0, loc1, time or are straw measurements
0180   /// @param measurements: Collection of composite space points of interest
0181   template <CompositeSpacePointContainer Cont_t>
0182   DoFcounts countDoF(const Cont_t& measurements) const;
0183   /// @brief Classify measurements according to whether they measure
0184   ///        loc0, loc1, time or are straw measurements
0185   /// @param measurements: Collection of composite space points of interest
0186   /// @param selector: Delegate to sort out the invalid measurements
0187   template <CompositeSpacePointContainer Cont_t>
0188   DoFcounts countDoF(const Cont_t& measurements,
0189                      const Selector_t<SpacePoint_t<Cont_t>>& selector) const;
0190 
0191   /// @brief Helper function to extract which parameters shall be
0192   ///        extracted from the hit counts.
0193   /// @param hitCounts: Filled array representing the degrees of freedom for
0194   ///                   nonBending, bending, timeStrip, and straw measurement
0195   std::vector<FitParIndex> extractFitablePars(const DoFcounts& hitCounts) const;
0196   /// @brief Fit a line to a set of Composite space point measurements.
0197   /// @param fitOpts: Auxiliary object carrying all necessary input
0198   ///                 needed to execute the fit
0199   template <CompositeSpacePointContainer Cont_t,
0200             CompositeSpacePointCalibrator<Cont_t, Cont_t> Calibrator_t>
0201   FitResult<Cont_t> fit(FitOptions<Cont_t, Calibrator_t>&& fitOpts) const;
0202 
0203  private:
0204   /// @brief Enumeration to classify the parameter update
0205   enum class UpdateStep : std::uint8_t {
0206     goodStep = 0,     // Good step proceed with fit
0207     converged = 1,    // The fit converged
0208     outOfBounds = 2,  // Too many fit parameters fell out of bounds -> abort
0209   };
0210 
0211   /// @brief Executes a fast (pre)fit using the FastStrawLineFitter. First the parameters
0212   ///        (theta, y0) are fitted using the straw measurements only, if
0213   ///        present. Otherwise, strips measuring the bending direction are
0214   ///        used. If non-bending information (x0, phi) is also available, a
0215   ///        second strip fit is executed and the directional parameters are
0216   ///        combined, but the covariance ignores a correlation between them.
0217   /// @param measurements: List of measurements to fit
0218   /// @param initialGuess: Line representing the start parameters parsed by the user. Needed to determine
0219   ///                      the L<->R ambiguity of the straws
0220   /// @param nStraws: number of straw measurements
0221   /// @param parsToUse: List of parameters to fit (y0, theta), (x0, phi) or (y0, theta, x0, phi).
0222   template <CompositeSpacePointContainer Cont_t>
0223   FitParameters fastFit(const Cont_t& measurements, const Line_t& initialGuess,
0224                         const std::size_t nStraws,
0225                         const std::vector<FitParIndex>& parsToUse) const;
0226 
0227   /// @brief Executes a fast (pre)fit using the FastStrawLineFitter. First the parameters
0228   ///        (theta, y0 and t0) are fitted using the straw measurements only.
0229   ///        If non-bending information (x0, phi) is also available, a
0230   ///        second strip fit is executed and the directional parameters are
0231   ///        combined, but the covariance ignores a correlation between them.
0232   /// @param ctx: Experiment specific calibration context
0233   /// @param calibrator: Calibrator
0234   /// @param measurements: List of measurements to fit
0235   /// @param initialGuess: Instantiated line from the start parameters needed for the L<->R ambiguity
0236   /// @param startT0: Initial guess for t0
0237   /// @param parsToUse: List of parameters to fit (y0, theta, t0) or (y0, theta, x0, phi, t0).
0238   template <
0239       CompositeSpacePointContainer Cont_t,
0240       CompositeSpacePointFastCalibrator<SpacePoint_t<Cont_t>> Calibrator_t>
0241   FitParameters fastFit(const Acts::CalibrationContext& ctx,
0242                         const Calibrator_t& calibrator,
0243                         const Cont_t& measurements, const Line_t& initialGuess,
0244                         const double startT0,
0245                         const std::vector<FitParIndex>& parsToUse) const;
0246 
0247   /// @brief Abrivation of the fit result returned by the FastStrawLineFitter
0248   using FastFitResult = std::optional<detail::FastStrawLineFitter::FitResult>;
0249   using FastFitResultT0 =
0250       std::optional<detail::FastStrawLineFitter::FitResultT0>;
0251 
0252   /// @brief Executes the fast line fit in the bending direction without time. The fit is performed
0253   ///        using straw measurements if at least 3 are provided, otherwise
0254   ///        strip measurements are used. Returns the result containing the chi2
0255   ///        and the parameters from the fast fitter if succeeds otherwise a
0256   ///        nullopt
0257   /// @param measurements: List of measurements to be fitted. Only the ones with measuresLoc1() are
0258   ///                      considered by the fast fitter
0259   /// @param initialGuess: Instantiated line from the start parameters needed for the L<->R ambiguity
0260   /// @param nStraws: number of straw measurements
0261   /// @param parsToUse: List of parameters to fit. Used as an initial check to ensure that there're
0262   ///                   at least enough measurements parsed for the fit.
0263   template <CompositeSpacePointContainer Cont_t>
0264   FastFitResult fastPrecFit(const Cont_t& measurements,
0265                             const Line_t& initialGuess,
0266                             const std::size_t nStraws,
0267                             const std::vector<FitParIndex>& parsToUse) const;
0268 
0269   /// @brief Executes the fast line fit in the bending direction with time. The fit is possible only
0270   ///        when at least 3 straw measurements are provided. Returns the result
0271   ///        containing the chi2 and the parameters from the fast fitter if
0272   ///        succeeds otherwise a nullopt
0273   /// @param ctx: Experiment specific calibration context
0274   /// @param calibrator: Calibrator
0275   /// @param measurements: List of measurements to be fitted. Only the ones with measuresLoc1() are
0276   ///                      considered by the fast fitter
0277   /// @param initialGuess: Instantiated line from the start parameters needed for the L<->R ambiguity
0278   /// @param initialT0: Initial guess for t0
0279   /// @param parsToUse: List of parameters to fit. Used as an initial check to ensure that there're
0280   ///                   at least enough measurements parsed for the fit.
0281   template <
0282       CompositeSpacePointContainer Cont_t,
0283       CompositeSpacePointFastCalibrator<SpacePoint_t<Cont_t>> Calibrator_t>
0284   FastFitResultT0 fastPrecFit(const Acts::CalibrationContext& ctx,
0285                               const Calibrator_t& calibrator,
0286                               const Cont_t& measurements,
0287                               const Line_t& initialGuess,
0288                               const double initialT0,
0289                               const std::vector<FitParIndex>& parsToUse) const;
0290 
0291   /// @brief Helper function that copies the precision fit result into the FitParameters fastFit
0292   ///        final result and combines it with a fast line fit in the
0293   ///        non-bending direction, when required.
0294   /// @param result: FitParameter obj that will contain the full result of the fastFit
0295   /// @param precResult: Result of the fast fit in the bending coordinate
0296   /// @param measurements: List of measurements to be fitted in the non-bending direction. Only the ones
0297   ///                      with measuresLoc0() are considered.
0298   /// @param parsToUse: List of parameters to fit. Used as an initial check to ensure that there're
0299   ///                   at least enough measurements parsed for the fast fit in
0300   ///                   the non-bending direction.
0301   /// @param fitT0: Flag that is true when the fast fit includes t0. Needed to toggle the chi2 computation
0302   ///               after the combination of bending and non-bending fit
0303   ///               results.
0304   template <CompositeSpacePointContainer Cont_t>
0305   void mergePrecAndNonPrec(FitParameters& result,
0306                            const FastFitResult& precResult,
0307                            const Cont_t& measurements,
0308                            const std::vector<FitParIndex>& parsToUse,
0309                            const bool fitT0 = false) const;
0310 
0311   /// @brief Update the straight line parameters based on the current chi2 and its
0312   ///        derivatives. Returns whether the parameter update succeeded or was
0313   ///        sufficiently small such that the fit is converged
0314   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0315   ///            both intercepts & angles, all 5 straight line parameters
0316   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0317   ///                  Toggles between x0 + phi vs y0 + theta fits
0318   /// @param cache: Evaluated chi2 & derivatives needed to calculate the update step via
0319   ///               Newton's method
0320   /// @param currentPars: Mutable referebce to the line parameter values at the current iteration
0321   template <unsigned N>
0322   UpdateStep updateParameters(const FitParIndex firstPar, ChiSqCache& cache,
0323                               ParamVec_t& currentPars) const
0324     requires(N >= 2 && N <= s_nPars);
0325 
0326   /// @brief Copies the inverse of the chi2's Hessian
0327   ///        to the covariance matrix of the fit
0328   /// @tparam N: Number of fitted parameters. Either 1 intercept + 1 angle (2D), 2D + time,
0329   ///            both intercepts & angles, all 5 straight line parameters
0330   /// @param firstPar: The first fitted straight line parameter in the parameter vector
0331   ///                  Toggles between x0 + phi vs y0 + theta fits
0332   /// @param hessian: Reference to the Hessian matrix
0333   /// @param covariance: Reference to the covariance matrix
0334   template <unsigned N>
0335   void fillCovariance(const FitParIndex firstPar, const CovMat_t& hessian,
0336                       CovMat_t& covariance) const
0337     requires(N >= 2 && N <= s_nPars);
0338   /// @brief Reference to the logger object
0339   const Logger& logger() const { return *m_logger; }
0340 
0341   /// @brief Configuration object of the fitter
0342   Config m_cfg{};
0343   /// @brief Logger instance
0344   std::unique_ptr<const Logger> m_logger{};
0345   /// @brief Helper function to create the fast fitter configuration object
0346   detail::FastStrawLineFitter::Config fastFitterCfg() const;
0347   /// @brief Instance of the fast line fitter
0348   detail::FastStrawLineFitter m_fastFitter{fastFitterCfg(), logger().clone()};
0349 };
0350 
0351 }  // namespace Acts::Experimental
0352 
0353 #include "Acts/Seeding/CompositeSpacePointLineFitter.ipp"