stjames 0.0.45__tar.gz → 0.0.46__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.

Files changed (65) hide show
  1. {stjames-0.0.45/stjames.egg-info → stjames-0.0.46}/PKG-INFO +1 -1
  2. {stjames-0.0.45 → stjames-0.0.46}/pyproject.toml +1 -1
  3. {stjames-0.0.45 → stjames-0.0.46}/stjames/constraint.py +6 -2
  4. {stjames-0.0.45 → stjames-0.0.46}/stjames/diis_settings.py +1 -1
  5. {stjames-0.0.45 → stjames-0.0.46}/stjames/scf_settings.py +1 -1
  6. stjames-0.0.46/stjames/workflows/__init__.py +55 -0
  7. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/bde.py +1 -2
  8. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/conformer_search.py +29 -22
  9. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/descriptors.py +1 -1
  10. stjames-0.0.46/stjames/workflows/electronic_properties.py +96 -0
  11. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/fukui.py +1 -1
  12. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/molecular_dynamics.py +3 -3
  13. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/multistage_opt.py +7 -12
  14. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/redox_potential.py +1 -1
  15. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/scan.py +1 -1
  16. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/spin_states.py +1 -1
  17. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/tautomer.py +1 -1
  18. {stjames-0.0.45 → stjames-0.0.46/stjames.egg-info}/PKG-INFO +1 -1
  19. stjames-0.0.45/stjames/workflows/__init__.py +0 -14
  20. stjames-0.0.45/stjames/workflows/electronic_properties.py +0 -86
  21. {stjames-0.0.45 → stjames-0.0.46}/LICENSE +0 -0
  22. {stjames-0.0.45 → stjames-0.0.46}/README.md +0 -0
  23. {stjames-0.0.45 → stjames-0.0.46}/setup.cfg +0 -0
  24. {stjames-0.0.45 → stjames-0.0.46}/stjames/__init__.py +0 -0
  25. {stjames-0.0.45 → stjames-0.0.46}/stjames/_deprecated_solvent_settings.py +0 -0
  26. {stjames-0.0.45 → stjames-0.0.46}/stjames/atom.py +0 -0
  27. {stjames-0.0.45 → stjames-0.0.46}/stjames/base.py +0 -0
  28. {stjames-0.0.45 → stjames-0.0.46}/stjames/basis_set.py +0 -0
  29. {stjames-0.0.45 → stjames-0.0.46}/stjames/calculation.py +0 -0
  30. {stjames-0.0.45 → stjames-0.0.46}/stjames/correction.py +0 -0
  31. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/__init__.py +0 -0
  32. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/bragg_radii.json +0 -0
  33. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/elements.py +0 -0
  34. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/isotopes.json +0 -0
  35. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/nist_isotopes.json +0 -0
  36. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/read_nist_isotopes.py +0 -0
  37. {stjames-0.0.45 → stjames-0.0.46}/stjames/data/symbol_element.json +0 -0
  38. {stjames-0.0.45 → stjames-0.0.46}/stjames/grid_settings.py +0 -0
  39. {stjames-0.0.45 → stjames-0.0.46}/stjames/int_settings.py +0 -0
  40. {stjames-0.0.45 → stjames-0.0.46}/stjames/message.py +0 -0
  41. {stjames-0.0.45 → stjames-0.0.46}/stjames/method.py +0 -0
  42. {stjames-0.0.45 → stjames-0.0.46}/stjames/mode.py +0 -0
  43. {stjames-0.0.45 → stjames-0.0.46}/stjames/molecule.py +0 -0
  44. {stjames-0.0.45 → stjames-0.0.46}/stjames/opt_settings.py +0 -0
  45. {stjames-0.0.45 → stjames-0.0.46}/stjames/periodic_cell.py +0 -0
  46. {stjames-0.0.45 → stjames-0.0.46}/stjames/py.typed +0 -0
  47. {stjames-0.0.45 → stjames-0.0.46}/stjames/settings.py +0 -0
  48. {stjames-0.0.45 → stjames-0.0.46}/stjames/solvent.py +0 -0
  49. {stjames-0.0.45 → stjames-0.0.46}/stjames/status.py +0 -0
  50. {stjames-0.0.45 → stjames-0.0.46}/stjames/task.py +0 -0
  51. {stjames-0.0.45 → stjames-0.0.46}/stjames/thermochem_settings.py +0 -0
  52. {stjames-0.0.45 → stjames-0.0.46}/stjames/types.py +0 -0
  53. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/admet.py +0 -0
  54. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/basic_calculation.py +0 -0
  55. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/conformer.py +0 -0
  56. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/pka.py +0 -0
  57. {stjames-0.0.45 → stjames-0.0.46}/stjames/workflows/workflow.py +0 -0
  58. {stjames-0.0.45 → stjames-0.0.46}/stjames.egg-info/SOURCES.txt +0 -0
  59. {stjames-0.0.45 → stjames-0.0.46}/stjames.egg-info/dependency_links.txt +0 -0
  60. {stjames-0.0.45 → stjames-0.0.46}/stjames.egg-info/requires.txt +0 -0
  61. {stjames-0.0.45 → stjames-0.0.46}/stjames.egg-info/top_level.txt +0 -0
  62. {stjames-0.0.45 → stjames-0.0.46}/tests/test_constraints.py +0 -0
  63. {stjames-0.0.45 → stjames-0.0.46}/tests/test_from_extxyz.py +0 -0
  64. {stjames-0.0.45 → stjames-0.0.46}/tests/test_molecule.py +0 -0
  65. {stjames-0.0.45 → stjames-0.0.46}/tests/test_settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stjames
