Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve DD4hep based detector building and add tests #2689

Merged
merged 6 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Acts/Utilities/BinningData.hpp"
#include "Acts/Utilities/detail/AxisFwd.hpp"

#include <sstream>
#include <string>
#include <tuple>
#include <vector>
Expand Down Expand Up @@ -52,6 +53,26 @@ inline BinningValue stringToBinningValue(const std::string &binningString) {
}
}

/// Helper method to cenvert a binning list string to a vector of binning values
/// e.g. "r,z" -> {binR, binZ}
///
/// @param binningString
///
/// @return a vector of binninng values
inline std::vector<BinningValue> stringToBinningValues(
const std::string &binningString, const char &del = ',') {
if (binningString.empty()) {
return {};
}
std::vector<BinningValue> bBinning;
std::stringstream s(binningString);
std::string b = "";
while (getline(s, b, del)) {
bBinning.push_back(stringToBinningValue(b));
}
return bBinning;
}

/// Helper method to decode the binning from what would appear in the
/// xml into variant parameters, such that it can be understood in the
/// downstream processing.
Expand All @@ -64,10 +85,10 @@ inline BinningValue stringToBinningValue(const std::string &binningString) {
/// Example for e.g. bname = \"surface_binning\":
///
/// - Equidistant binning in r and phi:
/// \< surface_binning nr=\"2\" rmin=\"25\" rmax=\"100\" nphi=\"22\"
/// \<acts_surface_binning nr=\"2\" rmin=\"25\" rmax=\"100\" nphi=\"22\"
/// phimin=\"-3.1415\" phimax=\"3.1415\" \/ \>
/// - Variable binning in z:
/// \< surface_binning zboundaries=\"-100,-90,90,100\" \/ \>
/// \<acts_surface_binning zboundaries=\"-100,-90,90,100\" \/ \>
///
/// And 2D combinations of this are allowed.
///
Expand All @@ -88,6 +109,10 @@ inline void decodeBinning(dd4hep::rec::VariantParameters &variantParams,
// Gather the bin expansion parameter, expansion of 0 is default
int nExpansion =
Acts::getAttrValueOr<int>(xmlBinning, std::string(bv + "expansion"), 0);
// Auto-range detection
bool autoRange = Acts::getAttrValueOr<bool>(
xmlBinning, std::string(bv + "autorange"), false);
variantParams.set<bool>(bname + "_" + bv + "_autorange", autoRange);
variantParams.set<int>(bname + "_" + bv + "_exp", nExpansion);
// Equidistant binning detected
if (nBins > 0) {
Expand All @@ -96,12 +121,14 @@ inline void decodeBinning(dd4hep::rec::VariantParameters &variantParams,
// Set the number of bins
variantParams.set<int>(bname + "_" + bv + "_n", nBins);
// Set min/max paraeter
variantParams.set<double>(
bname + "_" + bv + "_min",
xmlBinning.attr<double>(std::string(bv + "min").c_str()));
variantParams.set<double>(
bname + "_" + bv + "_max",
xmlBinning.attr<double>(std::string(bv + "max").c_str()));
if (!autoRange) {
variantParams.set<double>(
bname + "_" + bv + "_min",
xmlBinning.attr<double>(std::string(bv + "min").c_str()));
variantParams.set<double>(
bname + "_" + bv + "_max",
xmlBinning.attr<double>(std::string(bv + "max").c_str()));
}
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
} else {
// Variable binning detected
variantParams.set<std::string>(bname + "_" + bv + "_type", "variable");
Expand Down
21 changes: 17 additions & 4 deletions Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBlueprint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
#include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
#include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
#include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp"
#include "Acts/Geometry/Extent.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/VolumeBounds.hpp"
#include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp"
#include "Acts/Plugins/DD4hep/DD4hepLayerStructure.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <memory>
#include <optional>
#include <tuple>
#include <vector>

Expand Down Expand Up @@ -52,11 +55,13 @@ class DD4hepBlueprint {
/// @brief Create a blueprint from a DD4hep detector element
///
/// @param cache the cache object for the detector store
/// @param gctx the geometry context
/// @param dd4hepElement the dd4hep detector element tree
///
/// @return a new blueprint top node
std::unique_ptr<Blueprint::Node> create(
Cache& cache, const dd4hep::DetElement& dd4hepElement) const;
Cache& cache, const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement) const;

private:
/// @brief auto-calculate the unit length conversion
Expand All @@ -76,22 +81,28 @@ class DD4hepBlueprint {
///
/// @param cache the cache object
/// @param mother the mother node
/// @param gctx the geometry context
/// @param dd4hepElement the detector element at current level
/// @param hiearchyLevel the current hierarchy level
void recursiveParse(Cache& cache, Blueprint::Node& mother,
const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement,
unsigned int hiearchyLevel = 0) const;

/// @brief Extract the bounds type, values and binning from a DD4hep element
///
/// @param gctx the geometry context
/// @param dd4hepElement the DD4hep element
/// @param baseName the base name of the acts type, e.g. "acts_volume", "acts_container", ...
/// @param extOpt the optional extent as output from the internal parsing
///
/// @return a tuple of the bounds type, values and binning, auxiliary data
std::tuple<Transform3, VolumeBounds::BoundsType, std::vector<ActsScalar>,
std::vector<BinningValue>, std::string>
extractExternals(const dd4hep::DetElement& dd4hepElement,
const std::string& baseName) const;
extractExternals([[maybe_unused]] const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement,
const std::string& baseName,
const std::optional<Extent>& extOpt = std::nullopt) const;

/// @brief Extract the internals from a DD4hep element
///
Expand All @@ -101,6 +112,7 @@ class DD4hepBlueprint {
/// If any of the elements is not found, a nullptr is returned.
///
/// @param dd4hepStore the store for the created dd4hep detector elements
/// @param gctx the geometry context
/// @param dd4hepElement the DD4hep element
/// @param baseName the base name of the acts type, e.g. "acts_volume", "acts_container", ...
///
Expand All @@ -110,8 +122,9 @@ class DD4hepBlueprint {
std::tuple<std::shared_ptr<const IInternalStructureBuilder>,
std::shared_ptr<const IRootVolumeFinderBuilder>,
std::shared_ptr<const IGeometryIdGenerator>,
std::array<std::string, 3u>>
std::array<std::string, 3u>, std::optional<Extent>>
extractInternals(DD4hepDetectorElement::Store& dd4hepStore,
const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement,
const std::string& baseName) const;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@

#pragma once

#include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp"

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/Common.hpp"
#include "Acts/Definitions/Units.hpp"
#include "Acts/Detector/LayerStructureBuilder.hpp"
#include "Acts/Detector/ProtoBinning.hpp"
#include "Acts/Geometry/Extent.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/BinningData.hpp"

#include <tuple>
#include <vector>
Expand Down Expand Up @@ -61,6 +65,14 @@ class DD4hepDetectorSurfaceFactory {
std::vector<Experimental::ProtoBinning> binnings = {};
/// The collected supports
std::vector<Experimental::ProtoSupport> supports = {};
/// Optionally provide an Extent object to measure the sensitives
std::optional<Extent> sExtent = std::nullopt;
/// Optionally provide an Extent object to measure the passive
std::optional<Extent> pExtent = std::nullopt;
/// Optionally provide an Extent constraints to measure the layers
std::vector<BinningValue> extentContraints = {};
/// The approximination for extent measuring
std::size_t nExtentSegments = 1u;
};

/// Nested options struct to steer the conversion
Expand All @@ -87,11 +99,13 @@ class DD4hepDetectorSurfaceFactory {
/// Construction method of the detector elements
///
/// @param cache [in,out] into which the Elements are filled
/// @param gctx the geometry context
/// @param dd4hepElement the detector element representing the super structure
/// @param options to steer the conversion
///
/// @note this method will call the recursive construction
void construct(Cache& cache, const dd4hep::DetElement& dd4hepElement,
void construct(Cache& cache, const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement,
const Options& options);

private:
Expand All @@ -108,30 +122,41 @@ class DD4hepDetectorSurfaceFactory {
/// Construction method of the detector elements - recursive walk down
///
/// @param cache [in,out] into which the Elements are filled
/// @param gctx the geometry context
/// @param dd4hepElement the detector element representing the super structure
/// @param options to steer the conversion
/// @param level the current level of the tree, used for log message output
///
/// @note this method is called recursively
void recursiveConstruct(Cache& cache, const dd4hep::DetElement& dd4hepElement,
void recursiveConstruct(Cache& cache, const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement,
const Options& options, int level);

/// Method to convert a single sensitive detector element
///
/// @param cache [in,out] into which the Elements are filled
/// @param gctx the geometry context
/// @param dd4hepElement the detector element
/// @param options to steer the conversion
///
/// @note the cache is handed through in order to optionally measure the
/// extent of the sensitive surface and register it
///
/// @return a created detector element and surface
DD4hepSensitiveSurface constructSensitiveComponents(
Cache& cache, const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement, const Options& options) const;

/// Method to convert a single sensitive detector element
///
/// @param cache [in,out] into which the Elements are filled
/// @param gctx the geometry context
/// @param dd4hepElement the detector element
/// @param options to steer the conversion
///
/// @return a created surface
DD4hepPassiveSurface constructPassiveComponents(
Cache& cache, const GeometryContext& gctx,
const dd4hep::DetElement& dd4hepElement, const Options& options) const;

/// Attach surface material if present
Expand All @@ -141,6 +166,9 @@ class DD4hepDetectorSurfaceFactory {
/// @param thickness the thickness of the condensed component
/// @param options to steer the conversion
///
/// @note the cache is handed through in order to optionally measure the
/// extent of the sensitive surface and register it
///
/// @note void function that also checks the options if the attachment should be applied
void attachSurfaceMaterial(const dd4hep::DetElement& dd4hepElement,
Acts::Surface& surface, ActsScalar thickness,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
#include "Acts/Definitions/Units.hpp"
#include "Acts/Detector/LayerStructureBuilder.hpp"
#include "Acts/Detector/ProtoBinning.hpp"
#include "Acts/Geometry/Extent.hpp"
#include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp"
#include "Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp"
#include "Acts/Utilities/BinningData.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <memory>
#include <optional>
#include <string>
#include <tuple>

namespace dd4hep {
class DetElement;
Expand Down Expand Up @@ -59,8 +63,14 @@ class DD4hepLayerStructure {
std::string name = "";
/// An out put log level
Logging::Level logLevel = Logging::INFO;
// The extent structure - optionally
std::optional<Extent> extent = std::nullopt;
/// The extent constraints - optionally
std::vector<BinningValue> extentContraints = {};
/// Approximation for the polyhedron binning nSegments
unsigned int nSegments = 1u;
/// Patch the binning with the extent if possible
bool patchBinningWithExtent = true;
/// Conversion options
DD4hepDetectorSurfaceFactory::Options conversionOptions;
};
Expand All @@ -72,13 +82,15 @@ class DD4hepLayerStructure {
/// It takes the detector element from DD4hep and some optional parameters
///
/// @param dd4hepStore [in, out] the detector store for the built elements
/// @param gcxt the geometry context
/// @param dd4hepElement the dd4hep detector element
/// @param options containing the optional descriptions
///
/// @return a LayerStructureBuilder
std::shared_ptr<LayerStructureBuilder> builder(
DD4hepDetectorElement::Store& dd4hepStore,
const dd4hep::DetElement& dd4hepElement, const Options& options) const;
/// @return a LayerStructureBuilder, and an optional extent
std::tuple<std::shared_ptr<LayerStructureBuilder>, std::optional<Extent>>
builder(DD4hepDetectorElement::Store& dd4hepStore,
const GeometryContext& gctx, const dd4hep::DetElement& dd4hepElement,
const Options& options) const;

private:
/// The workorse: the surface factory
Expand Down
4 changes: 2 additions & 2 deletions Plugins/DD4hep/src/ConvertDD4hepDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ std::unique_ptr<const TrackingGeometry> convertDD4hepDetector(
auto volBuilder = volumeBuilder_dd4hep(
subDetector, logger, bTypePhi, bTypeR, bTypeZ, layerEnvelopeR,
layerEnvelopeZ, defaultLayerThickness);
if (volBuilder) {
if (volBuilder != nullptr) {
// distinguish beam pipe
if (volBuilder->getConfiguration().buildToRadiusZero) {
// check if beam pipe is already present
Expand All @@ -122,7 +122,7 @@ std::unique_ptr<const TrackingGeometry> convertDD4hepDetector(
}
}
// Finally add the beam pipe
if (beamPipeVolumeBuilder) {
if (beamPipeVolumeBuilder != nullptr) {
volumeBuilders.push_back(beamPipeVolumeBuilder);
}

Expand Down
Loading