rowan-python 2.1.16__py3-none-any.whl → 3.0.1__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.
Files changed (55) hide show
  1. rowan/__init__.py +24 -1
  2. rowan/calculation.py +112 -0
  3. rowan/config.py +680 -0
  4. rowan/folder.py +57 -16
  5. rowan/molecule.py +268 -0
  6. rowan/project.py +36 -9
  7. rowan/protein.py +155 -26
  8. rowan/rowan_rdkit/__init__.py +0 -15
  9. rowan/rowan_rdkit/chem_utils.py +68 -61
  10. rowan/types.py +15 -0
  11. rowan/user.py +66 -1
  12. rowan/utils.py +14 -3
  13. rowan/workflows/__init__.py +123 -0
  14. rowan/workflows/admet.py +72 -0
  15. rowan/workflows/analogue_docking.py +223 -0
  16. rowan/workflows/base.py +779 -0
  17. rowan/workflows/basic_calculation.py +263 -0
  18. rowan/workflows/batch_docking.py +96 -0
  19. rowan/workflows/bde.py +172 -0
  20. rowan/workflows/conformer_search.py +202 -0
  21. rowan/workflows/constants.py +19 -0
  22. rowan/workflows/descriptors.py +69 -0
  23. rowan/workflows/docking.py +207 -0
  24. rowan/workflows/double_ended_ts_search.py +202 -0
  25. rowan/workflows/electronic_properties.py +191 -0
  26. rowan/workflows/fukui.py +122 -0
  27. rowan/workflows/hydrogen_bond_donor_acceptor_strength.py +140 -0
  28. rowan/workflows/interaction_energy_decomposition.py +152 -0
  29. rowan/workflows/ion_mobility.py +99 -0
  30. rowan/workflows/irc.py +203 -0
  31. rowan/workflows/macropka.py +165 -0
  32. rowan/workflows/membrane_permeability.py +130 -0
  33. rowan/workflows/msa.py +135 -0
  34. rowan/workflows/multistage_optimization.py +175 -0
  35. rowan/workflows/nmr.py +154 -0
  36. rowan/workflows/pka.py +203 -0
  37. rowan/workflows/pose_analysis_md.py +244 -0
  38. rowan/workflows/protein_binder_design.py +204 -0
  39. rowan/workflows/protein_cofolding.py +325 -0
  40. rowan/workflows/protein_md.py +182 -0
  41. rowan/workflows/rbfe_graph.py +152 -0
  42. rowan/workflows/redox_potential.py +143 -0
  43. rowan/workflows/relative_binding_free_energy_perturbation.py +322 -0
  44. rowan/workflows/scan.py +159 -0
  45. rowan/workflows/solubility.py +231 -0
  46. rowan/workflows/solvent_dependent_conformers.py +178 -0
  47. rowan/workflows/spin_states.py +193 -0
  48. rowan/workflows/strain.py +165 -0
  49. rowan/workflows/tautomer_search.py +151 -0
  50. {rowan_python-2.1.16.dist-info → rowan_python-3.0.1.dist-info}/METADATA +3 -3
  51. rowan_python-3.0.1.dist-info/RECORD +55 -0
  52. {rowan_python-2.1.16.dist-info → rowan_python-3.0.1.dist-info}/WHEEL +1 -1
  53. rowan/workflow.py +0 -2230
  54. rowan_python-2.1.16.dist-info/RECORD +0 -15
  55. {rowan_python-2.1.16.dist-info → rowan_python-3.0.1.dist-info}/licenses/LICENSE +0 -0
rowan/__init__.py CHANGED
@@ -1,8 +1,31 @@
1
1
  # ruff: noqa
2
2
  from . import constants
3
+ from stjames import (
4
+ Constraint,
5
+ ConstraintType,
6
+ Correction,
7
+ Engine,
8
+ Method,
9
+ Mode,
10
+ OptimizationSettings,
11
+ Settings,
12
+ SolventSettings,
13
+ Task,
14
+ )
15
+ from stjames.optimization.freezing_string_method import (
16
+ FSMInterpolation,
17
+ FSMOptimizationCoordinates,
18
+ FSMSettings,
19
+ )
3
20
 
21
+ api_key: str | None = None
22
+ project_uuid: str | None = None
23
+
24
+ from .calculation import *
4
25
  from .folder import *
5
- from .workflow import *
26
+ from .molecule import *
27
+ from .types import RdkitMol, StJamesMolecule
28
+ from .workflows import *
6
29
  from .project import *
7
30
  from .protein import *
8
31
  from .user import *
rowan/calculation.py ADDED
@@ -0,0 +1,112 @@
1
+ """Calculation results from Rowan workflows."""
2
+
3
+ from typing import Self
4
+
5
+ import stjames
6
+ from pydantic import BaseModel, ConfigDict, Field
7
+
8
+ from .molecule import Molecule
9
+ from .utils import api_client
10
+
11
+
12
+ def _parse_molecules(data: list[dict]) -> list[Molecule]:
13
+ """Parse molecule dicts into Molecule objects."""
14
+ return [Molecule.from_stjames(stjames.Molecule.model_validate(m)) for m in data]
15
+
16
+
17
+ class Calculation(BaseModel):
18
+ """
19
+ Rowan calculation result.
20
+
21
+ :param uuid: UUID of the calculation.
22
+ :param name: Name of the calculation.
23
+ :param status: Status code of the calculation.
24
+ :param elapsed: Execution time in seconds.
25
+ :param engine: Compute engine used.
26
+ :param molecules: Molecules (geometries) from this calculation.
27
+ """
28
+
29
+ uuid: str
30
+ name: str | None = None
31
+ status: int | None = None
32
+ elapsed: float | None = None
33
+ engine: str | None = None
34
+ molecules: list[Molecule] = Field(default_factory=list)
35
+
36
+ model_config = ConfigDict(arbitrary_types_allowed=True)
37
+
38
+ def __repr__(self) -> str:
39
+ n_mols = len(self.molecules)
40
+ energy = self.energy
41
+ e_str = f"{energy:.6f}" if energy is not None else "None"
42
+ return f"<Calculation energy={e_str} molecules={n_mols} uuid='{self.uuid}'>"
43
+
44
+ @property
45
+ def energy(self) -> float | None:
46
+ """Energy of the final molecule (Hartree)."""
47
+ if self.molecules:
48
+ return self.molecules[-1].energy
49
+ return None
50
+
51
+ @property
52
+ def molecule(self) -> Molecule | None:
53
+ """Final molecule geometry."""
54
+ if self.molecules:
55
+ return self.molecules[-1]
56
+ return None
57
+
58
+ def refresh(self, in_place: bool = True) -> Self:
59
+ """
60
+ Fetch the latest calculation data from the API.
61
+
62
+ :param in_place: If True, update this instance in-place. If False, return new instance.
63
+ :returns: Updated Calculation object.
64
+ """
65
+ with api_client() as client:
66
+ response = client.get(f"/calculation/{self.uuid}/stjames")
67
+ response.raise_for_status()
68
+ data = response.json()
69
+
70
+ molecules = _parse_molecules(data.get("molecules", []))
71
+
72
+ if not in_place:
73
+ return self.__class__(
74
+ uuid=self.uuid,
75
+ name=data.get("name"),
76
+ status=data.get("status"),
77
+ elapsed=data.get("elapsed"),
78
+ engine=data.get("engine"),
79
+ molecules=molecules,
80
+ )
81
+
82
+ self.name = data.get("name")
83
+ self.status = data.get("status")
84
+ self.elapsed = data.get("elapsed")
85
+ self.engine = data.get("engine")
86
+ self.molecules = molecules
87
+ return self
88
+
89
+
90
+ def retrieve_calculation(uuid: str) -> Calculation:
91
+ """
92
+ Retrieve a calculation from the API by UUID.
93
+
94
+ :param uuid: UUID of the calculation to retrieve.
95
+ :returns: Calculation object with the fetched data.
96
+ :raises requests.HTTPError: If the API request fails.
97
+ """
98
+ with api_client() as client:
99
+ response = client.get(f"/calculation/{uuid}/stjames")
100
+ response.raise_for_status()
101
+ data = response.json()
102
+
103
+ molecules = _parse_molecules(data.get("molecules", []))
104
+
105
+ return Calculation(
106
+ uuid=uuid,
107
+ name=data.get("name"),
108
+ status=data.get("status"),
109
+ elapsed=data.get("elapsed"),
110
+ engine=data.get("engine"),
111
+ molecules=molecules,
112
+ )