3
- Version: 0.0.45
3
+ Version: 0.0.46
4
4
  Summary: standardized JSON atom/molecule encoding scheme
5
5
  Author-email: Corin Wagen <corin@rowansci.com>
6
6
  Project-URL: Homepage, https://github.com/rowansci/stjames
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stjames"
3
- version = "0.0.45"
3
+ version = "0.0.46"
4
4
  description = "standardized JSON atom/molecule encoding scheme"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -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: whch atoms to apply to
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
  """
@@ -4,7 +4,7 @@ from .base import Base, LowercaseStrEnum
4
4
 
5
5
 
6
6
  class DIISStrategy(LowercaseStrEnum):
7
- # regular pulay DIIS
7
+ # regular Pulay DIIS
8
8
  DIIS = "diis"
9
9
 
10
10
  # Hu/Yang JCP 2010 - ADIIS
@@ -20,7 +20,7 @@ class SCFInitMethod(LowercaseStrEnum):
20
20
  class OrthonormalizationMethod(LowercaseStrEnum):
21
21
  SYMMETRIC = "symmetric"
22
22
  CANONICAL = "canonical"
23
- # cholesky, in future?
23
+ # Cholesky, in future?
24
24
 
25
25
 
26
26
  class SCFSettings(Base):
@@ -0,0 +1,55 @@
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 .molecular_dynamics import *
13
+ from .multistage_opt import *
14
+ from .pka import *
15
+ from .redox_potential import *
16
+ from .scan import *
17
+ from .spin_states import *
18
+ from .tautomer import *
19
+ from .workflow import Workflow
20
+
21
+ WORKFLOW_NAME = Literal[
22
+ "admet",
23
+ "basic_calculation",
24
+ "bde",
25
+ "conformers",
26
+ "conformer_search",
27
+ "descriptors",
28
+ "electronic_properties",
29
+ "fukui",
30
+ "molecular_dynamics",
31
+ "multistage_opt",
32
+ "pka",
33
+ "redox_potential",
34
+ "scan",
35
+ "spin_states",
36
+ "tautomers",
37
+ ]
38
+
39
+ WORKFLOW_MAPPING: dict[str, Workflow] = {
40
+ "admet": ADMETWorkflow, # type: ignore [dict-item]
41
+ "basic_calculation": BasicCalculationWorkflow, # type: ignore [dict-item]
42
+ "bde": BDEWorkflow, # type: ignore [dict-item]
43
+ "conformers": ConformerWorkflow, # type: ignore [dict-item]
44
+ "conformer_search": ConformerSearchWorkflow, # type: ignore [dict-item]
45
+ "descriptors": DescriptorsWorkflow, # type: ignore [dict-item]
46
+ "electronic_properties": ElectronicPropertiesWorkflow, # type: ignore [dict-item]
47
+ "fukui": FukuiIndexWorkflow, # type: ignore [dict-item]
48
+ "molecular_dynamics": MolecularDynamicsWorkflow, # type: ignore [dict-item]
49
+ "multistage_opt": MultiStageOptWorkflow, # type: ignore [dict-item]
50
+ "pka": pKaWorkflow, # type: ignore [dict-item]
51
+ "redox_potential": RedoxPotentialWorkflow, # type: ignore [dict-item]
52
+ "scan": ScanWorkflow, # type: ignore [dict-item]
53
+ "spin_states": SpinStatesWorkflow, # type: ignore [dict-item]
54
+ "tautomers": TautomerWorkflow, # type: ignore [dict-item]
55
+ }
@@ -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)
@@ -26,16 +26,16 @@ def check_sentinel(value: _T, default: _U) -> _T | _U:
26
26
 
27
27
  class ScreeningSettings(BaseModel):
28
28
  """
29
- Settings for determing unique and useful conformers.
29
+ Settings for determining unique and useful conformers.
30
30
 
31
- :param energy_threshhold: maximum relative energy for screening
32
- :param rotational_constants_threshhold: maximum difference in rotational constants for screening
33
- :param rmsd: cartesian RMSD for screening
31
+ :param energy_threshold: maximum relative energy for screening
32
+ :param rotational_constants_threshold: maximum difference in rotational constants for screening
33
+ :param rmsd: Cartesian RMSD for screening
34
34
  :param max_confs: maximum number of conformers to keep
35
35
  """
36
36
 
37
- energy_threshhold: float | None = None # kcal/mol
38
- rotational_constants_threshhold: float | None = 0.02
37
+ energy_threshold: float | None = None # kcal/mol
38
+ rotational_constants_threshold: float | None = 0.02
39
39
  rmsd: float | None = 0.25
40
40
  max_confs: int | None = None
41
41
 
@@ -76,10 +76,11 @@ class ETKDGSettings(ConformerGenSettings):
76
76
 
77
77
  Inherited:
78
78
  :param mode: Mode for calculations
79
+ :param conf_opt_method: method for the optimization
79
80
  :param screening: post-generation screening settings
80
81
  :param constraints: constraints for conformer generation
81
82
  :param nci: add a constraining potential for non-covalent interactions (not supported in ETKDG)
82
- :param conf_opt_method: method for the optimization
83
+ :param max_confs: maximum number of conformers to keep
83
84
 
84
85
  New:
85
86
  :param num_initial_confs: number of initial conformers to generate
@@ -87,7 +88,6 @@ class ETKDGSettings(ConformerGenSettings):
87
88
  :param num_confs_taken: number of final conformers to take
88
89
  :param max_mmff_energy: MMFF energy cutoff
89
90
  :param max_mmff_iterations: MMFF optimization iterations
90
- :param max_confs: maximum number of conformers to keep
91
91
  """
92
92
 
93
93
  num_initial_confs: int = 300
@@ -117,10 +117,10 @@ class ETKDGSettings(ConformerGenSettings):
117
117
  case Mode.RECKLESS:
118
118
  self.num_initial_confs = 200
119
119
  self.num_confs_considered = 50
120
- self.max_confs = 20 if self.max_confs is _sentinel else self.max_confs
120
+ self.max_confs = 20 if self.max_confs is None else self.max_confs
121
121
  self.max_mmff_energy = 20
122
122
  case Mode.RAPID:
123
- self.max_confs = 50 if self.max_confs is _sentinel else self.max_confs
123
+ self.max_confs = 50 if self.max_confs is None else self.max_confs
124
124
  self.conf_opt_method = Method.GFN0_XTB
125
125
  case _:
126
126
  raise NotImplementedError(f"Unsupported mode: {self.mode}")
@@ -194,6 +194,7 @@ class iMTDSettings(ConformerGenSettings, ABC):
194
194
  :param screening: post-generation screening settings (not used)
195
195
  :param constraints: constraints to add
196
196
  :param nci: add an ellipsoide potential around the input structure
197
+ :param max_confs: maximum number of conformers to keep
197
198
 
198
199
  New:
199
200
  :param mtd_method: method for the metadynamics
@@ -216,11 +217,11 @@ class iMTDSettings(ConformerGenSettings, ABC):
216
217
  if self.reopt is _sentinel:
217
218
  raise ValueError("Must specify reopt with MANUAL mode")
218
219
  case Mode.RECKLESS: # GFN-FF//MTD(GFN-FF)
219
- self.max_confs = 20 if self.max_confs is _sentinel else self.max_confs
220
+ self.max_confs = 20 if self.max_confs is None else self.max_confs
220
221
  self.speed = iMTDSpeeds.MEGAQUICK
221
222
  self.reopt = check_sentinel(self.reopt, True)
222
223
  case Mode.RAPID: # GFN0//MTD(GFN-FF)
223
- self.max_confs = 50 if self.max_confs is _sentinel else self.max_confs
224
+ self.max_confs = 50 if self.max_confs is None else self.max_confs
224
225
  self.speed = iMTDSpeeds.SUPERQUICK
225
226
  self.conf_opt_method = Method.GFN0_XTB
226
227
  self.reopt = check_sentinel(self.reopt, True)
@@ -258,11 +259,16 @@ class ConformerGenMixin(BaseModel):
258
259
 
259
260
  :param conf_gen_mode: Mode for calculations
260
261
  :param conf_gen_settings: settings for conformer generation
262
+ :param constraints: constraints to add
263
+ :param nci: add a constraining potential for non-covalent interactions
264
+ :param max_confs: maximum number of conformers to keep
261
265
  """
262
266
 
263
267
  conf_gen_mode: Mode = Mode.RAPID
264
268
  conf_gen_settings: ConformerGenSettings = _sentinel # type: ignore [assignment]
265
269
  constraints: Sequence[Constraint] = tuple()
270
+ nci: bool = False
271
+ max_confs: int | None = None
266
272
 
267
273
  @model_validator(mode="after")
268
274
  def validate_and_build_conf_gen_settings(self) -> Self:
@@ -276,10 +282,10 @@ class ConformerGenMixin(BaseModel):
276
282
  raise ValueError("Must specify conf_gen_settings with MANUAL mode")
277
283
 
278
284
  case Mode.RECKLESS | Mode.RAPID:
279
- # ETKDGSettings will error if constraints added
280
- self.conf_gen_settings = ETKDGSettings(mode=self.conf_gen_mode, constraints=self.constraints)
285
+ # ETKDGSettings will error if constraints or nci are set
286
+ self.conf_gen_settings = ETKDGSettings(mode=self.conf_gen_mode, constraints=self.constraints, nci=self.nci, max_confs=self.max_confs)
281
287
  case Mode.CAREFUL | Mode.METICULOUS:
282
- self.conf_gen_settings = iMTDSettings(mode=self.conf_gen_mode, constraints=self.constraints)
288
+ self.conf_gen_settings = iMTDSettings(mode=self.conf_gen_mode, constraints=self.constraints, nci=self.nci, max_confs=self.max_confs)
283
289
 
284
290
  case _:
285
291
  raise NotImplementedError(f"Unsupported mode: {self.conf_gen_mode}")
@@ -291,22 +297,23 @@ class ConformerSearchMixin(ConformerGenMixin, MultiStageOptMixin):
291
297
  """
292
298
  Mixin for workflows that need conformer search—a combination of conformer generation and optimization.
293
299
 
294
- Inherited:
300
+ Inherited (ConformerGenMixin):
295
301
  :param conf_gen_mode: Mode for conformer generation
