stjames 0.0.32__py3-none-any.whl → 0.0.34__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.

Potentially problematic release.


This version of stjames might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
- import pydantic
1
+ from pydantic import PositiveFloat, PositiveInt
2
2
 
3
3
  from .base import Base, LowercaseStrEnum
4
4
 
@@ -14,6 +14,6 @@ class SolventSettings(Base):
14
14
  model: ImplicitSolventModel = ImplicitSolventModel.NONE
15
15
  epsilon: float = 78.36
16
16
 
17
- grid_points_per_atom: pydantic.PositiveInt = 170
18
- vdw_scale: pydantic.PositiveFloat = 1.2
19
- weight_cutoff: pydantic.PositiveFloat = 1e-8
17
+ grid_points_per_atom: PositiveInt = 170
18
+ vdw_scale: PositiveFloat = 1.2
19
+ weight_cutoff: PositiveFloat = 1e-8
stjames/base.py CHANGED
@@ -1,14 +1,16 @@
1
1
  from enum import Enum
2
- from typing import Annotated, Any, Hashable, TypeVar
2
+ from typing import Annotated, Hashable, TypeVar
3
3
 
4
4
  import numpy as np
5
5
  import pydantic
6
6
 
7
+ T = TypeVar("T")
8
+
7
9
 
8
10
  class Base(pydantic.BaseModel):
9
11
  @pydantic.field_validator("*", mode="before")
10
12
  @classmethod
11
- def coerce_numpy(cls, val: Any):
13
+ def coerce_numpy(cls, val: T) -> T | list:
12
14
  if isinstance(val, np.ndarray):
13
15
  return val.tolist()
14
16
  else:
@@ -19,7 +21,8 @@ class LowercaseStrEnum(str, Enum):
19
21
  """Enum where hyphens and case are ignored."""
20
22
 
21
23
  @classmethod
22
- def _missing_(cls, value: str):
24
+ def _missing_(cls, value: str) -> str | None: # type: ignore
25
+ # Type note: technically breaking Liskov, value: object in Enum
23
26
  for member in cls:
24
27
  if member.lower().replace("-", "") == value.lower().replace("-", ""):
25
28
  return member
@@ -27,14 +30,13 @@ class LowercaseStrEnum(str, Enum):
27
30
 
28
31
 
29
32
  # cf. https://github.com/pydantic/pydantic-core/pull/820#issuecomment-1670475909
30
- # there are python details here I don't really grasp
31
- T = TypeVar("T", bound=Hashable)
33
+ H = TypeVar("H", bound=Hashable)
32
34
 
33
35
 
34
- def _validate_unique_list(v: list[T]) -> list[T]:
36
+ def _validate_unique_list(v: list[H]) -> list[H]:
35
37
  if len(v) != len(set(v)):
36
38
  raise ValueError("this list must be unique, and isn't!")
37
39
  return v
38
40
 
39
41
 
40
- UniqueList = Annotated[list[T], pydantic.AfterValidator(_validate_unique_list)]
42
+ UniqueList = Annotated[list[H], pydantic.AfterValidator(_validate_unique_list)]
stjames/basis_set.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import pydantic
2
+ from pydantic import PositiveFloat, PositiveInt
2
3
 
3
4
  try:
4
5
  from typing import Optional, Self
@@ -10,8 +11,8 @@ from .base import Base
10
11
 
11
12
  class BasisSetOverride(Base):
12
13
  name: str
13
- atomic_numbers: Optional[list[pydantic.PositiveInt]] = None
14
- atoms: Optional[list[pydantic.PositiveInt]] = None # 1-indexed
14
+ atomic_numbers: Optional[list[PositiveInt]] = None
15
+ atoms: Optional[list[PositiveInt]] = None # 1-indexed
15
16
 
16
17
  @pydantic.model_validator(mode="after")
17
18
  def check_override(self) -> Self:
@@ -29,4 +30,4 @@ class BasisSet(Base):
29
30
  # value below which a basis function can be ignored
