Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1e035cd
Include new C++ classes in opengate_lib for field management. This:
srmarcballestero May 5, 2026
64fe1ba
Enhance field management on the Python side by adding support for fie…
srmarcballestero May 5, 2026
7e3a601
[pre-commit.ci] Automatic python and c++ formatting
pre-commit-ci[bot] May 5, 2026
2a552ea
Enhance support for electromagnetic fields (E or E+B) , and implement…
srmarcballestero May 5, 2026
5a1d3e1
Bind G4SextupoleMagField and add support for it on the Python side
srmarcballestero May 5, 2026
68f6b4f
Bind G4SextupoleMagField and add support for it on the Python side
srmarcballestero May 5, 2026
2864294
Fixes:
srmarcballestero May 5, 2026
682411d
Fix: robustness of `refresh_transforms`
srmarcballestero May 6, 2026
6e2e24c
Enahnce existing tests and add new ones
srmarcballestero May 6, 2026
98d6689
Document changes so far
srmarcballestero May 6, 2026
3f55744
Refactor internal GATE field management: one single base class conta…
srmarcballestero May 6, 2026
22ad8ec
Implement grid-based mapped electric and magnetic fields
srmarcballestero May 6, 2026
60f893d
Implement grid-based mapped electric and magnetic fields
srmarcballestero May 6, 2026
aca9dad
Implement mapped combined electric and magnetic fields
srmarcballestero May 6, 2026
e8b4ef9
Refactor tests and add new ones
srmarcballestero May 7, 2026
7a00fdb
Documentation for mapped fields + fix related build warnings
srmarcballestero May 7, 2026
1568993
Fix test description for MappedElectricField vs UniformElectricField
srmarcballestero May 7, 2026
fee57e6
Add round-trip serialization tests for MappedMagneticField, MappedEle…
srmarcballestero May 7, 2026
32bc5fe
Bind new stepper classes
srmarcballestero May 27, 2026
a80a74c
Add stepper type parameter to FieldBase class + guards for magnetic-o…
srmarcballestero May 27, 2026
780d92e
Update TODOs in fields.py
srmarcballestero May 27, 2026
b19b784
Update documentation
srmarcballestero May 27, 2026
f418ae2
Add tests
srmarcballestero May 27, 2026
171727e
Add tests
srmarcballestero May 27, 2026
50fdead
Trigger CI tests
srmarcballestero May 31, 2026
909c04f
Re-trigger test suite
srmarcballestero Jun 1, 2026
b0ddc77
Merge branch 'master' into feature/field_enhancement
srmarcballestero Jun 1, 2026
bad550a
Re-trigger test suite
srmarcballestero Jun 2, 2026
686a499
Merge branch 'OpenGATE:master' into feature/field_enhancement
srmarcballestero Jun 2, 2026
919b68b
Relax tolerances in test
srmarcballestero Jun 4, 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
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4BogackiShampine23.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4BogackiShampine23.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4BogackiShampine23(py::module &m) {
// G4BogackiShampine23 inherits from G4MagIntegratorStepper
py::class_<G4BogackiShampine23, G4MagIntegratorStepper,
std::unique_ptr<G4BogackiShampine23, py::nodelete>>(
m, "G4BogackiShampine23")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4BogackiShampine45.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4BogackiShampine45.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4BogackiShampine45(py::module &m) {
// G4BogackiShampine45 inherits from G4MagIntegratorStepper
py::class_<G4BogackiShampine45, G4MagIntegratorStepper,
std::unique_ptr<G4BogackiShampine45, py::nodelete>>(
m, "G4BogackiShampine45")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4CashKarpRKF45.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4CashKarpRKF45.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4CashKarpRKF45(py::module &m) {
// G4CashKarpRKF45 inherits from G4MagIntegratorStepper
py::class_<G4CashKarpRKF45, G4MagIntegratorStepper,
std::unique_ptr<G4CashKarpRKF45, py::nodelete>>(m,
"G4CashKarpRKF45")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4DormandPrince745.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4DormandPrince745.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4DormandPrince745(py::module &m) {
// G4DormandPrince745 inherits from G4MagIntegratorStepper
py::class_<G4DormandPrince745, G4MagIntegratorStepper,
std::unique_ptr<G4DormandPrince745, py::nodelete>>(
m, "G4DormandPrince745")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4DormandPrinceRK56.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4DormandPrinceRK56.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4DormandPrinceRK56(py::module &m) {
// G4DormandPrinceRK56 inherits from G4MagIntegratorStepper
py::class_<G4DormandPrinceRK56, G4MagIntegratorStepper,
std::unique_ptr<G4DormandPrinceRK56, py::nodelete>>(
m, "G4DormandPrinceRK56")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4DormandPrinceRK78.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4DormandPrinceRK78.hh"
#include "G4EquationOfMotion.hh"
#include "G4MagIntegratorStepper.hh"

void init_G4DormandPrinceRK78(py::module &m) {
// G4DormandPrinceRK78 inherits from G4MagIntegratorStepper
py::class_<G4DormandPrinceRK78, G4MagIntegratorStepper,
std::unique_ptr<G4DormandPrinceRK78, py::nodelete>>(
m, "G4DormandPrinceRK78")

.def(py::init<G4EquationOfMotion *, G4int>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4ExactHelixStepper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4ExactHelixStepper.hh"
#include "G4MagIntegratorStepper.hh"
#include "G4Mag_EqRhs.hh"

void init_G4ExactHelixStepper(py::module &m) {
// G4ExactHelixStepper <- G4MagHelicalStepper <- G4MagIntegratorStepper.
py::class_<G4ExactHelixStepper, G4MagIntegratorStepper,
std::unique_ptr<G4ExactHelixStepper, py::nodelete>>(
m, "G4ExactHelixStepper")

.def(py::init<G4Mag_EqRhs *>())

;
}
25 changes: 25 additions & 0 deletions core/opengate_core/g4_bindings/pyG4NystromRK4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --------------------------------------------------
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 "G4MagIntegratorStepper.hh"
#include "G4Mag_EqRhs.hh"
#include "G4NystromRK4.hh"

void init_G4NystromRK4(py::module &m) {
// G4NystromRK4 inherits from G4MagIntegratorStepper
py::class_<G4NystromRK4, G4MagIntegratorStepper,
std::unique_ptr<G4NystromRK4, py::nodelete>>(m, "G4NystromRK4")

.def(py::init<G4Mag_EqRhs *, G4double>(), py::arg("equation"),
py::arg("distanceConstField") = 0.0)

;
}
24 changes: 24 additions & 0 deletions core/opengate_core/g4_bindings/pyG4SextupoleMagField.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* --------------------------------------------------
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 "G4MagneticField.hh"
#include "G4SextupoleMagField.hh"

void init_G4SextupoleMagField(py::module &m) {

py::class_<G4SextupoleMagField, G4MagneticField,
std::unique_ptr<G4SextupoleMagField, py::nodelete>>(
m, "G4SextupoleMagField")

.def(py::init<G4double>())

;
}
42 changes: 42 additions & 0 deletions core/opengate_core/opengate_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ void init_G4UniformMagField(py::module &);

void init_G4QuadrupoleMagField(py::module &);

void init_G4SextupoleMagField(py::module &);

void init_G4UniformElectricField(py::module &);

void init_G4EquationOfMotion(py::module &);
Expand All @@ -204,12 +206,36 @@ void init_G4MagErrorStepper(py::module &);

void init_G4ClassicalRK4(py::module &);

void init_G4DormandPrince745(py::module &);

void init_G4DormandPrinceRK56(py::module &);

void init_G4DormandPrinceRK78(py::module &);

void init_G4BogackiShampine23(py::module &);

void init_G4BogackiShampine45(py::module &);

void init_G4CashKarpRKF45(py::module &);

void init_G4NystromRK4(py::module &);

void init_G4ExactHelixStepper(py::module &);

void init_G4VIntegrationDriver(py::module &);

void init_G4MagInt_Driver(py::module &);

void init_G4ChordFinder(py::module &);

void init_GateMagneticField(py::module &);
void init_GateElectroMagneticField(py::module &);
void init_GateUniformElectroMagneticField(py::module &);
void init_GateGridInterpolator(py::module &);
void init_GateMappedMagneticField(py::module &);
void init_GateMappedElectricField(py::module &);
void init_GateMappedElectroMagneticField(py::module &);

// geometry/solids
void init_G4Box(py::module &);

Expand Down Expand Up @@ -573,6 +599,7 @@ PYBIND11_MODULE(opengate_core, m) {
init_G4ElectricField(m);
init_G4UniformMagField(m);
init_G4QuadrupoleMagField(m);
init_G4SextupoleMagField(m);
init_G4UniformElectricField(m);
init_G4EquationOfMotion(m);
init_G4Mag_EqRhs(m);
Expand All @@ -581,9 +608,24 @@ PYBIND11_MODULE(opengate_core, m) {
init_G4MagIntegratorStepper(m);
init_G4MagErrorStepper(m);
init_G4ClassicalRK4(m);
init_G4DormandPrince745(m);
init_G4DormandPrinceRK56(m);
init_G4DormandPrinceRK78(m);
init_G4BogackiShampine23(m);
init_G4BogackiShampine45(m);
init_G4CashKarpRKF45(m);
init_G4NystromRK4(m);
init_G4ExactHelixStepper(m);
init_G4VIntegrationDriver(m);
init_G4MagInt_Driver(m);
init_G4ChordFinder(m);
init_GateMagneticField(m);
init_GateElectroMagneticField(m);
init_GateUniformElectroMagneticField(m);
init_GateGridInterpolator(m);
init_GateMappedMagneticField(m);
init_GateMappedElectricField(m);
init_GateMappedElectroMagneticField(m);

init_G4Box(m);
init_G4Ellipsoid(m);
Expand Down
28 changes: 28 additions & 0 deletions core/opengate_core/opengate_lib/GateElectroMagneticField.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* --------------------------------------------------
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 "GateElectroMagneticField.h"

GateElectroMagneticField::GateElectroMagneticField(
G4ElectroMagneticField *inner, const G4VSolid *solid,
std::vector<G4ThreeVector> translations,
std::vector<G4RotationMatrix> rotations, double deltaChordMM)
: G4ElectroMagneticField(),
GateFieldBase(solid, std::move(translations), std::move(rotations),
deltaChordMM),
m_inner(inner) {}

void GateElectroMagneticField::GetFieldValue(const G4double Point[4],
G4double *BEfield) const {
// localFieldFunc is a lambda that captures 'this' and calls
// m_inner->GetFieldValue
auto localFieldFunc = [this](const G4double pos[4], G4double *f) {
m_inner->GetFieldValue(pos, f);
};

applyTransforms(Point, BEfield, 6, localFieldFunc);
}
38 changes: 38 additions & 0 deletions core/opengate_core/opengate_lib/GateElectroMagneticField.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* --------------------------------------------------
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
-------------------------------------------------- */

#ifndef GateElectroMagneticField_h
#define GateElectroMagneticField_h

#include "G4ElectroMagneticField.hh"
#include "GateFieldBase.h"
#include <vector>

class G4VSolid;

// GATE wrapper for G4ElectroMagneticField.
class GateElectroMagneticField : public G4ElectroMagneticField,
public GateFieldBase {
public:
// constructor
GateElectroMagneticField(G4ElectroMagneticField *inner, const G4VSolid *solid,
std::vector<G4ThreeVector> translations,
std::vector<G4RotationMatrix> rotations,
double deltaChordMM);

// override GetFieldValue to apply the coordinate transforms
void GetFieldValue(const G4double Point[4], G4double *BEfield) const override;

// override DoesFieldChangeEnergy to return true for electro-magnetic fields
G4bool DoesFieldChangeEnergy() const override { return true; }

private:
// the inner field in the volume's local frame
G4ElectroMagneticField *m_inner;
};

#endif // GateElectroMagneticField_h
Loading
Loading