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

Load T1w-to-standard transform to same space as volumetric BOLD scan #926

Merged
merged 42 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
95294f1
Use MNI152NLin6Asym for fsLR no matter what.
tsalo Jul 11, 2023
d617856
Work on the warps.
tsalo Jul 12, 2023
cdfbc2b
Keep working on transforms.
tsalo Jul 14, 2023
adacff2
Revert collect_run_data.
tsalo Jul 14, 2023
a0652d8
Update execsummary.py
tsalo Jul 14, 2023
59184c3
Forgot to connect things.
tsalo Jul 14, 2023
c92fae3
Update execsummary.py
tsalo Jul 14, 2023
d3c7e2f
Test inverted version.
tsalo Jul 14, 2023
439066b
Update test_utils_utils.py
tsalo Jul 14, 2023
b50ef28
Fix test.
tsalo Jul 14, 2023
e358c91
Merge branch 'main' into fix-collection
tsalo Jul 27, 2023
fbe2ce0
Try reversing the transforms.
tsalo Jul 28, 2023
c1627e2
Revert the previous change.
tsalo Jul 28, 2023
8e41eb4
Try this.
tsalo Jul 28, 2023
afffc17
Try direct connection.
tsalo Jul 31, 2023
491a8d3
Use ITK version of transform.
tsalo Jul 31, 2023
533259b
Update utils.py
tsalo Jul 31, 2023
fdd589a
Merge remote-tracking branch 'upstream/main' into fix-collection
tsalo Jul 31, 2023
311a53d
Rename files.
tsalo Jul 31, 2023
88f6224
Update execsummary.py
tsalo Aug 1, 2023
6def5d5
Make MNI152NLin6Asym default for nibabies.
tsalo Aug 1, 2023
5e8d42c
Don't warp BOLD.
tsalo Aug 1, 2023
3159770
Fix.
tsalo Aug 1, 2023
f8d0b2f
Merge branch 'main' into fix-collection
tsalo Aug 1, 2023
9631760
Use anat_to_template_xfm to find niftis.
tsalo Aug 25, 2023
7fa5d6d
Raise exception is nifti is missing.
tsalo Aug 25, 2023
f2d2708
Don't split cohort out for pybids queries.
tsalo Aug 25, 2023
7556d50
Revert some changes.
tsalo Aug 25, 2023
58ee6f0
Revert changes to get_std2bold_xfms.
tsalo Aug 25, 2023
c58805a
Fix query.
tsalo Aug 25, 2023
fdc0ff5
Check for BOLD files in volumetric space for CIFTIs.
tsalo Aug 25, 2023
b96be01
Merge remote-tracking branch 'upstream/main' into fix-collection
tsalo Sep 8, 2023
cb3e312
Update bids.py
tsalo Sep 8, 2023
9a83f9b
Update bids.py
tsalo Sep 11, 2023
e25e2ae
Update bids.py
tsalo Sep 11, 2023
252fe01
Drop the density entity from the vol BOLD query.
tsalo Sep 11, 2023
f406056
Update bids.py
tsalo Sep 11, 2023
c784981
Update test_utils_bids.py
tsalo Sep 11, 2023
73908e6
Fix expected outputs.
tsalo Sep 12, 2023
a8168ce
Update test_utils_bids.py
tsalo Sep 12, 2023
7c9603d
Merge branch 'main' into fix-collection
tsalo Sep 14, 2023
8ffe6cb
Merge branch 'main' into fix-collection
tsalo Sep 25, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#Insight Transform File V1.0
#Transform 0
Transform: MatrixOffsetTransformBase_double_3_3
Parameters: 0.7514471411705017 -0.0022597732022405 -0.0056457491591573 -0.0011661121388897 0.7435653805732727 0.0801302567124367 0.0081897228956223 -0.0277762282639742 0.6979145407676697 0.4968573749065399 -3.0900352001190186 0.6142088770866394
FixedParameters: 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1.330660649 -0.004427136451 0.01025602509 -41.20370054
-0.003753457765 1.339140797 0.153721562 -68.37553187
-0.01546533827 -0.05324436952 1.426601839 -22.76900701
0 0 0 1
46 changes: 36 additions & 10 deletions xcp_d/tests/test_utils_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,18 @@ def test_denoise_with_nilearn(ds001419_data, tmp_path_factory):

