Fitlins crashes with a "Non-unique BOLD file in /data with entities" error message

Hello there,

I am running fitlins for the first time. I managed to get results on a single subject/single session and I tried to extend my work to a a multi-subject multi-session study.
It is a neurofeedback study where 15 subjects did 5 training sessions with 3 runs in each session (except the last session where only 2 runs were made).

This is the dataset :point_down: for a single subject.
It went :ok: throught bids-validator@1.9.9 :+1:

sub-02/
β”œβ”€β”€ ses-S1
β”‚   β”œβ”€β”€ anat
β”‚   β”‚   β”œβ”€β”€ sub-02_ses-S1_T1w.json
β”‚   β”‚   └── sub-02_ses-S1_T1w.nii.gz
β”‚   └── func
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_bold.nii.gz
β”‚       └── sub-02_ses-S1_task-NF_run-03_events.tsv
β”œβ”€β”€ ses-S2
β”‚   β”œβ”€β”€ anat
β”‚   β”‚   β”œβ”€β”€ sub-02_ses-S2_T1w.json
β”‚   β”‚   └── sub-02_ses-S2_T1w.nii.gz
β”‚   └── func
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-01_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-01_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-01_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-02_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-02_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-02_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-03_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S2_task-NF_run-03_bold.nii.gz
β”‚       └── sub-02_ses-S2_task-NF_run-03_events.tsv
β”œβ”€β”€ ses-S3
β”‚   └── func
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-01_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-01_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-01_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-02_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-02_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-02_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-03_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S3_task-NF_run-03_bold.nii.gz
β”‚       └── sub-02_ses-S3_task-NF_run-03_events.tsv
β”œβ”€β”€ ses-S4
β”‚   β”œβ”€β”€ anat
β”‚   β”‚   β”œβ”€β”€ sub-02_ses-S4_T1w.json
β”‚   β”‚   └── sub-02_ses-S4_T1w.nii.gz
β”‚   └── func
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-01_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-01_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-01_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-02_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-02_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-02_events.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-03_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S4_task-NF_run-03_bold.nii.gz
β”‚       └── sub-02_ses-S4_task-NF_run-03_events.tsv
└── ses-S5
    β”œβ”€β”€ anat
    β”‚   β”œβ”€β”€ sub-02_ses-S5_T1w.json
    β”‚   └── sub-02_ses-S5_T1w.nii.gz
    └── func
        β”œβ”€β”€ sub-02_ses-S5_task-NF_run-01_bold.json
        β”œβ”€β”€ sub-02_ses-S5_task-NF_run-01_bold.nii.gz
        β”œβ”€β”€ sub-02_ses-S5_task-NF_run-01_events.tsv
        β”œβ”€β”€ sub-02_ses-S5_task-NF_run-02_bold.json
        β”œβ”€β”€ sub-02_ses-S5_task-NF_run-02_bold.nii.gz
        └── sub-02_ses-S5_task-NF_run-02_events.tsv

The dataset was processed with fmriprep and this is is the content of the fmriprep output folder (for a single session) :point_down:

sub-02/
|── ses-S1
β”‚   β”œβ”€β”€ anat
β”‚   β”‚   └── sub-02_ses-S1_from-orig_to-T1w_mode-image_xfm.txt
β”‚   └── func
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_desc-confounds_timeseries.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_desc-confounds_timeseries.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_from-scanner_to-boldref_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_from-scanner_to-T1w_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_from-T1w_to-scanner_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-aparcaseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-aseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-brain_mask.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_desc-confounds_timeseries.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_desc-confounds_timeseries.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_from-scanner_to-boldref_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_from-scanner_to-T1w_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_from-T1w_to-scanner_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-aparcaseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-aseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-brain_mask.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-preproc_bold.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-02_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_desc-confounds_timeseries.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_desc-confounds_timeseries.tsv
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_from-scanner_to-boldref_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_from-scanner_to-T1w_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_from-T1w_to-scanner_mode-image_xfm.txt
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_boldref.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-aparcaseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-aseg_dseg.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-brain_mask.json
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz
β”‚       β”œβ”€β”€ sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-preproc_bold.json
β”‚       └── sub-02_ses-S1_task-NF_run-03_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz

:computer: This is the fitlins command I ran on a HPC

source .env  # I declare paths variables here (data_dir, work_dir, ...)

# Loading modules 
. /etc/profile.d/modules.sh
module load spack/singularity

singularity run --cleanenv \
    -B ${data_dir}:/data:ro \
    -B ${deri_dir}/fitlins:/outputs \
    -B ${deri_dir}/fmriprep:/fmriprep \
    -B ${work_dir}:/work \
    -B ${model_dir}:/model_dir \
    ${nas_dir}/fitlins-0.11.0.sif \
    /data \
    /outputs \
    dataset \
    -d /fmriprep \
    -m /model_dir/model_fitlins.json \
    --estimator nilearn \
    -w /work \
    --smoothing 5:dataset:iso

This is the model_fitlins.json file content :point_down: where I define a single contrast NF vs rest.