296
302
  :param mso_mode: Mode for MultiStageOptSettings
297
303
  :param conf_gen_settings: settings for conformer generation
304
+ :param nci: add a constraining potential for non-covalent interactions
305
+
306
+ Inherited (MultiStageOptMixin):
298
307
  :param multistage_opt_settings: set by mso_mode unless mode=MANUAL (ignores additional settings if set)
299
308
  :param solvent: solvent to use
300
309
  :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
310
  :param transition_state: whether this is a transition state
311
+ :param frequencies: whether to calculate frequencies
303
312
 
304
- Overridden:
305
- :param frequencies: whether to calculate frequencies (turned off)
313
+ Inherited (Both):
314
+ :param constraints: constraints to add (diamond inheritance, works as expected)
306
315
  """
307
316
 
308
- frequencies: bool = False
309
-
310
317
  def __str__(self) -> str:
311
318
  """Return a string representation of the ConformerSearch workflow."""
312
319
  return repr(self)
@@ -330,7 +337,7 @@ class ConformerSearchWorkflow(ConformerSearchMixin, Workflow):
330
337
  :param xtb_preopt: pre-optimize with xtb (sets based on mode when None)
331
338
  :param constraints: constraints to add
332
339
  :param transition_state: whether this is a transition state
333
- :param frequencies: whether to calculate frequencies (turned off)
340
+ :param frequencies: whether to calculate frequencies
334
341
 
335
342
  Ignored:
336
343
  :param mode: Mode to use (not used)
@@ -5,7 +5,7 @@ Descriptors = dict[str, dict[str, float] | tuple[float | None, ...] | float]
5
5
 
6
6
 
7
7
  class DescriptorsWorkflow(Workflow):
8
- # uuid of optimization
8
+ # UUID of optimization
9
9
  optimization: UUID | None = None
10
10
 
11
11
  descriptors: Descriptors | None = None
@@ -0,0 +1,96 @@
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
+ """Represents a "cubefile" of some property."""
18
+
19
+ cube_points: list[PropertyCubePoint]
20
+
21
+
22
+ class MolecularOrbitalCube(PropertyCube):
23
+ """
24
+ Cube of a molecular orbital.
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: settings for the calculation
42
+ :param compute_density_cube: whether to compute the density cube
43
+ :param compute_electrostatic_potential_cube: whether to compute the electrostatic potential cube
44
+ :param compute_num_occupied_orbitals: number of occupied orbitals to save
45
+ :param compute_num_virtual_orbitals: number of virtual orbitals to save
46
+
47
+ Populated while running:
48
+ :param calc_uuid: UUID of the calculation
49
+ :param dipole: dipole moment
50
+ :param quadrupole: quadrupole moment
51
+ :param lowdin_charges: Löwdin charges
52
+ :param mulliken_charges: Mulliken charges
53
+ :param wiberg_bond_orders: Wiberg bond orders (`atom1`, `atom2`, `order`)
54
+ :param mayer_bond_orders: Mayer bond orders (`atom1`, `atom2`, `order`)
55
+
56
+ :param density_cube: electron density, as a cube
57
+ :param density_cube_alpha: α electron density, as a cube
58
+ :param density_cube_beta: β electron density, as a cube
59
+ :param density_cube_difference: difference spin densities, as a cube
60
+
61
+ :param electrostatic_potential_cube: electrostatic potential, as a cube
62
+
63
+ :param molecular_orbitals: MOs, key is absolute orbital index (for closed-shell species (RHF))
64
+ :param molecular_orbitals_alpha: α MOs, key is absolute orbital index (for open-shell species (UHF/ROHF))
65
+ :param molecular_orbitals_beta: β MOs, key is absolute orbital index (for open-shell species (UHF/ROHF))
66
+ """
67
+
68
+ # Config settings
69
+ settings: Settings
70
+ compute_density_cube: bool = True
71
+ compute_electrostatic_potential_cube: bool = True
72
+ compute_num_occupied_orbitals: NonNegativeInt = 1
73
+ compute_num_virtual_orbitals: NonNegativeInt = 1
74
+
75
+ # Results
76
+ calc_uuid: UUID | None = None
77
+
78
+ dipole: Vector3D | None = None
79
+ quadrupole: Matrix3x3 | None = None
80
+
81
+ mulliken_charges: FloatPerAtom | None = None
82
+ lowdin_charges: FloatPerAtom | None = None
83
+
84
+ wiberg_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
85
+ mayer_bond_orders: list[tuple[NonNegativeInt, NonNegativeInt, NonNegativeFloat]] = []
86
+
87
+ density_cube: PropertyCube | None = None
88
+ density_cube_alpha: PropertyCube | None = None
89
+ density_cube_beta: PropertyCube | None = None
90
+ density_cube_difference: PropertyCube | None = None
91
+
92
+ electrostatic_potential_cube: PropertyCube | None = None
93
+
94
+ molecular_orbitals: dict[NonNegativeInt, MolecularOrbitalCube] = {}
95
+ molecular_orbitals_alpha: dict[NonNegativeInt, MolecularOrbitalCube] = {}
96
+ molecular_orbitals_beta: dict[NonNegativeInt, MolecularOrbitalCube] = {}
@@ -3,7 +3,7 @@ from .workflow import Workflow
3
3
 
4
4
 
5
5
  class FukuiIndexWorkflow(Workflow):
6
- # uuid of optimization
6
+ # UUID of optimization
7
7
  optimization: UUID | None = None
8
8
 
9
9
  global_electrophilicity_index: float | None = None
@@ -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):
@@ -37,6 +38,7 @@ class MolecularDynamicsSettings(Base):
37
38
 
38
39
  timestep: PositiveFloat = 1.0 # fs
39
40
  num_steps: PositiveInt = 500
41
+ save_interval: PositiveInt = 10
40
42
 
41
43
  confining_constraint: SphericalHarmonicConstraint | None = None
42
44
 
@@ -63,7 +65,5 @@ class MolecularDynamicsWorkflow(Workflow):
63
65
  calc_settings: Settings
64
66
  calc_engine: str | None = None
65
67
 
66
- save_interval: PositiveInt = 10
67
-
68
- # uuids of scan points
68
+ # UUIDs of scan points
69
69
  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 | None = None
54
+ xtb_preopt: bool = False
55
55
  constraints: Sequence[Constraint] = tuple()
56
56
  transition_state: bool = False
57
- frequencies: bool = True
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 | None = None
230
+ xtb_preopt: bool = False
236
231
  constraints: Sequence[Constraint] = tuple()
237
232
  transition_state: bool = False
238
- frequencies: bool = True
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 = True,
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: list of opt settings to apply successively
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: the final multistage opt settings
290
+ :returns: MultiStageOptSettings
296
291
  """
297
292
  if constraints is None:
298
293
  constraints = []
@@ -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
- # uuids
56
+ # UUIDs
57
57
  neutral_molecule: UUID | None = None
58
58
  anion_molecule: UUID | None = None
59
59
  cation_molecule: UUID | None = None
@@ -34,5 +34,5 @@ class ScanWorkflow(Workflow):
34
34
  calc_settings: Settings
35
35
  calc_engine: str
36
36
 
37
- # uuids of scan points
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 (sets based on mode when None)
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
@@ -10,7 +10,7 @@ class Tautomer(Base):
10
10
  weight: Optional[float] = None
11
11
  predicted_relative_energy: Optional[float] = None
12
12
 
13
- # uuids, optionally
13
+ # UUIDs, optionally
14
14
  structures: list[DBCalculation] = []
15
15
 
16
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stjames
3
- Version: 0.0.45
3
+ Version: 0.0.46
4
4
  Summary: standardized JSON atom/molecule encoding scheme
5
5
  Author-email: Corin Wagen <corin@rowansci.com>
6
6
  Project-URL: Homepage, https://github.com/rowansci/stjames
@@ -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