Skip to content

Commit 7ad1148

Browse files
authored
Merge pull request #1622 from haddocking/capri-ranking
Corrected ranking in caprieval for reverse sorting - Issue #1621
2 parents 0d0852c + 29efa80 commit 7ad1148

3 files changed

Lines changed: 60 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
=======
4+
- 2026-07-10: Corrected ranking in caprieval for reverse sorting - Issue #1621
45
- 2026-07-09: Added `deeprank` scoring module using deeprank-gnn-esm - Issue #569
56
- 2026-07-07: Re-add `gdock` as a sampling module
67
- 2026-07-02: Added support 1-O-methyl-2-N-Acetyl-alpha-D-galactopyranose (NGM) - Issue #1608

src/haddock/libs/libcapri.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,10 @@ def rank_according_to_score(
748748
its rank based on the 'score'.
749749
"""
750750
score_rankkey_values = [(k, v["score"]) for k, v in data.items()]
751-
score_rankkey_values.sort(key=lambda x: x[1])
751+
score_rankkey_values.sort(
752+
key=lambda x: x[1],
753+
reverse=True if not sort_ascending else False,
754+
)
752755

753756
for i, k in enumerate(score_rankkey_values):
754757
data_idx, _ = k
@@ -969,7 +972,10 @@ def capri_cluster_analysis(
969972

970973
# Rank according to the score
971974
score_rankkey_values = [(key, v["score"]) for key, v in output_dic.items()]
972-
score_rankkey_values.sort(key=lambda x: x[1])
975+
score_rankkey_values.sort(
976+
key=lambda x: x[1],
977+
reverse=True if not sort_ascending else False,
978+
)
973979
for i, k in enumerate(score_rankkey_values):
974980
idx, _ = k
975981
output_dic[idx]["caprieval_rank"] = i + 1

tests/test_module_caprieval.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from haddock.libs.libcapri import (
1010
CAPRI,
1111
capri_cluster_analysis,
12+
rank_according_to_score,
1213
)
1314
from haddock.modules.analysis.caprieval.capri import get_previous_cns_step
1415

@@ -203,6 +204,9 @@ def test_capri_cluster_analysis(protprot_caprimodule, protprot_input_list, monke
203204
path=Path("."),
204205
)
205206

207+
# With sort_ascending=False the caprieval_rank is assigned by score in
208+
# descending order, so the highest-scoring cluster (id 2, score 50) is
209+
# ranked first.
206210
observed_outf_l = read_capri_file("capri_clt.txt")
207211
expected_outf_l = [
208212
[
@@ -219,6 +223,8 @@ def test_capri_cluster_analysis(protprot_caprimodule, protprot_input_list, monke
219223
"lrmsd_std",
220224
"dockq",
221225
"dockq_std",
226+
"ilrmsd",
227+
"ilrmsd_std",
222228
"rmsd",
223229
"rmsd_std",
224230
"caprieval_rank",
@@ -237,9 +243,11 @@ def test_capri_cluster_analysis(protprot_caprimodule, protprot_input_list, monke
237243
"0.000",
238244
"nan",
239245
"nan",
246+
"4.300",
247+
"0.000",
240248
"0.010",
241249
"0.000",
242-
"2",
250+
"1",
243251
],
244252
[
245253
"1",
@@ -255,11 +263,52 @@ def test_capri_cluster_analysis(protprot_caprimodule, protprot_input_list, monke
255263
"0.000",
256264
"nan",
257265
"nan",
266+
"4.300",
267+
"0.000",
258268
"0.010",
259269
"0.000",
260-
"1",
270+
"2",
261271
],
262272
]
273+
assert observed_outf_l == expected_outf_l
274+
275+
276+
def test_rank_according_to_score_ascending():
277+
"""Test that the lowest score is ranked first when sort_ascending is True."""
278+
data = {
279+
0: {"score": 42.0, "irmsd": 1.0},
280+
1: {"score": 50.0, "irmsd": 2.0},
281+
2: {"score": 10.0, "irmsd": 3.0},
282+
}
283+
ranked = rank_according_to_score(data, sort_key="score", sort_ascending=True)
284+
285+
# Returned dict is keyed by rank (1..n) in ascending score order
286+
assert [v["score"] for v in ranked.values()] == [10.0, 42.0, 50.0]
287+
# caprieval_rank follows the score: lowest score gets rank 1
288+
assert ranked[1]["score"] == 10.0
289+
assert ranked[1]["caprieval_rank"] == 1
290+
assert ranked[2]["caprieval_rank"] == 2
291+
assert ranked[3]["score"] == 50.0
292+
assert ranked[3]["caprieval_rank"] == 3
293+
294+
295+
def test_rank_according_to_score_descending():
296+
"""Test that the highest score is ranked first when sort_ascending is False."""
297+
data = {
298+
0: {"score": 42.0, "irmsd": 1.0},
299+
1: {"score": 50.0, "irmsd": 2.0},
300+
2: {"score": 10.0, "irmsd": 3.0},
301+
}
302+
ranked = rank_according_to_score(data, sort_key="score", sort_ascending=False)
303+
304+
# Returned dict is keyed by rank (1..n) in descending score order
305+
assert [v["score"] for v in ranked.values()] == [50.0, 42.0, 10.0]
306+
# caprieval_rank follows the score: highest score gets rank 1
307+
assert ranked[1]["score"] == 50.0
308+
assert ranked[1]["caprieval_rank"] == 1
309+
assert ranked[2]["caprieval_rank"] == 2
310+
assert ranked[3]["score"] == 10.0
311+
assert ranked[3]["caprieval_rank"] == 3
263312

264313

265314
def test_get_previous_cns_step():

0 commit comments

Comments
 (0)