Cliff
Class for detecting activity cliffs in a set of compounds based on their similarities and activities.
ActivityCliffs(id_a, id_b, similarity, pAct_diff, pAct_a, pAct_b, winning_type_a, winning_type_b, is_cross_type, is_low_quality, is_same_assay, involves_inactive, landscape_index, severity_label=None)
¶
Dataclass holding the results of one activity cliff detection pass over a set of compounds.
id_a
¶
The compound id of the first compound in the cliff pair.
id_b
¶
The compound id of the second compound in the cliff pair.
involves_inactive
¶
True when at least one compound is labelled inactive by its source assay. This indicates an active-vs-inactive cliff.
is_cross_type
¶
True when the two winning types differ between the two compounds in the cliff pair.
is_low_quality
¶
True if either compound failed the activity quality gate. These cliffs may rest on measurement noise and can be excluded downstream.
is_same_assay
¶
True when the two compounds share at least one assay id (a within-assay cliff, firmest ground). Cross-assay cliffs can carry a systematic offset.
landscape_index
¶
The computed value of the landscape index SALI or TS_SALI (per params.metric) for this pair. It is None only on the SALI branch at Tm == 1 (resolved during labelling by sali_undefined).
pAct_a
¶
pActivity of compound a.
pAct_b
¶
pActivity of compound b.
pAct_diff
¶
The absolute difference in pActivity between the two compounds in the cliff pair.
severity_label = None
¶
The severity label (EXTREME / STRONG / MODERATE) for this cliff pair. It is None until label_cliff_severity runs, or if the pair
was not part of the ranked population.
similarity
¶
The Tanimoto similarity between the two compounds in the cliff pair.
winning_type_a
¶
Winning assay type behind pAct_a.
winning_type_b
¶
Winning assay type behind pAct_b.
CliffParams(min_delta=2.0, min_similarity=0.55, metric=SeverityMetric.TS_SALI, ts_truncation=3, extreme_frac=0.01, strong_frac=0.05, sali_undefined=SaliUndefined.NEXT_LARGEST)
¶
Configuration for a single cliff detection and severity pass.
extreme_frac = 0.01
¶
Top fraction of ranked cliffs to be labelled EXTREME.
metric = SeverityMetric.TS_SALI
¶
Which landscape index to compute and rank by. Default is TS_SALI.
min_delta = 2.0
¶
Minimum absolute difference in pActivity for a pair to be considered a cliff. Default is 2.0 which means a 100-fold difference.
min_similarity = 0.55
¶
Minimum Tanimoto similarity for a pair to be considered a cliff. Default is 0.55.
sali_undefined = SaliUndefined.NEXT_LARGEST
¶
SALI only parameter identifying the policy for Tm == 1 pairs i.e, the undefined values.
strong_frac = 0.05
¶
Cumulative top fraction of ranked cliffs to be labelled at least STRONG.
ts_truncation = 3
¶
TS_SALI only parameter representing the Taylor order k. Default is 3, which is the original order used by López-Pérez, K., & Miranda-Quintana, R. A. (2025).
__post_init__()
¶
CliffResult(cliffs, params, n_undefined=0)
¶
The standardized output of a cliff pass. It contains the pairs and the params that produced them.
cliffs
¶
All detected cliff pairs, in detection order (all cliffs generated by find_activity_cliffs).
metric
¶
The landscape index that will be used to label the severity of the cliffs.
n_cliffs
¶
Number of cliff pairs.
n_undefined = 0
¶
Count of SALI-branch pairs undefined at Tm == 1. This would be 0 when using TS_SALI, or when the SALI branch had no Tm == 1 pairs.
params
¶
The configuration these cliffs has used to be detected and will be used to label severity. It is stored here for reproducibility.
severity_counts()
¶
Count of cliffs in each severity band where unlabelled pairs are ignored.
CliffSeverity
¶
SaliUndefined
¶
Bases: StrEnum
Enum to declare how the SALI severity metric resolves pairs that are undefined at Tanimoto similarity (Tm) == 1.
EXCLUDE = 'exclude'
¶
Drop undefined pairs from the ranking where their severity_label remains None. This was also used in the original Guha & Van Drie (2008) paper, but it is not recommended because it discards potentially important extreme cliffs.
MAX_SEVERITY = 'max_severity'
¶
Rank undefined pairs above all finite ones by assigning them to infinity. As by definition,a Tm = 1 pair with a large activity gap is an extreme cliff where the same structure (based on the fingerprint), yet different activity. Thus, it should outrank even the largest finite SALI, not merely tie it.
NEXT_LARGEST = 'next_largest'
¶
Replace the undefined value with the largest finite SALI in the ranked set as described by Guha & Van Drie (2008). This is the default policy.
SeverityMetric
¶
Bases: StrEnum
Enum to declare which landscape index to use for severity ranking.
SALI = 'sali'
¶
This is the classic Structure-activity landscape index (SALI) introduced by Guha and Van Drie in 2008. It is undefined at Tanimoto similarity (Tm) == 1,
so the user must choose a policy for how to handle those undefined pairs. by declaring the sali_undefined parameter in CliffParams.
TS_SALI = 'ts_sali'
¶
Taylor-series Structure-activity landscape index (SALI). It is introduced by López-Pérez, K., & Miranda-Quintana, R. A. (2025). It is a taylor series expansion version of the classic SALI that is finite everywhere. It is the default metric.
find_activity_cliffs(sims, activity, params=CliffParams())
¶
Detect activity cliffs in a set of compounds based on their similarities and activities.
| PARAMETER | DESCRIPTION |
|---|---|
sims
|
Output of
TYPE:
|
activity
|
A dictionary with the compound ids as the keys and their
TYPE:
|
params
|
the
TYPE:
|
Returns:
A CliffResult holding the detected cliffs; severity labels are None until
label_cliff_severity is called.
high_confidence(c)
¶
Check whether a cliff is high-confidence, i.e. both compounds passed the quality gate and share a winning type.
| PARAMETER | DESCRIPTION |
|---|---|
c
|
The cliff pair to test.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if both compounds passed the quality gate and share a winning type. |
high_confidence_cliffs(cliffs)
¶
Filter a list of cliffs to only those that are high confidence, i.e. both compounds passed the quality gate and share a winning type.
| PARAMETER | DESCRIPTION |
|---|---|
cliffs
|
The full list from
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ActivityCliffs]
|
Only the cliffs where both compounds passed the quality gate and share a winning type. |
label_cliff_severity(result, restrict=None)
¶
Assign severity level by ranking the cliffs based on their landscape index.
| PARAMETER | DESCRIPTION |
|---|---|
result
|
The
TYPE:
|
restrict
|
A rule to filter the cliffs to be ranked. If true only cliffs that meet the criteria will be labelled. If None, all cliffs will be ranked.
TYPE:
|
Returns:
A new CliffResult with severity_label filled on the ranked cliffs.
same_assay(c)
¶
Check if a cliff pair is within-assay, i.e. the two compounds share at least one assay id.
| PARAMETER | DESCRIPTION |
|---|---|
c
|
The cliff pair to test.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the two compounds share at least one assay id. |
same_assay_cliffs(cliffs)
¶
Filter a list of cliffs to only within-assay pairs.
| PARAMETER | DESCRIPTION |
|---|---|
cliffs
|
The full list of cliffs identified in the detection pass, including cross-assay pairs.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ActivityCliffs]
|
Only the cliffs whose two compounds share at least one assay id. |