Before running LIANA+ methods, ensure your data is in the correct format. LIANA+ typically expects non-negative, library-size normalised, log1p expression in .X or a specified layer.
Important Data Checks:
- Negative Values: Single-cell methods will raise a
ValueError if the input matrix contains negative values (e.g., scaled or z-scored data). Use raw or log-normalised counts instead. - Log-transformation: If values are too large (max > ~709), it may indicate the data was not log-transformed correctly, which can cause overflows during log-fold-change calculations.
- Spatial Data: If using spatial methods, ensure coordinate information is present in
obsm['spatial'].
Use the following snippet to inspect your object's structure, modalities, and expression ranges:
import anndata as ad, mudata as mu, numpy as np
a = mu.read(path) if path.endswith(".h5mu") else ad.read_h5ad(path)
print(type(a).__name__, a.shape, "mods:", list(getattr(a, "mod", {})))
for c in a.obs.columns:
if a.obs[c].dtype.kind not in "biuf":
u = a.obs[c].unique()
print(c, len(u), list(u[:6]))
print("obsm:", list(a.obsm), "obsp:", list(a.obsp), "uns:", list(a.uns))
d = lambda M: M.toarray() if hasattr(M, "toarray") else np.asarray(M)
for name, m in (a.mod.items() if hasattr(a, "mod") else [("", a)]):
X = d(m.X[:200])
print(name, "layers:", list(m.layers), "X min/max:", X.min(), X.max(),
"integer-like:", np.allclose(X, X.round()), "var sample:", list(m.var_names[:5]))
if m.raw is not None:
R = d(m.raw.X[:200])
print(name, "raw min/max:", R.min(), R.max(), "(negative = scaled, do not use)")
if "spatial" in a.obsm:
print(
"coords min/max:",
a.obsm["spatial"].min(0),
a.obsm["spatial"].max(0),
"uns spatial:",
list(a.uns.get("spatial", {})),
)