File indexing completed on 2025-01-18 09:13:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Detector/DetectorVolume.hpp"
0013 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0014 #include "Acts/Detector/LayerStructureBuilder.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0017 #include "Acts/Geometry/ConeVolumeBounds.hpp"
0018 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0021 #include "Acts/Navigation/InternalNavigation.hpp"
0022 #include "Acts/Plugins/Json/DetectorVolumeJsonConverter.hpp"
0023 #include "Acts/Surfaces/CylinderBounds.hpp"
0024 #include "Acts/Surfaces/CylinderSurface.hpp"
0025 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027
0028 #include <fstream>
0029 #include <memory>
0030 #include <numbers>
0031 #include <vector>
0032
0033 #include <nlohmann/json.hpp>
0034
0035 namespace {
0036
0037
0038
0039 std::vector<std::shared_ptr<Acts::Surface>> unpackSurfaces(
0040 const std::vector<const Acts::Surface*>& surfaces) {
0041 std::vector<std::shared_ptr<Acts::Surface>> uSurfaces;
0042 uSurfaces.reserve(surfaces.size());
0043 for (const auto s : surfaces) {
0044 auto* ncs = const_cast<Acts::Surface*>(s);
0045 uSurfaces.push_back(ncs->getSharedPtr());
0046 }
0047 return uSurfaces;
0048 }
0049
0050 }
0051
0052 Acts::GeometryContext tContext;
0053 auto cGeometry = Acts::Test::CylindricalTrackingGeometry(tContext);
0054
0055 auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0056
0057 BOOST_AUTO_TEST_SUITE(DetectorVolumeJsonConverter)
0058
0059 BOOST_AUTO_TEST_CASE(SingleEmptyVolume) {
0060
0061 Acts::Transform3 nominal = Acts::Transform3::Identity();
0062 auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0063
0064 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0065 portalGenerator, tContext, "EmptyVolume", nominal, std::move(bounds),
0066 Acts::Experimental::tryAllPortals());
0067
0068 std::ofstream out;
0069
0070 auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0071 {volume.get()});
0072
0073 out.open("single-empty-volume.json");
0074 out << jVolume.dump(4);
0075 out.close();
0076
0077 auto in = std::ifstream("single-empty-volume.json",
0078 std::ifstream::in | std::ifstream::binary);
0079
0080 BOOST_CHECK(in.good());
0081 nlohmann::json jVolumeIn;
0082 in >> jVolumeIn;
0083 in.close();
0084
0085 auto volumeIn =
0086 Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0087
0088 BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0089 BOOST_CHECK(
0090 volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0091 BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0092 BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0093 }
0094
0095 BOOST_AUTO_TEST_CASE(SingleSurfaceVolume) {
0096
0097 Acts::Transform3 nominal = Acts::Transform3::Identity();
0098 auto volumeBounds =
0099 std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0100 auto surfaceBounds = std::make_unique<Acts::CylinderBounds>(25., 100.);
0101
0102 auto cylinderSurface = Acts::Surface::makeShared<Acts::CylinderSurface>(
0103 nominal, std::move(surfaceBounds));
0104
0105 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0106 portalGenerator, tContext, "CylinderVolume", nominal,
0107 std::move(volumeBounds), {cylinderSurface}, {},
0108 Acts::Experimental::tryRootVolumes(),
0109 Acts::Experimental::tryAllPortalsAndSurfaces());
0110
0111 std::ofstream out;
0112
0113 auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0114 {volume.get()});
0115
0116 out.open("single-surface-volume.json");
0117 out << jVolume.dump(4);
0118 out.close();
0119
0120 auto in = std::ifstream("single-surface-volume.json",
0121 std::ifstream::in | std::ifstream::binary);
0122
0123 BOOST_CHECK(in.good());
0124 nlohmann::json jVolumeIn;
0125 in >> jVolumeIn;
0126 in.close();
0127
0128 auto volumeIn =
0129 Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0130
0131 BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0132 BOOST_CHECK(
0133 volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0134 BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0135 BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0136 }
0137
0138 BOOST_AUTO_TEST_CASE(EndcapVolumeWithSurfaces) {
0139 Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0140
0141 auto rSurfaces = cGeometry.surfacesRing(dStore, 6.4, 12.4, 36., 0.125, 0.,
0142 55., -800, 2., 22u);
0143
0144 auto endcapSurfaces = std::make_shared<
0145 Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0146 unpackSurfaces(rSurfaces));
0147
0148 Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0149 lsConfig.auxiliary = "*** Endcap with 22 surfaces ***";
0150 lsConfig.surfacesProvider = endcapSurfaces;
0151 lsConfig.binnings = {Acts::Experimental::ProtoBinning(
0152 Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0153 -std::numbers::pi, std::numbers::pi, 22u, 1u)};
0154
0155 auto layerBuilder =
0156 std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0157 lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0158 Acts::Logging::VERBOSE));
0159
0160 Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0161 shapeConfig.boundValues = {10, 100, 10., std::numbers::pi, 0.};
0162 shapeConfig.transform =
0163 Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0164 Acts::Vector3(0., 0., -800.));
0165 shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0166
0167 auto shapeBuilder =
0168 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0169 shapeConfig,
0170 Acts::getDefaultLogger("EndcapShapeBuilder", Acts::Logging::VERBOSE));
0171
0172 Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0173 dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0174 dvCfg.name = "CylinderWithSurface";
0175 dvCfg.externalsBuilder = shapeBuilder;
0176 dvCfg.internalsBuilder = layerBuilder;
0177
0178 auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0179 dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0180
0181 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0182 auto volume = volumes.front();
0183
0184 auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0185 {volume.get()});
0186
0187 std::ofstream out;
0188 out.open("endcap-volume-with-surfaces.json");
0189 out << jVolume.dump(4);
0190 out.close();
0191
0192 auto in = std::ifstream("endcap-volume-with-surfaces.json",
0193 std::ifstream::in | std::ifstream::binary);
0194
0195 BOOST_CHECK(in.good());
0196 nlohmann::json jVolumeIn;
0197 in >> jVolumeIn;
0198 in.close();
0199
0200 auto volumeIn =
0201 Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0202
0203 BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0204 BOOST_CHECK(
0205 volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0206 BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0207 BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0208
0209
0210 jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0211 {volumeIn.get()});
0212 out.open("endcap-volume-with-surfaces-closure.json");
0213 out << jVolume.dump(4);
0214 out.close();
0215 }
0216
0217 BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) {
0218 Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0219 auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0220 3., 2., {32u, 14u});
0221
0222 auto barrelSurfaces = std::make_shared<
0223 Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0224 unpackSurfaces(cSurfaces));
0225
0226
0227 Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0228 lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0229 lsConfig.surfacesProvider = barrelSurfaces;
0230 lsConfig.binnings = {
0231 Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ,
0232 Acts::AxisBoundaryType::Bound, -480.,
0233 480., 14u, 1u},
0234 Acts::Experimental::ProtoBinning(
0235 Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0236 -std::numbers::pi, std::numbers::pi, 32u, 1u)};
0237
0238 auto barrelBuilder =
0239 std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0240 lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0241 Acts::Logging::VERBOSE));
0242
0243 Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0244 shapeConfig.boundValues = {60., 80., 800., std::numbers::pi, 0.};
0245 shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0246
0247 auto shapeBuilder =
0248 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0249 shapeConfig,
0250 Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0251
0252 Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0253 dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0254 dvCfg.name = "BarrelWithSurfaces";
0255 dvCfg.externalsBuilder = shapeBuilder;
0256 dvCfg.internalsBuilder = barrelBuilder;
0257
0258 auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0259 dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0260
0261 auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0262
0263 auto volume = volumes.front();
0264
0265 auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0266 {volume.get()});
0267
0268 std::ofstream out;
0269 out.open("barrel-volume-with-surfaces.json");
0270 out << jVolume.dump(4);
0271 out.close();
0272
0273 auto in = std::ifstream("barrel-volume-with-surfaces.json",
0274 std::ifstream::in | std::ifstream::binary);
0275
0276 BOOST_CHECK(in.good());
0277 nlohmann::json jVolumeIn;
0278 in >> jVolumeIn;
0279 in.close();
0280
0281 auto volumeIn =
0282 Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0283
0284 BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0285 BOOST_CHECK(
0286 volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0287 BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0288 BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0289
0290
0291 jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0292 {volumeIn.get()});
0293 out.open("barrel-volume-with-surfaces-closure.json");
0294 out << jVolume.dump(4);
0295 out.close();
0296 }
0297
0298 BOOST_AUTO_TEST_SUITE_END()