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: Multiwire builder #2275

Merged
merged 20 commits into from
Sep 12, 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
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
Loading