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
2 changes: 1 addition & 1 deletion ctc_metrics/metrics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ctc_metrics.metrics.validation.valid import valid
from ctc_metrics.metrics.biological.bc import bc
from ctc_metrics.metrics.biological.bc import bc, raw_division_metrics
from ctc_metrics.metrics.biological.ct import ct
from ctc_metrics.metrics.biological.cca import cca
from ctc_metrics.metrics.biological.tf import tf
Expand Down
49 changes: 34 additions & 15 deletions ctc_metrics/metrics/biological/bc.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,16 @@ def is_matching(
return False
return True


def bc(
def raw_division_metrics(
comp_tracks: np.ndarray,
ref_tracks: np.ndarray,
mapped_ref: list,
mapped_comp: list,
i: int
):
"""
Computes the branching correctness metric. As described in the paper,
"An objective comparison of cell-tracking algorithms."
- Vladimir Ulman et al., Nature methods 2017

Computes number of true positives, false positives, and false negatives for divisions.

Args:
comp_tracks: The result tracks. A (n,4) numpy ndarray with columns:
- label
Expand All @@ -128,21 +125,26 @@ def bc(
i: The maximal allowed error in frames.

Returns:
The branching correctness metric.
Tuple of true positives, false positives, and false negatives.
"""

# Extract relevant tracks with children in reference
ends_with_split_ref = get_ids_that_ends_with_split(ref_tracks)
t_ref = np.array([ref_tracks[ref_tracks[:, 0] == ref][0, 2]
for ref in ends_with_split_ref])
if len(ends_with_split_ref) == 0:
return None

# Extract relevant tracks with children in computed result
ends_with_split_comp = get_ids_that_ends_with_split(comp_tracks)
t_comp = np.asarray([comp_tracks[comp_tracks[:, 0] == comp][0, 2]
for comp in ends_with_split_comp])

# If there are no divisions in the reference
if len(ends_with_split_ref) == 0:
return (0, len(ends_with_split_comp), 0)

# If there are no divisions in the computed result
if len(ends_with_split_comp) == 0:
return 0
return (0, 0, len(ends_with_split_ref))

# Find all matches between reference and computed branching events (mitosis)
matches = []
for comp, tc in zip(ends_with_split_comp, t_comp):
Expand All @@ -162,8 +164,25 @@ def bc(
comp_children, tr, tc
):
matches.append((ref, comp))
return (len(matches), len(ends_with_split_comp) - len(matches), len(ends_with_split_ref) - len(matches))

def bc(
tp: int,
fp: int,
fn: int
):
"""
Computes the branching correctness metric. As described in the paper,
"An objective comparison of cell-tracking algorithms."
- Vladimir Ulman et al., Nature methods 2017

Args:
tp: The number of true positives.
fp: The number of false positives.
fn: The number of false negatives.

Returns:
The branching correctness metric.
"""
# Calculate BC(i)
return calculate_f1_score(
len(matches),
len(ends_with_split_comp) - len(matches),
len(ends_with_split_ref) - len(matches))
return calculate_f1_score(tp, fp, fn)
13 changes: 10 additions & 3 deletions ctc_metrics/scripts/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np

from ctc_metrics.metrics import (
valid, det, seg, tra, ct, tf, bc, cca, mota, hota, idf1, chota, mtml, faf,
valid, det, seg, tra, ct, tf, bc, raw_division_metrics, cca, mota, hota, idf1, chota, mtml, faf,
op_ctb, op_csb, bio, op_clb, lnk
)
from ctc_metrics.metrics import ALL_METRICS
Expand Down Expand Up @@ -226,10 +226,17 @@ def calculate_metrics(

if "BC" in metrics:
for i in range(4):
results[f"BC({i})"] = bc(
comp_tracks, ref_tracks,
tp, fp, fn = raw_division_metrics(comp_tracks, ref_tracks,
traj["mapped_ref"], traj["mapped_comp"],
i=i)

if "gt_divisions" not in results:
results["gt_divisions"] = tp + fn

results[f"tp_div({i})"] = tp
results[f"fp_div({i})"] = fp
results[f"fn_div({i})"] = fn
results[f"BC({i})"] = bc(tp, fp, fn)

if "CCA" in metrics:
results["CCA"] = cca(comp_tracks, ref_tracks)
Expand Down