Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 27 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,32 @@ jobs:
fail-fast: false
matrix:
include:
# Linux/macOS ship a single abi3 wheel (cp312-*) usable on 3.12+.
- platform: linux_x86_64
builder: ubuntu-24.04
cibw_archs: x86_64
cibw_build: "cp312-*"
- platform: linux_aarch64
builder: ubuntu-24.04-arm
cibw_archs: aarch64
cibw_build: "cp312-*"
- platform: macos_arm64
builder: macos-14
cibw_archs: arm64
# x86_64 is cross-compiled on the arm64 macOS runner; its tests cannot
# run here, so they are skipped and covered by smoke-wheels (Rosetta).
cibw_build: "cp312-*"
# x86_64 is cross-compiled on the arm64 macOS runner.
- platform: macos_x86_64
builder: macos-14
cibw_archs: x86_64
test_skip: "*"
cibw_build: "cp312-*"
# Windows cannot use abi3: the nanobind WrapDB subproject links the
# version-specific python3XY import library, so an "abi3" wheel built on
# 3.12 actually imports python312.dll and fails to load on 3.13+. Build
# per-version wheels instead (limited API disabled below).
Comment thread
georgeyiasemis marked this conversation as resolved.
- platform: windows_x86_64
builder: windows-2022
cibw_archs: AMD64
cibw_build: "cp312-* cp313-*"
steps:
- name: Checkout
uses: actions/checkout@v5
Expand All @@ -89,8 +97,11 @@ jobs:
package-dir: .
output-dir: artifacts/wheels
env:
# A single abi3 wheel per platform, built with CPython 3.12.
CIBW_BUILD: "cp312-*"
# abi3 (cp312-*) on Linux/macOS; per-version on Windows (see matrix).
CIBW_BUILD: ${{ matrix.cibw_build }}
# Skip musllinux: PyTorch (a hard runtime dependency) publishes no
# musllinux wheels, so a musllinux `direct-recon` wheel is not installable.
CIBW_SKIP: "*-musllinux*"
Comment thread
Copilot marked this conversation as resolved.
CIBW_ARCHS: ${{ matrix.cibw_archs }}
CIBW_BUILD_VERBOSITY: "1"
# C++20 (std::numbers, std::span) needs a modern toolchain; the
Expand All @@ -99,17 +110,15 @@ jobs:
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
# Force MSVC on Windows: the runner ships MinGW GCC on PATH, and
# Meson would otherwise auto-select it over MSVC. `--vsenv` activates
# the Visual Studio environment.
CIBW_CONFIG_SETTINGS_WINDOWS: "setup-args=--vsenv"
# Run the native extension smoke tests against the freshly built
# wheel. cibuildwheel runs this from a temporary directory, and
# `--import-mode=importlib` keeps pytest from putting the source tree
# (which has no compiled .so) on sys.path, so `import direct` resolves
# to the installed wheel.
CIBW_TEST_REQUIRES: "pytest numpy"
CIBW_TEST_COMMAND: >-
python -m pytest --import-mode=importlib {project}/tests/tests_common/_gaussian_native_test.py {project}/tests/tests_common/_poisson_native_test.py {project}/tests/tests_ssl/_gaussian_fill_native_test.py
CIBW_TEST_SKIP: ${{ matrix.test_skip }}
# the Visual Studio environment. `-Dpython.allow_limited_api=false`
# disables the limited API (overriding pyproject's limited-api=true) so
# each interpreter gets a wheel linked against its own pythonXY.dll.
CIBW_CONFIG_SETTINGS_WINDOWS: "setup-args=--vsenv setup-args=-Dpython.allow_limited_api=false"
# No in-build test here: cibuildwheel would `pip install` the wheel
# with its full runtime stack (torch + the CUDA wheels), which is slow
# and unavailable on some targets. The dedicated `smoke-wheels` job
# tests the native extensions against the built wheel with --no-deps
# on both 3.12 and 3.13 instead.
- name: Upload wheel
if: steps.gate.outputs.run == 'true'
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -149,7 +158,8 @@ jobs:
strategy:
fail-fast: false
matrix:
# Install the cp312-abi3 wheel on 3.12 and 3.13 to prove the stable ABI.
# Install on 3.12 and 3.13: proves the abi3 wheel on Linux/macOS and the
# per-version wheels on Windows both load on each interpreter.
python: ["3.12", "3.13"]
target:
- platform: linux_x86_64
Expand Down
83 changes: 41 additions & 42 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,61 +1,41 @@
.. raw:: html
.. image:: https://github.com/NKI-AI/direct/assets/71031687/14ce8234-7ef1-4e32-84c6-966dc393e7ca
:alt: DIRECT
:width: 400px
:align: center

