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/CuboidalContainerBuilder.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/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/RectangleBounds.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/BinningData.hpp"
0028
0029 #include <fstream>
0030
0031 class SurfaceBuilder : public Acts::Experimental::IInternalStructureBuilder {
0032 public:
0033 SurfaceBuilder(const Acts::Transform3& transform,
0034 const Acts::RectangleBounds& sBounds)
0035 : m_transform(transform), m_surfaceBounds(sBounds){};
0036
0037
0038
0039
0040
0041
0042 Acts::Experimental::InternalStructure construct(
0043 [[maybe_unused]] const Acts::GeometryContext& gctx) const final {
0044 auto surface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0045 (m_transform),
0046 std::make_shared<Acts::RectangleBounds>(m_surfaceBounds));
0047
0048
0049 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0050 internalVolumes = {};
0051 Acts::Experimental::DetectorVolumeUpdater internalVolumeUpdater =
0052 Acts::Experimental::tryNoVolumes();
0053
0054
0055 Acts::Experimental::SurfaceCandidatesUpdater internalCandidatesUpdater =
0056 Acts::Experimental::tryAllPortalsAndSurfaces();
0057
0058
0059 return Acts::Experimental::InternalStructure{
0060 {surface},
0061 internalVolumes,
0062 std::move(internalCandidatesUpdater),
0063 std::move(internalVolumeUpdater)};
0064 }
0065
0066 private:
0067 Acts::Transform3 m_transform;
0068 Acts::RectangleBounds m_surfaceBounds;
0069 };
0070
0071 BOOST_AUTO_TEST_SUITE(Detector)
0072
0073 BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) {
0074 Acts::GeometryContext tContext;
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 Acts::ActsScalar detectorX = 100.;
0088 Acts::ActsScalar detectorY = 100.;
0089 Acts::ActsScalar detectorZ = 100.;
0090
0091
0092 Acts::ActsScalar pixelX = 20;
0093 Acts::ActsScalar pixelY = 100;
0094 Acts::ActsScalar pixelZ = 10;
0095
0096
0097 std::vector<Acts::BinningValue> detectorBins = {Acts::binX};
0098 std::vector<Acts::ActsScalar> detectorBounds = {detectorX, detectorY,
0099 detectorZ};
0100
0101
0102 auto detectorBpr = std::make_unique<Acts::Experimental::Blueprint::Node>(
0103 "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCuboid,
0104 detectorBounds, detectorBins);
0105
0106
0107 std::vector<Acts::ActsScalar> leftArmBounds = {detectorX * 0.5, detectorY,
0108 detectorZ};
0109
0110 std::vector<Acts::BinningValue> leftArmBins = {Acts::binZ};
0111
0112 Acts::Transform3 leftArmTransform =
0113 Acts::Transform3::Identity() *
0114 Acts::Translation3(-detectorX * 0.5, 0., 0);
0115
0116 auto leftArm = std::make_unique<Acts::Experimental::Blueprint::Node>(
0117 "leftArm", leftArmTransform, Acts::VolumeBounds::eCuboid, leftArmBounds,
0118 leftArmBins);
0119
0120
0121 std::vector<Acts::ActsScalar> pixelL1Boundaries = {pixelX, pixelY, pixelZ};
0122
0123 Acts::Transform3 pixelL1Transform =
0124 Acts::Transform3::Identity() *
0125 Acts::Translation3(-pixelX - 5, 0., -detectorZ + pixelZ + 5);
0126
0127 auto pixelL1Structure = std::make_shared<SurfaceBuilder>(
0128 pixelL1Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0129
0130 auto pixelL1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0131 "pixelL1", pixelL1Transform, Acts::VolumeBounds::eCuboid,
0132 pixelL1Boundaries, pixelL1Structure);
0133
0134
0135 std::vector<Acts::ActsScalar> pixelL2Boundaries = {pixelX, pixelY, pixelZ};
0136
0137 Acts::Transform3 pixelL2Transform =
0138 Acts::Transform3::Identity() *
0139 Acts::Translation3(-pixelX - 5, 0., -detectorZ + 2 * pixelZ + 5 * 5);
0140
0141 auto pixelL2Structure = std::make_shared<SurfaceBuilder>(
0142 pixelL2Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0143
0144 auto pixelL2 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0145 "pixelL2", pixelL2Transform, Acts::VolumeBounds::eCuboid,
0146 pixelL2Boundaries, pixelL2Structure);
0147
0148
0149
0150 leftArm->add(std::move(pixelL1));
0151 leftArm->add(std::move(pixelL2));
0152 detectorBpr->add(std::move(leftArm));
0153
0154
0155 std::vector<Acts::ActsScalar> rightArmBounds = {detectorX * 0.5, detectorY,
0156 detectorZ};
0157
0158 std::vector<Acts::BinningValue> rightArmBins = {Acts::binZ};
0159
0160 Acts::Transform3 rightArmTransform =
0161 Acts::Transform3::Identity() * Acts::Translation3(detectorX * 0.5, 0., 0);
0162
0163 auto rightArm = std::make_unique<Acts::Experimental::Blueprint::Node>(
0164 "rightArm", rightArmTransform, Acts::VolumeBounds::eCuboid,
0165 rightArmBounds, rightArmBins);
0166
0167
0168 std::vector<Acts::ActsScalar> pixelR1Boundaries = {pixelX, pixelY, pixelZ};
0169
0170 Acts::Transform3 pixelR1Transform =
0171 Acts::Transform3::Identity() *
0172 Acts::Translation3(pixelX + 5, 0., -detectorZ + pixelZ + 5);
0173
0174 auto pixelR1Structure = std::make_shared<SurfaceBuilder>(
0175 pixelR1Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0176
0177 auto pixelR1 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0178 "pixelR1", pixelR1Transform, Acts::VolumeBounds::eCuboid,
0179 pixelR1Boundaries, pixelR1Structure);
0180
0181
0182 std::vector<Acts::ActsScalar> pixelR2Boundaries = {pixelX, pixelY, pixelZ};
0183
0184 Acts::Transform3 pixelR2Transform =
0185 Acts::Transform3::Identity() *
0186 Acts::Translation3(pixelX + 5, 0., -detectorZ + 2 * pixelZ + 5 * 5);
0187
0188 auto pixelR2Structure = std::make_shared<SurfaceBuilder>(
0189 pixelR2Transform, Acts::RectangleBounds(pixelX * 0.8, pixelY * 0.8));
0190
0191 auto pixelR2 = std::make_unique<Acts::Experimental::Blueprint::Node>(
0192 "pixelR2", pixelR2Transform, Acts::VolumeBounds::eCuboid,
0193 pixelR2Boundaries, pixelR2Structure);
0194
0195
0196
0197 rightArm->add(std::move(pixelR1));
0198 rightArm->add(std::move(pixelR2));
0199 detectorBpr->add(std::move(rightArm));
0200
0201
0202 detectorBpr->geoIdGenerator =
0203 std::make_shared<Acts::Experimental::GeometryIdGenerator>(
0204 Acts::Experimental::GeometryIdGenerator::Config{},
0205 Acts::getDefaultLogger("RecursiveIdGenerator",
0206 Acts::Logging::VERBOSE));
0207
0208 std::cout << "Fill gaps ..." << std::endl;
0209
0210 Acts::Experimental::detail::BlueprintHelper::fillGaps(*detectorBpr);
0211 std::cout << "Filled gaps ..." << std::endl;
0212
0213 std::fstream fs("cylindrical_detector_blueprint.dot", std::ios::out);
0214 Acts::Experimental::detail::BlueprintDrawer::dotStream(fs, *detectorBpr);
0215 fs.close();
0216
0217
0218
0219
0220 auto detectorBuilder =
0221 std::make_shared<Acts::Experimental::CuboidalContainerBuilder>(
0222 *detectorBpr, Acts::Logging::VERBOSE);
0223
0224
0225 Acts::Experimental::DetectorBuilder::Config dCfg;
0226 dCfg.auxiliary = "*** Test : auto generated cuboidal detector builder ***";
0227 dCfg.name = "Cuboidal detector from blueprint";
0228 dCfg.builder = detectorBuilder;
0229 dCfg.geoIdGenerator = detectorBpr->geoIdGenerator;
0230
0231 auto detector = Acts::Experimental::DetectorBuilder(dCfg).construct(tContext);
0232
0233 BOOST_REQUIRE_NE(detector, nullptr);
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 BOOST_CHECK_EQUAL(detector->volumes().size(), 10u);
0247 BOOST_CHECK_EQUAL(detector->volumes()[0]->name(), "leftArm_gap_0");
0248 BOOST_CHECK_EQUAL(detector->volumes()[1]->name(), "pixelL1");
0249 BOOST_CHECK_EQUAL(detector->volumes()[2]->name(), "leftArm_gap_1");
0250 BOOST_CHECK_EQUAL(detector->volumes()[3]->name(), "pixelL2");
0251 BOOST_CHECK_EQUAL(detector->volumes()[4]->name(), "leftArm_gap_2");
0252 BOOST_CHECK_EQUAL(detector->volumes()[5]->name(), "rightArm_gap_0");
0253 BOOST_CHECK_EQUAL(detector->volumes()[6]->name(), "pixelR1");
0254 BOOST_CHECK_EQUAL(detector->volumes()[7]->name(), "rightArm_gap_1");
0255 BOOST_CHECK_EQUAL(detector->volumes()[8]->name(), "pixelR2");
0256 BOOST_CHECK_EQUAL(detector->volumes()[9]->name(), "rightArm_gap_2");
0257
0258
0259
0260 double internalStretchLeftZ =
0261 detector->volumes()[0]->volumeBounds().values()[Acts::binZ] +
0262 detector->volumes()[1]->volumeBounds().values()[Acts::binZ] +
0263 detector->volumes()[2]->volumeBounds().values()[Acts::binZ] +
0264 detector->volumes()[3]->volumeBounds().values()[Acts::binZ] +
0265 detector->volumes()[4]->volumeBounds().values()[Acts::binZ];
0266
0267 double internalStretchRightZ =
0268 detector->volumes()[5]->volumeBounds().values()[Acts::binZ] +
0269 detector->volumes()[6]->volumeBounds().values()[Acts::binZ] +
0270 detector->volumes()[7]->volumeBounds().values()[Acts::binZ] +
0271 detector->volumes()[8]->volumeBounds().values()[Acts::binZ] +
0272 detector->volumes()[9]->volumeBounds().values()[Acts::binZ];
0273
0274 double internalStretchX1 =
0275 detector->volumes()[0]->volumeBounds().values()[Acts::binX] +
0276 detector->volumes()[5]->volumeBounds().values()[Acts::binX];
0277
0278 double internalStretchX2 =
0279 detector->volumes()[1]->volumeBounds().values()[Acts::binX] +
0280 detector->volumes()[6]->volumeBounds().values()[Acts::binX];
0281
0282 double internalStretchX3 =
0283 detector->volumes()[2]->volumeBounds().values()[Acts::binX] +
0284 detector->volumes()[7]->volumeBounds().values()[Acts::binX];
0285
0286 double internalStretchX4 =
0287 detector->volumes()[3]->volumeBounds().values()[Acts::binX] +
0288 detector->volumes()[8]->volumeBounds().values()[Acts::binX];
0289
0290 double internalStretchX5 =
0291 detector->volumes()[4]->volumeBounds().values()[Acts::binX] +
0292 detector->volumes()[9]->volumeBounds().values()[Acts::binX];
0293
0294 BOOST_CHECK_EQUAL(internalStretchLeftZ, detectorZ);
0295 BOOST_CHECK_EQUAL(internalStretchRightZ, detectorZ);
0296 BOOST_CHECK_EQUAL(internalStretchX1, detectorX);
0297 BOOST_CHECK_EQUAL(internalStretchX2, detectorX);
0298 BOOST_CHECK_EQUAL(internalStretchX3, detectorX);
0299 BOOST_CHECK_EQUAL(internalStretchX4, detectorX);
0300 BOOST_CHECK_EQUAL(internalStretchX5, detectorX);
0301
0302 for (auto& volume : detector->volumes()) {
0303 BOOST_CHECK_EQUAL(volume->volumeBounds().values()[Acts::binY], detectorY);
0304 }
0305
0306
0307
0308 BOOST_CHECK_EQUAL(detector->volumes()[1]->surfaces().size(), 1u);
0309 BOOST_CHECK_EQUAL(detector->volumes()[3]->surfaces().size(), 1u);
0310 BOOST_CHECK_EQUAL(detector->volumes()[6]->surfaces().size(), 1u);
0311 BOOST_CHECK_EQUAL(detector->volumes()[8]->surfaces().size(), 1u);
0312
0313
0314
0315
0316
0317
0318
0319 std::vector<const Acts::Experimental::Portal*> portals;
0320 for (auto& volume : detector->volumes()) {
0321 portals.insert(portals.end(), volume->portals().begin(),
0322 volume->portals().end());
0323 }
0324 std::sort(portals.begin(), portals.end());
0325 auto last = std::unique(portals.begin(), portals.end());
0326 portals.erase(last, portals.end());
0327 BOOST_CHECK_EQUAL(portals.size(), 19u);
0328
0329
0330
0331
0332 bool samePortalY1 = true, samePortalY2 = true;
0333 for (int i = 0; i < 4; i++) {
0334 samePortalY1 =
0335 samePortalY1 && (detector->volumes()[i]->portals().at(4) ==
0336 detector->volumes()[i + 1]->portals().at(4));
0337 samePortalY2 =
0338 samePortalY2 && (detector->volumes()[5 + i]->portals().at(4) ==
0339 detector->volumes()[5 + i + 1]->portals().at(4));
0340 }
0341 BOOST_CHECK_EQUAL(samePortalY1, true);
0342 BOOST_CHECK_EQUAL(samePortalY2, true);
0343 samePortalY1 = true, samePortalY2 = true;
0344 for (int i = 0; i < 4; i++) {
0345 samePortalY1 =
0346 samePortalY1 && (detector->volumes()[i]->portals().at(5) ==
0347 detector->volumes()[i + 1]->portals().at(5));
0348 samePortalY2 =
0349 samePortalY2 && (detector->volumes()[5 + i]->portals().at(5) ==
0350 detector->volumes()[5 + i + 1]->portals().at(5));
0351 }
0352 BOOST_CHECK_EQUAL(samePortalY1, true);
0353 BOOST_CHECK_EQUAL(samePortalY2, true);
0354
0355
0356 for (int i = 0; i < 4; i++) {
0357 bool samePortalZ1 = (detector->volumes()[i]->portals().at(1) ==
0358 detector->volumes()[i + 1]->portals().at(0));
0359 bool samePortalZ2 = (detector->volumes()[5 + i]->portals().at(1) ==
0360 detector->volumes()[5 + i + 1]->portals().at(0));
0361
0362 BOOST_CHECK_EQUAL(samePortalZ1, true);
0363 BOOST_CHECK_EQUAL(samePortalZ2, true);
0364 }
0365
0366
0367 for (int i = 0; i < 5; i++) {
0368 bool samePortalX = (detector->volumes()[i]->portals().at(3) ==
0369 detector->volumes()[5 + i]->portals().at(2));
0370 BOOST_CHECK_EQUAL(samePortalX, true);
0371 }
0372 }
0373
0374 BOOST_AUTO_TEST_SUITE_END()