Skip to content

Workflow's nodes' output directories point to TMPDIR instead of base_dir #3542

Open
niflows/nipype1-examples
#7
@tsalo

Description

@tsalo

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions