automol 0.0.1__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.
- automol-0.0.1/PKG-INFO +13 -0
- automol-0.0.1/pyproject.toml +86 -0
- automol-0.0.1/src/automol/__init__.py +8 -0
- automol-0.0.1/src/automol/element/__init__.py +5 -0
- automol-0.0.1/src/automol/element/core.py +140 -0
- automol-0.0.1/src/automol/element/elements-data.json +710 -0
- automol-0.0.1/src/automol/geom.py +80 -0
- automol-0.0.1/src/automol/rd/__init__.py +6 -0
- automol-0.0.1/src/automol/rd/mol.py +153 -0
- automol-0.0.1/src/automol/smiles.py +20 -0
- automol-0.0.1/src/automol/types/__init__.py +6 -0
- automol-0.0.1/src/automol/types/core.py +6 -0
- automol-0.0.1/src/automol/types/pydantic.py +44 -0
automol-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: automol
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Author: Andreas V. Copan
|
|
5
|
+
Author-email: Andreas V. Copan <avcopan@uga.edu>
|
|
6
|
+
Requires-Dist: networkx>=3.3
|
|
7
|
+
Requires-Dist: numpy>=2.0
|
|
8
|
+
Requires-Dist: pint>=0.24
|
|
9
|
+
Requires-Dist: py3dmol>=2.5
|
|
10
|
+
Requires-Dist: pydantic>=2.5
|
|
11
|
+
Requires-Dist: rdkit>=2025
|
|
12
|
+
Requires-Dist: scipy>=1.13
|
|
13
|
+
Requires-Python: >=3.12
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "automol"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
authors = [{name = "Andreas V. Copan", email = "avcopan@uga.edu"}]
|
|
5
|
+
requires-python = ">= 3.12"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"networkx>=3.3",
|
|
8
|
+
"numpy>=2.0",
|
|
9
|
+
"pint>=0.24",
|
|
10
|
+
"py3dmol>=2.5",
|
|
11
|
+
"pydantic>=2.5",
|
|
12
|
+
"rdkit>=2025",
|
|
13
|
+
"scipy>=1.13",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[build-system]
|
|
17
|
+
build-backend = "uv_build"
|
|
18
|
+
requires = ["uv_build"]
|
|
19
|
+
|
|
20
|
+
# Ruff configurations
|
|
21
|
+
[tool.ruff]
|
|
22
|
+
exclude = [
|
|
23
|
+
"docs",
|
|
24
|
+
"**/*.ipynb",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[tool.ruff.lint]
|
|
28
|
+
select = ["ALL"]
|
|
29
|
+
ignore = [
|
|
30
|
+
"COM812", # missing trailing comma (handled by format)
|
|
31
|
+
"RUF022", # `__all__` is not sorted
|
|
32
|
+
"TID252", # relative import
|
|
33
|
+
"D203", # confict: incorrect blank line before class (uses D211 instead)
|
|
34
|
+
"D213", # conflict: multi-line summary second line (uses D212 instead)
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[tool.ruff.lint.per-file-ignores]
|
|
38
|
+
"tests/**.py" = ["S101"]
|
|
39
|
+
|
|
40
|
+
[tool.ruff.lint.pydocstyle]
|
|
41
|
+
convention = "numpy"
|
|
42
|
+
|
|
43
|
+
# Ty configurations
|
|
44
|
+
[tool.ty.environment]
|
|
45
|
+
python = ".pixi/envs/dev/bin/python"
|
|
46
|
+
|
|
47
|
+
[tool.ty.src]
|
|
48
|
+
include = [
|
|
49
|
+
"src",
|
|
50
|
+
"tests",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# Import-linter configurations
|
|
54
|
+
[tool.importlinter]
|
|
55
|
+
root_package = "automol"
|
|
56
|
+
|
|
57
|
+
[[tool.importlinter.contracts]]
|
|
58
|
+
name = "Module Layering"
|
|
59
|
+
type = "layers"
|
|
60
|
+
layers = [
|
|
61
|
+
"automol.smiles",
|
|
62
|
+
"automol.geom",
|
|
63
|
+
"automol.rd",
|
|
64
|
+
"automol.types | automol.element",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# Pytest configurations
|
|
68
|
+
[tool.pytest.ini_options]
|
|
69
|
+
testpaths = ["tests", "src"]
|
|
70
|
+
addopts = [
|
|
71
|
+
"--doctest-modules",
|
|
72
|
+
"--cov=automol",
|
|
73
|
+
"--cov-report=term-missing",
|
|
74
|
+
"--cov-report=xml",
|
|
75
|
+
]
|
|
76
|
+
doctest_optionflags = "NORMALIZE_WHITESPACE"
|
|
77
|
+
|
|
78
|
+
# Pytest-cov configurations
|
|
79
|
+
[tool.coverage.run]
|
|
80
|
+
branch = true
|
|
81
|
+
source = ["automol"]
|
|
82
|
+
|
|
83
|
+
[tool.coverage.report]
|
|
84
|
+
show_missing = true
|
|
85
|
+
skip_covered = true
|
|
86
|
+
fail_under = 80
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Core element interface."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True, slots=True)
|
|
9
|
+
class Element:
|
|
10
|
+
"""
|
|
11
|
+
Chemical element.
|
|
12
|
+
|
|
13
|
+
Attributes
|
|
14
|
+
----------
|
|
15
|
+
Z :
|
|
16
|
+
Atomic number.
|
|
17
|
+
A :
|
|
18
|
+
Mass number.
|
|
19
|
+
symbol :
|
|
20
|
+
Chemical symbol.
|
|
21
|
+
mass :
|
|
22
|
+
Atomic mass.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
Z: int
|
|
26
|
+
A: int
|
|
27
|
+
symbol: str
|
|
28
|
+
mass: float
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
ELEMENT_BY_NUMBER: dict[int, Element] = {}
|
|
32
|
+
ELEMENT_BY_SYMBOL: dict[str, Element] = {}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _load_elements() -> None:
|
|
36
|
+
data_path = Path(__file__).with_name("elements-data.json")
|
|
37
|
+
|
|
38
|
+
with data_path.open() as f:
|
|
39
|
+
elements_data: list[dict[str, object]] = json.load(f)
|
|
40
|
+
|
|
41
|
+
for element_data in elements_data:
|
|
42
|
+
element = Element(**element_data)
|
|
43
|
+
|
|
44
|
+
ELEMENT_BY_NUMBER[element.Z] = element
|
|
45
|
+
ELEMENT_BY_SYMBOL[element.symbol.casefold()] = element
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
_load_elements()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def from_key(key: int | str) -> Element:
|
|
52
|
+
"""
|
|
53
|
+
Retrieve element by atomic number or symbol.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
key :
|
|
58
|
+
Atomic number (int) or symbol (str).
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
Requested element.
|
|
63
|
+
|
|
64
|
+
Raises
|
|
65
|
+
------
|
|
66
|
+
TypeError
|
|
67
|
+
If key is not int or str.
|
|
68
|
+
"""
|
|
69
|
+
if isinstance(key, int):
|
|
70
|
+
return ELEMENT_BY_NUMBER[key]
|
|
71
|
+
|
|
72
|
+
if isinstance(key, str):
|
|
73
|
+
return ELEMENT_BY_SYMBOL[key.casefold()]
|
|
74
|
+
|
|
75
|
+
msg = f"Element key must be int or str, got {type(key).__name__}"
|
|
76
|
+
raise TypeError(msg)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def number(key: int | str) -> int:
|
|
80
|
+
"""
|
|
81
|
+
Retrieve atomic number of element by atomic number or symbol.
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
key :
|
|
86
|
+
Atomic number (int) or symbol (str).
|
|
87
|
+
|
|
88
|
+
Returns
|
|
89
|
+
-------
|
|
90
|
+
Atomic number.
|
|
91
|
+
"""
|
|
92
|
+
return from_key(key).Z
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def mass_number(key: int | str) -> int:
|
|
96
|
+
"""
|
|
97
|
+
Retrieve mass number of element by atomic number or symbol.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
key :
|
|
102
|
+
Atomic number (int) or symbol (str).
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
Mass number.
|
|
107
|
+
"""
|
|
108
|
+
return from_key(key).A
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def symbol(key: int | str) -> str:
|
|
112
|
+
"""
|
|
113
|
+
Retrieve atomic symbol of element by atomic number or symbol.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
key :
|
|
118
|
+
Atomic number (int) or symbol (str).
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
Atomic symbol.
|
|
123
|
+
"""
|
|
124
|
+
return from_key(key).symbol
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def mass(key: int | str) -> float:
|
|
128
|
+
"""
|
|
129
|
+
Retrieve atomic mass of element by atomic number or symbol.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
key :
|
|
134
|
+
Atomic number (int) or symbol (str).
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
Atomic mass.
|
|
139
|
+
"""
|
|
140
|
+
return from_key(key).mass
|
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"Z": 1,
|
|
4
|
+
"A": 1,
|
|
5
|
+
"symbol": "H",
|
|
6
|
+
"mass": 1.007825031898
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"Z": 2,
|
|
10
|
+
"A": 4,
|
|
11
|
+
"symbol": "He",
|
|
12
|
+
"mass": 4.00260325413
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"Z": 3,
|
|
16
|
+
"A": 7,
|
|
17
|
+
"symbol": "Li",
|
|
18
|
+
"mass": 7.01600343426
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"Z": 4,
|
|
22
|
+
"A": 9,
|
|
23
|
+
"symbol": "Be",
|
|
24
|
+
"mass": 9.012183062
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"Z": 5,
|
|
28
|
+
"A": 11,
|
|
29
|
+
"symbol": "B",
|
|
30
|
+
"mass": 11.009305166
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"Z": 6,
|
|
34
|
+
"A": 12,
|
|
35
|
+
"symbol": "C",
|
|
36
|
+
"mass": 12.0
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"Z": 7,
|
|
40
|
+
"A": 14,
|
|
41
|
+
"symbol": "N",
|
|
42
|
+
"mass": 14.00307400425
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"Z": 8,
|
|
46
|
+
"A": 16,
|
|
47
|
+
"symbol": "O",
|
|
48
|
+
"mass": 15.99491461926
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"Z": 9,
|
|
52
|
+
"A": 19,
|
|
53
|
+
"symbol": "F",
|
|
54
|
+
"mass": 18.99840316207
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"Z": 10,
|
|
58
|
+
"A": 20,
|
|
59
|
+
"symbol": "Ne",
|
|
60
|
+
"mass": 19.99244017525
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"Z": 11,
|
|
64
|
+
"A": 23,
|
|
65
|
+
"symbol": "Na",
|
|
66
|
+
"mass": 22.98976928195
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"Z": 12,
|
|
70
|
+
"A": 24,
|
|
71
|
+
"symbol": "Mg",
|
|
72
|
+
"mass": 23.985041689
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"Z": 13,
|
|
76
|
+
"A": 27,
|
|
77
|
+
"symbol": "Al",
|
|
78
|
+
"mass": 26.981538408
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"Z": 14,
|
|
82
|
+
"A": 28,
|
|
83
|
+
"symbol": "Si",
|
|
84
|
+
"mass": 27.97692653442
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"Z": 15,
|
|
88
|
+
"A": 31,
|
|
89
|
+
"symbol": "P",
|
|
90
|
+
"mass": 30.97376199768
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"Z": 16,
|
|
94
|
+
"A": 32,
|
|
95
|
+
"symbol": "S",
|
|
96
|
+
"mass": 31.97207117354
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"Z": 17,
|
|
100
|
+
"A": 35,
|
|
101
|
+
"symbol": "Cl",
|
|
102
|
+
"mass": 34.968852694
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"Z": 18,
|
|
106
|
+
"A": 40,
|
|
107
|
+
"symbol": "Ar",
|
|
108
|
+
"mass": 39.96238312204
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"Z": 19,
|
|
112
|
+
"A": 39,
|
|
113
|
+
"symbol": "K",
|
|
114
|
+
"mass": 38.96370648482
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"Z": 20,
|
|
118
|
+
"A": 40,
|
|
119
|
+
"symbol": "Ca",
|
|
120
|
+
"mass": 39.96259085
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"Z": 21,
|
|
124
|
+
"A": 45,
|
|
125
|
+
"symbol": "Sc",
|
|
126
|
+
"mass": 44.955907051
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"Z": 22,
|
|
130
|
+
"A": 48,
|
|
131
|
+
"symbol": "Ti",
|
|
132
|
+
"mass": 47.947940677
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"Z": 23,
|
|
136
|
+
"A": 51,
|
|
137
|
+
"symbol": "V",
|
|
138
|
+
"mass": 50.943957664
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"Z": 24,
|
|
142
|
+
"A": 52,
|
|
143
|
+
"symbol": "Cr",
|
|
144
|
+
"mass": 51.940504714
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"Z": 25,
|
|
148
|
+
"A": 55,
|
|
149
|
+
"symbol": "Mn",
|
|
150
|
+
"mass": 54.93804304
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"Z": 26,
|
|
154
|
+
"A": 56,
|
|
155
|
+
"symbol": "Fe",
|
|
156
|
+
"mass": 55.934935537
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"Z": 27,
|
|
160
|
+
"A": 59,
|
|
161
|
+
"symbol": "Co",
|
|
162
|
+
"mass": 58.933193524
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"Z": 28,
|
|
166
|
+
"A": 58,
|
|
167
|
+
"symbol": "Ni",
|
|
168
|
+
"mass": 57.93534165
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"Z": 29,
|
|
172
|
+
"A": 63,
|
|
173
|
+
"symbol": "Cu",
|
|
174
|
+
"mass": 62.929597119
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"Z": 30,
|
|
178
|
+
"A": 64,
|
|
179
|
+
"symbol": "Zn",
|
|
180
|
+
"mass": 63.929141776
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"Z": 31,
|
|
184
|
+
"A": 69,
|
|
185
|
+
"symbol": "Ga",
|
|
186
|
+
"mass": 68.925573528
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"Z": 32,
|
|
190
|
+
"A": 74,
|
|
191
|
+
"symbol": "Ge",
|
|
192
|
+
"mass": 73.92117776
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"Z": 33,
|
|
196
|
+
"A": 75,
|
|
197
|
+
"symbol": "As",
|
|
198
|
+
"mass": 74.921594562
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"Z": 34,
|
|
202
|
+
"A": 80,
|
|
203
|
+
"symbol": "Se",
|
|
204
|
+
"mass": 79.916521761
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"Z": 35,
|
|
208
|
+
"A": 79,
|
|
209
|
+
"symbol": "Br",
|
|
210
|
+
"mass": 78.918337574
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"Z": 36,
|
|
214
|
+
"A": 84,
|
|
215
|
+
"symbol": "Kr",
|
|
216
|
+
"mass": 83.91149772708
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"Z": 37,
|
|
220
|
+
"A": 85,
|
|
221
|
+
"symbol": "Rb",
|
|
222
|
+
"mass": 84.91178973604
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"Z": 38,
|
|
226
|
+
"A": 88,
|
|
227
|
+
"symbol": "Sr",
|
|
228
|
+
"mass": 87.905612253
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"Z": 39,
|
|
232
|
+
"A": 89,
|
|
233
|
+
"symbol": "Y",
|
|
234
|
+
"mass": 88.905838156
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"Z": 40,
|
|
238
|
+
"A": 90,
|
|
239
|
+
"symbol": "Zr",
|
|
240
|
+
"mass": 89.904698755
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"Z": 41,
|
|
244
|
+
"A": 93,
|
|
245
|
+
"symbol": "Nb",
|
|
246
|
+
"mass": 92.90637317
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"Z": 42,
|
|
250
|
+
"A": 98,
|
|
251
|
+
"symbol": "Mo",
|
|
252
|
+
"mass": 97.905403609
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"Z": 43,
|
|
256
|
+
"A": 83,
|
|
257
|
+
"symbol": "Tc",
|
|
258
|
+
"mass": 82.966377
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"Z": 44,
|
|
262
|
+
"A": 102,
|
|
263
|
+
"symbol": "Ru",
|
|
264
|
+
"mass": 101.904340312
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"Z": 45,
|
|
268
|
+
"A": 103,
|
|
269
|
+
"symbol": "Rh",
|
|
270
|
+
"mass": 102.905494081
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"Z": 46,
|
|
274
|
+
"A": 106,
|
|
275
|
+
"symbol": "Pd",
|
|
276
|
+
"mass": 105.903480287
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"Z": 47,
|
|
280
|
+
"A": 107,
|
|
281
|
+
"symbol": "Ag",
|
|
282
|
+
"mass": 106.905091509
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"Z": 48,
|
|
286
|
+
"A": 114,
|
|
287
|
+
"symbol": "Cd",
|
|
288
|
+
"mass": 113.903364998
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"Z": 49,
|
|
292
|
+
"A": 115,
|
|
293
|
+
"symbol": "In",
|
|
294
|
+
"mass": 114.903878772
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"Z": 50,
|
|
298
|
+
"A": 120,
|
|
299
|
+
"symbol": "Sn",
|
|
300
|
+
"mass": 119.902202557
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"Z": 51,
|
|
304
|
+
"A": 121,
|
|
305
|
+
"symbol": "Sb",
|
|
306
|
+
"mass": 120.903811353
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"Z": 52,
|
|
310
|
+
"A": 130,
|
|
311
|
+
"symbol": "Te",
|
|
312
|
+
"mass": 129.906222745
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"Z": 53,
|
|
316
|
+
"A": 127,
|
|
317
|
+
"symbol": "I",
|
|
318
|
+
"mass": 126.904472592
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"Z": 54,
|
|
322
|
+
"A": 132,
|
|
323
|
+
"symbol": "Xe",
|
|
324
|
+
"mass": 131.90415508346
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"Z": 55,
|
|
328
|
+
"A": 133,
|
|
329
|
+
"symbol": "Cs",
|
|
330
|
+
"mass": 132.905451958
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"Z": 56,
|
|
334
|
+
"A": 138,
|
|
335
|
+
"symbol": "Ba",
|
|
336
|
+
"mass": 137.905247059
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"Z": 57,
|
|
340
|
+
"A": 139,
|
|
341
|
+
"symbol": "La",
|
|
342
|
+
"mass": 138.906362927
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"Z": 58,
|
|
346
|
+
"A": 140,
|
|
347
|
+
"symbol": "Ce",
|
|
348
|
+
"mass": 139.905448433
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"Z": 59,
|
|
352
|
+
"A": 141,
|
|
353
|
+
"symbol": "Pr",
|
|
354
|
+
"mass": 140.907659604
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"Z": 60,
|
|
358
|
+
"A": 142,
|
|
359
|
+
"symbol": "Nd",
|
|
360
|
+
"mass": 141.907728824
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"Z": 61,
|
|
364
|
+
"A": 126,
|
|
365
|
+
"symbol": "Pm",
|
|
366
|
+
"mass": 125.957327
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"Z": 62,
|
|
370
|
+
"A": 152,
|
|
371
|
+
"symbol": "Sm",
|
|
372
|
+
"mass": 151.919738646
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"Z": 63,
|
|
376
|
+
"A": 153,
|
|
377
|
+
"symbol": "Eu",
|
|
378
|
+
"mass": 152.921236789
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"Z": 64,
|
|
382
|
+
"A": 158,
|
|
383
|
+
"symbol": "Gd",
|
|
384
|
+
"mass": 157.9241112
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"Z": 65,
|
|
388
|
+
"A": 159,
|
|
389
|
+
"symbol": "Tb",
|
|
390
|
+
"mass": 158.925353707
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"Z": 66,
|
|
394
|
+
"A": 164,
|
|
395
|
+
"symbol": "Dy",
|
|
396
|
+
"mass": 163.929180819
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"Z": 67,
|
|
400
|
+
"A": 165,
|
|
401
|
+
"symbol": "Ho",
|
|
402
|
+
"mass": 164.930329116
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"Z": 68,
|
|
406
|
+
"A": 166,
|
|
407
|
+
"symbol": "Er",
|
|
408
|
+
"mass": 165.930301067
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"Z": 69,
|
|
412
|
+
"A": 169,
|
|
413
|
+
"symbol": "Tm",
|
|
414
|
+
"mass": 168.934218956
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"Z": 70,
|
|
418
|
+
"A": 174,
|
|
419
|
+
"symbol": "Yb",
|
|
420
|
+
"mass": 173.938867545
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"Z": 71,
|
|
424
|
+
"A": 175,
|
|
425
|
+
"symbol": "Lu",
|
|
426
|
+
"mass": 174.940777211
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"Z": 72,
|
|
430
|
+
"A": 180,
|
|
431
|
+
"symbol": "Hf",
|
|
432
|
+
"mass": 179.946559537
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"Z": 73,
|
|
436
|
+
"A": 181,
|
|
437
|
+
"symbol": "Ta",
|
|
438
|
+
"mass": 180.947998528
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"Z": 74,
|
|
442
|
+
"A": 184,
|
|
443
|
+
"symbol": "W",
|
|
444
|
+
"mass": 183.95093318
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"Z": 75,
|
|
448
|
+
"A": 187,
|
|
449
|
+
"symbol": "Re",
|
|
450
|
+
"mass": 186.955752217
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"Z": 76,
|
|
454
|
+
"A": 192,
|
|
455
|
+
"symbol": "Os",
|
|
456
|
+
"mass": 191.961478765
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"Z": 77,
|
|
460
|
+
"A": 193,
|
|
461
|
+
"symbol": "Ir",
|
|
462
|
+
"mass": 192.962923753
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"Z": 78,
|
|
466
|
+
"A": 195,
|
|
467
|
+
"symbol": "Pt",
|
|
468
|
+
"mass": 194.964794325
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"Z": 79,
|
|
472
|
+
"A": 197,
|
|
473
|
+
"symbol": "Au",
|
|
474
|
+
"mass": 196.966570103
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"Z": 80,
|
|
478
|
+
"A": 202,
|
|
479
|
+
"symbol": "Hg",
|
|
480
|
+
"mass": 201.970643604
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"Z": 81,
|
|
484
|
+
"A": 205,
|
|
485
|
+
"symbol": "Tl",
|
|
486
|
+
"mass": 204.974427318
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"Z": 82,
|
|
490
|
+
"A": 208,
|
|
491
|
+
"symbol": "Pb",
|
|
492
|
+
"mass": 207.976652005
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
"Z": 83,
|
|
496
|
+
"A": 209,
|
|
497
|
+
"symbol": "Bi",
|
|
498
|
+
"mass": 208.980398599
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
"Z": 84,
|
|
502
|
+
"A": 186,
|
|
503
|
+
"symbol": "Po",
|
|
504
|
+
"mass": 186.004403174
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"Z": 85,
|
|
508
|
+
"A": 191,
|
|
509
|
+
"symbol": "At",
|
|
510
|
+
"mass": 191.004148081
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"Z": 86,
|
|
514
|
+
"A": 193,
|
|
515
|
+
"symbol": "Rn",
|
|
516
|
+
"mass": 193.009707973
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"Z": 87,
|
|
520
|
+
"A": 197,
|
|
521
|
+
"symbol": "Fr",
|
|
522
|
+
"mass": 197.011008086
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
"Z": 88,
|
|
526
|
+
"A": 201,
|
|
527
|
+
"symbol": "Ra",
|
|
528
|
+
"mass": 201.012814699
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"Z": 89,
|
|
532
|
+
"A": 205,
|
|
533
|
+
"symbol": "Ac",
|
|
534
|
+
"mass": 205.015144152
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"Z": 90,
|
|
538
|
+
"A": 232,
|
|
539
|
+
"symbol": "Th",
|
|
540
|
+
"mass": 232.038053606
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"Z": 91,
|
|
544
|
+
"A": 231,
|
|
545
|
+
"symbol": "Pa",
|
|
546
|
+
"mass": 231.0358825
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"Z": 92,
|
|
550
|
+
"A": 238,
|
|
551
|
+
"symbol": "U",
|
|
552
|
+
"mass": 238.050786936
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"Z": 93,
|
|
556
|
+
"A": 219,
|
|
557
|
+
"symbol": "Np",
|
|
558
|
+
"mass": 219.031601865
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"Z": 94,
|
|
562
|
+
"A": 221,
|
|
563
|
+
"symbol": "Pu",
|
|
564
|
+
"mass": 221.038572
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
"Z": 95,
|
|
568
|
+
"A": 223,
|
|
569
|
+
"symbol": "Am",
|
|
570
|
+
"mass": 223.04584
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"Z": 96,
|
|
574
|
+
"A": 231,
|
|
575
|
+
"symbol": "Cm",
|
|
576
|
+
"mass": 231.050746
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"Z": 97,
|
|
580
|
+
"A": 233,
|
|
581
|
+
"symbol": "Bk",
|
|
582
|
+
"mass": 233.056652
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
"Z": 98,
|
|
586
|
+
"A": 237,
|
|
587
|
+
"symbol": "Cf",
|
|
588
|
+
"mass": 237.062199272
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"Z": 99,
|
|
592
|
+
"A": 239,
|
|
593
|
+
"symbol": "Es",
|
|
594
|
+
"mass": 239.06831
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"Z": 100,
|
|
598
|
+
"A": 241,
|
|
599
|
+
"symbol": "Fm",
|
|
600
|
+
"mass": 241.074311
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"Z": 101,
|
|
604
|
+
"A": 244,
|
|
605
|
+
"symbol": "Md",
|
|
606
|
+
"mass": 244.081157
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
"Z": 102,
|
|
610
|
+
"A": 248,
|
|
611
|
+
"symbol": "No",
|
|
612
|
+
"mass": 248.086623
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"Z": 103,
|
|
616
|
+
"A": 251,
|
|
617
|
+
"symbol": "Lr",
|
|
618
|
+
"mass": 251.094289
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"Z": 104,
|
|
622
|
+
"A": 253,
|
|
623
|
+
"symbol": "Rf",
|
|
624
|
+
"mass": 253.100528
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
"Z": 105,
|
|
628
|
+
"A": 255,
|
|
629
|
+
"symbol": "Db",
|
|
630
|
+
"mass": 255.106919
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"Z": 106,
|
|
634
|
+
"A": 258,
|
|
635
|
+
"symbol": "Sg",
|
|
636
|
+
"mass": 258.11304
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
"Z": 107,
|
|
640
|
+
"A": 260,
|
|
641
|
+
"symbol": "Bh",
|
|
642
|
+
"mass": 260.121443
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
"Z": 108,
|
|
646
|
+
"A": 263,
|
|
647
|
+
"symbol": "Hs",
|
|
648
|
+
"mass": 263.128479
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
"Z": 109,
|
|
652
|
+
"A": 265,
|
|
653
|
+
"symbol": "Mt",
|
|
654
|
+
"mass": 265.135937
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"Z": 110,
|
|
658
|
+
"A": 267,
|
|
659
|
+
"symbol": "Ds",
|
|
660
|
+
"mass": 267.143726
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"Z": 111,
|
|
664
|
+
"A": 272,
|
|
665
|
+
"symbol": "Rg",
|
|
666
|
+
"mass": 272.153273
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"Z": 112,
|
|
670
|
+
"A": 276,
|
|
671
|
+
"symbol": "Cn",
|
|
672
|
+
"mass": 276.161418
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"Z": 113,
|
|
676
|
+
"A": 278,
|
|
677
|
+
"symbol": "Nh",
|
|
678
|
+
"mass": 278.170725
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
"Z": 114,
|
|
682
|
+
"A": 284,
|
|
683
|
+
"symbol": "Fl",
|
|
684
|
+
"mass": 284.181192
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
"Z": 115,
|
|
688
|
+
"A": 287,
|
|
689
|
+
"symbol": "Mc",
|
|
690
|
+
"mass": 287.19082
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
"Z": 116,
|
|
694
|
+
"A": 289,
|
|
695
|
+
"symbol": "Lv",
|
|
696
|
+
"mass": 289.198023
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"Z": 117,
|
|
700
|
+
"A": 291,
|
|
701
|
+
"symbol": "Ts",
|
|
702
|
+
"mass": 291.205748
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
"Z": 118,
|
|
706
|
+
"A": 293,
|
|
707
|
+
"symbol": "Og",
|
|
708
|
+
"mass": 293.213423
|
|
709
|
+
}
|
|
710
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Molecular geometries."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from pydantic import BaseModel, ConfigDict
|
|
5
|
+
|
|
6
|
+
from . import element, rd
|
|
7
|
+
from .types import CoordinatesField, FloatArray
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Geometry(BaseModel):
|
|
11
|
+
"""
|
|
12
|
+
Molecular geometry.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
symbols : list[str]
|
|
17
|
+
Atomic symbols in order (e.g., ``["H", "O", "H"]``).
|
|
18
|
+
The length of ``symbols`` must match the number of atoms.
|
|
19
|
+
|
|
20
|
+
coordinates : CoordinatesField
|
|
21
|
+
Cartesian coordinates of the atoms.
|
|
22
|
+
Shape is ``(len(symbols), 3)`` and the ordering corresponds to ``symbols``.
|
|
23
|
+
Units are assumed to be **angstroms** unless otherwise specified.
|
|
24
|
+
|
|
25
|
+
charge : int, optional
|
|
26
|
+
Total molecular charge.
|
|
27
|
+
Default is ``0``.
|
|
28
|
+
|
|
29
|
+
spin : int, optional
|
|
30
|
+
Total spin multiplicity or spin quantum number (depending on convention).
|
|
31
|
+
Default is ``0``.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
symbols: list[str]
|
|
35
|
+
coordinates: CoordinatesField
|
|
36
|
+
charge: int = 0
|
|
37
|
+
spin: int = 0
|
|
38
|
+
|
|
39
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def from_rdkit_molecule(mol: rd.Mol) -> Geometry:
|
|
43
|
+
"""
|
|
44
|
+
Generate geometry from RDKit molecule.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
mol
|
|
49
|
+
RDKit molecule.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
Geometry.
|
|
54
|
+
"""
|
|
55
|
+
if not rd.mol.has_coordinates(mol):
|
|
56
|
+
mol = rd.mol.add_coordinates(mol)
|
|
57
|
+
|
|
58
|
+
return Geometry(
|
|
59
|
+
symbols=rd.mol.symbols(mol),
|
|
60
|
+
coordinates=rd.mol.coordinates(mol),
|
|
61
|
+
charge=rd.mol.charge(mol),
|
|
62
|
+
spin=rd.mol.spin(mol),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def center_of_mass(geo: Geometry) -> FloatArray:
|
|
67
|
+
"""
|
|
68
|
+
Calculate geometry center of mass.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
Geometry.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
Center of mass coordinates.
|
|
77
|
+
"""
|
|
78
|
+
masses = list(map(element.mass, geo.symbols))
|
|
79
|
+
coords = geo.coordinates
|
|
80
|
+
return np.sum(np.reshape(masses, (-1, 1)) * coords, axis=0) / np.sum(masses)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""RDKit molecule."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from rdkit import Chem
|
|
5
|
+
from rdkit.Chem import Descriptors, Mol
|
|
6
|
+
from rdkit.Chem.rdDistGeom import EmbedMolecule
|
|
7
|
+
|
|
8
|
+
from ..types import FloatArray
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Generators
|
|
12
|
+
def from_smiles(smi: str, *, with_coords: bool = False) -> Mol:
|
|
13
|
+
"""
|
|
14
|
+
Get RDKit molecule from SMILES string.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
smi
|
|
19
|
+
SMILES string.
|
|
20
|
+
|
|
21
|
+
with_coords, optional
|
|
22
|
+
If `True`, generate 3D coordinates for the molecule.
|
|
23
|
+
If `False` (default), return a molecule without coordinates.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
RDKit molecule.
|
|
28
|
+
"""
|
|
29
|
+
mol = Chem.MolFromSmiles(smi)
|
|
30
|
+
mol = Chem.AddHs(mol)
|
|
31
|
+
if with_coords:
|
|
32
|
+
add_coordinates(mol, in_place=True)
|
|
33
|
+
return mol
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Properties
|
|
37
|
+
def symbols(mol: Mol) -> list[str]:
|
|
38
|
+
"""
|
|
39
|
+
Get atomic symbols.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
mol
|
|
44
|
+
RDKit molecule object.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
List of atomic symbols.
|
|
49
|
+
"""
|
|
50
|
+
return [a.GetSymbol() for a in mol.GetAtoms()]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def coordinates(mol: Mol) -> FloatArray:
|
|
54
|
+
"""
|
|
55
|
+
Get atom coordinates.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
mol
|
|
60
|
+
RDKit molecule object.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
Atomic coordinates as (N, 3) numpy array.
|
|
65
|
+
|
|
66
|
+
Raises
|
|
67
|
+
------
|
|
68
|
+
ValueError
|
|
69
|
+
If the molecule has no coordinates.
|
|
70
|
+
"""
|
|
71
|
+
if not has_coordinates(mol):
|
|
72
|
+
msg = "Molecule has no coordinates. Did you forget to add them?"
|
|
73
|
+
raise ValueError(msg)
|
|
74
|
+
|
|
75
|
+
natms = mol.GetNumAtoms()
|
|
76
|
+
conf = mol.GetConformer()
|
|
77
|
+
coords = [conf.GetAtomPosition(i) for i in range(natms)]
|
|
78
|
+
return np.array(coords, dtype=np.float64)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def charge(mol: Mol) -> int:
|
|
82
|
+
"""
|
|
83
|
+
Get molecular charge.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
mol
|
|
88
|
+
RDKit molecule object.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
Molecular charge as an integer.
|
|
93
|
+
"""
|
|
94
|
+
return Chem.GetFormalCharge(mol)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def spin(mol: Mol) -> int:
|
|
98
|
+
"""
|
|
99
|
+
Get molecular spin (number of unpaired electrons).
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
mol
|
|
104
|
+
RDKit molecule object.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
Number of unpaired electrons as an integer.
|
|
109
|
+
"""
|
|
110
|
+
return Descriptors.NumRadicalElectrons(mol)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# Boolean properties
|
|
114
|
+
def has_coordinates(mol: Mol) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Check if coordinates have been added.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
mol
|
|
121
|
+
RDKit molecule object.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
`True` if the molecule has coordinates, False otherwise.
|
|
126
|
+
"""
|
|
127
|
+
return bool(mol.GetNumConformers())
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Transformations
|
|
131
|
+
def add_coordinates(mol: Mol, *, in_place: bool = False) -> Mol:
|
|
132
|
+
"""
|
|
133
|
+
Add coordinates, if missing.
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
mol
|
|
138
|
+
RDKit molecule object.
|
|
139
|
+
in_place, optional
|
|
140
|
+
If `True`, modify the molecule in place.
|
|
141
|
+
If `False` (default), return a new molecule.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
RDKit molecule object with coordinates.
|
|
146
|
+
(Unmodified if it already had coordinates.)
|
|
147
|
+
"""
|
|
148
|
+
if has_coordinates(mol):
|
|
149
|
+
return mol
|
|
150
|
+
|
|
151
|
+
mol = mol if in_place else Mol(mol)
|
|
152
|
+
EmbedMolecule(mol)
|
|
153
|
+
return mol
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""SMILES strings."""
|
|
2
|
+
|
|
3
|
+
from . import geom, rd
|
|
4
|
+
from .geom import Geometry
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def geometry(smi: str) -> Geometry:
|
|
8
|
+
"""Get the geometry corresponding to a SMILES string.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
smi : str
|
|
13
|
+
Input SMILES string.
|
|
14
|
+
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
Corresponding geometry.
|
|
18
|
+
"""
|
|
19
|
+
mol = rd.mol.from_smiles(smi, with_coords=True)
|
|
20
|
+
return geom.from_rdkit_molecule(mol)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Pydantic types."""
|
|
2
|
+
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from numpy import typing as npt
|
|
7
|
+
from pydantic import BeforeValidator, PlainSerializer
|
|
8
|
+
from pydantic.functional_validators import SkipValidation
|
|
9
|
+
|
|
10
|
+
from .core import FloatArray
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Float array field
|
|
14
|
+
def _float_array_validator(obj: object) -> FloatArray:
|
|
15
|
+
return np.asarray(obj, dtype=np.float64)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _float_array_serializer(arr: FloatArray) -> list:
|
|
19
|
+
return arr.tolist()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
FloatArrayField = Annotated[
|
|
23
|
+
SkipValidation[npt.ArrayLike],
|
|
24
|
+
BeforeValidator(_float_array_validator),
|
|
25
|
+
PlainSerializer(_float_array_serializer, return_type=list),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Coordinates field
|
|
30
|
+
def _coordinates_validator(obj: object) -> FloatArray:
|
|
31
|
+
arr = _float_array_validator(obj)
|
|
32
|
+
|
|
33
|
+
if arr.ndim != 2 or arr.shape[-1] != 3: # noqa: PLR2004
|
|
34
|
+
msg = f"Expected array of shape (N, 3) but got {arr.shape}."
|
|
35
|
+
raise ValueError(msg)
|
|
36
|
+
|
|
37
|
+
return arr
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
CoordinatesField = Annotated[
|
|
41
|
+
SkipValidation[npt.ArrayLike],
|
|
42
|
+
BeforeValidator(_coordinates_validator),
|
|
43
|
+
PlainSerializer(_float_array_serializer, return_type=list),
|
|
44
|
+
]
|