Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-22 07:46: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/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Utilities/AxisDefinitions.hpp"
0014 #include "Acts/Utilities/VectorHelpers.hpp"
0015 
0016 #include <functional>
0017 #include <memory>
0018 
0019 namespace Acts {
0020 
0021 /// Sorter functor for geometry objects by axis direction.
0022 template <class T>
0023 class ObjectSorterT {
0024  public:
0025   /// Constructor from a binning value
0026   ///
0027   /// @param aDir is the direction in which the sorting is done
0028   explicit ObjectSorterT(AxisDirection aDir) : m_sortingDirection(aDir) {}
0029 
0030   /// Comparison operator
0031   ///
0032   /// @param one first object
0033   /// @param two second object
0034   ///
0035   /// @return boolean indicator
0036   bool operator()(T one, T two) const {
0037     using VectorHelpers::eta;
0038     using VectorHelpers::perp;
0039     using VectorHelpers::phi;
0040     using enum AxisDirection;
0041     switch (m_sortingDirection) {
0042       // compare on x
0043       case AxisX: {
0044         return one.x() < two.x();
0045       }
0046       // compare on y
0047       case AxisY: {
0048         return one.y() < two.y();
0049       }
0050       // compare on z
0051       case AxisZ: {
0052         return one.z() < two.z();
0053       }
0054       // compare on r
0055       case AxisR: {
0056         return perp(one) < perp(two);
0057       }
0058       // compare on phi
0059       case AxisPhi: {
0060         return phi(one) < phi(two);
0061       }
0062       // compare on eta
0063       case AxisEta: {
0064         return eta(one) < eta(two);
0065       }
0066       // default for the moment
0067       default: {
0068         return one.norm() < two.norm();
0069       }
0070     }
0071   }
0072 
0073   /// Get the sorting direction
0074   /// @return The axis direction used for sorting
0075   AxisDirection sortingDirection() const { return m_sortingDirection; }
0076 
0077  private:
0078   AxisDirection m_sortingDirection;  ///< the binning value
0079 };
0080 
0081 /// This will check on absolute distance
0082 template <class T>
0083 class DistanceSorterT {
0084  public:
0085   /// Constructor from a binning value
0086   ///
0087   /// @param aDir is the value in which the sorting is done
0088   /// @param reference is the reference point
0089   DistanceSorterT(AxisDirection aDir, Vector3 reference)
0090       : m_sortingDirection(aDir),
0091         m_reference(reference),
0092         m_refR(VectorHelpers::perp(reference)),
0093         m_refPhi(VectorHelpers::phi(reference)),
0094         m_refEta(VectorHelpers::eta(reference)) {}
0095 
0096   /// Comparison operator
0097   /// @param one First object to compare
0098   /// @param two Second object to compare
0099   ///
0100   /// @return boolean indicator
0101   bool operator()(T one, T two) const {
0102     using Acts::VectorHelpers::eta;
0103     using Acts::VectorHelpers::perp;
0104     using Acts::VectorHelpers::phi;
0105     // switch the sorting value
0106     // - AxisX, AxisY, AxisZ, AxisR, AxisPhi, AxisRPhi, AxisTheta, AxisEta
0107     switch (m_sortingDirection) {
0108       // compare on diff x
0109       case AxisDirection::AxisX: {
0110         double diffOneX = one.x() - m_reference.x();
0111         double diffTwoX = two.x() - m_reference.x();
0112         return std::abs(diffOneX) < std::abs(diffTwoX);
0113       }
0114       // compare on diff y
0115       case AxisDirection::AxisY: {
0116         double diffOneY = one.y() - m_reference.y();
0117         double diffTwoY = two.y() - m_reference.y();
0118         return std::abs(diffOneY) < std::abs(diffTwoY);
0119       }
0120       // compare on diff z
0121       case AxisDirection::AxisZ: {
0122         double diffOneZ = one.z() - m_reference.z();
0123         double diffTwoZ = two.z() - m_reference.z();
0124         return std::abs(diffOneZ) < std::abs(diffTwoZ);
0125       }
0126       // compare on r
0127       case AxisDirection::AxisR: {
0128         double diffOneR = perp(one) - m_refR;
0129         double diffTwoR = perp(two) - m_refR;
0130         return std::abs(diffOneR) < std::abs(diffTwoR);
0131       }
0132       // compare on phi /// @todo add cyclic value
0133       case AxisDirection::AxisPhi: {
0134         double diffOnePhi = phi(one) - m_refPhi;
0135         double diffTwoPhi = phi(two) - m_refPhi;
0136         return std::abs(diffOnePhi) < std::abs(diffTwoPhi);
0137       }
0138       // compare on eta
0139       case AxisDirection::AxisEta: {
0140         double diffOneEta = eta(one) - m_refEta;
0141         double diffTwoEta = eta(two) - m_refEta;
0142         return std::abs(diffOneEta) < std::abs(diffTwoEta);
0143       }
0144       // default for the moment
0145       default: {
0146         T diffOne(one - m_reference);
0147         T diffTwo(two - m_reference);
0148         return diffOne.mag2() < diffTwo.mag2();
0149       }
0150     }
0151   }
0152 
0153  private:
0154   AxisDirection m_sortingDirection;  ///< the sorting direction
0155   T m_reference;
0156   double m_refR;
0157   double m_refPhi;
0158   double m_refEta;
0159 };
0160 
0161 /// Sorter functor for geometry objects by reference position.
0162 template <class T>
0163 class GeometryObjectSorterT {
0164  public:
0165   /// Constructor from a sorting direction
0166   ///
0167   /// @param gctx The geometry context to use
0168   /// @param aDir is the direction in which the sorting is done
0169   /// @param transform is an optional transform to be performed
0170   GeometryObjectSorterT(const GeometryContext& gctx, AxisDirection aDir,
0171                         std::shared_ptr<const Transform3> transform = nullptr)
0172       : m_context(gctx),
0173         m_objectSorter(aDir),
0174         m_transform(std::move(transform)) {}
0175 
0176   /// Comparison operator
0177   ///
0178   /// @param one is the first object
0179   /// @param two is the second object
0180   ///
0181   /// @return boolean indicator
0182   bool operator()(const T& one, const T& two) const {
0183     // get the pos one / pos two
0184     Vector3 posOne = m_transform
0185                          ? m_transform->inverse() *
0186                                one->referencePosition(
0187                                    m_context, m_objectSorter.sortingDirection())
0188                          : one->referencePosition(
0189                                m_context, m_objectSorter.sortingDirection());
0190     Vector3 posTwo = m_transform
0191                          ? m_transform->inverse() *
0192                                two->referencePosition(
0193                                    m_context, m_objectSorter.sortingDirection())
0194                          : two->referencePosition(
0195                                m_context, m_objectSorter.sortingDirection());
0196     // now call the distance sorter
0197     return m_objectSorter.operator()(posOne, posTwo);
0198   }
0199 
0200  protected:
0201   /// Geometry context for the sorting operation
0202   std::reference_wrapper<const GeometryContext> m_context;
0203   /// The sorting function object for vectors
0204   ObjectSorterT<Vector3> m_objectSorter;
0205   /// Optional transformation to apply before sorting
0206   std::shared_ptr<const Transform3> m_transform;
0207 };
0208 }  // namespace Acts