From ae0beeb46c9fa916b4a16130fb118fc26c31eea0 Mon Sep 17 00:00:00 2001 From: Ali Khan Date: Mon, 23 Dec 2024 21:12:05 -0500 Subject: [PATCH] Still WIP TODO: - make alternative script for volumetric subfield labelling that uses label_gifti intstead of label_nifti - the volumetric targets are all turned off for now until that is done, since the cropref space relies on the subfields - add some smoothing for native surfaces (maybe another PR) - verify that the unfoldreg warping is being performed properly (compare with images, or make a toy example) - try with a single subject atlas, where the atlas is defined on it's own unfolded tesselation instead of unfoldiso - could make some target rules to generate the files for this (e.g. the subject metrics in unfold 2d slice, along with native and unfold meshes) --- hippunfold/workflow/Snakefile | 3 +- hippunfold/workflow/rules/common.smk | 30 +---- hippunfold/workflow/rules/native_surf.smk | 133 +++++++++++++++++----- hippunfold/workflow/rules/subfields.smk | 2 + 4 files changed, 112 insertions(+), 56 deletions(-) diff --git a/hippunfold/workflow/Snakefile b/hippunfold/workflow/Snakefile index c9952da9..806ff004 100644 --- a/hippunfold/workflow/Snakefile +++ b/hippunfold/workflow/Snakefile @@ -62,7 +62,7 @@ if config["skip_inject_template_labels"]: # TODO do we need this? limit_to_list.add(config["modality"]) # if atlas doesn't contain alignment features -if not config["atlas"] == ["multihist7"] or config["native_surf"]: +if not config["atlas"] == ["multihist7"]: config["no_unfolded_reg"] = True @@ -172,7 +172,6 @@ else: include: "rules/shape_inject.smk" - rule all: input: get_final_output(), diff --git a/hippunfold/workflow/rules/common.smk b/hippunfold/workflow/rules/common.smk index 91fd1c23..64a20e1e 100644 --- a/hippunfold/workflow/rules/common.smk +++ b/hippunfold/workflow/rules/common.smk @@ -335,11 +335,11 @@ def get_final_qc(): def get_final_subj_output(): subj_output = [] subj_output.extend(get_final_spec()) - subj_output.extend(get_final_subfields()) - subj_output.extend(get_final_coords()) - subj_output.extend(get_final_transforms()) - subj_output.extend(get_final_anat()) - subj_output.extend(get_final_qc()) + # subj_output.extend(get_final_subfields()) + # subj_output.extend(get_final_coords()) + # subj_output.extend(get_final_transforms()) + # subj_output.extend(get_final_anat()) + # subj_output.extend(get_final_qc()) return subj_output @@ -349,25 +349,7 @@ def get_final_output(): else: subj_output = get_final_work_tar() - final_output = [] - - modality_suffix = get_modality_suffix(config["modality"]) - modality_key = config["modality"] - - # use a zip list for subject/session: - zip_list = inputs[modality_key].zip_lists - if "session" in zip_list: - zip_list = snakebids.filter_list( - zip_list, - {"session": inputs[config["modality"]].zip_lists["session"]}, - ) - final_output.extend( - expand( - expand(subj_output, zip, allow_missing=True, **zip_list), - modality_suffix=modality_suffix, - ) - ) - return final_output + return subj_output if "corobl" in ref_spaces: diff --git a/hippunfold/workflow/rules/native_surf.smk b/hippunfold/workflow/rules/native_surf.smk index fc99667a..81a6b418 100644 --- a/hippunfold/workflow/rules/native_surf.smk +++ b/hippunfold/workflow/rules/native_surf.smk @@ -16,14 +16,14 @@ resample_from_density = ( ) -unfoldreg_metrics = [ 'thickness', 'curvature', 'gyrification'] +# could allow user to select additional metrics (e.g. from bold, dwi ...) +unfoldreg_metrics = [ 'thickness', 'curvature', 'gyrification'] # if we aren't doing unfolded reg, then we have these rules override correct_bad_vertices2 ruleorder: resample_native_surf > cp_template_to_unfold -#ruleorder: cp_template_to_unfold > resample_native_surf -ruleorder: resample_native_surf > correct_bad_vertices2 -ruleorder: warp_midthickness_to_inout > correct_bad_vertices2 +#ruleorder: resample_native_surf > correct_bad_vertices2 +#ruleorder: warp_midthickness_to_inout > correct_bad_vertices2 ruleorder: unfold_spring_model > warp_unfold_native_to_unfoldreg rule prep_hipp_coords_for_meshing: @@ -497,6 +497,46 @@ rule warp_midthickness_to_inout: " -surface-secondary-type {params.secondary_type}" +# warp native surface from corobl to T1w/T2w +rule affine_gii_corobl_to_modality: + input: + gii=bids( + root=work, + datatype="surf", + suffix="{surfname}.surf.gii", + space="corobl", + hemi="{hemi}", + label="{autotop}", + **inputs.subj_wildcards + ), + xfm=bids( + root=work, + datatype="warps", + **inputs.subj_wildcards, + suffix="xfm.txt", + from_="{native_modality}", + to="corobl", + desc="affine", + type_="ras" + ), + output: + gii=bids( + root=root, + datatype="surf", + suffix="{surfname}.surf.gii", + space="{native_modality}", + hemi="{hemi}", + label="{autotop,hipp|dentate}", + **inputs.subj_wildcards + ), + container: + config["singularity"]["autotop"] + group: + "subj" + shell: + "wb_command -surface-apply-affine {input.gii} {input.xfm} {output.gii}" + + rule unfold_spring_model: input: @@ -801,20 +841,7 @@ rule native_metric_to_unfold_nii: " -ribbon-constrained {input.inner_surf} {input.outer_surf}" -print(bids( - root=work, - suffix="xfm.nii.gz", - datatype="warps", - desc="SyN", - from_="native", - to_="{atlas}", - space="unfold", - type_="itk", - hemi="{hemi}", - label="{label}", - **inputs.subj_wildcards, - )) - + rule unfoldreg: """performs 2D registration in unfolded space as in [reference paper] this is done in a shadow directory to get rid of the tmp files generated by ants.""" @@ -1000,7 +1027,7 @@ rule warp_unfold_native_to_unfoldreg: datatype="warps", desc="SyN", from_="native", - to="{atlas}", + to=config['atlas'][0], space="unfold", type_="surface", hemi="{hemi}", @@ -1017,7 +1044,6 @@ rule warp_unfold_native_to_unfoldreg: datatype="surf", suffix="{surfname}.surf.gii", space="unfoldreg", - atlas="{atlas}", hemi="{hemi}", label="{label}", **inputs.subj_wildcards @@ -1088,7 +1114,7 @@ rule resample_subfields_to_native_surf: rule resample_native_surf: input: - native_corobl=bids( + native=bids( root=work, datatype="surf", suffix="{surf_name}.surf.gii", @@ -1109,21 +1135,19 @@ rule resample_native_surf: datatype="surf", suffix="midthickness.surf.gii", space="unfoldreg", - atlas="{atlas}", hemi="{hemi}", label="{label}", **inputs.subj_wildcards ), output: - native_corobl_resampled=bids( + native_resampled=bids( root=work, datatype="surf", suffix="{surf_name,midthickness}.surf.gii", space="{space}", den="{density}", hemi="{hemi}", - atlas="{atlas}", label="{label}", **inputs.subj_wildcards, ), @@ -1133,7 +1157,7 @@ rule resample_native_surf: group: "subj" shell: - "wb_command -surface-resample {input.native_corobl} {input.native_unfold} {input.ref_unfold} BARYCENTRIC {output.native_corobl_resampled} -bypass-sphere-check" + "wb_command -surface-resample {input.native} {input.native_unfold} {input.ref_unfold} BARYCENTRIC {output.native_resampled} -bypass-sphere-check" rule resample_native_metric: @@ -1142,7 +1166,7 @@ rule resample_native_metric: root=work, datatype="surf", suffix="{metric}.{metrictype}.gii", - space="{space}", + space="corobl", #metrics always calculated in corobl hemi="{hemi}", label="{label}", **inputs.subj_wildcards @@ -1159,7 +1183,6 @@ rule resample_native_metric: datatype="surf", suffix="midthickness.surf.gii", space="unfoldreg", - atlas="{atlas}", hemi="{hemi}", label="{label}", **inputs.subj_wildcards @@ -1167,12 +1190,11 @@ rule resample_native_metric: output: metric_resampled=bids( - root=work, + root=root, datatype="surf", suffix="{metric}.{metrictype,shape|func}.gii", space="{space}", den="{density}", - atlas="{atlas}", hemi="{hemi}", label="{label}", **inputs.subj_wildcards, @@ -1185,5 +1207,56 @@ rule resample_native_metric: shell: "wb_command -metric-resample {input.native_metric} {input.native_unfold} {input.ref_unfold} BARYCENTRIC {output.metric_resampled} -bypass-sphere-check" +rule cp_surf_to_root: + input: + native_resampled=bids( + root=work, + datatype="surf", + suffix="{surf_name,midthickness}.surf.gii", + space="{space}", + den="{density}", + hemi="{hemi}", + label="{label}", + **inputs.subj_wildcards, + ), + output: + native_resampled=bids( + root=root, + datatype="surf", + suffix="{surf_name,midthickness}.surf.gii", + space="{space}", + den="{density}", + hemi="{hemi}", + label="{label}", + **inputs.subj_wildcards, + ), + shell: + "cp {input} {output}" +""" +rule cp_metric_to_root: + input: + metric_resampled=bids( + root=work, + datatype="surf", + suffix="{metricname}.{metrictype}.gii", + space="{space}", + den="{density}", + atlas=config['atlas'][0], + hemi="{hemi}", + label="{label}", + **inputs.subj_wildcards, + ), + output: + metric_resampled=bids( + root=root, + datatype="surf", + suffix="{metricname}.{metrictype,shape|func}.gii", + space="{space}", + den="{density}", + hemi="{hemi}", + label="{label}", + **inputs.subj_wildcards, + ), + shell: 'cp {input} {output}' - +""" diff --git a/hippunfold/workflow/rules/subfields.smk b/hippunfold/workflow/rules/subfields.smk index 229b5b87..5af5a7e9 100644 --- a/hippunfold/workflow/rules/subfields.smk +++ b/hippunfold/workflow/rules/subfields.smk @@ -73,6 +73,8 @@ def skip_unfoldreg_option_subfields(wildcards): return label_nii +#TODO: replace this with a function that operates on the label gifti instead for native_warp workflow +# to avoid use of the unfold2native warps rule label_subfields_from_vol_coords_corobl: """ Label subfields using the volumetric coords and atlas subfield labels""" input: