From e6967c80fca151525adcfe5668ec5bf8ab68ac18 Mon Sep 17 00:00:00 2001 From: Jordan DeKraker Date: Mon, 8 Jul 2024 11:25:54 -0400 Subject: [PATCH 1/3] bigbrain template laplace coords added --- hippunfold/config/snakebids.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hippunfold/config/snakebids.yml b/hippunfold/config/snakebids.yml index a9fa2b3a..8fc8bb61 100644 --- a/hippunfold/config/snakebids.yml +++ b/hippunfold/config/snakebids.yml @@ -151,6 +151,7 @@ parse_args: - 'MBMv3' - 'CIVM' - 'ABAv3' + - 'bigbrain' default: 'CITI168' help: 'Set the template to use for registration to coronal oblique (and optionally for template-based segmentation if --use-template-seg is enabled). CITI168 is for adult human data, dHCP is for neonatal human data, MBMv2 is for ex vivo marmoset data, MBMv3 is for in vivo marmoset data, CIVM is for in vivo macaque data, and ABAv3 is for mouse data. When using a non-human template, consider using a corresponding atlas. (default: %(default)s)' @@ -164,6 +165,7 @@ parse_args: - 'MBMv3' - 'CIVM' - 'ABAv3' + - 'bigbrain' default: 'upenn' help: 'Set the template to use for shape injection. (default: %(default)s)' @@ -400,7 +402,10 @@ template_based_segmentation: hemi: - R - L - + bigbrain: + hemi: + - R + - L template_files: CITI168: @@ -455,6 +460,13 @@ template_files: Mask_crop: tpl-ABAv3_hemi-{hemi}_space-corobl_desc-tissuemanual_dseg.nii.gz dseg: tpl-ABAv3_hemi-{hemi}_space-corobl_desc-tissuemanual_dseg.nii.gz coords: tpl-ABAv3_dir-{dir}_hemi-{hemi}_space-corobl_label-{autotop}_desc-laplace_coords.nii.gz + bigbrain: + T1w: tpl-bbhist_100um_T1w.nii.gz + xfm_corobl: tpl-bbhist_from-native_to-corobl_type-itk_affine.txt + crop_ref: tpl-bbhist_hemi-{hemi}_space-corobl_desc-tissuemanual_40um_dseg.nii.gz + Mask_crop: tpl-bbhist_hemi-{hemi}_space-corobl_desc-tissuemanual_40um_dseg.nii.gz + dseg: tpl-bbhist_hemi-{hemi}_space-corobl_desc-tissuemanual_40um_dseg.nii.gz + coords: tpl-bbhist_dir-{dir}_hemi-{hemi}_space-corobl_label-{autotop}_desc-laplace_coords.nii.gz atlas_files: multihist7: @@ -558,6 +570,7 @@ resource_urls: upenn: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395c1613d27b122a94ca09/?zip=' CIVM: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395bf62827451220b86e24/?zip=' ABAv3: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/6668855b6b6c8e2cc704ca97/?zip=' + bigbrain: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/666b1bc765e1de5972893e59/?zip=' #to get hash, see https://github.com/CenterForOpenScience/osf.io/issues/8256#issuecomment-379833911 From 98ea109ff424d94e5b3146edf82dfc46dc72805c Mon Sep 17 00:00:00 2001 From: Jordan DeKraker Date: Wed, 10 Jul 2024 13:32:56 -0400 Subject: [PATCH 2/3] bugfix for using L or R template injection --- hippunfold/config/snakebids.yml | 10 ++- hippunfold/workflow/rules/shape_inject.smk | 77 ++++++++++++++++------ 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/hippunfold/config/snakebids.yml b/hippunfold/config/snakebids.yml index 8fc8bb61..33fa2ac3 100644 --- a/hippunfold/config/snakebids.yml +++ b/hippunfold/config/snakebids.yml @@ -384,21 +384,25 @@ template_based_segmentation: hemi: - R - L - CIVM: + dHCP: hemi: - R - L + MBMv2: hemi: - R MBMv3: hemi: - R - ABAv3: + CIVM: hemi: - R - L - dHCP: + upenn: + hemi: + - R + ABAv3: hemi: - R - L diff --git a/hippunfold/workflow/rules/shape_inject.smk b/hippunfold/workflow/rules/shape_inject.smk index f895d00f..ba2d2e90 100644 --- a/hippunfold/workflow/rules/shape_inject.smk +++ b/hippunfold/workflow/rules/shape_inject.smk @@ -1,3 +1,36 @@ +# Template-based segmentation supports templates that have only a single hemisphere +# by mapping it to the flipped version of the other hemisphere. +# If a template has both L and R files, then we set hemi_constrained_wildcard to L|R. +# If a hemisphere is missing data, then we set it to flip that, e.g. if L missing, then use Lflip|R + +hemi_constraints = [] +if config["template"] in config["template_based_segmentation"]: + for hemi in config["hemi"]: + if hemi in config["template_based_segmentation"][config["template"]]["hemi"]: + hemi_constraints.append(hemi) + else: + hemi_constraints.append(f"{hemi}flip") + +hemi_constrained_wildcard = "{{hemi,{constraints}}}".format( + constraints="|".join(hemi_constraints) +) + + +def flipped(wildcards): + """function to map hemi in wildcards from Lflip to R, or Rflip to L, + for use in rules where e.g. the output wildcard is Lflip, but for the input, R is desired, such as + when mapping a R hemi dseg to the Lflip hemisphere of a subject.""" + + if wildcards.hemi == "L" or wildcards.hemi == "R": + return wildcards + elif wildcards.hemi == "Lflip": + wildcards.hemi = "R" + return wildcards + elif wildcards.hemi == "Rflip": + wildcards.hemi = "L" + return wildcard + + def get_input_for_shape_inject(wildcards): if config["modality"] == "cropseg": seg = bids( @@ -6,7 +39,7 @@ def get_input_for_shape_inject(wildcards): **config["subj_wildcards"], suffix="dseg.nii.gz", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ).format(**wildcards) elif get_modality_key(config["modality"]) == "seg": modality_suffix = get_modality_suffix(config["modality"]) @@ -29,7 +62,7 @@ def get_input_for_shape_inject(wildcards): suffix="dseg.nii.gz", desc="nnunet", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ).format(**wildcards) return seg @@ -42,7 +75,7 @@ def get_input_splitseg_for_shape_inject(wildcards): **config["subj_wildcards"], suffix="dsegsplit", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ).format(**wildcards) elif get_modality_key(config["modality"]) == "seg": @@ -64,11 +97,12 @@ def get_input_splitseg_for_shape_inject(wildcards): suffix="dsegsplit", desc="nnunet", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ).format(**wildcards) return seg + rule prep_segs_for_greedy: input: "{prefix}_dseg.nii.gz", @@ -92,7 +126,7 @@ rule import_template_shape: params: template_seg=lambda wildcards, input: Path(input.template_dir) / config["template_files"][config["inject_template"]]["dseg"].format( - **wildcards + **flipped(wildcards) ), output: template_seg=bids( @@ -101,6 +135,7 @@ rule import_template_shape: space="template", **config["subj_wildcards"], desc="hipptissue", + hemi=hemi_constrained_wildcard, suffix="dseg.nii.gz" ), group: @@ -164,6 +199,7 @@ rule template_shape_reg: space="template", **config["subj_wildcards"], desc="hipptissue", + hemi="{hemi}", suffix="dsegsplit" ), subject_seg=get_input_splitseg_for_shape_inject, @@ -183,7 +219,7 @@ rule template_shape_reg: to="subject", space="corobl", type_="ras", - hemi="{hemi,Lflip|R}" + hemi=hemi_constrained_wildcard, ), warp=bids( root=work, @@ -194,7 +230,7 @@ rule template_shape_reg: from_="template", to="subject", space="corobl", - hemi="{hemi,Lflip|R}" + hemi=hemi_constrained_wildcard, ), group: "subj" @@ -205,7 +241,7 @@ rule template_shape_reg: bids( root="logs", **config["subj_wildcards"], - hemi="{hemi,Lflip|R}", + hemi=hemi_constrained_wildcard, suffix="templateshapereg.txt" ), shell: @@ -222,6 +258,7 @@ rule template_shape_inject: space="template", **config["subj_wildcards"], desc="hipptissue", + hemi="{hemi}", suffix="dseg.nii.gz" ), subject_seg=get_input_for_shape_inject, @@ -235,7 +272,7 @@ rule template_shape_inject: to="subject", space="corobl", type_="ras", - hemi="{hemi}" + hemi="{hemi}", ), warp=bids( root=work, @@ -246,7 +283,7 @@ rule template_shape_inject: from_="template", to="subject", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ), params: interp_opt="-ri LABEL 0.2vox", @@ -258,14 +295,14 @@ rule template_shape_inject: suffix="dseg.nii.gz", desc="inject", space="corobl", - hemi="{hemi,Lflip|R}" + hemi=hemi_constrained_wildcard, ), log: bids( root="logs", **config["subj_wildcards"], suffix="templateshapeinject.txt", - hemi="{hemi,Lflip|R}" + hemi=hemi_constrained_wildcard, ), group: "subj" @@ -289,7 +326,7 @@ rule inject_init_laplace_coords: to="subject", space="corobl", type_="ras", - hemi="{hemi}" + hemi="{hemi}", ), warp=bids( root=work, @@ -300,7 +337,7 @@ rule inject_init_laplace_coords: from_="template", to="subject", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ), template_dir=Path(download_dir) / "template" / config["inject_template"], params: @@ -319,7 +356,7 @@ rule inject_init_laplace_coords: suffix="coords.nii.gz", desc="init", space="corobl", - hemi="{hemi,R|Lflip}" + hemi=hemi_constrained_wildcard, ), log: bids( @@ -329,7 +366,7 @@ rule inject_init_laplace_coords: label="{autotop}", suffix="injectcoords.txt", desc="init", - hemi="{hemi,R|Lflip}" + hemi=hemi_constrained_wildcard, ), group: "subj" @@ -365,7 +402,7 @@ rule unflip_init_coords: suffix="coords.nii.gz", desc="init", space="corobl", - hemi="{hemi,L}" + hemi="{hemi,L|R}" ), container: config["singularity"]["autotop"] @@ -385,7 +422,7 @@ rule reinsert_subject_labels: suffix="dseg.nii.gz", desc="inject", space="corobl", - hemi="{hemi}" + hemi="{hemi}", ), subject_seg=get_input_for_shape_inject, params: @@ -400,7 +437,7 @@ rule reinsert_subject_labels: suffix="dseg.nii.gz", desc="postproc", space="corobl", - hemi="{hemi,Lflip|R}" + hemi=hemi_constrained_wildcard, ), group: "subj" @@ -429,7 +466,7 @@ rule unflip_postproc: suffix="dseg.nii.gz", desc="postproc", space="corobl", - hemi="{hemi,L}", + hemi="{hemi,L|R}", **config["subj_wildcards"] ), container: From c8fe2b8c57aa96775e2e853b4d39f8bdbee8c0bf Mon Sep 17 00:00:00 2001 From: Jordan DeKraker Date: Wed, 10 Jul 2024 13:34:46 -0400 Subject: [PATCH 3/3] lint --- hippunfold/workflow/rules/shape_inject.smk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hippunfold/workflow/rules/shape_inject.smk b/hippunfold/workflow/rules/shape_inject.smk index ba2d2e90..635333a1 100644 --- a/hippunfold/workflow/rules/shape_inject.smk +++ b/hippunfold/workflow/rules/shape_inject.smk @@ -51,7 +51,7 @@ def get_input_for_shape_inject(wildcards): suffix="dseg.nii.gz", space="corobl", hemi="{hemi}", - from_="{modality_suffix}" + from_="{modality_suffix}", ).format(**wildcards, modality_suffix=modality_suffix), ) else: @@ -87,7 +87,7 @@ def get_input_splitseg_for_shape_inject(wildcards): suffix="dsegsplit", space="corobl", hemi="{hemi}", - from_="{modality_suffix}" + from_="{modality_suffix}", ).format(**wildcards, modality_suffix=modality_suffix) else: seg = bids( @@ -102,7 +102,6 @@ def get_input_splitseg_for_shape_inject(wildcards): return seg - rule prep_segs_for_greedy: input: "{prefix}_dseg.nii.gz",