Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-12 09:04:19

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/Units.hpp"
0012 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0013 #include "Acts/Surfaces/PlaneSurface.hpp"
0014 #include "Acts/Utilities/BinUtility.hpp"
0015 #include "ActsFatras/Digitization/Channelizer.hpp"
0016 #include "ActsFatras/Digitization/PlanarSurfaceDrift.hpp"
0017 #include "ActsFatras/Digitization/PlanarSurfaceMask.hpp"
0018 
0019 #include <numeric>
0020 
0021 using namespace Acts;
0022 using namespace Acts::UnitLiterals;
0023 using namespace ActsFatras;
0024 
0025 struct Helper {
0026   std::shared_ptr<Surface> surface;
0027   BinUtility segmentation;
0028 
0029   GeometryContext gctx{};
0030   double thickness = 125_um;
0031   Vector3 driftDir = Vector3::Zero();
0032 
0033   ActsFatras::Channelizer channelizer;
0034 
0035   Helper() {
0036     surface = CurvilinearSurface(Vector3::Zero(), Vector3{0.0, 0.0, 1.0})
0037                   .planeSurface();
0038 
0039     float pitchSize = 50_um;
0040     float min = -200_um;
0041     float max = 200_um;
0042     int bins = static_cast<int>((max - min) / pitchSize);
0043     segmentation =
0044         BinUtility(bins, min, max, BinningOption::open, AxisDirection::AxisX);
0045     segmentation +=
0046         BinUtility(bins, min, max, BinningOption::open, AxisDirection::AxisY);
0047   }
0048 
0049   auto channelize(const Vector3 &pos3, const Vector3 &dir3) const {
0050     Vector4 pos4 = Vector4::Zero();
0051     pos4.segment<3>(ePos0) = pos3;
0052     Vector4 mom4 = Vector4::Zero();
0053     mom4.segment<3>(eMom0) = dir3;
0054     ActsFatras::Hit hit({}, {}, pos4, mom4, mom4);
0055     auto res = channelizer.channelize(hit, *surface, gctx, driftDir,
0056                                       segmentation, thickness);
0057     BOOST_REQUIRE(res.ok());
0058     return *res;
0059   }
0060 };
0061 
0062 namespace ActsTests {
0063 
0064 BOOST_AUTO_TEST_SUITE(DigitizationSuite)
0065 
0066 BOOST_AUTO_TEST_CASE(test_upright_particle) {
0067   Helper helper;
0068 
0069   Vector3 pos3 = Vector3{10_um, 10_um, 0.0};
0070   Vector3 dir3 = Vector3{0.0, 0.0, helper.thickness}.normalized();
0071 
0072   auto segments = helper.channelize(pos3, dir3);
0073 
0074   BOOST_CHECK_EQUAL(segments.size(), 1);
0075   BOOST_CHECK_CLOSE(segments[0].activation, helper.thickness, 1.e-8);
0076 }
0077 
0078 BOOST_AUTO_TEST_CASE(test_tilted_particle) {
0079   Helper helper;
0080 
0081   const double disp = 10_um;
0082 
0083   Vector3 hitPosition = Vector3{10_um, 10_um, 0.0};
0084   Vector3 hitDirection = Vector3({disp, 0.0, helper.thickness}).normalized();
0085 
0086   auto segments = helper.channelize(hitPosition, hitDirection);
0087 
0088   std::cout << "Segments:\n";
0089   for (const auto &seg : segments) {
0090     std::cout << " - (" << seg.bin[0] << ", " << seg.bin[1]
0091               << "), activation: " << seg.activation << "\n";
0092   }
0093 
0094   BOOST_CHECK_EQUAL(segments.size(), 1);
0095   BOOST_CHECK_CLOSE(segments[0].activation, std::hypot(disp, helper.thickness),
0096                     1.e-8);
0097 }
0098 
0099 BOOST_AUTO_TEST_CASE(test_more_tilted_particle) {
0100   Helper helper;
0101 
0102   const double disp = 50_um;
0103 
0104   Vector3 hitPosition = Vector3{10_um, 10_um, 0.0};
0105   Vector3 hitDirection = Vector3{disp, 0.0, helper.thickness}.normalized();
0106 
0107   auto segments = helper.channelize(hitPosition, hitDirection);
0108 
0109   BOOST_CHECK_EQUAL(segments.size(), 2);
0110   auto sum =
0111       std::accumulate(segments.begin(), segments.end(), 0.0,
0112                       [](double s, auto seg) { return s + seg.activation; });
0113   BOOST_CHECK_CLOSE(sum, std::hypot(disp, helper.thickness), 1.e-8);
0114 }
0115 
0116 // This should go directly up on the segment border
0117 BOOST_AUTO_TEST_CASE(test_pathological_upright_particle) {
0118   Helper helper;
0119 
0120   Vector3 hitPosition = Vector3{0.0, 10_um, 0.0};
0121   Vector3 hitDirection = Vector3{0.0, 0.0, helper.thickness}.normalized();
0122 
0123   auto segments = helper.channelize(hitPosition, hitDirection);
0124 
0125   BOOST_CHECK_EQUAL(segments.size(), 1);
0126   BOOST_CHECK_CLOSE(segments[0].activation, helper.thickness, 1.e-8);
0127 }
0128 
0129 // This should go directly up on the segment border
0130 // TODO why does this does not activate both cells with half of the path???
0131 BOOST_AUTO_TEST_CASE(test_pathological_tilted_particle) {
0132   Helper helper;
0133 
0134   double disp = 2.0_um;
0135 
0136   Vector3 hitPosition = Vector3{-0.5 * disp, 10_um, 0.0};
0137   Vector3 hitDirection = Vector3{disp, 0.0, helper.thickness}.normalized();
0138 
0139   auto segments = helper.channelize(hitPosition, hitDirection);
0140 
0141   std::cout << "Segments:\n";
0142   for (const auto &seg : segments) {
0143     std::cout << " - (" << seg.bin[0] << ", " << seg.bin[1]
0144               << "), activation: " << seg.activation << "\n";
0145   }
0146 
0147   BOOST_CHECK_EQUAL(segments.size(), 2);
0148   auto sum =
0149       std::accumulate(segments.begin(), segments.end(), 0.0,
0150                       [](double s, auto seg) { return s + seg.activation; });
0151   BOOST_CHECK_CLOSE(sum, std::hypot(disp, helper.thickness), 1.e-8);
0152 }
0153 
0154 BOOST_AUTO_TEST_SUITE_END()
0155 
0156 }  // namespace ActsTests