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