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