Toxoplasma from Cell Mask (cross-channel)
Segments Toxoplasma gondii parasitophorous vacuoles from the host cell mask channel alone — no parasite-specific stain required. A cross-channel model: it is given the host cell image and predicts where the parasites are.
- Architecture: Cellpose-SAM (cpsam_v2)
- Model Zoo key:
toxoplasma_from_cellmask_v1
- Checkpoint:
toxoplasma_from_cellmask_pv
- Trained by: einarolafsson
Use it in spaCR
This model is distributed through the spaCR Model Zoo. spaCR is an open-source
package for spatial phenotype analysis of CRISPR screens and microscopy images.
pip install spacr
Model Zoo (GUI)
Launch the GUI and open the Model Zoo:
spacr
Find Toxoplasma from Cell Mask (cross-channel) in the model list and press Download. The Model Zoo verifies
the checkpoint's SHA-256 after download, so a truncated or substituted file is
rejected rather than silently used.
Model Zoo (Python)
from spacr import model_zoo
entry = next(e for e in model_zoo.catalogue() if e.key == "toxoplasma_from_cellmask_v1")
path = model_zoo.install(entry, dest="~/spacr_models")
print(path) # verified local checkpoint
Mask generation
Point spaCR's mask generation at the downloaded checkpoint:
from spacr.core import preprocess_generate_masks
settings = {
"src": "/path/to/images",
"pathogen": "cellpose",
"pathogen_model": str(path), # the checkpoint fetched above
"pathogen_diameter": 12,
}
preprocess_generate_masks(settings)
In the GUI the same thing is under Make masks — choose the downloaded model in
the Cellpose model field for the relevant object.
API: :func:spacr.core.preprocess_generate_masks,
:func:spacr.spacr_cellpose.generate_masks_from_imgs
Performance
| model |
train |
train obj. |
test |
test obj. |
CV |
F1 @ IoU 0.5 |
AJI |
Dice |
final train loss |
final val loss |
val - train |
best epoch |
| stock cpsam_v2 (no fine-tuning) |
— |
— |
463 |
6116 |
— |
0.0215 |
0.0080 |
0.0201 |
— |
— |
— |
— |
| this model |
2567 |
not recorded |
463 |
6116 |
no (single well-grouped split) |
0.6058 |
0.4939 |
0.6096 |
0.0072 |
0.0099 |
+0.0028 |
100 / 100 |
Scored on a well-grouped held-out split — no well appears in both train and test — including fields with no parasites, so false positives are counted.
Per host cell line:
| host |
n |
F1 |
AJI |
| HFF |
159 |
0.5568 |
0.5649 |
| HeLa |
151 |
0.7105 |
0.5963 |
| THP1 |
153 |
0.4652 |
0.3191 |
Objects are reference (ground-truth) objects. Training-set object counts were not recorded at training time; the held-out counts come from the scoring bundle.
Training curves
Loss is on a log scale. Train and validation tracking each other is the overfitting check: a validation curve that turns up while train keeps falling is the signature this model does not show.
Training data
2567 training fields and 463 held-out fields, split by well
(training/split_by_well.csv) so no well leaks across the split. Targets are
PV-regenerated masks (masks_pv). Hosts: HFF, HeLa and THP1.
Trained for 100 epochs from stock cpsam_v2, AdamW, lr 1e-5, weight decay 0.1, batch 1.
Provenance note. A power loss interrupted this run at 57/100 epochs. Training was
continued from the epoch-50 checkpoint with the original learning-rate schedule replayed
exactly from index 50 (validated bit-exactly against the interrupted run's recorded
learning rates), so epochs 51-100 follow the schedule the uninterrupted run would have used.
Cellpose stores net.state_dict() only, so the AdamW moments and augmentation RNG restarted;
validation loss shows the two runs converged again within two epochs. Both epoch histories
are in training/ for full transparency.
Files in this repository
| path |
what |
toxoplasma_from_cellmask_pv |
the checkpoint |
training/epoch_history.csv |
per-epoch losses + pixel metrics, epochs 51-100 |
training/epoch_history_epochs1-57_interrupted.csv |
the interrupted run, epochs 1-57 |
training/loss_per_epoch.csv |
slim loss view |
training/run_config.json |
exact hyperparameters, versions, GPU |
training/split_by_well.csv |
the well-grouped split |
training/training_curves.png |
loss and checkpoint-metric curves |
evaluation/report.json |
full scorecard, all checkpoints, per host |
evaluation/metrics.csv |
F1/AJI/Dice per checkpoint and per host |
evaluation/best_perimage.csv |
per-image scores for the best checkpoint |
evaluation/comparison_vs_stock_summary.csv |
this model vs stock cpsam_v2 |
evaluation/stock_cpsam_v2_summary.csv |
the stock baseline |
Limitations
- The held-out split is used for checkpoint selection, so it is validation data rather than a fully independent test set.
- Targets are automatic reference labels (PV-regenerated masks), not hand-drawn ground truth.
- THP1 is the weakest host (F1 0.465); HeLa the strongest (0.711).
- Accuracy falls above IoU 0.8 — suited to counting, occupancy and area rather than precise morphometry.
Links
- spaCR on GitHub: https://github.com/EinarOlafsson/spacr
- Model Zoo API:
spacr.model_zoo — catalogue(), install(), fetch(), verify()
- Mask generation API:
spacr.core.preprocess_generate_masks
- Issues and questions: https://github.com/EinarOlafsson/spacr/issues