Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
bc12783
Create ChemistryManager and ChemistryListManager
nkrah Nov 27, 2025
4ae4542
Create ChemistryEngine (mostly placeholder for now)
nkrah Nov 27, 2025
71feca3
Wrap G4DNAChemistryManager
nkrah Nov 27, 2025
62c80b1
Wrap G4MoleculeTable
nkrah Nov 27, 2025
d85d2c2
First version of chemistry.py
nkrah Feb 6, 2026
ef3e68f
binding for G4VUserChemistryList
nkrah Feb 6, 2026
7fdebea
Include new chemistry bindings in opengate_core.cpp
nkrah Feb 6, 2026
4b289f9
add g4_dna_chemistry_manager to ChemistryEngine
nkrah Feb 6, 2026
21ce127
Minor code style improvements in PhysicsListManager
nkrah Mar 23, 2026
cf832bc
Made create_modular_physics_list_class() clearer: class-statement ins…
nkrah Mar 24, 2026
c0809f3
Refactor chemistry and physics-list configuration
nkrah Mar 24, 2026
f9b13c1
Add chemistry actions and actor bindings
nkrah Mar 24, 2026
14909d9
Fix chemistry bindings for Geant4 11.4 build
nkrah Mar 26, 2026
279d37a
Expand ChemicalStageActor chemistry scoring
nkrah Mar 26, 2026
6c667b4
Add ChemicalStageActor output integration
nkrah Mar 26, 2026
851e654
Add chemistry counter configuration support
nkrah Mar 26, 2026
bc53835
Add region-based DNA EM physics configuration
nkrah Mar 26, 2026
5747c01
Register DNA physics activator for region-based DNA
nkrah Mar 26, 2026
ebbcde8
Add DNA region consistency test
nkrah Mar 26, 2026
e936575
Let ChemicalStageActor request DNA EM by volume
nkrah Mar 26, 2026
ed93cee
Add chemistry track interactivity aggregation
nkrah Mar 27, 2026
9fe1333
Filter chemistry tracks in ChemicalStageActor
nkrah Mar 27, 2026
80cc8cd
Clean up ChemicalStageActor volume filtering
nkrah Mar 27, 2026
c4c5242
Warn on large ChemicalStageActor volumes
nkrah Mar 27, 2026
94ac773
Add ChemicalStageActor chem6-style test
nkrah Mar 28, 2026
05111f0
Accept volume objects in PhysicsManager setters
nkrah Mar 28, 2026
659fde8
Add DNA EM convenience method to volumes
nkrah Mar 28, 2026
a3a0197
Add chemistry volume confinement in base actor
nkrah Mar 28, 2026
a107443
Refine ChemicalStageActor test API usage
nkrah Mar 28, 2026
cbb6264
Fix pybind for custom Geant4 chemistry lists
nkrah Mar 29, 2026
ee5807f
Register G4-DNA EM physics list variants
nkrah Mar 29, 2026
b3a462c
Reject global DNA EM physics lists
nkrah Mar 29, 2026
6d68bf9
Refactor region initialization lifecycle
nkrah Mar 29, 2026
f47b27a
Fix physics list setter hook ordering
nkrah Mar 29, 2026
1b03fb3
Keep DNA activator alive during initialization
nkrah Mar 29, 2026
629bd75
Avoid double initialization of built-in chemistry lists
nkrah Mar 29, 2026
4f97fdb
Move physics list wrappers into dedicated module
nkrah Mar 29, 2026
202fe9e
Expose built-in chemistry list lifecycle in pybind
nkrah Mar 29, 2026
241eeda
Default chemistry actors to volume confinement
nkrah Mar 29, 2026
6a0e672
Move chemistry list runtime ownership to engine
nkrah Mar 29, 2026
603b098
Configure Geant4 chemistry time-step model
nkrah Mar 29, 2026
006727f
Let chemistry actors request a chemistry list
nkrah Mar 29, 2026
1193b9f
Improve repeated-simulation guidance and chemistry test
nkrah Mar 29, 2026
8d5117c
Silence physics list binding debug output
nkrah Mar 29, 2026
ea6909f
Move DNA EM handling into chemistry actor base
nkrah Mar 29, 2026
ac600af
Add freeze-config hook for actor DNA EM requests
nkrah Mar 29, 2026
fe299b7
Improve chemistry test comparison output
nkrah Mar 29, 2026
92c2d7d
Generalize actor DNA EM requests in freeze phase
nkrah Mar 29, 2026
d12d5d1
Normalize reaction comparison in chemistry test
nkrah Mar 29, 2026
1fc52d7
Use volume DNA EM convenience API in test100
nkrah Mar 30, 2026
7498e38
Use object references in DNA region test
nkrah Mar 30, 2026
9ee45bf
Remove obsolete PhysicsHasBeenModified() call in SimulationEngine
nkrah Mar 30, 2026
1447218
Stabilize DNA region test validation
nkrah Mar 30, 2026
f18b9d8
[pre-commit.ci] Automatic python and c++ formatting
pre-commit-ci[bot] Mar 30, 2026
df71061
Fix reference physics list registry test
nkrah Mar 30, 2026
93430d4
Introduce ChemistryList as the user-facing chemistry configuration
nkrah Apr 11, 2026
8040457
Expose Geant4 chemistry construction APIs to Python
nkrah Apr 11, 2026
d9f9b55
Extend chemistry actor tests with chem6-style reactions
nkrah Apr 11, 2026
084f678
[pre-commit.ci] Automatic python and c++ formatting
pre-commit-ci[bot] Apr 11, 2026
bc1e485
Move PhysicsListBuilder and physics-list helpers into physics.py
nkrah Apr 11, 2026
12b0b9a
Implement dict serialization for chemistry
nkrah Apr 11, 2026
7942529
[pre-commit.ci] Automatic python and c++ formatting
pre-commit-ci[bot] Apr 11, 2026
d3adaef
Expose missing chemistry tracking interactivity hooks
nkrah Apr 12, 2026
ef533d0
Rename chemistry scheduler hooks for clarity
nkrah Apr 12, 2026
d7feb52
Restore compatibility alias for SimpleITK image info helper
nkrah Apr 12, 2026
ed01771
Rename DNA EM physics API to track-structure EM physics
nkrah Apr 13, 2026
5962617
Use full Geant4 names for track-structure EM physics options
nkrah Apr 13, 2026
8ff6872
Refine track-structure EM option handling
nkrah Apr 13, 2026
e16bfb8
[pre-commit.ci] Automatic python and c++ formatting
pre-commit-ci[bot] Apr 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions core/opengate_core/g4_bindings/pyG4DNAChemistryManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "G4DNAChemistryManager.hh"
#include "G4Scheduler.hh"
#include "G4VUserChemistryList.hh"
#include "pybind11/pybind11.h"

