Skip to content

Commit

Permalink
Merge branch 'dev-v2.0.0' into manseg_resample
Browse files Browse the repository at this point in the history
  • Loading branch information
akhanf committed Jan 28, 2025
2 parents 714669d + ccf2b76 commit 7ec2bed
Show file tree
Hide file tree
Showing 23 changed files with 2,999 additions and 1,889 deletions.
1 change: 1 addition & 0 deletions .dryrun_test_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ hippunfold test_data/bids_manualseg_1hemi test_out participant -np --modality ma
hippunfold test_data/bids_singleT2w test_out participant -np --modality T2w --t1_reg_template
hippunfold test_data/bids_singleT2w test_out participant -np --modality T2w --output_space T1w
hippunfold test_data/bids_T1w test_out participant -np --modality T1w --use-template-seg
hippunfold test_data/bids_singleT2w test_out participant -np --modality T2w --generate-myelin-map
10 changes: 0 additions & 10 deletions .github/workflows/python-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,4 @@ jobs:
run: |
poetry run hippunfold test_data/bids_singleT2w test_out participant -np --modality T1w --generate-myelin-map
- name: Test modality T1w with magdeburg atlas
run: |
poetry run hippunfold test_data/bids_T1w test_out participant -np --modality T1w --atlas magdeburg
- name: Test modality T1w with freesurfer atlas
run: |
poetry run hippunfold test_data/bids_T1w test_out participant -np --modality T1w --atlas freesurfer
- name: Test modality T1w with bigbrain and freesurfer atlas
run: |
poetry run hippunfold test_data/bids_T1w test_out participant -np --modality T1w --atlas bigbrain freesurfer
93 changes: 43 additions & 50 deletions hippunfold/config/snakebids.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ pybids_inputs:
suffix: 'T2w'
extension: '.nii.gz'
datatype: 'anat'
# invalid_filters: 'allow'
# space: null
wildcards:
- subject
- session
Expand All @@ -48,7 +46,6 @@ pybids_inputs:
filters:
suffix: 'b500'
extension: '.nii.gz'
invalid_filters: 'allow'
datatype: 'dwi'
wildcards:
- subject
Expand All @@ -59,8 +56,6 @@ pybids_inputs:
suffix: 'T1w'
extension: '.nii.gz'
datatype: 'anat'
# invalid_filters: 'allow'
# space: null
wildcards:
- subject
- session
Expand All @@ -72,7 +67,6 @@ pybids_inputs:
suffix: 'dseg'
extension: '.nii.gz'
datatype: 'anat'
invalid_filters: 'allow'
wildcards:
- subject
- session
Expand Down Expand Up @@ -179,28 +173,16 @@ parse_args:

--atlas:
choices:
- 'bigbrain'
- 'magdeburg'
- 'freesurfer'
- 'multihist7'
- 'macaque'
- 'mouse'
default:
- 'multihist7'
nargs: '+'
- 'bbhist'
default: 'multihist7'
help: 'Select the atlas (unfolded space) to use for subfield labels. (default: %(default)s)'

--no_unfolded_reg:
help: 'Do not perform unfolded space (2D) registration based on thickness, curvature, and gyrification for closer alignment to the reference atlas. NOTE: only multihist7 has these features currently, so this unfolded_reg is automatically skipped if a different atlas is chosen. (default: %(default)s)'
default: False
action: store_true

--native_surf:
help: 'Use native surf workflow to generate isosurfaces in native space, and use wb_command tools to resample. Note: this currently disables unfolded registration if applied (until it is implemented).'
help: "Do not perform unfolded space (2D) registration based on surface metrics (e.g. thickness, curvature, and gyrification) for closer alignment to the reference atlas. (default: %(default)s)"
default: False
action: store_true


--generate_myelin_map:
help: 'Generate myelin map using T1w divided by T2w, and map to surface with ribbon approach. Requires both T1w and T2w images to be present. (default: %(default)s)'
default: False
Expand Down Expand Up @@ -291,10 +273,10 @@ parse_args:

--workdir:
help: |
Folder for storing working files. If not specified, a temporary folder
will be made in your system's temp directory (e.g. /tmp). You can also
use environment variables when setting the workdir, e.g. --workdir '$SLURM_TMPDIR'.
default: null
Folder for storing working files. If not specified, will be in "work/" subfolder
in the output folder. You can also use environment variables when setting the
workdir, e.g. --workdir '$SLURM_TMPDIR'.
default: work
type: str


Expand Down Expand Up @@ -345,14 +327,15 @@ outlier_opts:
0p5mm: 7
1mm: 3
2mm: 1
default: 15
vertexOutlierThreshold: 3



#--- workflow specific configuration --

singularity:
autotop: 'docker://khanlab/hippunfold_deps:v0.5.1'
autotop: 'docker://khanlab/hippunfold_deps:workbench-2.0.1'

