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