-
Notifications
You must be signed in to change notification settings - Fork 3
feat(dd4hep): add experimental DDG4 integration plugins and examples #266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 30 commits
38123c8
7ad57c3
10c7a1f
2c54e77
2bca8fb
e8e95f2
620924b
732496e
ca9dd60
38d2764
d78307e
cfc869b
d4fde26
c4a6751
5d36375
c084196
cfb55ef
1350cd2
fba67e0
7717636
09f0701
df563cc
da2d0b4
72fb922
4ee7da3
288a570
180f748
7b27080
65bfcee
664b313
8da8410
0b7595e
71d7f41
8c53d91
399228b
6af15f6
277765c
585d0da
afff87a
d88a4b5
a81f9fe
8f76af5
d5b8b6e
656e529
3ec3797
c5a3bc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| #------------------------------- -*- cmake -*- -------------------------------# | ||
| # eic-opticks DD4hep integration plugins | ||
| # | ||
| # Builds DD4hep action plugins that integrate eic-opticks GPU-accelerated | ||
| # optical photon simulation into DD4hep/Geant4. | ||
| # | ||
| # Works both as part of the top-level eic-opticks build (in-tree) and as a | ||
| # standalone project against an installed eic-opticks. | ||
| # | ||
| # Usage from a DD4hep steering file: | ||
| # OpticsRun -- initializes/finalizes G4CXOpticks per run | ||
| # OpticsEvent -- triggers GPU simulation per event | ||
| #----------------------------------------------------------------------------# | ||
|
|
||
| # Detect standalone vs in-tree build | ||
| if(NOT TARGET G4CX) | ||
| cmake_minimum_required(VERSION 3.18 FATAL_ERROR) | ||
| project(ddeicopticks VERSION 0.1.0 LANGUAGES CXX) | ||
| find_package(DD4hep REQUIRED COMPONENTS DDG4 DDCore) | ||
| find_package(eic-opticks REQUIRED) | ||
| find_package(Geant4 REQUIRED) | ||
| set(_g4cx eic-opticks::G4CX) | ||
| set(_u4 eic-opticks::U4) | ||
| set(_sysrap eic-opticks::SysRap) | ||
| else() | ||
| # In-tree: DD4hep already found by parent, targets use local names | ||
| find_package(Geant4 REQUIRED) | ||
| set(_g4cx G4CX) | ||
| set(_u4 U4) | ||
| set(_sysrap SysRap) | ||
| endif() | ||
|
|
||
| dd4hep_set_compiler_flags() | ||
|
|
||
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") | ||
| set(LIBRARY_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}") | ||
|
|
||
| dd4hep_add_plugin(ddeicopticks | ||
| SOURCES | ||
| OpticsRun.cc | ||
| OpticsEvent.cc | ||
| OpticsSteppingAction.cc | ||
| USES | ||
| DD4hep::DDG4 | ||
| DD4hep::DDCore | ||
| ${_g4cx} | ||
| ${_u4} | ||
| ${_sysrap} | ||
| ) | ||
| target_compile_definitions(ddeicopticks PRIVATE STANDALONE) | ||
|
|
||
| install(TARGETS ddeicopticks | ||
| LIBRARY DESTINATION lib | ||
| ) | ||
|
|
||
| install(FILES | ||
| ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_MODULE_PREFIX}ddeicopticks.components | ||
| DESTINATION lib | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #pragma once | ||
| /** | ||
| DD4hepSensorIdentifier.hh | ||
| =========================== | ||
|
|
||
| Custom sensor identifier for DD4hep geometries. | ||
|
|
||
| Unlike the default U4SensorIdentifierDefault which relies on | ||
| GLOBAL_SENSOR_BOUNDARY_LIST env var for non-instanced geometries, | ||
| this implementation directly checks G4VSensitiveDetector on volumes. | ||
|
|
||
| This works for DD4hep geometries where sensitive detectors are | ||
| explicitly set via DetElement::setSensitiveDetector(). | ||
| **/ | ||
|
|
||
| #include "G4PVPlacement.hh" | ||
| #include "G4VSensitiveDetector.hh" | ||
|
|
||
| #include "U4SensorIdentifier.h" | ||
|
|
||
plexoos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| struct DD4hepSensorIdentifier : public U4SensorIdentifier | ||
| { | ||
| int level = 0 ; | ||
|
|
||
| void setLevel(int _level) override { level = _level ; } | ||
|
|
||
| /** | ||
| getGlobalIdentity | ||
| ------------------- | ||
| Checks if the physical volume has a G4VSensitiveDetector attached. | ||
| Returns the copy number as sensor_id, or -1 if not sensitive. | ||
| **/ | ||
| int getGlobalIdentity(const G4VPhysicalVolume* pv, | ||
| const G4VPhysicalVolume* /*ppv*/) override | ||
| { | ||
| if (!pv) return -1 ; | ||
|
|
||
| const G4LogicalVolume* lv = pv->GetLogicalVolume() ; | ||
| G4VSensitiveDetector* sd = lv->GetSensitiveDetector() ; | ||
|
|
||
| if (!sd) return -1 ; | ||
|
|
||
| const G4PVPlacement* pvp = dynamic_cast<const G4PVPlacement*>(pv) ; | ||
| int copyno = pvp ? pvp->GetCopyNo() : 0 ; | ||
|
|
||
| if (level > 0) | ||
| std::cout << "DD4hepSensorIdentifier::getGlobalIdentity" | ||
| << " copyno " << copyno | ||
| << " sd " << sd->GetName() | ||
| << " pv " << pv->GetName() | ||
| << std::endl ; | ||
|
|
||
| return copyno ; | ||
| } | ||
|
|
||
| /** | ||
| getInstanceIdentity | ||
| --------------------- | ||
| Same as default: recursively search for G4VSensitiveDetector | ||
| within the instance subtree. | ||
| **/ | ||
| int getInstanceIdentity(const G4VPhysicalVolume* instance_outer_pv) const override | ||
| { | ||
| if (!instance_outer_pv) return -1 ; | ||
|
|
||
| std::vector<const G4VPhysicalVolume*> sdpv ; | ||
| FindSD_r(sdpv, instance_outer_pv, 0) ; | ||
|
|
||
| if (sdpv.empty()) return -1 ; | ||
|
|
||
| const G4PVPlacement* pvp = | ||
| dynamic_cast<const G4PVPlacement*>(instance_outer_pv) ; | ||
| return pvp ? pvp->GetCopyNo() : 0 ; | ||
| } | ||
|
|
||
| static void FindSD_r(std::vector<const G4VPhysicalVolume*>& sdpv, | ||
| const G4VPhysicalVolume* pv, int depth) | ||
| { | ||
| const G4LogicalVolume* lv = pv->GetLogicalVolume() ; | ||
| G4VSensitiveDetector* sd = lv->GetSensitiveDetector() ; | ||
| if (sd) sdpv.push_back(pv) ; | ||
| for (size_t i = 0; i < size_t(lv->GetNoDaughters()); i++) | ||
| FindSD_r(sdpv, lv->GetDaughter(i), depth + 1) ; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,197 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include "OpticsEvent.hh" | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DD4hep/InstanceCount.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DDG4/Factories.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DDG4/Geant4Data.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
plexoos marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DDG4/Geant4HitCollection.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DDG4/Geant4SensDetAction.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <DDG4/Geant4Context.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
plexoos marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <G4Event.hh> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <chrono> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <G4CXOpticks.hh> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <SEvt.hh> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <SComp.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <sphoton.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
plexoos marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
plexoos marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #include <NP.hh> | ||||||||||||||||||||||||||||||||||||||||||||||||
| #include <NPFold.h> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| namespace ddeicopticks | ||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||
| //---------------------------------------------------------------------------// | ||||||||||||||||||||||||||||||||||||||||||||||||
| OpticsEvent::OpticsEvent(dd4hep::sim::Geant4Context* ctxt, | ||||||||||||||||||||||||||||||||||||||||||||||||
| std::string const& name) | ||||||||||||||||||||||||||||||||||||||||||||||||
plexoos marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||
| : dd4hep::sim::Geant4EventAction(ctxt, name) | ||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||
| dd4hep::InstanceCount::increment(this); | ||||||||||||||||||||||||||||||||||||||||||||||||
| declareProperty("Verbose", verbose_); | ||||||||||||||||||||||||||||||||||||||||||||||||
| declareProperty("PhotonThreshold", photon_threshold_); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| //---------------------------------------------------------------------------// | ||||||||||||||||||||||||||||||||||||||||||||||||
| OpticsEvent::~OpticsEvent() | ||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||
| dd4hep::InstanceCount::decrement(this); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| //---------------------------------------------------------------------------// | ||||||||||||||||||||||||||||||||||||||||||||||||
| void OpticsEvent::begin(G4Event const* event) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
| void OpticsEvent::begin(G4Event const* event) | |
| void OpticsEvent::begin(G4Event const *event) |
Copilot
AI
Apr 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
batch_begun_ mode calls SEvt::beginOfEvent(eventID) only once per batch. However SEvt::beginOfEvent sets the internal event index and clears output buffers (but preserves gensteps). Skipping it for subsequent events while later calling simulate/endOfEvent/reset with a different eventID risks inconsistent SEvt indexing/metadata and overwriting output state. Consider always updating the SEvt index for the current eventID (without clearing accumulated gensteps), or implement an explicit batching API in SEvt to support this safely.
| // In batch mode, only start a new SEvt at the beginning of each batch. | |
| // Skipping beginOfEvent between events lets gensteps accumulate | |
| // (SEvt::clear_output preserves gensteps by design). | |
| if (!batch_begun_) | |
| { | |
| SEvt::CreateOrReuse_EGPU(); | |
| SEvt* sev = SEvt::Get_EGPU(); | |
| if (sev) | |
| sev->beginOfEvent(eventID); | |
| batch_begun_ = true; | |
| } | |
| // In batch mode, create or reuse the SEvt once per batch, but still | |
| // begin each event so the internal event index/metadata is updated and | |
| // per-event output buffers are cleared. beginOfEvent preserves gensteps. | |
| if (!batch_begun_) | |
| { | |
| SEvt::CreateOrReuse_EGPU(); | |
| batch_begun_ = true; | |
| } | |
| SEvt* sev = SEvt::Get_EGPU(); | |
| if (sev) | |
| sev->beginOfEvent(eventID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is intentional. In batch mode, gensteps accumulate across events; calling beginOfEvent for each event would clear them. The bot doesn't understand the batching design.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| void OpticsEvent::end(G4Event const* event) | |
| void OpticsEvent::end(G4Event const *event) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| G4CXOpticks* gx = G4CXOpticks::Get(); | |
| G4CXOpticks *gx = G4CXOpticks::Get(); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| SEvt* sev = SEvt::Get_EGPU(); | |
| SEvt *sev = SEvt::Get_EGPU(); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| void OpticsEvent::injectHits(G4Event const* event, | |
| using dd4hep::sim::Geant4SensDetSequences; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| void OpticsEvent::injectHits(G4Event const* event, | |
| SEvt* sev, | |
| unsigned num_hit) | |
| void OpticsEvent::injectHits(G4Event const *event, SEvt *sev, unsigned num_hit) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
Please remove the line(s)
- 113
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| Geant4SensDetSequences& sens = context()->sensitiveActions(); | |
| auto const& seqs = sens.sequences(); | |
| Geant4SensDetSequences &sens = context()->sensitiveActions(); | |
| auto const &seqs = sens.sequences(); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| "call setupTracker() in steering script", eventID); | |
| "call setupTracker() in steering script", | |
| eventID); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| for (auto const& [det_name, seq] : seqs) | |
| for (auto const &[det_name, seq] : seqs) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| Geant4HitCollection* coll = seq->collection(0); | |
| Geant4HitCollection *coll = seq->collection(0); |
plexoos marked this conversation as resolved.
Show resolved
Hide resolved
plexoos marked this conversation as resolved.
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| info("Event #%d: injected %u hits into '%s' collection", | |
| eventID, num_hit, det_name.c_str()); | |
| info("Event #%d: injected %u hits into '%s' collection", eventID, num_hit, det_name.c_str()); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| dd4hep::sim::Geant4Tracker::Hit* | |
| OpticsEvent::createTrackerHit(sphoton const& ph) | |
| dd4hep::sim::Geant4Tracker::Hit *OpticsEvent::createTrackerHit(sphoton const &ph) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| auto* hit = new Geant4Tracker::Hit(); | |
| auto *hit = new Geant4Tracker::Hit(); |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format suggestion
| } // namespace ddeicopticks | |
| } // namespace ddeicopticks |
Uh oh!
There was an error while loading. Please reload this page.