Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:51

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