rdworks 0.25.8__py3-none-any.whl → 0.35.1__py3-none-any.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.
- rdworks/__init__.py +19 -20
- rdworks/conf.py +308 -117
- rdworks/display.py +244 -83
- rdworks/mol.py +620 -489
- rdworks/mollibr.py +336 -180
- rdworks/readin.py +2 -4
- rdworks/scaffold.py +1 -1
- rdworks/std.py +64 -24
- rdworks/torsion.py +477 -0
- rdworks/units.py +7 -58
- rdworks/utils.py +141 -258
- rdworks/xtb/__init__.py +0 -0
- rdworks/xtb/wrapper.py +304 -0
- {rdworks-0.25.8.dist-info → rdworks-0.35.1.dist-info}/METADATA +6 -9
- {rdworks-0.25.8.dist-info → rdworks-0.35.1.dist-info}/RECORD +18 -15
- {rdworks-0.25.8.dist-info → rdworks-0.35.1.dist-info}/WHEEL +1 -1
- {rdworks-0.25.8.dist-info → rdworks-0.35.1.dist-info}/licenses/LICENSE +0 -0
- {rdworks-0.25.8.dist-info → rdworks-0.35.1.dist-info}/top_level.txt +0 -0
rdworks/units.py
CHANGED
@@ -1,63 +1,12 @@
|
|
1
|
-
from types import SimpleNamespace
|
2
|
-
|
3
1
|
# In ASE, the default energy unit is eV (electron volt).
|
4
|
-
#
|
5
|
-
|
2
|
+
# In xtb, the default energy unit it Eh (hartree).
|
3
|
+
|
4
|
+
# CODATA 2018 energy conversion factor
|
5
|
+
|
6
6
|
hartree2ev = 27.211386245988
|
7
7
|
hartree2kcalpermol = 627.50947337481
|
8
8
|
ev2kcalpermol = 23.060547830619026
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
11: 'Na', 12: 'Mg', 13: 'Al', 14: 'Si', 15: 'P', 16: 'S', 17: 'Cl', 18: 'Ar', 19: 'K', 20: 'Ca',
|
14
|
-
21: 'Sc', 22: 'Ti', 23: 'V', 24: 'Cr', 25: 'Mn', 26: 'Fe', 27: 'Co', 28: 'Ni', 29: 'Cu', 30: 'Zn',
|
15
|
-
31: 'Ga', 32: 'Ge', 33: 'As', 34: 'Se', 35: 'Br', 36: 'Kr', 37: 'Rb', 38: 'Sr', 39: 'Y', 40: 'Zr',
|
16
|
-
41: 'Nb', 42: 'Mo', 43: 'Tc', 44: 'Ru', 45: 'Rh', 46: 'Pd', 47: 'Ag', 48: 'Cd', 49: 'In', 50: 'Sn',
|
17
|
-
51: 'Sb', 52: 'Te', 53: 'I', 54: 'Xe', 55: 'Cs', 56: 'Ba', 57: 'La', 58: 'Ce', 59: 'Pr', 60: 'Nd',
|
18
|
-
61: 'Pm', 62: 'Sm', 63: 'Eu', 64: 'Gd', 65: 'Tb', 66: 'Dy', 67: 'Ho', 68: 'Er', 69: 'Tm', 70: 'Yb',
|
19
|
-
71: 'Lu', 72: 'Hf', 73: 'Ta', 74: 'W', 75: 'Re', 76: 'Os', 77: 'Ir', 78: 'Pt', 79: 'Au', 80: 'Hg',
|
20
|
-
81: 'Tl', 82: 'Pb', 83: 'Bi', 84: 'Po', 85: 'At', 86: 'Rn', 87: 'Fr', 88: 'Ra', 89: 'Ac', 90: 'Th',
|
21
|
-
91: 'Pa', 92: 'U', 93: 'Np', 94: 'Pu', 95: 'Am', 96: 'Cm', 97: 'Bk', 98: 'Cf', 99: 'Es', 100: 'Fm',
|
22
|
-
101: 'Md', 102: 'No', 103: 'Lr', 104: 'Rf', 105: 'Db', 106: 'Sg', 107: 'Bh', 108: 'Hs', 109: 'Mt', 110: 'Ds',
|
23
|
-
111: 'Rg', 112: 'Cn', 113: 'Nh', 114: 'Fl', 115: 'Mc', 116: 'Lv', 117: 'Ts', 118: 'Og'
|
24
|
-
},
|
25
|
-
long_symbol = {
|
26
|
-
1: 'Hydrogen', 2: 'Helium', 3: 'Lithium', 4: 'Beryllium', 5: 'Boron',
|
27
|
-
6: 'Carbon', 7: 'Nitrogen', 8: 'Oxygen', 9: 'Fluorine', 10: 'Neon',
|
28
|
-
11: 'Sodium', 12: 'Magnesium', 13: 'Aluminum', 14: 'Silicon', 15: 'Phosphorus',
|
29
|
-
16: 'Sulfur', 17: 'Chlorine', 18: 'Argon', 19: 'Potassium', 20: 'Calcium',
|
30
|
-
21: 'Scandium', 22: 'Titanium', 23: 'Vanadium', 24: 'Chromium', 25: 'Manganese',
|
31
|
-
26: 'Iron', 27: 'Cobalt', 28: 'Nickel', 29: 'Copper', 30: 'Zinc',
|
32
|
-
31: 'Gallium', 32: 'Germanium', 33: 'Arsenic', 34: 'Selenium', 35: 'Bromine',
|
33
|
-
36: 'Krypton', 37: 'Rubidium', 38: 'Strontium', 39: 'Yttrium', 40: 'Zirconium',
|
34
|
-
41: 'Niobium', 42: 'Molybdenum', 43: 'Technetium', 44: 'Ruthenium', 45: 'Rhodium',
|
35
|
-
46: 'Palladium', 47: 'Silver', 48: 'Cadmium', 49: 'Indium', 50: 'Tin',
|
36
|
-
51: 'Antimony', 52: 'Tellurium', 53: 'Iodine', 54: 'Xenon', 55: 'Cesium',
|
37
|
-
56: 'Barium', 57: 'Lanthanum', 58: 'Cerium', 59: 'Praseodymium', 60: 'Neodymium',
|
38
|
-
61: 'Promethium', 62: 'Samarium', 63: 'Europium', 64: 'Gadolinium', 65: 'Terbium',
|
39
|
-
66: 'Dysprosium', 67: 'Holmium', 68: 'Erbium', 69: 'Thulium', 70: 'Ytterbium',
|
40
|
-
71: 'Lutetium', 72: 'Hafnium', 73: 'Tantalum', 74: 'Tungsten', 75: 'Rhenium',
|
41
|
-
76: 'Osmium', 77: 'Iridium', 78: 'Platinum', 79: 'Gold', 80: 'Mercury',
|
42
|
-
81: 'Thallium', 82: 'Lead', 83: 'Bismuth', 84: 'Polonium', 85: 'Astatine',
|
43
|
-
86: 'Radon', 87: 'Francium', 88: 'Radium', 89: 'Actinium', 90: 'Thorium',
|
44
|
-
91: 'Protactinium', 92: 'Uranium', 93: 'Neptunium', 94: 'Plutonium', 95: 'Americium',
|
45
|
-
96: 'Curium', 97: 'Berkelium', 98: 'Californium', 99: 'Einsteinium', 100: 'Fermium',
|
46
|
-
101: 'Mendelevium', 102: 'Nobelium', 103: 'Lawrencium', 104: 'Rutherfordium', 105: 'Dubnium',
|
47
|
-
106: 'Seaborgium', 107: 'Bohrium', 108: 'Hassium', 109: 'Meitnerium', 110: 'Darmstadtium',
|
48
|
-
111: 'Roentgenium', 112: 'Copernicium', 113: 'Nihonium', 114: 'Flerovium', 115: 'Moscovium',
|
49
|
-
116: 'Livermorium', 117: 'Tennessine', 118: 'Oganesson'
|
50
|
-
},
|
51
|
-
)
|
52
|
-
|
53
|
-
|
54
|
-
# Initialize UFF bond radii (Rappe et al. JACS 1992)
|
55
|
-
# Units of angstroms
|
56
|
-
# These radii neglect the bond-order and electronegativity corrections in the original paper.
|
57
|
-
# Where several values exist for the same atom, the largest was used.
|
58
|
-
radii = {
|
59
|
-
1:0.354, 5:0.838, 6:0.757, 7:0.700, 8:0.658, 9:0.668,
|
60
|
-
14:1.117, 15:1.117, 16:1.064, 17:1.044,
|
61
|
-
32:1.197, 33:1.211, 34:1.190, 35:1.192,
|
62
|
-
51:1.407, 52:1.386, 53:1.382,
|
63
|
-
}
|
10
|
+
# In mendeleev, the default length unit is pm.
|
11
|
+
# picometer (e-12) to angstrom (e-10)
|
12
|
+
pm2angstrom = 0.01
|
rdworks/utils.py
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
import numpy as np
|
2
2
|
import math
|
3
|
-
import networkx as nx
|
4
|
-
import gzip
|
5
3
|
import operator
|
6
|
-
import re
|
7
|
-
import shlex
|
8
4
|
|
9
|
-
from rdkit import Chem
|
10
5
|
from pathlib import Path
|
11
|
-
from
|
12
|
-
from
|
6
|
+
from types import SimpleNamespace
|
7
|
+
from typing import Any
|
8
|
+
from collections.abc import Callable
|
13
9
|
from concurrent.futures import ProcessPoolExecutor
|
14
10
|
from tqdm import tqdm
|
15
11
|
|
12
|
+
from rdkit import Chem
|
13
|
+
|
16
14
|
from rdworks.autograph.centroid import centroid_medoid
|
17
15
|
|
18
16
|
|
@@ -96,13 +94,47 @@ def guess_mol_id(lprops:list[dict]) -> tuple[str, int, int]:
|
|
96
94
|
return (property_key, count, total)
|
97
95
|
|
98
96
|
|
97
|
+
def dict_to_simplenamespace(data):
|
98
|
+
if isinstance(data, dict):
|
99
|
+
return SimpleNamespace(**{k: dict_to_simplenamespace(v) for k, v in data.items()})
|
100
|
+
elif isinstance(data, list):
|
101
|
+
return [dict_to_simplenamespace(item) for item in data]
|
102
|
+
else:
|
103
|
+
return data
|
104
|
+
|
105
|
+
|
106
|
+
def recursive_round(data:Any, decimals:int=2) -> Any:
|
107
|
+
"""Recursively round float values to a given decimal places.
|
99
108
|
|
100
|
-
|
109
|
+
Args:
|
110
|
+
data: The input data, which can be a list, dictionary, or any
|
111
|
+
other data type. It can contain nested lists and dictionaries.
|
112
|
+
decimals: number of decimal places.
|
113
|
+
"""
|
114
|
+
if not isinstance(decimals, int) or decimals < 0:
|
115
|
+
raise ValueError("decimals must be a non-negative integer.")
|
116
|
+
|
117
|
+
def _recursive_round(current_item):
|
118
|
+
if isinstance(current_item, float):
|
119
|
+
return round(current_item, decimals)
|
120
|
+
elif isinstance(current_item, np.float64):
|
121
|
+
return round(float(current_item), decimals)
|
122
|
+
elif isinstance(current_item, list):
|
123
|
+
return [_recursive_round(item) for item in current_item]
|
124
|
+
elif isinstance(current_item, dict):
|
125
|
+
return {key: _recursive_round(value) for key, value in current_item.items()}
|
126
|
+
else:
|
127
|
+
return current_item
|
128
|
+
|
129
|
+
return _recursive_round(data)
|
130
|
+
|
131
|
+
|
132
|
+
def fix_decimals_in_list(in_list:list, decimals:int=2) -> list:
|
101
133
|
"""Fixes the decimal places of all float values in a list.
|
102
134
|
|
103
135
|
Args:
|
104
136
|
list: The list to fix.
|
105
|
-
|
137
|
+
decimals (int): The number of decimal places to fix the float values to.
|
106
138
|
|
107
139
|
Returns:
|
108
140
|
list: a list with the float values fixed to the specified number of decimal places.
|
@@ -111,22 +143,22 @@ def fix_decimal_places_in_list(in_list:list, decimal_places:int=2) -> list:
|
|
111
143
|
out_list = []
|
112
144
|
for item in in_list:
|
113
145
|
if isinstance(item, float):
|
114
|
-
out_list.append(round(item,
|
146
|
+
out_list.append(round(item, decimals))
|
115
147
|
elif isinstance(item, dict):
|
116
|
-
out_list.append(
|
148
|
+
out_list.append(fix_decimals_in_dict(item, decimals))
|
117
149
|
elif isinstance(item, list) or isinstance(item, tuple):
|
118
|
-
out_list.append(
|
150
|
+
out_list.append(fix_decimals_in_list(item, decimals))
|
119
151
|
else:
|
120
152
|
out_list.append(item)
|
121
153
|
return out_list
|
122
154
|
|
123
155
|
|
124
|
-
def
|
156
|
+
def fix_decimals_in_dict(in_dict:dict, decimals:int=2) -> dict:
|
125
157
|
"""Fixes the decimal places of all float values in a dictionary.
|
126
158
|
|
127
159
|
Args:
|
128
160
|
dictionary: The dictionary to fix.
|
129
|
-
|
161
|
+
decimals (int): The number of decimal places to fix the float values to.
|
130
162
|
|
131
163
|
Returns:
|
132
164
|
dict: a dictionary with the float values fixed to the specified number of decimal places.
|
@@ -134,11 +166,11 @@ def fix_decimal_places_in_dict(in_dict:dict, decimal_places:int=2) -> dict:
|
|
134
166
|
out_dict = {}
|
135
167
|
for k, v in in_dict.items():
|
136
168
|
if isinstance(v, float):
|
137
|
-
out_dict[k] = round(v,
|
169
|
+
out_dict[k] = round(v, decimals)
|
138
170
|
elif isinstance(v, list) or isinstance(v, tuple):
|
139
|
-
out_dict[k] =
|
171
|
+
out_dict[k] = fix_decimals_in_list(v, decimals)
|
140
172
|
elif isinstance(v, dict):
|
141
|
-
out_dict[k] =
|
173
|
+
out_dict[k] = fix_decimals_in_dict(v, decimals)
|
142
174
|
else:
|
143
175
|
out_dict[k] = v
|
144
176
|
return out_dict
|
@@ -252,244 +284,95 @@ def QT(rmsd_matrix:np.ndarray, threshold:float) -> tuple:
|
|
252
284
|
return cluster_assignment, centroid_indices
|
253
285
|
|
254
286
|
|
255
|
-
def rdmol_to_graph(rdmol:Chem.Mol) -> nx.Graph:
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
def rdmol_to_graph_(rdmol:Chem.Mol) -> nx.Graph:
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
def graph_to_rdmol(G:nx.Graph) -> Chem.Mol:
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
def mae_rd_index(mol_dict:dict, smiles:str) -> dict:
|
350
|
-
"""Returns a map for atom indexes between a rdkit.Chem.Mol and a maestro file.
|
351
|
-
|
352
|
-
It uses networkx's `vf2pp_all_isomorphisms()` function.
|
353
|
-
|
354
|
-
Args:
|
355
|
-
mol_dict (dict): a dictionary generated from a maestro file.
|
356
|
-
smiles (str): SMILES of the molecule.
|
357
|
-
|
358
|
-
Returns:
|
359
|
-
dict: a map for atom indexes (maestro -> rdkit.Chem.Mol)
|
360
|
-
"""
|
361
|
-
bond_order_map = {
|
362
|
-
Chem.BondType.SINGLE : 1.0,
|
363
|
-
Chem.BondType.DOUBLE : 2.0,
|
364
|
-
Chem.BondType.TRIPLE : 3.0,
|
365
|
-
Chem.BondType.AROMATIC : 1.5,
|
366
|
-
Chem.BondType.UNSPECIFIED : 0.0,
|
367
|
-
}
|
368
|
-
|
369
|
-
G = nx.Graph()
|
370
|
-
for idx, atomic_num in enumerate(mol_dict['f_m_ct']['m_atom']['i_m_atomic_number'], start=1):
|
371
|
-
G.add_node(idx, atomic_num=int(atomic_num))
|
372
|
-
for (bond_from, bond_to, bond_order) in zip(mol_dict['f_m_ct']['m_bond']['i_m_from'],
|
373
|
-
mol_dict['f_m_ct']['m_bond']['i_m_to'],
|
374
|
-
mol_dict['f_m_ct']['m_bond']['i_m_order']):
|
375
|
-
G.add_edge(int(bond_from), int(bond_to), bond_order=int(bond_order))
|
376
|
-
|
377
|
-
H = nx.Graph()
|
378
|
-
rdmol = Chem.MolFromSmiles(smiles)
|
379
|
-
rdmol = Chem.AddHs(rdmol)
|
380
|
-
for atom in rdmol.GetAtoms():
|
381
|
-
H.add_node(atom.GetIdx(), atomic_num=atom.GetAtomicNum())
|
382
|
-
for bond in rdmol.GetBonds():
|
383
|
-
H.add_edge(bond.GetBeginAtomIdx(),
|
384
|
-
bond.GetEndAtomIdx(),
|
385
|
-
bond_order=bond_order_map[bond.GetBondType()])
|
386
|
-
|
387
|
-
try:
|
388
|
-
assert nx.is_isomorphic(G, H)
|
389
|
-
return nx.vf2pp_isomorphism(G, H, node_label="atomic_num")
|
390
|
-
except:
|
391
|
-
return {}
|
392
|
-
|
393
|
-
|
394
|
-
def _get_from_dict(dataDict:dict, mapList:list) -> None:
|
395
|
-
"""A subroutine for `mae_to_dict()`.
|
396
|
-
|
397
|
-
Args:
|
398
|
-
dataDict (dict): data dictionary.
|
399
|
-
mapList (list): map list.
|
400
|
-
"""
|
401
|
-
return reduce(operator.getitem, mapList, dataDict)
|
402
|
-
|
403
|
-
|
404
|
-
def _set_in_dict(dataDict:dict, mapList:list, value:Any) -> None:
|
405
|
-
"""A subroutine for `mae_to_dict()`.
|
406
|
-
|
407
|
-
Args:
|
408
|
-
dataDict (dict): data dictionary.
|
409
|
-
mapList (list): map list.
|
410
|
-
value (Any): value to set.
|
411
|
-
"""
|
412
|
-
if mapList:
|
413
|
-
_get_from_dict(dataDict, mapList[:-1])[mapList[-1]] = value
|
414
|
-
else:
|
415
|
-
for k,v in value.items():
|
416
|
-
dataDict[k] = v
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
def mae_to_dict(path:str | Path) -> dict:
|
421
|
-
"""Converts Schrodinger Maestro file to a dictionary.
|
422
|
-
|
423
|
-
Args:
|
424
|
-
path (Union[str, Path]): filename or path to a .mae or .maegz file.
|
425
|
-
|
426
|
-
Returns:
|
427
|
-
dict: python dictionary.
|
428
|
-
"""
|
429
|
-
tokens = None
|
430
|
-
if isinstance(path, str):
|
431
|
-
path = Path(path)
|
432
|
-
if path.suffix == 'gz':
|
433
|
-
with gzip.open(path, "rt") as f:
|
434
|
-
tokens = shlex.split(f.read())
|
435
|
-
else:
|
436
|
-
with open(path, "r") as f:
|
437
|
-
tokens = shlex.split(f.read())
|
438
|
-
count = re.compile(r'(\w+)\[(\d+)\]')
|
439
|
-
DATA = []
|
440
|
-
level = []
|
441
|
-
data = {}
|
442
|
-
previous_token = None
|
443
|
-
header = False
|
444
|
-
extra_column = 0
|
445
|
-
num_repeat = 1
|
446
|
-
skip = False
|
447
|
-
for token in tokens :
|
448
|
-
if token == "#" :
|
449
|
-
skip = not skip # invert
|
450
|
-
continue
|
451
|
-
elif skip:
|
452
|
-
continue
|
453
|
-
elif token == "{" :
|
454
|
-
header = True
|
455
|
-
key = []
|
456
|
-
val = []
|
457
|
-
arr = []
|
458
|
-
if previous_token:
|
459
|
-
if previous_token == "f_m_ct" and data:
|
460
|
-
DATA.append(data)
|
461
|
-
data = {}
|
462
|
-
try:
|
463
|
-
(block, num_repeat) = count.findall(previous_token)[0]
|
464
|
-
num_repeat = int(num_repeat)
|
465
|
-
extra_column = 1
|
466
|
-
except:
|
467
|
-
block = previous_token
|
468
|
-
num_repeat = 1
|
469
|
-
extra_column = 0
|
470
|
-
level.append(block)
|
471
|
-
|
472
|
-
elif token == "}":
|
473
|
-
if level:
|
474
|
-
level.pop()
|
475
|
-
elif token == ":::":
|
476
|
-
header = False
|
477
|
-
elif header:
|
478
|
-
key.append(token)
|
479
|
-
else:
|
480
|
-
val.append(token)
|
481
|
-
# only store f_m_ct blocks (level != [])
|
482
|
-
if len(val) == (len(key)+extra_column) and level :
|
483
|
-
arr.append(val[extra_column:])
|
484
|
-
val = []
|
485
|
-
if len(arr) == num_repeat:
|
486
|
-
if len(arr) == 1:
|
487
|
-
_set_in_dict(data, level, dict(zip(key,arr[0])))
|
488
|
-
else:
|
489
|
-
T = list(zip(*arr)) # transpose
|
490
|
-
_set_in_dict(data, level, dict(zip(key,T)))
|
491
|
-
previous_token = token
|
492
|
-
if data:
|
493
|
-
DATA.append(data)
|
494
|
-
|
495
|
-
return DATA
|
287
|
+
# def rdmol_to_graph(rdmol:Chem.Mol) -> nx.Graph:
|
288
|
+
# """Converts rdkit.Chem.Mol to a networkx graph object.
|
289
|
+
|
290
|
+
# Args:
|
291
|
+
# rdmol (Chem.Mol): input molecule.
|
292
|
+
|
293
|
+
# Returns:
|
294
|
+
# nx.Graph: networkx graph object.
|
295
|
+
# """
|
296
|
+
# G = nx.Graph()
|
297
|
+
# for atom in rdmol.GetAtoms():
|
298
|
+
# G.add_node(atom.GetIdx(), # 0-based index
|
299
|
+
# atomic_num=atom.GetAtomicNum(),
|
300
|
+
# formal_charge=atom.GetFormalCharge(),
|
301
|
+
# chiral_tag=atom.GetChiralTag(),
|
302
|
+
# hybridization=atom.GetHybridization(),
|
303
|
+
# num_explicit_hs=atom.GetNumExplicitHs(),
|
304
|
+
# is_aromatic=atom.GetIsAromatic())
|
305
|
+
# for bond in rdmol.GetBonds():
|
306
|
+
# G.add_edge(bond.GetBeginAtomIdx(),
|
307
|
+
# bond.GetEndAtomIdx(),
|
308
|
+
# bond_type=bond.GetBondType())
|
309
|
+
# return G
|
310
|
+
|
311
|
+
|
312
|
+
# def rdmol_to_graph_(rdmol:Chem.Mol) -> nx.Graph:
|
313
|
+
# """Converts rdkit.Chem.Mol to a networkx graph object (another implementation).
|
314
|
+
|
315
|
+
# Args:
|
316
|
+
# rdmol (Chem.Mol): input molecule.
|
317
|
+
|
318
|
+
# Returns:
|
319
|
+
# nx.Graph: networkx graph object.
|
320
|
+
# """
|
321
|
+
# atomic_nums = [atom.GetAtomicNum() for atom in rdmol.GetAtoms()]
|
322
|
+
# formal_charges = [atom.GetFormalCharge() for atom in rdmol.GetAtoms()]
|
323
|
+
# ad_matrix = Chem.GetAdjacencyMatrix(rdmol, useBO=True)
|
324
|
+
# # useBO: (optional) toggles use of bond orders in calculating the matrix. Default value is 0.
|
325
|
+
# # RETURNS: a Numeric array of floats containing the adjacency matrix
|
326
|
+
# # [[0. 1. 0. 0. 0. 0. 0. 0. 0.]
|
327
|
+
# # [1. 0. 1. 1. 1. 0. 0. 0. 0.]
|
328
|
+
# # [0. 1. 0. 0. 0. 0. 0. 0. 0.]
|
329
|
+
# # [0. 1. 0. 0. 0. 0. 0. 0. 0.]
|
330
|
+
# # [0. 1. 0. 0. 0. 1. 0. 1. 0.]
|
331
|
+
# # [0. 0. 0. 0. 1. 0. 2. 0. 0.]
|
332
|
+
# # [0. 0. 0. 0. 0. 2. 0. 0. 0.]
|
333
|
+
# # [0. 0. 0. 0. 1. 0. 0. 0. 2.]
|
334
|
+
# # [0. 0. 0. 0. 0. 0. 0. 2. 0.]]
|
335
|
+
# for i,(a_num,f_c) in enumerate(zip(atomic_nums, formal_charges)):
|
336
|
+
# if f_c !=0:
|
337
|
+
# ad_matrix[i,i] = a_num + f_c
|
338
|
+
# else:
|
339
|
+
# ad_matrix[i,i] = a_num
|
340
|
+
# G = nx.from_numpy_array(ad_matrix)
|
341
|
+
# return G
|
342
|
+
|
343
|
+
|
344
|
+
# def graph_to_rdmol(G:nx.Graph) -> Chem.Mol:
|
345
|
+
# """Converts a networkx graph object to rdkit.Chem.Mol object.
|
346
|
+
|
347
|
+
# Args:
|
348
|
+
# G (nx.Graph): a networkx graph.
|
349
|
+
|
350
|
+
# Returns:
|
351
|
+
# Chem.Mol: rdkit.Chem.Mol object.
|
352
|
+
# """
|
353
|
+
# rdmol = Chem.RWMol()
|
354
|
+
# atomic_nums = nx.get_node_attributes(G, 'atomic_num')
|
355
|
+
# chiral_tags = nx.get_node_attributes(G, 'chiral_tag')
|
356
|
+
# formal_charges = nx.get_node_attributes(G, 'formal_charge')
|
357
|
+
# node_is_aromatics = nx.get_node_attributes(G, 'is_aromatic')
|
358
|
+
# node_hybridizations = nx.get_node_attributes(G, 'hybridization')
|
359
|
+
# num_explicit_hss = nx.get_node_attributes(G, 'num_explicit_hs')
|
360
|
+
# node_to_idx = {}
|
361
|
+
# for node in G.nodes():
|
362
|
+
# a=Chem.Atom(atomic_nums[node])
|
363
|
+
# a.SetChiralTag(chiral_tags[node])
|
364
|
+
# a.SetFormalCharge(formal_charges[node])
|
365
|
+
# a.SetIsAromatic(node_is_aromatics[node])
|
366
|
+
# a.SetHybridization(node_hybridizations[node])
|
367
|
+
# a.SetNumExplicitHs(num_explicit_hss[node])
|
368
|
+
# idx = rdmol.AddAtom(a)
|
369
|
+
# node_to_idx[node] = idx
|
370
|
+
# bond_types = nx.get_edge_attributes(G, 'bond_type')
|
371
|
+
# for edge in G.edges():
|
372
|
+
# first, second = edge
|
373
|
+
# ifirst = node_to_idx[first]
|
374
|
+
# isecond = node_to_idx[second]
|
375
|
+
# bond_type = bond_types[first, second]
|
376
|
+
# rdmol.AddBond(ifirst, isecond, bond_type)
|
377
|
+
# Chem.SanitizeMol(rdmol)
|
378
|
+
# return rdmol
|
rdworks/xtb/__init__.py
ADDED
File without changes
|