stjames 0.0.33__tar.gz → 0.0.35__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.33/stjames.egg-info → stjames-0.0.35}/PKG-INFO +2 -1
- {stjames-0.0.33 → stjames-0.0.35}/pyproject.toml +5 -1
- {stjames-0.0.33 → stjames-0.0.35}/stjames/_deprecated_solvent_settings.py +4 -4
- {stjames-0.0.33 → stjames-0.0.35}/stjames/base.py +9 -7
- {stjames-0.0.33 → stjames-0.0.35}/stjames/basis_set.py +4 -3
- {stjames-0.0.33 → stjames-0.0.35}/stjames/molecule.py +10 -13
- {stjames-0.0.33 → stjames-0.0.35}/stjames/opt_settings.py +6 -6
- stjames-0.0.35/stjames/py.typed +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/scf_settings.py +10 -9
- {stjames-0.0.33 → stjames-0.0.35}/stjames/settings.py +17 -9
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/redox_potential.py +8 -2
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/tautomer.py +0 -1
- {stjames-0.0.33 → stjames-0.0.35/stjames.egg-info}/PKG-INFO +2 -1
- {stjames-0.0.33 → stjames-0.0.35}/stjames.egg-info/SOURCES.txt +1 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames.egg-info/requires.txt +1 -0
- {stjames-0.0.33 → stjames-0.0.35}/LICENSE +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/README.md +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/setup.cfg +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/__init__.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/calculation.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/correction.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/diis_settings.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/grid_settings.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/int_settings.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/method.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/mode.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/solvent.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/status.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/task.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/thermochem_settings.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/__init__.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/conformer.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/fukui.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/pka.py +1 -1
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/scan.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames/workflows/workflow.py +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames.egg-info/dependency_links.txt +0 -0
- {stjames-0.0.33 → stjames-0.0.35}/stjames.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stjames
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.35
|
|
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,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "stjames"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.35"
|
|
4
4
|
description = "standardized JSON atom/molecule encoding scheme"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.8"
|
|
@@ -10,6 +10,7 @@ authors = [
|
|
|
10
10
|
|
|
11
11
|
dependencies = [
|
|
12
12
|
"pydantic>=2.4",
|
|
13
|
+
"numpy",
|
|
13
14
|
]
|
|
14
15
|
|
|
15
16
|
[build-system]
|
|
@@ -38,3 +39,6 @@ select = [
|
|
|
38
39
|
"W", # pycodestyle warnings
|
|
39
40
|
]
|
|
40
41
|
ignore = ["E741"]
|
|
42
|
+
|
|
43
|
+
[tool.mypy]
|
|
44
|
+
plugins = ["pydantic.mypy"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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:
|
|
18
|
-
vdw_scale:
|
|
19
|
-
weight_cutoff:
|
|
17
|
+
grid_points_per_atom: PositiveInt = 170
|
|
18
|
+
vdw_scale: PositiveFloat = 1.2
|
|
19
|
+
weight_cutoff: PositiveFloat = 1e-8
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from typing import Annotated,
|
|
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:
|
|
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
|
-
|
|
31
|
-
T = TypeVar("T", bound=Hashable)
|
|
33
|
+
H = TypeVar("H", bound=Hashable)
|
|
32
34
|
|
|
33
35
|
|
|
34
|
-
def _validate_unique_list(v: list[
|
|
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[
|
|
42
|
+
UniqueList = Annotated[list[H], pydantic.AfterValidator(_validate_unique_list)]
|
|
@@ -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[
|
|
14
|
-
atoms: Optional[list[
|
|
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:
|
|
33
|
+
cutoff_threshold: PositiveFloat = 1e-10
|
|
@@ -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:
|
|
20
|
+
atomic_number: NonNegativeInt
|
|
20
21
|
position: list[float]
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class Molecule(Base):
|
|
24
25
|
charge: int
|
|
25
|
-
multiplicity:
|
|
26
|
+
multiplicity: PositiveInt
|
|
26
27
|
atoms: list[Atom]
|
|
27
28
|
|
|
28
29
|
energy: Optional[float] = None
|
|
29
|
-
scf_iterations: Optional[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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:
|
|
22
|
+
max_steps: PositiveInt = 250
|
|
23
23
|
transition_state: bool = False
|
|
24
24
|
|
|
25
25
|
# when are we converged?
|
|
26
|
-
max_gradient_threshold:
|
|
27
|
-
rms_gradient_threshold:
|
|
28
|
-
energy_threshold:
|
|
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] =
|
|
30
|
+
constraints: list[Constraint] = Field(default_factory=list)
|
|
File without changes
|
|
@@ -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:
|
|
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:
|
|
47
|
+
level_shift_magnitude: PositiveFloat = 0.25
|
|
47
48
|
# when should we stop?
|
|
48
|
-
end_level_shift_error:
|
|
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:
|
|
55
|
+
rebuild_frequency: PositiveInt = 20
|
|
55
56
|
|
|
56
57
|
#### when are we converged?
|
|
57
|
-
energy_threshold:
|
|
58
|
-
rms_error_threshold:
|
|
59
|
-
max_error_threshold:
|
|
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:
|
|
67
|
+
start_diis_iter: PositiveInt = 3
|
|
67
68
|
# iteration past which we'll start DIIS even if error is high
|
|
68
|
-
start_diis_anyway:
|
|
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
|
|
@@ -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 = [
|
|
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) ->
|
|
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
|
|
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
|
-
|
|
85
|
-
|
|
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
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
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,14 @@ class RedoxPotentialWorkflow(Workflow):
|
|
|
22
24
|
oxidation_potential: Optional[float] = None
|
|
23
25
|
|
|
24
26
|
def model_post_init(self, __context: Any) -> None:
|
|
25
|
-
"""
|
|
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
|
+
if self.oxidation_potential is None:
|
|
32
|
+
self.oxidation_potential = self.redox_potential
|
|
29
33
|
elif self.redox_type == "reduction":
|
|
30
34
|
self.oxidation = False
|
|
31
35
|
self.reduction = True
|
|
36
|
+
if self.reduction_potential is None:
|
|
37
|
+
self.reduction_potential = self.redox_potential
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stjames
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.35
|
|
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
|
|
|
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
|