Summary of what happened:
For a longitudinal fMRI study with children, I’ve created a study-specific template using the FreeSurfer longitudinal pipeline. I would like to use the generated FreeSurfer surfaces as a (non-standard) output space with fMRIPrep so that I can analyze the functional data in this custom study-specific surface space.
As pointed out in here, here, and here, it is possible to specify custom templates as --output-spaces if one puts them into the TemplateFlow home directory in the correct format as expected by TemplateFlow. However, this only seems to work for volumetric templates (e.g., a NIfTI-converted version of FreeSurfer’s brain.mgz), not for surface templates (e.g., GIfTI-converted versions of FreeSurfers *.lh/*.rh files).
I’ve tried adding all the NIfTI/GIfTI converted FreeSurfer outputs to a custom TemplateFlow template directory that now has a structure similar to tpl-fsaverge, but for my custom template (here called tpl-fslong):
/templateflow_home/tpl-fslong
├─ template_description.json
├─ tpl-fslong_hemi-L_den-164k_inflated.surf.gii
├─ tpl-fslong_hemi-L_den-164k_pial.surf.gii
├─ tpl-fslong_hemi-L_den-164k_smoothwm.surf.gii
├─ tpl-fslong_hemi-L_den-164k_sphere.surf.gii
├─ tpl-fslong_hemi-L_den-164k_white.surf.gii
├─ tpl-fslong_hemi-R_den-164k_inflated.surf.gii
├─ tpl-fslong_hemi-R_den-164k_pial.surf.gii
├─ tpl-fslong_hemi-R_den-164k_smoothwm.surf.gii
├─ tpl-fslong_hemi-R_den-164k_sphere.surf.gii
├─ tpl-fslong_hemi-R_den-164k_white.surf.gii
├─ tpl-fslong_res-01_desc-brain_mask.nii.gz
└─ tpl-fslong_res-01_T1w.nii.gz
However, when now specifying --output-spaces fslong, fMRIPrep automatically treats this as volume space (tpl-fslong:res-01) and aligns things to the volumetric tpl-fslong_res-01_T1w.nii.gz file (ignoring the surface files). When specifically asking for a mesh density (i.e., --output_spaces fslong:den164k), fMRIPrep complains about ValueError: 'den' is not a recognized entity.
I assume it’s currently simply not possible to normalize to custom surface templates, only to the “special” fsaverage and fsnative? If so, are there any plans to make this possible in the future, or do you have any ideas for a workaround to map the preprocessed functional data to a custom surface template?
Thanks a lot in advance for your help and for all the efforts your putting into these amazing software packages!
Command used (and if a helper script was used, a link to the helper script or the command generated):
fmriprep \
/bids_dir \
/bids_dir/derivatives/fmriprep \
participant \
--participant-label sub-SA27 \
--output-spaces T1w MNIPediatricAsym:cohort-2 fsnative fsaverage fslong \
--fs-license-file /bids_dir/code/license.txt \
Version:
fMRIPrep 21.0.2
Environment (Docker, Singularity, custom installation):
Singularity container from the ReproNim container collection
Relevant log outputs (more than 20 lines, I’m sorry!):
When using --output-spaces fslong, fMRIPrep runs through but only outputs stuff in volumetric template-aligned space:
add(ok): fmriprep/sub-SA27/figures/sub-SA27_ses-01_run-1_space-fslong_T1w.svg (file)
add(ok): fmriprep/sub-SA27/log/20230306-085704_a2c1a596-a393-4e3b-8a49-97285a05ef93/fmriprep.toml (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_from-T1w_to-fslong_mode-image_xfm.h5 (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_from-fslong_to-T1w_mode-image_xfm.h5 (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_desc-brain_mask.json (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_desc-brain_mask.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_desc-preproc_T1w.json (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_desc-preproc_T1w.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_dseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_label-CSF_probseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_label-GM_probseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/anat/sub-SA27_ses-01_run-1_space-fslong_label-WM_probseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_boldref.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-aparcaseg_dseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-aseg_dseg.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-brain_mask.json (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-brain_mask.nii.gz (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-preproc_bold.json (file)
add(ok): fmriprep/sub-SA27/ses-01/func/sub-SA27_ses-01_task-language_run-1_space-fslong_desc-preproc_bold.nii.gz (file)
...
When using --output-spaces fslong:den-164k, fMRIPrep returns the following error (because it’s still treating fslong:den-164 as a volumetric template):
230306-13:32:39,480 nipype.workflow WARNING:
[Node] Error on "fmriprep_wf.single_subject_SA27_wf.func_preproc_ses_01_task_language_run_1_wf.bold_std_trans_wf.select_tpl" (/ptmp/aenge/tmp/work_job_6551480/fmriprep_wf/single_subject_SA27_wf/func_preproc_ses_01_task_language_run_1_wf/bold_std_trans_wf/_std_target_fslong.den164k.resnative/select_tpl)
230306-13:32:39,484 nipype.workflow ERROR:
Node select_tpl.a1 failed to run on host co6508.
230306-13:32:39,484 nipype.workflow ERROR:
Saving crash info to /ptmp/aenge/tmp/ds_job_6551480/derivatives/fmriprep/sub-SA27/log/20230306-133005_1465a266-40d8-4454-bbe3-2812a11b09dc/crash-20230306-133239-aenge-select_tpl.a1-22bae3a5-2649-4a66-8328-cff6221bdb03.txt
Traceback (most recent call last):
File "/opt/conda/lib/python3.8/site-packages/nipype/pipeline/plugins/multiproc.py", line 344, in _send_procs_to_workers
self.procs[jobid].run(updatehash=updatehash)
File "/opt/conda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 516, in run
result = self._run_interface(execute=True)
File "/opt/conda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 635, in _run_interface
return self._run_command(execute)
File "/opt/conda/lib/python3.8/site-packages/nipype/pipeline/engine/nodes.py", line 741, in _run_command
result = self._interface.run(cwd=outdir)
File "/opt/conda/lib/python3.8/site-packages/nipype/interfaces/base/core.py", line 428, in run
runtime = self._run_interface(runtime)
File "/opt/conda/lib/python3.8/site-packages/nipype/interfaces/utility/wrappers.py", line 142, in _run_interface
out = function_handle(**args)
File "<string>", line 18, in _select_template
File "/opt/conda/lib/python3.8/site-packages/niworkflows/utils/misc.py", line 79, in get_template_specs
tpl_target_path = get_template(in_template, **template_spec)
File "/opt/conda/lib/python3.8/site-packages/templateflow/conf/__init__.py", line 31, in wrapper
return func(*args, **kwargs)
File "/opt/conda/lib/python3.8/site-packages/templateflow/api.py", line 66, in get
Path(p) for p in TF_LAYOUT.get(template=template, return_type="file", **kwargs)
File "/opt/conda/lib/python3.8/site-packages/bids/layout/layout.py", line 619, in get
raise ValueError(msg + "If you're sure you want to impose "
ValueError: 'den' is not a recognized entity. Did you mean ['density']? If you're sure you want to impose this constraint, set invalid_filters='allow'.