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