Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-29 08:19:25

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 "ActsExamples/GenericDetector/GenericDetector.hpp"
0010 
0011 #include "Acts/Geometry/Blueprint.hpp"
0012 #include "Acts/Geometry/BlueprintNode.hpp"
0013 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/CylinderVolumeBuilder.hpp"
0016 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0017 #include "Acts/Geometry/Extent.hpp"
0018 #include "Acts/Geometry/LayerArrayCreator.hpp"
0019 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0020 #include "Acts/Geometry/LayerCreator.hpp"
0021 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0022 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0023 #include "Acts/Geometry/PassiveLayerBuilder.hpp"
0024 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0025 #include "Acts/Geometry/TrackingGeometry.hpp"
0026 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0027 #include "Acts/Geometry/TrackingVolume.hpp"
0028 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
0029 #include "Acts/Geometry/VolumeAttachmentStrategy.hpp"
0030 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0031 #include "Acts/Navigation/CylinderNavigationPolicy.hpp"
0032 #include "Acts/Navigation/SurfaceArrayNavigationPolicy.hpp"
0033 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0034 #include "Acts/Utilities/AxisDefinitions.hpp"
0035 #include "ActsExamples/GenericDetector/GenericDetectorElement.hpp"
0036 #include "ActsExamples/GenericDetector/LayerBuilder.hpp"
0037 
0038 #include <fstream>
0039 
0040 #include "./GenericDetectorBuilder.hpp"
0041 
0042 namespace ActsExamples {
0043 
0044 namespace Generic {
0045 namespace {
0046 
0047 class Gen1GenericDetectorBuilder : public GenericDetectorBuilder {
0048  public:
0049   using GenericDetectorBuilder::GenericDetectorBuilder;
0050 
0051   std::unique_ptr<const Acts::TrackingGeometry> buildTrackingGeometry(
0052       const Acts::GeometryContext& gctx,
0053       std::shared_ptr<const Acts::IMaterialDecorator> matDecorator,
0054       Acts::Logging::Level surfaceLLevel, Acts::Logging::Level volumeLLevel);
0055 };
0056 
0057 std::unique_ptr<const Acts::TrackingGeometry>
0058 Gen1GenericDetectorBuilder::buildTrackingGeometry(
0059     const Acts::GeometryContext& gctx,
0060     std::shared_ptr<const Acts::IMaterialDecorator> matDecorator,
0061     Acts::Logging::Level surfaceLLevel, Acts::Logging::Level volumeLLevel) {
0062   ACTS_INFO("Building tracking geometry for Generic Detector in Gen1 mode");
0063   using namespace Acts::UnitLiterals;
0064 
0065   // configure surface array creator
0066   Acts::SurfaceArrayCreator::Config sacConfig;
0067   auto surfaceArrayCreator = std::make_shared<const Acts::SurfaceArrayCreator>(
0068       sacConfig, logger().clone("SurfaceArrayCreator", surfaceLLevel));
0069   // configure the layer creator that uses the surface array creator
0070   Acts::LayerCreator::Config lcConfig;
0071   lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0072   auto layerCreator = std::make_shared<const Acts::LayerCreator>(
0073       lcConfig, logger().clone("LayerCreator", m_cfg.layerLogLevel));
0074   // configure the layer array creator
0075   Acts::LayerArrayCreator::Config lacConfig;
0076   auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
0077       lacConfig, logger().clone("LayerArrayCreator", m_cfg.layerLogLevel));
0078   // tracking volume array creator
0079   Acts::TrackingVolumeArrayCreator::Config tvacConfig;
0080   auto tVolumeArrayCreator =
0081       std::make_shared<const Acts::TrackingVolumeArrayCreator>(
0082           tvacConfig,
0083           logger().clone("TrackingVolumeArrayCreator", volumeLLevel));
0084   // configure the cylinder volume helper
0085   Acts::CylinderVolumeHelper::Config cvhConfig;
0086   cvhConfig.layerArrayCreator = layerArrayCreator;
0087   cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator;
0088   auto cylinderVolumeHelper =
0089       std::make_shared<const Acts::CylinderVolumeHelper>(
0090           cvhConfig, logger().clone("CylinderVolumeHelper", volumeLLevel));
0091   //-------------------------------------------------------------------------------------
0092   // vector of the volume builders
0093   std::vector<std::shared_ptr<const Acts::ITrackingVolumeBuilder>>
0094       volumeBuilders;
0095 
0096   ACTS_DEBUG("Building BeamPipe");
0097   //-------------------------------------------------------------------------------------
0098   // Beam Pipe
0099   //-------------------------------------------------------------------------------------
0100 
0101   // configure the beam pipe layer builder
0102   Acts::PassiveLayerBuilder::Config bplConfig;
0103   bplConfig.layerIdentification = "BeamPipe";
0104   bplConfig.centralLayerRadii = std::vector<double>(1, kBeamPipeRadius);
0105   bplConfig.centralLayerHalflengthZ =
0106       std::vector<double>(1, kBeamPipeHalfLengthZ);
0107   bplConfig.centralLayerThickness = std::vector<double>(1, kBeamPipeThickness);
0108   bplConfig.centralLayerMaterial = {m_beamPipeMaterial};
0109   auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
0110       bplConfig, logger().clone("BeamPipeLayerBuilder", m_cfg.layerLogLevel));
0111   // create the volume for the beam pipe
0112   Acts::CylinderVolumeBuilder::Config bpvConfig;
0113   bpvConfig.trackingVolumeHelper = cylinderVolumeHelper;
0114   bpvConfig.volumeName = "BeamPipe";
0115   bpvConfig.layerBuilder = beamPipeBuilder;
0116   bpvConfig.layerEnvelopeR = {1. * Acts::UnitConstants::mm,
0117                               1. * Acts::UnitConstants::mm};
0118   bpvConfig.buildToRadiusZero = true;
0119   auto beamPipeVolumeBuilder =
0120       std::make_shared<const Acts::CylinderVolumeBuilder>(
0121           bpvConfig, logger().clone("BeamPipeVolumeBuilder", volumeLLevel));
0122   // add to the list of builders
0123   volumeBuilders.push_back(beamPipeVolumeBuilder);
0124 
0125   ACTS_DEBUG("Building Pixel");
0126   //-------------------------------------------------------------------------------------
0127   //-------------------------------------------------------------------------------------
0128   // Pixel detector
0129   //-------------------------------------------------------------------------------------
0130   // some prep work
0131 
0132   ProtoLayerCreator pplCreator = createPixelProtoLayerCreator();
0133 
0134   // configure pixel layer builder
0135   LayerBuilder::Config plbConfig;
0136   plbConfig.layerCreator = layerCreator;
0137   plbConfig.layerIdentification = "Pixel";
0138   // material concentration always outside the modules
0139   plbConfig.centralProtoLayers = pplCreator.centralProtoLayers(gctx);
0140   plbConfig.centralLayerMaterialConcentration = {1, 1, 1, 1};
0141   plbConfig.centralLayerMaterial = {
0142       m_pixelCentralMaterial, m_pixelCentralMaterial, m_pixelCentralMaterial,
0143       m_pixelCentralMaterial};
0144   if (m_cfg.buildLevel > 0) {
0145     // material concentration is always behind the layer in the pixels
0146     plbConfig.posnegLayerMaterialConcentration = std::vector<int>(7, 0);
0147     // layer structure surface has pixel material properties
0148     plbConfig.posnegLayerMaterial = {
0149         m_pixelEndcapMaterial, m_pixelEndcapMaterial, m_pixelEndcapMaterial,
0150         m_pixelEndcapMaterial, m_pixelEndcapMaterial, m_pixelEndcapMaterial,
0151         m_pixelEndcapMaterial};
0152     // negative proto layers
0153     plbConfig.negativeProtoLayers = pplCreator.negativeProtoLayers(gctx);
0154     plbConfig.positiveProtoLayers = pplCreator.positiveProtoLayers(gctx);
0155   }
0156   // define the builder
0157   auto pixelLayerBuilder = std::make_shared<const LayerBuilder>(
0158       plbConfig, logger().clone("PixelLayerBuilder", m_cfg.layerLogLevel));
0159   //-------------------------------------------------------------------------------------
0160   // build the pixel volume
0161   Acts::CylinderVolumeBuilder::Config pvbConfig;
0162   pvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
0163   pvbConfig.volumeName = "Pixel";
0164   pvbConfig.buildToRadiusZero = false;
0165   pvbConfig.layerEnvelopeR = {1. * Acts::UnitConstants::mm,
0166                               5. * Acts::UnitConstants::mm};
0167   pvbConfig.layerBuilder = pixelLayerBuilder;
0168   auto pixelVolumeBuilder = std::make_shared<const Acts::CylinderVolumeBuilder>(
0169       pvbConfig, logger().clone("PixelVolumeBuilder", volumeLLevel));
0170   // add to the list of builders
0171   volumeBuilders.push_back(pixelVolumeBuilder);
0172 
0173   if (m_cfg.buildLevel > 1) {
0174     ACTS_DEBUG("Building PST");
0175     //-------------------------------------------------------------------------------------
0176     //-------------------------------------------------------------------------------------
0177     // Pixel Support Tybe (PST)
0178     //-------------------------------------------------------------------------------------
0179 
0180     // Configuration
0181     Acts::PassiveLayerBuilder::Config pstConfig;
0182     pstConfig.layerIdentification = "PST";
0183     pstConfig.centralLayerRadii = std::vector<double>(1, kPstRadius);
0184     pstConfig.centralLayerHalflengthZ = std::vector<double>(1, kPstHalfLengthZ);
0185     pstConfig.centralLayerThickness = std::vector<double>(1, kPstThickness);
0186     pstConfig.centralLayerMaterial = {m_pstMaterial};
0187     auto pstBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
0188         pstConfig, logger().clone("PSTLayerBuilder", m_cfg.layerLogLevel));
0189     // create the volume for the beam pipe
0190     Acts::CylinderVolumeBuilder::Config pstvolConfig;
0191     pstvolConfig.trackingVolumeHelper = cylinderVolumeHelper;
0192     pstvolConfig.volumeName = "PST";
0193     pstvolConfig.buildToRadiusZero = false;
0194     pstvolConfig.layerBuilder = pstBuilder;
0195     auto pstVolumeBuilder = std::make_shared<const Acts::CylinderVolumeBuilder>(
0196         pstvolConfig, logger().clone("PSTVolumeBuilder", volumeLLevel));
0197     // add to the detector builds
0198     volumeBuilders.push_back(pstVolumeBuilder);
0199 
0200     ACTS_DEBUG("Building SStrip");
0201     //-------------------------------------------------------------------------------------
0202     // SHORT strip detector
0203     //-------------------------------------------------------------------------------------
0204     // first add a Pixel Support Tube
0205     // STRIPS
0206     //
0207     // fill necessary vectors for configuration
0208     //-------------------------------------------------------------------------------------
0209     // some prep work
0210 
0211     ProtoLayerCreator ssplCreator = createShortStripProtoLayerCreator();
0212 
0213     std::size_t nposnegs = ssplCreator.config().posnegLayerPositionsZ.size();
0214 
0215     // configure short strip layer builder
0216     LayerBuilder::Config sslbConfig;
0217     sslbConfig.layerCreator = layerCreator;
0218     sslbConfig.layerIdentification = "SStrip";
0219 
0220     sslbConfig.centralProtoLayers = ssplCreator.centralProtoLayers(gctx);
0221     sslbConfig.centralLayerMaterialConcentration = {-1, -1, -1, -1};
0222     sslbConfig.centralLayerMaterial = {
0223         m_shortStripCentralMaterial, m_shortStripCentralMaterial,
0224         m_shortStripCentralMaterial, m_shortStripCentralMaterial};
0225 
0226     if (m_cfg.buildLevel > 2) {
0227       sslbConfig.negativeProtoLayers = ssplCreator.negativeProtoLayers(gctx);
0228       sslbConfig.positiveProtoLayers = ssplCreator.positiveProtoLayers(gctx);
0229 
0230       sslbConfig.posnegLayerMaterialConcentration =
0231           std::vector<int>(nposnegs, 0);
0232       sslbConfig.posnegLayerMaterial =
0233           std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>(
0234               nposnegs, m_shortStripEndcapMaterial);
0235     }
0236 
0237     // define the builder
0238     auto sstripLayerBuilder = std::make_shared<const LayerBuilder>(
0239         sslbConfig, logger().clone("SStripLayerBuilder", m_cfg.layerLogLevel));
0240     //-------------------------------------------------------------------------------------
0241     // build the pixel volume
0242     Acts::CylinderVolumeBuilder::Config ssvbConfig;
0243     ssvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
0244     ssvbConfig.volumeName = "SStrip";
0245     ssvbConfig.buildToRadiusZero = false;
0246     ssvbConfig.layerBuilder = sstripLayerBuilder;
0247     auto sstripVolumeBuilder =
0248         std::make_shared<const Acts::CylinderVolumeBuilder>(
0249             ssvbConfig, logger().clone("SStripVolumeBuilder", volumeLLevel));
0250 
0251     //-------------------------------------------------------------------------------------
0252     // add to the list of builders
0253     volumeBuilders.push_back(sstripVolumeBuilder);
0254     //-------------------------------------------------------------------------------------
0255     ACTS_DEBUG("Building LStrip");
0256     //-------------------------------------------------------------------------------------
0257     // LONG strip detector
0258     //-------------------------------------------------------------------------------------
0259     // fill necessary vectors for configuration
0260     //-------------------------------------------------------------------------------------
0261 
0262     // some prep work
0263 
0264     ProtoLayerCreator lsplCreator = createLongStripProtoLayerCreator();
0265 
0266     // configure short strip layer builder
0267     Generic::LayerBuilder::Config lslbConfig;
0268     lslbConfig.layerCreator = layerCreator;
0269     lslbConfig.layerIdentification = "LStrip";
0270     lslbConfig.centralLayerMaterialConcentration = {-1, -1};
0271     lslbConfig.centralLayerMaterial = {m_longStripCentralMaterial,
0272                                        m_longStripCentralMaterial};
0273     lslbConfig.centralProtoLayers = lsplCreator.centralProtoLayers(gctx);
0274 
0275     if (m_cfg.buildLevel > 2) {
0276       lslbConfig.posnegLayerMaterialConcentration =
0277           std::vector<int>(nposnegs, 0);
0278       lslbConfig.posnegLayerMaterial =
0279           std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>(
0280               nposnegs, m_longStripEndcapMaterial);
0281       lslbConfig.negativeProtoLayers = lsplCreator.negativeProtoLayers(gctx);
0282       lslbConfig.positiveProtoLayers = lsplCreator.positiveProtoLayers(gctx);
0283     }
0284 
0285     // define the builder
0286     auto lstripLayerBuilder = std::make_shared<const LayerBuilder>(
0287         lslbConfig, logger().clone("LStripLayerBuilder", m_cfg.layerLogLevel));
0288     //-------------------------------------------------------------------------------------
0289     // build the pixel volume
0290     Acts::CylinderVolumeBuilder::Config lsvbConfig;
0291     lsvbConfig.trackingVolumeHelper = cylinderVolumeHelper;
0292     lsvbConfig.volumeName = "LStrip";
0293     lsvbConfig.buildToRadiusZero = false;
0294     lsvbConfig.layerBuilder = lstripLayerBuilder;
0295     auto lstripVolumeBuilder =
0296         std::make_shared<const Acts::CylinderVolumeBuilder>(
0297             lsvbConfig, logger().clone("LStripVolumeBuilder", volumeLLevel));
0298     // add to the list of builders
0299     volumeBuilders.push_back(lstripVolumeBuilder);
0300   }
0301 
0302   ACTS_DEBUG("Building TrackingGeometry");
0303   //-------------------------------------------------------------------------------------
0304   // create the tracking geometry
0305   Acts::TrackingGeometryBuilder::Config tgConfig;
0306   // Add the build call functions
0307   for (auto& vb : volumeBuilders) {
0308     tgConfig.trackingVolumeBuilders.emplace_back(
0309         [=](const auto& context, const auto& inner, const auto&) {
0310           return vb->trackingVolume(context, inner);
0311         });
0312   }
0313   tgConfig.trackingVolumeHelper = cylinderVolumeHelper;
0314   tgConfig.materialDecorator = std::move(matDecorator);
0315 
0316   auto cylinderGeometryBuilder =
0317       std::make_shared<const Acts::TrackingGeometryBuilder>(
0318           tgConfig,
0319           logger().clone("CylinderGeometryBuilder", Acts::Logging::INFO));
0320   // get the geometry
0321   auto trackingGeometry = cylinderGeometryBuilder->trackingGeometry(gctx);
0322   // return the tracking geometry
0323   return trackingGeometry;
0324 }
0325 
0326 class Gen3GenericDetectorBuilder : public GenericDetectorBuilder {
0327  public:
0328   using GenericDetectorBuilder::GenericDetectorBuilder;
0329 
0330   std::unique_ptr<const Acts::TrackingGeometry> buildTrackingGeometry(
0331       const Acts::GeometryContext& gctx,
0332       std::optional<std::filesystem::path> graphvizFile);
0333 
0334   void buildPixel(Acts::BlueprintNode& parent,
0335                   const Acts::GeometryContext& gctx);
0336 
0337   void buildShortStrip(Acts::BlueprintNode& parent,
0338                        const Acts::GeometryContext& gctx);
0339 
0340   void buildLongStrip(Acts::BlueprintNode& parent,
0341                       const Acts::GeometryContext& gctx);
0342 
0343   static std::shared_ptr<const Acts::HomogeneousSurfaceMaterial> asHomogeneous(
0344       std::string_view debugLabel,
0345       const std::shared_ptr<const Acts::ISurfaceMaterial>& material) {
0346     auto hm = std::dynamic_pointer_cast<const Acts::HomogeneousSurfaceMaterial>(
0347         material);
0348     if (hm == nullptr) {
0349       throw std::runtime_error(std::string{debugLabel} +
0350                                " material is not homogeneous");
0351     }
0352     return hm;
0353   }
0354 
0355   using LayerType = Acts::SurfaceArrayNavigationPolicy::LayerType;
0356   std::unique_ptr<Acts::NavigationPolicyFactory> createNavigationPolicy(
0357       LayerType layerType,
0358       std::pair<std::size_t, std::size_t> bins = {0, 0}) const {
0359     using SrfArrayNavPol = Acts::SurfaceArrayNavigationPolicy;
0360     return Acts::NavigationPolicyFactory{}
0361         .add<Acts::CylinderNavigationPolicy>()
0362         .add<SrfArrayNavPol>(
0363             SrfArrayNavPol::Config{.layerType = layerType, .bins = bins})
0364         .asUniquePtr();
0365   }
0366 };
0367 
0368 std::unique_ptr<const Acts::TrackingGeometry>
0369 Gen3GenericDetectorBuilder::buildTrackingGeometry(
0370     const Acts::GeometryContext& gctx,
0371     std::optional<std::filesystem::path> graphvizFile) {
0372   using enum Acts::AxisDirection;
0373   using namespace Acts::UnitLiterals;
0374   using namespace Acts;
0375   using enum Acts::AxisBoundaryType;
0376   using enum Acts::CylinderVolumeBounds::Face;
0377   ACTS_INFO("GenericDetector construction in  Gen3 mode");
0378 
0379   Blueprint::Config cfg;
0380   cfg.envelope = Acts::ExtentEnvelope{{
0381       .z = {20_mm, 20_mm},
0382       .r = {0_mm, 20_mm},
0383   }};
0384   Blueprint root{cfg};
0385 
0386   root.addCylinderContainer("Detector", AxisR, [&](auto& detector) {
0387     auto beampipeBounds = std::make_unique<Acts::CylinderVolumeBounds>(
0388         0_mm, kBeamPipeRadius, kBeamPipeHalfLengthZ);
0389     auto beampipe = std::make_unique<Acts::TrackingVolume>(
0390         Acts::Transform3::Identity(), std::move(beampipeBounds), "Beampipe");
0391 
0392     detector.addMaterial("BeampipeMaterial", [&](auto& bpMat) {
0393       bpMat.configureFace(OuterCylinder,
0394                           asHomogeneous("Beam pipe", m_beamPipeMaterial));
0395       bpMat.addStaticVolume(std::move(beampipe));
0396     });
0397 
0398     buildPixel(detector, gctx);
0399 
0400     if (m_cfg.buildLevel > 1) {
0401       buildShortStrip(detector, gctx);
0402       buildLongStrip(detector, gctx);
0403     }
0404   });
0405 
0406   if (graphvizFile) {
0407     std::ofstream file(*graphvizFile);
0408     root.graphviz(file);
0409   }
0410 
0411   BlueprintOptions options;
0412   auto trackingGeometry =
0413       root.construct(options, gctx, *logger().clone("Blprnt"));
0414   return trackingGeometry;
0415 }
0416 
0417 void Gen3GenericDetectorBuilder::buildPixel(Acts::BlueprintNode& parent,
0418                                             const Acts::GeometryContext& gctx) {
0419   using enum Acts::AxisDirection;
0420   using namespace Acts;
0421   using namespace Acts::UnitLiterals;
0422   using enum Acts::CylinderVolumeBounds::Face;
0423   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0424   using ResizeStrategy = Acts::VolumeResizeStrategy;
0425 
0426   ACTS_DEBUG("Building Pixel");
0427 
0428   ProtoLayerCreator pplCreator = createPixelProtoLayerCreator();
0429 
0430   auto& pixel = parent.addCylinderContainer("Pixel", AxisR);
0431 
0432   if (m_cfg.buildLevel > 1) {
0433     ACTS_DEBUG("Building PST");
0434     auto pstVolume = std::make_unique<Acts::TrackingVolume>(
0435         Acts::Transform3::Identity(),
0436         std::make_unique<Acts::CylinderVolumeBounds>(
0437             kPstRadius - kPstThickness, kPstRadius, kPstHalfLengthZ),
0438         "PST");
0439 
0440     pixel.addMaterial("PSTMaterial", [&](auto& pstMat) {
0441       pstMat.configureFace(OuterCylinder, asHomogeneous("PST", m_pstMaterial));
0442       pstMat.addStaticVolume(std::move(pstVolume));
0443     });
0444   }
0445 
0446   auto& sensitive = pixel.addCylinderContainer("Pixel", AxisZ);
0447   sensitive.addCylinderContainer("Pixel_Barrel", AxisR, [&](auto& barrel) {
0448     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0449     barrel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Gap);
0450 
0451     auto centralProtoLayerSurfaces = pplCreator.centralProtoLayers(gctx);
0452     ACTS_DEBUG("Adding " << centralProtoLayerSurfaces.size()
0453                          << " central proto layers to "
0454                          << "Pixel_Barrel");
0455     for (const auto& [idx, temp] :
0456 
0457          Acts::enumerate(centralProtoLayerSurfaces)) {
0458       auto& pl = temp.protoLayer;
0459       std::string layerName = "Pixel_Barrel_L" + std::to_string(idx);
0460       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0461         mat.configureFace(OuterCylinder,
0462                           asHomogeneous("Pixel", m_pixelCentralMaterial));
0463         mat.addLayer(layerName, [&](auto& layer) {
0464           ACTS_VERBOSE("Adding layer " << layer.name());
0465           layer.setProtoLayer(pl);
0466           layer.setEnvelope(
0467               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0468           layer.setNavigationPolicyFactory(
0469               createNavigationPolicy(LayerType::Cylinder));
0470 
0471           ACTS_VERBOSE("-> Number of surfaces: " << layer.surfaces().size());
0472         });
0473       });
0474     }
0475   });
0476 
0477   sensitive.addCylinderContainer("Pixel_nEC", AxisZ, [&](auto& endcap) {
0478     endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0479     endcap.setResizeStrategy(ResizeStrategy::Gap);
0480 
0481     auto protoLayerSurfaces = pplCreator.negativeProtoLayers(gctx);
0482     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0483                          << " negative proto layers to "
0484                          << "Pixel_nEC");
0485     for (const auto& [idx, temp] :
0486 
0487          Acts::enumerate(protoLayerSurfaces)) {
0488       auto& pl = temp.protoLayer;
0489       std::string layerName = "Pixel_nEC_L" + std::to_string(idx);
0490       endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0491         mat.configureFace(NegativeDisc,
0492                           asHomogeneous("Pixel", m_pixelEndcapMaterial));
0493         mat.addLayer(layerName, [&](auto& layer) {
0494           layer.setNavigationPolicyFactory(
0495               createNavigationPolicy(LayerType::Disc));
0496           ACTS_VERBOSE("Adding layer " << layer.name());
0497           layer.setProtoLayer(pl);
0498           layer.setEnvelope(
0499               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0500         });
0501       });
0502     }
0503   });
0504 
0505   sensitive.addCylinderContainer("Pixel_pEC", AxisZ, [&](auto& endcap) {
0506     endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0507     endcap.setResizeStrategy(ResizeStrategy::Gap);
0508     auto protoLayerSurfaces = pplCreator.positiveProtoLayers(gctx);
0509     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0510                          << " positive proto layers to "
0511                          << "Pixel_pEC");
0512     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0513       auto& pl = temp.protoLayer;
0514       std::string layerName = "Pixel_pEC_L" + std::to_string(idx);
0515       endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0516         mat.configureFace(PositiveDisc,
0517                           asHomogeneous("Pixel", m_pixelEndcapMaterial));
0518         mat.addLayer(layerName, [&](auto& layer) {
0519           layer.setNavigationPolicyFactory(
0520               createNavigationPolicy(LayerType::Disc));
0521           ACTS_VERBOSE("Adding layer " << layer.name());
0522           layer.setProtoLayer(pl);
0523           layer.setEnvelope(
0524               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0525         });
0526       });
0527     }
0528   });
0529 }
0530 
0531 void Gen3GenericDetectorBuilder::buildShortStrip(
0532     Acts::BlueprintNode& parent, const Acts::GeometryContext& gctx) {
0533   using enum Acts::AxisDirection;
0534   using namespace Acts;
0535   using namespace Acts::UnitLiterals;
0536   using enum Acts::CylinderVolumeBounds::Face;
0537   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0538   using ResizeStrategy = Acts::VolumeResizeStrategy;
0539 
0540   ACTS_DEBUG("Building Short Strip");
0541 
0542   ProtoLayerCreator ssplCreator = createShortStripProtoLayerCreator();
0543 
0544   auto& sstrip = parent.addCylinderContainer("ShortStrip", AxisZ);
0545   sstrip.setAttachmentStrategy(AttachmentStrategy::Gap);
0546   sstrip.setResizeStrategy(ResizeStrategy::Gap);
0547 
0548   sstrip.addCylinderContainer("ShortStrip_Barrel", AxisR, [&](auto& barrel) {
0549     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0550     barrel.setResizeStrategy(ResizeStrategy::Gap);
0551 
0552     auto protoLayerSurfaces = ssplCreator.centralProtoLayers(gctx);
0553     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0554                          << " central proto layers to "
0555                          << "ShortStrip");
0556     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0557       auto& pl = temp.protoLayer;
0558       std::string layerName = "ShortStrip_Barrel_L" + std::to_string(idx);
0559       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0560         mat.configureFace(
0561             InnerCylinder,
0562             asHomogeneous("ShortStrip", m_shortStripCentralMaterial));
0563         mat.addLayer(layerName, [&](auto& layer) {
0564           layer.setNavigationPolicyFactory(
0565               createNavigationPolicy(LayerType::Cylinder));
0566           ACTS_VERBOSE("Adding layer " << layer.name());
0567           layer.setProtoLayer(pl);
0568           layer.setEnvelope(
0569               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0570         });
0571       });
0572     }
0573   });
0574 
0575   if (m_cfg.buildLevel > 2) {
0576     sstrip.addCylinderContainer("ShortStrip_nEC", AxisZ, [&](auto& endcap) {
0577       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0578       endcap.setResizeStrategy(ResizeStrategy::Gap);
0579 
0580       auto protoLayerSurfaces = ssplCreator.negativeProtoLayers(gctx);
0581 
0582       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0583                            << " negative proto layers to "
0584                            << "ShortStrip_nEC");
0585       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0586         auto& pl = temp.protoLayer;
0587         std::string layerName = "ShortStrip_nEC_L" + std::to_string(idx);
0588         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0589           mat.configureFace(
0590               NegativeDisc,
0591               asHomogeneous("ShortStrip", m_shortStripEndcapMaterial));
0592           mat.addLayer(layerName, [&](auto& layer) {
0593             layer.setNavigationPolicyFactory(
0594                 createNavigationPolicy(LayerType::Disc));
0595             ACTS_VERBOSE("Adding layer " << layer.name());
0596             layer.setProtoLayer(pl);
0597             layer.setEnvelope(
0598                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0599           });
0600         });
0601       }
0602     });
0603 
0604     sstrip.addCylinderContainer("ShortStrip_pEC", AxisZ, [&](auto& endcap) {
0605       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0606       endcap.setResizeStrategy(ResizeStrategy::Gap);
0607 
0608       auto protoLayerSurfaces = ssplCreator.positiveProtoLayers(gctx);
0609 
0610       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0611                            << " positive proto layers to "
0612                            << "ShortStrip_pEC");
0613       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0614         auto& pl = temp.protoLayer;
0615         std::string layerName = "ShortStrip_pEC_L" + std::to_string(idx);
0616         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0617           mat.configureFace(
0618               PositiveDisc,
0619               asHomogeneous("ShortStrip", m_shortStripEndcapMaterial));
0620           mat.addLayer(layerName, [&](auto& layer) {
0621             layer.setNavigationPolicyFactory(
0622                 createNavigationPolicy(LayerType::Disc));
0623             ACTS_VERBOSE("Adding layer " << layer.name());
0624             layer.setProtoLayer(pl);
0625             layer.setEnvelope(
0626                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0627           });
0628         });
0629       }
0630     });
0631   }
0632 }
0633 
0634 void Gen3GenericDetectorBuilder::buildLongStrip(
0635     Acts::BlueprintNode& parent, const Acts::GeometryContext& gctx) {
0636   using enum Acts::AxisDirection;
0637   using namespace Acts;
0638   using namespace Acts::UnitLiterals;
0639   using enum Acts::CylinderVolumeBounds::Face;
0640   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0641   using ResizeStrategy = Acts::VolumeResizeStrategy;
0642 
0643   ACTS_DEBUG("Building Long Strip");
0644 
0645   ProtoLayerCreator lsplCreator = createLongStripProtoLayerCreator();
0646 
0647   auto& lstrip = parent.addCylinderContainer("LongStrip", AxisZ);
0648   lstrip.setAttachmentStrategy(AttachmentStrategy::Gap);
0649   lstrip.setResizeStrategy(ResizeStrategy::Gap);
0650 
0651   lstrip.addCylinderContainer("LongStrip_Barrel", AxisR, [&](auto& barrel) {
0652     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0653     barrel.setResizeStrategy(ResizeStrategy::Gap);
0654 
0655     auto protoLayerSurfaces = lsplCreator.centralProtoLayers(gctx);
0656     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0657                          << " central proto layers to "
0658                          << "LongStrip_Barrel");
0659     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0660       auto& pl = temp.protoLayer;
0661       std::string layerName = "LongStrip_Barrel_L" + std::to_string(idx);
0662       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0663         mat.configureFace(
0664             InnerCylinder,
0665             asHomogeneous("LongStrip", m_longStripCentralMaterial));
0666         mat.addLayer(layerName, [&](auto& layer) {
0667           layer.setNavigationPolicyFactory(
0668               createNavigationPolicy(LayerType::Cylinder));
0669           ACTS_VERBOSE("Adding layer " << layer.name());
0670           layer.setProtoLayer(pl);
0671           layer.setEnvelope(
0672               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0673         });
0674       });
0675     }
0676   });
0677 
0678   if (m_cfg.buildLevel > 2) {
0679     lstrip.addCylinderContainer("LongStrip_nEC", AxisZ, [&](auto& endcap) {
0680       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0681       endcap.setResizeStrategy(ResizeStrategy::Gap);
0682 
0683       auto protoLayerSurfaces = lsplCreator.negativeProtoLayers(gctx);
0684 
0685       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0686                            << " negative proto layers to "
0687                            << "LongStrip_nEC");
0688       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0689         auto& pl = temp.protoLayer;
0690         std::string layerName = "LongStrip_nEC_L" + std::to_string(idx);
0691         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0692           mat.configureFace(
0693               NegativeDisc,
0694               asHomogeneous("LongStrip", m_longStripEndcapMaterial));
0695           mat.addLayer(layerName, [&](auto& layer) {
0696             layer.setNavigationPolicyFactory(
0697                 createNavigationPolicy(LayerType::Disc));
0698             ACTS_VERBOSE("Adding layer " << layer.name());
0699             layer.setProtoLayer(pl);
0700             layer.setEnvelope(
0701                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0702           });
0703         });
0704       }
0705     });
0706 
0707     lstrip.addCylinderContainer("LongStrip_pEC", AxisZ, [&](auto& endcap) {
0708       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0709       endcap.setResizeStrategy(ResizeStrategy::Gap);
0710 
0711       auto protoLayerSurfaces = lsplCreator.positiveProtoLayers(gctx);
0712 
0713       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0714                            << " positive proto layers to "
0715                            << "LongStrip_pEC");
0716       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0717         auto& pl = temp.protoLayer;
0718         std::string layerName = "LongStrip_pEC_L" + std::to_string(idx);
0719         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0720           mat.configureFace(
0721               PositiveDisc,
0722               asHomogeneous("LongStrip", m_longStripEndcapMaterial));
0723           mat.addLayer(layerName, [&](auto& layer) {
0724             layer.setNavigationPolicyFactory(
0725                 createNavigationPolicy(LayerType::Disc));
0726             ACTS_VERBOSE("Adding layer " << layer.name());
0727             layer.setProtoLayer(pl);
0728             layer.setEnvelope(
0729                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0730           });
0731         });
0732       }
0733     });
0734   }
0735 }
0736 }  // namespace
0737 }  // namespace Generic
0738 
0739 GenericDetector::GenericDetector(const Config& cfg)
0740     : Detector(Acts::getDefaultLogger("GenericDetector", cfg.logLevel)),
0741       m_cfg(cfg) {
0742   m_nominalGeometryContext =
0743       Acts::GeometryContext::dangerouslyDefaultConstruct();
0744   auto detectorElementFactory =
0745       [this](const Acts::Transform3& transform,
0746              std::shared_ptr<const Acts::PlanarBounds> bounds, double thickness,
0747              std::shared_ptr<const Acts::ISurfaceMaterial> material)
0748       -> std::shared_ptr<GenericDetectorElement> {
0749     auto id =
0750         static_cast<GenericDetectorElement::Identifier>(m_detectorStore.size());
0751     auto detElem = std::make_shared<GenericDetectorElement>(
0752         id, transform, std::move(bounds), thickness, std::move(material));
0753     m_detectorStore.push_back(detElem);
0754     return detElem;
0755   };
0756   buildTrackingGeometry(detectorElementFactory);
0757 }
0758 
0759 GenericDetector::GenericDetector(const Config& cfg, NoBuildTag /*tag*/)
0760     : Detector(Acts::getDefaultLogger("GenericDetector", cfg.logLevel)),
0761       m_cfg(cfg) {}
0762 
0763 void GenericDetector::buildTrackingGeometry(
0764     const Generic::ProtoLayerCreator::DetectorElementFactory&
0765         detectorElementFactory) {
0766   ACTS_INFO("Building tracking geometry");
0767   if (m_trackingGeometry != nullptr) {
0768     throw std::runtime_error("Tracking geometry already built");
0769   }
0770 
0771   Generic::GenericDetectorBuilder::Config cfg;
0772   cfg.detectorElementFactory = detectorElementFactory;
0773   cfg.protoMaterial = m_cfg.buildProto;
0774   cfg.layerLogLevel = m_cfg.layerLogLevel;
0775   cfg.buildLevel = m_cfg.buildLevel;
0776 
0777   if (m_cfg.gen3) {
0778     m_trackingGeometry =
0779         Generic::Gen3GenericDetectorBuilder(cfg, logger().clone())
0780             .buildTrackingGeometry(m_nominalGeometryContext,
0781                                    m_cfg.graphvizFile);
0782   } else {
0783     m_trackingGeometry =
0784         Generic::Gen1GenericDetectorBuilder(cfg, logger().clone())
0785             .buildTrackingGeometry(m_nominalGeometryContext,
0786                                    m_cfg.materialDecorator,
0787                                    m_cfg.surfaceLogLevel, m_cfg.volumeLogLevel);
0788   }
0789 
0790   if (m_trackingGeometry == nullptr) {
0791     throw std::runtime_error("Error building tracking geometry");
0792   }
0793 
0794   ACTS_INFO("Tracking geometry built");
0795 }
0796 
0797 }  // namespace ActsExamples