mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
Deterministic kekulize, independent of atom and bond order (#9125)
* Make kekulization deterministic * Add tautomer order-independence regression (python) * Adjust tautomer tests for deterministic kekulization * Update graphmol wedged-bond kekulization checks * SmilesParse: update aromatic bond index expectations * SmilesParse: refresh cxsmilesTest expected files * Depictor: update testDepictor expected MolBlocks * Depictor: update depictorCatch expectations * Depictor Wrap: update expected MolBlock for pyDepictor * MarvinParse: update testMrvToMol expected outputs * FileParsers: refresh testAtropisomers expected outputs * FileParsers: update tests for deterministic kekulization * MolDraw2D: refresh brittle bond assertions * RascalMCES: update expected cluster size * MinimalLib: make cffi wedging check order-independent * documentation fix * MinimalLib: update Kekulé bond table in aligned-coords test * Hoist duplicated lambdas to TEST_CASE scope * Remove unused originalWedges variable * Remove redundant bounds check; clarify wedge-end preference * Pre-sort allAtms by wedge-end + rank * Use mol.atomNeighbors() for neighbor iteration * Check inAllAtms before linear-scanning done * Drop redundant optsV/wedgedOptsV sorts * Remove unused Canon.h include * Add canonical parameter to Kekulize; skip ranking during sanitization * Test canonical re-kekulization preserves stereo across atom orderings * MinimalLib: update Kekulé bond orders in invertedWedges * Change Kekulize canonical default to false, expose in Python wrappers * keep rank order, push_back * Revert "RascalMCES: update expected cluster size" This reverts commita81bb39495. * docstring change * expose new flag to python wrapper * document changes in ReleaseNotes.md * revert minimallib test changes again * canonical = true defaults * Revert "revert minimallib test changes again" This reverts commit039e1d84da. * Reapply "RascalMCES: update expected cluster size" This reverts commit7b83a7a3e8. --------- Co-authored-by: greg landrum <greg.landrum@gmail.com>
This commit is contained in:
@@ -195,6 +195,30 @@ double angle_deg_between_vectors(double *v1, double *v2) {
|
||||
(v2[0] * v2[0] + v2[1] * v2[1])));
|
||||
}
|
||||
|
||||
static int molblock_has_wedge_lines(const char *molblock,
|
||||
const char *expected_bond_table) {
|
||||
// expected_bond_table is a list of bond lines like:
|
||||
// " 2 1 1 6\n 2 3 1 0\n ...".
|
||||
// Only require that each wedge/dash bond line (bond_dir != 0) appears
|
||||
// somewhere in the molblock. This is order-independent but still brittle.
|
||||
if (!molblock || !expected_bond_table) {
|
||||
return 0;
|
||||
}
|
||||
char *dup = strdup(expected_bond_table);
|
||||
assert(dup);
|
||||
for (char *line = strtok(dup, "\n"); line; line = strtok(NULL, "\n")) {
|
||||
int a1 = 0, a2 = 0, btype = 0, bdir = 0;
|
||||
if (sscanf(line, "%d %d %d %d", &a1, &a2, &btype, &bdir) == 4 && bdir != 0) {
|
||||
if (!strstr(molblock, line)) {
|
||||
free(dup);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(dup);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void test_io() {
|
||||
char *pkl;
|
||||
char *pkl2;
|
||||
@@ -1583,12 +1607,12 @@ M END\n",
|
||||
10 12 1 0\n\
|
||||
6 12 1 6\n\
|
||||
2 13 1 0\n\
|
||||
13 14 2 0\n\
|
||||
14 15 1 0\n\
|
||||
15 16 2 0\n\
|
||||
16 17 1 0\n\
|
||||
17 18 2 0\n\
|
||||
13 18 1 0\n\
|
||||
13 14 1 0\n\
|
||||
14 15 2 0\n\
|
||||
15 16 1 0\n\
|
||||
16 17 2 0\n\
|
||||
17 18 1 0\n\
|
||||
13 18 2 0\n\
|
||||
17 19 1 0\n\
|
||||
19 20 1 0\n\
|
||||
20 21 1 0\n\
|
||||
@@ -1681,7 +1705,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
double v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 10.0 && v1v2Theta < 15.0);
|
||||
assert(strstr(molblock, inverted_wedges));
|
||||
assert(molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
@@ -1708,7 +1732,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 105.0 && v1v2Theta < 110.0);
|
||||
assert(strstr(molblock, inverted_wedges));
|
||||
assert(molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
@@ -1737,7 +1761,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 145.0 && v1v2Theta < 150.0);
|
||||
assert(!strstr(molblock, inverted_wedges));
|
||||
assert(!molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
@@ -1813,7 +1837,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
double v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 10.0 && v1v2Theta < 15.0);
|
||||
assert(strstr(molblock, inverted_wedges));
|
||||
assert(molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
@@ -1839,7 +1863,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 105.0 && v1v2Theta < 110.0);
|
||||
assert(!strstr(molblock, inverted_wedges));
|
||||
assert(!molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
@@ -1868,7 +1892,7 @@ M END\n",
|
||||
v2[1] = xy25[1] - xy26[1];
|
||||
v1v2Theta = angle_deg_between_vectors(v1, v2);
|
||||
assert(v1v2Theta > 145.0 && v1v2Theta < 150.0);
|
||||
assert(!strstr(molblock, inverted_wedges));
|
||||
assert(!molblock_has_wedge_lines(molblock, inverted_wedges));
|
||||
free(mpkl_copy);
|
||||
free(molblock);
|
||||
free(svg);
|
||||
|
||||
@@ -719,12 +719,12 @@ M END
|
||||
-3.4910 1.0942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
1.7051 1.0942 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
-3.4910 -1.9059 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
1 2 2 0
|
||||
2 3 1 0
|
||||
3 4 2 0
|
||||
4 5 1 0
|
||||
5 6 2 0
|
||||
6 1 1 0
|
||||
1 2 1 0
|
||||
2 3 2 0
|
||||
3 4 1 0
|
||||
4 5 2 0
|
||||
5 6 1 0
|
||||
6 1 2 0
|
||||
6 8 1 0
|
||||
3 9 1 0
|
||||
2 7 1 0
|
||||
@@ -1556,12 +1556,12 @@ M END
|
||||
10 12 1 0
|
||||
6 12 1 6
|
||||
2 13 1 0
|
||||
13 14 2 0
|
||||
14 15 1 0
|
||||
15 16 2 0
|
||||
16 17 1 0
|
||||
17 18 2 0
|
||||
13 18 1 0
|
||||
13 14 1 0
|
||||
14 15 2 0
|
||||
15 16 1 0
|
||||
16 17 2 0
|
||||
17 18 1 0
|
||||
13 18 2 0
|
||||
17 19 1 0
|
||||
19 20 1 0
|
||||
20 21 1 0
|
||||
|
||||
Reference in New Issue
Block a user