Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 08:11:35

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/Utilities/ArrayHelpers.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014 #include "Acts/Utilities/detail/Line3DWithPartialDerivatives.hpp"
0015 
0016 #include <cstdint>
0017 
0018 namespace Acts::Experimental::detail {
0019 /// @brief Helper class to calculate the residual between a straight line and
0020 ///        a CompositeSpacePoint measurement as well as the partial derivatives.
0021 ///        The residual is expressed as a 3D vector, where first two components
0022 ///        describe the spatial residual w.r.t. the precision & non-precision
0023 ///        direction, and the last one expresses the residual between the
0024 ///        parametrized time of arrival of the track and the measurement's
0025 ///        recorded time.
0026 ///
0027 ///        For straw type measurements, the precision residual is calculated as
0028 ///        the difference between the signed line distance between straw wire &
0029 ///        line, and the signed drift radius where the sign simply encodes the
0030 ///        left/right amibiguity. If the measurement additionally carries
0031 ///        information about the passage along the wire, the non-precision
0032 ///        residual is then defined to be the distance along the wire.
0033 ///
0034 ///        For strip type measurements, the residual is the distance in the
0035 ///        strip-readout plane between the point along the line that intersects
0036 ///        the plane spanned by the measurement.
0037 ///
0038 ///        If the strip measurements provide also the time of their record, the
0039 ///        residual calculation can be extended to the time of arrival parameter
0040 ///        The residual is then defined as the strip's recorded time minus the
0041 ///        time of flight of a particle on a straight line minus the time
0042 ///        offset.
0043 ///
0044 ///        Straw measurements are indirectly influenced by the time offset
0045 ///        parameter. The primary electrons produced by the traversing ionizing
0046 ///        particle drift towards the central straw wire. The drift time can be
0047 ///        directly mapped to the drift radius during the calibration procedure
0048 ///        where the rt relation and its first two derivatives are known
0049 ///        apprxomately. Further, it's assumed that the chip records are
0050 ///        composed timestamp that includes the drift time & the time of flight
0051 ///        of the ionizing particle. An update of the point of closest approach
0052 ///        leads to an indirect update of the drift radius and hence additional
0053 ///        terms need to be considered when calculating the residual's
0054 ///        derivatives.
0055 
0056 class CompSpacePointAuxiliaries {
0057  public:
0058   using Line_t = Acts::detail::Line3DWithPartialDerivatives<double>;
0059   using LineIndex = Line_t::ParIndex;
0060   using Vector = Line_t::Vector;
0061   enum class FitParIndex : std::uint8_t {
0062     x0 = toUnderlying(LineIndex::x0),
0063     y0 = toUnderlying(LineIndex::y0),
0064     theta = toUnderlying(LineIndex::theta),
0065     phi = toUnderlying(LineIndex::phi),
0066     t0 = 4,  // time offset
0067     nPars = 5
0068   };
0069   static constexpr auto s_nPars = toUnderlying(FitParIndex::nPars);
0070   /// @brief Prints a fit parameter as string
0071   static std::string parName(const FitParIndex idx);
0072   /// @brief Assignment of the residual components.
0073   enum class ResidualIdx : std::uint8_t {
0074     nonBending = 0,
0075     bending = 1,
0076     time = 2
0077   };
0078   /// @brief Configuration object of the residual calculator
0079   struct Config {
0080     /// @brief Transform to place the composite station frame inside the
0081     ///        global experiment's frame. Needed for the time residual
0082     ///        calculation with time of flight
0083     Acts::Transform3 localToGlobal{Acts::Transform3::Identity()};
0084     /// @brief Flag toggling whether the hessian of the residual shall be calculated
0085     bool useHessian{false};
0086     /// @brief Flag toggling whether the along the wire component of straws shall be calculated
0087     ///        if provided by the straw measurement.
0088     bool calcAlongStraw{true};
0089     /// @brief Flag toggling whether the residual along the strip direction
0090     ///        shall be calculated if the space point does not measure both
0091     ///        spatial coordinates on the plane
0092     bool calcAlongStrip{true};
0093     /// @brief  Include the time of flight assuming that the particle travels with the
0094     ///         speed of light in the time residual calculations
0095     bool includeToF{true};
0096     /// @brief List of fit parameters to which the partial derivative of the
0097     ///        residual shall be calculated
0098     std::vector<FitParIndex> parsToUse{FitParIndex::x0, FitParIndex::y0,
0099                                        FitParIndex::theta, FitParIndex::phi};
0100   };
0101   /// @brief Constructor to instantiate a new instance
0102   /// @param cfg: Configuration object to toggle the calculation of the complementary residual components & the full evaluation of the second derivative
0103   /// @param logger: New logging object for debugging
0104   explicit CompSpacePointAuxiliaries(
0105       const Config& cfg,
0106       std::unique_ptr<const Logger> logger =
0107           getDefaultLogger("CompSpacePointAuxiliaries", Logging::Level::INFO));
0108 
0109   /// @brief Updates the spatial residual components between the line and the passed
0110   ///        measurement. The result is cached internally and can be later
0111   ///        fetched by the residual(), gradient() and hessian() methods. If the
0112   ///        residual calculation fails due to parallel line & measurement, all
0113   ///        components are set to zero.
0114   /// @param line: Reference to the line to which the residual is calculated
0115   /// @param spacePoint: Reference to the space point measurement to which the residual is calculated
0116   template <CompositeSpacePoint Point_t>
0117   void updateSpatialResidual(const Line_t& line, const Point_t& spacePoint);
0118   /// @brief Updates all residual components between the line and the passed measurement
0119   ///        First the spatial components are calculated and then if the
0120   ///        measurement also provides time information, the time residual & its
0121   ///        derivatives are evaluated.
0122   /// @param line: Reference to the line to which the residual is calculated
0123   /// @param timeOffet: Value of the t0 fit parameter.
0124   /// @param spacePoint: Reference to the space point measurement to which the residual is calculated
0125   /// @param driftV: Associated drift velocity given as the derivative of the r-t relation
0126   /// @param driftA: Associated drift acceleration given as the second derivative of the r-t relation
0127   template <CompositeSpacePoint Point_t>
0128   void updateFullResidual(const Line_t& line, const double timeOffset,
0129                           const Point_t& spacePoint, const double driftV = 0.,
0130                           const double driftA = 0.);
0131 
0132   /// @brief Helper struct to calculate the overall chi2 from the composite space points
0133   struct ChiSqWithDerivatives {
0134     /// @brief Chi2 squared term
0135     double chi2{0.};
0136     /// @brief First derivative of the chi2 w.r.t. the fit parameters
0137     Acts::ActsVector<s_nPars> gradient{Acts::ActsVector<s_nPars>::Zero()};
0138     /// @brief Second derivative of the chi2 w.r.t. the fit parameters
0139     Acts::ActsSquareMatrix<s_nPars> hessian{
0140         Acts::ActsSquareMatrix<s_nPars>::Zero()};
0141     /// @brief Set the chi2, the gradient and hessian back to zero
0142     void reset();
0143   };
0144   /// @brief Updates the passed chi2 object by adding up the residual contributions
0145   ///        from the previous composite space point used to update the
0146   ///        Auxiliary class. For the Hessian term only the lower triangle is
0147   ///        updated. The other triangle needs to be copied later from the lower
0148   ///        one.
0149   /// @param chiSqObj: Chi2 & derivatives to be updated
0150   /// @param cov: The composite space point's covariance values
0151   void updateChiSq(ChiSqWithDerivatives& chiSqObj,
0152                    const std::array<double, 3>& cov) const;
0153 
0154   /// @brief Returns the previously calculated residual.
0155   const Vector& residual() const;
0156   /// @brief Returns the gradient of the previously calculated residual
0157   /// @param par: Index of the partiald derivative
0158   const Vector& gradient(const FitParIndex param) const;
0159   /// @brief Returns the gradient of the previously calculated residual
0160   /// @param param1: First index of the second partial derivative
0161   /// @param param2: Second index of the second partial derivative
0162   const Vector& hessian(const FitParIndex param1,
0163                         const FitParIndex param2) const;
0164   /// @brief Returns whether the passed parameter describes a direction angle
0165   static constexpr bool isDirectionParam(const FitParIndex param) {
0166     return param == FitParIndex::theta || param == FitParIndex::phi;
0167   }
0168   /// @brief Returns whether the passed parameter describes the displacement
0169   ///        in the reference plane
0170   static constexpr bool isPositionParam(const FitParIndex param) {
0171     return param == FitParIndex::x0 || param == FitParIndex::y0;
0172   }
0173   /// @brief Extrapolates the straight line onto the space point's strip-plane defined by the
0174   ///         `localPosition()` and the `planeNormal()`
0175   /// @param line: Reference to the line of interest
0176   /// @param hit: Reference to the hit of interest
0177   template <CompositeSpacePoint SpacePoint_t>
0178   static Vector extrapolateToPlane(const Line_t& line, const SpacePoint_t& hit);
0179   /// @brief Extrapolates the straight line parametrized by a point and a direction
0180   ///        onto the space point's strip-plane defined by the
0181   ///         `localPosition()` and the `planeNormal()`
0182   /// @param pos: Point on the line
0183   /// @param dir: Direction of the line
0184   /// @param hit: Reference to the hit of interest
0185   template <CompositeSpacePoint SpacePoint_t>
0186   static Vector extrapolateToPlane(const Vector& pos, const Vector& dir,
0187                                    const SpacePoint_t& hit);
0188   /// @brief Calculates the spaztial chiSq term of a composite space point to a line
0189   /// @param line: Reference to the line of interest
0190   /// @param hit: Reference to the hit of interest
0191   template <CompositeSpacePoint SpacePoint_t>
0192   static double chi2Term(const Line_t& line, const SpacePoint_t& hit);
0193   /// @brief Calculates the spatial chiSq term of a composite space point to a line parameterized
0194   ///         by a position & direction vector
0195   /// @param pos: Point on the line
0196   /// @param dir: Direction of the line
0197   /// @param hit: Reference to the hit of interest
0198   template <CompositeSpacePoint SpacePoint_t>
0199   static double chi2Term(const Vector& pos, const Vector& dir,
0200                          const SpacePoint_t& hit);
0201   /// @brief Calculates the chiSq term of a composite space point to a line taking into account
0202   ///        the time offset t0
0203   /// @param line: Reference to the line of interest
0204   /// @param t0: Time off set evaluated at the measurement's plane
0205   /// @param hit: Reference to the hit of interest
0206   template <CompositeSpacePoint SpacePoint_t>
0207   static double chi2Term(const Line_t& line, const double t0,
0208                          const SpacePoint_t& hit);
0209   /// @brief Calculates the chiSq term of a composite space point to a line taking into account
0210   ///        the time offset t0
0211   /// @param pos: Point on the line
0212   /// @param dir: Direction of the line
0213   /// @param t0: Time off set evaluated at the measurement's plane
0214   /// @param hit: Reference to the hit of interest
0215   template <CompositeSpacePoint SpacePoint_t>
0216   static double chi2Term(const Vector& pos, const Vector& dir, const double t0,
0217                          const SpacePoint_t& hit);
0218   ///  @brief Calculates the chiSq term of a composite space point taking into account
0219   ///        the time offset t0 & the time of arrival of the particle assuming
0220   ///        the speed of light
0221   /// @param line: Reference to the line of interest
0222   /// @param t0: Time off set evaluated at the measurement's plane
0223   /// @param hit: Reference to the hit of interest
0224   template <CompositeSpacePoint SpacePoint_t>
0225   static double chi2Term(const Line_t& line,
0226                          const Acts::Transform3& localToGlobal, const double t0,
0227                          const SpacePoint_t& hit);
0228   ///  @brief Calculates the chiSq term of a composite space point taking into account
0229   ///        the time offset t0 & the time of arrival of the particle assuming
0230   ///        the speed of light
0231   /// @param pos: Point on the line
0232   /// @param dir: Direction of the line
0233   /// @param t0: Time off set evaluated at the measurement's plane
0234   /// @param hit: Reference to the hit of interest
0235   template <CompositeSpacePoint SpacePoint_t>
0236   static double chi2Term(const Vector& pos, const Vector& dir,
0237                          const Acts::Transform3& localToGlobal, const double t0,
0238                          const SpacePoint_t& hit);
0239   /// @brief Calculate whether the track passed on the left (-1) or the right (1) side
0240   ///        of the straw wire. Returns 0 for strips
0241   /// @param line: Reference to the line of interest
0242   /// @param strawSp: Straw measurement of interest
0243   template <CompositeSpacePoint Point_t>
0244   static int strawSign(const Line_t& line, const Point_t& strawSp);
0245   /// @brief Calculate whether a generic line is on the left (-1) or right (1) side
0246   ///         of the straw wire. Return 0 for strip
0247   /// @param pos: Point on the line
0248   /// @param dir: Direction of the line
0249   /// @param strawSp: Straw measurement of interest
0250   template <CompositeSpacePoint Point_t>
0251   static int strawSign(const Vector& pos, const Vector& dir,
0252                        const Point_t& strawSp);
0253   /// @brief Calculate the straw signs for a set of measurements
0254   /// @param line: Reference to the line to which the residual is calculated
0255   /// @param measurements: List of straw measurements to calculate the signs for
0256   template <CompositeSpacePointContainer StrawCont_t>
0257   static std::vector<int> strawSigns(const Line_t& line,
0258                                      const StrawCont_t& measurements);
0259   /// @brief Calculate the straw signs for a set of measurements
0260   /// @param pos: Point on the line
0261   /// @param dir: Direction of the line
0262   /// @param measurements: List of straw measurements to calculate the signs for
0263   template <CompositeSpacePointContainer StrawCont_t>
0264   static std::vector<int> strawSigns(const Vector& pos, const Vector& dir,
0265                                      const StrawCont_t& measurements);
0266 
0267  private:
0268   /// @brief Reference to the logging object
0269   const Logger& logger() const { return *m_logger; }
0270   /// @brief  Update the auxiliary variables needed to calculate the residuals
0271   ///         of a straw measurement to the current line. They are the
0272   ///         projection of the line direction vector into the straw's wire
0273   ///         plane and its derivatives. Returns fals if line and wire are
0274   ///         parallel to each other
0275   /// @param line: Reference to the line to project
0276   /// @param wireDir: Reference to the straw wire direction vector
0277   bool updateStrawAuxiliaries(const Line_t& line, const Vector& wireDir);
0278   /// @brief Updates the residuals of a straw measurement to a line ignoring
0279   ///        the distance along the straw wire. Returns false if the residual
0280   ///        cannot be updated due to parallelism between straw wire and line
0281   /// @param line: Reference to the line to which the residual is calculated
0282   /// @param hitMinSeg: Difference of the line reference point & the straw
0283   ///                   position
0284   /// @param wireDir: Direction vector of the straw wire
0285   /// @param driftRadius: Measured radius of the straw measurement
0286   bool updateStrawResidual(const Line_t& line, const Vector& hitMinSeg,
0287                            const Vector& wireDir, const double driftRadius);
0288   /// @brief Calculates the along-the wire component of the straw
0289   ///        measurement's residual to the line
0290   /// @param line: Reference to the line to which the residual is calculated
0291   /// @param hitMinSeg: Difference of the straw position & the line reference point
0292   /// @param wireDir: Direction vector of the straw wire
0293   void updateAlongTheStraw(const Line_t& line, const Vector& hitMinSeg,
0294                            const Vector& wireDir);
0295   /// @brief Calculates the residual of a strip measurement w.r.t. the line
0296   /// @param line: Reference to the line to which the residual is calculated
0297   /// @param normal: Reference to the vector normal on the strip measurement plane
0298   /// @param sensorN: Reference to the first basis vector inside the strip measruement plane,
0299   ///            which is given by the sensor normal
0300   /// @param sensorD: Reference to the second basis vector inside the strip measruement plane,
0301   ///            which is given by the sensor direction
0302   /// @param stripPos: Position of the strip measurement
0303   /// @param isBending: Flag toggling whether the precision direction is constrained
0304   /// @param isNonBending: Flag toggling whether the non-precision direction is constrained
0305   void updateStripResidual(const Line_t& line, const Vector& normal,
0306                            const Vector& sensorN, const Vector& sensorD,
0307                            const Vector& stripPos, const bool isBending,
0308                            const bool isNonBending);
0309   /// @brief Calculates the reidual of a strip measurement w.r.t. the time offset parameter
0310   /// @param sensorN: Reference to the first basis vector inside the strip measruement plane,
0311   ///            which is given by the sensor normal
0312   /// @param sensorD: Reference to the second basis vector inside the strip measruement plane,
0313   ///            which is given by the sensor direction
0314   /// @param stripPos: Position of the strip measurement
0315   /// @param isBending: Flag toggling whether the precision direction is constrained
0316   /// @param recordTime: Time of the measurement
0317   /// @param timeOffet: Value of the t0 fit parameter.
0318   void updateTimeStripRes(const Vector& sensorN, const Vector& sensorD,
0319                           const Vector& stripPos, const bool isBending,
0320                           const double recordTime, const double timeOffset);
0321   /// @brief Calculates the residual derivatives of a straw tube measurement when the drift radius is
0322   //         an implicit function of the point of closest approach and the time
0323   //         offset parameter
0324   /// @param line: Reference to the line to which the residual is calculated
0325   /// @param hitMinSeg: Difference of the straw position & the line reference point
0326   /// @param wireDir: The direction along the wire
0327   /// @param driftR: Current drift radius of the straw measurement
0328 
0329   /// @param driftV: Associated drift velocity given as the derivative of the r-t relation
0330   /// @param driftA: Associated drift acceleration given as the second derivative of the r-t relation
0331   void updateTimeStrawRes(const Line_t& line, const Vector& hitMinSeg,
0332                           const Vector& wireDir, const double driftR,
0333                           const double driftV, const double driftA);
0334   /// @brief Resets the residual and all partial derivatives to zero.
0335   void reset();
0336   /// @brief Resets the time residual and the partial derivatives
0337   void resetTime();
0338   Config m_cfg{};
0339   std::unique_ptr<const Logger> m_logger{};
0340 
0341   /// @brief Cached residual vector calculated from the measurement & the parametrized line
0342   Vector m_residual{Vector::Zero()};
0343   /// @brief Partial derivatives of the residual w.r.t. the fit parameters parameters
0344   std::array<Vector3, s_nPars> m_gradient{
0345       filledArray<Vector3, s_nPars>(Vector3::Zero())};
0346   /// @brief  Second partial derivatives of the residual w.r.t. the fit parameters parameters
0347   std::array<Vector3, sumUpToN(s_nPars)> m_hessian{
0348       filledArray<Vector3, sumUpToN(s_nPars)>(Vector3::Zero())};
0349 
0350   //  Auxiliary parameters needed to calculate the residual of the
0351   //  point of closest approach and its derivatives
0352 
0353   /// @brief Number of spatial line parameters
0354   static constexpr std::uint8_t s_nLinePars = Line_t::s_nPars;
0355   /// @brief projection of the segment direction onto the wire plane
0356   Vector m_projDir{Vector::Zero()};
0357   /// @brief Partial derivatives of the dir projection w.r.t. line parameters
0358   std::array<Vector, s_nLinePars> m_gradProjDir{
0359       filledArray<Vector, s_nLinePars>(Vector::Zero())};
0360   /// @brief Component of the direction vector parallel to the wire
0361   double m_wireProject{1.};
0362   /// @brief Length squared of the projected direction
0363   double m_invProjDirLenSq{0.};
0364   /// @brief Inverse of the projected direction length
0365   double m_invProjDirLen{0.};
0366   /// @brief Partial derivatives of the dir projection lengths w.r.t line parameters
0367   std::array<double, s_nLinePars> m_projDirLenPartial{
0368       filledArray<double, s_nLinePars>(0.)};
0369 
0370   std::array<Vector, sumUpToN(s_nLinePars)> m_hessianProjDir{
0371       filledArray<Vector, sumUpToN(s_nLinePars)>(Vector::Zero())};
0372 
0373   /// @brief Gradient vector of the point of closest approach
0374   std::array<Vector, s_nLinePars> m_gradCloseApproach{
0375       filledArray<Vector, s_nLinePars>(Vector::Zero())};
0376   /// @brief Partial derivative of the actual distance of the closest approach
0377   std::array<double, s_nLinePars> m_partialApproachDist{
0378       filledArray<double, s_nLinePars>(0.)};
0379   /// @brief Tansform matrix to treat stereo angles amongst the strips
0380   ActsSquareMatrix<2> m_stereoTrf{ActsSquareMatrix<2>::Identity()};
0381 };
0382 
0383 }  // namespace Acts::Experimental::detail
0384 #include "Acts/Seeding/detail/CompSpacePointAuxiliaries.ipp"