From b12dde46ceeeae8d44a9edeb75c56c020cd7655c Mon Sep 17 00:00:00 2001 From: Kavya Wadhwa Date: Sun, 11 Oct 2026 16:40:53 +0530 Subject: [PATCH 1/3] Fix Build and Test, and update the README for the PyPI release Build and Test has failed on main since March: - conda on macOS installed the Intel compiler on Apple Silicon runners, so the module could not be imported; use clang_osx-arm64. - Geant4's bundled zlib no longer compiles against the macOS SDK; use the system zlib on macOS and patch the g4tools typo newer clang rejects, as the Wheels workflow does. - Drop Windows: there are no Windows wheels and conda has no Geant4. - Include the OS and architecture in the Xerces/Geant4 cache keys so a build from one runner is never restored on another. - Test Python 3.13 too. README: link the Build and Test badge to the right workflow, add PyPI badges, use absolute links so they work on PyPI, explain where the data goes, note that the examples need a clone, and drop the temporary data directory from the first example (it re-downloads ~2 GB). Add project URLs for the PyPI sidebar. --- .github/workflows/build-test.yaml | 67 ++++++++++--------------------- README.md | 43 ++++++++++++-------- pyproject.toml | 7 ++++ 3 files changed, 56 insertions(+), 61 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 8284cc5..995e954 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] # Geant4 is not available on conda for windows TODO: update this when it is + os: [ubuntu-latest, macos-latest] # Geant4 is not available on conda for Windows defaults: run: shell: bash -l {0} @@ -49,7 +49,9 @@ jobs: - name: Install additional dependencies (MacOS) if: matrix.os == 'macos-latest' run: | - conda install -c conda-forge clang_osx-64 + # macos-latest is Apple Silicon; clang_osx-64 would build an x86_64 + # module that the arm64 Python cannot load. + conda install -c conda-forge clang_osx-arm64 - name: Print versions run: | @@ -89,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] steps: - name: Setup CMake @@ -100,14 +102,14 @@ jobs: uses: actions/cache@v4 with: path: ${{ github.workspace }}/xerces - key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }} + key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} - name: Build and Install Xerces-C if: steps.cache-xerces.outputs.cache-hit != 'true' run: | git clone https://github.com/apache/xerces-c.git xerces-source git -C xerces-source checkout tags/v${{ env.XERCES_VERSION }} - cmake -B xerces-build -S xerces-source -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/xerces -DCMAKE_CXX_STANDARD=${{ env.CPP_STANDARD }} -DBUILD_SHARED_LIBS=OFF ${{ matrix.os == 'windows-latest' && '-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_CXX_FLAGS_RELEASE="/MT"' || '-G Ninja -DCMAKE_CXX_FLAGS=-fPIC -DCMAKE_C_FLAGS=-fPIC -Dnetwork-accessor=socket -Dtranscoder=iconv' }} + cmake -G Ninja -B xerces-build -S xerces-source -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/xerces -DCMAKE_CXX_STANDARD=${{ env.CPP_STANDARD }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-fPIC -DCMAKE_C_FLAGS=-fPIC -Dnetwork-accessor=socket -Dtranscoder=iconv cmake --build xerces-build --parallel $(nproc) --config Release --target install - name: Cache Geant4 Installation @@ -115,13 +117,16 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }} + key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} - name: Build and Install Geant4 (without datasets) if: steps.cache-geant4.outputs.cache-hit != 'true' run: | git clone https://github.com/Geant4/geant4.git ${{ github.workspace }}/geant4-source --depth 1 --branch v${{ env.GEANT4_VERSION }} - cmake -B geant4-build -S geant4-source -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ env.Geant4_DIR }} -DXERCESC_ROOT_DIR=${{ github.workspace }}/xerces -DCMAKE_CXX_STANDARD=${{ env.CPP_STANDARD }} -DGEANT4_USE_GDML=ON -DGEANT4_INSTALL_EXAMPLES=OFF -DGEANT4_INSTALL_DATA=OFF -DGEANT4_BUILD_TLS_MODEL=global-dynamic -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF ${{ matrix.os == 'windows-latest' && '-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_CXX_FLAGS_RELEASE="/MT"' || '-G Ninja -DCMAKE_CXX_FLAGS=-fPIC -DCMAKE_C_FLAGS=-fPIC -DGEANT4_USE_SYSTEM_EXPAT=OFF' }} + # Typo in Geant4 11.2.2's g4tools (fixed in later releases) that Xcode 16.3+ clang rejects. + sed -i.bak 's/a_from\.m_barnch/a_from.m_branch/' geant4-source/source/externals/g4tools/include/tools/wroot/columns.icc + # Geant4's bundled zlib does not compile against recent macOS SDKs; use the system one there. + cmake -G Ninja -B geant4-build -S geant4-source -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ env.Geant4_DIR }} -DXERCESC_ROOT_DIR=${{ github.workspace }}/xerces -DCMAKE_CXX_STANDARD=${{ env.CPP_STANDARD }} -DGEANT4_USE_GDML=ON -DGEANT4_INSTALL_EXAMPLES=OFF -DGEANT4_INSTALL_DATA=OFF -DGEANT4_BUILD_TLS_MODEL=global-dynamic -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-fPIC -DCMAKE_C_FLAGS=-fPIC -DGEANT4_USE_SYSTEM_EXPAT=OFF ${{ runner.os == 'macOS' && '-DGEANT4_USE_SYSTEM_ZLIB=ON' || '' }} cmake --build geant4-build --parallel $(nproc) --config Release --target install install-geant4-datasets: @@ -132,7 +137,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] steps: - name: Cache Geant4 Installation @@ -140,7 +145,7 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }} + key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: Cache Geant4 Datasets @@ -152,27 +157,14 @@ jobs: enableCrossOsArchive: true lookup-only: true - - name: Move Geant4 datasets (Ubuntu/MacOS) - if: - steps.cache-geant4-data.outputs.cache-hit != 'true' && matrix.os != - 'windows-latest' + - name: Move Geant4 datasets + if: steps.cache-geant4-data.outputs.cache-hit != 'true' shell: bash run: | bash ${{ env.Geant4_DIR }}/bin/geant4-config --install-datasets bash ${{ env.Geant4_DIR }}/bin/geant4-config --check-datasets mv ${{ env.Geant4_DIR }}/share/Geant4/data ${{ github.workspace }}/geant4-data - - name: Move Geant4 datasets (Windows) - if: - steps.cache-geant4-data.outputs.cache-hit != 'true' && matrix.os == - 'windows-latest' - shell: powershell - run: | - Get-ChildItem -Path ${{ env.Geant4_DIR }}\bin - cmd /c ${{ env.Geant4_DIR }}\bin\geant4-config.cmd --install-datasets - cmd /c ${{ env.Geant4_DIR }}\bin\geant4-config.cmd --check-datasets - Move-Item ${{ env.Geant4_DIR }}\share\Geant4\data ${{ github.workspace }}\geant4-data - build-test: name: Build and Test for ${{ matrix.os }} (Python ${{ matrix.python-version }}) @@ -182,13 +174,14 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] python-version: - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" + - "3.13" steps: - name: Checkout @@ -202,18 +195,12 @@ jobs: - name: Setup CMake uses: lukka/get-cmake@v3.30.3 - - name: Setup Windows environment variables - if: matrix.os == 'windows-latest' - shell: bash - run: | - echo "CMAKE_ARGS=-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded" >> $GITHUB_ENV - - name: Cache Xerces-C Installation id: cache-xerces uses: actions/cache@v4 with: path: ${{ github.workspace }}/xerces - key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }} + key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: Cache Geant4 Installation @@ -221,7 +208,7 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }} + key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: pip install the package @@ -242,23 +229,13 @@ jobs: fail-on-cache-miss: true enableCrossOsArchive: true - - name: Move Geant4 datasets (Ubuntu/MacOS) - if: matrix.python-version != '3.11' && matrix.os != 'windows-latest' + - name: Move Geant4 datasets + if: matrix.python-version != '3.11' run: | GEANT4_DATA_DIR=$(python -c "import geant4_python_application; print(geant4_python_application.data_directory())") mkdir -p ${{ github.workspace }}/geant4-data "$GEANT4_DATA_DIR" mv ${{ github.workspace }}/geant4-data/* "$GEANT4_DATA_DIR" - # TODO: unify this with the above - - name: Move Geant4 datasets (Windows) - if: matrix.python-version != '3.11' && matrix.os == 'windows-latest' - shell: powershell - run: | - $env:GEANT4_DATA_DIR = python -c "import geant4_python_application; print(geant4_python_application.data_directory())" - New-Item -ItemType Directory -Path "${{ github.workspace }}\geant4-data" -Force - New-Item -ItemType Directory -Path $env:GEANT4_DATA_DIR -Force - Move-Item "${{ github.workspace }}\geant4-data\*" $env:GEANT4_DATA_DIR -Force - - name: Install datasets uses: nick-fields/retry@v3 with: diff --git a/README.md b/README.md index f5cc690..724ad45 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ [![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) +[![PyPI](https://img.shields.io/pypi/v/geant4-python-application)](https://pypi.org/project/geant4-python-application/) +[![Python](https://img.shields.io/pypi/pyversions/geant4-python-application)](https://pypi.org/project/geant4-python-application/) [![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) +[![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/build-test.yaml) This is an experiment at providing a pythonic interface to Geant4. @@ -24,7 +26,7 @@ looking at [geant4_pybind](https://github.com/HaarigerHarald/geant4_pybind). [awkward array](https://github.com/scikit-hep/awkward) New to Geant4 or this package? See the -[Python developer guide](PYTHON_DEVELOPER_GUIDE.md). +[Python developer guide](https://github.com/lobis/geant4-python-application/blob/main/PYTHON_DEVELOPER_GUIDE.md). ## Platform support @@ -35,36 +37,45 @@ 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. +- Prebuilt wheels for macOS (Apple Silicon and Intel) and Linux x86_64, Python + 3.8–3.13. Geant4 is bundled, so no separate Geant4 (C++) installation is + needed. +- `[gui]` adds the interactive Qt viewer (`app.visualize()`); leave it out for a + physics-only install. +- Check the installation: + + ```bash + python -c "import geant4_python_application as g4; print(g4.__version__)" + ``` + +- The first simulation downloads Geant4's data files (~2 GB) once per user, to + `~/Library/Application Support/geant4_python_application` (macOS) or + `~/.local/share/geant4_python_application` (Linux). Set + `GEANT4_PYTHON_APPLICATION_DIR` to use another location. +- Windows, Linux aarch64, building from source and data file management are + covered in [INSTALLATION.md](https://github.com/lobis/geant4-python-application/blob/main/INSTALLATION.md). On Windows, WSL works with + the Linux wheels. -Geant4's physics data files download automatically on first use, so you can run -an example straight away: +The examples are not part of the package; run them from a clone of the +repository: ```bash +git clone https://github.com/lobis/geant4-python-application +cd geant4-python-application 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) @@ -157,7 +168,7 @@ 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 +or for source builds see [INSTALLATION.md](https://github.com/lobis/geant4-python-application/blob/main/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: diff --git a/pyproject.toml b/pyproject.toml index c3c5aad..302b57b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,13 @@ readme = "README.md" requires-python = ">=3.8" dynamic = ["version"] +[project.urls] +Homepage = "https://github.com/lobis/geant4-python-application" +Source = "https://github.com/lobis/geant4-python-application" +Issues = "https://github.com/lobis/geant4-python-application/issues" +Documentation = "https://github.com/lobis/geant4-python-application/blob/main/INSTALLATION.md" +Changelog = "https://github.com/lobis/geant4-python-application/releases" + [tool.scikit-build] metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" sdist.include = ["src/geant4_python_application/_version.py"] From 939e271818c8e5f958621f50aaacb25da5a7a510 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2026 11:11:08 +0000 Subject: [PATCH 2/3] style: pre-commit fixes --- .github/workflows/build-test.yaml | 20 +++++++++++++++----- README.md | 12 +++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 995e954..03c3655 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -102,7 +102,9 @@ jobs: uses: actions/cache@v4 with: path: ${{ github.workspace }}/xerces - key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} + key: + xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ + runner.os }}-${{ runner.arch }} - name: Build and Install Xerces-C if: steps.cache-xerces.outputs.cache-hit != 'true' @@ -117,7 +119,9 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} + key: + geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ + runner.os }}-${{ runner.arch }} - name: Build and Install Geant4 (without datasets) if: steps.cache-geant4.outputs.cache-hit != 'true' @@ -145,7 +149,9 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} + key: + geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ + runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: Cache Geant4 Datasets @@ -200,7 +206,9 @@ jobs: uses: actions/cache@v4 with: path: ${{ github.workspace }}/xerces - key: xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} + key: + xerces-v${{ env.XERCES_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ + runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: Cache Geant4 Installation @@ -208,7 +216,9 @@ jobs: uses: actions/cache@v4 with: path: ${{ env.Geant4_DIR }} - key: geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ runner.os }}-${{ runner.arch }} + key: + geant4-v${{ env.GEANT4_VERSION }}-cpp${{ env.CPP_STANDARD }}-${{ + runner.os }}-${{ runner.arch }} fail-on-cache-miss: true - name: pip install the package diff --git a/README.md b/README.md index 724ad45..1cbd338 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,9 @@ pip install "geant4-python-application[gui]" `~/.local/share/geant4_python_application` (Linux). Set `GEANT4_PYTHON_APPLICATION_DIR` to use another location. - Windows, Linux aarch64, building from source and data file management are - covered in [INSTALLATION.md](https://github.com/lobis/geant4-python-application/blob/main/INSTALLATION.md). On Windows, WSL works with - the Linux wheels. + covered in + [INSTALLATION.md](https://github.com/lobis/geant4-python-application/blob/main/INSTALLATION.md). + On Windows, WSL works with the Linux wheels. The examples are not part of the package; run them from a clone of the repository: @@ -168,9 +169,10 @@ 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](https://github.com/lobis/geant4-python-application/blob/main/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: +or for source builds see +[INSTALLATION.md](https://github.com/lobis/geant4-python-application/blob/main/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 From 2aae61d614185db7369c9d31edd364267a1d5086 Mon Sep 17 00:00:00 2001 From: Kavya Wadhwa Date: Sun, 11 Oct 2026 16:52:09 +0530 Subject: [PATCH 3/3] Credit Kavya Wadhwa as author and maintainer in the package metadata --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 302b57b..4ab5e53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,12 @@ requires = ["scikit-build-core>=0.3.3", "pybind11"] [project] authors = [ - { name = "Luis Antonio Obis Aparicio", email = "luis.antonio.obis@gmail.com" } + { name = "Luis Antonio Obis Aparicio", email = "luis.antonio.obis@gmail.com" }, + { name = "Kavya Wadhwa", email = "kavyavadhwa@gmail.com" }, +] +maintainers = [ + { name = "Luis Antonio Obis Aparicio", email = "luis.antonio.obis@gmail.com" }, + { name = "Kavya Wadhwa", email = "kavyavadhwa@gmail.com" }, ] classifiers = [ "Intended Audience :: Developers",