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

stjames/base.py CHANGED
@@ -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
 
stjames/method.py CHANGED
@@ -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)
stjames/workflows/scan.py CHANGED
@@ -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
@@ -1,7 +1,7 @@
1
1
  stjames/__init__.py,sha256=LkWCylP4VeXyQL0iu5w6yeYK1UHjcUH55hwWXTy4mQQ,576
2
2
  stjames/_deprecated_solvent_settings.py,sha256=gj5j9p3zakIwSTK5_ndqBXJx--IzjZNxZ75z-wipLOo,450
3
3
  stjames/atom.py,sha256=w7q-x9xpBw4sJ1WGrWt65WAaStxhz-m7dugXCYEOpq4,2064
4
- stjames/base.py,sha256=9PvUjBeVSkmA3TaruaB0uvjFMbWYTGKXECISNGAj_AU,1201
4
+ stjames/base.py,sha256=hroQjvC8G88UiK520i1TDqnOlgw_ihmzevQGTO5yeUY,1215
5
5
  stjames/basis_set.py,sha256=wI3M2q9uPf9jhKpAi4E2DrsyKzloDGLRjAlk7krdYgc,949
6
6
  stjames/calculation.py,sha256=O2LwwQ_cOLmDOGXTHA9J71YbUZXigUSbvbLA-fSVm3w,915
7
7
  stjames/constraint.py,sha256=B6oV0rYjmAWr8gpi5f03gRy_uuqjUURVDVwoez5Cfbg,2442
@@ -10,7 +10,7 @@ stjames/diis_settings.py,sha256=4m1EQQWBlpHhMnWopix8qOqJv7QCluvdnV9jSKJDFtE,552
10
10
  stjames/grid_settings.py,sha256=WrSNGc-8_f87YBZYt9Hh7RbhM4MweADoVzwBMcSqcsE,640
11
11
  stjames/int_settings.py,sha256=5HXp8opt5ZyY1UpmfaK7NVloWVLM5jkG0elEEqpVLUo,896
12
12
  stjames/message.py,sha256=Rq6QqmHZKecWxYH8fVyXmuoCCPZv8YinvgykSeorXSU,216
13
- stjames/method.py,sha256=a6QQff-0YsutkOTuOcGrdDW76x9ZexiNLdKzzoE1Vcw,1698
13
+ stjames/method.py,sha256=teV0nQZTu8gRSZdFpMhjHtvLPf-XeTIMy330rYWDeZ8,1855
14
14
  stjames/mode.py,sha256=xw46Cc7f3eTS8i35qECi-8DocAlANhayK3w4akD4HBU,496
15
15
  stjames/molecule.py,sha256=v8NikFHfwOahXSo4VKGSqeHKI2HIoRdNjGE0GkZgNS4,10554
16
16
  stjames/opt_settings.py,sha256=gxXGtjy9l-Q5Wen9eO6T6HHRCuS8rfOofdVQIJj0JcI,550
@@ -30,25 +30,26 @@ stjames/data/isotopes.json,sha256=5ba8QnLrHD_Ypv2xekv2cIRwYrX3MQ19-1FOFtt0RuU,83
30
30
  stjames/data/nist_isotopes.json,sha256=d5DNk1dX0iB1waEYIRR6JMHuA7AuYwSBEgBvb4EKyhM,14300
31
31
  stjames/data/read_nist_isotopes.py,sha256=y10FNjW43QpC45qib7VHsIghEwT7GG5rsNwHdc9osRI,3309
32
32
  stjames/data/symbol_element.json,sha256=vl_buFusTqBd-muYQtMLtTDLy2OtBI6KkBeqkaWRQrg,1186
33
- stjames/workflows/__init__.py,sha256=IRcfBNaFWVMmixQHjPKcBJkcUYWRnXNwrx2MUFNiQKM,1843
33
+ stjames/workflows/__init__.py,sha256=XQ89vfQxqz2cWmwcOMp_GKZFQ-RDm8B1s8PqAeQTK3g,1999
34
34
  stjames/workflows/admet.py,sha256=V8noO0Eb7h2bDFSnj6Pxv4ILm0lGxyVRCi13hE0zmEQ,149
35
35
  stjames/workflows/basic_calculation.py,sha256=q48bpab7ZqmRTR4PsGC6bWkuxqkVdJRM8gysevTYXP0,212
