diff --git a/pixi.lock b/pixi.lock index c8af0d7..2b8a679 100644 --- a/pixi.lock +++ b/pixi.lock @@ -55,9 +55,9 @@ environments: - 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 - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e1/11/1a9a693e424b2a75755d56ecb67ccc6f77e6e5bb7417dec5e73d9c410314/rdkit-2026.3.4-cp314-cp314-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl - 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: - pypi: https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/bf/64/0e215f2048dd11a55bb989ed41b3585ef57452404e638d703a211a3e4157/numpy-2.5.1-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl dev: @@ -192,7 +192,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/c7/7b/14882602ddee241d7984a742fcb423cb4a30fb0d6efc546ac3129fba475a/python_discovery-1.5.0-py3-none-any.whl - 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 - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl @@ -202,6 +201,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e1/11/1a9a693e424b2a75755d56ecb67ccc6f77e6e5bb7417dec5e73d9c410314/rdkit-2026.3.4-cp314-cp314-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl @@ -296,7 +296,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/c7/7b/14882602ddee241d7984a742fcb423cb4a30fb0d6efc546ac3129fba475a/python_discovery-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl @@ -307,6 +306,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl @@ -820,7 +820,7 @@ packages: name: rowan-python requires_dist: - httpx - - stjames>=0.0.236 + - stjames>=0.0.237 - setuptools - rdkit - nest-asyncio @@ -1706,17 +1706,6 @@ packages: version: 2.3.0 sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/d0/fb/be7d2e16e6c6143cd6834cd488d990d75352a5c9cdad6d5c615b5f01d736/stjames-0.0.236-py3-none-any.whl - name: stjames - version: 0.0.236 - sha256: ea1459a5d0e0ccd206e5a387b201beec5e60ad6bc4f15dbcf649e2d4667fc40c - requires_dist: - - pydantic>=2.4 - - numpy - - requests - - more-itertools - - rdkit ; extra == 'rdkit' - requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl name: colorama version: 0.4.6 @@ -1803,6 +1792,17 @@ packages: - mkdocs-section-index ; extra == 'docs' - mkdocs-literate-nav ; extra == 'docs' requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/df/95/bdd01bbd523a63b113407c34c99af8495daa4651757cc28f3fabc393d131/stjames-0.0.237-py3-none-any.whl + name: stjames + version: 0.0.237 + sha256: 790c32bdc829efe52b7ccc442083d0d95fc01587d4063a08ea73cd9f686f6d21 + requires_dist: + - pydantic>=2.4 + - numpy + - requests + - more-itertools + - rdkit ; extra == 'rdkit' + requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl name: packaging version: '26.2' diff --git a/pyproject.toml b/pyproject.toml index a9b47bd..926759f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ authors = [ ] dependencies = [ "httpx", - "stjames>=0.0.236", + "stjames>=0.0.237", "setuptools", "rdkit", "nest-asyncio", diff --git a/rowan/__init__.py b/rowan/__init__.py index 0bcf357..461b81c 100644 --- a/rowan/__init__.py +++ b/rowan/__init__.py @@ -3,6 +3,7 @@ from stjames import ( Atom, BandStructure, + Binder, BindingPoseContact, HydrationBridgeResidue, HydrationSite, diff --git a/rowan/workflows/pose_analysis_md.py b/rowan/workflows/pose_analysis_md.py index 2d85433..6afe99c 100644 --- a/rowan/workflows/pose_analysis_md.py +++ b/rowan/workflows/pose_analysis_md.py @@ -62,7 +62,7 @@ def trajectories(self) -> list[TrajectoryResult]: return [ TrajectoryResult( uuid=t.uuid, - ligand_rmsd=t.ligand_rmsd, + ligand_rmsd=t.binder_rmsd, contacts=t.contacts, sasa=t.sasa, polar_sasa=t.polar_sasa, diff --git a/rowan/workflows/protein_md.py b/rowan/workflows/protein_md.py index e286ced..dbac958 100644 --- a/rowan/workflows/protein_md.py +++ b/rowan/workflows/protein_md.py @@ -4,7 +4,7 @@ from pathlib import Path import stjames -from stjames import GreedyClusteringSettings, KMeansClusteringSettings +from stjames import Binder, GreedyClusteringSettings, KMeansClusteringSettings from ..folder import Folder from ..protein import Protein, retrieve_protein @@ -171,6 +171,10 @@ def submit_protein_md_workflow( ionic_strength_M: float = 0.0, water_buffer: float = 10.0, save_solvent: bool = False, + num_solvent_to_save: int | None = None, + binder: Binder | None = None, + protein_restraint_cutoff: float | None = None, + protein_restraint_constant: float = 100, analysis_interval_ps: float | None = None, clustering: KMeansClusteringSettings | GreedyClusteringSettings | None = None, validate_forcefield: bool = True, @@ -198,6 +202,16 @@ def submit_protein_md_workflow( :param ionic_strength_M: ionic strength of the solution, in M (molar) :param water_buffer: amount of water to add around the protein, in A :param save_solvent: whether solvent should be saved + :param num_solvent_to_save: keep this many solvent molecules nearest the binder, or all if None; + only meaningful when save_solvent is True and a binder is present + :param binder: optional binder specification (protein chains and/or small molecules). + When set, per-frame MM/GBSA scores are computed against the whole binder. + Per-frame binder RMSD is populated only when the binder is a single component + (one small molecule → heavy-atom RMSD; one binder chain → backbone N/CA/C/O RMSD); + it is empty for multi-molecule, multi-chain, or combined chain+molecule binders. + :param protein_restraint_cutoff: cutoff distance from the binder past which Cα atoms are + harmonically restrained, in Å; None disables restraints + :param protein_restraint_constant: force constant for Cα backbone restraints, in kcal/mol/Ų :param analysis_interval_ps: Interval at which to compute per-frame SASA and polar SASA, in ps. None disables those analyses. :param clustering: How to cluster trajectory frames. None disables clustering; pass a @@ -222,7 +236,14 @@ def submit_protein_md_workflow( protein = protein.uuid if validate_forcefield: - Protein(uuid=protein).validate_protein_forcefield() + exclude_residue_names = ( + [name for name in binder.small_molecules if isinstance(name, str)] + if binder is not None and binder.small_molecules + else None + ) + Protein(uuid=protein).validate_protein_forcefield( + exclude_residue_names=exclude_residue_names + ) workflow = stjames.ProteinMolecularDynamicsWorkflow( protein=protein, @@ -238,6 +259,10 @@ def submit_protein_md_workflow( ionic_strength_M=ionic_strength_M, water_buffer=water_buffer, save_solvent=save_solvent, + num_solvent_to_save=num_solvent_to_save, + binder=binder, + protein_restraint_cutoff=protein_restraint_cutoff, + protein_restraint_constant=protein_restraint_constant, analysis_interval_ps=analysis_interval_ps, clustering=clustering, )