grassp.tl.resolve_soft_labels

grassp.tl.resolve_soft_labels#

resolve_soft_labels(data, prob_key, categories_key=None, seed_key=None, obsp_key=None, method=None, iterative=None, alpha=None, max_iter=30, rtol=0.0001, unknown_label='unknown', unknown_gate=0.5, null='permutation', n_permutations=1000, alpha_fdr=0.05, renormalize_class_mass=True, multi_label_cum=0.8, single_eff_k=1.5, eff_k_max=3.0, max_labels=3, min_secondary_mass=0.2, canonical_order=False, key_added=None, random_state=0, set_colors=True, inplace=True)[source]#

Resolve soft propagated probabilities into single / multi / unresolved labels.

A single min_probability cutoff on the top propagated probability cannot tell apart two opposite cases: a protein in an unresolved region (mass smeared over many compartments) and a genuine intermediate (mass concentrated on 2-3 clean compartments). Both have a low top probability, but the shape of the distribution differs. This function decides using the entropy of the propagated distribution, compared to a per-protein null.

For each protein it computes the Shannon entropy H of the propagated distribution over real compartments (unknown excluded and handled by a separate gate); the effective number of compartments is exp(H). It then tests H against a null in which the protein carries no local structure:

  • null="permutation" (default): randomly permute which seed vector sits on which protein, keep the graph fixed, re-propagate with the same math, recompute H. Repeated n_permutations times this gives a per-protein null entropy distribution (preserving graph geometry, each protein’s effective neighbourhood size, the class-balance normalization and the global class prior). A left-tail p-value is BH-FDR adjusted.

  • null="analytic": a fast approximation using the population mean seed and each protein’s effective neighbour count n_eff (E[H|H0] ≈ H(π̄) - (k-1)/(2 n_eff) with a delta-method variance), avoiding permutations.

  • null=None: no test; a protein is resolved iff exp(H) <= eff_k_max.

Decision per protein: unknown_mass >= unknown_gate -> unresolved; else a significantly-low entropy (q < alpha_fdr) -> single (exp(H) < single_eff_k) or multi; otherwise unresolved. For resolved proteins the emitted compartment set is the smallest reaching cumulative mass multi_label_cum.

Parameters:
data AnnData

AnnData carrying the propagated probabilities in data.obsm[prob_key] and the matching category order in data.uns[categories_key].

prob_key str

obsm key with the (n_obs, n_categories) propagated probability matrix (e.g. "ann_soft_probabilities").

categories_key str | None (default: None)

uns key with the ordered category names for the columns of prob_key. Optional: when prob_key is a labelled DataFrame (everything grassp writes via set_matrix()) its own column names are used, and this is only needed for bare arrays written by older versions.

seed_key str | None (default: None)

obsm key with the soft seed matrix; required when null="permutation".

obsp_key str | None (default: None)

Affinity graph used for re-propagating the null. None (default) takes it from the annotation’s own uns[f"{key}_params"], so the null sees the graph the annotator saw.

method Optional[Literal['propagation', 'spreading']] (default: None)

Propagation settings for the null. None takes each from the annotation’s recorded parameters, which is what makes the null test the same math that produced the probabilities. Give them explicitly to override.

iterative bool | None (default: None)

Propagation settings for the null. None takes each from the annotation’s recorded parameters, which is what makes the null test the same math that produced the probabilities. Give them explicitly to override.

alpha float | None (default: None)

Propagation settings for the null. None takes each from the annotation’s recorded parameters, which is what makes the null test the same math that produced the probabilities. Give them explicitly to override.

max_iter int (default: 30)

Propagation settings for the null. None takes each from the annotation’s recorded parameters, which is what makes the null test the same math that produced the probabilities. Give them explicitly to override.

rtol float (default: 0.0001)

Propagation settings for the null. None takes each from the annotation’s recorded parameters, which is what makes the null test the same math that produced the probabilities. Give them explicitly to override.

unknown_label str | None (default: 'unknown')

Name of the background/unknown category in the vocabulary, or None if there is no such class. Used both to exclude it from the entropy and as a gate.

unknown_gate float (default: 0.5)

Proteins with unknown mass at or above this are called unresolved outright.

null Optional[Literal['permutation', 'analytic']] (default: 'permutation')

Null model, number of permutations, and FDR level (see above).

n_permutations int (default: 1000)

Null model, number of permutations, and FDR level (see above).

alpha_fdr float (default: 0.05)

Null model, number of permutations, and FDR level (see above).

renormalize_class_mass bool (default: True)

Must match the setting used to produce prob_key so the null re-propagation is faithful. It is recorded in uns[f"{key}_params"] by the annotators.

multi_label_cum float (default: 0.8)

Cumulative probability mass used to select how many compartments to emit for the detailed multiloc_label.

single_eff_k float (default: 1.5)

exp(H) below this is labelled single, otherwise multi.

eff_k_max float (default: 3.0)

Only used when null=None: resolved iff exp(H) <= eff_k_max.

max_labels int (default: 3)

Hard cap on the number of compartments in the compact label_compact.

min_secondary_mass float (default: 0.2)

A secondary compartment is only added to label_compact if it holds at least this probability mass. This is what suppresses gene-set-overlap tails (e.g. a 0.16 Lipid-droplet share on ER proteins) and keeps the number of distinct compact labels small.

canonical_order bool (default: False)

If True, sort the compartments in label_compact alphabetically so that "A; B" and "B; A" collapse into one plot category (drops primary ordering). Default False keeps the primary compartment first.

key_added str | None (default: None)

Output prefix in .obs. Defaults to f"{prob_key}_resolved".

random_state int (default: 0)

Seed for the permutation null.

set_colors bool (default: True)

If True (default), assign consistent compartment colours to the emitted label columns via set_sensible_compartment_colors(), so the same compartment renders identically here and in other annotation columns. Ignored when inplace=False.

inplace bool (default: True)

If True (default) write results to data; otherwise return a dict.

Returns:

None or dict Writes obs[key] (primary label / NaN), obs[key+"_multiloc"] (bool), obs[key+"_multiloc_label"] (detailed "A; B" string from the cumulative-mass rule), obs[key+"_label_compact"] (plot-friendly label: primary + secondaries above min_secondary_mass, capped at max_labels) and obs[key+"_multiloc_compact"] (bool), obs[key+"_secondary"], obs[key+"_type"] and diagnostics _entropy, _eff_k, _zscore, _qvalue, _unknown_mass; a null summary in uns[key+"_null"].