Skip to content

Commit acf90bb

Browse files
2 parents 33a0f16 + d2b62f4 commit acf90bb

9 files changed

Lines changed: 166 additions & 47 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build & Push Inference Image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
paths:
8+
- "src/baseline-inference/**"
9+
- ".github/workflows/inference-docker.yml"
10+
11+
jobs:
12+
build-push:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Log in to GHCR
23+
uses: docker/login-action@v3
24+
with:
25+
registry: ghcr.io
26+
username: ${{ github.actor }}
27+
password: ${{ secrets.GITHUB_TOKEN }}
28+
29+
- name: Extract metadata
30+
id: meta
31+
uses: docker/metadata-action@v5
32+
with:
33+
images: ghcr.io/bic-mac-challenge/inference
34+
tags: |
35+
type=semver,pattern={{version}}
36+
type=semver,pattern={{major}}.{{minor}}
37+
type=sha,prefix=sha-,format=short
38+
type=raw,value=latest,enable={{is_default_branch}}
39+
40+
- name: Set up Docker Buildx
41+
uses: docker/setup-buildx-action@v3
42+
43+
- name: Build and push
44+
uses: docker/build-push-action@v6
45+
with:
46+
context: src/baseline-inference
47+
push: true
48+
tags: ${{ steps.meta.outputs.tags }}
49+
labels: ${{ steps.meta.outputs.labels }}

README.md

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,19 @@
2727
Your algorithm receives the files under `features/` for each subject and must output a predicted CT volume as a NIfTI file in Hounsfield units (HU). Predictions are evaluated two ways:
2828

2929
1. **CT accuracy** — predicted CT is compared directly against the ground-truth CT
30-
2. **PET accuracy** — predicted CT is fed into the reconstruction pipeline to produce an attenuation-corrected PET (ACPET) image, which is then compared against the ground-truth PET
30+
2. **PET accuracy** — predicted CT is fed into the reconstruction pipeline to produce an attenuation-corrected PET image, which is then compared against the ground-truth PET
3131

32-
The dataset (100 subjects, Siemens Biograph Vision Quadra + MAGNETOM Vida) is split as follows:
32+
Note that no PET reconstruction experience is needed to participate in the challenge, and the main purpose of the reconstruction is to enable clinically meaningful metrics.
33+
34+
The dataset comprises 99 subject-unique cases, with 20 reserved for testing and the remaining 79 available on huggingface and split as follows:
3335

3436
| Split | Subjects | Contents |
3537
|-------|----------|----------|
3638
| `train/` (full) | 8 | `features/` + `ct-label/` + `recon/` + `pet-label/` |
37-
| `train/` (no recon) | 68 | `features/` + `ct-label/` |
39+
| `train/` (no recon) | 67 | `features/` + `ct-label/` |
3840
| `val/` | 4 | `features/` + `recon/` |
3941

40-
All train subjects have CT labels. The 8 fully-equipped subjects additionally include sinogram data and PET labels, enabling closed-loop local evaluation. Validation subjects have sinogram data but no labels — submit reconstructed PET to Codabench.
42+
All train cases have CT labels, but due to the size of the sinograms, only 8 include the recon and pet-label folders needed for closed loop reconstruction. Validation subjects have sinogram data but no labels — submit predicted CTs and reconstructed PET to Codabench to get live leaderboard metrics throughout the challenge.
4143

4244
---
4345

@@ -75,38 +77,34 @@ uv sync
7577
---
7678

