Skip to content

Commit

Permalink
Merge branch 'main' into refactor-ckf-combine-filter-material-and-mea…
Browse files Browse the repository at this point in the history
…surement-and-hole
  • Loading branch information
kodiakhq[bot] authored Oct 14, 2024
2 parents e6dfbde + a108ee9 commit b433310
Show file tree
Hide file tree
Showing 26 changed files with 1,083 additions and 264 deletions.
35 changes: 25 additions & 10 deletions Core/include/Acts/Geometry/CompositePortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

namespace Acts {

class GridPortalLink;
class Surface;

/// Composite portal links can graft together other portal link instances, for
/// example grids that could not be merged due to invalid binnings.
///
Expand Down Expand Up @@ -49,6 +52,15 @@ class CompositePortalLink final : public PortalLinkBase {
std::unique_ptr<PortalLinkBase> b, BinningValue direction,
bool flatten = true);

/// Construct a composite portal from any number of arbitrary other portal
/// links. The only requirement is that the portal link surfaces are
/// mergeable.
/// @param links The portal links
/// @param direction The binning direction
/// @param flatten If true, the composite will flatten any nested composite
CompositePortalLink(std::vector<std::unique_ptr<PortalLinkBase>> links,
BinningValue direction, bool flatten = true);

/// Print the composite portal link
/// @param os The output stream
void toStream(std::ostream& os) const override;
Expand Down Expand Up @@ -81,19 +93,22 @@ class CompositePortalLink final : public PortalLinkBase {
/// @return The number of children
std::size_t size() const;

private:
/// Helper function to construct a merged surface from two portal links along
/// a given direction
/// @param a The first portal link
/// @param b The second portal link
/// @param direction The merging direction
/// @return The merged surface
static std::shared_ptr<RegularSurface> mergedSurface(const PortalLinkBase* a,
const PortalLinkBase* b,
BinningValue direction);
/// (Potentially) create a grid portal link that represents this composite
/// portal link.
/// @note This only works, if the composite is **flat** and only contains
/// **trivial portal links**. If these preconditions are not met, this
/// function returns a nullptr.
/// @param gctx The geometry context
/// @param logger The logger
/// @return The grid portal link
std::unique_ptr<GridPortalLink> makeGrid(const GeometryContext& gctx,
const Logger& logger) const;

private:
boost::container::small_vector<std::unique_ptr<PortalLinkBase>, 4>
m_children{};

BinningValue m_direction;
};

} // namespace Acts
13 changes: 13 additions & 0 deletions Core/include/Acts/Geometry/CylinderVolumeBounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/BoundarySurfaceFace.hpp"
#include "Acts/Geometry/Volume.hpp"
#include "Acts/Geometry/VolumeBounds.hpp"
#include "Acts/Utilities/BinningType.hpp"
Expand Down Expand Up @@ -80,6 +81,18 @@ class CylinderVolumeBounds : public VolumeBounds {
eSize
};

/// Enum describing the possible faces of a cylinder volume
/// @note These values are synchronized with the BoundarySurfaceFace enum.
/// Once Gen1 is removed, this can be changed.
enum class Face : unsigned int {
PositiveDisc = BoundarySurfaceFace::positiveFaceXY,
NegativeDisc = BoundarySurfaceFace::negativeFaceXY,
OuterCylinder = BoundarySurfaceFace::tubeOuterCover,
InnerCylinder = BoundarySurfaceFace::tubeInnerCover,
NegativePhiPlane = BoundarySurfaceFace::tubeSectorNegativePhi,
PositivePhiPlane = BoundarySurfaceFace::tubeSectorPositivePhi
};

CylinderVolumeBounds() = delete;

