Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workflow with separate M0 fails at registration step #319

Closed
chidiugonna opened this issue Sep 3, 2023 · 8 comments · Fixed by #320 or #321
Closed

Workflow with separate M0 fails at registration step #319

chidiugonna opened this issue Sep 3, 2023 · 8 comments · Fixed by #320 or #321
Labels
bug Something isn't working

Comments

@chidiugonna
Copy link

chidiugonna commented Sep 3, 2023

Summary

Aslprep crashes while executing Node "extract_deltam" with the following error message:

traits.trait_errors.TraitError: The 'in_file' trait of a FLIRTInputSpec instance must be a pathlike object or string representing an existing file, but a value of  '/output/aslprep_work/aslprep_wf/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii' <class 'str'> was specified.

Additional details

  • ASLPrep version: 0.4.0
  • Docker version:
  • Singularity version: Singularity Image Built from Docker image 0.4.0 (docker://pennlinc/aslprep:0.4.0) using apptainer version 1.1.9-1.el7

What were you trying to do?

Ran Aslprep with the following command line call. My dataset included a PASL file and a separate M0 acquisition. The M0 file has 4 volumes while the PASL file (single PLD) has 20 volumes (control/label)

singularity run aslprep_0.4.sif \
    /data/BIDS \
    /output/aslprep_output \
    participant \
    --participant_label z50XWAAY \
    --low-mem \
    --skip-bids-validation \
    --stop-on-first-crash \
    --use-syn-sdc \
    --fs-license-file $PWD/license.txt \
    --ignore fieldmaps \
    -w /output/aslprep_work

Error Log

230902-21:56:14,182 nipype.workflow ERROR:
	 Saving crash info to /output/aslprep_output/aslprep/sub-z50XWAAY/log/20230902-210847_83c32feb-3615-4409-9c4e-ad0f5eb93bcf/crash-20230902-215614-chidiugonna-extract_deltam-8578fd20-372d-4144-b48c-878a2f9a3395.txt
Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/plugins/multiproc.py", line 344, in _send_procs_to_workers
    self.procs[jobid].run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 527, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 645, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 771, in _run_command
    raise NodeExecutionError(msg)
nipype.pipeline.engine.nodes.NodeExecutionError: Exception raised while executing Node extract_deltam.

Traceback:
	Traceback (most recent call last):
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/core.py", line 397, in run
	    runtime = self._run_interface(runtime)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py", line 158, in _run_interface
	    m0_in_asl = regmotoasl(asl=self.inputs.asl_file, m0file=m0file, m02asl=m0_in_asl)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py", line 966, in regmotoasl
	    flt.inputs.in_file = meanm0.inputs.out_file
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/traits_extension.py", line 330, in validate
	    value = super(File, self).validate(objekt, name, value, return_pathlike=True)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/traits_extension.py", line 135, in validate
	    self.error(objekt, name, str(value))
	  File "/usr/local/miniconda/lib/python3.8/site-packages/traits/base_trait_handler.py", line 74, in error
	    raise TraitError(
	traits.trait_errors.TraitError: The 'in_file' trait of a FLIRTInputSpec instance must be a pathlike object or string representing an existing file, but a value of '/output/aslprep_work/aslprep_wf/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii' <class 'str'> was specified.


230902-21:56:14,215 nipype.workflow CRITICAL:
	 ASLPrep failed: Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/plugins/multiproc.py", line 344, in _send_procs_to_workers
    self.procs[jobid].run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 527, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 645, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 771, in _run_command
    raise NodeExecutionError(msg)
nipype.pipeline.engine.nodes.NodeExecutionError: Exception raised while executing Node extract_deltam.

Traceback:
	Traceback (most recent call last):
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/core.py", line 397, in run
	    runtime = self._run_interface(runtime)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py", line 158, in _run_interface
	    m0_in_asl = regmotoasl(asl=self.inputs.asl_file, m0file=m0file, m02asl=m0_in_asl)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py", line 966, in regmotoasl
	    flt.inputs.in_file = meanm0.inputs.out_file
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/traits_extension.py", line 330, in validate
	    value = super(File, self).validate(objekt, name, value, return_pathlike=True)
	  File "/usr/local/miniconda/lib/python3.8/site-packages/nipype/interfaces/base/traits_extension.py", line 135, in validate
	    self.error(objekt, name, str(value))
	  File "/usr/local/miniconda/lib/python3.8/site-packages/traits/base_trait_handler.py", line 74, in error
	    raise TraitError(
	traits.trait_errors.TraitError: The 'in_file' trait of a FLIRTInputSpec instance must be a pathlike object or string representing an existing file, but a value of '/output/aslprep_work/aslprep_wf/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii' <class 'str'> was specified.

230902-21:56:14,380 nipype.workflow INFO:
	 [Node] Finished "gm_tfm", elapsed time 0.477332s.
230902-21:56:14,406 nipype.workflow INFO:

Reproducing the bug

Error appears to happen in function regmotoasl in /usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py on line 966

960  	    meanasl.run()
961  	    meanm0 = fsl.MeanImage()
962  	    meanm0.inputs.in_file = m0file
963  	    meanm0.inputs.out_file = fname_presuffix(asl, suffix="_meanm0")
964  	    meanm0.run()
965  	    flt = fsl.FLIRT(bins=640, cost_func="mutualinfo")
966  ->	    flt.inputs.in_file = meanm0.inputs.out_file
967  	    flt.inputs.reference = meanasl.inputs.out_file
968  	    flt.inputs.out_file = m02asl
969  	    flt.run()
970  	    return m02asl

The FLIRT node is expecting vol0000_xform-00000_merged_meanm0.nii

(Pdb) meanm0.inputs.out_file
'/output/aslprep_work/aslprep_wf/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii'

But the meanm0 process actually creates vol0000_xform-00000_merged_meanm0.nii.gz despite being explicitly set to produce the .nii file on line 963.

(Pdb) os.listdir("/output/aslprep_work/aslprep_wf/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/")
['_node.pklz', '_report', 'vol0000_xform-00000_merged_meanasl.nii.gz', 'vol0000_xform-00000_merged.nii', 'vol0000_xform-00000_merged_meanm0.nii.gz', '_0x7ec2f0c13ca027be6f34c8af2a9f9fb9.json', 'result_merge.pklz', '_inputs.pklz']
@chidiugonna chidiugonna added the bug Something isn't working label Sep 3, 2023
@tsalo
Copy link
Member

tsalo commented Sep 3, 2023

@chidiugonna thank you for the detailed bug report. I won't be able to get to this until around Tuesday, but I'll try to get back to you then.

@chidiugonna
Copy link
Author

@tsalo thank you! I just tried to update the filepath for meanm0.inputs.out_file to remove the long parent directory which was distracting.

@tsalo tsalo mentioned this issue Sep 6, 2023
@tsalo tsalo closed this as completed in #320 Sep 6, 2023
@tsalo
Copy link
Member

tsalo commented Sep 6, 2023

@chidiugonna would you mind waiting a couple of hours until the unstable tag on DockerHub updates with the changes from #320, then pulling that version and trying it out on your data? My hope is that #320 will fix the problem.

@chidiugonna
Copy link
Author

Hi @tsalo ,
Thank you for quickly getting this fix up so I could test it. The error still persists. The problem seems to be that the fsl,MeanImage() node insists on saving the mean image with extension of ".nii.gz" (perhaps because of the FSLOUTPUTTYPE environ variable) but this is not reflected in its advertised outputs which show an extension of ".nii". I am not sure what the most elegant way to address this would be -it looks like it might be necessary to enforce an extension of ".nii.gz" when filenames are set up in lines 965 and 969.

965  	    meanasl.inputs.out_file = fname_presuffix(asl, suffix="_meanasl")
..
969  	    meanm0.inputs.out_file = fname_presuffix(asl, suffix="_meanm0")

Here are some debugging outputs that show code flow - error is occurring on line 972:

963 	            meanasl = fsl.MeanImage()
964  	    meanasl.inputs.in_file = asl
965  	    meanasl.inputs.out_file = fname_presuffix(asl, suffix="_meanasl")
966  	    meanasl_results = meanasl.run()
967  	    meanm0 = fsl.MeanImage()
968  	    meanm0.inputs.in_file = m0file
969  	    meanm0.inputs.out_file = fname_presuffix(asl, suffix="_meanm0")
970  	    meanm0_results = meanm0.run()
971  	    flt = fsl.FLIRT(bins=640, cost_func="mutualinfo")
972   --->	    flt.inputs.in_file = meanm0_results.outputs.out_file
973  	    flt.inputs.reference = meanasl_results.outputs.out_file
974  	    flt.inputs.out_file = m02asl
975  	    flt_results = flt.run()
976  	    return flt_results.outputs.out_file

ASL file has extension .nii

(Pdb) asl
'/output/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged.nii'

Results from meanasl and meanm0 advertise .nii as outputs

(Pdb) meanasl_results.outputs
out_file = /output/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanasl.nii

(Pdb) meanm0_results.outputs
out_file = /output/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii

But in actual fact meanasl and meanm0 create files with extension .nii.gz

(Pdb) os.listdir("/output/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/")
['_node.pklz', '_report', '_0xec8f6bd17d14211fdb7854483aedeee0.json', 'vol0000_xform-00000_merged_meanasl.nii.gz', 'vol0000_xform-00000_merged.nii', 'vol0000_xform-00000_merged_meanm0.nii.gz', 'result_merge.pklz', '_inputs.pklz']

This causes flirt node to fail at line 972

967  	    meanm0 = fsl.MeanImage()
968  	    meanm0.inputs.in_file = m0file
969  	    meanm0.inputs.out_file = fname_presuffix(asl, suffix="_meanm0")
970  	    meanm0_results = meanm0.run()
971  	    flt = fsl.FLIRT(bins=640, cost_func="mutualinfo")
972  ->	    flt.inputs.in_file = meanm0_results.outputs.out_file
973  	    flt.inputs.reference = meanasl_results.outputs.out_file
974  	    flt.inputs.out_file = m02asl
975  	    flt_results = flt.run()
976  	    return flt_results.outputs.out_file
977  	
(Pdb) n
traits.trait_errors.TraitError: The 'in_file' trait of a FLIRTInputSpec instance must be a pathlike object or string representing an existing file, but a value of '/output/single_subject_z50XWAAY_wf/asl_preproc_ses_SESSION001_acq_prod_wf/asl_asl_trans_wf/merge/vol0000_xform-00000_merged_meanm0.nii' <class 'str'> was specified.
> /usr/local/miniconda/lib/python3.8/site-packages/aslprep/interfaces/cbf.py(972)regmotoasl()
-> flt.inputs.in_file = meanm0_results.outputs.out_file

@tsalo tsalo reopened this Sep 7, 2023
@tsalo
Copy link
Member

tsalo commented Sep 7, 2023

Oof sorry. I've got a couple of ideas to fix it then. I'll probably just rely on the auto-generated filename, rather than passing one through the different nodes.

@tsalo
Copy link
Member

tsalo commented Sep 7, 2023

I just merged #321 and I'm hoping it works. It'll be a couple of hours before the update pushes to DockerHub.

@chidiugonna
Copy link
Author

@tsalo This works perfectly now! Thank you!

@tsalo
Copy link
Member

tsalo commented Sep 8, 2023

That's a relief. Thank you for your patience with my debugging process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants