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

Crash on AROMA if all ICs are classified as motion #1300

Closed
andersonwinkler opened this issue Oct 1, 2018 · 27 comments · Fixed by #1467
Closed

Crash on AROMA if all ICs are classified as motion #1300

andersonwinkler opened this issue Oct 1, 2018 · 27 comments · Fixed by #1467

Comments

@andersonwinkler
Copy link

The title says it all. For every functional run, out of hundreds, in which AROMA incidentally classified all ICs as being motion-related, FMRIPREP crashes.

It doesn't seem to be an issue with AROMA as fsl_regfilt works fine even in these cases. But somehow the workflow doesn't finish.

When I try to open the pklz crash reports with nipypecli, then nipypecli itself crashes too...

@andersonwinkler
Copy link
Author

The error message, btw, is this:

$ nipypecli crash result_ica_aroma.pklz
Traceback (most recent call last):
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/bin/nipypecli", line 11, in <module>
    sys.exit(cli())
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/nipype/scripts/cli.py", line 94, in crash
    display_crash_file(crashfile, rerun, debug, dir)
  File "/gpfs/gsfs6/users/EDB/Networks/Flanker2/code/env-hpc/lib/python3.6/site-packages/nipype/scripts/crash_files.py", line 53, in display_crash_file
    if 'node' in crash_data:
TypeError: argument of type 'InterfaceResult' is not iterable

@effigies effigies added the bug label Oct 2, 2018
@effigies
Copy link
Member

effigies commented Oct 2, 2018

Thanks for the report. Could you post that nipypecli error to nipype issues?

What version of fMRIPrep are you using? I assume you're running it in a Singularity container?

@andersonwinkler
Copy link
Author

Will report there, thanks! (will do later today).

We are using version 1.1.6, not using a container, but working local installs of the pre-requisites, with python 3.6 and modules in a virtualenv.

We've run for 404 subjects, each with 1 session, each session with 4 or 5 functional runs (task and rest). Out of these 404, 386 subjects finished fMRIprep successfully without any problems, so it shouldn't be a problem with the install. For the 18 subjects that fail, they fail in one of their funcional runs -- the one in which AROMA classified all ICs as motion. We've repeated 2-3 times for these 18, to no avail.

Thanks!

@effigies
Copy link
Member

effigies commented Oct 2, 2018

Looks like AROMA has edge cases where all or no ICs are classified as motion. I suspect it will be that some files are not produced in each case, and the Nipype interface is throwing up. Could you share the _report/report.rst from a failing AROMA node?

@andersonwinkler
Copy link
Author

Hi Chris,

Please see below for a case in which it failed, and further down, to compare, for a case in which it didn't fail.

user@host:~/Projects/project/fmriprep/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction $ ls
AROMAnoiseICs.csv  _inputs.pklz  MELODICmix.tsv  _node.pklz  _report  result_ica_aroma_confound_extraction.pklz
user@host:~/Projects/project/fmriprep/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction $ cat _report/report.rst 
Node: single_subject_23212_wf (func_preproc_ses_1_task_flanker2_run_2_wf (ica_aroma_wf (ica_aroma_confound_extraction (confounds)
=================================================================================================================================


 Hierarchy : fmriprep_wf.single_subject_23212_wf.func_preproc_ses_1_task_flanker2_run_2_wf.ica_aroma_wf.ica_aroma_confound_extraction
 Exec ID : ica_aroma_confound_extraction


Original Inputs
---------------


* ignore_aroma_err : False
* in_directory : /lscratch/10202724/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out

The above is all the content of the *.rst file.

Below for the case in which it worked. I'm omitting the Environment section, but can paste it if you need.

user@host:~/Projects/project/fmriprep/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction $ ls
_0xb8720c07616c1233fa8054cfe458e1de.json  AROMAAggrCompAROMAConfounds.tsv  AROMAnoiseICs.csv  _inputs.pklz  MELODICmix.tsv  _node.pklz  _report  result_ica_aroma_confound_extraction.pklz
user@host:~/Projects/project/fmriprep/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction $ cat _report/report.rst 
Node: single_subject_21055_wf (func_preproc_ses_1_task_flanker2_run_2_wf (ica_aroma_wf (ica_aroma_confound_extraction (confounds)
=================================================================================================================================


 Hierarchy : fmriprep_wf.single_subject_21055_wf.func_preproc_ses_1_task_flanker2_run_2_wf.ica_aroma_wf.ica_aroma_confound_extraction
 Exec ID : ica_aroma_confound_extraction


Original Inputs
---------------


* ignore_aroma_err : False
* in_directory : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out

Execution Inputs
----------------


* ignore_aroma_err : False
* in_directory : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out


Execution Outputs
-----------------


* aroma_confounds : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction/AROMAAggrCompAROMAConfounds.tsv
* aroma_noise_ics : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction/AROMAnoiseICs.csv
* melodic_mix : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction/MELODICmix.tsv


Runtime info
------------


* duration : 0.030848
* hostname : cn3216
* prev_wd : /gpfs/gsfs6/users/EDB/Networks/Flanker2/code
* working_dir : /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma_confound_extraction


Environment
~~~~~~~~~~~

[...]

@effigies
Copy link
Member

effigies commented Oct 3, 2018

Does the directory /lscratch/10202724/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out exist? And if so, could you compare the tree output for:

  • /lscratch/10202724/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out
  • /lscratch/10202574/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/ica_aroma/out

@andersonwinkler
Copy link
Author

Please, see below. The first is for the one that failed, the second for the one that worked. They seem to be the same. Thanks.

$ tree -l
.
├── classification_overview.txt
├── classified_motion_ICs.txt
├── denoised_func_data_nonaggr.nii.gz
├── feature_scores.txt
├── ICA_AROMA_component_assessment.pdf
├── mask.nii.gz
├── melodic.ica -> /data/EDB/Networks/Flanker2/fmriprep/sub-23212.wrk/fmriprep_wf/single_subject_23212_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/melodic
│   ├── _0xb23d060903cc2a3484c6e81687d3c3bf.json
│   ├── command.txt
│   ├── eigenvalues_percent
│   ├── _inputs.pklz
│   ├── log.txt
│   ├── mask.nii.gz
│   ├── mean.nii.gz
│   ├── melodic_FTmix
│   ├── melodic_IC.nii.gz
│   ├── melodic_ICstats
│   ├── melodic_mix
│   ├── melodic_Tmodes
│   ├── _node.pklz
│   ├── _report
│   │   └── report.rst
│   ├── result_melodic.pklz
│   └── stats
│       ├── MMstats_1
│       ├── MMstats_10
│       ├── MMstats_11
│       ├── MMstats_12
│       ├── MMstats_13
│       ├── MMstats_14
│       ├── MMstats_15
│       ├── MMstats_16
│       ├── MMstats_17
│       ├── MMstats_18
│       ├── MMstats_19
│       ├── MMstats_2
│       ├── MMstats_20
│       ├── MMstats_21
│       ├── MMstats_22
│       ├── MMstats_23
│       ├── MMstats_24
│       ├── MMstats_25
│       ├── MMstats_26
│       ├── MMstats_27
│       ├── MMstats_28
│       ├── MMstats_29
│       ├── MMstats_3
│       ├── MMstats_30
│       ├── MMstats_31
│       ├── MMstats_32
│       ├── MMstats_33
│       ├── MMstats_34
│       ├── MMstats_35
│       ├── MMstats_36
│       ├── MMstats_37
│       ├── MMstats_38
│       ├── MMstats_39
│       ├── MMstats_4
│       ├── MMstats_40
│       ├── MMstats_41
│       ├── MMstats_42
│       ├── MMstats_43
│       ├── MMstats_44
│       ├── MMstats_45
│       ├── MMstats_46
│       ├── MMstats_47
│       ├── MMstats_48
│       ├── MMstats_49
│       ├── MMstats_5
│       ├── MMstats_50
│       ├── MMstats_6
│       ├── MMstats_7
│       ├── MMstats_8
│       ├── MMstats_9
│       ├── probmap_10.nii.gz
│       ├── probmap_11.nii.gz
│       ├── probmap_12.nii.gz
│       ├── probmap_13.nii.gz
│       ├── probmap_14.nii.gz
│       ├── probmap_15.nii.gz
│       ├── probmap_16.nii.gz
│       ├── probmap_17.nii.gz
│       ├── probmap_18.nii.gz
│       ├── probmap_19.nii.gz
│       ├── probmap_1.nii.gz
│       ├── probmap_20.nii.gz
│       ├── probmap_21.nii.gz
│       ├── probmap_22.nii.gz
│       ├── probmap_23.nii.gz
│       ├── probmap_24.nii.gz
│       ├── probmap_25.nii.gz
│       ├── probmap_26.nii.gz
│       ├── probmap_27.nii.gz
│       ├── probmap_28.nii.gz
│       ├── probmap_29.nii.gz
│       ├── probmap_2.nii.gz
│       ├── probmap_30.nii.gz
│       ├── probmap_31.nii.gz
│       ├── probmap_32.nii.gz
│       ├── probmap_33.nii.gz
│       ├── probmap_34.nii.gz
│       ├── probmap_35.nii.gz
│       ├── probmap_36.nii.gz
│       ├── probmap_37.nii.gz
│       ├── probmap_38.nii.gz
│       ├── probmap_39.nii.gz
│       ├── probmap_3.nii.gz
│       ├── probmap_40.nii.gz
│       ├── probmap_41.nii.gz
│       ├── probmap_42.nii.gz
│       ├── probmap_43.nii.gz
│       ├── probmap_44.nii.gz
│       ├── probmap_45.nii.gz
│       ├── probmap_46.nii.gz
│       ├── probmap_47.nii.gz
│       ├── probmap_48.nii.gz
│       ├── probmap_49.nii.gz
│       ├── probmap_4.nii.gz
│       ├── probmap_50.nii.gz
│       ├── probmap_5.nii.gz
│       ├── probmap_6.nii.gz
│       ├── probmap_7.nii.gz
│       ├── probmap_8.nii.gz
│       ├── probmap_9.nii.gz
│       ├── stats.log
│       ├── thresh_zstat10.nii.gz
│       ├── thresh_zstat11.nii.gz
│       ├── thresh_zstat12.nii.gz
│       ├── thresh_zstat13.nii.gz
│       ├── thresh_zstat14.nii.gz
│       ├── thresh_zstat15.nii.gz
│       ├── thresh_zstat16.nii.gz
│       ├── thresh_zstat17.nii.gz
│       ├── thresh_zstat18.nii.gz
│       ├── thresh_zstat19.nii.gz
│       ├── thresh_zstat1.nii.gz
│       ├── thresh_zstat20.nii.gz
│       ├── thresh_zstat21.nii.gz
│       ├── thresh_zstat22.nii.gz
│       ├── thresh_zstat23.nii.gz
│       ├── thresh_zstat24.nii.gz
│       ├── thresh_zstat25.nii.gz
│       ├── thresh_zstat26.nii.gz
│       ├── thresh_zstat27.nii.gz
│       ├── thresh_zstat28.nii.gz
│       ├── thresh_zstat29.nii.gz
│       ├── thresh_zstat2.nii.gz
│       ├── thresh_zstat30.nii.gz
│       ├── thresh_zstat31.nii.gz
│       ├── thresh_zstat32.nii.gz
│       ├── thresh_zstat33.nii.gz
│       ├── thresh_zstat34.nii.gz
│       ├── thresh_zstat35.nii.gz
│       ├── thresh_zstat36.nii.gz
│       ├── thresh_zstat37.nii.gz
│       ├── thresh_zstat38.nii.gz
│       ├── thresh_zstat39.nii.gz
│       ├── thresh_zstat3.nii.gz
│       ├── thresh_zstat40.nii.gz
│       ├── thresh_zstat41.nii.gz
│       ├── thresh_zstat42.nii.gz
│       ├── thresh_zstat43.nii.gz
│       ├── thresh_zstat44.nii.gz
│       ├── thresh_zstat45.nii.gz
│       ├── thresh_zstat46.nii.gz
│       ├── thresh_zstat47.nii.gz
│       ├── thresh_zstat48.nii.gz
│       ├── thresh_zstat49.nii.gz
│       ├── thresh_zstat4.nii.gz
│       ├── thresh_zstat50.nii.gz
│       ├── thresh_zstat5.nii.gz
│       ├── thresh_zstat6.nii.gz
│       ├── thresh_zstat7.nii.gz
│       ├── thresh_zstat8.nii.gz
│       └── thresh_zstat9.nii.gz
└── melodic_IC_thr_MNI2mm.nii.gz

3 directories, 173 files
$ tree -l
.
├── classification_overview.txt
├── classified_motion_ICs.txt
├── denoised_func_data_nonaggr.nii.gz
├── feature_scores.txt
├── ICA_AROMA_component_assessment.pdf
├── mask.nii.gz
├── melodic.ica -> /data/EDB/Networks/Flanker2/fmriprep/sub-21055.wrk/fmriprep_wf/single_subject_21055_wf/func_preproc_ses_1_task_flanker2_run_2_wf/ica_aroma_wf/melodic
│   ├── _0x64062d51bd4a9f78a9f5bc1db9564caf.json
│   ├── command.txt
│   ├── eigenvalues_percent
│   ├── _inputs.pklz
│   ├── log.txt
│   ├── mask.nii.gz
│   ├── mean.nii.gz
│   ├── melodic_FTmix
│   ├── melodic_IC.nii.gz
│   ├── melodic_ICstats
│   ├── melodic_mix
│   ├── melodic_Tmodes
│   ├── _node.pklz
│   ├── _report
│   │   └── report.rst
│   ├── result_melodic.pklz
│   └── stats
│       ├── MMstats_1
│       ├── MMstats_10
│       ├── MMstats_11
│       ├── MMstats_12
│       ├── MMstats_13
│       ├── MMstats_14
│       ├── MMstats_15
│       ├── MMstats_16
│       ├── MMstats_17
│       ├── MMstats_18
│       ├── MMstats_19
│       ├── MMstats_2
│       ├── MMstats_20
│       ├── MMstats_21
│       ├── MMstats_22
│       ├── MMstats_23
│       ├── MMstats_24
│       ├── MMstats_25
│       ├── MMstats_26
│       ├── MMstats_27
│       ├── MMstats_28
│       ├── MMstats_29
│       ├── MMstats_3
│       ├── MMstats_30
│       ├── MMstats_31
│       ├── MMstats_32
│       ├── MMstats_33
│       ├── MMstats_34
│       ├── MMstats_35
│       ├── MMstats_36
│       ├── MMstats_37
│       ├── MMstats_38
│       ├── MMstats_39
│       ├── MMstats_4
│       ├── MMstats_40
│       ├── MMstats_41
│       ├── MMstats_42
│       ├── MMstats_43
│       ├── MMstats_44
│       ├── MMstats_45
│       ├── MMstats_46
│       ├── MMstats_47
│       ├── MMstats_48
│       ├── MMstats_49
│       ├── MMstats_5
│       ├── MMstats_50
│       ├── MMstats_6
│       ├── MMstats_7
│       ├── MMstats_8
│       ├── MMstats_9
│       ├── probmap_10.nii.gz
│       ├── probmap_11.nii.gz
│       ├── probmap_12.nii.gz
│       ├── probmap_13.nii.gz
│       ├── probmap_14.nii.gz
│       ├── probmap_15.nii.gz
│       ├── probmap_16.nii.gz
│       ├── probmap_17.nii.gz
│       ├── probmap_18.nii.gz
│       ├── probmap_19.nii.gz
│       ├── probmap_1.nii.gz
│       ├── probmap_20.nii.gz
│       ├── probmap_21.nii.gz
│       ├── probmap_22.nii.gz
│       ├── probmap_23.nii.gz
│       ├── probmap_24.nii.gz
│       ├── probmap_25.nii.gz
│       ├── probmap_26.nii.gz
│       ├── probmap_27.nii.gz
│       ├── probmap_28.nii.gz
│       ├── probmap_29.nii.gz
│       ├── probmap_2.nii.gz
│       ├── probmap_30.nii.gz
│       ├── probmap_31.nii.gz
│       ├── probmap_32.nii.gz
│       ├── probmap_33.nii.gz
│       ├── probmap_34.nii.gz
│       ├── probmap_35.nii.gz
│       ├── probmap_36.nii.gz
│       ├── probmap_37.nii.gz
│       ├── probmap_38.nii.gz
│       ├── probmap_39.nii.gz
│       ├── probmap_3.nii.gz
│       ├── probmap_40.nii.gz
│       ├── probmap_41.nii.gz
│       ├── probmap_42.nii.gz
│       ├── probmap_43.nii.gz
│       ├── probmap_44.nii.gz
│       ├── probmap_45.nii.gz
│       ├── probmap_46.nii.gz
│       ├── probmap_47.nii.gz
│       ├── probmap_48.nii.gz
│       ├── probmap_49.nii.gz
│       ├── probmap_4.nii.gz
│       ├── probmap_50.nii.gz
│       ├── probmap_5.nii.gz
│       ├── probmap_6.nii.gz
│       ├── probmap_7.nii.gz
│       ├── probmap_8.nii.gz
│       ├── probmap_9.nii.gz
│       ├── stats.log
│       ├── thresh_zstat10.nii.gz
│       ├── thresh_zstat11.nii.gz
│       ├── thresh_zstat12.nii.gz
│       ├── thresh_zstat13.nii.gz
│       ├── thresh_zstat14.nii.gz
│       ├── thresh_zstat15.nii.gz
│       ├── thresh_zstat16.nii.gz
│       ├── thresh_zstat17.nii.gz
│       ├── thresh_zstat18.nii.gz
│       ├── thresh_zstat19.nii.gz
│       ├── thresh_zstat1.nii.gz
│       ├── thresh_zstat20.nii.gz
│       ├── thresh_zstat21.nii.gz
│       ├── thresh_zstat22.nii.gz
│       ├── thresh_zstat23.nii.gz
│       ├── thresh_zstat24.nii.gz
│       ├── thresh_zstat25.nii.gz
│       ├── thresh_zstat26.nii.gz
│       ├── thresh_zstat27.nii.gz
│       ├── thresh_zstat28.nii.gz
│       ├── thresh_zstat29.nii.gz
│       ├── thresh_zstat2.nii.gz
│       ├── thresh_zstat30.nii.gz
│       ├── thresh_zstat31.nii.gz
│       ├── thresh_zstat32.nii.gz
│       ├── thresh_zstat33.nii.gz
│       ├── thresh_zstat34.nii.gz
│       ├── thresh_zstat35.nii.gz
│       ├── thresh_zstat36.nii.gz
│       ├── thresh_zstat37.nii.gz
│       ├── thresh_zstat38.nii.gz
│       ├── thresh_zstat39.nii.gz
│       ├── thresh_zstat3.nii.gz
│       ├── thresh_zstat40.nii.gz
│       ├── thresh_zstat41.nii.gz
│       ├── thresh_zstat42.nii.gz
│       ├── thresh_zstat43.nii.gz
│       ├── thresh_zstat44.nii.gz
│       ├── thresh_zstat45.nii.gz
│       ├── thresh_zstat46.nii.gz
│       ├── thresh_zstat47.nii.gz
│       ├── thresh_zstat48.nii.gz
│       ├── thresh_zstat49.nii.gz
│       ├── thresh_zstat4.nii.gz
│       ├── thresh_zstat50.nii.gz
│       ├── thresh_zstat5.nii.gz
│       ├── thresh_zstat6.nii.gz
│       ├── thresh_zstat7.nii.gz
│       ├── thresh_zstat8.nii.gz
│       └── thresh_zstat9.nii.gz
└── melodic_IC_thr_MNI2mm.nii.gz

3 directories, 173 files

@andersonwinkler
Copy link
Author

Btw, I had previously choosen 50 as the Melodic dimensionality, hence same number of ICs that Melodic finds. This is unrelated to the problem. Even if we let Melodic choose the number of ICs, whenever the number of ICs classified as motion is the same as the total number of ICs, fMRIprep crashes. Thanks.

@effigies
Copy link
Member

effigies commented Oct 3, 2018

@jdkent Would you mind having a look at this thread and letting us know if you see something or can think of another diagnostic question? I'll have another look in a bit, but I think we're going to have to dig into contents.

@jdkent
Copy link
Collaborator

jdkent commented Oct 13, 2018

I looked into the code and I don't see anywhere obvious where the interface would blow up. Once we can see the error report from the pickled file, that should point us in the right direction.
I suppose the other issue (irrespective of fmriprep having error output) is to understand why all the components are being classified as noise.

For the failing ICA-AROMA node, could we see the contents of feature_scores.txt and classification_overview.txt? Thanks!

P.S.
sorry for taking so long (I've switched from getting notification from all the fmriprep issues to just ones I'm participating in/mentioned, so I should be better at responding in the future).

@oliver-xie
Copy link

I also had this issue that fmriprep crashed when all ICs were classified as noise. We can still get the smoothAROMAnonaggr_preproc.nii.gz but no bold_confounds.tsv or bold_MELODICmix.tsv were generated.

We are using 1.1.4 on docker and below is the crash log

Node: fmriprep_wf.single_subject_17sess06pl02_wf.func_preproc_ses_session_task_storytelling_run_01_wf.ica_aroma_wf.ica_aroma_confound_extraction
Working directory: /work/fmriprep_wf/single_subject_17sess06pl02_wf/func_preproc_ses_session_task_storytelling_run_01_wf/ica_aroma_wf/ica_aroma_confound_extraction

Node inputs:

ignore_aroma_err = False
in_directory = /work/fmriprep_wf/single_subject_17sess06pl02_wf/func_preproc_ses_session_task_storytelling_run_01_wf/ica_aroma_wf/ica_aroma/out

Traceback (most recent call last):
File "/usr/local/miniconda/lib/python3.6/site-packages/nipype/pipeline/plugins/multiproc.py", line 69, in run_node
result['result'] = node.run(updatehash=updatehash)
File "/usr/local/miniconda/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 480, in run
result = self._run_interface(execute=True)
File "/usr/local/miniconda/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 564, in _run_interface
return self._run_command(execute)
File "/usr/local/miniconda/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 644, in _run_command
result = self._interface.run(cwd=outdir)
File "/usr/local/miniconda/lib/python3.6/site-packages/nipype/interfaces/base/core.py", line 521, in run
runtime = self._run_interface(runtime)
File "/usr/local/miniconda/lib/python3.6/site-packages/fmriprep/interfaces/confounds.py", line 119, in _run_interface
raise RuntimeError('ICA-AROMA failed')
RuntimeError: ICA-AROMA failed

Thanks!

Oliver

@jdkent
Copy link
Collaborator

jdkent commented Oct 17, 2018

I just got this error on some of my data as well, so I can take take a deeper look into it.

@jdkent
Copy link
Collaborator

jdkent commented Oct 18, 2018

Looking at the code, the function _get_ica_confounds returns None for aroma_confounds if either none or all the components were classified as noise.

Then back in the main _run_interface function, if aroma_confounds is None the specified behavior is to raise an error that ICA-AROMA failed since for it to be useful, it should have a mix a signal and noise components. The idea is that one should modify their fmriprep command (e.g. perhaps through using --ignore-aroma-denoising-errors or --aroma-melodic-dimensionality to change how the output is interpreted or to change the dimensionality of how many components aroma has to work with).

So if we were to implement a change, my current thought process is to not raise an error if all the components are classified as noise, but present a warning. Given an example report from ICA-AROMA, their classification does not appear to be wonky. All the components look like noise (however, only 7 components were generated, suggesting perhaps there is something amiss in the dimensionality of the data. Within the current framework, try using --ignore-aroma-denoising-errors and hopefully the missing files will generate, but with the consideration that ICA-AROMA may not be a good denoising strategy in these instances.

ICA_AROMA_component_assessment.pdf

@jdkent
Copy link
Collaborator

jdkent commented Oct 19, 2018

I did some playing with my data. We did not have the non steady state volumes removed beforehand, and removing them appears to significantly impact the results of melodic, my previously 7 components became a more typical 55 components, I did not run ica aroma subsequent, but visual inspection indicated there were more noise-like and signal-like components.

@andersonwinkler @oliver-xie, do your data have the non steady state volumes removed or are they still present in the nifti files? If they are still present, then that may be the deeper issue to fix in fmriprep.
This discussion is related to nipreps/fmripost-aroma#13.

@oliver-xie
Copy link

@jdkent, my data still have dummy scans in the nifti files, and the non steady state signals are captured not only by noise-like ICs but present in signal-like ICs as well for ICA-AROMA.

@andersonwinkler
Copy link
Author

andersonwinkler commented Oct 19, 2018

Hi James,

Thanks for looking into this. Yes, same as with Oliver: the initial, non-steady state volumes are still in the file.

I didn't get why you mention that, for AROMA to be useful, it would need a mix of noise and non-noise. If all are noise, what happens is that the difference between the "agressive" and "non-aggressive" denoising strategies disappear: they both become "aggressive". As far as regression goes, it's fine, shouldn't be a problem, that is, maybe there is no need to raise that error then.

Thanks!

All the best,

Anderson

@jdkent
Copy link
Collaborator

jdkent commented Oct 19, 2018

Thanks Anderson, I agree with what you've said; as far as regression goes, identifying everything as noise is a-okay. I wasn't very clear with what I was trying to get at. I'm coming from an assumption that there is structured low frequency signal in the brain that is spatially non-guassian. If all of the generated components are highly correlated with motion, have significant edge/csf fractions, or are all high frequency, then a large amount (perhaps too much) of the variance is attributable to noise. I say perhaps too much because melodic only generates enough components that explain a certain percentage of the variance of the data. Now, the non-steady state volumes demonstrate a large amount of the variance in the data (you don't have signal change like that from any biologically plausible source), and so any component that matches the non-steady state volumes will explain a large portion of the data, perhaps resulting in a greater likelihood of other more interesting components not being selected since they do not explain a significant portion of the variance (relative to the non-steady state volumes).

Coming from that perspective, I currently think that if all the components are identified as noise, then there is something either different with the data (e.g. the non-steady state volumes are included or substantially different acquisition parameters were used that ICA-AROMA wasn't trained on), and/or ica-aroma is being applied incorrectly.

Whether or not that should raise an error, I'm on the fence because as you said all components being identified as noise is not an issue in of itself, but I'm currently of the belief that it is a symptom of a deeper issue that should not be ignored (I'm open to being convinced otherwise).

Best,
James

@andersonwinkler
Copy link
Author

andersonwinkler commented Oct 19, 2018

Hi James,

It would be great if that power were given to the users. No authority (the code in this case) should decide what is better for them. A warning written to a log would be great, if that much, as the number of ICs and ICs classified as noise can always be checked among the outputs.

Same goes for the related nipreps/fmripost-aroma#13: the ultimate decision of allowing the user to choose between not removing initial scans, removing a fixed number, or removing the number detected by the algorithm (potentially different for each subject) is ideal in terms of flexibility, and accommodates more scenarios that users encounter.

I wonder if there are other cases as these, i.e., errors raised that are deliberate in the pursue of a common good... are there? If so, maybe these too could become switches, while keeping sensible defaults that would not raise errors. What do you think?

Thanks!

All the best,

Anderson

@jdkent
Copy link
Collaborator

jdkent commented Oct 19, 2018

Great reasoning, I'm convinced. I think we should raise a warning if all or none components are identified as noise, but the error does rob users of power.
@effigies @oesteban WDYT?

I wonder if there are other cases as these, i.e., errors raised that are deliberate in the pursue of a common good... are there?

I don't think there are other scenarios within fmriprep that behave this way.

If we are all in agreement, would you like to submit a pull request to change the error to a warning?
I think it should be a pretty straightforward pull request, but there may be a couple gotchas to think about. I can help you through the process.

Thanks!

@oesteban
Copy link
Member

I think it would be good to flip the default and turn --ignore-aroma-denoising-errors into something like --error-on-aroma-warnings for users who don't want to miss out these kind of errors.

Also, this new approach should be accompanied by heavy-fat signs on the report that AROMA did not produce a clean output. We want to avoid that these pass overlooked by the user.

@andersonwinkler
Copy link
Author

andersonwinkler commented Oct 26, 2018

Hi all,

Thanks again for looking into this. Just one additional piece of information. When we include "--ignore-aroma-denoising-errors", and the issue of having the same number of IC classified as motion as the total number of ICs, the file *_bold_confounds.tsv is not created.

I think ideally this should not be considered an error at all (i.e., we shouldn't conceptualise it as an error, as in "showing warnings in place of these errors"). These shouldn't be considered errors really. A warning that the number of ICs as motion is the same as all ICs should be sufficient, perhaps with a longer sentence suggesting that the user inspects closely their data.

For now we will exclude 12 subjects from one dataset and 6 from another because of this as we can't move forward otherwise, even though the data per se would be fine.

Thanks all!

Anderson

@jdkent
Copy link
Collaborator

jdkent commented Oct 26, 2018

Hi @andersonwinkler,

I agree, and I think the contribution should be relatively straight forward, would you like to contribute to the project? I would help you along the process.

Also, the most recent pull request (#1335) just merged in should (indirectly) fix the error you are receiving.

@andersonwinkler
Copy link
Author

Hi James,
Absolutely, just let me know how. Thanks!
Anderson

@jdkent
Copy link
Collaborator

jdkent commented Oct 30, 2018

Great! 😃

To start off, you can follow these instructions to get the code on your machine and start making changes (you can reference this issue for your pull request).

  1. The first change is to remove the lines here,

  2. and then we are going to have to depreciate the option --ignore-aroma-denoising-errors and create a new option --error-on-aroma-warnings in the run.py file

  3. and then we are going to have to change the output spec to accommodate the possibility that the return value could be None.

...potentially more steps.

Its best if you start a pull request early so we can continue to walk through the process via the pull request (e.g. just do step number one, include [WIP, FIX] in your pull request title and you can include [skip tests][skip docs][skip ds005][skip ds210][skip ds054] in your commit message since we should make multiple changes before deciding to test the pull request).

I realized after typing this I through a lot of information at you, so please feel free to ask any questions about any steps in the process or just say I'm confused and I will do my best to help.

@andersonwinkler
Copy link
Author

Hi James,
You know already the problem. Could you fix it?
Thanks!
Anderson

@oesteban
Copy link
Member

Hi @jdkent, I'd like to revamp this issue. Do you have the bandwidth and appetite to look into this?

@jdkent
Copy link
Collaborator

jdkent commented Jan 12, 2019

Yeah, I can pick this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants