spacr.infection¶
Infection metrics, assembled from a finished Measure run.
This module builds a report from existing tables and runs no image processing: thirteen of the sixteen candidate infection metrics can be derived from tables Measure has already written. The three that do not – intracellular fraction, vacuoles per cell, distance to the host boundary – belong to the invasion module and to segmentation, and are deliberately absent here rather than approximated.
Every number this module produces carries its own denominator, because most errors in infection metrics come from a denominator that does not match its numerator:
The relationship table has no row for a cell with no parasites.
measure.get_componentsexplodes the per-cell child list and drops the empty ones, so counting rows there counts infected cells, not all cells. The denominator has to come from thecelltable, which holds every segmented cell whether or not anything is inside it.io.pydrops pathogens with nocell_idand can filter rows bypathogen_prcfo_count. Neither touches the cell table. A numerator built from a filtered pathogen table over an unfiltered cell table counts two different populations, and the ratio looks entirely plausible.
So infection_report() returns the denominator, and its size, on every
row. A reader who disagrees with a number can see immediately which of the two
halves they disagree with.
The module adds no new terms. uninfected, pathogen_count and
pathogen_prcfo_count already exist across measure, io and
timelapse; this module reuses them.
Functions¶
|
Whether cells and parasites were border-filtered the same way. |
|
Compare host measurements of infected and uninfected cells per well. |
|
Infection metrics per well, each with the denominator it was computed over. |
|
Per-well distribution of the number of parasites per cell. |
|
Every host cell with its parasite count, including cells with zero. |
|
Whether the Measure run that wrote |
|
Write the infection report beside the database it came from. |
Module Contents¶
- spacr.infection.border_rules_agree(db_path: str) bool | None[source]¶
Whether cells and parasites were border-filtered the same way.
The numerator and the denominator must use the same border rule; otherwise the rate is computed against a different cell count than the numerator.
remove_border_objectsis applied at segmentation time, per object type, so it decides what is in each table rather than how the table is counted. The two settings are independent and default to False together, so they agree unless somebody changed one:pathogens cleared and cells kept – a host cell whose only parasite touched the edge is still in the cell table, now with a count of zero. It reads as uninfected and deflates the rate.
cells cleared and pathogens kept – a parasite can name a cell that is no longer in the cell table, so it is counted in neither numerator nor denominator and the infection index drifts.
This is the same kind of problem as
include_uninfected: a setting that changes what a table contains, and therefore what a ratio over it means, without any indication in the output.include_uninfectedmade every well 1.000000 on a real plate; a border mismatch instead deflates the rate, which can be mistaken for a biological effect.- Parameters:
db_path – path to a
measurements.db.- Returns:
Truewhen both rules match,Falsewhen they differ,Nonewhen the run recorded neither (an older database), so the answer is unknown.
- spacr.infection.host_contrast(db_path: str, columns: Sequence[str], *, statistic: str = 'mean') pandas.DataFrame[source]¶
Compare host measurements of infected and uninfected cells per well.
The comparison is made within a well: comparing an infected well to an uninfected one confounds infection with everything else that differs between two wells, whereas here both populations share the same well.
- Parameters:
db_path – path to a
measurements.db.columns – the host-cell measurements to contrast, e.g.
("area", "eccentricity").statistic – any name
DataFrameGroupBy.aggaccepts.
- Returns:
one row per (well, measurement) with the infected and uninfected values and both group sizes.
- spacr.infection.infection_report(db_path: str, *, by_field: bool = False, monolayer_filter: bool = False) pandas.DataFrame[source]¶
Infection metrics per well, each with the denominator it was computed over.
Every row carries its denominator, because a mismatched denominator is the usual error in these numbers.
infection rateover “cells” andparasites per infectedover “infected cells” are different populations, and a table that reports only the ratios cannot be checked.- Parameters:
db_path – path to a
measurements.db.by_field – group by field as well as well, which is what shows a settling gradient a well mean hides.
- Returns:
tidy frame – identity columns, then
metric,value,denominatorandn_denominator. Empty when there is no cell table to count.
- spacr.infection.multiplicity_distribution(db_path: str) pandas.DataFrame[source]¶
Per-well distribution of the number of parasites per cell.
Two conditions can share an infection index and differ completely: a few heavily infected cells against many lightly infected ones is different biology with the same average. The distribution is the number that distinguishes them, so it is reported rather than summarised.
- Parameters:
db_path – path to a
measurements.db.- Returns:
one row per (well, parasite count) with
cellsand the fraction of the well’s cells at that count.
- spacr.infection.parasites_per_cell(db_path: str) pandas.DataFrame[source]¶
Every host cell with its parasite count, including cells with zero.
The relationship between a cell and its parasites is stored on the parasite, so a cell containing none appears nowhere in the pathogen table. Any count taken from that table alone counts only infected cells.
- Parameters:
db_path – path to a
measurements.db.- Returns:
one row per cell, with the identity columns,
object_labelandpathogen_count. Empty when there is no cell table.
- spacr.infection.uninfected_cells_were_measured(db_path: str) bool | None[source]¶
Whether the Measure run that wrote
db_pathkept uninfected cells.The answer determines what the cell table holds.
include_uninfected=False– the default for a screen that only crops infected cells, and what the TSG101 plates were measured with – means Measure wrote no row for a cell with no parasite. The cell table is then a selection of infected cells rather than the segmented population, andinfected / cellsis 1.0 for every well no matter what the biology did.A column of 1.000 would read as 100% infection, and nothing in the table would indicate otherwise, so this module withholds the rate instead of printing it.
- Parameters:
db_path – path to a
measurements.db.- Returns:
TrueorFalsewhen the run recorded the setting,Nonewhen it did not (an older database), so the answer is unknown.
- spacr.infection.write_infection_report(db_path: str, *, by_field: bool = False, destination: str | None = None) str | None[source]¶
Write the infection report beside the database it came from.
A Measure run writes the report automatically; it needs no button, screen or setting.
Nothing is written when the report is empty. A plate with no cell table, or none of the columns the metrics need, gives an empty report; no empty CSV is written and None is returned.
Written to a dot-name in the same folder and renamed over the target, so a reader never sees half a file.
- Parameters:
db_path – a
measurements.db.by_field – group by field as well as well.
destination – where to write it; the default is
REPORT_NAMEbesidedb_path.
- Returns:
the path written, or None when the report is empty.
Nested helpers¶
- infection_report.add(metric, value, denominator, n)¶
Record one metric together with the population it is over.
The denominator travels with the value rather than being implied by the metric’s name, because two of these are ratios over different populations and a reader cannot check a ratio whose denominator they have to guess.
- Parameters:
metric – the metric’s name.
value – its value for this group.
denominator – what the value was computed over, in words.
n – how many things that denominator contained.
spacr/infection.py:416