Skip to content

Commit

Permalink
Merge branch 'main' into build/geomodel-version-requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Oct 8, 2024
2 parents 2173eb1 + 39c6aca commit 27ed2c7
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 43 deletions.
32 changes: 30 additions & 2 deletions Core/include/Acts/Geometry/ProtoLayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct ProtoLayer {
/// The envelope parameters
ExtentEnvelope envelope = ExtentEnvelope::Zero();

/// The local transform
Transform3 transform = Transform3::Identity();

/// Constructor
///
/// Loops over a provided vector of surface and calculates the various
Expand All @@ -41,8 +44,10 @@ struct ProtoLayer {
///
/// @param gctx The current geometry context object, e.g. alignment
/// @param surfaces The vector of surfaces to consider
/// @param transformIn The local transform to evaluate the sizing in
ProtoLayer(const GeometryContext& gctx,
const std::vector<const Surface*>& surfaces);
const std::vector<const Surface*>& surfaces,
const Transform3& transformIn = Transform3::Identity());

/// Constructor
///
Expand All @@ -52,8 +57,23 @@ struct ProtoLayer {
///
/// @param gctx The current geometry context object, e.g. alignment
/// @param surfaces The vector of surfaces to consider
/// @param transformIn The local transform to evaluate the sizing in
ProtoLayer(const GeometryContext& gctx,
const std::vector<std::shared_ptr<const Surface>>& surfaces);
const std::vector<std::shared_ptr<const Surface>>& surfaces,
const Transform3& transformIn = Transform3::Identity());

/// Constructor
///
/// Loops over a provided vector of surface and calculates the various
/// min/max values in one go. Also takes into account the thickness
/// of an associated DetectorElement, if it exists.
///
/// @param gctx The current geometry context object, e.g. alignment
/// @param surfaces The vector of surfaces to consider
/// @param transformIn The local transform to evaluate the sizing in
ProtoLayer(const GeometryContext& gctx,
const std::vector<std::shared_ptr<Surface>>& surfaces,
const Transform3& transformIn = Transform3::Identity());

ProtoLayer() = default;

Expand Down Expand Up @@ -81,6 +101,14 @@ struct ProtoLayer {
/// @param sl the input ostream
std::ostream& toStream(std::ostream& sl) const;

/// Output stream operator
/// @param sl the input ostream
/// @param pl the ProtoLayer to be printed
/// @return the output ostream
friend std::ostream& operator<<(std::ostream& sl, const ProtoLayer& pl) {
return pl.toStream(sl);
}

/// Give access to the surfaces used/assigned to the ProtoLayer
const std::vector<const Surface*>& surfaces() const;

Expand Down
34 changes: 20 additions & 14 deletions Core/src/Geometry/ProtoLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,34 @@
#include "Acts/Surfaces/RegularSurface.hpp"
#include "Acts/Utilities/Helpers.hpp"

#include <algorithm>
#include <array>
#include <string>
#include <utility>

using Acts::VectorHelpers::perp;
using Acts::VectorHelpers::phi;

namespace Acts {

ProtoLayer::ProtoLayer(const GeometryContext& gctx,
const std::vector<const Surface*>& surfaces)
: m_surfaces(surfaces) {
const std::vector<const Surface*>& surfaces,
const Transform3& transformIn)
: transform(transformIn), m_surfaces(surfaces) {
measure(gctx, surfaces);
}

ProtoLayer::ProtoLayer(
const GeometryContext& gctx,
const std::vector<std::shared_ptr<const Surface>>& surfaces)
: m_surfaces(unpack_shared_vector(surfaces)) {
const std::vector<std::shared_ptr<const Surface>>& surfaces,
const Transform3& transformIn)
: transform(transformIn), m_surfaces(unpack_shared_vector(surfaces)) {
measure(gctx, m_surfaces);
}

ProtoLayer::ProtoLayer(const GeometryContext& gctx,
const std::vector<std::shared_ptr<Surface>>& surfaces,
const Transform3& transformIn)
: transform(transformIn) {
m_surfaces.reserve(surfaces.size());
for (const auto& sf : surfaces) {
m_surfaces.push_back(sf.get());
}
measure(gctx, m_surfaces);
}

Expand Down Expand Up @@ -78,15 +86,13 @@ void ProtoLayer::measure(const GeometryContext& gctx,
double thickness = element->thickness();
// We need a translation along and opposite half thickness
Vector3 sfNormal = regSurface->normal(gctx, sf->center(gctx));
std::vector<double> deltaT = {-0.5 * thickness, 0.5 * thickness};
for (const auto& dT : deltaT) {
Transform3 dtransform = Transform3::Identity();
dtransform.pretranslate(dT * sfNormal);
for (const auto& dT : {-0.5 * thickness, 0.5 * thickness}) {
Transform3 dtransform = transform * Translation3{dT * sfNormal};
extent.extend(sfPolyhedron.extent(dtransform));
}
continue;
}
extent.extend(sfPolyhedron.extent());
extent.extend(sfPolyhedron.extent(transform));
}
}

Expand Down
161 changes: 134 additions & 27 deletions Tests/UnitTests/Core/Geometry/ProtoLayerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,33 @@
#include <boost/test/unit_test.hpp>

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/Units.hpp"
#include "Acts/Geometry/DetectorElementBase.hpp"
#include "Acts/Geometry/Extent.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/ProtoLayer.hpp"
#include "Acts/Surfaces/PlaneSurface.hpp"
#include "Acts/Surfaces/RectangleBounds.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
#include "Acts/Utilities/BinningType.hpp"
#include "Acts/Utilities/RangeXD.hpp"

#include <array>
#include <cmath>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

namespace Acts::Test::Layers {

GeometryContext tgContext = GeometryContext();

BOOST_AUTO_TEST_SUITE(Geometry)

BOOST_AUTO_TEST_CASE(ProtoLayerTests) {
GeometryContext tgContext = GeometryContext();
using enum BinningValue;

// Create a proto layer with 4 surfaces on the x/y grid
auto recBounds = std::make_shared<RectangleBounds>(3., 6.);
Expand Down Expand Up @@ -105,20 +108,20 @@ BOOST_AUTO_TEST_CASE(ProtoLayerTests) {
// Test 1 - identity transform
auto protoLayer = createProtoLayer(Transform3::Identity());

CHECK_CLOSE_ABS(protoLayer.range(BinningValue::binX), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(BinningValue::binX), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(BinningValue::binX), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(BinningValue::binX), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.range(BinningValue::binY), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(BinningValue::binY), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(BinningValue::binY), -3., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(BinningValue::binY), 3., 1e-8);
CHECK_CLOSE_ABS(protoLayer.range(BinningValue::binZ), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(BinningValue::binZ), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(BinningValue::binZ), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(BinningValue::binZ), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(BinningValue::binR), std::hypot(3, 6), 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(BinningValue::binR), 3., 1e-8);
CHECK_CLOSE_ABS(protoLayer.range(binX), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(binX), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(binX), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(binX), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.range(binY), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(binY), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(binY), -3., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(binY), 3., 1e-8);
CHECK_CLOSE_ABS(protoLayer.range(binZ), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayer.medium(binZ), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(binZ), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(binZ), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayer.max(binR), std::hypot(3, 6), 1e-8);
CHECK_CLOSE_ABS(protoLayer.min(binR), 3., 1e-8);

// Test 1a

Expand All @@ -127,16 +130,15 @@ BOOST_AUTO_TEST_CASE(ProtoLayerTests) {
auto protoLayerRot = createProtoLayer(AngleAxis3(-0.345, Vector3::UnitZ()) *
Transform3::Identity());

BOOST_CHECK_NE(protoLayer.min(BinningValue::binX), -6.);
CHECK_CLOSE_ABS(protoLayerRot.medium(BinningValue::binX), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.medium(BinningValue::binY), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.range(BinningValue::binZ), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.medium(BinningValue::binZ), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.min(BinningValue::binZ), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.max(BinningValue::binZ), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.min(BinningValue::binR), 3., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.max(BinningValue::binR), std::hypot(3, 6),
1e-8);
BOOST_CHECK_NE(protoLayer.min(binX), -6.);
CHECK_CLOSE_ABS(protoLayerRot.medium(binX), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.medium(binY), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.range(binZ), 12., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.medium(binZ), 0., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.min(binZ), -6., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.max(binZ), 6., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.min(binR), 3., 1e-8);
CHECK_CLOSE_ABS(protoLayerRot.max(binR), std::hypot(3, 6), 1e-8);

std::stringstream sstream;
protoLayerRot.toStream(sstream);
Expand All @@ -155,6 +157,111 @@ Extent in space :
BOOST_CHECK_EQUAL(sstream.str(), oString);
}

BOOST_AUTO_TEST_CASE(OrientedLayer) {
using enum BinningValue;
using namespace Acts::UnitLiterals;

Transform3 base = Transform3::Identity();

auto recBounds = std::make_shared<RectangleBounds>(3_mm, 6_mm);

std::vector<std::unique_ptr<DetectorElementBase>> detectorElements;

auto makeFan = [&](double yrot, double thickness = 0) {
detectorElements.clear();

std::size_t nSensors = 8;
double deltaPhi = 2 * M_PI / nSensors;
double r = 20_mm;
std::vector<std::shared_ptr<const Surface>> surfaces;
for (std::size_t i = 0; i < nSensors; i++) {
// Create a fan of sensors

Transform3 trf = base * AngleAxis3{yrot, Vector3::UnitY()} *
AngleAxis3{deltaPhi * i, Vector3::UnitZ()} *
Translation3(Vector3::UnitX() * r);

auto& element = detectorElements.emplace_back(
std::make_unique<DetectorElementStub>(trf, recBounds, thickness));

surfaces.push_back(element->surface().getSharedPtr());
}
return surfaces;
};

std::vector<std::shared_ptr<const Surface>> surfaces = makeFan(0_degree);

ProtoLayer protoLayer(tgContext, surfaces);

BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binZ), 0_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binZ), 0_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binR), 17_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binR), 23.769728648_mm, 1e-8);

surfaces = makeFan(45_degree);

// Do NOT provide rotation matrix: sizing will be affected
protoLayer = {tgContext, surfaces};

BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
BOOST_CHECK_CLOSE(protoLayer.min(binX), -16.26345596_mm, 1e-4);
BOOST_CHECK_CLOSE(protoLayer.max(binX), 16.26345596_mm, 1e-4);
BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binZ), -16.26345596_mm, 1e-4);
BOOST_CHECK_CLOSE(protoLayer.max(binZ), 16.26345596_mm, 1e-4);

protoLayer = {tgContext, surfaces,
Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()};

BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8);
CHECK_SMALL(protoLayer.range(binZ), 1e-14);
CHECK_SMALL(protoLayer.min(binZ), 1e-14);
CHECK_SMALL(protoLayer.max(binZ), 1e-14);

surfaces = makeFan(0_degree, 10_mm);

protoLayer = {tgContext, surfaces};

BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.range(binZ), 10_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binZ), -5_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binZ), 5_mm, 1e-8);

surfaces = makeFan(45_degree, 10_mm);

protoLayer = {tgContext, surfaces,
Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()};

BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8);
BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.range(binZ), 10_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.min(binZ), -5_mm, 1e-8);
BOOST_CHECK_CLOSE(protoLayer.max(binZ), 5_mm, 1e-8);
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace Acts::Test::Layers

0 comments on commit 27ed2c7

Please sign in to comment.