diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 8284cc5..03c3655 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,16 @@ 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 +119,18 @@ 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 +141,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 +149,9 @@ 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 +163,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 +180,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 +201,14 @@ 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 +216,9 @@ 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 +239,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..1cbd338 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,46 @@ 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: +- 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. + +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,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](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 diff --git a/pyproject.toml b/pyproject.toml index c3c5aad..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", @@ -46,6 +51,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"]