Skip to content

Commit

Permalink
feat: Multiwire builder (#2275)
Browse files Browse the repository at this point in the history
This PR introduces the builder for a Multi Layer Wire Structure using an internal and external builder. It also introduces a multilayer updator for grid-based indexed surfaces that is used inside the inner builder and a unit test that checks the surface candidates collected along a projected path as shown in the attached pictures.
![GridXYMultiWire](https://github.com/acts-project/acts/assets/63058524/bf724080-7c00-4cf5-8957-0257b80aeda1)

![grid](https://github.com/acts-project/acts/assets/63058524/57c35292-e75f-40b5-8e1a-cf32649e1f3d)
  • Loading branch information
dimitra97 authored Sep 12, 2023
1 parent 8f07d6c commit 3214740
Show file tree
Hide file tree
Showing 10 changed files with 584 additions and 7 deletions.
76 changes: 76 additions & 0 deletions Core/include/Acts/Detector/MultiWireStructureBuilder.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// This file is part of the Acts project.
//
// Copyright (C) 2022-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Detector/LayerStructureBuilder.hpp"
#include "Acts/Detector/ProtoBinning.hpp"
#include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
#include "Acts/Detector/interface/IExternalStructureBuilder.hpp"
#include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <iostream>
#include <string>
#include <vector>

namespace Acts {
namespace Experimental {

class MultiWireStructureBuilder {
public:
/// @brief Configuration struct for the MultiWireStructure Builder

struct Config {
/// The name of the detector volume component
std::string name = "";

/// The surfaces of the Multi Wire
std::vector<std::shared_ptr<Acts::Surface>> mlSurfaces = {};

/// The bounds of the multi-wire volume
std::vector<ActsScalar> mlBounds = {};

// The binning of the multi wire structure
std::vector<ProtoBinning> mlBinning = {};

/// A tolerance config
float toleranceOverlap = 10.;
};

/// Constructor
/// @param config The configure of the MultiWireStructureBuilder
/// @param logger logging instance for screen output

MultiWireStructureBuilder(
const Config& config,
std::unique_ptr<const Acts::Logger> logger = Acts::getDefaultLogger(
"MultiWireStructureBuilder", Acts::Logging::VERBOSE));

~MultiWireStructureBuilder() = default;

/// Construct the detector component

/// @param gctx The Geometry Context of the current geometry
/// @return a detector component object with the detector volume of the multilayer

Acts::Experimental::DetectorComponent construct(
const Acts::GeometryContext& gctx);

private:
Config mCfg;

const Acts::Logger& logger() const { return *mLogger; }

std::unique_ptr<const Acts::Logger> mLogger;
};

} // namespace Experimental
} // namespace Acts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,8 @@ struct IndexedSurfacesGenerator {
bvArray[ibv] = bv;
}

// The indexed surfaces delegate
// IndexedSurfacesImpl<GridType> indexedSurfaces(std::move(grid), bvArray,
// transform);
indexed_updator<GridType> indexedSurfaces(std::move(grid), bvArray,
transform);

// Fill the bin indices
IndexedGridFiller filler{binExpansion};
filler.oLogger = oLogger->cloneWithSuffix("_filler");
Expand Down
143 changes: 143 additions & 0 deletions Core/include/Acts/Navigation/MultiLayerSurfacesUpdator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// This file is part of the Acts project.
//
// Copyright (C) 2022 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Detector/DetectorVolume.hpp"
#include "Acts/Navigation/NavigationDelegates.hpp"
#include "Acts/Navigation/NavigationStateFillers.hpp"
#include "Acts/Navigation/NavigationStateUpdators.hpp"
#include "Acts/Utilities/VectorHelpers.hpp"

#include <array>
#include <memory>

namespace Acts {
namespace Experimental {

template <typename grid_t, typename path_generator>
class MultiLayerSurfacesUpdatorImpl : public INavigationDelegate {
public:
/// Broadcast the grid type
using grid_type = grid_t;

/// The grid where the indices are stored
grid_type grid;

/// These are the cast parameters - copied from constructor
std::array<BinningValue, grid_type::DIM> casts{};

/// A transform to be applied to the position
Transform3 transform = Transform3::Identity();

/// The path generator
path_generator pgenerator;

/// @brief Constructor for a grid based surface attacher
///@param igrid the grid that is moved into this attacher
/// @param icasts is the cast values array
/// @param itr a transform applied to the global position
MultiLayerSurfacesUpdatorImpl(
grid_type&& igrid, const std::array<BinningValue, grid_type::DIM>& icasts,
const Transform3& itr = Transform3::Identity())
: grid(std::move(igrid)), casts(icasts), transform(itr) {}

MultiLayerSurfacesUpdatorImpl() = delete;

void update(const GeometryContext& gctx, NavigationState& nState) const {
auto step = std::sqrt(std::pow(grid.binWidth()[0], 2) +
std::pow(grid.binWidth()[1], 2));
auto path = pgenerator(nState.position, nState.direction, step,
grid.numLocalBins()[1]);

std::vector<const Acts::Surface*> surfCandidates = {};

for (const auto& p : path) {
const auto& entry = grid.atPosition(castPosition(p));
const auto extracted =
IndexedSurfacesExtractor::extract(gctx, nState, entry);
surfCandidates.insert(surfCandidates.end(), extracted.begin(),
extracted.end());
}

resolveDuplicates(gctx, surfCandidates);
SurfacesFiller::fill(nState, surfCandidates);
}

/// Cast into a lookup position
///
/// @param position is the position of the update call
std::array<ActsScalar, grid_type::DIM> castPosition(
const Vector3& position) const {
// Transform into local 3D frame
Vector3 tposition = transform * position;

std::array<ActsScalar, grid_type::DIM> casted{};
fillCasts(tposition, casted,
std::make_integer_sequence<std::size_t, grid_type::DIM>{});
return casted;
}

/// Resolve duplicate on surface candidates
///
/// @param gctx The geometry context of the current geometry
/// @param surfaces is the surface candidates to check and resolve for duplicates
void resolveDuplicates(const GeometryContext& gctx,
std::vector<const Acts::Surface*>& surfaces) const {
// sorting the surfaces according to their radial distance
std::sort(surfaces.begin(), surfaces.end(),
[&gctx](const auto& surf1, const auto& surf2) {
if (surf1->center(gctx).x() != surf2->center(gctx).x()) {
return surf1->center(gctx).x() < surf2->center(gctx).x();
}
if (surf1->center(gctx).y() != surf2->center(gctx).y()) {
return surf1->center(gctx).y() < surf2->center(gctx).y();
}
return surf1->center(gctx).z() < surf2->center(gctx).z();
});

// Remove the duplicates
surfaces.erase(std::unique(surfaces.begin(), surfaces.end()),
surfaces.end());
}

private:
/// Unroll the cast loop
/// @param position is the position of the update call
/// @param a is the array to be filled
template <typename Array, std::size_t... idx>
void fillCasts(const Vector3& position, Array& a,
std::index_sequence<idx...> /*indices*/) const {
((a[idx] = VectorHelpers::cast(position, casts[idx])), ...);
}
};

struct PathGridSurfacesGenerator {
std::vector<Vector3> operator()(Vector3 startPosition,
const Vector3& direction, ActsScalar stepSize,
std::size_t numberOfSteps) const {
std::vector<Vector3> pathCoordinates = {};
pathCoordinates.reserve(numberOfSteps);

auto tposition = std::move(startPosition);
auto stepSizeY = stepSize * sin(Acts::VectorHelpers::phi(direction));
auto stepSizeX = stepSize * cos(Acts::VectorHelpers::phi(direction));

for (std::size_t i = 0; i < numberOfSteps; i++) {
pathCoordinates.push_back(tposition);
tposition.y() = tposition.y() + stepSizeY;
tposition.x() = tposition.x() + stepSizeX;
}

return pathCoordinates;
}
};

} // namespace Experimental

} // namespace Acts
13 changes: 10 additions & 3 deletions Core/include/Acts/Navigation/SurfaceCandidatesUpdators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Acts/Detector/DetectorVolume.hpp"
#include "Acts/Detector/Portal.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Navigation/MultiLayerSurfacesUpdator.hpp"
#include "Acts/Navigation/NavigationState.hpp"
#include "Acts/Navigation/NavigationStateFillers.hpp"
#include "Acts/Navigation/NavigationStateUpdators.hpp"
Expand Down Expand Up @@ -45,9 +46,8 @@ inline static void updateCandidates(const GeometryContext& gctx,
(c.surface != nullptr) ? (*c.surface) : (c.portal->surface());

// Get the intersection @todo make a templated intersector
// TODO surface tolerance
auto sIntersection = sRep.intersect(gctx, position, direction,
c.boundaryCheck, s_onSurfaceTolerance);
auto sIntersection =
sRep.intersect(gctx, position, direction, c.boundaryCheck);
// Re-order and swap if necessary
if (sIntersection.intersection.pathLength + s_onSurfaceTolerance <
nState.overstepTolerance and
Expand Down Expand Up @@ -192,6 +192,13 @@ template <typename grid_type>
using IndexedSurfacesImpl =
IndexedUpdatorImpl<grid_type, IndexedSurfacesExtractor, SurfacesFiller>;

/// @brief An indexed multi layer surface implementation access
///
/// @tparam grid_type is the grid type used for this indexed lookup
template <typename grid_type>
using MultiLayerSurfacesImpl =
MultiLayerSurfacesUpdatorImpl<grid_type, PathGridSurfacesGenerator>;

/// @brief An indexed surface implementation with portal access
///
///@tparam inexed_updator is the updator for the indexed surfaces
Expand Down
3 changes: 3 additions & 0 deletions Core/src/Detector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ target_sources(
PortalGenerators.cpp
ProtoDetector.cpp
VolumeStructureBuilder.cpp
MultiWireStructureBuilder.cpp


)
Loading

0 comments on commit 3214740

Please sign in to comment.