Skip to content

Commit

Permalink
test infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
asalzburger committed Mar 18, 2024
1 parent 6bd04ba commit a580f23
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 17 deletions.
97 changes: 85 additions & 12 deletions Core/include/Acts/Utilities/GridAccessHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@ typename grid_type::point_t castPosition(const Vector3& position,
/// @param ra is the array to be filled
///
/// @note void function that fills the provided array
template <typename Array, std::size_t... idx>
void fillLocal(const Vector2& lposition,
const std::vector<std::size_t>& laccess, Array& ra,
std::index_sequence<idx...> /*indices*/) {
template <typename Array, typename local_indices, std::size_t... idx>
void fillLocal(const Vector2& lposition, const local_indices& laccess,
Array& ra, std::index_sequence<idx...> /*indices*/) {
((ra[idx] = lposition[laccess[idx]]), ...);
}

Expand All @@ -79,9 +78,9 @@ void fillLocal(const Vector2& lposition,
/// @param laccess the local accessors
///
/// @return an array suitable for the grid
template <typename grid_type>
typename grid_type::point_t accessLocal(
const Vector2& lposition, const std::vector<std::size_t>& laccess) {
template <typename grid_type, typename local_indices>
typename grid_type::point_t accessLocal(const Vector2& lposition,
const local_indices& laccess) {
if constexpr (grid_type::DIM > 2u) {
throw std::invalid_argument(
"GridAccessHelper: only 1-D and 2-D grids are possible for local "
Expand Down Expand Up @@ -143,25 +142,26 @@ class Affine3Transformed final : public IGlobalToGridLocal {
/// position
/// @tparam ...Args
template <BinningValue... Args>
class GlobalSubSpace final : public IGlobalToGridLocal {
class GlobalSubspace final : public IGlobalToGridLocal {
public:
using grid_local_t = std::array<ActsScalar, sizeof...(Args)>;

// Constructor with sanity checks
GlobalSubSpace() {
GlobalSubspace() {
if constexpr (sizeof...(Args) == 0) {
throw std::invalid_argument(
"GlobalSubSpace: cannot have an empty binning value list.");
"GlobalSubspace: cannot have an empty binning value list.");
}

if constexpr (sizeof...(Args) > 3) {
throw std::invalid_argument(
"GlobalSubSpace: cannot have more than 3 binning values.");
"GlobalSubspace: cannot have more than 3 binning values.");
}
}

/// The binning values
std::array<BinningValue, sizeof...(Args)> bValues = {Args...};
static constexpr std::array<BinningValue, sizeof...(Args)> bValues = {
Args...};

/// Transform in to the local frame, then the grid local position
///
Expand All @@ -178,6 +178,79 @@ class GlobalSubSpace final : public IGlobalToGridLocal {
}
};

// The bound to grid local transformation, if only access of a subspace
// is requested
template <std::size_t... Args>
class LocalSubspace final : public IBoundToGridLocal {
public:
using grid_local_t = std::array<ActsScalar, sizeof...(Args)>;

// Constructor with sanity checks
LocalSubspace() {
if constexpr (sizeof...(Args) == 0) {
throw std::invalid_argument(
"LocalSubspace: cannot have an empty binning value list.");
}

if constexpr (sizeof...(Args) > 2) {
throw std::invalid_argument(
"LocalSubspace: cannot have more than 2 binning values.");
}

if constexpr (sizeof...(Args) == 1) {
if (std::get<0>(accessors) >= 2) {
throw std::invalid_argument(
"LocalSubspace: local access needs to be 0u or 1u");
}
}

if constexpr (sizeof...(Args) == 2) {
if (std::get<0>(accessors) == std::get<1>(accessors)) {
throw std::invalid_argument(
"LocalSubspace: local access needs to be unique");
}
if (std::get<0>(accessors) >= 2 || std::get<1>(accessors) >= 2) {
throw std::invalid_argument(
"LocalSubspace: local access needs to be 0u or 1u");
}
}
}

static constexpr std::array<std::size_t, sizeof...(Args)> accessors = {
Args...};

/// Access the local entries
///
/// @param lposition is the local position
///
/// @return the grid position
grid_local_t toGridLocal(const Vector2& lposition) const {
// Fill the grid point from local according to the accessors
grid_local_t accessed{};
GridAccessHelpers::fillLocal(
lposition, accessors, accessed,
std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
return accessed;
}
};

class BoundCylinderToZPhi final : public IBoundToGridLocal {
public:
ActsScalar radius = 1.;
ActsScalar shift = 0.;

/// Constructor with arguments
/// @param r the radius
/// @param z the shift
BoundCylinderToZPhi(ActsScalar r, ActsScalar z) : radius(r), shift(z) {}

std::array<ActsScalar, 2u> l2ZPhi(const Vector2& local) const {
return {local[1u] + shift, local[0u] / radius};
}

using BoundDiscToRPhi = LocalSubspace<0u, 1u>;
};

} // namespace GridAccess

} // namespace Acts
49 changes: 44 additions & 5 deletions Tests/UnitTests/Core/Utilities/GridAccessHelpersTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <boost/test/unit_test.hpp>

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
#include "Acts/Utilities/Grid.hpp"
#include "Acts/Utilities/GridAccessHelpers.hpp"
#include "Acts/Utilities/GridAxisGenerators.hpp"
Expand Down Expand Up @@ -86,31 +87,69 @@ BOOST_AUTO_TEST_CASE(Grid2DAccess) {
}

BOOST_AUTO_TEST_CASE(GlobalToGridLocalTests) {
Acts::GridAccess::GlobalSubSpace<binX, binY> gssXY;
Acts::GridAccess::GlobalSubspace<binX, binY> gssXY;

auto xy = gssXY.toGridLocal(Vector3{1., 2., 3.});
BOOST_CHECK_EQUAL(xy[0], 1.);
BOOST_CHECK_EQUAL(xy[1], 2.);

Acts::GridAccess::GlobalSubSpace<binZ> gssZ;
Acts::GridAccess::GlobalSubspace<binZ> gssZ;
auto z = gssZ.toGridLocal(Vector3{1., 2., 3.});
BOOST_CHECK_EQUAL(z[0], 3.);

Acts::GridAccess::Affine3Transformed<Acts::GridAccess::GlobalSubSpace<binZ>>
Acts::GridAccess::Affine3Transformed<Acts::GridAccess::GlobalSubspace<binZ>>
gssZT(gssZ, Acts::Transform3(Acts::Transform3::Identity())
.pretranslate(Vector3{0., 0., 100.}));

auto zt = gssZT.toGridLocal(Vector3{1., 2., 3.});
BOOST_CHECK_EQUAL(zt[0], 103.);

// Invalidy checks
using SubSpace0 = Acts::GridAccess::GlobalSubSpace<>;
using SubSpace0 = Acts::GridAccess::GlobalSubspace<>;
BOOST_CHECK_THROW(auto gss0 = SubSpace0(), std::invalid_argument);

// This could in principle be allowed, but does not make sense
using SubSpace4 = Acts::GridAccess::GlobalSubSpace<Acts::binX, Acts::binY,
using SubSpace4 = Acts::GridAccess::GlobalSubspace<Acts::binX, Acts::binY,
Acts::binZ, Acts::binPhi>;
BOOST_CHECK_THROW(auto gss4 = SubSpace4(), std::invalid_argument);
}

BOOST_AUTO_TEST_CASE(BoundToGridLocalTests) {
Acts::GridAccess::LocalSubspace<0u, 1u> bssXY;
auto xy = bssXY.toGridLocal(Vector2{
1.,
2.,
});

BOOST_CHECK_EQUAL(xy[0], 1.);
BOOST_CHECK_EQUAL(xy[1], 2.);

using Invalid0 = Acts::GridAccess::LocalSubspace<>;
BOOST_CHECK_THROW(auto invalid0 = Invalid0(), std::invalid_argument);

using Invalid3 = Acts::GridAccess::LocalSubspace<0u, 1u, 2u>;
BOOST_CHECK_THROW(auto invalid3 = Invalid0(), std::invalid_argument);

using InvalidL0G2 = Acts::GridAccess::LocalSubspace<2u, 0u>;
BOOST_CHECK_THROW(auto invalidl0g2 = InvalidL0G2(), std::invalid_argument);

using InvalidL1G2 = Acts::GridAccess::LocalSubspace<0u, 2u>;
BOOST_CHECK_THROW(auto invalidl1g2 = InvalidL1G2(), std::invalid_argument);

using InvalidL0G2D1 = Acts::GridAccess::LocalSubspace<2u>;
BOOST_CHECK_THROW(auto invalidl0g2d1 = InvalidL0G2D1(),
std::invalid_argument);
}

BOOST_AUTO_TEST_CASE(BoundCylinderToZPhiTests) {
Acts::ActsScalar radius = 100.;
Acts::ActsScalar shift = 0.;
Acts::GridAccess::BoundCylinderToZPhi bctzp(radius, shift);

auto zphi = bctzp.l2ZPhi(Vector2{0.25 * radius, 52.});

CHECK_CLOSE_ABS(zphi[0], 52., 1.e-6);
CHECK_CLOSE_ABS(zphi[1], 0.25, 1.e-6);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit a580f23

Please sign in to comment.