rdworks 0.43.3__py3-none-any.whl → 0.45.2__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 +1 -1
- rdworks/conf.py +47 -4
- rdworks/xtb/wrapper.py +236 -32
- {rdworks-0.43.3.dist-info → rdworks-0.45.2.dist-info}/METADATA +1 -1
- {rdworks-0.43.3.dist-info → rdworks-0.45.2.dist-info}/RECORD +8 -8
- {rdworks-0.43.3.dist-info → rdworks-0.45.2.dist-info}/WHEEL +0 -0
- {rdworks-0.43.3.dist-info → rdworks-0.45.2.dist-info}/licenses/LICENSE +0 -0
- {rdworks-0.43.3.dist-info → rdworks-0.45.2.dist-info}/top_level.txt +0 -0
rdworks/__init__.py
CHANGED
rdworks/conf.py
CHANGED
@@ -210,7 +210,7 @@ class Conf:
|
|
210
210
|
|
211
211
|
if calculator.lower() == 'xTB'.lower():
|
212
212
|
water = kwargs.get('water', None)
|
213
|
-
|
213
|
+
results = GFN2xTB(self.rdmol).optimize(water=water)
|
214
214
|
# SimpleNamespace(
|
215
215
|
# PE = datadict['total energy'] * hartree2kcalpermol,
|
216
216
|
# charges = datadict['partial charges'],
|
@@ -218,8 +218,8 @@ class Conf:
|
|
218
218
|
# geometry = rdmol_opt,
|
219
219
|
# )
|
220
220
|
try:
|
221
|
-
self.rdmol =
|
222
|
-
PE_final =
|
221
|
+
self.rdmol = results.geometry
|
222
|
+
PE_final = results.PE
|
223
223
|
retcode = 0
|
224
224
|
except:
|
225
225
|
retcode = 1
|
@@ -382,7 +382,14 @@ class Conf:
|
|
382
382
|
if isinstance(calculator, str):
|
383
383
|
if calculator.lower() == 'xTB'.lower():
|
384
384
|
water = kwargs.get('water', None)
|
385
|
-
|
385
|
+
results = GFN2xTB(self.rdmol).singlepoint(water=water)
|
386
|
+
# SimpleNamespace(
|
387
|
+
# PE = datadict['total energy'] * hartree2kcalpermol,
|
388
|
+
# Gsolv = Gsolv,
|
389
|
+
# charges = datadict['partial charges'],
|
390
|
+
# wbo = Wiberg_bond_orders,
|
391
|
+
# )
|
392
|
+
PE = results.PE
|
386
393
|
|
387
394
|
elif calculator.lower() == 'MMFF94'.lower() or calculator.lower() == 'MMFF'.lower():
|
388
395
|
mp = Chem.rdForceFieldHelpers.MMFFGetMoleculeProperties(self.rdmol, mmffVariant='MMFF94')
|
@@ -677,6 +684,42 @@ class Conf:
|
|
677
684
|
return '\n'.join(lines)
|
678
685
|
|
679
686
|
|
687
|
+
def to_turbomole_coord(self, bohr: bool = False) -> str:
|
688
|
+
"""Returns TURBOMOLE coord file formatted strings.
|
689
|
+
|
690
|
+
Turbomole coord file format:
|
691
|
+
|
692
|
+
- It starts with the keyword `$coord`.
|
693
|
+
- Each line after the $coord line specifies an atom, consisting of:
|
694
|
+
- Three real numbers representing the Cartesian coordinates (x, y, z).
|
695
|
+
- A string for the element name.
|
696
|
+
- Optional: an "f" label at the end to indicate that the atom's coordinates are frozen during optimization.
|
697
|
+
- Coordinates can be given in Bohr (default), Ångström (`$coord angs`), or fractional coordinates (`$coord frac`).
|
698
|
+
- Optional data groups like periodicity (`$periodic`), lattice parameters (`$lattice`), and cell parameters (`$cell`) can also be included.
|
699
|
+
- Regarding precision:
|
700
|
+
The precision of the coordinates is crucial for accurate calculations, especially geometry optimizations.
|
701
|
+
Tools like the TURBOMOLEOptimizer might check for differences in atomic positions with a tolerance of 1e-13.
|
702
|
+
|
703
|
+
Args:
|
704
|
+
bohr (bool): whether to use Bohr units of the coordinates. Defaults to False.
|
705
|
+
Otherwise, Angstrom units will be used.
|
706
|
+
|
707
|
+
Returns:
|
708
|
+
str: TURBOMOLE coord formatted file.
|
709
|
+
"""
|
710
|
+
if bohr:
|
711
|
+
lines = ["$coord"]
|
712
|
+
else:
|
713
|
+
lines = ["$coord angs"]
|
714
|
+
|
715
|
+
for (x, y, z), e in zip(self.positions(), self.symbols()):
|
716
|
+
lines.append(f"{x:20.15f} {y:20.15f} {z:20.15f} {e}")
|
717
|
+
|
718
|
+
lines.append("$end")
|
719
|
+
|
720
|
+
return '\n'.join(lines)
|
721
|
+
|
722
|
+
|
680
723
|
def to_sdf(self, props:bool=True) -> str:
|
681
724
|
"""Returns the SDF-formatted strings.
|
682
725
|
|
rdworks/xtb/wrapper.py
CHANGED
@@ -4,6 +4,8 @@ import subprocess
|
|
4
4
|
import json
|
5
5
|
import tempfile
|
6
6
|
import logging
|
7
|
+
import shutil
|
8
|
+
import re
|
7
9
|
|
8
10
|
from pathlib import Path
|
9
11
|
from types import SimpleNamespace
|
@@ -12,7 +14,7 @@ from rdkit import Chem
|
|
12
14
|
from rdkit.Geometry import Point3D
|
13
15
|
|
14
16
|
|
15
|
-
|
17
|
+
logger = logging.getLogger()
|
16
18
|
|
17
19
|
# In ASE, the default energy unit is eV (electron volt).
|
18
20
|
# It will be converted to kcal/mol
|
@@ -23,13 +25,15 @@ ev2kcalpermol = 23.060547830619026
|
|
23
25
|
|
24
26
|
|
25
27
|
class GFN2xTB:
|
26
|
-
def __init__(self, molecule: Chem.Mol
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
def __init__(self, molecule: Chem.Mol, ncores: int = 8):
|
29
|
+
assert isinstance(molecule, Chem.Mol), "molecule is not rdkit.Chem.Mol type"
|
30
|
+
assert molecule.GetConformer().Is3D(), "molecule is not a 3D conformer"
|
31
|
+
assert self.is_xtb_ready(), "xtb is not accessible"
|
32
|
+
|
33
|
+
self.rdmol = molecule
|
34
|
+
self.natoms = molecule.GetNumAtoms()
|
35
|
+
self.symbols = [ atom.GetSymbol() for atom in molecule.GetAtoms() ]
|
36
|
+
self.positions = molecule.GetConformer().GetPositions().tolist()
|
33
37
|
|
34
38
|
# Parallelisation
|
35
39
|
os.environ['OMP_STACKSIZE'] = '4G'
|
@@ -58,6 +62,45 @@ class GFN2xTB:
|
|
58
62
|
return None
|
59
63
|
|
60
64
|
|
65
|
+
def is_xtb_ready(self, cmd: str = 'xtb') -> bool:
|
66
|
+
"""Check if xtb is available.
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
bool: True if `xtb` is available, False otherwise.
|
70
|
+
"""
|
71
|
+
return shutil.which(cmd) is not None
|
72
|
+
|
73
|
+
|
74
|
+
def is_cpx_ready(self, cmd: str = 'cpx') -> bool:
|
75
|
+
"""Checks if the CPCM-X command-line tool, `cpx`, is accessible in the system.
|
76
|
+
|
77
|
+
Returns:
|
78
|
+
bool: True if the cpx is found, False otherwise.
|
79
|
+
"""
|
80
|
+
return shutil.which(cmd) is not None
|
81
|
+
|
82
|
+
|
83
|
+
def is_cpcmx_ready(self) -> bool:
|
84
|
+
"""Checks if xtb works with the `--cpcmx` option.
|
85
|
+
|
86
|
+
xtb distributed by the conda does not include CPCM-X function (as of June 17, 2025).
|
87
|
+
xtb installed from the github source codes by using meson and ninja includes it.
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
bool: True if the --cpcmx option is working, False otherwise.
|
91
|
+
"""
|
92
|
+
cmd = ['xtb', '--cpcmx']
|
93
|
+
proc = subprocess.run(cmd, capture_output=True, text=True)
|
94
|
+
# we are expecting an error because no input file is given
|
95
|
+
assert proc.returncode != 0
|
96
|
+
for line in proc.stdout.split('\n'):
|
97
|
+
line = line.strip()
|
98
|
+
if 'CPCM-X library was not included' in line:
|
99
|
+
return False
|
100
|
+
|
101
|
+
return True
|
102
|
+
|
103
|
+
|
61
104
|
def to_xyz(self) -> str:
|
62
105
|
"""Export to XYZ formatted string.
|
63
106
|
|
@@ -71,17 +114,53 @@ class GFN2xTB:
|
|
71
114
|
return '\n'.join(lines)
|
72
115
|
|
73
116
|
|
74
|
-
def
|
117
|
+
def to_turbomole_coord(self, bohr: bool = False) -> str:
|
118
|
+
"""Returns TURBOMOLE coord file formatted strings.
|
119
|
+
|
120
|
+
Turbomole coord file format:
|
121
|
+
|
122
|
+
- It starts with the keyword `$coord`.
|
123
|
+
- Each line after the $coord line specifies an atom, consisting of:
|
124
|
+
- Three real numbers representing the Cartesian coordinates (x, y, z).
|
125
|
+
- A string for the element name.
|
126
|
+
- Optional: an "f" label at the end to indicate that the atom's coordinates are frozen during optimization.
|
127
|
+
- Coordinates can be given in Bohr (default), Ångström (`$coord angs`), or fractional coordinates (`$coord frac`).
|
128
|
+
- Optional data groups like periodicity (`$periodic`), lattice parameters (`$lattice`), and cell parameters (`$cell`) can also be included.
|
129
|
+
- Regarding precision:
|
130
|
+
The precision of the coordinates is crucial for accurate calculations, especially geometry optimizations.
|
131
|
+
Tools like the TURBOMOLEOptimizer might check for differences in atomic positions with a tolerance of 1e-13.
|
132
|
+
|
133
|
+
Args:
|
134
|
+
bohr (bool): whether to use Bohr units of the coordinates. Defaults to False.
|
135
|
+
Otherwise, Angstrom units will be used.
|
136
|
+
|
137
|
+
Returns:
|
138
|
+
str: TURBOMOLE coord formatted file.
|
139
|
+
"""
|
140
|
+
if bohr:
|
141
|
+
lines = ["$coord"]
|
142
|
+
else:
|
143
|
+
lines = ["$coord angs"]
|
144
|
+
|
145
|
+
for (x, y, z), e in zip(self.positions, self.symbols):
|
146
|
+
lines.append(f"{x:20.15f} {y:20.15f} {z:20.15f} {e}")
|
147
|
+
|
148
|
+
lines.append("$end")
|
149
|
+
|
150
|
+
return '\n'.join(lines)
|
151
|
+
|
152
|
+
|
153
|
+
def load_xyz(self, geometry_input_path: Path) -> Chem.Mol:
|
75
154
|
"""Load geometry.
|
76
155
|
|
77
156
|
Args:
|
78
|
-
|
157
|
+
geometry_input_path (Path): pathlib.Path to the xyz
|
79
158
|
|
80
159
|
Returns:
|
81
160
|
Chem.Mol: rdkit Chem.Mol object.
|
82
161
|
"""
|
83
162
|
rdmol_opt = Chem.Mol(self.rdmol)
|
84
|
-
with open(
|
163
|
+
with open(geometry_input_path, 'r') as f:
|
85
164
|
for lineno, line in enumerate(f):
|
86
165
|
if lineno == 0:
|
87
166
|
assert int(line.strip()) == self.natoms
|
@@ -100,6 +179,8 @@ class GFN2xTB:
|
|
100
179
|
def load_wbo(self, wbo_path: Path) -> dict[tuple[int, int], float]:
|
101
180
|
"""Load Wiberg bond order.
|
102
181
|
|
182
|
+
singlepoint() creates a wbo output file.
|
183
|
+
|
103
184
|
Args:
|
104
185
|
wbo_path (Path): path to the wbo file.
|
105
186
|
|
@@ -125,6 +206,104 @@ class GFN2xTB:
|
|
125
206
|
return Wiberg_bond_orders
|
126
207
|
|
127
208
|
|
209
|
+
def cpx(self, verbose: bool = False) -> float | None:
|
210
|
+
"""Runs cpx and returns Gsolv (kcal/mol)
|
211
|
+
|
212
|
+
Warning:
|
213
|
+
Solvation energy obtained from `xtb --cpcmx water` differs from
|
214
|
+
`cpx --solvent water` (difference between gas.out and solv.out in terms of total energy).
|
215
|
+
There are other correction terms not clearly defined in the output files.
|
216
|
+
So, this method is not reliable and should be discarded
|
217
|
+
|
218
|
+
Returns:
|
219
|
+
float or None: Gsolv energy in kcal/mol or None.
|
220
|
+
"""
|
221
|
+
with tempfile.TemporaryDirectory() as temp_dir: # tmpdir is a string
|
222
|
+
workdir = Path(temp_dir)
|
223
|
+
if verbose:
|
224
|
+
logger.info(f'xtb.cpx workdir= {temp_dir}')
|
225
|
+
|
226
|
+
geometry_input_path = workdir / 'coord'
|
227
|
+
geometry_output_path = workdir / 'xtbtopo.mol'
|
228
|
+
gas_out_path = workdir / 'gas.out'
|
229
|
+
solv_out_path = workdir / 'solv.out'
|
230
|
+
wbo_path = workdir / 'wbo'
|
231
|
+
|
232
|
+
with open(geometry_input_path, 'w') as f:
|
233
|
+
f.write(self.to_turbomole_coord())
|
234
|
+
|
235
|
+
cmd = ['cpx']
|
236
|
+
options = ['--solvent', 'water']
|
237
|
+
|
238
|
+
proc = subprocess.run(cmd + options, cwd=temp_dir, capture_output=True, text=True)
|
239
|
+
# cpx creates the following files:
|
240
|
+
# charges gas.energy solute_sigma.txt solvent_sigma.txt xtbtopo.mol
|
241
|
+
# coord gas.out solute_sigma3.txt solvent_sigma3.txt
|
242
|
+
# error solute.cosmo solv.out wbo
|
243
|
+
|
244
|
+
# example of solv.out
|
245
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
246
|
+
# :: SUMMARY ::
|
247
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
248
|
+
# :: total energy -119.507131639760 Eh ::
|
249
|
+
# :: w/o Gsasa/hb/shift -119.494560363045 Eh ::
|
250
|
+
# :: gradient norm 0.084154442395 Eh/a0 ::
|
251
|
+
# :: HOMO-LUMO gap 2.966157362876 eV ::
|
252
|
+
# ::.................................................::
|
253
|
+
# :: SCC energy -121.121278922798 Eh ::
|
254
|
+
# :: -> isotropic ES 0.180705208303 Eh ::
|
255
|
+
# :: -> anisotropic ES 0.003924951393 Eh ::
|
256
|
+
# :: -> anisotropic XC 0.040710819025 Eh ::
|
257
|
+
# :: -> dispersion -0.088336282215 Eh ::
|
258
|
+
# :: -> Gsolv -0.039236762590 Eh ::
|
259
|
+
# :: -> Gelec -0.026665485874 Eh ::
|
260
|
+
# :: -> Gsasa -0.012571276716 Eh ::
|
261
|
+
# :: -> Ghb 0.000000000000 Eh ::
|
262
|
+
# :: -> Gshift 0.000000000000 Eh ::
|
263
|
+
# :: repulsion energy 1.614147283037 Eh ::
|
264
|
+
# :: add. restraining 0.000000000000 Eh ::
|
265
|
+
# :: total charge -0.000000000000 e ::
|
266
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
267
|
+
|
268
|
+
# example gas.out
|
269
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
270
|
+
# :: SUMMARY ::
|
271
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
272
|
+
# :: total energy -119.473726280382 Eh ::
|
273
|
+
# :: gradient norm 0.085445002241 Eh/a0 ::
|
274
|
+
# :: HOMO-LUMO gap 2.562893747102 eV ::
|
275
|
+
# ::.................................................::
|
276
|
+
# :: SCC energy -121.087873563419 Eh ::
|
277
|
+
# :: -> isotropic ES 0.152557320965 Eh ::
|
278
|
+
# :: -> anisotropic ES 0.007343156635 Eh ::
|
279
|
+
# :: -> anisotropic XC 0.039625076440 Eh ::
|
280
|
+
# :: -> dispersion -0.088605122696 Eh ::
|
281
|
+
# :: repulsion energy 1.614147283037 Eh ::
|
282
|
+
# :: add. restraining 0.000000000000 Eh ::
|
283
|
+
# :: total charge -0.000000000000 e ::
|
284
|
+
# :::::::::::::::::::::::::::::::::::::::::::::::::::::
|
285
|
+
|
286
|
+
if proc.returncode == 0:
|
287
|
+
total_energy_solv = None
|
288
|
+
total_energy_gas = None
|
289
|
+
|
290
|
+
with open(solv_out_path, 'r') as f:
|
291
|
+
for line in f:
|
292
|
+
if 'total energy' in line:
|
293
|
+
m = re.search(r"total energy\s+(?P<solv>[-+]?\d*\.?\d+)\s+Eh", line)
|
294
|
+
total_energy_solv = float(m.group('solv'))
|
295
|
+
with open(gas_out_path, 'r') as f:
|
296
|
+
for line in f:
|
297
|
+
if 'total energy' in line:
|
298
|
+
m = re.search(r"total energy\s+(?P<gas>[-+]?\d*.?\d+)\s+Eh", line)
|
299
|
+
total_energy_gas = float(m.group('gas'))
|
300
|
+
|
301
|
+
if total_energy_solv and total_energy_gas:
|
302
|
+
return (total_energy_solv - total_energy_gas) * hartree2kcalpermol
|
303
|
+
|
304
|
+
return None
|
305
|
+
|
306
|
+
|
128
307
|
def singlepoint(self, water: str | None = None, verbose: bool = False) -> SimpleNamespace:
|
129
308
|
"""Calculate single point energy.
|
130
309
|
|
@@ -142,25 +321,33 @@ class GFN2xTB:
|
|
142
321
|
with tempfile.TemporaryDirectory() as temp_dir: # tmpdir is a string
|
143
322
|
workdir = Path(temp_dir)
|
144
323
|
if verbose:
|
145
|
-
|
324
|
+
logger.info(f'xtb.singlepoint workdir= {temp_dir}')
|
146
325
|
|
147
|
-
|
326
|
+
geometry_input_path = workdir / 'geometry.xyz'
|
148
327
|
xtbout_path = workdir / 'xtbout.json'
|
328
|
+
stdout_path = workdir / 'fort.6'
|
149
329
|
wbo_path = workdir / 'wbo'
|
330
|
+
geometry_output_path = workdir / 'xtbtopo.mol'
|
150
331
|
|
151
|
-
with open(
|
332
|
+
with open(geometry_input_path, 'w') as geometry:
|
152
333
|
geometry.write(self.to_xyz())
|
153
334
|
|
154
|
-
cmd = ['xtb',
|
335
|
+
cmd = ['xtb', geometry_input_path.as_posix()]
|
155
336
|
|
156
337
|
options = ['--gfn', '2', '--json']
|
157
338
|
|
339
|
+
Gsolv = None
|
340
|
+
|
158
341
|
if water is not None and isinstance(water, str):
|
159
342
|
if water == 'gbsa':
|
160
343
|
options += ['--gbsa', 'H2O']
|
344
|
+
# it does not provide Gsolv contribution to the total energy
|
161
345
|
elif water == 'alpb':
|
162
346
|
options += ['--alpb', 'water']
|
163
|
-
|
347
|
+
# it does not provide Gsolv contribution to the total energy
|
348
|
+
elif water == 'cpcmx' and self.is_cpcmx_ready():
|
349
|
+
options += ['--cpcmx', 'water']
|
350
|
+
|
164
351
|
# 'xtbout.json', 'xtbrestart', 'xtbtopo.mol', 'charges', and 'wbo' files will be
|
165
352
|
# created in the current working directory.
|
166
353
|
proc = subprocess.run(cmd + options, cwd=temp_dir, capture_output=True, text=True)
|
@@ -172,16 +359,31 @@ class GFN2xTB:
|
|
172
359
|
# print("Error:")
|
173
360
|
# print(proc.stderr)
|
174
361
|
|
175
|
-
if proc.returncode == 0
|
176
|
-
|
177
|
-
|
178
|
-
|
362
|
+
if proc.returncode == 0:
|
363
|
+
if xtbout_path.is_file():
|
364
|
+
with open(xtbout_path, 'r') as f:
|
365
|
+
datadict = json.load(f) # takes the file object as input
|
366
|
+
|
367
|
+
if (water is not None) and (Gsolv is None) and stdout_path.is_file():
|
368
|
+
# Free Energy contributions: [Eh] [kcal/mol]
|
369
|
+
# -------------------------------------------------------------------------
|
370
|
+
# solvation free energy (dG_solv): -0.92587E-03 -0.58099
|
371
|
+
# gas phase energy (E) -0.52068E+01
|
372
|
+
# -------------------------------------------------------------------------
|
373
|
+
# total free energy (dG) -0.52077E+01
|
374
|
+
with open(stdout_path, 'r') as f:
|
375
|
+
for line in f:
|
376
|
+
if 'solvation free energy' in line:
|
377
|
+
m = re.search(r"solvation free energy \(dG_solv\)\:\s+[-+]?\d*\.?\d+E[-+]?\d*\s+(?P<kcalpermol>[-+]?\d*\.?\d+)", line)
|
378
|
+
Gsolv = float(m.group('kcalpermol'))
|
379
|
+
|
179
380
|
Wiberg_bond_orders = self.load_wbo(wbo_path)
|
180
381
|
|
181
382
|
return SimpleNamespace(
|
182
|
-
PE = datadict['total energy'] * hartree2kcalpermol,
|
383
|
+
PE = datadict['total energy'] * hartree2kcalpermol,
|
384
|
+
Gsolv = Gsolv,
|
183
385
|
charges = datadict['partial charges'],
|
184
|
-
wbo = Wiberg_bond_orders,
|
386
|
+
wbo = Wiberg_bond_orders,
|
185
387
|
)
|
186
388
|
|
187
389
|
# something went wrong if it reaches here
|
@@ -210,17 +412,17 @@ class GFN2xTB:
|
|
210
412
|
with tempfile.TemporaryDirectory() as temp_dir: # tmpdir is a string
|
211
413
|
workdir = Path(temp_dir)
|
212
414
|
if verbose:
|
213
|
-
|
415
|
+
logger.info(f'xtb.optimize workdir= {temp_dir}')
|
214
416
|
|
215
|
-
|
417
|
+
geometry_input_path = workdir / 'geometry.xyz'
|
216
418
|
xtbout_path = workdir / 'xtbout.json'
|
217
|
-
|
419
|
+
geometry_output_path = workdir / 'xtbopt.xyz'
|
218
420
|
wbo_path = workdir / 'wbo'
|
219
421
|
|
220
|
-
with open(
|
422
|
+
with open(geometry_input_path, 'w') as geometry:
|
221
423
|
geometry.write(self.to_xyz())
|
222
424
|
|
223
|
-
cmd = ['xtb',
|
425
|
+
cmd = ['xtb', geometry_input_path.as_posix()]
|
224
426
|
|
225
427
|
options = ['--opt', '--gfn', '2', '--json']
|
226
428
|
|
@@ -229,6 +431,8 @@ class GFN2xTB:
|
|
229
431
|
options += ['--gbsa', 'H2O']
|
230
432
|
elif water == 'alpb':
|
231
433
|
options += ['--alpb', 'water']
|
434
|
+
elif water == 'cpcmx':
|
435
|
+
logger.warning('optimize with --cpcmx option is not implemented in xtb yet')
|
232
436
|
|
233
437
|
proc = subprocess.run(cmd + options, cwd=temp_dir, capture_output=True, text=True)
|
234
438
|
|
@@ -237,7 +441,7 @@ class GFN2xTB:
|
|
237
441
|
datadict = json.load(f) # takes the file object as input
|
238
442
|
|
239
443
|
Wiberg_bond_orders = self.load_wbo(wbo_path)
|
240
|
-
rdmol_opt = self.load_xyz(
|
444
|
+
rdmol_opt = self.load_xyz(geometry_output_path)
|
241
445
|
|
242
446
|
return SimpleNamespace(
|
243
447
|
PE = datadict['total energy'] * hartree2kcalpermol,
|
@@ -276,15 +480,15 @@ class GFN2xTB:
|
|
276
480
|
with tempfile.TemporaryDirectory() as temp_dir: # tmpdir is a string
|
277
481
|
workdir = Path(temp_dir)
|
278
482
|
if verbose:
|
279
|
-
|
483
|
+
logger.info(f'xtb.optimize workdir= {temp_dir}')
|
280
484
|
|
281
|
-
|
485
|
+
geometry_input_path = workdir / 'geometry.xyz'
|
282
486
|
xtb_esp_dat = workdir / 'xtb_esp_dat'
|
283
487
|
|
284
|
-
with open(
|
488
|
+
with open(geometry_input_path, 'w') as geometry:
|
285
489
|
geometry.write(self.to_xyz())
|
286
490
|
|
287
|
-
cmd = ['xtb',
|
491
|
+
cmd = ['xtb', geometry_input_path.as_posix()]
|
288
492
|
|
289
493
|
options = ['--esp', '--gfn', '2']
|
290
494
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
rdworks/__init__.py,sha256=
|
2
|
-
rdworks/conf.py,sha256=
|
1
|
+
rdworks/__init__.py,sha256=SK_EU8Z7TY12w-fszqAQN03x6MydoGabg98zBOetlLI,1368
|
2
|
+
rdworks/conf.py,sha256=iQLb3Qg3pjGiiMVMJ5-d57BC1id3zxEhEGlhhrLrA_c,34162
|
3
3
|
rdworks/descriptor.py,sha256=34T_dQ6g8v3u-ym8TLKbQtxIIV5TEo-d3pdedq3o-cg,2106
|
4
4
|
rdworks/display.py,sha256=JR0gR26UpH-JCxVOaqXZCUj2MiGZSrx9Me87FncspVI,13469
|
5
5
|
rdworks/ionized.py,sha256=5oIjMRpkX792RIpEEE2Ir96icfFaN_h21mSihhfQPAw,6713
|
@@ -65,9 +65,9 @@ rdworks/predefined/misc/reactive-part-2.xml,sha256=0vNTMwWrrQmxBpbgbyRHx8sVs83cq
|
|
65
65
|
rdworks/predefined/misc/reactive-part-3.xml,sha256=LgWHSEbRTVmgBoIO45xbTo1xQJs0Xu51j3JnIapRYo4,3094
|
66
66
|
rdworks/predefined/misc/reactive.xml,sha256=syedoQ6VYUfRLnxy99ObuDniJ_a_WhrWAJbTKFfJ6VY,11248
|
67
67
|
rdworks/xtb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
|
-
rdworks/xtb/wrapper.py,sha256=
|
69
|
-
rdworks-0.
|
70
|
-
rdworks-0.
|
71
|
-
rdworks-0.
|
72
|
-
rdworks-0.
|
73
|
-
rdworks-0.
|
68
|
+
rdworks/xtb/wrapper.py,sha256=GqcseDk_sgmKbmKvDvObjNTk0tvAWYd7ZxjnLq0uVK0,21596
|
69
|
+
rdworks-0.45.2.dist-info/licenses/LICENSE,sha256=UOkJSBqYyQUvtCp7a-vdCANeEcLE2dnTie_eB1By5SY,1074
|
70
|
+
rdworks-0.45.2.dist-info/METADATA,sha256=DfyxepI-h3XBWrwQzzCLVQWBXs-mc5snQ4LIKbGzW4w,1967
|
71
|
+
rdworks-0.45.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
72
|
+
rdworks-0.45.2.dist-info/top_level.txt,sha256=05C98HbvBK2axUBogC_hAT_CdpOeQYGnQ6vRAgawr8s,8
|
73
|
+
rdworks-0.45.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|