7779
## 🗂️ Data Format
78-
80+
All images are resampled to the label CT image (tensor size: 512x512x531, voxel size 1.52x1.52,2.00mm^3) and structured in four folders per case.
81+
- `features/` All the files you can use as input to your generative CT model at inference.
82+
-
7983
```
84+
85+
8086
train/
8187
└── sub-000/
82-
├── features/ # model inputs (all subjects)
83-
│ ├── nacpet.nii.gz # non-attenuation-corrected PET
84-
│ ├── topogram.nii.gz # 2D scout X-ray resampled to CT grid
85-
│ ├── mri_chunk_0_in_phase.nii.gz # DIXON MRI bed position 0, in-phase
86-
│ ├── mri_chunk_0_out_phase.nii.gz # DIXON MRI bed position 0, out-of-phase
87-
│ ├── mri_chunk_1_in_phase.nii.gz # ... (chunks 0–3 for each phase)
88-
│ ├── mri_chunk_1_out_phase.nii.gz
89-
│ ├── mri_chunk_2_in_phase.nii.gz
90-
│ ├── mri_chunk_2_out_phase.nii.gz
91-
│ ├── mri_chunk_3_in_phase.nii.gz
92-
│ ├── mri_chunk_3_out_phase.nii.gz
93-
│ ├── mri_combined_in_phase.nii.gz # stitched whole-body MRI, in-phase
94-
│ ├── mri_combined_out_phase.nii.gz # stitched whole-body MRI, out-of-phase
95-
│ ├── mri_face_mask.nii.gz # binary face mask in MRI space
88+
├── features/ # generative model inputs
89+
│ ├── nacpet.nii.gz # non-attenuation-corrected PET.
90+
│ ├── topogram.nii.gz # 2D scout X-ray
91+
│ ├── mri_chunk_{0-3}_{in/out}_phase.nii.gz # DIXON MRI bed position (0-3), in-phase and out-phase
92+
│ ├── mri_combined_{in/out}_phase.nii.gz # stitched whole-body MRI, out-of-phase
93+
│ ├── mri_face_mask.nii.gz # binary anonymization mask
9694
│ └── metadata.json # {sex, age, height, weight}
97-
├── ct-label/ # ground-truth CT (train only)
98-
│ ├── ct.nii.gz # anonymized CT in HU
99-
│ ├── body_seg.nii.gz # multi-class body segmentation
100-
│ ├── organ_seg.nii.gz # TotalSegmentator organ labels
101-
│ └── prediction_mask.nii.gz # binary mask: 1 where predictions are evaluated (excludes face + scanner bed)
102-
├── recon/ # sinogram data (labeled train + val)
103-
│ ├── mult_nac_rd85.hs/.s # multiplicative correction sinogram
104-
│ ├── add_nac_rd85.hs/.s # additive correction sinogram (scatter + randoms)
105-
│ ├── prompts_rd85.hs/.s # prompt (raw) sinogram
95+
├── ct-label/ # ground-truth CT
96+
│ ├── ct.nii.gz # in HU this is what your algorithm should predict
97+
│ ├── body_seg.nii.gz # TotalSegmentator body seg.
98+
│ ├── organ_seg.nii.gz # TotalSegmentator organ seg.
99+
│ └── prediction_mask.nii.gz # The generative model should focus only on these voxels (face + scanner are excluded)
100+
├── recon/ # sinogram data
101+
│ ├── mult_nac_rd85.hs/.s # multiplicative sinogram
102+
│ ├── add_nac_rd85.hs/.s # additive sinogram
103+
│ ├── prompts_rd85.hs/.s # raw sinogram
106104
│ ├── offset.json # bed position and gantry offset
107-
│ ├── ct_face_and_bed.nii.gz # GT CT values at face + scanner bed (for swap-back)
105+
│ ├── ct_face_and_bed.nii.gz # GT CT values at face + scanner bed (automatically superimposed on your prediction before reconstruction)
108106
│ └── face_and_bed_mask.nii.gz # binary face + scanner bed mask
109-
└── pet-label/ # ground-truth PET (labeled train only)
107+
└── pet-label/ # ground-truth PET
110108
├── pet.nii.gz # CT-attenuation-corrected PET (reference)
111109
├── body_seg.nii.gz # body mask in PET space
112110
└── organ_seg.nii.gz # organ labels in PET space
@@ -129,6 +127,54 @@ python src/baseline/model.py data/sub-000/features/ results/sub-000/ct_pred.nii.
129127
```
130128

131129
---
130+
## 🐳 Inference Docker (`src/baseline-inference/`)
131+
132+
To simplify reproducibility and submission, the baseline model is also provided as a **fully self-contained Docker image**. This container wraps the same baseline UNet model and runs inference directly from the command line.
133+
134+
This Docker image should be considered the **official baseline submission** — participants are expected to improve upon it.
135+
136+
### 📦 Pull Image
137+
138+
```bash
139+
docker pull ghcr.io/bic-mac-challenge/inference:latest
140+
```
141+
142+
### ▶️ Run Inference
143+
144+
```bash
145+
docker run --rm \
146+
--gpus all \
147+
-v /absolute/path/to/data:/data \
148+
ghcr.io/bic-mac-challenge/inference:latest \
149+
--input /data/sub-XXX/features/nacpet.nii.gz \
150+
--output /data/sub-XXX/pseudo_ct.nii.gz
151+
```
152+
153+
### 📁 Input
154+
155+
* Expects NAC-PET input (`nacpet.nii.gz`)
156+
* Path must be mounted into the container (e.g., `/data`)
157+
158+
### 📁 Output
159+
160+
* Writes predicted CT (in HU) to the specified output path
161+
162+
### ⚙️ Notes
163+
164+
* All model weights and dependencies are **baked into the container**
165+
* No internet access is required at runtime
166+
* Designed to be **fully compliant with challenge submission requirements**
167+
* Serves as a **reference baseline for participants**
168+
169+
### 🧠 Relation to Baseline Code
170+
171+
This container directly wraps the implementation in:
172+
173+
```
174+
src/baseline/
175+
```
176+
177+
with identical preprocessing, model architecture, and inference logic.
132178

