Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 07:52:27

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/Detector/Detector.hpp"
0012 #include "Acts/Geometry/Blueprint.hpp"
0013 #include "Acts/Geometry/BlueprintNode.hpp"
0014 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0015 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBuilder.hpp"
0017 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0018 #include "Acts/Geometry/Extent.hpp"
0019 #include "Acts/Geometry/LayerArrayCreator.hpp"
0020 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0021 #include "Acts/Geometry/LayerCreator.hpp"
0022 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0023 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0024 #include "Acts/Geometry/PassiveLayerBuilder.hpp"
0025 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0026 #include "Acts/Geometry/TrackingGeometry.hpp"
0027 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0028 #include "Acts/Geometry/TrackingVolume.hpp"
0029 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
0030 #include "Acts/Geometry/VolumeAttachmentStrategy.hpp"
0031 #include "Acts/Material/HomogeneousSurfaceMaterial.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 alsways 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::Experimental::BlueprintNode& parent,
0335                   const Acts::GeometryContext& gctx);
0336 
0337   void buildShortStrip(Acts::Experimental::BlueprintNode& parent,
0338                        const Acts::GeometryContext& gctx);
0339 
0340   void buildLongStrip(Acts::Experimental::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::make()
0361         .add<Acts::TryAllNavigationPolicy>(
0362             Acts::TryAllNavigationPolicy::Config{.sensitives = false})
0363         .add<SrfArrayNavPol>(
0364             SrfArrayNavPol::Config{.layerType = layerType, .bins = bins})
0365         .asUniquePtr();
0366   }
0367 };
0368 
0369 std::unique_ptr<const Acts::TrackingGeometry>
0370 Gen3GenericDetectorBuilder::buildTrackingGeometry(
0371     const Acts::GeometryContext& gctx,
0372     std::optional<std::filesystem::path> graphvizFile) {
0373   using enum Acts::AxisDirection;
0374   using namespace Acts::UnitLiterals;
0375   using namespace Acts::Experimental;
0376   using enum Acts::AxisBoundaryType;
0377   using enum Acts::CylinderVolumeBounds::Face;
0378   ACTS_INFO("GenericDetector construction in  Gen3 mode");
0379 
0380   Blueprint::Config cfg;
0381   cfg.envelope = Acts::ExtentEnvelope{{
0382       .z = {20_mm, 20_mm},
0383       .r = {0_mm, 20_mm},
0384   }};
0385   Blueprint root{cfg};
0386 
0387   root.addCylinderContainer("Detector", AxisR, [&](auto& detector) {
0388     auto beampipeBounds = std::make_unique<Acts::CylinderVolumeBounds>(
0389         0_mm, kBeamPipeRadius, kBeamPipeHalfLengthZ);
0390     auto beampipe = std::make_unique<Acts::TrackingVolume>(
0391         Acts::Transform3::Identity(), std::move(beampipeBounds), "Beampipe");
0392 
0393     detector.addMaterial("BeampipeMaterial", [&](auto& bpMat) {
0394       bpMat.configureFace(OuterCylinder,
0395                           asHomogeneous("Beam pipe", m_beamPipeMaterial));
0396       bpMat.addStaticVolume(std::move(beampipe));
0397     });
0398 
0399     buildPixel(detector, gctx);
0400 
0401     if (m_cfg.buildLevel > 1) {
0402       buildShortStrip(detector, gctx);
0403       buildLongStrip(detector, gctx);
0404     }
0405   });
0406 
0407   if (graphvizFile) {
0408     std::ofstream file(*graphvizFile);
0409     root.graphviz(file);
0410   }
0411 
0412   BlueprintOptions options;
0413   auto trackingGeometry =
0414       root.construct(options, gctx, *logger().clone("Blprnt"));
0415   return trackingGeometry;
0416 }
0417 
0418 void Gen3GenericDetectorBuilder::buildPixel(
0419     Acts::Experimental::BlueprintNode& parent,
0420     const Acts::GeometryContext& gctx) {
0421   using enum Acts::AxisDirection;
0422   using namespace Acts::Experimental;
0423   using namespace Acts::UnitLiterals;
0424   using enum Acts::CylinderVolumeBounds::Face;
0425   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0426   using ResizeStrategy = Acts::VolumeResizeStrategy;
0427 
0428   ACTS_DEBUG("Building Pixel");
0429 
0430   ProtoLayerCreator pplCreator = createPixelProtoLayerCreator();
0431 
0432   auto& pixel = parent.addCylinderContainer("Pixel", AxisR);
0433 
0434   if (m_cfg.buildLevel > 1) {
0435     ACTS_DEBUG("Building PST");
0436     auto pstVolume = std::make_unique<Acts::TrackingVolume>(
0437         Acts::Transform3::Identity(),
0438         std::make_unique<Acts::CylinderVolumeBounds>(
0439             kPstRadius - kPstThickness, kPstRadius, kPstHalfLengthZ),
0440         "PST");
0441 
0442     pixel.addMaterial("PSTMaterial", [&](auto& pstMat) {
0443       pstMat.configureFace(OuterCylinder, asHomogeneous("PST", m_pstMaterial));
0444       pstMat.addStaticVolume(std::move(pstVolume));
0445     });
0446   }
0447 
0448   auto& sensitive = pixel.addCylinderContainer("Pixel", AxisZ);
0449   sensitive.addCylinderContainer("Pixel_Barrel", AxisR, [&](auto& barrel) {
0450     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0451     barrel.setResizeStrategies(ResizeStrategy::Expand, ResizeStrategy::Gap);
0452 
0453     auto centralProtoLayerSurfaces = pplCreator.centralProtoLayers(gctx);
0454     ACTS_DEBUG("Adding " << centralProtoLayerSurfaces.size()
0455                          << " central proto layers to "
0456                          << "Pixel_Barrel");
0457     for (const auto& [idx, temp] :
0458 
0459          Acts::enumerate(centralProtoLayerSurfaces)) {
0460       auto& pl = temp.protoLayer;
0461       std::string layerName = "Pixel_Barrel_L" + std::to_string(idx);
0462       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0463         mat.configureFace(OuterCylinder,
0464                           asHomogeneous("Pixel", m_pixelCentralMaterial));
0465         mat.addLayer(layerName, [&](auto& layer) {
0466           ACTS_VERBOSE("Adding layer " << layer.name());
0467           layer.setProtoLayer(pl);
0468           layer.setEnvelope(
0469               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0470           layer.setNavigationPolicyFactory(
0471               createNavigationPolicy(LayerType::Cylinder));
0472 
0473           ACTS_VERBOSE("-> Number of surfaces: " << layer.surfaces().size());
0474         });
0475       });
0476     }
0477   });
0478 
0479   sensitive.addCylinderContainer("Pixel_nEC", AxisZ, [&](auto& endcap) {
0480     endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0481     endcap.setResizeStrategy(ResizeStrategy::Gap);
0482 
0483     auto protoLayerSurfaces = pplCreator.negativeProtoLayers(gctx);
0484     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0485                          << " negative proto layers to "
0486                          << "Pixel_nEC");
0487     for (const auto& [idx, temp] :
0488 
0489          Acts::enumerate(protoLayerSurfaces)) {
0490       auto& pl = temp.protoLayer;
0491       std::string layerName = "Pixel_nEC_L" + std::to_string(idx);
0492       endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0493         mat.configureFace(NegativeDisc,
0494                           asHomogeneous("Pixel", m_pixelEndcapMaterial));
0495         mat.addLayer(layerName, [&](auto& layer) {
0496           layer.setNavigationPolicyFactory(
0497               createNavigationPolicy(LayerType::Disc));
0498           ACTS_VERBOSE("Adding layer " << layer.name());
0499           layer.setProtoLayer(pl);
0500           layer.setEnvelope(
0501               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0502         });
0503       });
0504     }
0505   });
0506 
0507   sensitive.addCylinderContainer("Pixel_pEC", AxisZ, [&](auto& endcap) {
0508     endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0509     endcap.setResizeStrategy(ResizeStrategy::Gap);
0510     auto protoLayerSurfaces = pplCreator.positiveProtoLayers(gctx);
0511     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0512                          << " positive proto layers to "
0513                          << "Pixel_pEC");
0514     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0515       auto& pl = temp.protoLayer;
0516       std::string layerName = "Pixel_pEC_L" + std::to_string(idx);
0517       endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0518         mat.configureFace(PositiveDisc,
0519                           asHomogeneous("Pixel", m_pixelEndcapMaterial));
0520         mat.addLayer(layerName, [&](auto& layer) {
0521           layer.setNavigationPolicyFactory(
0522               createNavigationPolicy(LayerType::Disc));
0523           ACTS_VERBOSE("Adding layer " << layer.name());
0524           layer.setProtoLayer(pl);
0525           layer.setEnvelope(
0526               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0527         });
0528       });
0529     }
0530   });
0531 }
0532 
0533 void Gen3GenericDetectorBuilder::buildShortStrip(
0534     Acts::Experimental::BlueprintNode& parent,
0535     const Acts::GeometryContext& gctx) {
0536   using enum Acts::AxisDirection;
0537   using namespace Acts::Experimental;
0538   using namespace Acts::UnitLiterals;
0539   using enum Acts::CylinderVolumeBounds::Face;
0540   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0541   using ResizeStrategy = Acts::VolumeResizeStrategy;
0542 
0543   ACTS_DEBUG("Building Short Strip");
0544 
0545   ProtoLayerCreator ssplCreator = createShortStripProtoLayerCreator();
0546 
0547   auto& sstrip = parent.addCylinderContainer("ShortStrip", AxisZ);
0548   sstrip.setAttachmentStrategy(AttachmentStrategy::Gap);
0549   sstrip.setResizeStrategy(ResizeStrategy::Gap);
0550 
0551   sstrip.addCylinderContainer("ShortStrip_Barrel", AxisR, [&](auto& barrel) {
0552     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0553     barrel.setResizeStrategy(ResizeStrategy::Gap);
0554 
0555     auto protoLayerSurfaces = ssplCreator.centralProtoLayers(gctx);
0556     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0557                          << " central proto layers to "
0558                          << "ShortStrip");
0559     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0560       auto& pl = temp.protoLayer;
0561       std::string layerName = "ShortStrip_Barrel_L" + std::to_string(idx);
0562       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0563         mat.configureFace(
0564             InnerCylinder,
0565             asHomogeneous("ShortStrip", m_shortStripCentralMaterial));
0566         mat.addLayer(layerName, [&](auto& layer) {
0567           layer.setNavigationPolicyFactory(
0568               createNavigationPolicy(LayerType::Cylinder));
0569           ACTS_VERBOSE("Adding layer " << layer.name());
0570           layer.setProtoLayer(pl);
0571           layer.setEnvelope(
0572               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0573         });
0574       });
0575     }
0576   });
0577 
0578   if (m_cfg.buildLevel > 2) {
0579     sstrip.addCylinderContainer("ShortStrip_nEC", AxisZ, [&](auto& endcap) {
0580       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0581       endcap.setResizeStrategy(ResizeStrategy::Gap);
0582 
0583       auto protoLayerSurfaces = ssplCreator.negativeProtoLayers(gctx);
0584 
0585       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0586                            << " negative proto layers to "
0587                            << "ShortStrip_nEC");
0588       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0589         auto& pl = temp.protoLayer;
0590         std::string layerName = "ShortStrip_nEC_L" + std::to_string(idx);
0591         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0592           mat.configureFace(
0593               NegativeDisc,
0594               asHomogeneous("ShortStrip", m_shortStripEndcapMaterial));
0595           mat.addLayer(layerName, [&](auto& layer) {
0596             layer.setNavigationPolicyFactory(
0597                 createNavigationPolicy(LayerType::Disc));
0598             ACTS_VERBOSE("Adding layer " << layer.name());
0599             layer.setProtoLayer(pl);
0600             layer.setEnvelope(
0601                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0602           });
0603         });
0604       }
0605     });
0606 
0607     sstrip.addCylinderContainer("ShortStrip_pEC", AxisZ, [&](auto& endcap) {
0608       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0609       endcap.setResizeStrategy(ResizeStrategy::Gap);
0610 
0611       auto protoLayerSurfaces = ssplCreator.positiveProtoLayers(gctx);
0612 
0613       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0614                            << " positive proto layers to "
0615                            << "ShortStrip_pEC");
0616       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0617         auto& pl = temp.protoLayer;
0618         std::string layerName = "ShortStrip_pEC_L" + std::to_string(idx);
0619         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0620           mat.configureFace(
0621               PositiveDisc,
0622               asHomogeneous("ShortStrip", m_shortStripEndcapMaterial));
0623           mat.addLayer(layerName, [&](auto& layer) {
0624             layer.setNavigationPolicyFactory(
0625                 createNavigationPolicy(LayerType::Disc));
0626             ACTS_VERBOSE("Adding layer " << layer.name());
0627             layer.setProtoLayer(pl);
0628             layer.setEnvelope(
0629                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0630           });
0631         });
0632       }
0633     });
0634   }
0635 }
0636 
0637 void Gen3GenericDetectorBuilder::buildLongStrip(
0638     Acts::Experimental::BlueprintNode& parent,
0639     const Acts::GeometryContext& gctx) {
0640   using enum Acts::AxisDirection;
0641   using namespace Acts::Experimental;
0642   using namespace Acts::UnitLiterals;
0643   using enum Acts::CylinderVolumeBounds::Face;
0644   using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
0645   using ResizeStrategy = Acts::VolumeResizeStrategy;
0646 
0647   ACTS_DEBUG("Building Long Strip");
0648 
0649   ProtoLayerCreator lsplCreator = createLongStripProtoLayerCreator();
0650 
0651   auto& lstrip = parent.addCylinderContainer("LongStrip", AxisZ);
0652   lstrip.setAttachmentStrategy(AttachmentStrategy::Gap);
0653   lstrip.setResizeStrategy(ResizeStrategy::Gap);
0654 
0655   lstrip.addCylinderContainer("LongStrip_Barrel", AxisR, [&](auto& barrel) {
0656     barrel.setAttachmentStrategy(AttachmentStrategy::Gap);
0657     barrel.setResizeStrategy(ResizeStrategy::Gap);
0658 
0659     auto protoLayerSurfaces = lsplCreator.centralProtoLayers(gctx);
0660     ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0661                          << " central proto layers to "
0662                          << "LongStrip_Barrel");
0663     for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0664       auto& pl = temp.protoLayer;
0665       std::string layerName = "LongStrip_Barrel_L" + std::to_string(idx);
0666       barrel.addMaterial(layerName + "_Mat", [&](auto& mat) {
0667         mat.configureFace(
0668             InnerCylinder,
0669             asHomogeneous("LongStrip", m_longStripCentralMaterial));
0670         mat.addLayer(layerName, [&](auto& layer) {
0671           layer.setNavigationPolicyFactory(
0672               createNavigationPolicy(LayerType::Cylinder));
0673           ACTS_VERBOSE("Adding layer " << layer.name());
0674           layer.setProtoLayer(pl);
0675           layer.setEnvelope(
0676               Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {5_mm, 5_mm}}});
0677         });
0678       });
0679     }
0680   });
0681 
0682   if (m_cfg.buildLevel > 2) {
0683     lstrip.addCylinderContainer("LongStrip_nEC", AxisZ, [&](auto& endcap) {
0684       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0685       endcap.setResizeStrategy(ResizeStrategy::Gap);
0686 
0687       auto protoLayerSurfaces = lsplCreator.negativeProtoLayers(gctx);
0688 
0689       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0690                            << " negative proto layers to "
0691                            << "LongStrip_nEC");
0692       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0693         auto& pl = temp.protoLayer;
0694         std::string layerName = "LongStrip_nEC_L" + std::to_string(idx);
0695         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0696           mat.configureFace(
0697               NegativeDisc,
0698               asHomogeneous("LongStrip", m_longStripEndcapMaterial));
0699           mat.addLayer(layerName, [&](auto& layer) {
0700             layer.setNavigationPolicyFactory(
0701                 createNavigationPolicy(LayerType::Disc));
0702             ACTS_VERBOSE("Adding layer " << layer.name());
0703             layer.setProtoLayer(pl);
0704             layer.setEnvelope(
0705                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0706           });
0707         });
0708       }
0709     });
0710 
0711     lstrip.addCylinderContainer("LongStrip_pEC", AxisZ, [&](auto& endcap) {
0712       endcap.setAttachmentStrategy(AttachmentStrategy::Gap);
0713       endcap.setResizeStrategy(ResizeStrategy::Gap);
0714 
0715       auto protoLayerSurfaces = lsplCreator.positiveProtoLayers(gctx);
0716 
0717       ACTS_DEBUG("Adding " << protoLayerSurfaces.size()
0718                            << " positive proto layers to "
0719                            << "LongStrip_pEC");
0720       for (const auto& [idx, temp] : Acts::enumerate(protoLayerSurfaces)) {
0721         auto& pl = temp.protoLayer;
0722         std::string layerName = "LongStrip_pEC_L" + std::to_string(idx);
0723         endcap.addMaterial(layerName + "_Mat", [&](auto& mat) {
0724           mat.configureFace(
0725               PositiveDisc,
0726               asHomogeneous("LongStrip", m_longStripEndcapMaterial));
0727           mat.addLayer(layerName, [&](auto& layer) {
0728             layer.setNavigationPolicyFactory(
0729                 createNavigationPolicy(LayerType::Disc));
0730             ACTS_VERBOSE("Adding layer " << layer.name());
0731             layer.setProtoLayer(pl);
0732             layer.setEnvelope(
0733                 Acts::ExtentEnvelope{{.z = {5_mm, 5_mm}, .r = {0_mm, 0_mm}}});
0734           });
0735         });
0736       }
0737     });
0738   }
0739 }
0740 }  // namespace
0741 }  // namespace Generic
0742 
0743 GenericDetector::GenericDetector(const Config& cfg)
0744     : Detector(Acts::getDefaultLogger("GenericDetector", cfg.logLevel)),
0745       m_cfg(cfg) {
0746   m_nominalGeometryContext = Acts::GeometryContext();
0747   auto detectorElementFactory =
0748       [this](std::shared_ptr<const Acts::Transform3> transform,
0749              std::shared_ptr<const Acts::PlanarBounds> bounds, double thickness,
0750              std::shared_ptr<const Acts::ISurfaceMaterial> material)
0751       -> std::shared_ptr<GenericDetectorElement> {
0752     auto id =
0753         static_cast<GenericDetectorElement::Identifier>(m_detectorStore.size());
0754     auto detElem = std::make_shared<GenericDetectorElement>(
0755         id, std::move(transform), std::move(bounds), thickness,
0756         std::move(material));
0757     m_detectorStore.push_back(detElem);
0758     return detElem;
0759   };
0760   buildTrackingGeometry(detectorElementFactory);
0761 }
0762 
0763 GenericDetector::GenericDetector(const Config& cfg, NoBuildTag /*tag*/)
0764     : Detector(Acts::getDefaultLogger("GenericDetector", cfg.logLevel)),
0765       m_cfg(cfg) {}
0766 
0767 void GenericDetector::buildTrackingGeometry(
0768     const Generic::ProtoLayerCreator::DetectorElementFactory&
0769         detectorElementFactory) {
0770   ACTS_INFO("Building tracking geometry");
0771   if (m_trackingGeometry != nullptr) {
0772     throw std::runtime_error("Tracking geometry already built");
0773   }
0774 
0775   Generic::GenericDetectorBuilder::Config cfg;
0776   cfg.detectorElementFactory = detectorElementFactory;
0777   cfg.protoMaterial = m_cfg.buildProto;
0778   cfg.layerLogLevel = m_cfg.layerLogLevel;
0779   cfg.buildLevel = m_cfg.buildLevel;
0780 
0781   if (m_cfg.gen3) {
0782     m_trackingGeometry =
0783         Generic::Gen3GenericDetectorBuilder(cfg, logger().clone())
0784             .buildTrackingGeometry(m_nominalGeometryContext,
0785                                    m_cfg.graphvizFile);
0786   } else {
0787     m_trackingGeometry =
0788         Generic::Gen1GenericDetectorBuilder(cfg, logger().clone())
0789             .buildTrackingGeometry(m_nominalGeometryContext,
0790                                    m_cfg.materialDecorator,
0791                                    m_cfg.surfaceLogLevel, m_cfg.volumeLogLevel);
0792   }
0793 
0794   if (m_trackingGeometry == nullptr) {
0795     throw std::runtime_error("Error building tracking geometry");
0796   }
0797 
0798   ACTS_INFO("Tracking geometry built");
0799 }
0800 
0801 }  // namespace ActsExamples