Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-27 07:56:55

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