Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:39

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