xfm_identity: resources/etc/identity_xfm.txt
xfm_identity_itk: resources/etc/identity_xfm_itk.txt
Expand Down Expand Up @@ -453,12 +436,35 @@ template_files:

atlas_files:
multihist7:
label_nii: sub-maxprob_label-hipp_desc-manualsubfieldsunfoldaligned_dseg.nii.gz
lut: desc-subfields_atlas-multihist7_dseg.tsv
label_list: labellist.txt
thickness: thickness.nii.gz
curvature: curvature.nii.gz
gyrification: gyrification.nii.gz
lut: desc-subfields_atlas-multihist7_dseg.tsv #<-- perhaps generate this from the cifti instead of having user provide it
surf_gii: hemi-{hemi}_space-unfold_label-{label}_{surf_type}.surf.gii
metric_gii: hemi-{hemi}_label-{label}_{metric}.shape.gii
label_gii: hemi-{hemi}_label-{label}_dseg.label.gii
label_wildcards:
- hipp
hemi_wildcards:
- L
- R
metric_wildcards:
- thickness
- gyrification
- curvature

bbhist:
lut: desc-subfields_dseg.tsv
surf_gii: sub-bbhist_hemi-{hemi}_space-unfold_label-{label}_{surf_type}.surf.gii
metric_gii: sub-bbhist_hemi-{hemi}_space-corobl_label-{label}_{metric}.shape.gii
label_gii: sub-bbhist_hemi-{hemi}_space-corobl_label-{label}_desc-manual_subfields.label.gii
label_wildcards:
- hipp
hemi_wildcards:
- L
- R
metric_wildcards:
- thickness
- gyrification
- curvature

bigbrain:
label_nii: sub-bigbrain_hemi-{hemi}_label-hipp_desc-manualsubfields_dseg.nii.gz
lut: desc-subfields_atlas-bigbrain_dseg.tsv
Expand Down Expand Up @@ -488,14 +494,6 @@ tissue_atlas_mapping:
dg: 8
srlm: 2
cyst: 7
bigbrain:
dg: 6
srlm: 7
cyst: 8
multihist7:
dg: 6
srlm: 7
cyst: 8
magdeburg:
dg: 3
srlm: 9
Expand All @@ -504,14 +502,11 @@ tissue_atlas_mapping:
dg: 209
srlm: 227
cyst: 228
mouse:
dg: 6
srlm: 7
cyst: 8
macaque:
default: #this is used for any other atlases
dg: 6
srlm: 7
cyst: 8


rigid_reg_template: False
no_reg_template: False
Expand All @@ -522,8 +517,7 @@ inject_template: upenn

template: CITI168

atlas:
- multihist7
atlas: multihist7



Expand All @@ -539,7 +533,8 @@ resource_urls:
synthseg_v0.1: 'zenodo.org/record/8184230/files/trained_model.3d_fullres.Task102_synsegGenDetailed.nnUNetTrainerV2.model_best.tar'
synthseg_v0.2: 'zenodo.org/record/8184230/files/trained_model.3d_fullres.Task203_synthseg.nnUNetTrainerV2.model_best.tar'
atlas:
multihist7: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395b782827451220b86dd8/?zip='
bbhist: 'www.dropbox.com/scl/fi/fdqujkekhlzbnxsah5kqr/atlas-bbhist_20250108.zip?rlkey=dupo8jtwjynbdou6xmr736txt&st=aiaqzpri&dl=0'
multihist7: 'www.dropbox.com/scl/fi/g07u7la7v1kwfgsty6ujc/atlas-multihist7_20250108.zip?rlkey=bi7wbdsm93upgnn3bmlv4f1hx&st=5iv33isc&dl=0'
bigbrain: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395b8b13d27b123094c96f/?zip='
magdeburg: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395b8013d27b122f94c938/?zip='
freesurfer: 'files.ca-1.osf.io/v1/resources/v8acf/providers/osfstorage/65395b8513d27b123094c96a/?zip='
Expand Down Expand Up @@ -689,9 +684,7 @@ skip_inject_template_labels: False
force_nnunet_model: False
t1_reg_template: False
generate_myelin_map: False
no_unfolded_reg: False
root: results
workdir: null
use_template_seg: False
template_seg_smoothing_factor: 2
native_surf: False
7 changes: 7 additions & 0 deletions hippunfold/resources/atlas-v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# WIP - workflow for updating atlases to new v2 specs

This example is run from the existing multihist atlas folder.

Still needs updates for cifti structure labels etc (will add this in once we have an updated wb_command/wb_view in our deps)

