File indexing completed on 2025-08-06 08:11:17
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/CylindricalContainerBuilder.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/SurfaceCandidatesUpdaters.hpp"
0024 #include "Acts/Surfaces/CylinderSurface.hpp"
0025 #include "Acts/Surfaces/DiscSurface.hpp"
0026 #include "Acts/Utilities/BinningData.hpp"
0027
0028 #include <fstream>
0029
0030 template <typename surface_type>
0031 class SurfaceBuilder : public Acts::Experimental::IInternalStructureBuilder {
0032 public:
0033 SurfaceBuilder(const Acts::Transform3& trf, Acts::ActsScalar p0,
0034 Acts::ActsScalar p1)
0035 : m_surface(Acts::Surface::makeShared<surface_type>(trf, p0, p1)) {}
0036
0037
0038
0039
0040
0041 Acts::Experimental::InternalStructure construct(
0042 [[maybe_unused]] const Acts::GeometryContext& gctx) const final {
0043
0044 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0045 internalVolumes = {};
0046 Acts::Experimental::DetectorVolumeUpdater internalVolumeUpdater =
0047 Acts::Experimental::tryNoVolumes();
0048
0049
0050 Acts::Experimental::SurfaceCandidatesUpdater internalCandidatesUpdater =
0051 Acts::Experimental::tryAllPortalsAndSurfaces();
0052
0053
0054 return Acts::Experimental::InternalStructure{
0055 {m_surface},
0056 internalVolumes,
0057 std::move(internalCandidatesUpdater),
0058 std::move(internalVolumeUpdater)};
0059 }
0060
0061 private:
0062 std::shared_ptr<Acts::Surface> m_surface;
0063 };
0064
0065 BOOST_AUTO_TEST_SUITE(Detector)
0066
0067 BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) {
0068 Acts::GeometryContext tContext;
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 Acts::ActsScalar detectorIr = 0.;
0082 Acts::ActsScalar detectorOr = 120.;
0083 Acts::ActsScalar detectorHz = 400.;
0084
0085
0086 Acts::ActsScalar beamPipeOr = 20.;
0087
0088
0089 Acts::ActsScalar pixelIr = 25;
0090 Acts::ActsScalar pixelOr = 115;
0091 Acts::ActsScalar pixelEcHz = 50;
0092 Acts::ActsScalar pixelEcLayerHz = 10;
0093
0094
0095 std::vector<Acts::BinningValue> detectorBinning = {Acts::binR};
0096 std::vector<Acts::ActsScalar> detectorBoundaries = {detectorIr, detectorOr,
0097 detectorHz};
0098
0099
0100 auto detectorBpr = std::make_unique<Acts::Experimental::Blueprint::Node>(
0101 "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0102 detectorBoundaries, detectorBinning);
0103
0104
0105 std::vector<Acts::ActsScalar> beamPipeBoundaries = {detectorIr, beamPipeOr,
0106 detectorHz};
0107
0108 auto beamPipeStructure =
0109 std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0110 Acts::Transform3::Identity(), 18, 0.99 * detectorHz);
0111 auto beamPipe = std::make_unique<Acts::Experimental::Blueprint::Node>(
0112 "beam_pipe", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0113 beamPipeBoundaries, beamPipeStructure);
0114 detectorBpr->add(std::move(beamPipe));
0115
0116
0117 std::vector<Acts::ActsScalar> pixelBoundaries = {pixelIr, pixelOr,
0118 detectorHz};
0119 std::vector<Acts::BinningValue> pixelBinning = {Acts::binZ};
0120 auto pixel = std::make_unique<Acts::Experimental::Blueprint::Node>(
0121 "pixel", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder,
0122 pixelBoundaries, pixelBinning);
0123
0124
0125 std::vector<Acts::ActsScalar> pixelEcBoundaries = {pixelIr, pixelOr - 5.,
0126 pixelEcHz};
0127 std::vector<Acts::BinningValue> pixelEcBinning = {Acts::binZ};
0128
0129 Acts::Transform3 pixelNecTransform =
0130 Acts::Transform3::Identity() *
0131 Acts::Translation3(0., 0., -detectorHz + pixelEcHz);
0132
0133 auto pixelNec = std::make_unique<Acts::Experimental::Blueprint::Node>(
0134 "pixel_nec", pixelNecTransform, Acts::VolumeBounds::eCylinder,
0135 pixelEcBoundaries, pixelEcBinning);
0136
0137
0138 std::vector<Acts::ActsScalar> pixelNecBoundaries = {pixelIr + 2, pixelOr - 7.,
0139 pixelEcLayerHz};
0140
0141 auto pixelNecLayerStructure =
0142 std::make_shared<SurfaceBuilder<Acts::DiscSurface>>(
0143 pixelNecTransform, pixelIr + 10., pixelOr - 10.);
0144
0145 auto pixelNecLayer = std::make_unique<Acts::Experimental::Blueprint::Node>(
0146 "pixel_nec_layer", pixelNecTransform, Acts::VolumeBounds::eCylinder,
0147 pixelNecBoundaries, pixelNecLayerStructure);
0148
0149 pixelNec->add(std::move(pixelNecLayer));
0150
0151
0152 std::vector<Acts::ActsScalar> pixelBarrelBoundaries = {
0153 pixelIr + 1, pixelOr - 1., detectorHz - 2 * pixelEcHz};
0154 std::vector<Acts::BinningValue> pixelBarrelBinning = {Acts::binR};
0155
0156 auto pixelBarrel = std::make_unique<Acts::Experimental::Blueprint::Node>(
0157 "pixel_barrel", Acts::Transform3::Identity(),
0158 Acts::VolumeBounds::eCylinder, pixelBarrelBoundaries, pixelBarrelBinning);
0159
0160 auto pixelBarrelL0Structure =
0161 std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0162 Acts::Transform3::Identity(), 62.5, detectorHz - 2 * pixelEcHz - 10.);
0163 std::vector<Acts::ActsScalar> pixelBarrelL0Boundaries = {
0164 60, 65., detectorHz - 2 * pixelEcHz};
0165 auto pixelBarrelL0 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0166 "pixel_barrel_l0", Acts::Transform3::Identity(),
0167 Acts::VolumeBounds::eCylinder, pixelBarrelL0Boundaries,
0168 pixelBarrelL0Structure);
0169
0170 auto pixelBarrelL1Structure =
0171 std::make_shared<SurfaceBuilder<Acts::CylinderSurface>>(
0172 Acts::Transform3::Identity(), 102.5,
0173 detectorHz - 2 * pixelEcHz - 10.);
0174
0175 std::vector<Acts::ActsScalar> pixelBarrelL1Boundaries = {
0176 100, 105., detectorHz - 2 * pixelEcHz};
0177 auto pixelBarrelL1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0178 "pixel_barrel_l1", Acts::Transform3::Identity(),
0179 Acts::VolumeBounds::eCylinder, pixelBarrelL1Boundaries,
0180 pixelBarrelL1Structure);
0181 pixelBarrel->add(std::move(pixelBarrelL0));
0182 pixelBarrel->add(std::move(pixelBarrelL1));
0183
0184 Acts::Transform3 pixelPecTransform =
0185 Acts::Transform3::Identity() *
0186 Acts::Translation3(0., 0., detectorHz - pixelEcHz);
0187
0188 auto pixelPec = std::make_unique<Acts::Experimental::Blueprint::Node>(
0189 "pixel_pec", pixelPecTransform, Acts::VolumeBounds::eCylinder,
0190 pixelEcBoundaries, pixelEcBinning);
0191
0192 std::vector<Acts::ActsScalar> pixelPecBoundaries = {pixelIr + 2, pixelOr - 7.,
0193 10.};
0194
0195 auto pixelPecLayerStructure =
0196 std::make_shared<SurfaceBuilder<Acts::DiscSurface>>(
0197 pixelPecTransform, pixelIr + 10., pixelOr - 10.);
0198
0199 auto pixelPecLayer = std::make_unique<Acts::Experimental::Blueprint::Node>(
0200 "pixel_pec_layer", pixelPecTransform, Acts::VolumeBounds::eCylinder,
0201 pixelPecBoundaries, pixelPecLayerStructure);
0202
0203 pixelPec->add(std::move(pixelPecLayer));
0204
0205
0206 pixel->add(std::move(pixelNec));
0207 pixel->add(std::move(pixelPec));
0208 pixel->add(std::move(pixelBarrel));
0209
0210 detectorBpr->add(std::move(pixel));
0211
0212
0213 std::vector<Acts::BinningValue> rootVolumeBinning = {Acts::binZ, Acts::binR};
0214 detectorBpr->rootVolumeFinderBuilder =
0215 std::make_shared<Acts::Experimental::IndexedRootVolumeFinderBuilder>(
0216 rootVolumeBinning);
0217
0218
0219 detectorBpr->geoIdGenerator =
0220 std::make_shared<Acts::Experimental::GeometryIdGenerator>(
0221 Acts::Experimental::GeometryIdGenerator::Config{},
0222 Acts::getDefaultLogger("RecursiveIdGenerator",
0223 Acts::Logging::VERBOSE));
0224
0225
0226 Acts::Experimental::detail::BlueprintHelper::fillGaps(*detectorBpr);
0227
0228 std::fstream fs("cylindrical_detector_blueprint.dot", std::ios::out);
0229 Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detectorBpr);
0230 fs.close();
0231
0232
0233
0234
0235 auto detectorBuilder =
0236 std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0237 *detectorBpr, Acts::Logging::VERBOSE);
0238
0239
0240 Acts::Experimental::DetectorBuilder::Config dCfg;
0241 dCfg.auxiliary =
0242 "*** Test : auto generated cylindrical detector builder ***";
0243 dCfg.name = "Cylindrical detector from blueprint";
0244 dCfg.builder = detectorBuilder;
0245 dCfg.geoIdGenerator = detectorBpr->geoIdGenerator;
0246
0247 auto detector = Acts::Experimental::DetectorBuilder(dCfg).construct(tContext);
0248
0249 BOOST_REQUIRE_NE(detector, nullptr);
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 BOOST_CHECK_EQUAL(detector->volumes().size(), 14u);
0267 BOOST_CHECK_EQUAL(detector->volumes()[0]->name(), "beam_pipe");
0268 BOOST_CHECK_EQUAL(detector->volumes()[1]->name(), "detector_gap_0");
0269 BOOST_CHECK_EQUAL(detector->volumes()[2]->name(), "pixel_nec_gap_0");
0270 BOOST_CHECK_EQUAL(detector->volumes()[3]->name(), "pixel_nec_layer");
0271 BOOST_CHECK_EQUAL(detector->volumes()[4]->name(), "pixel_nec_gap_1");
0272 BOOST_CHECK_EQUAL(detector->volumes()[5]->name(), "pixel_barrel_gap_0");
0273 BOOST_CHECK_EQUAL(detector->volumes()[6]->name(), "pixel_barrel_l0");
0274 BOOST_CHECK_EQUAL(detector->volumes()[7]->name(), "pixel_barrel_gap_1");
0275 BOOST_CHECK_EQUAL(detector->volumes()[8]->name(), "pixel_barrel_l1");
0276 BOOST_CHECK_EQUAL(detector->volumes()[9]->name(), "pixel_barrel_gap_2");
0277 BOOST_CHECK_EQUAL(detector->volumes()[10]->name(), "pixel_pec_gap_0");
0278 BOOST_CHECK_EQUAL(detector->volumes()[11]->name(), "pixel_pec_layer");
0279 BOOST_CHECK_EQUAL(detector->volumes()[12]->name(), "pixel_pec_gap_1");
0280 BOOST_CHECK_EQUAL(detector->volumes()[13]->name(), "detector_gap_1");
0281 }
0282
0283 BOOST_AUTO_TEST_SUITE_END()