From 8f54fadacfa63b31d9760ae69f7bac0988192afd Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Thu, 12 Dec 2024 14:17:02 -0500 Subject: [PATCH] Draft medic workflow test. --- sdcflows/interfaces/fmap.py | 2 +- sdcflows/workflows/fit/medic.py | 6 +- sdcflows/workflows/fit/tests/test_medic.py | 82 ++++++++++++++++++++++ 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 sdcflows/workflows/fit/tests/test_medic.py diff --git a/sdcflows/interfaces/fmap.py b/sdcflows/interfaces/fmap.py index d86bb112b4..255c4fa3e8 100644 --- a/sdcflows/interfaces/fmap.py +++ b/sdcflows/interfaces/fmap.py @@ -475,7 +475,7 @@ class _MEDICInputSpec(CommandLineInputSpec): class _MEDICOutputSpec(TraitedSpec): native_field_map = File( exists=True, - desc="4D ative (distorted) space field map in Hertz", + desc="4D native (distorted) space field map in Hertz", ) displacement_map = File( exists=True, diff --git a/sdcflows/workflows/fit/medic.py b/sdcflows/workflows/fit/medic.py index 343d282d30..7d6c5ecfab 100644 --- a/sdcflows/workflows/fit/medic.py +++ b/sdcflows/workflows/fit/medic.py @@ -59,7 +59,7 @@ def init_medic_wf(name="medic_wf"): Outputs ------- - fieldmap : :obj:`str` + fmap : :obj:`str` The path of the estimated fieldmap time series file. Units are Hertz. displacement : :obj:`list` of :obj:`str` Path to the displacement time series files. Units are mm. @@ -85,7 +85,7 @@ def init_medic_wf(name="medic_wf"): inputnode = pe.Node(niu.IdentityInterface(fields=INPUT_FIELDS), name="inputnode") outputnode = pe.Node( - niu.IdentityInterface(fields=["fieldmap", "displacement", "method"]), + niu.IdentityInterface(fields=["fmap", "displacement", "method"]), name="outputnode", ) outputnode.inputs.method = "MEDIC" @@ -119,7 +119,7 @@ def init_medic_wf(name="medic_wf"): (write_metadata, medic, [("out_file", "metadata")]), (phase2rad, medic, [("out_file", "phase_files")]), (medic, outputnode, [ - ("native_field_map", "fieldmap"), + ("native_field_map", "fmap"), ("displacement_map", "displacement"), ]), ]) # fmt:skip diff --git a/sdcflows/workflows/fit/tests/test_medic.py b/sdcflows/workflows/fit/tests/test_medic.py new file mode 100644 index 0000000000..6cf546af7d --- /dev/null +++ b/sdcflows/workflows/fit/tests/test_medic.py @@ -0,0 +1,82 @@ +# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- +# vi: set ft=python sts=4 ts=4 sw=4 et: +# +# Copyright 2021 The NiPreps Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# We support and encourage derived works from this project, please read +# about our expectations at +# +# https://www.nipreps.org/community/licensing/ +# +"""Test phase-difference type of fieldmaps.""" +from pathlib import Path +from json import loads + +import pytest + +from ..medic import init_medic_wf, Workflow + + +@pytest.mark.slow +def test_medic(tmpdir, datadir, workdir, outdir): + """Test creation of the workflow.""" + tmpdir.chdir() + + pattern = 'ds005250/sub-04/ses-2/func/*_part-mag_bold.nii.gz' + magnitude_files = sorted(datadir.glob(pattern)) + phase_files = [f.with_name(f.name.replace("part-mag", "part-phase")) for f in magnitude_files] + metadata_dicts = [ + loads(Path(f.name.replace('.nii.gz', '.json')).read_text()) for f in magnitude_files + ] + + wf = Workflow(name=f"medic_{magnitude_files[0].name.replace('.nii.gz', '').replace('-', '_')}") + medic_wf = init_medic_wf() + medic_wf.inputs.inputnode.magnitude = magnitude_files + medic_wf.inputs.inputnode.phase = phase_files + medic_wf.inputs.inputnode.metadata = metadata_dicts + + if outdir: + from ...outputs import init_fmap_derivatives_wf, init_fmap_reports_wf + + outdir = outdir / "unittests" / magnitude_files[0].split("/")[0] + fmap_derivatives_wf = init_fmap_derivatives_wf( + output_dir=str(outdir), + write_coeff=True, + bids_fmap_id="phasediff_id", + ) + fmap_derivatives_wf.inputs.inputnode.source_files = [str(f) for f in magnitude_files] + fmap_derivatives_wf.inputs.inputnode.fmap_meta = metadata_dicts + + fmap_reports_wf = init_fmap_reports_wf( + output_dir=str(outdir), + fmap_type='medic', + ) + fmap_reports_wf.inputs.inputnode.source_files = [str(f) for f in magnitude_files] + + wf.connect([ + (medic_wf, fmap_reports_wf, [ + ("outputnode.fmap", "inputnode.fieldmap"), + ]), + (medic_wf, fmap_derivatives_wf, [ + ("outputnode.fmap", "inputnode.fieldmap"), + ]), + ]) # fmt:skip + else: + wf.add_nodes([medic_wf]) + + if workdir: + wf.base_dir = str(workdir) + + wf.run(plugin="Linear")