Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid splitting reaction SMILES at dative bonds #30

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/rxn/chemutils/extended_reaction_smiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def convert(
if remove_atom_maps:
pure_smiles = remove_atom_mapping(pure_smiles)

reactant_groups = pure_smiles.split(">")
# We split at the ">" characters, only if they are not preceded by a "-",
# which would indicate a dative bond.
reactant_groups = re.split(r"(?<!-)>", pure_smiles)
mols_groups = [group.split(".") for group in reactant_groups]
mols_groups = [[mol for mol in group if mol] for group in mols_groups]

Expand Down
5 changes: 4 additions & 1 deletion src/rxn/chemutils/reaction_equation.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
from functools import partial
from typing import (
Callable,
Expand Down Expand Up @@ -75,9 +76,11 @@ def from_string(
Convert a ReactionEquation from an "rxn" reaction SMILES.
"""

# We split at the ">" characters, only if they are not preceded by a "-",
# which would indicate a dative bond.
groups = [
multicomponent_smiles_to_list(smiles_group, fragment_bond=fragment_bond)
for smiles_group in reaction_string.split(">")
for smiles_group in re.split(r"(?<!-)>", reaction_string)
]

try:
Expand Down
14 changes: 14 additions & 0 deletions tests/test_extended_reaction_smiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ def test_from_reaction_smiles_with_fragments() -> None:
assert reaction.products == ["OC1=CC=C2C3=C(C(=O)OC2=C1)C=C(COC)C=C3"]


def test_from_reaction_smiles_with_dative_bond() -> None:
reaction_smiles = "COC(=O)CCBr.O=C[O-]->[K+].[OH-].[Na+]>>COC(=O)CCOC(=O)C |f:2.3|"

reaction = parse_extended_reaction_smiles(reaction_smiles)

assert reaction.reactants == [
"COC(=O)CCBr",
"O=C[O-]->[K+]",
"[OH-].[Na+]",
]
assert reaction.agents == []
assert reaction.products == ["COC(=O)CCOC(=O)C"]


def test_from_reaction_smiles_with_other_extended_information() -> None:
# the part with "&1:", "c:", "H:", must not be considered for determination of fragments
reaction_smiles = (
Expand Down
15 changes: 15 additions & 0 deletions tests/test_reaction_equation.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ def test_equation_from_string_with_no_agent() -> None:
assert reaction == expected_reaction


def test_equation_from_string_with_dative_bond() -> None:
reaction_string = "COC(=O)CCBr.O=C([O-]->[K+])>>COC(=O)CCOC(=O)C"

reaction = ReactionEquation.from_string(reaction_string)

expected_reactants = ["COC(=O)CCBr", "O=C([O-]->[K+])"]
expected_agents: List[str] = []
expected_products = ["COC(=O)CCOC(=O)C"]
expected_reaction = ReactionEquation(
expected_reactants, expected_agents, expected_products
)

assert reaction == expected_reaction


def test_iter_all_smiles() -> None:
reaction_string = "COCO.[Na+].[OH-]>O>NCOC"
reaction = ReactionEquation.from_string(reaction_string)
Expand Down
Loading