Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-09 08:31:31

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/Geometry/DiscLayer.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0014 #include "Acts/Geometry/Layer.hpp"
0015 #include "Acts/Geometry/LayerCreator.hpp"
0016 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0017 #include "Acts/Surfaces/DiscSurface.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/RadialBounds.hpp"
0020 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0021 #include "Acts/Utilities/TransformHelpers.hpp"
0022 #include "ActsPlugins/ActSVG/LayerSvgConverter.hpp"
0023 #include "ActsPlugins/ActSVG/SvgUtils.hpp"
0024 #include "ActsTests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0025 
0026 #include <fstream>
0027 #include <memory>
0028 #include <numbers>
0029 #include <vector>
0030 
0031 using namespace Acts;
0032 using namespace ActsPlugins;
0033 
0034 namespace ActsTests {
0035 
0036 auto tgContext = GeometryContext::dangerouslyDefaultConstruct();
0037 
0038 std::shared_ptr<const LayerCreator> lCreator(nullptr);
0039 
0040 void setupTools() {
0041   if (lCreator == nullptr) {
0042     LayerCreator::Config lCreatorCfg;
0043     lCreatorCfg.surfaceArrayCreator =
0044         std::make_shared<const SurfaceArrayCreator>();
0045     lCreator = std::make_shared<const LayerCreator>(lCreatorCfg);
0046   }
0047 }
0048 
0049 std::shared_ptr<Layer> generateDiscLayer(double rInner, double rOuter,
0050                                          unsigned int quarterSegments,
0051                                          unsigned int nRings,
0052                                          bool useTrapezoids = false) {
0053   // Some preparations
0054   setupTools();
0055   unsigned int fullSegments = 4 * quarterSegments;
0056   std::vector<std::shared_ptr<const Surface>> moduleSurfaces;
0057   double phiStep = 2 * std::numbers::pi / fullSegments;
0058   double rStep = (rOuter - rInner) / nRings;
0059   // Reserve & fill
0060   moduleSurfaces.reserve(fullSegments * nRings);
0061   // Radial disc
0062   if (!useTrapezoids) {
0063     for (unsigned int ir = 0; ir < nRings; ++ir) {
0064       std::shared_ptr<const RadialBounds> rBounds = nullptr;
0065       rBounds = std::make_shared<RadialBounds>(
0066           rInner + ir * rStep - 0.025 * rInner,
0067           rInner + (ir + 1u) * rStep + 0.025 * rInner, 0.55 * phiStep, 0.);
0068       for (unsigned int is = 0; is < fullSegments; ++is) {
0069         // Place the module
0070         auto placement = Transform3::Identity();
0071         if ((is % 2) != 0u) {
0072           placement.pretranslate(Vector3{0., 0., 2.});
0073         }
0074         placement.rotate(Eigen::AngleAxisd(is * phiStep, Vector3(0, 0, 1)));
0075         auto dModule = Surface::makeShared<DiscSurface>(placement, rBounds);
0076         moduleSurfaces.push_back(dModule);
0077       }
0078     }
0079   } else {
0080     for (unsigned int ir = 0; ir < nRings; ++ir) {
0081       // Trapezoid parameters
0082       double radius = rInner + (ir + 0.5) * rStep;
0083       double yHalf = rStep * 0.5125;
0084 
0085       double xHalfMin =
0086           1.15 * (rInner + ir * rStep) * std::numbers::pi / fullSegments;
0087       double xHalfMax =
0088           1.15 * (rInner + (ir + 1) * rStep) * std::numbers::pi / fullSegments;
0089 
0090       std::shared_ptr<const TrapezoidBounds> tBounds =
0091           std::make_shared<const TrapezoidBounds>(xHalfMin, xHalfMax, yHalf);
0092       for (unsigned int is = 0; is < fullSegments; ++is) {
0093         // Setting the phi
0094         double cphi = -std::numbers::pi + is * phiStep;
0095         Vector3 center(radius * std::cos(cphi), radius * std::sin(cphi),
0096                        (is % 2) * 2 + (ir % 2) * 5);
0097         // Local axis system
0098         Vector3 localY(std::cos(cphi), std::sin(cphi), 0.);
0099         Vector3 localZ(0., 0., 1.);
0100         Vector3 localX = localY.cross(localZ);
0101         RotationMatrix3 rotation;
0102         rotation.col(0) = localX;
0103         rotation.col(1) = localY;
0104         rotation.col(2) = localZ;
0105         Transform3 placement = makeTransform3(rotation, center);
0106         // Create the module surface
0107         auto dModule = Surface::makeShared<PlaneSurface>(placement, tBounds);
0108         moduleSurfaces.push_back(dModule);
0109       }
0110     }
0111   }
0112   // Let's create the disc layer
0113   return lCreator->discLayer(tgContext, moduleSurfaces, nRings, fullSegments);
0114 }
0115 
0116 BOOST_AUTO_TEST_SUITE(ActSvgSuite)
0117 
0118 BOOST_AUTO_TEST_CASE(DiscLayerRadialSvg) {
0119   // Planar style
0120   Svg::Style discLayerStyle;
0121   discLayerStyle.fillColor = {51, 153, 255};
0122   discLayerStyle.fillOpacity = 0.75;
0123   discLayerStyle.highlightColor = {255, 153, 51};
0124   discLayerStyle.highlights = {"mouseover", "mouseout"};
0125   discLayerStyle.strokeColor = {25, 25, 25};
0126   discLayerStyle.strokeWidth = 0.5;
0127   discLayerStyle.quarterSegments = 72u;
0128 
0129   GeometryIdentifier geoID{0};
0130 
0131   // Get the layer
0132   auto discLayer = generateDiscLayer(100, 250, 32u, 4u);
0133 
0134   Svg::LayerConverter::Options lOptions;
0135   lOptions.name = "disc_layer_sectors";
0136   lOptions.surfaceStyles =
0137       GeometryHierarchyMap<Svg::Style>({{geoID, discLayerStyle}});
0138 
0139   // Get the layer sheets
0140   auto discLayerSheets =
0141       Svg::LayerConverter::convert(tgContext, *discLayer, lOptions);
0142 
0143   for (const auto& s : discLayerSheets) {
0144     Svg::toFile({s}, s._id + ".svg");
0145   }
0146 }
0147 
0148 BOOST_AUTO_TEST_CASE(DiscLayerTrapezoidSvg) {
0149   // Planar style
0150   Svg::Style discLayerStyle;
0151   discLayerStyle.fillColor = {51, 153, 255};
0152   discLayerStyle.fillOpacity = 0.75;
0153   discLayerStyle.highlightColor = {255, 153, 51};
0154   discLayerStyle.highlights = {"mouseover", "mouseout"};
0155   discLayerStyle.strokeColor = {25, 25, 25};
0156   discLayerStyle.strokeWidth = 0.5;
0157   discLayerStyle.quarterSegments = 72u;
0158 
0159   GeometryIdentifier geoID{0};
0160 
0161   // Get the layer
0162   auto discLayer = generateDiscLayer(100, 250, 32u, 4u, true);
0163 
0164   Svg::LayerConverter::Options lOptions;
0165   lOptions.name = "disc_layer_trapezoid";
0166   lOptions.surfaceStyles =
0167       GeometryHierarchyMap<Svg::Style>({{geoID, discLayerStyle}});
0168 
0169   // Get the layer sheets
0170   auto discLayerSheets =
0171       Svg::LayerConverter::convert(tgContext, *discLayer, lOptions);
0172 
0173   for (const auto& s : discLayerSheets) {
0174     Svg::toFile({s}, s._id + ".svg");
0175   }
0176 }
0177 
0178 BOOST_AUTO_TEST_CASE(CylinderLayerSvg) {
0179   // Planar style
0180   Svg::Style cylinderLayerStyle;
0181   cylinderLayerStyle.fillColor = {51, 153, 255};
0182   cylinderLayerStyle.fillOpacity = 0.75;
0183   cylinderLayerStyle.highlightColor = {255, 153, 51};
0184   cylinderLayerStyle.highlights = {"mouseover", "mouseout"};
0185   cylinderLayerStyle.strokeColor = {25, 25, 25};
0186   cylinderLayerStyle.strokeWidth = 0.5;
0187   cylinderLayerStyle.quarterSegments = 72u;
0188 
0189   GeometryIdentifier geoID{0};
0190 
0191   CylindricalTrackingGeometry cGeometry(tgContext);
0192   auto tGeometry = cGeometry();
0193   auto pixelVolume =
0194       tGeometry->resolveLowestTrackingVolume(tgContext, Vector3(50., 0., 0.))
0195           .value();
0196   if (pixelVolume != nullptr && pixelVolume->confinedLayers() != nullptr) {
0197     auto layers = pixelVolume->confinedLayers()->arrayObjects();
0198     std::size_t il = 0;
0199     for (const auto& layer : layers) {
0200       if (layer->surfaceArray() == nullptr) {
0201         continue;
0202       }
0203 
0204       Svg::LayerConverter::Options lOptions;
0205       lOptions.name = "cylinder_layer_" + std::to_string(il++);
0206       lOptions.surfaceStyles =
0207           GeometryHierarchyMap<Svg::Style>({{geoID, cylinderLayerStyle}});
0208 
0209       // Get the layer sheets
0210       auto layerSheets =
0211           Svg::LayerConverter::convert(tgContext, *layer, lOptions);
0212       for (const auto& s : layerSheets) {
0213         Svg::toFile({s}, s._id + ".svg");
0214       }
0215     }
0216   }
0217 }
0218 
0219 BOOST_AUTO_TEST_CASE(PlaeyLayerSvg) {}
0220 
0221 BOOST_AUTO_TEST_SUITE_END()
0222 
0223 }  // namespace ActsTests