Source code for cycombinepy.preprocessing
"""Preprocessing utilities: asinh transform with optional derandomization."""
from __future__ import annotations
from typing import Iterable
import numpy as np
from anndata import AnnData
from cycombinepy._utils import marker_matrix, resolve_markers, set_marker_matrix
[docs]
def transform_asinh(
adata: AnnData,
markers: Iterable[str] | None = None,
cofactor: float = 5.0,
derand: bool = True,
reverse: bool = False,
layer: str | None = None,
copy: bool = False,
seed: int | None = None,
) -> AnnData | None:
"""Asinh-transform marker columns of ``adata`` with an optional derandomization step.
Port of ``transform_asinh`` in ``R/01_prepare_data.R:375``. Derandomization mirrors
``randomize_matrix`` in ``R/utils_helper.R``: take ``ceil(x)`` then subtract a
uniform draw on ``[0, 0.9999]`` before the asinh.
Parameters
----------
adata
AnnData with raw expression in ``adata.X`` (or ``adata.layers[layer]``).
markers
Var names to transform. If ``None``, uses :func:`cycombinepy.get_markers`.
cofactor
Asinh cofactor. Common values: 5 (CyTOF), 150 (flow), 6000 (spectral).
derand
If True, apply the derandomization before asinh.
reverse
If True, apply ``sinh(x) * cofactor`` instead (inverse transform).
layer
If given, read / write that layer instead of ``adata.X``.
copy
If True, return a copy; otherwise modify in place and return None.
seed
Seed for derandomization RNG.
"""
markers = resolve_markers(adata, markers)
if copy:
adata = adata.copy()
X = marker_matrix(adata, markers, layer=layer)
if reverse:
X = np.sinh(X) * cofactor
else:
if derand:
rng = np.random.default_rng(seed)
X = np.ceil(X) - rng.uniform(0.0, 0.9999, size=X.shape)
X[X < 0] = 0.0
X = np.arcsinh(X / cofactor)
set_marker_matrix(adata, markers, X, layer=layer)
return adata if copy else None