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