Skip to content

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

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

Merged
merged 13 commits into from
Apr 13, 2023

Conversation

madisoth
Copy link
Contributor

Adds option --project-goodvoxels.

If enabled, voxels whose timeseries have locally high coefficient of variation, or which lie outside the cortex (based on signed distance volumes generated from the WM and pial surfaces), are excluded from volume-to-surface sampling of BOLD timeseries.

Note that unlike HCP / ciftify, no dilation or spatial smoothing is applied to the surface-resampled BOLD timeseries

@codecov-commenter
Copy link

codecov-commenter commented Sep 15, 2022

Codecov Report

Base: 30.70% // Head: 31.52% // Increases project coverage by +0.81% 🎉

Coverage data is based on head (ba5bac8) compared to base (177de34).
Patch coverage: 29.73% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #235      +/-   ##
==========================================
+ Coverage   30.70%   31.52%   +0.81%     
==========================================
  Files          43       49       +6     
  Lines        3696     4634     +938     
==========================================
+ Hits         1135     1461     +326     
- Misses       2561     3173     +612     
Impacted Files Coverage Δ
nibabies/cli/parser.py 2.20% <0.00%> (-0.10%) ⬇️
nibabies/utils/confounds.py 3.92% <0.00%> (ø)
nibabies/utils/filtering.py 4.87% <0.00%> (ø)
nibabies/utils/validation.py 21.05% <ø> (ø)
nibabies/cli/run.py 7.14% <2.63%> (+0.89%) ⬆️
nibabies/utils/viz.py 4.87% <4.87%> (ø)
nibabies/reports/core.py 17.30% <11.11%> (-5.77%) ⬇️
nibabies/workflows/anatomical/base.py 6.25% <11.11%> (-0.21%) ⬇️
nibabies/workflows/anatomical/surfaces.py 11.42% <11.11%> (-11.98%) ⬇️
nibabies/cli/workflow.py 2.66% <11.76%> (+0.06%) ⬆️
... and 37 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Collaborator

@mgxd mgxd left a comment

Choose a reason for hiding this comment

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

Hey Thomas, thank you for the PR! I've gone through a first pass and left some comments.

Regarding some of the style changes - nibabies leverages pre-commit to run styling hooks automatically when committing. To get this, first install it (pip install pre-commit) and then run pre-commit install in the root. This will trigger some automatic checks when attempting to git commit. You may have to run black and isort manually to fix the previous commits. I'm just realizing we don't really have a nibabies-specific contributor's guideline, so will work on adding one.

Comment on lines 141 to 143
def _list_outputs(self):
outputs = super(CreateSignedDistanceVolume, self)._list_outputs()
return outputs
Copy link
Collaborator

Choose a reason for hiding this comment

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

No need for this since it's just calling the inherited method

Suggested change
def _list_outputs(self):
outputs = super(CreateSignedDistanceVolume, self)._list_outputs()
return outputs

@@ -135,48 +199,422 @@ def select_target(subject_id, space):
name="outputnode",
)

# fmt: off
# 0, 1 = wm; 2, 3 = pial; 6, 7 = mid
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this is such a large addition, I think it would make more sense to make this a subworkflow, and call it within init_bold_surf_wf so we don't clutter the connections.

Comment on lines 209 to 210
mem_gb=DEFAULT_MEMORY_MIN_GB,
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Generally, we can run most nipype utility interfaces on the master process since they are not intense operations - no need to potentially submit to a job queue.

Suggested change
mem_gb=DEFAULT_MEMORY_MIN_GB,
)
mem_gb=DEFAULT_MEMORY_MIN_GB,
run_without_submitting=True,
)

Comment on lines 215 to 216
mem_gb=DEFAULT_MEMORY_MIN_GB,
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
mem_gb=DEFAULT_MEMORY_MIN_GB,
)
mem_gb=DEFAULT_MEMORY_MIN_GB,
run_without_submitting=True,
)

