Skip to content

Commit

Permalink
new framework
Browse files Browse the repository at this point in the history
  • Loading branch information
casperdcl committed Jun 14, 2024
1 parent cb60654 commit 15507b9
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 73 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: run
on:
push:
branches: ['**']
tags: ['**']
paths-ignore: ['LICENSE*', 'LICENCE*', 'README.md']
jobs:
check:
defaults: {run: {shell: 'bash -el {0}'}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: conda-incubator/setup-miniconda@v3
with: {mamba-version: "*", channels: conda-forge}
- name: Install dependencies
run: |
conda activate test
if test -f apt.txt; then
sudo apt-get update
xargs -a apt.txt sudo apt-get install -y
fi
if test -f environment.yml; then
conda install --file environment.yml
fi
if test -f requirements.txt; then
pip install -r requirements.txt
fi
- name: Test imports
run:
conda activate test
python <<EOF
from main import Submission
from cil.optimisation.algorithms import Algorithm
assert issubclass(Submission, Algorithm)
EOF
full:
if: startsWith(github.ref, 'refs/tags')
runs-on: [self-hosted, docker, cuda]
steps:
- uses: actions/checkout@v4
with: {fetch-depth: 0, submodules: recursive}
- run: petric
54 changes: 22 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
# SyneRBI Challenge

## TL;DR

The organisers will execute:

```python
test = main.Test("/some/private/input_patients_dir")
from main import Submission
assert issubclass(Submission, cil.optimisation.algorithms.Algorithm)
with Timeout(minutes=5):
test.run_all_patients("/some/private/output_patients_dir")
evaluate_metrics("/some/private/output_patients_dir")
Submission(data).run(np.inf, callbacks=metrics)
```

To avoid timing out, please disable any debugging/plotting code before submitting!

Layout:

- /challenge/
- input_patients_dir/
- patient_01/
- sinogram.npy
- reference.npy
- patient_02/
- ...
- output_patients_dir/
- patient_01/
- 000.npy
- 001.npy
- ...

Private (organiser) test machine:

- /$JOB_ID/
- input_patients_dir/
- patient_01/
- sinogram.npy
- output_patients_dir/
- patient_01/
- 000.npy
- /hidden/patients/reference/dir/
- patient_01/
- reference.npy
> [!WARNING]
> To avoid timing out, please disable any debugging/plotting code before submitting!
The organisers will have private versions of `data` and `metrics`.
Smaller test (public) versions of `data` and `metrics` are defined in the [`notebook.ipynb`](notebook.ipynb).

## Layout

Only [`main.py`](main.py) is required.
[SIRF](https://github.com/SyneRBI/SIRF), [CIL](https://github.com/TomographicImaging/CIL), and CUDA are already installed.
Additional dependencies may be specified via `apt.txt`, `environment.yml`, and/or `requirements.txt`.

- (required) `main.py`: must define a `class Submission(cil.optimisation.algorithms.Algorithm)`
- `notebook.ipynb`: can be used for experimenting. Runs `main.Submission()` on test `data` with basic `metrics`
- `apt.txt`: passed to `apt install`
- `environment.yml`: passed to `conda install`
- `requirements.txt`: passed to `pip install`
50 changes: 9 additions & 41 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,11 @@
from pathlib import Path, PurePath
from cil.optimisation.algorithms import GD

import numpy as np
from tqdm import trange
class Submission(GD):
def __init__(self, data, *args, **kwargs):
super().__init__(*args, **kwargs)
# Your code here
self.data = data


class PatientData:
def __init__(self, patient_dir: PurePath):
self.patient_dir = Path(patient_dir)
self.sinogram = np.random.random((252, 344, 344)) # TODO
self.image_size = (127, 344, 344) # TODO
self.image_reference = np.random.random(self.image_size) # TODO


class Test:
def __init__(self, input_patients_dir: PurePath):
self.input_patients_dir = Path(input_patients_dir)

def run_all_patients(self, output_patients_dir: PurePath | None = None):
for input_dir in self.input_patients_dir.glob("*/"):
output_dir = Path(output_patients_dir) / input_dir.name if output_patients_dir else None
self.run(input_dir, output_dir=output_dir)

def run(self, input_dir: PurePath, output_dir: PurePath | None = None, max_iterations=100):
data = PatientData(input_dir)
img = np.ones(data.image_size)
with trange(max_iterations) as t:
for iter in t:
img = self.reconstruct(data.sinogram, img)
if output_dir:
np.save(Path(output_dir) / f"{iter:03d}.npy", img)
nrmse = (((img - data.image_reference) ** 2).sum() / (data.image_reference ** 2).sum()) ** 0.5
t.set_postfix(nrmse=nrmse, refresh=False)

def reconstruct(self, sinogram: np.ndarray, image: np.ndarray) -> np.ndarray:
raise NotImplementedError("""TODO: write your code for 1 iteration here, e.g.
return image * backward(sinogram / (forward(image) + randoms_and_scatter)) / backward(np.ones_like(image))
""")


if __name__ == "__main__":
test = Test("input_patients_dir")
test.run_all_patients("output_patients_dir")
def update(self):
# Your code here
return super().update()

0 comments on commit 15507b9

Please sign in to comment.