|
|
|||
File indexing completed on 2025-11-04 09:21:32
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 /// @note This file is foreseen for the `Geometry` module to replace `Extent` 0012 0013 #include "Acts/Definitions/Algebra.hpp" 0014 #include "Acts/Utilities/AxisDefinitions.hpp" 0015 #include "Acts/Utilities/Enumerate.hpp" 0016 #include "Acts/Utilities/Helpers.hpp" 0017 #include "Acts/Utilities/RangeXD.hpp" 0018 0019 #include <array> 0020 #include <bitset> 0021 #include <optional> 0022 #include <ostream> 0023 #include <string> 0024 #include <vector> 0025 0026 namespace Acts { 0027 0028 /// @brief Type alias for envelope values in different directions 0029 /// @details Stores the envelope values for both positive and negative directions 0030 using Envelope = std::array<double, 2>; 0031 0032 /// Zero envelope constant for no extension 0033 constexpr Envelope zeroEnvelope = {0, 0}; 0034 0035 /// This struct models a multi-dimensional enveloper along the axis directions 0036 struct ExtentEnvelope { 0037 /// Access a single envelope configuration 0038 /// @param aDir the axis definition 0039 /// @return the envelope 0040 Envelope& operator[](AxisDirection aDir) { 0041 return m_values.at(toUnderlying(aDir)); 0042 } 0043 0044 /// Access a single envelope configuration 0045 /// @param aDir the axis direction 0046 /// @return the envelope 0047 const Envelope& operator[](AxisDirection aDir) const { 0048 return m_values.at(toUnderlying(aDir)); 0049 } 0050 0051 /// Constructor from a single envelope that is assigned to all values 0052 /// @param envelope the envelope to be assigned 0053 explicit ExtentEnvelope(const Envelope& envelope = zeroEnvelope) { 0054 for (auto& val : m_values) { 0055 val = envelope; 0056 } 0057 } 0058 0059 /// Static factory for a zero envelope 0060 /// @return the zero envelope 0061 constexpr static ExtentEnvelope Zero() { 0062 return ExtentEnvelope{{ 0063 zeroEnvelope, 0064 zeroEnvelope, 0065 zeroEnvelope, 0066 zeroEnvelope, 0067 zeroEnvelope, 0068 zeroEnvelope, 0069 zeroEnvelope, 0070 zeroEnvelope, 0071 zeroEnvelope, 0072 }}; 0073 } 0074 0075 /// Helper struct for designated initializer construction 0076 struct Arguments { 0077 /// Envelope for x-coordinate direction 0078 Envelope x = zeroEnvelope; 0079 /// Envelope for y-coordinate direction 0080 Envelope y = zeroEnvelope; 0081 /// Envelope for z-coordinate direction 0082 Envelope z = zeroEnvelope; 0083 /// Envelope for radial coordinate direction 0084 Envelope r = zeroEnvelope; 0085 /// Envelope for azimuthal angle direction 0086 Envelope phi = zeroEnvelope; 0087 /// Envelope for r*phi coordinate direction 0088 Envelope rPhi = zeroEnvelope; 0089 /// Envelope for polar angle direction 0090 Envelope theta = zeroEnvelope; 0091 /// Envelope for pseudorapidity direction 0092 Envelope eta = zeroEnvelope; 0093 /// Envelope for magnitude direction 0094 Envelope mag = zeroEnvelope; 0095 }; 0096 0097 /// Constructor using a helper struct for designated initializaion 0098 /// @param args the arguments 0099 constexpr explicit ExtentEnvelope(Arguments&& args) { 0100 using enum AxisDirection; 0101 m_values[toUnderlying(AxisX)] = args.x; 0102 m_values[toUnderlying(AxisY)] = args.y; 0103 m_values[toUnderlying(AxisZ)] = args.z; 0104 m_values[toUnderlying(AxisR)] = args.r; 0105 m_values[toUnderlying(AxisPhi)] = args.phi; 0106 m_values[toUnderlying(AxisTheta)] = args.theta; 0107 m_values[toUnderlying(AxisEta)] = args.eta; 0108 m_values[toUnderlying(AxisMag)] = args.mag; 0109 } 0110 0111 /// Comparison operator between envelope sets 0112 /// @param lhs the left hand side 0113 /// @param rhs the right hand side 0114 /// @return true if the envelopes are equal 0115 friend bool operator==(const ExtentEnvelope& lhs, const ExtentEnvelope& rhs) { 0116 return lhs.m_values == rhs.m_values; 0117 } 0118 0119 private: 0120 std::array<Envelope, numAxisDirections()> m_values{}; 0121 }; 0122 0123 /// A class representing the geometric extent of an object in its possible 0124 /// dimensions, these can be all dimensions that are described as AxisDirections 0125 /// 0126 /// The extent object can have an optional envelope in all of those values 0127 /// @note that the consistency of the different envelopes is not checked 0128 /// 0129 class Extent { 0130 public: 0131 /// Constructor with (optional) @param envelope 0132 explicit Extent(const ExtentEnvelope& envelope = ExtentEnvelope::Zero()); 0133 0134 /// Define a comparison operator 0135 /// @param e The extent to compare with 0136 /// @return True if the extents are equal, false otherwise 0137 bool operator==(const Extent& e) const; 0138 0139 /// Extend with a position vertex 0140 /// 0141 /// @param vtx the vertex to be used for extending 0142 /// @param aDirs the axis directions 0143 /// @param applyEnv boolean to steer if envelope should be applied 0144 /// @param fillHistograms is a boolean flag to steer whether the values 0145 /// to fill this extent should be stored 0146 void extend(const Vector3& vtx, 0147 const std::vector<AxisDirection>& aDirs = allAxisDirections(), 0148 bool applyEnv = true, bool fillHistograms = false); 0149 0150 /// Extend with a set of vectors by iterators 0151 /// 0152 /// @param start the start iterator of the loop 0153 /// @param end the end iterator of the loop 0154 /// @param aDirs the axis directions 0155 /// @param applyEnv boolean to steer if envelope should be applied 0156 /// @param fillHistograms is a boolean flag to steer whether the values 0157 /// to fill this extent should be stored 0158 template <typename vector_iterator_t> 0159 void extend(const vector_iterator_t& start, const vector_iterator_t& end, 0160 const std::vector<AxisDirection>& aDirs = allAxisDirections(), 0161 bool applyEnv = true, bool fillHistograms = false) { 0162 for (vector_iterator_t vIt = start; vIt < end; ++vIt) { 0163 extend(*vIt, aDirs, applyEnv, fillHistograms); 0164 } 0165 } 0166 0167 /// Extend with another geometric extent, usually pushes the 0168 /// current range to the boundaries of the rhs extent, 0169 /// unless the current extent is already bigger. 0170 /// 0171 /// @note the extent can also simply set an envelope 0172 /// which then is applied to the current one 0173 /// 0174 /// @param rhs is the other source Extent 0175 /// @param aDirs the axis directions 0176 /// @param applyEnv boolean to steer if envelope should be applied 0177 /// on the constraint values, if only an envelope is given 0178 /// but the value not constraint, then it is always applied 0179 /// 0180 /// @note that the histogram values can not be filled in this call 0181 void extend(const Extent& rhs, 0182 const std::vector<AxisDirection>& aDirs = allAxisDirections(), 0183 bool applyEnv = true); 0184 0185 /// Constrain an extent by another one, this is 0186 /// - values that are already constrained are not touched 0187 /// - values not constrained by @param rhs are not touched 0188 /// - values that are constrained by the external one, but not 0189 /// by the current one, are touched 0190 /// 0191 /// @param envelope an envelope applied to the constrained value 0192 void addConstrain(const Extent& rhs, 0193 const ExtentEnvelope& envelope = ExtentEnvelope::Zero()); 0194 0195 /// Set a range for a dedicated binning value 0196 /// 0197 /// @param aDir the axis direction 0198 /// @param min the minimum parameter 0199 /// @param max the maximum parameter 0200 void set(AxisDirection aDir, double min, double max); 0201 0202 /// Set a min value for a dedicated binning value 0203 /// 0204 /// @param aDir the axis direction 0205 /// @param min the minimum parameter 0206 void setMin(AxisDirection aDir, double min); 0207 0208 /// Set a max value for a dedicated binning value 0209 /// 0210 /// @param aDir the axis direction 0211 /// @param max the maximum parameter 0212 void setMax(AxisDirection aDir, double max); 0213 0214 /// (re-)Set the envelope 0215 /// 0216 /// @param envelope new envelope to be set 0217 void setEnvelope(const ExtentEnvelope& envelope = ExtentEnvelope::Zero()); 0218 0219 /// Return the individual 1-dimensional range 0220 /// 0221 /// @param aDir is the axis direction to be returned 0222 /// 0223 /// @return a one dimensional arrange 0224 auto range(AxisDirection aDir) { return m_range[toUnderlying(aDir)]; } 0225 0226 /// Return the individual 1-dimensional range 0227 /// 0228 /// @param aDir is the axis direction to be returned 0229 /// 0230 /// @return a one dimensional arrange 0231 Range1D<double> range(AxisDirection aDir) const; 0232 0233 /// Return the N-dimension range 0234 /// @return Reference to the complete multi-dimensional range 0235 const RangeXD<numAxisDirections(), double>& range() const; 0236 0237 /// Return an D-dimensional sub range according to the 0238 /// the given binvalues 0239 /// @tparam kSUBDIM the number of sub dimensions 0240 /// @param axisDirections the axis directions 0241 /// @return the sub range 0242 template <unsigned int kSUBDIM> 0243 RangeXD<kSUBDIM, double> range( 0244 const std::array<AxisDirection, kSUBDIM>& axisDirections) const { 0245 RangeXD<kSUBDIM, double> rRange; 0246 for (auto [i, v] : enumerate(axisDirections)) { 0247 rRange[i] = range(v); 0248 } 0249 return rRange; 0250 } 0251 0252 /// Return the envelope - non-const access 0253 /// @return Reference to the envelope for modification 0254 ExtentEnvelope& envelope(); 0255 0256 /// Return the envelope - const access 0257 /// @return Const reference to the envelope 0258 const ExtentEnvelope& envelope() const; 0259 0260 /// Return the histogram store 0261 /// 0262 /// The histogram store can be used for automated binning detection 0263 const std::array<std::vector<double>, numAxisDirections()>& valueHistograms() 0264 const; 0265 0266 /// Access the minimum parameter 0267 /// 0268 /// @param aDir the axis direction 0269 /// @return Minimum value along the specified axis direction 0270 double min(AxisDirection aDir) const { 0271 return m_range[toUnderlying(aDir)].min(); 0272 } 0273 0274 /// Access the maximum parameter 0275 /// 0276 /// @param aDir the axis direction 0277 /// @return Maximum value along the specified axis direction 0278 double max(AxisDirection aDir) const { 0279 return m_range[toUnderlying(aDir)].max(); 0280 } 0281 0282 /// Access the midpoint 0283 /// 0284 /// @param aDir the axis direction 0285 /// @return Midpoint value along the specified axis direction 0286 double medium(AxisDirection aDir) const { 0287 return 0.5 * (m_range[toUnderlying(aDir)].min() + 0288 m_range[toUnderlying(aDir)].max()); 0289 } 0290 0291 /// Access the parameter interval (i.e. the range span) 0292 /// 0293 /// @param aDir the axis direction 0294 /// @return Interval size along the specified axis direction 0295 double interval(AxisDirection aDir) const { 0296 return m_range[toUnderlying(aDir)].size(); 0297 } 0298 0299 /// Contains check 0300 /// 0301 /// @param rhs the extent that is check if it is contained 0302 /// @param aDir is the axis direction, if set to nullopt 0303 /// the check on all is done 0304 /// 0305 /// @return true if the rhs is contained 0306 bool contains(const Extent& rhs, 0307 std::optional<AxisDirection> aDir = std::nullopt) const; 0308 0309 /// Contains check for a single point 0310 /// 0311 /// @param vtx the point that is check if it is contained 0312 /// 0313 /// @return true if the rhs is contained 0314 bool contains(const Vector3& vtx) const; 0315 0316 /// Intersection checks 0317 /// 0318 /// @param rhs the extent that is check for intersection 0319 /// @param aDir is the axis direction, if set to nulloptr 0320 /// the check on all is done 0321 /// 0322 /// @return true if the rhs intersects 0323 bool intersects(const Extent& rhs, 0324 std::optional<AxisDirection> aDir = std::nullopt) const; 0325 0326 /// Check if this object constrains a given direction 0327 /// 0328 /// @param aDir is the axis direction 0329 /// @return True if the specified axis direction is constrained, false otherwise 0330 bool constrains(AxisDirection aDir) const; 0331 0332 /// Check if this object constrains any direction 0333 /// @return True if any axis direction is constrained, false otherwise 0334 bool constrains() const; 0335 0336 /// Convert to output stream for screen output 0337 /// 0338 /// @param indent indentation for the screen display 0339 /// @return String representation of the extent 0340 std::string toString(const std::string& indent = "") const; 0341 0342 private: 0343 /// A bitset that remembers the constraint values 0344 std::bitset<numAxisDirections()> m_constrains{0}; 0345 /// The actual range store 0346 RangeXD<numAxisDirections(), double> m_range; 0347 /// A potential envelope 0348 ExtentEnvelope m_envelope = ExtentEnvelope::Zero(); 0349 /// (Optional) Value histograms for bin detection 0350 std::array<std::vector<double>, numAxisDirections()> m_valueHistograms; 0351 }; 0352 0353 inline Range1D<double> Acts::Extent::range(AxisDirection aDir) const { 0354 return m_range[toUnderlying(aDir)]; 0355 } 0356 0357 inline const RangeXD<numAxisDirections(), double>& Extent::range() const { 0358 return m_range; 0359 } 0360 0361 inline ExtentEnvelope& Extent::envelope() { 0362 return m_envelope; 0363 } 0364 0365 inline const ExtentEnvelope& Extent::envelope() const { 0366 return m_envelope; 0367 } 0368 0369 /// Return the value histograms 0370 /// @return Reference to the value histograms array 0371 inline const std::array<std::vector<double>, numAxisDirections()>& 0372 Extent::valueHistograms() const { 0373 return m_valueHistograms; 0374 } 0375 0376 /// Overload of << operator for std::ostream for debug output 0377 /// @param sl Output stream 0378 /// @param rhs Extent to output 0379 /// @return Reference to output stream 0380 std::ostream& operator<<(std::ostream& sl, const Extent& rhs); 0381 0382 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|