File size: 3,559 Bytes
6bc44d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""The parcellation's pure-numpy pieces: the node table (84 nodes, 14 lobar groups), the majority vote and the
derived labels / stop mask. No SynthSeg, no TensorFlow, no download -- everything here is synthetic and fast."""
import numpy as np
import pytest

from tools import build_parcellation as BP


def test_node_table_has_84_nodes_and_14_lobar_groups():
    nodes = BP.node_table()
    assert len(nodes) == 84
    assert len(set(n["id"] for n in nodes)) == 84
    assert set(n["id"] for n in nodes) == set(range(1, 85))
    left = [n for n in nodes if n["hemisphere"] == "left"]
    right = [n for n in nodes if n["hemisphere"] == "right"]
    assert len(left) == 42 and len(right) == 42
    cortical = [n for n in nodes if n["lobe"] != "subcortical"]
    subcortical = [n for n in nodes if n["lobe"] == "subcortical"]
    assert len(cortical) == 68 and len(subcortical) == 16
    regions = BP.regions_payload()
    groups = regions["lobes"]
    assert len(groups) == 14 and len(set(groups)) == 14
    for lobe in BP.LOBES:
        assert f"{lobe}-left" in groups and f"{lobe}-right" in groups


def test_node_table_ids_are_unique_per_fs_label_and_hemisphere():
    nodes = BP.node_table()
    keys = [(n["fs_label"], n["hemisphere"]) for n in nodes]
    assert len(set(keys)) == len(keys)


def test_supersampled_affine_centres_subvoxels_within_the_parent_voxel():
    ref_affine = np.array([[2.5, 0, 0, 10.0], [0, 2.5, 0, -5.0], [0, 0, 2.5, 3.0], [0, 0, 0, 1]])
    for factor in (1, 2, 4, 5):
        sup = BP._supersampled_affine(ref_affine, factor)
        # the mean of the factor**3 sub-voxel centres of parent voxel (2, 1, 0) must equal that parent's own centre
        idx = np.arange(factor)
        grid = np.stack(np.meshgrid(idx, idx, idx, indexing="ij"), axis=-1).reshape(-1, 3)
        sub_index = np.array([2, 1, 0]) * factor + grid
        world = sub_index @ sup[:3, :3].T + sup[:3, 3]
        parent_world = ref_affine[:3, :3] @ [2, 1, 0] + ref_affine[:3, 3]
        np.testing.assert_allclose(world.mean(axis=0), parent_world, atol=1e-9)


def test_majority_vote_picks_the_plurality_label_under_identity_registration():
    # a tiny "T1" label volume at 1 mm, two blocks of 3x3x3 mostly-9 voxels with a 2-voxel minority, at the origin;
    # the "diffusion" grid is 3x coarser (3 mm) and exactly covers one combined super-voxel.
    seg = np.full((3, 3, 3), 9, dtype=np.int32)
    seg[0, 0, 0] = 5
    seg[0, 0, 1] = 5
    seg_affine = np.eye(4)
    ref_affine = np.diag([3.0, 3.0, 3.0, 1.0])
    ref_affine[:3, 3] = 1.0  # the single ref voxel's centre sits at the seg block's centre
    majority = BP.majority_vote(seg, seg_affine, (1, 1, 1), ref_affine, np.eye(4), factor=3)
    assert majority.shape == (1, 1, 1)
    assert majority[0, 0, 0] == 9  # 25 votes for 9 against 2 for 5


def test_labels_and_stop_mask_from_majority_labels():
    majority = np.array([[[0, 2, 1001]]])  # background, left cerebral WM, left bankssts
    labels, stop = BP.labels_and_stop_mask(majority)
    assert labels[0, 0, 0] == 0
    assert labels[0, 0, 2] == 1  # bankssts is fs id 1001, the first (lowest) left-hemisphere node
    assert stop.tolist() == [[[False, True, False]]]


def test_label_volumes_mm3():
    labels = np.array([0, 0, 1, 1, 1, 2], dtype=np.int16)
    vols = BP.label_volumes_mm3(labels, voxel_volume_mm3=8.0)
    assert vols == {1: 24.0, 2: 8.0}


def test_every_cortical_name_has_a_lobe():
    assert set(BP.LOBE_OF_CORTICAL) == set(BP.CORTICAL_NAMES.values())
    assert set(BP.LOBE_OF_CORTICAL.values()) <= set(BP.LOBES)