Getting fmriprep outputs into fsLR32k space - viewing issue

Summary of what happened:

I have been working on a mini pipeline to get fmriprep outputs in the native volume space (will change to post-processed data in the same space later) onto the fsLR32k surface for use in templateICAr. The pipeline runs, but I am having trouble checking the surface quality in workbench because my final functional surface does not seem to map onto a volume space. I am wondering, must there be a volume that matches the final surface I am viewing in workbench? If so, how can I identify the appropriate volume?

Also, I believe step (4) is creating a registration gifti from subject’s native freesurfer surface space to fsLR32k space, but it is not clear to me from the documentation. Does anyone know for sure if this is the case?

Note: I came up with the steps for the pipeline using a very helpful pdf I found online (Resampling-FreeSurfer-HCP.pdf) and ChatGPT.

The pipeline:

ssfreedir="/projects/b1108/studies/mwmh/data/processed/neuroimaging/fmriprep_23.1.4/sourcedata/freesurfer/sub-"${subid}
ssprepdir="/projects/b1108/studies/mwmh/data/processed/neuroimaging/fmriprep_23.1.4/sub-"${subid}"/ses-"${sesid}
sssurfdir="/projects/b1108/studies/mwmh/data/processed/neuroimaging/surf/sub-"${subid}"/ses-"${sesid}
hcptempdir=""
export SUBJECTS_DIR="/projects/b1108/studies/mwmh/data/processed/neuroimaging/fmriprep_23.1.4/sourcedata/freesurfer"
tfdir="/projects/b1108/templateflow"
fslrdir=${tfdir}"/tpl-fsLR"


##### 1) Project the subject's BOLD data to their native freesurfer surface
mri_vol2surf --src ${ssprepdir}/func/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold.nii.gz \
  --out ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.mgh \
  --regheader sub-${subid} --hemi lh
mri_vol2surf --src ${ssprepdir}/func/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold.nii.gz \
  --out ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_rh.mgh \
  --regheader sub-${subid} --hemi rh

