nipype icon indicating copy to clipboard operation
nipype copied to clipboard

MCFLIRT naming error with FSL 6.0.7.13

Open b1060t opened this issue 1 year ago • 3 comments
trafficstars

Summary

I'm walking through miykael's tutorial and found the output of mcflirt could not be correctly recognized:

FileNotFoundError: No such file or directory '/xxx/working_dir/preprocWF/mcflirt/sub-01_ses-test_task-fingerfootlips_bold_mcf_mean_reg.nii.gz' for output 'mean_img' of a MCFLIRT interface

and the real output name of mcflirt was sub-01_ses-test_task-fingerfootlips_bold_mcf.nii.gz_mean_reg.nii.gz. I think this issue should have been resolved after referring to a previous commit.

By simply replacing this line with the hardcoded path of the output file, the workflow finished without any error.

I don't know if this pattern of filename (.nii.gz_mean_reg.nii.gz) shouldn't appear in FLS 6, or there's something wrong on nipype side?

Platform details:

{'commit_hash': '62fc392',
 'commit_source': 'repository',
 'networkx_version': '3.3',
 'nibabel_version': '5.2.1',
 'nipype_version': '1.8.6',
 'numpy_version': '1.26.3',
 'pkg_path': '/xxx/.pyenv/versions/3.11.10/lib/python3.11/site-packages/nipype',
 'scipy_version': '1.14.1',
 'sys_executable': '/xxx/.pyenv/versions/3.11.10/bin/python',
 'sys_platform': 'linux',
 'sys_version': '3.11.10 (main, Sep 23 2024, 14:48:25) [GCC 7.5.0]',
 'traits_version': '6.3.2'}

Execution environment

FSL: 6.0.7.13

b1060t avatar Sep 28 '24 14:09 b1060t

I'm not sure. If you're able to describe an environment and minimal reproducible example, we could definitely debug this.

effigies avatar Nov 18 '24 21:11 effigies

I'm just refering to the nipype tutorial:

from nipype import SelectFiles, Node
from os.path import abspath
templates={'func': '{subject}/{session}/func/{subject}_{session}_task-fingerfootlips_bold.nii.gz'}
sf = Node(SelectFiles(templates),
          name='selectfiles')
sf.inputs.base_directory = abspath('../data/ds000114')
sf.inputs.subject = 'sub-01'
sf.inputs.session = 'ses-test'
from nipype.interfaces.fsl import MCFLIRT, IsotropicSmooth
mcflirt = Node(MCFLIRT(mean_vol=True,
                       save_plots=True),
               name='mcflirt')
smooth = Node(IsotropicSmooth(fwhm=4),
              name='smooth')
from nipype import Workflow
wf = Workflow(name="preprocWF")
wf.base_dir = 'output/working_dir'
wf.connect([(sf, mcflirt, [("func", "in_file")]),
            #(mcflirt, smooth, [("out_file", "in_file")])
            ])
wf.run()

b1060t avatar May 08 '25 12:05 b1060t

Hi, I noticed an issue when running mcflirt from the command line using:

mcflirt -in name.nii -meanvol -out outname.nii

This produces an output file named outname.nii.nii, which causes a naming error. The same behavior occurs when using Nipype unless you explicitly specify the output filename without the .nii extension. In my Python code, I work around this by setting out_file='outname':

mcflirt = Node(MCFLIRT(mean_vol=True,
                       save_plots=True),
               name='mcflirt', out_file='outname')

Then modify nipype MCFLIRT class

class MCFLIRT(FSLCommand):

    def _list_outputs(self):
        outputs = self._outputs().get()

        outputs["out_file"] = self._gen_outfilename()
        output_dir = os.path.dirname(outputs["out_file"])

        if isdefined(self.inputs.stats_imgs) and self.inputs.stats_imgs:
            if LooseVersion(Info.version()) < LooseVersion("6.0.0"):
                # FSL <6.0 outputs have .nii.gz_variance.nii.gz as extension
                outputs["variance_img"] = self._gen_fname(
                    outputs["out_file"] + "_variance.ext", cwd=output_dir
                )
                outputs["std_img"] = self._gen_fname(
                    outputs["out_file"] + "_sigma.ext", cwd=output_dir
                )
            else:
                outputs["variance_img"] = self._gen_fname(
                    outputs["out_file"], suffix="_variance", cwd=output_dir
                )
                outputs["std_img"] = self._gen_fname(
                    outputs["out_file"], suffix="_sigma", cwd=output_dir
                )

        # The mean image created if -stats option is specified ('meanvol')
        # is missing the top and bottom slices. Therefore we only expose the
        # mean image created by -meanvol option ('mean_reg') which isn't
        # corrupted.
        # Note that the same problem holds for the std and variance image.

        if isdefined(self.inputs.mean_vol) and self.inputs.mean_vol:
            if LooseVersion(Info.version()) < LooseVersion("6.0.0"):
                # FSL <6.0 outputs have .nii.gz_mean_img.nii.gz as extension
                outputs["mean_img"] = self._gen_fname(
                    outputs["out_file"] + "_mean_reg.ext", cwd=output_dir
                )
            else:
                outputs["mean_img"] = self._gen_fname(
                    outputs["out_file"], suffix="_mean_reg", cwd=output_dir
                )


        if isdefined(self.inputs.save_mats) and self.inputs.save_mats:
            _, filename = os.path.split(outputs["out_file"])
            matpathname = os.path.join(output_dir, filename + ".mat")
            _, _, _, timepoints = load(self.inputs.in_file).shape
            outputs["mat_file"] = []
            for t in range(timepoints):
                outputs["mat_file"].append(os.path.join(matpathname, "MAT_%04d" % t))
        if isdefined(self.inputs.save_plots) and self.inputs.save_plots:
            # Note - if e.g. out_file has .nii.gz, you get .nii.gz.par,
            # which is what mcflirt does!
            outputs["par_file"] = outputs["out_file"] + ".par"
        if isdefined(self.inputs.save_rms) and self.inputs.save_rms:
            outfile = outputs["out_file"]
            outputs["rms_files"] = [outfile + "_abs.rms", outfile + "_rel.rms"]

        #! add this line ************************************
        outputs["out_file"] = outputs["out_file"] + ".nii" # .nii or .nii.gz depend on your output
        #! end of add

        return outputs

Hope this help

44REAM avatar Jun 03 '25 08:06 44REAM