File indexing completed on 2025-10-16 08:03:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/DD4hep/ConvertDD4hepDetector.hpp"
0010
0011 #include "Acts/Geometry/CylinderVolumeBuilder.hpp"
0012 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0013 #include "Acts/Geometry/GeometryContext.hpp"
0014 #include "Acts/Geometry/ITrackingVolumeArrayCreator.hpp"
0015 #include "Acts/Geometry/ITrackingVolumeBuilder.hpp"
0016 #include "Acts/Geometry/LayerArrayCreator.hpp"
0017 #include "Acts/Geometry/LayerCreator.hpp"
0018 #include "Acts/Geometry/PassiveLayerBuilder.hpp"
0019 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0020 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0021 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
0022 #include "Acts/Geometry/Volume.hpp"
0023 #include "Acts/Material/ISurfaceMaterial.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 #include "ActsPlugins/DD4hep/DD4hepConversionHelpers.hpp"
0026 #include "ActsPlugins/DD4hep/DD4hepMaterialHelpers.hpp"
0027 #include "ActsPlugins/DD4hep/DD4hepVolumeBuilder.hpp"
0028
0029 #include <array>
0030 #include <cmath>
0031 #include <list>
0032 #include <regex>
0033 #include <stdexcept>
0034 #include <string>
0035 #include <utility>
0036
0037 #include "DD4hep/DetType.h"
0038 #include "DDRec/DetectorData.h"
0039 #include "TGeoManager.h"
0040
0041 namespace {
0042
0043 struct DebugVisitor {
0044 std::string operator()(int value) { return std::to_string(value); }
0045
0046 std::string operator()(double value) { return std::to_string(value); }
0047
0048 std::string operator()(std::string value) { return value; }
0049 };
0050
0051 }
0052
0053 using namespace Acts;
0054
0055 std::unique_ptr<const TrackingGeometry> ActsPlugins::convertDD4hepDetector(
0056 dd4hep::DetElement worldDetElement, const Logger& logger,
0057 BinningType bTypePhi, BinningType bTypeR, BinningType bTypeZ,
0058 double layerEnvelopeR, double layerEnvelopeZ, double defaultLayerThickness,
0059 const std::function<void(std::vector<dd4hep::DetElement>& detectors)>&
0060 sortSubDetectors,
0061 const GeometryContext& gctx,
0062 std::shared_ptr<const IMaterialDecorator> matDecorator,
0063 std::shared_ptr<const GeometryIdentifierHook> geometryIdentifierHook,
0064 const DD4hepLayerBuilder::ElementFactory& detectorElementFactory) {
0065
0066 ACTS_INFO("Translating DD4hep geometry into Acts geometry");
0067
0068
0069 std::vector<dd4hep::DetElement> subDetectors;
0070
0071 collectSubDetectors_dd4hep(worldDetElement, subDetectors, logger);
0072 ACTS_VERBOSE("Collected " << subDetectors.size() << " sub detectors");
0073
0074 sortSubDetectors(subDetectors);
0075
0076 std::list<std::shared_ptr<const ITrackingVolumeBuilder>> volumeBuilders;
0077
0078
0079 std::shared_ptr<const CylinderVolumeBuilder> beamPipeVolumeBuilder;
0080
0081 for (auto& subDetector : subDetectors) {
0082 ACTS_INFO("Translating DD4hep sub detector: " << subDetector.name());
0083
0084 const dd4hep::rec::VariantParameters* params =
0085 subDetector.extension<dd4hep::rec::VariantParameters>(false);
0086
0087 if (params != nullptr) {
0088 ACTS_VERBOSE("VariantParameters from DD4hep:");
0089 for (const auto& [k, v] : params->variantParameters) {
0090 ACTS_VERBOSE("- " << k << ": "
0091 << boost::apply_visitor(DebugVisitor{}, v));
0092 }
0093 }
0094
0095
0096 auto volBuilder = volumeBuilder_dd4hep(
0097 subDetector, logger, bTypePhi, bTypeR, bTypeZ, layerEnvelopeR,
0098 layerEnvelopeZ, defaultLayerThickness, detectorElementFactory);
0099 if (volBuilder != nullptr) {
0100
0101 if (volBuilder->getConfiguration().buildToRadiusZero) {
0102
0103 if (beamPipeVolumeBuilder) {
0104 throw std::logic_error(
0105 std::string("Beampipe has already been set! There can only "
0106 "exist one beam pipe. Please check your "
0107 "detector construction. Current volume name: ") +
0108 volBuilder->getConfiguration().volumeName +
0109 std::string(", name of volume, already set as beam pipe: ") +
0110 beamPipeVolumeBuilder->getConfiguration().volumeName);
0111 }
0112
0113 beamPipeVolumeBuilder = volBuilder;
0114 } else {
0115 volumeBuilders.push_back(volBuilder);
0116 }
0117 }
0118 }
0119
0120 if (beamPipeVolumeBuilder != nullptr) {
0121 volumeBuilders.push_back(beamPipeVolumeBuilder);
0122 }
0123
0124 std::vector<std::function<std::shared_ptr<TrackingVolume>(
0125 const GeometryContext&, const TrackingVolumePtr&,
0126 const std::shared_ptr<const VolumeBounds>&)>>
0127 volumeFactories;
0128
0129 for (const auto& vb : volumeBuilders) {
0130 volumeFactories.push_back(
0131 [vb](const GeometryContext& vgctx,
0132 const std::shared_ptr<const TrackingVolume>& inner,
0133 const std::shared_ptr<const VolumeBounds>&) {
0134 return vb->trackingVolume(vgctx, inner);
0135 });
0136 }
0137
0138
0139 auto volumeHelper = cylinderVolumeHelper_dd4hep(logger);
0140
0141 TrackingGeometryBuilder::Config tgbConfig;
0142 tgbConfig.trackingVolumeHelper = volumeHelper;
0143 tgbConfig.materialDecorator = std::move(matDecorator);
0144 tgbConfig.trackingVolumeBuilders = std::move(volumeFactories);
0145 tgbConfig.geometryIdentifierHook = std::move(geometryIdentifierHook);
0146 auto trackingGeometryBuilder =
0147 std::make_shared<const TrackingGeometryBuilder>(tgbConfig);
0148 return (trackingGeometryBuilder->trackingGeometry(gctx));
0149 }
0150
0151 std::shared_ptr<const CylinderVolumeBuilder> ActsPlugins::volumeBuilder_dd4hep(
0152 dd4hep::DetElement subDetector, const Logger& logger, BinningType bTypePhi,
0153 BinningType bTypeR, BinningType bTypeZ, double layerEnvelopeR,
0154 double layerEnvelopeZ, double defaultLayerThickness,
0155 const ActsPlugins::DD4hepLayerBuilder::ElementFactory&
0156 detectorElementFactory) {
0157
0158 auto volumeHelper = cylinderVolumeHelper_dd4hep(logger);
0159
0160 ACTS_VERBOSE("Processing detector element: " << subDetector.name());
0161 dd4hep::DetType subDetType{subDetector.typeFlag()};
0162 ACTS_VERBOSE("SubDetector type is: ["
0163 << subDetType << "], compound: "
0164 << (subDetector.type() == "compound" ? "yes" : "no"));
0165
0166 if (subDetector.type() == "compound") {
0167 ACTS_VERBOSE("Subdetector: '" << subDetector.name()
0168 << "' has type compound ");
0169 ACTS_VERBOSE(
0170 "handling as a compound volume (a hierarchy of a "
0171 "barrel-endcap structure) and resolving the "
0172 "subvolumes...");
0173
0174
0175
0176 std::vector<dd4hep::DetElement> negativeLayers;
0177
0178 std::vector<dd4hep::DetElement> centralLayers;
0179
0180 std::vector<dd4hep::DetElement> positiveLayers;
0181
0182
0183 CylinderVolumeBuilder::Config cvbConfig;
0184
0185
0186 std::vector<dd4hep::DetElement> compounds;
0187 collectCompounds_dd4hep(subDetector, compounds);
0188
0189
0190 double zPos = 0.;
0191
0192 bool nEndCap = false;
0193 bool pEndCap = false;
0194 bool barrel = false;
0195 for (auto& volumeDetElement : compounds) {
0196 ACTS_VERBOSE("Volume: '"
0197 << subDetector.name()
0198 << "' is a compound volume -> resolve the sub volumes");
0199
0200
0201 TGeoShape* geoShape =
0202 volumeDetElement.placement().ptr()->GetVolume()->GetShape();
0203
0204 if (geoShape != nullptr) {
0205 zPos = volumeDetElement.placement()
0206 .ptr()
0207 ->GetMatrix()
0208 ->GetTranslation()[2] *
0209 UnitConstants::cm;
0210 } else {
0211 throw std::logic_error(std::string("Volume of DetElement: ") +
0212 volumeDetElement.name() +
0213 std::string(" has no shape!"));
0214 }
0215
0216 dd4hep::DetType type{volumeDetElement.typeFlag()};
0217
0218 if (!type.is(dd4hep::DetType::TRACKER)) {
0219 continue;
0220 }
0221
0222 if (type.is(dd4hep::DetType::ENDCAP)) {
0223 ACTS_VERBOSE("Subvolume: '" << volumeDetElement.name()
0224 << "' is marked ENDCAP");
0225 if (zPos < 0.) {
0226 if (nEndCap) {
0227 throw std::logic_error(
0228 "Negative Endcap was already given for this "
0229 "hierarchy! Please create a new "
0230 "DD4hep_SubDetectorAssembly for the next "
0231 "hierarchy.");
0232 }
0233 nEndCap = true;
0234 ACTS_VERBOSE("-> is negative endcap");
0235 ACTS_VERBOSE("-> collecting layers");
0236 collectLayers_dd4hep(volumeDetElement, negativeLayers, logger);
0237
0238 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0239 ACTS_VERBOSE(
0240 "-> boundary_material flag detected, creating proto "
0241 "material.");
0242 auto& params = getParams(volumeDetElement);
0243 if (hasParam("boundary_material_negative", volumeDetElement)) {
0244 ACTS_VERBOSE("--> negative");
0245 cvbConfig.boundaryMaterial[2] = createProtoMaterial(
0246 params, "boundary_material_negative",
0247 {{"binPhi", closed}, {"binR", open}}, logger);
0248 }
0249 if (hasParam("boundary_material_positive", volumeDetElement)) {
0250 ACTS_VERBOSE("--> positive");
0251 cvbConfig.boundaryMaterial[3] = createProtoMaterial(
0252 params, "boundary_material_positive",
0253 {{"binPhi", closed}, {"binR", open}}, logger);
0254 }
0255 }
0256 } else {
0257 if (pEndCap) {
0258 throw std::logic_error(
0259 "Positive Endcap was already given for this "
0260 "hierarchy! Please create a new "
0261 "DD4hep_SubDetectorAssembly for the next "
0262 "hierarchy.");
0263 }
0264 pEndCap = true;
0265 ACTS_VERBOSE("-> is positive endcap");
0266 ACTS_VERBOSE("-> collecting layers");
0267 collectLayers_dd4hep(volumeDetElement, positiveLayers, logger);
0268
0269 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0270 ACTS_VERBOSE(
0271 "-> boundary_material flag detected, creating proto "
0272 "material.");
0273 auto& params = getParams(volumeDetElement);
0274 if (params.contains("boundary_material_negative")) {
0275 ACTS_VERBOSE("--> negative");
0276 cvbConfig.boundaryMaterial[4] = createProtoMaterial(
0277 params, "boundary_material_negative",
0278 {{"binPhi", closed}, {"binR", open}}, logger);
0279 }
0280 if (params.contains("boundary_material_positive")) {
0281 ACTS_VERBOSE("--> positive");
0282 cvbConfig.boundaryMaterial[5] = createProtoMaterial(
0283 params, "boundary_material_positive",
0284 {{"binPhi", closed}, {"binR", open}}, logger);
0285 }
0286 }
0287 }
0288 } else if (type.is(dd4hep::DetType::BARREL)) {
0289 if (barrel) {
0290 throw std::logic_error(
0291 "Barrel was already given for this "
0292 "hierarchy! Please create a new "
0293 "DD4hep_SubDetectorAssembly for the next "
0294 "hierarchy.");
0295 }
0296 barrel = true;
0297 ACTS_VERBOSE("Subvolume: " << volumeDetElement.name()
0298 << " is marked as BARREL");
0299 ACTS_VERBOSE("-> collecting layers");
0300 collectLayers_dd4hep(volumeDetElement, centralLayers, logger);
0301
0302 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0303 ACTS_VERBOSE(
0304 "-> boundary_material flag detected, creating proto "
0305 "material.");
0306 auto& params = getParams(volumeDetElement);
0307 if (params.contains("boundary_material_negative")) {
0308 ACTS_VERBOSE("--> negative");
0309 cvbConfig.boundaryMaterial[3] = createProtoMaterial(
0310 params, "boundary_material_negative",
0311 {{"binPhi", closed}, {"binR", open}}, logger);
0312 }
0313 if (params.contains("boundary_material_positive")) {
0314 ACTS_VERBOSE("--> positive");
0315 cvbConfig.boundaryMaterial[4] = createProtoMaterial(
0316 params, "boundary_material_positive",
0317 {{"binPhi", closed}, {"binR", open}}, logger);
0318 }
0319 }
0320 } else {
0321 throw std::logic_error(
0322 std::string("Current DetElement: ") + volumeDetElement.name() +
0323 std::string(" has inconsistent settings. It's a compound,"
0324 " but its DetectorType is neither BARREL nor ENDCAP"
0325 " Please check your detector construction."));
0326 }
0327
0328
0329 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0330 ACTS_VERBOSE(
0331 "-> boundary_material flag detected, creating proto "
0332 "material.");
0333 auto& params = getParams(volumeDetElement);
0334 if (params.contains("boundary_material_inner")) {
0335 ACTS_VERBOSE("--> inner");
0336 cvbConfig.boundaryMaterial[0] =
0337 createProtoMaterial(params, "boundary_material_inner",
0338 {{"binPhi", closed}, {"binZ", open}}, logger);
0339 }
0340 if (params.contains("boundary_material_outer")) {
0341 ACTS_VERBOSE("--> outer");
0342 cvbConfig.boundaryMaterial[1] =
0343 createProtoMaterial(params, "boundary_material_outer",
0344 {{"binPhi", closed}, {"binZ", open}}, logger);
0345 }
0346 }
0347 }
0348
0349 if ((pEndCap && !nEndCap) || (!pEndCap && nEndCap)) {
0350 throw std::logic_error(
0351 "Only one Endcap is given for the current "
0352 "hierarchy! Endcaps should always occur in "
0353 "pairs. Please check your detector "
0354 "construction.");
0355 }
0356
0357
0358 auto surfaceArrayCreator =
0359 std::make_shared<const SurfaceArrayCreator>(logger.clone("D2A_SAC"));
0360
0361 LayerCreator::Config lcConfig;
0362 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0363 auto layerCreator =
0364 std::make_shared<const LayerCreator>(lcConfig, logger.clone("D2A_LAC"));
0365
0366 DD4hepLayerBuilder::Config lbConfig;
0367 lbConfig.configurationName = subDetector.name();
0368 lbConfig.layerCreator = layerCreator;
0369 lbConfig.negativeLayers = negativeLayers;
0370 lbConfig.centralLayers = centralLayers;
0371 lbConfig.positiveLayers = positiveLayers;
0372 lbConfig.bTypePhi = bTypePhi;
0373 lbConfig.bTypeR = bTypeR;
0374 lbConfig.bTypeZ = bTypeZ;
0375 lbConfig.defaultThickness = defaultLayerThickness;
0376 lbConfig.detectorElementFactory = detectorElementFactory;
0377 auto dd4hepLayerBuilder = std::make_shared<const DD4hepLayerBuilder>(
0378 lbConfig, logger.clone(std::string("D2A_L:") + subDetector.name()));
0379
0380
0381
0382
0383 cvbConfig.layerEnvelopeR = std::make_pair(layerEnvelopeR, layerEnvelopeR);
0384 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0385 cvbConfig.trackingVolumeHelper = volumeHelper;
0386 cvbConfig.volumeName = subDetector.name();
0387 cvbConfig.layerBuilder = dd4hepLayerBuilder;
0388 auto cylinderVolumeBuilder = std::make_shared<const CylinderVolumeBuilder>(
0389 cvbConfig, logger.clone(std::string("D2A_V:") + subDetector.name()));
0390 return cylinderVolumeBuilder;
0391 } else if (subDetType.is(dd4hep::DetType::BEAMPIPE) ||
0392 getParamOr<bool>("passive_layer", subDetector, false)) {
0393 ACTS_VERBOSE("Subdetector: " << subDetector.name()
0394 << " - building a passive cylinder.");
0395
0396 if (subDetType.is(dd4hep::DetType::BEAMPIPE)) {
0397 ACTS_VERBOSE("This is the beam pipe - will be built to r -> 0.");
0398 }
0399
0400
0401 TGeoShape* geoShape =
0402 subDetector.placement().ptr()->GetVolume()->GetShape();
0403 TGeoTubeSeg* tube = dynamic_cast<TGeoTubeSeg*>(geoShape);
0404 if (tube == nullptr) {
0405 throw std::logic_error(
0406 "Cylinder has wrong shape - needs to be TGeoTubeSeg!");
0407 }
0408
0409 double rMin = tube->GetRmin() * UnitConstants::cm - layerEnvelopeR;
0410 double rMax = tube->GetRmax() * UnitConstants::cm + layerEnvelopeR;
0411 double halfZ = tube->GetDz() * UnitConstants::cm + layerEnvelopeZ;
0412 ACTS_VERBOSE(
0413 "Extracting cylindrical volume bounds ( rmin / rmax / "
0414 "halfZ )= ( "
0415 << rMin << " / " << rMax << " / " << halfZ << " )");
0416
0417 std::shared_ptr<ISurfaceMaterial> plMaterial = nullptr;
0418 if (getParamOr<bool>("layer_material", subDetector, false)) {
0419
0420 ACTS_VERBOSE("--> adding layer material at 'representing'");
0421 plMaterial = createProtoMaterial(
0422 getParams(subDetector), "layer_material_representing",
0423 {{"binPhi", closed}, {"binZ", open}}, logger);
0424 }
0425
0426
0427 PassiveLayerBuilder::Config plbConfig;
0428 plbConfig.layerIdentification = subDetector.name();
0429 plbConfig.centralLayerRadii = std::vector<double>(1, 0.5 * (rMax + rMin));
0430 plbConfig.centralLayerHalflengthZ = std::vector<double>(1, halfZ);
0431 plbConfig.centralLayerThickness =
0432 std::vector<double>(1, std::abs(rMax - rMin));
0433 plbConfig.centralLayerMaterial = {plMaterial};
0434 auto pcLayerBuilder = std::make_shared<const PassiveLayerBuilder>(
0435 plbConfig, logger.clone(std::string("D2A_PL:") + subDetector.name()));
0436
0437
0438 CylinderVolumeBuilder::Config cvbConfig;
0439 cvbConfig.trackingVolumeHelper = volumeHelper;
0440 cvbConfig.volumeName = subDetector.name();
0441 cvbConfig.layerBuilder = pcLayerBuilder;
0442 cvbConfig.layerEnvelopeR = {layerEnvelopeR, layerEnvelopeR};
0443 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0444 cvbConfig.buildToRadiusZero = subDetType.is(dd4hep::DetType::BEAMPIPE);
0445
0446
0447 if (getParamOr<bool>("boundary_material", subDetector, false)) {
0448 ACTS_VERBOSE(
0449 "-> boundary_material flag detected, creating proto "
0450 "material.");
0451 auto& params = getParams(subDetector);
0452 if (hasParam("boundary_material_inner", subDetector)) {
0453 ACTS_VERBOSE("--> inner");
0454 cvbConfig.boundaryMaterial[0] =
0455 createProtoMaterial(params, "boundary_material_inner",
0456 {{"binPhi", closed}, {"binZ", open}}, logger);
0457 }
0458 if (hasParam("boundary_material_outer", subDetector)) {
0459 ACTS_VERBOSE("--> outer");
0460 cvbConfig.boundaryMaterial[1] =
0461 createProtoMaterial(params, "boundary_material_outer",
0462 {{"binPhi", closed}, {"binZ", open}}, logger);
0463 }
0464 }
0465
0466
0467 auto pcVolumeBuilder = std::make_shared<const CylinderVolumeBuilder>(
0468 cvbConfig, logger.clone(std::string("D2A_V:") + subDetector.name()));
0469 return pcVolumeBuilder;
0470 } else if (subDetType.is(dd4hep::DetType::BARREL)) {
0471 ACTS_VERBOSE("Subdetector: "
0472 << subDetector.name()
0473 << " is a (sensitive) Barrel volume - building barrel.");
0474
0475 std::vector<dd4hep::DetElement> centralLayers, centralVolumes;
0476 ACTS_VERBOSE("-> collecting layers");
0477 collectLayers_dd4hep(subDetector, centralLayers, logger);
0478
0479
0480 auto surfaceArrayCreator =
0481 std::make_shared<const SurfaceArrayCreator>(logger.clone("D2A_SAC"));
0482
0483 LayerCreator::Config lcConfig;
0484 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0485 auto layerCreator =
0486 std::make_shared<const LayerCreator>(lcConfig, logger.clone("D2A_LAC"));
0487
0488 DD4hepLayerBuilder::Config lbConfig;
0489 lbConfig.configurationName = subDetector.name();
0490 lbConfig.layerCreator = layerCreator;
0491 lbConfig.centralLayers = centralLayers;
0492 lbConfig.bTypePhi = bTypePhi;
0493 lbConfig.bTypeZ = bTypeZ;
0494 lbConfig.defaultThickness = defaultLayerThickness;
0495 auto dd4hepLayerBuilder = std::make_shared<const DD4hepLayerBuilder>(
0496 lbConfig, logger.clone(std::string("D2A_LB_") + subDetector.name()));
0497
0498
0499 DD4hepVolumeBuilder::Config vbConfig;
0500 vbConfig.configurationName = subDetector.name();
0501 vbConfig.centralVolumes = centralVolumes;
0502 auto dd4hepVolumeBuilder = std::make_shared<const DD4hepVolumeBuilder>(
0503 vbConfig, logger.clone(std::string("D2A_VB_") + subDetector.name()));
0504
0505
0506 CylinderVolumeBuilder::Config cvbConfig;
0507
0508 TGeoShape* geoShape =
0509 subDetector.placement().ptr()->GetVolume()->GetShape();
0510
0511 if (geoShape == nullptr) {
0512 throw std::logic_error(std::string("Volume of DetElement: ") +
0513 subDetector.name() +
0514 std::string(" has no a shape!"));
0515 }
0516
0517 cvbConfig.layerEnvelopeR = std::make_pair(layerEnvelopeR, layerEnvelopeR);
0518 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0519 cvbConfig.trackingVolumeHelper = volumeHelper;
0520 cvbConfig.volumeName = subDetector.name();
0521 cvbConfig.layerBuilder = dd4hepLayerBuilder;
0522 cvbConfig.ctVolumeBuilder = dd4hepVolumeBuilder;
0523 auto cylinderVolumeBuilder = std::make_shared<const CylinderVolumeBuilder>(
0524 cvbConfig, logger.clone(std::string("D2A_V:") + subDetector.name()));
0525 return cylinderVolumeBuilder;
0526 } else {
0527 ACTS_WARNING(
0528 "Subdetector with name: '"
0529 << subDetector.name()
0530 << "' has inconsistent information for translation and is not of type "
0531 "'compound'. If you want to have this DetElement be translated "
0532 "into the tracking geometry you need add the right DetectorType "
0533 "or VariantParameters (at this stage the subvolume needs to be "
0534 "declared as BEAMPIPE or BARREl, or have a VariantParameter "
0535 "passive_layer=true) or if it is a compound DetElement (containing "
0536 "a barrel-endcap hierarchy), the type needs to be set to "
0537 "'compound'.");
0538 return nullptr;
0539 }
0540 }
0541
0542 std::shared_ptr<const CylinderVolumeHelper>
0543 ActsPlugins::cylinderVolumeHelper_dd4hep(const Logger& logger) {
0544
0545
0546 LayerArrayCreator::Config lacConfig;
0547 auto layerArrayCreator = std::make_shared<const LayerArrayCreator>(
0548 lacConfig, logger.clone("D2A_LAC"));
0549
0550 TrackingVolumeArrayCreator::Config tvacConfig;
0551 auto trackingVolumeArrayCreator =
0552 std::make_shared<const TrackingVolumeArrayCreator>(
0553 tvacConfig, logger.clone("D2A_TVAC"));
0554
0555 CylinderVolumeHelper::Config cvhConfig;
0556 cvhConfig.layerArrayCreator = layerArrayCreator;
0557 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
0558 auto cylinderVolumeHelper = std::make_shared<const CylinderVolumeHelper>(
0559 cvhConfig, logger.clone("D2A_CVH"));
0560
0561 return cylinderVolumeHelper;
0562 }
0563
0564 void ActsPlugins::collectCompounds_dd4hep(
0565 dd4hep::DetElement& detElement,
0566 std::vector<dd4hep::DetElement>& compounds) {
0567 const dd4hep::DetElement::Children& children = detElement.children();
0568 for (auto& child : children) {
0569 dd4hep::DetElement childDetElement = child.second;
0570 dd4hep::DetType type{childDetElement.typeFlag()};
0571 if (type.is(dd4hep::DetType::BARREL) || type.is(dd4hep::DetType::ENDCAP)) {
0572 compounds.push_back(childDetElement);
0573 }
0574 collectCompounds_dd4hep(childDetElement, compounds);
0575 }
0576 }
0577
0578 void ActsPlugins::collectSubDetectors_dd4hep(
0579 dd4hep::DetElement& detElement,
0580 std::vector<dd4hep::DetElement>& subdetectors, const Logger& logger) {
0581 const dd4hep::DetElement::Children& children = detElement.children();
0582 for (auto& child : children) {
0583 dd4hep::DetElement childDetElement = child.second;
0584 dd4hep::DetType type{childDetElement.typeFlag()};
0585 if (childDetElement.type() == "compound") {
0586
0587
0588
0589 if (getParamOr<bool>("acts_legacy_assembly", childDetElement, true)) {
0590 subdetectors.push_back(childDetElement);
0591 continue;
0592 }
0593 }
0594
0595 if (type.is(dd4hep::DetType::TRACKER)) {
0596 subdetectors.push_back(childDetElement);
0597 }
0598 collectSubDetectors_dd4hep(childDetElement, subdetectors, logger);
0599 }
0600 }
0601
0602 void ActsPlugins::collectLayers_dd4hep(dd4hep::DetElement& detElement,
0603 std::vector<dd4hep::DetElement>& layers,
0604 const Logger& logger) {
0605 const dd4hep::DetElement::Children& children = detElement.children();
0606 for (auto& child : children) {
0607 std::string _expr{"$^"};
0608
0609 dd4hep::rec::VariantParameters* params =
0610 detElement.extension<dd4hep::rec::VariantParameters>(false);
0611
0612 if (params != nullptr) {
0613 _expr = params->value_or<std::string>("layer_pattern", _expr);
0614 ACTS_VERBOSE("--> Layer pattern for elt " << detElement.name() << ": "
0615 << _expr);
0616 }
0617 std::regex expr{_expr};
0618
0619 dd4hep::DetElement childDetElement = child.second;
0620
0621 if (std::regex_search(childDetElement.name(), expr)) {
0622 ACTS_VERBOSE("--> Layer candidate match: " << _expr << " -> "
0623 << childDetElement.name());
0624 layers.push_back(childDetElement);
0625 continue;
0626 }
0627
0628 collectLayers_dd4hep(childDetElement, layers, logger);
0629 }
0630 }