30
31
  # (for improving DFT grid calcs, as per Stratmann/Scuseria/Frisch CPL 1996)
31
32
  # this shouldn't really need to be modified...
32
- cutoff_threshold: pydantic.PositiveFloat = 1e-10
33
+ cutoff_threshold: PositiveFloat = 1e-10
stjames/molecule.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import pydantic
2
+ from pydantic import NonNegativeInt, PositiveInt
2
3
 
3
4
  try:
4
5
  from typing import Optional, Self
@@ -16,17 +17,17 @@ class VibrationalMode(Base):
16
17
 
17
18
 
18
19
  class Atom(Base):
19
- atomic_number: pydantic.NonNegativeInt
20
+ atomic_number: NonNegativeInt
20
21
  position: list[float]
21
22
 
22
23
 
23
24
  class Molecule(Base):
24
25
  charge: int
25
- multiplicity: pydantic.PositiveInt
26
+ multiplicity: PositiveInt
26
27
  atoms: list[Atom]
27
28
 
28
29
  energy: Optional[float] = None
29
- scf_iterations: Optional[pydantic.NonNegativeInt] = None
30
+ scf_iterations: Optional[NonNegativeInt] = None
30
31
  scf_completed: Optional[bool] = None
31
32
  elapsed: Optional[float] = None
32
33
 
@@ -46,40 +47,36 @@ class Molecule(Base):
46
47
  thermal_free_energy_corr: Optional[float] = None
47
48
 
48
49
  @property
49
- def coordinates(self):
50
+ def coordinates(self) -> list[list[float]]:
50
51
  return [a.position for a in self.atoms]
51
52
 
52
53
  @property
53
- def atomic_numbers(self):
54
+ def atomic_numbers(self) -> list[NonNegativeInt]:
54
55
  return [a.atomic_number for a in self.atoms]
55
56
 
56
57
  @property
57
58
  def sum_energy_zpe(self) -> Optional[float]:
58
59
  if (self.energy is None) or (self.zero_point_energy is None):
59
60
  return None
60
- else:
61
- return self.energy + self.zero_point_energy
61
+ return self.energy + self.zero_point_energy
62
62
 
63
63
  @property
64
64
  def sum_energy_thermal_corr(self) -> Optional[float]:
65
65
  if (self.energy is None) or (self.thermal_energy_corr is None):
66
66
  return None
67
- else:
68
- return self.energy + self.thermal_energy_corr
67
+ return self.energy + self.thermal_energy_corr
69
68
 
70
69
  @property
71
70
  def sum_energy_enthalpy(self) -> Optional[float]:
72
71
  if (self.energy is None) or (self.thermal_enthalpy_corr is None):
73
72
  return None
74
- else:
75
- return self.energy + self.thermal_enthalpy_corr
73
+ return self.energy + self.thermal_enthalpy_corr
76
74
 
77
75
  @property
78
76
  def sum_energy_free_energy(self) -> Optional[float]:
79
77
  if (self.energy is None) or (self.thermal_free_energy_corr is None):
80
78
  return None
81
- else:
82
- return self.energy + self.thermal_free_energy_corr
79
+ return self.energy + self.thermal_free_energy_corr
83
80
 
84
81
  @pydantic.model_validator(mode="after")
85
82
  def check_electron_sanity(self) -> Self:
stjames/opt_settings.py CHANGED
@@ -1,4 +1,4 @@
1
- import pydantic
1
+ from pydantic import Field, PositiveFloat, PositiveInt
2
2
 
3
3
  from .base import Base, LowercaseStrEnum
4
4
 
@@ -19,12 +19,12 @@ class Constraint(Base):
19
19
 
20
20
 
21
21
  class OptimizationSettings(Base):
22
- max_steps: pydantic.PositiveInt = 250
22
+ max_steps: PositiveInt = 250
23
23
  transition_state: bool = False
24
24
 
25
25
  # when are we converged?