# View the BOLD data on the subject's native freesurfer surface
freeview -f ${SUBJECTS_DIR}/sub-${subid}/surf/lh.pial:overlay=${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.mgh:overlay_threshold=2,5

##### 2) Convert the freesurfer spherical surface to gifti format
mris_convert ${ssfreedir}/surf/lh.sphere ${sssurfdir}/lh.sphere.gii
mris_convert ${ssfreedir}/surf/rh.sphere ${sssurfdir}/rh.sphere.gii

##### 3) Convert the BOLD data on the subject's native freesurfer surface to gifti format
mri_convert ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.mgh \
  ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.func.gii
mri_convert ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_rh.mgh \
  ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_rh.func.gii

##### 4) Get registration gifti from subject's native freesurfer surface space
#####    to fsLR32k space (?)
wb_shortcuts -freesurfer-resample-prep ${ssfreedir}/surf/lh.white \
  ${ssfreedir}/surf/lh.pial \
  ${ssfreedir}/surf/lh.sphere.reg \
  ${hcptempdir}/fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii \
  ${sssurfdir}/lh.midthickness.surf.gii \
  ${sssurfdir}/sub-${subid}.L.midthickness.32k_fs_LR.surf.gii \
  ${sssurfdir}/lh.sphere.reg.surf.gii
wb_shortcuts -freesurfer-resample-prep ${ssfreedir}/surf/rh.white \
  ${ssfreedir}/surf/rh.pial \
  ${ssfreedir}/surf/rh.sphere.reg \
  ${hcptempdir}/fs_LR-deformed_to-fsaverage.R.sphere.32k_fs_LR.surf.gii \
  ${sssurfdir}/rh.midthickness.surf.gii \
  ${sssurfdir}/sub-${subid}.R.midthickness.32k_fs_LR.surf.gii \
  ${sssurfdir}/rh.sphere.reg.surf.gii

##### 5) Use the registration gifti from (4) to project the BOLD data on the
#####    subject's native freesurfer surface to fsLR32k space
wb_command -metric-resample ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.func.gii \
  ${sssurfdir}/lh.sphere.reg.surf.gii \
  ${hcptempdir}/fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii \
  ADAP_BARY_AREA \
  ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.L.32k_fs_LR.func.gii \
  -area-surfs ${sssurfdir}/lh.midthickness.surf.gii \
  ${sssurfdir}/sub-${subid}.L.midthickness.32k_fs_LR.surf.gii
wb_command -metric-resample ${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_rh.func.gii \
  ${sssurfdir}/rh.sphere.reg.surf.gii \
  ${hcptempdir}/fs_LR-deformed_to-fsaverage.R.sphere.32k_fs_LR.surf.gii \
  ADAP_BARY_AREA \
  ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.R.32k_fs_LR.func.gii \
  -area-surfs ${sssurfdir}/rh.midthickness.surf.gii \
  ${sssurfdir}/sub-${subid}.R.midthickness.32k_fs_LR.surf.gii

##### 6)
wb_command -set-structure ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.L.32k_fs_LR.func.gii CORTEX_LEFT
wb_command -set-structure ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.R.32k_fs_LR.func.gii CORTEX_RIGHT

# View the BOLD data on the fsLR32k surface
wb_view ${sssurfdir}/sub-${subid}.L.midthickness.32k_fs_LR.surf.gii \
  ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.L.32k_fs_LR.func.gii \
  ${sssurfdir}/sub-${subid}.R.midthickness.32k_fs_LR.surf.gii \
  ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.R.32k_fs_LR.func.gii \
  ${ssprepdir}/anat/sub-${subid}_ses-${sesid}_desc-preproc_T1w.nii.gz


wb_command -file-information ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.L.32k_fs_LR.func.gii
# returns "Maps to Volume:           false"

Version:

Freesurfer: 7.4.1
Connectome Workbench: 1.5.0
fMRIPrep: 23.1.4

Environment (Docker, Singularity, custom installation):

Local

Data formatted according to a validatable standard? Please provide the output of the validator:

BIDS

Screenshots / relevant information:

freeview -f ${SUBJECTS_DIR}/sub-${subid}/surf/lh.pial:overlay=${sssurfdir}/sub-${subid}_ses-${sesid}_task-rest_space-T1w_desc-preproc_bold_lh.mgh:overlay_threshold=2,5
returns


and

wb_view ${sssurfdir}/sub-${subid}.L.midthickness.32k_fs_LR.surf.gii \ ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.L.32k_fs_LR.func.gii \ ${sssurfdir}/sub-${subid}.R.midthickness.32k_fs_LR.surf.gii \ ${sssurfdir}/sub-${subid}_ses-${sesid}.task-rest.R.32k_fs_LR.func.gii \ ${ssprepdir}/anat/sub-${subid}_ses-${sesid}_desc-preproc_T1w.nii.gz
returns


so clearly ${ssprepdir}/anat/sub-${subid}_ses-${sesid}_desc-preproc_T1w.nii.gz is not the corresponding volume space.

Sorry, forgot to put the path for hcptempdir: hcptempdir="/projects/b1108/hcp/global/templates/standard_mesh_atlases/resample_fsaverage"

Hi @butellyn,

Not a direct answer to your question, but is there a reason you are not using the --cifti-output 91k --project-goodvoxels flags in fMRIPrep? The outputs will be fsLR32k ciftis, and all the interpolation happens in one instance, as opposed to the additional layer you are imposing here.

Best,
Steven

Hi Steven,

I have created that output as well (but without the --project-goodvoxels flag; hadn’t heard of that one), but my post-processing script is currently in the volume space. I am not sure if it is adaptable to the surface space and I don’t have the bandwidth to try to adapt it in the near future. If you’re aware of a post processing script that works with fsLR32k ciftis, I’d love to try it out!

Best,
Ellyn

Hi @butellyn,

Ah sorry, I didn’t see the part where you said you will be putting this pipeline on postprocessed data (not directly on the fmriprep BOLD outputs). Fitlins can run GLMs on CIFTI data, if that would solve your issues.

Best,
Steven

Hi Steven,

My postprocessing pipeline has censoring and interpolating in it as well right now. Ideally, I’d like to keep that. But if it turns out to be undoable, I’ll take a look!

Best,
Ellyn

Is this for task or resting state? XCP_D should be able to return a denoised time series after censoring and interpolating that is more suitable for resting state / naturalistic data. If task, Fitlins can include a motion outliers column for censoring, although it won’t interpolate over them.

1 Like

I’m combining resting state with task-regressed data. I can give those two a look. It sounds like it might be helpful for me to look at the fmriprep codebase to see how they get their data onto the fsLR32k surface, though. I’d like to figure out how to get this surface pipeline working, even if it isn’t the ultimate solution.