rowan-python 3.2.3__tar.gz → 3.2.4__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.
Files changed (278) hide show
  1. {rowan_python-3.2.3 → rowan_python-3.2.4}/PKG-INFO +2 -2
  2. rowan_python-3.2.4/examples/mixmd_pocket_detection.py +41 -0
  3. {rowan_python-3.2.3 → rowan_python-3.2.4}/pyproject.toml +2 -2
  4. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/__init__.py +5 -1
  5. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/user.py +1 -3
  6. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/__init__.py +8 -1
  7. rowan_python-3.2.4/rowan/workflows/pocket_detection.py +253 -0
  8. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/protein_md.py +7 -1
  9. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/protein_preparation.py +4 -0
  10. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/relative_binding_free_energy_perturbation.py +17 -4
  11. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/SKILL.md +1 -1
  12. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/pocket_detection.md +9 -4
  13. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/protein_md.md +43 -1
  14. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/protein_preparation.md +1 -0
  15. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/relative_binding_free_energy_perturbation.md +2 -1
  16. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_md_workflow_updates.py +42 -0
  17. rowan_python-3.2.4/tests/test_pocket_detection.py +141 -0
  18. rowan_python-3.2.4/tests/test_rbfe_submission.py +80 -0
  19. rowan_python-3.2.4/tests/test_user.py +22 -0
  20. {rowan_python-3.2.3 → rowan_python-3.2.4}/uv.lock +83 -78
  21. rowan_python-3.2.3/rowan/workflows/pocket_detection.py +0 -118
  22. {rowan_python-3.2.3 → rowan_python-3.2.4}/.claude-plugin/marketplace.json +0 -0
  23. {rowan_python-3.2.3 → rowan_python-3.2.4}/.codex-plugin/plugin.json +0 -0
  24. {rowan_python-3.2.3 → rowan_python-3.2.4}/.editorconfig +0 -0
  25. {rowan_python-3.2.3 → rowan_python-3.2.4}/.envrc +0 -0
  26. {rowan_python-3.2.3 → rowan_python-3.2.4}/.github/workflows/build-and-deploy-docs.yml +0 -0
  27. {rowan_python-3.2.3 → rowan_python-3.2.4}/.github/workflows/publish-skill.yml +0 -0
  28. {rowan_python-3.2.3 → rowan_python-3.2.4}/.github/workflows/python-publish.yml +0 -0
  29. {rowan_python-3.2.3 → rowan_python-3.2.4}/.github/workflows/test.yml +0 -0
  30. {rowan_python-3.2.3 → rowan_python-3.2.4}/.gitignore +0 -0
  31. {rowan_python-3.2.3 → rowan_python-3.2.4}/.python-version +0 -0
  32. {rowan_python-3.2.3 → rowan_python-3.2.4}/.rumdl.toml +0 -0
  33. {rowan_python-3.2.3 → rowan_python-3.2.4}/LICENSE +0 -0
  34. {rowan_python-3.2.3 → rowan_python-3.2.4}/README.md +0 -0
  35. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/api-keys.md +0 -0
  36. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/calculation.md +0 -0
  37. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/folder.md +0 -0
  38. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/molecule.md +0 -0
  39. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/project.md +0 -0
  40. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/protein.md +0 -0
  41. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/user.md +0 -0
  42. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/webhooks.md +0 -0
  43. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/api/workflow.md +0 -0
  44. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/images/RowanLogoLarge.png +0 -0
  45. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/images/RowanSquareLogo.png +0 -0
  46. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/images/favicon.svg +0 -0
  47. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/index.md +0 -0
  48. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/stylesheets/colors.css +0 -0
  49. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/admet.md +0 -0
  50. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/analogue-docking.md +0 -0
  51. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/basic-calculation.md +0 -0
  52. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/batch-docking.md +0 -0
  53. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/binding-affinity.md +0 -0
  54. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/bond-dissociation-energy.md +0 -0
  55. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/conformer-search-settings.md +0 -0
  56. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/conformer-search.md +0 -0
  57. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/covalent-inhibitor-scan.md +0 -0
  58. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/descriptors.md +0 -0
  59. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/docking.md +0 -0
  60. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/double-ended-ts-search.md +0 -0
  61. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/electronic-properties.md +0 -0
  62. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/fukui.md +0 -0
  63. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/hydrogen-bond-donor-acceptor-strength.md +0 -0
  64. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/interaction-energy-decomposition.md +0 -0
  65. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/ion-mobility.md +0 -0
  66. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/irc.md +0 -0
  67. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/logp.md +0 -0
  68. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/macropka.md +0 -0
  69. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/membrane-permeability.md +0 -0
  70. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/msa.md +0 -0
  71. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/multistage-optimization.md +0 -0
  72. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/nmr.md +0 -0
  73. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/pka.md +0 -0
  74. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/pocket-detection.md +0 -0
  75. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/pose-analysis-md.md +0 -0
  76. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/protein-binder-design.md +0 -0
  77. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/protein-cofolding.md +0 -0
  78. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/protein-md.md +0 -0
  79. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/protein-preparation.md +0 -0
  80. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/rbfe-graph.md +0 -0
  81. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/redox-potential.md +0 -0
  82. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/relative-binding-free-energy-perturbation.md +0 -0
  83. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/scan.md +0 -0
  84. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/settings.md +0 -0
  85. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/solubility.md +0 -0
  86. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/solvent-dependent-conformers.md +0 -0
  87. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/spin-states.md +0 -0
  88. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/strain.md +0 -0
  89. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/tautomer-search.md +0 -0
  90. {rowan_python-3.2.3 → rowan_python-3.2.4}/docs/workflows/types.md +0 -0
  91. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/PROTAC_solubility.py +0 -0
  92. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/admet.py +0 -0
  93. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/analogue_docking.py +0 -0
  94. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/aqueous_solubility.py +0 -0
  95. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/basic_calculation.py +0 -0
  96. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/basic_calculation_from_json.py +0 -0
  97. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/basic_calculation_with_constraint.py +0 -0
  98. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/basic_calculation_with_solvent.py +0 -0
  99. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/batch_docking.py +0 -0
  100. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/batch_solubility.py +0 -0
  101. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/bde.py +0 -0
  102. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/binding_affinity.py +0 -0
  103. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/boltz_paired_msa.py +0 -0
  104. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/boltz_single_msa.py +0 -0
  105. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/chai_paired_msa.py +0 -0
  106. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/chai_single_msa.py +0 -0
  107. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/cofolding_screen.py +0 -0
  108. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/colabfold_paired_msa.py +0 -0
  109. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/colabfold_single_msa.py +0 -0
  110. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/conformer_dependent_redox.py +0 -0
  111. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/conformers.py +0 -0
  112. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/conformers_screen.py +0 -0
  113. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/covalent_docking.py +0 -0
  114. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/covalent_inhibitor_scan.py +0 -0
  115. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/1iep_receptorH.pdb +0 -0
  116. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/Al_FCC.xyz +0 -0
  117. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/citalopram_1iep.xyz +0 -0
  118. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/ibuprofen_conformers.sdf +0 -0
  119. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/tyk2_ligands.sdf +0 -0
  120. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/tyk2_structure.pdb +0 -0
  121. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/data/workflow_example.json +0 -0
  122. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/dcd_download.py +0 -0
  123. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/descriptors.py +0 -0
  124. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/docking.py +0 -0
  125. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/docking_screen.py +0 -0
  126. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/double_ended_ts_search.py +0 -0
  127. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/electronic_properties.py +0 -0
  128. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/estimate_workflow.py +0 -0
  129. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/fukui_index.py +0 -0
  130. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/hydrogen_bond_basicity.py +0 -0
  131. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/induced_fit_docking.py +0 -0
  132. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/interaction_energy_decomposition.py +0 -0
  133. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/ion_mobility.py +0 -0
  134. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/irc.py +0 -0
  135. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/logp.py +0 -0
  136. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/macropka.py +0 -0
  137. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/membrane_permeability.py +0 -0
  138. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/multistage_optimization.py +0 -0
  139. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/nmr.py +0 -0
  140. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/optimization.py +0 -0
  141. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/periodic_dft.py +0 -0
  142. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/phenol_pka.py +0 -0
  143. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/pka.py +0 -0
  144. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/pocket_detection.py +0 -0
  145. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/pose_analysis_md.py +0 -0
  146. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/project_scoped_api_key.py +0 -0
  147. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_binder_design.py +0 -0
  148. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_cofolding.py +0 -0
  149. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_cofolding_modified_inputs.py +0 -0
  150. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_cofolding_with_constraints.py +0 -0
  151. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_cofolding_with_templates.py +0 -0
  152. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_file_download.py +0 -0
  153. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_md.py +0 -0
  154. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/protein_preparation.py +0 -0
  155. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/rbfe_graph.py +0 -0
  156. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/rbfe_resubmit.py +0 -0
  157. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/redox_potential.py +0 -0
  158. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/relative_binding_free_energy_perturbation.py +0 -0
  159. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/resubmit_with_perturbations.py +0 -0
  160. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/retrieve_workflow.py +0 -0
  161. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/scan.py +0 -0
  162. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/solvent_dependent_conformers.py +0 -0
  163. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/spin_states.py +0 -0
  164. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/strain.py +0 -0
  165. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/tautomer.py +0 -0
  166. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/template.py +0 -0
  167. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/temporary_workflow_sharing.py +0 -0
  168. {rowan_python-3.2.3 → rowan_python-3.2.4}/examples/webhook.py +0 -0
  169. {rowan_python-3.2.3 → rowan_python-3.2.4}/mkdocs.yml +0 -0
  170. {rowan_python-3.2.3 → rowan_python-3.2.4}/prek.toml +0 -0
  171. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/api_keys.py +0 -0
  172. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/calculation.py +0 -0
  173. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/config.py +0 -0
  174. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/constants.py +0 -0
  175. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/folder.py +0 -0
  176. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/molecule.py +0 -0
  177. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/project.py +0 -0
  178. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/protein.py +0 -0
  179. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/py.typed +0 -0
  180. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/spectra.py +0 -0
  181. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/types.py +0 -0
  182. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/utils.py +0 -0
  183. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/_molecular_dynamics.py +0 -0
  184. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/admet.py +0 -0
  185. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/analogue_docking.py +0 -0
  186. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/base.py +0 -0
  187. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/basic_calculation.py +0 -0
  188. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/batch_docking.py +0 -0
  189. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/bde.py +0 -0
  190. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/binding_affinity.py +0 -0
  191. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/conformer_search.py +0 -0
  192. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/constants.py +0 -0
  193. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/covalent_inhibitor_scan.py +0 -0
  194. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/descriptors.py +0 -0
  195. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/docking.py +0 -0
  196. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/double_ended_ts_search.py +0 -0
  197. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/electronic_properties.py +0 -0
  198. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/fukui.py +0 -0
  199. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/hydrogen_bond_donor_acceptor_strength.py +0 -0
  200. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/interaction_energy_decomposition.py +0 -0
  201. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/ion_mobility.py +0 -0
  202. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/irc.py +0 -0
  203. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/logp.py +0 -0
  204. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/macropka.py +0 -0
  205. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/membrane_permeability.py +0 -0
  206. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/msa.py +0 -0
  207. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/multistage_optimization.py +0 -0
  208. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/nmr.py +0 -0
  209. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/pka.py +0 -0
  210. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/pose_analysis_md.py +0 -0
  211. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/protein_binder_design.py +0 -0
  212. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/protein_cofolding.py +0 -0
  213. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/rbfe_graph.py +0 -0
  214. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/redox_potential.py +0 -0
  215. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/scan.py +0 -0
  216. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/solubility.py +0 -0
  217. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/solvent_dependent_conformers.py +0 -0
  218. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/spin_states.py +0 -0
  219. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/strain.py +0 -0
  220. {rowan_python-3.2.3 → rowan_python-3.2.4}/rowan/workflows/tautomer_search.py +0 -0
  221. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/.claude-plugin/plugin.json +0 -0
  222. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/admet.md +0 -0
  223. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/analogue_docking.md +0 -0
  224. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/basic_calculation.md +0 -0
  225. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/batch_docking.md +0 -0
  226. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/bde.md +0 -0
  227. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/binding_affinity.md +0 -0
  228. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/conformer_search.md +0 -0
  229. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/covalent_inhibitor_scan.md +0 -0
  230. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/descriptors.md +0 -0
  231. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/docking.md +0 -0
  232. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/double_ended_ts_search.md +0 -0
  233. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/electronic_properties.md +0 -0
  234. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/folders_and_projects.md +0 -0
  235. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/fukui.md +0 -0
  236. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/hydrogen_bond_donor_acceptor_strength.md +0 -0
  237. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/interaction_energy_decomposition.md +0 -0
  238. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/ion_mobility.md +0 -0
  239. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/irc.md +0 -0
  240. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/logp.md +0 -0
  241. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/macropka.md +0 -0
  242. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/mcp_execution.md +0 -0
  243. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/membrane_permeability.md +0 -0
  244. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/msa.md +0 -0
  245. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/multistage_optimization.md +0 -0
  246. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/nmr.md +0 -0
  247. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/pka.md +0 -0
  248. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/pose_analysis_md.md +0 -0
  249. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/protein_binder_design.md +0 -0
  250. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/protein_cofolding.md +0 -0
  251. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/python_sdk.md +0 -0
  252. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/rbfe_graph.md +0 -0
  253. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/redox_potential.md +0 -0
  254. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/scan.md +0 -0
  255. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/solubility.md +0 -0
  256. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/solvent_dependent_conformers.md +0 -0
  257. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/spin_states.md +0 -0
  258. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/strain.md +0 -0
  259. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/tautomer_search.md +0 -0
  260. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/reference/webhooks.md +0 -0
  261. {rowan_python-3.2.3 → rowan_python-3.2.4}/skills/computational-chemistry-and-biology/scripts/check_env.py +0 -0
  262. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_binding_affinity.py +0 -0
  263. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_cofolding_workflow_updates.py +0 -0
  264. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_conformer_search.py +0 -0
  265. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_docking_workflow.py +0 -0
  266. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_docking_workflow_updates.py +0 -0
  267. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_download_presigned_files.py +0 -0
  268. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_macropka_nmr.py +0 -0
  269. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_mango_forcefields.py +0 -0
  270. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_plugin.py +0 -0
  271. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_project.py +0 -0
  272. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_protein.py +0 -0
  273. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_rbfe_trajectory_download.py +0 -0
  274. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_solvent_dependent_conformers.py +0 -0
  275. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_tautomer_search.py +0 -0
  276. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_utils.py +0 -0
  277. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_workflow_results.py +0 -0
  278. {rowan_python-3.2.3 → rowan_python-3.2.4}/tests/test_workflow_submission.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rowan-python
