stjames 0.0.45__tar.gz → 0.0.47__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.
Potentially problematic release.
This version of stjames might be problematic. Click here for more details.
- {stjames-0.0.45/stjames.egg-info → stjames-0.0.47}/PKG-INFO +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/pyproject.toml +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames/base.py +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames/constraint.py +6 -2
- {stjames-0.0.45 → stjames-0.0.47}/stjames/diis_settings.py +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames/method.py +7 -2
- {stjames-0.0.45 → stjames-0.0.47}/stjames/scf_settings.py +1 -1
- stjames-0.0.47/stjames/workflows/__init__.py +58 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/bde.py +1 -2
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/conformer_search.py +69 -22
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/descriptors.py +1 -1
- stjames-0.0.47/stjames/workflows/electronic_properties.py +109 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/fukui.py +1 -1
- stjames-0.0.47/stjames/workflows/hydrogen_bond_basicity.py +18 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/molecular_dynamics.py +11 -5
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/multistage_opt.py +33 -12
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/redox_potential.py +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/scan.py +2 -2
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/spin_states.py +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/tautomer.py +1 -1
- {stjames-0.0.45 → stjames-0.0.47/stjames.egg-info}/PKG-INFO +1 -1
- {stjames-0.0.45 → stjames-0.0.47}/stjames.egg-info/SOURCES.txt +1 -0
- stjames-0.0.45/stjames/workflows/__init__.py +0 -14
- stjames-0.0.45/stjames/workflows/electronic_properties.py +0 -86
- {stjames-0.0.45 → stjames-0.0.47}/LICENSE +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/README.md +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/setup.cfg +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/__init__.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/_deprecated_solvent_settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/atom.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/basis_set.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/calculation.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/correction.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/__init__.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/bragg_radii.json +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/elements.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/isotopes.json +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/nist_isotopes.json +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/read_nist_isotopes.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/data/symbol_element.json +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/grid_settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/int_settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/message.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/mode.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/molecule.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/opt_settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/periodic_cell.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/py.typed +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/solvent.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/status.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/task.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/thermochem_settings.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/types.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/admet.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/basic_calculation.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/conformer.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/pka.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames/workflows/workflow.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames.egg-info/dependency_links.txt +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames.egg-info/requires.txt +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/stjames.egg-info/top_level.txt +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/tests/test_constraints.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/tests/test_from_extxyz.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/tests/test_molecule.py +0 -0
- {stjames-0.0.45 → stjames-0.0.47}/tests/test_settings.py +0 -0
|
@@ -12,7 +12,7 @@ class Base(pydantic.BaseModel):
|
|
|
12
12
|
@classmethod
|
|
13
13
|
def coerce_numpy(cls, val: _T) -> _T | list[Any]:
|
|
14
14
|
if isinstance(val, np.ndarray):
|
|
15
|
-
return val.tolist() # type: ignore [no-any-return, unused-ignore]
|
|
15
|
+
return val.tolist() # type: ignore [no-any-return, unused-ignore, return-value]
|
|
16
16
|
|
|
17
17
|
return val
|
|
18
18
|
|
|
@@ -11,6 +11,7 @@ class ConstraintType(LowercaseStrEnum):
|
|
|
11
11
|
BOND = "bond"
|
|
12
12
|
ANGLE = "angle"
|
|
13
13
|
DIHEDRAL = "dihedral"
|
|
14
|
+
FREEZE_ATOMS = "freeze_atoms"
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class Constraint(Base):
|
|
@@ -18,7 +19,7 @@ class Constraint(Base):
|
|
|
18
19
|
Represents a single (absolute) constraint.
|
|
19
20
|
|
|
20
21
|
:param constraint_type: which type
|
|
21
|
-
:param atoms: the atoms in question
|
|
22
|
+
:param atoms: the atoms in question. n.b. - these are 1-indexed!
|
|
22
23
|
:param value: the value to constrain this to, leaving this blank sets the current value
|
|
23
24
|
"""
|
|
24
25
|
|
|
@@ -38,6 +39,9 @@ class Constraint(Base):
|
|
|
38
39
|
case ConstraintType.DIHEDRAL:
|
|
39
40
|
if len(self.atoms) != 4:
|
|
40
41
|
raise ValueError("Dihedral constraint needs four atom indices!")
|
|
42
|
+
case ConstraintType.FREEZE_ATOMS:
|
|
43
|
+
if len(self.atoms) == 0:
|
|
44
|
+
raise ValueError("Can't freeze atoms without any atoms to freeze!")
|
|
41
45
|
case _:
|
|
42
46
|
raise ValueError("Unknown constraint_type!")
|
|
43
47
|
|
|
@@ -48,7 +52,7 @@ class PairwiseHarmonicConstraint(Base):
|
|
|
48
52
|
"""
|
|
49
53
|
Represents a harmonic constraint, with a characteristic spring constant.
|
|
50
54
|
|
|
51
|
-
:param atoms:
|
|
55
|
+
:param atoms: which atoms to apply to
|
|
52
56
|
:param force_constant: the strength of the attraction, in kcal/mol/Å
|
|
53
57
|
:param equilibrium: the distance at which force is zero
|
|
54
58
|
"""
|
|
@@ -43,6 +43,8 @@ class Method(LowercaseStrEnum):
|
|
|
43
43
|
# this was going to be removed, but Jonathon wrote such a nice basis set test... it's off the front end.
|
|
44
44
|
BP86 = "bp86"
|
|
45
45
|
|
|
46
|
+
OFF_SAGE_2_2_1 = "off_sage_2_2_1"
|
|
47
|
+
|
|
46
48
|
|
|
47
49
|
NNPMethod = Literal[Method.AIMNET2_WB97MD3]
|
|
48
50
|
NNP_METHODS = [Method.AIMNET2_WB97MD3]
|
|
@@ -53,8 +55,11 @@ XTB_METHODS = [Method.GFN_FF, Method.GFN0_XTB, Method.GFN1_XTB, Method.GFN2_XTB]
|
|
|
53
55
|
CompositeMethod = Literal[Method.HF3C, Method.B973C, Method.R2SCAN3C, Method.WB97X3C]
|
|
54
56
|
COMPOSITE_METHODS = [Method.HF3C, Method.B973C, Method.R2SCAN3C, Method.WB97X3C]
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
FFMethod = Literal[Method.OFF_SAGE_2_2_1]
|
|
59
|
+
FF_METHODS = [Method.OFF_SAGE_2_2_1]
|
|
60
|
+
|
|
61
|
+
PrepackagedMethod = XTBMethod | CompositeMethod | NNPMethod | FFMethod
|
|
62
|
+
PREPACKAGED_METHODS = [*XTB_METHODS, *COMPOSITE_METHODS, *NNP_METHODS, *FF_METHODS]
|
|
58
63
|
|
|
59
64
|
MethodWithCorrection = Literal[Method.WB97XD3, Method.WB97XV, Method.WB97MV, Method.WB97MD3BJ, Method.DSDBLYPD3BJ]
|
|
60
65
|
METHODS_WITH_CORRECTION = [Method.WB97XD3, Method.WB97XV, Method.WB97MV, Method.WB97MD3BJ, Method.DSDBLYPD3BJ, Method.B97D3BJ]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ruff: noqa: F405
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from .admet import *
|
|
5
|
+
from .basic_calculation import *
|
|
6
|
+
from .bde import *
|
|
7
|
+
from .conformer import *
|
|
8
|
+
from .conformer_search import *
|
|
9
|
+
from .descriptors import *
|
|
10
|
+
from .electronic_properties import *
|
|
11
|
+
from .fukui import *
|
|
12
|
+
from .hydrogen_bond_basicity import *
|
|
13
|
+
from .molecular_dynamics import *
|
|
14
|
+
from .multistage_opt import *
|
|
15
|
+
from .pka import *
|
|
16
|
+
from .redox_potential import *
|
|
17
|
+
from .scan import *
|
|
18
|
+
from .spin_states import *
|
|
19
|
+
from .tautomer import *
|
|
20
|
+
from .workflow import Workflow
|
|
21
|
+
|
|
22
|
+
WORKFLOW_NAME = Literal[
|
|
23
|
+
"admet",
|
|
24
|
+
"basic_calculation",
|
|
25
|
+
"bde",
|
|
26
|
+
"conformers",
|
|
27
|
+
"conformer_search",
|
|
28
|
+
"descriptors",
|
|
29
|
+
"electronic_properties",
|
|
30
|
+
"fukui",
|
|
31
|
+
"hydrogen_bond_basicity",
|
|
32
|
+
"molecular_dynamics",
|
|
33
|
+
"multistage_opt",
|
|
34
|
+
"pka",
|
|
35
|
+
"redox_potential",
|
|
36
|
+
"scan",
|
|
37
|
+
"spin_states",
|
|
38
|
+
"tautomers",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
WORKFLOW_MAPPING: dict[str, Workflow] = {
|
|
42
|
+
"admet": ADMETWorkflow, # type: ignore [dict-item]
|
|
43
|
+
"basic_calculation": BasicCalculationWorkflow, # type: ignore [dict-item]
|
|
44
|
+
"bde": BDEWorkflow, # type: ignore [dict-item]
|
|
45
|
+
"conformers": ConformerWorkflow, # type: ignore [dict-item]
|
|
46
|
+
"conformer_search": ConformerSearchWorkflow, # type: ignore [dict-item]
|
|
47
|
+
"descriptors": DescriptorsWorkflow, # type: ignore [dict-item]
|
|
48
|
+
"electronic_properties": ElectronicPropertiesWorkflow, # type: ignore [dict-item]
|
|
49
|
+
"fukui": FukuiIndexWorkflow, # type: ignore [dict-item]
|
|
50
|
+
"hydrogen_bond_basicity": HydrogenBondBasicityWorkflow, # type: ignore [dict-item]
|
|
51
|
+
"molecular_dynamics": MolecularDynamicsWorkflow, # type: ignore [dict-item]
|
|
52
|
+
"multistage_opt": MultiStageOptWorkflow, # type: ignore [dict-item]
|
|
53
|
+
"pka": pKaWorkflow, # type: ignore [dict-item]
|
|
54
|
+
"redox_potential": RedoxPotentialWorkflow, # type: ignore [dict-item]
|
|
55
|
+
"scan": ScanWorkflow, # type: ignore [dict-item]
|
|
56
|
+
"spin_states": SpinStatesWorkflow, # type: ignore [dict-item]
|
|
57
|
+
"tautomers": TautomerWorkflow, # type: ignore [dict-item]
|
|
58
|
+
}
|
|
@@ -60,10 +60,10 @@ class BDEWorkflow(Workflow, MultiStageOptMixin):
|
|
|
60
60
|
:param multistage_opt_settings: set by mode unless mode=MANUAL (ignores additional settings if set)
|
|
61
61
|
:param solvent: solvent to use for singlepoint
|
|
62
62
|
:param xtb_preopt: pre-optimize with xtb (sets based on mode when None)
|
|
63
|
+
:param frequencies: whether to calculate frequencies
|
|
63
64
|
|
|
64
65
|
Overridden:
|
|
65
66
|
:param mso_mode: Mode for MultiStageOptSettings
|
|
66
|
-
:param frequencies: whether to calculate frequencies
|
|
67
67
|
|
|
68
68
|
Turned off:
|
|
69
69
|
:param constraints: constraints to add (not supported)
|
|
@@ -81,7 +81,6 @@ class BDEWorkflow(Workflow, MultiStageOptMixin):
|
|
|
81
81
|
"""
|
|
82
82
|
|
|
83
83
|
mso_mode: Mode = _sentinel_mso_mode # type: ignore [assignment]
|
|
84
|
-
frequencies: bool = False
|
|
85
84
|
optimize_fragments: bool = None # type: ignore [assignment]
|
|
86
85
|
|
|
87
86
|
atoms: tuple[PositiveInt, ...] = Field(default_factory=tuple)
|
|
@@ -9,6 +9,7 @@ from ..base import LowercaseStrEnum
|
|
|
9
9
|
from ..constraint import Constraint
|
|
10
10
|
from ..method import Method, XTBMethod
|
|
11
11
|
from ..mode import Mode
|
|
12
|
+
from ..task import Task
|
|
12
13
|
from ..types import UUID
|
|
13
14
|
from .multistage_opt import MultiStageOptMixin
|
|
14
15
|
from .workflow import Workflow
|
|
@@ -26,16 +27,16 @@ def check_sentinel(value: _T, default: _U) -> _T | _U:
|
|
|
26
27
|
|
|
27
28
|
class ScreeningSettings(BaseModel):
|
|
28
29
|
"""
|
|
29
|
-
Settings for
|
|
30
|
+
Settings for determining unique and useful conformers.
|
|
30
31
|
|
|
31
|
-
:param
|
|
32
|
-
:param
|
|
33
|
-
:param rmsd:
|
|
32
|
+
:param energy_threshold: maximum relative energy for screening
|
|
33
|
+
:param rotational_constants_threshold: maximum difference in rotational constants for screening
|
|
34
|
+
:param rmsd: Cartesian RMSD for screening
|
|
34
35
|
:param max_confs: maximum number of conformers to keep
|
|
35
36
|
"""
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
energy_threshold: float | None = None # kcal/mol
|
|
39
|
+
rotational_constants_threshold: float | None = 0.02
|
|
39
40
|
rmsd: float | None = 0.25
|
|
40
41
|
max_confs: int | None = None
|
|
41
42
|
|
|
@@ -76,10 +77,11 @@ class ETKDGSettings(ConformerGenSettings):
|
|
|
76
77
|
|
|
77
78
|
Inherited:
|
|
78
79
|
:param mode: Mode for calculations
|
|
80
|
+
:param conf_opt_method: method for the optimization
|
|
79
81
|
:param screening: post-generation screening settings
|
|
80
82
|
:param constraints: constraints for conformer generation
|
|
81
83
|
:param nci: add a constraining potential for non-covalent interactions (not supported in ETKDG)
|
|
82
|
-
:param
|
|
84
|
+
:param max_confs: maximum number of conformers to keep
|
|
83
85
|
|
|
84
86
|
New:
|
|
85
87
|
:param num_initial_confs: number of initial conformers to generate
|
|
@@ -87,7 +89,6 @@ class ETKDGSettings(ConformerGenSettings):
|
|
|
87
89
|
:param num_confs_taken: number of final conformers to take
|
|
88
90
|
:param max_mmff_energy: MMFF energy cutoff
|
|
89
91
|
:param max_mmff_iterations: MMFF optimization iterations
|
|
90
|
-
:param max_confs: maximum number of conformers to keep
|
|
91
92
|
"""
|
|
92
93
|
|
|
93
94
|
num_initial_confs: int = 300
|
|
@@ -117,10 +118,10 @@ class ETKDGSettings(ConformerGenSettings):
|
|
|
117
118
|
case Mode.RECKLESS:
|
|
118
119
|
self.num_initial_confs = 200
|
|
119
120
|
self.num_confs_considered = 50
|
|
120
|
-
self.max_confs = 20 if self.max_confs is
|
|
121
|
+
self.max_confs = 20 if self.max_confs is None else self.max_confs
|
|
121
122
|
self.max_mmff_energy = 20
|
|
122
123
|
case Mode.RAPID:
|
|
123
|
-
self.max_confs = 50 if self.max_confs is
|
|
124
|
+
self.max_confs = 50 if self.max_confs is None else self.max_confs
|
|
124
125
|
self.conf_opt_method = Method.GFN0_XTB
|
|
125
126
|
case _:
|
|
126
127
|
raise NotImplementedError(f"Unsupported mode: {self.mode}")
|
|
@@ -194,6 +195,7 @@ class iMTDSettings(ConformerGenSettings, ABC):
|
|
|
194
195
|
:param screening: post-generation screening settings (not used)
|
|
195
196
|
:param constraints: constraints to add
|
|
196
197
|
:param nci: add an ellipsoide potential around the input structure
|
|
198
|
+
:param max_confs: maximum number of conformers to keep
|
|
197
199
|
|
|
198
200
|
New:
|
|
199
201
|
:param mtd_method: method for the metadynamics
|
|
@@ -216,11 +218,11 @@ class iMTDSettings(ConformerGenSettings, ABC):
|
|
|
216
218
|
if self.reopt is _sentinel:
|
|
217
219
|
raise ValueError("Must specify reopt with MANUAL mode")
|
|
218
220
|
case Mode.RECKLESS: # GFN-FF//MTD(GFN-FF)
|
|
219
|
-
self.max_confs = 20 if self.max_confs is
|
|
221
|
+
self.max_confs = 20 if self.max_confs is None else self.max_confs
|
|
220
222
|
self.speed = iMTDSpeeds.MEGAQUICK
|
|
221
223
|
self.reopt = check_sentinel(self.reopt, True)
|
|
222
224
|
case Mode.RAPID: # GFN0//MTD(GFN-FF)
|
|
223
|
-
self.max_confs = 50 if self.max_confs is
|
|
225
|
+
self.max_confs = 50 if self.max_confs is None else self.max_confs
|
|
224
226
|
self.speed = iMTDSpeeds.SUPERQUICK
|
|
225
227
|
self.conf_opt_method = Method.GFN0_XTB
|
|
226
228
|
self.reopt = check_sentinel(self.reopt, True)
|
|
@@ -258,11 +260,16 @@ class ConformerGenMixin(BaseModel):
|
|
|
258
260
|
|
|
259
261
|
:param conf_gen_mode: Mode for calculations
|
|
260
262
|
:param conf_gen_settings: settings for conformer generation
|
|
263
|
+
:param constraints: constraints to add
|
|
264
|
+
:param nci: add a constraining potential for non-covalent interactions
|
|
265
|
+
:param max_confs: maximum number of conformers to keep
|
|
261
266
|
"""
|
|
262
267
|
|
|
263
268
|
conf_gen_mode: Mode = Mode.RAPID
|
|
264
269
|
conf_gen_settings: ConformerGenSettings = _sentinel # type: ignore [assignment]
|
|
265
270
|
constraints: Sequence[Constraint] = tuple()
|
|
271
|
+
nci: bool = False
|
|
272
|
+
max_confs: int | None = None
|
|
266
273
|
|
|
267
274
|
@model_validator(mode="after")
|
|
268
275
|
def validate_and_build_conf_gen_settings(self) -> Self:
|
|
@@ -276,10 +283,10 @@ class ConformerGenMixin(BaseModel):
|
|
|
276
283
|
raise ValueError("Must specify conf_gen_settings with MANUAL mode")
|
|
277
284
|
|
|
278
285
|
case Mode.RECKLESS | Mode.RAPID:
|
|
279
|
-
# ETKDGSettings will error if constraints
|
|
280
|
-
self.conf_gen_settings = ETKDGSettings(mode=self.conf_gen_mode, constraints=self.constraints)
|
|
286
|
+
# ETKDGSettings will error if constraints or nci are set
|
|
287
|
+
self.conf_gen_settings = ETKDGSettings(mode=self.conf_gen_mode, constraints=self.constraints, nci=self.nci, max_confs=self.max_confs)
|
|
281
288
|
case Mode.CAREFUL | Mode.METICULOUS:
|
|
282
|
-
self.conf_gen_settings = iMTDSettings(mode=self.conf_gen_mode, constraints=self.constraints)
|
|
289
|
+
self.conf_gen_settings = iMTDSettings(mode=self.conf_gen_mode, constraints=self.constraints, nci=self.nci, max_confs=self.max_confs)
|
|
283
290
|
|
|
284
291
|
case _:
|
|
285
292
|
raise NotImplementedError(f"Unsupported mode: {self.conf_gen_mode}")
|
|
@@ -291,22 +298,23 @@ class ConformerSearchMixin(ConformerGenMixin, MultiStageOptMixin):
|
|
|
291
298
|
"""
|
|
292
299
|
Mixin for workflows that need conformer search—a combination of conformer generation and optimization.
|
|
293
300
|
|
|
294
|
-
Inherited:
|
|
301
|
+
Inherited (ConformerGenMixin):
|
|
295
302
|
:param conf_gen_mode: Mode for conformer generation
|
|
296
303
|
:param mso_mode: Mode for MultiStageOptSettings
|
|
297
304
|
:param conf_gen_settings: settings for conformer generation
|
|
305
|
+
:param nci: add a constraining potential for non-covalent interactions
|
|
306
|
+
|
|
307
|
+
Inherited (MultiStageOptMixin):
|
|
298
308
|
:param multistage_opt_settings: set by mso_mode unless mode=MANUAL (ignores additional settings if set)
|
|
299
309
|
:param solvent: solvent to use
|
|
300
310
|
:param xtb_preopt: pre-optimize with xtb (sets based on mode when None)
|
|
301
|
-
:param constraints: constraints to add (diamond inheritance, works as expected)
|
|
302
311
|
:param transition_state: whether this is a transition state
|
|
312
|
+
:param frequencies: whether to calculate frequencies
|
|
303
313
|
|
|
304
|
-
|
|
305
|
-
:param
|
|
314
|
+
Inherited (Both):
|
|
315
|
+
:param constraints: constraints to add (diamond inheritance, works as expected)
|
|
306
316
|
"""
|
|
307
317
|
|
|
308
|
-
frequencies: bool = False
|
|
309
|
-
|
|
310
318
|
def __str__(self) -> str:
|
|
311
319
|
"""Return a string representation of the ConformerSearch workflow."""
|
|
312
320
|
return repr(self)
|
|
@@ -315,6 +323,45 @@ class ConformerSearchMixin(ConformerGenMixin, MultiStageOptMixin):
|
|
|
315
323
|
"""Return a string representation of the ConformerSearch workflow."""
|
|
316
324
|
return f"<{type(self).__name__} {self.conf_gen_mode.name} {self.mso_mode.name}>"
|
|
317
325
|
|
|
326
|
+
@model_validator(mode="after")
|
|
327
|
+
def deduplicate(self) -> Self:
|
|
328
|
+
"""
|
|
329
|
+
Deduplicate optimizations between conf_gen and multistage_opt.
|
|
330
|
+
|
|
331
|
+
Also affects Manual Mode.
|
|
332
|
+
"""
|
|
333
|
+
cgs = self.conf_gen_settings
|
|
334
|
+
msos = self.multistage_opt_settings
|
|
335
|
+
|
|
336
|
+
if self.transition_state or not msos.optimization_settings:
|
|
337
|
+
return self
|
|
338
|
+
|
|
339
|
+
first_opt = msos.optimization_settings[0]
|
|
340
|
+
if cgs.conf_opt_method != first_opt.method or "optimize" not in first_opt.tasks:
|
|
341
|
+
return self
|
|
342
|
+
|
|
343
|
+
first_opt.tasks.remove(Task.OPTIMIZE)
|
|
344
|
+
if msos.singlepoint_settings or len(msos.optimization_settings) > 1:
|
|
345
|
+
if (not first_opt.tasks) or first_opt.tasks == ["singlepoint"]:
|
|
346
|
+
msos.optimization_settings = msos.optimization_settings[1:]
|
|
347
|
+
|
|
348
|
+
return self
|
|
349
|
+
|
|
350
|
+
@model_validator(mode="after")
|
|
351
|
+
def remove_ts_constraints(self) -> Self:
|
|
352
|
+
"""
|
|
353
|
+
Remove constraints from optimization if a TS.
|
|
354
|
+
|
|
355
|
+
Also affects Manual Mode.
|
|
356
|
+
"""
|
|
357
|
+
msos = self.multistage_opt_settings
|
|
358
|
+
if msos.transition_state and msos.constraints:
|
|
359
|
+
msos.constraints = []
|
|
360
|
+
for opt_set in msos.optimization_settings:
|
|
361
|
+
opt_set.opt_settings.constraints = []
|
|
362
|
+
|
|
363
|
+
return self
|
|
364
|
+
|
|
318
365
|
|
|
319
366
|
class ConformerSearchWorkflow(ConformerSearchMixin, Workflow):
|
|
320
367
|
"""
|
|
@@ -330,7 +377,7 @@ class ConformerSearchWorkflow(ConformerSearchMixin, Workflow):
|
|
|
330
377
|
:param xtb_preopt: pre-optimize with xtb (sets based on mode when None)
|
|
331
378
|
:param constraints: constraints to add
|
|
332
379
|
:param transition_state: whether this is a transition state
|
|
333
|
-
:param frequencies: whether to calculate frequencies
|
|
380
|
+
:param frequencies: whether to calculate frequencies
|
|
334
381
|
|
|
335
382
|
Ignored:
|
|
336
383
|
:param mode: Mode to use (not used)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from typing import Annotated, Callable
|
|
2
|
+
|
|
3
|
+
from pydantic import AfterValidator, NonNegativeFloat, NonNegativeInt
|
|
4
|
+
|
|
5
|
+
from ..base import Base
|
|
6
|
+
from ..settings import Settings
|
|
7
|
+
from ..types import UUID, FloatPerAtom, Matrix3x3, Vector3D
|
|
8
|
+
from .workflow import Workflow
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def round_float(round_to: int) -> Callable[[float], float]:
|
|
12
|
+
"""Return a function that rounds a float to a given number of decimal places."""
|
|
13
|
+
|
|
14
|
+
def inner_round(v: float) -> float:
|
|
15
|
+
return round(v, round_to)
|
|
16
|
+
|
|
17
|
+
return inner_round
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class PropertyCubePoint(Base):
|
|
21
|
+
"""A point in a cube file, all values rounded to 6 decimal places."""
|
|
22
|
+
|
|
23
|
+
x: Annotated[float, AfterValidator(round_float(3))]
|
|
24
|
+
y: Annotated[float, AfterValidator(round_float(3))]
|
|
25
|
+
z: Annotated[float, AfterValidator(round_float(3))]
|
|
26
|
+
val: Annotated[float, AfterValidator(round_float(6))]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PropertyCube(Base):
|
|
30
|
+
"""Represents a "cubefile" of some property."""
|
|
31
|
+
|
|
32
|
+
cube_points: list[PropertyCubePoint]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MolecularOrbitalCube(PropertyCube):
|
|
36
|
+
"""
|
|
37
|
+
Cube of a molecular orbital.
|
|
38
|
+
|
|
39
|
+
Inherits `cube_data`.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
occupation: NonNegativeInt
|
|
43
|
+
energy: float
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ElectronicPropertiesWorkflow(Workflow):
|
|
47
|
+
"""
|
|
48
|
+
Workflow for computing electronic properties.
|
|
49
|
+
|
|
50
|
+
Inherited
|
|
51
|
+
:param initial_molecule: Molecule of interest
|
|
52
|
+
|
|
53
|
+
Config settings:
|
|
54
|
+
:param settings: settings for the calculation
|
|
55
|
+
:param compute_density_cube: whether to compute the density cube
|
|
56
|
+
:param compute_electrostatic_potential_cube: whether to compute the electrostatic potential cube
|
|
57
|
+
:param compute_num_occupied_orbitals: number of occupied orbitals to save
|
|
58
|
+
:param compute_num_virtual_orbitals: number of virtual orbitals to save
|
|
59
|
+
|
|
60
|
+
Populated while running:
|
|
61
|
+
:param calc_uuid: UUID of the calculation
|
|
62
|
+
:param dipole: dipole moment
|
|
63
|
+
:param quadrupole: quadrupole moment
|
|
64
|
+
:param lowdin_charges: Löwdin charges
|
|
65
|
+
:param mulliken_charges: Mulliken charges
|
|
66
|
+
:param wiberg_bond_orders: Wiberg bond orders (`atom1`, `atom2`, `order`)
|
|
67
|
+
:param mayer_bond_orders: Mayer bond orders (`atom1`, `atom2`, `order`)
|
|
68
|
+
|
|
69
|
+
:param density_cube: electron density, as a cube
|
|
70
|
+
:param density_cube_alpha: α electron density, as a cube
|
|
71
|
+
:param density_cube_beta: β electron density, as a cube
|
|
72
|
+
:param density_cube_difference: difference spin densities, as a cube
|
|
73
|
+
|
|
74
|
+
:param electrostatic_potential_cube: electrostatic potential, as a cube
|
|
75
|
+
|
|
76
|
+
:param molecular_orbitals: MOs, key is absolute orbital index (for closed-shell species (RHF))
|
|
77
|
+
:param molecular_orbitals_alpha: α MOs, key is absolute orbital index (for open-shell species (UHF/ROHF))
|
|
78
|
+
:param molecular_orbitals_beta: β MOs, key is absolute orbital index (for open-shell species (UHF/ROHF))
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# Config settings
|
|
82
|
+
settings: Settings
|
|
83
|
+
compute_density_cube: bool = True
|
|
84
|
+
compute_electrostatic_potential_cube: bool = True
|
|
85
|
+
compute_num_occupied_orbitals: NonNegativeInt = 1
|
|
86
|
+
compute_num_virtual_orbitals: NonNegativeInt = 1
|
|
87
|
+
|
|
88
|
+
# Results
|
|
89
|
+
calc_uuid: UUID | None = None
|
|
90
|
+
|
|
91
|
+
dipole: Vector3D | None = None
|
|
92
|
+
quadrupole: Matrix3x3 | None = None
|
|
93
|
+
|
|
94
|
+
mulliken_charges: FloatPerAtom | None = None
|
|
95
|
+
lowdin_charges: FloatPerAtom | None = None
|
|
96
|
+
|
|
97
|
+
wiberg_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
|
|
98
|
+
mayer_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
|
|
99
|
+
|
|
100
|
+
density_cube: PropertyCube | None = None
|
|
101
|
+
density_cube_alpha: PropertyCube | None = None
|
|
102
|
+
density_cube_beta: PropertyCube | None = None
|
|
103
|
+
density_cube_difference: PropertyCube | None = None
|
|
104
|
+
|
|
105
|
+
electrostatic_potential_cube: PropertyCube | None = None
|
|
106
|
+
|
|
107
|
+
molecular_orbitals: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
108
|
+
molecular_orbitals_alpha: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
109
|
+
molecular_orbitals_beta: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from ..base import Base
|
|
2
|
+
from ..types import UUID
|
|
3
|
+
from .workflow import Workflow
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class HydrogenBondAcceptorSite(Base):
|
|
7
|
+
atom_idx: int # zero-indexed
|
|
8
|
+
pkbhx: float
|
|
9
|
+
position: tuple[float, float, float]
|
|
10
|
+
name: str | None = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class HydrogenBondBasicityWorkflow(Workflow):
|
|
14
|
+
# UUID of optimization
|
|
15
|
+
optimization: UUID | None = None
|
|
16
|
+
|
|
17
|
+
# hydrogen-bond-acceptor sites
|
|
18
|
+
hba_sites: list[HydrogenBondAcceptorSite] = [] # noqa: RUF012
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Self
|
|
2
2
|
|
|
3
|
-
from pydantic import PositiveFloat, PositiveInt, model_validator
|
|
3
|
+
from pydantic import PositiveFloat, PositiveInt, computed_field, model_validator
|
|
4
4
|
|
|
5
5
|
from ..base import Base, LowercaseStrEnum
|
|
6
6
|
from ..constraint import PairwiseHarmonicConstraint, SphericalHarmonicConstraint
|
|
@@ -12,6 +12,7 @@ from .workflow import Workflow
|
|
|
12
12
|
class MolecularDynamicsInitialization(LowercaseStrEnum):
|
|
13
13
|
RANDOM = "random"
|
|
14
14
|
QUASICLASSICAL = "quasiclassical"
|
|
15
|
+
READ = "read"
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class ThermodynamicEnsemble(LowercaseStrEnum):
|
|
@@ -28,7 +29,13 @@ class Frame(Base):
|
|
|
28
29
|
pressure: float
|
|
29
30
|
temperature: float
|
|
30
31
|
volume: float
|
|
31
|
-
|
|
32
|
+
potential_energy: float # kcal/mol
|
|
33
|
+
kinetic_energy: float # kcal/mol
|
|
34
|
+
|
|
35
|
+
@computed_field # type: ignore[misc, prop-decorator, unused-ignore]
|
|
36
|
+
@property
|
|
37
|
+
def energy(self) -> float:
|
|
38
|
+
return self.potential_energy + self.kinetic_energy
|
|
32
39
|
|
|
33
40
|
|
|
34
41
|
class MolecularDynamicsSettings(Base):
|
|
@@ -37,6 +44,7 @@ class MolecularDynamicsSettings(Base):
|
|
|
37
44
|
|
|
38
45
|
timestep: PositiveFloat = 1.0 # fs
|
|
39
46
|
num_steps: PositiveInt = 500
|
|
47
|
+
save_interval: PositiveInt = 10
|
|
40
48
|
|
|
41
49
|
confining_constraint: SphericalHarmonicConstraint | None = None
|
|
42
50
|
|
|
@@ -63,7 +71,5 @@ class MolecularDynamicsWorkflow(Workflow):
|
|
|
63
71
|
calc_settings: Settings
|
|
64
72
|
calc_engine: str | None = None
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# uuids of scan points
|
|
74
|
+
# UUIDs of scan points
|
|
69
75
|
frames: list[Frame] = []
|
|
@@ -51,10 +51,10 @@ class MultiStageOptSettings(BaseModel):
|
|
|
51
51
|
optimization_settings: Sequence[Settings] = tuple()
|
|
52
52
|
singlepoint_settings: Settings | None = None
|
|
53
53
|
solvent: Solvent | None = None
|
|
54
|
-
xtb_preopt: bool
|
|
54
|
+
xtb_preopt: bool = False
|
|
55
55
|
constraints: Sequence[Constraint] = tuple()
|
|
56
56
|
transition_state: bool = False
|
|
57
|
-
frequencies: bool =
|
|
57
|
+
frequencies: bool = False
|
|
58
58
|
|
|
59
59
|
def __str__(self) -> str:
|
|
60
60
|
return repr(self)
|
|
@@ -152,7 +152,6 @@ class MultiStageOptSettings(BaseModel):
|
|
|
152
152
|
self.singlepoint_settings = sp(Method.GFN2_XTB, solvent=self.solvent)
|
|
153
153
|
|
|
154
154
|
case Mode.RAPID:
|
|
155
|
-
self.xtb_preopt = bool(self.xtb_preopt)
|
|
156
155
|
self.optimization_settings = [
|
|
157
156
|
*gfn0_pre_opt * self.xtb_preopt,
|
|
158
157
|
opt(Method.GFN2_XTB, freq=self.frequencies),
|
|
@@ -160,7 +159,6 @@ class MultiStageOptSettings(BaseModel):
|
|
|
160
159
|
self.singlepoint_settings = sp(Method.R2SCAN3C, solvent=self.solvent)
|
|
161
160
|
|
|
162
161
|
case Mode.CAREFUL:
|
|
163
|
-
self.xtb_preopt = (self.xtb_preopt is None) or self.xtb_preopt
|
|
164
162
|
self.optimization_settings = [
|
|
165
163
|
*gfn2_pre_opt * self.xtb_preopt,
|
|
166
164
|
opt(Method.R2SCAN3C, freq=self.frequencies),
|
|
@@ -168,7 +166,6 @@ class MultiStageOptSettings(BaseModel):
|
|
|
168
166
|
self.singlepoint_settings = sp(Method.WB97X3C, solvent=self.solvent)
|
|
169
167
|
|
|
170
168
|
case Mode.METICULOUS:
|
|
171
|
-
self.xtb_preopt = (self.xtb_preopt is None) or self.xtb_preopt
|
|
172
169
|
self.optimization_settings = [
|
|
173
170
|
*gfn2_pre_opt * self.xtb_preopt,
|
|
174
171
|
opt(Method.R2SCAN3C),
|
|
@@ -179,8 +176,6 @@ class MultiStageOptSettings(BaseModel):
|
|
|
179
176
|
case mode:
|
|
180
177
|
raise NotImplementedError(f"Cannot assign settings for {mode=}")
|
|
181
178
|
|
|
182
|
-
assert self.xtb_preopt is not None
|
|
183
|
-
|
|
184
179
|
|
|
185
180
|
class MultiStageOptWorkflow(Workflow, MultiStageOptSettings):
|
|
186
181
|
"""
|
|
@@ -232,10 +227,10 @@ class MultiStageOptMixin(BaseModel):
|
|
|
232
227
|
# Need to use a sentinel object to make both mypy and pydantic happy
|
|
233
228
|
multistage_opt_settings: MultiStageOptSettings = _sentinel_msos # type: ignore [assignment]
|
|
234
229
|
solvent: Solvent | None = None
|
|
235
|
-
xtb_preopt: bool
|
|
230
|
+
xtb_preopt: bool = False
|
|
236
231
|
constraints: Sequence[Constraint] = tuple()
|
|
237
232
|
transition_state: bool = False
|
|
238
|
-
frequencies: bool =
|
|
233
|
+
frequencies: bool = False
|
|
239
234
|
|
|
240
235
|
@model_validator(mode="after")
|
|
241
236
|
def set_mso_settings(self) -> Self:
|
|
@@ -277,14 +272,14 @@ def build_mso_settings(
|
|
|
277
272
|
use_solvent_for_opt: bool = False,
|
|
278
273
|
constraints: list[Constraint] | None = None,
|
|
279
274
|
transition_state: bool = False,
|
|
280
|
-
frequencies: bool =
|
|
275
|
+
frequencies: bool = False,
|
|
281
276
|
) -> MultiStageOptSettings:
|
|
282
277
|
"""
|
|
283
278
|
Helper function to construct multi-stage opt settings objects manually.
|
|
284
279
|
|
|
285
280
|
There's no xTB pre-optimization here - add that yourself!
|
|
286
281
|
|
|
287
|
-
:param optimization_settings:
|
|
282
|
+
:param optimization_settings: optimization settings to apply successively
|
|
288
283
|
:param singlepoint_settings: final single point settings
|
|
289
284
|
:param mode: Mode for settings, defaults to `MANUAL`
|
|
290
285
|
:param solvent: solvent to use
|
|
@@ -292,7 +287,7 @@ def build_mso_settings(
|
|
|
292
287
|
:param constraints: constraints for optimization
|
|
293
288
|
:param transition_state: whether this is a transition state
|
|
294
289
|
:param frequencies: whether to calculate frequencies
|
|
295
|
-
:returns:
|
|
290
|
+
:returns: MultiStageOptSettings
|
|
296
291
|
"""
|
|
297
292
|
if constraints is None:
|
|
298
293
|
constraints = []
|
|
@@ -336,3 +331,29 @@ def build_mso_settings(
|
|
|
336
331
|
transition_state=transition_state,
|
|
337
332
|
frequencies=frequencies,
|
|
338
333
|
)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def multi_stage_opt_settings_from_workflow(msow: MultiStageOptWorkflow) -> MultiStageOptSettings:
|
|
337
|
+
"""
|
|
338
|
+
Helper function to convert a MultiStageOptWorkflow to MultiStageOptSettings.
|
|
339
|
+
|
|
340
|
+
:param msow: MultiStageOptWorkflow
|
|
341
|
+
:returns: MultiStageOptSettings
|
|
342
|
+
|
|
343
|
+
>>> from stjames.molecule import Atom, Molecule
|
|
344
|
+
>>> He = Molecule(charge=0, multiplicity=1, atoms=[Atom(atomic_number=2, position=[0, 0, 0])])
|
|
345
|
+
>>> msos = multi_stage_opt_settings_from_workflow(
|
|
346
|
+
... MultiStageOptWorkflow(initial_molecule=He, mode=Mode.RAPID, solvent="water")
|
|
347
|
+
... )
|
|
348
|
+
>>> print(msos)
|
|
349
|
+
<MultiStageOptSettings RAPID>
|
|
350
|
+
>>> msos.level_of_theory
|
|
351
|
+
'r2scan_3c/cpcm(water)//gfn2_xtb'
|
|
352
|
+
>>> msos.solvent
|
|
353
|
+
<Solvent.WATER: 'water'>
|
|
354
|
+
>>> msos.xtb_preopt
|
|
355
|
+
False
|
|
356
|
+
"""
|
|
357
|
+
data = dict(msow)
|
|
358
|
+
del data["calculations"]
|
|
359
|
+
return MultiStageOptSettings.construct(**data)
|
|
@@ -53,7 +53,7 @@ class RedoxPotentialWorkflow(Workflow, MultiStageOptMixin):
|
|
|
53
53
|
redox_type: str | None = None
|
|
54
54
|
redox_potential: float | None = None
|
|
55
55
|
|
|
56
|
-
#
|
|
56
|
+
# UUIDs
|
|
57
57
|
neutral_molecule: UUID | None = None
|
|
58
58
|
anion_molecule: UUID | None = None
|
|
59
59
|
cation_molecule: UUID | None = None
|
|
@@ -23,7 +23,7 @@ class ScanSettings(Base):
|
|
|
23
23
|
num: int
|
|
24
24
|
|
|
25
25
|
def vals(self) -> NDArray[np.float64]:
|
|
26
|
-
return np.linspace(self.start, self.stop, self.num)
|
|
26
|
+
return np.linspace(self.start, self.stop, self.num) # type: ignore [return-value, unused-ignore]
|
|
27
27
|
|
|
28
28
|
class Config:
|
|
29
29
|
from_attributes = True
|
|
@@ -34,5 +34,5 @@ class ScanWorkflow(Workflow):
|
|
|
34
34
|
calc_settings: Settings
|
|
35
35
|
calc_engine: str
|
|
36
36
|
|
|
37
|
-
#
|
|
37
|
+
# UUIDs of scan points
|
|
38
38
|
scan_points: list[UUID | None] = []
|
|
@@ -52,7 +52,7 @@ class SpinStatesWorkflow(Workflow, MultiStageOptMixin):
|
|
|
52
52
|
:param mode: Mode for workflow
|
|
53
53
|
:param multistage_opt_settings: set by mode unless mode=MANUAL (ignores additional settings if set)
|
|
54
54
|
:param solvent: solvent to use for optimization
|
|
55
|
-
:param xtb_preopt: pre-optimize with xtb
|
|
55
|
+
:param xtb_preopt: pre-optimize with xtb
|
|
56
56
|
:param constraints: constraints to add
|
|
57
57
|
:param transition_state: whether this is a transition state
|
|
58
58
|
:param frequencies: whether to calculate frequencies
|
|
@@ -47,6 +47,7 @@ stjames/workflows/conformer_search.py
|
|
|
47
47
|
stjames/workflows/descriptors.py
|
|
48
48
|
stjames/workflows/electronic_properties.py
|
|
49
49
|
stjames/workflows/fukui.py
|
|
50
|
+
stjames/workflows/hydrogen_bond_basicity.py
|
|
50
51
|
stjames/workflows/molecular_dynamics.py
|
|
51
52
|
stjames/workflows/multistage_opt.py
|
|
52
53
|
stjames/workflows/pka.py
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from .admet import *
|
|
2
|
-
from .basic_calculation import *
|
|
3
|
-
from .bde import *
|
|
4
|
-
from .conformer import *
|
|
5
|
-
from .conformer_search import *
|
|
6
|
-
from .descriptors import *
|
|
7
|
-
from .fukui import *
|
|
8
|
-
from .molecular_dynamics import *
|
|
9
|
-
from .multistage_opt import *
|
|
10
|
-
from .pka import *
|
|
11
|
-
from .redox_potential import *
|
|
12
|
-
from .scan import *
|
|
13
|
-
from .spin_states import *
|
|
14
|
-
from .tautomer import *
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
from pydantic import NonNegativeFloat, NonNegativeInt
|
|
2
|
-
|
|
3
|
-
from ..base import Base
|
|
4
|
-
from ..settings import Settings
|
|
5
|
-
from ..types import UUID, FloatPerAtom, Matrix3x3, Vector3D
|
|
6
|
-
from .workflow import Workflow
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class PropertyCubePoint(Base):
|
|
10
|
-
x: float
|
|
11
|
-
y: float
|
|
12
|
-
z: float
|
|
13
|
-
val: float
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class PropertyCube(Base):
|
|
17
|
-
"""
|
|
18
|
-
Represents a "cubefile" of some property.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
cube_data: list[PropertyCubePoint]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class MolecularOrbitalCube(PropertyCube):
|
|
25
|
-
"""
|
|
26
|
-
Inherits `cube_data`.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
occupation: NonNegativeInt
|
|
30
|
-
energy: float
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class ElectronicPropertiesWorkflow(Workflow):
|
|
34
|
-
"""
|
|
35
|
-
Workflow for computing electronic properties!
|
|
36
|
-
|
|
37
|
-
Inherited
|
|
38
|
-
:param initial_molecule: molecule of interest
|
|
39
|
-
|
|
40
|
-
Config settings:
|
|
41
|
-
:param settings: the level of theory to use
|
|
42
|
-
:param compute_density_cube: whether or not to compute the density on a cube
|
|
43
|
-
:param compute_electrostatic_potential_cube: whether or not to compute the electrostatic potential on a cube
|
|
44
|
-
:param compute_num_occupied_orbitals: how many occupied orbitals to save
|
|
45
|
-
:param compute_num_virtual_orbitals: how many virtual orbitals to save
|
|
46
|
-
|
|
47
|
-
Populated while running:
|
|
48
|
-
:param calculation: the UUID of the calculation
|
|
49
|
-
:param dipole: the dipole moment
|
|
50
|
-
:param quadrupole: the quadrupole moment
|
|
51
|
-
:param mulliken_charges: the Mulliken charges
|
|
52
|
-
:param lowdin_charges: the Lowdin charges
|
|
53
|
-
:param wiberg_bond_orders: the Wiberg bond orders (`atom1`, `atom2`, `order`)
|
|
54
|
-
:param mayer_bond_orders: the Mayer bond orders (`atom1`, `atom2`, `order`)
|
|
55
|
-
:param density_cube: the electron density, as a cube
|
|
56
|
-
:param electrostatic_potential_cube: the electrostatic potential, as a cube
|
|
57
|
-
:param molecular_orbitals_alpha: for open-shell species (UHF/ROHF), a dict containing the alpha MOs
|
|
58
|
-
(The key is the absolute orbital index.)
|
|
59
|
-
:param molecular_orbitals_beta: for open-shell species (UHF/ROHF), a dict containing the beta MOs
|
|
60
|
-
(The key is the absolute orbital index.)
|
|
61
|
-
:param molecular_orbitals: for closed-shell species (RHF), a dict containing the MOs
|
|
62
|
-
(The key is the absolute orbital index.)
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
settings: Settings
|
|
66
|
-
compute_density_cube: bool = True
|
|
67
|
-
compute_electrostatic_potential_cube: bool = True
|
|
68
|
-
compute_num_occupied_orbitals: NonNegativeInt = 1
|
|
69
|
-
compute_num_virtual_orbitals: NonNegativeInt = 1
|
|
70
|
-
|
|
71
|
-
calculation: UUID | None = None
|
|
72
|
-
|
|
73
|
-
dipole: Vector3D | None = None
|
|
74
|
-
quadrupole: Matrix3x3 | None = None
|
|
75
|
-
|
|
76
|
-
mulliken_charges: FloatPerAtom | None = None
|
|
77
|
-
lowdin_charges: FloatPerAtom | None = None
|
|
78
|
-
|
|
79
|
-
wiberg_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
|
|
80
|
-
mayer_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
|
|
81
|
-
|
|
82
|
-
density_cube: PropertyCube | None = None
|
|
83
|
-
electrostatic_potential_cube: PropertyCube | None = None
|
|
84
|
-
molecular_orbitals_alpha: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
85
|
-
molecular_orbitals_beta: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
86
|
-
molecular_orbitals: dict[NonNegativeInt, MolecularOrbitalCube] = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|