File indexing completed on 2025-01-18 09:12:52
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Surfaces/PlanarBounds.hpp"
0014 #include "Acts/Surfaces/PlaneSurface.hpp"
0015 #include "Acts/Surfaces/RectangleBounds.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Surfaces/SurfaceArray.hpp"
0018 #include "Acts/Utilities/Axis.hpp"
0019 #include "Acts/Utilities/AxisDefinitions.hpp"
0020 #include "Acts/Utilities/BinningType.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022
0023 #include <cmath>
0024 #include <cstddef>
0025 #include <fstream>
0026 #include <iomanip>
0027 #include <iostream>
0028 #include <memory>
0029 #include <numbers>
0030 #include <string>
0031 #include <tuple>
0032 #include <utility>
0033 #include <vector>
0034
0035 #include <boost/format.hpp>
0036
0037 using Acts::VectorHelpers::phi;
0038
0039 namespace Acts::Test {
0040
0041
0042 GeometryContext tgContext = GeometryContext();
0043
0044 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
0045 struct SurfaceArrayFixture {
0046 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0047
0048 SurfaceArrayFixture() { BOOST_TEST_MESSAGE("setup fixture"); }
0049 ~SurfaceArrayFixture() { BOOST_TEST_MESSAGE("teardown fixture"); }
0050
0051 SrfVec fullPhiTestSurfacesEC(std::size_t n = 10, double shift = 0,
0052 double zbase = 0, double r = 10) {
0053 SrfVec res;
0054
0055 double phiStep = 2 * std::numbers::pi / n;
0056 for (std::size_t i = 0; i < n; ++i) {
0057 double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
0058
0059 Transform3 trans;
0060 trans.setIdentity();
0061 trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
0062 trans.translate(Vector3(r, 0, z));
0063
0064 auto bounds = std::make_shared<const RectangleBounds>(2, 1);
0065 std::shared_ptr<const Surface> srf =
0066 Surface::makeShared<PlaneSurface>(trans, bounds);
0067
0068 res.push_back(srf);
0069 m_surfaces.push_back(
0070 std::move(srf));
0071 }
0072
0073 return res;
0074 }
0075
0076 SrfVec fullPhiTestSurfacesBRL(int n = 10, double shift = 0, double zbase = 0,
0077 double incl = std::numbers::pi / 9.,
0078 double w = 2, double h = 1.5) {
0079 SrfVec res;
0080
0081 double phiStep = 2 * std::numbers::pi / n;
0082 for (int i = 0; i < n; ++i) {
0083 double z = zbase;
0084
0085 Transform3 trans;
0086 trans.setIdentity();
0087 trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
0088 trans.translate(Vector3(10, 0, z));
0089 trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
0090 trans.rotate(Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0)));
0091
0092 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0093 std::shared_ptr<const Surface> srf =
0094 Surface::makeShared<PlaneSurface>(trans, bounds);
0095
0096 res.push_back(srf);
0097 m_surfaces.push_back(
0098 std::move(srf));
0099 }
0100
0101 return res;
0102 }
0103
0104 SrfVec straightLineSurfaces(
0105 std::size_t n = 10., double step = 3, const Vector3& origin = {0, 0, 1.5},
0106 const Transform3& pretrans = Transform3::Identity(),
0107 const Vector3& dir = {0, 0, 1}) {
0108 SrfVec res;
0109 for (std::size_t i = 0; i < n; ++i) {
0110 Transform3 trans;
0111 trans.setIdentity();
0112 trans.translate(origin + dir * step * i);
0113
0114 trans.rotate(AngleAxis3(std::numbers::pi / 2., Vector3(1, 0, 0)));
0115 trans = trans * pretrans;
0116
0117 auto bounds = std::make_shared<const RectangleBounds>(2, 1.5);
0118
0119 std::shared_ptr<const Surface> srf =
0120 Surface::makeShared<PlaneSurface>(trans, bounds);
0121
0122 res.push_back(srf);
0123 m_surfaces.push_back(
0124 std::move(srf));
0125 }
0126
0127 return res;
0128 }
0129
0130 SrfVec makeBarrel(int nPhi, int nZ, double w, double h) {
0131 double z0 = -(nZ - 1) * w;
0132 SrfVec res;
0133
0134 for (int i = 0; i < nZ; i++) {
0135 double z = i * w * 2 + z0;
0136 SrfVec ring =
0137 fullPhiTestSurfacesBRL(nPhi, 0, z, std::numbers::pi / 9., w, h);
0138 res.insert(res.end(), ring.begin(), ring.end());
0139 }
0140
0141 return res;
0142 }
0143
0144 void draw_surfaces(const SrfVec& surfaces, const std::string& fname) {
0145 std::ofstream os;
0146 os.open(fname);
0147
0148 os << std::fixed << std::setprecision(4);
0149
0150 std::size_t nVtx = 0;
0151 for (const auto& srfx : surfaces) {
0152 std::shared_ptr<const PlaneSurface> srf =
0153 std::dynamic_pointer_cast<const PlaneSurface>(srfx);
0154 const PlanarBounds* bounds =
0155 dynamic_cast<const PlanarBounds*>(&srf->bounds());
0156
0157 for (const auto& vtxloc : bounds->vertices()) {
0158 Vector3 vtx =
0159 srf->transform(tgContext) * Vector3(vtxloc.x(), vtxloc.y(), 0);
0160 os << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
0161 }
0162
0163
0164 os << "f";
0165 for (std::size_t i = 1; i <= bounds->vertices().size(); ++i) {
0166 os << " " << nVtx + i;
0167 }
0168 os << "\n";
0169
0170 nVtx += bounds->vertices().size();
0171 }
0172
0173 os.close();
0174 }
0175 };
0176
0177 BOOST_AUTO_TEST_SUITE(Surfaces)
0178
0179 BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) {
0180 GeometryContext tgContext = GeometryContext();
0181
0182 SrfVec brl = makeBarrel(30, 7, 2, 1);
0183 std::vector<const Surface*> brlRaw = unpack_shared_vector(brl);
0184 draw_surfaces(brl, "SurfaceArray_create_BRL_1.obj");
0185
0186 Axis<AxisType::Equidistant, AxisBoundaryType::Closed> phiAxis(
0187 -std::numbers::pi, std::numbers::pi, 30u);
0188 Axis<AxisType::Equidistant, AxisBoundaryType::Bound> zAxis(-14, 14, 7u);
0189
0190 double angleShift = 2 * std::numbers::pi / 30. / 2.;
0191 auto transform = [angleShift](const Vector3& pos) {
0192 return Vector2(phi(pos) + angleShift, pos.z());
0193 };
0194 double R = 10;
0195 auto itransform = [angleShift, R](const Vector2& loc) {
0196 return Vector3(R * std::cos(loc[0] - angleShift),
0197 R * std::sin(loc[0] - angleShift), loc[1]);
0198 };
0199
0200 auto sl = std::make_unique<
0201 SurfaceArray::SurfaceGridLookup<decltype(phiAxis), decltype(zAxis)>>(
0202 transform, itransform,
0203 std::make_tuple(std::move(phiAxis), std::move(zAxis)));
0204 sl->fill(tgContext, brlRaw);
0205 SurfaceArray sa(std::move(sl), brl);
0206
0207
0208 sa.toStream(tgContext, std::cout);
0209
0210 for (const auto& srf : brl) {
0211 Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR);
0212 std::vector<const Surface*> binContent = sa.at(ctr);
0213
0214 BOOST_CHECK_EQUAL(binContent.size(), 1u);
0215 BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
0216 }
0217
0218 std::vector<const Surface*> neighbors =
0219 sa.neighbors(itransform(Vector2(0, 0)));
0220 BOOST_CHECK_EQUAL(neighbors.size(), 9u);
0221
0222 auto sl2 = std::make_unique<
0223 SurfaceArray::SurfaceGridLookup<decltype(phiAxis), decltype(zAxis)>>(
0224 transform, itransform,
0225 std::make_tuple(std::move(phiAxis), std::move(zAxis)));
0226
0227 sl2->completeBinning(tgContext, brlRaw);
0228 SurfaceArray sa2(std::move(sl2), brl);
0229 sa.toStream(tgContext, std::cout);
0230 for (const auto& srf : brl) {
0231 Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR);
0232 std::vector<const Surface*> binContent = sa2.at(ctr);
0233
0234 BOOST_CHECK_EQUAL(binContent.size(), 1u);
0235 BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
0236 }
0237 }
0238
0239 BOOST_AUTO_TEST_CASE(SurfaceArray_singleElement) {
0240 const double w = 3;
0241 const double h = 4;
0242 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0243 auto srf = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
0244
0245 SurfaceArray sa(srf);
0246
0247 auto binContent = sa.at(Vector3(42, 42, 42));
0248 BOOST_CHECK_EQUAL(binContent.size(), 1u);
0249 BOOST_CHECK_EQUAL(binContent.at(0), srf.get());
0250 BOOST_CHECK_EQUAL(sa.surfaces().size(), 1u);
0251 BOOST_CHECK_EQUAL(sa.surfaces().at(0), srf.get());
0252 }
0253
0254 BOOST_AUTO_TEST_CASE(SurfaceArray_manyElementsSingleLookup) {
0255 const double w = 3;
0256 const double h = 4;
0257 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0258 auto srf0 = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
0259 auto srf1 = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
0260
0261 std::vector<const Surface*> sfPointers = {srf0.get(), srf1.get()};
0262 std::vector<std::shared_ptr<const Surface>> surfaces = {srf0, srf1};
0263
0264 auto singleLookUp =
0265 std::make_unique<Acts::SurfaceArray::SingleElementLookup>(sfPointers);
0266
0267 SurfaceArray sa(std::move(singleLookUp), surfaces);
0268
0269 auto binContent = sa.at(Vector3(42, 42, 42));
0270 BOOST_CHECK_EQUAL(binContent.size(), 2u);
0271 BOOST_CHECK_EQUAL(sa.surfaces().size(), 2u);
0272 }
0273
0274 BOOST_AUTO_TEST_SUITE_END()
0275 }