Metadata-Version: 2.2
Name: geant4_python_application
Version: 0.1.0
Summary: Geant4 Python Application
Author-Email: Luis Antonio Obis Aparicio <luis.antonio.obis@gmail.com>
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX
Classifier: Operating System :: Unix
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Requires-Dist: awkward
Requires-Dist: vector
Requires-Dist: fsspec
Requires-Dist: pyarrow
Requires-Dist: awkward-pandas
Requires-Dist: numpy
Requires-Dist: requests
Requires-Dist: platformdirs
Requires-Dist: tqdm
Provides-Extra: gui
Requires-Dist: PyQt5-Qt5<5.16,>=5.15.2; extra == "gui"
Provides-Extra: dev
Requires-Dist: boost_histogram; extra == "dev"
Requires-Dist: hist; extra == "dev"
Requires-Dist: uproot; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-xdist; extra == "test"
Requires-Dist: pytest-timeout; extra == "test"
Requires-Dist: pytest-rerunfailures; extra == "test"
Description-Content-Type: text/markdown

# Geant4 Python Application

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/lobis/geant4-python-application/HEAD?labpath=attenuation.ipynb)
[![Binder](https://binderhub.ssl-hep.org/badge_logo.svg)](https://binderhub.ssl-hep.org/v2/gh/lobis/geant4-python-application/HEAD?labpath=attenuation.ipynb)

[![Wheels](https://github.com/lobis/geant4-python-application/actions/workflows/wheels.yaml/badge.svg)](https://github.com/lobis/geant4-python-application/actions/workflows/wheels.yaml)
[![Build and Test](https://github.com/lobis/geant4-python-application/actions/workflows/build-test.yaml/badge.svg)](https://github.com/lobis/geant4-python-application/actions/workflows/test.yaml)

This is an experiment at providing a pythonic interface to Geant4.

The goal is not to provide a full python interface to Geant4, but rather to
provide a high-level interface to a generic Geant4 application which is highly
configurable.

If you are looking for a full set of python bindings for Geant4, I recommend
looking at [geant4_pybind](https://github.com/HaarigerHarald/geant4_pybind).

## Overview

- Configurable Geant4 application written in C++
- Python interface to the application via
  [pybind11](https://github.com/pybind/pybind11)
- The complete event data is available as an
  [awkward array](https://github.com/scikit-hep/awkward)

New to Geant4 or this package? See the
[Python developer guide](PYTHON_DEVELOPER_GUIDE.md).

## Platform support

Tested on macOS and Ubuntu; still undergoing broader testing. If you hit a bug,
please report it via
[GitHub Issues](https://github.com/lobis/geant4-python-application/issues) or
reach out to kavyavadhwa@gmail.com.

## Installation

Prebuilt wheels for macOS (Apple Silicon and Intel) and Linux x86_64, Python 3.8
– 3.13, bundle Geant4 — no separate Geant4 (C++) installation is needed:

```bash
pip install "geant4-python-application[gui]"
```

The `gui` extra adds the interactive Qt viewer; leave it out for a physics-only
install.

Geant4's physics data files download automatically on first use, so you can run
an example straight away:

```bash
python examples/geant4-examples/Geant4-11.4.2-examples-python/basic/B1/b1.py --batch -n 10
```

`--batch` runs headless; drop it to open the Qt viewer.

Building from source (other platforms, development), the Qt viewer, and data
file management are covered in [INSTALLATION.md](INSTALLATION.md).

## Usage

```python
import geant4_python_application as g4

# Use a temporary directory for the Geant4 data files (remove this line to use the default location)
g4.application_directory(temp=True)

with g4.Application(gdml=g4.basic_gdml, seed=137) as app:
    events = app.run(100)

print(events)
```

A Geant4 reference physics list can be selected by name:

```python
with g4.Application(gdml=g4.basic_gdml, physics="FTFP_BERT") as app:
    events = app.run(100)

print(g4.Application.available_physics_lists())
```

Particle guns and Geant4's General Particle Source have a Python interface:

```python
with g4.Application(gdml=g4.basic_gdml) as app:
    app.generator.use_gps().particle("gamma").energy(2, "MeV")
    app.generator.position(0, 0, -10, "cm").direction(0, 0, 1)
    events = app.run(100)
```

Advanced GPS distributions remain accessible through
`app.generator.commands(["/gps/pos/type Plane", ...])`.

Optical physics and uniform global magnetic/electric fields can be enabled
directly:

```python
with g4.Application(gdml=my_optical_gdml, optical=True) as app:
    app.detector.magnetic_field = (0.0, 0.0, 1.5)  # tesla
    app.detector.electric_field = (0.0, 0.0, 0.5)  # kV/cm
    events = app.run(100)
```

Optical scintillator GDML + tuning helpers:

```python
from geant4_python_application import optical as gopt

with g4.Application(gdml=gopt.optical_water_gdml, optical=True) as app:
    app.commands(gopt.scintillation_commands(yield_factor=1.0))
    events = app.run(100)  # track.particle contains 'opticalphoton'
```

Recorded steps can be scored per event or into a Cartesian energy mesh:

```python
energy_per_event = g4.Scoring.energy_deposit(events, volume="detector")
mesh, edges = g4.Scoring.energy_mesh(events, bins=(20, 20, 40))
```

Python run/event/track/step callbacks (offline over awkward arrays):

```python
with g4.Application(gdml=g4.basic_gdml) as app:
    events = app.run_with_callbacks(
        100,
        on_run=lambda evs: print(len(evs)),
        on_event=lambda ev: None,
        on_track=lambda tr, ev: None,
        on_step=lambda st, tr, ev: None,
    )
```

Extra physics constructors incl. DNA, CAD/VTK/ROOT/HepMC, and MPI splitting:

```python
print(g4.Application.available_extra_physics())
with g4.Application(gdml=g4.basic_gdml, physics="FTFP_BERT") as app:
    app.add_physics(
        "G4EmDNAPhysics_option2"
    )  # or G4EmExtraPhysics, G4OpticalPhysics...
    events = app.run(100)

from geant4_python_application import cad, io as gio, distributed as dist

gdml = cad.mesh_to_gdml(*cad.cube_mesh(100.0))  # or cad.stl_ascii_to_gdml(stl_text)
gio.mesh_to_vtk(mesh, edges, "mesh.vtk")
gio.events_to_parquet(events, "events.parquet")
gio.events_to_root(events, "events.root")  # needs uproot
primaries = gio.hepmc_to_primaries(open("events.hepmc").read())

rank, size = dist.get_rank_size()
start, count = dist.split_count(1000, rank, size)  # mpiexec -n 2 python run.py
```

### Interactive Qt visualization

Install with the `gui` extra (`pip install "geant4-python-application[gui]"`),
or for source builds see [INSTALLATION.md](INSTALLATION.md). Then open Geant4's
interactive Qt viewer. The call returns when the window is closed, and commands
can be entered in the viewer's command panel:

```python
import geant4_python_application as g4

with g4.Application(gdml=g4.basic_gdml, seed=137) as app:
    app.command("/gun/particle e-")
    app.command("/gun/energy 100 MeV")
    app.visualize()
```
