Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions config/branch_metric.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"threshold_dis": 2,
"threshold_mode": 1,
"z_scale": 1,
"true_positive_type": 3,
"false_negative_type": 4,
"false_positive_type": 5
"true_positive": 3,
"missed": 4,
"excess": 5
}
12 changes: 6 additions & 6 deletions config/schemas/branch_metric_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
"threshold_dis",
"threshold_mode",
"z_scale",
"true_positive_type",
"false_negative_type",
"false_positive_type"
"true_positive",
"missed",
"excess"
],
"properties": {
"threshold_dis": {"type": "number", "exclusiveMinimum": 0},
"threshold_mode": {"type": "number", "enum": [1, 2]},
"z_scale": {"type": "number","minimum": 0},
"true_positive_type": {"type": "integer", "exclusiveMinimum": 0},
"false_negative_type": {"type": "integer", "exclusiveMinimum": 0},
"false_positive_type": {"type": "integer", "exclusiveMinimum": 0}
"true_positive": {"type": "integer", "exclusiveMinimum": 0},
"missed": {"type": "integer", "exclusiveMinimum": 0},
"excess": {"type": "integer", "exclusiveMinimum": 0}
}
}
22 changes: 14 additions & 8 deletions pyneval/cli/pyneval.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from pyneval.metric import branch_leaf_metric
from pyneval.metric import link_metric
from pyneval.metric import ssd_metric
from pyneval.metric.utils import anno_utils


METRICS = {
'diadem_metric': {
Expand Down Expand Up @@ -193,10 +195,9 @@ def set_configs(abs_dir, args):

config = read_json.read_json(config_path)
config_schema = read_json.read_json(config_schema_path)
try:
jsonschema.validate(config, config_schema)
except Exception:
raise Exception("[Error: ]Error in analyzing config json file")

jsonschema.validate(config, config_schema)


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

if detail_dir:
swc_save(swc_tree=res_gold_swc_tree,
out_path=os.path.join(detail_dir, file_name + "recall.swc"))
swc_save(swc_tree=res_test_swc_tree,
out_path=os.path.join(detail_dir, file_name + "precision.swc"))
if res_gold_swc_tree is not None:
swc_save(swc_tree=res_gold_swc_tree,
out_path=os.path.join(detail_dir, file_name + "recall.swc"),
extra=anno_utils.get_detail_type(metric))
if res_test_swc_tree is not None:
swc_save(swc_tree=res_test_swc_tree,
out_path=os.path.join(detail_dir, file_name + "precision.swc"),
extra=anno_utils.get_detail_type(metric))


if output_dir:
read_json.save_json(data=result,
Expand Down
4 changes: 3 additions & 1 deletion pyneval/io/swc_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ def print_swc(object):
print_line_tuple_swc(object)


def swc_save(swc_tree, out_path):
def swc_save(swc_tree, out_path, extra=None):
if not is_path_valid(out_path):
return False
swc_node_list = swc_tree.get_node_list()
swc_tree.sort_node_list(key="id")
with open(out_path, 'w') as f:
f.truncate()
if extra is not None:
f.write(extra)
for node in swc_node_list:
if node.is_virtual():
continue
Expand Down
6 changes: 3 additions & 3 deletions pyneval/metric/branch_leaf_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ def branch_leaf_metric(gold_swc_tree, test_swc_tree, config):
threshold_dis = threshold_dis * tot_dis / edge_num
# denote the color id of different type of nodes.
color = [
config["true_positive_type"],
config["false_negative_type"],
config["false_positive_type"]
config["true_positive"],
config["missed"],
config["excess"]
]
gold_swc_tree.type_clear(0, 0)
test_swc_tree.type_clear(0, 0)
Expand Down
48 changes: 48 additions & 0 deletions pyneval/metric/utils/anno_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pyneval.io.read_json import read_json


def get_detail_type(metric_name):
detail_type_annotation = dict()
detail_type_annotation["ssd_metric"] = "# 1: gold standard root\n" \
"# 2: gold standard branch(degree >= 3)\n" \
"# 3: gold standard continuation(degree == 2)\n" \
"# 4: gold standard leaf(degree == 1)\n" \
"# 5: reconstruction root\n" \
"# 6: reconstruction branch(degree >= 3)\n" \
"# 7: reconstruction continuation(degree == 2)\n" \
"# 8: reconstruction leaf(degree == 1)\n" \
"# 9: mismatched node(regardless rules above)\n\n"
detail_type_annotation["length_metric"] = "# 1: gold standard root\n" \
"# 2: gold standard branch(degree >= 3)\n" \
"# 3: gold standard continuation(degree == 2)\n" \
"# 4: gold standard leaf(degree == 1)\n" \
"# 5: reconstruction root\n" \
"# 6: reconstruction branch(degree >= 3)\n" \
"# 7: reconstruction continuation(degree == 2)\n" \
"# 8: reconstruction leaf(degree == 1)\n" \
"# 9: edge between this node and its parent is mismatched" \
"(regardless rules above)\n\n"
detail_type_annotation["branch_metric"] = "# type of nodes in this metric detail could be change in configs\n" \
"# true_positive_type: successfully reconstructed nodes, " \
"exists in both GS and R\n" \
"# missed: wrongly reconstructed as negative. " \
"exist in GS but not in R\n" \
"# excess: wrongly reconstructed as positive. " \
"exist in R but not in GS.\n\n"
detail_type_annotation["diadem_metric"] = "# 1: gold standard root\n" \
"# 2: gold standard branch(degree >= 3)\n" \
"# 3: gold standard continuation(degree == 2)\n" \
"# 4: gold standard leaf(degree == 1)\n" \
"# 5: reconstruction root\n" \
"# 6: reconstruction branch(degree >= 3)\n" \
"# 7: reconstruction continuation(degree == 2)\n" \
"# 8: reconstruction leaf(degree == 1)\n" \
"# 9: missed: exist in GS but not in R\n" \
"# 10 excess: exist in R but not in GS\n\n"
if metric_name not in detail_type_annotation:
return None
return detail_type_annotation[metric_name]


if __name__ == "__main__":
print(get_detail_type("branch_metric"))