aamutils 0.0.7__tar.gz → 0.0.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {aamutils-0.0.7 → aamutils-0.0.9}/PKG-INFO +14 -2
  2. {aamutils-0.0.7 → aamutils-0.0.9}/README.md +13 -0
  3. aamutils-0.0.9/aamutils/aam_expand.py +58 -0
  4. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/utils.py +12 -5
  5. {aamutils-0.0.7 → aamutils-0.0.9}/pyproject.toml +1 -1
  6. aamutils-0.0.9/test/test_aam_expand.py +36 -0
  7. {aamutils-0.0.7 → aamutils-0.0.9}/.github/workflows/publish-package.yml +0 -0
  8. {aamutils-0.0.7 → aamutils-0.0.9}/.github/workflows/test-and-lint.yml +0 -0
  9. {aamutils-0.0.7 → aamutils-0.0.9}/.gitignore +0 -0
  10. {aamutils-0.0.7 → aamutils-0.0.9}/LICENSE +0 -0
  11. {aamutils-0.0.7 → aamutils-0.0.9}/Makefile +0 -0
  12. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/__init__.py +0 -0
  13. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/__main__.py +0 -0
  14. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/algorithm/__init__.py +0 -0
  15. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/algorithm/aaming.py +0 -0
  16. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/algorithm/ilp.py +0 -0
  17. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/cmd/__init__.py +0 -0
  18. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/cmd/expanding.py +0 -0
  19. {aamutils-0.0.7 → aamutils-0.0.9}/aamutils/mapping.py +0 -0
  20. {aamutils-0.0.7 → aamutils-0.0.9}/benchmark.py +0 -0
  21. {aamutils-0.0.7 → aamutils-0.0.9}/conf.py +0 -0
  22. {aamutils-0.0.7 → aamutils-0.0.9}/data/test_dataset.json +0 -0
  23. {aamutils-0.0.7 → aamutils-0.0.9}/doc/getting_started.rst +0 -0
  24. {aamutils-0.0.7 → aamutils-0.0.9}/doc/reference.rst +0 -0
  25. {aamutils-0.0.7 → aamutils-0.0.9}/index.rst +0 -0
  26. {aamutils-0.0.7 → aamutils-0.0.9}/lint.sh +0 -0
  27. {aamutils-0.0.7 → aamutils-0.0.9}/make.bat +0 -0
  28. {aamutils-0.0.7 → aamutils-0.0.9}/requirements.txt +0 -0
  29. {aamutils-0.0.7 → aamutils-0.0.9}/test/__init__.py +0 -0
  30. {aamutils-0.0.7 → aamutils-0.0.9}/test/algorithm/__init__.py +0 -0
  31. {aamutils-0.0.7 → aamutils-0.0.9}/test/algorithm/test_aaming.py +0 -0
  32. {aamutils-0.0.7 → aamutils-0.0.9}/test/algorithm/test_ilp.py +0 -0
  33. {aamutils-0.0.7 → aamutils-0.0.9}/test/test_mapping.py +0 -0
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aamutils
3
- Version: 0.0.7
3
+ Version: 0.0.9
4
4
  Summary: Collection of atom-atom-mapping utility functions.
5
5
  Project-URL: homepage, https://github.com/klausweinbauer/AAMUtils
6
6
  Project-URL: source, https://github.com/klausweinbauer/AAMUtils
7
7
  Project-URL: issues, https://github.com/klausweinbauer/AAMUtils/issues
8
8
  Author-email: Klaus Weinbauer <klaus@bioinf.uni-leipzig.de>
9
- License-File: LICENSE
10
9
  Classifier: License :: OSI Approved :: MIT License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Classifier: Programming Language :: Python :: 3
@@ -35,6 +34,8 @@ pip install aamutils
35
34
 
36
35
  ## Usage
37
36
 
37
+ ### Use in command line
38
+
38
39
  The input is a list of partial atom-atom-maps (AAMs). Data is read line-by-line
39
40
  from a text file. Each line should contain one reaction SMILES.
40
41
 
@@ -69,6 +70,17 @@ cat testinput_extended.json
69
70
  }
70
71
  ]
