Skip to content

Commit aa17291

Browse files
👔 Restore nhp FNIRT logic
Co-authored-by: Elizabeth Kenneally <[email protected]>
1 parent f9fb924 commit aa17291

File tree

1 file changed

+99
-84
lines changed

1 file changed

+99
-84
lines changed

CPAC/registration/registration.py

Lines changed: 99 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2012-2024 C-PAC Developers
1+
# Copyright (C) 2012-2025 C-PAC Developers
22

33
# This file is part of C-PAC.
44

@@ -17,7 +17,7 @@
1717
# pylint: disable=too-many-lines,ungrouped-imports,wrong-import-order
1818
"""Workflows for registration."""
1919

20-
from typing import Optional
20+
from typing import Literal, Optional
2121

2222
from voluptuous import RequiredFieldInvalid
2323
from nipype.interfaces import afni, ants, c3, fsl, utility as util
@@ -40,6 +40,7 @@
4040
seperate_warps_list,
4141
single_ants_xfm_to_list,
4242
)
43+
from CPAC.utils.configuration import Configuration
4344
from CPAC.utils.interfaces import Function
4445
from CPAC.utils.interfaces.fsl import Merge as fslMerge
4546
from CPAC.utils.utils import check_prov_for_motion_tool, check_prov_for_regtool
@@ -1454,9 +1455,15 @@ def create_wf_calculate_ants_warp(
14541455

14551456

14561457
def FSL_registration_connector(
1457-
wf_name, cfg, orig="T1w", opt=None, symmetric=False, template="T1w"
1458-
):
1458+
wf_name: str,
1459+
cfg: Configuration,
1460+
orig: str = "T1w",
1461+
opt: Literal["FSL", "FSL-linear"] = "FSL",
1462+
symmetric: bool = False,
1463+
template: str = "T1w",
1464+
) -> tuple[pe.Workflow, dict[str, tuple]]:
14591465
"""Transform raw data to template with FSL."""
1466+
assert opt in ["FSL", "FSL-linear"]
14601467
wf = pe.Workflow(name=wf_name)
14611468

