File indexing completed on 2025-12-16 09:25:31
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/Geometry/GeometryContext.hpp"
0013 #include "Acts/Surfaces/Surface.hpp"
0014 #include "ActsPlugins/DD4hep/DD4hepDetectorElement.hpp"
0015 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0016
0017 #include <fstream>
0018 #include <iostream>
0019
0020 #include <DD4hep/DetElement.h>
0021 #include <DD4hep/Detector.h>
0022
0023 #include "DD4hep/DetFactoryHelper.h"
0024 #include "XML/Utilities.h"
0025 #include "XMLFragments.hpp"
0026
0027 using namespace Acts;
0028 using namespace ActsPlugins;
0029
0030 GeometryContext tContext;
0031
0032 const char* cylinder_xml =
0033 R""""(
0034 <detectors>
0035 <detector id="1" name="Cylinder" type="Cylinder">
0036 <type_flags type="DetType_TRACKER"/>
0037 <tubs name="Cylinder" rmin="10*cm" rmax="11*cm" dz="100*cm" material="Vacuum" sensitive="true"/>
0038 </detector>
0039 </detectors>
0040 )"""";
0041
0042 const char* sectoral_cylinder_xml =
0043 R""""(
0044 <detectors>
0045 <detector id="1" name="SectoralCylinder" type="Cylinder">
0046 <type_flags type="DetType_TRACKER"/>
0047 <tubs name="Cylinder" rmin="10*cm" rmax="11*cm" dz="100*cm" phimin="0.1*rad" phimax="0.8*rad" material="Vacuum" sensitive="true"/>
0048 </detector>
0049 </detectors>
0050 )"""";
0051
0052 const char* disc_xml =
0053 R""""(
0054 <detectors>
0055 <detector id="1" name="Disc" type="Disc">
0056 <type_flags type="DetType_TRACKER"/>
0057 <tubs name="Disc" rmin="10*cm" rmax="90*cm" dz="1*cm" material="Vacuum" sensitive="true"/>
0058 </detector>
0059 </detectors>
0060 )"""";
0061
0062 const char* sectoral_disc_xml =
0063 R""""(
0064 <detectors>
0065 <detector id="1" name="SectoralDisc" type="Disc">
0066 <type_flags type="DetType_TRACKER"/>
0067 <tubs name="Disc" rmin="10*cm" rmax="90*cm" dz="1*cm" phimin="0.*rad" phimax="1.5*rad" material="Vacuum" sensitive="true"/>
0068 </detector>
0069 </detectors>
0070 )"""";
0071
0072 const char* rectangle_xml =
0073 R""""(
0074 <detectors>
0075 <detector id="1" name="Rectangle" type="Rectangle">
0076 <type_flags type="DetType_TRACKER"/>
0077 <box name="Rectangle" dx="10*cm" dy="90*cm" dz="0.1*cm" cx="1.*cm" cy="2.*cm" cz="3.*cm" material="Vacuum" sensitive="true"/>
0078 </detector>
0079 </detectors>
0080 )"""";
0081
0082 const char* trapezoid_xml =
0083 R""""(
0084 <detectors>
0085 <detector id="1" name="Trapezoid" type="Trapezoid">
0086 <type_flags type="DetType_TRACKER"/>
0087 <trap name="Trapezoid" x1="10*cm" x2="20*cm" dy="30*cm" dz="0.1*cm" cx="2.*cm" cy="3.*cm" cz="4.*cm" material="Vacuum" sensitive="true"/>
0088 </detector>
0089 </detectors>
0090 )"""";
0091
0092 namespace ActsTests {
0093
0094 BOOST_AUTO_TEST_SUITE(DD4hepSuite)
0095
0096 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementCylinder) {
0097 std::ofstream cxml;
0098 cxml.open("Cylinder.xml");
0099 cxml << head_xml;
0100 cxml << cylinder_xml;
0101 cxml << end_xml;
0102 cxml.close();
0103
0104 auto lcdd = &(dd4hep::Detector::getInstance());
0105 lcdd->fromCompact("Cylinder.xml");
0106 lcdd->volumeManager();
0107 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0108
0109 auto world = lcdd->world();
0110
0111 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> cylindricalElement =
0112 nullptr;
0113 for (const auto& [chn, child] : world.children()) {
0114 cylindricalElement =
0115 std::make_shared<ActsPlugins::DD4hepDetectorElement>(child, "XYZ", 10.);
0116 }
0117
0118 BOOST_REQUIRE_NE(cylindricalElement, nullptr);
0119
0120 const auto& surface = cylindricalElement->surface();
0121 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Cylinder);
0122 BOOST_CHECK(surface.transform(tContext).isApprox(Transform3::Identity()));
0123 auto boundValues = surface.bounds().values();
0124 CHECK_CLOSE_ABS(boundValues[0u], 105., 1e-10);
0125 CHECK_CLOSE_ABS(boundValues[1u], 1000., 1e-10);
0126 lcdd->destroyInstance();
0127 }
0128
0129 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementSectoralCylinder) {
0130 std::ofstream cxml;
0131 cxml.open("SectoralCylinder.xml");
0132 cxml << head_xml;
0133 cxml << sectoral_cylinder_xml;
0134 cxml << end_xml;
0135 cxml.close();
0136
0137 auto lcdd = &(dd4hep::Detector::getInstance());
0138 lcdd->fromCompact("SectoralCylinder.xml");
0139 lcdd->volumeManager();
0140 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0141
0142 auto world = lcdd->world();
0143
0144 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> cylindricalElement =
0145 nullptr;
0146 for (const auto& [chn, child] : world.children()) {
0147 cylindricalElement =
0148 std::make_shared<ActsPlugins::DD4hepDetectorElement>(child, "XYZ", 10.);
0149 }
0150
0151 BOOST_REQUIRE_NE(cylindricalElement, nullptr);
0152
0153 const auto& surface = cylindricalElement->surface();
0154 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Cylinder);
0155 BOOST_CHECK(surface.transform(tContext).isApprox(Transform3::Identity()));
0156 auto boundValues = surface.bounds().values();
0157 CHECK_CLOSE_ABS(boundValues[0u], 105., 1e-10);
0158 CHECK_CLOSE_ABS(boundValues[1u], 1000., 1e-10);
0159 CHECK_CLOSE_ABS(boundValues[2u], 0.35, 1e-10);
0160 CHECK_CLOSE_ABS(boundValues[3u], 0.45, 1e-10);
0161 lcdd->destroyInstance();
0162 }
0163
0164 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementDisc) {
0165 std::ofstream cxml;
0166 cxml.open("Disc.xml");
0167 cxml << head_xml;
0168 cxml << disc_xml;
0169 cxml << end_xml;
0170 cxml.close();
0171
0172 auto lcdd = &(dd4hep::Detector::getInstance());
0173 lcdd->fromCompact("Disc.xml");
0174 lcdd->volumeManager();
0175 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0176
0177 auto world = lcdd->world();
0178
0179 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> discElement = nullptr;
0180 for (const auto& [chn, child] : world.children()) {
0181 discElement = std::make_shared<ActsPlugins::DD4hepDetectorElement>(
0182 child, "XYZ", 10., true);
0183 }
0184
0185 BOOST_REQUIRE_NE(discElement, nullptr);
0186
0187 const auto& surface = discElement->surface();
0188 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Disc);
0189 BOOST_CHECK(surface.transform(tContext).isApprox(Transform3::Identity()));
0190 auto boundValues = surface.bounds().values();
0191 CHECK_CLOSE_ABS(boundValues[0u], 100., 1e-10);
0192 CHECK_CLOSE_ABS(boundValues[1u], 900., 1e-10);
0193 lcdd->destroyInstance();
0194 }
0195
0196 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementSectoralDisc) {
0197 std::ofstream cxml;
0198 cxml.open("SectoralDisc.xml");
0199 cxml << head_xml;
0200 cxml << sectoral_disc_xml;
0201 cxml << end_xml;
0202 cxml.close();
0203
0204 auto lcdd = &(dd4hep::Detector::getInstance());
0205 lcdd->fromCompact("SectoralDisc.xml");
0206 lcdd->volumeManager();
0207 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0208
0209 auto world = lcdd->world();
0210
0211 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> discElement = nullptr;
0212 for (const auto& [chn, child] : world.children()) {
0213 discElement = std::make_shared<ActsPlugins::DD4hepDetectorElement>(
0214 child, "XYZ", 10., true);
0215 }
0216
0217 BOOST_REQUIRE_NE(discElement, nullptr);
0218
0219 const auto& surface = discElement->surface();
0220 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Disc);
0221 BOOST_CHECK(surface.transform(tContext).isApprox(Transform3::Identity()));
0222 auto boundValues = surface.bounds().values();
0223
0224 CHECK_CLOSE_ABS(boundValues[0u], 100., 1e-10);
0225 CHECK_CLOSE_ABS(boundValues[1u], 900., 1e-10);
0226 CHECK_CLOSE_ABS(boundValues[2u], 0.75, 1e-10);
0227 CHECK_CLOSE_ABS(boundValues[3u], 0.75, 1e-10);
0228 lcdd->destroyInstance();
0229 }
0230
0231 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementRectangle) {
0232 std::ofstream cxml;
0233 cxml.open("Rectangle.xml");
0234 cxml << head_xml;
0235 cxml << rectangle_xml;
0236 cxml << end_xml;
0237 cxml.close();
0238
0239 auto lcdd = &(dd4hep::Detector::getInstance());
0240 lcdd->fromCompact("Rectangle.xml");
0241 lcdd->volumeManager();
0242 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0243
0244 auto world = lcdd->world();
0245
0246 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> rectangleElement =
0247 nullptr;
0248 for (const auto& [chn, child] : world.children()) {
0249 rectangleElement = std::make_shared<ActsPlugins::DD4hepDetectorElement>(
0250 child, "XYZ", 10., true);
0251 }
0252
0253 BOOST_REQUIRE_NE(rectangleElement, nullptr);
0254
0255 Surface& surface = rectangleElement->surface();
0256 surface.assignGeometryId(GeometryIdentifier().withVolume(1).withLayer(2));
0257 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Plane);
0258
0259 auto sTransform = surface.transform(tContext);
0260 BOOST_CHECK(sTransform.translation().isApprox(Vector3(10., 20., 30.)));
0261
0262 const auto& sBounds = surface.bounds();
0263 BOOST_CHECK_EQUAL(sBounds.type(), SurfaceBounds::BoundsType::eRectangle);
0264
0265 auto boundValues = sBounds.values();
0266
0267 CHECK_CLOSE_ABS(boundValues[0u], -50., 1e-10);
0268 CHECK_CLOSE_ABS(boundValues[1u], -450., 1e-10);
0269 CHECK_CLOSE_ABS(boundValues[2u], 50, 1e-10);
0270 CHECK_CLOSE_ABS(boundValues[3u], 450, 1e-10);
0271
0272
0273 lcdd->destroyInstance();
0274 }
0275
0276 BOOST_AUTO_TEST_CASE(DD4hepPluginDetectorElementTrapezoid) {
0277 std::ofstream cxml;
0278 cxml.open("Trapezoid.xml");
0279 cxml << head_xml;
0280 cxml << trapezoid_xml;
0281 cxml << end_xml;
0282 cxml.close();
0283
0284 auto lcdd = &(dd4hep::Detector::getInstance());
0285 lcdd->fromCompact("Trapezoid.xml");
0286 lcdd->volumeManager();
0287 lcdd->apply("DD4hepVolumeManager", 0, nullptr);
0288
0289 auto world = lcdd->world();
0290
0291 std::shared_ptr<ActsPlugins::DD4hepDetectorElement> trapezoidElement =
0292 nullptr;
0293 for (const auto& [chn, child] : world.children()) {
0294 trapezoidElement = std::make_shared<ActsPlugins::DD4hepDetectorElement>(
0295 child, "xZ", 10., true);
0296 }
0297
0298 BOOST_REQUIRE_NE(trapezoidElement, nullptr);
0299
0300 const auto& surface = trapezoidElement->surface();
0301 BOOST_CHECK_EQUAL(surface.type(), Surface::SurfaceType::Plane);
0302
0303 auto sTransform = surface.transform(tContext);
0304 BOOST_CHECK(sTransform.translation().isApprox(Vector3(20., 30., 40.)));
0305
0306 const auto& sBounds = surface.bounds();
0307 BOOST_CHECK_EQUAL(sBounds.type(), SurfaceBounds::BoundsType::eTrapezoid);
0308
0309 auto boundValues = sBounds.values();
0310 CHECK_CLOSE_ABS(boundValues[0u], 100., 1e-10);
0311 CHECK_CLOSE_ABS(boundValues[1u], 200., 1e-10);
0312 CHECK_CLOSE_ABS(boundValues[2u], 150, 1e-10);
0313
0314 lcdd->destroyInstance();
0315 }
0316
0317 BOOST_AUTO_TEST_SUITE_END()
0318
0319 }