Skip to content

Commit 79fe2b9

Browse files
refactor evaluation and reintroduce baseline docker workflow
1 parent 9c7b315 commit 79fe2b9

4 files changed

Lines changed: 61 additions & 6 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 Baseline Image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
paths:
8+
- "src/baseline/**"
9+
- ".github/workflows/baseline-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/baseline
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
47+
push: true
48+
tags: ${{ steps.meta.outputs.tags }}
49+
labels: ${{ steps.meta.outputs.labels }}

src/baseline/dataset.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44

55
def get_case_features(features_dir):
6+
"""Return all available model inputs for a case: NAC-PET, topogram, combined and chunked
7+
DIXON MRI (in/out-phase), MRI face mask, and metadata (sex, age, height, weight).
8+
These are everything a participant model may use to predict the pseudo-CT."""
69
paths = {
710
"nacpet": os.path.join(features_dir, "nacpet.nii.gz"),
811
"topogram": os.path.join(features_dir, "topogram.nii.gz"),
@@ -18,6 +21,8 @@ def get_case_features(features_dir):
1821

1922

2023
def get_case_ct_labels(ct_label_dir):
24+
"""Return label paths for a case. The target to predict is `ct` (Hounsfield Units),
25+
along with body/organ segmentations and a prediction mask."""
2126
return {
2227
"ct": os.path.join(ct_label_dir, "ct.nii.gz"),
2328
"body_seg": os.path.join(ct_label_dir, "body_seg.nii.gz"),
@@ -27,6 +32,7 @@ def get_case_ct_labels(ct_label_dir):
2732

2833

2934
def get_dataset(data_dir):
35+
"""Build a list of cases from a directory of subjects, each combining features and CT labels."""
3036
cases = []
3137
for sub in sorted(os.listdir(data_dir)):
3238
case_dir = os.path.join(data_dir, sub)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
)
2323

2424

25-
def evaluate_subject(subject_path, pred_pet_path=None, pred_ct_path=None):
25+
def evaluate_case(subject_path, pred_pet_path=None, pred_ct_path=None):
2626
"""
2727
Run metrics for a single subject.
2828
@@ -103,7 +103,7 @@ def main():
103103
if args.pred_pet is None and args.pred_ct is None:
104104
parser.error("At least one of --pred_pet or --pred_ct must be provided.")
105105

106-
results = evaluate_subject(args.subject_path, args.pred_pet, args.pred_ct)
106+
results = evaluate_case(args.subject_path, args.pred_pet, args.pred_ct)
107107

108108
print("\n================ Evaluation Results ================")
109109
print(f"Subject: {os.path.basename(args.subject_path)}")

src/evaluation/eval_dataset.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626

2727
import numpy as np
2828

29-
from eval import evaluate_subject
29+
from eval_case import evaluate_case
3030
from metrics import compute_brain_outlier_score
3131

3232

33-
def evaluate(dataset_path, pred_dir, subjects=None):
33+
def eval_dataset(dataset_path, pred_dir, subjects=None):
3434
"""
3535
Evaluate predictions across multiple subjects.
3636
@@ -70,7 +70,7 @@ def evaluate(dataset_path, pred_dir, subjects=None):
7070
pred_pet = os.path.join(pred_dir, subject_id, "pet.nii.gz")
7171
pred_ct = os.path.join(pred_dir, subject_id, "ct.nii.gz")
7272

73-
results = evaluate_subject(subject_path, pred_pet, pred_ct)
73+
results = evaluate_case(subject_path, pred_pet, pred_ct)
7474
per_subject[subject_id] = results
7575

7676
print(f" {subject_id}")
@@ -129,7 +129,7 @@ def main():
129129
)
130130
args = parser.parse_args()
131131

132-
evaluate(args.dataset_path, args.pred_dir, args.subjects)
132+
eval_dataset(args.dataset_path, args.pred_dir, args.subjects)
133133

134134

135135
if __name__ == "__main__":

0 commit comments

Comments
 (0)