{
    "Name":"HEMISFER",
    "BIDSModelVersion":"1.0.0",
    "Description":"HEMISFER NF",
    "Input":{"task":"NF"},
    "Nodes":
    [
        {
            "Level":"Run",
            "Name":"subject",
            "GroupBy":["run","subject"],
            "Transformations":
            {
                "Transformer":"pybids-transforms-v1",
                "Instructions":[{"Name":"Factor","Input":["trial_type"]},{"Name":"Convolve","Input":["trial_type.NF","trial_type.rest"],"Model":"spm"}]
            },
            "Model":{ "X":["trial_type.NF","trial_type.rest","framewise_displacement","trans_x", "trans_y", "trans_z","rot_x", "rot_y", "rot_z","a_comp_cor_00", "a_comp_cor_01","a_comp_cor_02", "a_comp_cor_03","a_comp_cor_04", "a_comp_cor_05",1],"Type":"glm"},
            "DummyContrasts":{"Contrasts":["trial_type.NF","trial_type.rest"],"Test":"t"},
            "Contrasts":[{"Name":"NF_vs_rest","ConditionList":["trial_type.NF","trial_type.rest"],"Weights":[1,-1],"Test":"t"}]
        },
        {
            "Level":"Dataset",
            "Name":"t-test",
            "GroupBy":["contrast"],
            "Model":{"X":[1],"Type":"glm"},
            "DummyContrasts":{"Test":"t"}
        }
    ],
    "Edges":
    [
        {
            "Source":"subject",
            "Destination":"t-test",
            "Filter":{"contrast":["NF_vs_rest"]}
        }
    ]
}

:x: This is the error I get :point_down:

Traceback:
	Traceback (most recent call last):
	  File "/opt/miniconda-latest/envs/neuro/lib/python3.9/site-packages/nipype/interfaces/base/core.py", line 398, in run
	    runtime = self._run_interface(runtime)
	  File "/opt/miniconda-latest/envs/neuro/lib/python3.9/site-packages/fitlins/interfaces/bids.py", line 373, in _run_interface
	    raise ValueError(
	ValueError: Non-unique BOLD file in /data with entities {'desc': 'preproc', 'task': 'NF', 'run': 1, 'subject': '02', 'suffix': 'bold', 'space': 'MNI152NLin2009cAsym', 'extension': ['.nii', '.nii.gz', '.dtseries.nii', '.func.gii']}.
	Matches:
		/fmriprep/sub-02/ses-S1/func/sub-02_ses-S1_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz ({'DelayTime': 0.01749999999999996, 'RepetitionTime': 1, 'SkullStripped': True, 'SliceTimingCorrected': True, 'StartTime': 0.46, 'TaskName': 'NF', 'datatype': 'func', 'desc': 'preproc', 'extension': '.nii.gz', 'run': 01, 'session': 'S1', 'space': 'MNI152NLin2009cAsym', 'subject': '02', 'suffix': 'bold', 'task': 'NF'})
		/fmriprep/sub-02/ses-S2/func/sub-02_ses-S2_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz ({'DelayTime': 0.01749999999999996, 'RepetitionTime': 1, 'SkullStripped': True, 'SliceTimingCorrected': True, 'StartTime': 0.46, 'TaskName': 'NF', 'datatype': 'func', 'desc': 'preproc', 'extension': '.nii.gz', 'run': 01, 'session': 'S2', 'space': 'MNI152NLin2009cAsym', 'subject': '02', 'suffix': 'bold', 'task': 'NF'})
		/fmriprep/sub-02/ses-S3/func/sub-02_ses-S3_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz ({'DelayTime': 0.01749999999999996, 'RepetitionTime': 1, 'SkullStripped': True, 'SliceTimingCorrected': True, 'StartTime': 0.46, 'TaskName': 'NF', 'datatype': 'func', 'desc': 'preproc', 'extension': '.nii.gz', 'run': 01, 'session': 'S3', 'space': 'MNI152NLin2009cAsym', 'subject': '02', 'suffix': 'bold', 'task': 'NF'})
		/fmriprep/sub-02/ses-S4/func/sub-02_ses-S4_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz ({'DelayTime': 0.022499999999999964, 'RepetitionTime': 1, 'SkullStripped': True, 'SliceTimingCorrected': True, 'StartTime': 0.459, 'TaskName': 'NF', 'datatype': 'func', 'desc': 'preproc', 'extension': '.nii.gz', 'run': 01, 'session': 'S4', 'space': 'MNI152NLin2009cAsym', 'subject': '02', 'suffix': 'bold', 'task': 'NF'})
		/fmriprep/sub-02/ses-S5/func/sub-02_ses-S5_task-NF_run-01_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz ({'DelayTime': 0.022499999999999964, 'RepetitionTime': 1, 'SkullStripped': True, 'SliceTimingCorrected': True, 'StartTime': 0.459, 'TaskName': 'NF', 'datatype': 'func', 'desc': 'preproc', 'extension': '.nii.gz', 'run': 01, 'session': 'S5', 'space': 'MNI152NLin2009cAsym', 'subject': '02', 'suffix': 'bold', 'task': 'NF'})

While I understand the meaning of the error message, I am not too sure how I should edit my data structure to make it work.

Would any one have some feedback regarding my issue ?

My feeling is that it might come from the model specification. I guess the β€œsession” level is not specified…

Thank you very much for your help.
Quentin

Just hunch but maybe you should group by β€œsubject”, β€œrun” and β€œsession” rather than just by subject and run.

1 Like

Hello RΓ©mi.
Thank you very much, that was the right fix. It is running fine.
All the best.
Quentin

1 Like