<div align="center">
<img src="https://github.com/NKI-AI/direct/assets/71031687/14ce8234-7ef1-4e32-84c6-966dc393e7ca" width="400"/>
<br>
<figcaption margin-top:10px; font-size:24px !important; font-weight:bold !important;">DIRECT: Deep Image REConstruction Toolkit</figcaption>
=========================================
DIRECT: Deep Image REConstruction Toolkit
=========================================

</div>

.. raw:: html

<div align="center">

<br />

<a href="https://doi.org/10.21105/joss.04278">
<img src="https://joss.theoj.org/papers/10.21105/joss.04278/status.svg" alt="JOSS"></a>
<a href="https://github.com/NKI-AI/direct/actions/workflows/tests.yml">
<img src="https://github.com/NKI-AI/direct/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
<a href="https://github.com/NKI-AI/direct/actions/workflows/ruff.yml">
<img src="https://github.com/NKI-AI/direct/actions/workflows/ruff.yml/badge.svg" alt="Ruff"></a>
<a href="https://app.codacy.com/gh/NKI-AI/direct?utm_source=github.com&utm_medium=referral&utm_content=NKI-AI/direct&utm_campaign=Badge_Grade_Settings">
<img src="https://api.codacy.com/project/badge/Grade/1c55d497dead4df69d6f256da51c98b7" alt="Codacy"></a>
<a href="https://codecov.io/gh/NKI-AI/direct">
<img src="https://codecov.io/gh/NKI-AI/direct/branch/main/graph/badge.svg?token=STYAUFCKJY" alt="Codecov"></a>

</div>

<p align="center">
<a href="https://docs.aiforoncology.nl/direct/installation.html">Installation</a> •
<a href="https://docs.aiforoncology.nl/direct/getting_started.html">Quick Start</a> •
<a href="https://docs.aiforoncology.nl/direct/index.html">Documentation</a> •
<a href="https://docs.aiforoncology.nl/direct/model_zoo.html">Model Zoo</a> <br>
</p>

<br />
|PyPI| |JOSS| |Tests| |Ruff| |Codacy| |Codecov|

`Installation <https://docs.aiforoncology.nl/direct/installation.html>`_ •
`Quick Start <https://docs.aiforoncology.nl/direct/getting_started.html>`_ •
`Documentation <https://docs.aiforoncology.nl/direct/index.html>`_ •
`Model Zoo <https://docs.aiforoncology.nl/direct/model_zoo.html>`_

``DIRECT`` is a Python, end-to-end pipeline for solving Inverse Problems emerging in Imaging Processing.
It is built with PyTorch and stores state-of-the-art Deep Learning imaging inverse problem solvers such as denoising, dealiasing and reconstruction.
By defining a base forward linear or non-linear operator, ``DIRECT`` can be used for training models for recovering images such as MRIs from partially observed or noisy input data.
``DIRECT`` stores inverse problem solvers such as the vSHARP, Learned Primal Dual algorithm, Recurrent Inference Machine and Recurrent Variational Network, which were part of the winning solutions in Facebook & NYUs FastMRI challenge in 2019, the Calgary-Campinas MRI reconstruction challenge at MIDL 2020 and the CMRxRecon challenge 2023.
For a full list of the baselines currently implemented in DIRECT see `here <#baselines-and-trained-models>`_.

.. raw:: html
.. figure:: https://raw.githubusercontent.com/NKI-AI/direct/main/.github/direct.png
:alt: DIRECT reconstruction examples
:align: center

<div align="center">
<img src=".github/direct.png"/>
<figcaption>Zero-filled reconstruction, Compressed-Sensing (CS) reconstruction using the BART toolbox, Reconstruction using a RIM model trained with DIRECT</figcaption>
</div>
Zero-filled reconstruction, Compressed-Sensing (CS) reconstruction using the BART toolbox, Reconstruction using a RIM model trained with DIRECT

Quick install
-------------

``DIRECT`` is published to PyPI as ``direct``:

.. code-block:: bash

Quick install
-------------
pip install direct

The recommended way to install ``DIRECT`` is with `uv <https://docs.astral.sh/uv/>`_:
For development, the recommended way is with `uv <https://docs.astral.sh/uv/>`_:

.. code-block:: bash

Expand Down Expand Up @@ -101,3 +81,22 @@ If you use DIRECT in your own research, or want to refer to baseline results pub
title = {DIRECT: Deep Image REConstruction Toolkit},
journal = {Journal of Open Source Software}
}