namespace py = pybind11;

void init_G4DNAChemistryManager(py::module &m) {
py::class_<G4DNAChemistryManager,
std::unique_ptr<G4DNAChemistryManager, py::nodelete>>(
m, "G4DNAChemistryManager")
.def_static("Instance", &G4DNAChemistryManager::Instance,
py::return_value_policy::reference)

.def(
"SetChemistryList",
[](G4DNAChemistryManager *self, py::object pychemlist) {
if (!pychemlist) {
throw std::runtime_error(
"SetChemistryList() requires a ChemistryList object");
}
auto ptr = pychemlist.cast<G4VUserChemistryList *>();
if (!ptr) {
throw std::runtime_error("Invalid ChemistryList: null pointer");
}
self->SetChemistryList(*ptr);
},
py::arg("chemistry_list"),
"Register a user-defined ChemistryList with the DNA chemistry "
"manager")

.def(
"Deregister",
[](G4DNAChemistryManager *self, py::object pychemlist) {
if (!pychemlist) {
throw std::runtime_error(
"Deregister() requires a ChemistryList object");
}
auto ptr = pychemlist.cast<G4VUserChemistryList *>();
if (!ptr) {
throw std::runtime_error("Invalid ChemistryList: null pointer");
}
self->Deregister(*ptr);
},
py::arg("chemistry_list"),
"Deregister a chemistry list from the DNA chemistry manager")

.def("Initialize",
py::overload_cast<>(&G4DNAChemistryManager::Initialize),
py::call_guard<py::gil_scoped_release>(),
"Initialize the DNA chemistry system")

.def("SetChemistryActivation",
&G4DNAChemistryManager::SetChemistryActivation,
py::arg("chemistry_active_flag"),
"Enable or disable Geant4-DNA chemistry")

.def_static("IsActivated", &G4DNAChemistryManager::IsActivated,
"Return True if DNA chemistry is active")

.def("Run", &G4DNAChemistryManager::Run,
py::call_guard<py::gil_scoped_release>(),
"Run the chemistry stage using the underlying G4Scheduler")

// expose the underlying scheduler (read-only)
.def_property_readonly(
"scheduler",
[](G4DNAChemistryManager *self) { return G4Scheduler::Instance(); },
py::return_value_policy::reference,
"Return the underlying G4Scheduler instance");
}
9 changes: 9 additions & 0 deletions core/opengate_core/g4_bindings/pyG4EmParameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ namespace py = pybind11;
#include "G4EmParameters.hh"

