Skip to content

Commit

Permalink
refactor: SP builder uses SourceLinks instead of Measurements (#1953)
Browse files Browse the repository at this point in the history
This PR changes the SP builder input from Measurements to SourceLink so that users can avoid unnecessary measurement creation.
Some SP builder parameters are moved from the config to the option to allow event/module-dependent parameters.
  • Loading branch information
toyamaza authored Mar 22, 2023
1 parent cf036b6 commit 56aff8b
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 273 deletions.
32 changes: 14 additions & 18 deletions Core/include/Acts/SpacePointFormation/SpacePointBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "Acts/Digitization/CartesianSegmentation.hpp"
#include "Acts/Digitization/DigitizationModule.hpp"
#include "Acts/Digitization/Segmentation.hpp"
#include "Acts/EventData/Measurement.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/TrackingGeometry.hpp"
#include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
Expand All @@ -29,12 +28,11 @@ namespace Acts {
///
/// After the particle interaction with surfaces are recorded and digitized
/// measurements on the pixel or strip detectors need further treatment. This
/// class takes the measurements and provides the corresponding space points.
/// class takes the SouceLinks and provides the corresponding space points.
///
template <typename spacepoint_t>
class SpacePointBuilder {
public:
using Measurement = Acts::BoundVariantMeasurement;
// Constructor
/// @param cfg The configuration for the space point builder
/// @param func The function that provides user's SP constructor with global pos, global cov, and sourceLinks.
Expand All @@ -50,33 +48,32 @@ class SpacePointBuilder {
// Default constructor
SpacePointBuilder() = default;

/// @brief Calculates the space points out of a given collection of measurements
/// @brief Calculates the space points out of a given collection of SourceLinks
/// and stores the results
///
/// @param gctx The current geometry context object, e.g. alignment
/// @param measurements vector of measurements
/// @param sourceLinks vector of Sourcelink
/// @param opt option for the space point bulding. It contains the ends of the strips for strip SP building
/// @param spacePointIt Output iterator for the space point
template <template <typename...> typename container_t>
void buildSpacePoint(
const GeometryContext& gctx,
const std::vector<const Measurement*>& measurements,
const GeometryContext& gctx, const std::vector<SourceLink>& sourceLinks,
const SpacePointBuilderOptions& opt,
std::back_insert_iterator<container_t<spacepoint_t>> spacePointIt) const;

/// @brief Searches possible combinations of two measurements on different
/// @brief Searches possible combinations of two SourceLinks on different
/// surfaces that may come from the same particles
///
/// @param gctx The current geometry context object, e.g. alignment
/// @param measurementsFront vector of measurements on a surface
/// @param measurementsBack vector of measurements on another surface
/// @param measurementPairs storage of the measurement pairs
void makeMeasurementPairs(
const GeometryContext& gctx,
const std::vector<const Measurement*>& measurementsFront,
const std::vector<const Measurement*>& measurementsBack,
std::vector<std::pair<const Measurement*, const Measurement*>>&
measurementPairs) const;
/// @param slinksFront vector of Sourcelinks on a surface
/// @param slinksBack vector of SoruceLinks on another surface
/// @param slinkPairs storage of the SouceLink pairs
/// @param pairOpt pair maker option with paramCovAccessor
void makeSourceLinkPairs(
const GeometryContext& gctx, const std::vector<SourceLink>& slinksFront,
const std::vector<SourceLink>& slinksBack,
std::vector<std::pair<SourceLink, SourceLink>>& slinkPairs,
const StripPairOptions& pairOpt) const;

protected:
// configuration of the single hit space point builder
Expand All @@ -88,7 +85,6 @@ class SpacePointBuilder {
std::function<spacepoint_t(Acts::Vector3, Acts::Vector2,
boost::container::static_vector<SourceLink, 2>)>
m_spConstructor;

/// the logging instance
std::unique_ptr<const Acts::Logger> m_logger;

Expand Down
12 changes: 0 additions & 12 deletions Core/include/Acts/SpacePointFormation/SpacePointBuilderConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ namespace Acts {
struct SpacePointBuilderConfig {
/// Tracking geometry
std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry;
/// vertex position
Vector3 vertex = {0., 0., 0.};
/// Accepted squared difference in theta for two clusters
double diffTheta2 = 1.;
/// Accepted squared difference in phi for two clusters
double diffPhi2 = 1.;
/// Accepted distance between two clusters
double diffDist = 100. * UnitConstants::mm;
/// Allowed increase of strip length
double stripLengthTolerance = 0.01;
/// Allowed increase of strip length wrt gaps between strips
double stripLengthGapTolerance = 0.01;
/// Perform the perpendicular projection for space point finding
bool usePerpProj = false;

Expand Down
28 changes: 28 additions & 0 deletions Core/include/Acts/SpacePointFormation/SpacePointBuilderOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,40 @@

#pragma once

#include "Acts/EventData/SourceLink.hpp"

namespace Acts {

struct SpacePointBuilderOptions {
// ends of strip pairs
std::pair<const std::pair<Vector3, Vector3>,
const std::pair<Vector3, Vector3>>
stripEndsPair;
// accessor of local position and covariance from soruce link
std::function<std::pair<const BoundVector, const BoundSymMatrix>(SourceLink)>
paramCovAccessor;
/// vertex position
Vector3 vertex = {0., 0., 0.};
/// Allowed increase of strip length
double stripLengthTolerance = 0.01;
/// Allowed increase of strip length wrt gaps between strips
double stripLengthGapTolerance = 0.01;
SpacePointBuilderOptions() = default;
};

struct StripPairOptions {
// accessor of local position and covariance from soruce link
std::function<std::pair<const BoundVector, const BoundSymMatrix>(SourceLink)>
paramCovAccessor;
/// vertex position
Vector3 vertex = {0., 0., 0.};
/// Accepted squared difference in theta for two clusters
double diffTheta2 = 1.;
/// Accepted squared difference in phi for two clusters
double diffPhi2 = 1.;
/// Accepted distance between two clusters
double diffDist = 100. * UnitConstants::mm;
StripPairOptions() = default;
};

} // namespace Acts
112 changes: 47 additions & 65 deletions Core/include/Acts/SpacePointFormation/detail/SpacePointBuilder.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// 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/.

namespace Acts {

template <typename spacepoint_t>
SpacePointBuilder<spacepoint_t>::SpacePointBuilder(
const SpacePointBuilderConfig& cfg,
Expand All @@ -21,22 +21,21 @@ SpacePointBuilder<spacepoint_t>::SpacePointBuilder(
template <typename spacepoint_t>
template <template <typename...> typename container_t>
void SpacePointBuilder<spacepoint_t>::buildSpacePoint(
const GeometryContext& gctx,
const std::vector<const Measurement*>& measurements,
const GeometryContext& gctx, const std::vector<SourceLink>& sourceLinks,
const SpacePointBuilderOptions& opt,
std::back_insert_iterator<container_t<spacepoint_t>> spacePointIt) const {
const unsigned int num_meas = measurements.size();
const unsigned int num_slinks = sourceLinks.size();

Acts::Vector3 gPos = Acts::Vector3::Zero();
Acts::Vector2 gCov = Acts::Vector2::Zero();

if (num_meas == 1) { // pixel SP formation

auto gPosCov = m_spUtility->globalCoords(gctx, *(measurements[0]));
if (num_slinks == 1) { // pixel SP formation
auto slink = sourceLinks.at(0);
auto [param, cov] = opt.paramCovAccessor(sourceLinks.at(0));
auto gPosCov = m_spUtility->globalCoords(gctx, slink, param, cov);
gPos = gPosCov.first;
gCov = gPosCov.second;

} else if (num_meas == 2) { // strip SP formation
} else if (num_slinks == 2) { // strip SP formation

const auto& ends1 = opt.stripEndsPair.first;
const auto& ends2 = opt.stripEndsPair.second;
Expand All @@ -46,12 +45,11 @@ void SpacePointBuilder<spacepoint_t>::buildSpacePoint(
if (!m_config.usePerpProj) { // default strip SP building

auto spFound = m_spUtility->calculateStripSPPosition(
ends1, ends2, m_config.vertex, spParams,
m_config.stripLengthTolerance);
ends1, ends2, opt.vertex, spParams, opt.stripLengthTolerance);

if (!spFound.ok()) {
spFound = m_spUtility->recoverSpacePoint(
spParams, m_config.stripLengthGapTolerance);
spFound = m_spUtility->recoverSpacePoint(spParams,
opt.stripLengthGapTolerance);
}

if (!spFound.ok()) {
Expand All @@ -76,75 +74,59 @@ void SpacePointBuilder<spacepoint_t>::buildSpacePoint(
acos(spParams.firstBtmToTop.dot(spParams.secondBtmToTop) /
(spParams.firstBtmToTop.norm() * spParams.secondBtmToTop.norm()));

gCov = m_spUtility->calcRhoZVars(gctx, *(measurements.at(0)),
*(measurements.at(1)), gPos, theta);
gCov = m_spUtility->calcRhoZVars(gctx, sourceLinks.at(0), sourceLinks.at(1),
opt.paramCovAccessor, gPos, theta);

} else {
ACTS_ERROR("More than 2 measurements are given for a space point.");
}

boost::container::static_vector<SourceLink, 2> slinks;
for (const auto& meas : measurements) {
const auto& slink =
std::visit([](const auto& x) { return x.sourceLink(); }, *meas);
slinks.emplace_back(slink);
ACTS_ERROR("More than 2 sourceLinks are given for a space point.");
}
boost::container::static_vector<SourceLink, 2> slinks(sourceLinks.begin(),
sourceLinks.end());

spacePointIt = m_spConstructor(gPos, gCov, std::move(slinks));
}

template <typename spacepoint_t>
void SpacePointBuilder<spacepoint_t>::makeMeasurementPairs(
const GeometryContext& gctx,
const std::vector<const Measurement*>& measurementsFront,
const std::vector<const Measurement*>& measurementsBack,
std::vector<std::pair<const Measurement*, const Measurement*>>&
measurementPairs) const {
// Return if no Measurements are given in a vector
if (measurementsFront.empty() || measurementsBack.empty()) {
void SpacePointBuilder<spacepoint_t>::makeSourceLinkPairs(
const GeometryContext& gctx, const std::vector<SourceLink>& slinksFront,
const std::vector<SourceLink>& slinksBack,
std::vector<std::pair<SourceLink, SourceLink>>& slinkPairs,
const StripPairOptions& pairOpt) const {
if (slinksFront.empty() || slinksBack.empty()) {
return;
}
// Declare helper variables
double currentDiff = 0;
double diffMin = 0;
unsigned int measurementMinDist = 0;

// Walk through all Measurements on both surfaces
for (unsigned int iMeasurementsFront = 0;
iMeasurementsFront < measurementsFront.size(); iMeasurementsFront++) {
// Set the closest distance to the maximum of double
diffMin = std::numeric_limits<double>::max();
// Set the corresponding index to an element not in the list of Measurements
measurementMinDist = measurementsBack.size();
for (unsigned int iMeasurementsBack = 0;
iMeasurementsBack < measurementsBack.size(); iMeasurementsBack++) {
auto [gposFront, gcovFront] = m_spUtility->globalCoords(
gctx, *(measurementsFront[iMeasurementsFront]));
auto [gposBack, gcovBack] = m_spUtility->globalCoords(
gctx, *(measurementsBack[iMeasurementsBack]));
double minDistance = 0;
unsigned int closestIndex = 0;

for (unsigned int i = 0; i < slinksFront.size(); i++) {
const auto& slinkFront = slinksFront[i];
minDistance = std::numeric_limits<double>::max();
closestIndex = slinksBack.size();
for (unsigned int j = 0; j < slinksBack.size(); j++) {
const auto& slinkBack = slinksBack[j];

const auto [paramFront, covFront] = pairOpt.paramCovAccessor(slinkFront);
const auto [gposFront, gcovFront] =
m_spUtility->globalCoords(gctx, slinkFront, paramFront, covFront);

const auto [paramBack, covBack] = pairOpt.paramCovAccessor(slinkBack);
const auto [gposBack, gcovBack] =
m_spUtility->globalCoords(gctx, slinkBack, paramBack, covBack);

auto res = m_spUtility->differenceOfMeasurementsChecked(
gposFront, gposBack, m_config.vertex, m_config.diffDist,
m_config.diffPhi2, m_config.diffTheta2);
gposFront, gposBack, pairOpt.vertex, pairOpt.diffDist,
pairOpt.diffPhi2, pairOpt.diffTheta2);
if (!res.ok()) {
continue;
}

currentDiff = res.value();

// Store the closest Measurements (distance and index) calculated so far
if (currentDiff < diffMin && currentDiff >= 0.) {
diffMin = currentDiff;
measurementMinDist = iMeasurementsBack;
const auto distance = res.value();
if (distance >= 0. && distance < minDistance) {
minDistance = distance;
closestIndex = j;
}
}

// Store the best (=closest) result
if (measurementMinDist < measurementsBack.size()) {
std::pair<const Measurement*, const Measurement*> measurementPair =
std::make_pair(measurementsFront[iMeasurementsFront],
measurementsBack[measurementMinDist]);
measurementPairs.push_back(measurementPair);
if (closestIndex < slinksBack.size()) {
slinkPairs.emplace_back(slinksFront[i], slinksBack[closestIndex]);
}
}
}
Expand Down
Loading

0 comments on commit 56aff8b

Please sign in to comment.