def test_list_to_str():
"""Test the list_to_str function."""
lst = ["a"]
string = utils.list_to_str(lst)
string = utils.list_to_str(["a"])
assert string == "a"

lst = ["a", "b"]
string = utils.list_to_str(lst)
string = utils.list_to_str(["a", "b"])
assert string == "a and b"

lst = ["a", "b", "c"]
string = utils.list_to_str(lst)
string = utils.list_to_str(["a", "b", "c"])
assert string == "a, b, and c"

with pytest.raises(ValueError, match="Zero-length list provided."):
utils.list_to_str([])


def test_get_bold2std_and_t1w_xfms(ds001419_data):
"""Test get_bold2std_and_t1w_xfms."""
Expand Down Expand Up @@ -331,30 +331,56 @@ def test_get_std2bold_xfms(ds001419_data):
"""
bold_file_nlin2009c = ds001419_data["nifti_file"]

# MNI152NLin6Asym --> MNI152NLin2009cAsym
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin2009c, inverted=False)
assert len(xforms_to_mni) == 1

# MNI152NLin6Asym --> MNI152NLin6Asym
bold_file_nlin6asym = bold_file_nlin2009c.replace(
"space-MNI152NLin2009cAsym_",
"space-MNI152NLin6Asym_",
)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin6asym, inverted=False)
assert len(xforms_to_mni) == 1

# MNI152NLin6Asym --> MNIInfant
bold_file_infant = bold_file_nlin2009c.replace(
"space-MNI152NLin2009cAsym_",
"space-MNIInfant_cohort-1_",
)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_infant, inverted=False)
assert len(xforms_to_mni) == 2

# MNI152NLin6Asym --> tofail
bold_file_tofail = bold_file_nlin2009c.replace("space-MNI152NLin2009cAsym_", "space-tofail_")
with pytest.raises(ValueError, match="Space 'tofail'"):
utils.get_std2bold_xfms(bold_file_tofail, inverted=False)

# Inverted version
# MNI152NLin2009cAsym --> MNI152NLin6Asym
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin2009c)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin2009c, inverted=True)
assert len(xforms_to_mni) == 1

# MNI152NLin6Asym --> MNI152NLin6Asym
bold_file_nlin6asym = bold_file_nlin2009c.replace(
"space-MNI152NLin2009cAsym_",
"space-MNI152NLin6Asym_",
)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin6asym)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_nlin6asym, inverted=True)
assert len(xforms_to_mni) == 1

# MNIInfant --> MNI152NLin6Asym
bold_file_infant = bold_file_nlin2009c.replace(
"space-MNI152NLin2009cAsym_",
"space-MNIInfant_cohort-1_",
)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_infant)
xforms_to_mni = utils.get_std2bold_xfms(bold_file_infant, inverted=True)
assert len(xforms_to_mni) == 2

# tofail --> MNI152NLin6Asym
bold_file_tofail = bold_file_nlin2009c.replace("space-MNI152NLin2009cAsym_", "space-tofail_")
with pytest.raises(ValueError, match="Space 'tofail'"):
utils.get_std2bold_xfms(bold_file_tofail)
utils.get_std2bold_xfms(bold_file_tofail, inverted=True)


def test_fwhm2sigma():
Expand Down
2 changes: 1 addition & 1 deletion xcp_d/utils/bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"nibabies": {
"cifti": ["fsLR"],
"nifti": [
"MNIInfant",
"MNI152NLin6Asym",
"MNIInfant",
"MNI152NLin2009cAsym",
],
Comment on lines 34 to 38
Copy link
Member Author

Choose a reason for hiding this comment

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

Make MNI152NLin6Asym the preferred space for nibabies data.

},
Expand Down
61 changes: 44 additions & 17 deletions xcp_d/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def get_bold2std_and_t1w_xfms(bold_file, template_to_anat_xfm, anat_to_native_xf
return xforms_to_MNI, xforms_to_MNI_invert, xforms_to_T1w, xforms_to_T1w_invert


def get_std2bold_xfms(bold_file):
def get_std2bold_xfms(bold_file, inverted=False):
"""Obtain transforms to warp atlases from MNI152NLin6Asym to the same template as the BOLD.