void init_G4EmParameters(py::module &m) {
py::enum_<G4ChemTimeStepModel>(m, "G4ChemTimeStepModel")
.value("Unknown", G4ChemTimeStepModel::Unknown)
.value("SBS", G4ChemTimeStepModel::SBS)
.value("IRT", G4ChemTimeStepModel::IRT)
.value("IRT_syn", G4ChemTimeStepModel::IRT_syn);

// (prevent to delete from py side with py::nodelete)
py::class_<G4EmParameters, std::unique_ptr<G4EmParameters, py::nodelete>>(
m, "G4EmParameters")
Expand Down Expand Up @@ -249,6 +255,9 @@ void init_G4EmParameters(py::module &m) {
.def("SetNuclearFormfactorType",
&G4EmParameters::SetNuclearFormfactorType)

.def("SetTimeStepModel", &G4EmParameters::SetTimeStepModel)
.def("GetTimeStepModel", &G4EmParameters::GetTimeStepModel)

.def("SetDNAeSolvationSubType", &G4EmParameters::SetDNAeSolvationSubType)

// 5d
Expand Down
41 changes: 41 additions & 0 deletions core/opengate_core/g4_bindings/pyG4ITTrackingInteractivity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* --------------------------------------------------
Copyright (C): OpenGATE Collaboration
This software is distributed under the terms
of the GNU Lesser General Public Licence (LGPL)
See LICENSE.md for further details
-------------------------------------------------- */
#include <pybind11/pybind11.h>

namespace py = pybind11;

#include "G4ITTrackingInteractivity.hh"
#include "G4Step.hh"
#include "G4Track.hh"

class PyG4ITTrackingInteractivity : public G4ITTrackingInteractivity {
public:
using G4ITTrackingInteractivity::G4ITTrackingInteractivity;

void StartTracking(G4Track *track) override {
PYBIND11_OVERLOAD(void, G4ITTrackingInteractivity, StartTracking, track);
}

void AppendStep(G4Track *track, G4Step *step) override {
PYBIND11_OVERLOAD(void, G4ITTrackingInteractivity, AppendStep, track, step);
}

void EndTracking(G4Track *track) override {
PYBIND11_OVERLOAD(void, G4ITTrackingInteractivity, EndTracking, track);
}
};

void init_G4ITTrackingInteractivity(py::module &m) {

py::class_<G4ITTrackingInteractivity, PyG4ITTrackingInteractivity,
std::unique_ptr<G4ITTrackingInteractivity, py::nodelete>>(
m, "G4ITTrackingInteractivity")
.def(py::init())
.def("StartTracking", &G4ITTrackingInteractivity::StartTracking)
.def("AppendStep", &G4ITTrackingInteractivity::AppendStep)
.def("EndTracking", &G4ITTrackingInteractivity::EndTracking);
}
40 changes: 40 additions & 0 deletions core/opengate_core/g4_bindings/pyG4MoleculeCounter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"

#include "G4MoleculeCounter.hh"
#include "G4MoleculeTable.hh"

namespace py = pybind11;

void init_G4MoleculeCounter(py::module &m) {
py::class_<G4MoleculeCounter,
std::unique_ptr<G4MoleculeCounter, py::nodelete>>(
m, "G4MoleculeCounter")
.def(py::init<>())
.def(py::init<G4String>())
.def("Initialize", &G4MoleculeCounter::Initialize)
.def("GetName", &G4MoleculeCounter::GetName)
.def("SetVerbose", &G4MoleculeCounter::SetVerbose)
.def("SetTimeComparer", &G4MoleculeCounter::SetTimeComparer)
.def(
"IgnoreMolecule",
[](G4MoleculeCounter *self, const std::string &name) {
auto *molecule =
G4MoleculeTable::Instance()->GetMoleculeDefinition(name, false);
if (molecule == nullptr) {
throw std::runtime_error("Unknown molecule name: " + name);
}
self->IgnoreMolecule(molecule);
},
py::arg("name"))
.def("RegisterAll", &G4MoleculeCounter::RegisterAll)
.def("SetCheckTimeConsistencyWithScheduler",
&G4MoleculeCounter::SetCheckTimeConsistencyWithScheduler)
.def("SetCheckRecordedTimeConsistency",
&G4MoleculeCounter::SetCheckRecordedTimeConsistency)
.def("SetActiveLowerBound", &G4MoleculeCounter::SetActiveLowerBound,
py::arg("time"), py::arg("inclusive") = true)
.def("SetActiveUpperBound", &G4MoleculeCounter::SetActiveUpperBound,
py::arg("time"), py::arg("inclusive") = true)
.def("GetManagedId", &G4MoleculeCounter::GetManagedId);
}
50 changes: 50 additions & 0 deletions core/opengate_core/g4_bindings/pyG4MoleculeCounterManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "pybind11/pybind11.h"

#include "G4MoleculeCounter.hh"
#include "G4MoleculeCounterManager.hh"
#include "G4MoleculeReactionCounter.hh"

namespace py = pybind11;

void init_G4MoleculeCounterManager(py::module &m) {
py::class_<G4MoleculeCounterManager,
std::unique_ptr<G4MoleculeCounterManager, py::nodelete>>(
m, "G4MoleculeCounterManager")
.def_static("Instance", &G4MoleculeCounterManager::Instance,
py::return_value_policy::reference)
.def("SetResetCountersBeforeEvent",
&G4MoleculeCounterManager::SetResetCountersBeforeEvent,
py::arg("flag") = true)
.def("SetResetCountersBeforeRun",
&G4MoleculeCounterManager::SetResetCountersBeforeRun,
py::arg("flag") = true)
.def("SetResetMasterCounterWithWorkers",
&G4MoleculeCounterManager::SetResetMasterCounterWithWorkers,
py::arg("flag") = true)
.def("SetAccumulateCounterIntoMaster",
&G4MoleculeCounterManager::SetAccumulateCounterIntoMaster,
py::arg("flag") = true)
.def("GetResetCountersBeforeEvent",
&G4MoleculeCounterManager::GetResetCountersBeforeEvent)
.def("GetResetCountersBeforeRun",
&G4MoleculeCounterManager::GetResetCountersBeforeRun)
.def("GetResetMasterCounterWithWorkers",
&G4MoleculeCounterManager::GetResetMasterCounterWithWorkers)
.def("GetAccumulateCounterIntoMaster",
&G4MoleculeCounterManager::GetAccumulateCounterIntoMaster)
.def(
"RegisterMoleculeCounter",
[](G4MoleculeCounterManager *self, G4MoleculeCounter *counter) {
return self->RegisterCounter(
std::unique_ptr<G4VMoleculeCounter>(counter));
},
py::arg("counter"))
.def(
"RegisterReactionCounter",
[](G4MoleculeCounterManager *self,
G4MoleculeReactionCounter *counter) {
return self->RegisterCounter(
std::unique_ptr<G4VMoleculeReactionCounter>(counter));
},
py::arg("counter"));
}
20 changes: 20 additions & 0 deletions core/opengate_core/g4_bindings/pyG4MoleculeCounterTimeComparer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "pybind11/pybind11.h"

#include "G4MoleculeCounterTimeComparer.hh"

namespace py = pybind11;

void init_G4MoleculeCounterTimeComparer(py::module &m) {
py::class_<G4MoleculeCounterTimeComparer>(m, "G4MoleculeCounterTimeComparer")
.def(py::init<>())
.def("SetFixedPrecision",
&G4MoleculeCounterTimeComparer::SetFixedPrecision)
.def_static("CreateWithFixedPrecision",
&G4MoleculeCounterTimeComparer::CreateWithFixedPrecision)
.def_static(
"CreateWithVariablePrecision",
py::overload_cast<const std::map<G4double, G4double> &>(
&G4MoleculeCounterTimeComparer::CreateWithVariablePrecision))
.def("GetPrecisionAtTime",
&G4MoleculeCounterTimeComparer::GetPrecisionAtTime);
}
28 changes: 28 additions & 0 deletions core/opengate_core/g4_bindings/pyG4MoleculeReactionCounter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "pybind11/pybind11.h"

#include "G4MoleculeReactionCounter.hh"

namespace py = pybind11;

void init_G4MoleculeReactionCounter(py::module &m) {
py::class_<G4MoleculeReactionCounter,
std::unique_ptr<G4MoleculeReactionCounter, py::nodelete>>(
m, "G4MoleculeReactionCounter")
.def(py::init<>())
.def(py::init<G4String>())
.def("Initialize", &G4MoleculeReactionCounter::Initialize)
.def("GetName", &G4MoleculeReactionCounter::GetName)
.def("SetVerbose", &G4MoleculeReactionCounter::SetVerbose)
.def("SetTimeComparer", &G4MoleculeReactionCounter::SetTimeComparer)
.def("SetCheckTimeConsistencyWithScheduler",
&G4MoleculeReactionCounter::SetCheckTimeConsistencyWithScheduler)
.def("SetCheckRecordedTimeConsistency",
&G4MoleculeReactionCounter::SetCheckRecordedTimeConsistency)
.def("SetActiveLowerBound",
&G4MoleculeReactionCounter::SetActiveLowerBound, py::arg("time"),
py::arg("inclusive") = true)
.def("SetActiveUpperBound",
&G4MoleculeReactionCounter::SetActiveUpperBound, py::arg("time"),
py::arg("inclusive") = true)
.def("GetManagedId", &G4MoleculeReactionCounter::GetManagedId);
}
Loading
Loading