Skip to content

EM Field Enhancement: local coordinates, dynamic placements and mapped fields#1012

Open
srmarcballestero wants to merge 19 commits into
OpenGATE:masterfrom
srmarcballestero:feature/field_enhancement
Open

EM Field Enhancement: local coordinates, dynamic placements and mapped fields#1012
srmarcballestero wants to merge 19 commits into
OpenGATE:masterfrom
srmarcballestero:feature/field_enhancement

Conversation

@srmarcballestero
Copy link
Copy Markdown
Contributor

@srmarcballestero srmarcballestero commented May 5, 2026

Rationale

Enhancement and maintenance of the internal field management infrastructure. Implement mapped fields. User API remains unchanged.

Fixes

  • Previously, fields were defined in global coordinates and didn't follow volume rotation or translation. Fields are now defined in the local coordinate system of the attached logical volume. The world-to-local coordinate transform is computed for every physical placement of that logical volume and applied on each GetFieldValue call, so a field attached to a repeated or rotated volume automatically applies with the correct orientation and position at each placement.
  • The per-placement world-to-local transforms are cached internally and updated between runs, so fields correctly track volumes that are moved or rotated by dynamic geometry changes.

New Features

  • The Geant4 built-in sextupole magnetic field is now exposed to the user.
  • Mapped magnetic, electric or combined electromagnetic fields defined on a regular, complete 3D cartesian grid can now be used.

Internal Changes

The whole C++ field management infrastructure has been rethought and refactored. Now, all field types share a single base class, GateFieldBase, which resolves the physical placement of the volume and manages coordinate transforms. Concrete implementations are minimal.

Tests and Documentation

Tests for the new features have been added, and I have updated the EM fields documentation page.

Cheers,

Marc :)

- Allows fields to be defined relative to the local coordinate system of the physical volumes.
- Paves the way for the mapped field implementation
…ld definition in local coordinates and updates for dynamic geometry changes
Copilot AI review requested due to automatic review settings May 5, 2026 08:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This draft PR refactors magnetic-field handling so fields are defined in the local coordinate system of the volume they’re attached to, and introduces infrastructure to cache and refresh placement transforms (including multi-placement logical volumes) across dynamic geometry updates between runs.

Changes:

  • Wraps magnetic fields in a new C++ GateMagneticField (built on GateField) to transform query points world↔local per physical placement and to support transform refreshes.
  • Updates Python magnetic-field classes to construct an “inner” Geant4 field in local coordinates and then wrap it with GateMagneticField.
  • Adds a run-start hook to refresh cached transforms after dynamic geometry changers are applied, and wires the attached volume object into field construction.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
opengate/geometry/fields.py Refactors magnetic fields to create local-coordinate inner fields and wrap them with GateMagneticField; adds refresh_transforms().
opengate/engines.py Passes the attached volume object into field instances before creating field managers.
opengate/actors/dynamicactors.py Refreshes field transforms after dynamic geometry changes at begin-of-run.
core/opengate_core/opengate_lib/GateField.h / GateField.cpp Adds a C++ helper to cache placement transforms and locate the containing placement (with overshoot fallback).
core/opengate_core/opengate_lib/GateMagneticField.h / GateMagneticField.cpp Adds a C++ magnetic-field wrapper that evaluates inner fields in local coords and rotates results back to world.
core/opengate_core/opengate_lib/pyGateMagneticField.cpp Adds pybind11 bindings for GateMagneticField and SetTransforms.
core/opengate_core/opengate_core.cpp Registers GateMagneticField bindings in the Python module init.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/opengate_core/opengate_lib/GateFieldBase.cpp
Comment thread opengate/geometry/fields.py Outdated
Comment thread opengate/geometry/fields.py Outdated
Comment thread opengate/engines.py
Comment thread opengate/actors/dynamicactors.py
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/opengate_core/opengate_lib/GateField.cpp Outdated
Comment thread opengate/geometry/fields.py Outdated
Comment thread opengate/engines.py Outdated
Comment thread opengate/geometry/fields.py
Comment thread core/opengate_core/opengate_lib/GateField.cpp Outdated
@srmarcballestero srmarcballestero changed the title WIP: EM field support maintenance and enhancement EM Field Enhancement: local coordinates, dynamic placements and mapped fields May 7, 2026
@srmarcballestero srmarcballestero marked this pull request as ready for review May 7, 2026 06:34
@srmarcballestero srmarcballestero requested a review from Copilot May 7, 2026 06:36
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 47 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

docs/source/user_guide/user_guide_fields.rst:165

  • The CustomElectroMagneticField code snippet also uses tesla without defining it in the snippet. Consider adding tesla = gate.g4_units.tesla near the existing volt/m definitions so users can copy-paste the example successfully.
**CustomElectroMagneticField** -- Arbitrary combined field. The callback must return all six components ``[Bx, By, Bz, Ex, Ey, Ez]``.

.. code-block:: python

   def my_EM_field(x, y, z, t):
       return [0, 1 * tesla, 0, 1e6 * volt / m, 0, 0]

Comment thread core/opengate_core/opengate_lib/GateFieldBase.cpp
Comment thread core/opengate_core/opengate_lib/GateFieldBase.cpp
Comment thread opengate/tests/src/geometry/test099_fields_mapped_vs_uniform_E.py
Comment thread opengate/tests/src/geometry/test099_fields_mapped_vs_uniform_E.py
Comment thread opengate/tests/src/geometry/test099_fields_serialization.py
Comment thread docs/source/user_guide/user_guide_fields.rst
@srmarcballestero
Copy link
Copy Markdown
Contributor Author

Fork synced with master and PR ready for review

@srmarcballestero srmarcballestero force-pushed the feature/field_enhancement branch from 9e165ae to 0a5457f Compare May 7, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants