rowan-python 3.1.9__tar.gz → 3.1.10__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.
- {rowan_python-3.1.9 → rowan_python-3.1.10}/PKG-INFO +2 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/docs/index.md +11 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/covalent_inhibitor_scan.py +3 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/docking.py +1 -1
- rowan_python-3.1.10/examples/logp.py +19 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/protein_md.py +1 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/pixi.lock +16 -16
- {rowan_python-3.1.9 → rowan_python-3.1.10}/pyproject.toml +2 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/__init__.py +1 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/protein.py +62 -20
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/__init__.py +1 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/analogue_docking.py +1 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/base.py +2 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/docking.py +1 -1
- rowan_python-3.1.10/rowan/workflows/logp.py +80 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/pose_analysis_md.py +4 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/protein_cofolding.py +6 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/protein_md.py +30 -4
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/relative_binding_free_energy_perturbation.py +3 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/SKILL.md +2 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/analogue_docking.md +1 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/batch_docking.md +2 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/covalent_inhibitor_scan.md +2 -0
- rowan_python-3.1.10/skills/computational-chemistry-and-biology/reference/logp.md +37 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/pocket_detection.md +2 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/protein_md.md +8 -4
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/protein_prep.md +6 -2
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/python_sdk.md +9 -9
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/relative_binding_free_energy_perturbation.md +1 -1
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.agents/plugins/marketplace.json +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.claude-plugin/marketplace.json +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.codex-plugin/plugin.json +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.envrc +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.github/workflows/build-and-deploy-docs.yml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.github/workflows/publish-skill.yml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.github/workflows/python-publish.yml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.github/workflows/test.yml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.gitignore +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/.pre-commit-config.yaml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/AGENTS.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/CLAUDE.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/GEMINI.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/LICENSE +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/README.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/docs/images/deciduous-tree-favicon.png +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/docs/stylesheets/colors.css +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/PROTAC_solubility.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/admet.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/analogue_docking.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/aqueous_solubility.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/basic_calculation.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/basic_calculation_from_json.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/basic_calculation_with_constraint.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/basic_calculation_with_solvent.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/batch_docking.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/bde.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/binding_affinity.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/boltz_paired_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/boltz_single_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/chai_paired_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/chai_single_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/cofolding_screen.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/colabfold_paired_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/colabfold_single_msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/conformer_dependent_redox.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/conformers.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/conformers_screen.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/covalent_docking.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/1iep_receptorH.pdb +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/Al_FCC.xyz +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/citalopram_1iep.xyz +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/ibuprofen_conformers.sdf +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/tyk2_ligands.sdf +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/tyk2_structure.pdb +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/data/workflow_example.json +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/dcd_download.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/descriptors.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/docking_screen.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/double_ended_ts_search.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/electronic_properties.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/estimate_workflow.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/fukui_index.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/hydrogen_bond_basicity.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/interaction_energy_decomposition.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/ion_mobility.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/irc.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/macropka.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/membrane_permeability.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/multistage_optimization.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/nmr.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/optimization.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/pdb_download.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/periodic_dft.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/phenol_pka.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/pka.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/pocket_detection.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/pose_analysis_md.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/project_scoped_api_key.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/protein_binder_design.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/protein_cofolding.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/protein_cofolding_with_constraints.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/protein_cofolding_with_templates.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/rbfe_graph.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/rbfe_resubmit.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/redox_potential.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/relative_binding_free_energy_perturbation.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/resubmit_with_perturbations.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/retrieve_workflow.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/scan.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/solvent_dependent_conformers.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/spin_states.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/strain.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/tautomer.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/template.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/examples/webhook.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/mkdocs.yml +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/api_keys.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/calculation.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/config.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/constants.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/folder.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/molecule.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/project.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/py.typed +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/test_utils.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/types.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/user.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/utils.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/admet.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/basic_calculation.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/batch_docking.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/bde.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/binding_affinity.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/conformer_search.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/constants.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/covalent_inhibitor_scan.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/descriptors.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/double_ended_ts_search.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/electronic_properties.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/fukui.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/hydrogen_bond_donor_acceptor_strength.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/interaction_energy_decomposition.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/ion_mobility.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/irc.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/macropka.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/membrane_permeability.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/msa.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/multistage_optimization.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/nmr.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/pka.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/pocket_detection.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/protein_binder_design.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/rbfe_graph.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/redox_potential.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/scan.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/solubility.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/solvent_dependent_conformers.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/spin_states.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/strain.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/rowan/workflows/tautomer_search.py +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/admet.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/basic_calculation.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/bde.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/binding_affinity.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/conformer_search.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/descriptors.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/docking.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/double_ended_ts_search.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/electronic_properties.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/folders_and_projects.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/fukui.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/hydrogen_bond_donor_acceptor_strength.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/interaction_energy_decomposition.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/ion_mobility.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/irc.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/macropka.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/mcp_execution.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/membrane_permeability.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/msa.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/multistage_optimization.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/nmr.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/pka.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/pose_analysis_md.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/protein_binder_design.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/protein_cofolding.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/rbfe_graph.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/redox_potential.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/scan.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/solubility.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/solvent_dependent_conformers.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/spin_states.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/strain.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/tautomer_search.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/reference/webhooks.md +0 -0
- {rowan_python-3.1.9 → rowan_python-3.1.10}/skills/computational-chemistry-and-biology/scripts/check_env.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rowan-python
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.10
|
|
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
|
|
@@ -11,7 +11,7 @@ Requires-Dist: httpx
|
|
|
11
11
|
Requires-Dist: nest-asyncio
|
|
12
12
|
Requires-Dist: rdkit
|
|
13
13
|
Requires-Dist: setuptools
|
|
14
|
-
Requires-Dist: stjames
|
|
14
|
+
Requires-Dist: stjames<0.0.238,>=0.0.237
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
|
|
17
17
|
# Rowan Python Library
|
|
@@ -209,6 +209,17 @@
|
|
|
209
209
|
group_by_category: true
|
|
210
210
|
filters: ["!^__"]
|
|
211
211
|
|
|
212
|
+
## LogP
|
|
213
|
+
::: rowan.workflows.logp
|
|
214
|
+
handler: python
|
|
215
|
+
options:
|
|
216
|
+
show_source: false
|
|
217
|
+
show_root_heading: false
|
|
218
|
+
show_root_toc_entry: false
|
|
219
|
+
members_order: source
|
|
220
|
+
group_by_category: true
|
|
221
|
+
filters: ["!^__"]
|
|
222
|
+
|
|
212
223
|
## MacropKa
|
|
213
224
|
::: rowan.workflows.macropka
|
|
214
225
|
handler: python
|
|
@@ -15,10 +15,13 @@ protein.prepare(remove_heterogens=False)
|
|
|
15
15
|
protein_reactive_atom_index = 1571
|
|
16
16
|
ligand_reactive_atom_index = 4492
|
|
17
17
|
|
|
18
|
+
ligand_smiles = "CC(C)(C)C[C@@H](C#N)C(=O)N1CCC[C@H](C1)n2nc(c3ccc(Oc4ccccc4)cc3)c5c(N)ncnc25"
|
|
19
|
+
|
|
18
20
|
workflow = rowan.submit_covalent_inhibitor_scan_workflow(
|
|
19
21
|
protein=protein,
|
|
20
22
|
protein_reactive_atom_index=protein_reactive_atom_index,
|
|
21
23
|
ligand_reactive_atom_index=ligand_reactive_atom_index,
|
|
24
|
+
ligand_smiles=ligand_smiles,
|
|
22
25
|
settings=rowan.CovalentInhibitorScanSettings(scan_num=4),
|
|
23
26
|
name="BTK covalent inhibitor scan (Cys481, 4YHF)",
|
|
24
27
|
folder=folder,
|
|
@@ -35,5 +35,5 @@ for i, score in enumerate(result.scores):
|
|
|
35
35
|
|
|
36
36
|
# Download the top-scoring protein–ligand complex as a PDB
|
|
37
37
|
complex_protein = result.get_complex(0)
|
|
38
|
-
complex_protein.download_pdb_file("dasatinib_2GQG_complex
|
|
38
|
+
complex_protein.download_pdb_file(name="dasatinib_2GQG_complex")
|
|
39
39
|
print("Saved dasatinib_2GQG_complex.pdb")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import rowan
|
|
2
|
+
|
|
3
|
+
# Set your API key or use the ROWAN_API_KEY environment variable
|
|
4
|
+
# rowan.api_key = "rowan-sk..."
|
|
5
|
+
folder = rowan.get_folder("examples")
|
|
6
|
+
|
|
7
|
+
oseltamivir_SMILES = "C1CCOC(=O)C1=C[C@@H](OC(CC)CC)[C@H](NC(C)=O)[C@@H]([NH3+])C1CCC1"
|
|
8
|
+
|
|
9
|
+
workflow = rowan.submit_logp_workflow(
|
|
10
|
+
initial_smiles=oseltamivir_SMILES,
|
|
11
|
+
method="chemprop_sangster2026",
|
|
12
|
+
name="Oseltamivir logP",
|
|
13
|
+
folder=folder,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
print(f"View workflow privately at: https://labs.rowansci.com/logp/{workflow.uuid}")
|
|
17
|
+
result = workflow.result()
|
|
18
|
+
print(result)
|
|
19
|
+
# e.g. <LogPResult logp=2.541>
|
|
@@ -55,9 +55,9 @@ environments:
|
|
|
55
55
|
- pypi: https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
|
56
56
|
- pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl
|
|
57
57
|
- pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl
|
|
58
|
-
- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl
|
|
59
58
|
- pypi: https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl
|
|
60
59
|
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
|
60
|
+
- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl
|
|
61
61
|
- pypi: https://files.pythonhosted.org/packages/e1/11/1a9a693e424b2a75755d56ecb67ccc6f77e6e5bb7417dec5e73d9c410314/rdkit-2026.3.4-cp314-cp314-manylinux_2_28_x86_64.whl
|
|
62
62
|
- pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl
|
|
63
63
|
- pypi: https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
|
|
@@ -96,9 +96,9 @@ environments:
|
|
|
96
96
|
- pypi: https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl
|
|
97
97
|
- pypi: https://files.pythonhosted.org/packages/bf/64/0e215f2048dd11a55bb989ed41b3585ef57452404e638d703a211a3e4157/numpy-2.5.1-cp314-cp314-macosx_11_0_arm64.whl
|
|
98
98
|
- pypi: https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl
|
|
99
|
-
- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl
|
|
100
99
|
- pypi: https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl
|
|
101
100
|
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
|
101
|
+
- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl
|
|
102
102
|
- pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl
|
|
103
103
|
- pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl
|
|
104
104
|
dev:
|
|
@@ -192,7 +192,6 @@ environments:
|
|
|
192
192
|
- pypi: https://files.pythonhosted.org/packages/c7/7b/14882602ddee241d7984a742fcb423cb4a30fb0d6efc546ac3129fba475a/python_discovery-1.5.0-py3-none-any.whl
|
|
193
193
|
- pypi: https://files.pythonhosted.org/packages/ca/87/b4d6c38e0ccd5e85dc54cecdf933a152c60b28fe5d993a6d8a72fa6d5896/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
|
|
194
194
|
- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl
|
|
195
|
-
- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl
|
|
196
195
|
- pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl
|
|
197
196
|
- pypi: https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl
|
|
198
197
|
- pypi: https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl
|
|
@@ -202,6 +201,7 @@ environments:
|
|
|
202
201
|
- pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl
|
|
203
202
|
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
|
204
203
|
- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl
|
|
204
|
+
- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl
|
|
205
205
|
- pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl
|
|
206
206
|
- pypi: https://files.pythonhosted.org/packages/e1/11/1a9a693e424b2a75755d56ecb67ccc6f77e6e5bb7417dec5e73d9c410314/rdkit-2026.3.4-cp314-cp314-manylinux_2_28_x86_64.whl
|
|
207
207
|
- pypi: https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl
|
|
@@ -296,7 +296,6 @@ environments:
|
|
|
296
296
|
- pypi: https://files.pythonhosted.org/packages/c7/7b/14882602ddee241d7984a742fcb423cb4a30fb0d6efc546ac3129fba475a/python_discovery-1.5.0-py3-none-any.whl
|
|
297
297
|
- pypi: https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl
|
|
298
298
|
- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl
|
|
299
|
-
- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl
|
|
300
299
|
- pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl
|
|
301
300
|
- pypi: https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl
|
|
302
301
|
- pypi: https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl
|
|
@@ -307,6 +306,7 @@ environments:
|
|
|
307
306
|
- pypi: https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz
|
|
308
307
|
- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl
|
|
309
308
|
- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl
|
|
309
|
+
- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl
|
|
310
310
|
- pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl
|
|
311
311
|
- pypi: https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl
|
|
312
312
|
- pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl
|
|
@@ -820,7 +820,7 @@ packages:
|
|
|
820
820
|
name: rowan-python
|
|
821
821
|
requires_dist:
|
|
822
822
|
- httpx
|
|
823
|
-
- stjames>=0.0.
|
|
823
|
+
- stjames>=0.0.237,<0.0.238
|
|
824
824
|
- setuptools
|
|
825
825
|
- rdkit
|
|
826
826
|
- nest-asyncio
|
|
@@ -1706,17 +1706,6 @@ packages:
|
|
|
1706
1706
|
version: 2.3.0
|
|
1707
1707
|
sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12
|
|
1708
1708
|
requires_python: '>=3.10'
|
|
1709
|
-
- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl
|
|
1710
|
-
name: stjames
|
|
1711
|
-
version: 0.0.236
|
|
1712
|
-
sha256: ea1459a5d0e0ccd206e5a387b201beec5e60ad6bc4f15dbcf649e2d4667fc40c
|
|
1713
|
-
requires_dist:
|
|
1714
|
-
- pydantic>=2.4
|
|
1715
|
-
- numpy
|
|
1716
|
-
- requests
|
|
1717
|
-
- more-itertools
|
|
1718
|
-
- rdkit ; extra == 'rdkit'
|
|
1719
|
-
requires_python: '>=3.11'
|
|
1720
1709
|
- pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl
|
|
1721
1710
|
name: colorama
|
|
1722
1711
|
version: 0.4.6
|
|
@@ -1803,6 +1792,17 @@ packages:
|
|
|
1803
1792
|
- mkdocs-section-index ; extra == 'docs'
|
|
1804
1793
|
- mkdocs-literate-nav ; extra == 'docs'
|
|
1805
1794
|
requires_python: '>=3.10'
|
|
1795
|
+
- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl
|
|
1796
|
+
name: stjames
|
|
1797
|
+
version: 0.0.237
|
|
1798
|
+
sha256: 790c32bdc829efe52b7ccc442083d0d95fc01587d4063a08ea73cd9f686f6d21
|
|
1799
|
+
requires_dist:
|
|
1800
|
+
- pydantic>=2.4
|
|
1801
|
+
- numpy
|
|
1802
|
+
- requests
|
|
1803
|
+
- more-itertools
|
|
1804
|
+
- rdkit ; extra == 'rdkit'
|
|
1805
|
+
requires_python: '>=3.11'
|
|
1806
1806
|
- pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl
|
|
1807
1807
|
name: packaging
|
|
1808
1808
|
version: '26.2'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "rowan-python"
|
|
3
|
-
version = "3.1.
|
|
3
|
+
version = "3.1.10"
|
|
4
4
|
description = "Rowan Python Library"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
]
|
|
10
10
|
dependencies = [
|
|
11
11
|
"httpx",
|
|
12
|
-
"stjames>=0.0.
|
|
12
|
+
"stjames>=0.0.237,<0.0.238",
|
|
13
13
|
"setuptools",
|
|
14
14
|
"rdkit",
|
|
15
15
|
"nest-asyncio",
|
|
@@ -4,7 +4,8 @@ from datetime import datetime
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Any, Self
|
|
6
6
|
|
|
7
|
-
from pydantic import BaseModel
|
|
7
|
+
from pydantic import BaseModel, PrivateAttr
|
|
8
|
+
from stjames.pdb import PDB, pdb_object_to_pdb_filestring
|
|
8
9
|
|
|
9
10
|
from .project import Project
|
|
10
11
|
from .utils import api_client
|
|
@@ -37,6 +38,8 @@ class Protein(BaseModel):
|
|
|
37
38
|
public: bool | None = None
|
|
38
39
|
pocket: list[list[float]] | None = None
|
|
39
40
|
|
|
41
|
+
_workflow_uuid: str | None = PrivateAttr(default=None)
|
|
42
|
+
|
|
40
43
|
def __repr__(self) -> str:
|
|
41
44
|
return f"<Protein name='{self.name}' created_at='{self.created_at}' uuid='{self.uuid}'>"
|
|
42
45
|
|
|
@@ -119,18 +122,24 @@ class Protein(BaseModel):
|
|
|
119
122
|
response.raise_for_status()
|
|
120
123
|
return Protein(**response.json())
|
|
121
124
|
|
|
122
|
-
def refresh(self, in_place: bool = True) -> Self:
|
|
125
|
+
def refresh(self, in_place: bool = True, workflow_uuid: str | None = None) -> Self:
|
|
123
126
|
"""
|
|
124
127
|
Loads protein data
|
|
125
128
|
|
|
129
|
+
:param workflow_uuid: UUID of a workflow referencing this protein, for proteins reachable
|
|
130
|
+
only through a workflow you can read. Not needed for proteins from a workflow result.
|
|
126
131
|
:returns: protein with loaded data
|
|
127
132
|
"""
|
|
133
|
+
workflow_uuid = workflow_uuid or self._workflow_uuid
|
|
134
|
+
params = {"workflow_uuid": workflow_uuid} if workflow_uuid else None
|
|
128
135
|
with api_client() as client:
|
|
129
|
-
response = client.get(f"/protein/{self.uuid}")
|
|
136
|
+
response = client.get(f"/protein/{self.uuid}", params=params)
|
|
130
137
|
response.raise_for_status()
|
|
131
138
|
protein_data = response.json()
|
|
132
139
|
if not in_place:
|
|
133
|
-
|
|
140
|
+
refreshed = self.__class__.model_validate(protein_data)
|
|
141
|
+
refreshed._workflow_uuid = workflow_uuid
|
|
142
|
+
return refreshed
|
|
134
143
|
|
|
135
144
|
self.name = protein_data.get("name")
|
|
136
145
|
self.data = protein_data.get("data")
|
|
@@ -138,6 +147,7 @@ class Protein(BaseModel):
|
|
|
138
147
|
self.pocket = protein_data.get("pocket")
|
|
139
148
|
self.sanitized = protein_data.get("sanitized")
|
|
140
149
|
self.used_in_workflow = protein_data.get("used_in_workflow")
|
|
150
|
+
self._workflow_uuid = workflow_uuid
|
|
141
151
|
return self
|
|
142
152
|
|
|
143
153
|
def update(
|
|
@@ -291,7 +301,7 @@ class Protein(BaseModel):
|
|
|
291
301
|
|
|
292
302
|
raise RuntimeError(f"Protein preparation timed out after {timeout:.0f}s for {self.uuid}.")
|
|
293
303
|
|
|
294
|
-
def validate_protein_forcefield(self,
|
|
304
|
+
def validate_protein_forcefield(self, exclude_residues: list[str | int] | None = None) -> None:
|
|
295
305
|
"""
|
|
296
306
|
Validate that this protein can be parameterized with the MD forcefield.
|
|
297
307
|
|
|
@@ -299,16 +309,24 @@ class Protein(BaseModel):
|
|
|
299
309
|
recognized by OpenMM and that there are no clashing atoms. Call this
|
|
300
310
|
before submitting any MD workflow to catch preparation issues early.
|
|
301
311
|
|
|
302
|
-
Ligand residues (
|
|
303
|
-
separately by the MD workflow from the provided SMILES.
|
|
312
|
+
Ligand residues (`LIG`) are always excluded — they are parameterized
|
|
313
|
+
separately by the MD workflow from the provided SMILES. Pass the keys of a
|
|
314
|
+
binder's `small_molecules` to exclude those as well.
|
|
315
|
+
|
|
316
|
+
A name is matched case-insensitively and excludes only the first residue
|
|
317
|
+
with that name, so further copies are still validated. Integer entries are
|
|
318
|
+
0-based indices into the protein's sorted non-polymer records, and reference
|
|
319
|
+
a record without naming it.
|
|
304
320
|
|
|
305
321
|
If validation fails, try re-preparing with ``remove_invalid_hydrogens=True``:
|
|
306
322
|
``protein.prepare(remove_invalid_hydrogens=True)``
|
|
307
323
|
|
|
308
|
-
:param
|
|
324
|
+
:param exclude_residues: additional residue names and/or 0-based non-polymer indices to skip
|
|
309
325
|
:raises requests.HTTPError: if validation fails or the API request fails.
|
|
310
326
|
"""
|
|
311
|
-
|
|
327
|
+
entries: list[str | int] = ["LIG"]
|
|
328
|
+
entries += [r.upper() if isinstance(r, str) else r for r in exclude_residues or []]
|
|
329
|
+
excluded = list(dict.fromkeys(entries))
|
|
312
330
|
with api_client() as client:
|
|
313
331
|
response = client.post(
|
|
314
332
|
f"/protein/{self.uuid}/validate_forcefield",
|
|
@@ -316,42 +334,66 @@ class Protein(BaseModel):
|
|
|
316
334
|
)
|
|
317
335
|
response.raise_for_status()
|
|
318
336
|
|
|
319
|
-
def download_pdb_file(
|
|
337
|
+
def download_pdb_file(
|
|
338
|
+
self,
|
|
339
|
+
path: Path | str | None = None,
|
|
340
|
+
name: str | None = None,
|
|
341
|
+
workflow_uuid: str | None = None,
|
|
342
|
+
) -> None:
|
|
320
343
|
"""
|
|
321
|
-
Downloads the PDB file for a protein
|
|
344
|
+
Downloads the PDB file for a protein.
|
|
345
|
+
|
|
346
|
+
Builds the file locally from this protein's data, calling `refresh()` if needed, so it
|
|
347
|
+
works anywhere `refresh()` does — including proteins reachable only through a workflow.
|
|
322
348
|
|
|
323
349
|
:param path: Directory to save the file to (defaults to current directory)
|
|
324
350
|
:param name: Optional custom name for the file (defaults to protein name)
|
|
351
|
+
:param workflow_uuid: UUID of a workflow referencing this protein, for proteins reachable
|
|
352
|
+
only through a workflow you can read. Not needed for proteins from a workflow result.
|
|
325
353
|
:raises requests.HTTPError: if the request to the API fails
|
|
326
354
|
"""
|
|
327
355
|
path = Path(path) if path is not None else Path.cwd()
|
|
328
356
|
|
|
329
357
|
path.mkdir(parents=True, exist_ok=True)
|
|
330
358
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
359
|
+
if self.data is None:
|
|
360
|
+
self.refresh(workflow_uuid=workflow_uuid)
|
|
361
|
+
|
|
362
|
+
pdb_object = PDB.model_validate(self.data)
|
|
363
|
+
pdb_string = pdb_object_to_pdb_filestring(
|
|
364
|
+
pdb=pdb_object,
|
|
365
|
+
header=True,
|
|
366
|
+
source=True,
|
|
367
|
+
keyword=True,
|
|
368
|
+
crystallography=True,
|
|
369
|
+
remark=False,
|
|
370
|
+
)
|
|
334
371
|
|
|
335
|
-
file_path = path / f"{name or self.name}.pdb"
|
|
336
|
-
with open(file_path, "
|
|
337
|
-
f.write(
|
|
372
|
+
file_path = path / f"{name or self.name or self.uuid}.pdb"
|
|
373
|
+
with open(file_path, "w") as f:
|
|
374
|
+
f.write(pdb_string)
|
|
338
375
|
|
|
339
376
|
|
|
340
|
-
def retrieve_protein(uuid: str) -> Protein:
|
|
377
|
+
def retrieve_protein(uuid: str, workflow_uuid: str | None = None) -> Protein:
|
|
341
378
|
"""
|
|
342
379
|
Retrieves a protein from the API using its UUID.
|
|
343
380
|
|
|
344
381
|
:param uuid: UUID of the protein to retrieve.
|
|
382
|
+
:param workflow_uuid: UUID of a workflow referencing this protein, for proteins reachable
|
|
383
|
+
only through a workflow you can read. Not needed for proteins from a workflow result.
|
|
345
384
|
:returns: Protein object representing the retrieved protein.
|
|
346
385
|
:raises requests.HTTPError: if the request to the API fails.
|
|
347
386
|
"""
|
|
387
|
+
params = {"workflow_uuid": workflow_uuid} if workflow_uuid else None
|
|
348
388
|
|
|
349
389
|
with api_client() as client:
|
|
350
|
-
response = client.get(f"/protein/{uuid}")
|
|
390
|
+
response = client.get(f"/protein/{uuid}", params=params)
|
|
351
391
|
response.raise_for_status()
|
|
352
392
|
protein_data = response.json()
|
|
353
393
|
|
|
354
|
-
|
|
394
|
+
protein = Protein(**protein_data)
|
|
395
|
+
protein._workflow_uuid = workflow_uuid
|
|
396
|
+
return protein
|
|
355
397
|
|
|
356
398
|
|
|
357
399
|
def list_proteins(
|
|
@@ -83,6 +83,7 @@ from .interaction_energy_decomposition import (
|
|
|
83
83
|
)
|
|
84
84
|
from .ion_mobility import IonMobilityResult, submit_ion_mobility_workflow
|
|
85
85
|
from .irc import IRCResult, submit_irc_workflow
|
|
86
|
+
from .logp import LogPResult, submit_logp_workflow
|
|
86
87
|
from .macropka import (
|
|
87
88
|
MacropKaMicrostate,
|
|
88
89
|
MacropKaResult,
|
|
@@ -160,7 +160,7 @@ class AnalogueDockingResult(WorkflowResult):
|
|
|
160
160
|
|
|
161
161
|
cache_key = f"complex_{smiles}_{index}"
|
|
162
162
|
if cache_key not in self._cache:
|
|
163
|
-
self._cache[cache_key] = retrieve_protein(uuid)
|
|
163
|
+
self._cache[cache_key] = retrieve_protein(uuid, workflow_uuid=self.workflow_uuid)
|
|
164
164
|
return self._cache[cache_key]
|
|
165
165
|
|
|
166
166
|
def get_complexes(self, smiles: str) -> list[Protein]:
|
|
@@ -144,10 +144,10 @@ the server (a field is missing, extra, or the wrong type). Underlying validation
|
|
|
144
144
|
RESULT_REGISTRY: dict[str, type[WorkflowResult]] = {}
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
def register_result(workflow_type: str) -> Callable[[type[
|
|
147
|
+
def register_result[R: WorkflowResult](workflow_type: str) -> Callable[[type[R]], type[R]]:
|
|
148
148
|
"""Decorator to register a result class for a workflow type."""
|
|
149
149
|
|
|
150
|
-
def decorator(cls: type[
|
|
150
|
+
def decorator(cls: type[R]) -> type[R]:
|
|
151
151
|
RESULT_REGISTRY[workflow_type] = cls
|
|
152
152
|
return cls
|
|
153
153
|
|
|
@@ -133,7 +133,7 @@ class DockingResult(WorkflowResult):
|
|
|
133
133
|
|
|
134
134
|
cache_key = f"complex_{index}"
|
|
135
135
|
if cache_key not in self._cache:
|
|
136
|
-
self._cache[cache_key] = retrieve_protein(uuid)
|
|
136
|
+
self._cache[cache_key] = retrieve_protein(uuid, workflow_uuid=self.workflow_uuid)
|
|
137
137
|
return self._cache[cache_key]
|
|
138
138
|
|
|
139
139
|
def get_complexes(self) -> list[Protein]:
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""logP workflow - predict the octanol/water partition coefficient."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
import stjames
|
|
6
|
+
|
|
7
|
+
from ..folder import Folder
|
|
8
|
+
from ..utils import api_client
|
|
9
|
+
from .base import SMILES, Workflow, WorkflowResult, extract_smiles, register_result
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@register_result("logp")
|
|
13
|
+
class LogPResult(WorkflowResult):
|
|
14
|
+
"""Result from a logP workflow."""
|
|
15
|
+
|
|
16
|
+
_stjames_class = stjames.LogPWorkflow
|
|
17
|
+
|
|
18
|
+
def __repr__(self) -> str:
|
|
19
|
+
return f"<LogPResult logp={self.logp}>"
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def logp(self) -> float | None:
|
|
23
|
+
"""Predicted octanol/water partition coefficient."""
|
|
24
|
+
return self._workflow.logp
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def submit_logp_workflow(
|
|
28
|
+
initial_smiles: SMILES,
|
|
29
|
+
method: Literal["chemprop_sangster2026", "crippen", "cosmors"] = "chemprop_sangster2026",
|
|
30
|
+
name: str = "LogP Workflow",
|
|
31
|
+
folder_uuid: str | None = None,
|
|
32
|
+
folder: Folder | None = None,
|
|
33
|
+
max_credits: int | None = None,
|
|
34
|
+
webhook_url: str | None = None,
|
|
35
|
+
is_draft: bool = False,
|
|
36
|
+
) -> Workflow:
|
|
37
|
+
"""
|
|
38
|
+
Submits a logP workflow to the API.
|
|
39
|
+
|
|
40
|
+
:param initial_smiles: Molecule to predict logP for. Accepts a SMILES string or any
|
|
41
|
+
molecule type (RowanMolecule, stjames.Molecule, RDKit Mol, or dict). The molecule
|
|
42
|
+
must have a SMILES string associated with it, as this workflow is SMILES-based and
|
|
43
|
+
does not use 3D coordinates.
|
|
44
|
+
:param method: logP prediction method:
|
|
45
|
+
- "chemprop_sangster2026": chemprop v2 D-MPNN trained on experimental octanol/water
|
|
46
|
+
logP from the Sangster dataset.
|
|
47
|
+
- "crippen": RDKit implementation of the Wildman-Crippen atom-contribution model.
|
|
48
|
+
- "cosmors": Boltzmann-weighted COSMO-RS logP over a conformer ensemble.
|
|
49
|
+
:param name: Name of the workflow.
|
|
50
|
+
:param folder_uuid: UUID of the folder to store the workflow in.
|
|
51
|
+
:param folder: Folder object to store the workflow in.
|
|
52
|
+
:param max_credits: Maximum number of credits to use for the workflow.
|
|
53
|
+
:param webhook_url: URL that Rowan will POST to when the workflow completes.
|
|
54
|
+
:param is_draft: If True, submit the workflow as a draft without starting execution.
|
|
55
|
+
:returns: Workflow object representing the submitted workflow.
|
|
56
|
+
:raises ValueError: If the molecule has no SMILES associated with it.
|
|
57
|
+
:raises requests.HTTPError: if the request to the API fails.
|
|
58
|
+
"""
|
|
59
|
+
if folder and folder_uuid:
|
|
60
|
+
raise ValueError("Provide either `folder` or `folder_uuid`, not both.")
|
|
61
|
+
if folder:
|
|
62
|
+
folder_uuid = folder.uuid
|
|
63
|
+
initial_smiles = extract_smiles(initial_smiles)
|
|
64
|
+
workflow = stjames.LogPWorkflow(initial_smiles=initial_smiles, logp_method=method)
|
|
65
|
+
|
|
66
|
+
data = {
|
|
67
|
+
"workflow_type": "logp",
|
|
68
|
+
"workflow_data": workflow.model_dump(mode="json"),
|
|
69
|
+
"initial_smiles": initial_smiles,
|
|
70
|
+
"name": name,
|
|
71
|
+
"folder_uuid": folder_uuid,
|
|
72
|
+
"max_credits": max_credits,
|
|
73
|
+
"webhook_url": webhook_url,
|
|
74
|
+
"is_draft": is_draft,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
with api_client() as client:
|
|
78
|
+
response = client.post("/workflow", json=data)
|
|
79
|
+
response.raise_for_status()
|
|
80
|
+
return Workflow(**response.json())
|
|
@@ -62,7 +62,7 @@ class PoseAnalysisMDResult(WorkflowResult):
|
|
|
62
62
|
return [
|
|
63
63
|
TrajectoryResult(
|
|
64
64
|
uuid=t.uuid,
|
|
65
|
-
ligand_rmsd=t.
|
|
65
|
+
ligand_rmsd=t.binder_rmsd,
|
|
66
66
|
contacts=t.contacts,
|
|
67
67
|
sasa=t.sasa,
|
|
68
68
|
polar_sasa=t.polar_sasa,
|
|
@@ -104,7 +104,9 @@ class PoseAnalysisMDResult(WorkflowResult):
|
|
|
104
104
|
if not (uuid := self.minimized_protein_uuid):
|
|
105
105
|
return None
|
|
106
106
|
if "minimized_protein" not in self._cache:
|
|
107
|
-
self._cache["minimized_protein"] = retrieve_protein(
|
|
107
|
+
self._cache["minimized_protein"] = retrieve_protein(
|
|
108
|
+
uuid, workflow_uuid=self.workflow_uuid
|
|
109
|
+
)
|
|
108
110
|
return self._cache["minimized_protein"]
|
|
109
111
|
|
|
110
112
|
@property
|
|
@@ -165,7 +165,9 @@ class ProteinCofoldingResult(WorkflowResult):
|
|
|
165
165
|
if not (uuid := self.predicted_structure_uuid):
|
|
166
166
|
return None
|
|
167
167
|
if "predicted_structure" not in self._cache:
|
|
168
|
-
self._cache["predicted_structure"] = retrieve_protein(
|
|
168
|
+
self._cache["predicted_structure"] = retrieve_protein(
|
|
169
|
+
uuid, workflow_uuid=self.workflow_uuid
|
|
170
|
+
)
|
|
169
171
|
return self._cache["predicted_structure"]
|
|
170
172
|
|
|
171
173
|
def get_refined_structure(self) -> Protein | None:
|
|
@@ -178,7 +180,9 @@ class ProteinCofoldingResult(WorkflowResult):
|
|
|
178
180
|
if not (uuid := self.predicted_refined_structure_uuid):
|
|
179
181
|
return None
|
|
180
182
|
if "refined_structure" not in self._cache:
|
|
181
|
-
self._cache["refined_structure"] = retrieve_protein(
|
|
183
|
+
self._cache["refined_structure"] = retrieve_protein(
|
|
184
|
+
uuid, workflow_uuid=self.workflow_uuid
|
|
185
|
+
)
|
|
182
186
|
return self._cache["refined_structure"]
|
|
183
187
|
|
|
184
188
|
@property
|
|
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
import stjames
|
|
7
|
-
from stjames import GreedyClusteringSettings, KMeansClusteringSettings
|
|
7
|
+
from stjames import Binder, GreedyClusteringSettings, KMeansClusteringSettings
|
|
8
8
|
|
|
9
9
|
from ..folder import Folder
|
|
10
10
|
from ..protein import Protein, retrieve_protein
|
|
@@ -87,7 +87,9 @@ class ProteinMDResult(WorkflowResult):
|
|
|
87
87
|
if not (uuid := self.minimized_protein_uuid):
|
|
88
88
|
return None
|
|
89
89
|
if "minimized_protein" not in self._cache:
|
|
90
|
-
self._cache["minimized_protein"] = retrieve_protein(
|
|
90
|
+
self._cache["minimized_protein"] = retrieve_protein(
|
|
91
|
+
uuid, workflow_uuid=self.workflow_uuid
|
|
92
|
+
)
|
|
91
93
|
return self._cache["minimized_protein"]
|
|
92
94
|
|
|
93
95
|
@property
|
|
@@ -171,6 +173,10 @@ def submit_protein_md_workflow(
|
|
|
171
173
|
ionic_strength_M: float = 0.0,
|
|
172
174
|
water_buffer: float = 10.0,
|
|
173
175
|
save_solvent: bool = False,
|
|
176
|
+
num_solvent_to_save: int | None = None,
|
|
177
|
+
binder: Binder | None = None,
|
|
178
|
+
protein_restraint_cutoff: float | None = None,
|
|
179
|
+
protein_restraint_constant: float = 100,
|
|
174
180
|
analysis_interval_ps: float | None = None,
|
|
175
181
|
clustering: KMeansClusteringSettings | GreedyClusteringSettings | None = None,
|
|
176
182
|
validate_forcefield: bool = True,
|
|
@@ -198,13 +204,26 @@ def submit_protein_md_workflow(
|
|
|
198
204
|
:param ionic_strength_M: ionic strength of the solution, in M (molar)
|
|
199
205
|
:param water_buffer: amount of water to add around the protein, in A
|
|
200
206
|
:param save_solvent: whether solvent should be saved
|
|
207
|
+
:param num_solvent_to_save: keep this many solvent molecules nearest the binder, or all if None;
|
|
208
|
+
only meaningful when save_solvent is True and a binder is present
|
|
209
|
+
:param binder: optional binder specification (protein chains and/or small molecules).
|
|
210
|
+
When set, per-frame MM/GBSA scores are computed against the whole binder.
|
|
211
|
+
Per-frame binder RMSD is populated only when the binder is a single component
|
|
212
|
+
(one small molecule → heavy-atom RMSD; one binder chain → backbone N/CA/C/O RMSD);
|
|
213
|
+
it is empty for multi-molecule, multi-chain, or combined chain+molecule binders.
|
|
214
|
+
:param protein_restraint_cutoff: cutoff distance from the binder past which Cα atoms are
|
|
215
|
+
harmonically restrained, in Å; None disables restraints
|
|
216
|
+
:param protein_restraint_constant: force constant for Cα backbone restraints, in kcal/mol/Ų
|
|
201
217
|
:param analysis_interval_ps: Interval at which to compute per-frame SASA and polar SASA, in ps.
|
|
202
218
|
None disables those analyses.
|
|
203
219
|
:param clustering: How to cluster trajectory frames. None disables clustering; pass a
|
|
204
220
|
KMeansClusteringSettings (num_clusters) or GreedyClusteringSettings (cutoff_angstrom).
|
|
205
221
|
:param validate_forcefield: if True (default), validate the protein forcefield
|
|
206
222
|
compatibility before submitting. Raises an error early if the protein cannot
|
|
207
|
-
be parameterized or has clashing residues.
|
|
223
|
+
be parameterized or has clashing residues. Binder small molecules are skipped,
|
|
224
|
+
whether given by residue name or by index, since they are parameterized from their
|
|
225
|
+
SMILES rather than the protein forcefield; cofactors, metals, and glycans outside
|
|
226
|
+
the binder are still validated.
|
|
208
227
|
:param name: Name of the workflow.
|
|
209
228
|
:param folder_uuid: UUID of the folder to place the workflow in.
|
|
210
229
|
:param folder: Folder object to store the workflow in.
|
|
@@ -222,7 +241,10 @@ def submit_protein_md_workflow(
|
|
|
222
241
|
protein = protein.uuid
|
|
223
242
|
|
|
224
243
|
if validate_forcefield:
|
|
225
|
-
|
|
244
|
+
exclude_residues = (
|
|
245
|
+
list(binder.small_molecules) if binder is not None and binder.small_molecules else None
|
|
246
|
+
)
|
|
247
|
+
Protein(uuid=protein).validate_protein_forcefield(exclude_residues=exclude_residues)
|
|
226
248
|
|
|
227
249
|
workflow = stjames.ProteinMolecularDynamicsWorkflow(
|
|
228
250
|
protein=protein,
|
|
@@ -238,6 +260,10 @@ def submit_protein_md_workflow(
|
|
|
238
260
|
ionic_strength_M=ionic_strength_M,
|
|
239
261
|
water_buffer=water_buffer,
|
|
240
262
|
save_solvent=save_solvent,
|
|
263
|
+
num_solvent_to_save=num_solvent_to_save,
|
|
264
|
+
binder=binder,
|
|
265
|
+
protein_restraint_cutoff=protein_restraint_cutoff,
|
|
266
|
+
protein_restraint_constant=protein_restraint_constant,
|
|
241
267
|
analysis_interval_ps=analysis_interval_ps,
|
|
242
268
|
clustering=clustering,
|
|
243
269
|
)
|
|
@@ -90,7 +90,9 @@ class RelativeBindingFreeEnergyPerturbationResult(WorkflowResult):
|
|
|
90
90
|
@property
|
|
91
91
|
def protein(self) -> Protein:
|
|
92
92
|
"""Prepared protein structure used as the simulation target."""
|
|
93
|
-
|
|
93
|
+
protein = Protein(uuid=str(self._workflow.protein))
|
|
94
|
+
protein._workflow_uuid = self.workflow_uuid
|
|
95
|
+
return protein
|
|
94
96
|
|
|
95
97
|
@property
|
|
96
98
|
def settings(self) -> TMDRBFESettings:
|