Skip to content

Commit 5a71c9c

Browse files
authored
Merge pull request #54 from CSDLLab/2021_0607_add_config_help
add explaination on the detail type
2 parents c1dec9d + 67e0b11 commit 5a71c9c

File tree

6 files changed

+77
-21
lines changed

6 files changed

+77
-21
lines changed

config/branch_metric.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"threshold_dis": 2,
33
"threshold_mode": 1,
44
"z_scale": 1,
5-
"true_positive_type": 3,
6-
"false_negative_type": 4,
7-
"false_positive_type": 5
5+
"true_positive": 3,
6+
"missed": 4,
7+
"excess": 5
88
}

config/schemas/branch_metric_schema.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
"threshold_dis",
66
"threshold_mode",
77
"z_scale",
8-
"true_positive_type",
9-
"false_negative_type",
10-
"false_positive_type"
8+
"true_positive",
9+
"missed",
10+
"excess"
1111
],
1212
"properties": {
1313
"threshold_dis": {"type": "number", "exclusiveMinimum": 0},
1414
"threshold_mode": {"type": "number", "enum": [1, 2]},
1515
"z_scale": {"type": "number","minimum": 0},
16-
"true_positive_type": {"type": "integer", "exclusiveMinimum": 0},
17-
"false_negative_type": {"type": "integer", "exclusiveMinimum": 0},
18-
"false_positive_type": {"type": "integer", "exclusiveMinimum": 0}
16+
"true_positive": {"type": "integer", "exclusiveMinimum": 0},
17+
"missed": {"type": "integer", "exclusiveMinimum": 0},
18+
"excess": {"type": "integer", "exclusiveMinimum": 0}
1919
}
2020
}

pyneval/cli/pyneval.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from pyneval.metric import branch_leaf_metric
1414
from pyneval.metric import link_metric
1515
from pyneval.metric import ssd_metric
16+
from pyneval.metric.utils import anno_utils
17+
1618

1719
METRICS = {
1820
'diadem_metric': {
@@ -193,10 +195,9 @@ def set_configs(abs_dir, args):
193195

194196
config = read_json.read_json(config_path)
195197
config_schema = read_json.read_json(config_schema_path)
196-
try:
197-
jsonschema.validate(config, config_schema)
198-
except Exception:
199-
raise Exception("[Error: ]Error in analyzing config json file")
198+
199+
jsonschema.validate(config, config_schema)
200+
200201

201202
# argument: output
202203
output_dir = None
@@ -230,10 +231,15 @@ def excute_metric(metric, gold_swc_tree, test_swc_tree, config, detail_dir, outp
230231
file_name = test_swc_name[:-4] + "_" + metric + "_"
231232

232233
if detail_dir:
233-
swc_save(swc_tree=res_gold_swc_tree,
234-
out_path=os.path.join(detail_dir, file_name + "recall.swc"))
235-
swc_save(swc_tree=res_test_swc_tree,
236-
out_path=os.path.join(detail_dir, file_name + "precision.swc"))
234+
if res_gold_swc_tree is not None:
235+
swc_save(swc_tree=res_gold_swc_tree,
236+
out_path=os.path.join(detail_dir, file_name + "recall.swc"),
237+
extra=anno_utils.get_detail_type(metric))
238+
if res_test_swc_tree is not None:
239+
swc_save(swc_tree=res_test_swc_tree,
240+
out_path=os.path.join(detail_dir, file_name + "precision.swc"),
241+
extra=anno_utils.get_detail_type(metric))
242+
237243

238244
if output_dir:
239245
read_json.save_json(data=result,

pyneval/io/swc_writer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ def print_swc(object):
4646
print_line_tuple_swc(object)
4747

4848

49-
def swc_save(swc_tree, out_path):
49+
def swc_save(swc_tree, out_path, extra=None):
5050
if not is_path_valid(out_path):
5151
return False
5252
swc_node_list = swc_tree.get_node_list()
5353
swc_tree.sort_node_list(key="id")
5454
with open(out_path, 'w') as f:
5555
f.truncate()
56+
if extra is not None:
57+
f.write(extra)
5658
for node in swc_node_list:
5759
if node.is_virtual():
5860
continue

pyneval/metric/branch_leaf_metric.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ def branch_leaf_metric(gold_swc_tree, test_swc_tree, config):
161161
threshold_dis = threshold_dis * tot_dis / edge_num
162162
# denote the color id of different type of nodes.
163163
color = [
164-
config["true_positive_type"],
165-
config["false_negative_type"],
166-
config["false_positive_type"]
164+
config["true_positive"],
165+
config["missed"],
166+
config["excess"]
167167
]
168168
gold_swc_tree.type_clear(0, 0)
169169
test_swc_tree.type_clear(0, 0)

pyneval/metric/utils/anno_utils.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from pyneval.io.read_json import read_json
2+
3+
4+
def get_detail_type(metric_name):
5+
detail_type_annotation = dict()
6+
detail_type_annotation["ssd_metric"] = "# 1: gold standard root\n" \
7+
"# 2: gold standard branch(degree >= 3)\n" \
8+
"# 3: gold standard continuation(degree == 2)\n" \
9+
"# 4: gold standard leaf(degree == 1)\n" \
10+
"# 5: reconstruction root\n" \
11+
"# 6: reconstruction branch(degree >= 3)\n" \
12+
"# 7: reconstruction continuation(degree == 2)\n" \
13+
"# 8: reconstruction leaf(degree == 1)\n" \
14+
"# 9: mismatched node(regardless rules above)\n\n"
15+
detail_type_annotation["length_metric"] = "# 1: gold standard root\n" \
16+
"# 2: gold standard branch(degree >= 3)\n" \
17+
"# 3: gold standard continuation(degree == 2)\n" \
18+
"# 4: gold standard leaf(degree == 1)\n" \
19+
"# 5: reconstruction root\n" \
20+
"# 6: reconstruction branch(degree >= 3)\n" \
21+
"# 7: reconstruction continuation(degree == 2)\n" \
22+
"# 8: reconstruction leaf(degree == 1)\n" \
23+
"# 9: edge between this node and its parent is mismatched" \
24+
"(regardless rules above)\n\n"
25+
detail_type_annotation["branch_metric"] = "# type of nodes in this metric detail could be change in configs\n" \
26+
"# true_positive_type: successfully reconstructed nodes, " \
27+
"exists in both GS and R\n" \
28+
"# missed: wrongly reconstructed as negative. " \
29+
"exist in GS but not in R\n" \
30+
"# excess: wrongly reconstructed as positive. " \
31+
"exist in R but not in GS.\n\n"
32+
detail_type_annotation["diadem_metric"] = "# 1: gold standard root\n" \
33+
"# 2: gold standard branch(degree >= 3)\n" \
34+
"# 3: gold standard continuation(degree == 2)\n" \
35+
"# 4: gold standard leaf(degree == 1)\n" \
36+
"# 5: reconstruction root\n" \
37+
"# 6: reconstruction branch(degree >= 3)\n" \
38+
"# 7: reconstruction continuation(degree == 2)\n" \
39+
"# 8: reconstruction leaf(degree == 1)\n" \
40+
"# 9: missed: exist in GS but not in R\n" \
41+
"# 10 excess: exist in R but not in GS\n\n"
42+
if metric_name not in detail_type_annotation:
43+
return None
44+
return detail_type_annotation[metric_name]
45+
46+
47+
if __name__ == "__main__":
48+
print(get_detail_type("branch_metric"))

0 commit comments

Comments
 (0)