Skip to content

Commit 8606791

Browse files
committed
Classify a reaction directly from AMChIs
1 parent 020be14 commit 8606791

File tree

4 files changed

+41
-5
lines changed

4 files changed

+41
-5
lines changed

src/automol/graph/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
# # isomorphisms and equivalence
5757
# submodules:
5858
from .base import enum, ts, vmat
59+
from .base import ReactionSmarts
5960

6061
# # getters
6162
# # setters

src/automol/graph/base/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# # constructors
2929
# submodules:
3030
from . import enum, ts, vmat
31+
from .enum import ReactionSmarts
3132

3233
# # getters
3334
# # setters

src/automol/reac/enum.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Functions for enumerating reactions."""
22

3-
from collections.abc import Callable, Mapping, Sequence
3+
from collections.abc import Callable, Mapping, Sequence, Collection
44

55
from .. import amchi, graph, smiles
66
from .. import smarts as smarts_
@@ -67,6 +67,40 @@ def from_graphs(
6767
return rxns
6868

6969

70+
def classify_from_amchis(
71+
class_smarts: dict[str, str], rct_chis: Sequence[str], prd_chis: Collection[str]
72+
) -> str | None:
73+
"""Classify a reaction by matching it to a set of SMARTS templates.
74+
75+
:param class_smarts: Dictionary mapping class names to SMARTS strings
76+
:param rct_chis: Reactant ChIs
77+
:param prd_chis: Product ChIs
78+
:return: Class name or None if no match is found
79+
"""
80+
if any(map(amchi.has_stereo, rct_chis)) or any(map(amchi.has_stereo, prd_chis)):
81+
msg = f"Cannot match SMARTS for AMChIs with stereo:\n{rct_chis} = {prd_chis}"
82+
raise ValueError(msg)
83+
84+
comp_prd_chis = set(prd_chis)
85+
86+
# Prepare reactants graph
87+
rct_gras = [graph.explicit(amchi.graph(c)) for c in rct_chis]
88+
rct_gras, _ = graph.standard_keys_for_sequence(rct_gras)
89+
rcts_gra = graph.union_from_sequence(rct_gras)
90+
91+
for class_, smarts in class_smarts.items():
92+
# Enumerate reactions
93+
ts_gras = graph.enum.reactions(smarts, rcts_gra)
94+
for ts_gra in ts_gras:
95+
prds_gra = graph.ts.products_graph(ts_gra, stereo=False, dummy=False)
96+
prd_gras = graph.connected_components(prds_gra)
97+
prd_chis = set(map(graph.amchi, prd_gras))
98+
if prd_chis == comp_prd_chis:
99+
return class_
100+
101+
return None
102+
103+
70104
# helpers
71105
def reactants(
72106
smarts: str,

src/automol/smarts/_core.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ def shape(smarts: str) -> tuple[list[int], list[int]]:
1313
return rd.shape(rd.from_smarts(smarts))
1414

1515

16-
def reactant_count(smarts: str) -> tuple[list[int], list[int]]:
16+
def reactant_count(smarts: str) -> int:
1717
"""Get number of reactants in SMARTS string.
1818
1919
:param smarts: SMARTS string
20-
:return: Reaction shape
20+
:return: Reactant count
2121
"""
2222
return rd.reactant_count(rd.from_smarts(smarts))
2323

2424

25-
def product_count(smarts: str) -> tuple[list[int], list[int]]:
25+
def product_count(smarts: str) -> int:
2626
"""Get number of products in SMARTS string.
2727
2828
:param smarts: SMARTS string
29-
:return: Reaction shape
29+
:return: Product count
3030
"""
3131
return rd.product_count(rd.from_smarts(smarts))

0 commit comments

Comments
 (0)