stjames 0.0.77__tar.gz → 0.0.79__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.77/stjames.egg-info → stjames-0.0.79}/PKG-INFO +2 -1
- {stjames-0.0.77 → stjames-0.0.79}/pyproject.toml +2 -1
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atomium_stjames/pdb.py +35 -10
- {stjames-0.0.77 → stjames-0.0.79}/stjames/molecule.py +16 -11
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/hydrogen_bond_basicity.py +19 -3
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/multistage_opt.py +72 -1
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/protein_cofolding.py +13 -1
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/workflow.py +1 -0
- {stjames-0.0.77 → stjames-0.0.79/stjames.egg-info}/PKG-INFO +2 -1
- {stjames-0.0.77 → stjames-0.0.79}/stjames.egg-info/requires.txt +1 -0
- {stjames-0.0.77 → stjames-0.0.79}/LICENSE +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/README.md +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/setup.cfg +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/__init__.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/_deprecated_solvent_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atom.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atomium_stjames/__init__.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atomium_stjames/data.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atomium_stjames/mmcif.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/atomium_stjames/utilities.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/base.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/basis_set.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/calculation.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/compute_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/constraint.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/correction.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/__init__.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/bragg_radii.json +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/elements.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/isotopes.json +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/nist_isotopes.json +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/read_nist_isotopes.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/data/symbol_element.json +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/diis_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/grid_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/int_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/message.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/method.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/mode.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/opt_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/pdb.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/periodic_cell.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/py.typed +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/scf_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/solvent.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/status.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/task.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/thermochem_settings.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/types.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/__init__.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/admet.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/basic_calculation.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/bde.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/conformer.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/conformer_search.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/descriptors.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/docking.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/electronic_properties.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/fukui.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/ion_mobility.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/irc.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/macropka.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/molecular_dynamics.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/pka.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/redox_potential.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/scan.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/solubility.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/spin_states.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames/workflows/tautomer.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames.egg-info/SOURCES.txt +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames.egg-info/dependency_links.txt +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/stjames.egg-info/top_level.txt +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_constraints.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_from_extxyz.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_molecule.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_pdb.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_rounding.py +0 -0
- {stjames-0.0.77 → stjames-0.0.79}/tests/test_settings.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stjames
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.79
|
|
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
|
|
@@ -12,6 +12,7 @@ Requires-Dist: pydantic>=2.4
|
|
|
12
12
|
Requires-Dist: numpy
|
|
13
13
|
Requires-Dist: requests
|
|
14
14
|
Requires-Dist: rdkit
|
|
15
|
+
Requires-Dist: more-itertools
|
|
15
16
|
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
# stjames
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "stjames"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.79"
|
|
4
4
|
description = "standardized JSON atom/molecule encoding scheme"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -13,6 +13,7 @@ dependencies = [
|
|
|
13
13
|
"numpy",
|
|
14
14
|
"requests",
|
|
15
15
|
"rdkit",
|
|
16
|
+
"more-itertools",
|
|
16
17
|
]
|
|
17
18
|
|
|
18
19
|
[build-system]
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import re
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from itertools import chain, groupby
|
|
6
|
-
from typing import Any, Callable
|
|
6
|
+
from typing import Any, Callable, TypedDict
|
|
7
7
|
|
|
8
8
|
from .data import CODES
|
|
9
9
|
from .mmcif import add_secondary_structure_to_polymers
|
|
@@ -476,15 +476,17 @@ def add_atom_to_polymer(line: str, model: dict[Any, Any], chain_id: str, res_id:
|
|
|
476
476
|
:param str res_id: the molecule ID to add to.
|
|
477
477
|
:param dict aniso_dict: lookup dictionary for anisotropy information."""
|
|
478
478
|
|
|
479
|
+
atom = atom_line_to_dict(line, aniso_dict)
|
|
480
|
+
|
|
479
481
|
try:
|
|
480
|
-
model["polymer"][chain_id]["residues"][res_id]["atoms"][int(line[6:11])] =
|
|
482
|
+
model["polymer"][chain_id]["residues"][res_id]["atoms"][int(line[6:11])] = atom
|
|
481
483
|
except Exception:
|
|
482
484
|
name = line[17:20].strip()
|
|
483
485
|
try:
|
|
484
486
|
model["polymer"][chain_id]["residues"][res_id] = {
|
|
485
487
|
"name": name,
|
|
486
488
|
"full_name": full_names.get(name),
|
|
487
|
-
"atoms": {int(line[6:11]):
|
|
489
|
+
"atoms": {int(line[6:11]): atom},
|
|
488
490
|
"number": len(model["polymer"][chain_id]["residues"]) + 1,
|
|
489
491
|
}
|
|
490
492
|
except Exception:
|
|
@@ -495,7 +497,7 @@ def add_atom_to_polymer(line: str, model: dict[Any, Any], chain_id: str, res_id:
|
|
|
495
497
|
"residues": {
|
|
496
498
|
res_id: {
|
|
497
499
|
"name": line[17:20].strip(),
|
|
498
|
-
"atoms": {int(line[6:11]):
|
|
500
|
+
"atoms": {int(line[6:11]): atom},
|
|
499
501
|
"number": 1,
|
|
500
502
|
"full_name": None,
|
|
501
503
|
}
|
|
@@ -511,10 +513,11 @@ def add_atom_to_non_polymer(line: str, model: dict[Any, Any], res_id: str, aniso
|
|
|
511
513
|
:param dict model: the model to update.
|
|
512
514
|
:param str res_id: the molecule ID to add to.
|
|
513
515
|
:param dict aniso_dict: lookup dictionary for anisotropy information."""
|
|
516
|
+
atom = atom_line_to_dict(line, aniso_dict)
|
|
514
517
|
|
|
515
518
|
key = "water" if line[17:20] in ["HOH", "DOD"] else "non_polymer"
|
|
516
519
|
try:
|
|
517
|
-
model[key][res_id]["atoms"][int(line[6:11])] =
|
|
520
|
+
model[key][res_id]["atoms"][int(line[6:11])] = atom
|
|
518
521
|
except Exception:
|
|
519
522
|
name = line[17:20].strip()
|
|
520
523
|
model[key][res_id] = {
|
|
@@ -522,7 +525,7 @@ def add_atom_to_non_polymer(line: str, model: dict[Any, Any], res_id: str, aniso
|
|
|
522
525
|
"full_name": full_names.get(name),
|
|
523
526
|
"internal_id": line[21],
|
|
524
527
|
"polymer": line[21],
|
|
525
|
-
"atoms": {int(line[6:11]):
|
|
528
|
+
"atoms": {int(line[6:11]): atom},
|
|
526
529
|
}
|
|
527
530
|
|
|
528
531
|
|
|
@@ -545,14 +548,32 @@ def guess_element_from_name(atom_name: str) -> str | None:
|
|
|
545
548
|
return atom_name[0].upper()
|
|
546
549
|
|
|
547
550
|
|
|
548
|
-
|
|
549
|
-
"""
|
|
551
|
+
class AtomDict(TypedDict, total=False):
|
|
552
|
+
"""A dictionary representing an atom in a PDB file."""
|
|
553
|
+
|
|
554
|
+
occupancy: float | None
|
|
555
|
+
bvalue: float | None
|
|
556
|
+
charge: int | None
|
|
557
|
+
anisotropy: float | None
|
|
558
|
+
is_hetatm: bool | None
|
|
559
|
+
name: str | None
|
|
560
|
+
alt_loc: str | None
|
|
561
|
+
x: float
|
|
562
|
+
y: float
|
|
563
|
+
z: float
|
|
564
|
+
element: str | None
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def atom_line_to_dict(line: str, aniso_dict: dict[Any, Any]) -> AtomDict:
|
|
568
|
+
"""
|
|
569
|
+
Converts an ATOM or HETATM record to an atom dictionary.
|
|
550
570
|
|
|
551
571
|
:param str line: the record to convert.
|
|
552
572
|
:param dict aniso_dict: the anisotropy dictionary to use.
|
|
553
|
-
:
|
|
573
|
+
:return: atom dictionary
|
|
574
|
+
"""
|
|
554
575
|
|
|
555
|
-
a = {"occupancy": 1, "bvalue": None, "charge": 0, "anisotropy": aniso_dict.get(int(line[6:11].strip()), None)}
|
|
576
|
+
a: AtomDict = {"occupancy": 1, "bvalue": None, "charge": 0, "anisotropy": aniso_dict.get(int(line[6:11].strip()), None)}
|
|
556
577
|
a["is_hetatm"] = line[:6] == "HETATM"
|
|
557
578
|
a["name"] = line[12:16].strip() or None
|
|
558
579
|
a["alt_loc"] = line[16].strip() or None
|
|
@@ -565,6 +586,9 @@ def atom_line_to_dict(line: str, aniso_dict: dict[Any, Any]) -> dict[str, Any]:
|
|
|
565
586
|
a["bvalue"] = float(line[60:66].strip())
|
|
566
587
|
a["element"] = line[76:78].strip() or None
|
|
567
588
|
if not a["element"]:
|
|
589
|
+
if not a["name"]:
|
|
590
|
+
raise ValueError("Cannot guess element from empty name.")
|
|
591
|
+
assert isinstance(a["name"], str)
|
|
568
592
|
a["element"] = guess_element_from_name(a["name"])
|
|
569
593
|
if line[78:80].strip():
|
|
570
594
|
try:
|
|
@@ -582,6 +606,7 @@ def atom_line_to_dict(line: str, aniso_dict: dict[Any, Any]) -> dict[str, Any]:
|
|
|
582
606
|
a["occupancy"] = None
|
|
583
607
|
if a["name"] == a["element"]:
|
|
584
608
|
a["name"] = None
|
|
609
|
+
|
|
585
610
|
return a
|
|
586
611
|
|
|
587
612
|
|
|
@@ -90,20 +90,27 @@ class Molecule(Base):
|
|
|
90
90
|
r"""
|
|
91
91
|
Calculate the angle between three atoms.
|
|
92
92
|
|
|
93
|
-
>>> Molecule.from_xyz("H 0 0 0\nO 0 0 1\nH 0 1 1").angle(
|
|
93
|
+
>>> Molecule.from_xyz("H 0 0 0\nO 0 0 1\nH 0 1 1").angle(1, 2, 3)
|
|
94
94
|
90.0
|
|
95
95
|
"""
|
|
96
96
|
|
|
97
|
-
return angle(self.coordinates[i], self.coordinates[j], self.coordinates[k], degrees=degrees)
|
|
97
|
+
return angle(self.coordinates[i - 1], self.coordinates[j - 1], self.coordinates[k - 1], degrees=degrees)
|
|
98
98
|
|
|
99
99
|
def dihedral(self, i: int, j: int, k: int, l: int, degrees: bool = True, positive_domain: bool = True) -> float:
|
|
100
100
|
r"""
|
|
101
101
|
Calculate the dihedral angle between four atoms.
|
|
102
102
|
|
|
103
|
-
>>> Molecule.from_xyz("H 0 0 0\nO 0 0 1\nO 0 1 1\nH 1 1 1").dihedral(
|
|
103
|
+
>>> Molecule.from_xyz("H 0 0 0\nO 0 0 1\nO 0 1 1\nH 1 1 1").dihedral(1, 2, 3, 4)
|
|
104
104
|
270.0
|
|
105
105
|
"""
|
|
106
|
-
return dihedral(
|
|
106
|
+
return dihedral(
|
|
107
|
+
self.coordinates[i - 1],
|
|
108
|
+
self.coordinates[j - 1],
|
|
109
|
+
self.coordinates[k - 1],
|
|
110
|
+
self.coordinates[l - 1],
|
|
111
|
+
degrees=degrees,
|
|
112
|
+
positive_domain=positive_domain,
|
|
113
|
+
)
|
|
107
114
|
|
|
108
115
|
@property
|
|
109
116
|
def coordinates(self) -> Vector3DPerAtom:
|
|
@@ -365,19 +372,17 @@ class Molecule(Base):
|
|
|
365
372
|
return cls(atoms=atoms, cell=cell, charge=charge, multiplicity=multiplicity, energy=energy, gradient=gradients)
|
|
366
373
|
|
|
367
374
|
@classmethod
|
|
368
|
-
def from_rdkit(cls: type[Self], rdkm: RdkitMol, cid: int = 0) -> Self:
|
|
375
|
+
def from_rdkit(cls: type[Self], rdkm: RdkitMol, cid: int = 0, multiplicity: int = 1) -> Self:
|
|
369
376
|
if len(rdkm.GetConformers()) == 0:
|
|
370
377
|
rdkm = _embed_rdkit_mol(rdkm)
|
|
371
378
|
|
|
372
|
-
atoms = []
|
|
373
379
|
atomic_numbers = [atom.GetAtomicNum() for atom in rdkm.GetAtoms()] # type: ignore [no-untyped-call, unused-ignore]
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
380
|
+
atoms = [
|
|
381
|
+
Atom(atomic_number=atom, position=xyz) # keep open
|
|
382
|
+
for atom, xyz in zip(atomic_numbers, rdkm.GetConformers()[cid].GetPositions(), strict=True)
|
|
383
|
+
]
|
|
378
384
|
|
|
379
385
|
charge = Chem.GetFormalCharge(rdkm)
|
|
380
|
-
multiplicity = 1
|
|
381
386
|
|
|
382
387
|
return cls(atoms=atoms, charge=charge, multiplicity=multiplicity)
|
|
383
388
|
|
|
@@ -7,10 +7,10 @@ from .workflow import MoleculeWorkflow
|
|
|
7
7
|
|
|
8
8
|
class HydrogenBondAcceptorSite(Base):
|
|
9
9
|
"""
|
|
10
|
-
A hydrogen
|
|
10
|
+
A hydrogen-bond-acceptor site.
|
|
11
11
|
|
|
12
12
|
:param atom_idx: index of the atom
|
|
13
|
-
:param pkbhx: Hydrogen
|
|
13
|
+
:param pkbhx: Hydrogen-bond basicity
|
|
14
14
|
:param position: position of the atom
|
|
15
15
|
:param name: name of the atom
|
|
16
16
|
"""
|
|
@@ -21,9 +21,23 @@ class HydrogenBondAcceptorSite(Base):
|
|
|
21
21
|
name: str | None = None
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class HydrogenBondDonorSite(Base):
|
|
25
|
+
"""
|
|
26
|
+
A hydrogen-bond-donor site.
|
|
27
|
+
|
|
28
|
+
:param atom_idx: index of the atom
|
|
29
|
+
:param pk_alpha: Hydrogen-bond acidity
|
|
30
|
+
:param position: position of the atom
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
atom_idx: int # zero-indexed
|
|
34
|
+
pk_alpha: float
|
|
35
|
+
position: tuple[float, float, float]
|
|
36
|
+
|
|
37
|
+
|
|
24
38
|
class HydrogenBondBasicityWorkflow(MoleculeWorkflow):
|
|
25
39
|
"""
|
|
26
|
-
Workflow for calculating hydrogen
|
|
40
|
+
Workflow for calculating hydrogen-bond basicity and acidity.
|
|
27
41
|
|
|
28
42
|
Inherited:
|
|
29
43
|
:param initial_molecule: Molecule of interest
|
|
@@ -36,6 +50,7 @@ class HydrogenBondBasicityWorkflow(MoleculeWorkflow):
|
|
|
36
50
|
Results:
|
|
37
51
|
:param optimization: UUID of optimization
|
|
38
52
|
:param hba_sites: hydrogen-bond-acceptor sites
|
|
53
|
+
:param hbd_sites: hydrogen-bond-donor sites
|
|
39
54
|
"""
|
|
40
55
|
|
|
41
56
|
do_csearch: bool = True
|
|
@@ -43,3 +58,4 @@ class HydrogenBondBasicityWorkflow(MoleculeWorkflow):
|
|
|
43
58
|
|
|
44
59
|
optimization: UUID | None = None
|
|
45
60
|
hba_sites: list[HydrogenBondAcceptorSite] = [] # noqa: RUF012
|
|
61
|
+
hbd_sites: list[HydrogenBondDonorSite] = [] # noqa: RUF012
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"""Multi-stage optimization workflow."""
|
|
2
2
|
|
|
3
|
+
import re
|
|
3
4
|
from typing import Self, Sequence
|
|
4
5
|
|
|
6
|
+
import more_itertools as mit
|
|
5
7
|
from pydantic import BaseModel, Field, model_validator
|
|
6
8
|
|
|
9
|
+
from stjames.correction import Correction
|
|
10
|
+
|
|
7
11
|
from ..constraint import Constraint
|
|
8
12
|
from ..method import XTB_METHODS, Method
|
|
9
13
|
from ..mode import Mode
|
|
10
14
|
from ..opt_settings import OptimizationSettings
|
|
11
15
|
from ..settings import Settings
|
|
12
|
-
from ..solvent import Solvent, SolventSettings
|
|
16
|
+
from ..solvent import Solvent, SolventModel, SolventSettings
|
|
13
17
|
from ..task import Task
|
|
14
18
|
from ..types import UUID
|
|
15
19
|
from .workflow import MoleculeWorkflow
|
|
@@ -264,6 +268,73 @@ class MultiStageOptMixin(BaseModel):
|
|
|
264
268
|
return self
|
|
265
269
|
|
|
266
270
|
|
|
271
|
+
def mso_settings_from_method_string(
|
|
272
|
+
methods: str,
|
|
273
|
+
solvent: Solvent | None = None,
|
|
274
|
+
use_solvent_for_opt: bool = False,
|
|
275
|
+
constraints: list[Constraint] | None = None,
|
|
276
|
+
transition_state: bool = False,
|
|
277
|
+
frequencies: bool = False,
|
|
278
|
+
) -> MultiStageOptSettings:
|
|
279
|
+
"""
|
|
280
|
+
Helper function to construct multi-stage opt settings objects from a method string.
|
|
281
|
+
|
|
282
|
+
>>> mso_settings_from_method_string("r2SCAN-3c/CPCM(Water)//B3LYP-D3/6-31G(d)/ALPB(Water)//GFN2-xTB/CPCM(Water)//GFN0-xTB").level_of_theory
|
|
283
|
+
'r2scan_3c/cpcm(water)//b3lyp-d3/6-31g(d)/alpb(water)//gfn2_xtb/cpcm(water)//gfn0_xtb'
|
|
284
|
+
"""
|
|
285
|
+
solvent_models = "|".join(model.name for model in SolventModel)
|
|
286
|
+
|
|
287
|
+
pattern = rf"""
|
|
288
|
+
(?P<method>[^/()]+) # Method + optional corrections
|
|
289
|
+
(?:/(?P<basis_set>(?!{solvent_models})[^/]+?))? # Optional basis_set, not starting with solvent model name
|
|
290
|
+
(?:/(?P<solvent_model>{solvent_models}) # Optional solvent model
|
|
291
|
+
\((?P<solvent>[^()]+)\))? # Solvent name in parentheses
|
|
292
|
+
(?:\/\/|$) # End or separator
|
|
293
|
+
"""
|
|
294
|
+
constraints = constraints or []
|
|
295
|
+
opt_settings = OptimizationSettings(constraints=constraints, transition_state=transition_state)
|
|
296
|
+
OPT = [Task.OPTIMIZE if not transition_state else Task.OPTIMIZE_TS]
|
|
297
|
+
|
|
298
|
+
valid_corrections = {c.name.lower() for c in Correction} # Python3.11 hack
|
|
299
|
+
|
|
300
|
+
def process(match: re.Match[str]) -> Settings:
|
|
301
|
+
data = match.groupdict()
|
|
302
|
+
|
|
303
|
+
method, corrections = mit.partition(lambda x: x.lower() in valid_corrections, data["method"].split("-"))
|
|
304
|
+
solvent_settings = SolventSettings(solvent=data["solvent"], model=data["solvent_model"]) if data["solvent"] else None
|
|
305
|
+
|
|
306
|
+
return Settings(
|
|
307
|
+
method="-".join(method),
|
|
308
|
+
basis_set=data["basis_set"],
|
|
309
|
+
tasks=OPT,
|
|
310
|
+
solvent_settings=solvent_settings,
|
|
311
|
+
opt_settings=opt_settings,
|
|
312
|
+
corrections=list(corrections),
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
optimization_settings = [process(match) for match in re.finditer(pattern, methods, re.VERBOSE | re.IGNORECASE)]
|
|
316
|
+
if len(optimization_settings) > 1:
|
|
317
|
+
sp_settings = optimization_settings.pop(0)
|
|
318
|
+
sp_settings.tasks = [Task.ENERGY]
|
|
319
|
+
else:
|
|
320
|
+
sp_settings = None
|
|
321
|
+
|
|
322
|
+
optimization_settings = optimization_settings[::-1]
|
|
323
|
+
if frequencies:
|
|
324
|
+
optimization_settings[-1].tasks.append(Task.FREQUENCIES)
|
|
325
|
+
|
|
326
|
+
return MultiStageOptSettings(
|
|
327
|
+
mode=Mode.MANUAL,
|
|
328
|
+
optimization_settings=optimization_settings,
|
|
329
|
+
singlepoint_settings=sp_settings,
|
|
330
|
+
solvent=solvent,
|
|
331
|
+
xtb_preopt=False,
|
|
332
|
+
constraints=constraints,
|
|
333
|
+
transition_state=transition_state,
|
|
334
|
+
frequencies=frequencies,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
267
338
|
def build_mso_settings(
|
|
268
339
|
sp_method: Method,
|
|
269
340
|
sp_basis_set: str | None,
|
|
@@ -12,6 +12,7 @@ class CofoldingModel(LowercaseStrEnum):
|
|
|
12
12
|
|
|
13
13
|
CHAI_1R = "chai_1r"
|
|
14
14
|
BOLTZ_1 = "boltz_1"
|
|
15
|
+
BOLTZ_2 = "boltz_2"
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class CofoldingScores(BaseModel):
|
|
@@ -20,6 +21,15 @@ class CofoldingScores(BaseModel):
|
|
|
20
21
|
iptm: float # interface predicted template modeling score
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
class AffinityScore(BaseModel):
|
|
25
|
+
pred_value: float
|
|
26
|
+
probability_binary: float
|
|
27
|
+
pred_value1: float
|
|
28
|
+
probability_binary1: float
|
|
29
|
+
pred_value2: float
|
|
30
|
+
probability_binary2: float
|
|
31
|
+
|
|
32
|
+
|
|
23
33
|
class ProteinCofoldingWorkflow(FASTAWorkflow):
|
|
24
34
|
"""
|
|
25
35
|
A workflow for predicting structures. Especially protein structures.
|
|
@@ -36,6 +46,8 @@ class ProteinCofoldingWorkflow(FASTAWorkflow):
|
|
|
36
46
|
|
|
37
47
|
use_msa_server: bool = False
|
|
38
48
|
use_templates_server: bool = False
|
|
49
|
+
use_potentials: bool = False
|
|
39
50
|
predicted_structure_uuid: UUID | None = None
|
|
40
51
|
scores: CofoldingScores | None = None
|
|
41
|
-
model: CofoldingModel = CofoldingModel.
|
|
52
|
+
model: CofoldingModel = CofoldingModel.BOLTZ_2
|
|
53
|
+
affinity_score: AffinityScore | None = None
|
|
@@ -32,6 +32,7 @@ class FASTAWorkflow(Workflow):
|
|
|
32
32
|
|
|
33
33
|
initial_protein_sequences: list[str]
|
|
34
34
|
initial_smiles_list: list[str] | None = None
|
|
35
|
+
ligand_binding_affinity_index: int | None = None
|
|
35
36
|
|
|
36
37
|
def __repr__(self) -> str:
|
|
37
38
|
return f"<{type(self).__name__} {self.initial_protein_sequences} {self.initial_smiles_list}>"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stjames
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.79
|
|
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
|
|
@@ -12,6 +12,7 @@ Requires-Dist: pydantic>=2.4
|
|
|
12
12
|
Requires-Dist: numpy
|
|
13
13
|
Requires-Dist: requests
|
|
14
14
|
Requires-Dist: rdkit
|
|
15
|
+
Requires-Dist: more-itertools
|
|
15
16
|
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
# stjames
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|