grassp.tl.mgsa_to_cluster_distribution

grassp.tl.mgsa_to_cluster_distribution#

mgsa_to_cluster_distribution(posterior, map_matrix=None, use_map=True, unknown_label='unknown', inactivity='product', drop_empty=True)[source]#

Convert a per-cluster MGSA posterior matrix into a soft-label distribution.

MGSA returns per-set marginal activity probabilities q_t (each in [0, 1]; several compartments can be active simultaneously), whereas the soft-label seed used by soft_cluster_annotation() is a per-cluster distribution over compartments (plus an explicit unknown class) that sums to 1.

The recommended mode (use_map=True) uses the MAP active set as a filter and the marginals as weights: only compartments in the MAP (the single best joint configuration) receive mass, weighted by their marginals. This is important because a completely redundant subset term (e.g. Nucleolus inside an active Nucleus) has a marginal equal to the prior activation rate p — it is never in the MAP, so the filter removes that ≈p residual that would otherwise inflate the distribution. With use_map=False all marginals are used (the residuals leak in).

After (optional) MAP masking, Q[c, t] q_t and the leftover mass goes to unknown via the probability that no (admissible) compartment is active:

  • inactivity="product" (default): unknown ∏_t (1 - q_t) (over the admissible sets; an independence approximation of “no set active”).

  • inactivity="complement": unknown 1 - max_t q_t.

everything renormalized so each cluster row sums to 1. A confidently single-compartment cluster becomes peaked, a genuine multi-compartment MAP is split by its marginals (equal marginals -> uniform), and a cluster with an empty MAP / nothing active puts its mass on unknown.

Parameters:
posterior DataFrame

(cluster x compartment) matrix of MGSA marginal activity probabilities, as produced by calculate_mgsa() (data.uns[..._posterior]).

map_matrix DataFrame | None (default: None)

(cluster x compartment) 0/1 indicator of the MAP active set per cluster (data.uns[..._map]). Required when use_map=True.

use_map bool (default: True)

If True (default) mask the marginals to the MAP active set before building the distribution, removing redundant-subset ≈p residuals.

unknown_label str | None (default: 'unknown')

Name of the background/unknown class, or None to omit it.

inactivity Literal['product', 'complement'] (default: 'product')

How to compute the unknown/inactivity mass (see above).

drop_empty bool (default: True)

Drop compartments that never carry mass, tightening the vocabulary.

Return type:

tuple[DataFrame, list[str]]

Returns:

Qpandas.DataFrame

Row-stochastic (cluster x category) matrix, unknown last if present.

categorieslist of str

Column order, suitable as seed_categories for competitive_propagation().