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