Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions specs/australian-imaging-service/mri/phantoms/vial-signal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
schema_version: '2.0'
title: Phantom vial signal metrics
version: &package_version "0.1.7"
authors:
- name: Arkiev D'Souza
email: arkiev.dsouza@sydney.edu.au
- name: Thomas G. Close
email: tom.g.close@gmail.com
docs:
description: >-
End-to-end pydra workflow for processing a GSP SPIRIT or 120E phantom MRI
session.

Supports three processing stages:

Stage 1 — DWI preprocessing: automatic series classification and
phase-encoding correction mode selection (rpe_none, rpe_pair, rpe_all,
rpe_split), FSL dwifslpreproc, DWI bias correction, tensor fitting to
produce ADC and FA maps, and T1-to-DWI coregistration via FLIRT.

Stage 2 — Phantom QC in DWI space: iterative ANTs rigid registration of
the T1 (in DWI space) to the phantom template, inverse transform of vial
segmentations into DWI space, and per-vial ADC and FA metric extraction.

Stage 3 — Native contrast QC: registration of the T1 to the phantom
template, inverse transform of vial segmentations, and per-vial metric
extraction across all contrast images (T1, IR, TE). Generates
publication-quality scatter plots and parametric map plots.

All stages are invoked from a single command pointing at a DICOM session
directory; series classification and preprocessing mode selection are fully
automatic.
info_url: https://github.com/Australian-Imaging-Service/phantomkit
packages:
pip:
phantomkit: *package_version
pydra: 1.0a9
neurodocker:
dcm2niix: v1.0.20240202
mrtrix3: 3.0.4
ants: 2.6.2
fsl: 6.0.7.9
commands:
all_metrics:
operates_on: medimage/session
task: phantomkit.analyses.vial_signal:VialSignalAnalysis
pipeline:
operates_on: medimage/session
task: phantomkit.pipeline:run_pipeline
99 changes: 99 additions & 0 deletions tests/test_vial_signal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import json
import typing as ty
from pathlib import Path
from pydra2app.core.cli import make
from pydra2app.xnat import XnatApp
from frametree.core.utils import show_cli_trace
from pydra2app.xnat.deploy import install_and_launch_xnat_cs_command
from conftest import upload_test_dataset_to_xnat, test_data_dir

PKG_DIR = Path(__file__).parent.parent

SPEC_PATH = (
PKG_DIR
/ "specs"
/ "australian-imaging-service"
/ "mri"
/ "phantoms"
/ "vial-signal.yaml"
)

SKIP_BUILD = False


def test_vial_signal_app(
run_prefix: str,
xnat_connect: ty.Any,
cli_runner: ty.Callable[..., ty.Any],
tmp_path: Path,
):

build_dir = tmp_path / "build"

build_dir.mkdir(exist_ok=True, parents=True)

project_id = f"{run_prefix}qualitycontrolgspspirit"

test_data = test_data_dir / "specs" / "mri" / "phantoms" / "vial-signal"
upload_test_dataset_to_xnat(project_id, test_data, xnat_connect)

if SKIP_BUILD:
build_arg = "--generate-only"
else:
build_arg = "--build"

result = cli_runner(
make,
[
"xnat",
str(SPEC_PATH),
"--build-dir",
str(build_dir),
build_arg,
"--for-localhost",
"--use-local-packages",
"--raise-errors",
],
)

assert result.exit_code == 0, show_cli_trace(result)

image_spec = XnatApp.load(SPEC_PATH)

command_inputs = {
"all_metrics": {
"input_image": "foo_bar",
}
}

with xnat_connect() as xlogin:

for command_obj in image_spec.commands:
with open(build_dir / "xnat_commands" / (command_obj.name + ".json")) as f:
command_json = json.load(f)
command_json["name"] = command_json["label"] = (
image_spec.name + command_obj.name + run_prefix
)

test_xsession = next(iter(xlogin.projects[project_id].experiments.values()))

inputs_json = command_inputs[command_obj.name]
inputs_json["pydra2app_flags"] = (
"--worker debug "
"--work /work " # NB: work dir moved inside container due to file-locking issue on some mounted volumes (see https://github.com/tox-dev/py-filelock/issues/147)
"--dataset-name default "
"--logger frametree debug "
"--logger frametree-xnat debug "
"--logger pydra2app debug "
"--logger pydra2app-xnat debug "
)

workflow_id, status, out_str = install_and_launch_xnat_cs_command(
command_json=command_json,
project_id=project_id,
session_id=test_xsession.id,
inputs=inputs_json,
xlogin=xlogin,
timeout=30000,
)
assert status == "Complete", f"Workflow {workflow_id} failed.\n{out_str}"
Loading