diff --git a/.gitignore b/.gitignore index ff31314..b57b697 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,4 @@ .DS_Store -*/.DS_Store -*/*/.DS_Store -*/*/*/.DS_Store -*/.DS_Store -*/*/*/*/.DS_Store -*/*/*/*/*/.DS_Store - # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/pydra/tasks/fsl/_version.py b/pydra/tasks/fsl/_version.py new file mode 100644 index 0000000..c519089 --- /dev/null +++ b/pydra/tasks/fsl/_version.py @@ -0,0 +1,4 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +__version__ = version = '0.1.dev123+gd6b46a1.d20230502' +__version_tuple__ = version_tuple = (0, 1, 'dev123', 'gd6b46a1.d20230502') diff --git a/pydra/tasks/fsl/utils/split.py b/pydra/tasks/fsl/utils/split.py index 7a2d63c..cc001c6 100644 --- a/pydra/tasks/fsl/utils/split.py +++ b/pydra/tasks/fsl/utils/split.py @@ -2,6 +2,14 @@ from pydra import ShellCommandTask import typing as ty + +def Split_output(inputs): + import os, glob + + output_dir = os.getcwd() + return sorted(glob.glob(os.path.join(output_dir, f"{inputs.output_basename}*.*"))) + + input_fields = [ ( "in_file", @@ -14,9 +22,9 @@ }, ), ( - "out_base_name", + "output_basename", str, - {"help_string": "outputs prefix", "argstr": "{out_base_name}", "position": 1}, + {"help_string": "outputs prefix", "argstr": "{output_basename}", "position": 1}, ), ( "dimension", @@ -31,13 +39,34 @@ ] Split_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) -output_fields = [] +output_fields = [ + ( + "out_files", + specs.MultiOutputFile, + { + "help_string": "output files", + "requires": ["in_file", "output_basename", "dimension"], + "callable": Split_output, + }, + ) +] Split_output_spec = specs.SpecInfo( name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) ) class Split(ShellCommandTask): + """ + Example + ------- + >>> task = Split() + >>> task.inputs.in_file = "test.nii.gz" + >>> task.inputs.output_basename = "test_split" + >>> task.inputs.dimension = "t" + >>> task.cmdline + 'fslsplit test.nii.gz test_split -t' + """ + input_spec = Split_input_spec output_spec = Split_output_spec executable = "fslsplit" diff --git a/pydra/tasks/fsl/utils/tests/test_run_split.py b/pydra/tasks/fsl/utils/tests/test_run_split.py index 204ccfe..970a85e 100644 --- a/pydra/tasks/fsl/utils/tests/test_run_split.py +++ b/pydra/tasks/fsl/utils/tests/test_run_split.py @@ -4,7 +4,19 @@ @pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) +@pytest.mark.parametrize( + "inputs, outputs", + [ + ( + { + "in_file": "test.nii.gz", + "output_basename": "test_split", + "dimension": "t", + }, + ["out_files"], + ) + ], +) def test_Split(test_data, inputs, outputs): if inputs is None: in_file = Path(test_data) / "test.nii.gz" @@ -39,34 +51,3 @@ def test_Split(test_data, inputs, outputs): assert [os.path.exists(x) for x in getattr(res.output, out_nm)] else: assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_Split_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Split(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Split(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_split.py b/pydra/tasks/fsl/utils/tests/test_spec_split.py index a07fea1..af3704b 100644 --- a/pydra/tasks/fsl/utils/tests/test_spec_split.py +++ b/pydra/tasks/fsl/utils/tests/test_spec_split.py @@ -3,7 +3,19 @@ from ..split import Split -@pytest.mark.parametrize("inputs, outputs", []) +@pytest.mark.parametrize( + "inputs, outputs", + [ + ( + { + "in_file": "test.nii.gz", + "output_basename": "test_split", + "dimension": "t", + }, + ["out_files"], + ) + ], +) def test_Split(test_data, inputs, outputs): if inputs is None: in_file = Path(test_data) / "test.nii.gz" @@ -31,34 +43,3 @@ def test_Split(test_data, inputs, outputs): pass task = Split(**inputs) assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_Split_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Split(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Split(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/specs/callables.py b/specs/callables.py index 10aff6e..44240cf 100644 --- a/specs/callables.py +++ b/specs/callables.py @@ -392,13 +392,20 @@ def MELODIC_output(field, inputs): return outputs -def SLICE_output(inputs): - import glob +# def SLICE_output(inputs): +# import glob - suffix = "slice_*" - if inputs.out_base_name: - fname_template = f"{inputs.out_base_name}_{suffix}" - else: - fname_template = f"{inputs.in_file}_{suffix}" +# suffix = "slice_*" +# if inputs.out_base_name: +# fname_template = f"{inputs.out_base_name}_{suffix}" +# else: +# fname_template = f"{inputs.in_file}_{suffix}" + +# return sorted(glob(fname_template)) + + +def Split_output(inputs): + import os, glob - return sorted(glob(fname_template)) + output_dir = os.getcwd() + return sorted(glob.glob(os.path.join(output_dir, f"{inputs.output_basename}*.*"))) diff --git a/specs/fsl_utils_param.yml b/specs/fsl_utils_param.yml index 3eb94e1..f62cc9f 100644 --- a/specs/fsl_utils_param.yml +++ b/specs/fsl_utils_param.yml @@ -332,13 +332,21 @@ Smooth: Split: output_requirements: - out_file: [in_file, dimension] - output_templates: + out_files: [in_file, output_basename, dimension] + output_callables: + out_files: Split_output doctest: + in_file: test.nii.gz + output_basename: test_split + dimension: t + cmdline: fslsplit test.nii.gz test_split -t + tests_inputs: - - + - in_file: test.nii.gz + output_basename: test_split + dimension: t tests_outputs: - - AttributeError + - out_files SwapDimensions: output_requirements: