|
3 | 3 | from pathlib import Path |
4 | 4 | from typing import List, Optional |
5 | 5 |
|
| 6 | +import networkx as nx |
6 | 7 | import pytest |
7 | 8 |
|
8 | 9 | import webknossos as wk |
@@ -51,6 +52,15 @@ def create_dummy_skeleton() -> wk.Skeleton: |
51 | 52 | return nml |
52 | 53 |
|
53 | 54 |
|
| 55 | +def create_dummy_nx_graph() -> nx.Graph: |
| 56 | + nx_graph = nx.Graph() |
| 57 | + nx_graph.add_node(1, position=(0, 1, 2), comment="node 1 nx") |
| 58 | + nx_graph.add_node(2, position=(3, 1, 2), comment="node 2 nx") |
| 59 | + nx_graph.add_edge(1, 2) |
| 60 | + |
| 61 | + return nx_graph |
| 62 | + |
| 63 | + |
54 | 64 | def test_doc_example() -> None: |
55 | 65 | from webknossos import Annotation |
56 | 66 |
|
@@ -108,6 +118,90 @@ def test_skeleton_creation() -> None: |
108 | 118 | assert grand_children[0].group == groups[0] |
109 | 119 |
|
110 | 120 |
|
| 121 | +def test_add_nx_graph() -> None: |
| 122 | + skeleton = create_dummy_skeleton() |
| 123 | + node_count = skeleton.get_total_node_count() |
| 124 | + tree_count = len(list(skeleton.flattened_trees())) |
| 125 | + group_count = len(list(skeleton.flattened_groups())) |
| 126 | + max_node_id = skeleton.get_max_node_id() |
| 127 | + |
| 128 | + nx_graph = create_dummy_nx_graph() |
| 129 | + skeleton.add_nx_graphs( |
| 130 | + {"first_group": [nx_graph, nx_graph], "second_group": [nx_graph]} |
| 131 | + ) |
| 132 | + |
| 133 | + # check number of groups, nodes and trees |
| 134 | + assert len(list(skeleton.flattened_groups())) == group_count + 2 |
| 135 | + assert skeleton.get_total_node_count() == node_count + 6 |
| 136 | + assert len(list(skeleton.flattened_trees())) == tree_count + 3 |
| 137 | + |
| 138 | + # check group names |
| 139 | + for group in skeleton.flattened_groups(): |
| 140 | + assert group.name in [ |
| 141 | + "first_group", |
| 142 | + "second_group", |
| 143 | + "Example Group", |
| 144 | + "Nested Group", |
| 145 | + ] |
| 146 | + |
| 147 | + # check node attributes |
| 148 | + max_node_id = skeleton.get_max_node_id() |
| 149 | + assert skeleton.get_node_by_id(max_node_id).comment == "node 2 nx" |
| 150 | + assert skeleton.get_node_by_id(max_node_id).position == (3, 1, 2) |
| 151 | + assert skeleton.get_node_by_id(max_node_id - 1).comment == "node 1 nx" |
| 152 | + assert skeleton.get_node_by_id(max_node_id - 1).position == (0, 1, 2) |
| 153 | + |
| 154 | + # check if edge was added |
| 155 | + for edge in skeleton.get_tree_by_id(max_node_id - 2).edges: |
| 156 | + assert (edge[0].id, edge[1].id) == (max_node_id - 1, max_node_id) |
| 157 | + |
| 158 | + |
| 159 | +def test_nml_generation(tmp_path: Path) -> None: |
| 160 | + OLD_NML_PATH = TESTDATA_DIR / "nmls" / "generate_nml_snapshot.nml" |
| 161 | + |
| 162 | + tree1 = create_dummy_nx_graph() |
| 163 | + tree2 = create_dummy_nx_graph() |
| 164 | + tree2.add_node(3, position=(3, 3, 3), comment="node 3 nx") |
| 165 | + |
| 166 | + tree_dict = {"first_group": [tree1], "second_group": [tree2]} |
| 167 | + |
| 168 | + # old_nml was generated with the old wknml library as follows: |
| 169 | + # params_wknml = {"name": "MyDataset", "scale": (1, 1, 1), "zoomLevel": 0.4} |
| 170 | + # old_nml = generate_nml(tree_dict=tree_dict, parameters=params_wknml) |
| 171 | + # with open(tmp_path / "annotation_old.nml", "wb") as f: |
| 172 | + # write_nml(f, old_nml) |
| 173 | + |
| 174 | + tree_dict = {"first_group": [tree1], "second_group": [tree2]} |
| 175 | + |
| 176 | + annotation = wk.Annotation( |
| 177 | + name="MyAnnotation", |
| 178 | + dataset_name="MyDataset", |
| 179 | + voxel_size=(1, 1, 1), |
| 180 | + zoom_level=0.4, |
| 181 | + ) |
| 182 | + |
| 183 | + annotation.skeleton.add_nx_graphs(tree_dict) |
| 184 | + |
| 185 | + annotation.save(tmp_path / "annotation_new.nml") |
| 186 | + |
| 187 | + old_skeleton = wk.Skeleton.load(OLD_NML_PATH) |
| 188 | + new_skeleton = wk.Skeleton.load(tmp_path / "annotation_new.nml") |
| 189 | + |
| 190 | + for old_group, new_group in zip( |
| 191 | + old_skeleton.flattened_groups(), new_skeleton.flattened_groups() |
| 192 | + ): |
| 193 | + assert old_group.name == new_group.name |
| 194 | + for old_child, new_child in zip(old_group.children, new_group.children): |
| 195 | + if isinstance(old_child, wk.Tree) and isinstance(new_child, wk.Tree): |
| 196 | + for old_node, new_node in zip(old_child.nodes, new_child.nodes): |
| 197 | + assert old_node.comment == new_node.comment |
| 198 | + assert old_node.position == new_node.position |
| 199 | + assert old_node.radius == new_node.radius |
| 200 | + for old_edge, new_edge in zip(old_child.edges, new_child.edges): |
| 201 | + assert old_edge[0].position == new_edge[0].position |
| 202 | + assert old_edge[1].position == new_edge[1].position |
| 203 | + |
| 204 | + |
111 | 205 | def diff_lines(lines_a: List[str], lines_b: List[str]) -> List[str]: |
112 | 206 | diff = list( |
113 | 207 | difflib.unified_diff( |
|
0 commit comments