Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:28

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2018-2022 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.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<Scalar>::max()`
0044 class ConstrainedStep {
0045  public:
0046   using Scalar = ActsScalar;
0047 
0048   /// the types of constraints
0049   /// from actor    - this would be a typical navigation step
0050   /// from aborter  - this would be a target condition
0051   /// from user     - this is user given for what reason ever
0052   enum Type : int { actor = 0, aborter = 1, user = 2 };
0053 
0054   constexpr ConstrainedStep() = default;
0055 
0056   /// constructor from Scalar
0057   /// @param value is the user given initial value
0058   constexpr explicit ConstrainedStep(Scalar value) { setUser(value); }
0059 
0060   /// set accuracy by one Scalar
0061   ///
0062   /// this will set only the accuracy, as this is the most
0063   /// exposed to the Propagator
0064   ///
0065   /// @param value is the new accuracy value
0066   constexpr void setAccuracy(Scalar value) {
0067     assert(value > 0 && "ConstrainedStep accuracy must be > 0.");
0068     // set the accuracy value
0069     m_accuracy = value;
0070   }
0071 
0072   /// set user by one Scalar
0073   ///
0074   /// @param value is the new user value
0075   constexpr void setUser(Scalar value) {
0076     // TODO enable assert; see https://github.com/acts-project/acts/issues/2543
0077     // assert(value != 0 && "ConstrainedStep user must be != 0.");
0078     // set the user value
0079     m_values[user] = value;
0080   }
0081 
0082   /// returns the min step size
0083   constexpr Scalar value() const {
0084     Scalar min = *std::min_element(m_values.begin(), m_values.end());
0085     // accuracy is always positive and therefore handled separately
0086     Scalar result = std::min(std::abs(min), m_accuracy);
0087     return std::signbit(min) ? -result : result;
0088   }
0089 
0090   /// Access a specific value
0091   ///
0092   /// @param type is the requested parameter type
0093   constexpr Scalar value(Type type) const { return m_values[type]; }
0094 
0095   /// Access the accuracy value
0096   constexpr Scalar accuracy() const { return m_accuracy; }
0097 
0098   /// release a certain constraint value
0099   ///
0100   /// @param type is the constraint type to be released
0101   constexpr void release(Type type) { m_values[type] = kNotSet; }
0102 
0103   /// release accuracy
0104   constexpr void releaseAccuracy() { m_accuracy = kNotSet; }
0105 
0106   /// Update the step size of a certain type
0107   ///
0108   /// Only navigation and target abortion step size
0109   /// updates may change the sign due to overstepping
0110   ///
0111   /// @param value is the new value to be updated
0112   /// @param type is the constraint type
0113   /// @param releaseStep Allow step size to increase again
0114   constexpr void update(Scalar value, Type type, bool releaseStep = false) {
0115     if (releaseStep) {
0116       release(type);
0117     }
0118     // check the current value and set it if appropriate
0119     // this will also allow signed values due to overstepping
0120     if (std::abs(value) < std::abs(m_values[type])) {
0121       // TODO enable assert; see
0122       // https://github.com/acts-project/acts/issues/2543
0123       // assert(value != 0 && "ConstrainedStep user must be != 0.");
0124       m_values[type] = value;
0125     }
0126   }
0127 
0128   std::ostream& toStream(std::ostream& os) const {
0129     // Helper method to avoid unreadable screen output
0130     auto streamValue = [&](Scalar val) {
0131       os << std::setw(5);
0132       if (std::abs(val) == kNotSet) {
0133         os << (val > 0 ? "+∞" : "-∞");
0134       } else {
0135         os << val;
0136       }
0137     };
0138 
0139     os << "(";
0140     streamValue(m_accuracy);
0141     os << ", ";
0142     streamValue(value(actor));
0143     os << ", ";
0144     streamValue(value(aborter));
0145     os << ", ";
0146     streamValue(value(user));
0147     os << ")";
0148 
0149     return os;
0150   }
0151 
0152   std::string toString() const {
0153     std::stringstream dstream;
0154     toStream(dstream);
0155     return dstream.str();
0156   }
0157 
0158  private:
0159   inline static constexpr auto kNotSet = std::numeric_limits<Scalar>::max();
0160 
0161   /// the step size tuple
0162   std::array<Scalar, 3> m_values = {kNotSet, kNotSet, kNotSet};
0163   /// the accuracy value - this can vary up and down given a good step estimator
0164   Scalar m_accuracy = kNotSet;
0165 };
0166 
0167 inline std::ostream& operator<<(std::ostream& os, const ConstrainedStep& step) {
0168   return step.toStream(os);
0169 }
0170 
0171 }  // namespace Acts