File indexing completed on 2025-01-18 09:12:41
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/Geometry/ProtoLayer.hpp"
0014 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0015 #include "Acts/Surfaces/PlanarBounds.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Surfaces/RectangleBounds.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Surfaces/SurfaceArray.hpp"
0020 #include "Acts/Surfaces/SurfaceBounds.hpp"
0021 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0022 #include "Acts/Utilities/Axis.hpp"
0023 #include "Acts/Utilities/AxisDefinitions.hpp"
0024 #include "Acts/Utilities/BinningType.hpp"
0025 #include "Acts/Utilities/Grid.hpp"
0026 #include "Acts/Utilities/Helpers.hpp"
0027 #include "Acts/Utilities/IAxis.hpp"
0028 #include "Acts/Utilities/Logger.hpp"
0029 #include "Acts/Utilities/detail/grid_helper.hpp"
0030 #include "Acts/Visualization/GeometryView3D.hpp"
0031 #include "Acts/Visualization/ObjVisualization3D.hpp"
0032
0033 #include <algorithm>
0034 #include <cmath>
0035 #include <cstddef>
0036 #include <fstream>
0037 #include <iomanip>
0038 #include <iterator>
0039 #include <memory>
0040 #include <numbers>
0041 #include <set>
0042 #include <stdexcept>
0043 #include <string>
0044 #include <tuple>
0045 #include <utility>
0046 #include <vector>
0047
0048 #include <boost/format.hpp>
0049
0050 using Acts::VectorHelpers::perp;
0051 using Acts::VectorHelpers::phi;
0052
0053 namespace Acts::Test {
0054
0055
0056 GeometryContext tgContext = GeometryContext();
0057
0058 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
0059
0060 struct SurfaceArrayCreatorFixture {
0061 SurfaceArrayCreator m_SAC;
0062 std::vector<std::shared_ptr<const Surface>> m_surfaces;
0063
0064 SurfaceArrayCreatorFixture()
0065 : m_SAC(SurfaceArrayCreator::Config(),
0066 Acts::getDefaultLogger("SurfaceArrayCreator",
0067 Acts::Logging::VERBOSE)) {
0068 BOOST_TEST_MESSAGE("setup fixture");
0069 }
0070 ~SurfaceArrayCreatorFixture() { BOOST_TEST_MESSAGE("teardown fixture"); }
0071
0072 template <typename... Args>
0073 SurfaceArrayCreator::ProtoAxis createEquidistantAxis(Args&&... args) {
0074 return m_SAC.createEquidistantAxis(std::forward<Args>(args)...);
0075 }
0076
0077 template <typename... Args>
0078 SurfaceArrayCreator::ProtoAxis createVariableAxis(Args&&... args) {
0079 return m_SAC.createVariableAxis(std::forward<Args>(args)...);
0080 }
0081
0082 template <AxisBoundaryType bdtA, AxisBoundaryType bdtB, typename... Args>
0083 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> makeSurfaceGridLookup2D(
0084 Args&&... args) {
0085 return m_SAC.makeSurfaceGridLookup2D<bdtA, bdtB>(
0086 std::forward<Args>(args)...);
0087 }
0088
0089 SrfVec fullPhiTestSurfacesEC(std::size_t n = 10, double shift = 0,
0090 double zbase = 0, double r = 10, double w = 2,
0091 double h = 1) {
0092 SrfVec res;
0093
0094
0095 double phiStep = 2 * std::numbers::pi / n;
0096 for (std::size_t i = 0; i < n; ++i) {
0097 double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
0098 double phi = std::fma(i, phiStep, shift);
0099
0100 Transform3 trans;
0101 trans.setIdentity();
0102 trans.rotate(Eigen::AngleAxisd(phi, Vector3(0, 0, 1)));
0103 trans.translate(Vector3(r, 0, z));
0104
0105 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0106
0107 std::shared_ptr<Surface> srf =
0108 Surface::makeShared<PlaneSurface>(trans, bounds);
0109
0110 res.push_back(srf);
0111 m_surfaces.push_back(
0112 std::move(srf));
0113 }
0114
0115 return res;
0116 }
0117
0118 SrfVec fullPhiTestSurfacesBRL(std::size_t n = 10, double shift = 0,
0119 double zbase = 0,
0120 double incl = std::numbers::pi / 9.,
0121 double w = 2, double h = 1.5) {
0122 SrfVec res;
0123
0124
0125 double phiStep = 2 * std::numbers::pi / n;
0126 for (std::size_t i = 0; i < n; ++i) {
0127 double z = zbase;
0128 double phi = std::fma(i, phiStep, shift);
0129
0130 Transform3 trans;
0131 trans.setIdentity();
0132 trans.rotate(Eigen::AngleAxisd(phi, Vector3(0, 0, 1)));
0133 trans.translate(Vector3(10, 0, z));
0134 trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
0135 trans.rotate(Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0)));
0136
0137 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0138 std::shared_ptr<Surface> srf =
0139 Surface::makeShared<PlaneSurface>(trans, bounds);
0140
0141 res.push_back(srf);
0142 m_surfaces.push_back(
0143 std::move(srf));
0144 }
0145
0146 return res;
0147 }
0148
0149 SrfVec straightLineSurfaces(
0150 std::size_t n = 10., double step = 3, const Vector3& origin = {0, 0, 1.5},
0151 const Transform3& pretrans = Transform3::Identity(),
0152 const Vector3& dir = {0, 0, 1}) {
0153 SrfVec res;
0154 for (std::size_t i = 0; i < n; ++i) {
0155 Transform3 trans;
0156 trans.setIdentity();
0157 trans.translate(origin + dir * step * i);
0158
0159 trans.rotate(AngleAxis3(std::numbers::pi / 2., Vector3(1, 0, 0)));
0160 trans = trans * pretrans;
0161
0162 auto bounds = std::make_shared<const RectangleBounds>(2, 1.5);
0163
0164 std::shared_ptr<Surface> srf =
0165 Surface::makeShared<PlaneSurface>(trans, bounds);
0166
0167 res.push_back(srf);
0168 m_surfaces.push_back(
0169 std::move(srf));
0170 }
0171
0172 return res;
0173 }
0174
0175 SrfVec makeBarrel(int nPhi, int nZ, double w, double h) {
0176 double z0 = -(nZ - 1) * w;
0177 SrfVec res;
0178
0179 for (int i = 0; i < nZ; i++) {
0180 double z = i * w * 2 + z0;
0181
0182 SrfVec ring =
0183 fullPhiTestSurfacesBRL(nPhi, 0, z, std::numbers::pi / 9., w, h);
0184 res.insert(res.end(), ring.begin(), ring.end());
0185 }
0186
0187 return res;
0188 }
0189
0190 std::pair<SrfVec, std::vector<std::pair<const Surface*, const Surface*>>>
0191 makeBarrelStagger(int nPhi, int nZ, double shift = 0,
0192 double incl = std::numbers::pi / 9., double w = 2,
0193 double h = 1.5) {
0194 double z0 = -(nZ - 1) * w;
0195 SrfVec res;
0196 std::vector<std::pair<const Surface*, const Surface*>> pairs;
0197
0198
0199 double phiStep = 2 * std::numbers::pi / nPhi;
0200 for (int i = 0; i < nZ; i++) {
0201 double z = i * w * 2 + z0;
0202 for (int j = 0; j < nPhi; ++j) {
0203 double phi = std::fma(j, phiStep, shift);
0204 Transform3 trans;
0205 trans.setIdentity();
0206 trans.rotate(Eigen::AngleAxisd(phi, Vector3(0, 0, 1)));
0207 trans.translate(Vector3(10, 0, z));
0208 trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
0209 trans.rotate(
0210 Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0)));
0211
0212 auto bounds = std::make_shared<const RectangleBounds>(w, h);
0213 std::shared_ptr<PlaneSurface> srfA =
0214 Surface::makeShared<PlaneSurface>(trans, bounds);
0215
0216 Vector3 nrm = srfA->normal(tgContext);
0217 Transform3 transB = trans;
0218 transB.pretranslate(nrm * 0.1);
0219 std::shared_ptr<Surface> srfB =
0220 Surface::makeShared<PlaneSurface>(transB, bounds);
0221
0222 pairs.push_back(std::make_pair(srfA.get(), srfB.get()));
0223
0224 res.push_back(srfA);
0225 res.push_back(srfB);
0226 m_surfaces.push_back(std::move(srfA));
0227 m_surfaces.push_back(std::move(srfB));
0228 }
0229 }
0230
0231 return {res, pairs};
0232 }
0233 };
0234
0235 void draw_surfaces(const SrfVec& surfaces, const std::string& fname) {
0236 std::ofstream os;
0237 os.open(fname);
0238
0239 os << std::fixed << std::setprecision(4);
0240
0241 std::size_t nVtx = 0;
0242 for (const auto& srfx : surfaces) {
0243 std::shared_ptr<const PlaneSurface> srf =
0244 std::dynamic_pointer_cast<const PlaneSurface>(srfx);
0245 const PlanarBounds* bounds =
0246 dynamic_cast<const PlanarBounds*>(&srf->bounds());
0247
0248 for (const auto& vtxloc : bounds->vertices()) {
0249 Vector3 vtx =
0250 srf->transform(tgContext) * Vector3(vtxloc.x(), vtxloc.y(), 0);
0251 os << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
0252 }
0253
0254
0255 os << "f";
0256 for (std::size_t i = 1; i <= bounds->vertices().size(); ++i) {
0257 os << " " << nVtx + i;
0258 }
0259 os << "\n";
0260
0261 nVtx += bounds->vertices().size();
0262 }
0263
0264 os.close();
0265 }
0266
0267 BOOST_AUTO_TEST_SUITE(Tools)
0268
0269 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi,
0270 SurfaceArrayCreatorFixture) {
0271
0272 std::vector<const Surface*> emptyRaw;
0273 ProtoLayer pl(tgContext, emptyRaw);
0274 auto tr = Transform3::Identity();
0275 BOOST_CHECK_THROW(createEquidistantAxis(tgContext, emptyRaw,
0276 AxisDirection::AxisPhi, pl, tr),
0277 std::logic_error);
0278
0279 std::vector<float> bdExp = {
0280 -3.14159, -2.93215, -2.72271, -2.51327, -2.30383, -2.0944, -1.88496,
0281 -1.67552, -1.46608, -1.25664, -1.0472, -0.837758, -0.628319, -0.418879,
0282 -0.20944, 0, 0.20944, 0.418879, 0.628319, 0.837758, 1.0472,
0283 1.25664, 1.46608, 1.67552, 1.88496, 2.09439, 2.30383, 2.51327,
0284 2.72271, 2.93215, 3.14159};
0285
0286 double step = 2 * std::numbers::pi / 30.;
0287
0288
0289
0290 for (int i = -1; i <= 2; i += 2) {
0291 double z = 10 * i;
0292
0293 double angleShift = step / 2.;
0294 auto surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
0295 std::vector<const Surface*> surfacesRaw = unpack_shared_vector(surfaces);
0296 pl = ProtoLayer(tgContext, surfacesRaw);
0297 tr = Transform3::Identity();
0298 auto axis = createEquidistantAxis(tgContext, surfacesRaw,
0299 AxisDirection::AxisPhi, pl, tr);
0300
0301 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0302 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0303 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0304 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0305 CHECK_SMALL(phi(tr * Vector3::UnitX()), 1e-6);
0306
0307
0308 angleShift = 0.;
0309 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
0310 surfacesRaw = unpack_shared_vector(surfaces);
0311 pl = ProtoLayer(tgContext, surfacesRaw);
0312 tr = Transform3::Identity();
0313 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0314 pl, tr);
0315 draw_surfaces(surfaces,
0316 "SurfaceArrayCreator_createEquidistantAxis_EC_2.obj");
0317 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0318 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0319 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0320 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0321
0322 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), -0.5 * step, 1e-3);
0323
0324 angleShift = step / -4.;
0325 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
0326 surfacesRaw = unpack_shared_vector(surfaces);
0327 pl = ProtoLayer(tgContext, surfacesRaw);
0328 tr = Transform3::Identity();
0329 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0330 pl, tr);
0331 draw_surfaces(surfaces,
0332 "SurfaceArrayCreator_createEquidistantAxis_EC_3.obj");
0333 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0334 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0335 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0336 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0337 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), step / -4., 1e-3);
0338
0339
0340 angleShift = step / 4.;
0341 surfaces = fullPhiTestSurfacesEC(30, angleShift, z);
0342 surfacesRaw = unpack_shared_vector(surfaces);
0343 pl = ProtoLayer(tgContext, surfaces);
0344 surfacesRaw = unpack_shared_vector(surfaces);
0345 tr = Transform3::Identity();
0346 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0347 pl, tr);
0348 surfacesRaw = unpack_shared_vector(surfaces);
0349 draw_surfaces(surfaces,
0350 "SurfaceArrayCreator_createEquidistantAxis_EC_4.obj");
0351 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0352 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0353 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0354 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0355 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), step / 4., 1e-3);
0356 }
0357
0358 for (int i = -1; i <= 2; i += 2) {
0359 double z = 10 * i;
0360
0361 double angleShift = step / 2.;
0362 auto surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
0363 auto surfacesRaw = unpack_shared_vector(surfaces);
0364 pl = ProtoLayer(tgContext, surfacesRaw);
0365 tr = Transform3::Identity();
0366 auto axis = createEquidistantAxis(tgContext, surfacesRaw,
0367 AxisDirection::AxisPhi, pl, tr);
0368 draw_surfaces(surfaces,
0369 "SurfaceArrayCreator_createEquidistantAxis_BRL_1.obj");
0370 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0371 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0372 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0373 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0374 CHECK_SMALL(phi(tr * Vector3::UnitX()), 1e-6);
0375
0376
0377 angleShift = 0.;
0378 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
0379 surfacesRaw = unpack_shared_vector(surfaces);
0380 pl = ProtoLayer(tgContext, surfacesRaw);
0381 tr = Transform3::Identity();
0382 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0383 pl, tr);
0384 draw_surfaces(surfaces,
0385 "SurfaceArrayCreator_createEquidistantAxis_BRL_2.obj");
0386 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0387 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0388 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0389 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0390
0391 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), -0.5 * step, 1e-3);
0392
0393
0394 angleShift = step / -4.;
0395 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
0396 surfacesRaw = unpack_shared_vector(surfaces);
0397 pl = ProtoLayer(tgContext, surfacesRaw);
0398 tr = Transform3::Identity();
0399 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0400 pl, tr);
0401 draw_surfaces(surfaces,
0402 "SurfaceArrayCreator_createEquidistantAxis_BRL_3.obj");
0403 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0404 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0405 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0406 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0407
0408 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), step / -4., 1e-3);
0409
0410
0411 angleShift = step / 4.;
0412 surfaces = fullPhiTestSurfacesBRL(30, angleShift, z);
0413 surfacesRaw = unpack_shared_vector(surfaces);
0414 pl = ProtoLayer(tgContext, surfacesRaw);
0415 tr = Transform3::Identity();
0416 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi,
0417 pl, tr);
0418 draw_surfaces(surfaces,
0419 "SurfaceArrayCreator_createEquidistantAxis_BRL_4.obj");
0420 BOOST_CHECK_EQUAL(axis.nBins, 30u);
0421 CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6);
0422 CHECK_CLOSE_REL(axis.min, -std::numbers::pi, 1e-6);
0423 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0424
0425 CHECK_CLOSE_REL(phi(tr * Vector3::UnitX()), step / 4., 1e-3);
0426 }
0427
0428 SrfVec surfaces;
0429
0430
0431 surfaces = fullPhiTestSurfacesEC(1);
0432 auto surfacesRaw = unpack_shared_vector(surfaces);
0433 draw_surfaces(surfaces,
0434 "SurfaceArrayCreator_createEquidistantAxis_EC_Single.obj");
0435
0436 pl = ProtoLayer(tgContext, surfacesRaw);
0437 tr = Transform3::Identity();
0438 auto axis = createEquidistantAxis(tgContext, surfacesRaw,
0439 AxisDirection::AxisPhi, pl, tr);
0440 BOOST_CHECK_EQUAL(axis.nBins, 1u);
0441
0442 CHECK_CLOSE_ABS(axis.max, phi(Vector3(8, 1, 0)), 1e-3);
0443 CHECK_CLOSE_ABS(axis.min, phi(Vector3(8, -1, 0)), 1e-3);
0444 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0445 }
0446
0447 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Z,
0448 SurfaceArrayCreatorFixture) {
0449
0450 auto surfaces = straightLineSurfaces(1);
0451 auto surfacesRaw = unpack_shared_vector(surfaces);
0452 ProtoLayer pl = ProtoLayer(tgContext, surfacesRaw);
0453 auto trf = Transform3::Identity();
0454 auto axis = createEquidistantAxis(tgContext, surfacesRaw,
0455 AxisDirection::AxisZ, pl, trf);
0456 draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_Z_1.obj");
0457 BOOST_CHECK_EQUAL(axis.nBins, 1u);
0458 CHECK_CLOSE_ABS(axis.max, 3, 1e-6);
0459 CHECK_CLOSE_ABS(axis.min, 0, 1e-6);
0460 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0461
0462
0463 for (std::size_t i = 0; i <= 20; i++) {
0464 double z0 = -10 + 1. * i;
0465 surfaces = straightLineSurfaces(10, 3, Vector3(0, 0, z0 + 1.5));
0466 surfacesRaw = unpack_shared_vector(surfaces);
0467 pl = ProtoLayer(tgContext, surfacesRaw);
0468 trf = Transform3::Identity();
0469 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisZ,
0470 pl, trf);
0471 draw_surfaces(
0472 surfaces,
0473 (boost::format(
0474 "SurfaceArrayCreator_createEquidistantAxis_Z_2_%1%.obj") %
0475 i)
0476 .str());
0477 BOOST_CHECK_EQUAL(axis.nBins, 10u);
0478 CHECK_CLOSE_ABS(axis.max, 30 + z0, 1e-6);
0479 CHECK_CLOSE_ABS(axis.min, z0, 1e-6);
0480 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0481 }
0482
0483
0484 Transform3 tr = Transform3::Identity();
0485 tr.rotate(AngleAxis3(std::numbers::pi / 4., Vector3(0, 0, 1)));
0486 surfaces = straightLineSurfaces(10, 3, Vector3(0, 0, 0 + 1.5), tr);
0487 surfacesRaw = unpack_shared_vector(surfaces);
0488 pl = ProtoLayer(tgContext, surfacesRaw);
0489 trf = Transform3::Identity();
0490 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisZ, pl,
0491 trf);
0492 draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_Z_3.obj");
0493 BOOST_CHECK_EQUAL(axis.nBins, 10u);
0494 CHECK_CLOSE_ABS(axis.max, 30.9749, 1e-3);
0495 CHECK_CLOSE_ABS(axis.min, -0.974873, 1e-3);
0496 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0497 }
0498
0499 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_R,
0500 SurfaceArrayCreatorFixture) {
0501
0502 auto surfaces = fullPhiTestSurfacesEC(1, 0, 0, 15);
0503 auto surfacesRaw = unpack_shared_vector(surfaces);
0504 draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_R_1.obj");
0505 auto trf = Transform3::Identity();
0506 ProtoLayer pl = ProtoLayer(tgContext, surfacesRaw);
0507 auto axis = createEquidistantAxis(tgContext, surfacesRaw,
0508 AxisDirection::AxisR, pl, trf);
0509 BOOST_CHECK_EQUAL(axis.nBins, 1u);
0510 CHECK_CLOSE_ABS(axis.max, perp(Vector3(17, 1, 0)), 1e-3);
0511 CHECK_CLOSE_ABS(axis.min, 13, 1e-3);
0512 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0513
0514
0515 surfaces.resize(0);
0516 auto ringa = fullPhiTestSurfacesEC(30, 0, 0, 10);
0517 surfaces.insert(surfaces.end(), ringa.begin(), ringa.end());
0518 auto ringb = fullPhiTestSurfacesEC(30, 0, 0, 15);
0519 surfaces.insert(surfaces.end(), ringb.begin(), ringb.end());
0520 auto ringc = fullPhiTestSurfacesEC(30, 0, 0, 20);
0521 surfaces.insert(surfaces.end(), ringc.begin(), ringc.end());
0522 draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_R_2.obj");
0523
0524 surfacesRaw = unpack_shared_vector(surfaces);
0525 pl = ProtoLayer(tgContext, surfacesRaw);
0526 trf = Transform3::Identity();
0527 axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisR, pl,
0528 trf);
0529
0530 BOOST_CHECK_EQUAL(axis.nBins, 3u);
0531 CHECK_CLOSE_REL(axis.max, perp(Vector3(20 + 2, 1, 0)), 1e-3);
0532 CHECK_CLOSE_ABS(axis.min, 8, 1e-3);
0533 BOOST_CHECK_EQUAL(axis.bType, equidistant);
0534 }
0535
0536
0537
0538
0539
0540
0541 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_dependentBinCounts,
0542 SurfaceArrayCreatorFixture) {
0543 auto ringA = fullPhiTestSurfacesEC(10, 0, 0, 10, 2, 3);
0544 auto ringB = fullPhiTestSurfacesEC(15, 0, 0, 15, 2, 3.5);
0545 auto ringC = fullPhiTestSurfacesEC(20, 0, 0, 20, 2, 3.8);
0546
0547 std::vector<std::shared_ptr<const Surface>> surfaces;
0548 std::copy(ringA.begin(), ringA.end(), std::back_inserter(surfaces));
0549 std::copy(ringB.begin(), ringB.end(), std::back_inserter(surfaces));
0550 std::copy(ringC.begin(), ringC.end(), std::back_inserter(surfaces));
0551 draw_surfaces(surfaces, "SurfaceArrayCreator_dependentBinCounts.obj");
0552
0553 std::unique_ptr<SurfaceArray> sArray =
0554 m_SAC.surfaceArrayOnDisc(tgContext, surfaces, equidistant, equidistant);
0555 auto axes = sArray->getAxes();
0556 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 3u);
0557 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 10u);
0558
0559
0560 ObjVisualization3D objVis;
0561 GeometryView3D::drawSurfaceArray(objVis, *sArray, tgContext);
0562 objVis.write("SurfaceArrayCreator_EndcapGrid");
0563 }
0564
0565 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_completeBinning,
0566 SurfaceArrayCreatorFixture) {
0567 SrfVec brl = makeBarrel(30, 7, 2, 1);
0568 std::vector<const Surface*> brlRaw = unpack_shared_vector(brl);
0569 draw_surfaces(brl, "SurfaceArrayCreator_completeBinning_BRL.obj");
0570
0571 Axis<AxisType::Equidistant, AxisBoundaryType::Closed> phiAxis(
0572 -std::numbers::pi, std::numbers::pi, 30u);
0573 Axis<AxisType::Equidistant, AxisBoundaryType::Bound> zAxis(-14, 14, 7u);
0574
0575 double R = 10.;
0576 auto globalToLocal = [](const Vector3& pos) {
0577 return Vector2(phi(pos) + 2 * std::numbers::pi / 30 / 2, pos.z());
0578 };
0579 auto localToGlobal = [R](const Vector2& loc) {
0580 double phi = loc[0] - 2 * std::numbers::pi / 30 / 2;
0581 return Vector3(R * std::cos(phi), R * std::sin(phi), loc[1]);
0582 };
0583
0584 auto sl = std::make_unique<
0585 SurfaceArray::SurfaceGridLookup<decltype(phiAxis), decltype(zAxis)>>(
0586 globalToLocal, localToGlobal,
0587 std::make_tuple(std::move(phiAxis), std::move(zAxis)));
0588 sl->fill(tgContext, brlRaw);
0589 SurfaceArray sa(std::move(sl), brl);
0590
0591
0592 ObjVisualization3D objVis;
0593 GeometryView3D::drawSurfaceArray(objVis, sa, tgContext);
0594 objVis.write("SurfaceArrayCreator_BarrelGrid");
0595
0596
0597 for (const auto& srf : brl) {
0598 Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR);
0599 auto binContent = sa.at(ctr);
0600
0601 BOOST_CHECK_EQUAL(binContent.size(), 1u);
0602 BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
0603 }
0604 }
0605
0606 BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_barrelStagger,
0607 SurfaceArrayCreatorFixture) {
0608 auto barrel = makeBarrelStagger(30, 7, 0, std::numbers::pi / 9.);
0609 auto brl = barrel.first;
0610 std::vector<const Surface*> brlRaw = unpack_shared_vector(brl);
0611 draw_surfaces(brl, "SurfaceArrayCreator_barrelStagger.obj");
0612
0613 ProtoLayer pl(tgContext, brl);
0614
0615
0616 Transform3 tr = Transform3::Identity();
0617
0618 auto pAxisPhi =
0619 createEquidistantAxis(tgContext, brlRaw, AxisDirection::AxisPhi, pl, tr);
0620 auto pAxisZ =
0621 createEquidistantAxis(tgContext, brlRaw, AxisDirection::AxisZ, pl, tr);
0622
0623 double R = 10.;
0624 Transform3 itr = tr.inverse();
0625
0626 auto globalToLocal = [tr](const Vector3& pos) {
0627 Vector3 rot = tr * pos;
0628 return Vector2(phi(rot), rot.z());
0629 };
0630 auto localToGlobal = [R, itr](const Vector2& loc) {
0631 return itr * Vector3(R * std::cos(loc[0]), R * std::sin(loc[0]), loc[1]);
0632 };
0633
0634 auto sl = makeSurfaceGridLookup2D<AxisBoundaryType::Closed,
0635 AxisBoundaryType::Bound>(
0636 globalToLocal, localToGlobal, pAxisPhi, pAxisZ);
0637
0638 sl->fill(tgContext, brlRaw);
0639 SurfaceArray sa(std::move(sl), brl);
0640 auto axes = sa.getAxes();
0641 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0642 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0643
0644 for (const auto& pr : barrel.second) {
0645 auto A = pr.first;
0646 auto B = pr.second;
0647
0648 Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR);
0649 auto binContent = sa.at(ctr);
0650 BOOST_CHECK_EQUAL(binContent.size(), 2u);
0651 std::set<const Surface*> act;
0652 act.insert(binContent[0]);
0653 act.insert(binContent[1]);
0654
0655 std::set<const Surface*> exp;
0656 exp.insert(A);
0657 exp.insert(B);
0658
0659 BOOST_CHECK(act == exp);
0660 }
0661
0662
0663 BOOST_TEST_CONTEXT("Barrel Stagger Variable binning") {
0664 tr = Transform3::Identity();
0665
0666 auto pAxisPhiVar =
0667 createVariableAxis(tgContext, brlRaw, AxisDirection::AxisPhi, pl, tr);
0668 auto pAxisZVar =
0669 createVariableAxis(tgContext, brlRaw, AxisDirection::AxisZ, pl, tr);
0670
0671 itr = tr.inverse();
0672
0673 auto globalToLocalVar = [tr](const Vector3& pos) {
0674 Vector3 rot = tr * pos;
0675 return Vector2(phi(rot), rot.z());
0676 };
0677 auto localToGlobalVar = [R, itr](const Vector2& loc) {
0678 return itr * Vector3(R * std::cos(loc[0]), R * std::sin(loc[0]), loc[1]);
0679 };
0680
0681 auto sl2 = makeSurfaceGridLookup2D<AxisBoundaryType::Closed,
0682 AxisBoundaryType::Bound>(
0683 globalToLocalVar, localToGlobalVar, pAxisPhiVar, pAxisZVar);
0684
0685 sl2->fill(tgContext, brlRaw);
0686 SurfaceArray sa2(std::move(sl2), brl);
0687 axes = sa2.getAxes();
0688 BOOST_CHECK_EQUAL(axes.at(0)->getNBins(), 30u);
0689 BOOST_CHECK_EQUAL(axes.at(1)->getNBins(), 7u);
0690
0691
0692 std::vector<double> phiEdgesExp = {
0693 -3.14159, -2.93215, -2.72271, -2.51327, -2.30383, -2.0944,
0694 -1.88496, -1.67552, -1.46608, -1.25664, -1.0472, -0.837758,
0695 -0.628319, -0.418879, -0.20944, 4.44089e-16, 0.20944, 0.418879,
0696 0.628319, 0.837758, 1.0472, 1.25664, 1.46608, 1.67552,
0697 1.88496, 2.0944, 2.30383, 2.51327, 2.72271, 3.00831,
0698 3.14159};
0699 std::vector<double> zEdgesExp = {-14, -10, -6, -2, 2, 6, 10, 14};
0700 std::size_t i = 0;
0701 for (const auto& edge : axes.at(0)->getBinEdges()) {
0702 BOOST_TEST_INFO("phi edge index " << i);
0703 auto phiEdge = phiEdgesExp.at(i);
0704 CHECK_CLOSE_ABS(edge, phiEdge, 1e-5 * std::numbers::pi);
0705 i++;
0706 }
0707 i = 0;
0708 for (const auto& edge : axes.at(1)->getBinEdges()) {
0709 BOOST_TEST_INFO("z edge index " << i);
0710 CHECK_CLOSE_ABS(edge, zEdgesExp.at(i), 1e-6);
0711 i++;
0712 }
0713
0714 for (const auto& pr : barrel.second) {
0715 auto A = pr.first;
0716 auto B = pr.second;
0717
0718 Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR);
0719 auto binContent = sa2.at(ctr);
0720 BOOST_CHECK_EQUAL(binContent.size(), 2u);
0721 std::set<const Surface*> act;
0722 act.insert(binContent[0]);
0723 act.insert(binContent[1]);
0724
0725 std::set<const Surface*> exp;
0726 exp.insert(A);
0727 exp.insert(B);
0728
0729 BOOST_CHECK(act == exp);
0730 }
0731 }
0732 }
0733
0734 BOOST_AUTO_TEST_SUITE_END()
0735 }