File indexing completed on 2025-10-29 07:55:50
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Surfaces/SurfaceBounds.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014 #include "ActsPlugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp"
0015 #include "ActsPlugins/DD4hep/DD4hepLayerStructure.hpp"
0016 #include "ActsTests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0017
0018 #include <fstream>
0019 #include <string>
0020
0021 #include <DD4hep/DetElement.h>
0022 #include <DD4hep/DetFactoryHelper.h>
0023 #include <DD4hep/Detector.h>
0024 #include <XML/Utilities.h>
0025 #include <XMLFragments.hpp>
0026
0027 #include "DD4hepTestsHelper.hpp"
0028
0029 using namespace Acts;
0030 using namespace ActsPlugins;
0031
0032 namespace ActsTests {
0033
0034 GeometryContext tContext;
0035 CylindricalTrackingGeometry cGeometry = CylindricalTrackingGeometry(tContext);
0036
0037 const char* beampipe_head_xml =
0038 R""""(
0039 <detectors>
0040 <detector id="0" name="BeamPipe" type="BarrelDetector">
0041 <type_flags type="DetType_TRACKER + DetType_BEAMPIPE"/>
0042 <layers>
0043 <layer name="BP" id="0">
0044 )"""";
0045
0046 const char* cylinder_layer_head_xml =
0047 R""""(
0048 <detectors>
0049 <detector id="1" name="BarrelLayer" type="BarrelDetector" readout="PixelReadout">
0050 <type_flags type="DetType_TRACKER + DetType_BARREL"/>
0051 <layers>
0052 <layer name="B0" id="0">
0053 )"""";
0054
0055 const char* tail_xml =
0056 R""""(
0057 </layer>
0058 </layers>
0059 </detector>
0060 </detectors>
0061 )"""";
0062
0063 const std::string indent_12_xml(12, ' ');
0064
0065 BOOST_AUTO_TEST_SUITE(DD4hepSuite)
0066
0067
0068 BOOST_AUTO_TEST_CASE(DD4hepPluginBeampipeStructure) {
0069
0070 std::ofstream cxml;
0071
0072 std::string fNameBase = "BeamPipe";
0073
0074 cxml.open(fNameBase + ".xml");
0075 cxml << head_xml;
0076 cxml << beampipe_head_xml;
0077 cxml << indent_12_xml << " <acts_passive_surface>" << '\n';
0078 cxml << indent_12_xml
0079 << " <tubs rmin=\"25*mm\" rmax=\"25.8*mm\" dz=\"1800*mm\" "
0080 "material=\"Air\"/>"
0081 << '\n';
0082 cxml << indent_12_xml << " </acts_passive_surface>" << '\n';
0083
0084 cxml << tail_xml;
0085 cxml << end_xml;
0086 cxml.close();
0087
0088 auto lcdd = &(dd4hep::Detector::getInstance());
0089 lcdd->fromCompact(fNameBase + ".xml");
0090 lcdd->volumeManager();
0091 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0092
0093 auto world = lcdd->world();
0094
0095
0096 DD4hepDetectorSurfaceFactory::Config sFactoryConfig;
0097 auto sFactory = std::make_shared<DD4hepDetectorSurfaceFactory>(
0098 sFactoryConfig,
0099 getDefaultLogger("DD4hepDetectorSurfaceFactory", Logging::DEBUG));
0100
0101 DD4hepLayerStructure beamPipeStructure(
0102 std::move(sFactory),
0103 getDefaultLogger("DD4hepBeamPipeStructure", Logging::VERBOSE));
0104
0105 DD4hepDetectorElement::Store dd4hepStore;
0106
0107 DD4hepLayerStructure::Options lsOptions;
0108 lsOptions.name = "BeamPipe";
0109 lsOptions.logLevel = Logging::VERBOSE;
0110
0111 auto [beamPipeInternalsBuilder, beamPipeExt] =
0112 beamPipeStructure.builder(dd4hepStore, tContext, world, lsOptions);
0113
0114
0115 BOOST_CHECK(beamPipeExt == std::nullopt);
0116
0117
0118 auto [surfaces, volumes, surfacesUpdater, volumeUpdater] =
0119 beamPipeInternalsBuilder->construct(tContext);
0120
0121
0122 BOOST_CHECK_EQUAL(surfaces.size(), 1u);
0123
0124 BOOST_CHECK(volumes.empty());
0125
0126 BOOST_CHECK(surfacesUpdater.connected());
0127
0128 BOOST_CHECK(volumeUpdater.connected());
0129
0130
0131 lcdd->destroyInstance();
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 BOOST_AUTO_TEST_CASE(DD4hepPluginCylinderLayerStructure) {
0145
0146 CylindricalTrackingGeometry::DetectorStore dStore;
0147 auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145,
0148 116., 3., 2., {52, 14});
0149
0150
0151
0152
0153
0154 std::vector<std::array<unsigned int, 4u> > zphiBinning = {
0155 {1u, 1u, 0u, 0u}, {14u, 52u, 1u, 1u}, {28u, 104u, 0u, 0u}};
0156
0157 std::size_t itest = 0;
0158 for (auto [nz, nphi, ez, ephi] : zphiBinning) {
0159
0160 std::ofstream cxml;
0161
0162 std::string fNameBase = "CylinderLayer_nz";
0163 fNameBase += std::to_string(nz);
0164 fNameBase += "_nphi";
0165 fNameBase += std::to_string(nphi);
0166
0167 cxml.open(fNameBase + ".xml");
0168 cxml << head_xml;
0169 cxml << segmentation_xml;
0170 cxml << cylinder_layer_head_xml;
0171
0172
0173 if (nz * nphi > 1u) {
0174 cxml << indent_12_xml << "<acts_surface_binning";
0175 cxml << " ztype=\"equidistant\"";
0176 cxml << " phitype=\"equidistant\"";
0177 cxml << " nz=\"" << nz << "\" zmin=\"-500*mm\" zmax=\"500*mm\"";
0178 cxml << " zexpansion= \"" << ez << "\"";
0179 cxml << " nphi=\"" << nphi << "\" phimin=\"-3.1415\" phimax=\"3.1415\"";
0180 cxml << " phiexpansion= \"" << ephi << "\"/>";
0181 }
0182 cxml << "<modules>" << '\n';
0183
0184 for (const auto& s : cSurfaces) {
0185 cxml << indent_12_xml
0186 << DD4hepTestsHelper::surfaceToXML(tContext, *s,
0187 Transform3::Identity())
0188 << "\n";
0189 }
0190
0191 cxml << "</modules>" << '\n';
0192
0193
0194 unsigned int passiveAddon = 0u;
0195 if (itest == 1u) {
0196 cxml << indent_12_xml << " <acts_passive_surface>" << '\n';
0197 cxml << indent_12_xml
0198 << " <tubs rmin=\"122*mm\" rmax=\"124*mm\" dz=\"500*mm\" "
0199 "material=\"Air\"/>"
0200 << '\n';
0201 cxml << indent_12_xml << " </acts_passive_surface>" << '\n';
0202 passiveAddon = 1u;
0203 }
0204 ++itest;
0205
0206 cxml << tail_xml;
0207 cxml << end_xml;
0208 cxml.close();
0209
0210 auto lcdd = &(dd4hep::Detector::getInstance());
0211 lcdd->fromCompact(fNameBase + ".xml");
0212 lcdd->volumeManager();
0213 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0214
0215 auto world = lcdd->world();
0216
0217
0218 DD4hepDetectorSurfaceFactory::Config sFactoryConfig;
0219 auto sFactory = std::make_shared<DD4hepDetectorSurfaceFactory>(
0220 sFactoryConfig,
0221 getDefaultLogger("DD4hepDetectorSurfaceFactory", Logging::VERBOSE));
0222
0223 DD4hepLayerStructure barrelStructure(
0224 std::move(sFactory),
0225 getDefaultLogger("DD4hepLayerStructure", Logging::VERBOSE));
0226
0227 DD4hepDetectorElement::Store dd4hepStore;
0228
0229 DD4hepLayerStructure::Options lsOptions;
0230 lsOptions.name = "BarrelLayer";
0231 lsOptions.logLevel = Logging::VERBOSE;
0232
0233 auto [barrelInternalsBuilder, barrelExt] =
0234 barrelStructure.builder(dd4hepStore, tContext, world, lsOptions);
0235
0236
0237 auto [surfaces, volumes, surfacesUpdater, volumeUpdater] =
0238 barrelInternalsBuilder->construct(tContext);
0239
0240
0241 BOOST_CHECK_EQUAL(surfaces.size(), 14u * 52u + passiveAddon);
0242
0243 BOOST_CHECK(volumes.empty());
0244
0245 BOOST_CHECK(surfacesUpdater.connected());
0246
0247 BOOST_CHECK(volumeUpdater.connected());
0248
0249
0250 lcdd->destroyInstance();
0251 }
0252 }
0253
0254
0255 BOOST_AUTO_TEST_CASE(DD4hepPluginCylinderLayerStructureAutoRange) {
0256
0257 CylindricalTrackingGeometry::DetectorStore dStore;
0258 auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145,
0259 116., 3., 2., {52, 14});
0260
0261
0262 std::ofstream cxml;
0263 std::string fName = "CylinderLayer_auto_range.xml";
0264
0265 cxml.open(fName);
0266 cxml << head_xml;
0267 cxml << segmentation_xml;
0268 cxml << cylinder_layer_head_xml;
0269
0270 cxml << "<modules>" << '\n';
0271 for (const auto& s : cSurfaces) {
0272 cxml << indent_12_xml
0273 << DD4hepTestsHelper::surfaceToXML(tContext, *s,
0274 Transform3::Identity())
0275 << "\n";
0276 }
0277 cxml << "</modules>" << '\n';
0278 cxml << tail_xml;
0279 cxml << end_xml;
0280 cxml.close();
0281
0282 auto lcdd = &(dd4hep::Detector::getInstance());
0283 lcdd->fromCompact(fName);
0284 lcdd->volumeManager();
0285 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0286
0287 auto world = lcdd->world();
0288
0289
0290 DD4hepDetectorSurfaceFactory::Config sFactoryConfig;
0291 auto sFactory = std::make_shared<DD4hepDetectorSurfaceFactory>(
0292 sFactoryConfig,
0293 getDefaultLogger("DD4hepDetectorSurfaceFactory", Logging::VERBOSE));
0294
0295 DD4hepLayerStructure barrelStructure(
0296 std::move(sFactory),
0297 getDefaultLogger("DD4hepLayerStructure", Logging::VERBOSE));
0298
0299 DD4hepDetectorElement::Store dd4hepStore;
0300
0301 DD4hepLayerStructure::Options lsOptions;
0302 lsOptions.name = "AutoRangeLayer";
0303 auto extent = Extent();
0304 lsOptions.extent = extent;
0305 lsOptions.extentConstraints = {AxisDirection::AxisZ, AxisDirection::AxisR};
0306 lsOptions.logLevel = Logging::VERBOSE;
0307
0308 auto [barrelInternalsBuilder, barrelExt] =
0309 barrelStructure.builder(dd4hepStore, tContext, world, lsOptions);
0310
0311 BOOST_CHECK(barrelExt != std::nullopt);
0312 BOOST_CHECK(barrelExt.value().constrains(AxisDirection::AxisZ));
0313 BOOST_CHECK(barrelExt.value().constrains(AxisDirection::AxisR));
0314 }
0315
0316 BOOST_AUTO_TEST_SUITE_END()
0317
0318 }