File indexing completed on 2025-07-13 07:51:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp"
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Detector/detail/ProtoMaterialHelper.hpp"
0013 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0014 #include "Acts/Plugins/DD4hep/DD4hepBinningHelpers.hpp"
0015 #include "Acts/Plugins/DD4hep/DD4hepConversionHelpers.hpp"
0016 #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp"
0017 #include "Acts/Plugins/Root/TGeoMaterialConverter.hpp"
0018 #include "Acts/Plugins/Root/TGeoSurfaceConverter.hpp"
0019
0020 #include "DD4hep/DetElement.h"
0021
0022 using namespace Acts::detail;
0023
0024 Acts::DD4hepDetectorSurfaceFactory::DD4hepDetectorSurfaceFactory(
0025 const Config& config, std::unique_ptr<const Logger> mlogger)
0026 : m_config(config), m_logger(std::move(mlogger)) {}
0027
0028 void Acts::DD4hepDetectorSurfaceFactory::construct(
0029 Cache& cache, const GeometryContext& gctx,
0030 const dd4hep::DetElement& dd4hepElement, const Options& options) {
0031 ACTS_DEBUG("Configured to convert "
0032 << (options.convertSensitive ? "sensitive components and " : "")
0033 << (options.convertPassive
0034 ? "passive surfaces."
0035 : (!options.convertSensitive
0036 ? "nothing (this is likely a configuration error)."
0037 : "")));
0038 ACTS_DEBUG("Constructing DD4hepDetectorElements - tree level call from "
0039 << dd4hepElement.name() << ".");
0040 recursiveConstruct(cache, gctx, dd4hepElement, options, 1);
0041 ACTS_DEBUG("Recursive search did yield: "
0042 << cache.sensitiveSurfaces.size() << " sensitive surface(s), "
0043 << cache.passiveSurfaces.size() << " passive surface(s)");
0044
0045
0046 if (!cache.binnings.empty() && cache.sExtent.has_value()) {
0047 ACTS_DEBUG("Autorange deterimnation of binning enabled.");
0048 }
0049 }
0050
0051 void Acts::DD4hepDetectorSurfaceFactory::recursiveConstruct(
0052 Cache& cache, const GeometryContext& gctx,
0053 const dd4hep::DetElement& dd4hepElement, const Options& options,
0054 int level) {
0055 ACTS_VERBOSE("Conversion call at level " << level << " for element "
0056 << dd4hepElement.name());
0057
0058
0059 int sBinning = getParamOr<int>("acts_surface_binning_dim", dd4hepElement, 0);
0060 if (sBinning > 0) {
0061 cache.binnings = DD4hepBinningHelpers::convertBinning(
0062 dd4hepElement, "acts_surface_binning");
0063 }
0064
0065
0066 bool pSurface =
0067 getParamOr<bool>("acts_passive_surface", dd4hepElement, false);
0068 if (pSurface && options.convertPassive) {
0069 ACTS_VERBOSE("Passive surface(s) detected.");
0070 cache.passiveSurfaces.push_back(
0071 constructPassiveComponents(cache, gctx, dd4hepElement, options));
0072 }
0073
0074 const dd4hep::DetElement::Children& children = dd4hepElement.children();
0075 if (!children.empty()) {
0076 ACTS_VERBOSE(children.size() << " child(ren) detected.");
0077 for (auto& child : children) {
0078 dd4hep::DetElement childDetElement = child.second;
0079 ACTS_VERBOSE("Processing child " << childDetElement.name());
0080 if (childDetElement.volume().isSensitive() && options.convertSensitive) {
0081 ACTS_VERBOSE("Sensitive surface detected.");
0082 cache.sensitiveSurfaces.push_back(constructSensitiveComponents(
0083 cache, gctx, childDetElement, options));
0084 }
0085 recursiveConstruct(cache, gctx, childDetElement, options, level + 1);
0086 }
0087 } else {
0088 ACTS_VERBOSE("No children detected.");
0089 }
0090 }
0091
0092 Acts::DD4hepDetectorSurfaceFactory::DD4hepSensitiveSurface
0093 Acts::DD4hepDetectorSurfaceFactory::constructSensitiveComponents(
0094 Cache& cache, const GeometryContext& gctx,
0095 const dd4hep::DetElement& dd4hepElement, const Options& options) const {
0096
0097 std::string detAxis =
0098 getParamOr<std::string>("axis_definitions", dd4hepElement, "XYZ");
0099 std::shared_ptr<const Acts::ISurfaceMaterial> surfaceMaterial = nullptr;
0100
0101
0102 auto dd4hepDetElement = m_config.detectorElementFactory(
0103 dd4hepElement, detAxis, unitLength, false, nullptr);
0104 auto sSurface = dd4hepDetElement->surface().getSharedPtr();
0105
0106 if (cache.sExtent.has_value()) {
0107 auto sExtent =
0108 sSurface->polyhedronRepresentation(gctx, cache.nExtentQSegments)
0109 .extent();
0110 cache.sExtent.value().extend(sExtent, cache.extentConstraints);
0111 }
0112
0113
0114 attachSurfaceMaterial(gctx, "acts_surface_", dd4hepElement, *sSurface,
0115 dd4hepDetElement->thickness(), options);
0116
0117 return {dd4hepDetElement, sSurface};
0118 }
0119
0120 Acts::DD4hepDetectorSurfaceFactory::DD4hepPassiveSurface
0121 Acts::DD4hepDetectorSurfaceFactory::constructPassiveComponents(
0122 Cache& cache, const GeometryContext& gctx,
0123 const dd4hep::DetElement& dd4hepElement, const Options& options) const {
0124
0125 const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0126 auto tgeoShape = tgeoNode.GetVolume()->GetShape();
0127 const auto tgeoTransform = dd4hepElement.nominal().worldTransformation();
0128
0129 auto detAxis =
0130 getParamOr<std::string>("axis_definitions", dd4hepElement, "XYZ");
0131 bool assignToAll = getParamOr<bool>("assign_to_all", dd4hepElement, true);
0132 auto [pSurface, thickness] =
0133 TGeoSurfaceConverter::toSurface(*tgeoShape, tgeoTransform, detAxis);
0134
0135 if (cache.pExtent.has_value()) {
0136 auto sExtent =
0137 pSurface->polyhedronRepresentation(gctx, cache.nExtentQSegments)
0138 .extent();
0139 cache.pExtent.value().extend(sExtent, cache.extentConstraints);
0140 }
0141 attachSurfaceMaterial(gctx, "acts_passive_surface", dd4hepElement,
0142 *pSurface.get(), thickness, options);
0143
0144 return {pSurface, assignToAll};
0145 }
0146
0147 void Acts::DD4hepDetectorSurfaceFactory::attachSurfaceMaterial(
0148 const GeometryContext& gctx, const std::string& prefix,
0149 const dd4hep::DetElement& dd4hepElement, Acts::Surface& surface,
0150 double thickness, const Options& options) const {
0151
0152 bool protoMaterial =
0153 getParamOr<bool>(prefix + "_proto_material", dd4hepElement, false);
0154 if (protoMaterial) {
0155 ACTS_VERBOSE(" - proto material binning for passive surface found.");
0156 auto materialBinning = DD4hepBinningHelpers::convertBinning(
0157 dd4hepElement, prefix + "_proto_material_binning");
0158 std::vector<DirectedProtoAxis> pmBinning = {};
0159 for (const auto& [dpAxis, bins] : materialBinning) {
0160 pmBinning.emplace_back(dpAxis);
0161 }
0162 ACTS_VERBOSE(" - converted binning is " << pmBinning);
0163 Experimental::detail::ProtoMaterialHelper::attachProtoMaterial(
0164 gctx, surface, pmBinning);
0165
0166 } else if (options.convertMaterial) {
0167 ACTS_VERBOSE(" - direct conversion of DD4hep material triggered.");
0168
0169 const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0170 auto tgeoMaterial = tgeoNode.GetMedium()->GetMaterial();
0171
0172 TGeoMaterialConverter::Options materialOptions;
0173 materialOptions.unitLengthScalor = unitLength;
0174 auto materialSlab = TGeoMaterialConverter::materialSlab(
0175 *tgeoMaterial, thickness, options.surfaceMaterialThickness,
0176 materialOptions);
0177 auto surfaceMaterial =
0178 std::make_shared<HomogeneousSurfaceMaterial>(materialSlab);
0179
0180 surface.assignSurfaceMaterial(std::move(surfaceMaterial));
0181 }
0182 }