.. |PyPI| image:: https://img.shields.io/pypi/v/direct.svg
:target: https://pypi.org/project/direct/
:alt: PyPI
.. |JOSS| image:: https://joss.theoj.org/papers/10.21105/joss.04278/status.svg
:target: https://doi.org/10.21105/joss.04278
:alt: JOSS
.. |Tests| image:: https://github.com/NKI-AI/direct/actions/workflows/tests.yml/badge.svg
:target: https://github.com/NKI-AI/direct/actions/workflows/tests.yml
:alt: Tests
.. |Ruff| image:: https://github.com/NKI-AI/direct/actions/workflows/ruff.yml/badge.svg
:target: https://github.com/NKI-AI/direct/actions/workflows/ruff.yml
:alt: Ruff
.. |Codacy| image:: https://api.codacy.com/project/badge/Grade/1c55d497dead4df69d6f256da51c98b7
:target: https://app.codacy.com/gh/NKI-AI/direct
:alt: Codacy
.. |Codecov| image:: https://codecov.io/gh/NKI-AI/direct/branch/main/graph/badge.svg?token=STYAUFCKJY
:target: https://codecov.io/gh/NKI-AI/direct
:alt: Codecov
2 changes: 1 addition & 1 deletion direct/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
__author__ = """direct contributors"""
__version__ = "2.1.0"
__version__ = "2.1.1"
31 changes: 30 additions & 1 deletion installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ directly from ``pyproject.toml`` and the committed ``uv.lock``.
uv run direct --help
uv run pytest

Install from PyPI (``pip``)
---------------------------

``DIRECT`` is published to PyPI as ``direct``. On the supported platforms this
fetches a prebuilt wheel (``abi3`` on Linux/macOS, Python-version-specific on
Windows), so nothing is compiled:

.. code-block::

pip install direct

.. code-block:: python

import direct

If no wheel is available for your platform, ``pip`` builds the C++ extensions
from the source distribution via ``meson-python`` + ``nanobind`` in an isolated
build environment; only a working C++20 compiler is required. The conda section
below shows a step-by-step build, including installing PyTorch with CUDA first.

For an editable/development install, install the build tooling first and disable
build isolation so the on-import rebuild keeps working:

.. code-block::

pip install meson-python meson ninja
pip install --no-build-isolation -e .

Install using Docker
--------------------

Expand Down Expand Up @@ -106,7 +134,8 @@ Install using ``conda`` (alternative)

#.
Install ``DIRECT`` from PyPI. On the supported platforms this fetches a
prebuilt ``abi3`` wheel, so nothing is compiled:
prebuilt wheel (``abi3`` on Linux/macOS, Python-version-specific on
Windows), so nothing is compiled:

.. code-block::

Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

project('direct', 'cpp',
version : '2.1.0',
version : '2.1.1',
license : 'Apache-2.0',
meson_version : '>=1.3',
default_options : [
Expand Down
19 changes: 11 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ requires = ["meson-python>=0.18", "meson>=1.5"]
build-backend = "mesonpy"

[project]
# Distribution name on PyPI and import package name.
name = "direct"
description = "DIRECT - Deep Image REConsTruction - is a deep learning framework for MRI reconstruction."
Comment on lines 5 to 8

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could you clarify what change you want in this thread—update the PR title/description, or revert/split the packaging rename changes?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

apply suggestion

readme = "README.rst"
Expand All @@ -25,7 +26,7 @@ classifiers = [
# Static so uv can read metadata without invoking the build backend (required
# because `direct` is built without isolation; see `[tool.uv]` below). Kept in
# sync with meson.build and direct/__init__.py by tests/version_test.py.
version = "2.1.0"
version = "2.1.1"
dependencies = [
"numpy>=2.4,<3",
"h5py>=3.16",
Expand Down Expand Up @@ -72,10 +73,11 @@ docs = [

[tool.uv]
default-groups = ["dev", "build"]
# Build `direct` against the already-synced `build` group instead of an isolated
# build environment. Without this, meson-python's editable install records the
# absolute path of the isolated build env's `ninja`, which uv later deletes,
# breaking `import direct` on the next run.
# Build `direct` against the already-synced `build` group instead of an
# isolated build environment. Without this, meson-python's editable install
# records the absolute path of the isolated build env's `ninja`, which uv later
# deletes, breaking `import direct` on the next run. Matches the distribution
# name in `[project] name`, not the import package.
no-build-isolation-package = ["direct"]

[tool.pytest.ini_options]
Expand All @@ -91,9 +93,10 @@ direct = "direct.cli.cli:main"
Homepage = "https://github.com/NKI-AI/direct"

[tool.meson-python]
# The C++ extensions target the CPython 3.12 stable ABI (abi3), so the wheels
# are tagged `abi3` and a single wheel per platform serves every supported
# interpreter.
# The C++ extensions target the CPython 3.12 stable ABI (abi3), so non-Windows
# wheels are tagged `abi3` and a single wheel per platform serves every
# supported interpreter. Windows builds override this in the release workflow
# and emit per-version wheels.
limited-api = true

[tool.meson-python.args]
Expand Down
1 change: 1 addition & 0 deletions tests/version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def _pyproject_version() -> str:


def test_dunder_version_matches_installed_metadata() -> None:
# Distribution name (PyPI) matches the import package.
assert direct.__version__ == importlib.metadata.version("direct")


Expand Down
18 changes: 9 additions & 9 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.