Since ANTSApplyTransforms takes in the transform files as a stack,
Expand All @@ -155,6 +155,9 @@ def get_std2bold_xfms(bold_file):
----------
bold_file : :obj:`str`
The preprocessed BOLD file.
inverted : :obj:`bool`, optional
If False (default), transforms from MNI152NLin6Asym will be returned.
If True, transforms *to* MNI152NLin6Asym will be returned.

Returns
-------
Expand All @@ -168,9 +171,7 @@ def get_std2bold_xfms(bold_file):
- to resample dseg in init_postprocess_nifti_wf for QCReport
- to warp atlases to the same space as the BOLD data in init_functional_connectivity_nifti_wf
- to resample dseg to BOLD space for the executive summary plots

Does not include inversion flag output because there is no need (yet).
Can easily be added in the future.
- to warp any BOLD images that will be overlaid on anatomical images to MNI152NLin6Asym
"""
import os

Expand All @@ -192,30 +193,56 @@ def get_std2bold_xfms(bold_file):
**{"from": "MNI152NLin6Asym"},
),
)
MNI152NLin2009cAsym_to_MNI152NLin6Asym = str(
get_template(
template="MNI152NLin6Asym",
mode="image",
suffix="xfm",
extension=".h5",
**{"from": "MNI152NLin2009cAsym"},
),
)

# Find the appropriate transform(s)
if bold_space == "MNI152NLin6Asym":
# NLin6 --> NLin6 (identity)
transform_list = ["identity"]

elif bold_space == "MNI152NLin2009cAsym":
# NLin6 --> NLin2009c
transform_list = [MNI152NLin6Asym_to_MNI152NLin2009cAsym]
if inverted:
# NLin2009c --> NLin6
transform_list = [MNI152NLin2009cAsym_to_MNI152NLin6Asym]

else:
# NLin6 --> NLin2009c
transform_list = [MNI152NLin6Asym_to_MNI152NLin2009cAsym]

elif bold_space == "MNIInfant":
# NLin6 --> NLin2009c --> MNIInfant
MNI152NLin2009cAsym_to_MNI152Infant = pkgrf(
"xcp_d",
"data/transform/tpl-MNIInfant_from-MNI152NLin2009cAsym_mode-image_xfm.h5",
)
transform_list = [
MNI152NLin2009cAsym_to_MNI152Infant,
MNI152NLin6Asym_to_MNI152NLin2009cAsym,
]
if inverted:
# MNIInfant --> NLin2009c --> NLin6
# The available MNIInfant --> MNI152* transforms seem to be of poor quality
MNI152Infant_to_MNI152NLin2009cAsym = pkgrf(
"xcp_d",
"data/transform/tpl-MNI152NLin2009cAsym_from-MNIInfant_mode-image_xfm.h5",
)
transform_list = [
MNI152NLin2009cAsym_to_MNI152NLin6Asym,
MNI152Infant_to_MNI152NLin2009cAsym,
]

else:
# NLin6 --> NLin2009c --> MNIInfant
MNI152NLin2009cAsym_to_MNI152Infant = pkgrf(
"xcp_d",
"data/transform/tpl-MNIInfant_from-MNI152NLin2009cAsym_mode-image_xfm.h5",
)
transform_list = [
MNI152NLin2009cAsym_to_MNI152Infant,
MNI152NLin6Asym_to_MNI152NLin2009cAsym,
]

else:
file_base = os.path.basename(bold_file)
raise ValueError(f"Space '{bold_space}' in {file_base} not supported.")
raise ValueError(f"Space '{bold_space}' in {os.path.basename(bold_file)} not supported.")

return transform_list

Expand Down
6 changes: 3 additions & 3 deletions xcp_d/workflows/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,9 @@ def init_subject_wf(

for j_run, bold_file in enumerate(task_files):
run_data = collect_run_data(
layout,
input_type,
bold_file,
layout=layout,
input_type=input_type,
bold_file=bold_file,
cifti=cifti,
primary_anat=primary_anat,
)
Expand Down
Loading