Skip to content

Commit

Permalink
Track proximal sources of functional GIFTIs (#3263)
Browse files Browse the repository at this point in the history
Related to #3261.

## Changes proposed in this pull request

- Add an outputnode to `init_ds_volumes_wf` with the saved `bold` path.
- Add `sources` field to `init_bold_surf_wf`'s inputnode.
- Infer Sources for functional GIFTI outputs.
- If the user has requested T1w-space outputs, then this should be
`bold` from the associated `ds_volumes_wf` and `fsnative2t1w_xfm`
- If the user didn't want T1w-space volumetric outputs, then this should
be the raw BOLD file, `motion_xfm`, `boldref2anat_xfm`,
`fsnative2t1w_xfm`.
  • Loading branch information
tsalo authored Mar 29, 2024
1 parent ecf8580 commit 123c3f8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
19 changes: 19 additions & 0 deletions fmriprep/workflows/bold/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,25 @@ def init_bold_wf(
(bold_anat_wf, bold_surf_wf, [('outputnode.bold_file', 'inputnode.bold_t1w')]),
]) # fmt:skip

# sources are bold_file, motion_xfm, boldref2anat_xfm, fsnative2t1w_xfm
merge_surface_sources = pe.Node(
niu.Merge(4),
name='merge_surface_sources',
run_without_submitting=True,
)
merge_surface_sources.inputs.in1 = bold_file
workflow.connect([
(bold_fit_wf, merge_surface_sources, [
('outputnode.motion_xfm', 'in2'),
('outputnode.boldref2anat_xfm', 'in3'),
]),
(inputnode, merge_surface_sources, [
('fsnative2t1w_xfm', 'in4'),
]),
]) # fmt:skip

workflow.connect([(merge_surface_sources, bold_surf_wf, [('out', 'inputnode.sources')])])

if config.workflow.cifti_output:
from .resampling import (
init_bold_fsLR_resampling_wf,
Expand Down
30 changes: 22 additions & 8 deletions fmriprep/workflows/bold/resampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
from niworkflows.interfaces.fixes import FixHeaderApplyTransforms as ApplyTransforms
from niworkflows.interfaces.freesurfer import MedialNaNs

from ... import config
from ...config import DEFAULT_MEMORY_MIN_GB
from ...interfaces.bids import BIDSURI
from ...interfaces.workbench import MetricDilate, MetricMask, MetricResample
from ...utils.bids import dismiss_echo
from .outputs import prepare_timing_parameters
Expand Down Expand Up @@ -93,6 +95,8 @@ def init_bold_surf_wf(
------
source_file
Original BOLD series
sources
List of files used to create the output files.
bold_t1w
Motion-corrected BOLD series in T1 space
subjects_dir
Expand Down Expand Up @@ -128,6 +132,7 @@ def init_bold_surf_wf(
niu.IdentityInterface(
fields=[
'source_file',
'sources',
'bold_t1w',
'subject_id',
'subjects_dir',
Expand All @@ -139,6 +144,15 @@ def init_bold_surf_wf(
itersource = pe.Node(niu.IdentityInterface(fields=['target']), name='itersource')
itersource.iterables = [('target', surface_spaces)]

surfs_sources = pe.Node(
BIDSURI(
numinputs=1,
dataset_links=config.execution.dataset_links,
out_dir=str(config.execution.fmriprep_dir.absolute()),
),
name='surfs_sources',
)

get_fsnative = pe.Node(FreeSurferSource(), name='get_fsnative', run_without_submitting=True)

def select_target(subject_id, space):
Expand Down Expand Up @@ -212,6 +226,8 @@ def select_target(subject_id, space):
(itk2lta, sampler, [('out_inv', 'reg_file')]),
(targets, sampler, [('out', 'target_subject')]),
(inputnode, ds_bold_surfs, [('source_file', 'source_file')]),
(inputnode, surfs_sources, [('sources', 'in1')]),
(surfs_sources, ds_bold_surfs, [('out', 'Sources')]),
(itersource, ds_bold_surfs, [('target', 'space')]),
(update_metadata, ds_bold_surfs, [('out_file', 'in_file')]),
]) # fmt:skip
Expand Down Expand Up @@ -488,14 +504,12 @@ def _calc_lower_thr(in_stats):
)

# apply goodvoxels ribbon mask to bold
workflow.connect(
[
(goodvoxels_mask, goodvoxels_ribbon_mask, [('out_file', 'in_file')]),
(ribbon_boldsrc_xfm, goodvoxels_ribbon_mask, [('output_image', 'mask_file')]),
(goodvoxels_mask, outputnode, [('out_file', 'goodvoxels_mask')]),
(goodvoxels_ribbon_mask, outputnode, [('out_file', 'goodvoxels_ribbon')]),
]
)
workflow.connect([
(goodvoxels_mask, goodvoxels_ribbon_mask, [('out_file', 'in_file')]),
(ribbon_boldsrc_xfm, goodvoxels_ribbon_mask, [('output_image', 'mask_file')]),
(goodvoxels_mask, outputnode, [('out_file', 'goodvoxels_mask')]),
(goodvoxels_ribbon_mask, outputnode, [('out_file', 'goodvoxels_ribbon')]),
]) # fmt:skip

return workflow

Expand Down

0 comments on commit 123c3f8

Please sign in to comment.