71
72
  ```
73
+ ### Use in script
74
+ ```python
75
+ from aamutils.aam_expand import extend_aam_from_rsmi
76
+
77
+ rsmi = "CC[CH2:3][Cl:1].[N:2]>>CC[CH2:3][N:2].[Cl:1]"
78
+
79
+ result_smiles = extend_aam_from_rsmi(rsmi)
80
+
81
+ print(result_smiles)
82
+ >>> "[Cl:1][CH2:3][CH2:5][CH3:4].[NH3:2]>>[ClH:1].[NH2:2][CH2:3][CH2:5][CH3:4]"
83
+ ```
72
84
 
73
85
  ## Benchmark
74
86
 
@@ -13,6 +13,8 @@ pip install aamutils
13
13
 
14
14
  ## Usage
15
15
 
16
+ ### Use in command line
17
+
16
18
  The input is a list of partial atom-atom-maps (AAMs). Data is read line-by-line
17
19
  from a text file. Each line should contain one reaction SMILES.
18
20
 
@@ -47,6 +49,17 @@ cat testinput_extended.json
47
49
  }
48
50
  ]
49
51
  ```
52
+ ### Use in script
53
+ ```python
54
+ from aamutils.aam_expand import extend_aam_from_rsmi
55
+
56
+ rsmi = "CC[CH2:3][Cl:1].[N:2]>>CC[CH2:3][N:2].[Cl:1]"
57
+
58
+ result_smiles = extend_aam_from_rsmi(rsmi)
59
+
60
+ print(result_smiles)
61
+ >>> "[Cl:1][CH2:3][CH2:5][CH3:4].[NH3:2]>>[ClH:1].[NH2:2][CH2:3][CH2:5][CH3:4]"
62
+ ```
50
63
 
51
64
  ## Benchmark
52
65
 
@@ -0,0 +1,58 @@
1
+ import networkx as nx
2
+ import rdkit.Chem.rdmolfiles as rdmolfiles
3
+ from aamutils.algorithm.ilp import expand_partial_aam_balanced
4
+ from aamutils.utils import smiles_to_graph, graph_to_mol, set_aam
5
+
6
+
7
+ def extend_aam_from_graph(G: nx.Graph, H: nx.Graph) -> str:
8
+ """
9
+ Extends atom-atom mappings (AAM) from two input graphs,
10
+ G (reactants) and H (products),by solving the AAM problem using an
11
+ Integer Linear Programming (ILP) approach and generating
12
+ a reaction SMILES (RSMI) string.
13
+
14
+ Parameters:
15
+ - G (nx.Graph): Graph representing the reactants.
16
+ Nodes should contain necessary attributes for AAM.
17
+ - H (nx.Graph): Graph representing the products.
18
+ Nodes should contain necessary attributes for AAM.
19
+
20
+ Returns:
21
+ - str: A reaction SMILES string (RSMI) in the format 'reactant>>product'
22
+ with extended atom mappings.
23
+ """
24
+ # Solve the partial AAM problem using ILP and retrieve the mapping matrix
25
+ M, _, _ = expand_partial_aam_balanced(G, H)
26
+
27
+ # Apply the AAM matrix to the graphs
28
+ set_aam(G, H, M)
29
+
30
+ # Convert the modified graphs back to RDKit molecules
31
+ r_mol = graph_to_mol(G)
32
+ p_mol = graph_to_mol(H)
33
+
34
+ # Generate reaction SMILES string from the RDKit molecules
35
+ result_smiles = "{}>>{}".format(
36
+ rdmolfiles.MolToSmiles(
37
+ r_mol, canonical=True, kekuleSmiles=False, allHsExplicit=True
38
+ ),
39
+ rdmolfiles.MolToSmiles(
40
+ p_mol, canonical=True, kekuleSmiles=False, allHsExplicit=True
41
+ ),
42
+ )
43
+ return result_smiles
44
+
45
+
46
+ def extend_aam_from_rsmi(rsmi: str) -> str:
47
+ """
48
+ Extends atom-atom mappings (AAM) from a reaction SMILES (RSMI) string,
49
+ and returns the resulting reaction SMILES string.
50
+
51
+ Parameters:
52
+ - rsmi (str): A reaction SMILES string in the format 'reactant>>product'.
53
+
54
+ Returns:
55
+ - str: A reaction SMILES string with extended atom mappings.
56
+ """
57
+ G, H = smiles_to_graph(rsmi)
58
+ return extend_aam_from_graph(G, H)
@@ -17,7 +17,10 @@ def mol_to_graph(mol: Chem.rdchem.Mol) -> nx.Graph:
17
17
  g = nx.Graph()
18
18
  for atom in mol.GetAtoms():
19
19
  aam = atom.GetAtomMapNum()
