Skip to content

Commit

Permalink
update new features
Browse files Browse the repository at this point in the history
  • Loading branch information
TieuLongPhan committed Nov 25, 2024
1 parent 9db18e8 commit d78aa0b
Show file tree
Hide file tree
Showing 15 changed files with 680 additions and 32 deletions.
97 changes: 97 additions & 0 deletions Test/SynAAM/test_aam_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import unittest
from synutility.SynAAM.aam_validator import AAMValidator


class TestAMMValidator(unittest.TestCase):

def setUp(self):
self.true_pair = (
(
"[CH:8]=1[S:9][CH:10]=[C:6]([C:5]#[C:4][CH2:3][N:2]([C:11]2=[CH:12]"
+ "[CH:13]=[CH:14][CH:15]=[CH:16]2)[CH3:1])[CH:7]=1.[OH2:17]>>[C:5]([N:2]"
+ "([CH3:1])[C:11]1=[CH:12][CH:13]=[CH:14][CH:15]=[CH:16]1)([C:6]2="
+ "[CH:10][S:9][CH:8]=[CH:7]2)=[CH:4][CH:3]=[O:17]"
),
(
"[OH2:17].[cH:12]1[cH:13][cH:14][cH:15][cH:16][c:11]1[N:2]([CH3:1])"
+ "[CH2:3][C:4]#[C:5][c:6]1[cH:10][s:9][cH:8][cH:7]1>>[cH:12]1[cH:13]"
+ "[cH:14][cH:15][cH:16][c:11]1[N:2]([CH3:1])[C:5](=[CH:4][CH:3]=[O:17])"
+ "[c:6]1[cH:10][s:9][cH:8][cH:7]1"
),
)
self.false_pair = (
(
"[CH:8]=1[S:9][CH:10]=[C:6]([C:5]#[C:4][CH2:3][N:2]([C:11]2=[CH:12]"
+ "[CH:13]=[CH:14][CH:15]=[CH:16]2)[CH3:1])[CH:7]=1.[OH2:17]>>[C:5]"
+ "([N:2]([CH3:1])[C:11]1=[CH:12][CH:13]=[CH:14][CH:15]=[CH:16]1)"
+ "([C:6]2=[CH:10][S:9][CH:8]=[CH:7]2)=[CH:4][CH:3]=[O:17]"
),
(
"[CH3:1][N:2]([CH2:3][C:4]#[C:5][c:7]1[cH:8][cH:9][s:10][cH:11]1)"
+ "[c:12]1[cH:13][cH:14][cH:15][cH:16][cH:17]1.[OH2:6]>>[CH3:1][N:2]"
+ "([C:3](=[CH:4][CH:5]=[O:6])[c:7]1[cH:8][cH:9][s:10][cH:11]1)"
+ "[c:12]1[cH:13][cH:14][cH:15][cH:16][cH:17]1"
),
)
self.tautomer = (
"[CH3:1][C:2](=[O:3])[OH:4].[CH3:5][CH2:6][OH:7]>>[CH3:1][C:2](=[O:3])"
+ "[O:7][CH2:6][CH3:5].[OH2:4]",
"[CH3:1][C:2](=[O:3])[OH:4].[CH3:5][CH2:6][OH:7]>>"
+ "[CH3:1][C:2](=[O:4])[O:7][CH2:6][CH3:5].[OH2:3]",
)

self.data_dict_1 = {"ref": self.true_pair[0], "map": self.true_pair[1]}
self.data_dict_2 = {"ref": self.false_pair[0], "map": self.false_pair[1]}
self.data_dict_3 = {"ref": self.tautomer[0], "map": self.tautomer[1]}
self.data = [self.data_dict_1, self.data_dict_2, self.data_dict_3]

def test_smiles_check(self):

self.assertTrue(
AAMValidator.smiles_check(
*self.true_pair, check_method="RC", ignore_aromaticity=False
)
)
self.assertFalse(
AAMValidator.smiles_check(
*self.false_pair, check_method="RC", ignore_aromaticity=False
)
)

def test_smiles_check_tautomer(self):
self.assertFalse(
AAMValidator.smiles_check(
self.tautomer[0],
self.tautomer[1],
check_method="RC",
ignore_aromaticity=False,
)
)

self.assertTrue(
AAMValidator.smiles_check_tautomer(
self.tautomer[0],
self.tautomer[1],
check_method="RC",
ignore_aromaticity=True,
)
)

