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

refactor!: Explicit BoundaryTolerance constructors #3974

Merged
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
101 changes: 56 additions & 45 deletions Core/include/Acts/Surfaces/BoundaryTolerance.hpp
andiwand marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,16 @@ namespace Acts {
///
class BoundaryTolerance {
public:
/// Infinite tolerance i.e. no boundary check
struct Infinite {};
struct InfiniteParams {};

/// No tolerance i.e. exact boundary check
struct None {};
struct NoneParams {};

/// Absolute tolerance in bound coordinates
struct AbsoluteBound {
struct AbsoluteBoundParams {
double tolerance0{};
double tolerance1{};

AbsoluteBound() = default;
AbsoluteBound(double tolerance0_, double tolerance1_)
AbsoluteBoundParams() = default;
AbsoluteBoundParams(double tolerance0_, double tolerance1_)
: tolerance0(tolerance0_), tolerance1(tolerance1_) {
if (tolerance0 < 0 || tolerance1 < 0) {
throw std::invalid_argument(
Expand All @@ -75,13 +72,12 @@ class BoundaryTolerance {
}
};

/// Absolute tolerance in Cartesian coordinates
struct AbsoluteCartesian {
struct AbsoluteCartesianParams {
double tolerance0{};
double tolerance1{};

AbsoluteCartesian() = default;
AbsoluteCartesian(double tolerance0_, double tolerance1_)
AbsoluteCartesianParams() = default;
AbsoluteCartesianParams(double tolerance0_, double tolerance1_)
: tolerance0(tolerance0_), tolerance1(tolerance1_) {
if (tolerance0 < 0 || tolerance1 < 0) {
throw std::invalid_argument(
Expand All @@ -94,50 +90,65 @@ class BoundaryTolerance {
}
};

/// Absolute tolerance in Euclidean distance
struct AbsoluteEuclidean {
struct AbsoluteEuclideanParams {
double tolerance{};

AbsoluteEuclidean() = default;
explicit AbsoluteEuclidean(double tolerance_) : tolerance(tolerance_) {}
AbsoluteEuclideanParams() = default;
explicit AbsoluteEuclideanParams(double tolerance_)
: tolerance(tolerance_) {}
};

/// Chi2 tolerance in bound coordinates
struct Chi2Bound {
struct Chi2BoundParams {
double maxChi2{};
SquareMatrix2 weight = SquareMatrix2::Identity();

Chi2Bound() = default;
Chi2Bound(const SquareMatrix2& weight_, double maxChi2_)
Chi2BoundParams() = default;
Chi2BoundParams(const SquareMatrix2& weight_, double maxChi2_)
: maxChi2(maxChi2_), weight(weight_) {}
};

private:
/// Underlying variant type
using Variant = std::variant<InfiniteParams, NoneParams, AbsoluteBoundParams,
AbsoluteCartesianParams, AbsoluteEuclideanParams,
Chi2BoundParams>;

/// Construct from variant
explicit BoundaryTolerance(Variant variant);

public:
/// Infinite tolerance i.e. no boundary check
static auto Infinite() { return BoundaryTolerance{InfiniteParams{}}; }

/// No tolerance i.e. exact boundary check
static auto None() { return BoundaryTolerance{NoneParams{}}; }

/// Absolute tolerance in bound coordinates
static auto AbsoluteBound(double tolerance0, double tolerance1) {
return BoundaryTolerance{AbsoluteBoundParams{tolerance0, tolerance1}};
}

/// Absolute tolerance in Cartesian coordinates
static auto AbsoluteCartesian(double tolerance0, double tolerance1) {
return BoundaryTolerance{AbsoluteCartesianParams{tolerance0, tolerance1}};
}

/// Absolute tolerance in Euclidean distance
static auto AbsoluteEuclidean(double tolerance) {
return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}};
}

/// Chi2 tolerance in bound coordinates
static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) {
return BoundaryTolerance{Chi2BoundParams{weight, maxChi2}};
}

enum class ToleranceMode {
Extend, // Extend the boundary
None, // No tolerance
Shrink // Shrink the boundary
};

/// Underlying variant type
using Variant = std::variant<Infinite, None, AbsoluteBound, AbsoluteCartesian,
AbsoluteEuclidean, Chi2Bound>;

/// Construct with infinite tolerance.
BoundaryTolerance(const Infinite& infinite);
/// Construct with no tolerance.
BoundaryTolerance(const None& none);
/// Construct with absolute tolerance in bound coordinates.
BoundaryTolerance(const AbsoluteBound& AbsoluteBound);
/// Construct with absolute tolerance in Cartesian coordinates.
BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian);
/// Construct with absolute tolerance in Euclidean distance.
BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean);
/// Construct with chi2 tolerance in bound coordinates.
BoundaryTolerance(const Chi2Bound& Chi2Bound);

/// Construct from variant
BoundaryTolerance(Variant variant);

/// Check if the tolerance is infinite.
bool isInfinite() const;
/// Check if the is no tolerance.
Expand All @@ -155,16 +166,16 @@ class BoundaryTolerance {
ToleranceMode toleranceMode() const;

/// Get the tolerance as absolute bound.
AbsoluteBound asAbsoluteBound(bool isCartesian = false) const;
AbsoluteBoundParams asAbsoluteBound(bool isCartesian = false) const;
/// Get the tolerance as absolute Cartesian.
const AbsoluteCartesian& asAbsoluteCartesian() const;
const AbsoluteCartesianParams& asAbsoluteCartesian() const;
/// Get the tolerance as absolute Euclidean.
const AbsoluteEuclidean& asAbsoluteEuclidean() const;
const AbsoluteEuclideanParams& asAbsoluteEuclidean() const;
/// Get the tolerance as chi2 bound.
const Chi2Bound& asChi2Bound() const;
const Chi2BoundParams& asChi2Bound() const;

/// Get the tolerance as absolute bound if possible.
std::optional<AbsoluteBound> asAbsoluteBoundOpt(
std::optional<AbsoluteBoundParams> asAbsoluteBoundOpt(
bool isCartesian = false) const;

/// Check if the distance is tolerated.
Expand Down
2 changes: 1 addition & 1 deletion Core/src/Geometry/TrapezoidVolumeBounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ bool TrapezoidVolumeBounds::inside(const Vector3& pos, double tol) const {
}
Vector2 locp(pos.x(), pos.y());
bool inside(m_faceXYTrapezoidBounds->inside(
locp, BoundaryTolerance::AbsoluteBound{tol, tol}));
locp, BoundaryTolerance::AbsoluteBound(tol, tol)));
return inside;
}

Expand Down
75 changes: 30 additions & 45 deletions Core/src/Surfaces/BoundaryTolerance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,32 @@

namespace Acts {

BoundaryTolerance::BoundaryTolerance(const Infinite& infinite)
: m_variant{infinite} {}

BoundaryTolerance::BoundaryTolerance(const None& none) : m_variant{none} {}

BoundaryTolerance::BoundaryTolerance(const AbsoluteBound& absoluteBound)
: m_variant{absoluteBound} {}

BoundaryTolerance::BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian)
: m_variant{absoluteCartesian} {}

BoundaryTolerance::BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean)
: m_variant{absoluteEuclidean} {}

BoundaryTolerance::BoundaryTolerance(const Chi2Bound& chi2Bound)
: m_variant{chi2Bound} {}

BoundaryTolerance::BoundaryTolerance(Variant variant)
: m_variant{std::move(variant)} {}

bool BoundaryTolerance::isInfinite() const {
return holdsVariant<Infinite>();
return holdsVariant<InfiniteParams>();
}

bool BoundaryTolerance::isNone() const {
return holdsVariant<None>();
return holdsVariant<NoneParams>();
}

bool BoundaryTolerance::hasAbsoluteBound(bool isCartesian) const {
return holdsVariant<None>() || holdsVariant<AbsoluteBound>() ||
(isCartesian && holdsVariant<AbsoluteCartesian>());
return holdsVariant<NoneParams>() || holdsVariant<AbsoluteBoundParams>() ||
(isCartesian && holdsVariant<AbsoluteCartesianParams>());
}

bool BoundaryTolerance::hasAbsoluteCartesian() const {
return holdsVariant<AbsoluteCartesian>();
return holdsVariant<AbsoluteCartesianParams>();
}

bool BoundaryTolerance::hasAbsoluteEuclidean() const {
return holdsVariant<AbsoluteEuclidean>();
return holdsVariant<AbsoluteEuclideanParams>();
}

bool BoundaryTolerance::hasChi2Bound() const {
return holdsVariant<Chi2Bound>();
return holdsVariant<Chi2BoundParams>();
}

BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
Expand All @@ -70,7 +53,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
return None;
}

if (const auto* absoluteBound = getVariantPtr<AbsoluteBound>();
if (const auto* absoluteBound = getVariantPtr<AbsoluteBoundParams>();
absoluteBound != nullptr) {
if (absoluteBound->tolerance0 == 0. && absoluteBound->tolerance1 == 0.) {
return None;
Expand All @@ -79,7 +62,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
return Extend;
}

if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesian>();
if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesianParams>();
absoluteCartesian != nullptr) {
if (absoluteCartesian->tolerance0 == 0. &&
absoluteCartesian->tolerance1 == 0.) {
Expand All @@ -89,7 +72,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
return Extend;
}

if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclidean>();
if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclideanParams>();
absoluteEuclidean != nullptr) {
if (absoluteEuclidean->tolerance == 0.) {
return None;
Expand All @@ -100,7 +83,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
}
}

if (const auto* chi2Bound = getVariantPtr<Chi2Bound>();
if (const auto* chi2Bound = getVariantPtr<Chi2BoundParams>();
chi2Bound != nullptr) {
if (chi2Bound->maxChi2 == 0.) {
return None;
Expand All @@ -115,35 +98,36 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
return None;
}

BoundaryTolerance::AbsoluteBound BoundaryTolerance::asAbsoluteBound(
BoundaryTolerance::AbsoluteBoundParams BoundaryTolerance::asAbsoluteBound(
bool isCartesian) const {
if (isNone()) {
return AbsoluteBound{0., 0.};
return AbsoluteBoundParams{0., 0.};
}

if (isCartesian && hasAbsoluteCartesian()) {
const auto& cartesian = getVariant<AbsoluteCartesian>();
return AbsoluteBound{cartesian.tolerance0, cartesian.tolerance1};
const auto& cartesian = getVariant<AbsoluteCartesianParams>();
return AbsoluteBoundParams{cartesian.tolerance0, cartesian.tolerance1};
}

return getVariant<AbsoluteBound>();
return getVariant<AbsoluteBoundParams>();
}

const BoundaryTolerance::AbsoluteCartesian&
const BoundaryTolerance::AbsoluteCartesianParams&
BoundaryTolerance::asAbsoluteCartesian() const {
return getVariant<AbsoluteCartesian>();
return getVariant<AbsoluteCartesianParams>();
}

const BoundaryTolerance::AbsoluteEuclidean&
const BoundaryTolerance::AbsoluteEuclideanParams&
BoundaryTolerance::asAbsoluteEuclidean() const {
return getVariant<AbsoluteEuclidean>();
return getVariant<AbsoluteEuclideanParams>();
}

const BoundaryTolerance::Chi2Bound& BoundaryTolerance::asChi2Bound() const {
return getVariant<Chi2Bound>();
const BoundaryTolerance::Chi2BoundParams& BoundaryTolerance::asChi2Bound()
const {
return getVariant<Chi2BoundParams>();
}

std::optional<BoundaryTolerance::AbsoluteBound>
std::optional<BoundaryTolerance::AbsoluteBoundParams>
BoundaryTolerance::asAbsoluteBoundOpt(bool isCartesian) const {
return hasAbsoluteBound(isCartesian)
? std::optional(asAbsoluteBound(isCartesian))
Expand All @@ -161,13 +145,13 @@ bool BoundaryTolerance::isTolerated(
return distance == Vector2::Zero();
}

if (const auto* absoluteBound = getVariantPtr<AbsoluteBound>();
if (const auto* absoluteBound = getVariantPtr<AbsoluteBoundParams>();
absoluteBound != nullptr) {
return std::abs(distance[0]) <= absoluteBound->tolerance0 &&
std::abs(distance[1]) <= absoluteBound->tolerance1;
}

if (const auto* chi2Bound = getVariantPtr<Chi2Bound>();
if (const auto* chi2Bound = getVariantPtr<Chi2BoundParams>();
chi2Bound != nullptr) {
// Mahalanobis distances mean is 2 in 2-dim. cut is 1-d sigma.
double chi2 = distance.transpose() * chi2Bound->weight * distance;
Expand All @@ -187,13 +171,13 @@ bool BoundaryTolerance::isTolerated(
cartesianDistance = jacobian * distance;
}

if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesian>();
if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesianParams>();
absoluteCartesian != nullptr) {
return std::abs(cartesianDistance[0]) <= absoluteCartesian->tolerance0 &&
std::abs(cartesianDistance[1]) <= absoluteCartesian->tolerance1;
}

if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclidean>();
if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclideanParams>();
absoluteEuclidean != nullptr) {
if (absoluteEuclidean->tolerance < 0) {
return cartesianDistance.norm() > std::abs(absoluteEuclidean->tolerance);
Expand All @@ -214,7 +198,8 @@ SquareMatrix2 BoundaryTolerance::getMetric(
bool isCartesian = !jacobianOpt.has_value();
SquareMatrix2 metric = SquareMatrix2::Identity();

if (const auto* chi2Bound = getVariantPtr<BoundaryTolerance::Chi2Bound>();
if (const auto* chi2Bound =
getVariantPtr<BoundaryTolerance::Chi2BoundParams>();
chi2Bound != nullptr) {
metric = chi2Bound->weight;
} else if (!isCartesian) {
Expand Down
4 changes: 2 additions & 2 deletions Examples/Io/Root/src/RootAthenaDumpReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ RootAthenaDumpReader::readMeasurements(

bool inside =
surface->isOnSurface(gctx, cluster.globalPosition, {},
Acts::BoundaryTolerance::AbsoluteEuclidean{
m_cfg.absBoundaryTolerance},
Acts::BoundaryTolerance::AbsoluteEuclidean(
m_cfg.absBoundaryTolerance),
std::numeric_limits<double>::max());

if (!inside) {
Expand Down
8 changes: 4 additions & 4 deletions Tests/Benchmarks/AnnulusBoundsBenchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ int main(int /*argc*/, char** /*argv[]*/) {
cov << 1.0, 0, 0, 0.05;

BoundaryTolerance bcAbs = BoundaryTolerance::None();
BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound{1.0, 0};
BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound{0, 0.2};
BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound{1.0, 0.2};
BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound{cov, 1};
BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound(1.0, 0.0);
BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound(0.0, 0.2);
BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound(1.0, 0.2);
BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound(cov, 1.0);

// visualization to make sense of things
for (std::size_t i = 0; i < 10000; i++) {
Expand Down
Loading
Loading