File indexing completed on 2025-01-18 09:12:31
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Detector/Blueprint.hpp"
0012 #include "Acts/Detector/CuboidalContainerBuilder.hpp"
0013 #include "Acts/Detector/DetectorBuilder.hpp"
0014 #include "Acts/Detector/DetectorComponents.hpp"
0015 #include "Acts/Detector/DetectorVolume.hpp"
0016 #include "Acts/Detector/GeometryIdGenerator.hpp"
0017 #include "Acts/Detector/IndexedRootVolumeFinderBuilder.hpp"
0018 #include "Acts/Detector/detail/BlueprintDrawer.hpp"
0019 #include "Acts/Detector/detail/BlueprintHelper.hpp"
0020 #include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0023 #include "Acts/Navigation/InternalNavigation.hpp"
0024 #include "Acts/Surfaces/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/RectangleBounds.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/BinningData.hpp"
0028
0029 #include <algorithm>
0030 #include <fstream>
0031
0032 class SurfaceBuilder : public Acts::Experimental::IInternalStructureBuilder {
0033 public:
0034 SurfaceBuilder(const Acts::Transform3& transform,
0035 const Acts::RectangleBounds& sBounds)
0036 : m_transform(transform), m_surfaceBounds(sBounds) {};
0037
0038
0039
0040
0041
0042
0043 Acts::Experimental::InternalStructure construct(
0044 [[maybe_unused]] const Acts::GeometryContext& gctx) const final {
0045 auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0046 (m_transform),
0047 std::make_shared<Acts::RectangleBounds>(m_surfaceBounds));
0048
0049
0050 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0051 internalVolumes = {};
0052 Acts::Experimental::ExternalNavigationDelegate internalVolumeUpdater =
0053 Acts::Experimental::tryNoVolumes();
0054
0055
0056 Acts::Experimental::InternalNavigationDelegate internalCandidatesUpdater =
0057 Acts::Experimental::tryAllPortalsAndSurfaces();
0058
0059
0060 return Acts::Experimental::InternalStructure{
0061 {surface},
0062 internalVolumes,
0063 std::move(internalCandidatesUpdater),
0064 std::move(internalVolumeUpdater)};
0065 }
0066
0067 private:
0068 Acts::Transform3 m_transform;
0069 Acts::RectangleBounds m_surfaceBounds;
0070 };
0071
0072 BOOST_AUTO_TEST_SUITE(Detector)
0073
0074 BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) {
0075 Acts::GeometryContext tContext;
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 double detectorX = 100.;
0089 double detectorY = 100.;
0090 double detectorZ = 100.;
0091
0092
0093 double pixelX = 20;
0094 double pixelY = 100;
0095 double pixelZ = 10;
0096
0097
0098 std::vector<Acts::AxisDirection> detectorBins = {Acts::AxisDirection::AxisX};
0099 std::vector<double> detectorBounds = {detectorX, detectorY, detectorZ};
0100
0101
0102 auto detectorBpr = std::make_unique<Acts::Experimental::Blueprint::Node>(
0103 "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCuboid,
0104 detectorBounds, detectorBins);
0105
0106
0107 std::vector<double> leftArmBounds = {detectorX * 0.5, detectorY, detectorZ};
0108
0109 std::vector<Acts::AxisDirection> leftArmBins = {Acts::AxisDirection::AxisZ};
0110
0111 Acts::Transform3 leftArmTransform =
0112 Acts::Transform3::Identity() *
0113 Acts::Translation3(-detectorX * 0.5, 0., 0);
0114
0115 auto leftArm = std::make_unique<Acts::Experimental::Blueprint::Node>(
0116 "leftArm", leftArmTransform, Acts::VolumeBounds::eCuboid, leftArmBounds,
0117 leftArmBins);
0118
0119
0120 std::vector<double> pixelL1Boundaries = {pixelX, pixelY, pixelZ};
0121
0122 Acts::Transform3 pixelL1Transform =
0123 Acts::Transform3::Identity() *
0124 Acts::Translation3(-pixelX - 5, 0., -detectorZ + pixelZ + 5);
0125
0126 auto pixelL1Structure = std::make_shared<SurfaceBuilder>(
0127 pixelL1Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0128
0129 auto pixelL1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0130 "pixelL1", pixelL1Transform, Acts::VolumeBounds::eCuboid,
0131 pixelL1Boundaries, pixelL1Structure);
0132
0133
0134 std::vector<double> pixelL2Boundaries = {pixelX, pixelY, pixelZ};
0135
0136 Acts::Transform3 pixelL2Transform =
0137 Acts::Transform3::Identity() *
0138 Acts::Translation3(-pixelX - 5, 0., -detectorZ + 2 * pixelZ + 5 * 5);
0139
0140 auto pixelL2Structure = std::make_shared<SurfaceBuilder>(
0141 pixelL2Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0142
0143 auto pixelL2 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0144 "pixelL2", pixelL2Transform, Acts::VolumeBounds::eCuboid,
0145 pixelL2Boundaries, pixelL2Structure);
0146
0147
0148
0149 leftArm->add(std::move(pixelL1));
0150 leftArm->add(std::move(pixelL2));
0151 detectorBpr->add(std::move(leftArm));
0152
0153
0154 std::vector<double> rightArmBounds = {detectorX * 0.5, detectorY, detectorZ};
0155
0156 std::vector<Acts::AxisDirection> rightArmBins = {Acts::AxisDirection::AxisZ};
0157
0158 Acts::Transform3 rightArmTransform =
0159 Acts::Transform3::Identity() * Acts::Translation3(detectorX * 0.5, 0., 0);
0160
0161 auto rightArm = std::make_unique<Acts::Experimental::Blueprint::Node>(
0162 "rightArm", rightArmTransform, Acts::VolumeBounds::eCuboid,
0163 rightArmBounds, rightArmBins);
0164
0165
0166 std::vector<double> pixelR1Boundaries = {pixelX, pixelY, pixelZ};
0167
0168 Acts::Transform3 pixelR1Transform =
0169 Acts::Transform3::Identity() *
0170 Acts::Translation3(pixelX + 5, 0., -detectorZ + pixelZ + 5);
0171
0172 auto pixelR1Structure = std::make_shared<SurfaceBuilder>(
0173 pixelR1Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0174
0175 auto pixelR1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0176 "pixelR1", pixelR1Transform, Acts::VolumeBounds::eCuboid,
0177 pixelR1Boundaries, pixelR1Structure);
0178
0179
0180 std::vector<double> pixelR2Boundaries = {pixelX, pixelY, pixelZ};
0181
0182 Acts::Transform3 pixelR2Transform =
0183 Acts::Transform3::Identity() *
0184 Acts::Translation3(pixelX + 5, 0., -detectorZ + 2 * pixelZ + 5 * 5);
0185
0186 auto pixelR2Structure = std::make_shared<SurfaceBuilder>(
0187 pixelR2Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0188
0189 auto pixelR2 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0190 "pixelR2", pixelR2Transform, Acts::VolumeBounds::eCuboid,
0191 pixelR2Boundaries, pixelR2Structure);
0192
0193
0194
0195 rightArm->add(std::move(pixelR1));
0196 rightArm->add(std::move(pixelR2));
0197 detectorBpr->add(std::move(rightArm));
0198
0199
0200 detectorBpr->geoIdGenerator =
0201 std::make_shared<Acts::Experimental::GeometryIdGenerator>(
0202 Acts::Experimental::GeometryIdGenerator::Config{},
0203 Acts::getDefaultLogger("RecursiveIdGenerator",
0204 Acts::Logging::VERBOSE));
0205
0206 std::cout << "Fill gaps ..." << std::endl;
0207
0208 Acts::Experimental::detail::BlueprintHelper::fillGaps(*detectorBpr);
0209 std::cout << "Filled gaps ..." << std::endl;
0210
0211 std::fstream fs("cylindrical_detector_blueprint.dot", std::ios::out);
0212 Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detectorBpr);
0213 fs.close();
0214
0215
0216
0217
0218 auto detectorBuilder =
0219 std::make_shared<Acts::Experimental::CuboidalContainerBuilder>(
0220 *detectorBpr, Acts::Logging::VERBOSE);
0221
0222
0223 Acts::Experimental::DetectorBuilder::Config dCfg;
0224 dCfg.auxiliary = "*** Test : auto generated cuboidal detector builder ***";
0225 dCfg.name = "Cuboidal detector from blueprint";
0226 dCfg.builder = detectorBuilder;
0227 dCfg.geoIdGenerator = detectorBpr->geoIdGenerator;
0228
0229 auto detector = Acts::Experimental::DetectorBuilder(dCfg).construct(tContext);
0230
0231 BOOST_REQUIRE_NE(detector, nullptr);
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 BOOST_CHECK_EQUAL(detector->volumes().size(), 10u);
0245 BOOST_CHECK_EQUAL(detector->volumes()[0]->name(), "leftArm_gap_0");
0246 BOOST_CHECK_EQUAL(detector->volumes()[1]->name(), "pixelL1");
0247 BOOST_CHECK_EQUAL(detector->volumes()[2]->name(), "leftArm_gap_1");
0248 BOOST_CHECK_EQUAL(detector->volumes()[3]->name(), "pixelL2");
0249 BOOST_CHECK_EQUAL(detector->volumes()[4]->name(), "leftArm_gap_2");
0250 BOOST_CHECK_EQUAL(detector->volumes()[5]->name(), "rightArm_gap_0");
0251 BOOST_CHECK_EQUAL(detector->volumes()[6]->name(), "pixelR1");
0252 BOOST_CHECK_EQUAL(detector->volumes()[7]->name(), "rightArm_gap_1");
0253 BOOST_CHECK_EQUAL(detector->volumes()[8]->name(), "pixelR2");
0254 BOOST_CHECK_EQUAL(detector->volumes()[9]->name(), "rightArm_gap_2");
0255
0256
0257
0258 double internalStretchLeftZ =
0259 detector->volumes()[0]
0260 ->volumeBounds()
0261 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0262 detector->volumes()[1]
0263 ->volumeBounds()
0264 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0265 detector->volumes()[2]
0266 ->volumeBounds()
0267 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0268 detector->volumes()[3]
0269 ->volumeBounds()
0270 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0271 detector->volumes()[4]
0272 ->volumeBounds()
0273 .values()[toUnderlying(Acts::AxisDirection::AxisZ)];
0274
0275 double internalStretchRightZ =
0276 detector->volumes()[5]
0277 ->volumeBounds()
0278 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0279 detector->volumes()[6]
0280 ->volumeBounds()
0281 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0282 detector->volumes()[7]
0283 ->volumeBounds()
0284 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0285 detector->volumes()[8]
0286 ->volumeBounds()
0287 .values()[toUnderlying(Acts::AxisDirection::AxisZ)] +
0288 detector->volumes()[9]
0289 ->volumeBounds()
0290 .values()[toUnderlying(Acts::AxisDirection::AxisZ)];
0291
0292 double internalStretchX1 =
0293 detector->volumes()[0]
0294 ->volumeBounds()
0295 .values()[toUnderlying(Acts::AxisDirection::AxisX)] +
0296 detector->volumes()[5]
0297 ->volumeBounds()
0298 .values()[toUnderlying(Acts::AxisDirection::AxisX)];
0299
0300 double internalStretchX2 =
0301 detector->volumes()[1]
0302 ->volumeBounds()
0303 .values()[toUnderlying(Acts::AxisDirection::AxisX)] +
0304 detector->volumes()[6]
0305 ->volumeBounds()
0306 .values()[toUnderlying(Acts::AxisDirection::AxisX)];
0307
0308 double internalStretchX3 =
0309 detector->volumes()[2]
0310 ->volumeBounds()
0311 .values()[toUnderlying(Acts::AxisDirection::AxisX)] +
0312 detector->volumes()[7]
0313 ->volumeBounds()
0314 .values()[toUnderlying(Acts::AxisDirection::AxisX)];
0315
0316 double internalStretchX4 =
0317 detector->volumes()[3]
0318 ->volumeBounds()
0319 .values()[toUnderlying(Acts::AxisDirection::AxisX)] +
0320 detector->volumes()[8]
0321 ->volumeBounds()
0322 .values()[toUnderlying(Acts::AxisDirection::AxisX)];
0323
0324 double internalStretchX5 =
0325 detector->volumes()[4]
0326 ->volumeBounds()
0327 .values()[toUnderlying(Acts::AxisDirection::AxisX)] +
0328 detector->volumes()[9]
0329 ->volumeBounds()
0330 .values()[toUnderlying(Acts::AxisDirection::AxisX)];
0331
0332 BOOST_CHECK_EQUAL(internalStretchLeftZ, detectorZ);
0333 BOOST_CHECK_EQUAL(internalStretchRightZ, detectorZ);
0334 BOOST_CHECK_EQUAL(internalStretchX1, detectorX);
0335 BOOST_CHECK_EQUAL(internalStretchX2, detectorX);
0336 BOOST_CHECK_EQUAL(internalStretchX3, detectorX);
0337 BOOST_CHECK_EQUAL(internalStretchX4, detectorX);
0338 BOOST_CHECK_EQUAL(internalStretchX5, detectorX);
0339
0340 for (auto& volume : detector->volumes()) {
0341 BOOST_CHECK_EQUAL(volume->volumeBounds()
0342 .values()[toUnderlying(Acts::AxisDirection::AxisY)],
0343 detectorY);
0344 }
0345
0346
0347
0348 BOOST_CHECK_EQUAL(detector->volumes()[1]->surfaces().size(), 1u);
0349 BOOST_CHECK_EQUAL(detector->volumes()[3]->surfaces().size(), 1u);
0350 BOOST_CHECK_EQUAL(detector->volumes()[6]->surfaces().size(), 1u);
0351 BOOST_CHECK_EQUAL(detector->volumes()[8]->surfaces().size(), 1u);
0352
0353
0354
0355
0356
0357
0358
0359 std::vector<const Acts::Experimental::Portal*> portals;
0360 for (auto& volume : detector->volumes()) {
0361 portals.insert(portals.end(), volume->portals().begin(),
0362 volume->portals().end());
0363 }
0364 std::ranges::sort(portals);
0365 auto last = std::unique(portals.begin(), portals.end());
0366 portals.erase(last, portals.end());
0367 BOOST_CHECK_EQUAL(portals.size(), 19u);
0368
0369
0370
0371
0372 bool samePortalY1 = true, samePortalY2 = true;
0373 for (int i = 0; i < 4; i++) {
0374 samePortalY1 =
0375 samePortalY1 && (detector->volumes()[i]->portals().at(4) ==
0376 detector->volumes()[i + 1]->portals().at(4));
0377 samePortalY2 =
0378 samePortalY2 && (detector->volumes()[5 + i]->portals().at(4) ==
0379 detector->volumes()[5 + i + 1]->portals().at(4));
0380 }
0381 BOOST_CHECK_EQUAL(samePortalY1, true);
0382 BOOST_CHECK_EQUAL(samePortalY2, true);
0383 samePortalY1 = true, samePortalY2 = true;
0384 for (int i = 0; i < 4; i++) {
0385 samePortalY1 =
0386 samePortalY1 && (detector->volumes()[i]->portals().at(5) ==
0387 detector->volumes()[i + 1]->portals().at(5));
0388 samePortalY2 =
0389 samePortalY2 && (detector->volumes()[5 + i]->portals().at(5) ==
0390 detector->volumes()[5 + i + 1]->portals().at(5));
0391 }
0392 BOOST_CHECK_EQUAL(samePortalY1, true);
0393 BOOST_CHECK_EQUAL(samePortalY2, true);
0394
0395
0396 for (int i = 0; i < 4; i++) {
0397 bool samePortalZ1 = (detector->volumes()[i]->portals().at(1) ==
0398 detector->volumes()[i + 1]->portals().at(0));
0399 bool samePortalZ2 = (detector->volumes()[5 + i]->portals().at(1) ==
0400 detector->volumes()[5 + i + 1]->portals().at(0));
0401
0402 BOOST_CHECK_EQUAL(samePortalZ1, true);
0403 BOOST_CHECK_EQUAL(samePortalZ2, true);
0404 }
0405
0406
0407 for (int i = 0; i < 5; i++) {
0408 bool samePortalX = (detector->volumes()[i]->portals().at(3) ==
0409 detector->volumes()[5 + i]->portals().at(2));
0410 BOOST_CHECK_EQUAL(samePortalX, true);
0411 }
0412 }
0413
0414 BOOST_AUTO_TEST_SUITE_END()