Description
Summary
I am trying to write tests for nipype workflows, and I would like to use get_node()
to select nodes' outputs, rather than hardcoding paths to output files. However, I've noticed that the nodes' output_dir()
methods point to a subfolder in the TMPDIR
environment variable, rather than to subfolders in the workflow's base_dir
. It seems like this is a bug.
Tagging @mattcieslak as he's been helping me debug this.
Actual behavior
node = wf.get_node("write_string").output_dir()
points to temporary directory (/private/var/.../init_minimal_wf/write_string
).
Expected behavior
node = wf.get_node("write_string").output_dir()
would point to /some/absolute/path/init_minimal_wf/write_string
(the node's subfolder in base_dir
).
How to replicate the behavior
I wrote a minimal workflow with
"""A test workflow."""
import os
from nipype.interfaces import utility as niu
from nipype.pipeline import engine as pe
from nipype.interfaces.base import (
BaseInterfaceInputSpec,
File,
SimpleInterface,
TraitedSpec,
traits,
)
class _WriteStringInputSpec(BaseInterfaceInputSpec):
in_str = traits.Str(mandatory=True)
class _WriteStringOutputSpec(TraitedSpec):
out_file = File(exists=True)
class WriteString(SimpleInterface):
"""Write a string to a file."""
input_spec = _WriteStringInputSpec
output_spec = _WriteStringOutputSpec
def _run_interface(self, runtime):
self._results["out_file"] = os.path.join(runtime.cwd, "out_file.txt")
with open(self._results["out_file"], "w") as fo:
fo.write(self.inputs.in_str)
return runtime
def init_minimal_wf(
mem_gb=0.1,
omp_nthreads=1,
name="init_minimal_wf",
):
"""A minimal workflow to reproduce a bug."""
workflow = pe.Workflow(name=name)
inputnode = pe.Node(
niu.IdentityInterface(fields=["in_str"]),
name="inputnode",
)
outputnode = pe.Node(
niu.IdentityInterface(fields=["out_file"]),
name="outputnode",
)
write_string = pe.Node(
WriteString(),
mem_gb=mem_gb,
n_procs=omp_nthreads,
name="write_string",
)
# fmt:off
workflow.connect([
(inputnode, write_string, [("in_str", "in_str")]),
(write_string, outputnode, [("out_file", "out_file")]),
])
# fmt:on
return workflow
if __name__ == "__main__":
wf = init_minimal_wf()
wf.inputs.inputnode.in_str = "hello world"
wf.base_dir = "/some/absolute/path/" # *not* TMPDIR
wf.run()
node = wf.get_node("write_string")
print(node.output_dir()) # this *should* point to base_dir, but points to TMPDIR instead
Script/Workflow details
Please put URL to code or code here (if not too long).
Platform details:
{'commit_hash': '<not found>',
'commit_source': '(none found)',
'networkx_version': '2.8.8',
'nibabel_version': '3.2.1',
'nipype_version': '1.8.5',
'numpy_version': '1.24.1',
'pkg_path': '/opt/miniconda3/lib/python3.8/site-packages/nipype',
'scipy_version': '1.8.1',
'sys_executable': '/opt/miniconda3/bin/python',
'sys_platform': 'darwin',
'sys_version': '3.8.5 (default, Sep 4 2020, 02:22:02) \n[Clang 10.0.0 ]',
'traits_version': '6.3.2'}
Execution environment
My python environment outside container