Skip to content

Commit

Permalink
Merge branch 'templateseg2' of https://github.com/khanlab/hippunfold
Browse files Browse the repository at this point in the history
…into templateseg2
  • Loading branch information
Jordan DeKraker committed Apr 18, 2024
2 parents f2039f4 + 29836ad commit 42b9f1c
Show file tree
Hide file tree
Showing 22 changed files with 79 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:

- name: Setup env for hippunfold
run: |
echo "HIPPUNFOLD_CACHE_DIR=`pwd`/test_data/fake_models" >> $GITHUB_ENV
echo "HIPPUNFOLD_CACHE_DIR=`pwd`/test_data/hippunfold_cache_dir" >> $GITHUB_ENV
- name: Test single T2w bids
run: |
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.7"
python: "3.8"

# Build documentation in the docs/ directory with Sphinx
sphinx:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/images/QC/sub-001_hemi-L_desc-unetf3d_dice.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.8502973449669877
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pipeline/algorithms
outputs/output_files
outputs/visualization
outputs/QC
```


Expand Down
56 changes: 56 additions & 0 deletions docs/outputs/QC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Quality Control

A complex pipeline can have multiple points of failure, so its imprtant to check the QC folder to ensure results make sense. This will contain (for example) the following files:

hippunfold/
└── sub-001
└── qc
├── sub-001_from-T1w_to-CITI168_regqc.png
├── sub-001_hemi-L_desc-unetf3d_dice.tsv
├── sub-001_hemi-L_space-cropT1w_desc-subfields_atlas-histologyReference2023_dseg.png
├── sub-001_hemi-L_space-T1w_den-0p5mm_label-dentate_desc-subfields_midthickness.surf.png
└── sub-001_hemi-L_space-T1w_den-0p5mm_label-hipp_desc-subfields_midthickness.surf.png

These files will be mirrored in the right (`hemi-R`) hemisphere, but we will skip that here for brevity.

## Automated checks

A very fast quality check is to simply look at `sub-001_hemi-L_desc-unetf3d_dice.tsv` and ensure that this number is greater than `0.7`. Typically this criterion can be applied to all subjects, and subjects `<0.7` can simply be automatically discarded. A more in-depth explanation for this is provided at the bottom of this page.

To better understand some common points of failure, let's walk through the other files contained here:

## Catch-all failures

A good way to be sure that nothing has failed is also to look at the final results, as in the following snapshot images.

`sub-001_hemi-L_space-cropT1w_desc-subfields_atlas-histologyReference2023_dseg.png`:

![image](../images/QC/sub-001_hemi-L_space-cropT1w_desc-subfields_atlas-histologyReference2023_dseg.png)

Here we see a volumetric output of subfield parcellations. If you have some hippocampal expertise then you may be able to see right away whether the results make sense. Some common errors include missed parts of the hippocampus and, sometimes, parts of collateral sulcus are included as part of the hippocapus. This is because of gross or "catastrophic" failures in the UNet tissue classification, which should be caught be the above automated check. Still, this collage of sample slices should give a good sense for whether/how the segmentation has failed.

`sub-001_hemi-L_space-T1w_den-0p5mm_label-hipp_desc-subfields_midthickness.surf.png`:

![image](../images/QC/sub-001_hemi-L_space-T1w_den-0p5mm_label-hipp_desc-subfields_midthickness.surf.png)

`sub-001_hemi-L_space-T1w_den-0p5mm_label-dentate_desc-subfields_midthickness.surf.png`:

![image](../images/QC/sub-001_hemi-L_space-T1w_den-0p5mm_label-dentate_desc-subfields_midthickness.surf.png)

In these two images we see the output hippocampal and dentate gyrus surfaces, which should roughly resemble those shown in the HippUnfold manuscript (though they may have some differences in shape and/or sulcal/gyral patterning due to inter-individual variance!).

Sometimes the dentate gyrus surface may show a few large triangles that obscure the rest of the surface, as in the example here. This typically arises when just a few vertices are badly misplaced, and so typically this doesn't have much impact on quantitative results but it can look quite ugly in a figure. This can arise because the structure is small and contains few voxels, none of which have a laplace field close to a given value and so the xyz coordinate of a given laplace value is extrapolated badly. We will try to fix this issue in future releases.

## Registration/cropping failures

Though it seems simple, just getting the image roughly aligned to a template so we can then crop around the left and right hippocampi for subsequent processing (in `space-corobl`) can sometimes fail. We can examine this in the file `sub-001_from-T1w_to-CITI168_regqc.png`:

![image](../images/QC/sub-001_from-T1w_to-CITI168_regqc.png)

In this image, the subject tissue boundaries (e.g. grey matter, white matter, CSF, skull) are overlaid on a standard template. This is a linear alignment, so while gyri/sulci may not be well aligned, we should still see fairly good overlap that is sufficient to derive the position of the hippocampus in the image. This most often fails if the input images are in an unexpected orientation (e.g. this sometimes arises in ex-vivo scanning), and can sometimes be imporved by first running FSL's [reorient2std](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Fslutils).

## Checking the automated check

The `Dice > 0.7` rule is a good automatic check because HippUnfold typically shows high sensitivity to details in hippocampal structure, but when it fails it often does so catastrophically. These failures are very obvious, and can often be shown by this simple Dice score that compares a whole mask of the hippocampus to a whole mask of a hippocampus generated by a more conventional but less precise measure: diffeomorphic registration to a standard template. The Dice score should be good between the two methods, but will never be close to perfect (`>0.9`) since the HippUnfold method will differ as its more precise.

This issue typically only occurs in ~1% of cases.
7 changes: 4 additions & 3 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
docutils==0.17
sphinx-argparse
sphinx-argparse==0.4.0
sphinx_rtd_theme>=1.0.0
snakebids>=0.4.0
myst-parser
sphinxcontrib.asciinema
myst-parser==1.0.0
sphinxcontrib.asciinema==0.3.7
pulp<2.8.0

3 changes: 2 additions & 1 deletion hippunfold/config/snakebids.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ parse_args:
--version:
help: 'Print the version of HippUnfold'
action: version
version: "1.4.2-pre.35"
version: "1.4.2-pre.37"

--modality:
help: 'Type of image to run hippunfold on. Modality prefixed with seg will import an existing (manual) hippocampal tissue segmentation from that space, instead of running neural network (default: %(default)s)'
Expand Down Expand Up @@ -355,6 +355,7 @@ singularity:
autotop: 'docker://khanlab/hippunfold_deps:v0.5.0'

xfm_identity: resources/etc/identity_xfm.txt
xfm_identity_itk: resources/etc/identity_xfm_itk.txt

#templates enabled for template-based segmentation are here
# TODO: should also perhaps include modalities avaialble, and any custom crop_native_res settings
Expand Down
2 changes: 1 addition & 1 deletion hippunfold/pipeline_description.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"GeneratedBy": [
{
"Name": "hippunfold",
"Version": "1.4.2-pre.35",
"Version": "1.4.2-pre.37",
"CodeURL": "https://github.com/khanlab/hippunfold",
"Author": "Jordan DeKraker & Ali Khan",
"AuthorEmail": "[email protected]"
Expand Down
5 changes: 5 additions & 0 deletions hippunfold/resources/etc/identity_xfm_itk.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#Insight Transform File V1.0
#Transform 0
Transform: MatrixOffsetTransformBase_double_3_3
Parameters: 1 0 0 0 1 0 0 0 1 0 0 0
FixedParameters: 0 0 0
1 change: 1 addition & 0 deletions hippunfold/workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ wildcard_constraints:
density="[a-zA-Z0-9]+",
atlas="[a-zA-Z0-9]+",
autotop="[a-zA-Z0-9]+",
template="[a-zA-Z0-9]+",


root = os.path.join(config["root"], "hippunfold")
Expand Down
10 changes: 5 additions & 5 deletions hippunfold/workflow/rules/preproc_t2.smk
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def get_inputs_compose_t2_xfm_corobl(wildcards):
from_="T2w",
to="T1w",
desc="rigid",
type_="itk"
type_="itk",
),
)
t1_to_cor = (
Expand All @@ -271,7 +271,7 @@ def get_inputs_compose_t2_xfm_corobl(wildcards):
from_="T1w",
to="corobl",
desc="affine",
type_="itk"
type_="itk",
),
)
return {"t2_to_t1": t2_to_t1, "t1_to_cor": t1_to_cor}
Expand All @@ -287,7 +287,7 @@ def get_inputs_compose_t2_xfm_corobl(wildcards):
from_="T2w",
to=config["template"],
desc="affine",
type_="itk"
type_="itk",
),
)

Expand All @@ -296,7 +296,7 @@ def get_inputs_compose_t2_xfm_corobl(wildcards):
return {"t2_to_std": t2_to_std, "template_dir": template_dir}


def get_cmd_compose_t2_xfm_corobl(wildcards, input):
def get_cmd_compose_t2_xfm_corobl(wildcards, input, output):
if config["t1_reg_template"]:
# xfm0: t2 to t1
xfm0 = input.t2_to_t1
Expand All @@ -310,7 +310,7 @@ def get_cmd_compose_t2_xfm_corobl(wildcards, input):
"xfm_corobl"
].format(**wildcards)

return "c3d_affine_tool -itk {xfm0} -itk {xfm1} -mult -oitk {output}"
return f"c3d_affine_tool -itk {xfm0} -itk {xfm1} -mult -oitk {output}"


# now have t2 to t1 xfm, compose this with t1 to corobl xfm
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "hippunfold"
version = "1.4.2-pre.35"
version = "1.4.2-pre.37"
description = "BIDS App for Hippocampal AutoTop (automated hippocampal unfolding and subfield segmentation)"
authors = ["Jordan DeKraker & Ali Khan <[email protected]>"]

Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.

0 comments on commit 42b9f1c

Please sign in to comment.