chython 2.4__cp312-cp312-win_amd64.whl

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 (171) hide show
  1. chython/__init__.py +31 -0
  2. chython/_functions.py +69 -0
  3. chython/algorithms/__init__.py +18 -0
  4. chython/algorithms/_isomorphism.cp312-win_amd64.pyd +0 -0
  5. chython/algorithms/_isomorphism.pyx +189 -0
  6. chython/algorithms/aromatics/__init__.py +27 -0
  7. chython/algorithms/aromatics/_rules.py +124 -0
  8. chython/algorithms/aromatics/kekule.py +530 -0
  9. chython/algorithms/aromatics/test/__init__.py +18 -0
  10. chython/algorithms/aromatics/test/test_kekule.py +160 -0
  11. chython/algorithms/aromatics/test/test_thiele.py +263 -0
  12. chython/algorithms/aromatics/thiele.py +226 -0
  13. chython/algorithms/calculate2d/__init__.py +23 -0
  14. chython/algorithms/calculate2d/clean2d.js +1 -0
  15. chython/algorithms/calculate2d/molecule.py +149 -0
  16. chython/algorithms/calculate2d/reaction.py +80 -0
  17. chython/algorithms/depict.py +523 -0
  18. chython/algorithms/fingerprints/__init__.py +48 -0
  19. chython/algorithms/fingerprints/linear.py +208 -0
  20. chython/algorithms/fingerprints/morgan.py +137 -0
  21. chython/algorithms/fingerprints/test/__init__.py +18 -0
  22. chython/algorithms/fingerprints/test/test_linear.py +127 -0
  23. chython/algorithms/fingerprints/test/test_morgan.py +79 -0
  24. chython/algorithms/isomorphism.py +667 -0
  25. chython/algorithms/mapping/__init__.py +28 -0
  26. chython/algorithms/mapping/_groups.py +94 -0
  27. chython/algorithms/mapping/_reactions.py +72 -0
  28. chython/algorithms/mapping/attention.py +216 -0
  29. chython/algorithms/mapping/fixmapper.py +84 -0
  30. chython/algorithms/mapping/groups.py +137 -0
  31. chython/algorithms/mcs.py +202 -0
  32. chython/algorithms/morgan.py +82 -0
  33. chython/algorithms/rings.py +551 -0
  34. chython/algorithms/smiles.py +556 -0
  35. chython/algorithms/standardize/__init__.py +30 -0
  36. chython/algorithms/standardize/_charged.py +115 -0
  37. chython/algorithms/standardize/_groups.py +926 -0
  38. chython/algorithms/standardize/_metal_organics.py +189 -0
  39. chython/algorithms/standardize/_reagents.py +44 -0
  40. chython/algorithms/standardize/_salts.py +68 -0
  41. chython/algorithms/standardize/molecule.py +479 -0
  42. chython/algorithms/standardize/reaction.py +429 -0
  43. chython/algorithms/standardize/resonance.py +196 -0
  44. chython/algorithms/standardize/salts.py +128 -0
  45. chython/algorithms/standardize/saturation.py +378 -0
  46. chython/algorithms/standardize/test/__init__.py +18 -0
  47. chython/algorithms/standardize/test/test_groups.py +118 -0
  48. chython/algorithms/stereo.py +1222 -0
  49. chython/algorithms/tautomers/__init__.py +171 -0
  50. chython/algorithms/tautomers/_acid.py +59 -0
  51. chython/algorithms/tautomers/_base.py +116 -0
  52. chython/algorithms/tautomers/_keto_enol.py +107 -0
  53. chython/algorithms/tautomers/acid_base.py +214 -0
  54. chython/algorithms/tautomers/heteroarenes.py +108 -0
  55. chython/algorithms/tautomers/keto_enol.py +148 -0
  56. chython/algorithms/tautomers/test/__init__.py +18 -0
  57. chython/algorithms/tautomers/test/test_tautomers.py +80 -0
  58. chython/algorithms/test/__init__.py +18 -0
  59. chython/algorithms/test/test_isomorphism.py +58 -0
  60. chython/algorithms/test/test_smiles.py +76 -0
  61. chython/algorithms/x3dom.py +355 -0
  62. chython/containers/__init__.py +43 -0
  63. chython/containers/_pack_v2.cp312-win_amd64.pyd +0 -0
  64. chython/containers/_pack_v2.pyx +271 -0
  65. chython/containers/_unpack_v0v2.cp312-win_amd64.pyd +0 -0
  66. chython/containers/_unpack_v0v2.pyx +300 -0
  67. chython/containers/bonds.py +255 -0
  68. chython/containers/cgr.py +115 -0
  69. chython/containers/graph.py +200 -0
  70. chython/containers/molecule.py +695 -0
  71. chython/containers/query.py +66 -0
  72. chython/containers/reaction.py +324 -0
  73. chython/exceptions.py +114 -0
  74. chython/files/MRVrw.py +523 -0
  75. chython/files/PDBrw.py +257 -0
  76. chython/files/RDFrw.py +298 -0
  77. chython/files/SDFrw.py +221 -0
  78. chython/files/__init__.py +29 -0
  79. chython/files/_convert.py +207 -0
  80. chython/files/_mapping.py +117 -0
  81. chython/files/_xyz.cp312-win_amd64.pyd +0 -0
  82. chython/files/_xyz.pyx +74 -0
  83. chython/files/daylight/__init__.py +24 -0
  84. chython/files/daylight/parser.py +157 -0
  85. chython/files/daylight/smarts.py +107 -0
  86. chython/files/daylight/smiles.py +245 -0
  87. chython/files/daylight/test/__init__.py +18 -0
  88. chython/files/daylight/test/test_daylight_smarts.py +289 -0
  89. chython/files/daylight/test/test_daylight_smiles.py +101 -0
  90. chython/files/daylight/test/test_parser.py +118 -0
  91. chython/files/daylight/test/test_tokenize.py +77 -0
  92. chython/files/daylight/tokenize.py +376 -0
  93. chython/files/libinchi/__init__.py +22 -0
  94. chython/files/libinchi/libinchi.dll +0 -0
  95. chython/files/libinchi/wrapper.py +555 -0
  96. chython/files/mdl/__init__.py +25 -0
  97. chython/files/mdl/emol.py +209 -0
  98. chython/files/mdl/erxn.py +67 -0
  99. chython/files/mdl/mol.py +144 -0
  100. chython/files/mdl/read.py +225 -0
  101. chython/files/mdl/rxn.py +67 -0
  102. chython/files/mdl/stereo.py +63 -0
  103. chython/files/mdl/write.py +165 -0
  104. chython/files/xyz.py +78 -0
  105. chython/periodictable/__init__.py +69 -0
  106. chython/periodictable/base/__init__.py +25 -0
  107. chython/periodictable/base/dynamic.py +149 -0
  108. chython/periodictable/base/element.py +452 -0
  109. chython/periodictable/base/groups.py +90 -0
  110. chython/periodictable/base/periods.py +46 -0
  111. chython/periodictable/base/query.py +473 -0
  112. chython/periodictable/base/vector.py +119 -0
  113. chython/periodictable/groupI.py +252 -0
  114. chython/periodictable/groupII.py +223 -0
  115. chython/periodictable/groupIII.py +1154 -0
  116. chython/periodictable/groupIV.py +210 -0
  117. chython/periodictable/groupIX.py +196 -0
  118. chython/periodictable/groupV.py +192 -0
  119. chython/periodictable/groupVI.py +183 -0
  120. chython/periodictable/groupVII.py +162 -0
  121. chython/periodictable/groupVIII.py +161 -0
  122. chython/periodictable/groupX.py +166 -0
  123. chython/periodictable/groupXI.py +164 -0
  124. chython/periodictable/groupXII.py +158 -0
  125. chython/periodictable/groupXIII.py +239 -0
  126. chython/periodictable/groupXIV.py +262 -0
  127. chython/periodictable/groupXV.py +276 -0
  128. chython/periodictable/groupXVI.py +457 -0
  129. chython/periodictable/groupXVII.py +324 -0
  130. chython/periodictable/groupXVIII.py +260 -0
  131. chython/reactor/__init__.py +24 -0
  132. chython/reactor/base.py +212 -0
  133. chython/reactor/deprotection.py +565 -0
  134. chython/reactor/groups.py +128 -0
  135. chython/reactor/reactions/__init__.py +157 -0
  136. chython/reactor/reactions/_amidation.py +58 -0
  137. chython/reactor/reactions/_amine_isocyanate.py +52 -0
  138. chython/reactor/reactions/_buchwald_hartwig.py +50 -0
  139. chython/reactor/reactions/_esterification.py +49 -0
  140. chython/reactor/reactions/_macmillan.py +43 -0
  141. chython/reactor/reactions/_reductive_amination.py +50 -0
  142. chython/reactor/reactions/_sonogashira.py +49 -0
  143. chython/reactor/reactions/_sulfonamidation.py +52 -0
  144. chython/reactor/reactions/_suzuki_miyaura.py +88 -0
  145. chython/reactor/reactions/ufe.py +99 -0
  146. chython/reactor/reactor.py +170 -0
  147. chython/reactor/retro/__init__.py +77 -0
  148. chython/reactor/retro/_amidation.py +39 -0
  149. chython/reactor/retro/_aryl_amination.py +32 -0
  150. chython/reactor/retro/_mitsunobu.py +49 -0
  151. chython/reactor/retro/_sonogashira.py +49 -0
  152. chython/reactor/retro/_suzuki_miyaura.py +54 -0
  153. chython/reactor/scaffold.py +122 -0
  154. chython/reactor/test/__init__.py +18 -0
  155. chython/reactor/test/test_deprotection.py +57 -0
  156. chython/reactor/test/test_reactor.py +40 -0
  157. chython/reactor/test/test_scaffold.py +57 -0
  158. chython/reactor/test/test_transformer.py +40 -0
  159. chython/reactor/transformer.py +62 -0
  160. chython/utils/__init__.py +57 -0
  161. chython/utils/free_wilson.py +114 -0
  162. chython/utils/grid.py +130 -0
  163. chython/utils/rdkit.py +165 -0
  164. chython/utils/retro.py +139 -0
  165. chython/utils/svg.py +57 -0
  166. chython/utils/test/__init__.py +18 -0
  167. chython/utils/test/test_rdkit.py +71 -0
  168. chython-2.4.dist-info/LICENSE +165 -0
  169. chython-2.4.dist-info/METADATA +101 -0
  170. chython-2.4.dist-info/RECORD +171 -0
  171. chython-2.4.dist-info/WHEEL +4 -0
