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