Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-16 08:02:14

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/Utilities/Helpers.hpp"
0012 
0013 #include <algorithm>
0014 #include <array>
0015 #include <cassert>
0016 #include <cmath>
0017 #include <iomanip>
0018 #include <limits>
0019 #include <ostream>
0020 #include <sstream>
0021 
0022 namespace Acts {
0023 
0024 /// A constrained step class for the steppers.
0025 ///
0026 /// This class is symmetrical for forward and backward propagation. The sign of
0027 /// the propagation direction should not enter here but rather be applied the
0028 /// step is actually taken.
0029 ///
0030 /// As simple as this class looks it hides a few very important details:
0031 /// - Overstepping handling. The step size sign will flip if we happened to pass
0032 /// our target.
0033 /// - Convergence handling. Smaller and smaller step sizes have to be used in
0034 /// order to converge on a target.
0035 ///
0036 /// Because of the points mentioned above, the update function will always
0037 /// prefer negative step sizes. A side effect of this is that we will propagate
0038 /// in the opposite direction if the target is "behind us".
0039 ///
0040 /// The hierarchy is:
0041 /// - Overstepping resolution / backpropagation
0042 /// - Convergence
0043 /// - Step into the void with `std::numeric_limits<double>::max()`
0044 class ConstrainedStep {
0045  public:
0046   /// the types of constraints
0047   /// from navigator - this would be a navigation step
0048   /// from actor     - this would be an actor condition
0049   /// from user      - this is user given for what reason ever
0050   enum class Type : int { Navigator = 0, Actor = 1, User = 2 };
0051 
0052   constexpr ConstrainedStep() = default;
0053 
0054   /// constructor
0055   /// @param v is the user given initial value
0056   constexpr explicit ConstrainedStep(double v) { setUser(v); }
0057 
0058   /// set accuracy
0059   ///
0060   /// this will set only the accuracy, as this is the most
0061   /// exposed to the Propagator
0062   ///
0063   /// @param v is the new accuracy value
0064   constexpr void setAccuracy(double v) {
0065     assert(v > 0 && "ConstrainedStep accuracy must be > 0.");
0066     // set the accuracy value
0067     m_accuracy = v;
0068   }
0069 
0070   /// set user
0071   ///
0072   /// @param v is the new user value
0073   constexpr void setUser(double v) {
0074     // TODO enable assert; see https://github.com/acts-project/acts/issues/2543
0075     // assert(v != 0 && "ConstrainedStep user must be != 0.");
0076     // set the user value
0077     setValue(Type::User, v);
0078   }
0079 
0080   /// returns the min step size
0081   /// @return The minimum constrained step size considering all constraints
0082   constexpr double value() const {
0083     double min = *std::min_element(m_values.begin(), m_values.end());
0084     // accuracy is always positive and therefore handled separately
0085     double result = std::min(std::abs(min), m_accuracy);
0086     return std::signbit(min) ? -result : result;
0087   }
0088 
0089   /// Access a specific value
0090   ///
0091   /// @param type is the requested parameter type
0092   /// @return The step size for the specified constraint type
0093   constexpr double value(Type type) const {
0094     return m_values[toUnderlying(type)];
0095   }
0096 
0097   /// Access the accuracy value
0098   /// @return The step size accuracy constraint
0099   constexpr double accuracy() const { return m_accuracy; }
0100 
0101   /// release a certain constraint value
0102   ///
0103   /// @param type is the constraint type to be released
0104   constexpr void release(Type type) { setValue(type, kNotSet); }
0105 
0106   /// release accuracy
0107   constexpr void releaseAccuracy() { m_accuracy = kNotSet; }
0108 
0109   /// Update the step size of a certain type
0110   ///
0111   /// Only navigation and target abortion step size
0112   /// updates may change the sign due to overstepping
0113   ///
0114   /// @param v is the new value to be updated
0115   /// @param type is the constraint type
0116   constexpr void update(double v, Type type) {
0117     // check the current value and set it if appropriate
0118     // this will also allow signed values due to overstepping
0119     if (std::abs(v) < std::abs(value(type))) {
0120       // TODO enable assert; see
0121       // https://github.com/acts-project/acts/issues/2543
0122       // assert(value != 0 && "ConstrainedStep user must be != 0.");
0123       setValue(type, v);
0124     }
0125   }
0126 
0127   /// Stream the constrained step into an output stream
0128   /// @param os Output stream to write to
0129   /// @return Reference to the output stream for chaining
0130   std::ostream& toStream(std::ostream& os) const {
0131     // Helper method to avoid unreadable screen output
0132     auto streamValue = [&](double v) {
0133       os << std::setw(5);
0134       if (std::abs(v) == kNotSet) {
0135         os << (v > 0 ? "+∞" : "-∞");
0136       } else {
0137         os << v;
0138       }
0139     };
0140 
0141     os << "(";
0142     streamValue(m_accuracy);
0143     os << ", ";
0144     streamValue(value(Type::Navigator));
0145     os << ", ";
0146     streamValue(value(Type::Actor));
0147     os << ", ";
0148     streamValue(value(Type::User));
0149     os << ")";
0150 
0151     return os;
0152   }
0153 
0154   /// Convert the constrained step to a string representation
0155   /// @return String representation of the constrained step
0156   std::string toString() const {
0157     std::stringstream dstream;
0158     toStream(dstream);
0159     return dstream.str();
0160   }
0161 
0162  private:
0163   static constexpr auto kNotSet = std::numeric_limits<double>::max();
0164 
0165   /// the step size tuple
0166   std::array<double, 3> m_values = {kNotSet, kNotSet, kNotSet};
0167   /// the accuracy value - this can vary up and down given a good step estimator
0168   double m_accuracy = kNotSet;
0169 
0170   constexpr void setValue(Type type, double v) {
0171     m_values[toUnderlying(type)] = v;
0172   }
0173 };
0174 
0175 /// Stream operator for ConstrainedStep
0176 /// @param os Output stream
0177 /// @param step ConstrainedStep to output
0178 /// @return Reference to output stream
0179 inline std::ostream& operator<<(std::ostream& os, const ConstrainedStep& step) {
0180   return step.toStream(os);
0181 }
0182 
0183 }  // namespace Acts