Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ConstrainedStep.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ConstrainedStep.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2022 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
12 
13 #include <algorithm>
14 #include <array>
15 #include <cassert>
16 #include <cmath>
17 #include <iomanip>
18 #include <limits>
19 #include <ostream>
20 #include <sstream>
21 
22 namespace Acts {
23 
45  public:
46  using Scalar = ActsScalar;
47 
52  enum Type : int { actor = 0, aborter = 1, user = 2 };
53 
56  size_t nStepTrials = std::numeric_limits<size_t>::max();
57 
58  constexpr ConstrainedStep() = default;
59 
62  constexpr explicit ConstrainedStep(Scalar value) { setUser(value); }
63 
70  constexpr void setAccuracy(Scalar value) {
71  assert(value > 0 && "ConstrainedStep accuracy must be > 0.");
72  // set the accuracy value
73  m_accuracy = value;
74  }
75 
79  constexpr void setUser(Scalar value) {
80  // TODO enable assert; see https://github.com/acts-project/acts/issues/2543
81  // assert(value != 0 && "ConstrainedStep user must be != 0.");
82  // set the user value
83  m_values[user] = value;
84  }
85 
87  constexpr Scalar value() const {
88  Scalar min = *std::min_element(m_values.begin(), m_values.end());
89  // accuracy is always positive and therefore handled separately
90  Scalar result = std::min(std::abs(min), m_accuracy);
91  return std::signbit(min) ? -result : result;
92  }
93 
97  constexpr Scalar value(Type type) const { return m_values[type]; }
98 
102  constexpr Scalar accuracy() const { return m_accuracy; }
103 
107  constexpr void release(Type type) { m_values[type] = kNotSet; }
108 
112  constexpr void releaseAccuracy() { m_accuracy = kNotSet; }
113 
122  constexpr void update(Scalar value, Type type, bool releaseStep = false) {
123  if (releaseStep) {
124  release(type);
125  }
126  // check the current value and set it if appropriate
127  // this will also allow signed values due to overstepping
128  if (std::abs(value) < std::abs(m_values[type])) {
129  // TODO enable assert; see
130  // https://github.com/acts-project/acts/issues/2543
131  // assert(value != 0 && "ConstrainedStep user must be != 0.");
132  m_values[type] = value;
133  }
134  }
135 
136  std::ostream& toStream(std::ostream& os) const {
137  // Helper method to avoid unreadable screen output
138  auto streamValue = [&](Scalar val) {
139  os << std::setw(5);
140  if (std::abs(val) == kNotSet) {
141  os << (val > 0 ? "+∞" : "-∞");
142  } else {
143  os << val;
144  }
145  };
146 
147  os << "(";
148  streamValue(m_accuracy);
149  os << ", ";
150  streamValue(value(actor));
151  os << ", ";
152  streamValue(value(aborter));
153  os << ", ";
154  streamValue(value(user));
155  os << ")";
156 
157  return os;
158  }
159 
161  std::stringstream dstream;
162  toStream(dstream);
163  return dstream.str();
164  }
165 
166  private:
167  inline static constexpr auto kNotSet = std::numeric_limits<Scalar>::max();
168 
170  std::array<Scalar, 3> m_values = {kNotSet, kNotSet, kNotSet};
173 };
174 
175 inline std::ostream& operator<<(std::ostream& os, const ConstrainedStep& step) {
176  return step.toStream(os);
177 }
178 
179 } // namespace Acts