Skip to content
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

Add a node for selecting specific shells from preprocessed dwis #194

Merged
merged 13 commits into from
Dec 6, 2024

Conversation

mattcieslak
Copy link
Contributor

Background

The SS3T workflow needs to have only b=0s and one shell of b>0s sent to it. Similarly, the BabyAFQ pipeline requires selecting only a few shells for msmt.

Recon Spec

This PR adds a select_gradients action that lets users pick which shells to send to a downstream node. The parameters are

  1. A list of shells to select. These can be specific numeric b-values or the strings "highest" for highest b-value shell or "lowest" for lowest b>0 shell. If no b=0 shell is selected then one is added in the workflow.
  2. A parameter for how different the b-values can be from the b-values selected in (1). There are usually some differences in the acquired b-value and the requested b-value. This parameter is similar to the --b0-threshold parameter from qsiprep.
  3. If the user wants to do a sanity check on their input data, they can also specify the expected_n_input_shells to make sure that this many shells (including the b=0s as a shell) are detected in the input data.

An example in a recon spec for HBCD might look like:

-   action: select_gradients
    input: qsirecon
    name: select_single_shell
    parameters:
        requested_shells:
            - 0
            - highest
        bval_distance_cutoff: 100
        expected_n_input_shells: 5

Implementation

The trickiest part about this is making it general enough that it can be included in a built-in recon workflow and work with the many different shell schemes out there. The value 0 can be hard-coded because has a specific meaning/use in DWI. Because of the minor variations in b-values we also don't always know immediately what the intended shell b-values are. So the steps for selecting shells are

  1. Figure out how many shells there are using the bval_distance_cutoff and agglomerative clustering with complete linkage
  2. Select the median b-value per cluster as the intended b-value
  3. loop over the requested bvals and find which shells they correspond to

Tests and reports

The implementation in this PR creates a Pandas DataFrame with each b-value in the input data and which shell it corresponds to. I think saving this data frame to a tsv would be a sufficient sanity check for users. We had talked about plots with histograms of b-values per assigned shell, but these end up not looking very good/informative when plotted.

Copy link
Member

@tsalo tsalo left a comment

Choose a reason for hiding this comment

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

A few initial thoughts.

The big thing I think this needs is a comprehensive unit test for _find_shells with a bunch of simulated b-val schemes.

qsirecon/interfaces/gradients.py Show resolved Hide resolved
qsirecon/interfaces/gradients.py Outdated Show resolved Hide resolved
qsirecon/interfaces/gradients.py Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Dec 5, 2024

Codecov Report

Attention: Patch coverage is 77.69784% with 31 lines in your changes missing coverage. Please review.

Project coverage is 48.57%. Comparing base (619341b) to head (b43b9c2).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
qsirecon/interfaces/gradients.py 76.56% 20 Missing and 10 partials ⚠️
qsirecon/workflows/recon/utils.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #194      +/-   ##
==========================================
+ Coverage   47.90%   48.57%   +0.66%     
==========================================
  Files          56       56              
  Lines        7198     7309     +111     
  Branches      978      999      +21     
==========================================
+ Hits         3448     3550     +102     
+ Misses       3544     3543       -1     
- Partials      206      216      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mattcieslak mattcieslak requested a review from tsalo December 5, 2024 23:28
Copy link
Member

@tsalo tsalo left a comment

Choose a reason for hiding this comment

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

I have a couple of ideas for the tests.

qsirecon/interfaces/gradients.py Outdated Show resolved Hide resolved
qsirecon/tests/test_interfaces.py Outdated Show resolved Hide resolved
qsirecon/tests/test_interfaces.py Show resolved Hide resolved
qsirecon/tests/test_interfaces.py Show resolved Hide resolved
@mattcieslak mattcieslak merged commit f95211a into main Dec 6, 2024
25 checks passed
@mattcieslak mattcieslak deleted the enh/fod-autotrack branch December 6, 2024 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants