Source code for mantispy.pp._names
"""Rename features to a canonical grammar."""
from __future__ import annotations
import numpy as np
import pandas as pd
from anndata import AnnData
from mantispy._core._utils import as_frame, inplace_or_copy
TARGETS = ("cp_measure",)
def _canonical(row: dict) -> str:
"""Rebuild a name from its parsed components, in cp_measure order."""
parts = [row["object"], row["feature_group"], row["feature"], row["channel"]]
tokens = [str(part) for part in parts if isinstance(part, str) and part]
for key in ("params", "radial_bin"):
if isinstance(row.get(key), str) and row[key]:
tokens.append(row[key])
return "_".join(tokens)
[docs]
@inplace_or_copy()
def standardize_feature_names(adata: AnnData, target: str = "cp_measure", copy: bool = False) -> AnnData | None:
"""Rename features to ``target`` grammar, keeping the original in ``var``.
CellProfiler feature names differ between versions, so renaming makes a dataset from
an older pipeline comparable with one from a newer pipeline.
Args:
adata: Object to rename.
target: Naming grammar. Only ``"cp_measure"`` is supported.
copy: Return a modified copy instead of mutating in place.
Returns:
``None``, or the modified copy. Writes ``var["original_name"]`` on the first call and
never overwrites it afterwards, so the incoming names survive repeated calls.
Raises:
ValueError: If ``target`` is not supported, or renaming would give two features the same
name (for example two Zernike orders).
"""
if target not in TARGETS:
raise ValueError(f"target must be one of {TARGETS}, got {target!r}")
if "original_name" not in adata.var:
adata.var["original_name"] = adata.var_names.to_numpy()
renamed = [
_canonical(row) if row["is_feature"] else name
for name, row in zip(adata.var_names, as_frame(adata.var).to_dict("records"), strict=True)
]
values, counts = np.unique(renamed, return_counts=True)
if (counts > 1).any():
raise ValueError(f"renaming would make these names collide: {values[counts > 1][:5].tolist()}")
adata.var_names = pd.Index(renamed) # type: ignore[assignment]
return None