36
36
  stjames/workflows/bde.py,sha256=iNrBiAUJA-VaAB-eFddApUO2xIc5PyPYXNtC2stQ_OU,9667
37
37
  stjames/workflows/conformer.py,sha256=YYwL3l7OaVeea4N9-ihghwa_ieKY6hia9LNbiTraMb0,2732
38
- stjames/workflows/conformer_search.py,sha256=zmGaSuka0VClmX36AkKvJAN565-hyp2ZJQIjhkAMQRM,12924
38
+ stjames/workflows/conformer_search.py,sha256=y64WpdVZcrUit9ub-yWwJ0zNK8ofPlcjOG4K6pV6UEM,14241
39
39
  stjames/workflows/descriptors.py,sha256=lRRCsGzad3nIg0wI1090ffaXB0FVh0nRRb2lNxCY0kI,281
40
- stjames/workflows/electronic_properties.py,sha256=DFrzU49rux13Fy5q7pgvuYNjiyC2KwMtqU6FTAxg9jo,3339
40
+ stjames/workflows/electronic_properties.py,sha256=0PqS04CfLM4pzx67Ph3JJTrzc1LCwDTT5E8x4_wW-g8,3888
41
41
  stjames/workflows/fukui.py,sha256=CsJ3_gvzqEqcxwYN7bnNIa37F3KlLm7obsU77TGmDgo,348
42
- stjames/workflows/molecular_dynamics.py,sha256=wx633IhPjRwEYvfyuRnSb0c84lN2WtZJET2q-SJv5DY,2211
43
- stjames/workflows/multistage_opt.py,sha256=FXSm-adv9TIiE6ftWPO50Yq9ypoJ7GSPkJKpnC0r4kQ,12686
42
+ stjames/workflows/hydrogen_bond_basicity.py,sha256=xn4AP_PbCUluzrj05ufw3LaN-xBMsAmt2mFsVy1bf-8,455
43
+ stjames/workflows/molecular_dynamics.py,sha256=4HmYETU1VT2BA4-PqAayRZLjnj1WuYxd5bqpIyH9g5k,2465
44
+ stjames/workflows/multistage_opt.py,sha256=0ou-UYMGIrewZIg3QZIgwS_eweYdsh2pRplxgRCqLcE,13572
44
45
  stjames/workflows/pka.py,sha256=zpR90Yv2L-D56o2mGArM8027DWpnFFnay31UR9Xh5Nc,774
45
46
  stjames/workflows/redox_potential.py,sha256=e7WOyTIC_1NPfh7amvW7YzqQezcswX9YaXT-qPiePAo,3651
46
- stjames/workflows/scan.py,sha256=Wqimw1nMErKOYHcC7U1hNC8LZb5XPtS-nE1a-c_6_88,814
47
+ stjames/workflows/scan.py,sha256=cQ29DKlLCH7_6_1TFATnaM3ac9G1asUoRoDDlQYAfG0,860
47
48
  stjames/workflows/spin_states.py,sha256=TXHqB7ClTkkCy1Yfcsv99v2woAhT8oG1-uaF20-oMbQ,4592
48
49
  stjames/workflows/tautomer.py,sha256=owZOOfGlohxlaOG1pGpx7dVPvas8ZEnl_9Ms5F0Kpms,421
49
50
  stjames/workflows/workflow.py,sha256=tIu5naADYgYS7kdW8quvGEWHWosBcrIdcD7L86v-uMQ,976
50
- stjames-0.0.46.dist-info/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
51
- stjames-0.0.46.dist-info/METADATA,sha256=sagkuDdeazTP1wvoGMsletsSSFzY_8Qjv0shhmcj17w,1627
52
- stjames-0.0.46.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
53
- stjames-0.0.46.dist-info/top_level.txt,sha256=FYCwxl6quhYOAgG-mnPQcCK8vsVM7B8rIUrO-WrQ_PI,8
54
- stjames-0.0.46.dist-info/RECORD,,
51
+ stjames-0.0.47.dist-info/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
52
+ stjames-0.0.47.dist-info/METADATA,sha256=jJX69FHFW3VDQtIwM7lR7tIZgM_CDeIvbC8qeERRhMU,1627
53
+ stjames-0.0.47.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
54
+ stjames-0.0.47.dist-info/top_level.txt,sha256=FYCwxl6quhYOAgG-mnPQcCK8vsVM7B8rIUrO-WrQ_PI,8
55
+ stjames-0.0.47.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5