stjames 0.0.46__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.

Files changed (64) hide show
  1. {stjames-0.0.46/stjames.egg-info → stjames-0.0.47}/PKG-INFO +1 -1
  2. {stjames-0.0.46 → stjames-0.0.47}/pyproject.toml +1 -1
  3. {stjames-0.0.46 → stjames-0.0.47}/stjames/base.py +1 -1
  4. {stjames-0.0.46 → stjames-0.0.47}/stjames/method.py +7 -2
  5. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/__init__.py +3 -0
  6. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/conformer_search.py +40 -0
  7. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/electronic_properties.py +18 -5
  8. stjames-0.0.47/stjames/workflows/hydrogen_bond_basicity.py +18 -0
  9. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/molecular_dynamics.py +8 -2
  10. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/multistage_opt.py +26 -0
  11. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/scan.py +1 -1
  12. {stjames-0.0.46 → stjames-0.0.47/stjames.egg-info}/PKG-INFO +1 -1
  13. {stjames-0.0.46 → stjames-0.0.47}/stjames.egg-info/SOURCES.txt +1 -0
  14. {stjames-0.0.46 → stjames-0.0.47}/LICENSE +0 -0
  15. {stjames-0.0.46 → stjames-0.0.47}/README.md +0 -0
  16. {stjames-0.0.46 → stjames-0.0.47}/setup.cfg +0 -0
  17. {stjames-0.0.46 → stjames-0.0.47}/stjames/__init__.py +0 -0
  18. {stjames-0.0.46 → stjames-0.0.47}/stjames/_deprecated_solvent_settings.py +0 -0
  19. {stjames-0.0.46 → stjames-0.0.47}/stjames/atom.py +0 -0
  20. {stjames-0.0.46 → stjames-0.0.47}/stjames/basis_set.py +0 -0
  21. {stjames-0.0.46 → stjames-0.0.47}/stjames/calculation.py +0 -0
  22. {stjames-0.0.46 → stjames-0.0.47}/stjames/constraint.py +0 -0
  23. {stjames-0.0.46 → stjames-0.0.47}/stjames/correction.py +0 -0
  24. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/__init__.py +0 -0
  25. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/bragg_radii.json +0 -0
  26. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/elements.py +0 -0
  27. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/isotopes.json +0 -0
  28. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/nist_isotopes.json +0 -0
  29. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/read_nist_isotopes.py +0 -0
  30. {stjames-0.0.46 → stjames-0.0.47}/stjames/data/symbol_element.json +0 -0
  31. {stjames-0.0.46 → stjames-0.0.47}/stjames/diis_settings.py +0 -0
  32. {stjames-0.0.46 → stjames-0.0.47}/stjames/grid_settings.py +0 -0
  33. {stjames-0.0.46 → stjames-0.0.47}/stjames/int_settings.py +0 -0
  34. {stjames-0.0.46 → stjames-0.0.47}/stjames/message.py +0 -0
  35. {stjames-0.0.46 → stjames-0.0.47}/stjames/mode.py +0 -0
  36. {stjames-0.0.46 → stjames-0.0.47}/stjames/molecule.py +0 -0
  37. {stjames-0.0.46 → stjames-0.0.47}/stjames/opt_settings.py +0 -0
  38. {stjames-0.0.46 → stjames-0.0.47}/stjames/periodic_cell.py +0 -0
  39. {stjames-0.0.46 → stjames-0.0.47}/stjames/py.typed +0 -0
  40. {stjames-0.0.46 → stjames-0.0.47}/stjames/scf_settings.py +0 -0
  41. {stjames-0.0.46 → stjames-0.0.47}/stjames/settings.py +0 -0
  42. {stjames-0.0.46 → stjames-0.0.47}/stjames/solvent.py +0 -0
  43. {stjames-0.0.46 → stjames-0.0.47}/stjames/status.py +0 -0
  44. {stjames-0.0.46 → stjames-0.0.47}/stjames/task.py +0 -0
  45. {stjames-0.0.46 → stjames-0.0.47}/stjames/thermochem_settings.py +0 -0
  46. {stjames-0.0.46 → stjames-0.0.47}/stjames/types.py +0 -0
  47. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/admet.py +0 -0
  48. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/basic_calculation.py +0 -0
  49. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/bde.py +0 -0
  50. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/conformer.py +0 -0
  51. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/descriptors.py +0 -0
  52. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/fukui.py +0 -0
  53. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/pka.py +0 -0
  54. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/redox_potential.py +0 -0
  55. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/spin_states.py +0 -0
  56. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/tautomer.py +0 -0
  57. {stjames-0.0.46 → stjames-0.0.47}/stjames/workflows/workflow.py +0 -0
  58. {stjames-0.0.46 → stjames-0.0.47}/stjames.egg-info/dependency_links.txt +0 -0
  59. {stjames-0.0.46 → stjames-0.0.47}/stjames.egg-info/requires.txt +0 -0
  60. {stjames-0.0.46 → stjames-0.0.47}/stjames.egg-info/top_level.txt +0 -0
  61. {stjames-0.0.46 → stjames-0.0.47}/tests/test_constraints.py +0 -0
  62. {stjames-0.0.46 → stjames-0.0.47}/tests/test_from_extxyz.py +0 -0
  63. {stjames-0.0.46 → stjames-0.0.47}/tests/test_molecule.py +0 -0
  64. {stjames-0.0.46 → stjames-0.0.47}/tests/test_settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stjames