133179
## ⚙️ Reconstruction Pipeline (`src/recon/`)
134180

File renamed without changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
services:
2+
recon:
3+
image: ghcr.io/bic-mac-challenge/inference:latest
File renamed without changes.
File renamed without changes.

src/baseline/v2/inference/docker/readme.md renamed to src/baseline-inference/readme.md

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
# 🧠 Pseudo-CT Inference Docker
1+
# 🧠 Baseline Inference Docker (Pseudo-CT)
22

3-
This repository provides a **Dockerized inference pipeline** for generating pseudo-CT images from NAC PET input using a trained 3D U-Net model.
3+
This repository provides a **Dockerized baseline inference pipeline** for generating pseudo-CT images from NAC PET input using a trained 3D U-Net model.
4+
5+
This container corresponds to the **official baseline model** of the BIC-MAC challenge.
46

57
---
68

79
## 🚀 Features
810

911
* ✅ GPU-accelerated inference (CUDA)
1012
* ✅ Sliding window inference (overlap = 0.75)
11-
* ✅ PET-only input
13+
* ✅ PET-only input (baseline setting)
1214
* ✅ Outputs CT in Hounsfield Units (HU)
1315
* ✅ Clean CLI interface
1416
* ✅ Runtime + inference timing logs
17+
* ✅ Fully self-contained (no external downloads)
1518

1619
---
1720

@@ -23,32 +26,32 @@ This repository provides a **Dockerized inference pipeline** for generating pseu
2326

2427
---
2528

26-
## 🏗️ Build Docker Image
27-
28-
Navigate to the docker directory:
29+
## 📦 Pull Prebuilt Image (Recommended)
2930

3031
```bash
31-
cd inference/docker
32+
docker pull ghcr.io/bic-mac-challenge/inference:latest
3233
```
3334

34-
Build the image:
35+
---
36+
37+
## 🏗️ Build Docker Image (Optional)
38+
39+
If you want to build locally:
3540

3641
```bash
37-
docker build -t pseudoct .
42+
docker build -t ghcr.io/bic-mac-challenge/inference:latest .
3843
```
3944

4045
---
4146

4247
## ▶️ Run Inference
4348

44-
### 🔹 Basic Usage
45-
4649
```bash
4750
docker run --rm \
4851
--gpus all \
4952
--user $(id -u):$(id -g) \
5053
-v /absolute/path/to/data:/data \
51-
pseudoct \
54+
ghcr.io/bic-mac-challenge/inference:latest \
5255
--input /data/sub-XXX/features/nacpet.nii.gz \
5356
--output /data/sub-XXX/pseudo_ct.nii.gz
5457
```
@@ -116,6 +119,14 @@ Otherwise inference will run on CPU.
116119

117120
---
118121

122+
### 🔸 Self-contained Model
123+
124+
* All model weights are **baked into the container**
125+
* No internet access is required
126+
* Suitable for **offline evaluation environments (e.g., Codabench)**
127+
128+
---
129+
119130
## ⏱️ Output Logs
120131

121132
Example output:
@@ -136,7 +147,7 @@ Saved: /data/sub-XXX/pseudo_ct.nii.gz
136147
```bash
137148
docker run --rm -it \
138149
-v /your/data:/data \
139-
pseudoct bash
150+
ghcr.io/bic-mac-challenge/inference:latest bash
140151

141152
ls /data
142153
```
@@ -157,9 +168,19 @@ inside `inference.py`.
157168

158169
## 📌 Summary
159170

160-
| Step | Command |
161-
| ----- | -------------------------------------------------- |
162-
| Build | `docker build -t pseudoct .` |
163-
| Run | `docker run ... pseudoct --input ... --output ...` |
171+
| Step | Command |
172+
| ---- | ---------------------------------------------------- |
173+
| Pull | `docker pull ghcr.io/bic-mac-challenge/inference` |
174+
| Run | `docker run ... ghcr.io/bic-mac-challenge/inference` |
164175

165176
---
177+
178+
## 🧠 Relation to Challenge
179+
180+
This container represents the **baseline pseudo-CT model** provided in:
181+
182+
```
183+
src/baseline/
184+
```
185+
186+
Participants are expected to **build upon and improve this baseline** using additional modalities such as MRI and topogram.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)