/// Constructor
Expand Down
11 changes: 5 additions & 6 deletions Core/include/Acts/Geometry/GridPortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,12 @@ class GridPortalLink : public PortalLinkBase {
/// Helper function to get grid bin content in type-eraased way.
/// @param indices The bin indices
/// @return The tracking volume at the bin
virtual TrackingVolume*& atLocalBins(IndexType indices) = 0;
virtual const TrackingVolume*& atLocalBins(IndexType indices) = 0;

/// Helper function to get grid bin content in type-eraased way.
/// @param indices The bin indices
/// @return The tracking volume at the bin
virtual TrackingVolume* atLocalBins(IndexType indices) const = 0;
virtual const TrackingVolume* atLocalBins(IndexType indices) const = 0;

private:
BinningValue m_direction;
Expand All @@ -399,7 +399,7 @@ template <typename... Axes>
class GridPortalLinkT final : public GridPortalLink {
public:
/// The internal grid type
using GridType = Grid<TrackingVolume*, Axes...>;
using GridType = Grid<const TrackingVolume*, Axes...>;

/// The dimension of the grid
static constexpr std::size_t DIM = sizeof...(Axes);
Expand Down Expand Up @@ -530,7 +530,6 @@ class GridPortalLinkT final : public GridPortalLink {
return m_grid.atPosition(m_projection(position));
}

protected:
/// Type erased access to the number of bins
/// @return The number of bins in each direction
IndexType numLocalBins() const override {
Expand All @@ -545,7 +544,7 @@ class GridPortalLinkT final : public GridPortalLink {
/// Type erased local bin access
/// @param indices The bin indices
/// @return The tracking volume at the bin
TrackingVolume*& atLocalBins(IndexType indices) override {
const TrackingVolume*& atLocalBins(IndexType indices) override {
throw_assert(indices.size() == DIM, "Invalid number of indices");
typename GridType::index_t idx;
for (std::size_t i = 0; i < DIM; i++) {
Expand All @@ -557,7 +556,7 @@ class GridPortalLinkT final : public GridPortalLink {
/// Type erased local bin access
/// @param indices The bin indices
/// @return The tracking volume at the bin
TrackingVolume* atLocalBins(IndexType indices) const override {
const TrackingVolume* atLocalBins(IndexType indices) const override {
throw_assert(indices.size() == DIM, "Invalid number of indices");
typename GridType::index_t idx;
for (std::size_t i = 0; i < DIM; i++) {
Expand Down
18 changes: 4 additions & 14 deletions Core/include/Acts/Geometry/PortalShell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#pragma once

#include "Acts/Geometry/BoundarySurfaceFace.hpp"
#include "Acts/Geometry/CylinderVolumeBounds.hpp"
#include "Acts/Utilities/BinningType.hpp"
#include "Acts/Utilities/Logger.hpp"

Expand Down Expand Up @@ -68,19 +68,9 @@ class PortalShellBase {
/// volumes
class CylinderPortalShell : public PortalShellBase {
public:
/// Enum describing the possible faces of a cylinder portal shell
/// @note These values are synchronized with the BoundarySurfaceFace enum.
/// Once Gen1 is removed, this can be changed.
enum class Face : unsigned int {
PositiveDisc = BoundarySurfaceFace::positiveFaceXY,
NegativeDisc = BoundarySurfaceFace::negativeFaceXY,
OuterCylinder = BoundarySurfaceFace::tubeOuterCover,
InnerCylinder = BoundarySurfaceFace::tubeInnerCover,
NegativePhiPlane = BoundarySurfaceFace::tubeSectorNegativePhi,
PositivePhiPlane = BoundarySurfaceFace::tubeSectorPositivePhi
};

using enum Face;
using Face = CylinderVolumeBounds::Face;

using enum CylinderVolumeBounds::Face;

/// Retrieve the portal associated to the given face. Can be nullptr if unset.
/// @param face The face to retrieve the portal for
Expand Down
4 changes: 4 additions & 0 deletions Core/include/Acts/Geometry/TrivialPortalLink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class TrivialPortalLink final : public PortalLinkBase {
const GeometryContext& gctx, const Vector3& position,
double tolerance = s_onSurfaceTolerance) const override;

/// Get the single volume that this trivial portal link is associated with
/// @return The target volume
const TrackingVolume& volume() const;

private:
TrackingVolume* m_volume;
};
Expand Down
10 changes: 10 additions & 0 deletions Core/include/Acts/Seeding/SeedFinder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ class SeedFinder {
const Acts::Range1D<float>& rMiddleSPRange) const;

private:
/// Given a middle space point candidate, get the proper radius validity range
/// In case the radius range changes according to the z-bin we need to
/// retrieve the proper range. We can do this computation only once, since
/// all the middle space point candidates belong to the same z-bin
/// @param spM space point candidate to be used as middle SP in a seed
/// @param rMiddleSPRange range object containing the minimum and maximum r for middle SP for a certain z bin.
std::pair<float, float> retrieveRadiusRangeForMiddle(
const external_spacepoint_t& spM,
const Acts::Range1D<float>& rMiddleSPRange) const;

/// Iterates over dublets and tests the compatibility between them by applying
/// a series of cuts that can be tested with only two SPs
/// @param options frequently changing configuration (like beam position)
Expand Down
61 changes: 31 additions & 30 deletions Core/include/Acts/Seeding/SeedFinder.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -104,40 +104,20 @@ void SeedFinder<external_spacepoint_t, grid_t, platform_t>::createSeedsForGroup(
return;
}

// we compute this here since all middle space point candidates belong to the
// same z-bin
auto [minRadiusRangeForMiddle, maxRadiusRangeForMiddle] =
retrieveRadiusRangeForMiddle(*middleSPs.front(), rMiddleSPRange);
for (const external_spacepoint_t* spM : middleSPs) {
const float rM = spM->radius();

// check if spM is outside our radial region of interest
if (m_config.useVariableMiddleSPRange) {
if (rM < rMiddleSPRange.min()) {
continue;
}
if (rM > rMiddleSPRange.max()) {
// break because SPs are sorted in r
break;
}
} else if (!m_config.rRangeMiddleSP.empty()) {
/// get zBin position of the middle SP
auto pVal = std::lower_bound(m_config.zBinEdges.begin(),
m_config.zBinEdges.end(), spM->z());
int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
/// protects against zM at the limit of zBinEdges
zBin == 0 ? zBin : --zBin;
if (rM < m_config.rRangeMiddleSP[zBin][0]) {
continue;
}
if (rM > m_config.rRangeMiddleSP[zBin][1]) {
// break because SPs are sorted in r
break;
}
} else {
if (rM < m_config.rMinMiddle) {
continue;
}
if (rM > m_config.rMaxMiddle) {
// break because SPs are sorted in r
break;
}
if (rM < minRadiusRangeForMiddle) {
continue;
}
if (rM > maxRadiusRangeForMiddle) {
// break because SPs are sorted in r
break;
}

const float zM = spM->z();
Expand Down Expand Up @@ -827,4 +807,25 @@ SeedFinder<external_spacepoint_t, grid_t, platform_t>::filterCandidates(
} // loop on bottoms
}

template <typename external_spacepoint_t, typename grid_t, typename platform_t>
std::pair<float, float> SeedFinder<external_spacepoint_t, grid_t, platform_t>::
retrieveRadiusRangeForMiddle(
const external_spacepoint_t& spM,
const Acts::Range1D<float>& rMiddleSPRange) const {
if (m_config.useVariableMiddleSPRange) {
return std::make_pair(rMiddleSPRange.min(), rMiddleSPRange.max());
}
if (!m_config.rRangeMiddleSP.empty()) {
/// get zBin position of the middle SP
auto pVal = std::lower_bound(m_config.zBinEdges.begin(),
m_config.zBinEdges.end(), spM.z());
int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
/// protects against zM at the limit of zBinEdges
zBin == 0 ? zBin : --zBin;
return std::make_pair(m_config.rRangeMiddleSP[zBin][0],
m_config.rRangeMiddleSP[zBin][1]);
}
return std::make_pair(m_config.rMinMiddle, m_config.rMaxMiddle);
}

} // namespace Acts
41 changes: 24 additions & 17 deletions Core/src/Detector/detail/BlueprintDrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,58 +57,65 @@ std::string labelStr(
void Acts::Experimental::detail::BlueprintDrawer::dotStream(
std::ostream& ss, const Acts::Experimental::Blueprint::Node& node,
const Options& options) {
// Replace the "/" in node names
std::string nodeName = node.name;
std::replace(nodeName.begin(), nodeName.end(), '/', '_');

// Root / leaf or branch
if (node.isRoot()) {
ss << "digraph " << options.graphName << " {" << '\n';
ss << node.name << " " << labelStr(options.root, node.name, node.auxiliary)
ss << nodeName << " " << labelStr(options.root, nodeName, node.auxiliary)
<< '\n';
ss << node.name << " " << shapeStr(options.root) << '\n';
ss << nodeName << " " << shapeStr(options.root) << '\n';

} else if (node.isLeaf()) {
ss << node.name << " " << labelStr(options.leaf, node.name, node.auxiliary)
ss << nodeName << " " << labelStr(options.leaf, nodeName, node.auxiliary)
<< '\n';
ss << node.name << " "
ss << nodeName << " "
<< ((node.internalsBuilder != nullptr) ? shapeStr(options.leaf)
: shapeStr(options.gap))
<< '\n';
} else {
ss << node.name << " "
<< labelStr(options.branch, node.name, node.auxiliary) << '\n';
ss << node.name << " " << shapeStr(options.branch) << '\n';
ss << nodeName << " " << labelStr(options.branch, nodeName, node.auxiliary)
<< '\n';
ss << nodeName << " " << shapeStr(options.branch) << '\n';
}
// Recursive for children
for (const auto& c : node.children) {
ss << node.name << " -> " << c->name << ";" << '\n';
// Replace the "/" in node names
std::string childName = c->name;
std::replace(childName.begin(), childName.end(), '/', '_');
ss << nodeName << " -> " << childName << ";" << '\n';
dotStream(ss, *c, options);
}

// Shape
Options::Node shape = node.isLeaf() ? options.shape : options.virtualShape;
std::stringstream bts;
bts << node.boundsType;
ss << node.name + "_shape " << shapeStr(shape) << '\n';
ss << node.name + "_shape "
ss << nodeName + "_shape " << shapeStr(shape) << '\n';
ss << nodeName + "_shape "
<< labelStr(shape, bts.str(),
{"t = " + toString(node.transform.translation(), 1),
"b = " + toString(node.boundaryValues, 1)})
<< '\n';
ss << node.name << " -> " << node.name + "_shape [ arrowhead = \"none\" ];"
ss << nodeName << " -> " << nodeName + "_shape [ arrowhead = \"none\" ];"
<< '\n';

// Sub node detection
if (node.internalsBuilder != nullptr) {
ss << node.name + "_int " << shapeStr(options.internals) << '\n';
ss << node.name << " -> " << node.name + "_int;" << '\n';
ss << nodeName + "_int " << shapeStr(options.internals) << '\n';
ss << nodeName << " -> " << nodeName + "_int;" << '\n';
}

if (node.geoIdGenerator != nullptr) {
ss << node.name + "_geoID " << shapeStr(options.geoID) << '\n';
ss << node.name << " -> " << node.name + "_geoID;" << '\n';
ss << nodeName + "_geoID " << shapeStr(options.geoID) << '\n';
ss << nodeName << " -> " << nodeName + "_geoID;" << '\n';
}

if (node.rootVolumeFinderBuilder != nullptr) {
ss << node.name + "_roots " << shapeStr(options.roots) << '\n';
ss << node.name << " -> " << node.name + "_roots;" << '\n';
ss << nodeName + "_roots " << shapeStr(options.roots) << '\n';
ss << nodeName << " -> " << nodeName + "_roots;" << '\n';
}

if (node.isRoot()) {
Expand Down
Loading

0 comments on commit b433310

Please sign in to comment.