def test_validate_smiles_dataframe(self):

results = AAMValidator.validate_smiles(
data=self.data,
ground_truth_col="ref",
mapped_cols=["map"],
check_method="RC",
ignore_aromaticity=False,
n_jobs=2,
verbose=0,
ignore_tautomers=False,
)
self.assertEqual(results[0]["accuracy"], 66.67)
self.assertEqual(results[0]["success_rate"], 100)


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest
import networkx as nx
from synutility.SynIO.Format.its_construction import ITSConstruction
from synutility.SynAAM.its_construction import ITSConstruction


class TestITSConstruction(unittest.TestCase):
Expand Down
94 changes: 94 additions & 0 deletions Test/SynIO/Format/test_chemcal_conversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import unittest
import networkx as nx

from synutility.SynChem.Reaction.standardize import Standardize
from synutility.SynIO.Format.chemical_conversion import (
smiles_to_graph,
rsmi_to_graph,
graph_to_rsmi,
smart_to_gml,
gml_to_smart,
)

from synutility.SynGraph.Morphism.misc import rule_isomorphism


class TestChemicalConversions(unittest.TestCase):

def setUp(self) -> None:
self.rsmi = "[CH2:1]([H:4])[CH2:2][OH:3]>>[CH2:1]=[CH2:2].[H:4][OH:3]"
self.gml = (
"rule [\n"
' ruleID "rule"\n'
" left [\n"
' edge [ source 1 target 4 label "-" ]\n'
' edge [ source 1 target 2 label "-" ]\n'
' edge [ source 2 target 3 label "-" ]\n'
" ]\n"
" context [\n"
' node [ id 1 label "C" ]\n'
' node [ id 4 label "H" ]\n'
' node [ id 2 label "C" ]\n'
' node [ id 3 label "O" ]\n'
" ]\n"
" right [\n"
' edge [ source 1 target 2 label "=" ]\n'
' edge [ source 4 target 3 label "-" ]\n'
" ]\n"
"]"
)

self.std = Standardize()

def test_smiles_to_graph_valid(self):
# Test converting a valid SMILES to a graph
result = smiles_to_graph("[CH3:1][CH2:2][OH:3]", False, True, True)
self.assertIsInstance(result, nx.Graph)
self.assertEqual(result.number_of_nodes(), 3)

def test_smiles_to_graph_invalid(self):
# Test converting an invalid SMILES string to a graph
result = smiles_to_graph("invalid_smiles", True, False, False)
self.assertIsNone(result)

def test_rsmi_to_graph_valid(self):
# Test converting valid reaction SMILES to graphs for reactants and products
reactants_graph, products_graph = rsmi_to_graph(self.rsmi, sanitize=True)
self.assertIsInstance(reactants_graph, nx.Graph)
self.assertEqual(reactants_graph.number_of_nodes(), 3)
self.assertIsInstance(products_graph, nx.Graph)
self.assertEqual(products_graph.number_of_nodes(), 3)

reactants_graph, products_graph = rsmi_to_graph(self.rsmi, sanitize=False)
self.assertIsInstance(reactants_graph, nx.Graph)
self.assertEqual(reactants_graph.number_of_nodes(), 4)
self.assertIsInstance(products_graph, nx.Graph)
self.assertEqual(products_graph.number_of_nodes(), 4)

def test_rsmi_to_graph_invalid(self):
# Test handling of invalid RSMI format
result = rsmi_to_graph("invalid_format")
self.assertEqual((None, None), result)

def test_graph_to_rsmi(self):
r, p = rsmi_to_graph(self.rsmi, sanitize=False)
rsmi = graph_to_rsmi(r, p)
self.assertIsInstance(rsmi, str)
self.assertEqual(self.std.fit(rsmi, False), self.std.fit(self.rsmi, False))

def test_smart_to_gml(self):
result = smart_to_gml(self.rsmi, core=False, sanitize=False, reindex=False)
self.assertIsInstance(result, str)
self.assertEqual(result, self.gml)

result = smart_to_gml(self.rsmi, core=False, sanitize=False, reindex=True)
self.assertTrue(rule_isomorphism(result, self.gml))

def test_gml_to_smart(self):
smarts, _ = gml_to_smart(self.gml)
self.assertIsInstance(smarts, str)
self.assertEqual(self.std.fit(smarts, False), self.std.fit(self.rsmi, False))


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit d78aa0b

Please sign in to comment.