14621469
inputNode = pe.Node(
@@ -1485,78 +1492,71 @@ def FSL_registration_connector(
14851492
tmpl = ""
14861493
if template == "EPI":
14871494
tmpl = "EPI"
1495+
flirt_reg_anat_mni = create_fsl_flirt_linear_reg(f"anat_mni_flirt_register{symm}")
14881496

1489-
if opt in ("FSL", "FSL-linear"):
1490-
flirt_reg_anat_mni = create_fsl_flirt_linear_reg(
1491-
f"anat_mni_flirt_register{symm}"
1492-
)
1497+
# Input registration parameters
1498+
wf.connect(inputNode, "interpolation", flirt_reg_anat_mni, "inputspec.interp")
14931499

1494-
# Input registration parameters
1495-
wf.connect(inputNode, "interpolation", flirt_reg_anat_mni, "inputspec.interp")
1500+
wf.connect(inputNode, "input_brain", flirt_reg_anat_mni, "inputspec.input_brain")
14961501

1497-
wf.connect(
1498-
inputNode, "input_brain", flirt_reg_anat_mni, "inputspec.input_brain"
1499-
)
1502+
wf.connect(
1503+
inputNode,
1504+
"reference_brain",
1505+
flirt_reg_anat_mni,
1506+
"inputspec.reference_brain",
1507+
)
15001508

1501-
wf.connect(
1502-
inputNode,
1503-
"reference_brain",
1504-
flirt_reg_anat_mni,
1505-
"inputspec.reference_brain",
1506-
)
1509+
write_lin_composite_xfm = pe.Node(
1510+
interface=fsl.ConvertWarp(), name=f"fsl_lin-warp_to_nii{symm}"
1511+
)
15071512

1508-
write_lin_composite_xfm = pe.Node(
1509-
interface=fsl.ConvertWarp(), name=f"fsl_lin-warp_to_nii{symm}"
1510-
)
1513+
wf.connect(inputNode, "reference_brain", write_lin_composite_xfm, "reference")
15111514

1512-
wf.connect(inputNode, "reference_brain", write_lin_composite_xfm, "reference")
1515+
wf.connect(
1516+
flirt_reg_anat_mni,
1517+
"outputspec.linear_xfm",
1518+
write_lin_composite_xfm,
1519+
"premat",
1520+
)
15131521

1514-
wf.connect(
1515-
flirt_reg_anat_mni,
1516-
"outputspec.linear_xfm",
1517-
write_lin_composite_xfm,
1518-
"premat",
1519-
)
1522+
write_invlin_composite_xfm = pe.Node(
1523+
interface=fsl.ConvertWarp(), name=f"fsl_invlin-warp_to_nii{symm}"
1524+
)
15201525

1521-
write_invlin_composite_xfm = pe.Node(
1522-
interface=fsl.ConvertWarp(), name=f"fsl_invlin-warp_to_nii{symm}"
1523-
)
1526+
wf.connect(inputNode, "reference_brain", write_invlin_composite_xfm, "reference")
15241527

1525-
wf.connect(
1526-
inputNode, "reference_brain", write_invlin_composite_xfm, "reference"
1527-
)
1528+
wf.connect(
1529+
flirt_reg_anat_mni,
1530+
"outputspec.invlinear_xfm",
1531+
write_invlin_composite_xfm,
1532+
"premat",
1533+
)
15281534

1529-
wf.connect(
1535+
outputs = {
1536+
f"space-{sym}template_desc-preproc_{orig}": (
15301537
flirt_reg_anat_mni,
1531-
"outputspec.invlinear_xfm",
1538+
"outputspec.output_brain",
1539+
),
1540+
f"from-{orig}_to-{sym}{tmpl}template_mode-image_desc-linear_xfm": (
1541+
write_lin_composite_xfm,
1542+
"out_file",
1543+
),
1544+
f"from-{sym}{tmpl}template_to-{orig}_mode-image_desc-linear_xfm": (
15321545
write_invlin_composite_xfm,
1533-
"premat",
1534-
)
1535-
1536-
outputs = {
1537-
f"space-{sym}template_desc-preproc_{orig}": (
1538-
flirt_reg_anat_mni,
1539-
"outputspec.output_brain",
1540-
),
1541-
f"from-{orig}_to-{sym}{tmpl}template_mode-image_desc-linear_xfm": (
1542-
write_lin_composite_xfm,
1543-
"out_file",
1544-
),
1545-
f"from-{sym}{tmpl}template_to-{orig}_mode-image_desc-linear_xfm": (
1546-
write_invlin_composite_xfm,
1547-
"out_file",
1548-
),
1549-
f"from-{orig}_to-{sym}{tmpl}template_mode-image_xfm": (
1550-
write_lin_composite_xfm,
1551-
"out_file",
1552-
),
1553-
}
1554-
1555-
if opt == "FSL" and cfg["pipeline_setup", "organism"] == "non-human primate":
1556-
fnirt_reg_anat_mni = create_fsl_fnirt_nonlinear_reg_nhp(
1557-
f"anat_mni_fnirt_register{symm}"
1558-
)
1546+
"out_file",
1547+
),
1548+
f"from-{orig}_to-{sym}{tmpl}template_mode-image_xfm": (
1549+
write_lin_composite_xfm,
1550+
"out_file",
1551+
),
1552+
}
15591553

1554+
if opt == "FSL":
1555+
fnirt_reg_anat_mni = (
1556+
create_fsl_fnirt_nonlinear_reg_nhp
1557+
if cfg["pipeline_setup", "organism"] == "non-human primate"
1558+
else create_fsl_fnirt_nonlinear_reg
1559+
)(f"anat_mni_fnirt_register{symm}")
15601560
wf.connect(
15611561
inputNode, "input_brain", fnirt_reg_anat_mni, "inputspec.input_brain"
15621562
)
@@ -1597,30 +1597,35 @@ def FSL_registration_connector(
15971597
fnirt_reg_anat_mni,
15981598
"outputspec.output_brain",
15991599
),
1600-
f"space-{sym}template_desc-head_{orig}": (
1601-
fnirt_reg_anat_mni,
1602-
"outputspec.output_head",
1603-
),
1604-
f"space-{sym}template_desc-{'brain' if orig == 'T1w' else orig}_mask": (
1605-
fnirt_reg_anat_mni,
1606-
"outputspec.output_mask",
1607-
),
1608-
f"space-{sym}template_desc-T1wT2w_biasfield": (
1609-
fnirt_reg_anat_mni,
1610-
"outputspec.output_biasfield",
1611-
),
16121600
f"from-{orig}_to-{sym}{tmpl}template_mode-image_xfm": (
16131601
fnirt_reg_anat_mni,
16141602
"outputspec.nonlinear_xfm",
16151603
),
1616-
f"from-{orig}_to-{sym}{tmpl}template_mode-image_warp": (
1617-
fnirt_reg_anat_mni,
1618-
"outputspec.nonlinear_warp",
1619-
),
16201604
}
1605+
if cfg["pipeline_setup", "organism"] == "non-human primate":
1606+
added_outputs.update(
1607+
{
1608+
f"space-{sym}template_desc-head_{orig}": (
1609+
fnirt_reg_anat_mni,
1610+
"outputspec.output_head",
1611+
),
1612+
f"space-{sym}template_desc-{'brain' if orig == 'T1w' else orig}_mask": (
1613+
fnirt_reg_anat_mni,
1614+
"outputspec.output_mask",
1615+
),
1616+
f"space-{sym}template_desc-T1wT2w_biasfield": (
1617+
fnirt_reg_anat_mni,
1618+
"outputspec.output_biasfield",
1619+
),
1620+
f"from-{orig}_to-{sym}{tmpl}template_mode-image_warp": (
1621+
fnirt_reg_anat_mni,
1622+
"outputspec.nonlinear_warp",
1623+
),
1624+
}
1625+
)
16211626
outputs.update(added_outputs)
16221627

1623-
return (wf, outputs)
1628+
return wf, outputs
16241629

16251630

16261631
def ANTs_registration_connector(
@@ -2256,6 +2261,7 @@ def bold_to_T1template_xfm_connector(
22562261
)
22572262
def register_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None):
22582263
"""Register T1w to template with FSL."""
2264+
assert opt in ["FSL", "FSL-linear"]
22592265
fsl, outputs = FSL_registration_connector(
22602266
f"register_{opt}_anat_to_template_{pipe_num}", cfg, orig="T1w", opt=opt
22612267
)
@@ -2274,11 +2280,18 @@ def register_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None):
22742280
node, out = connect
22752281
wf.connect(node, out, fsl, "inputspec.input_brain")
22762282

