|
28 | 28 | fsl_aff_to_rigid, |
29 | 29 | fslmaths_command, |
30 | 30 | mri_convert, |
31 | | - normalize_wmparc, |
32 | 31 | pad, |
33 | 32 | VolumeRemoveIslands, |
34 | 33 | wb_command, |
@@ -696,13 +695,15 @@ def afni_brain_connector(wf, cfg, strat_pool, pipe_num, opt): |
696 | 695 |
|
697 | 696 | wf.connect(anat_skullstrip, "out_file", anat_brain_mask, "in_file_a") |
698 | 697 |
|
| 698 | + outputs = {} |
| 699 | + |
699 | 700 | if strat_pool.check_rpool("desc-preproc_T1w"): |
700 | 701 | outputs = {"space-T1w_desc-brain_mask": (anat_brain_mask, "out_file")} |
701 | 702 |
|
702 | 703 | elif strat_pool.check_rpool("desc-preproc_T2w"): |
703 | 704 | outputs = {"space-T2w_desc-brain_mask": (anat_brain_mask, "out_file")} |
704 | 705 |
|
705 | | - return (wf, outputs) |
| 706 | + return wf, outputs |
706 | 707 |
|
707 | 708 |
|
708 | 709 | def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): |
@@ -1322,22 +1323,29 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): |
1322 | 1323 |
|
1323 | 1324 | wf.connect(combine_mask, "out_file", binarize_combined_mask, "in_file") |
1324 | 1325 |
|
1325 | | - if opt == "FreeSurfer-BET-Tight": |
1326 | | - outputs = { |
1327 | | - "space-T1w_desc-tight_brain_mask": ( |
1328 | | - binarize_combined_mask, |
1329 | | - "out_file", |
1330 | | - ) |
1331 | | - } |
1332 | | - elif opt == "FreeSurfer-BET-Loose": |
1333 | | - outputs = { |
1334 | | - "space-T1w_desc-loose_brain_mask": ( |
1335 | | - binarize_combined_mask, |
1336 | | - "out_file", |
1337 | | - ) |
1338 | | - } |
| 1326 | + # CCS brain mask is in FS space, transfer it back to native T1 space |
| 1327 | + match_fov_ccs_brain_mask = pe.Node( |
| 1328 | + interface=fsl.FLIRT(), name=f"match_fov_CCS_brain_mask_{node_id}" |
| 1329 | + ) |
| 1330 | + match_fov_ccs_brain_mask.inputs.apply_xfm = True |
| 1331 | + match_fov_ccs_brain_mask.inputs.uses_qform = True |
| 1332 | + match_fov_ccs_brain_mask.inputs.interp = "nearestneighbour" |
1339 | 1333 |
|
1340 | | - return (wf, outputs) |
| 1334 | + node, out = strat_pool.get_data("pipeline-fs_raw-average") |
| 1335 | + convert_fs_T1_to_nifti = pe.Node( |
| 1336 | + Function( |
| 1337 | + input_names=["in_file"], output_names=["out_file"], function=mri_convert |
| 1338 | + ), |
| 1339 | + name=f"convert_fs_T1_to_nifti_for_ccs_{node_id}", |
| 1340 | + ) |
| 1341 | + wf.connect(node, out, convert_fs_T1_to_nifti, "in_file") |
| 1342 | + wf.connect( |
| 1343 | + convert_fs_T1_to_nifti, "out_file", match_fov_ccs_brain_mask, "reference" |
| 1344 | + ) |
| 1345 | + |
| 1346 | + wf.connect(binarize_combined_mask, "out_file", match_fov_ccs_brain_mask, "in_file") |
| 1347 | + |
| 1348 | + return wf, {"space-T1w_desc-brain_mask": (match_fov_ccs_brain_mask, "out_file")} |
1341 | 1349 |
|
1342 | 1350 |
|
1343 | 1351 | def mask_T2(wf_name="mask_T2"): |
@@ -1408,9 +1416,8 @@ def mask_T2(wf_name="mask_T2"): |
1408 | 1416 | ) |
1409 | 1417 | def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None): |
1410 | 1418 | if opt not in anatomical_init.option_val: |
1411 | | - raise ValueError( |
1412 | | - f"\n[!] Error: Invalid option for deoblique: {opt}. \nExpected one of {anatomical_init.option_val}" |
1413 | | - ) |
| 1419 | + msg = f"\n[!] Error: Invalid option for deoblique: {opt}. \nExpected one of {anatomical_init.option_val}" |
| 1420 | + raise ValueError(msg) |
1414 | 1421 |
|
1415 | 1422 | if opt == "warp": |
1416 | 1423 | anat_deoblique = pe.Node( |
@@ -1500,15 +1507,15 @@ def acpc_align_head(wf, cfg, strat_pool, pipe_num, opt=None): |
1500 | 1507 | ( |
1501 | 1508 | "desc-head_T1w", |
1502 | 1509 | "desc-preproc_T1w", |
1503 | | - ["space-T1w_desc-brain_mask", "space-T1w_desc-brain_mask"], |
| 1510 | + "space-T1w_desc-brain_mask", |
1504 | 1511 | ), |
1505 | 1512 | "T1w-ACPC-template", |
1506 | 1513 | "T1w-brain-ACPC-template", |
1507 | 1514 | ], |
1508 | 1515 | outputs=[ |
1509 | 1516 | "desc-head_T1w", |
1510 | 1517 | "desc-preproc_T1w", |
1511 | | - ["space-T1w_desc-brain_mask", "space-T1w_desc-brain_mask"], |
| 1518 | + "space-T1w_desc-brain_mask", |
1512 | 1519 | "from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm", |
1513 | 1520 | ], |
1514 | 1521 | ) |
@@ -1939,211 +1946,102 @@ def brain_mask_acpc_unet(wf, cfg, strat_pool, pipe_num, opt=None): |
1939 | 1946 | ["anatomical_preproc", "run"], |
1940 | 1947 | ], |
1941 | 1948 | option_key=["anatomical_preproc", "brain_extraction", "using"], |
1942 | | - option_val="FreeSurfer-Brainmask", |
1943 | | - inputs=[ |
1944 | | - "pipeline-fs_raw-average", |
1945 | | - "pipeline-fs_brainmask", |
1946 | | - "freesurfer-subject-dir", |
| 1949 | + option_val=[ |
| 1950 | + "FreeSurfer-ABCD", |
| 1951 | + "FreeSurfer-BET-Loose", |
| 1952 | + "FreeSurfer-BET-Tight", |
| 1953 | + "FreeSurfer-Brainmask", |
1947 | 1954 | ], |
1948 | | - outputs=["space-T1w_desc-brain_mask"], |
1949 | | -) |
1950 | | -def brain_mask_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): |
1951 | | - wf, outputs = freesurfer_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
1952 | | - |
1953 | | - return (wf, outputs) |
1954 | | - |
1955 | | - |
1956 | | -@nodeblock( |
1957 | | - name="brain_mask_acpc_freesurfer", |
1958 | | - switch=[ |
1959 | | - ["anatomical_preproc", "brain_extraction", "run"], |
1960 | | - ["anatomical_preproc", "run"], |
1961 | | - ], |
1962 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
1963 | | - option_val="FreeSurfer-Brainmask", |
1964 | | - inputs=[ |
1965 | | - "space-T1w_desc-brain_mask", |
1966 | | - "pipeline-fs_raw-average", |
1967 | | - "freesurfer-subject-dir", |
1968 | | - ], |
1969 | | - outputs=["space-T1w_desc-acpcbrain_mask"], |
1970 | | -) |
1971 | | -def brain_mask_acpc_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): |
1972 | | - wf, wf_outputs = freesurfer_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
1973 | | - |
1974 | | - outputs = {"space-T1w_desc-acpcbrain_mask": wf_outputs["space-T1w_desc-brain_mask"]} |
1975 | | - |
1976 | | - return (wf, outputs) |
1977 | | - |
1978 | | - |
1979 | | -@nodeblock( |
1980 | | - name="brain_mask_freesurfer_abcd", |
1981 | | - switch=[ |
1982 | | - ["anatomical_preproc", "brain_extraction", "run"], |
1983 | | - ["anatomical_preproc", "run"], |
1984 | | - ], |
1985 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
1986 | | - option_val="FreeSurfer-ABCD", |
1987 | 1955 | inputs=[ |
1988 | | - ["desc-restore_T1w", "desc-preproc_T1w"], |
1989 | | - "pipeline-fs_wmparc", |
1990 | | - "pipeline-fs_raw-average", |
1991 | | - "freesurfer-subject-dir", |
1992 | | - ], |
1993 | | - outputs=["space-T1w_desc-brain_mask"], |
1994 | | -) |
1995 | | -def brain_mask_freesurfer_abcd(wf, cfg, strat_pool, pipe_num, opt=None): |
1996 | | - wf, outputs = freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
1997 | | - |
1998 | | - return (wf, outputs) |
1999 | | - |
2000 | | - |
2001 | | -@nodeblock( |
2002 | | - name="brain_mask_freesurfer_fsl_tight", |
2003 | | - switch=[ |
2004 | | - ["anatomical_preproc", "brain_extraction", "run"], |
2005 | | - ["anatomical_preproc", "run"], |
2006 | | - ], |
2007 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
2008 | | - option_val="FreeSurfer-BET-Tight", |
2009 | | - inputs=[ |
2010 | | - "pipeline-fs_brainmask", |
2011 | | - "pipeline-fs_T1", |
2012 | | - "pipeline-fs_raw-average", |
2013 | | - "freesurfer-subject-dir", |
| 1956 | + ( |
| 1957 | + ["desc-restore_T1w", "desc-preproc_T1w"], |
| 1958 | + "space-T1w_desc-brain_mask", |
| 1959 | + "pipeline-fs_T1", |
| 1960 | + "pipeline-fs_wmparc", |
| 1961 | + "pipeline-fs_raw-average", |
| 1962 | + "pipeline-fs_brainmask", |
| 1963 | + "freesurfer-subject-dir", |
| 1964 | + ), |
2014 | 1965 | "T1w-brain-template-mask-ccs", |
2015 | 1966 | "T1w-ACPC-template", |
2016 | 1967 | ], |
2017 | | - outputs={ |
2018 | | - "space-T1w_desc-brain_mask": { |
2019 | | - "Description": "Brain mask extracted using FreeSurfer-BET-Tight method", |
2020 | | - "Method": "FreeSurfer-BET-Tight", |
2021 | | - "Threshold": "tight", |
2022 | | - } |
2023 | | - }, |
| 1968 | + outputs={"space-T1w_desc-brain_mask": {}}, |
2024 | 1969 | ) |
2025 | | -def brain_mask_freesurfer_fsl_tight(wf, cfg, strat_pool, pipe_num, opt=None): |
2026 | | - wf, outputs = freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
2027 | | - |
2028 | | - # Convert the tight brain mask to generic brain mask |
2029 | | - outputs["space-T1w_desc-brain_mask"] = outputs.pop( |
2030 | | - "space-T1w_desc-tight_brain_mask" |
2031 | | - ) |
2032 | | - return (wf, outputs) |
| 1970 | +def brain_mask_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): |
| 1971 | + assert isinstance(brain_mask_freesurfer.outputs, dict) |
| 1972 | + brain_mask_freesurfer.outputs["space-T1w_desc-brain_mask"] = { |
| 1973 | + "Description": f"Brain mask extracted using {opt} method", |
| 1974 | + "Method": opt, |
| 1975 | + } |
| 1976 | + match opt: |
| 1977 | + case "FreeSurfer-ABCD": |
| 1978 | + return freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
| 1979 | + case "FreeSurfer-BET-Loose" | "FreeSurfer-BET-Tight": |
| 1980 | + brain_mask_freesurfer.outputs["space-T1w_desc-brain_mask"]["Threshold"] = ( |
| 1981 | + opt.rsplit("-")[-1].lower() |
| 1982 | + ) |
| 1983 | + return freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
| 1984 | + case "FreeSurfer-Brainmask": |
| 1985 | + return freesurfer_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
| 1986 | + return wf, {} |
2033 | 1987 |
|
2034 | 1988 |
|
2035 | 1989 | @nodeblock( |
2036 | | - name="brain_mask_acpc_freesurfer_abcd", |
| 1990 | + name="brain_mask_acpc_freesurfer", |
2037 | 1991 | switch=[ |
2038 | 1992 | ["anatomical_preproc", "brain_extraction", "run"], |
2039 | 1993 | ["anatomical_preproc", "run"], |
2040 | 1994 | ], |
2041 | 1995 | option_key=["anatomical_preproc", "brain_extraction", "using"], |
2042 | | - option_val="FreeSurfer-ABCD", |
2043 | | - inputs=[ |
2044 | | - ["desc-restore_T1w", "desc-preproc_T1w"], |
2045 | | - "pipeline-fs_wmparc", |
2046 | | - "pipeline-fs_raw-average", |
2047 | | - "freesurfer-subject-dir", |
2048 | | - ], |
2049 | | - outputs=["space-T1w_desc-acpcbrain_mask"], |
2050 | | -) |
2051 | | -def brain_mask_acpc_freesurfer_abcd(wf, cfg, strat_pool, pipe_num, opt=None): |
2052 | | - wf, wf_outputs = freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
2053 | | - |
2054 | | - outputs = {"space-T1w_desc-acpcbrain_mask": wf_outputs["space-T1w_desc-brain_mask"]} |
2055 | | - |
2056 | | - return (wf, outputs) |
2057 | | - |
2058 | | - |
2059 | | -@nodeblock( |
2060 | | - name="brain_mask_freesurfer_fsl_loose", |
2061 | | - switch=[ |
2062 | | - ["anatomical_preproc", "brain_extraction", "run"], |
2063 | | - ["anatomical_preproc", "run"], |
| 1996 | + option_val=[ |
| 1997 | + "FreeSurfer-ABCD", |
| 1998 | + "FreeSurfer-Brainmask", |
| 1999 | + "FreeSurfer-BET-Loose", |
| 2000 | + "FreeSurfer-BET-Tight", |
2064 | 2001 | ], |
2065 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
2066 | | - option_val="FreeSurfer-BET-Loose", |
2067 | 2002 | inputs=[ |
2068 | | - "pipeline-fs_brainmask", |
2069 | | - "pipeline-fs_T1", |
2070 | | - "pipeline-fs_raw-average", |
2071 | | - "freesurfer-subject-dir", |
2072 | | - "T1w-brain-template-mask-ccs", |
2073 | | - "T1w-ACPC-template", |
2074 | | - ], |
2075 | | - outputs={ |
2076 | | - "space-T1w_desc-brain_mask": { |
2077 | | - "Description": "Brain mask extracted using FreeSurfer-BET-Loose method", |
2078 | | - "Method": "FreeSurfer-BET-Loose", |
2079 | | - "Threshold": "loose", |
2080 | | - } |
2081 | | - }, |
2082 | | -) |
2083 | | -def brain_mask_freesurfer_fsl_loose(wf, cfg, strat_pool, pipe_num, opt=None): |
2084 | | - wf, outputs = freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
2085 | | - |
2086 | | - # Convert the loose brain mask to generic brain mask |
2087 | | - outputs["space-T1w_desc-brain_mask"] = outputs.pop( |
2088 | | - "space-T1w_desc-loose_brain_mask" |
2089 | | - ) |
2090 | | - return (wf, outputs) |
2091 | | - |
2092 | | - |
2093 | | -@nodeblock( |
2094 | | - name="brain_mask_acpc_freesurfer_fsl_tight", |
2095 | | - switch=[ |
2096 | | - ["anatomical_preproc", "brain_extraction", "run"], |
2097 | | - ["anatomical_preproc", "run"], |
2098 | | - ], |
2099 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
2100 | | - option_val="FreeSurfer-BET-Tight", |
2101 | | - inputs=[ |
2102 | | - "pipeline-fs_brainmask", |
2103 | | - "pipeline-fs_T1", |
2104 | | - "T1w-brain-template-mask-ccs", |
| 2003 | + ( |
| 2004 | + ["desc-restore_T1w", "desc-preproc_T1w"], |
| 2005 | + "space-T1w_desc-brain_mask", |
| 2006 | + "space-T1w_desc-acpcbrain_mask", |
| 2007 | + "pipeline-fs_brainmask", |
| 2008 | + "pipeline-fs_raw-average", |
| 2009 | + "pipeline-fs_T1", |
| 2010 | + "pipeline-fs_wmparc", |
| 2011 | + "freesurfer-subject-dir", |
| 2012 | + ), |
2105 | 2013 | "T1w-ACPC-template", |
2106 | | - ], |
2107 | | - outputs=["space-T1w_desc-tight_acpcbrain_mask"], |
2108 | | -) |
2109 | | -def brain_mask_acpc_freesurfer_fsl_tight(wf, cfg, strat_pool, pipe_num, opt=None): |
2110 | | - wf, wf_outputs = freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
2111 | | - |
2112 | | - outputs = { |
2113 | | - "space-T1w_desc-tight_acpcbrain_mask": wf_outputs[ |
2114 | | - "space-T1w_desc-tight_brain_mask" |
2115 | | - ] |
2116 | | - } |
2117 | | - |
2118 | | - return (wf, outputs) |
2119 | | - |
2120 | | - |
2121 | | -@nodeblock( |
2122 | | - name="brain_mask_acpc_freesurfer_fsl_loose", |
2123 | | - switch=[ |
2124 | | - ["anatomical_preproc", "brain_extraction", "run"], |
2125 | | - ["anatomical_preproc", "run"], |
2126 | | - ], |
2127 | | - option_key=["anatomical_preproc", "brain_extraction", "using"], |
2128 | | - option_val="FreeSurfer-BET-Loose", |
2129 | | - inputs=[ |
2130 | | - "pipeline-fs_brainmask", |
2131 | | - "pipeline-fs_T1", |
2132 | 2014 | "T1w-brain-template-mask-ccs", |
2133 | | - "T1w-ACPC-template", |
2134 | 2015 | ], |
2135 | | - outputs=["space-T1w_desc-loose_acpcbrain_mask"], |
| 2016 | + outputs={"space-T1w_desc-acpcbrain_mask": {}}, |
2136 | 2017 | ) |
2137 | | -def brain_mask_acpc_freesurfer_fsl_loose(wf, cfg, strat_pool, pipe_num, opt=None): |
2138 | | - wf, wf_outputs = freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt) |
2139 | | - |
2140 | | - outputs = { |
2141 | | - "space-T1w_desc-loose_acpcbrain_mask": wf_outputs[ |
2142 | | - "space-T1w_desc-loose_brain_mask" |
2143 | | - ] |
| 2018 | +def brain_mask_acpc_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): |
| 2019 | + if opt != strat_pool.get_json("space-T1w_desc-brain_mask").get( |
| 2020 | + "CpacVariant", {} |
| 2021 | + ).get("space-T1w_mask", opt): |
| 2022 | + # https://tenor.com/baIhQ.gif |
| 2023 | + return wf, {} |
| 2024 | + assert isinstance(brain_mask_acpc_freesurfer.outputs, dict) |
| 2025 | + outputs = wf_outputs = {} |
| 2026 | + key = "space-T1w_desc-brain_mask" |
| 2027 | + functions = { |
| 2028 | + "FreeSurfer-ABCD": freesurfer_abcd_brain_connector, |
| 2029 | + "FreeSurfer-Brainmask": freesurfer_brain_connector, |
| 2030 | + "FreeSurfer-BET-Loose": freesurfer_fsl_brain_connector, |
| 2031 | + "FreeSurfer-BET-Tight": freesurfer_fsl_brain_connector, |
2144 | 2032 | } |
| 2033 | + if opt in ["FreeSurfer-BET-Loose", "FreeSurfer-BET-Tight"]: |
| 2034 | + brain_mask_acpc_freesurfer.outputs["space-T1w_desc-acpcbrain_mask"] = { |
| 2035 | + "Description": f"Brain mask extracted using {opt} method", |
| 2036 | + "Method": opt, |
| 2037 | + "Threshold": opt.rsplit("-")[-1].lower(), |
| 2038 | + } |
| 2039 | + if opt in functions: |
| 2040 | + wf, wf_outputs = functions[opt](wf, cfg, strat_pool, pipe_num, opt) |
| 2041 | + if key in wf_outputs: |
| 2042 | + outputs = {"space-T1w_desc-acpcbrain_mask": wf_outputs[key]} |
2145 | 2043 |
|
2146 | | - return (wf, outputs) |
| 2044 | + return wf, outputs |
2147 | 2045 |
|
2148 | 2046 |
|
2149 | 2047 | @nodeblock( |
|
0 commit comments