Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 07:51:11

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 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Geometry/GeometryContext.hpp"
0014 #include "Acts/Surfaces/PlaneSurface.hpp"
0015 #include "Acts/Surfaces/RectangleBounds.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Result.hpp"
0018 
0019 #include <array>
0020 #include <memory>
0021 #include <utility>
0022 
0023 namespace Acts {
0024 class PlanarBounds;
0025 }  // namespace Acts
0026 
0027 using namespace Acts::UnitLiterals;
0028 
0029 namespace Acts::Test {
0030 
0031 /// @class AlignmentContext
0032 struct AlignmentContext {
0033   /// We have 2 different transforms
0034   std::shared_ptr<const std::array<Transform3, 2>> alignmentStore = nullptr;
0035 
0036   /// Context index
0037   unsigned int alignmentIndex{0};
0038 
0039   /// Default constructor
0040   AlignmentContext() = default;
0041 
0042   /// Constructor with Store and context index
0043   explicit AlignmentContext(
0044       std::shared_ptr<const std::array<Transform3, 2>> aStore,
0045       unsigned int aIndex = 0)
0046       : alignmentStore(std::move(aStore)), alignmentIndex(aIndex) {}
0047 };
0048 
0049 /// @class AlignableDetectorElement
0050 ///
0051 /// This is a lightweight type of detector element,
0052 /// it simply implements the base class.
0053 class AlignableDetectorElement : public DetectorElementBase {
0054  public:
0055   // Deleted default constructor
0056   AlignableDetectorElement() = delete;
0057 
0058   /// Constructor for single sided detector element
0059   /// - bound to a Plane Surface
0060   ///
0061   /// @param transform is the transform that element the layer in 3D frame
0062   /// @param pBounds is the planar bounds for the planar detector element
0063   /// @param thickness is the module thickness
0064   AlignableDetectorElement(std::shared_ptr<const Transform3> transform,
0065                            const std::shared_ptr<const PlanarBounds>& pBounds,
0066                            double thickness)
0067       : DetectorElementBase(),
0068         m_elementTransform(std::move(transform)),
0069         m_elementThickness(thickness) {
0070     m_elementSurface = Surface::makeShared<PlaneSurface>(pBounds, *this);
0071   }
0072 
0073   ///  Destructor
0074   ~AlignableDetectorElement() override = default;
0075 
0076   /// Return local to global transform associated with this identifier
0077   ///
0078   /// @param gctx The current geometry context object, e.g. alignment
0079   ///
0080   /// @note this is called from the surface().transform() in the PROXY mode
0081   const Transform3& transform(const GeometryContext& gctx) const override;
0082 
0083   /// Return surface associated with this detector element
0084   const Surface& surface() const override;
0085 
0086   /// Non-const access to the surface associated with this detector element
0087   Surface& surface() override;
0088 
0089   /// The maximal thickness of the detector element wrt normal axis
0090   double thickness() const override;
0091 
0092  private:
0093   /// the transform for positioning in 3D space
0094   std::shared_ptr<const Transform3> m_elementTransform;
0095   /// the surface represented by it
0096   std::shared_ptr<Surface> m_elementSurface{nullptr};
0097   /// the element thickness
0098   double m_elementThickness{0.};
0099 };
0100 
0101 inline const Transform3& AlignableDetectorElement::transform(
0102     const GeometryContext& gctx) const {
0103   auto alignContext = gctx.get<AlignmentContext>();
0104   if (alignContext.alignmentStore != nullptr &&
0105       alignContext.alignmentIndex < 2) {
0106     return (*(alignContext.alignmentStore))[alignContext.alignmentIndex];
0107   }
0108   return (*m_elementTransform);
0109 }
0110 
0111 inline const Surface& AlignableDetectorElement::surface() const {
0112   return *m_elementSurface;
0113 }
0114 
0115 inline Surface& AlignableDetectorElement::surface() {
0116   return *m_elementSurface;
0117 }
0118 
0119 inline double AlignableDetectorElement::thickness() const {
0120   return m_elementThickness;
0121 }
0122 
0123 /// Unit test for creating compliant/non-compliant Surface object
0124 BOOST_AUTO_TEST_CASE(AlignmentContextTests) {
0125   // The nominal and alignments
0126   Vector3 nominalCenter(0., 0., 0.);
0127   Vector3 negativeCenter(0., 0., -1.);
0128   Vector3 positiveCenter(0., 0., 1.);
0129 
0130   // Checkpoints
0131   Vector3 onNominal(3., 3., 0.);
0132   Vector3 onNegative(3., 3., -1.);
0133   Vector3 onPositive(3., 3., 1.);
0134 
0135   // Local position
0136   Vector2 localPosition(3., 3.);
0137 
0138   // A position placeholder and dummy momentum
0139   Vector3 globalPosition(100_cm, 100_cm, 100_cm);
0140   Vector3 dummyMomentum(4., 4., 4.);
0141 
0142   Transform3 negativeTransform = Transform3::Identity();
0143   negativeTransform.translation() = negativeCenter;
0144 
0145   Transform3 positiveTransform = Transform3::Identity();
0146   positiveTransform.translation() = positiveCenter;
0147 
0148   std::array<Transform3, 2> alignmentArray = {negativeTransform,
0149                                               positiveTransform};
0150 
0151   std::shared_ptr<const std::array<Transform3, 2>> alignmentStore =
0152       std::make_shared<const std::array<Transform3, 2>>(alignmentArray);
0153 
0154   // The detector element at nominal position
0155   AlignableDetectorElement alignedElement(
0156       std::make_shared<const Transform3>(Transform3::Identity()),
0157       std::make_shared<const RectangleBounds>(100_cm, 100_cm), 1_mm);
0158 
0159   const auto& alignedSurface = alignedElement.surface();
0160 
0161   // The alignment contexts
0162   GeometryContext defaultContext{AlignmentContext{}};
0163   GeometryContext negativeContext{AlignmentContext{alignmentStore, 0}};
0164   GeometryContext positiveContext{AlignmentContext{alignmentStore, 1}};
0165 
0166   // Test the transforms
0167   BOOST_CHECK(alignedSurface.transform(defaultContext)
0168                   .isApprox(Transform3::Identity()));
0169   BOOST_CHECK(
0170       alignedSurface.transform(negativeContext).isApprox(negativeTransform));
0171   BOOST_CHECK(
0172       alignedSurface.transform(positiveContext).isApprox(positiveTransform));
0173 
0174   // Test the centers
0175   BOOST_CHECK_EQUAL(alignedSurface.center(defaultContext), nominalCenter);
0176   BOOST_CHECK_EQUAL(alignedSurface.center(negativeContext), negativeCenter);
0177   BOOST_CHECK_EQUAL(alignedSurface.center(positiveContext), positiveCenter);
0178 
0179   // Test OnSurface
0180   BOOST_CHECK(
0181       alignedSurface.isOnSurface(defaultContext, onNominal, dummyMomentum));
0182   BOOST_CHECK(
0183       alignedSurface.isOnSurface(negativeContext, onNegative, dummyMomentum));
0184   BOOST_CHECK(
0185       alignedSurface.isOnSurface(positiveContext, onPositive, dummyMomentum));
0186 
0187   // Test local to Global and vice versa
0188   globalPosition = alignedSurface.localToGlobal(defaultContext, localPosition,
0189                                                 dummyMomentum);
0190   BOOST_CHECK_EQUAL(globalPosition, onNominal);
0191   localPosition =
0192       alignedSurface.globalToLocal(defaultContext, onNominal, dummyMomentum)
0193           .value();
0194   BOOST_CHECK_EQUAL(localPosition, Vector2(3., 3.));
0195 
0196   globalPosition = alignedSurface.localToGlobal(negativeContext, localPosition,
0197                                                 dummyMomentum);
0198   BOOST_CHECK_EQUAL(globalPosition, onNegative);
0199   localPosition =
0200       alignedSurface.globalToLocal(negativeContext, onNegative, dummyMomentum)
0201           .value();
0202   BOOST_CHECK_EQUAL(localPosition, Vector2(3., 3.));
0203 
0204   globalPosition = alignedSurface.localToGlobal(positiveContext, localPosition,
0205                                                 dummyMomentum);
0206   BOOST_CHECK_EQUAL(globalPosition, onPositive);
0207   localPosition =
0208       alignedSurface.globalToLocal(positiveContext, onPositive, dummyMomentum)
0209           .value();
0210   BOOST_CHECK_EQUAL(localPosition, Vector2(3., 3.));
0211 }
0212 
0213 }  // namespace Acts::Test