Spaces:
Running on Zero
Running on Zero
Deploy CellQuant
Browse files- README.md +24 -15
- cellquant/__init__.py +1 -1
- cellquant/postprocess.py +32 -1
- evaluate.py +48 -8
- reports/SUMMARY.md +64 -62
- reports/final/final_fit.json +484 -471
- scripts/build_summary.py +42 -18
- validation/C100 35D SC Iba_Annotated.zip +0 -0
- validation/C122 F 35D SC Tmem W003_Annotated.zip +0 -0
- validation/F110 F 35D SC Iba W002_Annotated.zip +0 -0
- validation/F113 F 35D SC Tmem W001_Annotated.zip +0 -0
README.md
CHANGED
|
@@ -37,7 +37,10 @@ Every nucleus receives exactly one of the four *Cell* labels.
|
|
| 37 |
refinement stage keeps 5-pixel puncta.
|
| 38 |
* **Instances** – nucleus foreground comes from the class map; markers (distance > 0.5) and the
|
| 39 |
watershed landscape come from the predicted distance map, which has one peak per nucleus and
|
| 40 |
-
a valley between touching ones;
|
|
|
|
|
|
|
|
|
|
| 41 |
Checkpoints without the distance channel fall back to a watershed on the interior map.
|
| 42 |
* **Labels** – antibody status is the mean probability inside each nucleus; a nucleus is
|
| 43 |
"Nostril" when a punctum classified "in nucleus" lies inside it (the annotation protocol;
|
|
@@ -46,7 +49,7 @@ Every nucleus receives exactly one of the four *Cell* labels.
|
|
| 46 |
* **Training data** – nine 1024×1024 RGB images with 1,569 nucleus outlines and 1,057
|
| 47 |
punctum outlines, parsed directly from the CVAT zip exports (`cellquant/annotations.py`).
|
| 48 |
|
| 49 |
-
## Validation (see `reports/SUMMARY.md`, `reports/
|
| 50 |
|
| 51 |
Leave-one-image-out cross-validation: nine models, each tested on an image it never saw, and
|
| 52 |
each image tested 23 times (repeat runs, TTA settings, 8 rotations/flips, 6 photometric
|
|
@@ -54,21 +57,22 @@ perturbations, rule variants). Micro-averaged over the nine held-out images:
|
|
| 54 |
|
| 55 |
| Measure | Precision | Recall | F1 |
|
| 56 |
|---|---:|---:|---:|
|
| 57 |
-
| Nucleus detection, IoU ≥ 0.5 |
|
| 58 |
-
| Nucleus detection, centroid inside the annotated nucleus |
|
| 59 |
| Punctum detection (centroid within 6 px) | 76.4% | 84.8% | 80.4% |
|
| 60 |
|
| 61 |
-
Among matched nuclei the antibody +/− call is right for 93.
|
| 62 |
-
95.
|
| 63 |
at most ±3 F1 points across the 14 rotated/perturbed runs of each image, and repeated runs are
|
| 64 |
-
bit-identical. The weak spots are antibody-negative nuclei (F1
|
| 65 |
them in one image, and the class-balanced loss trades their precision for recall), the five-example
|
| 66 |
-
"Cell, Nostril, Antibody −" class, dense clusters of touching nuclei (still the main source of misses,
|
| 67 |
-
although the distance-map watershed
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
|
|
|
| 72 |
|
| 73 |
## Using the Space
|
| 74 |
|
|
@@ -137,16 +141,21 @@ Retrain when more annotated images are available (put the TIFs and the CVAT zips
|
|
| 137 |
|
| 138 |
```bash
|
| 139 |
python train.py --data-dir /path/to/folder --out weights/cellquant.pt --iters 3000
|
| 140 |
-
python evaluate.py cv --data-dir /path/to/folder --runs-dir runs/
|
|
|
|
| 141 |
```
|
| 142 |
|
|
|
|
|
|
|
|
|
|
| 143 |
Training uses Apple-silicon MPS, CUDA or CPU automatically.
|
| 144 |
|
| 145 |
## Limitations
|
| 146 |
|
| 147 |
* The annotator skipped faint / out-of-focus nuclei; the model learned that criterion only
|
| 148 |
approximately, so very dim nuclei may be counted or not. Raise *Minimum nucleus area* or the
|
| 149 |
-
thresholds in *Advanced* to tune for your images.
|
|
|
|
| 150 |
* "Cell, Nostril, Antibody −" had only five training examples; its predictions are the
|
| 151 |
product of the (well-trained) antibody and punctum heads rather than a learned class.
|
| 152 |
* Images must have the same channel convention (blue nuclei, green antibody, red puncta) and a
|
|
|
|
| 37 |
refinement stage keeps 5-pixel puncta.
|
| 38 |
* **Instances** – nucleus foreground comes from the class map; markers (distance > 0.5) and the
|
| 39 |
watershed landscape come from the predicted distance map, which has one peak per nucleus and
|
| 40 |
+
a valley between touching ones; a nucleus whose peak predicted distance stays below 0.64 is
|
| 41 |
+
dropped (the distance head is trained to reach 1 in every annotated nucleus and 0 elsewhere,
|
| 42 |
+
so a low peak marks a faint blob the annotator would have skipped; `PostConfig.min_peak_dist`,
|
| 43 |
+
0 switches it off); puncta are connected components (`cellquant/postprocess.py`).
|
| 44 |
Checkpoints without the distance channel fall back to a watershed on the interior map.
|
| 45 |
* **Labels** – antibody status is the mean probability inside each nucleus; a nucleus is
|
| 46 |
"Nostril" when a punctum classified "in nucleus" lies inside it (the annotation protocol;
|
|
|
|
| 49 |
* **Training data** – nine 1024×1024 RGB images with 1,569 nucleus outlines and 1,057
|
| 50 |
punctum outlines, parsed directly from the CVAT zip exports (`cellquant/annotations.py`).
|
| 51 |
|
| 52 |
+
## Validation (see `reports/SUMMARY.md`, `reports/cv_v3/cv_report.md` and `reports/cv_v3/comparison.md`)
|
| 53 |
|
| 54 |
Leave-one-image-out cross-validation: nine models, each tested on an image it never saw, and
|
| 55 |
each image tested 23 times (repeat runs, TTA settings, 8 rotations/flips, 6 photometric
|
|
|
|
| 57 |
|
| 58 |
| Measure | Precision | Recall | F1 |
|
| 59 |
|---|---:|---:|---:|
|
| 60 |
+
| Nucleus detection, IoU ≥ 0.5 | 81.1% | 84.2% | 82.6% |
|
| 61 |
+
| Nucleus detection, centroid inside the annotated nucleus | 88.8% | 92.2% | 90.5% |
|
| 62 |
| Punctum detection (centroid within 6 px) | 76.4% | 84.8% | 80.4% |
|
| 63 |
|
| 64 |
+
Among matched nuclei the antibody +/− call is right for 93.8% and the Nostril attribute for
|
| 65 |
+
95.7%; puncta are classified in-nucleus vs external correctly 93.4% of the time. Scores vary by
|
| 66 |
at most ±3 F1 points across the 14 rotated/perturbed runs of each image, and repeated runs are
|
| 67 |
+
bit-identical. The weak spots are antibody-negative nuclei (F1 40%; only 110 examples, 62 of
|
| 68 |
them in one image, and the class-balanced loss trades their precision for recall), the five-example
|
| 69 |
+
"Cell, Nostril, Antibody −" class, and dense clusters of touching nuclei (still the main source of misses,
|
| 70 |
+
although the distance-map watershed recovers many that the first version merged). The model predicts
|
| 71 |
+
1629 nuclei for the 1569 annotated ones across the nine held-out images. Earlier versions on the same
|
| 72 |
+
protocol: v1 (2-px border, watershed on the interior map, unweighted antibody loss) 77.9% nucleus F1,
|
| 73 |
+
87.5% by the centroid rule, 79.9% puncta F1 (`reports/cv/`); v2 (this model without the peak-distance
|
| 74 |
+
rule) 80.4%, 88.8% and 80.4% (`reports/cv_v2/`). The shipped `weights/cellquant.pt` was trained on all nine
|
| 75 |
+
images with the v2 recipe; the peak-distance rule is post-processing only.
|
| 76 |
|
| 77 |
## Using the Space
|
| 78 |
|
|
|
|
| 141 |
|
| 142 |
```bash
|
| 143 |
python train.py --data-dir /path/to/folder --out weights/cellquant.pt --iters 3000
|
| 144 |
+
python evaluate.py cv --data-dir /path/to/folder --runs-dir runs/cv_v3 --iters 3000
|
| 145 |
+
python scripts/rule_study.py --data-dir /path/to/folder --runs-dir runs/cv_v2 --out runs/cv_v3/rule_study --weights weights/cellquant.pt
|
| 146 |
```
|
| 147 |
|
| 148 |
+
The last line re-chooses the peak-distance threshold from the training-set fit (per fold and for the
|
| 149 |
+
all-image model); copy the printed value into `PostConfig.min_peak_dist`.
|
| 150 |
+
|
| 151 |
Training uses Apple-silicon MPS, CUDA or CPU automatically.
|
| 152 |
|
| 153 |
## Limitations
|
| 154 |
|
| 155 |
* The annotator skipped faint / out-of-focus nuclei; the model learned that criterion only
|
| 156 |
approximately, so very dim nuclei may be counted or not. Raise *Minimum nucleus area* or the
|
| 157 |
+
thresholds in *Advanced* to tune for your images; `PostConfig(min_peak_dist=...)` (default
|
| 158 |
+
0.64, 0 = off) sets how confident the distance head must be before a nucleus is counted.
|
| 159 |
* "Cell, Nostril, Antibody −" had only five training examples; its predictions are the
|
| 160 |
product of the (well-trained) antibody and punctum heads rather than a learned class.
|
| 161 |
* Images must have the same channel convention (blue nuclei, green antibody, red puncta) and a
|
cellquant/__init__.py
CHANGED
|
@@ -3,4 +3,4 @@
|
|
| 3 |
Trained on CVAT polygon annotations of 1024x1024 RGB images (blue = DAPI nuclei,
|
| 4 |
green = antibody stain such as Iba1 or Tmem119, red = puncta).
|
| 5 |
"""
|
| 6 |
-
__version__ = "1.
|
|
|
|
| 3 |
Trained on CVAT polygon annotations of 1024x1024 RGB images (blue = DAPI nuclei,
|
| 4 |
green = antibody stain such as Iba1 or Tmem119, red = puncta).
|
| 5 |
"""
|
| 6 |
+
__version__ = "1.2.0"
|
cellquant/postprocess.py
CHANGED
|
@@ -18,6 +18,12 @@ class PostConfig:
|
|
| 18 |
# P(interior)) > thr -> watershed markers
|
| 19 |
min_marker_area: int = 12 # px
|
| 20 |
min_cell_area: int = 50 # px (smallest traced nucleus in the training set is 35 px)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
nos_fg_thr: float = 0.5 # 1 - P(background) > thr -> punctum foreground
|
| 22 |
min_nos_area: int = 3 # px
|
| 23 |
antibody_thr: float = 0.5
|
|
@@ -53,7 +59,9 @@ def segment_cells(p_cell: np.ndarray, cfg: PostConfig, dist: np.ndarray | None =
|
|
| 53 |
Foreground always comes from the class map. Markers and the watershed
|
| 54 |
landscape come from ``dist`` (the predicted normalised distance to the
|
| 55 |
outline, which has one peak per nucleus and a valley between touching ones)
|
| 56 |
-
when the model provides it, otherwise from P(interior).
|
|
|
|
|
|
|
| 57 |
p_int, p_bor = p_cell[1], p_cell[2]
|
| 58 |
fg = (p_int + p_bor) > cfg.cell_fg_thr
|
| 59 |
land = p_int if dist is None else dist
|
|
@@ -78,10 +86,33 @@ def segment_cells(p_cell: np.ndarray, cfg: PostConfig, dist: np.ndarray | None =
|
|
| 78 |
base = inst.max()
|
| 79 |
for j, oid in enumerate(orphan_ids, start=1):
|
| 80 |
inst[orphan == oid] = base + j
|
|
|
|
|
|
|
| 81 |
inst = _fill_and_filter(inst, cfg.min_cell_area)
|
| 82 |
return inst
|
| 83 |
|
| 84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
def _fill_and_filter(inst: np.ndarray, min_area: int) -> np.ndarray:
|
| 86 |
"""Fill holes inside every instance, drop instances below ``min_area`` and
|
| 87 |
keep only the largest connected piece of each instance; relabel 1..n."""
|
|
|
|
| 18 |
# P(interior)) > thr -> watershed markers
|
| 19 |
min_marker_area: int = 12 # px
|
| 20 |
min_cell_area: int = 50 # px (smallest traced nucleus in the training set is 35 px)
|
| 21 |
+
min_peak_dist: float = 0.64 # drop a nucleus whose peak predicted distance is below this (0 = off;
|
| 22 |
+
# only applied when the model provides the distance map). The distance
|
| 23 |
+
# head is trained to reach 1 inside every annotated nucleus and to stay
|
| 24 |
+
# at 0 elsewhere, so a low peak marks a blob the annotator would skip.
|
| 25 |
+
# 0.64 maximises nucleus F1 on the training-set fit of the shipped model
|
| 26 |
+
# (scripts/rule_study.py); see reports/cv_v3/.
|
| 27 |
nos_fg_thr: float = 0.5 # 1 - P(background) > thr -> punctum foreground
|
| 28 |
min_nos_area: int = 3 # px
|
| 29 |
antibody_thr: float = 0.5
|
|
|
|
| 59 |
Foreground always comes from the class map. Markers and the watershed
|
| 60 |
landscape come from ``dist`` (the predicted normalised distance to the
|
| 61 |
outline, which has one peak per nucleus and a valley between touching ones)
|
| 62 |
+
when the model provides it, otherwise from P(interior). With ``dist`` given,
|
| 63 |
+
instances whose peak distance is below ``cfg.min_peak_dist`` are dropped
|
| 64 |
+
(see PostConfig)."""
|
| 65 |
p_int, p_bor = p_cell[1], p_cell[2]
|
| 66 |
fg = (p_int + p_bor) > cfg.cell_fg_thr
|
| 67 |
land = p_int if dist is None else dist
|
|
|
|
| 86 |
base = inst.max()
|
| 87 |
for j, oid in enumerate(orphan_ids, start=1):
|
| 88 |
inst[orphan == oid] = base + j
|
| 89 |
+
if dist is not None and cfg.min_peak_dist > 0:
|
| 90 |
+
inst = drop_low_peaks(inst, dist, cfg.min_peak_dist)
|
| 91 |
inst = _fill_and_filter(inst, cfg.min_cell_area)
|
| 92 |
return inst
|
| 93 |
|
| 94 |
|
| 95 |
+
def peak_dist(inst: np.ndarray, dist: np.ndarray) -> np.ndarray:
|
| 96 |
+
"""Maximum of ``dist`` inside every instance (index 0 = background, set to 0)."""
|
| 97 |
+
n = int(inst.max())
|
| 98 |
+
out = np.zeros(n + 1, dtype=np.float64)
|
| 99 |
+
if n:
|
| 100 |
+
out[1:] = ndi.maximum(dist, inst, np.arange(1, n + 1))
|
| 101 |
+
return out
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def drop_low_peaks(inst: np.ndarray, dist: np.ndarray, thr: float) -> np.ndarray:
|
| 105 |
+
"""Zero every instance whose peak predicted distance is below ``thr``
|
| 106 |
+
(ids are not renumbered; _fill_and_filter does that)."""
|
| 107 |
+
pk = peak_dist(inst, dist)
|
| 108 |
+
low = pk < thr
|
| 109 |
+
low[0] = False
|
| 110 |
+
if low.any():
|
| 111 |
+
inst = inst.copy()
|
| 112 |
+
inst[low[inst]] = 0
|
| 113 |
+
return inst
|
| 114 |
+
|
| 115 |
+
|
| 116 |
def _fill_and_filter(inst: np.ndarray, min_area: int) -> np.ndarray:
|
| 117 |
"""Fill holes inside every instance, drop instances below ``min_area`` and
|
| 118 |
keep only the largest connected piece of each instance; relabel 1..n."""
|
evaluate.py
CHANGED
|
@@ -26,6 +26,7 @@ import os
|
|
| 26 |
import subprocess
|
| 27 |
import sys
|
| 28 |
import time
|
|
|
|
| 29 |
|
| 30 |
import numpy as np
|
| 31 |
from PIL import Image
|
|
@@ -40,6 +41,35 @@ from cellquant.postprocess import PostConfig, Result, analyze, render_overlay #
|
|
| 40 |
DIHEDRAL = [(k, f) for f in (False, True) for k in range(4)]
|
| 41 |
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
def fwd_np(a: np.ndarray, k: int, flip: bool) -> np.ndarray:
|
| 44 |
if flip:
|
| 45 |
a = a[..., ::-1]
|
|
@@ -146,9 +176,10 @@ def inst_hash(res: Result) -> str:
|
|
| 146 |
return h.hexdigest()[:16]
|
| 147 |
|
| 148 |
|
| 149 |
-
def test_image(weights: str, img: np.ndarray, R, gt_counts: dict, device: str, out_prefix: str | None = None
|
| 150 |
-
|
| 151 |
-
|
|
|
|
| 152 |
p1 = Predictor(weights, device=device, tta=1)
|
| 153 |
# base + determinism
|
| 154 |
hashes = []
|
|
@@ -181,7 +212,7 @@ def test_image(weights: str, img: np.ndarray, R, gt_counts: dict, device: str, o
|
|
| 181 |
# post-processing rule variants (same probabilities as the base run)
|
| 182 |
for nr in ("head", "geometric"):
|
| 183 |
for cr in ("head", "contains", "either"):
|
| 184 |
-
res = analyze(base_probs,
|
| 185 |
out["runs"][f"rule_nos={nr}_cell={cr}"] = score(R, res, gt_counts)
|
| 186 |
return out
|
| 187 |
|
|
@@ -318,6 +349,7 @@ def cmd_cv(a):
|
|
| 318 |
samples, _ = discover(a.data_dir)
|
| 319 |
keys = a.keys.split(",") if a.keys else [s.key for s in samples]
|
| 320 |
os.makedirs(a.runs_dir, exist_ok=True)
|
|
|
|
| 321 |
per_key = {}
|
| 322 |
for s in samples:
|
| 323 |
if s.key not in keys:
|
|
@@ -344,7 +376,11 @@ def cmd_cv(a):
|
|
| 344 |
img = load_image(s.image_path)
|
| 345 |
R = rasterize(s.annotation, img.shape[0], img.shape[1])
|
| 346 |
t = time.time()
|
| 347 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
res["train_keys"] = list(meta.get("train_keys", []))
|
| 349 |
res["checkpoint"] = os.path.basename(ck)
|
| 350 |
per_key[s.key] = res
|
|
@@ -355,6 +391,7 @@ def cmd_cv(a):
|
|
| 355 |
agg = aggregate(per_key)
|
| 356 |
totals = {lab: sum(s.annotation.count(lab) for s in samples) for lab in ALL_LABELS}
|
| 357 |
agg["dataset_totals"] = totals
|
|
|
|
| 358 |
with open(os.path.join(a.runs_dir, "cv_results.json"), "w") as f:
|
| 359 |
json.dump({"aggregate": agg, "per_image": per_key}, f, indent=1)
|
| 360 |
n_nuc = sum(totals[c] for c in CELL_LABELS)
|
|
@@ -368,19 +405,20 @@ def cmd_cv(a):
|
|
| 368 |
def cmd_final(a):
|
| 369 |
samples, unann = discover(a.data_dir)
|
| 370 |
os.makedirs(a.out_dir, exist_ok=True)
|
|
|
|
| 371 |
pred = Predictor(a.weights, device=a.device, tta=1)
|
| 372 |
-
rows = {}
|
| 373 |
for s in samples:
|
| 374 |
img = load_image(s.image_path)
|
| 375 |
R = rasterize(s.annotation, img.shape[0], img.shape[1])
|
| 376 |
-
res, _ = pred.predict(img,
|
| 377 |
rows[s.key] = score(R, res, s.annotation.counts())
|
| 378 |
Image.fromarray(render_overlay(img, res)).save(os.path.join(a.out_dir, f"{s.key}_pred.png"))
|
| 379 |
b = rows[s.key]["summary"]
|
| 380 |
print(f"[{s.key}] TRAINING-SET fit: nuclei F1 {b['cell_det_f1']:.3f} attr {b['cell_attr_both']:.3f} puncta F1 {b['nos_det_f1']:.3f}")
|
| 381 |
for p in unann:
|
| 382 |
img = load_image(p)
|
| 383 |
-
res, _ = pred.predict(img,
|
| 384 |
key = os.path.basename(p).split(" ")[0]
|
| 385 |
Image.fromarray(render_overlay(img, res)).save(os.path.join(a.out_dir, f"{key}_unlabeled_pred.png"))
|
| 386 |
rows[f"{key} (no annotation)"] = {"counts": res.counts}
|
|
@@ -401,11 +439,13 @@ def main(argv=None):
|
|
| 401 |
c.add_argument("--device", default="auto")
|
| 402 |
c.add_argument("--retrain", action="store_true")
|
| 403 |
c.add_argument("--reuse-eval", action="store_true", help="reuse <key>_eval.json files newer than their checkpoint")
|
|
|
|
| 404 |
f = sub.add_parser("final")
|
| 405 |
f.add_argument("--data-dir", required=True)
|
| 406 |
f.add_argument("--weights", required=True)
|
| 407 |
f.add_argument("--out-dir", default="reports/final")
|
| 408 |
f.add_argument("--device", default="auto")
|
|
|
|
| 409 |
a = ap.parse_args(argv)
|
| 410 |
{"cv": cmd_cv, "final": cmd_final}[a.cmd](a)
|
| 411 |
|
|
|
|
| 26 |
import subprocess
|
| 27 |
import sys
|
| 28 |
import time
|
| 29 |
+
from dataclasses import asdict, replace
|
| 30 |
|
| 31 |
import numpy as np
|
| 32 |
from PIL import Image
|
|
|
|
| 41 |
DIHEDRAL = [(k, f) for f in (False, True) for k in range(4)]
|
| 42 |
|
| 43 |
|
| 44 |
+
def load_post_config(spec: str) -> dict:
|
| 45 |
+
"""``--post-config`` argument -> dict. Either a JSON file / literal holding
|
| 46 |
+
PostConfig field overrides for every image ({"min_peak_dist": 0.63}) or a
|
| 47 |
+
mapping image key -> overrides ({"C100": {"min_peak_dist": 0.61}, ...}),
|
| 48 |
+
e.g. thresholds chosen per fold on that fold's training images."""
|
| 49 |
+
if not spec:
|
| 50 |
+
return {}
|
| 51 |
+
if os.path.exists(spec):
|
| 52 |
+
with open(spec) as f:
|
| 53 |
+
d = json.load(f)
|
| 54 |
+
else:
|
| 55 |
+
d = json.loads(spec)
|
| 56 |
+
if not isinstance(d, dict):
|
| 57 |
+
raise SystemExit("--post-config must be a JSON object")
|
| 58 |
+
return d
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def post_config_for(overrides: dict, key: str) -> PostConfig:
|
| 62 |
+
"""PostConfig for one image from the --post-config dict (see load_post_config)."""
|
| 63 |
+
if overrides and all(isinstance(v, dict) for v in overrides.values()):
|
| 64 |
+
o = overrides.get(key, {})
|
| 65 |
+
else:
|
| 66 |
+
o = overrides
|
| 67 |
+
unknown = set(o) - set(PostConfig.__dataclass_fields__)
|
| 68 |
+
if unknown:
|
| 69 |
+
raise SystemExit(f"--post-config: unknown PostConfig fields {sorted(unknown)}")
|
| 70 |
+
return PostConfig(**o)
|
| 71 |
+
|
| 72 |
+
|
| 73 |
def fwd_np(a: np.ndarray, k: int, flip: bool) -> np.ndarray:
|
| 74 |
if flip:
|
| 75 |
a = a[..., ::-1]
|
|
|
|
| 176 |
return h.hexdigest()[:16]
|
| 177 |
|
| 178 |
|
| 179 |
+
def test_image(weights: str, img: np.ndarray, R, gt_counts: dict, device: str, out_prefix: str | None = None,
|
| 180 |
+
cfg: PostConfig | None = None) -> dict:
|
| 181 |
+
cfg = cfg or PostConfig()
|
| 182 |
+
out: dict = {"runs": {}, "post_config": asdict(cfg)}
|
| 183 |
p1 = Predictor(weights, device=device, tta=1)
|
| 184 |
# base + determinism
|
| 185 |
hashes = []
|
|
|
|
| 212 |
# post-processing rule variants (same probabilities as the base run)
|
| 213 |
for nr in ("head", "geometric"):
|
| 214 |
for cr in ("head", "contains", "either"):
|
| 215 |
+
res = analyze(base_probs, replace(cfg, nostril_rule=nr, cellnos_rule=cr))
|
| 216 |
out["runs"][f"rule_nos={nr}_cell={cr}"] = score(R, res, gt_counts)
|
| 217 |
return out
|
| 218 |
|
|
|
|
| 349 |
samples, _ = discover(a.data_dir)
|
| 350 |
keys = a.keys.split(",") if a.keys else [s.key for s in samples]
|
| 351 |
os.makedirs(a.runs_dir, exist_ok=True)
|
| 352 |
+
overrides = load_post_config(a.post_config)
|
| 353 |
per_key = {}
|
| 354 |
for s in samples:
|
| 355 |
if s.key not in keys:
|
|
|
|
| 376 |
img = load_image(s.image_path)
|
| 377 |
R = rasterize(s.annotation, img.shape[0], img.shape[1])
|
| 378 |
t = time.time()
|
| 379 |
+
cfg = post_config_for(overrides, s.key)
|
| 380 |
+
if overrides:
|
| 381 |
+
changed = {k: v for k, v in asdict(cfg).items() if v != getattr(PostConfig(), k)}
|
| 382 |
+
print(f"[{s.key}] post-processing overrides: {changed}", flush=True)
|
| 383 |
+
res = test_image(ck, img, R, s.annotation.counts(), a.device, out_prefix=os.path.join(a.runs_dir, s.key), cfg=cfg)
|
| 384 |
res["train_keys"] = list(meta.get("train_keys", []))
|
| 385 |
res["checkpoint"] = os.path.basename(ck)
|
| 386 |
per_key[s.key] = res
|
|
|
|
| 391 |
agg = aggregate(per_key)
|
| 392 |
totals = {lab: sum(s.annotation.count(lab) for s in samples) for lab in ALL_LABELS}
|
| 393 |
agg["dataset_totals"] = totals
|
| 394 |
+
agg["post_config"] = {k: per_key[k].get("post_config", asdict(PostConfig())) for k in per_key}
|
| 395 |
with open(os.path.join(a.runs_dir, "cv_results.json"), "w") as f:
|
| 396 |
json.dump({"aggregate": agg, "per_image": per_key}, f, indent=1)
|
| 397 |
n_nuc = sum(totals[c] for c in CELL_LABELS)
|
|
|
|
| 405 |
def cmd_final(a):
|
| 406 |
samples, unann = discover(a.data_dir)
|
| 407 |
os.makedirs(a.out_dir, exist_ok=True)
|
| 408 |
+
overrides = load_post_config(a.post_config)
|
| 409 |
pred = Predictor(a.weights, device=a.device, tta=1)
|
| 410 |
+
rows = {"post_config": asdict(post_config_for(overrides, ""))}
|
| 411 |
for s in samples:
|
| 412 |
img = load_image(s.image_path)
|
| 413 |
R = rasterize(s.annotation, img.shape[0], img.shape[1])
|
| 414 |
+
res, _ = pred.predict(img, post_config_for(overrides, s.key))
|
| 415 |
rows[s.key] = score(R, res, s.annotation.counts())
|
| 416 |
Image.fromarray(render_overlay(img, res)).save(os.path.join(a.out_dir, f"{s.key}_pred.png"))
|
| 417 |
b = rows[s.key]["summary"]
|
| 418 |
print(f"[{s.key}] TRAINING-SET fit: nuclei F1 {b['cell_det_f1']:.3f} attr {b['cell_attr_both']:.3f} puncta F1 {b['nos_det_f1']:.3f}")
|
| 419 |
for p in unann:
|
| 420 |
img = load_image(p)
|
| 421 |
+
res, _ = pred.predict(img, post_config_for(overrides, ""))
|
| 422 |
key = os.path.basename(p).split(" ")[0]
|
| 423 |
Image.fromarray(render_overlay(img, res)).save(os.path.join(a.out_dir, f"{key}_unlabeled_pred.png"))
|
| 424 |
rows[f"{key} (no annotation)"] = {"counts": res.counts}
|
|
|
|
| 439 |
c.add_argument("--device", default="auto")
|
| 440 |
c.add_argument("--retrain", action="store_true")
|
| 441 |
c.add_argument("--reuse-eval", action="store_true", help="reuse <key>_eval.json files newer than their checkpoint")
|
| 442 |
+
c.add_argument("--post-config", default="", help="JSON (file or literal) of PostConfig overrides, global or per image key")
|
| 443 |
f = sub.add_parser("final")
|
| 444 |
f.add_argument("--data-dir", required=True)
|
| 445 |
f.add_argument("--weights", required=True)
|
| 446 |
f.add_argument("--out-dir", default="reports/final")
|
| 447 |
f.add_argument("--device", default="auto")
|
| 448 |
+
f.add_argument("--post-config", default="", help="JSON (file or literal) of PostConfig overrides")
|
| 449 |
a = ap.parse_args(argv)
|
| 450 |
{"cv": cmd_cv, "final": cmd_final}[a.cmd](a)
|
| 451 |
|
reports/SUMMARY.md
CHANGED
|
@@ -1,27 +1,27 @@
|
|
| 1 |
# CellQuant: validation summary
|
| 2 |
|
| 3 |
Data: 9 annotated 1024×1024 images, 1569 nucleus outlines and 1057 punctum outlines.
|
| 4 |
-
Protocol: leave-one-image-out cross-validation (one model per image, 3000 iterations each, held-out image never seen in training), then a final model trained on all images with the same recipe. Each held-out image was tested 23 times: 3 identical runs (determinism), no-TTA / 4× / 8× test-time augmentation, 8 rotations and flips, 6 photometric perturbations, and 6 post-processing rule variants. The only choice made on held-out data is the rule that gives a nucleus the Nostril attribute: of three candidate rules, 'contains an in-nucleus punctum' (the annotation protocol) scored best and is the default; see the rule-variant table in cv_report.md.
|
| 5 |
|
| 6 |
-
Recipe (
|
| 7 |
|
| 8 |
## Headline numbers (micro-averaged over all held-out images, no TTA)
|
| 9 |
|
| 10 |
| Measure | Precision | Recall | F1 |
|
| 11 |
|---|---:|---:|---:|
|
| 12 |
-
| Nucleus detection, IoU ≥ 0.5 |
|
| 13 |
-
| Nucleus detection, IoU ≥ 0.3 |
|
| 14 |
-
| Nucleus detection, centroid inside GT nucleus |
|
| 15 |
| Punctum detection (centroid ≤ 6 px) | 76.4% | 84.8% | 80.4% |
|
| 16 |
-
| Nucleus detection, IoU ≥ 0.5, 8× TTA |
|
| 17 |
|
| 18 |
Per-class F1 (a true positive needs a matched object **and** the right label):
|
| 19 |
|
| 20 |
| Label | GT | Pred | F1 |
|
| 21 |
|---|---:|---:|---:|
|
| 22 |
-
| Cell, Antibody + | 1061 |
|
| 23 |
-
| Cell, Antibody - | 105 |
|
| 24 |
-
| Cell, Nostril, Antibody + | 398 |
|
| 25 |
| Cell, Nostril, Antibody - | 5 | 0 | 0.0% |
|
| 26 |
| Nostril in Nucleus | 525 | 532 | 78.7% |
|
| 27 |
| Nostril External of Nucleus | 532 | 641 | 71.8% |
|
|
@@ -30,68 +30,68 @@ Per-class F1 (a true positive needs a matched object **and** the right label):
|
|
| 30 |
|
| 31 |
| Image | Nuclei F1 | Antibody acc | Nostril-attr acc | Puncta F1 | Nuclei F1 over 14 perturbed runs (mean ± sd) | Deterministic |
|
| 32 |
|---|---:|---:|---:|---:|---|---|
|
| 33 |
-
| C100 |
|
| 34 |
-
| C102 |
|
| 35 |
-
| C110 |
|
| 36 |
-
| C112 |
|
| 37 |
-
| F100 |
|
| 38 |
-
| F110 |
|
| 39 |
-
| F113 |
|
| 40 |
-
| F114 |
|
| 41 |
-
| F99 |
|
| 42 |
|
| 43 |
## Final model (trained on all images) – fit on its own training images, NOT a generalisation estimate
|
| 44 |
|
| 45 |
| Image | Nuclei F1 | Attribute acc | Puncta F1 |
|
| 46 |
|---|---:|---:|---:|
|
| 47 |
-
| C100 |
|
| 48 |
-
| C102 |
|
| 49 |
-
| C110 |
|
| 50 |
-
| C112 |
|
| 51 |
-
| F100 |
|
| 52 |
-
| F110 |
|
| 53 |
-
| F113 |
|
| 54 |
-
| F114 |
|
| 55 |
-
| F99 | 91.
|
| 56 |
-
|
| 57 |
-
## Change from
|
| 58 |
-
|
| 59 |
-
| Measure |
|
| 60 |
|---|---:|---:|---:|
|
| 61 |
-
| Nucleus F1, IoU ≥ 0.5 |
|
| 62 |
-
| Nucleus precision, IoU ≥ 0.5 |
|
| 63 |
-
| Nucleus recall, IoU ≥ 0.5 |
|
| 64 |
-
| Nucleus F1, centroid rule |
|
| 65 |
-
| Nucleus F1, IoU ≥ 0.5, 8× TTA |
|
| 66 |
-
| Puncta F1 |
|
| 67 |
-
| F1 [Cell, Antibody +] |
|
| 68 |
-
| F1 [Cell, Antibody -] |
|
| 69 |
-
| F1 [Cell, Nostril, Antibody +] |
|
| 70 |
| F1 [Cell, Nostril, Antibody -] | 0.0% | 0.0% | +0.0 |
|
| 71 |
-
| F1 [Nostril in Nucleus] | 78.
|
| 72 |
-
| F1 [Nostril External of Nucleus] |
|
| 73 |
-
| Attribute accuracy, both (each model's own matched nuclei) |
|
| 74 |
-
| Punctum type accuracy (matched puncta) | 93.
|
| 75 |
-
| Nuclei F1, C100 held out |
|
| 76 |
-
| Nuclei F1, C102 held out |
|
| 77 |
-
| Nuclei F1, C110 held out |
|
| 78 |
-
| Nuclei F1, C112 held out |
|
| 79 |
-
| Nuclei F1, F100 held out |
|
| 80 |
-
| Nuclei F1, F110 held out |
|
| 81 |
-
| Nuclei F1, F113 held out |
|
| 82 |
-
| Nuclei F1, F114 held out |
|
| 83 |
-
| Nuclei F1, F99 held out |
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
## Antibody − threshold (held-out matched nuclei:
|
| 88 |
-
|
| 89 |
-
Default threshold 0.5. Best Antibody − F1 in the sweep:
|
| 90 |
|
| 91 |
## What limits the scores
|
| 92 |
|
| 93 |
* **Touching nuclei** are still the main source of IoU-0.5 misses (worst on F113, the densest image). The distance-map watershed of v2 recovers many clusters that v1 merged (v1 marker/threshold sweeps in `reports/cv/postprocess_sweep.json` had shown post-processing alone could not), but some clusters are still merged and a few nuclei are now split in two.
|
| 94 |
-
* **Annotation completeness**: most unmatched predictions overlap an annotated nucleus (outline disagreement)
|
| 95 |
* **Antibody − is rare** (110 of 1569 nuclei, 62 in one image), and **Cell, Nostril, Antibody −** has five examples; their scores are not reliable. The class-balanced loss of v2 trades antibody-negative precision for recall.
|
| 96 |
* Scores are from nine images of one experiment (35-day spinal cord, Iba1/TMEM119). New staining batches or magnifications need a check against a few annotated images.
|
| 97 |
|
|
@@ -99,7 +99,9 @@ Default threshold 0.5. Best Antibody − F1 in the sweep: 50.8% at threshold 0.9
|
|
| 99 |
|
| 100 |
```bash
|
| 101 |
python evaluate.py cv --data-dir <folder with TIFs and CVAT zips> --runs-dir runs/cv_v2 --iters 3000
|
|
|
|
|
|
|
| 102 |
python evaluate.py final --data-dir <folder> --weights weights/cellquant.pt
|
| 103 |
-
python scripts/compare_cv.py reports/
|
| 104 |
-
python scripts/build_summary.py --cv-dir
|
| 105 |
```
|
|
|
|
| 1 |
# CellQuant: validation summary
|
| 2 |
|
| 3 |
Data: 9 annotated 1024×1024 images, 1569 nucleus outlines and 1057 punctum outlines.
|
| 4 |
+
Protocol: leave-one-image-out cross-validation (one model per image, 3000 iterations each, held-out image never seen in training), then a final model trained on all images with the same recipe. Each held-out image was tested 23 times: 3 identical runs (determinism), no-TTA / 4× / 8× test-time augmentation, 8 rotations and flips, 6 photometric perturbations, and 6 post-processing rule variants. The only choice made on held-out data is the rule that gives a nucleus the Nostril attribute: of three candidate rules, 'contains an in-nucleus punctum' (the annotation protocol) scored best and is the default; see the rule-variant table in cv_report.md. The peak-distance threshold of v3 was chosen, for every fold, on that fold's eight training images only (scripts/rule_study.py), and for the shipped model on its own nine training images; the held-out images never entered that choice.
|
| 5 |
|
| 6 |
+
Recipe (v3, shipped): the v2 model (ResNet34-UNet with a full-resolution stem; targets are a 3-px inner border ring (class weight 3), a per-nucleus normalised distance-to-outline map that the watershed uses as its landscape (markers = distance > 0.5), an antibody head whose loss up-weights antibody-negative pixels by sqrt(positive / negative pixels) (4.5 on the full set), and 25 % of training crops centred on an antibody-negative nucleus) plus one post-processing rule: a nucleus whose peak predicted distance is below 0.64 is dropped (PostConfig.min_peak_dist). The distance head is trained to reach 1 inside every annotated nucleus and to stay at 0 everywhere else, so a low peak marks a blob the annotator would have skipped. The weights are unchanged from v2 (reports/cv_v2/); v1 (reports/cv/) used a 2-px ring, the interior map as watershed landscape and an unweighted antibody loss. The change table below compares the shipped recipe with the previous one under the same protocol.
|
| 7 |
|
| 8 |
## Headline numbers (micro-averaged over all held-out images, no TTA)
|
| 9 |
|
| 10 |
| Measure | Precision | Recall | F1 |
|
| 11 |
|---|---:|---:|---:|
|
| 12 |
+
| Nucleus detection, IoU ≥ 0.5 | 81.1% | 84.2% | 82.6% |
|
| 13 |
+
| Nucleus detection, IoU ≥ 0.3 | 88.0% | 91.3% | 89.6% |
|
| 14 |
+
| Nucleus detection, centroid inside GT nucleus | 88.8% | 92.2% | 90.5% |
|
| 15 |
| Punctum detection (centroid ≤ 6 px) | 76.4% | 84.8% | 80.4% |
|
| 16 |
+
| Nucleus detection, IoU ≥ 0.5, 8× TTA | 82.5% | 83.4% | 82.9% |
|
| 17 |
|
| 18 |
Per-class F1 (a true positive needs a matched object **and** the right label):
|
| 19 |
|
| 20 |
| Label | GT | Pred | F1 |
|
| 21 |
|---|---:|---:|---:|
|
| 22 |
+
| Cell, Antibody + | 1061 | 1191 | 76.8% |
|
| 23 |
+
| Cell, Antibody - | 105 | 75 | 40.0% |
|
| 24 |
+
| Cell, Nostril, Antibody + | 398 | 363 | 74.1% |
|
| 25 |
| Cell, Nostril, Antibody - | 5 | 0 | 0.0% |
|
| 26 |
| Nostril in Nucleus | 525 | 532 | 78.7% |
|
| 27 |
| Nostril External of Nucleus | 532 | 641 | 71.8% |
|
|
|
|
| 30 |
|
| 31 |
| Image | Nuclei F1 | Antibody acc | Nostril-attr acc | Puncta F1 | Nuclei F1 over 14 perturbed runs (mean ± sd) | Deterministic |
|
| 32 |
|---|---:|---:|---:|---:|---|---|
|
| 33 |
+
| C100 | 87.4% | 96.9% | 98.1% | 71.4% | 87.6 ± 1.4 | yes |
|
| 34 |
+
| C102 | 88.7% | 100.0% | 89.5% | 78.9% | 89.0 ± 1.3 | yes |
|
| 35 |
+
| C110 | 82.4% | 98.7% | 94.2% | 83.8% | 82.6 ± 1.6 | yes |
|
| 36 |
+
| C112 | 74.6% | 95.8% | 97.5% | 76.9% | 74.2 ± 1.5 | yes |
|
| 37 |
+
| F100 | 84.4% | 98.1% | 94.4% | 85.7% | 80.5 ± 2.7 | yes |
|
| 38 |
+
| F110 | 80.2% | 97.1% | 91.4% | 82.9% | 76.7 ± 2.3 | yes |
|
| 39 |
+
| F113 | 71.8% | 100.0% | 97.3% | 83.3% | 72.1 ± 1.5 | yes |
|
| 40 |
+
| F114 | 83.1% | 91.2% | 94.3% | 63.5% | 82.0 ± 1.1 | yes |
|
| 41 |
+
| F99 | 88.0% | 79.6% | 99.6% | 74.3% | 88.3 ± 0.8 | yes |
|
| 42 |
|
| 43 |
## Final model (trained on all images) – fit on its own training images, NOT a generalisation estimate
|
| 44 |
|
| 45 |
| Image | Nuclei F1 | Attribute acc | Puncta F1 |
|
| 46 |
|---|---:|---:|---:|
|
| 47 |
+
| C100 | 94.2% | 98.8% | 80.0% |
|
| 48 |
+
| C102 | 94.8% | 94.5% | 78.8% |
|
| 49 |
+
| C110 | 90.5% | 96.4% | 83.9% |
|
| 50 |
+
| C112 | 84.8% | 99.2% | 82.0% |
|
| 51 |
+
| F100 | 90.1% | 94.8% | 90.3% |
|
| 52 |
+
| F110 | 91.9% | 97.5% | 88.6% |
|
| 53 |
+
| F113 | 85.2% | 97.8% | 92.1% |
|
| 54 |
+
| F114 | 91.7% | 95.0% | 82.5% |
|
| 55 |
+
| F99 | 91.9% | 97.0% | 90.9% |
|
| 56 |
+
|
| 57 |
+
## Change from v2 (same protocol, same nine held-out images; `reports/cv_v3/comparison.md` has the full table)
|
| 58 |
+
|
| 59 |
+
| Measure | v2 | v3 | Δ (points) |
|
| 60 |
|---|---:|---:|---:|
|
| 61 |
+
| Nucleus F1, IoU ≥ 0.5 | 80.4% | 82.6% | +2.3 |
|
| 62 |
+
| Nucleus precision, IoU ≥ 0.5 | 75.8% | 81.1% | +5.3 |
|
| 63 |
+
| Nucleus recall, IoU ≥ 0.5 | 85.5% | 84.2% | -1.3 |
|
| 64 |
+
| Nucleus F1, centroid rule | 88.8% | 90.5% | +1.7 |
|
| 65 |
+
| Nucleus F1, IoU ≥ 0.5, 8× TTA | 80.5% | 82.9% | +2.4 |
|
| 66 |
+
| Puncta F1 | 80.4% | 80.4% | +0.0 |
|
| 67 |
+
| F1 [Cell, Antibody +] | 74.4% | 76.8% | +2.4 |
|
| 68 |
+
| F1 [Cell, Antibody -] | 37.8% | 40.0% | +2.2 |
|
| 69 |
+
| F1 [Cell, Nostril, Antibody +] | 72.8% | 74.1% | +1.3 |
|
| 70 |
| F1 [Cell, Nostril, Antibody -] | 0.0% | 0.0% | +0.0 |
|
| 71 |
+
| F1 [Nostril in Nucleus] | 78.7% | 78.7% | +0.0 |
|
| 72 |
+
| F1 [Nostril External of Nucleus] | 71.8% | 71.8% | +0.0 |
|
| 73 |
+
| Attribute accuracy, both (each model's own matched nuclei) | 89.3% | 89.6% | +0.3 |
|
| 74 |
+
| Punctum type accuracy (matched puncta) | 93.4% | 93.4% | +0.0 |
|
| 75 |
+
| Nuclei F1, C100 held out | 84.4% | 87.4% | +3.0 |
|
| 76 |
+
| Nuclei F1, C102 held out | 86.4% | 88.7% | +2.2 |
|
| 77 |
+
| Nuclei F1, C110 held out | 77.4% | 82.4% | +5.0 |
|
| 78 |
+
| Nuclei F1, C112 held out | 71.6% | 74.6% | +3.0 |
|
| 79 |
+
| Nuclei F1, F100 held out | 82.9% | 84.4% | +1.5 |
|
| 80 |
+
| Nuclei F1, F110 held out | 77.0% | 80.2% | +3.1 |
|
| 81 |
+
| Nuclei F1, F113 held out | 69.9% | 71.8% | +1.9 |
|
| 82 |
+
| Nuclei F1, F114 held out | 82.4% | 83.1% | +0.6 |
|
| 83 |
+
| Nuclei F1, F99 held out | 87.5% | 88.0% | +0.4 |
|
| 84 |
+
|
| 85 |
+
v3 keeps the v2 weights and drops 142 of the 1771 nuclei v2 predicted on the nine held-out images (1569 annotated): unmatched predictions fall from 429 to 308 (those overlapping no annotated nucleus from 143 to 72) while matched ones fall from 1342 to 1321, so precision rises by 5.3 points and recall drops by 1.3. Puncta are untouched. The over-count of nuclei on the annotated images shrinks from 13 % to 4 %. The threshold was never tuned on a held-out image: each fold used the value chosen on its own training images (0.60-0.67, see rule_study.md), the shipped model the value chosen on all nine (0.64).
|
| 86 |
+
|
| 87 |
+
## Antibody − threshold (held-out matched nuclei: 1321, of which 94 negative)
|
| 88 |
+
|
| 89 |
+
Default threshold 0.5. Best Antibody − F1 in the sweep: 51.6% at threshold 0.90 (precision 52.2%, recall 51.1%); the full curve is in cv_report.md. The default was kept because the class is dominated by a single image (F99 holds 62 of the 110 negatives).
|
| 90 |
|
| 91 |
## What limits the scores
|
| 92 |
|
| 93 |
* **Touching nuclei** are still the main source of IoU-0.5 misses (worst on F113, the densest image). The distance-map watershed of v2 recovers many clusters that v1 merged (v1 marker/threshold sweeps in `reports/cv/postprocess_sweep.json` had shown post-processing alone could not), but some clusters are still merged and a few nuclei are now split in two.
|
| 94 |
+
* **Annotation completeness**: most unmatched predictions overlap an annotated nucleus (outline disagreement); the rest are dimmer, smaller objects the annotator skipped, which the peak-distance rule of v3 halves (143 → 72 on the held-out images) at the price of 21 matched nuclei. Many faint red dots were likewise not annotated, which caps external-punctum precision.
|
| 95 |
* **Antibody − is rare** (110 of 1569 nuclei, 62 in one image), and **Cell, Nostril, Antibody −** has five examples; their scores are not reliable. The class-balanced loss of v2 trades antibody-negative precision for recall.
|
| 96 |
* Scores are from nine images of one experiment (35-day spinal cord, Iba1/TMEM119). New staining batches or magnifications need a check against a few annotated images.
|
| 97 |
|
|
|
|
| 99 |
|
| 100 |
```bash
|
| 101 |
python evaluate.py cv --data-dir <folder with TIFs and CVAT zips> --runs-dir runs/cv_v2 --iters 3000
|
| 102 |
+
python scripts/rule_study.py --data-dir <folder> --runs-dir runs/cv_v2 --out runs/cv_v3/rule_study --weights weights/cellquant.pt
|
| 103 |
+
python evaluate.py cv --data-dir <folder> --runs-dir runs/cv_v3 --post-config runs/cv_v3/rule_study_post_config.json # fold_*.pt linked from runs/cv_v2
|
| 104 |
python evaluate.py final --data-dir <folder> --weights weights/cellquant.pt
|
| 105 |
+
python scripts/compare_cv.py reports/cv_v2/cv_results.json runs/cv_v3/cv_results.json --names v2,v3 --out reports/cv_v3/comparison.md
|
| 106 |
+
python scripts/build_summary.py --cv-dir reports/cv_v3 --compare reports/cv_v2/cv_results.json --names v2,v3
|
| 107 |
```
|
reports/final/final_fit.json
CHANGED
|
@@ -1,57 +1,70 @@
|
|
| 1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
"C100": {
|
| 3 |
"cells": {
|
| 4 |
"detection": {
|
| 5 |
-
"tp":
|
| 6 |
-
"fp":
|
| 7 |
-
"fn":
|
| 8 |
-
"precision": 0.
|
| 9 |
-
"recall": 0.
|
| 10 |
-
"f1": 0.
|
| 11 |
-
"mean_iou_matched": 0.
|
| 12 |
"iou30": {
|
| 13 |
-
"tp":
|
| 14 |
-
"fp":
|
| 15 |
-
"fn":
|
| 16 |
-
"precision": 0.
|
| 17 |
-
"recall": 0.
|
| 18 |
-
"f1": 0.
|
| 19 |
},
|
| 20 |
"centroid": {
|
| 21 |
-
"tp":
|
| 22 |
-
"fp":
|
| 23 |
-
"fn":
|
| 24 |
-
"precision": 0.
|
| 25 |
-
"recall":
|
| 26 |
-
"f1": 0.
|
| 27 |
}
|
| 28 |
},
|
| 29 |
"attribute_accuracy": {
|
| 30 |
-
"antibody": 0.
|
| 31 |
-
"nostril": 0.
|
| 32 |
-
"both": 0.
|
| 33 |
-
"n_matched":
|
| 34 |
},
|
| 35 |
"per_class": {
|
| 36 |
"Cell, Antibody +": {
|
| 37 |
-
"tp":
|
| 38 |
-
"fp":
|
| 39 |
-
"fn":
|
| 40 |
-
"precision": 0.
|
| 41 |
-
"recall": 0.
|
| 42 |
-
"f1": 0.
|
| 43 |
"gt_count": 165,
|
| 44 |
-
"pred_count":
|
| 45 |
},
|
| 46 |
"Cell, Antibody -": {
|
| 47 |
"tp": 0,
|
| 48 |
-
"fp":
|
| 49 |
"fn": 0,
|
| 50 |
"precision": 0.0,
|
| 51 |
"recall": 0.0,
|
| 52 |
"f1": 0.0,
|
| 53 |
"gt_count": 0,
|
| 54 |
-
"pred_count":
|
| 55 |
},
|
| 56 |
"Cell, Nostril, Antibody +": {
|
| 57 |
"tp": 12,
|
|
@@ -76,8 +89,8 @@
|
|
| 76 |
},
|
| 77 |
"confusion": {
|
| 78 |
"Cell, Antibody +": {
|
| 79 |
-
"Cell, Antibody +":
|
| 80 |
-
"Cell, Antibody -":
|
| 81 |
"Cell, Nostril, Antibody +": 0,
|
| 82 |
"Cell, Nostril, Antibody -": 0
|
| 83 |
},
|
|
@@ -101,7 +114,7 @@
|
|
| 101 |
}
|
| 102 |
},
|
| 103 |
"n_gt": 178,
|
| 104 |
-
"n_pred":
|
| 105 |
},
|
| 106 |
"nostrils": {
|
| 107 |
"detection": {
|
|
@@ -142,14 +155,14 @@
|
|
| 142 |
"counts": {
|
| 143 |
"Cell, Antibody +": {
|
| 144 |
"gt": 165,
|
| 145 |
-
"pred":
|
| 146 |
-
"abs_err":
|
| 147 |
-
"rel_err": 0.
|
| 148 |
},
|
| 149 |
"Cell, Antibody -": {
|
| 150 |
"gt": 0,
|
| 151 |
-
"pred":
|
| 152 |
-
"abs_err":
|
| 153 |
"rel_err": Infinity
|
| 154 |
},
|
| 155 |
"Cell, Nostril, Antibody +": {
|
|
@@ -180,20 +193,20 @@
|
|
| 180 |
"fp_analysis": null,
|
| 181 |
"pairs": null,
|
| 182 |
"summary": {
|
| 183 |
-
"cell_det_f1": 0.
|
| 184 |
-
"cell_det_precision": 0.
|
| 185 |
-
"cell_det_recall": 0.
|
| 186 |
-
"cell_mean_iou": 0.
|
| 187 |
-
"cell_det_f1_iou30": 0.
|
| 188 |
-
"cell_det_f1_centroid": 0.
|
| 189 |
-
"cell_attr_antibody": 0.
|
| 190 |
-
"cell_attr_nostril": 0.
|
| 191 |
-
"cell_attr_both": 0.
|
| 192 |
"nos_det_f1": 0.8000000000000002,
|
| 193 |
"nos_det_precision": 0.8,
|
| 194 |
"nos_det_recall": 0.8,
|
| 195 |
"nos_type_acc": 1.0,
|
| 196 |
-
"f1[Cell, Antibody +]": 0.
|
| 197 |
"f1[Cell, Antibody -]": 0.0,
|
| 198 |
"f1[Cell, Nostril, Antibody +]": 0.9600000000000001,
|
| 199 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
|
@@ -205,27 +218,27 @@
|
|
| 205 |
"cells": {
|
| 206 |
"detection": {
|
| 207 |
"tp": 91,
|
| 208 |
-
"fp":
|
| 209 |
"fn": 0,
|
| 210 |
-
"precision": 0.
|
| 211 |
"recall": 1.0,
|
| 212 |
-
"f1": 0.
|
| 213 |
"mean_iou_matched": 0.8036863197012898,
|
| 214 |
"iou30": {
|
| 215 |
"tp": 91,
|
| 216 |
-
"fp":
|
| 217 |
"fn": 0,
|
| 218 |
-
"precision": 0.
|
| 219 |
"recall": 1.0,
|
| 220 |
-
"f1": 0.
|
| 221 |
},
|
| 222 |
"centroid": {
|
| 223 |
"tp": 91,
|
| 224 |
-
"fp":
|
| 225 |
"fn": 0,
|
| 226 |
-
"precision": 0.
|
| 227 |
"recall": 1.0,
|
| 228 |
-
"f1": 0.
|
| 229 |
}
|
| 230 |
},
|
| 231 |
"attribute_accuracy": {
|
|
@@ -237,33 +250,33 @@
|
|
| 237 |
"per_class": {
|
| 238 |
"Cell, Antibody +": {
|
| 239 |
"tp": 41,
|
| 240 |
-
"fp":
|
| 241 |
"fn": 0,
|
| 242 |
-
"precision": 0.
|
| 243 |
"recall": 1.0,
|
| 244 |
-
"f1": 0.
|
| 245 |
"gt_count": 41,
|
| 246 |
-
"pred_count":
|
| 247 |
},
|
| 248 |
"Cell, Antibody -": {
|
| 249 |
"tp": 0,
|
| 250 |
-
"fp":
|
| 251 |
"fn": 0,
|
| 252 |
"precision": 0.0,
|
| 253 |
"recall": 0.0,
|
| 254 |
"f1": 0.0,
|
| 255 |
"gt_count": 0,
|
| 256 |
-
"pred_count":
|
| 257 |
},
|
| 258 |
"Cell, Nostril, Antibody +": {
|
| 259 |
"tp": 45,
|
| 260 |
-
"fp":
|
| 261 |
"fn": 5,
|
| 262 |
-
"precision": 0.
|
| 263 |
"recall": 0.9,
|
| 264 |
-
"f1": 0.
|
| 265 |
"gt_count": 50,
|
| 266 |
-
"pred_count":
|
| 267 |
},
|
| 268 |
"Cell, Nostril, Antibody -": {
|
| 269 |
"tp": 0,
|
|
@@ -303,7 +316,7 @@
|
|
| 303 |
}
|
| 304 |
},
|
| 305 |
"n_gt": 91,
|
| 306 |
-
"n_pred":
|
| 307 |
},
|
| 308 |
"nostrils": {
|
| 309 |
"detection": {
|
|
@@ -344,21 +357,21 @@
|
|
| 344 |
"counts": {
|
| 345 |
"Cell, Antibody +": {
|
| 346 |
"gt": 41,
|
| 347 |
-
"pred":
|
| 348 |
-
"abs_err":
|
| 349 |
-
"rel_err": 0.
|
| 350 |
},
|
| 351 |
"Cell, Antibody -": {
|
| 352 |
"gt": 0,
|
| 353 |
-
"pred":
|
| 354 |
-
"abs_err":
|
| 355 |
-
"rel_err":
|
| 356 |
},
|
| 357 |
"Cell, Nostril, Antibody +": {
|
| 358 |
"gt": 50,
|
| 359 |
-
"pred":
|
| 360 |
-
"abs_err":
|
| 361 |
-
"rel_err": 0.
|
| 362 |
},
|
| 363 |
"Cell, Nostril, Antibody -": {
|
| 364 |
"gt": 0,
|
|
@@ -382,12 +395,12 @@
|
|
| 382 |
"fp_analysis": null,
|
| 383 |
"pairs": null,
|
| 384 |
"summary": {
|
| 385 |
-
"cell_det_f1": 0.
|
| 386 |
-
"cell_det_precision": 0.
|
| 387 |
"cell_det_recall": 1.0,
|
| 388 |
"cell_mean_iou": 0.8036863197012898,
|
| 389 |
-
"cell_det_f1_iou30": 0.
|
| 390 |
-
"cell_det_f1_centroid": 0.
|
| 391 |
"cell_attr_antibody": 1.0,
|
| 392 |
"cell_attr_nostril": 0.945054945054945,
|
| 393 |
"cell_attr_both": 0.945054945054945,
|
|
@@ -395,9 +408,9 @@
|
|
| 395 |
"nos_det_precision": 0.6910112359550562,
|
| 396 |
"nos_det_recall": 0.917910447761194,
|
| 397 |
"nos_type_acc": 0.991869918699187,
|
| 398 |
-
"f1[Cell, Antibody +]": 0.
|
| 399 |
"f1[Cell, Antibody -]": 0.0,
|
| 400 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 401 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 402 |
"f1[Nostril in Nucleus]": 0.8503937007874016,
|
| 403 |
"f1[Nostril External of Nucleus]": 0.7351351351351352
|
|
@@ -406,46 +419,46 @@
|
|
| 406 |
"C110": {
|
| 407 |
"cells": {
|
| 408 |
"detection": {
|
| 409 |
-
"tp":
|
| 410 |
-
"fp":
|
| 411 |
-
"fn":
|
| 412 |
-
"precision": 0.
|
| 413 |
-
"recall": 0.
|
| 414 |
-
"f1": 0.
|
| 415 |
-
"mean_iou_matched": 0.
|
| 416 |
"iou30": {
|
| 417 |
-
"tp":
|
| 418 |
-
"fp":
|
| 419 |
-
"fn":
|
| 420 |
-
"precision": 0.
|
| 421 |
-
"recall": 0.
|
| 422 |
-
"f1": 0.
|
| 423 |
},
|
| 424 |
"centroid": {
|
| 425 |
-
"tp":
|
| 426 |
-
"fp":
|
| 427 |
-
"fn":
|
| 428 |
-
"precision": 0.
|
| 429 |
-
"recall": 0.
|
| 430 |
-
"f1": 0.
|
| 431 |
}
|
| 432 |
},
|
| 433 |
"attribute_accuracy": {
|
| 434 |
-
"antibody": 0.
|
| 435 |
-
"nostril": 0.
|
| 436 |
-
"both": 0.
|
| 437 |
-
"n_matched":
|
| 438 |
},
|
| 439 |
"per_class": {
|
| 440 |
"Cell, Antibody +": {
|
| 441 |
"tp": 52,
|
| 442 |
-
"fp":
|
| 443 |
"fn": 9,
|
| 444 |
-
"precision": 0.
|
| 445 |
"recall": 0.8524590163934426,
|
| 446 |
-
"f1": 0.
|
| 447 |
"gt_count": 61,
|
| 448 |
-
"pred_count":
|
| 449 |
},
|
| 450 |
"Cell, Antibody -": {
|
| 451 |
"tp": 1,
|
|
@@ -458,14 +471,14 @@
|
|
| 458 |
"pred_count": 2
|
| 459 |
},
|
| 460 |
"Cell, Nostril, Antibody +": {
|
| 461 |
-
"tp":
|
| 462 |
-
"fp":
|
| 463 |
-
"fn":
|
| 464 |
-
"precision": 0.
|
| 465 |
-
"recall": 0.
|
| 466 |
-
"f1": 0.
|
| 467 |
"gt_count": 122,
|
| 468 |
-
"pred_count":
|
| 469 |
},
|
| 470 |
"Cell, Nostril, Antibody -": {
|
| 471 |
"tp": 0,
|
|
@@ -494,7 +507,7 @@
|
|
| 494 |
"Cell, Nostril, Antibody +": {
|
| 495 |
"Cell, Antibody +": 3,
|
| 496 |
"Cell, Antibody -": 0,
|
| 497 |
-
"Cell, Nostril, Antibody +":
|
| 498 |
"Cell, Nostril, Antibody -": 0
|
| 499 |
},
|
| 500 |
"Cell, Nostril, Antibody -": {
|
|
@@ -505,7 +518,7 @@
|
|
| 505 |
}
|
| 506 |
},
|
| 507 |
"n_gt": 184,
|
| 508 |
-
"n_pred":
|
| 509 |
},
|
| 510 |
"nostrils": {
|
| 511 |
"detection": {
|
|
@@ -546,9 +559,9 @@
|
|
| 546 |
"counts": {
|
| 547 |
"Cell, Antibody +": {
|
| 548 |
"gt": 61,
|
| 549 |
-
"pred":
|
| 550 |
-
"abs_err":
|
| 551 |
-
"rel_err": 0.
|
| 552 |
},
|
| 553 |
"Cell, Antibody -": {
|
| 554 |
"gt": 1,
|
|
@@ -558,7 +571,7 @@
|
|
| 558 |
},
|
| 559 |
"Cell, Nostril, Antibody +": {
|
| 560 |
"gt": 122,
|
| 561 |
-
"pred":
|
| 562 |
"abs_err": 3,
|
| 563 |
"rel_err": 0.02459016393442623
|
| 564 |
},
|
|
@@ -584,22 +597,22 @@
|
|
| 584 |
"fp_analysis": null,
|
| 585 |
"pairs": null,
|
| 586 |
"summary": {
|
| 587 |
-
"cell_det_f1": 0.
|
| 588 |
-
"cell_det_precision": 0.
|
| 589 |
-
"cell_det_recall": 0.
|
| 590 |
-
"cell_mean_iou": 0.
|
| 591 |
-
"cell_det_f1_iou30": 0.
|
| 592 |
-
"cell_det_f1_centroid": 0.
|
| 593 |
-
"cell_attr_antibody": 0.
|
| 594 |
-
"cell_attr_nostril": 0.
|
| 595 |
-
"cell_attr_both": 0.
|
| 596 |
"nos_det_f1": 0.8391777509068925,
|
| 597 |
"nos_det_precision": 0.7694013303769401,
|
| 598 |
"nos_det_recall": 0.9228723404255319,
|
| 599 |
"nos_type_acc": 0.9740634005763689,
|
| 600 |
-
"f1[Cell, Antibody +]": 0.
|
| 601 |
"f1[Cell, Antibody -]": 0.6666666666666666,
|
| 602 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 603 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 604 |
"f1[Nostril in Nucleus]": 0.8324022346368716,
|
| 605 |
"f1[Nostril External of Nucleus]": 0.8059701492537313
|
|
@@ -608,66 +621,66 @@
|
|
| 608 |
"C112": {
|
| 609 |
"cells": {
|
| 610 |
"detection": {
|
| 611 |
-
"tp":
|
| 612 |
-
"fp":
|
| 613 |
-
"fn":
|
| 614 |
-
"precision": 0.
|
| 615 |
-
"recall": 0.
|
| 616 |
-
"f1": 0.
|
| 617 |
-
"mean_iou_matched": 0.
|
| 618 |
"iou30": {
|
| 619 |
-
"tp":
|
| 620 |
-
"fp":
|
| 621 |
-
"fn":
|
| 622 |
-
"precision": 0.
|
| 623 |
-
"recall": 0.
|
| 624 |
-
"f1": 0.
|
| 625 |
},
|
| 626 |
"centroid": {
|
| 627 |
-
"tp":
|
| 628 |
-
"fp":
|
| 629 |
-
"fn":
|
| 630 |
-
"precision": 0.
|
| 631 |
-
"recall": 0.
|
| 632 |
-
"f1": 0.
|
| 633 |
}
|
| 634 |
},
|
| 635 |
"attribute_accuracy": {
|
| 636 |
"antibody": 1.0,
|
| 637 |
-
"nostril": 0.
|
| 638 |
-
"both": 0.
|
| 639 |
-
"n_matched":
|
| 640 |
},
|
| 641 |
"per_class": {
|
| 642 |
"Cell, Antibody +": {
|
| 643 |
-
"tp":
|
| 644 |
-
"fp":
|
| 645 |
-
"fn":
|
| 646 |
-
"precision": 0.
|
| 647 |
-
"recall": 0.
|
| 648 |
-
"f1": 0.
|
| 649 |
"gt_count": 124,
|
| 650 |
-
"pred_count":
|
| 651 |
},
|
| 652 |
"Cell, Antibody -": {
|
| 653 |
"tp": 5,
|
| 654 |
-
"fp":
|
| 655 |
"fn": 0,
|
| 656 |
-
"precision":
|
| 657 |
"recall": 1.0,
|
| 658 |
-
"f1":
|
| 659 |
"gt_count": 5,
|
| 660 |
-
"pred_count":
|
| 661 |
},
|
| 662 |
"Cell, Nostril, Antibody +": {
|
| 663 |
"tp": 15,
|
| 664 |
-
"fp":
|
| 665 |
"fn": 2,
|
| 666 |
-
"precision": 0.
|
| 667 |
"recall": 0.8823529411764706,
|
| 668 |
-
"f1": 0.
|
| 669 |
"gt_count": 17,
|
| 670 |
-
"pred_count":
|
| 671 |
},
|
| 672 |
"Cell, Nostril, Antibody -": {
|
| 673 |
"tp": 0,
|
|
@@ -682,7 +695,7 @@
|
|
| 682 |
},
|
| 683 |
"confusion": {
|
| 684 |
"Cell, Antibody +": {
|
| 685 |
-
"Cell, Antibody +":
|
| 686 |
"Cell, Antibody -": 0,
|
| 687 |
"Cell, Nostril, Antibody +": 1,
|
| 688 |
"Cell, Nostril, Antibody -": 0
|
|
@@ -707,7 +720,7 @@
|
|
| 707 |
}
|
| 708 |
},
|
| 709 |
"n_gt": 146,
|
| 710 |
-
"n_pred":
|
| 711 |
},
|
| 712 |
"nostrils": {
|
| 713 |
"detection": {
|
|
@@ -748,21 +761,21 @@
|
|
| 748 |
"counts": {
|
| 749 |
"Cell, Antibody +": {
|
| 750 |
"gt": 124,
|
| 751 |
-
"pred":
|
| 752 |
-
"abs_err":
|
| 753 |
-
"rel_err": 0.
|
| 754 |
},
|
| 755 |
"Cell, Antibody -": {
|
| 756 |
"gt": 5,
|
| 757 |
-
"pred":
|
| 758 |
-
"abs_err":
|
| 759 |
-
"rel_err": 0.
|
| 760 |
},
|
| 761 |
"Cell, Nostril, Antibody +": {
|
| 762 |
"gt": 17,
|
| 763 |
-
"pred":
|
| 764 |
-
"abs_err":
|
| 765 |
-
"rel_err": 0.
|
| 766 |
},
|
| 767 |
"Cell, Nostril, Antibody -": {
|
| 768 |
"gt": 0,
|
|
@@ -786,22 +799,22 @@
|
|
| 786 |
"fp_analysis": null,
|
| 787 |
"pairs": null,
|
| 788 |
"summary": {
|
| 789 |
-
"cell_det_f1": 0.
|
| 790 |
-
"cell_det_precision": 0.
|
| 791 |
-
"cell_det_recall": 0.
|
| 792 |
-
"cell_mean_iou": 0.
|
| 793 |
-
"cell_det_f1_iou30": 0.
|
| 794 |
-
"cell_det_f1_centroid": 0.
|
| 795 |
"cell_attr_antibody": 1.0,
|
| 796 |
-
"cell_attr_nostril": 0.
|
| 797 |
-
"cell_attr_both": 0.
|
| 798 |
"nos_det_f1": 0.819672131147541,
|
| 799 |
"nos_det_precision": 0.6944444444444444,
|
| 800 |
"nos_det_recall": 1.0,
|
| 801 |
"nos_type_acc": 1.0,
|
| 802 |
-
"f1[Cell, Antibody +]": 0.
|
| 803 |
-
"f1[Cell, Antibody -]":
|
| 804 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 805 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 806 |
"f1[Nostril in Nucleus]": 0.92,
|
| 807 |
"f1[Nostril External of Nucleus]": 0.3636363636363636
|
|
@@ -811,27 +824,27 @@
|
|
| 811 |
"cells": {
|
| 812 |
"detection": {
|
| 813 |
"tp": 172,
|
| 814 |
-
"fp":
|
| 815 |
"fn": 14,
|
| 816 |
-
"precision": 0.
|
| 817 |
"recall": 0.9247311827956989,
|
| 818 |
-
"f1": 0.
|
| 819 |
"mean_iou_matched": 0.7905866698793166,
|
| 820 |
"iou30": {
|
| 821 |
-
"tp":
|
| 822 |
-
"fp":
|
| 823 |
-
"fn":
|
| 824 |
-
"precision": 0.
|
| 825 |
-
"recall": 0.
|
| 826 |
-
"f1": 0.
|
| 827 |
},
|
| 828 |
"centroid": {
|
| 829 |
-
"tp":
|
| 830 |
-
"fp":
|
| 831 |
-
"fn":
|
| 832 |
-
"precision": 0.
|
| 833 |
-
"recall": 0.
|
| 834 |
-
"f1": 0.
|
| 835 |
}
|
| 836 |
},
|
| 837 |
"attribute_accuracy": {
|
|
@@ -843,23 +856,23 @@
|
|
| 843 |
"per_class": {
|
| 844 |
"Cell, Antibody +": {
|
| 845 |
"tp": 80,
|
| 846 |
-
"fp":
|
| 847 |
"fn": 7,
|
| 848 |
-
"precision": 0.
|
| 849 |
"recall": 0.9195402298850575,
|
| 850 |
-
"f1": 0.
|
| 851 |
"gt_count": 87,
|
| 852 |
-
"pred_count":
|
| 853 |
},
|
| 854 |
"Cell, Antibody -": {
|
| 855 |
"tp": 5,
|
| 856 |
-
"fp":
|
| 857 |
"fn": 1,
|
| 858 |
-
"precision": 0.
|
| 859 |
"recall": 0.8333333333333334,
|
| 860 |
-
"f1": 0.
|
| 861 |
"gt_count": 6,
|
| 862 |
-
"pred_count":
|
| 863 |
},
|
| 864 |
"Cell, Nostril, Antibody +": {
|
| 865 |
"tp": 78,
|
|
@@ -909,7 +922,7 @@
|
|
| 909 |
}
|
| 910 |
},
|
| 911 |
"n_gt": 186,
|
| 912 |
-
"n_pred":
|
| 913 |
},
|
| 914 |
"nostrils": {
|
| 915 |
"detection": {
|
|
@@ -950,15 +963,15 @@
|
|
| 950 |
"counts": {
|
| 951 |
"Cell, Antibody +": {
|
| 952 |
"gt": 87,
|
| 953 |
-
"pred":
|
| 954 |
-
"abs_err":
|
| 955 |
-
"rel_err": 0.
|
| 956 |
},
|
| 957 |
"Cell, Antibody -": {
|
| 958 |
"gt": 6,
|
| 959 |
-
"pred":
|
| 960 |
-
"abs_err":
|
| 961 |
-
"rel_err": 0.
|
| 962 |
},
|
| 963 |
"Cell, Nostril, Antibody +": {
|
| 964 |
"gt": 93,
|
|
@@ -988,12 +1001,12 @@
|
|
| 988 |
"fp_analysis": null,
|
| 989 |
"pairs": null,
|
| 990 |
"summary": {
|
| 991 |
-
"cell_det_f1": 0.
|
| 992 |
-
"cell_det_precision": 0.
|
| 993 |
"cell_det_recall": 0.9247311827956989,
|
| 994 |
"cell_mean_iou": 0.7905866698793166,
|
| 995 |
-
"cell_det_f1_iou30": 0.
|
| 996 |
-
"cell_det_f1_centroid": 0.
|
| 997 |
"cell_attr_antibody": 0.9941860465116279,
|
| 998 |
"cell_attr_nostril": 0.9534883720930233,
|
| 999 |
"cell_attr_both": 0.9476744186046512,
|
|
@@ -1001,8 +1014,8 @@
|
|
| 1001 |
"nos_det_precision": 0.9171974522292994,
|
| 1002 |
"nos_det_recall": 0.8888888888888888,
|
| 1003 |
"nos_type_acc": 0.9930555555555556,
|
| 1004 |
-
"f1[Cell, Antibody +]": 0.
|
| 1005 |
-
"f1[Cell, Antibody -]": 0.
|
| 1006 |
"f1[Cell, Nostril, Antibody +]": 0.8764044943820225,
|
| 1007 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1008 |
"f1[Nostril in Nucleus]": 0.8803418803418803,
|
|
@@ -1012,66 +1025,66 @@
|
|
| 1012 |
"F110": {
|
| 1013 |
"cells": {
|
| 1014 |
"detection": {
|
| 1015 |
-
"tp":
|
| 1016 |
-
"fp":
|
| 1017 |
-
"fn":
|
| 1018 |
-
"precision": 0.
|
| 1019 |
-
"recall": 0.
|
| 1020 |
-
"f1": 0.
|
| 1021 |
-
"mean_iou_matched": 0.
|
| 1022 |
"iou30": {
|
| 1023 |
-
"tp":
|
| 1024 |
-
"fp":
|
| 1025 |
-
"fn":
|
| 1026 |
-
"precision": 0.
|
| 1027 |
-
"recall": 0.
|
| 1028 |
-
"f1": 0.
|
| 1029 |
},
|
| 1030 |
"centroid": {
|
| 1031 |
-
"tp":
|
| 1032 |
-
"fp":
|
| 1033 |
-
"fn":
|
| 1034 |
-
"precision": 0.
|
| 1035 |
-
"recall": 0.
|
| 1036 |
-
"f1": 0.
|
| 1037 |
}
|
| 1038 |
},
|
| 1039 |
"attribute_accuracy": {
|
| 1040 |
"antibody": 1.0,
|
| 1041 |
-
"nostril": 0.
|
| 1042 |
-
"both": 0.
|
| 1043 |
-
"n_matched":
|
| 1044 |
},
|
| 1045 |
"per_class": {
|
| 1046 |
"Cell, Antibody +": {
|
| 1047 |
-
"tp":
|
| 1048 |
-
"fp":
|
| 1049 |
-
"fn":
|
| 1050 |
-
"precision": 0.
|
| 1051 |
-
"recall": 0.
|
| 1052 |
-
"f1": 0.
|
| 1053 |
"gt_count": 87,
|
| 1054 |
-
"pred_count":
|
| 1055 |
},
|
| 1056 |
"Cell, Antibody -": {
|
| 1057 |
"tp": 6,
|
| 1058 |
-
"fp":
|
| 1059 |
"fn": 1,
|
| 1060 |
-
"precision": 0.
|
| 1061 |
"recall": 0.8571428571428571,
|
| 1062 |
-
"f1": 0.
|
| 1063 |
"gt_count": 7,
|
| 1064 |
-
"pred_count":
|
| 1065 |
},
|
| 1066 |
"Cell, Nostril, Antibody +": {
|
| 1067 |
-
"tp":
|
| 1068 |
-
"fp":
|
| 1069 |
-
"fn":
|
| 1070 |
-
"precision": 0.
|
| 1071 |
-
"recall": 0.
|
| 1072 |
-
"f1": 0.
|
| 1073 |
"gt_count": 33,
|
| 1074 |
-
"pred_count":
|
| 1075 |
},
|
| 1076 |
"Cell, Nostril, Antibody -": {
|
| 1077 |
"tp": 0,
|
|
@@ -1086,7 +1099,7 @@
|
|
| 1086 |
},
|
| 1087 |
"confusion": {
|
| 1088 |
"Cell, Antibody +": {
|
| 1089 |
-
"Cell, Antibody +":
|
| 1090 |
"Cell, Antibody -": 0,
|
| 1091 |
"Cell, Nostril, Antibody +": 0,
|
| 1092 |
"Cell, Nostril, Antibody -": 0
|
|
@@ -1100,7 +1113,7 @@
|
|
| 1100 |
"Cell, Nostril, Antibody +": {
|
| 1101 |
"Cell, Antibody +": 3,
|
| 1102 |
"Cell, Antibody -": 0,
|
| 1103 |
-
"Cell, Nostril, Antibody +":
|
| 1104 |
"Cell, Nostril, Antibody -": 0
|
| 1105 |
},
|
| 1106 |
"Cell, Nostril, Antibody -": {
|
|
@@ -1111,7 +1124,7 @@
|
|
| 1111 |
}
|
| 1112 |
},
|
| 1113 |
"n_gt": 128,
|
| 1114 |
-
"n_pred":
|
| 1115 |
},
|
| 1116 |
"nostrils": {
|
| 1117 |
"detection": {
|
|
@@ -1152,21 +1165,21 @@
|
|
| 1152 |
"counts": {
|
| 1153 |
"Cell, Antibody +": {
|
| 1154 |
"gt": 87,
|
| 1155 |
-
"pred":
|
| 1156 |
-
"abs_err":
|
| 1157 |
-
"rel_err": 0.
|
| 1158 |
},
|
| 1159 |
"Cell, Antibody -": {
|
| 1160 |
"gt": 7,
|
| 1161 |
-
"pred":
|
| 1162 |
-
"abs_err":
|
| 1163 |
-
"rel_err": 0.
|
| 1164 |
},
|
| 1165 |
"Cell, Nostril, Antibody +": {
|
| 1166 |
"gt": 33,
|
| 1167 |
-
"pred":
|
| 1168 |
-
"abs_err":
|
| 1169 |
-
"rel_err": 0.
|
| 1170 |
},
|
| 1171 |
"Cell, Nostril, Antibody -": {
|
| 1172 |
"gt": 1,
|
|
@@ -1190,22 +1203,22 @@
|
|
| 1190 |
"fp_analysis": null,
|
| 1191 |
"pairs": null,
|
| 1192 |
"summary": {
|
| 1193 |
-
"cell_det_f1": 0.
|
| 1194 |
-
"cell_det_precision": 0.
|
| 1195 |
-
"cell_det_recall": 0.
|
| 1196 |
-
"cell_mean_iou": 0.
|
| 1197 |
-
"cell_det_f1_iou30": 0.
|
| 1198 |
-
"cell_det_f1_centroid": 0.
|
| 1199 |
"cell_attr_antibody": 1.0,
|
| 1200 |
-
"cell_attr_nostril": 0.
|
| 1201 |
-
"cell_attr_both": 0.
|
| 1202 |
"nos_det_f1": 0.8864864864864865,
|
| 1203 |
"nos_det_precision": 0.9318181818181818,
|
| 1204 |
"nos_det_recall": 0.845360824742268,
|
| 1205 |
"nos_type_acc": 0.9878048780487805,
|
| 1206 |
-
"f1[Cell, Antibody +]": 0.
|
| 1207 |
-
"f1[Cell, Antibody -]": 0.
|
| 1208 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 1209 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1210 |
"f1[Nostril in Nucleus]": 0.8518518518518519,
|
| 1211 |
"f1[Nostril External of Nucleus]": 0.8854961832061069
|
|
@@ -1214,46 +1227,46 @@
|
|
| 1214 |
"F113": {
|
| 1215 |
"cells": {
|
| 1216 |
"detection": {
|
| 1217 |
-
"tp":
|
| 1218 |
-
"fp":
|
| 1219 |
-
"fn":
|
| 1220 |
-
"precision": 0.
|
| 1221 |
-
"recall": 0.
|
| 1222 |
-
"f1": 0.
|
| 1223 |
-
"mean_iou_matched": 0.
|
| 1224 |
"iou30": {
|
| 1225 |
-
"tp":
|
| 1226 |
-
"fp":
|
| 1227 |
-
"fn":
|
| 1228 |
-
"precision": 0.
|
| 1229 |
-
"recall": 0.
|
| 1230 |
-
"f1": 0.
|
| 1231 |
},
|
| 1232 |
"centroid": {
|
| 1233 |
-
"tp":
|
| 1234 |
-
"fp":
|
| 1235 |
-
"fn":
|
| 1236 |
-
"precision": 0.
|
| 1237 |
-
"recall": 0.
|
| 1238 |
-
"f1": 0.
|
| 1239 |
}
|
| 1240 |
},
|
| 1241 |
"attribute_accuracy": {
|
| 1242 |
"antibody": 1.0,
|
| 1243 |
-
"nostril": 0.
|
| 1244 |
-
"both": 0.
|
| 1245 |
-
"n_matched":
|
| 1246 |
},
|
| 1247 |
"per_class": {
|
| 1248 |
"Cell, Antibody +": {
|
| 1249 |
-
"tp":
|
| 1250 |
-
"fp":
|
| 1251 |
-
"fn":
|
| 1252 |
-
"precision": 0.
|
| 1253 |
-
"recall": 0.
|
| 1254 |
-
"f1": 0.
|
| 1255 |
"gt_count": 138,
|
| 1256 |
-
"pred_count":
|
| 1257 |
},
|
| 1258 |
"Cell, Antibody -": {
|
| 1259 |
"tp": 2,
|
|
@@ -1266,14 +1279,14 @@
|
|
| 1266 |
"pred_count": 3
|
| 1267 |
},
|
| 1268 |
"Cell, Nostril, Antibody +": {
|
| 1269 |
-
"tp":
|
| 1270 |
-
"fp":
|
| 1271 |
-
"fn":
|
| 1272 |
-
"precision": 0.
|
| 1273 |
-
"recall": 0.
|
| 1274 |
-
"f1": 0.
|
| 1275 |
"gt_count": 22,
|
| 1276 |
-
"pred_count":
|
| 1277 |
},
|
| 1278 |
"Cell, Nostril, Antibody -": {
|
| 1279 |
"tp": 0,
|
|
@@ -1288,7 +1301,7 @@
|
|
| 1288 |
},
|
| 1289 |
"confusion": {
|
| 1290 |
"Cell, Antibody +": {
|
| 1291 |
-
"Cell, Antibody +":
|
| 1292 |
"Cell, Antibody -": 0,
|
| 1293 |
"Cell, Nostril, Antibody +": 0,
|
| 1294 |
"Cell, Nostril, Antibody -": 0
|
|
@@ -1302,7 +1315,7 @@
|
|
| 1302 |
"Cell, Nostril, Antibody +": {
|
| 1303 |
"Cell, Antibody +": 3,
|
| 1304 |
"Cell, Antibody -": 0,
|
| 1305 |
-
"Cell, Nostril, Antibody +":
|
| 1306 |
"Cell, Nostril, Antibody -": 0
|
| 1307 |
},
|
| 1308 |
"Cell, Nostril, Antibody -": {
|
|
@@ -1313,7 +1326,7 @@
|
|
| 1313 |
}
|
| 1314 |
},
|
| 1315 |
"n_gt": 163,
|
| 1316 |
-
"n_pred":
|
| 1317 |
},
|
| 1318 |
"nostrils": {
|
| 1319 |
"detection": {
|
|
@@ -1354,9 +1367,9 @@
|
|
| 1354 |
"counts": {
|
| 1355 |
"Cell, Antibody +": {
|
| 1356 |
"gt": 138,
|
| 1357 |
-
"pred":
|
| 1358 |
-
"abs_err":
|
| 1359 |
-
"rel_err": 0.
|
| 1360 |
},
|
| 1361 |
"Cell, Antibody -": {
|
| 1362 |
"gt": 3,
|
|
@@ -1366,9 +1379,9 @@
|
|
| 1366 |
},
|
| 1367 |
"Cell, Nostril, Antibody +": {
|
| 1368 |
"gt": 22,
|
| 1369 |
-
"pred":
|
| 1370 |
-
"abs_err":
|
| 1371 |
-
"rel_err": 0.
|
| 1372 |
},
|
| 1373 |
"Cell, Nostril, Antibody -": {
|
| 1374 |
"gt": 0,
|
|
@@ -1392,22 +1405,22 @@
|
|
| 1392 |
"fp_analysis": null,
|
| 1393 |
"pairs": null,
|
| 1394 |
"summary": {
|
| 1395 |
-
"cell_det_f1": 0.
|
| 1396 |
-
"cell_det_precision": 0.
|
| 1397 |
-
"cell_det_recall": 0.
|
| 1398 |
-
"cell_mean_iou": 0.
|
| 1399 |
-
"cell_det_f1_iou30": 0.
|
| 1400 |
-
"cell_det_f1_centroid": 0.
|
| 1401 |
"cell_attr_antibody": 1.0,
|
| 1402 |
-
"cell_attr_nostril": 0.
|
| 1403 |
-
"cell_attr_both": 0.
|
| 1404 |
"nos_det_f1": 0.9206349206349206,
|
| 1405 |
"nos_det_precision": 1.0,
|
| 1406 |
"nos_det_recall": 0.8529411764705882,
|
| 1407 |
"nos_type_acc": 0.9310344827586207,
|
| 1408 |
-
"f1[Cell, Antibody +]": 0.
|
| 1409 |
"f1[Cell, Antibody -]": 0.6666666666666666,
|
| 1410 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 1411 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1412 |
"f1[Nostril in Nucleus]": 0.8979591836734695,
|
| 1413 |
"f1[Nostril External of Nucleus]": 0.7142857142857143
|
|
@@ -1416,66 +1429,66 @@
|
|
| 1416 |
"F114": {
|
| 1417 |
"cells": {
|
| 1418 |
"detection": {
|
| 1419 |
-
"tp":
|
| 1420 |
-
"fp":
|
| 1421 |
-
"fn":
|
| 1422 |
-
"precision": 0.
|
| 1423 |
-
"recall": 0.
|
| 1424 |
-
"f1": 0.
|
| 1425 |
-
"mean_iou_matched": 0.
|
| 1426 |
"iou30": {
|
| 1427 |
-
"tp":
|
| 1428 |
-
"fp":
|
| 1429 |
-
"fn":
|
| 1430 |
-
"precision": 0.
|
| 1431 |
-
"recall": 0.
|
| 1432 |
-
"f1": 0.
|
| 1433 |
},
|
| 1434 |
"centroid": {
|
| 1435 |
-
"tp":
|
| 1436 |
-
"fp":
|
| 1437 |
-
"fn":
|
| 1438 |
-
"precision": 0.
|
| 1439 |
-
"recall": 0.
|
| 1440 |
-
"f1": 0.
|
| 1441 |
}
|
| 1442 |
},
|
| 1443 |
"attribute_accuracy": {
|
| 1444 |
-
"antibody": 0.
|
| 1445 |
-
"nostril": 0.
|
| 1446 |
-
"both": 0.
|
| 1447 |
-
"n_matched":
|
| 1448 |
},
|
| 1449 |
"per_class": {
|
| 1450 |
"Cell, Antibody +": {
|
| 1451 |
-
"tp":
|
| 1452 |
-
"fp":
|
| 1453 |
-
"fn":
|
| 1454 |
-
"precision": 0.
|
| 1455 |
-
"recall": 0.
|
| 1456 |
-
"f1": 0.
|
| 1457 |
"gt_count": 175,
|
| 1458 |
-
"pred_count":
|
| 1459 |
},
|
| 1460 |
"Cell, Antibody -": {
|
| 1461 |
-
"tp":
|
| 1462 |
-
"fp":
|
| 1463 |
-
"fn":
|
| 1464 |
-
"precision": 0.
|
| 1465 |
-
"recall":
|
| 1466 |
-
"f1": 0.
|
| 1467 |
"gt_count": 21,
|
| 1468 |
-
"pred_count":
|
| 1469 |
},
|
| 1470 |
"Cell, Nostril, Antibody +": {
|
| 1471 |
"tp": 36,
|
| 1472 |
-
"fp":
|
| 1473 |
"fn": 6,
|
| 1474 |
-
"precision": 0.
|
| 1475 |
"recall": 0.8571428571428571,
|
| 1476 |
-
"f1": 0.
|
| 1477 |
"gt_count": 42,
|
| 1478 |
-
"pred_count":
|
| 1479 |
},
|
| 1480 |
"Cell, Nostril, Antibody -": {
|
| 1481 |
"tp": 1,
|
|
@@ -1490,14 +1503,14 @@
|
|
| 1490 |
},
|
| 1491 |
"confusion": {
|
| 1492 |
"Cell, Antibody +": {
|
| 1493 |
-
"Cell, Antibody +":
|
| 1494 |
"Cell, Antibody -": 2,
|
| 1495 |
"Cell, Nostril, Antibody +": 5,
|
| 1496 |
"Cell, Nostril, Antibody -": 0
|
| 1497 |
},
|
| 1498 |
"Cell, Antibody -": {
|
| 1499 |
"Cell, Antibody +": 0,
|
| 1500 |
-
"Cell, Antibody -":
|
| 1501 |
"Cell, Nostril, Antibody +": 0,
|
| 1502 |
"Cell, Nostril, Antibody -": 0
|
| 1503 |
},
|
|
@@ -1515,7 +1528,7 @@
|
|
| 1515 |
}
|
| 1516 |
},
|
| 1517 |
"n_gt": 242,
|
| 1518 |
-
"n_pred":
|
| 1519 |
},
|
| 1520 |
"nostrils": {
|
| 1521 |
"detection": {
|
|
@@ -1556,21 +1569,21 @@
|
|
| 1556 |
"counts": {
|
| 1557 |
"Cell, Antibody +": {
|
| 1558 |
"gt": 175,
|
| 1559 |
-
"pred":
|
| 1560 |
-
"abs_err":
|
| 1561 |
-
"rel_err": 0.
|
| 1562 |
},
|
| 1563 |
"Cell, Antibody -": {
|
| 1564 |
"gt": 21,
|
| 1565 |
-
"pred":
|
| 1566 |
-
"abs_err":
|
| 1567 |
-
"rel_err": 0.
|
| 1568 |
},
|
| 1569 |
"Cell, Nostril, Antibody +": {
|
| 1570 |
"gt": 42,
|
| 1571 |
-
"pred":
|
| 1572 |
-
"abs_err":
|
| 1573 |
-
"rel_err": 0.
|
| 1574 |
},
|
| 1575 |
"Cell, Nostril, Antibody -": {
|
| 1576 |
"gt": 4,
|
|
@@ -1594,22 +1607,22 @@
|
|
| 1594 |
"fp_analysis": null,
|
| 1595 |
"pairs": null,
|
| 1596 |
"summary": {
|
| 1597 |
-
"cell_det_f1": 0.
|
| 1598 |
-
"cell_det_precision": 0.
|
| 1599 |
-
"cell_det_recall": 0.
|
| 1600 |
-
"cell_mean_iou": 0.
|
| 1601 |
-
"cell_det_f1_iou30": 0.
|
| 1602 |
-
"cell_det_f1_centroid": 0.
|
| 1603 |
-
"cell_attr_antibody": 0.
|
| 1604 |
-
"cell_attr_nostril": 0.
|
| 1605 |
-
"cell_attr_both": 0.
|
| 1606 |
"nos_det_f1": 0.8252427184466019,
|
| 1607 |
"nos_det_precision": 0.7327586206896551,
|
| 1608 |
"nos_det_recall": 0.9444444444444444,
|
| 1609 |
"nos_type_acc": 1.0,
|
| 1610 |
-
"f1[Cell, Antibody +]": 0.
|
| 1611 |
-
"f1[Cell, Antibody -]": 0.
|
| 1612 |
-
"f1[Cell, Nostril, Antibody +]": 0.
|
| 1613 |
"f1[Cell, Nostril, Antibody -]": 0.4,
|
| 1614 |
"f1[Nostril in Nucleus]": 0.8648648648648649,
|
| 1615 |
"f1[Nostril External of Nucleus]": 0.7789473684210527
|
|
@@ -1618,56 +1631,56 @@
|
|
| 1618 |
"F99": {
|
| 1619 |
"cells": {
|
| 1620 |
"detection": {
|
| 1621 |
-
"tp":
|
| 1622 |
-
"fp":
|
| 1623 |
-
"fn":
|
| 1624 |
-
"precision": 0.
|
| 1625 |
-
"recall": 0.
|
| 1626 |
-
"f1": 0.
|
| 1627 |
-
"mean_iou_matched": 0.
|
| 1628 |
"iou30": {
|
| 1629 |
-
"tp":
|
| 1630 |
-
"fp":
|
| 1631 |
-
"fn":
|
| 1632 |
-
"precision": 0.
|
| 1633 |
-
"recall": 0.
|
| 1634 |
-
"f1": 0.
|
| 1635 |
},
|
| 1636 |
"centroid": {
|
| 1637 |
-
"tp":
|
| 1638 |
-
"fp":
|
| 1639 |
-
"fn":
|
| 1640 |
-
"precision": 0.
|
| 1641 |
-
"recall": 0.
|
| 1642 |
-
"f1": 0.
|
| 1643 |
}
|
| 1644 |
},
|
| 1645 |
"attribute_accuracy": {
|
| 1646 |
-
"antibody": 0.
|
| 1647 |
-
"nostril": 0.
|
| 1648 |
-
"both": 0.
|
| 1649 |
-
"n_matched":
|
| 1650 |
},
|
| 1651 |
"per_class": {
|
| 1652 |
"Cell, Antibody +": {
|
| 1653 |
-
"tp":
|
| 1654 |
-
"fp":
|
| 1655 |
-
"fn":
|
| 1656 |
-
"precision": 0.
|
| 1657 |
-
"recall": 0.
|
| 1658 |
-
"f1": 0.
|
| 1659 |
"gt_count": 183,
|
| 1660 |
-
"pred_count":
|
| 1661 |
},
|
| 1662 |
"Cell, Antibody -": {
|
| 1663 |
-
"tp":
|
| 1664 |
-
"fp":
|
| 1665 |
-
"fn":
|
| 1666 |
-
"precision": 0.
|
| 1667 |
-
"recall": 0.
|
| 1668 |
-
"f1": 0.
|
| 1669 |
"gt_count": 62,
|
| 1670 |
-
"pred_count":
|
| 1671 |
},
|
| 1672 |
"Cell, Nostril, Antibody +": {
|
| 1673 |
"tp": 4,
|
|
@@ -1692,14 +1705,14 @@
|
|
| 1692 |
},
|
| 1693 |
"confusion": {
|
| 1694 |
"Cell, Antibody +": {
|
| 1695 |
-
"Cell, Antibody +":
|
| 1696 |
"Cell, Antibody -": 4,
|
| 1697 |
"Cell, Nostril, Antibody +": 0,
|
| 1698 |
"Cell, Nostril, Antibody -": 0
|
| 1699 |
},
|
| 1700 |
"Cell, Antibody -": {
|
| 1701 |
"Cell, Antibody +": 1,
|
| 1702 |
-
"Cell, Antibody -":
|
| 1703 |
"Cell, Nostril, Antibody +": 0,
|
| 1704 |
"Cell, Nostril, Antibody -": 0
|
| 1705 |
},
|
|
@@ -1717,7 +1730,7 @@
|
|
| 1717 |
}
|
| 1718 |
},
|
| 1719 |
"n_gt": 251,
|
| 1720 |
-
"n_pred":
|
| 1721 |
},
|
| 1722 |
"nostrils": {
|
| 1723 |
"detection": {
|
|
@@ -1758,15 +1771,15 @@
|
|
| 1758 |
"counts": {
|
| 1759 |
"Cell, Antibody +": {
|
| 1760 |
"gt": 183,
|
| 1761 |
-
"pred":
|
| 1762 |
-
"abs_err":
|
| 1763 |
-
"rel_err": 0.
|
| 1764 |
},
|
| 1765 |
"Cell, Antibody -": {
|
| 1766 |
"gt": 62,
|
| 1767 |
-
"pred":
|
| 1768 |
-
"abs_err":
|
| 1769 |
-
"rel_err": 0.
|
| 1770 |
},
|
| 1771 |
"Cell, Nostril, Antibody +": {
|
| 1772 |
"gt": 6,
|
|
@@ -1796,21 +1809,21 @@
|
|
| 1796 |
"fp_analysis": null,
|
| 1797 |
"pairs": null,
|
| 1798 |
"summary": {
|
| 1799 |
-
"cell_det_f1": 0.
|
| 1800 |
-
"cell_det_precision": 0.
|
| 1801 |
-
"cell_det_recall": 0.
|
| 1802 |
-
"cell_mean_iou": 0.
|
| 1803 |
-
"cell_det_f1_iou30": 0.
|
| 1804 |
-
"cell_det_f1_centroid": 0.
|
| 1805 |
-
"cell_attr_antibody": 0.
|
| 1806 |
-
"cell_attr_nostril": 0.
|
| 1807 |
-
"cell_attr_both": 0.
|
| 1808 |
"nos_det_f1": 0.9090909090909091,
|
| 1809 |
"nos_det_precision": 0.9090909090909091,
|
| 1810 |
"nos_det_recall": 0.9090909090909091,
|
| 1811 |
"nos_type_acc": 1.0,
|
| 1812 |
-
"f1[Cell, Antibody +]": 0.
|
| 1813 |
-
"f1[Cell, Antibody -]": 0.
|
| 1814 |
"f1[Cell, Nostril, Antibody +]": 0.8,
|
| 1815 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1816 |
"f1[Nostril in Nucleus]": 0.8,
|
|
|
|
| 1 |
{
|
| 2 |
+
"post_config": {
|
| 3 |
+
"cell_fg_thr": 0.5,
|
| 4 |
+
"marker_thr": 0.5,
|
| 5 |
+
"min_marker_area": 12,
|
| 6 |
+
"min_cell_area": 50,
|
| 7 |
+
"min_peak_dist": 0.64,
|
| 8 |
+
"nos_fg_thr": 0.5,
|
| 9 |
+
"min_nos_area": 3,
|
| 10 |
+
"antibody_thr": 0.5,
|
| 11 |
+
"cellnos_thr": 0.5,
|
| 12 |
+
"nostril_rule": "head",
|
| 13 |
+
"cellnos_rule": "contains"
|
| 14 |
+
},
|
| 15 |
"C100": {
|
| 16 |
"cells": {
|
| 17 |
"detection": {
|
| 18 |
+
"tp": 171,
|
| 19 |
+
"fp": 14,
|
| 20 |
+
"fn": 7,
|
| 21 |
+
"precision": 0.9243243243243243,
|
| 22 |
+
"recall": 0.9606741573033708,
|
| 23 |
+
"f1": 0.9421487603305785,
|
| 24 |
+
"mean_iou_matched": 0.7972938750523493,
|
| 25 |
"iou30": {
|
| 26 |
+
"tp": 175,
|
| 27 |
+
"fp": 10,
|
| 28 |
+
"fn": 3,
|
| 29 |
+
"precision": 0.9459459459459459,
|
| 30 |
+
"recall": 0.9831460674157303,
|
| 31 |
+
"f1": 0.9641873278236914
|
| 32 |
},
|
| 33 |
"centroid": {
|
| 34 |
+
"tp": 175,
|
| 35 |
+
"fp": 10,
|
| 36 |
+
"fn": 3,
|
| 37 |
+
"precision": 0.9459459459459459,
|
| 38 |
+
"recall": 0.9831460674157303,
|
| 39 |
+
"f1": 0.9641873278236914
|
| 40 |
}
|
| 41 |
},
|
| 42 |
"attribute_accuracy": {
|
| 43 |
+
"antibody": 0.9941520467836257,
|
| 44 |
+
"nostril": 0.9941520467836257,
|
| 45 |
+
"both": 0.9883040935672515,
|
| 46 |
+
"n_matched": 171
|
| 47 |
},
|
| 48 |
"per_class": {
|
| 49 |
"Cell, Antibody +": {
|
| 50 |
+
"tp": 157,
|
| 51 |
+
"fp": 13,
|
| 52 |
+
"fn": 8,
|
| 53 |
+
"precision": 0.9235294117647059,
|
| 54 |
+
"recall": 0.9515151515151515,
|
| 55 |
+
"f1": 0.9373134328358209,
|
| 56 |
"gt_count": 165,
|
| 57 |
+
"pred_count": 170
|
| 58 |
},
|
| 59 |
"Cell, Antibody -": {
|
| 60 |
"tp": 0,
|
| 61 |
+
"fp": 3,
|
| 62 |
"fn": 0,
|
| 63 |
"precision": 0.0,
|
| 64 |
"recall": 0.0,
|
| 65 |
"f1": 0.0,
|
| 66 |
"gt_count": 0,
|
| 67 |
+
"pred_count": 3
|
| 68 |
},
|
| 69 |
"Cell, Nostril, Antibody +": {
|
| 70 |
"tp": 12,
|
|
|
|
| 89 |
},
|
| 90 |
"confusion": {
|
| 91 |
"Cell, Antibody +": {
|
| 92 |
+
"Cell, Antibody +": 157,
|
| 93 |
+
"Cell, Antibody -": 1,
|
| 94 |
"Cell, Nostril, Antibody +": 0,
|
| 95 |
"Cell, Nostril, Antibody -": 0
|
| 96 |
},
|
|
|
|
| 114 |
}
|
| 115 |
},
|
| 116 |
"n_gt": 178,
|
| 117 |
+
"n_pred": 185
|
| 118 |
},
|
| 119 |
"nostrils": {
|
| 120 |
"detection": {
|
|
|
|
| 155 |
"counts": {
|
| 156 |
"Cell, Antibody +": {
|
| 157 |
"gt": 165,
|
| 158 |
+
"pred": 170,
|
| 159 |
+
"abs_err": 5,
|
| 160 |
+
"rel_err": 0.030303030303030304
|
| 161 |
},
|
| 162 |
"Cell, Antibody -": {
|
| 163 |
"gt": 0,
|
| 164 |
+
"pred": 3,
|
| 165 |
+
"abs_err": 3,
|
| 166 |
"rel_err": Infinity
|
| 167 |
},
|
| 168 |
"Cell, Nostril, Antibody +": {
|
|
|
|
| 193 |
"fp_analysis": null,
|
| 194 |
"pairs": null,
|
| 195 |
"summary": {
|
| 196 |
+
"cell_det_f1": 0.9421487603305785,
|
| 197 |
+
"cell_det_precision": 0.9243243243243243,
|
| 198 |
+
"cell_det_recall": 0.9606741573033708,
|
| 199 |
+
"cell_mean_iou": 0.7972938750523493,
|
| 200 |
+
"cell_det_f1_iou30": 0.9641873278236914,
|
| 201 |
+
"cell_det_f1_centroid": 0.9641873278236914,
|
| 202 |
+
"cell_attr_antibody": 0.9941520467836257,
|
| 203 |
+
"cell_attr_nostril": 0.9941520467836257,
|
| 204 |
+
"cell_attr_both": 0.9883040935672515,
|
| 205 |
"nos_det_f1": 0.8000000000000002,
|
| 206 |
"nos_det_precision": 0.8,
|
| 207 |
"nos_det_recall": 0.8,
|
| 208 |
"nos_type_acc": 1.0,
|
| 209 |
+
"f1[Cell, Antibody +]": 0.9373134328358209,
|
| 210 |
"f1[Cell, Antibody -]": 0.0,
|
| 211 |
"f1[Cell, Nostril, Antibody +]": 0.9600000000000001,
|
| 212 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
|
|
|
| 218 |
"cells": {
|
| 219 |
"detection": {
|
| 220 |
"tp": 91,
|
| 221 |
+
"fp": 10,
|
| 222 |
"fn": 0,
|
| 223 |
+
"precision": 0.900990099009901,
|
| 224 |
"recall": 1.0,
|
| 225 |
+
"f1": 0.9479166666666667,
|
| 226 |
"mean_iou_matched": 0.8036863197012898,
|
| 227 |
"iou30": {
|
| 228 |
"tp": 91,
|
| 229 |
+
"fp": 10,
|
| 230 |
"fn": 0,
|
| 231 |
+
"precision": 0.900990099009901,
|
| 232 |
"recall": 1.0,
|
| 233 |
+
"f1": 0.9479166666666667
|
| 234 |
},
|
| 235 |
"centroid": {
|
| 236 |
"tp": 91,
|
| 237 |
+
"fp": 10,
|
| 238 |
"fn": 0,
|
| 239 |
+
"precision": 0.900990099009901,
|
| 240 |
"recall": 1.0,
|
| 241 |
+
"f1": 0.9479166666666667
|
| 242 |
}
|
| 243 |
},
|
| 244 |
"attribute_accuracy": {
|
|
|
|
| 250 |
"per_class": {
|
| 251 |
"Cell, Antibody +": {
|
| 252 |
"tp": 41,
|
| 253 |
+
"fp": 13,
|
| 254 |
"fn": 0,
|
| 255 |
+
"precision": 0.7592592592592593,
|
| 256 |
"recall": 1.0,
|
| 257 |
+
"f1": 0.8631578947368421,
|
| 258 |
"gt_count": 41,
|
| 259 |
+
"pred_count": 54
|
| 260 |
},
|
| 261 |
"Cell, Antibody -": {
|
| 262 |
"tp": 0,
|
| 263 |
+
"fp": 0,
|
| 264 |
"fn": 0,
|
| 265 |
"precision": 0.0,
|
| 266 |
"recall": 0.0,
|
| 267 |
"f1": 0.0,
|
| 268 |
"gt_count": 0,
|
| 269 |
+
"pred_count": 0
|
| 270 |
},
|
| 271 |
"Cell, Nostril, Antibody +": {
|
| 272 |
"tp": 45,
|
| 273 |
+
"fp": 2,
|
| 274 |
"fn": 5,
|
| 275 |
+
"precision": 0.9574468085106383,
|
| 276 |
"recall": 0.9,
|
| 277 |
+
"f1": 0.9278350515463918,
|
| 278 |
"gt_count": 50,
|
| 279 |
+
"pred_count": 47
|
| 280 |
},
|
| 281 |
"Cell, Nostril, Antibody -": {
|
| 282 |
"tp": 0,
|
|
|
|
| 316 |
}
|
| 317 |
},
|
| 318 |
"n_gt": 91,
|
| 319 |
+
"n_pred": 101
|
| 320 |
},
|
| 321 |
"nostrils": {
|
| 322 |
"detection": {
|
|
|
|
| 357 |
"counts": {
|
| 358 |
"Cell, Antibody +": {
|
| 359 |
"gt": 41,
|
| 360 |
+
"pred": 54,
|
| 361 |
+
"abs_err": 13,
|
| 362 |
+
"rel_err": 0.3170731707317073
|
| 363 |
},
|
| 364 |
"Cell, Antibody -": {
|
| 365 |
"gt": 0,
|
| 366 |
+
"pred": 0,
|
| 367 |
+
"abs_err": 0,
|
| 368 |
+
"rel_err": 0.0
|
| 369 |
},
|
| 370 |
"Cell, Nostril, Antibody +": {
|
| 371 |
"gt": 50,
|
| 372 |
+
"pred": 47,
|
| 373 |
+
"abs_err": 3,
|
| 374 |
+
"rel_err": 0.06
|
| 375 |
},
|
| 376 |
"Cell, Nostril, Antibody -": {
|
| 377 |
"gt": 0,
|
|
|
|
| 395 |
"fp_analysis": null,
|
| 396 |
"pairs": null,
|
| 397 |
"summary": {
|
| 398 |
+
"cell_det_f1": 0.9479166666666667,
|
| 399 |
+
"cell_det_precision": 0.900990099009901,
|
| 400 |
"cell_det_recall": 1.0,
|
| 401 |
"cell_mean_iou": 0.8036863197012898,
|
| 402 |
+
"cell_det_f1_iou30": 0.9479166666666667,
|
| 403 |
+
"cell_det_f1_centroid": 0.9479166666666667,
|
| 404 |
"cell_attr_antibody": 1.0,
|
| 405 |
"cell_attr_nostril": 0.945054945054945,
|
| 406 |
"cell_attr_both": 0.945054945054945,
|
|
|
|
| 408 |
"nos_det_precision": 0.6910112359550562,
|
| 409 |
"nos_det_recall": 0.917910447761194,
|
| 410 |
"nos_type_acc": 0.991869918699187,
|
| 411 |
+
"f1[Cell, Antibody +]": 0.8631578947368421,
|
| 412 |
"f1[Cell, Antibody -]": 0.0,
|
| 413 |
+
"f1[Cell, Nostril, Antibody +]": 0.9278350515463918,
|
| 414 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 415 |
"f1[Nostril in Nucleus]": 0.8503937007874016,
|
| 416 |
"f1[Nostril External of Nucleus]": 0.7351351351351352
|
|
|
|
| 419 |
"C110": {
|
| 420 |
"cells": {
|
| 421 |
"detection": {
|
| 422 |
+
"tp": 167,
|
| 423 |
+
"fp": 18,
|
| 424 |
+
"fn": 17,
|
| 425 |
+
"precision": 0.9027027027027027,
|
| 426 |
+
"recall": 0.907608695652174,
|
| 427 |
+
"f1": 0.9051490514905148,
|
| 428 |
+
"mean_iou_matched": 0.7834847507494777,
|
| 429 |
"iou30": {
|
| 430 |
+
"tp": 174,
|
| 431 |
+
"fp": 11,
|
| 432 |
+
"fn": 10,
|
| 433 |
+
"precision": 0.9405405405405406,
|
| 434 |
+
"recall": 0.9456521739130435,
|
| 435 |
+
"f1": 0.9430894308943089
|
| 436 |
},
|
| 437 |
"centroid": {
|
| 438 |
+
"tp": 175,
|
| 439 |
+
"fp": 10,
|
| 440 |
+
"fn": 9,
|
| 441 |
+
"precision": 0.9459459459459459,
|
| 442 |
+
"recall": 0.9510869565217391,
|
| 443 |
+
"f1": 0.948509485094851
|
| 444 |
}
|
| 445 |
},
|
| 446 |
"attribute_accuracy": {
|
| 447 |
+
"antibody": 0.9940119760479041,
|
| 448 |
+
"nostril": 0.9700598802395209,
|
| 449 |
+
"both": 0.9640718562874252,
|
| 450 |
+
"n_matched": 167
|
| 451 |
},
|
| 452 |
"per_class": {
|
| 453 |
"Cell, Antibody +": {
|
| 454 |
"tp": 52,
|
| 455 |
+
"fp": 12,
|
| 456 |
"fn": 9,
|
| 457 |
+
"precision": 0.8125,
|
| 458 |
"recall": 0.8524590163934426,
|
| 459 |
+
"f1": 0.8319999999999999,
|
| 460 |
"gt_count": 61,
|
| 461 |
+
"pred_count": 64
|
| 462 |
},
|
| 463 |
"Cell, Antibody -": {
|
| 464 |
"tp": 1,
|
|
|
|
| 471 |
"pred_count": 2
|
| 472 |
},
|
| 473 |
"Cell, Nostril, Antibody +": {
|
| 474 |
+
"tp": 108,
|
| 475 |
+
"fp": 11,
|
| 476 |
+
"fn": 14,
|
| 477 |
+
"precision": 0.907563025210084,
|
| 478 |
+
"recall": 0.8852459016393442,
|
| 479 |
+
"f1": 0.8962655601659751,
|
| 480 |
"gt_count": 122,
|
| 481 |
+
"pred_count": 119
|
| 482 |
},
|
| 483 |
"Cell, Nostril, Antibody -": {
|
| 484 |
"tp": 0,
|
|
|
|
| 507 |
"Cell, Nostril, Antibody +": {
|
| 508 |
"Cell, Antibody +": 3,
|
| 509 |
"Cell, Antibody -": 0,
|
| 510 |
+
"Cell, Nostril, Antibody +": 108,
|
| 511 |
"Cell, Nostril, Antibody -": 0
|
| 512 |
},
|
| 513 |
"Cell, Nostril, Antibody -": {
|
|
|
|
| 518 |
}
|
| 519 |
},
|
| 520 |
"n_gt": 184,
|
| 521 |
+
"n_pred": 185
|
| 522 |
},
|
| 523 |
"nostrils": {
|
| 524 |
"detection": {
|
|
|
|
| 559 |
"counts": {
|
| 560 |
"Cell, Antibody +": {
|
| 561 |
"gt": 61,
|
| 562 |
+
"pred": 64,
|
| 563 |
+
"abs_err": 3,
|
| 564 |
+
"rel_err": 0.04918032786885246
|
| 565 |
},
|
| 566 |
"Cell, Antibody -": {
|
| 567 |
"gt": 1,
|
|
|
|
| 571 |
},
|
| 572 |
"Cell, Nostril, Antibody +": {
|
| 573 |
"gt": 122,
|
| 574 |
+
"pred": 119,
|
| 575 |
"abs_err": 3,
|
| 576 |
"rel_err": 0.02459016393442623
|
| 577 |
},
|
|
|
|
| 597 |
"fp_analysis": null,
|
| 598 |
"pairs": null,
|
| 599 |
"summary": {
|
| 600 |
+
"cell_det_f1": 0.9051490514905148,
|
| 601 |
+
"cell_det_precision": 0.9027027027027027,
|
| 602 |
+
"cell_det_recall": 0.907608695652174,
|
| 603 |
+
"cell_mean_iou": 0.7834847507494777,
|
| 604 |
+
"cell_det_f1_iou30": 0.9430894308943089,
|
| 605 |
+
"cell_det_f1_centroid": 0.948509485094851,
|
| 606 |
+
"cell_attr_antibody": 0.9940119760479041,
|
| 607 |
+
"cell_attr_nostril": 0.9700598802395209,
|
| 608 |
+
"cell_attr_both": 0.9640718562874252,
|
| 609 |
"nos_det_f1": 0.8391777509068925,
|
| 610 |
"nos_det_precision": 0.7694013303769401,
|
| 611 |
"nos_det_recall": 0.9228723404255319,
|
| 612 |
"nos_type_acc": 0.9740634005763689,
|
| 613 |
+
"f1[Cell, Antibody +]": 0.8319999999999999,
|
| 614 |
"f1[Cell, Antibody -]": 0.6666666666666666,
|
| 615 |
+
"f1[Cell, Nostril, Antibody +]": 0.8962655601659751,
|
| 616 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 617 |
"f1[Nostril in Nucleus]": 0.8324022346368716,
|
| 618 |
"f1[Nostril External of Nucleus]": 0.8059701492537313
|
|
|
|
| 621 |
"C112": {
|
| 622 |
"cells": {
|
| 623 |
"detection": {
|
| 624 |
+
"tp": 128,
|
| 625 |
+
"fp": 28,
|
| 626 |
+
"fn": 18,
|
| 627 |
+
"precision": 0.8205128205128205,
|
| 628 |
+
"recall": 0.8767123287671232,
|
| 629 |
+
"f1": 0.847682119205298,
|
| 630 |
+
"mean_iou_matched": 0.7399381730547632,
|
| 631 |
"iou30": {
|
| 632 |
+
"tp": 137,
|
| 633 |
+
"fp": 19,
|
| 634 |
+
"fn": 9,
|
| 635 |
+
"precision": 0.8782051282051282,
|
| 636 |
+
"recall": 0.9383561643835616,
|
| 637 |
+
"f1": 0.9072847682119205
|
| 638 |
},
|
| 639 |
"centroid": {
|
| 640 |
+
"tp": 138,
|
| 641 |
+
"fp": 18,
|
| 642 |
+
"fn": 8,
|
| 643 |
+
"precision": 0.8846153846153846,
|
| 644 |
+
"recall": 0.9452054794520548,
|
| 645 |
+
"f1": 0.9139072847682119
|
| 646 |
}
|
| 647 |
},
|
| 648 |
"attribute_accuracy": {
|
| 649 |
"antibody": 1.0,
|
| 650 |
+
"nostril": 0.9921875,
|
| 651 |
+
"both": 0.9921875,
|
| 652 |
+
"n_matched": 128
|
| 653 |
},
|
| 654 |
"per_class": {
|
| 655 |
"Cell, Antibody +": {
|
| 656 |
+
"tp": 107,
|
| 657 |
+
"fp": 24,
|
| 658 |
+
"fn": 17,
|
| 659 |
+
"precision": 0.816793893129771,
|
| 660 |
+
"recall": 0.8629032258064516,
|
| 661 |
+
"f1": 0.8392156862745098,
|
| 662 |
"gt_count": 124,
|
| 663 |
+
"pred_count": 131
|
| 664 |
},
|
| 665 |
"Cell, Antibody -": {
|
| 666 |
"tp": 5,
|
| 667 |
+
"fp": 0,
|
| 668 |
"fn": 0,
|
| 669 |
+
"precision": 1.0,
|
| 670 |
"recall": 1.0,
|
| 671 |
+
"f1": 1.0,
|
| 672 |
"gt_count": 5,
|
| 673 |
+
"pred_count": 5
|
| 674 |
},
|
| 675 |
"Cell, Nostril, Antibody +": {
|
| 676 |
"tp": 15,
|
| 677 |
+
"fp": 5,
|
| 678 |
"fn": 2,
|
| 679 |
+
"precision": 0.75,
|
| 680 |
"recall": 0.8823529411764706,
|
| 681 |
+
"f1": 0.8108108108108107,
|
| 682 |
"gt_count": 17,
|
| 683 |
+
"pred_count": 20
|
| 684 |
},
|
| 685 |
"Cell, Nostril, Antibody -": {
|
| 686 |
"tp": 0,
|
|
|
|
| 695 |
},
|
| 696 |
"confusion": {
|
| 697 |
"Cell, Antibody +": {
|
| 698 |
+
"Cell, Antibody +": 107,
|
| 699 |
"Cell, Antibody -": 0,
|
| 700 |
"Cell, Nostril, Antibody +": 1,
|
| 701 |
"Cell, Nostril, Antibody -": 0
|
|
|
|
| 720 |
}
|
| 721 |
},
|
| 722 |
"n_gt": 146,
|
| 723 |
+
"n_pred": 156
|
| 724 |
},
|
| 725 |
"nostrils": {
|
| 726 |
"detection": {
|
|
|
|
| 761 |
"counts": {
|
| 762 |
"Cell, Antibody +": {
|
| 763 |
"gt": 124,
|
| 764 |
+
"pred": 131,
|
| 765 |
+
"abs_err": 7,
|
| 766 |
+
"rel_err": 0.056451612903225805
|
| 767 |
},
|
| 768 |
"Cell, Antibody -": {
|
| 769 |
"gt": 5,
|
| 770 |
+
"pred": 5,
|
| 771 |
+
"abs_err": 0,
|
| 772 |
+
"rel_err": 0.0
|
| 773 |
},
|
| 774 |
"Cell, Nostril, Antibody +": {
|
| 775 |
"gt": 17,
|
| 776 |
+
"pred": 20,
|
| 777 |
+
"abs_err": 3,
|
| 778 |
+
"rel_err": 0.17647058823529413
|
| 779 |
},
|
| 780 |
"Cell, Nostril, Antibody -": {
|
| 781 |
"gt": 0,
|
|
|
|
| 799 |
"fp_analysis": null,
|
| 800 |
"pairs": null,
|
| 801 |
"summary": {
|
| 802 |
+
"cell_det_f1": 0.847682119205298,
|
| 803 |
+
"cell_det_precision": 0.8205128205128205,
|
| 804 |
+
"cell_det_recall": 0.8767123287671232,
|
| 805 |
+
"cell_mean_iou": 0.7399381730547632,
|
| 806 |
+
"cell_det_f1_iou30": 0.9072847682119205,
|
| 807 |
+
"cell_det_f1_centroid": 0.9139072847682119,
|
| 808 |
"cell_attr_antibody": 1.0,
|
| 809 |
+
"cell_attr_nostril": 0.9921875,
|
| 810 |
+
"cell_attr_both": 0.9921875,
|
| 811 |
"nos_det_f1": 0.819672131147541,
|
| 812 |
"nos_det_precision": 0.6944444444444444,
|
| 813 |
"nos_det_recall": 1.0,
|
| 814 |
"nos_type_acc": 1.0,
|
| 815 |
+
"f1[Cell, Antibody +]": 0.8392156862745098,
|
| 816 |
+
"f1[Cell, Antibody -]": 1.0,
|
| 817 |
+
"f1[Cell, Nostril, Antibody +]": 0.8108108108108107,
|
| 818 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 819 |
"f1[Nostril in Nucleus]": 0.92,
|
| 820 |
"f1[Nostril External of Nucleus]": 0.3636363636363636
|
|
|
|
| 824 |
"cells": {
|
| 825 |
"detection": {
|
| 826 |
"tp": 172,
|
| 827 |
+
"fp": 24,
|
| 828 |
"fn": 14,
|
| 829 |
+
"precision": 0.8775510204081632,
|
| 830 |
"recall": 0.9247311827956989,
|
| 831 |
+
"f1": 0.900523560209424,
|
| 832 |
"mean_iou_matched": 0.7905866698793166,
|
| 833 |
"iou30": {
|
| 834 |
+
"tp": 181,
|
| 835 |
+
"fp": 15,
|
| 836 |
+
"fn": 5,
|
| 837 |
+
"precision": 0.923469387755102,
|
| 838 |
+
"recall": 0.9731182795698925,
|
| 839 |
+
"f1": 0.9476439790575916
|
| 840 |
},
|
| 841 |
"centroid": {
|
| 842 |
+
"tp": 179,
|
| 843 |
+
"fp": 17,
|
| 844 |
+
"fn": 7,
|
| 845 |
+
"precision": 0.9132653061224489,
|
| 846 |
+
"recall": 0.9623655913978495,
|
| 847 |
+
"f1": 0.9371727748691099
|
| 848 |
}
|
| 849 |
},
|
| 850 |
"attribute_accuracy": {
|
|
|
|
| 856 |
"per_class": {
|
| 857 |
"Cell, Antibody +": {
|
| 858 |
"tp": 80,
|
| 859 |
+
"fp": 21,
|
| 860 |
"fn": 7,
|
| 861 |
+
"precision": 0.7920792079207921,
|
| 862 |
"recall": 0.9195402298850575,
|
| 863 |
+
"f1": 0.851063829787234,
|
| 864 |
"gt_count": 87,
|
| 865 |
+
"pred_count": 101
|
| 866 |
},
|
| 867 |
"Cell, Antibody -": {
|
| 868 |
"tp": 5,
|
| 869 |
+
"fp": 5,
|
| 870 |
"fn": 1,
|
| 871 |
+
"precision": 0.5,
|
| 872 |
"recall": 0.8333333333333334,
|
| 873 |
+
"f1": 0.625,
|
| 874 |
"gt_count": 6,
|
| 875 |
+
"pred_count": 10
|
| 876 |
},
|
| 877 |
"Cell, Nostril, Antibody +": {
|
| 878 |
"tp": 78,
|
|
|
|
| 922 |
}
|
| 923 |
},
|
| 924 |
"n_gt": 186,
|
| 925 |
+
"n_pred": 196
|
| 926 |
},
|
| 927 |
"nostrils": {
|
| 928 |
"detection": {
|
|
|
|
| 963 |
"counts": {
|
| 964 |
"Cell, Antibody +": {
|
| 965 |
"gt": 87,
|
| 966 |
+
"pred": 101,
|
| 967 |
+
"abs_err": 14,
|
| 968 |
+
"rel_err": 0.16091954022988506
|
| 969 |
},
|
| 970 |
"Cell, Antibody -": {
|
| 971 |
"gt": 6,
|
| 972 |
+
"pred": 10,
|
| 973 |
+
"abs_err": 4,
|
| 974 |
+
"rel_err": 0.6666666666666666
|
| 975 |
},
|
| 976 |
"Cell, Nostril, Antibody +": {
|
| 977 |
"gt": 93,
|
|
|
|
| 1001 |
"fp_analysis": null,
|
| 1002 |
"pairs": null,
|
| 1003 |
"summary": {
|
| 1004 |
+
"cell_det_f1": 0.900523560209424,
|
| 1005 |
+
"cell_det_precision": 0.8775510204081632,
|
| 1006 |
"cell_det_recall": 0.9247311827956989,
|
| 1007 |
"cell_mean_iou": 0.7905866698793166,
|
| 1008 |
+
"cell_det_f1_iou30": 0.9476439790575916,
|
| 1009 |
+
"cell_det_f1_centroid": 0.9371727748691099,
|
| 1010 |
"cell_attr_antibody": 0.9941860465116279,
|
| 1011 |
"cell_attr_nostril": 0.9534883720930233,
|
| 1012 |
"cell_attr_both": 0.9476744186046512,
|
|
|
|
| 1014 |
"nos_det_precision": 0.9171974522292994,
|
| 1015 |
"nos_det_recall": 0.8888888888888888,
|
| 1016 |
"nos_type_acc": 0.9930555555555556,
|
| 1017 |
+
"f1[Cell, Antibody +]": 0.851063829787234,
|
| 1018 |
+
"f1[Cell, Antibody -]": 0.625,
|
| 1019 |
"f1[Cell, Nostril, Antibody +]": 0.8764044943820225,
|
| 1020 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1021 |
"f1[Nostril in Nucleus]": 0.8803418803418803,
|
|
|
|
| 1025 |
"F110": {
|
| 1026 |
"cells": {
|
| 1027 |
"detection": {
|
| 1028 |
+
"tp": 119,
|
| 1029 |
+
"fp": 12,
|
| 1030 |
+
"fn": 9,
|
| 1031 |
+
"precision": 0.9083969465648855,
|
| 1032 |
+
"recall": 0.9296875,
|
| 1033 |
+
"f1": 0.918918918918919,
|
| 1034 |
+
"mean_iou_matched": 0.79252398616283,
|
| 1035 |
"iou30": {
|
| 1036 |
+
"tp": 122,
|
| 1037 |
+
"fp": 9,
|
| 1038 |
+
"fn": 6,
|
| 1039 |
+
"precision": 0.9312977099236641,
|
| 1040 |
+
"recall": 0.953125,
|
| 1041 |
+
"f1": 0.9420849420849421
|
| 1042 |
},
|
| 1043 |
"centroid": {
|
| 1044 |
+
"tp": 123,
|
| 1045 |
+
"fp": 8,
|
| 1046 |
+
"fn": 5,
|
| 1047 |
+
"precision": 0.9389312977099237,
|
| 1048 |
+
"recall": 0.9609375,
|
| 1049 |
+
"f1": 0.9498069498069499
|
| 1050 |
}
|
| 1051 |
},
|
| 1052 |
"attribute_accuracy": {
|
| 1053 |
"antibody": 1.0,
|
| 1054 |
+
"nostril": 0.9747899159663865,
|
| 1055 |
+
"both": 0.9747899159663865,
|
| 1056 |
+
"n_matched": 119
|
| 1057 |
},
|
| 1058 |
"per_class": {
|
| 1059 |
"Cell, Antibody +": {
|
| 1060 |
+
"tp": 83,
|
| 1061 |
+
"fp": 9,
|
| 1062 |
+
"fn": 4,
|
| 1063 |
+
"precision": 0.9021739130434783,
|
| 1064 |
+
"recall": 0.9540229885057471,
|
| 1065 |
+
"f1": 0.9273743016759777,
|
| 1066 |
"gt_count": 87,
|
| 1067 |
+
"pred_count": 92
|
| 1068 |
},
|
| 1069 |
"Cell, Antibody -": {
|
| 1070 |
"tp": 6,
|
| 1071 |
+
"fp": 2,
|
| 1072 |
"fn": 1,
|
| 1073 |
+
"precision": 0.75,
|
| 1074 |
"recall": 0.8571428571428571,
|
| 1075 |
+
"f1": 0.7999999999999999,
|
| 1076 |
"gt_count": 7,
|
| 1077 |
+
"pred_count": 8
|
| 1078 |
},
|
| 1079 |
"Cell, Nostril, Antibody +": {
|
| 1080 |
+
"tp": 27,
|
| 1081 |
+
"fp": 4,
|
| 1082 |
+
"fn": 6,
|
| 1083 |
+
"precision": 0.8709677419354839,
|
| 1084 |
+
"recall": 0.8181818181818182,
|
| 1085 |
+
"f1": 0.84375,
|
| 1086 |
"gt_count": 33,
|
| 1087 |
+
"pred_count": 31
|
| 1088 |
},
|
| 1089 |
"Cell, Nostril, Antibody -": {
|
| 1090 |
"tp": 0,
|
|
|
|
| 1099 |
},
|
| 1100 |
"confusion": {
|
| 1101 |
"Cell, Antibody +": {
|
| 1102 |
+
"Cell, Antibody +": 83,
|
| 1103 |
"Cell, Antibody -": 0,
|
| 1104 |
"Cell, Nostril, Antibody +": 0,
|
| 1105 |
"Cell, Nostril, Antibody -": 0
|
|
|
|
| 1113 |
"Cell, Nostril, Antibody +": {
|
| 1114 |
"Cell, Antibody +": 3,
|
| 1115 |
"Cell, Antibody -": 0,
|
| 1116 |
+
"Cell, Nostril, Antibody +": 27,
|
| 1117 |
"Cell, Nostril, Antibody -": 0
|
| 1118 |
},
|
| 1119 |
"Cell, Nostril, Antibody -": {
|
|
|
|
| 1124 |
}
|
| 1125 |
},
|
| 1126 |
"n_gt": 128,
|
| 1127 |
+
"n_pred": 131
|
| 1128 |
},
|
| 1129 |
"nostrils": {
|
| 1130 |
"detection": {
|
|
|
|
| 1165 |
"counts": {
|
| 1166 |
"Cell, Antibody +": {
|
| 1167 |
"gt": 87,
|
| 1168 |
+
"pred": 92,
|
| 1169 |
+
"abs_err": 5,
|
| 1170 |
+
"rel_err": 0.05747126436781609
|
| 1171 |
},
|
| 1172 |
"Cell, Antibody -": {
|
| 1173 |
"gt": 7,
|
| 1174 |
+
"pred": 8,
|
| 1175 |
+
"abs_err": 1,
|
| 1176 |
+
"rel_err": 0.14285714285714285
|
| 1177 |
},
|
| 1178 |
"Cell, Nostril, Antibody +": {
|
| 1179 |
"gt": 33,
|
| 1180 |
+
"pred": 31,
|
| 1181 |
+
"abs_err": 2,
|
| 1182 |
+
"rel_err": 0.06060606060606061
|
| 1183 |
},
|
| 1184 |
"Cell, Nostril, Antibody -": {
|
| 1185 |
"gt": 1,
|
|
|
|
| 1203 |
"fp_analysis": null,
|
| 1204 |
"pairs": null,
|
| 1205 |
"summary": {
|
| 1206 |
+
"cell_det_f1": 0.918918918918919,
|
| 1207 |
+
"cell_det_precision": 0.9083969465648855,
|
| 1208 |
+
"cell_det_recall": 0.9296875,
|
| 1209 |
+
"cell_mean_iou": 0.79252398616283,
|
| 1210 |
+
"cell_det_f1_iou30": 0.9420849420849421,
|
| 1211 |
+
"cell_det_f1_centroid": 0.9498069498069499,
|
| 1212 |
"cell_attr_antibody": 1.0,
|
| 1213 |
+
"cell_attr_nostril": 0.9747899159663865,
|
| 1214 |
+
"cell_attr_both": 0.9747899159663865,
|
| 1215 |
"nos_det_f1": 0.8864864864864865,
|
| 1216 |
"nos_det_precision": 0.9318181818181818,
|
| 1217 |
"nos_det_recall": 0.845360824742268,
|
| 1218 |
"nos_type_acc": 0.9878048780487805,
|
| 1219 |
+
"f1[Cell, Antibody +]": 0.9273743016759777,
|
| 1220 |
+
"f1[Cell, Antibody -]": 0.7999999999999999,
|
| 1221 |
+
"f1[Cell, Nostril, Antibody +]": 0.84375,
|
| 1222 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1223 |
"f1[Nostril in Nucleus]": 0.8518518518518519,
|
| 1224 |
"f1[Nostril External of Nucleus]": 0.8854961832061069
|
|
|
|
| 1227 |
"F113": {
|
| 1228 |
"cells": {
|
| 1229 |
"detection": {
|
| 1230 |
+
"tp": 135,
|
| 1231 |
+
"fp": 19,
|
| 1232 |
+
"fn": 28,
|
| 1233 |
+
"precision": 0.8766233766233766,
|
| 1234 |
+
"recall": 0.8282208588957055,
|
| 1235 |
+
"f1": 0.8517350157728707,
|
| 1236 |
+
"mean_iou_matched": 0.7577631927559012,
|
| 1237 |
"iou30": {
|
| 1238 |
+
"tp": 148,
|
| 1239 |
+
"fp": 6,
|
| 1240 |
+
"fn": 15,
|
| 1241 |
+
"precision": 0.961038961038961,
|
| 1242 |
+
"recall": 0.9079754601226994,
|
| 1243 |
+
"f1": 0.9337539432176657
|
| 1244 |
},
|
| 1245 |
"centroid": {
|
| 1246 |
+
"tp": 146,
|
| 1247 |
+
"fp": 8,
|
| 1248 |
+
"fn": 17,
|
| 1249 |
+
"precision": 0.948051948051948,
|
| 1250 |
+
"recall": 0.8957055214723927,
|
| 1251 |
+
"f1": 0.9211356466876971
|
| 1252 |
}
|
| 1253 |
},
|
| 1254 |
"attribute_accuracy": {
|
| 1255 |
"antibody": 1.0,
|
| 1256 |
+
"nostril": 0.9777777777777777,
|
| 1257 |
+
"both": 0.9777777777777777,
|
| 1258 |
+
"n_matched": 135
|
| 1259 |
},
|
| 1260 |
"per_class": {
|
| 1261 |
"Cell, Antibody +": {
|
| 1262 |
+
"tp": 113,
|
| 1263 |
+
"fp": 19,
|
| 1264 |
+
"fn": 25,
|
| 1265 |
+
"precision": 0.8560606060606061,
|
| 1266 |
+
"recall": 0.8188405797101449,
|
| 1267 |
+
"f1": 0.837037037037037,
|
| 1268 |
"gt_count": 138,
|
| 1269 |
+
"pred_count": 132
|
| 1270 |
},
|
| 1271 |
"Cell, Antibody -": {
|
| 1272 |
"tp": 2,
|
|
|
|
| 1279 |
"pred_count": 3
|
| 1280 |
},
|
| 1281 |
"Cell, Nostril, Antibody +": {
|
| 1282 |
+
"tp": 17,
|
| 1283 |
+
"fp": 2,
|
| 1284 |
+
"fn": 5,
|
| 1285 |
+
"precision": 0.8947368421052632,
|
| 1286 |
+
"recall": 0.7727272727272727,
|
| 1287 |
+
"f1": 0.8292682926829269,
|
| 1288 |
"gt_count": 22,
|
| 1289 |
+
"pred_count": 19
|
| 1290 |
},
|
| 1291 |
"Cell, Nostril, Antibody -": {
|
| 1292 |
"tp": 0,
|
|
|
|
| 1301 |
},
|
| 1302 |
"confusion": {
|
| 1303 |
"Cell, Antibody +": {
|
| 1304 |
+
"Cell, Antibody +": 113,
|
| 1305 |
"Cell, Antibody -": 0,
|
| 1306 |
"Cell, Nostril, Antibody +": 0,
|
| 1307 |
"Cell, Nostril, Antibody -": 0
|
|
|
|
| 1315 |
"Cell, Nostril, Antibody +": {
|
| 1316 |
"Cell, Antibody +": 3,
|
| 1317 |
"Cell, Antibody -": 0,
|
| 1318 |
+
"Cell, Nostril, Antibody +": 17,
|
| 1319 |
"Cell, Nostril, Antibody -": 0
|
| 1320 |
},
|
| 1321 |
"Cell, Nostril, Antibody -": {
|
|
|
|
| 1326 |
}
|
| 1327 |
},
|
| 1328 |
"n_gt": 163,
|
| 1329 |
+
"n_pred": 154
|
| 1330 |
},
|
| 1331 |
"nostrils": {
|
| 1332 |
"detection": {
|
|
|
|
| 1367 |
"counts": {
|
| 1368 |
"Cell, Antibody +": {
|
| 1369 |
"gt": 138,
|
| 1370 |
+
"pred": 132,
|
| 1371 |
+
"abs_err": 6,
|
| 1372 |
+
"rel_err": 0.043478260869565216
|
| 1373 |
},
|
| 1374 |
"Cell, Antibody -": {
|
| 1375 |
"gt": 3,
|
|
|
|
| 1379 |
},
|
| 1380 |
"Cell, Nostril, Antibody +": {
|
| 1381 |
"gt": 22,
|
| 1382 |
+
"pred": 19,
|
| 1383 |
+
"abs_err": 3,
|
| 1384 |
+
"rel_err": 0.13636363636363635
|
| 1385 |
},
|
| 1386 |
"Cell, Nostril, Antibody -": {
|
| 1387 |
"gt": 0,
|
|
|
|
| 1405 |
"fp_analysis": null,
|
| 1406 |
"pairs": null,
|
| 1407 |
"summary": {
|
| 1408 |
+
"cell_det_f1": 0.8517350157728707,
|
| 1409 |
+
"cell_det_precision": 0.8766233766233766,
|
| 1410 |
+
"cell_det_recall": 0.8282208588957055,
|
| 1411 |
+
"cell_mean_iou": 0.7577631927559012,
|
| 1412 |
+
"cell_det_f1_iou30": 0.9337539432176657,
|
| 1413 |
+
"cell_det_f1_centroid": 0.9211356466876971,
|
| 1414 |
"cell_attr_antibody": 1.0,
|
| 1415 |
+
"cell_attr_nostril": 0.9777777777777777,
|
| 1416 |
+
"cell_attr_both": 0.9777777777777777,
|
| 1417 |
"nos_det_f1": 0.9206349206349206,
|
| 1418 |
"nos_det_precision": 1.0,
|
| 1419 |
"nos_det_recall": 0.8529411764705882,
|
| 1420 |
"nos_type_acc": 0.9310344827586207,
|
| 1421 |
+
"f1[Cell, Antibody +]": 0.837037037037037,
|
| 1422 |
"f1[Cell, Antibody -]": 0.6666666666666666,
|
| 1423 |
+
"f1[Cell, Nostril, Antibody +]": 0.8292682926829269,
|
| 1424 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1425 |
"f1[Nostril in Nucleus]": 0.8979591836734695,
|
| 1426 |
"f1[Nostril External of Nucleus]": 0.7142857142857143
|
|
|
|
| 1429 |
"F114": {
|
| 1430 |
"cells": {
|
| 1431 |
"detection": {
|
| 1432 |
+
"tp": 222,
|
| 1433 |
+
"fp": 20,
|
| 1434 |
+
"fn": 20,
|
| 1435 |
+
"precision": 0.9173553719008265,
|
| 1436 |
+
"recall": 0.9173553719008265,
|
| 1437 |
+
"f1": 0.9173553719008265,
|
| 1438 |
+
"mean_iou_matched": 0.8151069160963895,
|
| 1439 |
"iou30": {
|
| 1440 |
+
"tp": 231,
|
| 1441 |
+
"fp": 11,
|
| 1442 |
+
"fn": 11,
|
| 1443 |
+
"precision": 0.9545454545454546,
|
| 1444 |
+
"recall": 0.9545454545454546,
|
| 1445 |
+
"f1": 0.9545454545454546
|
| 1446 |
},
|
| 1447 |
"centroid": {
|
| 1448 |
+
"tp": 231,
|
| 1449 |
+
"fp": 11,
|
| 1450 |
+
"fn": 11,
|
| 1451 |
+
"precision": 0.9545454545454546,
|
| 1452 |
+
"recall": 0.9545454545454546,
|
| 1453 |
+
"f1": 0.9545454545454546
|
| 1454 |
}
|
| 1455 |
},
|
| 1456 |
"attribute_accuracy": {
|
| 1457 |
+
"antibody": 0.990990990990991,
|
| 1458 |
+
"nostril": 0.9594594594594594,
|
| 1459 |
+
"both": 0.9504504504504504,
|
| 1460 |
+
"n_matched": 222
|
| 1461 |
},
|
| 1462 |
"per_class": {
|
| 1463 |
"Cell, Antibody +": {
|
| 1464 |
+
"tp": 154,
|
| 1465 |
+
"fp": 15,
|
| 1466 |
+
"fn": 21,
|
| 1467 |
+
"precision": 0.9112426035502958,
|
| 1468 |
+
"recall": 0.88,
|
| 1469 |
+
"f1": 0.8953488372093023,
|
| 1470 |
"gt_count": 175,
|
| 1471 |
+
"pred_count": 169
|
| 1472 |
},
|
| 1473 |
"Cell, Antibody -": {
|
| 1474 |
+
"tp": 20,
|
| 1475 |
+
"fp": 5,
|
| 1476 |
+
"fn": 1,
|
| 1477 |
+
"precision": 0.8,
|
| 1478 |
+
"recall": 0.9523809523809523,
|
| 1479 |
+
"f1": 0.8695652173913043,
|
| 1480 |
"gt_count": 21,
|
| 1481 |
+
"pred_count": 25
|
| 1482 |
},
|
| 1483 |
"Cell, Nostril, Antibody +": {
|
| 1484 |
"tp": 36,
|
| 1485 |
+
"fp": 11,
|
| 1486 |
"fn": 6,
|
| 1487 |
+
"precision": 0.7659574468085106,
|
| 1488 |
"recall": 0.8571428571428571,
|
| 1489 |
+
"f1": 0.8089887640449439,
|
| 1490 |
"gt_count": 42,
|
| 1491 |
+
"pred_count": 47
|
| 1492 |
},
|
| 1493 |
"Cell, Nostril, Antibody -": {
|
| 1494 |
"tp": 1,
|
|
|
|
| 1503 |
},
|
| 1504 |
"confusion": {
|
| 1505 |
"Cell, Antibody +": {
|
| 1506 |
+
"Cell, Antibody +": 154,
|
| 1507 |
"Cell, Antibody -": 2,
|
| 1508 |
"Cell, Nostril, Antibody +": 5,
|
| 1509 |
"Cell, Nostril, Antibody -": 0
|
| 1510 |
},
|
| 1511 |
"Cell, Antibody -": {
|
| 1512 |
"Cell, Antibody +": 0,
|
| 1513 |
+
"Cell, Antibody -": 20,
|
| 1514 |
"Cell, Nostril, Antibody +": 0,
|
| 1515 |
"Cell, Nostril, Antibody -": 0
|
| 1516 |
},
|
|
|
|
| 1528 |
}
|
| 1529 |
},
|
| 1530 |
"n_gt": 242,
|
| 1531 |
+
"n_pred": 242
|
| 1532 |
},
|
| 1533 |
"nostrils": {
|
| 1534 |
"detection": {
|
|
|
|
| 1569 |
"counts": {
|
| 1570 |
"Cell, Antibody +": {
|
| 1571 |
"gt": 175,
|
| 1572 |
+
"pred": 169,
|
| 1573 |
+
"abs_err": 6,
|
| 1574 |
+
"rel_err": 0.03428571428571429
|
| 1575 |
},
|
| 1576 |
"Cell, Antibody -": {
|
| 1577 |
"gt": 21,
|
| 1578 |
+
"pred": 25,
|
| 1579 |
+
"abs_err": 4,
|
| 1580 |
+
"rel_err": 0.19047619047619047
|
| 1581 |
},
|
| 1582 |
"Cell, Nostril, Antibody +": {
|
| 1583 |
"gt": 42,
|
| 1584 |
+
"pred": 47,
|
| 1585 |
+
"abs_err": 5,
|
| 1586 |
+
"rel_err": 0.11904761904761904
|
| 1587 |
},
|
| 1588 |
"Cell, Nostril, Antibody -": {
|
| 1589 |
"gt": 4,
|
|
|
|
| 1607 |
"fp_analysis": null,
|
| 1608 |
"pairs": null,
|
| 1609 |
"summary": {
|
| 1610 |
+
"cell_det_f1": 0.9173553719008265,
|
| 1611 |
+
"cell_det_precision": 0.9173553719008265,
|
| 1612 |
+
"cell_det_recall": 0.9173553719008265,
|
| 1613 |
+
"cell_mean_iou": 0.8151069160963895,
|
| 1614 |
+
"cell_det_f1_iou30": 0.9545454545454546,
|
| 1615 |
+
"cell_det_f1_centroid": 0.9545454545454546,
|
| 1616 |
+
"cell_attr_antibody": 0.990990990990991,
|
| 1617 |
+
"cell_attr_nostril": 0.9594594594594594,
|
| 1618 |
+
"cell_attr_both": 0.9504504504504504,
|
| 1619 |
"nos_det_f1": 0.8252427184466019,
|
| 1620 |
"nos_det_precision": 0.7327586206896551,
|
| 1621 |
"nos_det_recall": 0.9444444444444444,
|
| 1622 |
"nos_type_acc": 1.0,
|
| 1623 |
+
"f1[Cell, Antibody +]": 0.8953488372093023,
|
| 1624 |
+
"f1[Cell, Antibody -]": 0.8695652173913043,
|
| 1625 |
+
"f1[Cell, Nostril, Antibody +]": 0.8089887640449439,
|
| 1626 |
"f1[Cell, Nostril, Antibody -]": 0.4,
|
| 1627 |
"f1[Nostril in Nucleus]": 0.8648648648648649,
|
| 1628 |
"f1[Nostril External of Nucleus]": 0.7789473684210527
|
|
|
|
| 1631 |
"F99": {
|
| 1632 |
"cells": {
|
| 1633 |
"detection": {
|
| 1634 |
+
"tp": 237,
|
| 1635 |
+
"fp": 28,
|
| 1636 |
+
"fn": 14,
|
| 1637 |
+
"precision": 0.8943396226415095,
|
| 1638 |
+
"recall": 0.9442231075697212,
|
| 1639 |
+
"f1": 0.9186046511627908,
|
| 1640 |
+
"mean_iou_matched": 0.8196380690151054,
|
| 1641 |
"iou30": {
|
| 1642 |
+
"tp": 243,
|
| 1643 |
+
"fp": 22,
|
| 1644 |
+
"fn": 8,
|
| 1645 |
+
"precision": 0.9169811320754717,
|
| 1646 |
+
"recall": 0.9681274900398407,
|
| 1647 |
+
"f1": 0.9418604651162791
|
| 1648 |
},
|
| 1649 |
"centroid": {
|
| 1650 |
+
"tp": 242,
|
| 1651 |
+
"fp": 23,
|
| 1652 |
+
"fn": 9,
|
| 1653 |
+
"precision": 0.9132075471698113,
|
| 1654 |
+
"recall": 0.9641434262948207,
|
| 1655 |
+
"f1": 0.937984496124031
|
| 1656 |
}
|
| 1657 |
},
|
| 1658 |
"attribute_accuracy": {
|
| 1659 |
+
"antibody": 0.9789029535864979,
|
| 1660 |
+
"nostril": 0.9915611814345991,
|
| 1661 |
+
"both": 0.9704641350210971,
|
| 1662 |
+
"n_matched": 237
|
| 1663 |
},
|
| 1664 |
"per_class": {
|
| 1665 |
"Cell, Antibody +": {
|
| 1666 |
+
"tp": 170,
|
| 1667 |
+
"fp": 24,
|
| 1668 |
+
"fn": 13,
|
| 1669 |
+
"precision": 0.8762886597938144,
|
| 1670 |
+
"recall": 0.9289617486338798,
|
| 1671 |
+
"f1": 0.9018567639257294,
|
| 1672 |
"gt_count": 183,
|
| 1673 |
+
"pred_count": 194
|
| 1674 |
},
|
| 1675 |
"Cell, Antibody -": {
|
| 1676 |
+
"tp": 56,
|
| 1677 |
+
"fp": 11,
|
| 1678 |
+
"fn": 6,
|
| 1679 |
+
"precision": 0.835820895522388,
|
| 1680 |
+
"recall": 0.9032258064516129,
|
| 1681 |
+
"f1": 0.8682170542635659,
|
| 1682 |
"gt_count": 62,
|
| 1683 |
+
"pred_count": 67
|
| 1684 |
},
|
| 1685 |
"Cell, Nostril, Antibody +": {
|
| 1686 |
"tp": 4,
|
|
|
|
| 1705 |
},
|
| 1706 |
"confusion": {
|
| 1707 |
"Cell, Antibody +": {
|
| 1708 |
+
"Cell, Antibody +": 170,
|
| 1709 |
"Cell, Antibody -": 4,
|
| 1710 |
"Cell, Nostril, Antibody +": 0,
|
| 1711 |
"Cell, Nostril, Antibody -": 0
|
| 1712 |
},
|
| 1713 |
"Cell, Antibody -": {
|
| 1714 |
"Cell, Antibody +": 1,
|
| 1715 |
+
"Cell, Antibody -": 56,
|
| 1716 |
"Cell, Nostril, Antibody +": 0,
|
| 1717 |
"Cell, Nostril, Antibody -": 0
|
| 1718 |
},
|
|
|
|
| 1730 |
}
|
| 1731 |
},
|
| 1732 |
"n_gt": 251,
|
| 1733 |
+
"n_pred": 265
|
| 1734 |
},
|
| 1735 |
"nostrils": {
|
| 1736 |
"detection": {
|
|
|
|
| 1771 |
"counts": {
|
| 1772 |
"Cell, Antibody +": {
|
| 1773 |
"gt": 183,
|
| 1774 |
+
"pred": 194,
|
| 1775 |
+
"abs_err": 11,
|
| 1776 |
+
"rel_err": 0.060109289617486336
|
| 1777 |
},
|
| 1778 |
"Cell, Antibody -": {
|
| 1779 |
"gt": 62,
|
| 1780 |
+
"pred": 67,
|
| 1781 |
+
"abs_err": 5,
|
| 1782 |
+
"rel_err": 0.08064516129032258
|
| 1783 |
},
|
| 1784 |
"Cell, Nostril, Antibody +": {
|
| 1785 |
"gt": 6,
|
|
|
|
| 1809 |
"fp_analysis": null,
|
| 1810 |
"pairs": null,
|
| 1811 |
"summary": {
|
| 1812 |
+
"cell_det_f1": 0.9186046511627908,
|
| 1813 |
+
"cell_det_precision": 0.8943396226415095,
|
| 1814 |
+
"cell_det_recall": 0.9442231075697212,
|
| 1815 |
+
"cell_mean_iou": 0.8196380690151054,
|
| 1816 |
+
"cell_det_f1_iou30": 0.9418604651162791,
|
| 1817 |
+
"cell_det_f1_centroid": 0.937984496124031,
|
| 1818 |
+
"cell_attr_antibody": 0.9789029535864979,
|
| 1819 |
+
"cell_attr_nostril": 0.9915611814345991,
|
| 1820 |
+
"cell_attr_both": 0.9704641350210971,
|
| 1821 |
"nos_det_f1": 0.9090909090909091,
|
| 1822 |
"nos_det_precision": 0.9090909090909091,
|
| 1823 |
"nos_det_recall": 0.9090909090909091,
|
| 1824 |
"nos_type_acc": 1.0,
|
| 1825 |
+
"f1[Cell, Antibody +]": 0.9018567639257294,
|
| 1826 |
+
"f1[Cell, Antibody -]": 0.8682170542635659,
|
| 1827 |
"f1[Cell, Nostril, Antibody +]": 0.8,
|
| 1828 |
"f1[Cell, Nostril, Antibody -]": 0.0,
|
| 1829 |
"f1[Nostril in Nucleus]": 0.8,
|
scripts/build_summary.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""Write reports/SUMMARY.md from a cross-validation run and reports/final/final_fit.json.
|
| 3 |
|
| 4 |
-
python scripts/build_summary.py
|
| 5 |
"""
|
| 6 |
from __future__ import annotations
|
| 7 |
|
|
@@ -19,16 +19,29 @@ def pct(x: float) -> str:
|
|
| 19 |
return f"{100 * x:.1f}%"
|
| 20 |
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
def main(argv=None):
|
| 23 |
ap = argparse.ArgumentParser()
|
| 24 |
ap.add_argument("--cv-dir", default="runs/cv", help="folder holding cv_results.json of the shipped recipe")
|
| 25 |
ap.add_argument("--compare", default="reports/cv/cv_results.json",
|
| 26 |
help="cv_results.json of the previous recipe for the change table ('' = none)")
|
|
|
|
| 27 |
a = ap.parse_args(argv)
|
|
|
|
| 28 |
cv = json.load(open(os.path.join(ROOT, a.cv_dir, "cv_results.json")))
|
| 29 |
prev = json.load(open(os.path.join(ROOT, a.compare)))["aggregate"] if a.compare and os.path.exists(os.path.join(ROOT, a.compare)) else None
|
| 30 |
agg = cv["aggregate"]
|
| 31 |
per = agg["per_image"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
fit = json.load(open(os.path.join(ROOT, "reports", "final", "final_fit.json")))
|
| 33 |
tot = agg["dataset_totals"]
|
| 34 |
n_nuc = sum(tot[c] for c in CELL_LABELS)
|
|
@@ -41,12 +54,17 @@ def main(argv=None):
|
|
| 41 |
"then a final model trained on all images with the same recipe. Each held-out image was tested 23 times: 3 identical runs "
|
| 42 |
"(determinism), no-TTA / 4× / 8× test-time augmentation, 8 rotations and flips, 6 photometric perturbations, and 6 post-processing rule variants. "
|
| 43 |
"The only choice made on held-out data is the rule that gives a nucleus the Nostril attribute: of three candidate rules, "
|
| 44 |
-
"'contains an in-nucleus punctum' (the annotation protocol) scored best and is the default; see the rule-variant table in cv_report.md.
|
| 45 |
-
"
|
|
|
|
|
|
|
| 46 |
"a per-nucleus normalised distance-to-outline map that the watershed uses as its landscape (markers = distance > 0.5), "
|
| 47 |
"an antibody head whose loss up-weights antibody-negative pixels by sqrt(positive / negative pixels) (4.5 on the full set), "
|
| 48 |
-
"and 25 % of training crops centred on an antibody-negative nucleus
|
| 49 |
-
"
|
|
|
|
|
|
|
|
|
|
| 50 |
"## Headline numbers (micro-averaged over all held-out images, no TTA)", "",
|
| 51 |
"| Measure | Precision | Recall | F1 |", "|---|---:|---:|---:|",
|
| 52 |
f"| Nucleus detection, IoU ≥ 0.5 | {pct(det['cells']['precision'])} | {pct(det['cells']['recall'])} | {pct(det['cells']['f1'])} |",
|
|
@@ -74,8 +92,8 @@ def main(argv=None):
|
|
| 74 |
L.append(f"| {k} | {pct(s['cell_det_f1'])} | {pct(s['cell_attr_both'])} | {pct(s['nos_det_f1'])} |")
|
| 75 |
if prev:
|
| 76 |
pd, pd8 = prev["detection_base"], prev["detection_tta8"]
|
| 77 |
-
L += ["", "## Change from
|
| 78 |
-
"| Measure |
|
| 79 |
def row(name, x, y):
|
| 80 |
L.append(f"| {name} | {pct(x)} | {pct(y)} | {100 * (y - x):+.1f} |")
|
| 81 |
row("Nucleus F1, IoU ≥ 0.5", pd["cells"]["f1"], det["cells"]["f1"])
|
|
@@ -92,15 +110,19 @@ def main(argv=None):
|
|
| 92 |
for k in sorted(per):
|
| 93 |
if k in prev["per_image"]:
|
| 94 |
row(f"Nuclei F1, {k} held out", prev["per_image"][k]["base"]["cell_det_f1"], per[k]["base"]["cell_det_f1"])
|
| 95 |
-
|
| 96 |
-
|
| 97 |
n_gt = det["cells"]["tp"] + det["cells"]["fn"]
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
"
|
| 102 |
-
"
|
| 103 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
sw = agg.get("antibody_threshold_sweep")
|
| 105 |
if sw:
|
| 106 |
best = max(sw["sweep"], key=lambda r: r["neg_f1"])
|
|
@@ -110,14 +132,16 @@ def main(argv=None):
|
|
| 110 |
f"The default was kept because the class is dominated by a single image (F99 holds 62 of the {tot['Cell, Antibody -'] + tot['Cell, Nostril, Antibody -']} negatives)."]
|
| 111 |
L += ["", "## What limits the scores", "",
|
| 112 |
"* **Touching nuclei** are still the main source of IoU-0.5 misses (worst on F113, the densest image). The distance-map watershed of v2 recovers many clusters that v1 merged (v1 marker/threshold sweeps in `reports/cv/postprocess_sweep.json` had shown post-processing alone could not), but some clusters are still merged and a few nuclei are now split in two.",
|
| 113 |
-
"* **Annotation completeness**: most unmatched predictions overlap an annotated nucleus (outline disagreement)
|
| 114 |
f"* **Antibody − is rare** ({tot['Cell, Antibody -'] + tot['Cell, Nostril, Antibody -']} of {n_nuc} nuclei, 62 in one image), and **Cell, Nostril, Antibody −** has five examples; their scores are not reliable. The class-balanced loss of v2 trades antibody-negative precision for recall.",
|
| 115 |
"* Scores are from nine images of one experiment (35-day spinal cord, Iba1/TMEM119). New staining batches or magnifications need a check against a few annotated images.",
|
| 116 |
"", "## Reproduce", "",
|
| 117 |
"```bash", "python evaluate.py cv --data-dir <folder with TIFs and CVAT zips> --runs-dir runs/cv_v2 --iters 3000",
|
|
|
|
|
|
|
| 118 |
"python evaluate.py final --data-dir <folder> --weights weights/cellquant.pt",
|
| 119 |
-
"python scripts/compare_cv.py reports/
|
| 120 |
-
"python scripts/build_summary.py --cv-dir
|
| 121 |
out = os.path.join(ROOT, "reports", "SUMMARY.md")
|
| 122 |
with open(out, "w") as f:
|
| 123 |
f.write("\n".join(L))
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""Write reports/SUMMARY.md from a cross-validation run and reports/final/final_fit.json.
|
| 3 |
|
| 4 |
+
python scripts/build_summary.py --cv-dir reports/cv_v3 --compare reports/cv_v2/cv_results.json --names v2,v3
|
| 5 |
"""
|
| 6 |
from __future__ import annotations
|
| 7 |
|
|
|
|
| 19 |
return f"{100 * x:.1f}%"
|
| 20 |
|
| 21 |
|
| 22 |
+
def peak_thr(agg: dict) -> float:
|
| 23 |
+
"""Shipped min_peak_dist: the final model's threshold from rule_study.json next to cv_results.json, else PostConfig's default."""
|
| 24 |
+
from cellquant.postprocess import PostConfig
|
| 25 |
+
return float(agg.get("final_min_peak_dist", PostConfig().min_peak_dist))
|
| 26 |
+
|
| 27 |
+
|
| 28 |
def main(argv=None):
|
| 29 |
ap = argparse.ArgumentParser()
|
| 30 |
ap.add_argument("--cv-dir", default="runs/cv", help="folder holding cv_results.json of the shipped recipe")
|
| 31 |
ap.add_argument("--compare", default="reports/cv/cv_results.json",
|
| 32 |
help="cv_results.json of the previous recipe for the change table ('' = none)")
|
| 33 |
+
ap.add_argument("--names", default="v1,v2", help="names of the previous and the shipped recipe")
|
| 34 |
a = ap.parse_args(argv)
|
| 35 |
+
prev_name, cur_name = a.names.split(",")
|
| 36 |
cv = json.load(open(os.path.join(ROOT, a.cv_dir, "cv_results.json")))
|
| 37 |
prev = json.load(open(os.path.join(ROOT, a.compare)))["aggregate"] if a.compare and os.path.exists(os.path.join(ROOT, a.compare)) else None
|
| 38 |
agg = cv["aggregate"]
|
| 39 |
per = agg["per_image"]
|
| 40 |
+
rs = os.path.join(ROOT, a.cv_dir, "rule_study.json")
|
| 41 |
+
if os.path.exists(rs):
|
| 42 |
+
fin = json.load(open(rs)).get("final")
|
| 43 |
+
if fin:
|
| 44 |
+
agg["final_min_peak_dist"] = fin["chosen"]["thr"]
|
| 45 |
fit = json.load(open(os.path.join(ROOT, "reports", "final", "final_fit.json")))
|
| 46 |
tot = agg["dataset_totals"]
|
| 47 |
n_nuc = sum(tot[c] for c in CELL_LABELS)
|
|
|
|
| 54 |
"then a final model trained on all images with the same recipe. Each held-out image was tested 23 times: 3 identical runs "
|
| 55 |
"(determinism), no-TTA / 4× / 8× test-time augmentation, 8 rotations and flips, 6 photometric perturbations, and 6 post-processing rule variants. "
|
| 56 |
"The only choice made on held-out data is the rule that gives a nucleus the Nostril attribute: of three candidate rules, "
|
| 57 |
+
"'contains an in-nucleus punctum' (the annotation protocol) scored best and is the default; see the rule-variant table in cv_report.md. "
|
| 58 |
+
"The peak-distance threshold of v3 was chosen, for every fold, on that fold's eight training images only (scripts/rule_study.py), "
|
| 59 |
+
"and for the shipped model on its own nine training images; the held-out images never entered that choice.", "",
|
| 60 |
+
"Recipe (v3, shipped): the v2 model (ResNet34-UNet with a full-resolution stem; targets are a 3-px inner border ring (class weight 3), "
|
| 61 |
"a per-nucleus normalised distance-to-outline map that the watershed uses as its landscape (markers = distance > 0.5), "
|
| 62 |
"an antibody head whose loss up-weights antibody-negative pixels by sqrt(positive / negative pixels) (4.5 on the full set), "
|
| 63 |
+
"and 25 % of training crops centred on an antibody-negative nucleus) plus one post-processing rule: a nucleus whose peak "
|
| 64 |
+
f"predicted distance is below {peak_thr(agg):.2f} is dropped (PostConfig.min_peak_dist). The distance head is trained to reach 1 inside "
|
| 65 |
+
"every annotated nucleus and to stay at 0 everywhere else, so a low peak marks a blob the annotator would have skipped. "
|
| 66 |
+
"The weights are unchanged from v2 (reports/cv_v2/); v1 (reports/cv/) used a 2-px ring, the interior map as watershed landscape "
|
| 67 |
+
"and an unweighted antibody loss. The change table below compares the shipped recipe with the previous one under the same protocol.", "",
|
| 68 |
"## Headline numbers (micro-averaged over all held-out images, no TTA)", "",
|
| 69 |
"| Measure | Precision | Recall | F1 |", "|---|---:|---:|---:|",
|
| 70 |
f"| Nucleus detection, IoU ≥ 0.5 | {pct(det['cells']['precision'])} | {pct(det['cells']['recall'])} | {pct(det['cells']['f1'])} |",
|
|
|
|
| 92 |
L.append(f"| {k} | {pct(s['cell_det_f1'])} | {pct(s['cell_attr_both'])} | {pct(s['nos_det_f1'])} |")
|
| 93 |
if prev:
|
| 94 |
pd, pd8 = prev["detection_base"], prev["detection_tta8"]
|
| 95 |
+
L += ["", f"## Change from {prev_name} (same protocol, same nine held-out images; `{a.cv_dir}/comparison.md` has the full table)", "",
|
| 96 |
+
f"| Measure | {prev_name} | {cur_name} | Δ (points) |", "|---|---:|---:|---:|"]
|
| 97 |
def row(name, x, y):
|
| 98 |
L.append(f"| {name} | {pct(x)} | {pct(y)} | {100 * (y - x):+.1f} |")
|
| 99 |
row("Nucleus F1, IoU ≥ 0.5", pd["cells"]["f1"], det["cells"]["f1"])
|
|
|
|
| 110 |
for k in sorted(per):
|
| 111 |
if k in prev["per_image"]:
|
| 112 |
row(f"Nuclei F1, {k} held out", prev["per_image"][k]["base"]["cell_det_f1"], per[k]["base"]["cell_det_f1"])
|
| 113 |
+
n_pred_prev = pd["cells"]["tp"] + pd["cells"]["fp"]
|
| 114 |
+
n_pred_cur = det["cells"]["tp"] + det["cells"]["fp"]
|
| 115 |
n_gt = det["cells"]["tp"] + det["cells"]["fn"]
|
| 116 |
+
nov_prev = sum(s["fp_analysis"]["n_fp_no_gt_overlap"] for s in prev["per_image"].values())
|
| 117 |
+
nov_cur = sum(s["fp_analysis"]["n_fp_no_gt_overlap"] for s in per.values())
|
| 118 |
+
L += ["", f"{cur_name} keeps the {prev_name} weights and drops {n_pred_prev - n_pred_cur} of the {n_pred_prev} nuclei {prev_name} predicted on the "
|
| 119 |
+
f"nine held-out images ({n_gt} annotated): unmatched predictions fall from {pd['cells']['fp']} to {det['cells']['fp']} "
|
| 120 |
+
f"(those overlapping no annotated nucleus from {nov_prev} to {nov_cur}) while matched ones fall from {pd['cells']['tp']} to {det['cells']['tp']}, "
|
| 121 |
+
f"so precision rises by {100 * (det['cells']['precision'] - pd['cells']['precision']):.1f} points and recall drops by "
|
| 122 |
+
f"{100 * (pd['cells']['recall'] - det['cells']['recall']):.1f}. Puncta are untouched. The over-count of nuclei on the annotated images "
|
| 123 |
+
f"shrinks from {100 * (n_pred_prev / n_gt - 1):.0f} % to {100 * (n_pred_cur / n_gt - 1):.0f} %. The threshold was never tuned on a held-out image: "
|
| 124 |
+
"each fold used the value chosen on its own training images (0.60-0.67, see rule_study.md), the shipped model the value chosen on all nine "
|
| 125 |
+
f"({peak_thr(agg):.2f})."]
|
| 126 |
sw = agg.get("antibody_threshold_sweep")
|
| 127 |
if sw:
|
| 128 |
best = max(sw["sweep"], key=lambda r: r["neg_f1"])
|
|
|
|
| 132 |
f"The default was kept because the class is dominated by a single image (F99 holds 62 of the {tot['Cell, Antibody -'] + tot['Cell, Nostril, Antibody -']} negatives)."]
|
| 133 |
L += ["", "## What limits the scores", "",
|
| 134 |
"* **Touching nuclei** are still the main source of IoU-0.5 misses (worst on F113, the densest image). The distance-map watershed of v2 recovers many clusters that v1 merged (v1 marker/threshold sweeps in `reports/cv/postprocess_sweep.json` had shown post-processing alone could not), but some clusters are still merged and a few nuclei are now split in two.",
|
| 135 |
+
"* **Annotation completeness**: most unmatched predictions overlap an annotated nucleus (outline disagreement); the rest are dimmer, smaller objects the annotator skipped, which the peak-distance rule of v3 halves (143 → 72 on the held-out images) at the price of 21 matched nuclei. Many faint red dots were likewise not annotated, which caps external-punctum precision.",
|
| 136 |
f"* **Antibody − is rare** ({tot['Cell, Antibody -'] + tot['Cell, Nostril, Antibody -']} of {n_nuc} nuclei, 62 in one image), and **Cell, Nostril, Antibody −** has five examples; their scores are not reliable. The class-balanced loss of v2 trades antibody-negative precision for recall.",
|
| 137 |
"* Scores are from nine images of one experiment (35-day spinal cord, Iba1/TMEM119). New staining batches or magnifications need a check against a few annotated images.",
|
| 138 |
"", "## Reproduce", "",
|
| 139 |
"```bash", "python evaluate.py cv --data-dir <folder with TIFs and CVAT zips> --runs-dir runs/cv_v2 --iters 3000",
|
| 140 |
+
"python scripts/rule_study.py --data-dir <folder> --runs-dir runs/cv_v2 --out runs/cv_v3/rule_study --weights weights/cellquant.pt",
|
| 141 |
+
"python evaluate.py cv --data-dir <folder> --runs-dir runs/cv_v3 --post-config runs/cv_v3/rule_study_post_config.json # fold_*.pt linked from runs/cv_v2",
|
| 142 |
"python evaluate.py final --data-dir <folder> --weights weights/cellquant.pt",
|
| 143 |
+
"python scripts/compare_cv.py reports/cv_v2/cv_results.json runs/cv_v3/cv_results.json --names v2,v3 --out reports/cv_v3/comparison.md",
|
| 144 |
+
"python scripts/build_summary.py --cv-dir reports/cv_v3 --compare reports/cv_v2/cv_results.json --names v2,v3", "```", ""]
|
| 145 |
out = os.path.join(ROOT, "reports", "SUMMARY.md")
|
| 146 |
with open(out, "w") as f:
|
| 147 |
f.write("\n".join(L))
|
validation/C100 35D SC Iba_Annotated.zip
CHANGED
|
Binary files a/validation/C100 35D SC Iba_Annotated.zip and b/validation/C100 35D SC Iba_Annotated.zip differ
|
|
|
validation/C122 F 35D SC Tmem W003_Annotated.zip
CHANGED
|
Binary files a/validation/C122 F 35D SC Tmem W003_Annotated.zip and b/validation/C122 F 35D SC Tmem W003_Annotated.zip differ
|
|
|
validation/F110 F 35D SC Iba W002_Annotated.zip
CHANGED
|
Binary files a/validation/F110 F 35D SC Iba W002_Annotated.zip and b/validation/F110 F 35D SC Iba W002_Annotated.zip differ
|
|
|
validation/F113 F 35D SC Tmem W001_Annotated.zip
CHANGED
|
Binary files a/validation/F113 F 35D SC Tmem W001_Annotated.zip and b/validation/F113 F 35D SC Tmem W001_Annotated.zip differ
|
|
|