Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:14:07

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
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   // Check for auto-range determination
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   // Check if any surface binnning can be detected
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   // Deal with passive surface if detected
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   // Extract the axis definition
0098   std::string detAxis =
0099       getParamOr<std::string>("axis_definitions", dd4hepElement, "XYZ");
0100   std::shared_ptr<const ISurfaceMaterial> surfaceMaterial = nullptr;
0101 
0102   // Create the corresponding detector element
0103   auto dd4hepDetElement = m_config.detectorElementFactory(
0104       dd4hepElement, detAxis, unitLength, false, nullptr);
0105   auto sSurface = dd4hepDetElement->surface().getSharedPtr();
0106   // Measure if configured to do so
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   // Attach surface material if present
0115   attachSurfaceMaterial(gctx, "acts_surface_", dd4hepElement, *sSurface,
0116                         dd4hepDetElement->thickness(), options);
0117   // return the surface
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   // Underlying TGeo node, shape & transform
0126   const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0127   auto tgeoShape = tgeoNode.GetVolume()->GetShape();
0128   const auto tgeoTransform = dd4hepElement.nominal().worldTransformation();
0129   // Extract the axis definition
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   // Measure if configured to do so
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   // Return a passive surface
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   // Bool proto material overrules converted material
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     // Extract the material
0170     const auto& tgeoNode = *(dd4hepElement.placement().ptr());
0171     auto tgeoMaterial = tgeoNode.GetMedium()->GetMaterial();
0172     // Convert the material
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     // Assign the material to the surface
0181     surface.assignSurfaceMaterial(std::move(surfaceMaterial));
0182   }
0183 }
0184 
0185 }  // namespace Acts