Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:04

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/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Tolerance.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/DiscBounds.hpp"
0016 #include "Acts/Surfaces/DiscSurface.hpp"
0017 #include "Acts/Surfaces/PlanarBounds.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/RadialBounds.hpp"
0020 #include "Acts/Surfaces/RectangleBounds.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 #include "Acts/Utilities/Helpers.hpp"
0024 #include "Acts/Utilities/Result.hpp"
0025 #include "ActsFatras/Digitization/PlanarSurfaceMask.hpp"
0026 
0027 #include <array>
0028 #include <cmath>
0029 #include <fstream>
0030 #include <memory>
0031 #include <numbers>
0032 #include <string>
0033 #include <tuple>
0034 #include <utility>
0035 #include <vector>
0036 
0037 #include "DigitizationCsvOutput.hpp"
0038 #include "PlanarSurfaceTestBeds.hpp"
0039 
0040 namespace bdata = boost::unit_test::data;
0041 
0042 namespace ActsFatras {
0043 
0044 std::vector<std::array<std::ofstream, 3>> out;
0045 
0046 BOOST_AUTO_TEST_SUITE(Digitization)
0047 
0048 BOOST_AUTO_TEST_CASE(PlaneMaskRectangleBounds) {
0049   auto rectangleBounds = std::make_shared<Acts::RectangleBounds>(2., 3.5);
0050   auto planeSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0051       Acts::Transform3::Identity(), rectangleBounds);
0052 
0053   ActsFatras::PlanarSurfaceMask psm;
0054 
0055   /// Case one : one outside
0056   std::array<Acts::Vector2, 2> segment = {Acts::Vector2(2.5, -4.5),
0057                                           Acts::Vector2(-1., -1.)};
0058   auto clipped = psm.apply(*planeSurface, segment).value();
0059 
0060   CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0061   CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0062   CHECK_CLOSE_ABS(clipped[0].x(), 1.5, Acts::s_epsilon);
0063   CHECK_CLOSE_ABS(clipped[0].y(), -3.5, Acts::s_epsilon);
0064 
0065   /// Case two : two outside
0066   segment = {Acts::Vector2(1., 4.), Acts::Vector2(3., 2.)};
0067   clipped = psm.apply(*planeSurface, segment).value();
0068 
0069   CHECK_CLOSE_ABS(clipped[1].x(), 2., Acts::s_epsilon);
0070   CHECK_CLOSE_ABS(clipped[1].y(), 3., Acts::s_epsilon);
0071   CHECK_CLOSE_ABS(clipped[0].x(), 1.5, Acts::s_epsilon);
0072   CHECK_CLOSE_ABS(clipped[0].y(), 3.5, Acts::s_epsilon);
0073 
0074   /// Case two : both inside (most likely case, untouched)
0075   segment = {Acts::Vector2(-1., 0.5), Acts::Vector2(0., 2.)};
0076   clipped = psm.apply(*planeSurface, segment).value();
0077 
0078   CHECK_CLOSE_ABS(clipped[0].x(), segment[0].x(), Acts::s_epsilon);
0079   CHECK_CLOSE_ABS(clipped[0].y(), segment[0].y(), Acts::s_epsilon);
0080   CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0081   CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0082 }
0083 
0084 BOOST_AUTO_TEST_CASE(DiscMaskRadialBounds) {
0085   auto discRadial = std::make_shared<Acts::RadialBounds>(
0086       2., 7.5, std::numbers::pi / 4., std::numbers::pi / 2.);
0087   auto discSurface = Acts::Surface::makeShared<Acts::DiscSurface>(
0088       Acts::Transform3::Identity(), discRadial);
0089 
0090   ActsFatras::PlanarSurfaceMask psm;
0091 
0092   /// Case one : one outside R min
0093   std::array<Acts::Vector2, 2> segment = {Acts::Vector2(0.5, 1.8),
0094                                           Acts::Vector2(0.9, 6.)};
0095   auto clipped = psm.apply(*discSurface, segment).value();
0096 
0097   CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0098   CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0099   CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[0]), 2.,
0100                   5 * Acts::s_epsilon);
0101 
0102   /// Case two : one outside R max
0103   segment = {Acts::Vector2(0.5, 2.8), Acts::Vector2(0.9, 8.5)};
0104   clipped = psm.apply(*discSurface, segment).value();
0105 
0106   CHECK_CLOSE_ABS(clipped[0].x(), segment[0].x(), Acts::s_epsilon);
0107   CHECK_CLOSE_ABS(clipped[0].y(), segment[0].y(), Acts::s_epsilon);
0108   CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[1]), 7.5,
0109                   5 * Acts::s_epsilon);
0110 
0111   /// Case three : both outside R min / max
0112   segment = {Acts::Vector2(0.5, 1.8), Acts::Vector2(0.9, 8.5)};
0113   clipped = psm.apply(*discSurface, segment).value();
0114   CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[0]), 2.,
0115                   5 * Acts::s_epsilon);
0116   CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[1]), 7.5,
0117                   5 * Acts::s_epsilon);
0118   /// Case four: outside phi min
0119   segment = {Acts::Vector2(2.8, 2.5), Acts::Vector2(0., 3.5)};
0120   clipped = psm.apply(*discSurface, segment).value();
0121   CHECK_CLOSE_ABS(Acts::VectorHelpers::phi(clipped[0]), std::numbers::pi / 4.,
0122                   Acts::s_epsilon);
0123 
0124   /// Case five: outside phi max
0125   segment = {Acts::Vector2(0., 3.5), Acts::Vector2(-8., 5.)};
0126   clipped = psm.apply(*discSurface, segment).value();
0127   CHECK_CLOSE_ABS(Acts::VectorHelpers::phi(clipped[1]),
0128                   std::numbers::pi / 2. + std::numbers::pi / 4.,
0129                   Acts::s_epsilon);
0130 }
0131 
0132 std::vector<std::array<std::ofstream, 3>> segmentOutput;
0133 int ntests = 100;
0134 
0135 /// Unit test for testing the Surface mask
0136 BOOST_DATA_TEST_CASE(
0137     RandomPlanarSurfaceMask,
0138     bdata::random((
0139         bdata::engine = std::mt19937(), bdata::seed = 1,
0140         bdata::distribution = std::uniform_real_distribution<double>(0., 1.))) ^
0141         bdata::random((bdata::engine = std::mt19937(), bdata::seed = 2,
0142                        bdata::distribution =
0143                            std::uniform_real_distribution<double>(0., 1.))) ^
0144         bdata::random((bdata::engine = std::mt19937(), bdata::seed = 3,
0145                        bdata::distribution =
0146                            std::uniform_real_distribution<double>(0., 1.))) ^
0147         bdata::random((bdata::engine = std::mt19937(), bdata::seed = 4,
0148                        bdata::distribution =
0149                            std::uniform_real_distribution<double>(0., 1.))) ^
0150         bdata::xrange(ntests),
0151     startR0, startR1, endR0, endR1, index) {
0152   Acts::GeometryContext geoCtx;
0153 
0154   ActsFatras::PlanarSurfaceMask psm;
0155 
0156   // Test beds with random numbers generated inside
0157   PlanarSurfaceTestBeds pstd;
0158   // Smearing 10 percent outside
0159   auto testBeds = pstd(1.1);
0160 
0161   DigitizationCsvOutput csvHelper;
0162 
0163   int itb = 0;
0164   for (const auto& tb : testBeds) {
0165     const auto& name = std::get<0>(tb);
0166     const auto* surface = (std::get<1>(tb)).get();
0167     const auto& randomizer = std::get<3>(tb);
0168 
0169     if (index == 0) {
0170       std::ofstream shape;
0171       const Acts::Vector2 centerXY = surface->center(geoCtx).segment<2>(0);
0172 
0173       // 0 - write the shape
0174       shape.open("PlanarSurfaceMask" + name + "Borders.csv");
0175       if (surface->type() == Acts::Surface::Plane) {
0176         const auto* pBounds =
0177             static_cast<const Acts::PlanarBounds*>(&(surface->bounds()));
0178         csvHelper.writePolygon(shape, pBounds->vertices(1), -centerXY);
0179       } else if (surface->type() == Acts::Surface::Disc) {
0180         const auto* dBounds =
0181             static_cast<const Acts::DiscBounds*>(&(surface->bounds()));
0182         csvHelper.writePolygon(shape, dBounds->vertices(72), -centerXY);
0183       }
0184 
0185       segmentOutput.push_back(std::array<std::ofstream, 3>());
0186       segmentOutput[itb][0].open("PlanarSurfaceMask" + name + "Inside.csv");
0187       segmentOutput[itb][1].open("PlanarSurfaceMask" + name + "Clipped.csv");
0188       segmentOutput[itb][2].open("PlanarSurfaceMask" + name + "Outside.csv");
0189     }
0190 
0191     auto start = randomizer(startR0, startR1);
0192     auto end = randomizer(endR0, endR1);
0193 
0194     std::array<Acts::Vector2, 2> segment = {start, end};
0195     auto clippedTest = psm.apply(*surface, segment);
0196     if (clippedTest.ok()) {
0197       auto clipped = clippedTest.value();
0198       if (segment == clipped) {
0199         csvHelper.writeLine(segmentOutput[itb][0], start, end);
0200       } else {
0201         csvHelper.writeLine(segmentOutput[itb][1], clipped[0], clipped[1]);
0202       }
0203     } else {
0204       csvHelper.writeLine(segmentOutput[itb][2], start, end);
0205     }
0206     ++itb;
0207   }
0208 
0209   // close the lines
0210   if (itb == ntests - 1) {
0211     segmentOutput[itb][0].close();
0212     segmentOutput[itb][1].close();
0213     segmentOutput[itb][2].close();
0214   }
0215 }
0216 
0217 BOOST_AUTO_TEST_SUITE_END()
0218 
0219 }  // namespace ActsFatras