File indexing completed on 2025-01-18 09:12:17
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/DD4hepLayerBuilder.hpp"
0026 #include "Acts/Plugins/DD4hep/DD4hepMaterialHelpers.hpp"
0027 #include "Acts/Plugins/DD4hep/DD4hepVolumeBuilder.hpp"
0028 #include "Acts/Utilities/Logger.hpp"
0029
0030 #include <array>
0031 #include <cmath>
0032 #include <list>
0033 #include <regex>
0034 #include <stdexcept>
0035 #include <string>
0036 #include <utility>
0037
0038 #include "DD4hep/DetType.h"
0039 #include "DDRec/DetectorData.h"
0040 #include "TGeoManager.h"
0041
0042 namespace Acts {
0043 class IMaterialDecorator;
0044 class ISurfaceMaterial;
0045 class TrackingGeometry;
0046 class TrackingVolume;
0047
0048 namespace {
0049 struct DebugVisitor {
0050 std::string operator()(int value) { return std::to_string(value); }
0051
0052 std::string operator()(double value) { return std::to_string(value); }
0053
0054 std::string operator()(std::string value) { return value; }
0055 };
0056 }
0057
0058 std::unique_ptr<const TrackingGeometry> convertDD4hepDetector(
0059 dd4hep::DetElement worldDetElement, const Logger& logger,
0060 BinningType bTypePhi, BinningType bTypeR, BinningType bTypeZ,
0061 double layerEnvelopeR, double layerEnvelopeZ, double defaultLayerThickness,
0062 const std::function<void(std::vector<dd4hep::DetElement>& detectors)>&
0063 sortSubDetectors,
0064 const Acts::GeometryContext& gctx,
0065 std::shared_ptr<const IMaterialDecorator> matDecorator,
0066 std::shared_ptr<const GeometryIdentifierHook> geometryIdentifierHook) {
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);
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
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 Acts::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::ENDCAP)) {
0219 ACTS_VERBOSE("Subvolume: '" << volumeDetElement.name()
0220 << "' is marked ENDCAP");
0221 if (zPos < 0.) {
0222 if (nEndCap) {
0223 throw std::logic_error(
0224 "Negative Endcap was already given for this "
0225 "hierarchy! Please create a new "
0226 "DD4hep_SubDetectorAssembly for the next "
0227 "hierarchy.");
0228 }
0229 nEndCap = true;
0230 ACTS_VERBOSE("-> is negative endcap");
0231 ACTS_VERBOSE("-> collecting layers");
0232 collectLayers_dd4hep(volumeDetElement, negativeLayers, logger);
0233
0234 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0235 ACTS_VERBOSE(
0236 "-> boundary_material flag detected, creating proto "
0237 "material.");
0238 auto& params = getParams(volumeDetElement);
0239 if (hasParam("boundary_material_negative", volumeDetElement)) {
0240 ACTS_VERBOSE("--> negative");
0241 cvbConfig.boundaryMaterial[2] = Acts::createProtoMaterial(
0242 params, "boundary_material_negative",
0243 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0244 }
0245 if (hasParam("boundary_material_positive", volumeDetElement)) {
0246 ACTS_VERBOSE("--> positive");
0247 cvbConfig.boundaryMaterial[3] = Acts::createProtoMaterial(
0248 params, "boundary_material_positive",
0249 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0250 }
0251 }
0252 } else {
0253 if (pEndCap) {
0254 throw std::logic_error(
0255 "Positive Endcap was already given for this "
0256 "hierarchy! Please create a new "
0257 "DD4hep_SubDetectorAssembly for the next "
0258 "hierarchy.");
0259 }
0260 pEndCap = true;
0261 ACTS_VERBOSE("-> is positive endcap");
0262 ACTS_VERBOSE("-> collecting layers");
0263 collectLayers_dd4hep(volumeDetElement, positiveLayers, logger);
0264
0265 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0266 ACTS_VERBOSE(
0267 "-> boundary_material flag detected, creating proto "
0268 "material.");
0269 auto& params = getParams(volumeDetElement);
0270 if (params.contains("boundary_material_negative")) {
0271 ACTS_VERBOSE("--> negative");
0272 cvbConfig.boundaryMaterial[4] = Acts::createProtoMaterial(
0273 params, "boundary_material_negative",
0274 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0275 }
0276 if (params.contains("boundary_material_positive")) {
0277 ACTS_VERBOSE("--> positive");
0278 cvbConfig.boundaryMaterial[5] = Acts::createProtoMaterial(
0279 params, "boundary_material_positive",
0280 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0281 }
0282 }
0283 }
0284 } else if (type.is(dd4hep::DetType::BARREL)) {
0285 if (barrel) {
0286 throw std::logic_error(
0287 "Barrel was already given for this "
0288 "hierarchy! Please create a new "
0289 "DD4hep_SubDetectorAssembly for the next "
0290 "hierarchy.");
0291 }
0292 barrel = true;
0293 ACTS_VERBOSE("Subvolume: " << volumeDetElement.name()
0294 << " is marked as BARREL");
0295 ACTS_VERBOSE("-> collecting layers");
0296 collectLayers_dd4hep(volumeDetElement, centralLayers, logger);
0297
0298 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0299 ACTS_VERBOSE(
0300 "-> boundary_material flag detected, creating proto "
0301 "material.");
0302 auto& params = getParams(volumeDetElement);
0303 if (params.contains("boundary_material_negative")) {
0304 ACTS_VERBOSE("--> negative");
0305 cvbConfig.boundaryMaterial[3] = Acts::createProtoMaterial(
0306 params, "boundary_material_negative",
0307 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0308 }
0309 if (params.contains("boundary_material_positive")) {
0310 ACTS_VERBOSE("--> positive");
0311 cvbConfig.boundaryMaterial[4] = Acts::createProtoMaterial(
0312 params, "boundary_material_positive",
0313 {{"binPhi", Acts::closed}, {"binR", Acts::open}}, logger);
0314 }
0315 }
0316 } else {
0317 throw std::logic_error(
0318 std::string("Current DetElement: ") + volumeDetElement.name() +
0319 std::string(" has inconsistent settings. It's a compound,"
0320 " but its DetectorType is neither BARREL nor ENDCAP"
0321 " Please check your detector construction."));
0322 }
0323
0324
0325 if (getParamOr<bool>("boundary_material", volumeDetElement, false)) {
0326 ACTS_VERBOSE(
0327 "-> boundary_material flag detected, creating proto "
0328 "material.");
0329 auto& params = getParams(volumeDetElement);
0330 if (params.contains("boundary_material_inner")) {
0331 ACTS_VERBOSE("--> inner");
0332 cvbConfig.boundaryMaterial[0] = Acts::createProtoMaterial(
0333 params, "boundary_material_inner",
0334 {{"binPhi", Acts::closed}, {"binZ", Acts::open}}, logger);
0335 }
0336 if (params.contains("boundary_material_outer")) {
0337 ACTS_VERBOSE("--> outer");
0338 cvbConfig.boundaryMaterial[1] = Acts::createProtoMaterial(
0339 params, "boundary_material_outer",
0340 {{"binPhi", Acts::closed}, {"binZ", Acts::open}}, logger);
0341 }
0342 }
0343 }
0344
0345 if ((pEndCap && !nEndCap) || (!pEndCap && nEndCap)) {
0346 throw std::logic_error(
0347 "Only one Endcap is given for the current "
0348 "hierarchy! Endcaps should always occur in "
0349 "pairs. Please check your detector "
0350 "construction.");
0351 }
0352
0353
0354 auto surfaceArrayCreator =
0355 std::make_shared<const Acts::SurfaceArrayCreator>(
0356 logger.clone("D2A_SAC"));
0357
0358 Acts::LayerCreator::Config lcConfig;
0359 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0360 auto layerCreator = std::make_shared<const Acts::LayerCreator>(
0361 lcConfig, logger.clone("D2A_LAC"));
0362
0363 Acts::DD4hepLayerBuilder::Config lbConfig;
0364 lbConfig.configurationName = subDetector.name();
0365 lbConfig.layerCreator = layerCreator;
0366 lbConfig.negativeLayers = negativeLayers;
0367 lbConfig.centralLayers = centralLayers;
0368 lbConfig.positiveLayers = positiveLayers;
0369 lbConfig.bTypePhi = bTypePhi;
0370 lbConfig.bTypeR = bTypeR;
0371 lbConfig.bTypeZ = bTypeZ;
0372 lbConfig.defaultThickness = defaultLayerThickness;
0373 auto dd4hepLayerBuilder = std::make_shared<const Acts::DD4hepLayerBuilder>(
0374 lbConfig, logger.clone(std::string("D2A_L:") + subDetector.name()));
0375
0376
0377
0378
0379 cvbConfig.layerEnvelopeR = std::make_pair(layerEnvelopeR, layerEnvelopeR);
0380 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0381 cvbConfig.trackingVolumeHelper = volumeHelper;
0382 cvbConfig.volumeName = subDetector.name();
0383 cvbConfig.layerBuilder = dd4hepLayerBuilder;
0384 auto cylinderVolumeBuilder =
0385 std::make_shared<const Acts::CylinderVolumeBuilder>(
0386 cvbConfig,
0387 logger.clone(std::string("D2A_V:") + subDetector.name()));
0388 return cylinderVolumeBuilder;
0389 } else if (subDetType.is(dd4hep::DetType::BEAMPIPE) ||
0390 getParamOr<bool>("passive_layer", subDetector, false)) {
0391 ACTS_VERBOSE("Subdetector: " << subDetector.name()
0392 << " - building a passive cylinder.");
0393
0394 if (subDetType.is(dd4hep::DetType::BEAMPIPE)) {
0395 ACTS_VERBOSE("This is the beam pipe - will be built to r -> 0.");
0396 }
0397
0398
0399 TGeoShape* geoShape =
0400 subDetector.placement().ptr()->GetVolume()->GetShape();
0401 TGeoTubeSeg* tube = dynamic_cast<TGeoTubeSeg*>(geoShape);
0402 if (tube == nullptr) {
0403 throw std::logic_error(
0404 "Cylinder has wrong shape - needs to be TGeoTubeSeg!");
0405 }
0406
0407 double rMin = tube->GetRmin() * UnitConstants::cm - layerEnvelopeR;
0408 double rMax = tube->GetRmax() * UnitConstants::cm + layerEnvelopeR;
0409 double halfZ = tube->GetDz() * UnitConstants::cm + layerEnvelopeZ;
0410 ACTS_VERBOSE(
0411 "Extracting cylindrical volume bounds ( rmin / rmax / "
0412 "halfZ )= ( "
0413 << rMin << " / " << rMax << " / " << halfZ << " )");
0414
0415 std::shared_ptr<Acts::ISurfaceMaterial> plMaterial = nullptr;
0416 if (getParamOr<bool>("layer_material", subDetector, false)) {
0417
0418 ACTS_VERBOSE("--> adding layer material at 'representing'");
0419 plMaterial = Acts::createProtoMaterial(
0420 getParams(subDetector), "layer_material_representing",
0421 {{"binPhi", Acts::closed}, {"binZ", Acts::open}}, logger);
0422 }
0423
0424
0425 Acts::PassiveLayerBuilder::Config plbConfig;
0426 plbConfig.layerIdentification = subDetector.name();
0427 plbConfig.centralLayerRadii = std::vector<double>(1, 0.5 * (rMax + rMin));
0428 plbConfig.centralLayerHalflengthZ = std::vector<double>(1, halfZ);
0429 plbConfig.centralLayerThickness =
0430 std::vector<double>(1, std::abs(rMax - rMin));
0431 plbConfig.centralLayerMaterial = {plMaterial};
0432 auto pcLayerBuilder = std::make_shared<const Acts::PassiveLayerBuilder>(
0433 plbConfig, logger.clone(std::string("D2A_PL:") + subDetector.name()));
0434
0435
0436 Acts::CylinderVolumeBuilder::Config cvbConfig;
0437 cvbConfig.trackingVolumeHelper = volumeHelper;
0438 cvbConfig.volumeName = subDetector.name();
0439 cvbConfig.layerBuilder = pcLayerBuilder;
0440 cvbConfig.layerEnvelopeR = {layerEnvelopeR, layerEnvelopeR};
0441 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0442 cvbConfig.buildToRadiusZero = subDetType.is(dd4hep::DetType::BEAMPIPE);
0443
0444
0445 if (getParamOr<bool>("boundary_material", subDetector, false)) {
0446 ACTS_VERBOSE(
0447 "-> boundary_material flag detected, creating proto "
0448 "material.");
0449 auto& params = getParams(subDetector);
0450 if (hasParam("boundary_material_inner", subDetector)) {
0451 ACTS_VERBOSE("--> inner");
0452 cvbConfig.boundaryMaterial[0] = Acts::createProtoMaterial(
0453 params, "boundary_material_inner",
0454 {{"binPhi", Acts::closed}, {"binZ", Acts::open}}, logger);
0455 }
0456 if (hasParam("boundary_material_outer", subDetector)) {
0457 ACTS_VERBOSE("--> outer");
0458 cvbConfig.boundaryMaterial[1] = Acts::createProtoMaterial(
0459 params, "boundary_material_outer",
0460 {{"binPhi", Acts::closed}, {"binZ", Acts::open}}, logger);
0461 }
0462 }
0463
0464
0465 auto pcVolumeBuilder = std::make_shared<const Acts::CylinderVolumeBuilder>(
0466 cvbConfig, logger.clone(std::string("D2A_V:") + subDetector.name()));
0467 return pcVolumeBuilder;
0468 } else if (subDetType.is(dd4hep::DetType::BARREL)) {
0469 ACTS_VERBOSE("Subdetector: "
0470 << subDetector.name()
0471 << " is a (sensitive) Barrel volume - building barrel.");
0472
0473 std::vector<dd4hep::DetElement> centralLayers, centralVolumes;
0474 ACTS_VERBOSE("-> collecting layers");
0475 collectLayers_dd4hep(subDetector, centralLayers, logger);
0476
0477
0478 auto surfaceArrayCreator =
0479 std::make_shared<const Acts::SurfaceArrayCreator>(
0480 logger.clone("D2A_SAC"));
0481
0482 Acts::LayerCreator::Config lcConfig;
0483 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0484 auto layerCreator = std::make_shared<const Acts::LayerCreator>(
0485 lcConfig, logger.clone("D2A_LAC"));
0486
0487 Acts::DD4hepLayerBuilder::Config lbConfig;
0488 lbConfig.configurationName = subDetector.name();
0489 lbConfig.layerCreator = layerCreator;
0490 lbConfig.centralLayers = centralLayers;
0491 lbConfig.bTypePhi = bTypePhi;
0492 lbConfig.bTypeZ = bTypeZ;
0493 lbConfig.defaultThickness = defaultLayerThickness;
0494 auto dd4hepLayerBuilder = std::make_shared<const Acts::DD4hepLayerBuilder>(
0495 lbConfig, logger.clone(std::string("D2A_LB_") + subDetector.name()));
0496
0497
0498 Acts::DD4hepVolumeBuilder::Config vbConfig;
0499 vbConfig.configurationName = subDetector.name();
0500 vbConfig.centralVolumes = centralVolumes;
0501 auto dd4hepVolumeBuilder =
0502 std::make_shared<const Acts::DD4hepVolumeBuilder>(
0503 vbConfig,
0504 logger.clone(std::string("D2A_VB_") + subDetector.name()));
0505
0506
0507 Acts::CylinderVolumeBuilder::Config cvbConfig;
0508
0509 TGeoShape* geoShape =
0510 subDetector.placement().ptr()->GetVolume()->GetShape();
0511
0512 if (geoShape == nullptr) {
0513 throw std::logic_error(std::string("Volume of DetElement: ") +
0514 subDetector.name() +
0515 std::string(" has no a shape!"));
0516 }
0517
0518 cvbConfig.layerEnvelopeR = std::make_pair(layerEnvelopeR, layerEnvelopeR);
0519 cvbConfig.layerEnvelopeZ = layerEnvelopeZ;
0520 cvbConfig.trackingVolumeHelper = volumeHelper;
0521 cvbConfig.volumeName = subDetector.name();
0522 cvbConfig.layerBuilder = dd4hepLayerBuilder;
0523 cvbConfig.ctVolumeBuilder = dd4hepVolumeBuilder;
0524 auto cylinderVolumeBuilder =
0525 std::make_shared<const Acts::CylinderVolumeBuilder>(
0526 cvbConfig,
0527 logger.clone(std::string("D2A_V:") + subDetector.name()));
0528 return cylinderVolumeBuilder;
0529 } else {
0530 ACTS_WARNING(
0531 "Subdetector with name: '"
0532 << subDetector.name()
0533 << "' has inconsistent information for translation and is not of type "
0534 "'compound'. If you want to have this DetElement be translated "
0535 "into the tracking geometry you need add the right DetectorType "
0536 "or VariantParameters (at this stage the subvolume needs to be "
0537 "declared as BEAMPIPE or BARREl, or have a VariantParameter "
0538 "passive_layer=true) or if it is a compound DetElement (containing "
0539 "a barrel-endcap hierarchy), the type needs to be set to "
0540 "'compound'.");
0541 return nullptr;
0542 }
0543 }
0544
0545 std::shared_ptr<const Acts::CylinderVolumeHelper> cylinderVolumeHelper_dd4hep(
0546 const Logger& logger) {
0547
0548
0549 Acts::LayerArrayCreator::Config lacConfig;
0550 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
0551 lacConfig, logger.clone("D2A_LAC"));
0552
0553 Acts::TrackingVolumeArrayCreator::Config tvacConfig;
0554 auto trackingVolumeArrayCreator =
0555 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
0556 tvacConfig, logger.clone("D2A_TVAC"));
0557
0558 Acts::CylinderVolumeHelper::Config cvhConfig;
0559 cvhConfig.layerArrayCreator = layerArrayCreator;
0560 cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
0561 auto cylinderVolumeHelper =
0562 std::make_shared<const Acts::CylinderVolumeHelper>(
0563 cvhConfig, logger.clone("D2A_CVH"));
0564
0565 return cylinderVolumeHelper;
0566 }
0567
0568 void collectCompounds_dd4hep(dd4hep::DetElement& detElement,
0569 std::vector<dd4hep::DetElement>& compounds) {
0570 const dd4hep::DetElement::Children& children = detElement.children();
0571 for (auto& child : children) {
0572 dd4hep::DetElement childDetElement = child.second;
0573 dd4hep::DetType type{childDetElement.typeFlag()};
0574 if (type.is(dd4hep::DetType::BARREL) || type.is(dd4hep::DetType::ENDCAP)) {
0575 compounds.push_back(childDetElement);
0576 }
0577 collectCompounds_dd4hep(childDetElement, compounds);
0578 }
0579 }
0580
0581 void collectSubDetectors_dd4hep(dd4hep::DetElement& detElement,
0582 std::vector<dd4hep::DetElement>& subdetectors,
0583 const Logger& logger) {
0584 const dd4hep::DetElement::Children& children = detElement.children();
0585 for (auto& child : children) {
0586 dd4hep::DetElement childDetElement = child.second;
0587 dd4hep::DetType type{childDetElement.typeFlag()};
0588 if (childDetElement.type() == "compound") {
0589
0590
0591
0592 if (getParamOr<bool>("acts_legacy_assembly", childDetElement, true)) {
0593 subdetectors.push_back(childDetElement);
0594 continue;
0595 }
0596 }
0597
0598 if (type.is(dd4hep::DetType::TRACKER)) {
0599 subdetectors.push_back(childDetElement);
0600 }
0601 collectSubDetectors_dd4hep(childDetElement, subdetectors, logger);
0602 }
0603 }
0604
0605 void collectLayers_dd4hep(dd4hep::DetElement& detElement,
0606 std::vector<dd4hep::DetElement>& layers,
0607 const Logger& logger) {
0608 const dd4hep::DetElement::Children& children = detElement.children();
0609 for (auto& child : children) {
0610 std::string _expr{"$^"};
0611
0612 dd4hep::rec::VariantParameters* params =
0613 detElement.extension<dd4hep::rec::VariantParameters>(false);
0614
0615 if (params != nullptr) {
0616 _expr = params->value_or<std::string>("layer_pattern", _expr);
0617 ACTS_VERBOSE("--> Layer pattern for elt " << detElement.name() << ": "
0618 << _expr);
0619 }
0620 std::regex expr{_expr};
0621
0622 dd4hep::DetElement childDetElement = child.second;
0623
0624 if (std::regex_search(childDetElement.name(), expr)) {
0625 ACTS_VERBOSE("--> Layer candidate match: " << _expr << " -> "
0626 << childDetElement.name());
0627 layers.push_back(childDetElement);
0628 continue;
0629 }
0630
0631 collectLayers_dd4hep(childDetElement, layers, logger);
0632 }
0633 }
0634
0635 }