File indexing completed on 2026-09-15 08:26:13
0001
0002
0003
0004 #include <DD4hep/DetElement.h>
0005 #include <DD4hep/Detector.h>
0006 #include <DD4hep/Handle.h>
0007 #include <DD4hep/IDDescriptor.h>
0008 #include <DD4hep/Objects.h>
0009 #include <DD4hep/Readout.h>
0010 #include <DD4hep/Segmentations.h>
0011 #include <DD4hep/Shapes.h>
0012 #include <DD4hep/VolumeManager.h>
0013 #include <DD4hep/Volumes.h>
0014 #include <DD4hep/detail/DetectorInterna.h>
0015 #include <DD4hep/detail/SegmentationsInterna.h>
0016 #include <DDSegmentation/CartesianGridXY.h>
0017 #include <DDSegmentation/MultiSegmentation.h>
0018 #include <Math/GenVector/Cartesian3D.h>
0019 #include <Math/GenVector/DisplacementVector3D.h>
0020 #include <TGeoMaterial.h>
0021 #include <TGeoMedium.h>
0022 #include <algorithms/geo.h>
0023 #include <algorithms/interfaces/ActsSvc.h>
0024 #include <algorithms/interfaces/UniqueIDGenSvc.h>
0025 #include <algorithms/random.h>
0026 #include <algorithms/service.h>
0027 #include <catch2/generators/catch_generators_random.hpp>
0028 #include <catch2/interfaces/catch_interfaces_reporter.hpp>
0029 #include <catch2/reporters/catch_reporter_event_listener.hpp>
0030 #include <catch2/reporters/catch_reporter_registrars.hpp>
0031 #include <services/evaluator/EvaluatorSvc.h>
0032 #include <services/particle/ParticleSvc.h>
0033 #include <services/pid_lut/PIDLookupTableSvc.h>
0034 #include <cstddef>
0035 #include <cstdint>
0036 #include <functional>
0037 #include <memory>
0038 #include <string>
0039 #include <utility>
0040
0041 #include "algorithms/tracking/ActsGeometryProvider.h"
0042 class algorithmsInitListener : public Catch::EventListenerBase {
0043 public:
0044 using Catch::EventListenerBase::EventListenerBase;
0045
0046 std::unique_ptr<const dd4hep::Detector> m_detector{nullptr};
0047 std::shared_ptr<ActsGeometryProvider> m_actsGeoProvider{nullptr};
0048
0049 void testRunStarting(Catch::TestRunInfo const& ) override {
0050 auto detector = dd4hep::Detector::make_unique("");
0051 detector->addConstant(dd4hep::Constant("MockCalorimeter_ID", "1"));
0052 dd4hep::Readout readout(std::string("MockCalorimeterHits"));
0053 dd4hep::IDDescriptor id_desc("MockCalorimeterHits", "system:8,layer:8,x:8,y:8");
0054 readout.setIDDescriptor(id_desc);
0055 detector->add(id_desc);
0056 detector->add(readout);
0057
0058 detector->addConstant(dd4hep::Constant("MockTracker_ID", "2"));
0059 dd4hep::Readout readoutTracker(std::string("MockTrackerHits"));
0060 dd4hep::IDDescriptor id_desc_tracker("MockTrackerHits", "system:8,layer:8,x:8,y:8");
0061
0062 dd4hep::Segmentation segmentation("CartesianGridXY", "TrackerHitsSeg",
0063 id_desc_tracker.decoder());
0064 readoutTracker.setIDDescriptor(id_desc_tracker);
0065 readoutTracker.setSegmentation(segmentation);
0066 detector->add(id_desc_tracker);
0067 detector->add(readoutTracker);
0068
0069 dd4hep::Readout readoutSilicon(std::string("MockSiliconHits"));
0070 dd4hep::IDDescriptor id_desc_Silicon("MockSiliconHits",
0071 "system:8,layer:4,module:12,sensor:10,x:40:-8,y:-16");
0072
0073 dd4hep::Segmentation segmentation_Silicon("CartesianGridXY", "SiliconHitsSeg",
0074 id_desc_tracker.decoder());
0075 readoutSilicon.setIDDescriptor(id_desc_Silicon);
0076 readoutSilicon.setSegmentation(segmentation_Silicon);
0077 detector->add(id_desc_Silicon);
0078 detector->add(readoutSilicon);
0079
0080
0081
0082
0083 dd4hep::Readout readoutMPGD(std::string("MockMPGDHits"));
0084 dd4hep::IDDescriptor id_desc_mpgd(
0085 "MockMPGDHits", "system:8,layer:4,module:12,sensor:24:4,strip:28:4,x:32:-16,y:-16");
0086 {
0087
0088 auto* multiSeg = new dd4hep::DDSegmentation::MultiSegmentation(
0089 "system:8,layer:4,module:12,sensor:24:4,strip:28:4,x:32:-16,y:-16");
0090
0091 multiSeg->parameter("key")->setValue("strip");
0092
0093
0094 auto* pSeg = new dd4hep::DDSegmentation::CartesianGridXY(
0095 "system:8,layer:4,module:12,sensor:24:4,strip:28:4,x:32:-16,y:-16");
0096 pSeg->setGridSizeX(1.0);
0097 pSeg->setGridSizeY(1.0);
0098 multiSeg->addSubsegmentation(1, 1, pSeg);
0099
0100
0101 auto* nSeg = new dd4hep::DDSegmentation::CartesianGridXY(
0102 "system:8,layer:4,module:12,sensor:24:4,strip:28:4,x:32:-16,y:-16");
0103 nSeg->setGridSizeX(1.0);
0104 nSeg->setGridSizeY(1.0);
0105 multiSeg->addSubsegmentation(2, 2, nSeg);
0106
0107
0108 auto* segObj = new dd4hep::SegmentationObject(multiSeg);
0109 multiSeg->setDecoder(id_desc_mpgd.decoder());
0110
0111 dd4hep::Segmentation segmentation_MPGD(segObj);
0112 readoutMPGD.setIDDescriptor(id_desc_mpgd);
0113 readoutMPGD.setSegmentation(segmentation_MPGD);
0114 }
0115 detector->add(id_desc_mpgd);
0116 detector->add(readoutMPGD);
0117
0118
0119 detector->add(dd4hep::Constant("world_x", "1000.0"));
0120 detector->add(dd4hep::Constant("world_y", "1000.0"));
0121 detector->add(dd4hep::Constant("world_z", "1000.0"));
0122
0123 dd4hep::_toDictionary("world_x", "1000.0");
0124 dd4hep::_toDictionary("world_y", "1000.0");
0125 dd4hep::_toDictionary("world_z", "1000.0");
0126
0127 auto* matVac = new TGeoMaterial("Vacuum", 0, 0, 0);
0128 auto* matAir = new TGeoMaterial("Air", 0, 0, 0);
0129 new TGeoMedium("Vacuum", 1, matVac);
0130 new TGeoMedium("Air", 2, matAir);
0131
0132 detector->init();
0133
0134
0135 dd4hep::SensitiveDetector sd("MockMPGD", "tracker");
0136 sd.setReadout(readoutMPGD);
0137 detector->add(sd);
0138
0139
0140
0141
0142
0143 dd4hep::Box sensorShape("sensor_shape", 5.0, 5.0, 0.025);
0144 dd4hep::Volume sensorVol("MockMPGDSensor", sensorShape, detector->air());
0145 sensorVol.setSensitiveDetector(sd);
0146
0147
0148 dd4hep::Box refShape("ref_shape", 5.0, 5.0, 0.025);
0149 dd4hep::Volume refVol("MockMPGDRef", refShape, detector->air());
0150 refVol.setSensitiveDetector(sd);
0151
0152 dd4hep::Box moduleShape("module_shape", 5.0, 5.0, 0.15);
0153 dd4hep::Box envShape("env_shape", 10.0, 10.0, 5.0);
0154 dd4hep::Volume envVol("MockMPGDEnvelope", envShape, detector->air());
0155
0156 dd4hep::Volume worldVol = detector->worldVolume();
0157 dd4hep::DetElement worldDet = detector->world();
0158 dd4hep::DetElement det(worldDet, "MockMPGD", 3);
0159
0160
0161 det.object<dd4hep::DetElement::Object>().flag |=
0162 dd4hep::DetElement::Object::HAVE_SENSITIVE_DETECTOR;
0163
0164 const int nModules = 2;
0165 int deID = 0;
0166
0167 for (int imod = 0; imod < nModules; imod++) {
0168 dd4hep::Volume moduleVol("MockMPGDModule_" + std::to_string(imod), moduleShape,
0169 detector->air());
0170
0171
0172 dd4hep::PlacedVolume refPV = moduleVol.placeVolume(refVol, dd4hep::Position(0, 0, 0));
0173 refPV.addPhysVolID("strip", 0);
0174
0175
0176 dd4hep::PlacedVolume stripPVs[2];
0177 const int stripIDs[] = {1, 2};
0178 for (int is = 0; is < 2; is++) {
0179 double zChild = (is == 0) ? -0.05 : +0.05;
0180 stripPVs[is] = moduleVol.placeVolume(sensorVol, dd4hep::Position(0, 0, zChild));
0181 stripPVs[is].addPhysVolID("strip", stripIDs[is]);
0182 }
0183
0184 dd4hep::PlacedVolume mpv = envVol.placeVolume(moduleVol, dd4hep::Position(0, 0, imod * 0.5));
0185 mpv.addPhysVolID("layer", 0);
0186 mpv.addPhysVolID("module", imod);
0187
0188 std::string modName = "module_" + std::to_string(imod);
0189 dd4hep::DetElement modDE(det, modName, deID++);
0190 modDE.setPlacement(mpv);
0191
0192
0193
0194 std::string refName = modName + "_strip0";
0195 dd4hep::DetElement refDE(modDE, refName, deID++);
0196 refDE.setPlacement(refPV);
0197
0198 for (int is = 0; is < 2; is++) {
0199 std::string sensName = modName + "_strip" + std::to_string(stripIDs[is]);
0200 dd4hep::DetElement sensDE(modDE, sensName, deID++);
0201 sensDE.setPlacement(stripPVs[is]);
0202 }
0203 }
0204
0205 dd4hep::PlacedVolume envPV = worldVol.placeVolume(envVol);
0206 envPV.addPhysVolID("system", 3);
0207 det.setPlacement(envPV);
0208
0209 detector->endDocument();
0210
0211
0212 dd4hep::VolumeManager vm(*detector, "tracking", detector->world(), dd4hep::Readout(),
0213 dd4hep::VolumeManager::NONE);
0214 vm.addSubdetector(det, readoutMPGD);
0215
0216 m_detector = std::move(detector);
0217
0218 auto& serviceSvc = algorithms::ServiceSvc::instance();
0219 [[maybe_unused]] auto& geoSvc = algorithms::GeoSvc::instance();
0220 serviceSvc.setInit<algorithms::GeoSvc>([this](auto&& g) { g.init(this->m_detector.get()); });
0221
0222
0223 m_actsGeoProvider = std::make_shared<ActsGeometryProvider>();
0224 [[maybe_unused]] auto& actsSvc = algorithms::ActsSvc::instance();
0225 serviceSvc.setInit<algorithms::ActsSvc>([this](auto&& g) { g.init(this->m_actsGeoProvider); });
0226
0227 [[maybe_unused]] auto& randomSvc = algorithms::RandomSvc::instance();
0228 auto seed = Catch::Generators::Detail::getSeed();
0229 serviceSvc.setInit<algorithms::RandomSvc>([seed](auto&& r) {
0230 r.setProperty("seed", static_cast<std::size_t>(seed));
0231 r.init();
0232 });
0233
0234 auto& evaluatorSvc = eicrecon::EvaluatorSvc::instance();
0235 serviceSvc.add<eicrecon::EvaluatorSvc>(&evaluatorSvc);
0236
0237 auto& lutSvc = eicrecon::PIDLookupTableSvc::instance();
0238 serviceSvc.add<eicrecon::PIDLookupTableSvc>(&lutSvc);
0239
0240 auto& particleSvc = algorithms::ParticleSvc::instance();
0241 serviceSvc.add<algorithms::ParticleSvc>(&particleSvc);
0242
0243 auto& uniqueIDSvc = algorithms::UniqueIDGenSvc::instance();
0244 serviceSvc.add<algorithms::UniqueIDGenSvc>(&uniqueIDSvc);
0245
0246 serviceSvc.init();
0247 }
0248 };
0249
0250 CATCH_REGISTER_LISTENER(algorithmsInitListener)