iscc.data.estimate_visium ¶
Method-of-moments estimate_visium() for the Visium assay.
The spatial analogue of the scRNA estimate() and DNA estimate_dna(): fits the technical
hyper-parameters of the spatial batch model (VisiumBatchHyperParams in batch.py) from a
real Visium AnnData reduced
to per-spot counts + spot coordinates — so realistic spatial-technical magnitudes are learned,
not guessed. The fitted VisiumBatchHyperParams drive Visium directly (same field names).
This is not ABC: every fitted Visium parameter maps to a marginal / spatial summary statistic, so estimation is closed-form / 1-D curve-fit — fast and simulation-free (ABC stays for the biology).
What is fit (and from what):
mu_counts mean per-spot library size (total UMIs / spot) (always)
sigma_counts NON-spatial (nugget) part of the per-spot log-library sd (always)
field_sigma SPATIAL (autocorrelated) part of the per-spot log-library (always)
sd — the capture-field strength
field_lengthscale capture-field autocorrelation scale: squared-exponential (always)
length-scale fit of the per-spot library-size residual
autocorrelation (Moran's-I correlogram / variogram range)
kappa (dm) per-spot count overdispersion (DM concentration) (always)
nb_dispersion (nb) per-spot count overdispersion phi (NB) (count_model=nb)
sigma_batch per-gene cross-section log-fold-change scale (needs >=2 sections)
The headline decomposition. The per-spot library total is mu_counts * field_s * noise_s with
field_s the spatially-autocorrelated capture field (mean 1) and noise_s the i.i.d. LogNormal
depth noise. So the variance of log(total) splits into a SPATIAL part (the field, recovered as
the autocorrelation amplitude a at zero lag) and a NON-SPATIAL nugget (the i.i.d. noise,
1-a): field_sigma = sqrt(a * Var[log total]), sigma_counts = sqrt((1-a) * Var[log total]).
This is exactly what separates the spatial technical layer from the per-spot depth noise — the
spatial analogue of the scRNA estimator's library-size de-biasing of the dispersion.
The _PRIOR_ONLY escape (as in estimate/estimate_dna) carries the genuinely
unidentifiable-from-one-section fields honestly: ambient_frac (needs off-tissue/background
spots), edge_sigma and diffusion_sigma (confounded with biology in a single section), and
sigma_batch on single-section data (the per-gene factor is constant within a section, so it is
confounded with the true expression — identifiable only across >=2 sections, exactly as the scRNA
estimator needs >=2 batches).
numpy / scipy only (no JAX / R); stateless and config-driven.
Classes:
| Name | Description |
|---|---|
VisiumEstimate |
Fitted Visium technical parameters, ready to drive |
Functions:
| Name | Description |
|---|---|
estimate_visium |
Fit |
estimate_visium_from_assay |
Fit from a run |
VisiumEstimate
dataclass
¶
VisiumEstimate(hypers: VisiumBatchHyperParams, count_model: str, n_spots: int, n_genes: int, n_sections: int, spots_per_tissue: int, occupied_fraction: float, fitted: list, diagnostics: dict = dict())
Fitted Visium technical parameters, ready to drive Visium(...).
hypers is a VisiumBatchHyperParams with the fitted magnitudes; visium_kwargs()
returns the hyper fields (minus count_model, an explicit assay constructor arg) as a kwargs
dict, so the fit splats straight back into the assay without redefinition. fitted lists the
fields actually learned; everything else is carried from the preset and flagged honestly.
spots_per_tissue / occupied_fraction are spatial-extent diagnostics (not hyper fields).
Methods:
| Name | Description |
|---|---|
visium_kwargs |
Hyper-parameter overrides to splat into |
visium_kwargs ¶
Hyper-parameter overrides to splat into Visium (minus count_model).
count_model is an explicit assay constructor arg, so drive the assay as
Visium(count_model=est.count_model, **est.visium_kwargs()).
estimate_visium ¶
estimate_visium(adata, *, count_model='dm', coords=None, section_labels=None, occupied_fraction=None)
Fit VisiumBatchHyperParams from a real Visium AnnData (MoM / curve-fit).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adata
|
AnnData | DataFrame | ndarray
|
Per-spot integer counts, spots x genes (raw, not normalized). |
required |
count_model
|
(dm, nb)
|
Count emission (chosen). Selects |
"dm"
|
coords
|
array | None
|
Per-spot |
None
|
section_labels
|
sequence | None
|
Per-spot section label. With >=2 sections, |
None
|
occupied_fraction
|
float | None
|
Fraction of laid spots that are on-tissue. Defaults to the fraction of non-empty spots
(spots with >0 counts). Sets |
None
|
Returns:
| Type | Description |
|---|---|
VisiumEstimate
|
|
estimate_visium_from_assay ¶
Fit from a run Visium instance (extracts per-spot counts + coords + occupancy).
The synthetic recovery convenience: pulls the spot count matrix, the spot coordinates, and the
on-tissue fraction straight from the run assay, then defers to :func:estimate_visium.