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: geant4 gdml detector - ODD light part 1 #2424

Merged
merged 13 commits into from
Sep 12, 2023
57 changes: 36 additions & 21 deletions Core/include/Acts/Detector/KdtSurfacesProvider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ namespace Experimental {
/// KDTree lookup positions
///
template <size_t kDIM = 2u, size_t bSize = 100u,
typename reference_generator = detail::PolyhedronReferenceGenerator>
typename reference_generator =
detail::PolyhedronReferenceGenerator<1u, false>>
class KdtSurfaces {
public:
/// Broadcast the surface KDT type
Expand All @@ -49,11 +50,11 @@ class KdtSurfaces {
/// @param surfaces the surfaces to be filled into the tree
/// @param casts the cast list from global position into kdtree local
/// @param rgen the reference point generator
KdtSurfaces(
const GeometryContext& gctx,
const std::vector<std::shared_ptr<Surface>>& surfaces,
const std::array<BinningValue, kDIM>& casts,
const reference_generator& rgen = detail::PolyhedronReferenceGenerator{})
KdtSurfaces(const GeometryContext& gctx,
const std::vector<std::shared_ptr<Surface>>& surfaces,
const std::array<BinningValue, kDIM>& casts,
const reference_generator& rgen =
detail::PolyhedronReferenceGenerator<1u, false>{})
: m_kdt(nullptr), m_casts(casts), m_rGenerator(rgen) {
// Simple check if the dimension is correct
if (kDIM == 0u) {
Expand All @@ -66,11 +67,16 @@ class KdtSurfaces {
for (auto& s : surfaces) {
// Generate the references and the center of gravity from it
const auto references = m_rGenerator.references(gctx, *s);
const auto ref = cog(references);
// Now cast into the correct fill position
std::array<ActsScalar, kDIM> fill = {};
fillCasts(ref, fill, std::make_integer_sequence<std::size_t, kDIM>{});
kdtEntries.push_back({fill, s});
std::vector<Query> castedReferences;
castedReferences.reserve(references.size());
for (const auto& r : references) {
// Now cast into the correct fill position
Query rc = {};
fillCasts(r, rc, std::make_integer_sequence<std::size_t, kDIM>{});
castedReferences.push_back(rc);
}
// Calculate the center of gravity in casted frame
kdtEntries.push_back({cog(castedReferences), s});
}
// Create the KDTree
m_kdt = std::make_unique<KDTS>(std::move(kdtEntries));
Expand Down Expand Up @@ -123,22 +129,30 @@ class KdtSurfaces {
((a[idx] = VectorHelpers::cast(position, m_casts[idx])), ...);
}

/// Helper method to calculate the center of gravity
/// Helper method to calculate the center of gravity in the
/// casted frame (i.e. query frame)
///
/// @param positions are the reference positions that go in
/// @param cQueries are the casted query positions
/// @note will do nothing if vector size is equal to 1
///
/// @note no checking on positions.empty() is done as the
/// @note no checking on qQueries.empty() is done as the
/// positions are to be provided by a generator which itself
/// is tested for consistency
///
/// @return the center of gravity
Vector3 cog(const std::vector<Vector3>& positions) const {
/// @return the center of gravity as a query object
Query cog(const std::vector<Query>& cQueries) const {
// If there is only one position, return it
if (cQueries.size() == 1) {
return cQueries.front();
}
// Build the center of gravity of the n positions
Vector3 c(0., 0., 0.);
ActsScalar weight = 1. / positions.size();
std::for_each(positions.begin(), positions.end(),
[&](const auto& p) { c += weight * p; });
Query c{};
float weight = 1. / cQueries.size();
for (auto& q : cQueries) {
std::transform(c.begin(), c.end(), q.begin(), c.begin(),
std::plus<ActsScalar>());
}
std::for_each(c.begin(), c.end(), [&](auto& v) { v *= weight; });
return c;
}
};
Expand All @@ -148,7 +162,8 @@ class KdtSurfaces {
/// This allows to create small region based callable structs at
/// configuration level that are then connected to an InternalStructureBuilder
template <size_t kDIM = 2u, size_t bSize = 100u,
typename reference_generator = detail::PolyhedronReferenceGenerator>
typename reference_generator =
detail::PolyhedronReferenceGenerator<1u, false>>
class KdtSurfacesProvider : public ISurfacesProvider {
public:
/// The prefilled surfaces in a KD tree structure, it is generally shared
Expand Down
23 changes: 11 additions & 12 deletions Core/include/Acts/Detector/detail/ReferenceGenerators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ struct CenterReferenceGenerator {

/// A struct to access reference positions based on bin values
///
/// @tparam bVAL the binning value to be used for the binning position call
///
/// This generator will provide only one filling point and hence
/// only a single bin in the indexed grid.
template <BinningValue bVAL = BinningValue::binValues>
struct BinningValueReferenceGenerator {
/// The binning value
BinningValue bValue = BinningValue::binValues;

/// Helper to access a reference position based on binning value
///
/// @param gctx the geometry context of this operation
Expand All @@ -53,23 +53,22 @@ struct BinningValueReferenceGenerator {
/// @return a vector of reference points for filling
const std::vector<Vector3> references(const GeometryContext& gctx,
const Surface& surface) const {
return {surface.binningPosition(gctx, bValue)};
return {surface.binningPosition(gctx, bVAL)};
}
};

/// A struct to access generated vertices from surface polyhedrons
/// These vertices are then used to find the bin boundary box for the
/// indexed grid.
///
/// @tparam nSEGS the number of segments to be used for the polyhedron
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
/// approximation of arcs between vertices
/// @tparam aBARY if true, the barycenter of the polyhedron is added
///
/// The grid filling then completes the empty bins in between and
/// expands if necessary.
template <size_t nSEGS = 1u, bool aBARY = true>
struct PolyhedronReferenceGenerator {
/// Also use the barycenter
bool addBarycenter = true;

/// The number of segments to approximate (1 means extrema points only)
unsigned int nSegments = 1;

/// Helper to access the Center point of for filling the grid
///
/// @param gctx the geometry context of this operation
Expand All @@ -80,11 +79,11 @@ struct PolyhedronReferenceGenerator {
const Surface& surface) const {
// Create the return vector
std::vector<Vector3> rPositions;
auto pHedron = surface.polyhedronRepresentation(gctx, nSegments);
auto pHedron = surface.polyhedronRepresentation(gctx, nSEGS);
rPositions.insert(rPositions.end(), pHedron.vertices.begin(),
pHedron.vertices.end());
// Add the barycenter if configured
if (addBarycenter) {
if constexpr (aBARY) {
Vector3 bc(0., 0., 0.);
std::for_each(rPositions.begin(), rPositions.end(),
[&](const auto& p) { bc += p; });
Expand Down
Loading
Loading