Skip to content

Commit

Permalink
Backmegre: #1533 System attach two explicit hydrogens to atoms connec…
Browse files Browse the repository at this point in the history
…ted to "any type" bonds (#1612) (#1708)
  • Loading branch information
AliaksandrDziarkach authored Feb 16, 2024
1 parent 414bfaa commit 3bd1ae6
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 15 deletions.
8 changes: 4 additions & 4 deletions api/tests/integration/ref/arom/arom_d_orbital.py.out
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
*** 0 ***
COC(c1[n]2s(c3c(c4c2cccc4)cccc3)(C(C)C)c1C(OC)=O)=O
element: can not calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
element: cannot calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
COC(c1[n]2s(c3c(c4c2cccc4)cccc3)(C(C)C)c1C(OC)=O)=O
element: can not calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
element: cannot calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
*** 1 ***
COC(C1N2S(C3C(C4C2=CC=CC=4)=CC=CC=3)(C(C)C)C=1C(OC)=O)=O
CC(C)S12C(=C(C(=O)OC)N1C1=CC=CC=C1C1=CC=CC=C21)C(=O)OC
COC(C1N2S(C3C(C4C2=CC=CC=4)=CC=CC=3)(C(C)C)C=1C(OC)=O)=O
CC(C)S12C(=C(C(=O)OC)N1C1=CC=CC=C1C1=CC=CC=C21)C(=O)OC
*** 2 ***
COC(C1[n]2s(c3c(c4c2cccc4)cccc3)(C(C)C)C=1C(OC)=O)=O
element: can not calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
element: cannot calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
COC(C1[n]2s(c3c(c4c2cccc4)cccc3)(C(C)C)C=1C(OC)=O)=O
element: can not calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
element: cannot calculate implicit hydrogens on aromatic S, charge 0, degree 4, 0 radical electrons
*** 3 ***
COC(c1[n]2s(C3C(C4C2=CC=CC=4)=CC=CC=3)(C(C)C)c1C(OC)=O)=O
CC(C)[s]12c(c(C(=O)OC)[n]1C1=CC=CC=C1C1=CC=CC=C21)C(=O)OC
Expand Down
59 changes: 59 additions & 0 deletions api/tests/integration/ref/basic/fold_unfold.py.out
Original file line number Diff line number Diff line change
Expand Up @@ -1316,3 +1316,62 @@ testing query [2H]C
testing query N#CC(C#N)=C1C([H])=C([H])C(=C(C#N)C#N)C([H])=C1[H] |t:4,10|
20
16
testing query c1ccccc1
12
6
testing query CCC
11
3
testing smarts c1ccccc1
12
6
testing smarts CCC
11
3
testing smarts C-C-C
11
3
testing query
Bond Single or Double 1252422 22D 1 1.00000 0.00000 0

2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 5 0 0 0
M END

2
2
testing query
Bond Single or Aromatic 1252422 22D 1 1.00000 0.00000 0

2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 6 0 0 0
M END

2
2
testing query
Bond Double or Aromatic 1252422 22D 1 1.00000 0.00000 0

2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 7 0 0 0
M END

2
2
testing query
Bond Any 1252422 22D 1 1.00000 0.00000 0

2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 8 0 0 0
M END

2
2
8 changes: 4 additions & 4 deletions api/tests/integration/ref/basic/validate.py.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
** 0 **
Exception: element: can not calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
Exception: element: cannot calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons

False
Cc1cccc[n]1
Expand Down Expand Up @@ -29,11 +29,11 @@ False
CC1NC=C(O)N=1
False
** 5 **
Exception: element: can not calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
Exception: element: cannot calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
dearomatization: non-unique dearomatization: Dearomatization is not unique. Cannot restore hydrogens.
Exception: element: can not calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
Exception: element: cannot calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
Exception: dearomatization: non-unique dearomatization: Dearomatization is not unique. Cannot restore hydrogens.
Exception: element: can not calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
Exception: element: cannot calculate implicit hydrogens on aromatic N, charge 0, degree 2, 0 radical electrons
** 6 **
True
element: bad valence on H having 1 drawn bonds, charge 1, and 0 radical electrons
Expand Down
56 changes: 56 additions & 0 deletions api/tests/integration/tests/basic/fold_unfold.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ def testFoldUnfoldSingleQueryMol(smiles):
print(mol2.countAtoms())


def testFoldUnfoldSMARTS(smarts):
print("testing smarts " + smarts)
mol = indigo.loadSmarts(smarts)
mol.unfoldHydrogens()
print(mol.countAtoms())
mol.foldHydrogens()
print(mol.countAtoms())


def testFoldUnfoldSingleReaction(smiles):
print("testing " + smiles)
rxn = indigo.loadReaction(smiles)
Expand Down Expand Up @@ -103,3 +112,50 @@ def testFoldUnfoldQueryReaction(smiles):
testFoldUnfoldSingleQueryMol(
"N#CC(C#N)=C1C([H])=C([H])C(=C(C#N)C#N)C([H])=C1[H] |t:4,10|"
)

testFoldUnfoldSingleQueryMol("c1ccccc1")
testFoldUnfoldSingleQueryMol("CCC")
testFoldUnfoldSMARTS("c1ccccc1")
testFoldUnfoldSMARTS("CCC")
testFoldUnfoldSMARTS("C-C-C")

mol = """
Bond Single or Double 1252422 22D 1 1.00000 0.00000 0
2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 5 0 0 0
M END
"""
testFoldUnfoldSingleQueryMol(mol)
mol = """
Bond Single or Aromatic 1252422 22D 1 1.00000 0.00000 0
2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 6 0 0 0
M END
"""
testFoldUnfoldSingleQueryMol(mol)
mol = """
Bond Double or Aromatic 1252422 22D 1 1.00000 0.00000 0
2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 7 0 0 0
M END
"""
testFoldUnfoldSingleQueryMol(mol)
mol = """
Bond Any 1252422 22D 1 1.00000 0.00000 0
2 1 0 0 0 0 0 0 0 0999 V2000
2.9920 -1.4500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.8580 -0.9500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 8 0 0 0
M END
"""
testFoldUnfoldSingleQueryMol(mol)
2 changes: 1 addition & 1 deletion bingo/tests/data/reactions/checkreaction/std.json
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@
{
"query_id": 206,
"query_type": "checkreaction",
"expected": "element: can not calculate implicit hydrogens on aromatic C, charge 0, degree 1, 0 radical electrons"
"expected": "element: cannot calculate implicit hydrogens on aromatic C, charge 0, degree 1, 0 radical electrons"
},
{
"query_id": 207,
Expand Down
2 changes: 1 addition & 1 deletion core/indigo-core/molecule/src/molecule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ int Molecule::_getImplicitHForConnectivity(int idx, int conn, bool use_cache)
if (_ignore_bad_valence)
impl_h = 0;
else
throw Element::Error("can not calculate implicit hydrogens on aromatic %s, charge %d, degree %d, %d radical electrons",
throw Element::Error("cannot calculate implicit hydrogens on aromatic %s, charge %d, degree %d, %d radical electrons",
Element::toString(atom.number), atom.charge, getVertex(idx).degree(), Element::radicalElectrons(radical));
}
}
Expand Down
21 changes: 16 additions & 5 deletions core/indigo-core/molecule/src/query_molecule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2434,16 +2434,25 @@ int QueryMolecule::getAtomTotalH(int idx)
int QueryMolecule::_calcAtomConnectivity(int idx)
{
const Vertex& vertex = getVertex(idx);
int i, conn = 0;
int i = 0, conn = 0;
bool was_aromatic = false;
int atom_aromaticy = -1;
// Smarts treat default bond as SINGLE_OR_AROMATIC so for this bonds look to atom aromaticy
if (original_format == SMARTS)
{
std::ignore = getAtom(idx).sureValue(ATOM_AROMATICITY, atom_aromaticy);
}

for (i = vertex.neiBegin(); i != vertex.neiEnd(); i = vertex.neiNext(i))
{
int order = getBondOrder(vertex.neiEdge(i));
if (order < 0)
order = getQueryBondType(getBond(vertex.neiEdge(i)));

if (order == BOND_SINGLE || order == BOND_DOUBLE || order == BOND_TRIPLE)
if (order == BOND_SINGLE || order == BOND_DOUBLE || order == BOND_TRIPLE ||
(original_format == SMARTS && order == _BOND_SINGLE_OR_AROMATIC && atom_aromaticy == ATOM_ALIPHATIC))
conn += order;
else if (order == BOND_AROMATIC || order == _BOND_SINGLE_OR_AROMATIC || order == _BOND_DOUBLE_OR_AROMATIC)
else if (order == BOND_AROMATIC || (original_format == SMARTS && order == _BOND_SINGLE_OR_AROMATIC && atom_aromaticy == ATOM_AROMATIC))
{
conn += 1;
if (was_aromatic)
Expand All @@ -2457,9 +2466,9 @@ int QueryMolecule::_calcAtomConnectivity(int idx)
}
}
else
conn += 1;
return -1;
}
if (was_aromatic)
if (was_aromatic) // +1 connection for odd aromatic bond
conn += 1;
return conn;
}
Expand Down Expand Up @@ -3215,6 +3224,8 @@ int QueryMolecule::getImplicitH(int idx, bool /*impl_h_no_throw*/)
// If implicit h is not set - calculate it
int max_h = 0;
int conn = _calcAtomConnectivity(idx);
if (conn < 0) // can't calculate - no implicit H
return 0;
if (properties.count(ATOM_TOTAL_H) > 0)
max_h = properties[ATOM_TOTAL_H]->value_min - getAtomConnectedH(idx);
else
Expand Down

0 comments on commit 3bd1ae6

Please sign in to comment.