Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:23:41

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