We currently have templates and atlases in hippunfold (selected by --template and --atlas), where the former selects the volume-based template used for volumetric registration, and the latter selects the unfolded-space subfields (and metrics for unfolded registration). I am proposing the latter become purely surface-based, so instead of providing labels and metrics in the volumetric unfolded space, we use giftis for everything, and this now becomes surface-templates instead of atlases.
106 changes: 106 additions & 0 deletions hippunfold/resources/atlas-v2/Snakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
hippunfold_dir = "/localscratch/hippunfold_khanlab"
hipp_dseg = "sub-maxprob_label-hipp_desc-manualsubfieldsunfoldaligned_dseg.nii.gz"
labellist = "labellist_withdg.txt"

hemis = ["L", "R"]
metrics = ["thickness", "curvature", "gyrification"]
surftypes = ["midthickness", "inner", "outer"]

hemi_to_structure = {"L": "CORTEX_LEFT", "R": "CORTEX_RIGHT"}
surf_to_secondary_type = {
"midthickness": "MIDTHICKNESS",
"inner": "PIAL",
"outer": "GRAY_WHITE",
}


rule all:
input:
expand(
"hemi-{hemi}_label-{label}_dseg.label.gii",
label=["hipp", "dentate"],
hemi=hemis,
),
expand(
"hemi-{hemi}_label-{label}_{metric}.shape.gii",
label=["hipp"],
hemi=hemis,
metric=metrics,
),
expand(
"hemi-{hemi}_space-unfold_label-{label}_{surftype}.surf.gii",
label=["hipp", "dentate"],
hemi=hemis,
surftype=surftypes,
),


rule hipp_dseg:
input:
hipp_dseg,
output:
temp("hipp_dseg.nii.gz"),
shell:
"cp {input} {output}"


rule dentate_dseg:
input:
hipp_dseg,
params:
dg_label=6,
output:
temp("dentate_dseg.nii.gz"),
shell:
"c3d {input} -scale 0 -shift {params.dg_label} -o {output}"


rule surf_gifti:
input:
surf_gii=Path(hippunfold_dir)
/ "hippunfold"
/ "resources"
/ "unfold_template_{label}"
/ "tpl-avg_space-unfold_den-unfoldiso_{surftype}.surf.gii",
params:
structure_type=lambda wildcards: hemi_to_structure[wildcards.hemi],
secondary_type=lambda wildcards: surf_to_secondary_type[wildcards.surftype],
surface_type="FLAT",
output:
surf_gii="hemi-{hemi}_space-unfold_label-{label}_{surftype}.surf.gii",
shell:
"cp {input} {output} && "
"wb_command -set-structure {output} {params.structure_type} -surface-type {params.surface_type}"
" -surface-secondary-type {params.secondary_type}"


rule label_gifti:
input:
dseg_nii="{label}_dseg.nii.gz",
lut=labellist,
surf_gii="hemi-{hemi}_space-unfold_label-{label}_midthickness.surf.gii",
params:
structure_type=lambda wildcards: hemi_to_structure[wildcards.hemi],
output:
label_gii="hemi-{hemi}_label-{label}_dseg.label.gii",
shadow:
"minimal"
shell:
"wb_command -volume-label-import {input.dseg_nii} {input.lut} label_vol.nii && "
"wb_command -volume-label-to-surface-mapping label_vol.nii {input.surf_gii} {output.label_gii} && "
"wb_command -set-structure {output} {params.structure_type}"


rule metric_gifti:
input:
metric_nii="{metric}.nii.gz",
surf_gii="hemi-{hemi}_space-unfold_label-{label}_inner.surf.gii", #existing metric niftis are on inner space
params:
structure_type=lambda wildcards: hemi_to_structure[wildcards.hemi],
output:
metric_gii="hemi-{hemi}_label-{label}_{metric}.shape.gii",
shadow:
"minimal"
shell:
"wb_command -volume-to-surface-mapping {input.metric_nii} {input.surf_gii} {output.metric_gii} -trilinear && "
"wb_command -set-structure {output} {params.structure_type}"
12 changes: 12 additions & 0 deletions hippunfold/resources/atlas-v2/labellist_withdg.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Subiculum
1 0 0 255 255
CA1
2 133 222 255 255
CA2
3 0 255 170 255
CA3
4 255 162 0 255
CA4
5 255 0 0 255
DG
6 255 255 0 255
10 changes: 1 addition & 9 deletions hippunfold/workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ 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"]:
config["no_unfolded_reg"] = True


inputs = snakebids.generate_inputs(
bids_dir=config["bids_dir"],
Expand Down Expand Up @@ -95,8 +91,6 @@ wildcard_constraints:
template="[a-zA-Z0-9]+",


if config["workdir"] == None:
config["workdir"] = mkdtemp()
work = os.path.expandvars(config["workdir"])
root = os.path.expandvars(config["root"])

Expand Down Expand Up @@ -151,9 +145,7 @@ include: "rules/qc.smk"
include: "rules/myelin_map.smk"


if config["native_surf"]:

include: "rules/native_surf.smk"
include: "rules/native_surf.smk"


if config["use_template_seg"]:
Expand Down
Loading

0 comments on commit 7ec2bed

Please sign in to comment.