spacr.annotation_umap_qc

Evaluate guide annotations against positive and negative control cells.

The workflow tunes an embedding on one control subset, evaluates separation on held-out controls, and summarizes each annotated cell by the fraction of nearby controls that are positive. Guide-level purity can then be compared with independently estimated effect signs by permutation testing.

This check is circular when the annotation method selected cells using the same phenotype score, or when that score is included among the embedding features. circularity_warning() reports those cases so apparent control agreement is not presented as independent validation.

Functions

circularity_warning(→ str)

Return a warning when control agreement is not independent.

effect_agreement(→ Dict[str, object])

Test whether guide effects agree with positive-control proximity.

fit_on_controls(→ Dict[str, object])

Select an embedding recipe using held-out control separation.

neighbour_purity(→ numpy.ndarray)

Compute the positive-control share among each cell's neighbours.

purity_by_guide(→ Dict[str, Dict[str, float]])

Summarize neighbour purity for each sufficiently represented guide.

Module Contents

spacr.annotation_umap_qc.circularity_warning(method: str, *, score_in_features: bool = False) → str[source]

Return a warning when control agreement is not independent.

Parameters:

method – annotation or cell-picking method being checked.

An empty string means that neither the method name nor the supplied feature flag identifies a known circularity.

spacr.annotation_umap_qc.effect_agreement(purity: Mapping[str, Mapping[str, float]], effects: Mapping[str, float], *, permutations: int = 999, seed: int = 0) → Dict[str, object][source]

Test whether guide effects agree with positive-control proximity.

Parameters:
  • purity – guide summaries containing mean purity values.

  • effects – numeric effect estimate keyed by guide.

The observed statistic is Spearman correlation between guide effect and mean neighbour purity. The permutation null shuffles effects between guides while preserving the purity values and guide counts. The result includes the correlation, two-sided permutation p-value, group means for positive and negative effects, and a boolean separation call.

spacr.annotation_umap_qc.fit_on_controls(features: numpy.ndarray, labels: Sequence[str], *, recipes: Sequence[Mapping[str, object]], seed: int = 0, holdout: float = 0.5, neighbours: int = 15, groups: Sequence[object] | None = None, group_by: str = 'well') → Dict[str, object][source]

Select an embedding recipe using held-out control separation.

Parameters:
  • features (numpy.ndarray) – Control-cell feature matrix with shape (n_cells, n_features).

  • labels (sequence of str) – POSITIVE or NEGATIVE for each control cell.

  • recipes (sequence of mappings) – Candidate UMAP parameter dictionaries.

  • seed (int, default=0) – Random seed for splitting and embedding.

  • holdout (float, default=0.5) – Fraction of controls reserved for evaluation.

  • neighbours (int, default=15) – Neighbour count passed to the embedding score.

  • groups (sequence, optional) – One group identity per control cell, usually the well. Control cells from one well share illumination, seeding and fixation, so a split that puts siblings on both sides reports a held-out silhouette the embedding did not earn. When groups are given no group appears on both sides; when they are omitted the split is per object and the result says so in split_level.

  • group_by (str, default='well') – The level groups names, one of the shared split ladder.

Returns:

dict – Winning recipe, tuned and held-out silhouette scores, overfit gap, trustworthiness flag, the split level used, and all attempted trials. Error dictionaries are returned when the controls cannot be split or scored.

spacr.annotation_umap_qc.neighbour_purity(embedding: numpy.ndarray, control_labels: Sequence[str | None], *, k: int = 25) → numpy.ndarray[source]

Compute the positive-control share among each cell’s neighbours.

Parameters:
  • embedding – embedding coordinates for controls and annotated cells.

  • control_labels – control label, or None, aligned to each row.

embedding contains controls and annotated cells together. control_labels uses POSITIVE, NEGATIVE, or None for non-control cells. Each control cell is excluded from its own neighbourhood. The result contains one value in [0, 1] per cell, or nan when no eligible control neighbour is available.

spacr.annotation_umap_qc.purity_by_guide(purity: numpy.ndarray, guides: Sequence[str], *, abstain: str = 'Non_annotated', minimum_cells: int = 10) → Dict[str, Dict[str, float]][source]

Summarize neighbour purity for each sufficiently represented guide.

Parameters:
  • purity – per-cell neighbour-purity values.

  • guides – guide name aligned to each purity value.

The abstention label is excluded. Guides with fewer than minimum_cells finite values are omitted; retained rows report mean purity, standard deviation, and cell count.