3
- Version: 0.0.46
3
+ Version: 0.0.47
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.46"
3
+ version = "0.0.47"
4
4
  description = "standardized JSON atom/molecule encoding scheme"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -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
 
@@ -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
- PrepackagedMethod = XTBMethod | CompositeMethod | NNPMethod
57
- PREPACKAGED_METHODS = [*XTB_METHODS, *COMPOSITE_METHODS]
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]
@@ -9,6 +9,7 @@ from .conformer_search import *
9
9
  from .descriptors import *
10
10
  from .electronic_properties import *
11
11
  from .fukui import *
12
+ from .hydrogen_bond_basicity import *
12
13
  from .molecular_dynamics import *
13
14
  from .multistage_opt import *
14
15
  from .pka import *
@@ -27,6 +28,7 @@ WORKFLOW_NAME = Literal[
27
28
  "descriptors",
28
29
  "electronic_properties",
29
30
  "fukui",
31
+ "hydrogen_bond_basicity",
30
32
  "molecular_dynamics",
31
33
  "multistage_opt",
32
34
  "pka",
@@ -45,6 +47,7 @@ WORKFLOW_MAPPING: dict[str, Workflow] = {
45
47
  "descriptors": DescriptorsWorkflow, # type: ignore [dict-item]
46
48
  "electronic_properties": ElectronicPropertiesWorkflow, # type: ignore [dict-item]
47
49
  "fukui": FukuiIndexWorkflow, # type: ignore [dict-item]
50
+ "hydrogen_bond_basicity": HydrogenBondBasicityWorkflow, # type: ignore [dict-item]
48
51
  "molecular_dynamics": MolecularDynamicsWorkflow, # type: ignore [dict-item]
49
52
  "multistage_opt": MultiStageOptWorkflow, # type: ignore [dict-item]
50
53
  "pka": pKaWorkflow, # type: ignore [dict-item]
@@ -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
@@ -322,6 +323,45 @@ class ConformerSearchMixin(ConformerGenMixin, MultiStageOptMixin):
322
323
  """Return a string representation of the ConformerSearch workflow."""
323
324
  return f"<{type(self).__name__} {self.conf_gen_mode.name} {self.mso_mode.name}>"
324
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
+
325
365
 
326
366
  class ConformerSearchWorkflow(ConformerSearchMixin, Workflow):
327
367
  """
@@ -1,4 +1,6 @@
1
- from pydantic import NonNegativeFloat, NonNegativeInt
1
+ from typing import Annotated, Callable
2
+
3
+ from pydantic import AfterValidator, NonNegativeFloat, NonNegativeInt
2
4
 
3
5
  from ..base import Base
4
6
  from ..settings import Settings
@@ -6,11 +8,22 @@ from ..types import UUID, FloatPerAtom, Matrix3x3, Vector3D
6
8
  from .workflow import Workflow
7
9
 
8
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
+
9
20
  class PropertyCubePoint(Base):
10
- x: float
11
- y: float
12
- z: float
13
- val: float
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))]
14
27
 
15
28
 
16
29
  class PropertyCube(Base):
@@ -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
@@ -29,7 +29,13 @@ class Frame(Base):
29
29
  pressure: float
30
30
  temperature: float
31
31
  volume: float
32
- energy: float
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
33
39
 
34
40
 
35
41
  class MolecularDynamicsSettings(Base):
@@ -331,3 +331,29 @@ def build_mso_settings(
331
331
  transition_state=transition_state,
332
332
  frequencies=frequencies,
333
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)
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stjames
3
- Version: 0.0.46
3
+ Version: 0.0.47
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
@@ -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
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