3
- Version: 3.2.3
3
+ Version: 3.2.4
4
4
  Summary: Rowan Python Library
5
5
  Project-URL: Homepage, https://github.com/rowansci/rowan-client
6
6
  Project-URL: Bug Tracker, https://github.com/rowansci/rowan-client/issues
@@ -12,7 +12,7 @@ Requires-Dist: httpx
12
12
  Requires-Dist: nest-asyncio
13
13
  Requires-Dist: rdkit
14
14
  Requires-Dist: setuptools
15
- Requires-Dist: stjames>=0.0.289
15
+ Requires-Dist: stjames>=0.0.293
16
16
  Description-Content-Type: text/markdown
17
17
 
18
18
  # Rowan Python Library
@@ -0,0 +1,41 @@
1
+ """Detect protein binding pockets with mixed-solvent molecular dynamics."""
2
+
3
+ import rowan
4
+
5
+ # Set your API key or use the ROWAN_API_KEY environment variable
6
+ # rowan.api_key = "rowan-sk..."
7
+ folder = rowan.get_folder("examples")
8
+
9
+ protein = rowan.create_protein_from_pdb_id("1OTP", name="thymidine phosphorylase")
10
+ preparation_workflow = rowan.submit_protein_preparation_workflow(
11
+ protein=protein.uuid,
12
+ name="Prepare thymidine phosphorylase",
13
+ folder=folder,
14
+ )
15
+ prepared_protein_uuid = preparation_workflow.result().prepared_protein_uuid
16
+ if prepared_protein_uuid is None:
17
+ raise ValueError("Protein preparation returned no prepared protein")
18
+
19
+ # Runs three independent replicas, each with 5 ns equilibration and 15 ns production.
20
+ workflow = rowan.submit_pocket_detection_workflow(
21
+ protein=prepared_protein_uuid,
22
+ settings=rowan.MixMDSettings(probe=rowan.Solvent.ACETONITRILE),
23
+ name="MixMD pocket detection on thymidine phosphorylase",
24
+ folder=folder,
25
+ )
26
+ print(f"View workflow privately at: https://labs.rowansci.com/pocket-detection/{workflow.uuid}")
27
+ result = workflow.result()
28
+
29
+ for message in result.messages:
30
+ print(message)
31
+
32
+ print(f"Detected {len(result.pockets)} pocket(s):")
33
+ for i, pocket in enumerate(result.pockets):
34
+ print(f" Pocket {i}: score={pocket.score}, enriched-region volume={pocket.volume} ų")
35
+ print(f" center={pocket.pocket_center}, sides={pocket.pocket_sides}")
36
+ print(f" residues={pocket.residue_numbers}")
37
+
38
+ # Pocket coordinates refer to this reference structure.
39
+ reference_protein = result.get_reference_protein()
40
+ if reference_protein is not None:
41
+ print(f"Reference protein: {reference_protein.uuid}")
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "rowan-python"
3
- version = "3.2.3"
3
+ version = "3.2.4"
4
4
  description = "Rowan Python Library"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -12,7 +12,7 @@ authors = [
12
12
  ]
