[ENH]: Add support for native space #252
8 changed files with 133 additions and 17 deletions
1
docs/changes/newsfragments/252.change
Normal file
1
docs/changes/newsfragments/252.change
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add ``native_t1w`` parameter to :class:`.DataladAOMICID1000`, :class:`.DataladAOMICPIOP1`, :class:`.DataladAOMICPIOP2`, enabling fetching of T1w data in subject-native space by `Synchon Mandal`_
|
||||||
1
docs/changes/newsfragments/252.feature
Normal file
1
docs/changes/newsfragments/252.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add support for subject-native space by `Synchon Mandal`_ and `Fede Raimondo`_
|
||||||
|
|
@ -28,6 +28,8 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
|
||||||
"probseg_WM", "DWI"} or a list of the options, optional
|
"probseg_WM", "DWI"} or a list of the options, optional
|
||||||
AOMIC data types. If None, all available data types are selected.
|
AOMIC data types. If None, all available data types are selected.
|
||||||
(default None).
|
(default None).
|
||||||
|
native_t1w : bool, optional
|
||||||
|
Whether to use T1w in native space (default False).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -35,6 +37,7 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
|
||||||
self,
|
self,
|
||||||
datadir: Union[str, Path, None] = None,
|
datadir: Union[str, Path, None] = None,
|
||||||
types: Union[str, List[str], None] = None,
|
types: Union[str, List[str], None] = None,
|
||||||
|
native_t1w: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
# The patterns
|
# The patterns
|
||||||
patterns = {
|
patterns = {
|
||||||
|
|
@ -84,6 +87,27 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
|
||||||
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
# Use native T1w assets
|
||||||
|
self.native_t1w = False
|
||||||
|
if native_t1w:
|
||||||
|
self.native_t1w = True
|
||||||
|
patterns.update(
|
||||||
|
{
|
||||||
|
"T1w": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-preproc_T1w.nii.gz"
|
||||||
|
),
|
||||||
|
"T1w_mask": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-brain_mask.nii.gz"
|
||||||
|
),
|
||||||
|
"Warp": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
||||||
|
"mode-image_xfm.h5"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
# Set default types
|
# Set default types
|
||||||
if types is None:
|
if types is None:
|
||||||
types = list(patterns.keys())
|
types = list(patterns.keys())
|
||||||
|
|
@ -126,5 +150,8 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
|
||||||
if out.get("T1w"):
|
if out.get("T1w"):
|
||||||
out["T1w"]["mask_item"] = "T1w_mask"
|
out["T1w"]["mask_item"] = "T1w_mask"
|
||||||
# Add space information
|
# Add space information
|
||||||
|
if self.native_t1w:
|
||||||
out["T1w"].update({"space": "native"})
|
out["T1w"].update({"space": "native"})
|
||||||
|
else:
|
||||||
|
out["T1w"].update({"space": "MNI152NLin2009cAsym"})
|
||||||
return out
|
return out
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
|
||||||
"gstroop", "workingmemory"} or list of the options, optional
|
"gstroop", "workingmemory"} or list of the options, optional
|
||||||
AOMIC PIOP1 task sessions. If None, all available task sessions are
|
AOMIC PIOP1 task sessions. If None, all available task sessions are
|
||||||
selected (default None).
|
selected (default None).
|
||||||
|
native_t1w : bool, optional
|
||||||
|
Whether to use T1w in native space (default False).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -42,6 +44,7 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
|
||||||
datadir: Union[str, Path, None] = None,
|
datadir: Union[str, Path, None] = None,
|
||||||
types: Union[str, List[str], None] = None,
|
types: Union[str, List[str], None] = None,
|
||||||
tasks: Union[str, List[str], None] = None,
|
tasks: Union[str, List[str], None] = None,
|
||||||
|
native_t1w: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
# Declare all tasks
|
# Declare all tasks
|
||||||
all_tasks = [
|
all_tasks = [
|
||||||
|
|
@ -114,6 +117,27 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
|
||||||
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
# Use native T1w assets
|
||||||
|
self.native_t1w = False
|
||||||
|
if native_t1w:
|
||||||
|
self.native_t1w = True
|
||||||
|
patterns.update(
|
||||||
|
{
|
||||||
|
"T1w": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-preproc_T1w.nii.gz"
|
||||||
|
),
|
||||||
|
"T1w_mask": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-brain_mask.nii.gz"
|
||||||
|
),
|
||||||
|
"Warp": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
||||||
|
"mode-image_xfm.h5"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
# Set default types
|
# Set default types
|
||||||
if types is None:
|
if types is None:
|
||||||
types = list(patterns.keys())
|
types = list(patterns.keys())
|
||||||
|
|
@ -171,7 +195,10 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
|
||||||
if out.get("T1w"):
|
if out.get("T1w"):
|
||||||
out["T1w"]["mask_item"] = "T1w_mask"
|
out["T1w"]["mask_item"] = "T1w_mask"
|
||||||
# Add space information
|
# Add space information
|
||||||
|
if self.native_t1w:
|
||||||
out["T1w"].update({"space": "native"})
|
out["T1w"].update({"space": "native"})
|
||||||
|
else:
|
||||||
|
out["T1w"].update({"space": "MNI152NLin2009cAsym"})
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def get_elements(self) -> List:
|
def get_elements(self) -> List:
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
|
||||||
or list of the options, optional
|
or list of the options, optional
|
||||||
AOMIC PIOP2 task sessions. If None, all available task sessions are
|
AOMIC PIOP2 task sessions. If None, all available task sessions are
|
||||||
selected (default None).
|
selected (default None).
|
||||||
|
native_t1w : bool, optional
|
||||||
|
Whether to use T1w in native space (default False).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -42,6 +44,7 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
|
||||||
datadir: Union[str, Path, None] = None,
|
datadir: Union[str, Path, None] = None,
|
||||||
types: Union[str, List[str], None] = None,
|
types: Union[str, List[str], None] = None,
|
||||||
tasks: Union[str, List[str], None] = None,
|
tasks: Union[str, List[str], None] = None,
|
||||||
|
native_t1w: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
# Declare all tasks
|
# Declare all tasks
|
||||||
all_tasks = [
|
all_tasks = [
|
||||||
|
|
@ -111,6 +114,27 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
|
||||||
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
"sub-{subject}_desc-preproc_dwi.nii.gz"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
# Use native T1w assets
|
||||||
|
self.native_t1w = False
|
||||||
|
if native_t1w:
|
||||||
|
self.native_t1w = True
|
||||||
|
patterns.update(
|
||||||
|
{
|
||||||
|
"T1w": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-preproc_T1w.nii.gz"
|
||||||
|
),
|
||||||
|
"T1w_mask": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_desc-brain_mask.nii.gz"
|
||||||
|
),
|
||||||
|
"Warp": (
|
||||||
|
"derivatives/fmriprep/sub-{subject}/anat/"
|
||||||
|
"sub-{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
||||||
|
"mode-image_xfm.h5"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
# Set default types
|
# Set default types
|
||||||
if types is None:
|
if types is None:
|
||||||
types = list(patterns.keys())
|
types = list(patterns.keys())
|
||||||
|
|
@ -171,5 +195,8 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
|
||||||
if out.get("T1w"):
|
if out.get("T1w"):
|
||||||
out["T1w"]["mask_item"] = "T1w_mask"
|
out["T1w"]["mask_item"] = "T1w_mask"
|
||||||
# Add space information
|
# Add space information
|
||||||
|
if self.native_t1w:
|
||||||
out["T1w"].update({"space": "native"})
|
out["T1w"].update({"space": "native"})
|
||||||
|
else:
|
||||||
|
out["T1w"].update({"space": "MNI152NLin2009cAsym"})
|
||||||
return out
|
return out
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class HCP1200(PatternDataGrabber):
|
||||||
)
|
)
|
||||||
suffix = "_hp2000_clean" if ica_fix else ""
|
suffix = "_hp2000_clean" if ica_fix else ""
|
||||||
# The types of data
|
# The types of data
|
||||||
types = ["BOLD"]
|
types = ["BOLD", "T1w", "Warp"]
|
||||||
# The patterns
|
# The patterns
|
||||||
patterns = {
|
patterns = {
|
||||||
"BOLD": (
|
"BOLD": (
|
||||||
|
|
@ -106,7 +106,9 @@ class HCP1200(PatternDataGrabber):
|
||||||
"{task}_{phase_encoding}/"
|
"{task}_{phase_encoding}/"
|
||||||
"{task}_{phase_encoding}"
|
"{task}_{phase_encoding}"
|
||||||
f"{suffix}.nii.gz"
|
f"{suffix}.nii.gz"
|
||||||
)
|
),
|
||||||
|
"T1w": "{subject}/T1w/T1w_acpc_dc_restore.nii.gz",
|
||||||
|
"Warp": "{subject}/MNINonLinear/xfms/standard2acpc_dc.nii.gz",
|
||||||
}
|
}
|
||||||
# The replacements
|
# The replacements
|
||||||
replacements = ["subject", "task", "phase_encoding"]
|
replacements = ["subject", "task", "phase_encoding"]
|
||||||
|
|
@ -147,6 +149,12 @@ class HCP1200(PatternDataGrabber):
|
||||||
out = super().get_item(
|
out = super().get_item(
|
||||||
subject=subject, task=new_task, phase_encoding=phase_encoding
|
subject=subject, task=new_task, phase_encoding=phase_encoding
|
||||||
)
|
)
|
||||||
|
# Add space for BOLD data type
|
||||||
|
if "BOLD" in out:
|
||||||
|
out["BOLD"].update({"space": "MNI152NLin6Asym"})
|
||||||
|
# Add space for T1w data type
|
||||||
|
if "T1w" in out:
|
||||||
|
out["T1w"].update({"space": "native"})
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def get_elements(self) -> List:
|
def get_elements(self) -> List:
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,10 @@ class DefaultDataReader(PipelineStepMixin, UpdateMetaMixin):
|
||||||
params = {}
|
params = {}
|
||||||
# For each type of data, try to read it
|
# For each type of data, try to read it
|
||||||
for type_ in input.keys():
|
for type_ in input.keys():
|
||||||
|
# Skip Warp data type
|
||||||
|
if type_ == "Warp":
|
||||||
|
continue
|
||||||
|
|
||||||
# Check for malformed datagrabber specification
|
# Check for malformed datagrabber specification
|
||||||
if "path" not in input[type_]:
|
if "path" not in input[type_]:
|
||||||
warn_with_log(
|
warn_with_log(
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
# License: AGPL
|
# License: AGPL
|
||||||
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from tempfile import TemporaryDirectory
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
import datalad.api as dl
|
import datalad.api as dl
|
||||||
|
|
||||||
|
|
@ -15,7 +15,6 @@ DST = "git@gin.g-node.org:/juaml/datalad-example-hcp1200.git"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
# Convert str to Path
|
# Convert str to Path
|
||||||
tmpdir_path = Path(tmpdir)
|
tmpdir_path = Path(tmpdir)
|
||||||
|
|
@ -29,7 +28,30 @@ if __name__ == "__main__":
|
||||||
# Create subject directory
|
# Create subject directory
|
||||||
subdir.mkdir()
|
subdir.mkdir()
|
||||||
|
|
||||||
for (task, phase_encoding) in product(
|
# T1w data
|
||||||
|
# Set subject data directory
|
||||||
|
sub_t1w_datadir = subdir / "T1w"
|
||||||
|
# Create subject data directory
|
||||||
|
sub_t1w_datadir.mkdir(parents=True)
|
||||||
|
# Set subject data file
|
||||||
|
sub_t1w_datafile = sub_t1w_datadir / "T1w_acpc_dc_restore.nii.gz"
|
||||||
|
# Write subject data file
|
||||||
|
with open(sub_t1w_datafile, "w") as f:
|
||||||
|
f.write("placeholder")
|
||||||
|
|
||||||
|
# Warp data
|
||||||
|
# Set subject data directory
|
||||||
|
sub_warp_datadir = subdir / "MNINonLinear" / "xfms"
|
||||||
|
# Create subject data directory
|
||||||
|
sub_warp_datadir.mkdir(parents=True)
|
||||||
|
# Set subject data file
|
||||||
|
sub_warp_datafile = sub_warp_datadir / "standard2acpc_dc.nii.gz"
|
||||||
|
# Write subject data file
|
||||||
|
with open(sub_warp_datafile, "w") as f:
|
||||||
|
f.write("placeholder")
|
||||||
|
|
||||||
|
# BOLD data
|
||||||
|
for task, phase_encoding in product(
|
||||||
[
|
[
|
||||||
"REST1",
|
"REST1",
|
||||||
"REST2",
|
"REST2",
|
||||||
|
|
@ -49,32 +71,31 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
new_task = f"tfMRI_{task}"
|
new_task = f"tfMRI_{task}"
|
||||||
# Set subject data directory
|
# Set subject data directory
|
||||||
sub_datadir = (
|
sub_bold_datadir = (
|
||||||
subdir
|
subdir
|
||||||
/ "MNINonLinear"
|
/ "MNINonLinear"
|
||||||
/ "Results"
|
/ "Results"
|
||||||
/ f"{new_task}_{phase_encoding}"
|
/ f"{new_task}_{phase_encoding}"
|
||||||
)
|
)
|
||||||
# Create subject data directory
|
# Create subject data directory
|
||||||
sub_datadir.mkdir(parents=True)
|
sub_bold_datadir.mkdir(parents=True)
|
||||||
|
|
||||||
# Set subject data file
|
# Set subject data file
|
||||||
sub_datafile = (
|
sub_bold_datafile = (
|
||||||
sub_datadir
|
sub_bold_datadir / f"{new_task}_{phase_encoding}.nii.gz"
|
||||||
/ f"{new_task}_{phase_encoding}.nii.gz"
|
|
||||||
)
|
)
|
||||||
# Create subject data file
|
# Create subject data file
|
||||||
with open(sub_datafile, "w") as f:
|
with open(sub_bold_datafile, "w") as f:
|
||||||
f.write("placeholder")
|
f.write("placeholder")
|
||||||
|
|
||||||
if "REST" in task:
|
if "REST" in task:
|
||||||
# Set subject data file with ICA+FIX
|
# Set subject data file with ICA+FIX
|
||||||
sub_datafile = (
|
sub_bold_datafile = (
|
||||||
sub_datadir
|
sub_bold_datadir
|
||||||
/ f"{new_task}_{phase_encoding}_hp2000_clean.nii.gz"
|
/ f"{new_task}_{phase_encoding}_hp2000_clean.nii.gz"
|
||||||
)
|
)
|
||||||
# Create subject data file with ICA+FIX
|
# Create subject data file with ICA+FIX
|
||||||
with open(sub_datafile, "w") as f:
|
with open(sub_bold_datafile, "w") as f:
|
||||||
f.write("placeholder")
|
f.write("placeholder")
|
||||||
|
|
||||||
# Save datalad dataset
|
# Save datalad dataset
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue