scdecon.deconvolution¶
deconvolution ¶
Deconvolution: estimate cell-type proportions from bulk expression.
The solvers (:class:~scdecon.deconvolution.base.Solver, e.g.
:class:~scdecon.deconvolution.nnls.NNLSSolver,
:class:~scdecon.deconvolution.nusvr.NuSVRSolver,
:class:~scdecon.deconvolution.robust.RobustSolver) are format-agnostic and
operate purely on NumPy arrays. Aligning a labelled signature and bulk matrix onto
shared genes (:mod:scdecon.deconvolution.align) and orchestrating per-sample
solving into a labelled result
(:func:~scdecon.deconvolution.deconvolve.deconvolve) are separate, pandas-aware
concerns.
AlignedInputs
dataclass
¶
AlignedInputs(signature: NDArray[float64], bulk: NDArray[float64], genes: list[str], cell_types: list[str], sample_names: list[str])
Gene-aligned deconvolution inputs, ready for a :class:Solver.
Attributes:
| Name | Type | Description |
|---|---|---|
signature |
NDArray[float64]
|
Aligned signature matrix, shape |
bulk |
NDArray[float64]
|
Aligned bulk matrix, shape |
genes |
list[str]
|
Shared gene identifiers, in signature row order. |
cell_types |
list[str]
|
Cell-type labels (signature columns). |
sample_names |
list[str]
|
Bulk sample labels (bulk columns). |
Solver ¶
Bases: ABC
Abstract base class for deconvolution solvers.
A solver estimates the cell-type proportion vector p for a single bulk
sample by (approximately) solving b ~= S @ p subject to p >= 0 and
sum(p) == 1. Implementations must enforce both constraints as part of
their contract.
fit
abstractmethod
¶
Estimate cell-type proportions for one bulk sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
NDArray[float64]
|
Signature matrix of shape |
required |
bulk
|
NDArray[float64]
|
Bulk expression vector of shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Proportion vector of shape |
BenchmarkResult
dataclass
¶
Comparison of solvers over one shared pseudobulk set.
Composes the M5 :class:~scdecon.validation.ValidationReport per solver plus
a runtime; introduces no second reporting abstraction. Solver names are
exactly the caller-supplied mapping keys.
Attributes:
| Name | Type | Description |
|---|---|---|
reports |
Mapping[str, ValidationReport]
|
Solver name -> :class: |
runtimes |
Mapping[str, float]
|
Solver name -> wall-clock seconds for the solving loop (informational). |
to_frame ¶
Return the comparison table (index = solver names, exactly as given).
Columns: overall_rmse, mean_pearson, mean_spearman,
runtime_s.
best ¶
Return the name of the best solver by a metric.
Lower is better for overall_rmse and runtime_s; higher is better
for mean_pearson and mean_spearman.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
NNLSSolver ¶
Bases: Solver
Deconvolution via non-negative least squares (see module docstring).
fit ¶
Estimate cell-type proportions for one bulk sample.
Solves min ‖S x − b‖₂ subject to x ≥ 0 (scipy.optimize.nnls),
then normalises to Σ p = 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
NDArray[float64]
|
Signature matrix |
required |
bulk
|
NDArray[float64]
|
Bulk expression vector |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Proportion vector of shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If NNLS returns the all-zero solution (its coefficients sum to zero), which cannot be normalised into proportions. This typically means the bulk sample has ~zero expression on the signature genes, the signature and bulk are on incompatible scales, or gene alignment left almost no usable signal. Check that the bulk was preprocessed on the same scale as the signature and that gene identifiers match. |
NuSVRSolver ¶
Bases: Solver
Deconvolution via linear nu support-vector regression (see module docstring).
fit ¶
Estimate cell-type proportions for one bulk sample.
Fits a linear nu-SVR of bulk on signature's columns, then clips
negative coefficients to zero and renormalises to sum(p) == 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
NDArray[float64]
|
Signature matrix |
required |
bulk
|
NDArray[float64]
|
Bulk expression vector |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Proportion vector of shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If every coefficient is non-positive (nothing to normalise). Likely
causes mirror :class: |
NuSVRConfig
dataclass
¶
Configuration for :class:~scdecon.deconvolution.nusvr.NuSVRSolver.
Attributes:
| Name | Type | Description |
|---|---|---|
nu |
float
|
The |
RobustConfig
dataclass
¶
Configuration for :class:~scdecon.deconvolution.robust.RobustSolver.
Attributes:
| Name | Type | Description |
|---|---|---|
loss |
RobustLoss
|
Robust loss function (:class: |
f_scale |
float
|
The soft-margin scale of the robust loss ( |
RobustLoss ¶
Bases: StrEnum
Robust loss for :class:~scdecon.deconvolution.robust.RobustSolver.
Values are the loss names accepted by scipy.optimize.least_squares.
RobustSolver ¶
Bases: Solver
Deconvolution via robust non-negative least squares (see module docstring).
fit ¶
Estimate cell-type proportions for one bulk sample.
Solves min sum_g rho((S @ p - b)_g) subject to p >= 0 with a robust
loss, then renormalises to sum(p) == 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
NDArray[float64]
|
Signature matrix |
required |
bulk
|
NDArray[float64]
|
Bulk expression vector |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Proportion vector of shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the bulk has no positive expression to fit, or the solution is all zero (nothing to normalise). Unlike NNLS/nu-SVR -- whose solvers return exact zeros for a degenerate bulk -- the trust-region optimiser converges to a tiny non-zero interior point, so the degenerate case is caught at the input (a bulk with no positive signal) rather than only at the solution. |
align_signature_and_bulk ¶
align_signature_and_bulk(signature: DataFrame, bulk: DataFrame, *, min_overlap: float = DEFAULT_MIN_OVERLAP) -> AlignedInputs
Restrict a signature and bulk matrix to their shared genes.
Genes common to both are selected in signature row order (deterministic).
A warning is emitted if the fraction of signature genes found in the bulk
matrix falls below min_overlap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
DataFrame
|
Signature matrix (genes x cell types), gene-indexed. |
required |
bulk
|
DataFrame
|
Bulk expression matrix (genes x samples), gene-indexed. |
required |
min_overlap
|
float
|
Minimum fraction of signature genes that must be present in |
DEFAULT_MIN_OVERLAP
|
Returns:
| Type | Description |
|---|---|
AlignedInputs
|
Aligned NumPy arrays plus gene / cell-type / sample labels. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
run_benchmark ¶
run_benchmark(signature: DataFrame, bulk: DataFrame, truth: DataFrame, solvers: Mapping[str, Solver], *, min_overlap: float = DEFAULT_MIN_OVERLAP) -> BenchmarkResult
Benchmark solvers over one shared, once-aligned pseudobulk set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
DataFrame
|
Signature matrix (genes x cell types), gene-indexed. |
required |
bulk
|
DataFrame
|
Bulk expression matrix (genes x samples), gene-indexed. |
required |
truth
|
DataFrame
|
Ground-truth proportions (cell types x samples). |
required |
solvers
|
Mapping[str, Solver]
|
Mapping of caller-chosen name -> :class: |
required |
min_overlap
|
float
|
Passed to :func: |
DEFAULT_MIN_OVERLAP
|
Returns:
| Type | Description |
|---|---|
BenchmarkResult
|
Per-solver validation report and runtime. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |