File indexing completed on 2025-10-16 08:03:59
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/detail/BlueprintDrawer.hpp"
0013 #include "Acts/Detector/detail/BlueprintHelper.hpp"
0014
0015 #include <exception>
0016 #include <fstream>
0017
0018 using namespace Acts;
0019
0020 namespace Acts::Experimental {
0021 class IInternalStructureBuilder {};
0022 }
0023
0024 namespace ActsTests {
0025
0026 BOOST_AUTO_TEST_SUITE(DetectorSuite)
0027
0028 BOOST_AUTO_TEST_CASE(BlueprintHelperSorting) {
0029
0030 std::vector<AxisDirection> detectorBinning = {AxisDirection::AxisR};
0031 std::vector<double> detectorBoundaries = {0., 50., 100.};
0032 auto detector = std::make_unique<Experimental::Gen2Blueprint::Node>(
0033 "detector", Transform3::Identity(), VolumeBounds::eCylinder,
0034 detectorBoundaries, detectorBinning);
0035
0036 BOOST_CHECK_EQUAL(detector->parent, nullptr);
0037 BOOST_CHECK(detector->children.empty());
0038 BOOST_CHECK_EQUAL(detector->name, "detector");
0039
0040 std::vector<AxisDirection> pixelsBinning = {AxisDirection::AxisZ};
0041 std::vector<double> pixelsBoundaries = {20., 50., 100.};
0042
0043 auto pixels = std::make_unique<Experimental::Gen2Blueprint::Node>(
0044 "pixels", Transform3::Identity(), VolumeBounds::eCylinder,
0045 pixelsBoundaries, pixelsBinning);
0046
0047 std::vector<double> beamPipeBoundaries = {0., 20., 100.};
0048 auto beamPipe = std::make_unique<Experimental::Gen2Blueprint::Node>(
0049 "beam_pipe", Transform3::Identity(), VolumeBounds::eOther,
0050 beamPipeBoundaries);
0051
0052 std::vector<double> gapBoundaries = {20., 50., 10.};
0053 auto gap0 = std::make_unique<Experimental::Gen2Blueprint::Node>(
0054 "gap0", Transform3::Identity() * Translation3(0., 0., -90.),
0055 VolumeBounds::eCylinder, gapBoundaries);
0056
0057 std::vector<double> layerBoundaries = {20., 50., 80.};
0058 auto layer = std::make_unique<Experimental::Gen2Blueprint::Node>(
0059 "layer", Transform3::Identity(), VolumeBounds::eCylinder, layerBoundaries,
0060 std::make_shared<Experimental::IInternalStructureBuilder>());
0061
0062 auto gap1 = std::make_unique<Experimental::Gen2Blueprint::Node>(
0063 "gap1", Transform3::Identity() * Translation3(0., 0., 90.),
0064 VolumeBounds::eCylinder, gapBoundaries);
0065
0066
0067 pixels->add(std::move(gap1));
0068 pixels->add(std::move(gap0));
0069 pixels->add(std::move(layer));
0070
0071 detector->add(std::move(pixels));
0072 detector->add(std::move(beamPipe));
0073
0074 std::ofstream fs("detector_unordered.dot");
0075 Experimental::detail::BlueprintDrawer::dotStream(fs, *detector);
0076 fs.close();
0077
0078
0079 Experimental::detail::BlueprintHelper::sort(*detector);
0080
0081
0082 BOOST_CHECK_EQUAL(detector->children.front()->name, "beam_pipe");
0083 BOOST_CHECK_EQUAL(detector->children.back()->name, "pixels");
0084 BOOST_CHECK_EQUAL(detector->children.back()->children.front()->name, "gap0");
0085 BOOST_CHECK_EQUAL(detector->children.back()->children[1u]->name, "layer");
0086 BOOST_CHECK_EQUAL(detector->children.back()->children.back()->name, "gap1");
0087
0088 std::ofstream fs2("detector_ordered.dot");
0089 Experimental::detail::BlueprintDrawer::dotStream(fs2, *detector);
0090 fs2.close();
0091 }
0092
0093 BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapFilling) {
0094
0095 double detectorIr = 0.;
0096 double detectorOr = 120.;
0097 double detectorHz = 400.;
0098
0099
0100 double beamPipeOr = 20.;
0101
0102
0103 double pixelIr = 25;
0104 double pixelOr = 115;
0105 double pixelEcHz = 50;
0106
0107 auto innerBuilder =
0108 std::make_shared<Experimental::IInternalStructureBuilder>();
0109
0110
0111 std::vector<AxisDirection> detectorBinning = {AxisDirection::AxisR};
0112 std::vector<double> detectorBoundaries = {detectorIr, detectorOr, detectorHz};
0113
0114
0115 auto detector = std::make_unique<Experimental::Gen2Blueprint::Node>(
0116 "detector", Transform3::Identity(), VolumeBounds::eCylinder,
0117 detectorBoundaries, detectorBinning);
0118
0119
0120 std::vector<double> beamPipeBoundaries = {detectorIr, beamPipeOr, detectorHz};
0121 auto beamPipe = std::make_unique<Experimental::Gen2Blueprint::Node>(
0122 "beam_pipe", Transform3::Identity(), VolumeBounds::eCylinder,
0123 beamPipeBoundaries, innerBuilder);
0124 detector->add(std::move(beamPipe));
0125
0126
0127 std::vector<double> pixelBoundaries = {pixelIr, pixelOr, detectorHz};
0128 std::vector<AxisDirection> pixelBinning = {AxisDirection::AxisZ};
0129 auto pixel = std::make_unique<Experimental::Gen2Blueprint::Node>(
0130 "pixel", Transform3::Identity(), VolumeBounds::eCylinder, pixelBoundaries,
0131 pixelBinning);
0132
0133
0134 std::vector<double> pixelEcBoundaries = {pixelIr, pixelOr - 5., pixelEcHz};
0135 std::vector<AxisDirection> pixelEcBinning = {AxisDirection::AxisZ};
0136
0137 auto pixelNec = std::make_unique<Experimental::Gen2Blueprint::Node>(
0138 "pixelNec",
0139 Transform3::Identity() * Translation3(0., 0., -detectorHz + pixelEcHz),
0140 VolumeBounds::eCylinder, pixelEcBoundaries, pixelEcBinning);
0141
0142
0143 std::vector<double> pixelNecBoundaries = {pixelIr + 2, pixelOr - 7., 10.};
0144 auto pixelNecLayer = std::make_unique<Experimental::Gen2Blueprint::Node>(
0145 "pixelNecLayer",
0146 Transform3::Identity() * Translation3(0., 0., -detectorHz + pixelEcHz),
0147 VolumeBounds::eCylinder, pixelNecBoundaries, innerBuilder);
0148
0149 pixelNec->add(std::move(pixelNecLayer));
0150
0151
0152 std::vector<double> pixelBarrelBoundaries = {pixelIr + 1, pixelOr - 1.,
0153 detectorHz - 2 * pixelEcHz};
0154 std::vector<AxisDirection> pixelBarrelBinning = {AxisDirection::AxisR};
0155
0156 auto pixelBarrel = std::make_unique<Experimental::Gen2Blueprint::Node>(
0157 "pixelBarrel", Transform3::Identity(), VolumeBounds::eCylinder,
0158 pixelBarrelBoundaries, pixelBarrelBinning);
0159
0160 std::vector<double> pixelBarrelL0Boundaries = {60, 65.,
0161 detectorHz - 2 * pixelEcHz};
0162 auto pixelBarrelL0 = std::make_unique<Experimental::Gen2Blueprint::Node>(
0163 "pixelBarrelL0", Transform3::Identity(), VolumeBounds::eCylinder,
0164 pixelBarrelL0Boundaries, innerBuilder);
0165
0166 std::vector<double> pixelBarrelL1Boundaries = {100, 105.,
0167 detectorHz - 2 * pixelEcHz};
0168 auto pixelBarrelL1 = std::make_unique<Experimental::Gen2Blueprint::Node>(
0169 "pixelBarrelL1", Transform3::Identity(), VolumeBounds::eCylinder,
0170 pixelBarrelL1Boundaries, innerBuilder);
0171 pixelBarrel->add(std::move(pixelBarrelL0));
0172 pixelBarrel->add(std::move(pixelBarrelL1));
0173
0174 auto pixelPec = std::make_unique<Experimental::Gen2Blueprint::Node>(
0175 "pixelPec",
0176 Transform3::Identity() * Translation3(0., 0., +detectorHz - pixelEcHz),
0177 VolumeBounds::eCylinder, pixelEcBoundaries, pixelEcBinning);
0178
0179 std::vector<double> pixelPecBoundaries = {pixelIr + 2, pixelOr - 7., 10.};
0180 auto pixelPecLayer = std::make_unique<Experimental::Gen2Blueprint::Node>(
0181 "pixelPecLayer",
0182 Transform3::Identity() * Translation3(0., 0., detectorHz - pixelEcHz),
0183 VolumeBounds::eCylinder, pixelPecBoundaries, innerBuilder);
0184
0185 pixelPec->add(std::move(pixelPecLayer));
0186
0187
0188 pixel->add(std::move(pixelNec));
0189 pixel->add(std::move(pixelPec));
0190 pixel->add(std::move(pixelBarrel));
0191
0192 detector->add(std::move(pixel));
0193
0194 std::ofstream fs("detector_with_gaps.dot");
0195 Experimental::detail::BlueprintDrawer::dotStream(fs, *detector);
0196 fs.close();
0197
0198
0199 BOOST_CHECK_EQUAL(detector->children.size(), 2u);
0200 BOOST_CHECK_EQUAL(detector->children[0u]->name, "beam_pipe");
0201 BOOST_CHECK_EQUAL(detector->children[1u]->name, "pixel");
0202
0203
0204 Experimental::detail::BlueprintHelper::fillGaps(*detector);
0205
0206
0207 BOOST_CHECK_EQUAL(detector->children.size(), 4u);
0208 BOOST_CHECK_EQUAL(detector->children[0u]->name, "beam_pipe");
0209 BOOST_CHECK_EQUAL(detector->children[1u]->name, "detector_gap_0");
0210 BOOST_CHECK_EQUAL(detector->children[2u]->name, "pixel");
0211 BOOST_CHECK_EQUAL(detector->children[3u]->name, "detector_gap_1");
0212
0213
0214 BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[0], beamPipeOr);
0215 BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[1], pixelIr);
0216 BOOST_CHECK_EQUAL(detector->children[1u]->boundaryValues[2], detectorHz);
0217
0218 BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[0], pixelOr);
0219 BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[1], detectorOr);
0220 BOOST_CHECK_EQUAL(detector->children[3u]->boundaryValues[2], detectorHz);
0221
0222
0223 BOOST_CHECK_EQUAL(detector->children[2u]->children.size(), 3u);
0224 BOOST_CHECK_EQUAL(detector->children[2u]->children[0u]->children.size(), 3u);
0225 BOOST_CHECK_EQUAL(detector->children[2u]->children[1u]->children.size(), 5u);
0226 BOOST_CHECK_EQUAL(detector->children[2u]->children[2u]->children.size(), 3u);
0227
0228
0229 BOOST_CHECK_EQUAL(
0230 detector->children[2u]->children[0u]->children[0]->boundaryValues[0],
0231 pixelIr);
0232 BOOST_CHECK_EQUAL(
0233 detector->children[2u]->children[0u]->children[0]->boundaryValues[1],
0234 pixelOr);
0235
0236 BOOST_CHECK_EQUAL(
0237 detector->children[2u]->children[0u]->children[1]->boundaryValues[0],
0238 pixelIr);
0239 BOOST_CHECK_EQUAL(
0240 detector->children[2u]->children[0u]->children[1]->boundaryValues[1],
0241 pixelOr);
0242
0243 BOOST_CHECK_EQUAL(
0244 detector->children[2u]->children[0u]->children[2]->boundaryValues[0],
0245 pixelIr);
0246 BOOST_CHECK_EQUAL(
0247 detector->children[2u]->children[0u]->children[2]->boundaryValues[1],
0248 pixelOr);
0249
0250 std::ofstream fs2("detector_without_gaps.dot");
0251 Experimental::detail::BlueprintDrawer::dotStream(fs2, *detector);
0252 fs2.close();
0253 }
0254
0255 BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapException) {
0256 auto innerBuilder =
0257 std::make_shared<Experimental::IInternalStructureBuilder>();
0258
0259
0260 std::vector<double> detectorBoundaries = {0., 50., 100.};
0261 std::vector<AxisDirection> detectorBinning = {AxisDirection::AxisX};
0262 auto detector = std::make_unique<Experimental::Gen2Blueprint::Node>(
0263 "detector", Transform3::Identity(), VolumeBounds::eCylinder,
0264 detectorBoundaries, detectorBinning);
0265
0266
0267 std::vector<double> volTwoBoundaries = {0., 20., 100.};
0268 auto vol = std::make_unique<Experimental::Gen2Blueprint::Node>(
0269 "vol", Transform3::Identity(), VolumeBounds::eCylinder, volTwoBoundaries,
0270 innerBuilder);
0271 detector->add(std::move(vol));
0272
0273
0274 BOOST_CHECK_THROW(Experimental::detail::BlueprintHelper::fillGaps(*detector),
0275 std::runtime_error);
0276 }
0277
0278 BOOST_AUTO_TEST_SUITE_END()
0279
0280 }