13
13
  dependencies = [
14
14
  "httpx",
15
- "stjames>=0.0.289",
15
+ "stjames>=0.0.293",
16
16
  "setuptools",
17
17
  "rdkit",
18
18
  "nest-asyncio",
@@ -28,7 +28,9 @@ from stjames import (
28
28
  iMTDSettings,
29
29
  InducedFitSettings,
30
30
  KMeansClusteringSettings,
31
+ MDRestraints,
31
32
  Method,
33
+ MixMDSettings,
32
34
  Mode,
33
35
  MSAFormat,
34
36
  MultiStageOptSettings,
@@ -39,9 +41,11 @@ from stjames import (
39
41
  OptimizationSettings,
40
42
  PBCDFTSettings,
41
43
  PeriodicCell,
44
+ PocketeerSettings,
42
45
  ProteinSequence,
43
46
  ProteinForceField,
44
47
  ResidueModification,
48
+ RestraintType,
45
49
  RNASequence,
46
50
  ScanSettings,
47
51
  Settings,
@@ -68,7 +72,7 @@ from stjames.engine_compatibility import (
68
72
  METHOD_ENGINES,
69
73
  get_supported_corrections,
70
74
  )
71
- from stjames.pdb import ResidueRef
75
+ from stjames.pdb import ResidueAtomRef, ResidueRef
72
76
  from stjames.optimization.band_method import NEBSettings
73
77
  from stjames.optimization.interpolation import Interpolation
74
78
  from stjames.optimization.string_method import FSMSettings, StringMethodSettings
@@ -60,7 +60,6 @@ class User(BaseModel):
60
60
  email: email of the user
61
61
  firstname: first name of the user
62
62
  lastname: last name of the user
63
- weekly_credits: weekly credits of the user
64
63
  credits: credits of the user
65
64
  billing_name: billing name of the user
66
65
  billing_address: billing address of the user
@@ -79,7 +78,6 @@ class User(BaseModel):
79
78
  email: str
80
79
  firstname: str | None = None
81
80
  lastname: str | None = None
82
- weekly_credits: float | None = None
83
81
  credits: float | None = None
84
82
  billing_name: str | None = None
85
83
  billing_address: str | dict | None = None
@@ -124,7 +122,7 @@ class User(BaseModel):
124
122
  Returns:
125
123
  string showing available credits
126
124
  """
127
- individual_credits = f"Weekly Credits: {self.weekly_credits}\nCredits: {self.credits}"
125
+ individual_credits = f"Credits: {self.credits}"
128
126
  if self.organization is not None:
129
127
  return (
130
128
  individual_credits
@@ -102,7 +102,14 @@ from .multistage_optimization import (
102
102
  )
103
103
  from .nmr import NMRCoupling, NMRPeak, NMRResult, submit_nmr_workflow
104
104
  from .pka import pKaMicrostate, pKaResult, submit_pka_workflow
105
- from .pocket_detection import Pocket, PocketDetectionResult, submit_pocket_detection_workflow
105
+ from .pocket_detection import (
106
+ MixMDPocketDiagnostics,
107
+ MixMDReplicaDiagnostics,
108
+ MixMDResults,
109
+ Pocket,
110
+ PocketDetectionResult,
111
+ submit_pocket_detection_workflow,
112
+ )
106
113
  from .pose_analysis_md import PoseAnalysisMDResult, submit_pose_analysis_md_workflow
107
114
  from .protein_binder_design import (
108
115
  ProteinBinder,
@@ -0,0 +1,253 @@
1
+ """Pocket detection workflow - detect potential binding sites on a protein."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ import stjames
6
+ from stjames import MixMDSettings, PocketeerSettings
7
+
8
+ from rowan.folder import Folder
9
+ from rowan.protein import Protein, retrieve_protein
10
+ from rowan.types import ProteinUUID
11
+ from rowan.utils import api_client
12
+
13
+ from .base import Message, Workflow, WorkflowResult, parse_messages, register_result
14
+
15
+
16
+ @dataclass(frozen=True, slots=True)
17
+ class MixMDPocketDiagnostics:
18
+ """Probe enrichment for a pocket found by mixed-solvent MD.
19
+
20
+ Attributes:
21
+ density_center: density-weighted center of the enriched region, in Å
22
+ peak_enrichment: maximum probe density relative to bulk solvent
23
+ integrated_excess_density: probe molecules above bulk, integrated over the region
24
+ """
25
+
26
+ density_center: tuple[float, float, float]
27
+ peak_enrichment: float
28
+ integrated_excess_density: float
29
+
30
+
31
+ @dataclass(frozen=True, slots=True)
32
+ class Pocket:
33
+ """A detected binding pocket.
34
+
35
+ Mixed-solvent MD pockets describe regions of enriched probe density, so their spheres
36
+ and volume outline that region rather than the cavity.
37
+
38
+ Attributes:
39
+ sphere_centers: centers of detected spheres, in Å
40
+ sphere_radii: radii of detected spheres, in Å
41
+ volume: pocket volume, in ų
42
+ score: method-specific ranking score; larger is better
43
+ pocket_center: center of axis-aligned bounding box, in Å
44
+ pocket_sides: side lengths of axis-aligned bounding box, in Å
45
+ residue_numbers: residue numbers lining the pocket
46
+ mixmd: probe-enrichment details for mixed-solvent MD pockets
47
+ """
48
+
49
+ sphere_centers: tuple[tuple[float, float, float], ...]
50
+ sphere_radii: tuple[float, ...]
51
+ volume: float
52
+ score: float
53
+ pocket_center: tuple[float, float, float]
54
+ pocket_sides: tuple[float, float, float]
55
+ residue_numbers: tuple[int, ...]
56
+ mixmd: MixMDPocketDiagnostics | None = None
57
+
58
+
59
+ @dataclass(frozen=True, slots=True)
60
+ class MixMDReplicaDiagnostics:
61
+ """One mixed-solvent MD replica.
62
+
63
+ Attributes:
64
+ index: zero-based replica index
65
+ seed: replica random seed
66
+ num_frames: analyzed frames; zero for a failed replica
67
+ num_probes: probe molecules in the simulation
68
+ largest_probe_cluster_fraction: mean fraction of probes in the largest cluster
69
+ trajectory_uuid: UUID of the stored trajectory
70
+ topology_uuid: UUID of the trajectory topology protein
71
+ density_map_uuid: UUID of the stored probe-density map
72
+ """
73
+
74
+ index: int
75
+ seed: int
76
+ num_frames: int
77
+ num_probes: int
78
+ largest_probe_cluster_fraction: float | None
79
+ trajectory_uuid: str | None
80
+ topology_uuid: str | None
81
+ density_map_uuid: str | None
82
+
83
+
84
+ @dataclass(frozen=True, slots=True)
85
+ class MixMDResults:
86
+ """Mixed-solvent MD replicas and consensus artifacts.
87
+
88
+ Attributes:
89
+ reference_uuid: UUID of the protein defining pocket and map coordinates
90
+ density_map_uuid: UUID of the consensus probe-density map
91
+ replicas: per-replica results, including failed replicas
92
+ """
93
+
94
+ reference_uuid: str | None
95
+ density_map_uuid: str | None
96
+ replicas: tuple[MixMDReplicaDiagnostics, ...]
97
+
98
+
99
+ def _mixmd_diagnostics(
100
+ raw: stjames.MixMDPocketDiagnostics | None,
101
+ ) -> MixMDPocketDiagnostics | None:
102
+ """Convert stjames probe-enrichment diagnostics, if present."""
103
+ if raw is None:
104
+ return None
105
+ return MixMDPocketDiagnostics(
106
+ density_center=tuple(raw.density_center),
107
+ peak_enrichment=raw.peak_enrichment,
108
+ integrated_excess_density=raw.integrated_excess_density,
109
+ )
110
+
111
+
112
+ @register_result("pocket_detection")
113
+ class PocketDetectionResult(WorkflowResult):
114
+ """Result from a pocket-detection workflow."""
115
+
116
+ _stjames_class = stjames.PocketDetectionWorkflow
117
+
118
+ def __repr__(self) -> str:
119
+ return f"<PocketDetectionResult pockets={len(self.pockets)}>"
120
+
121
+ @property
122
+ def pockets(self) -> list[Pocket]:
123
+ """Detected pockets, in the order returned by the backend."""
124
+ raw = getattr(self._workflow, "pockets", []) or []
125
+ return [
126
+ Pocket(
127
+ sphere_centers=tuple(tuple(c) for c in p.sphere_centers),
128
+ sphere_radii=tuple(p.sphere_radii),
129
+ volume=p.volume,
130
+ score=p.score,
131
+ pocket_center=tuple(p.pocket_center),
132
+ pocket_sides=tuple(p.pocket_sides),
133
+ residue_numbers=tuple(p.residue_numbers),
134
+ mixmd=_mixmd_diagnostics(p.mixmd),
135
+ )
136
+ for p in raw
137
+ ]
138
+
139
+ @property
140
+ def mixmd(self) -> MixMDResults | None:
141
+ """Mixed-solvent MD replicas and artifacts, or `None` for Pocketeer runs."""
142
+ if not (raw := getattr(self._workflow, "mixmd", None)):
143
+ return None
144
+ return MixMDResults(
145
+ reference_uuid=raw.reference_uuid,
146
+ density_map_uuid=raw.density_map_uuid,
147
+ replicas=tuple(
148
+ MixMDReplicaDiagnostics(
149
+ index=r.index,
150
+ seed=r.seed,
151
+ num_frames=r.num_frames,
152
+ num_probes=r.num_probes,
153
+ largest_probe_cluster_fraction=r.largest_probe_cluster_fraction,
154
+ trajectory_uuid=r.trajectory_uuid,
155
+ topology_uuid=r.topology_uuid,
156
+ density_map_uuid=r.density_map_uuid,
157
+ )
158
+ for r in raw.replicas
159
+ ),
160
+ )
161
+
162
+ @property
163
+ def messages(self) -> list[Message]:
164
+ """Any messages or warnings from the workflow, including MixMD reliability warnings."""
165
+ return parse_messages(getattr(self._workflow, "messages", None))
166
+
167
+ def get_reference_protein(self) -> Protein | None:
168
+ """Fetch and cache the protein defining mixed-solvent MD pocket and map coordinates.
169
+
170
+ Returns:
171
+ protein object, or `None` for Pocketeer runs
172
+ """
173
+ if not (mixmd := self.mixmd) or not mixmd.reference_uuid:
174
+ return None
175
+ if "reference_protein" not in self._cache:
176
+ self._cache["reference_protein"] = retrieve_protein(
177
+ mixmd.reference_uuid, workflow_uuid=self.workflow_uuid
178
+ )
179
+ return self._cache["reference_protein"]
180
+
181
+
182
+ def submit_pocket_detection_workflow(
183
+ protein: Protein | ProteinUUID,
184
+ merge_distance: float | None = None,
185
+ settings: PocketeerSettings | MixMDSettings | None = None,
186
+ validate_forcefield: bool = True,
187
+ name: str = "Pocket Detection Workflow",
188
+ folder_uuid: str | None = None,
189
+ folder: Folder | None = None,
190
+ max_credits: int | None = None,
191
+ webhook_url: str | None = None,
192
+ is_draft: bool = False,
193
+ ) -> Workflow[PocketDetectionResult]:
194
+ """Submits a pocket-detection workflow to the API.
195
+
196
+ Args:
197
+ protein: protein to analyze. Can be a UUID or a Protein object
198
+ merge_distance: Pocketeer distance for merging pocket spheres, in Å; defaults to 1.75.
199
+ Set it on `PocketeerSettings` instead when passing `settings`
200
+ settings: method settings; `PocketeerSettings` (default) for geometric detection or
201
+ `MixMDSettings` for mixed-solvent molecular dynamics
202
+ validate_forcefield: validate the protein forcefield compatibility before submitting a
203
+ mixed-solvent MD run. Raises an error early if the protein cannot be parameterized
204
+ or has clashing residues
205
+ name: name of the workflow
206
+ folder_uuid: UUID of the folder to place the workflow in
207
+ folder: destination folder
208
+ max_credits: maximum credits for the workflow
209
+ webhook_url: URL that Rowan will POST to when the workflow completes
210
+ is_draft: save as a draft without starting execution
211
+
212
+ Returns:
213
+ workflow object representing the submitted workflow
214
+
215
+ Raises:
216
+ ValueError: both `merge_distance` and `settings`, or both `folder` and `folder_uuid`,
217
+ are given
218
+ httpx.HTTPStatusError: request to the API fails
219
+ """
220
+ if folder and folder_uuid:
221
+ raise ValueError("Provide either `folder` or `folder_uuid`, not both.")
222
+ if settings is not None and merge_distance is not None:
223
+ raise ValueError("Set `merge_distance` on `PocketeerSettings` when passing `settings`.")
224
+ if folder:
225
+ folder_uuid = folder.uuid
226
+ if isinstance(protein, Protein):
227
+ protein = protein.uuid
228
+
229
+ if settings is None:
230
+ settings = (
231
+ PocketeerSettings()
232
+ if merge_distance is None
233
+ else PocketeerSettings(merge_distance=merge_distance)
234
+ )
235
+ if validate_forcefield and isinstance(settings, MixMDSettings):
236
+ Protein(uuid=protein).validate_protein_forcefield()
237
+
238
+ workflow = stjames.PocketDetectionWorkflow(protein=protein, settings=settings)
239
+
240
+ data = {
241
+ "workflow_type": "pocket_detection",
242
+ "workflow_data": workflow.model_dump(serialize_as_any=True, mode="json"),
243
+ "name": name,
244
+ "folder_uuid": folder_uuid,
245
+ "max_credits": max_credits,
246
+ "webhook_url": webhook_url,
247
+ "is_draft": is_draft,
248
+ }
249
+
250
+ with api_client() as client:
251
+ response = client.post("/workflow", json=data)
252
+ response.raise_for_status()
253
+ return Workflow[PocketDetectionResult](**response.json())
@@ -8,6 +8,7 @@ from stjames import (
8
8
  Binder,
9
9
  GreedyClusteringSettings,
10
10
  KMeansClusteringSettings,
11
+ MDRestraints,
11
12
  ProteinForceField,
12
13
  WaterForceField,
13
14
  )
@@ -158,6 +159,7 @@ def submit_protein_md_workflow(
158
159
  max_credits: int | None = None,
159
160
  webhook_url: str | None = None,
160
161
  is_draft: bool = False,
162
+ restraints: list[MDRestraints] | None = None,
161
163
  ) -> Workflow[ProteinMDResult]:
162
164
  """Submits a Protein Molecular Dynamics (MD) workflow to the API.
163
165
 
@@ -192,7 +194,7 @@ def submit_protein_md_workflow(
192
194
  (one small molecule → heavy-atom RMSD; one binder chain → backbone N/CA/C/O RMSD);
193
195
  it is empty for multi-molecule, multi-chain, or combined chain+molecule binders
194
196
  protein_restraint_cutoff: cutoff distance from the binder past which Cα atoms are
195
- harmonically restrained, in Å; None disables restraints
197
+ harmonically restrained, in Å; None disables these Cα restraints
196
198
  protein_restraint_constant: force constant for Cα backbone restraints, in kcal/mol/Ų
197
199
  analysis_interval_ps: interval at which to compute per-frame SASA and polar SASA
198
200
  (default 100), in ps. None disables those analyses
@@ -210,6 +212,9 @@ def submit_protein_md_workflow(
210
212
  max_credits: maximum credits for the workflow
211
213
  webhook_url: URL that Rowan will POST to when the workflow completes
212
214
  is_draft: save as a draft without starting execution
215
+ restraints: atom or whole-residue restraints applied during minimization,
216
+ equilibration, and production. Atoms use their positions; residues use
217
+ their centers of mass. Cannot be combined with protein_restraint_cutoff
213
218
 
214
219
  Returns:
215
220
  submitted workflow
@@ -256,6 +261,7 @@ def submit_protein_md_workflow(
256
261
  binder=binder,
257
262
  protein_restraint_cutoff=protein_restraint_cutoff,
258
263
  protein_restraint_constant=protein_restraint_constant,
264
+ restraints=restraints or [],
259
265
  analysis_interval_ps=analysis_interval_ps,
260
266
  clustering=clustering,
261
267
  )
@@ -71,6 +71,7 @@ def submit_protein_preparation_workflow(
71
71
  max_credits: int | None = None,
72
72
  webhook_url: str | None = None,
73
73
  is_draft: bool = False,
74
+ retain_noncanonical_residues: bool = False,
74
75
  ) -> Workflow[ProteinPreparationResult]:
75
76
  """Submit a protein-preparation workflow to the API.
76
77
 
@@ -97,6 +98,8 @@ def submit_protein_preparation_workflow(
97
98
  max_credits: maximum credits for the workflow
98
99
  webhook_url: URL that Rowan will POST to when the workflow completes
99
100
  is_draft: save as a draft without starting execution
101
+ retain_noncanonical_residues: preserve modified polymer residues such as SEP/TPO/PTR;
102
+ False replaces them with their unmodified parent residues
100
103
 
101
104
  Returns:
102
105
  workflow object representing the submitted workflow
@@ -119,6 +122,7 @@ def submit_protein_preparation_workflow(
119
122
  protonation_method=protonation_method,
120
123
  pH=pH,
121
124
  retain_protonation=retain_protonation,
125
+ retain_noncanonical_residues=retain_noncanonical_residues,
122
126
  retain_non_polymer=(dict(retain_non_polymer) if retain_non_polymer is not None else None),
123
127
  )
124
128
 
@@ -352,6 +352,8 @@ def submit_relative_binding_free_energy_perturbation_workflow(
352
352
  max_credits: int | None = None,
353
353
  webhook_url: str | None = None,
354
354
  is_draft: bool = False,
355
+ *,
356
+ small_molecules: dict[str | int, str | None] | None = None,
355
357
  ) -> Workflow[RelativeBindingFreeEnergyPerturbationResult]:
356
358
  """Submits a relative binding free energy perturbation (RBFE) workflow to the API.
357
359
 
@@ -388,13 +390,16 @@ def submit_relative_binding_free_energy_perturbation_workflow(
388
390
  save_trajectories: whether to save DCD trajectories
389
391
  trajectory_save_interval: save every Nth frame when saving trajectories
390
392
  validate_forcefield: validate protein forcefield
391
- compatibility before submitting
393
+ compatibility before submitting, excluding cofactors supplied with SMILES
392
394
  name: name of the workflow
393
395
  folder_uuid: UUID of the folder to place the workflow in
394
396
  folder: destination folder
395
397
  max_credits: maximum credits for the workflow
396
398
  webhook_url: URL that Rowan will POST to when the workflow completes
397
399
  is_draft: save as a draft without starting execution
400
+ small_molecules: fixed cofactors in the prepared protein, keyed by residue name
401
+ or zero-based index among all residues ordered by lowest atom ID, and mapped
402
+ to SMILES. Known ions and waters may map to None to use existing residue templates
398
403
 
399
404
  Returns:
400
405
  submitted workflow
@@ -410,9 +415,6 @@ def submit_relative_binding_free_energy_perturbation_workflow(
410
415
 
411
416
  protein_uuid = protein.uuid if isinstance(protein, Protein) else protein
412
417
 
413
- if validate_forcefield:
414
- Protein(uuid=protein_uuid).validate_protein_forcefield()
415
-
416
418
  if graph_result.graph is None:
417
419
  raise ValueError("RBFEGraphResult has no graph - has the workflow completed successfully?")
418
420
 
@@ -446,9 +448,20 @@ def submit_relative_binding_free_energy_perturbation_workflow(
446
448
  graph=graph_result.graph,
447
449
  target=protein_uuid,
448
450
  protein=protein_uuid,
451
+ small_molecules=small_molecules,
449
452
  settings=settings,
450
453
  )
451
454
 
455
+ if validate_forcefield:
456
+ exclude_residues = [
457
+ residue
458
+ for residue, smiles in (workflow.small_molecules or {}).items()
459
+ if smiles is not None
460
+ ]
461
+ Protein(uuid=protein_uuid).validate_protein_forcefield(
462
+ exclude_residues=exclude_residues or None
463
+ )
464
+
452
465
  data = {
453
466
  "workflow_type": "relative_binding_free_energy_perturbation",
454
467
  "workflow_data": workflow.model_dump(mode="json"),
@@ -73,7 +73,7 @@ dedicated reference, in which case trust MCP discovery or the installed SDK for
73
73
  - **Pose-analysis MD**: run MD on a docked protein-ligand complex to test pose stability. See [reference/pose_analysis_md.md](reference/pose_analysis_md.md).
74
74
  - **Protein binder design**: generate, filter, and rank protein binders for a given protein or small-molecule target. See [reference/protein_binder_design.md](reference/protein_binder_design.md).
75
75
  - **Protein co-folding**: predict 3D structures of biomolecules and protein-ligand complexes using AlphaFold 3-style models (Boltz-2, Chai-1r, Boltz-1). See [reference/protein_cofolding.md](reference/protein_cofolding.md).
76
- - **Protein MD**: run a molecular dynamics simulation on a protein. See [reference/protein_md.md](reference/protein_md.md).
76
+ - **Protein MD**: run a molecular dynamics simulation on a protein, with optional atom or residue restraints. See [reference/protein_md.md](reference/protein_md.md).
77
77
  - **Protein preparation**: repair missing protein structure, cap termini, assign protonation states, and retain selected non-polymer residues before docking, MD, or FEP. See [reference/protein_preparation.md](reference/protein_preparation.md).
78
78
  - **RBFE graph**: take a list of ligands and generate the graph used by the relative binding free energy perturbation (FEP) workflow. Its edges are the ligand pairs FEP transforms between. See [reference/rbfe_graph.md](reference/rbfe_graph.md).
79
79
  - **Redox potential**: predict a molecule's reduction or oxidation potential. See [reference/redox_potential.md](reference/redox_potential.md).
@@ -9,7 +9,7 @@ A `rowan.Protein` (or its UUID string). Proteins are not SMILES. Load one and pr
9
9
 
10
10
  Pocket detection accepts any stored `rowan.Protein` or protein UUID. Protein preparation is recommended before submission; when chaining from it, passing `prepared_protein_uuid` avoids an unnecessary structure fetch.
11
11
 
12
- Detects potential binding pockets on the protein structure using Pocketeer.
12
+ Detects potential binding pockets on the protein structure using Pocketeer (default), or with mixed-solvent molecular dynamics (MixMD), which finds regions where small probe molecules accumulate across independent replicas.
13
13
 
14
14
  ## Example
15
15
 
@@ -39,17 +39,22 @@ for i, pocket in enumerate(result.pockets):
39
39
 
40
40
  ## Settings
41
41
 
42
- - `merge_distance` (default `1.75`): distance in angstrom for merging detected pocket spheres into a single pocket.
42
+ - `merge_distance` (default `1.75`): Pocketeer distance in angstrom for merging detected pocket spheres into a single pocket.
43
+ - `settings`: `rowan.PocketeerSettings(merge_distance=...)` (default) or `rowan.MixMDSettings(...)`. MixMD settings include `probe` (`rowan.Solvent.ACETONITRILE` or `rowan.Solvent.ISOPROPANOL`), `num_trajectories` (default `3`), `equilibration_time_ns` (default `5`), `simulation_time_ns` (default `15`), `enrichment_threshold` (default `5`, probe density relative to bulk), and the same force-field and simulation settings as protein MD. Set `merge_distance` on `PocketeerSettings` when passing `settings`.
44
+ - `validate_forcefield` (default `True`): for MixMD, check that the protein can be parameterized before submitting.
43
45
 
44
46
  ## Result fields
45
47
 
46
48
  `result.pockets` is a list of detected pockets, each with:
47
49
 
48
- - `score`: druggability/quality score (larger is better).
49
- - `volume`: pocket volume in cubic angstrom.
50
+ - `score`: method-specific ranking score (larger is better); scores are not comparable between Pocketeer and MixMD.
51
+ - `volume`: pocket volume in cubic angstrom. For MixMD this is the volume of the enriched probe-density region, not the cavity.
50
52
  - `pocket_center`: center of the axis-aligned bounding box, in angstrom.
51
53
  - `pocket_sides`: side lengths of the bounding box, in angstrom.
52
54
  - `residue_numbers`: residue numbers lining the pocket.
53
55
  - `sphere_centers`, `sphere_radii`: centers and radii of the detected spheres, in angstrom.
56
+ - `mixmd`: for MixMD pockets, `density_center`, `peak_enrichment`, and `integrated_excess_density`; otherwise `None`.
57
+
58
+ For MixMD runs, `result.mixmd` lists each replica (`seed`, `num_frames`, `num_probes`, `largest_probe_cluster_fraction`, and artifact UUIDs), and `result.get_reference_protein()` returns the protein that defines pocket coordinates. Reliability warnings, such as fewer than three replicas or disagreement between replicas, appear in `result.messages`.
54
59
 
55
60
  To dock into a detected pocket, pass its `pocket_center` and `pocket_sides` as the docking workflow's `pocket`: `pocket=[list(p.pocket_center), list(p.pocket_sides)]`.
@@ -59,12 +59,54 @@ result.download_trajectories([0], path=".") # save DCD trajectory files
59
59
  - `num_solvent_to_save` (default `None`): when `save_solvent=True` and a `binder` is set, keep only the N solvent molecules nearest the binder each frame; `None` keeps all solvent. Ignored when `save_solvent=False` or no `binder`.
60
60
  - `small_molecules` (default `None`): SMILES keyed by non-polymer residue name or zero-based index. Use this to parameterize one or more small molecules in the protein; a `None` value selects an existing residue template.
61
61
  - `binder` (default `None`): a `rowan.Binder` specifying the binder within the complex — protein/peptide chains (`chain_ids`), small molecules (`small_molecule_residues`, identified by residue-name string or 0-based non-polymer residue index), or both. Enables per-frame MM/GBSA and binder RMSD analyses (see result fields).
62
- - `protein_restraint_cutoff` (default `None`): distance from the binder past which Cα atoms are harmonically restrained, in angstrom; `None` disables restraints. Useful for keeping the binding site mobile while stabilizing the rest of the protein.
62
+ - `restraints` (default `None`): a list of `rowan.MDRestraints` for atoms or whole residues. See [restraints](#restraints).
63
+ - `protein_restraint_cutoff` (default `None`): distance from the binder past which Cα atoms are harmonically restrained, in angstrom; `None` disables these Cα restraints. Useful for keeping the binding site mobile while stabilizing the rest of the protein.
63
64
  - `protein_restraint_constant` (default `100`): force constant for the Cα backbone restraints, in kcal/mol/Ų.
64
65
  - `analysis_interval_ps` (default `100`): interval at which to compute per-frame SASA and polar SASA, in ps. `None` disables those analyses.
65
66
  - `clustering` (default `None`): cluster the trajectory frames. `None` disables it; pass `rowan.KMeansClusteringSettings(num_clusters=10)` or `rowan.GreedyClusteringSettings(cutoff_angstrom=2.0)`.
66
67
  - `validate_forcefield` (default `True`): validate the protein forcefield before submitting; raises early if the protein cannot be parameterized or has clashing residues. When a `binder` is set, its small molecules are excluded from validation, whether keyed by residue name or by non-polymer index, since they are parameterized from their SMILES. Cofactors, metals, and glycans outside the binder are still validated — set `False` to skip the pre-check entirely.
67
68
 
69
+ ## Restraints
70
+
71
+ Pass a list of `rowan.MDRestraints`; each adds one spring during minimization, equilibration, and production. Leave `protein_restraint_cutoff=None`.
72
+
73
+ Select an atom with `rowan.ResidueAtomRef` or a whole residue with `rowan.ResidueRef`. Atoms use their positions; residues use their centers of mass, including added hydrogens. Use separate restraints to hold atoms individually.
74
+
75
+ | `restraint_type` | Selections | `target` |
76
+ | --- | --- | --- |
77
+ | `"position"` | 1 | Omit; uses the position before minimization |
78
+ | `"distance"` | 2 | ≥ 0 Å |
79
+ | `"angle"` | 3 | 0–180°; middle selection is the vertex |
80
+ | `"dihedral"` | 4 | -180–180°; selections in torsion order |
81
+
82
+ - `force_constant`: positive, in kcal/mol/Ų for position/distance or kcal/mol/rad² for angle/dihedral.
83
+ - `flat_bottom_range` (default `0`): ± tolerance in Å or degrees; for position, allowed displacement from the starting point. `target=8, flat_bottom_range=1` permits 7–9 Å. Dihedrals wrap: 179° and -179° differ by 2°.
84
+ - Use IDs and atom names from the submitted protein. For non-polymer residues, use e.g. `rowan.ResidueRef("non_polymer", "B.101")`.
85
+
86
+ ```python
87
+ residue_10 = rowan.ResidueRef("polymer", "A", "A.10")
88
+ residue_25 = rowan.ResidueRef("polymer", "A", "A.25")
89
+ ca_10 = rowan.ResidueAtomRef(residue_10, "CA")
90
+
91
+ restraints = [
92
+ rowan.MDRestraints(restraint_type="position", selections=[ca_10], force_constant=5),
93
+ rowan.MDRestraints(
94
+ restraint_type="distance",
95
+ selections=[residue_10, residue_25],
96
+ force_constant=5,
97
+ target=8,
98
+ flat_bottom_range=1,
99
+ ),
100
+ ]
101
+ wf = rowan.submit_protein_md_workflow(
102
+ protein=prepared_protein_uuid,
103
+ restraints=restraints,
104
+ num_trajectories=1,
105
+ simulation_time_ns=1,
106
+ folder=folder,
107
+ )
108
+ ```
109
+
68
110
  ## Result fields
69
111
 
70
112
  - `trajectory_uuids`: UUIDs of the trajectory calculations, one per replicate.
@@ -53,6 +53,7 @@ print(prepared_protein_uuid)
53
53
  - `protonation_method` (default `"openmm"`): use `"openmm"`, `"protonate_utils"`, or `"propka_3"` to add hydrogens.
54
54
  - `pH` (default `7.4`): pH used to assign protonation states.
55
55
  - `retain_protonation` (default `True`): retain existing protonation states where possible.
56
+ - `retain_noncanonical_residues` (default `False`): preserve modified polymer residues such as phosphorylated SEP/TPO/PTR. When `False`, replace them with their unmodified parent residues. Use OpenMM or PROPKA 3 protonation when retaining phosphorylated residues.
56
57
  - `retain_non_polymer` (default `{"NA": None, "CL": None, "MG": None}`): non-polymer residues to preserve, keyed by residue name or 0-based residue index. Map ligands and other non-ion residues to their SMILES for parameterization. Known ions and waters may map to `None`. Pass `None` to remove all non-polymer residues.
57
58
 
58
59
  Example retaining a ligand and a structural water:
@@ -6,6 +6,7 @@ A completed RBFE graph and a prepared protein.
6
6
 
7
7
  - `graph_result`: a `RelativeBindingFreeEnergyGraphResult` from the RBFE graph workflow, which turns a congeneric ligand series into the graph of ligand pairs FEP transforms between.
8
8
  - `protein`: any stored `rowan.Protein` or protein UUID. Upload your own PDB with `rowan.upload_protein(name, path)`, or get one from the PDB with `rowan.create_protein_from_pdb_id(pdb_code, name=..., project_uuid=...)`. Protein preparation is recommended before RBFE; when chaining from it, passing `prepared_protein_uuid` avoids fetching structure data solely for submission.
9
+ - `small_molecules` (default `None`): fixed cofactors present in the prepared protein, mapped from residue names or zero-based indices among all residues ordered by lowest atom ID to SMILES, for example `{"EDO": "OCCO"}`. Known ions and waters may map to `None` to use existing residue templates. These molecules are included in complex simulations rather than treated as candidate ligands.
9
10
 
10
11
  This workflow runs FEP simulations along the graph edges to predict relative binding free energies across the ligand series.
11
12
 
@@ -71,7 +72,7 @@ The `tmd_settings` profile is the intended interface: it sets sensible defaults
71
72
  - `legs` (default all): which thermodynamic-cycle legs to run, a subset of `vacuum`, `solvent`, `complex`.
72
73
  - `save_trajectories` (default `False`): save DCD trajectories.
73
74
  - `trajectory_save_interval` (default `1000`): when saving trajectories, save a frame every N production frames.
74
- - `validate_forcefield` (default `True`): validate protein forcefield compatibility before submitting.
75
+ - `validate_forcefield` (default `True`): validate protein forcefield compatibility before submitting, excluding cofactors supplied with SMILES. Template-backed ions and waters are still checked.
75
76
 
76
77
  ### Advanced sampling parameters
77
78