Skip to content

Commit

Permalink
Merge pull request #24 from guanhuaw/feature/pytest
Browse files Browse the repository at this point in the history
Feature/pytest: use pytest for unit tests
  • Loading branch information
guanhuaw authored Jul 28, 2024
2 parents 787ce33 + 9f24708 commit 67b9a9b
Show file tree
Hide file tree
Showing 39 changed files with 5,776 additions and 546 deletions.
51 changes: 33 additions & 18 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,50 @@ name: Python-CI
on:
push:
branches:
- main
- master
- develop
- feature/*
pull_request:
branches:
- main
- master
- develop
- feature/*

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x' # Specify the Python version you need

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install ruff pytest
- name: Lint with Ruff
run: |
ruff ./mirtorch
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10" # Specify the Python version you need
cache: 'pip' # caching pip dependencies

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install ruff pytest
- name: Lint with Ruff
run: |
ruff check ./mirtorch
- name: Test with pytest
run: |
pytest ./tests/*
- name: Automated Version Bump
if: github.ref == 'refs/heads/master'
uses: phips28/gh-action-bump-version@master
with:
tag-prefix: "v" # or an empty string if you don't want a prefix
filename: "pyproject.toml"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Push changes
if: github.ref == 'refs/heads/master'
run: git push && git push --tags
29 changes: 19 additions & 10 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,23 @@ jobs:
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
- name: Install pypa/build
run: >-
python3 -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: python3 -m build
- name: Store the distribution packages
uses: actions/upload-artifact@v3
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
name: python-package-distributions
path: dist/
- name: Download all the dists
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ mrt/
docs/_build
docs/_static
docs/_templates
.ruff_cache
19 changes: 10 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ repos:
language_version: python3
exclude: ^(?:tests|docs|examples)/

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.1.5'
hooks:
- id: ruff
types_or: [python, pyi, jupyter]
args: [ --fix, --exit-non-zero-on-fix ]
exclude: ^(?:tests|docs|examples)/

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.3.3
hooks:
# Run the linter.
- id: ruff
types_or: [python, pyi, jupyter]
args: [--fix]
exclude: ^(?:tests|docs|examples)/

- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
- id: codespell
exclude: ^(?:tests|docs|examples)/
exclude: ^(?:tests|docs|examples|mirtorch/vendors)/
29 changes: 29 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,32 @@ Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

----------------------------- LICENSE for pytorch_wavelets----------------------------
This licence applies to any parts of this library which are novel in comparison
to the original DTCWT MATLAB toolbox written by Nick Kingsbury and Cian
Shaffrey. See the Provenance section of README.rst file for details on any further
restrictions of use. If you wish to use the DTCWT, you should read that license as well.
The DWT sections come under this license.

MIT License

Copyright (c) 2020 Fergal Cotter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A Py***Torch***-based differentiable ***I***mage ***R***econstruction ***T***ool

The work is inspired by [MIRT](https://github.com/JeffFessler/mirt), a well-acclaimed toolbox for medical imaging reconstruction.

The main objective is to facilitate rapid, data-driven image reconstruction using CPUs and GPUs through fast prototyping and iteration. Researchers can conveniently develop new model-based and learning-based methods (e.g., unrolled neural networks) with abstraction layers. The availability of auto-differentiation enables optimization of imaging protocols and reconstruction parameters using gradient methods.
The main objective is to facilitate rapid, data-driven medical image reconstruction using CPUs and GPUs, for fast prototyping. Researchers can conveniently develop new model-based and learning-based methods (e.g., unrolled neural networks) with abstraction layers. The availability of auto-differentiation enables optimization of imaging protocols and reconstruction parameters using gradient methods.

Documentation: https://mirtorch.readthedocs.io/en/latest/

Expand All @@ -16,7 +16,8 @@ Documentation: https://mirtorch.readthedocs.io/en/latest/
### Installation

We recommend to [pre-install `PyTorch` first](https://pytorch.org/).
To install the `MIRTorch` package, after cloning the repo, please try `pip install -e .`(one may modify the package locally with this option.)
Use `pip install mirtorch` to install.
To install the `MIRTorch` locally, after cloning the repo, please try `pip install -e .`(one may modify the package locally with this option.)

------

Expand All @@ -26,13 +27,13 @@ To install the `MIRTorch` package, after cloning the repo, please try `pip insta

The `LinearMap` class overloads common matrix operations, such as `+, - , *`.

Instances include basic linear operations (like convolution), classical imaging processing, and MRI system matrix (Cartesian and Non-Cartesian, sensitivity- and B0-informed system models). ***NEW!*** MIRTorch recently adds the support for SPPET and CT.
Instances include basic linear operations (like convolution), classical imaging processing, and MRI system matrix (Cartesian and Non-Cartesian, sensitivity- and B0-informed system models). ***NEW!*** MIRTorch recently adds the support for SPECT and CT.

Since the Jacobian matrix of a linear operator is itself, the toolbox can actively calculate such Jacobians during backpropagation, avoiding the large cache cost required by auto-differentiation.

When defining linear operators, please make sure that all torch tensors are on the same device and compatible. For example, `torch.cfloat` are compatible with `torch.float` but not `torch.double`. Similarly, `torch.chalf` is compatible with `torch.half`.
When the data is image, there are 2 empirical formats: `[num_batch, num_channel, nx, ny, (nz)]` and `[nx, ny, (nz)]`.
For some LinearMaps, there is a boolean `batchmode` to control it.
For some LinearMaps, there is a boolean `batchmode` to control the shape.

#### Proximal operators

Expand Down Expand Up @@ -81,7 +82,7 @@ This work is inspired by (but not limited to):

* PyLops: https://github.com/PyLops/pylops

If the code is useful to your research, please cite:
If the code is useful to your research, please consider citing:

```bibtex
@article{wang:22:bjork,
Expand All @@ -102,6 +103,7 @@ If the code is useful to your research, please cite:
year={2022}
}
```
If you use the SPECT code, please consider citing:

```bibtex
@ARTICLE{li:23:tet,
Expand Down
8 changes: 4 additions & 4 deletions mirtorch/alg/fbpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ def __init__(
h_prox: Prox,
g_L: float,
G_norm: float,
G: LinearMap = None,
tau: float = None,
G: LinearMap | None = None,
tau: float | None = None,
max_iter: int = 10,
eval_func: Callable = None,
eval_func: Callable | None = None,
p: int = 1,
):
self.max_iter = max_iter
Expand Down Expand Up @@ -87,7 +87,7 @@ def run(self, x0: torch.Tensor):
if self.eval_func is not None:
saved.append(self.eval_func(xold))
logger.info(
"The cost function at %dth iter in FBPD: %10.3e." % (i, saved[-1])
"The cost function at %dth iter in FBPD: %10.3e.", i, saved[-1]
)
if self.eval_func is not None:
return xold, saved
Expand Down
2 changes: 1 addition & 1 deletion mirtorch/alg/fista.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def _update_momentum():
beta = (told - 1) / tnew
told = tnew

# initalize parameters
# initialize parameters
xold = x0
yold = x0
told = 1.0
Expand Down
11 changes: 10 additions & 1 deletion mirtorch/linear/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
ConjTranspose,
BlockDiagonal,
Kron,
Vstack,
Hstack,
)
from .basics import (
Diff1d,
Expand All @@ -20,7 +22,7 @@
Patch3D,
Diffnd,
)
from .mri import FFTCn
from .mri import FFTCn, NuSense, NuSenseGram, Gmri, GmriGram, Sense
from .wavelets import Wavelet2D
from .spect import SPECT

Expand All @@ -46,4 +48,11 @@
"Patch3D",
"FFTCn",
"SPECT",
"NuSense",
"NuSenseGram",
"Gmri",
"GmriGram",
"Sense",
"Vstack",
"Hstack",
]
Loading

0 comments on commit 67b9a9b

Please sign in to comment.