@@ -0,0 +1,99 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+ from typing import Iterator
20
+ from ._amidation import template as amidation_template
21
+ from ._amine_isocyanate import template as amine_isocyanate_template
22
+ from ._buchwald_hartwig import template as buchwald_hartwig_template
23
+ from ._esterification import template as esterification_template
24
+ from ._macmillan import template as macmillan_template
25
+ from ._reductive_amination import template as reductive_amination_template
26
+ from ._sonogashira import template as sonogashira_template
27
+ from ._sulfonamidation import template as sulfonamidation_template
28
+ from ._suzuki_miyaura import template as suzuki_miyaura_template
29
+ from ..transformer import Transformer
30
+ from ... import MoleculeContainer, smarts
31
+ from ...periodictable import At
32
+
33
+
34
+ __all__ = ['PreparedUFE']
35
+ __all__.extend(k[:-9] for k, v in globals().items() if k.endswith('_template') and isinstance(v, dict) and v)
36
+ _cache = {}
37
+
38
+
39
+ class TransformerWrapper:
40
+ def __init__(self, query, transformation, name):
41
+ if isinstance(transformation, str):
42
+ self.transformer = Transformer(smarts(query), smarts(transformation), copy_metadata=True,
43
+ fix_aromatic_rings=False, fix_tautomers=False)
44
+ else:
45
+ self.query = smarts(query)
46
+ self.mapping = transformation
47
+ self.transformer = None
48
+ self.name = name
49
+
50
+ def __call__(self, molecule: MoleculeContainer) -> Iterator[MoleculeContainer]:
51
+ if self.transformer is None:
52
+ for mapping in self.query.get_mapping(molecule):
53
+ n = mapping[self.mapping]
54
+ copy = molecule.copy()
55
+ copy._atoms[n].__class__ = At # ad-hoc for masking leaving group
56
+ copy._hydrogens[n] = 0
57
+ copy.meta[self.name] = n
58
+ yield copy
59
+ else:
60
+ for copy in self.transformer(molecule):
61
+ copy.meta[self.name] = max(copy)
62
+ yield copy
63
+
64
+
65
+ class PreparedUFE:
66
+ def __init__(self, rules, name):
67
+ self.name = name
68
+ self.rules = rules
69
+ self.transformations = []
70
+
71
+ for n, rule in enumerate(rules['templates']):
72
+ for g in 'AB':
73
+ for s in rule[g]:
74
+ t = TransformerWrapper(s, rule['ufe'][g], f'{name}_{g}{n}')
75
+ self.transformations.append(t)
76
+
77
+ def __call__(self, molecule: MoleculeContainer) -> Iterator[MoleculeContainer]:
78
+ for transformer in self.transformations:
79
+ yield from transformer(molecule)
80
+
81
+ def __repr__(self):
82
+ return f'{__name__}.{self.name}'
83
+
84
+ def __str__(self):
85
+ return f'UFE<{self.rules["name"]}>'
86
+
87
+
88
+ def __getattr__(name):
89
+ try:
90
+ return _cache[name]
91
+ except KeyError:
92
+ if name in __all__:
93
+ _cache[name] = t = PreparedUFE(globals()[f'{name}_template'], name)
94
+ return t
95
+ raise AttributeError
96
+
97
+
98
+ def __dir__():
99
+ return __all__
@@ -0,0 +1,170 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2019-2025 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # Copyright 2019 Adelia Fatykhova <adelik21979@gmail.com>
5
+ # This file is part of chython.
6
+ #
7
+ # chython is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation; either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+ from collections import deque
21
+ from functools import reduce
22
+ from itertools import count, permutations, combinations
23
+ from logging import getLogger, INFO
24
+ from operator import or_
25
+ from typing import List, Iterator, Tuple, Union
26
+ from .base import BaseReactor
27
+ from .._functions import lazy_product
28
+ from ..containers import QueryContainer, MoleculeContainer, ReactionContainer
29
+
30
+
31
+ logger = getLogger('chython.reactor')
32
+ logger.setLevel(INFO)
33
+
34
+
35
+ class Reactor(BaseReactor):
36
+ """
37
+ Reactor for molecules transformations.
38
+ Generates reaction from input molecules using transformation template.
39
+
40
+ Reactor calling transforms reactants to products and
41
+ returns generator of reaction transformations with all
42
+ possible reactions.
43
+ """
44
+ def __init__(self, patterns: Tuple[QueryContainer, ...],
45
+ products: Tuple[Union[MoleculeContainer, QueryContainer], ...], *,
46
+ delete_atoms: bool = True, one_shot: bool = True, polymerise_limit: int = 10,
47
+ automorphism_filter: bool = True, fix_aromatic_rings: bool = True, fix_tautomers: bool = True):
48
+ """
49
+ :param patterns: Search patterns for each reactant.
50
+ :param products: Resulted structures.
51
+ :param delete_atoms: If True atoms exists in reactants but not exists in products will be removed.
52
+ :param one_shot: Do only single reaction center then True, else do all possible combinations of reactions.
53
+ :param polymerise_limit: Limit of self reactions. Make sense than one_shot = False.
54
+ :param fix_aromatic_rings: Proceed kekule and thiele on products.
55
+ :param fix_tautomers: See `thiele()` docs.
56
+ :param automorphism_filter: Skip matches to same atoms.
57
+ """
58
+ if not patterns or not products:
59
+ raise ValueError('empty template')
60
+
61
+ if not all(isinstance(x, QueryContainer) for x in patterns):
62
+ raise TypeError('invalid params')
63
+ elif not all(isinstance(x, (QueryContainer, MoleculeContainer)) for x in products):
64
+ raise TypeError('invalid params')
65
+ self._patterns = patterns
66
+ self._products = products
67
+
68
+ self._one_shot = one_shot
69
+ self._polymerise_limit = polymerise_limit
70
+ self._products_atoms = tuple(set(m) for m in products)
71
+ self._automorphism_filter = automorphism_filter
72
+ super().__init__(reduce(or_, patterns), reduce(or_, products), delete_atoms, fix_aromatic_rings, fix_tautomers)
73
+
74
+ def __call__(self, *structures: MoleculeContainer):
75
+ if any(not isinstance(structure, MoleculeContainer) for structure in structures):
76
+ raise TypeError('only list of Molecules possible')
77
+
78
+ len_patterns = len(self._patterns)
79
+ structures = fix_mapping_overlap(structures)
80
+ s_nums = set(range(len(structures)))
81
+ seen = set()
82
+ if self._one_shot:
83
+ for chosen in permutations(s_nums, len_patterns):
84
+ ignored = [structures[x] for x in s_nums.difference(chosen)]
85
+ chosen = [structures[x] for x in chosen]
86
+ for new in self._single_stage(chosen, {x for x in ignored for x in x}):
87
+ # store reacted molecules in same order as matched pattern
88
+ r = ReactionContainer([x.copy() for x in chosen] + [x.copy() for x in ignored],
89
+ new + [x.copy() for x in ignored])
90
+ if len(new) > 1: # try to keep salts
91
+ r.contract_ions()
92
+ if str(r) in seen:
93
+ continue
94
+ seen.add(str(r))
95
+ yield r
96
+ else:
97
+ queue = deque(([structures[x] for x in chosen], [structures[x] for x in s_nums.difference(chosen)], 0)
98
+ for chosen in permutations(s_nums, len_patterns))
99
+ while queue:
100
+ chosen, ignored, depth = queue.popleft()
101
+ depth += 1
102
+ for new in self._single_stage(chosen, {x for x in ignored for x in x}):
103
+ r = ReactionContainer([x.copy() for x in structures], new + [x.copy() for x in ignored])
104
+ if len(new) > 1:
105
+ r.contract_ions() # try to keep salts
106
+ if str(r) in seen:
107
+ continue
108
+ seen.add(str(r))
109
+ if len(r.products) != len(ignored) + len(self._products_atoms):
110
+ logger.info('ambiguous multicomponent structures. skip multistage processing')
111
+ yield r
112
+ continue
113
+ elif str(r) in seen:
114
+ continue
115
+ else:
116
+ seen.add(str(r))
117
+
118
+ if depth < self._polymerise_limit:
119
+ prod = r.products
120
+ if len_patterns == 1: # simple case. only products or ignored can be transformed.
121
+ for i in range(len(prod)):
122
+ queue.append(([prod[i]], [*prod[:i], *prod[i + 1:]], depth))
123
+ else: # one of products molecule combined with previously chosen
124
+ for chp in combinations(chosen, len_patterns - 1):
125
+ for i in range(len(prod)):
126
+ for ch in permutations(fix_mapping_overlap((prod[i], *chp)), len_patterns):
127
+ queue.append((ch, [*prod[:i], *prod[i + 1:]], depth))
128
+ yield r
129
+
130
+ def _single_stage(self, chosen, ignored) -> Iterator[List[MoleculeContainer]]:
131
+ max_ignored_number = united_chosen = None
132
+ split = len(self._products_atoms) > 1
133
+ for match in lazy_product(*(x.get_mapping(y, automorphism_filter=self._automorphism_filter) for x, y in
134
+ zip(self._patterns, chosen))):
135
+ mapping = match[0].copy()
136
+ for m in match[1:]:
137
+ mapping.update(m)
138
+ if united_chosen is None:
139
+ united_chosen = reduce(or_, chosen)
140
+ max_ignored_number = max(ignored, default=0)
141
+ new = self._patcher(united_chosen, mapping)
142
+ collision = set(new).intersection(ignored)
143
+ if collision:
144
+ new.remap(dict(zip(collision, count(max(max_ignored_number, max(new)) + 1))))
145
+
146
+ if split:
147
+ yield new.split()
148
+ else:
149
+ yield [new]
150
+
151
+
152
+ def fix_mapping_overlap(structures) -> List[MoleculeContainer]:
153
+ if len(structures) == 1:
154
+ return list(structures)
155
+ checked = []
156
+ checked_atoms = set()
157
+ for structure in structures:
158
+ intersection = set(structure).intersection(checked_atoms)
159
+ if intersection:
160
+ mapping = dict(zip(intersection, count(max(max(checked_atoms), max(structure)) + 1)))
161
+ structure = structure.copy()
162
+ structure.remap(mapping)
163
+ logger.info('some atoms in input structures had the same numbers.\n'
164
+ f'atoms {list(mapping)} were remapped to {list(mapping.values())}')
165
+ checked_atoms.update(structure)
166
+ checked.append(structure)
167
+ return checked
168
+
169
+
170
+ __all__ = ['Reactor', 'fix_mapping_overlap']
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+ from chython import Reactor, ReactionContainer, smarts
20
+ from typing import Iterator
21
+ from ._amidation import template as amidation_template
22
+ from ._aryl_amination import template as aryl_amination_template
23
+ from ._mitsunobu import template as mitsunobu_template
24
+ from ._sonogashira import template as sonogashira_template
25
+ from ._suzuki_miyaura import template as suzuki_miyaura_template
26
+
27
+
28
+ __all__ = ['PreparedReactor']
29
+ __all__.extend(k[:-9] for k, v in globals().items() if k.endswith('_template') and isinstance(v, dict) and v)
30
+ _cache = {}
31
+
32
+
33
+ class PreparedReactor:
34
+ """
35
+ Prepared retrosynthetic reactors with predefined sets of templates.
36
+ """
37
+ def __init__(self, rules, name):
38
+ self.name = name
39
+ self.rules = rules
40
+
41
+ self.rxn = rxn = []
42
+ for tmp in rules['templates']:
43
+ p = smarts(tmp['product'])
44
+ rs = [smarts(x) for x in tmp['reactants']]
45
+ rxn.append(Reactor([p], rs, automorphism_filter=False)) # noqa
46
+
47
+ def __repr__(self):
48
+ return f'{__name__}.{self.name}'
49
+
50
+ def __str__(self):
51
+ return f'RetroReactor<{self.rules["name"]}>'
52
+
53
+ def __call__(self, molecule) -> Iterator[ReactionContainer]:
54
+ """
55
+ :param molecule: Product molecule
56
+ """
57
+ seen = set()
58
+ for rx in self.rxn:
59
+ for r in rx(molecule):
60
+ if str(r) in seen:
61
+ continue
62
+ seen.add(str(r))
63
+ yield r
64
+
65
+
66
+ def __getattr__(name):
67
+ try:
68
+ return _cache[name]
69
+ except KeyError:
70
+ if name in __all__:
71
+ _cache[name] = t = PreparedReactor(globals()[f'{name}_template'], name)
72
+ return t
73
+ raise AttributeError
74
+
75
+
76
+ def __dir__():
77
+ return __all__
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ template = {
21
+ 'name': 'Amidation reaction',
22
+ 'description': 'Amide Coupling with Amines and Acids/Halo-Anhydrides',
23
+ 'templates': [
24
+ {
25
+ 'product': '[N;D2,D3;z1:1]-;!@[C;x2;z2:2]=[O;M]', # any SP3 nitrogen with carboxy
26
+ 'reactants': [
27
+ '[A:1]',
28
+ '[A:2]-[O;M]'
29
+ ]
30
+ },
31
+ {
32
+ 'product': '[N;D2;z2;x0:1]-;!@[C;x2;z2:2]=[O;M]', # C=N-C(=O)R
33
+ 'reactants': [
34
+ '[A:1]',
35
+ '[A:2]-[O;M]'
36
+ ]
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ template = {
21
+ 'name': 'Aryl amination reaction',
22
+ 'description': 'C-N coupling of halo-aryles and amines',
23
+ 'templates': [
24
+ {
25
+ 'product': '[N;D2,D3;z1:1]-;!@[C;a:2]',
26
+ 'reactants': [
27
+ '[A:1]',
28
+ '[A:2]-[Br;M]'
29
+ ]
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ template = {
21
+ 'name': 'Mitsunobu reaction',
22
+ 'description': 'Phenol-Alcohol Phenol-Acid Acid-Alcohol couplings',
23
+ 'templates': [
24
+ {
25
+ # Ph-O-Alk
26
+ 'product': '[O;D2;x0;z1:1](-;!@[C;a;M])[C;z1;x1:2]',
27
+ 'reactants': [
28
+ '[A:1]',
29
+ '[A:2]-[O;M]'
30
+ ]
31
+ },
32
+ {
33
+ # Ac-O-Alk
34
+ 'product': '[O;D2;x0;z1:1](-;!@[C;x2;z2;M]=[O;M])[C;z1;x1:2]',
35
+ 'reactants': [
36
+ '[A:1]',
37
+ '[A:2]-[O;M]'
38
+ ]
39
+ },
40
+ {
41
+ # Ph-O-Ac
42
+ 'product': '[O;D2;x0;z1:1](-;!@[C;D3;x2;z2:2]=[O;M])[C;a;M]',
43
+ 'reactants': [
44
+ '[A:1]',
45
+ '[A:2]-[O;M]'
46
+ ]
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ template = {
21
+ 'name': 'Sonogashira reaction',
22
+ 'description': 'Alkyne Ar-X CSP2-X Ac-X couplings',
23
+ 'templates': [
24
+ {
25
+ # Ar
26
+ 'product': '[C;D2;x0;z3:1](-;!@[C;a:2])#[C;D2;x0;M]',
27
+ 'reactants': [
28
+ '[A:1]',
29
+ '[A:2]-[Br;M]'
30
+ ]
31
+ },
32
+ {
33
+ # Ac
34
+ 'product': '[C;D2;x0;z3:1](-;!@[C;D3;x1;z2:2]=[O;M])#[C;D2;x0;M]',
35
+ 'reactants': [
36
+ '[A:1]',
37
+ '[A:2]-[Cl;M]'
38
+ ]
39
+ },
40
+ {
41
+ # CSP2
42
+ 'product': '[C;D2;x0;z3:1](-;!@[C;x0;z2:2])#[C;D2;x0;M]',
43
+ 'reactants': [
44
+ '[A:1]',
45
+ '[A:2]-[Br;M]'
46
+ ]
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2024 Ramil Nugmanov <nougmanoff@protonmail.com>
4
+ # This file is part of chython.
5
+ #
6
+ # chython is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published by
8
+ # the Free Software Foundation; either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with this program; if not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ template = {
21
+ 'name': 'Suzuki-Miyaura reaction',
22
+ 'description': 'Ar-Ar Ar-CSP2 CSP2-CSP2 couplings',
23
+ 'templates': [
24
+ {
25
+ 'product': '[C;a;D3:1]-;!@[C;a:2]',
26
+ 'reactants': [
27
+ '[A:1]-[B;M]([O;M])[O;M]',
28
+ '[A:2]-[Br;M]'
29
+ ]
30
+ },
31
+ {
32
+ 'product': '[C;a;D3:1]-;!@[C;z2:2]=[C;M]',
33
+ 'reactants': [
34
+ '[A:1]-[B;M]([O;M])[O;M]',
35
+ '[A:2]-[Br;M]'
36
+ ]
37
+ },
38
+ {
39
+ # reverse
40
+ 'product': '[C;a;D3:1]-;!@[C;z2:2]=[C;M]',
41
+ 'reactants': [
42
+ '[A:1]-[Br;M]',
43
+ '[A:2]-[B;M]([O;M])[O;M]'
44
+ ]
45
+ },
46
+ {
47
+ 'product': '[C;D2,D3;z2:1](-;!@[C;z2:2]=[C;M])=[C;M]',
48
+ 'reactants': [
49
+ '[A:1]-[B;M]([O;M])[O;M]',
50
+ '[A:2]-[Br;M]'
51
+ ]
52
+ }
53
+ ]
54
+ }