Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-04 07:59:11

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 
0013 #include <cassert>
0014 #include <cstddef>
0015 #include <iosfwd>
0016 #include <string>
0017 
0018 namespace Acts {
0019 
0020 /// The direction is always with respect to a given momentum, surface normal or
0021 /// other general axes
0022 class Direction final {
0023  private:
0024   enum class Value : int {
0025     Negative = -1,
0026     Positive = 1,
0027   };
0028 
0029  public:
0030   /// Create negative direction (-1)
0031   /// @return Direction with negative value
0032   static constexpr Direction Negative() { return Direction{Value::Negative}; }
0033   /// Create positive direction (+1)
0034   /// @return Direction with positive value
0035   static constexpr Direction Positive() { return Direction{Value::Positive}; }
0036 
0037   /// Create backward direction (equivalent to negative)
0038   /// @return Direction with negative value for backward propagation
0039   static constexpr Direction Backward() { return Direction{Value::Negative}; }
0040   /// Create forward direction (equivalent to positive)
0041   /// @return Direction with positive value for forward propagation
0042   static constexpr Direction Forward() { return Direction{Value::Positive}; }
0043 
0044   /// Create direction opposite to normal (negative)
0045   /// @return Direction with negative value, opposite to surface normal
0046   static constexpr Direction OppositeNormal() {
0047     return Direction{Value::Negative};
0048   }
0049   /// Create direction along normal (positive)
0050   /// @return Direction with positive value, along surface normal
0051   static constexpr Direction AlongNormal() {
0052     return Direction{Value::Positive};
0053   }
0054 
0055   /// This turns a signed value into a direction. Will assert on zero.
0056   ///
0057   /// @param scalar is the signed value
0058   ///
0059   /// @return a direction enum
0060   static constexpr Direction fromScalar(double scalar) {
0061     assert(scalar != 0);
0062     return scalar >= 0 ? Positive() : Negative();
0063   }
0064 
0065   /// This turns a signed value into a direction and 0 will be handled as a
0066   /// positive direction. Only use this when you are convinced that the 0 case
0067   /// is properly handled downstream.
0068   ///
0069   /// @param scalar is the signed value
0070   ///
0071   /// @return a direction enum
0072   static constexpr Direction fromScalarZeroAsPositive(double scalar) {
0073     return scalar >= 0 ? Positive() : Negative();
0074   }
0075 
0076   /// Convert and index [0,1] to a direction e.g. for sorting in
0077   /// std::array<T, 2u>
0078   ///
0079   /// @param index is the direction at input
0080   /// @return Direction corresponding to the index (0->Negative, 1->Positive)
0081   static constexpr Direction fromIndex(std::size_t index) {
0082     return index == 0u ? Negative() : Positive();
0083   }
0084 
0085   /// Convert dir to index [0,1] which allows to store direction dependent
0086   /// objects in std::array<T, 2u>
0087   ///
0088   /// @return either 0 or 1
0089   constexpr std::size_t index() const {
0090     if (m_value == Value::Negative) {
0091       return 0u;
0092     }
0093     return 1u;
0094   }
0095 
0096   /// Turns the direction into a signed value
0097   ///
0098   /// @return a signed value
0099   constexpr int sign() const { return static_cast<int>(m_value); }
0100 
0101   /// Reverse the direction
0102   ///
0103   /// @return an opposite direction
0104   constexpr Direction invert() const {
0105     return *this == Positive() ? Negative() : Positive();
0106   }
0107 
0108   /// Convert direction to string representation
0109   /// @return String representation of the direction ("positive" or "negative")
0110   std::string toString() const;
0111 
0112   /// Check if two directions are equal
0113   /// @param rhs The Direction to compare to
0114   /// @return True if the two Directions are equal, false otherwise
0115   constexpr bool operator==(const Direction& rhs) const noexcept = default;
0116 
0117   /// Stream operator for Direction
0118   /// @param os Output stream
0119   /// @param dir Direction to output
0120   /// @return Reference to output stream
0121   friend std::ostream& operator<<(std::ostream& os, Direction dir) {
0122     os << dir.toString();
0123     return os;
0124   }
0125 
0126   /// Arithmetic operators
0127   /// @{
0128 
0129   // Direction * T
0130 
0131   /// Multiply Direction with integer
0132   /// @param dir Direction value
0133   /// @param value Integer to multiply
0134   /// @return Signed integer result
0135   friend constexpr int operator*(Direction dir, int value) {
0136     return dir.sign() * value;
0137   }
0138 
0139   /// Multiply Direction with float
0140   /// @param dir Direction value
0141   /// @param value Float to multiply
0142   /// @return Signed float result
0143   friend constexpr float operator*(Direction dir, float value) {
0144     return static_cast<float>(dir.sign()) * value;
0145   }
0146 
0147   /// Multiply Direction with double
0148   /// @param dir Direction value
0149   /// @param value Double to multiply
0150   /// @return Signed double result
0151   friend constexpr double operator*(Direction dir, double value) {
0152     return static_cast<double>(dir.sign()) * value;
0153   }
0154 
0155   /// Multiply Direction with Vector3
0156   /// @param dir Direction value
0157   /// @param value Vector3 to multiply
0158   /// @return Signed Vector3 result
0159   friend inline Acts::Vector3 operator*(Direction dir,
0160                                         const Acts::Vector3& value) {
0161     return static_cast<float>(dir.sign()) * value;
0162   }
0163 
0164   // T * Direction
0165 
0166   /// Multiply integer with Direction
0167   /// @param value Integer to multiply
0168   /// @param dir Direction value
0169   /// @return Signed integer result
0170   friend constexpr int operator*(int value, Direction dir) {
0171     return value * dir.sign();
0172   }
0173 
0174   /// Multiply float with Direction
0175   /// @param value Float to multiply
0176   /// @param dir Direction value
0177   /// @return Signed float result
0178   friend constexpr float operator*(float value, Direction dir) {
0179     return value * static_cast<float>(dir.sign());
0180   }
0181 
0182   /// Multiply double with Direction
0183   /// @param value Double to multiply
0184   /// @param dir Direction value
0185   /// @return Signed double result
0186   friend constexpr double operator*(double value, Direction dir) {
0187     return value * dir.sign();
0188   }
0189 
0190   /// Multiply Vector3 with Direction
0191   /// @param value Vector3 to multiply
0192   /// @param dir Direction value
0193   /// @return Signed Vector3 result
0194   friend Acts::Vector3 operator*(const Acts::Vector3& value, Direction dir) {
0195     return value * dir.sign();
0196   }
0197 
0198   // T *= Direction
0199 
0200   /// Multiply-assign integer with Direction
0201   /// @param value Integer reference to modify
0202   /// @param dir Direction value
0203   /// @return Reference to modified integer
0204   friend constexpr int operator*=(int& value, Direction dir) {
0205     value *= dir.sign();
0206     return value;
0207   }
0208 
0209   /// Multiply-assign float with Direction
0210   /// @param value Float reference to modify
0211   /// @param dir Direction value
0212   /// @return Reference to modified float
0213   friend constexpr float operator*=(float& value, Direction dir) {
0214     value *= static_cast<float>(dir.sign());
0215     return value;
0216   }
0217 
0218   /// Multiply-assign double with Direction
0219   /// @param value Double reference to modify
0220   /// @param dir Direction value
0221   /// @return Reference to modified double
0222   friend constexpr double operator*=(double& value, Direction dir) {
0223     value *= dir.sign();
0224     return value;
0225   }
0226 
0227   /// Multiply-assign Vector3 with Direction
0228   /// @param value Vector3 reference to modify
0229   /// @param dir Direction value
0230   /// @return Reference to modified Vector3
0231   friend Acts::Vector3& operator*=(Acts::Vector3& value, Direction dir) {
0232     value *= dir.sign();
0233     return value;
0234   }
0235 
0236   /// @}
0237 
0238  private:
0239   explicit constexpr Direction(Value value) : m_value(value) {}
0240 
0241   Value m_value = Value::Positive;
0242 };
0243 
0244 }  // namespace Acts