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