26
- max_gradient_threshold: pydantic.PositiveFloat = 4.5e-4
27
- rms_gradient_threshold: pydantic.PositiveFloat = 3.0e-4
28
- energy_threshold: pydantic.PositiveFloat = 1e-6
26
+ max_gradient_threshold: PositiveFloat = 4.5e-4
27
+ rms_gradient_threshold: PositiveFloat = 3.0e-4
28
+ energy_threshold: PositiveFloat = 1e-6
29
29
 
30
- constraints: list[Constraint] = pydantic.Field(default_factory=list)
30
+ constraints: list[Constraint] = Field(default_factory=list)
stjames/py.typed ADDED
File without changes
stjames/scf_settings.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from typing import Any, Optional
2
2
 
3
3
  import pydantic
4
+ from pydantic import PositiveFloat, PositiveInt
4
5
 
5
6
  from .base import Base, LowercaseStrEnum
6
7
  from .diis_settings import DIISSettings
@@ -36,36 +37,36 @@ class SCFSettings(Base):
36
37
  #### damping
37
38
  do_damping: bool = True
38
39
  # when should we stop damping?
39
- end_damping_error: pydantic.PositiveFloat = 0.1
40
+ end_damping_error: PositiveFloat = 0.1
40
41
  # what damping factor should we use?
41
42
  damping_factor: float = pydantic.Field(ge=0, le=1, default=0.7)
42
43
 
43
44
  #### level shifting
44
45
  do_level_shift: bool = True
45
46
  # how much? (Eh)
46
- level_shift_magnitude: pydantic.PositiveFloat = 0.25
47
+ level_shift_magnitude: PositiveFloat = 0.25
47
48
  # when should we stop?
48
- end_level_shift_error: pydantic.PositiveFloat = 0.1
49
+ end_level_shift_error: PositiveFloat = 0.1
49
50
 
50
51
  #### incremental
51
52
  # do incremental fock build?
52
53
  do_incremental: bool = True
53
54
  # reset incremental fock build
54
- rebuild_frequency: pydantic.PositiveInt = 20
55
+ rebuild_frequency: PositiveInt = 20
55
56
 
56
57
  #### when are we converged?
57
- energy_threshold: pydantic.PositiveFloat = 1e-6
58
- rms_error_threshold: pydantic.PositiveFloat = 1e-8
59
- max_error_threshold: pydantic.PositiveFloat = 1e-5
58
+ energy_threshold: PositiveFloat = 1e-6
59
+ rms_error_threshold: PositiveFloat = 1e-8
60
+ max_error_threshold: PositiveFloat = 1e-5
60
61
 
61
62
  #### DIIS
62
63
  do_diis: bool = True
63
64
  # error below which we'll start DIIS
64
65
  start_diis_max_error: pydantic.PositiveFloat = 0.2
65
66
  # first iteration we'll consider starting DIIS
66
- start_diis_iter: pydantic.PositiveInt = 3
67
+ start_diis_iter: PositiveInt = 3
67
68
  # iteration past which we'll start DIIS even if error is high
68
- start_diis_anyway: pydantic.PositiveInt = 7
69
+ start_diis_anyway: PositiveInt = 7
69
70
 
70
71
  # if ``read`` initialization is selected
71
72
  initial_density_matrix_guess: Optional[list[list[float]]] = None
stjames/settings.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional
1
+ from typing import Any, Optional, TypeVar
2
2
 
3
3
  import pydantic
4
4
 
@@ -13,7 +13,14 @@ from .solvent import SolventSettings
13
13
  from .task import Task
14
14
  from .thermochem_settings import ThermochemistrySettings
15
15
 
16
- PREPACKAGED_METHODS = [Method.HF3C, Method.B973C, Method.AIMNET2_WB97MD3, Method.AIMNET2_B973C, Method.GFN2_XTB, Method.GFN1_XTB]
16
+ PREPACKAGED_METHODS = [
17
+ Method.HF3C,
18
+ Method.B973C,
19
+ Method.AIMNET2_WB97MD3,
20
+ Method.AIMNET2_B973C,
21
+ Method.GFN2_XTB,
22
+ Method.GFN1_XTB,
23
+ ]
17
24
 
