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,200 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2018-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 abc import ABC, abstractmethod
20
+ from functools import cached_property
21
+ from typing import Dict, Generic, Iterator, Optional, Tuple, TypeVar
22
+ from ..exceptions import AtomNotFound, MappingError, BondNotFound
23
+
24
+
25
+ Atom = TypeVar('Atom')
26
+ Bond = TypeVar('Bond')
27
+
28
+
29
+ class Graph(Generic[Atom, Bond], ABC):
30
+ __slots__ = ('_atoms', '_bonds', '__dict__')
31
+ __class_cache__ = {}
32
+
33
+ _atoms: Dict[int, Atom]
34
+ _bonds: Dict[int, Dict[int, Bond]]
35
+
36
+ def __init__(self):
37
+ self._atoms = {}
38
+ self._bonds = {}
39
+
40
+ def atom(self, n: int) -> Atom:
41
+ return self._atoms[n]
42
+
43
+ def has_atom(self, n: int) -> bool:
44
+ return n in self._atoms
45
+
46
+ def atoms(self) -> Iterator[Tuple[int, Atom]]:
47
+ """
48
+ iterate over all atoms
49
+ """
50
+ return iter(self._atoms.items())
51
+
52
+ @property
53
+ def atoms_count(self) -> int:
54
+ return len(self._atoms)
55
+
56
+ @property
57
+ def atoms_numbers(self) -> Iterator[int]:
58
+ return iter(self._atoms)
59
+
60
+ def bond(self, n: int, m: int) -> Bond:
61
+ try:
62
+ return self._bonds[n][m]
63
+ except KeyError as e:
64
+ raise BondNotFound from e
65
+
66
+ def has_bond(self, n: int, m: int) -> bool:
67
+ try:
68
+ self._bonds[n] # check if atom exists
69
+ return n in self._bonds[m]
70
+ except KeyError:
71
+ raise AtomNotFound
72
+
73
+ def bonds(self) -> Iterator[Tuple[int, int, Bond]]:
74
+ """
75
+ iterate other all bonds
76
+ """
77
+ seen = set()
78
+ for n, m_bond in self._bonds.items():
79
+ seen.add(n)
80
+ for m, bond in m_bond.items():
81
+ if m not in seen:
82
+ yield n, m, bond
83
+
84
+ @cached_property
85
+ def bonds_count(self) -> int:
86
+ return sum(len(x) for x in self._bonds.values()) // 2
87
+
88
+ @abstractmethod
89
+ def add_atom(self, atom: Atom, n: Optional[int] = None) -> int:
90
+ """
91
+ new atom addition
92
+ """
93
+ if n is None:
94
+ n = max(self._atoms, default=0) + 1
95
+ elif not isinstance(n, int):
96
+ raise TypeError('mapping should be integer')
97
+ elif n in self._atoms:
98
+ raise MappingError('atom with same number exists')
99
+
100
+ self._atoms[n] = atom
101
+ self._bonds[n] = {}
102
+ self.flush_cache()
103
+ return n
104
+
105
+ @abstractmethod
106
+ def add_bond(self, n: int, m: int, bond: Bond):
107
+ """
108
+ Add bond.
109
+ """
110
+ if n == m:
111
+ raise MappingError('atom loops impossible')
112
+ if n not in self._bonds or m not in self._bonds:
113
+ raise AtomNotFound('atoms not found')
114
+ if n in self._bonds[m]:
115
+ raise MappingError('atoms already bonded')
116
+
117
+ self._bonds[n][m] = self._bonds[m][n] = bond
118
+ self.flush_cache()
119
+
120
+ def copy(self):
121
+ """
122
+ copy of graph
123
+ """
124
+ copy = object.__new__(self.__class__)
125
+ copy._atoms = {n: atom.copy(full=True) for n, atom in self.atoms()}
126
+ copy._bonds = cb = {}
127
+ for n, m_bond in self._bonds.items():
128
+ cb[n] = cbn = {}
129
+ for m, bond in m_bond.items():
130
+ if m in cb: # bond partially exists. need back-connection.
131
+ cbn[m] = cb[m][n]
132
+ else:
133
+ cbn[m] = bond.copy(full=True)
134
+ return copy
135
+
136
+ def remap(self, mapping: Dict[int, int]):
137
+ """
138
+ Change atom numbers
139
+
140
+ :param mapping: mapping of old numbers to the new
141
+ """
142
+ if len(mapping) != len(set(mapping.values())) or \
143
+ not (self._atoms.keys() - mapping.keys()).isdisjoint(mapping.values()):
144
+ raise ValueError('mapping overlap')
145
+
146
+ mg = mapping.get
147
+ self._atoms = {mg(n, n): atom for n, atom in self.atoms()}
148
+ self._bonds = {mg(n, n): {mg(m, m): bond for m, bond in m_bond.items()} for n, m_bond in self._bonds.items()}
149
+ self.flush_cache()
150
+
151
+ def union(self, other: 'Graph', *, remap: bool = False, copy: bool = True):
152
+ """
153
+ Merge Graphs into one.
154
+
155
+ :param remap: if atoms has collisions then remap other graph atoms else raise exception.
156
+ :param copy: keep original structure and return a new object
157
+ """
158
+ if self._atoms.keys() & other._atoms.keys():
159
+ if not remap:
160
+ raise MappingError('mapping of graphs is not disjoint')
161
+ other = other.copy()
162
+ other.remap({n: i for i, n in enumerate(other, start=max(self._atoms) + 1)})
163
+ else:
164
+ other = other.copy() # make a copy
165
+ u = self.copy() if copy else self
166
+ u._atoms.update(other._atoms)
167
+ u._bonds.update(other._bonds)
168
+ if not copy:
169
+ self.flush_cache()
170
+ return u
171
+
172
+ def flush_cache(self):
173
+ self.__dict__.clear()
174
+
175
+ def __copy__(self):
176
+ return self.copy()
177
+
178
+ def __or__(self, other):
179
+ """
180
+ G | H is union of graphs
181
+ """
182
+ return self.union(other, remap=True)
183
+
184
+ def __ior__(self, other):
185
+ """
186
+ G =| H is union of graphs
187
+ """
188
+ return self.union(other, remap=True, copy=False)
189
+
190
+ def __len__(self):
191
+ return len(self._atoms)
192
+
193
+ def __iter__(self) -> Iterator[int]:
194
+ return iter(self._atoms)
195
+
196
+ def __bool__(self):
197
+ return bool(self._atoms)
198
+
199
+
200
+ __all__ = ['Graph']