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