Skip to content

Commit b1fd5e3

Browse files
committed
Merge branch 'simple-svg-report' of github.com:openneuropet/petdeface into simple-svg-report
2 parents 289fe36 + 8572326 commit b1fd5e3

33 files changed

+5218
-119
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Check Python Compatibility
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
jobs:
10+
test-python-compatibility:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.10", "3.11", "3.12", "3.13"]
15+
toolchain: [uv, pip]
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Python ${{ matrix.python-version }}
22+
uses: actions/setup-python@v4
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
26+
- name: Install UV
27+
if: matrix.toolchain == 'uv'
28+
uses: astral-sh/setup-uv@v2
29+
with:
30+
version: "latest"
31+
32+
- name: Build package with ${{ matrix.toolchain }}
33+
if: matrix.toolchain == 'uv'
34+
run: |
35+
uv build
36+
ls -lh dist/
37+
38+
- name: Build package with ${{ matrix.toolchain }}
39+
if: matrix.toolchain == 'pip'
40+
run: |
41+
python -m pip install --upgrade pip build
42+
python -m build
43+
ls -lh dist/
44+
45+
- name: Install package with ${{ matrix.toolchain }}
46+
if: matrix.toolchain == 'uv'
47+
run: |
48+
uv pip install --system dist/*.whl
49+
uv run python -c "import petdeface; print('Package installed successfully')"
50+
51+
- name: Test CLI
52+
if: matrix.toolchain == 'uv'
53+
run: |
54+
uv run petdeface --help
55+
56+
- name: Install package with ${{ matrix.toolchain }}
57+
if: matrix.toolchain == 'pip'
58+
run: |
59+
python -m pip install dist/*.whl
60+
python -c "import petdeface; print('Package installed successfully')"
61+
62+
- name: Test CLI
63+
if: matrix.toolchain == 'pip'
64+
run: |
65+
petdeface --help

.github/workflows/petdeface.yaml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,28 @@ jobs:
1313
test_petdeface:
1414
runs-on: ubuntu-latest
1515
name: Test petdeface
16+
strategy:
17+
matrix:
18+
toolchain: [uv, pip]
1619
steps:
1720
- uses: actions/checkout@v3
18-
- name: Install Poetry
19-
run: pipx install poetry
2021
- uses: actions/setup-python@v4
2122
with:
2223
python-version: 3.11
23-
cache: poetry
24-
- run: poetry install
25-
- name: Run All Tests
26-
run: poetry run make testall
24+
- name: Install dependencies (UV)
25+
if: matrix.toolchain == 'uv'
26+
run: |
27+
curl -LsSf https://astral.sh/uv/install.sh | sh
28+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
29+
uv sync --dev
30+
- name: Install dependencies (pip)
31+
if: matrix.toolchain == 'pip'
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install .[dev]
35+
- name: Run All Tests (UV)
36+
if: matrix.toolchain == 'uv'
37+
run: uv run make testall
38+
- name: Run All Tests (pip)
39+
if: matrix.toolchain == 'pip'
40+
run: make testall
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- '**'
7+
workflow_call:
8+
workflow_dispatch:
9+
inputs:
10+
debug_enabled:
11+
type: boolean
12+
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
13+
required: false
14+
default: false
15+
16+
env:
17+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN_PETDEFACE }}
18+
19+
jobs:
20+
publish:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v3
24+
- uses: actions/setup-python@v4
25+
with:
26+
python-version: 3.11
27+
- name: Build Package
28+
run: |
29+
curl -LsSf https://astral.sh/uv/install.sh | sh
30+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
31+
uv sync --dev
32+
uv build
33+
34+
- name: Check PyPI token
35+
run: |
36+
if [ -z "$PYPI_TOKEN" ]; then
37+
echo "Error: PYPI_TOKEN_PETDEFACE is not set or is empty check your secrets"
38+
exit 1
39+
fi
40+
41+
- name: Publish Package
42+
run: |
43+
uv publish --token $PYPI_TOKEN

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44

55
# ignore virtualenv
66
venv/
7+
.venv/
78

89
# ignore pycache
910
__pycache__/
1011

1112
# ignore dist
1213
dist/
1314

15+
# ignore egg-info
16+
petdeface.egg-info/
17+
1418
# nipype generates pickle files, we need to redirect where it stores them,
1519
# but until then hack fix
1620
*.pkl

.readthedocs.yaml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,27 @@
22
# Read the Docs configuration file
33
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
44

5-
# Required
65
version: 2
76

8-
# Set the OS, Python version and other tools you might need
7+
# Build environment
98
build:
109
os: ubuntu-22.04
1110
tools:
1211
python: "3.12"
13-
jobs:
14-
post_create_environment:
15-
- pip install poetry
16-
- poetry config virtualenvs.create false
17-
post_install:
18-
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with=dev
12+
13+
# Python environment setup
14+
python:
15+
install:
16+
- method: pip
17+
path: .
18+
extra_requirements:
19+
- dev
1920

2021
# Build documentation in the "docs/" directory with Sphinx
2122
sphinx:
22-
configuration: docs/conf.py
23+
configuration: docs/conf.py
2324

2425
# Optionally build your docs in additional formats such as PDF and ePub
2526
# formats:
2627
# - pdf
2728
# - epub
28-
29-
# Optional but recommended, declare the Python requirements required
30-
# to build your documentation
31-
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
32-
# python:
33-
# install:
34-
# - requirements: docs/requirements.txt

README.md

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ This software can be installed via source or via pip from PyPi with `pip install
1414
|---------| ------ |
1515
| `docker build . -t petdeface` | ![docker_build](https://codebuild.us-east-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiYzdXV0tYSkQzTVNkcG04cHA2S055UXlKRlZTU1VONThUMVRoZVcwU3l1aHFhdVBlNDNaRGVCYzdWM1Q0WjYzQ1lRU2ZTSHpmSERPWFRkVXVyb3k3RTZBPSIsIml2UGFyYW1ldGVyU3BlYyI6IjRCZFFIQnNGT2lKcDA1VG4iLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=main) |
1616
| `docker push` | ![docker push icon](https://codebuild.us-east-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoia0c1bEJYUGI2SXlWYi9JMm1tcGtiYWVTdVd3bmlnOUFaTjN4QjJITU5PTVpvQnN3TlowajhxNmhHY2RwQ2Z5SU93OExqc2xvMzFnTHFvajlqVk1MV2FzPSIsIml2UGFyYW1ldGVyU3BlYyI6Ikl6SzRyc1RabzBnSkplTjciLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=main) |
17+
| `Python 3.14 >= 3.10` | [![Check Python Compatibility](https://github.com/openneuropet/petdeface/actions/workflows/check_python_compatibility.yaml/badge.svg)](https://github.com/openneuropet/petdeface/actions/workflows/check_python_compatibility.yaml) |
18+
| `packaging` | [![Publish to PyPI](https://github.com/openneuropet/petdeface/actions/workflows/publish_to_pypi.yaml/badge.svg)](https://github.com/openneuropet/petdeface/actions/workflows/publish_to_pypi.yaml) |
19+
| `Docs` | ![RTD BADGE](https://app.readthedocs.org/projects/petdeface/badge/?version=latest&style=default) |
1720

1821
## Requirements
1922

@@ -36,9 +39,9 @@ This software can be installed via source or via pip from PyPi with `pip install
3639

3740
```bash
3841
usage: petdeface.py [-h] [--anat_only] [--participant_label PARTICIPANT_LABEL [PARTICIPANT_LABEL ...]] [--docker] [--singularity] [--n_procs N_PROCS]
39-
[--skip_bids_validator] [--version] [--placement PLACEMENT] [--remove_existing] [--preview_pics]
42+
[--skip_bids_validator] [--version] [--placement PLACEMENT] [--remove_existing]
4043
[--participant_label_exclude participant_label_exclude [participant_label_exclude ...]] [--session_label SESSION [SESSION ...]]
41-
[--session_label_exclude session_label_exclude [session_label_exclude ...]]
44+
[--session_label_exclude session_label_exclude [session_label_exclude ...]] [--open_browser]
4245
bids_dir [output_dir] [analysis_level]
4346

4447
PetDeface
@@ -63,15 +66,18 @@ options:
6366
Where to place the defaced images. Options are 'adjacent': next to the bids_dir (default) in a folder appended with _defaced'inplace':
6467
defaces the dataset in place, e.g. replaces faced PET and T1w images w/ defaced at bids_dir'derivatives': does all of the defacing within
6568
the derivatives folder in bids_dir.
66-
--remove_existing, -r
67-
Remove existing output files in output_dir.
68-
--preview_pics Create preview pictures of defacing, defaults to false for docker
69+
--remove_existing, -r Remove existing output files in output_dir.
70+
--preview_pics Create preview pictures of defacing, defaults to false for docker (only works if FreeView is installed on machine)
6971
--participant_label_exclude participant_label_exclude [participant_label_exclude ...]
7072
Exclude a subject(s) from the defacing workflow. e.g. --participant_label_exclude sub-01 sub-02
7173
--session_label SESSION [SESSION ...]
7274
Select only a specific session(s) to include in the defacing workflow
7375
--session_label_exclude session_label_exclude [session_label_exclude ...]
7476
Select a specific session(s) to exclude from the defacing workflow
77+
--use_template_anat Use template anatomical image when no T1w is available for PET scans.
78+
Options: 't1' (included T1w template), 'mni' (MNI template), or 'pet'
79+
(averaged PET image).
80+
--open_browser Open browser to show QA reports after completion
7581
```
7682
7783
Working example usage:
@@ -80,6 +86,26 @@ Working example usage:
8086
petdeface /inputfolder /outputfolder --n_procs 16 --skip_bids_validator --placement adjacent
8187
```
8288
89+
### Template Anatomical Images
90+
91+
When PET scans lack corresponding T1w anatomical images, PETdeface can use template anatomical images for registration and defacing. Three options are available:
92+
93+
- **`--use_template_anat t1`**: Uses a T1w template included with the PETdeface library
94+
- **`--use_template_anat mni`**: Uses the MNI standard brain template
95+
- **`--use_template_anat pet`**: Creates a template by averaging the PET data across time
96+
97+
**Important**: When using template anatomical images, it's crucial to validate the defacing quality. Inspect the output using the generated HTML report (with `--open_browser`) or a NIfTI viewer to ensure the defacing is valid for your data.
98+
99+
**Recommended workflow for subjects missing T1w images**:
100+
1. First, exclude subjects missing T1w using `--participant_label_exclude`
101+
2. Run defacing on subjects with T1w images
102+
3. Then run defacing separately on subjects missing T1w using `--participant_label` and test different templates (`t1`, `mni`, `pet`) to determine which works best for your data
103+
104+
Example usage with template anatomical:
105+
```bash
106+
petdeface /inputfolder /outputfolder --use_template_anat t1 --n_procs 16
107+
```
108+
83109
### Docker Usage
84110

85111
Requirements:
@@ -138,12 +164,27 @@ trouble running this container in singularity/apptainer.
138164
139165
## Development
140166
141-
This project uses poetry to package and build, to create a pip installable version of the package run:
167+
This project supports both [UV](https://github.com/astral-sh/uv) and standard Python (pip + build) workflows for development and packaging.
168+
169+
### Using UV (recommended for speed)
170+
171+
```bash
172+
git clone https://github.com/openneuropet/petdeface.git
173+
cd petdeface
174+
uv build
175+
pip install dist/petdeface-<X.X.X>-py3-none-any.whl # where X.X.X is the version number of the generated file
176+
```
177+
178+
### Using pip and python (no UV required)
142179
143180
```bash
144181
git clone https://github.com/openneuropet/petdeface.git
145182
cd petdeface
146-
poetry build
183+
pip install --upgrade pip
184+
pip install .[dev]
185+
# To build a wheel or sdist:
186+
pip install build
187+
python -m build
147188
pip install dist/petdeface-<X.X.X>-py3-none-any.whl # where X.X.X is the version number of the generated file
148189
```
149190
-26 MB
Binary file not shown.
-26 MB
Binary file not shown.

docs/installation.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,22 @@ PETdeface can be installed via PyPi_::
99

1010
pip install petdeface
1111

12-
Or cloned and installed from source::
12+
Or cloned and installed from source (using UV)::
1313

1414
git clone https://github.com/openneuropet/petdeface.git
1515
cd petdeface
16-
poetry build
16+
uv build
17+
pip install dist/petdeface-<X.X.X>-py3-none-any.whl
18+
# where X.X.X is the version number of the generated file
19+
20+
Or cloned and installed from source (using pip and python)::
21+
22+
git clone https://github.com/openneuropet/petdeface.git
23+
cd petdeface
24+
pip install --upgrade pip
25+
pip install .[dev]
26+
pip install build
27+
python -m build
1728
pip install dist/petdeface-<X.X.X>-py3-none-any.whl
1829
# where X.X.X is the version number of the generated file
1930

docs/usage.rst

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ options:
123123
Select only a specific session(s) to include in the defacing workflow
124124
--session_label_exclude session_label_exclude [session_label_exclude ...]
125125
Select a specific session(s) to exclude from the defacing workflow
126+
--use_template_anat Use template anatomical image when no T1w is available for PET scans.
127+
Options: 't1' (included T1w template), 'mni' (MNI template), or 'pet'
128+
(averaged PET image).
129+
--open_browser Following defacing this flag will open the browser to view the defacing results
126130

127131
Docker Based
128132
------------
@@ -174,4 +178,31 @@ PETdeface will do it's best to locate a valid FreeSurfer license file on the hos
174178
to the container by checking `FREESURFER_HOME` and `FREESURFER_LICENSE` environment variables. If you
175179
receive an error message relating to the FreeSurfer license file, try setting and exporting the
176180
`FREESURFER_LICENSE` environment variable to the location of the FreeSurfer license file on the host
177-
machine.
181+
machine.
182+
183+
Template Anatomical Images
184+
-------------------------
185+
186+
When PET scans lack corresponding T1w anatomical images, PETdeface can use template anatomical images for
187+
registration and defacing. Three options are available:
188+
189+
- **`--use_template_anat t1`**: Uses a T1w template included with the PETdeface library
190+
- **`--use_template_anat mni`**: Uses the MNI standard brain template
191+
- **`--use_template_anat pet`**: Creates a template by averaging a subjects PET image and using that averaged image in place of a T1 image
192+
193+
**Important**: When using template anatomical images, it's crucial to validate the defacing quality.
194+
Inspect the output using the generated HTML report (with `--open_browser`) or a NIfTI viewer to ensure
195+
the defacing is valid for your data.
196+
197+
**Recommended workflow for subjects missing T1w images**:
198+
199+
1. First, exclude subjects missing T1w using `--participant_label_exclude`
200+
2. Run defacing on subjects with T1w images
201+
3. Then run defacing separately on subjects missing T1w using `--participant_label` and test
202+
different templates (`t1`, `mni`, `pet`) to determine which works best for your data
203+
204+
Example usage with template anatomical:
205+
206+
.. code-block:: bash
207+
208+
petdeface /inputfolder /outputfolder --use_template_anat t1 --n_procs 16

0 commit comments

Comments
 (0)