2277-
node, out = strat_pool.get_data("T1w-brain-template")
2278-
wf.connect(node, out, fsl, "inputspec.reference_brain")
2283+
if cfg["pipeline_setup", "organism"] == "non-human primate":
2284+
node, out = strat_pool.get_data("FNIRT-T1w-brain-template")
2285+
wf.connect(node, out, fsl, "inputspec.reference_brain")
22792286

2280-
node, out = strat_pool.get_data("T1w-template")
2281-
wf.connect(node, out, fsl, "inputspec.reference_head")
2287+
node, out = strat_pool.get_data("FNIRT-T1w-template")
2288+
wf.connect(node, out, fsl, "inputspec.reference_head")
2289+
else:
2290+
node, out = strat_pool.get_data("T1w-brain-template")
2291+
wf.connect(node, out, fsl, "inputspec.reference_brain")
2292+
2293+
node, out = strat_pool.get_data("T1w-template")
2294+
wf.connect(node, out, fsl, "inputspec.reference_head")
22822295

22832296
node, out = strat_pool.get_data(
22842297
["desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"]
@@ -2345,6 +2358,7 @@ def register_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None):
23452358
)
23462359
def register_symmetric_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None):
23472360
"""Register T1w to symmetric template with FSL."""
2361+
assert opt in ["FSL", "FSL-linear"]
23482362
fsl, outputs = FSL_registration_connector(
23492363
f"register_{opt}_anat_to_template_symmetric_{pipe_num}",
23502364
cfg,
@@ -2419,6 +2433,7 @@ def register_symmetric_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=N
24192433
)
24202434
def register_FSL_EPI_to_template(wf, cfg, strat_pool, pipe_num, opt=None):
24212435
"""Directly register the mean functional to an EPI template. No T1w involved."""
2436+
assert opt in ["FSL", "FSL-linear"]
24222437
fsl, outputs = FSL_registration_connector(
24232438
f"register_{opt}_EPI_to_template_{pipe_num}",
24242439
cfg,

0 commit comments

Comments
 (0)