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