20
- g.add_node(atom.GetIdx(), symbol=atom.GetSymbol(), aam=aam)
20
+ formal_charge = atom.GetFormalCharge() # Get the formal charge of the atom
21
+ g.add_node(
22
+ atom.GetIdx(), symbol=atom.GetSymbol(), aam=aam, formal_charge=formal_charge
23
+ ) # Store formal charge
21
24
  for bond in mol.GetBonds():
22
25
  bond_type = str(bond.GetBondType()).split(".")[-1]
23
26
  bond_order = 1
@@ -27,14 +30,16 @@ def mol_to_graph(mol: Chem.rdchem.Mol) -> nx.Graph:
27
30
  return g
28
31
 
29
32
 
30
- def smiles_to_graph(smiles: str) -> nx.Graph | tuple[nx.Graph, nx.Graph]:
33
+ def smiles_to_graph(
34
+ smiles: str, sanitize: bool = True
35
+ ) -> nx.Graph | tuple[nx.Graph, nx.Graph]:
31
36
  if ">>" in smiles:
32
37
  smiles_token = smiles.split(">>")
33
- g = mol_to_graph(rdmolfiles.MolFromSmiles(smiles_token[0]))
34
- h = mol_to_graph(rdmolfiles.MolFromSmiles(smiles_token[1]))
38
+ g = mol_to_graph(rdmolfiles.MolFromSmiles(smiles_token[0], sanitize=sanitize))
39
+ h = mol_to_graph(rdmolfiles.MolFromSmiles(smiles_token[1], sanitize=sanitize))
35
40
  return g, h
36
41
  else:
37
- return mol_to_graph(rdmolfiles.MolFromSmiles(smiles))
42
+ return mol_to_graph(rdmolfiles.MolFromSmiles(smiles, sanitize=sanitize))
38
43
 
39
44
 
40
45
  def graph_to_mol(
@@ -54,6 +59,8 @@ def graph_to_mol(
54
59
  idx_map[n] = idx
55
60
  if aam_key in d.keys() and d[aam_key] >= 0:
56
61
  rw_mol.GetAtomWithIdx(idx).SetAtomMapNum(d[aam_key])
62
+ if "formal_charge" in d: # Set the formal charge for the atom
63
+ rw_mol.GetAtomWithIdx(idx).SetFormalCharge(d["formal_charge"])
57
64
  for n1, n2, d in G.edges(data=True):
58
65
  idx1 = idx_map[n1]
59
66
  idx2 = idx_map[n2]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "aamutils"
7
- version = "0.0.7"
7
+ version = "0.0.9"
8
8
  authors = [
9
9
  {name="Klaus Weinbauer", email="klaus@bioinf.uni-leipzig.de"}
10
10
  ]
@@ -0,0 +1,36 @@
1
+ import unittest
2
+ from aamutils.utils import smiles_to_graph
3
+ from aamutils.aam_expand import extend_aam_from_graph, extend_aam_from_rsmi
4
+
5
+
6
+ class TestExtendAAMFromGraph(unittest.TestCase):
7
+ def test_extend_aam_from_graph(self):
8
+ """
9
+ Tests the extend_aam_from_graph function to ensure it correctly extends
10
+ atom-atom mappings and returns the expected reaction SMILES.
11
+ """
12
+ rsmi = "CC[CH2:3][Cl:1].[N:2]>>CC[CH2:3][N:2].[Cl:1]"
13
+ G, H = smiles_to_graph(rsmi)
14
+ result_smiles = extend_aam_from_graph(G, H)
15
+ expected = (
16
+ "[Cl:1][CH2:3][CH2:5][CH3:4].[NH3:2]>>[ClH:1].[NH2:2][CH2:3][CH2:5][CH3:4]"
17
+ )
18
+ self.assertEqual(result_smiles, expected)
19
+
20
+ def test_extend_aam_from_smiles(self):
21
+ """
22
+ Tests the extend_aam_from_graph function to ensure it correctly extends
23
+ atom-atom mappings and returns the expected reaction SMILES.
24
+ """
25
+ rsmi = "CC[CH2:3][Cl:1].[N:2]>>CC[CH2:3][N:2].[Cl:1]"
26
+
27
+ result_smiles = extend_aam_from_rsmi(rsmi)
28
+ expected = (
29
+ "[Cl:1][CH2:3][CH2:5][CH3:4].[NH3:2]>>[ClH:1].[NH2:2][CH2:3][CH2:5][CH3:4]"
30
+ )
31
+ self.assertEqual(result_smiles, expected)
32
+
33
+
34
+ # Run the unittest
35
+ if __name__ == "__main__":
36
+ unittest.main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes