Skip to content

scdecon.preprocessing

preprocessing

Single-cell preprocessing: QC and normalisation of in-memory AnnData objects.

This layer operates purely on AnnData objects already loaded by :mod:scdecon.io; it performs no file I/O of its own.

PreprocessConfig dataclass

PreprocessConfig(min_genes: int = 200, min_cells: int = 3, max_pct_mito: float = 20.0, mito_prefix: str = 'MT-', target_sum: float | None = 10000.0, counts_layer: str = 'counts')

Immutable configuration for QC filtering and normalisation.

Attributes:

Name Type Description
min_genes int

Minimum number of genes a cell must express to be kept (sc.pp.filter_cells(min_genes=...)).

min_cells int

Minimum number of cells a gene must be detected in to be kept (sc.pp.filter_genes(min_cells=...)).

max_pct_mito float

Maximum percentage of counts from mitochondrial genes allowed per cell, in the range [0, 100]. Cells above this are filtered out.

mito_prefix str

Gene-name prefix identifying mitochondrial genes (e.g. "MT-" for human symbols). Used to build the mito flag for QC metrics.

target_sum float | None

Per-cell total count after library-size normalisation (sc.pp.normalize_total(target_sum=...)). None uses Scanpy's median-count behaviour.

counts_layer str

Name of the adata.layers entry where raw counts are stored before normalisation, so the un-normalised data is never lost.

__post_init__

__post_init__() -> None

Validate parameters, failing loudly on nonsensical values.

QCSummary dataclass

QCSummary(n_cells_before: int, n_cells_after: int, n_genes_before: int, n_genes_after: int, n_cells_removed_by_min_genes: int, n_cells_removed_by_max_pct_mito: int, n_genes_removed_by_min_cells: int)

Typed, immutable record of a QC filtering step.

Attributes:

Name Type Description
n_cells_before, n_cells_after

Cell counts before and after filtering.

n_genes_before, n_genes_after

Gene counts before and after filtering.

n_cells_removed_by_min_genes int

Cells dropped for expressing fewer than min_genes genes.

n_cells_removed_by_max_pct_mito int

Cells dropped for exceeding max_pct_mito mitochondrial percentage.

n_genes_removed_by_min_cells int

Genes dropped for being detected in fewer than min_cells cells.

cells_removed property

cells_removed: int

Total cells removed across all cell filters.

genes_removed property

genes_removed: int

Total genes removed.

__post_init__

__post_init__() -> None

Validate that the counts reconcile, failing loudly otherwise.

to_dict

to_dict() -> dict[str, int]

Return a plain-int dict, suitable for serialisation into .uns.

render

render() -> str

Return a multi-line, human-readable summary.

preprocess

preprocess(adata: AnnData, config: PreprocessConfig) -> anndata.AnnData

Run the full preprocessing pipeline: QC metrics, filtering, normalisation.

The supplied adata is annotated in place with QC metadata (matching Scanpy conventions and avoiding an unnecessary copy); callers who need the original untouched should pass adata.copy(). Filtering then produces a new object, which is normalised and returned.

QC metrics are always recomputed and overwritten deterministically -- if compute_qc_metrics has already been run on adata, its columns are regenerated, not skipped -- so the result never depends on prior state.

The QC summary is stored in serialisable form at result.uns[QC_SUMMARY_KEY] (a dict of integer counts) so it travels with the processed object (e.g. through write_h5ad) without changing this function's return type.

Parameters:

Name Type Description Default
adata AnnData

Raw-count single-cell data. Annotated in place with QC metadata; its expression values and dimensions are not modified.

required
config PreprocessConfig

Thresholds and options for QC filtering and normalisation.

required

Returns:

Type Description
AnnData

A new filtered and normalised dataset, with .uns[QC_SUMMARY_KEY] set and raw counts preserved in .layers[config.counts_layer].

compute_qc_metrics

compute_qc_metrics(adata: AnnData, config: PreprocessConfig) -> anndata.AnnData

Annotate per-cell and per-gene QC metrics in place.

Flags mitochondrial genes by config.mito_prefix and delegates metric computation to sc.pp.calculate_qc_metrics. No filtering is performed.

Parameters:

Name Type Description Default
adata AnnData

The dataset to annotate. Modified in place (.obs/.var only).

required
config PreprocessConfig

Supplies mito_prefix for identifying mitochondrial genes.

required

Returns:

Type Description
AnnData

The same adata instance, with QC columns added. In particular .var["mt"] and .obs["pct_counts_mt"].

filter_cells_and_genes

filter_cells_and_genes(adata: AnnData, config: PreprocessConfig) -> tuple[anndata.AnnData, QCSummary]

Filter low-quality cells and rarely-detected genes into a new AnnData.

Applies, in this order: min_genes per cell, max_pct_mito per cell, then min_cells per gene (gene support counted after cell filtering).

Parameters:

Name Type Description Default
adata AnnData

A dataset already annotated by :func:compute_qc_metrics. Not modified.

required
config PreprocessConfig

Supplies min_genes, max_pct_mito, and min_cells.

required

Returns:

Type Description
tuple[AnnData, QCSummary]

The filtered copy and a summary of what was removed.

Raises:

Type Description
ValueError

If QC metrics are absent (obs['pct_counts_mt'] missing).