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,926 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2021-2023 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 lazy_object_proxy import Proxy
20
+ from ...periodictable import ListElement
21
+
22
+
23
+ def _rules_single():
24
+ """
25
+ rules without overlapping. these rules can match once to same set of atoms.
26
+ """
27
+ from ... import smarts
28
+ from ...containers import QueryContainer
29
+
30
+ rules = []
31
+
32
+ #
33
+ # A A
34
+ # | |
35
+ # P >> [P+]
36
+ # / | \ / | \
37
+ # A A A A A A
38
+ #
39
+ q = smarts('[P;D4;x0;z1]')
40
+ atom_fix = {1: (1, None)}
41
+ bonds_fix = ()
42
+ rules.append((q, atom_fix, bonds_fix, False))
43
+
44
+ #
45
+ # A H A A H A
46
+ # \ / \ / \ .. \ /
47
+ # B B >> B B
48
+ # / \ / \ / \ .. \
49
+ # A H A A H A
50
+ #
51
+ q = smarts('[B;z1:1]1[H;D2:3][B;z1:2][H;D2:4]1')
52
+ atom_fix = {}
53
+ bonds_fix = ((1, 3, 8), (2, 4, 8))
54
+ rules.append((q, atom_fix, bonds_fix, False))
55
+
56
+ # OGB DS
57
+ #
58
+ # O* A [O-] A
59
+ # \ / \ /
60
+ # N >> [N+]
61
+ # | ||
62
+ # C,N* C,N
63
+ #
64
+ q = smarts('[O;D1;z1][N;D3;z1][C,N;z1] |^1:0,2|')
65
+ atom_fix = {1: (-1, False), 2: (1, None), 3: (0, False)}
66
+ bonds_fix = ((2, 3, 2),)
67
+ rules.append((q, atom_fix, bonds_fix, False))
68
+
69
+ #
70
+ # | |
71
+ # O* -- S -- O* >> O=S=O
72
+ # | |
73
+ #
74
+ q = smarts('[O,S;D1;z1][S;D4;z1][O;D1;z1] |^1:0,2|')
75
+ atom_fix = {1: (0, False), 3: (0, False)}
76
+ bonds_fix = ((1, 2, 2), (2, 3, 2))
77
+ rules.append((q, atom_fix, bonds_fix, False))
78
+
79
+ #
80
+ # A A
81
+ # // //
82
+ # B - N >> B .. N
83
+ # \ \
84
+ # A A
85
+ #
86
+ q = smarts('[B]-[N;D3;z2]')
87
+ atom_fix = {}
88
+ bonds_fix = ((1, 2, 8),)
89
+ rules.append((q, atom_fix, bonds_fix, False))
90
+
91
+ #
92
+ # A A
93
+ # | |
94
+ # B = N - A >> B .. N - A
95
+ # | |
96
+ # A A
97
+ #
98
+ q = smarts('[B;z1,z2]-,=[N;D4;z1,z2]')
99
+ atom_fix = {}
100
+ bonds_fix = ((1, 2, 8),)
101
+ rules.append((q, atom_fix, bonds_fix, False))
102
+
103
+ #
104
+ # R2S - B >> R2S .. B
105
+ #
106
+ q = smarts('[B;z1]-[O,S;D3;z1]')
107
+ atom_fix = {}
108
+ bonds_fix = ((1, 2, 8),)
109
+ rules.append((q, atom_fix, bonds_fix, False))
110
+
111
+ #
112
+ # [B-] = [N+] >> B - N
113
+ #
114
+ q = smarts('[B;z2;-]=[N;D1,D2,D3;z2;+]')
115
+ atom_fix = {1: (1, None), 2: (-1, None)}
116
+ bonds_fix = ((1, 2, 1),)
117
+ rules.append((q, atom_fix, bonds_fix, False))
118
+
119
+ #
120
+ # [A-] A
121
+ # | |
122
+ # [A-] - [B+3] - [A-] >> A - [B-] - A
123
+ # | |
124
+ # [A-] A
125
+ #
126
+ q = smarts('[B;D4;z1;+3]([A;-])([A;-])([A;-])[A;-]')
127
+ atom_fix = {1: (-4, None), 2: (1, None), 3: (1, None), 4: (1, None), 5: (1, None)}
128
+ bonds_fix = ()
129
+ rules.append((q, atom_fix, bonds_fix, False))
130
+
131
+ #
132
+ # A A
133
+ # | |
134
+ # [A-] - B - A >> A - [B-] - A
135
+ # | |
136
+ # A A
137
+ #
138
+ q = smarts('[B;D4;z1]-[A;-]')
139
+ atom_fix = {1: (-1, None), 2: (1, None)}
140
+ bonds_fix = ()
141
+ rules.append((q, atom_fix, bonds_fix, False))
142
+
143
+ #
144
+ # A A
145
+ # | |
146
+ # A - B - A >> A - [B-] - A
147
+ # | |
148
+ # A A
149
+ #
150
+ q = smarts('[B;D4;z1]')
151
+ atom_fix = {1: (-1, None)}
152
+ bonds_fix = ()
153
+ rules.append((q, atom_fix, bonds_fix, False))
154
+
155
+ #
156
+ # A A
157
+ # | |
158
+ # N >> [N+]
159
+ # / | \ / | \
160
+ # A A A A A A
161
+ #
162
+ q = smarts('[N;D4;z1]')
163
+ atom_fix = {1: (1, None)}
164
+ bonds_fix = ()
165
+ rules.append((q, atom_fix, bonds_fix, False))
166
+
167
+ # aci-nitro
168
+ # O O
169
+ # // //
170
+ # C = N >> C - [N+]
171
+ # \ \
172
+ # OH [O-]
173
+ #
174
+ q = smarts('[N;D3;z3;x2](=[O;D1])([O;D1])=C')
175
+ atom_fix = {1: (1, None), 3: (-1, None)}
176
+ bonds_fix = ((1, 4, 1),)
177
+ rules.append((q, atom_fix, bonds_fix, True))
178
+
179
+ #
180
+ # O [O-]
181
+ # // /
182
+ # [C,N,O] = N >> [C,N,O] = [N+]
183
+ # \ \
184
+ # A A
185
+ #
186
+ q = smarts('[N;D3;z3](=[O;D1])(=[C,N,O])-[A]')
187
+ atom_fix = {1: (1, None), 2: (-1, None)}
188
+ bonds_fix = ((1, 2, 1),)
189
+ rules.append((q, atom_fix, bonds_fix, False))
190
+
191
+ # fix aci-nitro
192
+ # [O-] [O-]
193
+ # / /
194
+ # C = [N+ ] >> C - [N+]
195
+ # \ \\
196
+ # OH O
197
+ #
198
+ q = smarts('[N;D3;z2;x2;+]([O;D1;-])([O;D1])=C')
199
+ atom_fix = {}
200
+ bonds_fix = ((1, 3, 2), (1, 4, 1))
201
+ rules.append((q, atom_fix, bonds_fix, True))
202
+
203
+ # fix CN(=O)=N(=O)C
204
+ #
205
+ # [N+] = N = O >> [N+] = [N+] - O-
206
+ # | |
207
+ # A A
208
+ #
209
+ q = smarts('[N;D3;z3](=[N;D3;z2;+])(=[O;D1])[A]')
210
+ atom_fix = {1: (1, None), 3: (-1, None)}
211
+ bonds_fix = ((1, 3, 1),)
212
+ rules.append((q, atom_fix, bonds_fix, False))
213
+
214
+ # Fix CN(=O)=N(=N)C
215
+ # [N+] = N = N - ? >> [N+] = [N+] - [N-] - ?
216
+ # | |
217
+ # A A
218
+ #
219
+ q = smarts('[N;D3;z3](=[N;D3;z2;+])(=[N;D1,D2;z2])[A]')
220
+ atom_fix = {1: (1, None), 3: (-1, None)}
221
+ bonds_fix = ((1, 3, 1),)
222
+ rules.append((q, atom_fix, bonds_fix, False))
223
+
224
+ # For N-case is not unique!
225
+ # N [N-]
226
+ # // /
227
+ # [C,N] = N >> [C,N] = [N+]
228
+ # \ \
229
+ # A A
230
+ #
231
+ q = smarts('[N;D3;z3](=[N;D1,D2;z2])(=[C,N])[A]')
232
+ atom_fix = {1: (1, None), 2: (-1, None)}
233
+ bonds_fix = ((1, 2, 1),)
234
+ rules.append((q, atom_fix, bonds_fix, False))
235
+
236
+ #
237
+ # [N-] - [N+] = O >> N = [N+] - [O-]
238
+ # | |
239
+ # A A
240
+ #
241
+ q = smarts('[N;D3;z2;+](=[O;D1])[N;D1,D2;z1;-]')
242
+ atom_fix = {2: (-1, None), 3: (1, None)}
243
+ bonds_fix = ((1, 2, 1), (1, 3, 2))
244
+ rules.append((q, atom_fix, bonds_fix, False))
245
+
246
+ #
247
+ # O [O-]
248
+ # // /
249
+ # [A-] - N >> [A-] - [N+]
250
+ # \\ \\
251
+ # O O
252
+ #
253
+ q = smarts('[N;D3;z3](=[O;D1])(=[O;D1])[A;-]')
254
+ atom_fix = {1: (1, None), 2: (-1, None)}
255
+ bonds_fix = ((1, 2, 1),)
256
+ rules.append((q, atom_fix, bonds_fix, False))
257
+
258
+ #
259
+ # O : N : O O = [N+] - [O-]
260
+ # | >> |
261
+ # A A
262
+ #
263
+ q = smarts('[N;D3;a](:[O;D1])(:[O;D1])[A]')
264
+ atom_fix = {1: (1, None), 2: (-1, None)}
265
+ bonds_fix = ((1, 2, 1), (1, 3, 2))
266
+ rules.append((q, atom_fix, bonds_fix, False))
267
+
268
+ # Nitrite
269
+ #
270
+ # O [O-]
271
+ # // /
272
+ # [N-] >> N
273
+ # \\ \\
274
+ # O O
275
+ #
276
+ q = smarts('[N;D2;z3;x2;-](=[O;D1])=[O;D1]')
277
+ atom_fix = {1: (1, None), 2: (-1, None)}
278
+ bonds_fix = ((1, 2, 1),)
279
+ rules.append((q, atom_fix, bonds_fix, False))
280
+
281
+ #
282
+ # [O,C,N] = N # N >> [O,C,N] = [N+] = [N-]
283
+ #
284
+ q = smarts('[N;D2;z3](#[N;D1])=[C,N,O]')
285
+ atom_fix = {1: (1, None), 2: (-1, None)}
286
+ bonds_fix = ((1, 2, 2),)
287
+ rules.append((q, atom_fix, bonds_fix, False))
288
+
289
+ #
290
+ # [C,N,O-] - [N+] # N >> [C,N,O] = [N+] = [N-]
291
+ #
292
+ q = smarts('[N;D2;z3;+](#[N;D1])[C,N,O;z1;-]')
293
+ atom_fix = {2: (-1, None), 3: (1, None)}
294
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
295
+ rules.append((q, atom_fix, bonds_fix, False))
296
+
297
+ #
298
+ # A - [N+] # N = [N-] >> A - N = [N+] = [N-]
299
+ #
300
+ q = smarts('[N;D2;z3;x2](#[N;D2;+][A])=[N;D1;-]')
301
+ atom_fix = {1: (1, None), 2: (-1, None)}
302
+ bonds_fix = ((1, 2, 2),)
303
+ rules.append((q, atom_fix, bonds_fix, False))
304
+
305
+ #
306
+ # A - N = N = N >> A - N = [N+] = [N-]
307
+ #
308
+ q = smarts('[N;D2;z3;x2](=[N;D2;z2])=[N;D1]')
309
+ atom_fix = {1: (1, None), 3: (-1, None)}
310
+ bonds_fix = ()
311
+ rules.append((q, atom_fix, bonds_fix, False))
312
+
313
+ #
314
+ # A - NH - N # N >> A - N = [N+] = [N-]
315
+ #
316
+ q = smarts('[N;D2;z3;x2]([N;D2;z1])#[N;D1]')
317
+ atom_fix = {1: (1, None), 3: (-1, None)}
318
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
319
+ rules.append((q, atom_fix, bonds_fix, False))
320
+
321
+ #
322
+ # [N-] # N = N - A >> [N-] == [N+] == N - A
323
+ #
324
+ q = smarts('[N;D2;z3;x2](=[N;D2;z2])#[N;D1;-]')
325
+ atom_fix = {1: (1, None)}
326
+ bonds_fix = ((1, 3, 2),)
327
+ rules.append((q, atom_fix, bonds_fix, False))
328
+
329
+ #
330
+ # [N-] == N # N >> [N-] == [N+] == [N-]
331
+ #
332
+ q = smarts('[N;D2;z3;x2](=[N;D1;-])#[N;D1]')
333
+ atom_fix = {1: (1, None), 3: (-1, None)}
334
+ bonds_fix = ((1, 3, 2),)
335
+ rules.append((q, atom_fix, bonds_fix, False))
336
+
337
+ #
338
+ # A - C # N = NH >> A - [CH] = [N+] = [N-]
339
+ #
340
+ q = smarts('[N;D2;z3;x1](=[N;D1])#[C;D1,D2]')
341
+ atom_fix = {1: (1, None), 2: (-1, None)}
342
+ bonds_fix = ((1, 3, 2),)
343
+ rules.append((q, atom_fix, bonds_fix, False))
344
+
345
+ # note: order dependent
346
+ # A - C # N = [O,N] >> A - C # [N+] - [O,N-]
347
+ #
348
+ q = smarts('[N;D2;z3;x1](=[N,O;z2])#[C;D1,D2]')
349
+ atom_fix = {1: (1, None), 2: (-1, None)}
350
+ bonds_fix = ((1, 2, 1),)
351
+ rules.append((q, atom_fix, bonds_fix, False))
352
+
353
+ #
354
+ # [NH2,OH,SH] - N # C - A >> [NH,O,S-] - [N+] # C - A
355
+ #
356
+ q = smarts('[N;D2;z3;x1]([N,O,S;D1])#[C;D1,D2]')
357
+ atom_fix = {1: (1, None), 2: (-1, None)}
358
+ bonds_fix = ()
359
+ rules.append((q, atom_fix, bonds_fix, False))
360
+
361
+ #
362
+ # A - [NH] - N # C >> A - [N-] - [N+] # C
363
+ #
364
+ q = smarts('[N;D2;z3;x1]([N;D2;z1])#[C;D1,D2]')
365
+ atom_fix = {1: (1, None), 2: (-1, None)}
366
+ bonds_fix = ()
367
+ rules.append((q, atom_fix, bonds_fix, False))
368
+
369
+ #
370
+ # [NH2,OH,SH] - [N+] # [C-] >> [NH,O,S-] - [N+] # [CH]
371
+ #
372
+ q = smarts('[N;D2;z3;x1;+]([N,O,S;D1])#[C;D1;-]')
373
+ atom_fix = {2: (-1, None), 3: (1, None)}
374
+ bonds_fix = ()
375
+ rules.append((q, atom_fix, bonds_fix, True))
376
+
377
+ #
378
+ # A - [NH] - [N+] # [C-] >> A - [N-] - [N+] # [CH]
379
+ #
380
+ q = smarts('[N;D2;z3;x1;+]([N;D2;z1])#[C;D1;-]')
381
+ atom_fix = {2: (-1, None), 3: (1, None)}
382
+ bonds_fix = ()
383
+ rules.append((q, atom_fix, bonds_fix, True))
384
+
385
+ #
386
+ # A - N # C >> A - [N+] # [C-]
387
+ #
388
+ q = smarts('[N;D2;z3]([A])#[C;D1]')
389
+ atom_fix = {1: (1, None), 3: (-1, None)}
390
+ bonds_fix = ()
391
+ rules.append((q, atom_fix, bonds_fix, False))
392
+
393
+ # fix old diazo rule
394
+ #
395
+ # A - [C-] = [N+] = [NH] >> A - [CH] = [N+] = [N-]
396
+ #
397
+ q = smarts('[N;D2;z3;x1;+](=[N;D1])=[C;D1,D2;z2;-]')
398
+ atom_fix = {2: (-1, None), 3: (1, None)}
399
+ bonds_fix = ()
400
+ rules.append((q, atom_fix, bonds_fix, False))
401
+
402
+ #
403
+ # | |
404
+ # - N - >> - [N+] -
405
+ # \\ |
406
+ # [O,N] [O,N-]
407
+ #
408
+ q = smarts('[N;D4;z2]=[O,N;z2]')
409
+ atom_fix = {1: (1, None), 2: (-1, None)}
410
+ bonds_fix = ((1, 2, 1),)
411
+ rules.append((q, atom_fix, bonds_fix, False))
412
+
413
+ # N-oxide radical
414
+ #
415
+ # | |
416
+ # - N* >> - N
417
+ # \\ |
418
+ # O O*
419
+ #
420
+ q = smarts('[N;D3;z2]=[O;D1] |^1:0|')
421
+ atom_fix = {1: (0, False), 2: (0, True)}
422
+ bonds_fix = ((1, 2, 1),)
423
+ rules.append((q, atom_fix, bonds_fix, False))
424
+
425
+ # false N-oxide radical
426
+ #
427
+ # | |
428
+ # = N >> = [N+]
429
+ # \ \
430
+ # O* [O-]
431
+ #
432
+ q = smarts('[O;D1][N;D3;z2] |^1:0|')
433
+ atom_fix = {1: (-1, False), 2: (1, False)}
434
+ bonds_fix = ()
435
+ rules.append((q, atom_fix, bonds_fix, False))
436
+
437
+ #
438
+ # C C
439
+ # \ \
440
+ # N # N >> [N+] = [N-]
441
+ # / /
442
+ # C C
443
+ #
444
+ q = smarts('[N;D3;z3;x1](#[N;D1])(C)C')
445
+ atom_fix = {1: (1, None), 2: (-1, None)}
446
+ bonds_fix = ((1, 2, 2),)
447
+ rules.append((q, atom_fix, bonds_fix, False))
448
+
449
+ #
450
+ # C - N = [N+] >> C - [N+] # N
451
+ #
452
+ q = smarts('[N;D1;z2;x1;+]=[N;D2;x1;z2]')
453
+ atom_fix = {1: (-1, None), 2: (1, None)}
454
+ bonds_fix = ((1, 2, 3),)
455
+ rules.append((q, atom_fix, bonds_fix, False))
456
+
457
+ #
458
+ # [N+] - [C-] = O >> N = C = O
459
+ #
460
+ q = smarts('[C;D2;z2;x2;-]([N;D1,D2;z1;+])=[O;D1]')
461
+ atom_fix = {1: (1, None), 2: (-1, None)}
462
+ bonds_fix = ((1, 2, 2),)
463
+ rules.append((q, atom_fix, bonds_fix, False))
464
+
465
+ #
466
+ # N # C - OH >> HN = C = O
467
+ #
468
+ q = smarts('[N;D1;x0;z3]#[C;D2;z3;x2][O;D1]')
469
+ atom_fix = {}
470
+ bonds_fix = ((1, 2, 2), (2, 3, 2))
471
+ rules.append((q, atom_fix, bonds_fix, True))
472
+
473
+ #
474
+ # N # C - [O-] >> [N-] = C = O
475
+ #
476
+ q = smarts('[N;D1;x0;z3]#[C;D2;z3;x2][O;D1;-]')
477
+ atom_fix = {1: (-1, None), 3: (1, None)}
478
+ bonds_fix = ((1, 2, 2), (2, 3, 2))
479
+ rules.append((q, atom_fix, bonds_fix, False))
480
+
481
+ #
482
+ # - [N+] - [O-] >> - N = O
483
+ #
484
+ q = smarts('[O;D1;z1;x1;-][N;D2;z1;+]')
485
+ atom_fix = {1: (1, None), 2: (-1, None)}
486
+ bonds_fix = ((1, 2, 2),)
487
+ rules.append((q, atom_fix, bonds_fix, False))
488
+
489
+ #
490
+ # CH-N=O >> C=N-OH
491
+ #
492
+ q = smarts('[O;D1;z2;x1]=[N;D2;x1;z2][C;D1,D2,D3;z1]')
493
+ atom_fix = {}
494
+ bonds_fix = ((1, 2, 1), (2, 3, 2))
495
+ rules.append((q, atom_fix, bonds_fix, True))
496
+
497
+ #
498
+ # [O+]R [O]R
499
+ # // /
500
+ # R2N - C >> R2[N+] = C
501
+ #
502
+ q = smarts('[O;D2;z2;+]=[C;z2][N;D1,D2,D3;z1]')
503
+ atom_fix = {1: (-1, None), 3: (1, None)}
504
+ bonds_fix = ((1, 2, 1), (2, 3, 2))
505
+ rules.append((q, atom_fix, bonds_fix, False))
506
+
507
+ #
508
+ # [O,S]H [O,S]
509
+ # / //
510
+ # N = C >> NH - C
511
+ #
512
+ q = smarts('[N;z2]=[C;D2,D3;z2]-[O,S;D1]')
513
+ atom_fix = {}
514
+ bonds_fix = ((1, 2, 1), (2, 3, 2))
515
+ rules.append((q, atom_fix, bonds_fix, True))
516
+
517
+ #
518
+ # fix pyridin-2-one. note: only after amide rule
519
+ #
520
+ q = smarts('[O,S,N;D1;z2;x0]=[C;D3;r6]1[N;D2;z1][A;z2]-,=[A;z2][A;z2]-,=[A;z2]1')
521
+ atom_fix = {}
522
+ bonds_fix = ((1, 2, 1), (2, 3, 2))
523
+ rules.append((q, atom_fix, bonds_fix, True))
524
+
525
+ #
526
+ # fix pyridin-2-imine
527
+ #
528
+ q = smarts('[N;D2;z2;!R]=[C;D3;r6]1[N;D2;z1][A;z2]-,=[A;z2][A;z2]-,=[A;z2]1')
529
+ atom_fix = {}
530
+ bonds_fix = ((1, 2, 1), (2, 3, 2))
531
+ rules.append((q, atom_fix, bonds_fix, True))
532
+
533
+ #
534
+ # fix pyridin-4-one
535
+ #
536
+ q = smarts('[O,S;D1;z2;x0]=[C;D3;r6]1[A;z2]=[A;z2][N;D2;z1][A;z2]-,=[A;z2]1')
537
+ atom_fix = {}
538
+ bonds_fix = ((1, 2, 1), (2, 3, 2), (3, 4, 1), (4, 5, 2))
539
+ rules.append((q, atom_fix, bonds_fix, True))
540
+
541
+ # todo:
542
+ # [C;a:10][N;H:2][N:3]=[C:4]1[C:5]=,:[C:6][C:7](=[O:1])[C:8]=,:[C:9]1
543
+ # [C;a:10][N;H:2][N:3]=[C:4]1[C:5](=[O:1])[C:6]=,:[C:7]-,:[C:8]=,:[C:9]1
544
+
545
+ #
546
+ # OH O
547
+ # / //
548
+ # C = C >> C - C
549
+ # \ \
550
+ # [O,N] [O,N]
551
+ #
552
+ q = smarts('[O;D1;x0;z1]-[C;D3;z2;x2](-[O,N])=C')
553
+ atom_fix = {}
554
+ bonds_fix = ((1, 2, 2), (2, 4, 1))
555
+ rules.append((q, atom_fix, bonds_fix, True))
556
+
557
+ # acyclic keto-enol
558
+ # OH O
559
+ # / //
560
+ # C,H - C = C - C,H >> C,H - C - C - C,H
561
+ #
562
+ q = smarts('[O;D1;z1;x0][C;D2,D3;z2;x1;!R]=[C;z2;x0]')
563
+ atom_fix = {}
564
+ bonds_fix = ((1, 2, 2), (2, 3, 1))
565
+ rules.append((q, atom_fix, bonds_fix, True))
566
+
567
+ #
568
+ # fix pyridin. note: don't move.
569
+ #
570
+ q = smarts('[O,S,N;D1;z2;x0]=[C;D3;r6]1[N;D2;z2]=[A;z2][A;z2]-,=[A;z2][C;D2,D3;z1]1')
571
+ atom_fix = {}
572
+ bonds_fix = ((1, 2, 1), (2, 7, 2))
573
+ rules.append((q, atom_fix, bonds_fix, True))
574
+
575
+ #
576
+ # fix pyridin amine.
577
+ #
578
+ q = smarts('[N;D2;z2;!R]=[C;D3;r6]1[N;D2;z2]=[A;z2][A;z2]-,=[A;z2][C;D2,D3;z1]1')
579
+ atom_fix = {}
580
+ bonds_fix = ((1, 2, 1), (2, 7, 2))
581
+ rules.append((q, atom_fix, bonds_fix, True))
582
+
583
+ #
584
+ # A A
585
+ # | |
586
+ # A - [P+] - [O-] >> A - P = O
587
+ # | |
588
+ # A A
589
+ #
590
+ q = smarts('[P;D4;z1;+][O;D1;-]')
591
+ atom_fix = {1: (-1, None), 2: (1, None)}
592
+ bonds_fix = ((1, 2, 2),)
593
+ rules.append((q, atom_fix, bonds_fix, False))
594
+
595
+ #
596
+ # A A
597
+ # | |
598
+ # A - [P-] - [C+] >> A - P = C
599
+ # | |
600
+ # A A
601
+ #
602
+ q = smarts('[P;D4;z1;-][C;D1,D2,D3;z1;+]')
603
+ atom_fix = {1: (1, None), 2: (-1, None)}
604
+ bonds_fix = ((1, 2, 2),)
605
+ rules.append((q, atom_fix, bonds_fix, False))
606
+
607
+ #
608
+ # F F F F
609
+ # \ / \ /
610
+ # F - P - F >> F - [P-] - F
611
+ # / \ / \
612
+ # F F F F
613
+ #
614
+ q = smarts('[P;D6;z1]([F;D1])([F;D1])([F;D1])([F;D1])([F;D1])[F;D1]')
615
+ atom_fix = {1: (-1, None)}
616
+ bonds_fix = ()
617
+ rules.append((q, atom_fix, bonds_fix, False))
618
+
619
+ #
620
+ # O O
621
+ # \\ \\
622
+ # A - [P-] - A >> A - P - A
623
+ # // /
624
+ # O [O-]
625
+ #
626
+ q = smarts('[P;D4;z3;-](=[O;D1])(=[O;D1])([A])[A]')
627
+ atom_fix = {1: (1, None), 2: (-1, None)}
628
+ bonds_fix = ((1, 2, 1),)
629
+ rules.append((q, atom_fix, bonds_fix, False))
630
+
631
+ #
632
+ # O [O-]
633
+ # \\ \
634
+ # A - P - A >> A - P - A
635
+ # / //
636
+ # [S-] S
637
+ #
638
+ q = smarts('[S;D1;z1;x1;-][P;D4;z2]=[O;D1]')
639
+ atom_fix = {1: (1, None), 3: (-1, None)}
640
+ bonds_fix = ((1, 2, 2), (2, 3, 1))
641
+ rules.append((q, atom_fix, bonds_fix, False))
642
+
643
+ #
644
+ # O [OH]
645
+ # \\ \
646
+ # A - P - A >> A - P - A
647
+ # / //
648
+ # [SH] S
649
+ #
650
+ q = smarts('[S;D1;z1;x1][P;D4;z2]=[O;D1]')
651
+ atom_fix = {}
652
+ bonds_fix = ((1, 2, 2), (2, 3, 1))
653
+ rules.append((q, atom_fix, bonds_fix, True))
654
+
655
+ #
656
+ # A A
657
+ # \\ \\
658
+ # A - S - [S-] >> A - S - [O-]
659
+ # // //
660
+ # O S
661
+ #
662
+ q = smarts('[S;D1;-][S;D4;z3](=[O;D1])(=[A])[A]')
663
+ atom_fix = {1: (1, None), 3: (-1, None)}
664
+ bonds_fix = ((1, 2, 2), (2, 3, 1))
665
+ rules.append((q, atom_fix, bonds_fix, False))
666
+
667
+ #
668
+ # A A
669
+ # \\ \
670
+ # A - S - [SH] >> A - S - [OH]
671
+ # // //
672
+ # O S
673
+ #
674
+ q = smarts('[S;D1][S;D4;z3](=[O;D1])(=[A])[A]')
675
+ atom_fix = {}
676
+ bonds_fix = ((1, 2, 2), (2, 3, 1))
677
+ rules.append((q, atom_fix, bonds_fix, True))
678
+
679
+ #
680
+ # A A
681
+ # / /
682
+ # [O-] - [S,Si,Se+] >> O = [S,Si,Se]
683
+ # \ \
684
+ # A A
685
+ #
686
+ q = smarts('[S,Se,Si;D3;z1;+][O;D1;-]')
687
+ atom_fix = {1: (-1, None), 2: (1, None)}
688
+ bonds_fix = ((1, 2, 2),)
689
+ rules.append((q, atom_fix, bonds_fix, False))
690
+
691
+ #
692
+ # A? A?
693
+ # | |
694
+ # A = [S+] - [O-] >> A = S = O
695
+ # | |
696
+ # A? A?
697
+ #
698
+ q = smarts('[S;D2,D4;z2;+][O;D1;-]')
699
+ atom_fix = {1: (-1, None), 2: (1, None)}
700
+ bonds_fix = ((1, 2, 2),)
701
+ rules.append((q, atom_fix, bonds_fix, False))
702
+
703
+ #
704
+ # [O-] O
705
+ # / //
706
+ # A = [S+2] >> A = S
707
+ # \ \\
708
+ # [O-] O
709
+ #
710
+ q = smarts('[S;D3;z2;+2]([O;D1;-])[O;D1;-]')
711
+ atom_fix = {1: (-2, None), 2: (1, None), 3: (1, None)}
712
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
713
+ rules.append((q, atom_fix, bonds_fix, False))
714
+
715
+ #
716
+ # A A
717
+ # | |
718
+ # [O-] - [S+2] - [O-] >> O = S = O
719
+ # | |
720
+ # A A
721
+ #
722
+ q = smarts('[S;D4;z1;+2]([O;D1;-])[O;D1;-]')
723
+ atom_fix = {1: (-2, None), 2: (1, None), 3: (1, None)}
724
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
725
+ rules.append((q, atom_fix, bonds_fix, False))
726
+
727
+ #
728
+ # A - [S-] - [C+] >> A - S = C
729
+ # | |
730
+ # A A
731
+ #
732
+ q = smarts('[S;D3;z1;-]([C;D1,D2,D3;z1;+])')
733
+ atom_fix = {1: (1, None), 2: (-1, None)}
734
+ bonds_fix = ((1, 2, 2),)
735
+ rules.append((q, atom_fix, bonds_fix, False))
736
+
737
+ #
738
+ # O O
739
+ # \\ \\
740
+ # [S-] - A >> S - A
741
+ # // /
742
+ # O [O-]
743
+ #
744
+ q = smarts('[S;D3;z3;-](=[O;D1])(=[O;D1])[A]')
745
+ atom_fix = {1: (1, None), 2: (-1, None)}
746
+ bonds_fix = ((1, 2, 1),)
747
+ rules.append((q, atom_fix, bonds_fix, False))
748
+
749
+ #
750
+ # O [O-]
751
+ # \\ \
752
+ # A - [S-] = O >> A - S = O
753
+ # // //
754
+ # O O
755
+ #
756
+ q = smarts('[S;D4;z3;-](=[O;D1])(=[O;D1])(=[O;D1])[A]')
757
+ atom_fix = {1: (1, None), 2: (-1, None)}
758
+ bonds_fix = ((1, 2, 1),)
759
+ rules.append((q, atom_fix, bonds_fix, False))
760
+
761
+ #
762
+ # O [O-]
763
+ # \\ \
764
+ # [S-] - [S-] >> S = S
765
+ # // /
766
+ # O [O-]
767
+ #
768
+ q = smarts('[S;D3;z3;x3;-]([S;D1;-])(=[O;D1])=[O;D1]')
769
+ atom_fix = {1: (1, None), 2: (1, None), 3: (-1, None), 4: (-1, None)}
770
+ bonds_fix = ((1, 2, 2), (1, 3, 1), (1, 4, 1))
771
+ rules.append((q, atom_fix, bonds_fix, False))
772
+
773
+ #
774
+ # A A
775
+ # \ \
776
+ # A - S = O >> A - S = O
777
+ # / //
778
+ # [OH] O
779
+ #
780
+ q = smarts('[S;D4;z2](=[O;D1])[O;D1]')
781
+ atom_fix = {}
782
+ bonds_fix = ((1, 3, 2),)
783
+ rules.append((q, atom_fix, bonds_fix, False))
784
+
785
+ #
786
+ # A A
787
+ # \ \
788
+ # A - S = O >> A - S = O
789
+ # / //
790
+ # [NH] N
791
+ #
792
+ q = smarts('[S;D4;z2](=[O;D1])[N;D1,D2;z1]')
793
+ atom_fix = {}
794
+ bonds_fix = ((1, 3, 2),)
795
+ rules.append((q, atom_fix, bonds_fix, False))
796
+
797
+ #
798
+ # A{1,3} A{1,3}
799
+ # | |
800
+ # N = S - [OH] >> [NH] - S = O
801
+ #
802
+ q = smarts('[S;D3,D5;z2](=[N;D1,D2;z2])[O;D1]')
803
+ atom_fix = {}
804
+ bonds_fix = ((1, 2, 1), (1, 3, 2))
805
+ rules.append((q, atom_fix, bonds_fix, True))
806
+
807
+ #
808
+ # C # C - [O,NH,S]H >> C=C=[O,NH,S]
809
+ #
810
+ q = smarts('[C;D2;z3;x1]([N,O,S;D1])#[C;D1,D2]')
811
+ atom_fix = {}
812
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
813
+ rules.append((q, atom_fix, bonds_fix, True))
814
+
815
+ #
816
+ # C # C - [NH]R >> C=C=NR
817
+ #
818
+ q = smarts('[C;D2;z3;x1]([N;D2;z1])#[C;D1,D2]')
819
+ atom_fix = {}
820
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
821
+ rules.append((q, atom_fix, bonds_fix, True))
822
+
823
+ # Carbon Monoxide
824
+ #
825
+ # [CX1] = O >> [С-] # [O+]
826
+ #
827
+ q = smarts('[C;D1;x1;z2]=[O;D1] |^1:0|')
828
+ atom_fix = {1: (-1, False), 2: (1, None)}
829
+ bonds_fix = ((1, 2, 3),)
830
+ rules.append((q, atom_fix, bonds_fix, False))
831
+
832
+ # Ozone
833
+ #
834
+ # [O*] -- O -- [O*] >> O == [O+] -- [O-]
835
+ #
836
+ q = smarts('[O;D1][O;D2][O;D1] |^1:0,2|')
837
+ atom_fix = {1: (0, False), 2: (1, None), 3: (-1, False)}
838
+ bonds_fix = ((1, 2, 2),)
839
+ rules.append((q, atom_fix, bonds_fix, False))
840
+
841
+ # only after [A-] - [C+] rules!
842
+ # [C+] - N(R2) >> C = [N+](R2)
843
+ #
844
+ q = smarts('[C;D1,D2,D3;z1;+]-[N;D3;z1;x0]')
845
+ atom_fix = {1: (-1, None), 2: (1, None)}
846
+ bonds_fix = ((1, 2, 2),)
847
+ rules.append((q, atom_fix, bonds_fix, False))
848
+
849
+ # low priority for hetero-N
850
+ # [C+] - N(X2) >> C = [N+](X2)
851
+ #
852
+ q = smarts('[C;D1,D2,D3;z1;+]-[N;D3;z1]')
853
+ atom_fix = {1: (-1, None), 2: (1, None)}
854
+ bonds_fix = ((1, 2, 2),)
855
+ rules.append((q, atom_fix, bonds_fix, False))
856
+
857
+ #
858
+ # [C+] = N(R) >> C # [N+](R)
859
+ #
860
+ q = smarts('[C;D1,D2;z2;x1;+]=[N;D1,D2;z2]')
861
+ atom_fix = {1: (-1, None), 2: (1, None)}
862
+ bonds_fix = ((1, 2, 3),)
863
+ rules.append((q, atom_fix, bonds_fix, False))
864
+
865
+ # fix rdkit
866
+ # A-[Cl,Br,I+] - [O-] >> X = O
867
+ #
868
+ q = smarts('[Cl,Br,I;D2;z1;+][O;D1;-]')
869
+ atom_fix = {1: (-1, None), 2: (1, None)}
870
+ bonds_fix = ((1, 2, 2),)
871
+ rules.append((q, atom_fix, bonds_fix, False))
872
+
873
+ # fix rdkit
874
+ # A-[Hal+2]([O-])2
875
+ #
876
+ q = smarts('[Cl,Br,I;D3;z1;+2]([O;D1;-])[O;D1;-]')
877
+ atom_fix = {1: (-2, None), 2: (1, None), 3: (1, None)}
878
+ bonds_fix = ((1, 2, 2), (1, 3, 2))
879
+ rules.append((q, atom_fix, bonds_fix, False))
880
+
881
+ # fix rdkit
882
+ # A-[Hal+3]([O-])3
883
+ #
884
+ q = smarts('[Cl,Br,I;D4;z1;+3]([O;D1;-])([O;D1;-])[O;D1;-]')
885
+ atom_fix = {1: (-3, None), 2: (1, None), 3: (1, None), 4: (1, None)}
886
+ bonds_fix = ((1, 2, 2), (1, 3, 2), (1, 4, 2))
887
+ rules.append((q, atom_fix, bonds_fix, False))
888
+
889
+ # fix reaxys [Cl-]=O > Cl-[O-]
890
+ q = smarts('[Cl,Br,I;D1;z2;-]=[O;D1]')
891
+ atom_fix = {1: (1, None), 2: (-1, None)}
892
+ bonds_fix = ((1, 2, 1),)
893
+ rules.append((q, atom_fix, bonds_fix, False))
894
+
895
+ return [(q, atom_fix, bonds_fix,
896
+ [n for n, a in q.atoms() if a.atomic_symbol == 'A' and n not in atom_fix], is_tautomer)
897
+ for q, atom_fix, bonds_fix, is_tautomer in rules]
898
+
899
+
900
+ def _rules_double():
901
+ from ... import smarts
902
+
903
+ rules = []
904
+
905
+ #
906
+ # [OH] O
907
+ # | //
908
+ # N = S = A >> [NH] - S = A
909
+ # | |
910
+ # A A
911
+ #
912
+ q = smarts('[S;D4;z3:1]([O;D1:2])(=[N;D1,D2;z2:3])(=[A])[A]')
913
+ atom_fix = {}
914
+ bonds_fix = ((1, 2, 2), (1, 3, 1))
915
+ rules.append((q, atom_fix, bonds_fix, True))
916
+
917
+ return [(q, atom_fix, bonds_fix,
918
+ [n for n, a in q.atoms() if a.atomic_symbol == 'A' and n not in atom_fix], is_tautomer)
919
+ for q, atom_fix, bonds_fix, is_tautomer in rules]
920
+
921
+
922
+ single_rules = Proxy(_rules_single)
923
+ double_rules = Proxy(_rules_double)
924
+
925
+
926
+ __all__ = ['single_rules', 'double_rules']