File indexing completed on 2025-07-11 07:51:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Geometry/ApproachDescriptor.hpp"
0013 #include "Acts/Geometry/BoundarySurfaceT.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Geometry/Layer.hpp"
0017 #include "Acts/Geometry/TrackingGeometry.hpp"
0018 #include "Acts/Geometry/TrackingVolume.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Surfaces/SurfaceArray.hpp"
0021 #include "Acts/Utilities/BinnedArray.hpp"
0022
0023 #include <cstddef>
0024 #include <memory>
0025 #include <unordered_map>
0026 #include <vector>
0027
0028 #include "TrackingVolumeCreation.hpp"
0029
0030 using namespace Acts::UnitLiterals;
0031
0032 namespace Acts::Test {
0033
0034
0035 GeometryContext tgContext = GeometryContext();
0036
0037 TrackingGeometry makeTrackingGeometry(const GeometryIdentifierHook& hook) {
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 double surfaceHalfLengthZ = 50_mm;
0049 double surfaceRstagger = 5_mm;
0050 double surfaceZoverlap = 10_mm;
0051 double layerEnvelope = 0.5_mm;
0052 double volumeEnvelope = 10_mm;
0053
0054
0055 double iiv_surfaceR = 25_mm;
0056 double iiv_volumeR =
0057 iiv_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0058
0059
0060 double iov_surfaceR = 100_mm;
0061 double iov_volumeR =
0062 iov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0063
0064
0065 auto iiVolume = constructCylinderVolume(
0066 tgContext, surfaceHalfLengthZ, iiv_surfaceR, surfaceRstagger,
0067 surfaceZoverlap, layerEnvelope, volumeEnvelope, 0., iiv_volumeR,
0068 "InnerInnerVolume");
0069
0070 auto ioVolume = constructCylinderVolume(
0071 tgContext, surfaceHalfLengthZ, iov_surfaceR, surfaceRstagger,
0072 surfaceZoverlap, layerEnvelope, volumeEnvelope, iiv_volumeR, iov_volumeR,
0073 "InnerOuterVolume");
0074
0075
0076 double volumeHalfZ =
0077 (4 * surfaceHalfLengthZ - surfaceZoverlap) + volumeEnvelope;
0078
0079 auto iVolume = constructContainerVolume(
0080 tgContext, iiVolume, ioVolume, iov_volumeR, volumeHalfZ, "InnerVolume");
0081
0082
0083 double ov_surfaceR = 150_mm;
0084 double ov_volumeR =
0085 ov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
0086
0087
0088 auto oVolume = constructCylinderVolume(
0089 tgContext, surfaceHalfLengthZ, ov_surfaceR, surfaceRstagger,
0090 surfaceZoverlap, layerEnvelope, volumeEnvelope, iov_volumeR, ov_volumeR,
0091 "OuterVolume");
0092
0093 auto volume = constructContainerVolume(
0094 tgContext, iVolume, oVolume, ov_volumeR, volumeHalfZ, "WorldVolume");
0095
0096
0097
0098 TrackingGeometry tGeometry(volume, nullptr, hook);
0099 return tGeometry;
0100 }
0101
0102 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test) {
0103 GeometryIdentifierHook hook{};
0104 TrackingGeometry tGeometry = makeTrackingGeometry(hook);
0105 auto world = tGeometry.highestTrackingVolume();
0106
0107
0108 auto check_vol = [](const TrackingVolume& vol,
0109 GeometryIdentifier::Value geoid) {
0110
0111 BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
0112
0113
0114 GeometryIdentifier::Value bsurface_id = 0;
0115 for (const auto& bSf : vol.boundarySurfaces()) {
0116
0117 auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
0118 BOOST_CHECK_EQUAL(geoid, bs_vol_id);
0119
0120 auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
0121 auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
0122 BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
0123 BOOST_CHECK_EQUAL(bs_ext_id, 0);
0124 }
0125
0126 if (vol.confinedLayers() != nullptr) {
0127
0128 GeometryIdentifier::Value layer_id = 0;
0129 for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
0130
0131 auto lay_vol_id = lay->geometryId().volume();
0132 auto lay_lay_id = lay->geometryId().layer();
0133 BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
0134 BOOST_CHECK_EQUAL(geoid, lay_vol_id);
0135
0136 if (lay->approachDescriptor() != nullptr) {
0137
0138 GeometryIdentifier::Value asurface_id = 0;
0139 for (const auto& asf :
0140 lay->approachDescriptor()->containedSurfaces()) {
0141
0142 auto asf_vol_id = asf->geometryId().volume();
0143 auto asf_lay_id = asf->geometryId().layer();
0144 auto asf_asf_id = asf->geometryId().approach();
0145 auto ssf_ext_id = asf->geometryId().extra();
0146 BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
0147 BOOST_CHECK_EQUAL(geoid, asf_vol_id);
0148 BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
0149 BOOST_CHECK_EQUAL(0, ssf_ext_id);
0150 }
0151 }
0152
0153 if (lay->surfaceArray() != nullptr) {
0154
0155 GeometryIdentifier::Value ssurface_id = 0;
0156 for (const auto& ssf : lay->surfaceArray()->surfaces()) {
0157
0158 auto ssf_vol_id = ssf->geometryId().volume();
0159 auto ssf_lay_id = ssf->geometryId().layer();
0160 auto ssf_ssf_id = ssf->geometryId().sensitive();
0161 auto ssf_ext_id = ssf->geometryId().extra();
0162 BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
0163 BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
0164 BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
0165 BOOST_CHECK_EQUAL(0, ssf_ext_id);
0166 }
0167 }
0168 }
0169 }
0170 };
0171
0172
0173 auto ioVolumes = world->confinedVolumes()->arrayObjects();
0174
0175 BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
0176
0177 auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
0178
0179 BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
0180
0181
0182 check_vol(*world, 1);
0183
0184 check_vol(*ioVolumes[0], 2);
0185
0186 check_vol(*iioVolumes[0], 3);
0187
0188 check_vol(*iioVolumes[1], 4);
0189
0190 check_vol(*ioVolumes[1], 5);
0191 }
0192
0193 template <typename Callable>
0194 struct CallableHook : public Acts::GeometryIdentifierHook {
0195 Callable callable;
0196
0197 explicit CallableHook(const Callable& c) : callable(c) {}
0198
0199 Acts::GeometryIdentifier decorateIdentifier(
0200 Acts::GeometryIdentifier identifier,
0201 const Acts::Surface& surface) const override {
0202 return callable(identifier, surface);
0203 }
0204 };
0205
0206 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test_extra) {
0207 std::size_t extra = 0;
0208 std::unordered_map<const Surface*, std::size_t> extraMap;
0209 auto hookImpl = [&](GeometryIdentifier orig, const Surface& srf) {
0210 ++extra;
0211 extraMap[&srf] = extra;
0212 return orig.withExtra(extra);
0213 };
0214 CallableHook<decltype(hookImpl)> hook{hookImpl};
0215
0216 TrackingGeometry tGeometry = makeTrackingGeometry(hook);
0217 auto world = tGeometry.highestTrackingVolume();
0218
0219
0220 auto check_vol = [&extraMap](const TrackingVolume& vol,
0221 GeometryIdentifier::Value geoid) {
0222
0223 BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
0224
0225
0226 GeometryIdentifier::Value bsurface_id = 0;
0227 for (const auto& bSf : vol.boundarySurfaces()) {
0228
0229 auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
0230 BOOST_CHECK_EQUAL(geoid, bs_vol_id);
0231
0232 auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
0233 auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
0234 BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
0235 BOOST_CHECK_EQUAL(bs_ext_id, 0);
0236 }
0237
0238 if (vol.confinedLayers() != nullptr) {
0239
0240 GeometryIdentifier::Value layer_id = 0;
0241 for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
0242
0243 auto lay_vol_id = lay->geometryId().volume();
0244 auto lay_lay_id = lay->geometryId().layer();
0245 BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
0246 BOOST_CHECK_EQUAL(geoid, lay_vol_id);
0247
0248 if (lay->approachDescriptor() != nullptr) {
0249
0250 GeometryIdentifier::Value asurface_id = 0;
0251 for (const auto& asf :
0252 lay->approachDescriptor()->containedSurfaces()) {
0253
0254 auto asf_vol_id = asf->geometryId().volume();
0255 auto asf_lay_id = asf->geometryId().layer();
0256 auto asf_asf_id = asf->geometryId().approach();
0257 auto ssf_ext_id = asf->geometryId().extra();
0258 BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
0259 BOOST_CHECK_EQUAL(geoid, asf_vol_id);
0260 BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
0261 BOOST_CHECK_EQUAL(0, ssf_ext_id);
0262 }
0263 }
0264
0265 if (lay->surfaceArray() != nullptr) {
0266
0267 GeometryIdentifier::Value ssurface_id = 0;
0268 for (const auto& ssf : lay->surfaceArray()->surfaces()) {
0269
0270 auto ssf_vol_id = ssf->geometryId().volume();
0271 auto ssf_lay_id = ssf->geometryId().layer();
0272 auto ssf_ssf_id = ssf->geometryId().sensitive();
0273 auto ssf_ext_id = ssf->geometryId().extra();
0274 BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
0275 BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
0276 BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
0277 BOOST_CHECK_EQUAL(extraMap[ssf], ssf_ext_id);
0278 }
0279 }
0280 }
0281 }
0282 };
0283
0284
0285 auto ioVolumes = world->confinedVolumes()->arrayObjects();
0286
0287 BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
0288
0289 auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
0290
0291 BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
0292
0293
0294 check_vol(*world, 1);
0295
0296 check_vol(*ioVolumes[0], 2);
0297
0298 check_vol(*iioVolumes[0], 3);
0299
0300 check_vol(*iioVolumes[1], 4);
0301
0302 check_vol(*ioVolumes[1], 5);
0303 }
0304
0305 BOOST_AUTO_TEST_CASE(TrackingGeometry_testVisitSurfaces) {
0306 GeometryIdentifierHook hook{};
0307 auto tGeometry = makeTrackingGeometry(hook);
0308
0309
0310 std::size_t nSurfaces = 0;
0311 tGeometry.visitSurfaces([&nSurfaces](const auto*) { nSurfaces++; });
0312 BOOST_CHECK_EQUAL(nSurfaces, 9u);
0313
0314
0315 std::size_t nVolumes = 0;
0316 tGeometry.visitVolumes([&nVolumes](const auto*) { nVolumes++; });
0317 BOOST_CHECK_EQUAL(nVolumes,
0318 5u);
0319
0320
0321 bool volumeCalled = false;
0322 tGeometry.apply([&](TrackingVolume& ) { volumeCalled = true; });
0323 BOOST_CHECK(volumeCalled);
0324
0325
0326 bool constVolumeCalled = false;
0327 tGeometry.apply(
0328 [&](const TrackingVolume& ) { constVolumeCalled = true; });
0329 BOOST_CHECK(constVolumeCalled);
0330
0331
0332 bool surfaceCalled = false;
0333 bool portalCalled = false;
0334 tGeometry.apply(overloaded{
0335 [&](Surface& ) { surfaceCalled = true; },
0336 [&](Portal& ) { portalCalled = true; },
0337 [&](TrackingVolume& ) {},
0338 });
0339 BOOST_CHECK(surfaceCalled);
0340
0341 BOOST_CHECK(!portalCalled);
0342
0343
0344 bool lambdaVolumeCalled = false;
0345 tGeometry.apply([&](Volume& ) { lambdaVolumeCalled = true; });
0346 BOOST_CHECK(lambdaVolumeCalled);
0347 }
0348
0349 }