File indexing completed on 2025-01-18 09:12:32
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/Detector/Detector.hpp"
0013 #include "Acts/Detector/DetectorComponents.hpp"
0014 #include "Acts/Detector/DetectorVolume.hpp"
0015 #include "Acts/Detector/GeometryIdGenerator.hpp"
0016 #include "Acts/Detector/PortalGenerators.hpp"
0017 #include "Acts/Detector/detail/CylindricalDetectorHelper.hpp"
0018 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0019 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0020 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0023 #include "Acts/Navigation/InternalNavigation.hpp"
0024 #include "Acts/Utilities/Enumerate.hpp"
0025 #include "Acts/Utilities/Logger.hpp"
0026
0027 #include <algorithm>
0028 #include <array>
0029 #include <cmath>
0030 #include <iterator>
0031 #include <map>
0032 #include <memory>
0033 #include <numbers>
0034 #include <ostream>
0035 #include <stdexcept>
0036 #include <string>
0037 #include <utility>
0038 #include <vector>
0039
0040 namespace Acts::Experimental {
0041 class Portal;
0042 }
0043
0044 using namespace Acts;
0045 using namespace Experimental;
0046 using namespace Experimental::detail;
0047 using namespace Experimental::detail::CylindricalDetectorHelper;
0048
0049 Logging::Level logLevel = Logging::VERBOSE;
0050
0051 GeometryContext tContext;
0052 std::vector<std::shared_ptr<DetectorVolume>> eVolumes = {};
0053
0054 auto portalGenerator = defaultPortalGenerator();
0055
0056 BOOST_AUTO_TEST_SUITE(Experimental)
0057
0058 BOOST_AUTO_TEST_CASE(ConnectVolumeExceptions) {
0059 ACTS_LOCAL_LOGGER(getDefaultLogger("Faulty setups", logLevel));
0060
0061 auto cBounds0 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0062 auto volume0 = DetectorVolumeFactory::construct(
0063 portalGenerator, tContext, "Volume0", Transform3::Identity(),
0064 std::move(cBounds0), tryAllPortals());
0065
0066 auto cBounds1 =
0067 std::make_unique<CylinderVolumeBounds>(0., 100., 100, 0.2, 1.);
0068 auto volume1 = DetectorVolumeFactory::construct(
0069 portalGenerator, tContext, "Volume0", Transform3::Identity(),
0070 std::move(cBounds1), tryAllPortals());
0071
0072 ACTS_INFO("*** Test: nullptr in the list of volumes");
0073
0074
0075 std::vector<std::shared_ptr<DetectorVolume>> volumesWithNullptr = {
0076 volume0, nullptr, volume1};
0077 BOOST_CHECK_THROW(connectInR(tContext, volumesWithNullptr, {}, logLevel),
0078 std::invalid_argument);
0079
0080 ACTS_INFO("*** Test: non-cylinder in the list of volumes");
0081
0082 auto cubeBounds = std::make_unique<CuboidVolumeBounds>(100., 100., 100);
0083 auto cube = DetectorVolumeFactory::construct(
0084 portalGenerator, tContext, "Cube", Transform3::Identity(),
0085 std::move(cubeBounds), tryAllPortals());
0086
0087
0088 std::vector<std::shared_ptr<DetectorVolume>> volumesWithCube = {
0089 volume0, volume1, cube};
0090 BOOST_CHECK_THROW(connectInR(tContext, volumesWithCube, {}, logLevel),
0091 std::invalid_argument);
0092
0093 ACTS_INFO("*** Test: non-aligned volume in the list of volumes");
0094 Transform3 rotated = Transform3::Identity();
0095 AngleAxis3 rotX(0.1234, Vector3::UnitX());
0096 rotated *= rotX;
0097
0098 auto cBounds2 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0099 auto volume2 = DetectorVolumeFactory::construct(
0100 portalGenerator, tContext, "Volume2", rotated, std::move(cBounds2),
0101 tryAllPortals());
0102
0103
0104 std::vector<std::shared_ptr<DetectorVolume>> volumesWithNonaligned = {
0105 volume0, volume1, volume2};
0106 BOOST_CHECK_THROW(connectInR(tContext, volumesWithNonaligned, {}, logLevel),
0107 std::invalid_argument);
0108 }
0109
0110 BOOST_AUTO_TEST_CASE(ConnectInR) {
0111 ACTS_LOCAL_LOGGER(getDefaultLogger("Connect: R", logLevel));
0112 ACTS_INFO("*** Test: connect DetectorVolumes in R, create proto container");
0113
0114 std::vector<double> testOpenings = {std::numbers::pi, std::numbers::pi / 2.};
0115
0116 std::vector<double> radii = {0., 10., 100., 200.};
0117 double halfZ = 100.;
0118
0119
0120 for (auto [io, opening] : enumerate(testOpenings)) {
0121 ACTS_INFO(" -> test with phi opening: " << opening);
0122 std::string opStr = "opening_" + std::to_string(io);
0123 std::vector<std::shared_ptr<DetectorVolume>> rVolumes = {};
0124
0125 for (auto [i, r] : enumerate(radii)) {
0126 if (i > 0) {
0127 auto cBounds = std::make_unique<CylinderVolumeBounds>(
0128 radii[i - 1u], r, halfZ, opening, 0.);
0129 rVolumes.push_back(DetectorVolumeFactory::construct(
0130 portalGenerator, tContext, "Cylinder_r" + std::to_string(i),
0131 Transform3::Identity(), std::move(cBounds), tryAllPortals()));
0132 }
0133 }
0134
0135 auto protoContainer = connectInR(tContext, rVolumes, {}, logLevel);
0136
0137 BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[2u],
0138 rVolumes[1u]->portalPtrs()[3u]);
0139 BOOST_CHECK_EQUAL(rVolumes[1u]->portalPtrs()[2u],
0140 rVolumes[2u]->portalPtrs()[3u]);
0141 BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[0u],
0142 rVolumes[1u]->portalPtrs()[0u]);
0143 BOOST_CHECK_EQUAL(rVolumes[1u]->portalPtrs()[0u],
0144 rVolumes[2u]->portalPtrs()[0u]);
0145 BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[1u],
0146 rVolumes[1u]->portalPtrs()[1u]);
0147 BOOST_CHECK_EQUAL(rVolumes[1u]->portalPtrs()[1u],
0148 rVolumes[2u]->portalPtrs()[1u]);
0149 BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[0u], protoContainer[0u]);
0150 BOOST_CHECK_EQUAL(rVolumes[0u]->portalPtrs()[1u], protoContainer[1u]);
0151
0152
0153 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0154 GeometryIdGenerator generator(
0155 generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator",
0156 Acts::Logging::VERBOSE));
0157 auto cache = generator.generateCache();
0158 for (auto& vol : rVolumes) {
0159 generator.assignGeometryId(cache, *vol);
0160 }
0161
0162
0163 auto detector =
0164 Detector::makeShared("DetectorInR", rVolumes, tryRootVolumes());
0165
0166
0167 const auto& volumes = detector->volumes();
0168 auto boundaries = rzphiBoundaries(tContext, volumes);
0169 const auto& rBoundaries = boundaries[0u];
0170 const auto& zBoundaries = boundaries[1u];
0171
0172
0173 std::vector<double> zvalues = {-halfZ, halfZ};
0174 BOOST_CHECK(radii == rBoundaries);
0175 BOOST_CHECK(zvalues == zBoundaries);
0176 }
0177
0178
0179 ACTS_INFO("*** Test: faulty empty vector");
0180 BOOST_CHECK_THROW(connectInR(tContext, eVolumes, {}, logLevel),
0181 std::invalid_argument);
0182
0183
0184 ACTS_INFO("*** Test: volumes are not matching in R");
0185
0186 auto cBounds00 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0187 auto volume00 = DetectorVolumeFactory::construct(
0188 portalGenerator, tContext, "Volume00", Transform3::Identity(),
0189 std::move(cBounds00), tryAllPortals());
0190
0191 auto cBounds01 = std::make_unique<CylinderVolumeBounds>(101., 200., 100);
0192 auto volume01 = DetectorVolumeFactory::construct(
0193 portalGenerator, tContext, "Volume01", Transform3::Identity(),
0194 std::move(cBounds01), tryAllPortals());
0195
0196 std::vector<std::shared_ptr<DetectorVolume>> volumesNotMatching = {volume00,
0197 volume01};
0198 BOOST_CHECK_THROW(connectInR(tContext, volumesNotMatching, {}, logLevel),
0199 std::runtime_error);
0200
0201 ACTS_INFO("*** Test: volume bounds are not aligned");
0202 Transform3 shifted = Transform3::Identity();
0203 shifted.pretranslate(Vector3(0., 0., 10.));
0204
0205 auto cBounds10 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0206 auto volume10 = DetectorVolumeFactory::construct(
0207 portalGenerator, tContext, "Volume10", shifted, std::move(cBounds10),
0208 tryAllPortals());
0209
0210 auto cBounds11 = std::make_unique<CylinderVolumeBounds>(100., 200., 90);
0211 auto volume11 = DetectorVolumeFactory::construct(
0212 portalGenerator, tContext, "Volume11", shifted, std::move(cBounds11),
0213 tryAllPortals());
0214
0215 std::vector<std::shared_ptr<DetectorVolume>> volumesNotAligned = {volume10,
0216 volume11};
0217 BOOST_CHECK_THROW(connectInR(tContext, volumesNotAligned, {}, logLevel),
0218 std::runtime_error);
0219 }
0220
0221 BOOST_AUTO_TEST_CASE(ConnectInZ) {
0222 ACTS_LOCAL_LOGGER(getDefaultLogger("Connect: Z", logLevel));
0223 ACTS_INFO("*** Test: connect DetectorVolumes in Z, create proto container");
0224
0225
0226 std::vector<Transform3> transforms = {Transform3::Identity()};
0227 std::vector<std::array<double, 2>> radii = {{0., 100.}, {20., 120.}};
0228 std::vector<double> zValues = {-100., -20, 10., 100., 200.};
0229
0230 for (auto [it, t] : enumerate(transforms)) {
0231 ACTS_INFO(" -> test series with transform id " << it);
0232
0233 std::string trfStr = "_transform_" + std::to_string(it);
0234 for (auto [ir, r] : enumerate(radii)) {
0235 ACTS_INFO(" -> test series with radii setup "
0236 << radii[ir][0u] << ", " << radii[ir][1u]);
0237
0238 std::string radStr = "_radii_" + std::to_string(ir);
0239 std::vector<std::shared_ptr<DetectorVolume>> zVolumes = {};
0240 for (auto [i, z] : enumerate(zValues)) {
0241 if (i > 0) {
0242 auto cBounds = std::make_unique<CylinderVolumeBounds>(
0243 r[0], r[1], 0.5 * (z - zValues[i - 1u]));
0244
0245 double zCenter = 0.5 * (z + zValues[i - 1u]);
0246 Transform3 ti = Transform3::Identity();
0247 ti.pretranslate(t.translation() +
0248 zCenter * t.rotation().matrix().col(2));
0249 ti.prerotate(t.rotation());
0250
0251 zVolumes.push_back(DetectorVolumeFactory::construct(
0252 portalGenerator, tContext,
0253 "Cylinder_z" + std::to_string(i) + trfStr + radStr, ti,
0254 std::move(cBounds), tryAllPortals()));
0255 }
0256 }
0257
0258 auto protoContainer = connectInZ(tContext, zVolumes, {}, logLevel);
0259
0260
0261
0262 BOOST_CHECK_EQUAL(zVolumes[0u]->portalPtrs()[1u],
0263 zVolumes[1u]->portalPtrs()[0u]);
0264 BOOST_CHECK_EQUAL(zVolumes[1u]->portalPtrs()[1u],
0265 zVolumes[2u]->portalPtrs()[0u]);
0266 BOOST_CHECK_EQUAL(zVolumes[2u]->portalPtrs()[1u],
0267 zVolumes[3u]->portalPtrs()[0u]);
0268 BOOST_CHECK_EQUAL(protoContainer[0u], zVolumes[0u]->portalPtrs()[0u]);
0269 BOOST_CHECK_EQUAL(protoContainer[1u], zVolumes[3u]->portalPtrs()[1u]);
0270
0271
0272 std::vector<unsigned int> checkShared = {2u};
0273 if (radii[ir][0u] > 0.) {
0274 checkShared.push_back(3u);
0275 }
0276
0277 for (const auto& ip : checkShared) {
0278 BOOST_CHECK_EQUAL(zVolumes[0u]->portalPtrs()[ip],
0279 zVolumes[1u]->portalPtrs()[ip]);
0280 BOOST_CHECK_EQUAL(zVolumes[1u]->portalPtrs()[ip],
0281 zVolumes[2u]->portalPtrs()[ip]);
0282 BOOST_CHECK_EQUAL(zVolumes[2u]->portalPtrs()[ip],
0283 zVolumes[3u]->portalPtrs()[ip]);
0284 BOOST_CHECK_EQUAL(protoContainer[ip], zVolumes[0u]->portalPtrs()[ip]);
0285 }
0286
0287
0288 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0289 GeometryIdGenerator generator(
0290 generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator",
0291 Acts::Logging::VERBOSE));
0292 auto cache = generator.generateCache();
0293 for (auto& vol : zVolumes) {
0294 generator.assignGeometryId(cache, *vol);
0295 }
0296
0297 auto detector =
0298 Detector::makeShared("DetectorInZ", zVolumes, tryRootVolumes());
0299 }
0300 }
0301
0302
0303 BOOST_CHECK_THROW(connectInZ(tContext, eVolumes, {}, logLevel),
0304 std::invalid_argument);
0305
0306
0307 auto cBounds00 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0308 auto volume00 = DetectorVolumeFactory::construct(
0309 portalGenerator, tContext, "Volume00",
0310 Transform3::Identity() * Translation3(0., 0., -100.),
0311 std::move(cBounds00), tryAllPortals());
0312
0313 auto cBounds01 = std::make_unique<CylinderVolumeBounds>(0., 105., 100);
0314 auto volume01 = DetectorVolumeFactory::construct(
0315 portalGenerator, tContext, "Volume01",
0316 Transform3::Identity() * Translation3(0., 0., 100.), std::move(cBounds01),
0317 tryAllPortals());
0318
0319 std::vector<std::shared_ptr<DetectorVolume>> volumesNonalignedBounds = {
0320 volume00, volume01};
0321 BOOST_CHECK_THROW(connectInZ(tContext, volumesNonalignedBounds, {}, logLevel),
0322 std::runtime_error);
0323
0324
0325 auto cBounds10 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0326 auto volume10 = DetectorVolumeFactory::construct(
0327 portalGenerator, tContext, "Volume00",
0328 Transform3::Identity() * Translation3(0., 0., -105.),
0329 std::move(cBounds10), tryAllPortals());
0330
0331 auto cBounds11 = std::make_unique<CylinderVolumeBounds>(0., 100., 100);
0332 auto volume11 = DetectorVolumeFactory::construct(
0333 portalGenerator, tContext, "Volume01",
0334 Transform3::Identity() * Translation3(0., 0., 100.), std::move(cBounds11),
0335 tryAllPortals());
0336
0337 std::vector<std::shared_ptr<DetectorVolume>> volumesNotAttached = {volume10,
0338 volume11};
0339 BOOST_CHECK_THROW(connectInZ(tContext, volumesNotAttached, {}, logLevel),
0340 std::runtime_error);
0341 }
0342
0343 BOOST_AUTO_TEST_CASE(ConnectInPhi) {
0344 ACTS_LOCAL_LOGGER(getDefaultLogger("Connect: Phi", logLevel));
0345 ACTS_INFO("*** Test: connect DetectorVolumes in Phi, create proto container");
0346
0347 std::vector<Transform3> transforms = {Transform3::Identity()};
0348 unsigned int phiSectors = 5;
0349 double phiHalfSector = std::numbers::pi / phiSectors;
0350
0351 for (auto [it, t] : enumerate(transforms)) {
0352 ACTS_INFO(" -> test series with transform id " << it);
0353
0354 std::vector<std::shared_ptr<DetectorVolume>> phiVolumes = {};
0355 for (unsigned int i = 0; i < phiSectors; ++i) {
0356 auto cBounds = std::make_unique<CylinderVolumeBounds>(
0357 10., 100., 100., phiHalfSector,
0358 -std::numbers::pi + (2u * i + 1u) * phiHalfSector);
0359
0360
0361 phiVolumes.push_back(DetectorVolumeFactory::construct(
0362 portalGenerator, tContext, "Cylinder_phi" + std::to_string(i), t,
0363 std::move(cBounds), tryAllPortals()));
0364 }
0365
0366 auto protoContainer = connectInPhi(tContext, phiVolumes, {}, logLevel);
0367
0368
0369 std::vector<unsigned int> checkShared = {0u, 1u, 2u, 3u};
0370 for (auto [iv, v] : enumerate(phiVolumes)) {
0371 if (iv > 0u) {
0372 auto current = v;
0373 auto last = phiVolumes[iv - 1u];
0374 for (const auto& ch : checkShared) {
0375 BOOST_CHECK_EQUAL(current->portalPtrs()[ch], last->portalPtrs()[ch]);
0376 }
0377 }
0378 }
0379
0380
0381 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0382 GeometryIdGenerator generator(
0383 generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator",
0384 Acts::Logging::VERBOSE));
0385 auto cache = generator.generateCache();
0386 for (auto& vol : phiVolumes) {
0387 generator.assignGeometryId(cache, *vol);
0388 }
0389
0390 auto detector =
0391 Detector::makeShared("DetectorInPhi", phiVolumes, tryRootVolumes());
0392 }
0393
0394
0395 BOOST_CHECK_THROW(connectInPhi(tContext, eVolumes, {}, logLevel),
0396 std::invalid_argument);
0397 }
0398
0399 BOOST_AUTO_TEST_CASE(WrapVolumeinRZ) {
0400 ACTS_LOCAL_LOGGER(getDefaultLogger("Wrap: Z-R", logLevel));
0401 ACTS_INFO(
0402 "*** Test: wrap volume in Z-R with CutoutCylinderVolume, create proto "
0403 "container");
0404
0405
0406 std::vector<Transform3> transforms = {Transform3::Identity()};
0407
0408
0409 std::vector<std::array<double, 3u>> radii = {{0., 100., 500.},
0410 {20., 120., 500.}};
0411
0412 double innerHalfZ = 150.;
0413 double outerHalfZ = 175.;
0414
0415
0416 for (auto [it, tf] : enumerate(transforms)) {
0417 ACTS_INFO(" Test series with transform id " << it);
0418
0419 std::string trfStr = "_transform_" + std::to_string(it);
0420 for (auto [ir, r] : enumerate(radii)) {
0421 ACTS_INFO(" -> test series with radii setup " << radii[ir][0u] << ", "
0422 << radii[ir][1u]);
0423
0424 std::vector<std::shared_ptr<DetectorVolume>> volumes = {};
0425
0426 std::string radStr = "_radii_" + std::to_string(ir);
0427
0428 auto iBounds = std::make_unique<CylinderVolumeBounds>(
0429 radii[ir][0u], radii[ir][1u], innerHalfZ);
0430 volumes.push_back(DetectorVolumeFactory::construct(
0431 portalGenerator, tContext, "InnerCylinder" + radStr + trfStr, tf,
0432 std::move(iBounds), tryAllPortals()));
0433
0434
0435 auto wBounds = std::make_unique<CutoutCylinderVolumeBounds>(
0436 radii[ir][0u], radii[ir][1u], radii[ir][2u], outerHalfZ, innerHalfZ);
0437
0438 volumes.push_back(DetectorVolumeFactory::construct(
0439 portalGenerator, tContext, "WrappingCylinder" + radStr + trfStr, tf,
0440 std::move(wBounds), tryAllPortals()));
0441
0442 wrapInZR(tContext, volumes, logLevel);
0443 }
0444 }
0445
0446
0447 BOOST_CHECK_THROW(wrapInZR(tContext, eVolumes, logLevel),
0448 std::invalid_argument);
0449 }
0450
0451 BOOST_AUTO_TEST_CASE(ProtoContainerZR) {
0452 ACTS_LOCAL_LOGGER(getDefaultLogger("Container: Z-R", logLevel));
0453 ACTS_INFO("*** Test: create a container in Z-R.");
0454
0455 auto transform = Transform3::Identity();
0456
0457 std::vector<double> innerMostRadii = {0., 2.};
0458
0459 for (auto [ir, imr] : enumerate(innerMostRadii)) {
0460 ACTS_INFO(" -> test series innermost radius setup "
0461 << innerMostRadii[ir]);
0462
0463
0464 std::vector<double> radii = {25., 100., 200.};
0465 double halfZ = 200;
0466
0467
0468 auto bBounds =
0469 std::make_unique<CylinderVolumeBounds>(imr, radii[0u], halfZ);
0470
0471 auto innerPipe = DetectorVolumeFactory::construct(
0472 portalGenerator, tContext, "InnerPipe", transform, std::move(bBounds),
0473 tryAllPortals());
0474
0475
0476 std::map<unsigned int, std::shared_ptr<Portal>> ipContainer;
0477 for (auto [ip, p] : enumerate(innerPipe->portalPtrs())) {
0478 ipContainer[ip] = p;
0479 }
0480
0481
0482 std::vector<std::shared_ptr<DetectorVolume>> rVolumes = {};
0483
0484 for (auto [i, r] : enumerate(radii)) {
0485 if (i > 0) {
0486 auto cBounds =
0487 std::make_unique<CylinderVolumeBounds>(radii[i - 1u], r, halfZ);
0488 rVolumes.push_back(DetectorVolumeFactory::construct(
0489 portalGenerator, tContext, "Cylinder_r" + std::to_string(i),
0490 transform, std::move(cBounds), tryAllPortals()));
0491 }
0492 }
0493
0494 auto protoContainerInR = connectInR(tContext, rVolumes, {}, logLevel);
0495
0496 std::vector<double> zValues = {-200., -120, 10., 100., 200.};
0497 std::vector<std::shared_ptr<DetectorVolume>> zVolumes = {};
0498 for (auto [i, z] : enumerate(zValues)) {
0499 if (i > 0) {
0500 auto cBounds = std::make_unique<CylinderVolumeBounds>(
0501 200., 300., 0.5 * (z - zValues[i - 1u]));
0502
0503 double zCenter = 0.5 * (z + zValues[i - 1u]);
0504 Transform3 ti = transform;
0505 ti.pretranslate(transform.translation() +
0506 zCenter * transform.rotation().matrix().col(2));
0507
0508
0509 zVolumes.push_back(DetectorVolumeFactory::construct(
0510 portalGenerator, tContext, "Cylinder_z" + std::to_string(i), ti,
0511 std::move(cBounds), tryAllPortals()));
0512 }
0513 }
0514
0515 auto protoContainerInZ = connectInZ(tContext, zVolumes, {}, logLevel);
0516 auto centralContainer = connectInR(
0517 tContext, {ipContainer, protoContainerInR, protoContainerInZ}, {},
0518 logLevel);
0519
0520
0521
0522 auto necBounds = std::make_unique<CylinderVolumeBounds>(imr, 300., 50.);
0523
0524 auto necTransform = Transform3::Identity();
0525 necTransform.pretranslate(Vector3(0., 0., -250));
0526 auto necVolume = DetectorVolumeFactory::construct(
0527 portalGenerator, tContext, "Nec", necTransform, std::move(necBounds),
0528 tryAllPortals());
0529
0530 std::map<unsigned int, std::shared_ptr<Portal>> necContainer;
0531 for (auto [ip, p] : enumerate(necVolume->portalPtrs())) {
0532 necContainer[ip] = p;
0533 }
0534
0535
0536 auto pecInnerBounds =
0537 std::make_unique<CylinderVolumeBounds>(imr, 175., 100.);
0538
0539 auto pecOuterBounds =
0540 std::make_unique<CylinderVolumeBounds>(175., 300., 100.);
0541
0542 auto pecTransform = Transform3::Identity();
0543 pecTransform.pretranslate(Vector3(0., 0., 300));
0544 auto pecInner = DetectorVolumeFactory::construct(
0545 portalGenerator, tContext, "PecInner", pecTransform,
0546 std::move(pecInnerBounds), tryAllPortals());
0547 auto pecOuter = DetectorVolumeFactory::construct(
0548 portalGenerator, tContext, "PecOuter", pecTransform,
0549 std::move(pecOuterBounds), tryAllPortals());
0550
0551 std::vector<std::shared_ptr<DetectorVolume>> pecVolumes = {pecInner,
0552 pecOuter};
0553 auto pecContainer = connectInR(tContext, pecVolumes, {}, logLevel);
0554
0555 auto overallContainer = connectInZ(
0556 tContext, {necContainer, centralContainer, pecContainer}, {}, logLevel);
0557
0558
0559 std::vector<std::shared_ptr<DetectorVolume>> dVolumes;
0560 dVolumes.push_back(innerPipe);
0561 dVolumes.push_back(necVolume);
0562 dVolumes.insert(dVolumes.end(), rVolumes.begin(), rVolumes.end());
0563 dVolumes.insert(dVolumes.end(), zVolumes.begin(), zVolumes.end());
0564 dVolumes.push_back(pecInner);
0565 dVolumes.push_back(pecOuter);
0566
0567
0568 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0569 GeometryIdGenerator generator(
0570 generatorConfig, Acts::getDefaultLogger("SequentialIdGenerator",
0571 Acts::Logging::VERBOSE));
0572 auto cache = generator.generateCache();
0573 for (auto& vol : dVolumes) {
0574 generator.assignGeometryId(cache, *vol);
0575 }
0576
0577 auto detector = Detector::makeShared("DetectorFromProtoContainer", dVolumes,
0578 tryRootVolumes());
0579 }
0580 }
0581
0582 BOOST_AUTO_TEST_CASE(WrapContainernRZ) {
0583 ACTS_LOCAL_LOGGER(getDefaultLogger("Container: Wrap", logLevel));
0584 ACTS_INFO("*** Test: create a container in Z-R by wrapping.");
0585
0586
0587 std::vector<std::array<double, 3u>> radii = {{0., 100., 500.},
0588 {20., 120., 500.}};
0589
0590 double innerHalfZ = 150.;
0591 double innerBarrelHalfZ = 75.;
0592 double innerEndcapHalfZ = 0.5 * (innerHalfZ - innerBarrelHalfZ);
0593 double outerHalfZ = 175.;
0594
0595 Transform3 tf = Transform3::Identity();
0596
0597
0598 for (auto [ir, r] : enumerate(radii)) {
0599 std::string radStr = "_radii_" + std::to_string(ir);
0600 ACTS_INFO(" -> test series innermost radius setup " << radii[ir][0u]);
0601
0602
0603 std::vector<std::shared_ptr<DetectorVolume>> iVolumes = {};
0604
0605 auto iNecBounds = std::make_unique<CylinderVolumeBounds>(
0606 radii[ir][0u], radii[ir][1u], innerEndcapHalfZ);
0607 Transform3 ntf = tf;
0608 ntf.pretranslate(Vector3(0., 0., -innerBarrelHalfZ - innerEndcapHalfZ));
0609 iVolumes.push_back(DetectorVolumeFactory::construct(
0610 portalGenerator, tContext, "InnerNec" + radStr, ntf,
0611 std::move(iNecBounds), tryAllPortals()));
0612
0613 auto iBarrelBounds = std::make_unique<CylinderVolumeBounds>(
0614 radii[ir][0u], radii[ir][1u], innerBarrelHalfZ);
0615 iVolumes.push_back(DetectorVolumeFactory::construct(
0616 portalGenerator, tContext, "InnerBarrel" + radStr, tf,
0617 std::move(iBarrelBounds), tryAllPortals()));
0618
0619 auto iPecBounds = std::make_unique<CylinderVolumeBounds>(
0620 radii[ir][0u], radii[ir][1u], innerEndcapHalfZ);
0621 Transform3 ptf = tf;
0622 ptf.pretranslate(Vector3(0., 0., innerBarrelHalfZ + innerEndcapHalfZ));
0623 iVolumes.push_back(DetectorVolumeFactory::construct(
0624 portalGenerator, tContext, "InnerPec" + radStr, ptf,
0625 std::move(iPecBounds), tryAllPortals()));
0626
0627 auto innerContainer = connectInZ(tContext, iVolumes, {}, logLevel);
0628
0629
0630 auto wBounds = std::make_unique<CutoutCylinderVolumeBounds>(
0631 radii[ir][0u], radii[ir][1u], radii[ir][2u], outerHalfZ, innerHalfZ);
0632 auto wVolume = DetectorVolumeFactory::construct(
0633 portalGenerator, tContext, "WrappingVolume" + radStr, tf,
0634 std::move(wBounds), tryAllPortals());
0635
0636 std::vector<DetectorComponent::PortalContainer> containers;
0637 containers.push_back(innerContainer);
0638
0639 DetectorComponent::PortalContainer outerContainer;
0640 for (auto [ip, p] : enumerate(wVolume->portalPtrs())) {
0641 outerContainer[ip] = p;
0642 }
0643 containers.push_back(outerContainer);
0644
0645 auto detector = wrapInZR(tContext, containers, logLevel);
0646 }
0647 }
0648
0649 BOOST_AUTO_TEST_CASE(RZPhiBoundaries) {
0650 auto portalGenerator = defaultPortalGenerator();
0651
0652 auto innerB = std::make_unique<CylinderVolumeBounds>(0., 20., 100);
0653 auto innerV = DetectorVolumeFactory::construct(
0654 portalGenerator, tContext, "Inner", Transform3::Identity(),
0655 std::move(innerB), tryAllPortals());
0656
0657 auto middleLB = std::make_unique<CylinderVolumeBounds>(20., 60., 5);
0658 auto middleLT = Transform3::Identity();
0659 middleLT.pretranslate(Vector3(0., 0., -95));
0660 auto middleLV = DetectorVolumeFactory::construct(
0661 portalGenerator, tContext, "MiddleLeft", middleLT, std::move(middleLB),
0662 tryAllPortals());
0663
0664 auto middleDB = std::make_unique<CylinderVolumeBounds>(20., 40., 90);
0665 auto middleDV = DetectorVolumeFactory::construct(
0666 portalGenerator, tContext, "MiddleDown", Transform3::Identity(),
0667 std::move(middleDB), tryAllPortals());
0668
0669 auto middleUB = std::make_unique<CylinderVolumeBounds>(40., 60., 90);
0670 auto middleUV = DetectorVolumeFactory::construct(
0671 portalGenerator, tContext, "MiddleUp", Transform3::Identity(),
0672 std::move(middleUB), tryAllPortals());
0673
0674 auto middleRB = std::make_unique<CylinderVolumeBounds>(20., 60., 5);
0675 auto middleRT = Transform3::Identity();
0676 middleRT.pretranslate(Vector3(0., 0., 95));
0677 auto middleRV = DetectorVolumeFactory::construct(
0678 portalGenerator, tContext, "middleRight", middleRT, std::move(middleRB),
0679 tryAllPortals());
0680
0681 auto outerB = std::make_unique<CylinderVolumeBounds>(60., 120., 100);
0682 auto outerV = DetectorVolumeFactory::construct(
0683 portalGenerator, tContext, "Outer", Transform3::Identity(),
0684 std::move(outerB), tryAllPortals());
0685
0686 std::vector<std::shared_ptr<DetectorVolume>> volumes = {
0687 innerV, middleLV, middleDV, middleUV, middleRV, outerV};
0688
0689 auto boundaries =
0690 rzphiBoundaries(tContext, volumes, 0., Acts::Logging::VERBOSE);
0691 BOOST_CHECK_EQUAL(boundaries.size(), 3u);
0692
0693 std::vector<double> rBoundaries = {0., 20., 40., 60., 120.};
0694 BOOST_CHECK(boundaries[0u] == rBoundaries);
0695
0696 std::vector<double> zBoundaries = {-100., -90., 90., 100.};
0697 BOOST_CHECK(boundaries[1u] == zBoundaries);
0698 BOOST_CHECK_EQUAL(boundaries[2u].size(), 2u);
0699 }
0700
0701 BOOST_AUTO_TEST_CASE(RZPhiBoundariesWithTolerance) {
0702 auto innerB = std::make_unique<CylinderVolumeBounds>(0., 20., 100);
0703 auto innerV = DetectorVolumeFactory::construct(
0704 portalGenerator, tContext, "Inner", Transform3::Identity(),
0705 std::move(innerB), tryAllPortals());
0706
0707 auto outerB = std::make_unique<CylinderVolumeBounds>(20.001, 100., 100);
0708 auto outerV = DetectorVolumeFactory::construct(
0709 portalGenerator, tContext, "Inner", Transform3::Identity(),
0710 std::move(outerB), tryAllPortals());
0711
0712 std::vector<std::shared_ptr<DetectorVolume>> volumes = {innerV, outerV};
0713
0714 auto boundariesWoTol =
0715 rzphiBoundaries(tContext, volumes, 0., Acts::Logging::VERBOSE);
0716 BOOST_CHECK_EQUAL(boundariesWoTol[0u].size(), 4u);
0717
0718 auto boundariesWTol =
0719 rzphiBoundaries(tContext, volumes, 0.01, Acts::Logging::VERBOSE);
0720 BOOST_CHECK_EQUAL(boundariesWTol[0u].size(), 3u);
0721 }
0722
0723 BOOST_AUTO_TEST_SUITE_END()