Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:10:16

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
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/TGeoPrimitivesHelper.hpp"
0019 #include "Acts/Plugins/TGeo/TGeoSurfaceConverter.hpp"
0020 
0021 #include "DD4hep/DetElement.h"
0022 
0023 using namespace Acts::detail;
0024 
0025 Acts::DD4hepDetectorSurfaceFactory::DD4hepDetectorSurfaceFactory(
0026     std::unique_ptr<const Logger> mlogger)
0027     : m_logger(std::move(mlogger)) {
0028   ACTS_DEBUG("UnitLength conversion factor (DD4hep -> Acts): " << unitLength);
0029 }
0030 
0031 void Acts::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   // Check for auto-range determination
0049   if (!cache.binnings.empty() && cache.sExtent.has_value()) {
0050     ACTS_DEBUG("Autorange deterimnation of binning enabled.");
0051   }
0052 }
0053 
0054 void Acts::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   // Check if any surface binnning can be detected
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   // Deal with passive surface if detected
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 Acts::DD4hepDetectorSurfaceFactory::DD4hepSensitiveSurface
0096 Acts::DD4hepDetectorSurfaceFactory::constructSensitiveComponents(
0097     Cache& cache, const GeometryContext& gctx,
0098     const dd4hep::DetElement& dd4hepElement, const Options& options) const {
0099   // Extract the axis definition
0100   std::string detAxis =
0101       getParamOr<std::string>("axis_definitions", dd4hepElement, "XYZ");
0102   std::shared_ptr<const Acts::ISurfaceMaterial> surfaceMaterial = nullptr;
0103 
0104   // Create the corresponding detector element
0105   auto dd4hepDetElement = std::make_shared<Acts::DD4hepDetectorElement>(
0106       dd4hepElement, detAxis, unitLength, false, nullptr);
0107   auto sSurface = dd4hepDetElement->surface().getSharedPtr();
0108   // Measure if configured to do so
0109   if (cache.sExtent.has_value()) {
0110     auto sExtent =
0111         sSurface->polyhedronRepresentation(gctx, cache.nExtentSegments)
0112             .extent();
0113     cache.sExtent.value().extend(sExtent, cache.extentConstraints);
0114   }
0115 
0116   // Attach surface material if present
0117   attachSurfaceMaterial(gctx, "acts_surface_", dd4hepElement, *sSurface.get(),
0118                         dd4hepDetElement->thickness(), options);
0119   // return the surface
0120   return {dd4hepDetElement, sSurface};
0121 }
0122 
0123 Acts::DD4hepDetectorSurfaceFactory::DD4hepPassiveSurface
0124 Acts::DD4hepDetectorSurfaceFactory::constructPassiveComponents(
0125     Cache& cache, const GeometryContext& gctx,
0126     const dd4hep::DetElement& dd4hepElement, const Options& options) const {
0127   // Underlying TGeo node, shape & transform
0128   const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0129   auto tgeoShape = tgeoNode.GetVolume()->GetShape();
0130   const auto tgeoTransform = dd4hepElement.nominal().worldTransformation();
0131   // Extract the axis definition
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   // Measure if configured to do so
0138   if (cache.pExtent.has_value()) {
0139     auto sExtent =
0140         pSurface->polyhedronRepresentation(gctx, cache.nExtentSegments)
0141             .extent();
0142     cache.pExtent.value().extend(sExtent, cache.extentConstraints);
0143   }
0144   attachSurfaceMaterial(gctx, "acts_passive_surface", dd4hepElement,
0145                         *pSurface.get(), thickness, options);
0146   // Return a passive surface
0147   return {pSurface, assignToAll};
0148 }
0149 
0150 void Acts::DD4hepDetectorSurfaceFactory::attachSurfaceMaterial(
0151     const GeometryContext& gctx, const std::string& prefix,
0152     const dd4hep::DetElement& dd4hepElement, Acts::Surface& surface,
0153     ActsScalar thickness, const Options& options) const {
0154   // Bool proto material overrules converted material
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     Experimental::BinningDescription pmBinning{
0160         DD4hepBinningHelpers::convertBinning(
0161             dd4hepElement, prefix + "_proto_material_binning")};
0162     ACTS_VERBOSE(" - converted binning is " << pmBinning.toString());
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     // Extract the material
0169     const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0170     auto tgeoMaterial = tgeoNode.GetMedium()->GetMaterial();
0171     // Convert the material
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     // Assign the material to the surface
0180     surface.assignSurfaceMaterial(std::move(surfaceMaterial));
0181   }
0182 }