Skip to content

ENH: Add option to exclude projecting high variance voxels to surface #2855

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

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/workflows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,8 @@ EPI sampled to FreeSurfer surfaces
wf = init_bold_surf_wf(
mem_gb=1,
surface_spaces=['fsnative', 'fsaverage5'],
medial_surface_nan=False)
medial_surface_nan=False,
project_goodvoxels=False)

If FreeSurfer processing is enabled, the motion-corrected functional series
(after single shot resampling to T1w space) is sampled to the
Expand All @@ -488,6 +489,13 @@ surface, is sampled at 6 intervals and averaged.

Surfaces are generated for the "subject native" surface, as well as transformed to the
``fsaverage`` template space.

The flag ``--project_goodvoxels``, when enabled, excludes voxels whose timeseries have
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The flag ``--project_goodvoxels``, when enabled, excludes voxels whose timeseries have
The flag ``--project-goodvoxels``, when enabled, excludes voxels whose timeseries have

locally high coefficient of variation from the sampling to surface, by similar process
to `HCP Pipelines_`.



All surface outputs are in GIFTI format.

HCP Grayordinates
Expand Down
9 changes: 9 additions & 0 deletions fmriprep/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,15 @@ def _slice_time_ref(value, parser):
help="Replace medial wall values with NaNs on functional GIFTI files. Only "
"performed for GIFTI files mapped to a freesurfer subject (fsaverage or fsnative).",
)
g_conf.add_argument(
"--project-goodvoxels",
required=False,
action="store_true",
default=False,
help="Exclude voxels whose timeseries have locally high coefficient of variation "
"from surface resampling. Only performed for GIFTI files mapped to a freesurfer subject "
"(fsaverage or fsnative).",
)
g_conf.add_argument(
"--slice-time-ref",
required=False,
Expand Down
2 changes: 2 additions & 0 deletions fmriprep/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,8 @@ class workflow(_Config):
"""Run FreeSurfer ``recon-all`` with the ``-logitudinal`` flag."""
medial_surface_nan = None
"""Fill medial surface with :abbr:`NaNs (not-a-number)` when sampling."""
project_goodvoxels = False
"""Exclude voxels with locally high coefficient of variation from sampling."""
regressors_all_comps = None
"""Return all CompCor components."""
regressors_dvars_th = None
Expand Down
1 change: 1 addition & 0 deletions fmriprep/data/tests/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ hires = true
ignore = []
longitudinal = false
medial_surface_nan = false
project_goodvoxels = false
regressors_all_comps = false
regressors_dvars_th = 1.5
regressors_fd_th = 0.5
Expand Down
133 changes: 133 additions & 0 deletions fmriprep/interfaces/volume.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""This module provides interfaces for workbench volume commands"""
import os

from nipype.interfaces.base import TraitedSpec, File, traits, CommandLineInputSpec
from nipype.interfaces.workbench.base import WBCommand
from nipype import logging

iflogger = logging.getLogger("nipype.interface")


class CreateSignedDistanceVolumeInputSpec(CommandLineInputSpec):
surf_file = File(
exists=True,
mandatory=True,
argstr="%s",
position=0,
desc="Input surface GIFTI file (.surf.gii)",
)
ref_file = File(
exists=True,
mandatory=True,
argstr="%s",
position=1,
desc="NIfTI volume in the desired output space (dims, spacing, origin)",
)
out_file = File(
name_source=["surface"],
name_template="%s_distvol.nii.gz",
argstr="%s",
position=2,
desc="Name of output volume containing signed distances",
)
out_mask = File(
name_source=["surface"],
name_template="%s_distmask.nii.gz",
argstr="-roi-out %s",
desc="Name of file to store a mask where the ``out_file`` has a computed value",
)
fill_value = traits.Float(
mandatory=False,
default=0.,
usedefault=True,
argstr="-fill-value %f",
desc="value to put in all voxels that don't get assigned a distance",
)
exact_limit = traits.Float(
default=5.,
usedefault=True,
argstr="-exact-limit %f",
desc="distance for exact output in mm",
)
approx_limit = traits.Float(
default=20.,
usedefault=True,
argstr="-approx-limit %f",
desc="distance for approximate output in mm",
)
approx_neighborhood = traits.Int(
default=2,
usedefault=True,
argstr="-approx-neighborhood %d",
desc="size of neighborhood cube measured from center to face in voxels, default 2 = 5x5x5",
)
winding_method = traits.Enum(
"EVEN_ODD",
"NEGATIVE",
"NONZERO",
"NORMALS",
argstr="-winding %s",
usedefault=True,
desc="winding method for point inside surface test"
)

class CreateSignedDistanceVolumeOutputSpec(TraitedSpec):
out_file = File(desc="Name of output volume containing signed distances")
out_mask = File(desc="Name of file to store a mask where the ``out_file`` has a computed value")


class CreateSignedDistanceVolume(WBCommand):
"""CREATE SIGNED DISTANCE VOLUME FROM SURFACE
wb_command -create-signed-distance-volume
<surface> - the input surface
<refspace> - a volume in the desired output space (dims, spacing, origin)
<outvol> - output - the output volume

[-roi-out] - output an roi volume of where the output has a computed
value
<roi-vol> - output - the output roi volume

[-fill-value] - specify a value to put in all voxels that don't get
assigned a distance
<value> - value to fill with (default 0)

[-exact-limit] - specify distance for exact output
<dist> - distance in mm (default 5)

[-approx-limit] - specify distance for approximate output
<dist> - distance in mm (default 20)

[-approx-neighborhood] - voxel neighborhood for approximate calculation
<num> - size of neighborhood cube measured from center to face, in
voxels (default 2 = 5x5x5)

[-winding] - winding method for point inside surface test
<method> - name of the method (default EVEN_ODD)

Computes the signed distance function of the surface. Exact distance is
calculated by finding the closest point on any surface triangle to the
center of the voxel. Approximate distance is calculated starting with
these distances, using dijkstra's method with a neighborhood of voxels.
Specifying too small of an exact distance may produce unexpected results.
Valid specifiers for winding methods are as follows:

EVEN_ODD (default)
NEGATIVE
NONZERO
NORMALS

The NORMALS method uses the normals of triangles and edges, or the
closest triangle hit by a ray from the point. This method may be
slightly faster, but is only reliable for a closed surface that does not
cross through itself. All other methods count entry (positive) and exit
(negative) crossings of a vertical ray from the point, then counts as
inside if the total is odd, negative, or nonzero, respectively.

"""

input_spec = CreateSignedDistanceVolumeInputSpec
output_spec = CreateSignedDistanceVolumeOutputSpec
_cmd = "wb_command -create-signed-distance-volume"
Loading