18
25
  METHODS_WITH_CORRECTION = [
19
26
  Method.B97D3,
@@ -23,6 +30,8 @@ METHODS_WITH_CORRECTION = [
23
30
  Method.WB97MV,
24
31
  ]
25
32
 
33
+ T = TypeVar("T")
34
+
26
35
 
27
36
  class Settings(Base):
28
37
  method: Method = Method.HARTREE_FOCK
@@ -39,8 +48,8 @@ class Settings(Base):
39
48
  opt_settings: OptimizationSettings = OptimizationSettings()
40
49
  thermochem_settings: ThermochemistrySettings = ThermochemistrySettings()
41
50
 
42
- @pydantic.computed_field
43
51
  @property
52
+ @pydantic.computed_field
44
53
  def level_of_theory(self) -> str:
45
54
  if self.method in PREPACKAGED_METHODS or self.basis_set is None:
46
55
  method = self.method.value
@@ -72,18 +81,17 @@ class Settings(Base):
72
81
 
73
82
  @pydantic.field_validator("basis_set", mode="before")
74
83
  @classmethod
75
- def parse_basis_set(cls, v: Any) -> Optional[BasisSet]:
84
+ def parse_basis_set(cls, v: Any) -> BasisSet | dict | None:
76
85
  """Turn a string into a ``BasisSet`` object. (This is a little crude.)"""
77
86
  if isinstance(v, BasisSet):
78
87
  return None if v.name is None else v
79
88
  elif isinstance(v, dict):
80
- return None if v["name"] is None else v
89
+ return None if v.get("name") is None else v
81
90
  elif isinstance(v, str):
82
91
  if len(v):
83
92
  return BasisSet(name=v)
84
- else:
85
- # "" is basically None, let's be real here...
86
- return None
93
+ # "" is basically None, let's be real here...
94
+ return None
87
95
  elif v is None:
88
96
  return None
89
97
  else:
@@ -91,7 +99,7 @@ class Settings(Base):
91
99
 
92
100
  @pydantic.field_validator("corrections", mode="before")
93
101
  @classmethod
94
- def remove_empty_string(cls, v: list) -> list:
102
+ def remove_empty_string(cls, v: list[T]) -> list[T]:
95
103
  """Remove empty string values."""
96
104
  return [c for c in v if c]
97
105
 
stjames/workflows/pka.py CHANGED
@@ -1,15 +1,15 @@
1
1
  from typing import Optional
2
2
 
3
- from ..mode import Mode
4
3
  from ..base import Base
4
+ from ..mode import Mode
5
5
  from .workflow import DBCalculation, Workflow
6
6
 
7
7
 
8
8
  class pKaMicrostate(Base):
9
9
  atom_index: int
10
10
  structures: list[DBCalculation] = []
11
- delta_G: float
12
- pKa: float
11
+ deltaG: float
12
+ pka: float
13
13
 
14
14
 
15
15
  class pKaWorkflow(Workflow):
@@ -1,4 +1,4 @@
1
- from typing import Optional, Any
1
+ from typing import Any, Optional
2
2
 
3
3
  from ..mode import Mode
4
4
  from ..solvent import Solvent
@@ -11,7 +11,9 @@ class RedoxPotentialWorkflow(Workflow):
11
11
  reduction: bool = True
12
12
  oxidation: bool = True
13
13
 
14
+ # legacy values - remove in future release!
14
15
  redox_type: Optional[str] = None
16
+ redox_potential: Optional[float] = None
15
17
 
16
18
  # uuids
17
19
  neutral_molecule: Optional[str] = None
@@ -22,10 +24,12 @@ class RedoxPotentialWorkflow(Workflow):
22
24
  oxidation_potential: Optional[float] = None
23
25
 
24
26
  def model_post_init(self, __context: Any) -> None:
25
- """ Keep back-compatible with old schema. """
27
+ """Keep back-compatible with old schema."""
26
28
  if self.redox_type == "oxidation":
27
29
  self.oxidation = True
28
30
  self.reduction = False
31
+ self.oxidation_potential = self.redox_potential
29
32
  elif self.redox_type == "reduction":
30
33
  self.oxidation = False
31
34
  self.reduction = True
35
+ self.reduction_potential = self.redox_potential
@@ -2,7 +2,6 @@ from typing import Optional
2
2
 
3
3
  from ..base import Base
4
4
  from ..mode import Mode
5
- from .conformer import ConformerSettings
6
5
  from .workflow import DBCalculation, Workflow
7
6
 
8
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stjames
3
- Version: 0.0.32
3
+ Version: 0.0.34
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
@@ -9,6 +9,7 @@ Requires-Python: >=3.8
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: pydantic >=2.4
12
+ Requires-Dist: numpy
12
13
 
13
14
  # stjames
14
15
 
@@ -1,7 +1,7 @@
1
1
  stjames/__init__.py,sha256=_gX08PEdPHoE6oyc0OF2gKPBfk9op0am75y1TDUo-MU,451
2
- stjames/_deprecated_solvent_settings.py,sha256=ALUZeQoxDS11EvZexT1J2SDAlLTiXe-x4jV8tenDqMc,445
3
- stjames/base.py,sha256=cZNJq0TSRJk7aKVIl7fzRG6IYQeJ0ihWPi9eJxTiQfI,1070
4
- stjames/basis_set.py,sha256=4Su3K3Y7G-4S8WHWOQE94d6hxoN6L_MkQUz3qoFqcB0,1014
2
+ stjames/_deprecated_solvent_settings.py,sha256=gj5j9p3zakIwSTK5_ndqBXJx--IzjZNxZ75z-wipLOo,450
3
+ stjames/base.py,sha256=GTISjYPBi4KCxAR9DPLf4mp6ZYuh2MwlNI0jZ1N41Io,1142
4
+ stjames/basis_set.py,sha256=Fi6vJx-ni2aOozFYH2hrSlc9lL01XzPO4zO6onJliuE,1035
5
5
  stjames/calculation.py,sha256=6xnoKLn6tr1QaactTWsdu8Ciqdu8oa-hmB2y9RIrJTI,786
6
6
  stjames/correction.py,sha256=_pNG3qSylfx0iyUxqwx9HPU0m032YwP6wSPCjbJrD94,358
7
7
  stjames/diis_settings.py,sha256=QHc7L-hktkbOWBYr29byTdqL8lWJzKJiY9XW8ha4Qzo,552
@@ -9,10 +9,11 @@ stjames/grid_settings.py,sha256=WrSNGc-8_f87YBZYt9Hh7RbhM4MweADoVzwBMcSqcsE,640
9
9
  stjames/int_settings.py,sha256=5HXp8opt5ZyY1UpmfaK7NVloWVLM5jkG0elEEqpVLUo,896
10
10
  stjames/method.py,sha256=e7A3XH808JglgfCzISKyRKAxGDj7BQdcQQtgtTlgfNk,843
11
11
  stjames/mode.py,sha256=xw46Cc7f3eTS8i35qECi-8DocAlANhayK3w4akD4HBU,496
12
- stjames/molecule.py,sha256=y-NidMubuA9IsSruUKavyBndbf5hYodjihna9uBjkOc,2915
13
- stjames/opt_settings.py,sha256=RwXikvwW6fTODK3FK8Xvyqy4DY-qMVtZHndWirBxujk,735
14
- stjames/scf_settings.py,sha256=blJ5Mo2znF_H05gBCPZXTrDwCZuVzUJ_OIcmYGc0Eg0,2389
15
- stjames/settings.py,sha256=xw5m9Zq4L-oUoV53MMmn9t-KmzlZoFVJSRmac8f2Sfw,8420
12
+ stjames/molecule.py,sha256=t0jOmkTMgQE2ayBn9igjpY_4gPyqLPqZLlgtwd4uBOA,2910
13
+ stjames/opt_settings.py,sha256=81vYDBEbqLGN_crI1GtAxiOoRa791WN0m2HfT5_A7pE,729
14
+ stjames/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ stjames/scf_settings.py,sha256=xMMCQ0hVB4nNFSiWesNQZUa_aLsozSZGYWweAPPDGBg,2356
16
+ stjames/settings.py,sha256=cUiAydIVes9iDEky4coOYQ2kF97AYaLClx5qjJmEpWY,8462
16
17
  stjames/solvent.py,sha256=3ssY-vQCCa071srfJbwCYEKDpWos8Mgvmg_dTpAnbJw,1104
17
18
  stjames/status.py,sha256=wTKNcNxStoEHrxxgr_zTyN90NITa3rxMQZzOgrCifEw,332
18
19
  stjames/task.py,sha256=TTl-iTdvDNCZTdPsyS6bYmxzY0ez9PgYlL62fztayXQ,307
@@ -20,13 +21,13 @@ stjames/thermochem_settings.py,sha256=ZTLz31v8Ltutde5Nfm0vH5YahWjcfFWfr_R856Kffx
20
21
  stjames/workflows/__init__.py,sha256=TibQzeD3X3YGq9TaAzPlBMxU7zskFoa8PwPUam4TcZY,154
21
22
  stjames/workflows/conformer.py,sha256=tqACquXy8wqIbxl3T-n4dfNNNkVdLos2dIG1u0CV8cc,2169
22
23
  stjames/workflows/fukui.py,sha256=FAabgLi_ig6Zp_jiTkuveP0wAObwv68liuumr85rb0g,366
23
- stjames/workflows/pka.py,sha256=TdTZqCBOL6DnPnuGs7qlCVt21LVSveryP0h1hz_wBRU,775
24
- stjames/workflows/redox_potential.py,sha256=uQZvgzii9SiYYxwzUTlb43uCSVaQ5C5Sg52HJ3YPhcI,897
24
+ stjames/workflows/pka.py,sha256=zpR90Yv2L-D56o2mGArM8027DWpnFFnay31UR9Xh5Nc,774
25
+ stjames/workflows/redox_potential.py,sha256=5CApMfltVRrPKilGwW1_rKhA5HoL75ZSIOCVv90aN6k,1107
25
26
  stjames/workflows/scan.py,sha256=d1ca1uk1nxdzlSwqMLZ0W1_DHyrQMnHJmvPfziCS0SA,773
26
- stjames/workflows/tautomer.py,sha256=xJMDArpsuTLmgBZHXcBGVMcP_tncQzvxUH4Kbis4opg,462
27
+ stjames/workflows/tautomer.py,sha256=kZSCHo2Q7LzqtQjF_WyyxjECkndG49T9QOM12hsUkx8,421
27
28
  stjames/workflows/workflow.py,sha256=jzkHO8mdmoy9zW3iD457KAXYrCCkV2OHjg6T3896nCQ,304
28
- stjames-0.0.32.dist-info/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
29
- stjames-0.0.32.dist-info/METADATA,sha256=mtFI6nQUc_03w1bFfF7CKnyCoSCmhDFJKNTko8dLvw0,1605
30
- stjames-0.0.32.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
31
- stjames-0.0.32.dist-info/top_level.txt,sha256=FYCwxl6quhYOAgG-mnPQcCK8vsVM7B8rIUrO-WrQ_PI,8
32
- stjames-0.0.32.dist-info/RECORD,,
29
+ stjames-0.0.34.dist-info/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
30
+ stjames-0.0.34.dist-info/METADATA,sha256=Yv7Q-jpvJKU1wcU5VELqXUNcJks_EpOeDZBFDytihZc,1626
31
+ stjames-0.0.34.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
32
+ stjames-0.0.34.dist-info/top_level.txt,sha256=FYCwxl6quhYOAgG-mnPQcCK8vsVM7B8rIUrO-WrQ_PI,8
33
+ stjames-0.0.34.dist-info/RECORD,,