grassp.tl.enrichment_to_cluster_distribution#
- enrichment_to_cluster_distribution(enr_res, cluster_key='leiden', ranking_metric='Adjusted P-value Bonferroni', threshold=0.05, temperature=1.0, s0=0.0, s_max=300.0, unknown_label='unknown', weight_by='evidence')[source]#
Turn a per-cluster enrichment table into soft label distributions.
The default annotation pipeline assigns each cluster its single most significant term (a hard, one-hot label). This discards the fact that a cluster may be only marginally enriched, or enriched for several terms of near-equal significance. When such a hard label is subsequently propagated over the neighbour graph (
competitive_propagation()) it produces over-confident, and often wrong, annotations in poorly resolved regions.This function instead converts the full per-(cluster, term) enrichment table into a probability distribution over a shared compartment vocabulary, with an explicit
unknownclass that absorbs uncertainty. The resulting distribution can be broadcast to proteins and used as a soft seed forcompetitive_propagation()(seesoft_cluster_annotation()).For every cluster
cand termtan evidence score is computed as\[s(c, t) = \mathrm{clip}\bigl(\log_{10}(\text{threshold} / p_{\text{adj}}(c, t)),\; 0,\; s_{\max}\bigr)\]so that a term sitting exactly at
thresholdcontributes zero evidence, stronger enrichment contributes more (up tos_max), and only terms withp_adj <= thresholdcount. Probabilities follow a tempered softmax with an explicit unknown logits0:w(c, t) = exp(s(c, t) / temperature) for significant terms w(c, unknown) = exp(s0 / temperature) Q[c, :] = w / w.sum()
With the defaults (
s0 = 0) the unknown class ties a term that is only marginally significant, so weakly/ambiguously enriched clusters keep most of their mass onunknowninstead of committing to a wrong label. Astemperature -> 0the distribution collapses onto the single best term, recovering the behaviour of the hard pipeline.- Parameters:
- enr_res
DataFrame Per-(cluster, term) enrichment table as returned by
calculate_cluster_enrichment()(return_enrichment_res=True). Must contain the columns"Term",ranking_metricandcluster_key.- cluster_key
str(default:'leiden') Name of the column in
enr_resholding the cluster labels.- ranking_metric
Literal['Adjusted P-value','Adjusted P-value Bonferroni','P-value'] (default:'Adjusted P-value Bonferroni') p-value column used as the evidence metric. Defaults to
"Adjusted P-value Bonferroni"(corrected for both term- and cluster-multiplicity), matching the pipeline default.- threshold
float(default:0.05) Significance threshold. Terms with
ranking_metric > threshold(or missing) are treated as non-significant and contribute no evidence.- temperature
float(default:1.0) Softmax temperature. Larger values give more diffuse distributions;
temperature -> 0approaches winner-take-all.- s0
float(default:0.0) Evidence logit assigned to the
unknownclass.0(default) corresponds to a hypothetical term sitting exactly atthreshold.- s_max
float(default:300.0) Upper cap on the per-term evidence score
log10(threshold/padj). Its only role is to bound a literalpadj == 0(which would giveinf); it must stay well above realistic-log10(padj)values. The default300is effectively “off”. Do not set this small: a small cap collapses the evidence of any two strongly-enriched terms to equal, producing spurious ties between a compartment and an overlapping one (e.g. Lysosome/Endosome, 40S ribosome/Nucleolus).- weight_by
Literal['evidence','odds_ratio'] (default:'evidence') How admissible (significant) terms are weighted against each other:
"evidence"(default): logit is the clippedlog10(threshold/padj)evidence score — confidence-weighted, size-dependent."odds_ratio": logit islnof the Haldane-Anscombe odds ratio (gseapy’s already-HA-corrected"Odds Ratio"column). Effect-size weighted and size-independent, soP(A)/P(B) = (OR_A/OR_B)^(1/T). The p-value still gates which terms are admissible; only significant terms contribute regardless of this setting.
- unknown_label
str|None(default:'unknown') Name of the appended background/unknown category. If
None, no unknown class is added: the distribution is purely relative over significant terms and clusters with no significant term receive a uniform fallback (which propagates to a high-entropy, unresolved distribution). Provided mainly to ablate the value of the unknown class against the entropy-null resolver.
- enr_res
- Return type:
- Returns:
- Qpandas.DataFrame
Row-stochastic matrix indexed by cluster label, with one column per compartment in the vocabulary (plus
unknown_labelas the final column unlessunknown_label is None). Each row sums to 1.- categorieslist of str
The ordered column vocabulary (significant terms, plus
unknown_labellast unless it isNone), suitable asseed_categoriesforcompetitive_propagation().