rowan-python 3.0.5__py3-none-any.whl → 3.0.7__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.
- rowan/molecule.py +24 -16
- rowan/protein.py +2 -1
- rowan/workflows/__init__.py +1 -0
- rowan/workflows/electronic_properties.py +11 -1
- rowan/workflows/pka.py +11 -3
- rowan/workflows/pocket_detection.py +112 -0
- {rowan_python-3.0.5.dist-info → rowan_python-3.0.7.dist-info}/METADATA +1 -1
- {rowan_python-3.0.5.dist-info → rowan_python-3.0.7.dist-info}/RECORD +10 -9
- {rowan_python-3.0.5.dist-info → rowan_python-3.0.7.dist-info}/WHEEL +0 -0
- {rowan_python-3.0.5.dist-info → rowan_python-3.0.7.dist-info}/licenses/LICENSE +0 -0
rowan/molecule.py
CHANGED
|
@@ -52,28 +52,36 @@ class Molecule(BaseModel):
|
|
|
52
52
|
return cls(_stjames=stjames.Molecule.from_smiles(smiles))
|
|
53
53
|
|
|
54
54
|
@classmethod
|
|
55
|
-
def from_xyz(
|
|
55
|
+
def from_xyz(
|
|
56
|
+
cls, xyz_string: str, charge: int | None = None, multiplicity: int | None = None
|
|
57
|
+
) -> Self:
|
|
56
58
|
"""
|
|
57
|
-
Create
|
|
59
|
+
Create Molecule from XYZ string.
|
|
58
60
|
|
|
59
|
-
:param xyz_string: XYZ format string
|
|
60
|
-
:param charge:
|
|
61
|
-
:param multiplicity:
|
|
62
|
-
:returns: Molecule
|
|
61
|
+
:param xyz_string: XYZ format string
|
|
62
|
+
:param charge: charge
|
|
63
|
+
:param multiplicity: spin multiplicity
|
|
64
|
+
:returns: Molecule
|
|
63
65
|
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
return cls(
|
|
67
|
+
_stjames=stjames.Molecule.from_xyz(
|
|
68
|
+
xyz_string,
|
|
69
|
+
charge=charge,
|
|
70
|
+
multiplicity=multiplicity,
|
|
71
|
+
)
|
|
72
|
+
)
|
|
67
73
|
|
|
68
74
|
@classmethod
|
|
69
|
-
def from_xyz_file(
|
|
75
|
+
def from_xyz_file(
|
|
76
|
+
cls, path: str | Path, charge: int | None = None, multiplicity: int | None = None
|
|
77
|
+
) -> Self:
|
|
70
78
|
"""
|
|
71
79
|
Create molecule from XYZ file.
|
|
72
80
|
|
|
73
|
-
:param path:
|
|
74
|
-
:param charge:
|
|
75
|
-
:param multiplicity:
|
|
76
|
-
:returns: Molecule
|
|
81
|
+
:param path: path to XYZ file
|
|
82
|
+
:param charge: charge
|
|
83
|
+
:param multiplicity: spin multiplicity
|
|
84
|
+
:returns: Molecule
|
|
77
85
|
"""
|
|
78
86
|
return cls.from_xyz(Path(path).read_text(), charge=charge, multiplicity=multiplicity)
|
|
79
87
|
|
|
@@ -82,8 +90,8 @@ class Molecule(BaseModel):
|
|
|
82
90
|
"""
|
|
83
91
|
Create from stjames.Molecule.
|
|
84
92
|
|
|
85
|
-
:param stj: stjames.Molecule
|
|
86
|
-
:returns: Molecule
|
|
93
|
+
:param stj: stjames.Molecule
|
|
94
|
+
:returns: Molecule
|
|
87
95
|
"""
|
|
88
96
|
return cls(_stjames=stj)
|
|
89
97
|
|
rowan/protein.py
CHANGED
|
@@ -305,7 +305,7 @@ def list_proteins(
|
|
|
305
305
|
|
|
306
306
|
|
|
307
307
|
def upload_protein(
|
|
308
|
-
name: str, file_path: Path, project_uuid: str | Project | None = None
|
|
308
|
+
name: str, file_path: str | Path, project_uuid: str | Project | None = None
|
|
309
309
|
) -> Protein:
|
|
310
310
|
"""
|
|
311
311
|
Uploads a protein from a PDB file to the API.
|
|
@@ -315,6 +315,7 @@ def upload_protein(
|
|
|
315
315
|
:returns: Protein object representing the uploaded protein
|
|
316
316
|
:raises requests.HTTPError: if the request to the API fails
|
|
317
317
|
"""
|
|
318
|
+
file_path = Path(file_path)
|
|
318
319
|
if isinstance(project_uuid, Project):
|
|
319
320
|
project_uuid = project_uuid.uuid
|
|
320
321
|
with api_client() as client:
|
rowan/workflows/__init__.py
CHANGED
|
@@ -84,6 +84,7 @@ from .multistage_optimization import (
|
|
|
84
84
|
)
|
|
85
85
|
from .nmr import NMRPeak, NMRResult, submit_nmr_workflow
|
|
86
86
|
from .pka import pKaMicrostate, pKaResult, submit_pka_workflow
|
|
87
|
+
from .pocket_detection import Pocket, PocketDetectionResult, submit_pocket_detection_workflow
|
|
87
88
|
from .pose_analysis_md import PoseAnalysisMDResult, submit_pose_analysis_md_workflow
|
|
88
89
|
from .protein_binder_design import (
|
|
89
90
|
ProteinBinder,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
import stjames
|
|
6
|
+
from stjames import ENGINE_METHODS, Engine, Method
|
|
6
7
|
|
|
7
8
|
from ..folder import Folder
|
|
8
9
|
from ..types import MoleculeInput
|
|
@@ -155,6 +156,7 @@ def submit_electronic_properties_workflow(
|
|
|
155
156
|
:param webhook_url: URL that Rowan will POST to when the workflow completes.
|
|
156
157
|
:param is_draft: If True, submit the workflow as a draft without starting execution.
|
|
157
158
|
:returns: Workflow object representing the submitted workflow.
|
|
159
|
+
:raises ValueError: If the method is not supported by the psi4 engine.
|
|
158
160
|
:raises requests.HTTPError: if the request to the API fails.
|
|
159
161
|
"""
|
|
160
162
|
if folder and folder_uuid:
|
|
@@ -164,7 +166,15 @@ def submit_electronic_properties_workflow(
|
|
|
164
166
|
initial_molecule = molecule_to_dict(initial_molecule)
|
|
165
167
|
|
|
166
168
|
if isinstance(method, str):
|
|
167
|
-
method =
|
|
169
|
+
method = Method(method)
|
|
170
|
+
|
|
171
|
+
supported_methods = ENGINE_METHODS[Engine.PSI4]
|
|
172
|
+
if method not in supported_methods:
|
|
173
|
+
supported_names = sorted(m.value for m in supported_methods)
|
|
174
|
+
raise ValueError(
|
|
175
|
+
f"Method '{method.value}' is not supported by the psi4 engine. "
|
|
176
|
+
f"Supported methods: {', '.join(supported_names)}"
|
|
177
|
+
)
|
|
168
178
|
|
|
169
179
|
settings = stjames.Settings(method=method, basis_set=basis_set)
|
|
170
180
|
|
rowan/workflows/pka.py
CHANGED
|
@@ -183,13 +183,21 @@ def submit_pka_workflow(
|
|
|
183
183
|
)
|
|
184
184
|
if method in _PKA_SMILES_METHODS and not initial_smiles:
|
|
185
185
|
raise ValueError(
|
|
186
|
-
f"{method} requires a SMILES string. "
|
|
187
|
-
"Provide a SMILES string, not a 3D structure."
|
|
186
|
+
f"{method} requires a SMILES string. Provide a SMILES string, not a 3D structure."
|
|
188
187
|
)
|
|
189
188
|
if method in _PKA_WATER_ONLY_METHODS and solvent != "water":
|
|
190
189
|
raise ValueError(f"{method} only supports water as solvent.")
|
|
191
190
|
|
|
192
|
-
|
|
191
|
+
if method == "chemprop_nevolianis2025" and protonate_elements:
|
|
192
|
+
raise ValueError(
|
|
193
|
+
"chemprop_nevolianis2025 was only trained on deprotonation data; "
|
|
194
|
+
"protonation is disabled. Leave `protonate_elements` unset or pass []."
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if method == "chemprop_nevolianis2025":
|
|
198
|
+
protonate_elements = []
|
|
199
|
+
else:
|
|
200
|
+
protonate_elements = protonate_elements or [7]
|
|
193
201
|
deprotonate_elements = deprotonate_elements or [7, 8, 16]
|
|
194
202
|
|
|
195
203
|
workflow = stjames.pKaWorkflow(
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Pocket detection workflow - detect potential binding sites on a protein."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
import stjames
|
|
6
|
+
|
|
7
|
+
from ..folder import Folder
|
|
8
|
+
from ..protein import Protein
|
|
9
|
+
from ..utils import api_client
|
|
10
|
+
from .base import Workflow, WorkflowResult, register_result
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True, slots=True)
|
|
14
|
+
class Pocket:
|
|
15
|
+
"""
|
|
16
|
+
A detected binding pocket.
|
|
17
|
+
|
|
18
|
+
:param sphere_centers: centers of detected spheres, in Å
|
|
19
|
+
:param sphere_radii: radii of detected spheres, in Å
|
|
20
|
+
:param volume: pocket volume, in ų
|
|
21
|
+
:param score: druggability/quality score; larger is better
|
|
22
|
+
:param pocket_center: center of axis-aligned bounding box, in Å
|
|
23
|
+
:param pocket_sides: side lengths of axis-aligned bounding box, in Å
|
|
24
|
+
:param residue_numbers: residue numbers lining the pocket
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
sphere_centers: tuple[tuple[float, float, float], ...]
|
|
28
|
+
sphere_radii: tuple[float, ...]
|
|
29
|
+
volume: float
|
|
30
|
+
score: float
|
|
31
|
+
pocket_center: tuple[float, float, float]
|
|
32
|
+
pocket_sides: tuple[float, float, float]
|
|
33
|
+
residue_numbers: tuple[int, ...]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@register_result("pocket_detection")
|
|
37
|
+
class PocketDetectionResult(WorkflowResult):
|
|
38
|
+
"""Result from a pocket-detection workflow."""
|
|
39
|
+
|
|
40
|
+
_stjames_class = stjames.PocketDetectionWorkflow
|
|
41
|
+
|
|
42
|
+
def __repr__(self) -> str:
|
|
43
|
+
return f"<PocketDetectionResult pockets={len(self.pockets)}>"
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def pockets(self) -> list[Pocket]:
|
|
47
|
+
"""Detected pockets, in the order returned by the backend."""
|
|
48
|
+
raw = getattr(self._workflow, "pockets", []) or []
|
|
49
|
+
return [
|
|
50
|
+
Pocket(
|
|
51
|
+
sphere_centers=tuple(tuple(c) for c in p.sphere_centers),
|
|
52
|
+
sphere_radii=tuple(p.sphere_radii),
|
|
53
|
+
volume=p.volume,
|
|
54
|
+
score=p.score,
|
|
55
|
+
pocket_center=tuple(p.pocket_center),
|
|
56
|
+
pocket_sides=tuple(p.pocket_sides),
|
|
57
|
+
residue_numbers=tuple(p.residue_numbers),
|
|
58
|
+
)
|
|
59
|
+
for p in raw
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def submit_pocket_detection_workflow(
|
|
64
|
+
protein: str | Protein,
|
|
65
|
+
merge_distance: float = 1.75,
|
|
66
|
+
name: str = "Pocket Detection Workflow",
|
|
67
|
+
folder_uuid: str | None = None,
|
|
68
|
+
folder: Folder | None = None,
|
|
69
|
+
max_credits: int | None = None,
|
|
70
|
+
webhook_url: str | None = None,
|
|
71
|
+
is_draft: bool = False,
|
|
72
|
+
) -> Workflow:
|
|
73
|
+
"""
|
|
74
|
+
Submits a pocket-detection workflow to the API.
|
|
75
|
+
|
|
76
|
+
:param protein: protein to analyze. Can be a UUID or a Protein object.
|
|
77
|
+
:param merge_distance: distance for merging pocket spheres, in Å
|
|
78
|
+
:param name: name of the workflow
|
|
79
|
+
:param folder_uuid: UUID of the folder to place the workflow in
|
|
80
|
+
:param folder: Folder object to store the workflow in
|
|
81
|
+
:param max_credits: maximum number of credits to use for the workflow
|
|
82
|
+
:param webhook_url: URL that Rowan will POST to when the workflow completes
|
|
83
|
+
:param is_draft: if True, submit the workflow as a draft without starting execution
|
|
84
|
+
:returns: Workflow object representing the submitted workflow
|
|
85
|
+
:raises requests.HTTPError: if the request to the API fails
|
|
86
|
+
"""
|
|
87
|
+
if folder and folder_uuid:
|
|
88
|
+
raise ValueError("Provide either `folder` or `folder_uuid`, not both.")
|
|
89
|
+
if folder:
|
|
90
|
+
folder_uuid = folder.uuid
|
|
91
|
+
if isinstance(protein, Protein):
|
|
92
|
+
protein = protein.uuid
|
|
93
|
+
|
|
94
|
+
workflow = stjames.PocketDetectionWorkflow(
|
|
95
|
+
protein=protein,
|
|
96
|
+
merge_distance=merge_distance,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
data = {
|
|
100
|
+
"workflow_type": "pocket_detection",
|
|
101
|
+
"workflow_data": workflow.model_dump(mode="json"),
|
|
102
|
+
"name": name,
|
|
103
|
+
"folder_uuid": folder_uuid,
|
|
104
|
+
"max_credits": max_credits,
|
|
105
|
+
"webhook_url": webhook_url,
|
|
106
|
+
"is_draft": is_draft,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
with api_client() as client:
|
|
110
|
+
response = client.post("/workflow", json=data)
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
return Workflow(**response.json())
|
|
@@ -3,16 +3,16 @@ rowan/calculation.py,sha256=lZZ52DxPsuJWCTzFZXjhauHK6dV0KCUwzoxtmoxSY48,3442
|
|
|
3
3
|
rowan/config.py,sha256=3cVKHUNzkIPnN2bvx7l5sia7Zc5poXS8lKOJlowXyLA,21088
|
|
4
4
|
rowan/constants.py,sha256=emCH4m9OL2Hm5E-6mJGM_FgzrK_JrZT-FiKJ6pMNQ4Y,84
|
|
5
5
|
rowan/folder.py,sha256=NkimVeHho9nwRXeS87U1tivEVL-1gL2Vqfz1fJ6XpNQ,9222
|
|
6
|
-
rowan/molecule.py,sha256=
|
|
6
|
+
rowan/molecule.py,sha256=KQJhbNF2vmR8okBduXVqG7qG3LXbABLKHanpNhA-0TY,10003
|
|
7
7
|
rowan/project.py,sha256=Wy3VvhwIMIumAZD2s7hPk8jj4bAPHMDNvsqU23RRqFo,4598
|
|
8
|
-
rowan/protein.py,sha256=
|
|
8
|
+
rowan/protein.py,sha256=jyOM6g5eQH6KO8Eq07AiYBv2vZsGfbNOdtNOb2NWHFc,14799
|
|
9
9
|
rowan/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
rowan/types.py,sha256=rCAnUlCsemyBK9Bbus0pL-THoqNqJIQHaMoDferIfFU,471
|
|
11
11
|
rowan/user.py,sha256=Tnwz1-u_92ACt1xATQegtMj3FcosFsAG4m-4YuAkiyg,5955
|
|
12
12
|
rowan/utils.py,sha256=c1s6Ze-OqLtfvrD23OV60otskejmj-CD88nNf8_nFcw,3636
|
|
13
13
|
rowan/rowan_rdkit/__init__.py,sha256=EATX2VRzywzKxqkpCUMTf7RNQLkWsfi5VcCNDW6EIiw,503
|
|
14
14
|
rowan/rowan_rdkit/chem_utils.py,sha256=ZWdLziT59Qr5JzjvV789CAyRq0m5JIawsOP4RxUbQQA,35529
|
|
15
|
-
rowan/workflows/__init__.py,sha256=
|
|
15
|
+
rowan/workflows/__init__.py,sha256=UTkqcsqtANh9TtaYXwOSYmTOvzR9ucQ_xhDupAFHROI,4351
|
|
16
16
|
rowan/workflows/admet.py,sha256=0_wIwXXLfHF-3kgGx_1EM1ljjaYHLeEijJ-GbMYxpL8,2904
|
|
17
17
|
rowan/workflows/analogue_docking.py,sha256=LJpbbaug0tZ9Cg-m0b7EgGH5hJ5894fHOC16Wefx7mE,9206
|
|
18
18
|
rowan/workflows/base.py,sha256=eLGyzTc9NpXBGC-FRjsaUwKP6RluWrz0ipDZ4jDY_jc,30103
|
|
@@ -24,7 +24,7 @@ rowan/workflows/constants.py,sha256=el8jWE9gnGTLNWn5_n_V0H362vIRneOqgy7BOQ8CScg,
|
|
|
24
24
|
rowan/workflows/descriptors.py,sha256=rGrNca6kA4SzX5BAOjP6rE91MOLTvCWSYKF_LW2Z0y4,2963
|
|
25
25
|
rowan/workflows/docking.py,sha256=wmE7QJu1uDHBDynTT1XesXXAZtpB6xLjZUKsHOQyCcU,7386
|
|
26
26
|
rowan/workflows/double_ended_ts_search.py,sha256=abBblMkshhbzq5UTwIf-ovNFxY8Ltp2O-bGu_plkI58,7806
|
|
27
|
-
rowan/workflows/electronic_properties.py,sha256=
|
|
27
|
+
rowan/workflows/electronic_properties.py,sha256=2L0BUvhx0iT0k4gQf7hbceCpatznT2xui7rs6lpME7k,7564
|
|
28
28
|
rowan/workflows/fukui.py,sha256=wLimH3QmorSpvkovRPlI91VuxHG4J91F2EcLYqg3eP0,5112
|
|
29
29
|
rowan/workflows/hydrogen_bond_donor_acceptor_strength.py,sha256=WWiEK_GlumIEgTTOaqw-Y5gPDkRkaePWcIjTdIocrPc,4916
|
|
30
30
|
rowan/workflows/interaction_energy_decomposition.py,sha256=Kjwkb-pviFSFIIZNjMb9i8nAkdKrbjFftmG_lkYtE40,6120
|
|
@@ -35,7 +35,8 @@ rowan/workflows/membrane_permeability.py,sha256=oIDmB8qF_K_Kesv7o_FiljAk4dpptEeO
|
|
|
35
35
|
rowan/workflows/msa.py,sha256=V3B1SyWPR8MT306hh9W-T9JTpi_E-XgAIeF9yRQZ7tI,5075
|
|
36
36
|
rowan/workflows/multistage_optimization.py,sha256=HFVx8mnHxG97pDYyL6eOhNGmESqTxaKNgUdwrFpFUJ0,6456
|
|
37
37
|
rowan/workflows/nmr.py,sha256=hergJdsiawKj7iV-jHxDOS03n_EnZcaCIt_ZTl34-JY,5183
|
|
38
|
-
rowan/workflows/pka.py,sha256=
|
|
38
|
+
rowan/workflows/pka.py,sha256=TCFSE5HI5JLPslKdbUvJe4IxrVaLExrI_3PnDfXtxTw,8691
|
|
39
|
+
rowan/workflows/pocket_detection.py,sha256=aGHY0puxekp4c4nsNYHcvKCe1fsetygL04BcSvNFvE8,3864
|
|
39
40
|
rowan/workflows/pose_analysis_md.py,sha256=UvotLhWv0_VAkKteZboOutDry7l-Zt1K6_SBx3EXqgM,9530
|
|
40
41
|
rowan/workflows/protein_binder_design.py,sha256=J-9NSbRLdHb6JQRhY_vq43HlHCDCiQqrkOZUCAF-2dk,8604
|
|
41
42
|
rowan/workflows/protein_cofolding.py,sha256=1R29XjAVjWHyelGG-mylP2GIamZbLCQKaaaFsCAnYgI,13012
|
|
@@ -49,7 +50,7 @@ rowan/workflows/solvent_dependent_conformers.py,sha256=ovvnhCE4xlkpdhccLHEq7oBJR
|
|
|
49
50
|
rowan/workflows/spin_states.py,sha256=GZgBJPO6_ds9el4b7wbigIZ5213Z9DwXhokczJ5NDhs,7122
|
|
50
51
|
rowan/workflows/strain.py,sha256=r0tlZoUlAslAiF7dPTpa9WlQFUAKyVjZ19zASjSS8Hs,6339
|
|
51
52
|
rowan/workflows/tautomer_search.py,sha256=aqwXoj0ffWsb5gbvzfz_bpx5ifIfR_K07fbdWhU62Ko,5820
|
|
52
|
-
rowan_python-3.0.
|
|
53
|
-
rowan_python-3.0.
|
|
54
|
-
rowan_python-3.0.
|
|
55
|
-
rowan_python-3.0.
|
|
53
|
+
rowan_python-3.0.7.dist-info/METADATA,sha256=-sirW_Q74BeqsjNRR4wAWYoV8ebpuNLzc6-8FrgOKRs,1600
|
|
54
|
+
rowan_python-3.0.7.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
55
|
+
rowan_python-3.0.7.dist-info/licenses/LICENSE,sha256=i05z7xEhyrg6f8j0lR3XYjShnF-MJGFQ-DnpsZ8yiVI,1084
|
|
56
|
+
rowan_python-3.0.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|