select_midthick = pe.Node(
niu.Select(index=[6, 7]),
name="select_midthick",
mem_gb=DEFAULT_MEMORY_MIN_GB,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
mem_gb=DEFAULT_MEMORY_MIN_GB,
mem_gb=DEFAULT_MEMORY_MIN_GB,
run_without_submitting=True,

surface = File(
exists=True,
mandatory=True,
argstr="%s ",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think you need to add a trailing space for these

Suggested change
argstr="%s ",
argstr="%s",

)

cov_ribbon_mean = pe.Node(
fsl.ImageStats(op_string='-M '),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Trailing spaces again.

Suggested change
fsl.ImageStats(op_string='-M '),
fsl.ImageStats(op_string='-M'),

@mgxd
Copy link
Collaborator

mgxd commented Sep 22, 2022

@madisoth @effigies for the sake of keeping things consistent, I'm going to move my review over to fmriprep. Feel free to leave this as a draft or close it, and then once it has been merged within fmriprep, we can port that over and make minor changes as needed.

@mgxd mgxd added the blocked needs dependency update label Sep 22, 2022
@effigies
Copy link
Member

Ah, sorry, I hadn't noticed you'd started a review over here. Looks like we at least were thinking in the same direction where we overlapped.

@mgxd mgxd changed the title Enh/project goodvoxels ENH: Add option to exclude projecting high variance voxels to surface Sep 23, 2022
Removed duplicate code by abstracting it into functions, clarifying the goodvoxels logic
- Implemented the formatting suggestions by Mathias at the URLs below:
    - nipreps#235
    - nipreps/fmriprep#2855
- Split the 3 workflow-connect blocks in the project-goodvoxels section of resampling.py into 3 different functions: ribbon, outliers, and vol-to-surf
- Incomplete comments in resampling.py
Copy link
Collaborator

@mgxd mgxd left a comment

Choose a reason for hiding this comment

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

Hi @GregConan - thanks for contributing and pushing on this! I started going through and leaving some comments - let me know if anything doesn't make sense, or if you would like to schedule a call to go over some things.

@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this would be better suited to go in the workbench module https://github.com/nipreps/nibabies/blob/master/nibabies/interfaces/workbench.py

@@ -321,6 +321,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
"anat2std_xfm",
"std2anat_xfm",
"template",
"anat_giftis",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should probably be anat_surfaces to avoid confusion, now that morphometric files (which are also giftis) are available

"subjects_dir",
"t1w2fsnative_xfm",
"anat_giftis",
"t1w_mask",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if this is T1w specific, but one goal for down the line is to allow T1/T2 only processing, so to future-proof may want to rename this to anat_mask

if project_goodvoxels:
workflow.__desc__ += """\
Before resampling, a "goodvoxels" mask [@hcppipelines] was applied,
excluding voxels whose time-series have a locally high coetfficient of
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
excluding voxels whose time-series have a locally high coetfficient of
excluding voxels whose time-series have a locally high coefficient of


from niworkflows.interfaces.freesurfer import MedialNaNs
def make_ribbon_file(workflow, mem_gb, inputnode):
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like an anatomical workflow, so it should go in the https://github.com/nipreps/nibabies/tree/master/nibabies/workflows/anatomical module.

Also, to stay consistent with nipreps best practices, let's rename/restructure this as a separate workflow.

Suggested change
def make_ribbon_file(workflow, mem_gb, inputnode):
def init_ribbon_volume_wf(mem_gb, name='ribbon_volume_wf'):



def apply_med_surf_nans_if(
medial_surface_nan, workflow, inputnode, sampler, update_metadata, medial_nans
Copy link
Collaborator

Choose a reason for hiding this comment

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

We generally stay away from passing workflows / inputs / nodes as parameters, as that greatly complicates the logic / testing.

These connections can be applied within the init_ workflow function

return workflow


def connect_bold_surf_wf(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above

madisoth pushed a commit to madisoth/nibabies that referenced this pull request Feb 3, 2023
FIX: Minor anat wf & workbench.py fixes (+5 squashed commit)

Squashed commit:

[e995ec4] RF: Moved ribbon wf (from bold to anat) and reformatted

[9676f14] Updated Docker version tag

[532875e] STY: black and isort

[946dc7e] Formatting fixes and resampling.py modularization

- Implemented the formatting suggestions by Mathias at the URLs below:
    - nipreps#235
    - nipreps/fmriprep#2855
- Split the 3 workflow-connect blocks in the project-goodvoxels section of resampling.py into 3 different functions: ribbon, outliers, and vol-to-surf
- Incomplete comments in resampling.py

[114f982] Modularized goodvoxels code in resampling.py

Removed duplicate code by abstracting it into functions, clarifying the goodvoxels logic
mgxd added a commit that referenced this pull request Apr 13, 2023
ENH: Add option to exclude projecting high variance voxels to surface (update of #235)
@mgxd mgxd merged commit bd2bfd0 into nipreps:master Apr 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked needs dependency update
Projects
Status: Done (To be released)
Development

Successfully merging this pull request may close these issues.

5 participants