{"id":29950717,"url":"https://github.com/mlund/duello","last_synced_at":"2026-03-12T02:02:01.272Z","repository":{"id":302033932,"uuid":"913180765","full_name":"mlund/duello","owner":"mlund","description":"Osmotic second virial coefficient (𝐵₂) and dissociation constant (𝐾𝑑) for two rigid macromolecules","archived":false,"fork":false,"pushed_at":"2026-03-05T07:28:53.000Z","size":1847,"stargazers_count":1,"open_issues_count":4,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-09T10:34:35.050Z","etag":null,"topics":["chemistry","intermolecular-interactions","protein-protein-interaction"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlund.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":".zenodo.json","notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-07T07:30:14.000Z","updated_at":"2026-03-05T07:28:02.000Z","dependencies_parsed_at":"2025-08-18T13:22:22.136Z","dependency_job_id":"9d2c1897-38f6-41e1-b2c8-41e20921a4db","html_url":"https://github.com/mlund/duello","commit_stats":null,"previous_names":["mlund/duello"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mlund/duello","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fduello","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fduello/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fduello/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fduello/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlund","download_url":"https://codeload.github.com/mlund/duello/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fduello/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30412239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T00:40:14.898Z","status":"online","status_checked_at":"2026-03-12T02:00:07.260Z","response_time":114,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chemistry","intermolecular-interactions","protein-protein-interaction"],"created_at":"2025-08-03T11:18:54.833Z","updated_at":"2026-03-12T02:02:01.267Z","avatar_url":"https://github.com/mlund.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/duello-logo.png\" alt=\"crates.io\", height=\"300\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://doi.org/10/p5d4\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/doi-10.26434%2Fchemrxiv--2025--0bfhd-lightgrey\" alt=\"DOI:10.26434/chemrxiv-2025-0bfhd\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://doi.org/10.5281/zenodo.15772003\"\u003e\n        \u003cimg src=\"https://zenodo.org/badge/DOI/10.5281/zenodo.15772003.svg\" alt=\"Zenodo\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://colab.research.google.com/github/mlund/duello/blob/master/scripts/colab.ipynb\"\u003e\n        \u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/mlund/duello/actions/workflows/rust.yml\"\u003e\n        \u003cimg src=\"https://github.com/mlund/duello/actions/workflows/rust.yml/badge.svg\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n-----\n\n\u003cp align = \"center\"\u003e\n\u003cb\u003eDuello\u003c/b\u003e\u003c/br\u003e\n\u003ci\u003eVirial Coefficient and Dissociation Constant Estimation for Rigid Macromolecules\u003c/i\u003e\n\u003c/p\u003e\n\n-----\n\n# Introduction\n\nDuello is a tool to calculate the potential of mean force (PMF) between two rigid bodies, performing a\nstatistical mechanical average over inter-molecular orientations using subdivided icosahedrons.\nFor each mass center separation, _R_, the static contribution to the partition function,\n$\\mathcal{Z}(R) = \\sum_{\\mathbf{\\Omega}} e^{-V(R,\\mathbf{\\Omega})/k_BT}$, is explicitly\nevaluated to obtain the potential of mean force,\n$w(R) = -k_BT \\ln \\mathcal{Z}(R)$\nand the thermally averaged energy,\n\n$$\nU(R) = \\frac{\\sum V(R,\\mathbf{\\Omega}) e^{-V(R,\\mathbf{\\Omega})/k_BT}} {\\mathcal{Z}(R)}\n$$\n\nwhere $V(R,\\mathbf{\\Omega})$ is the total inter-body interaction energy and $\\mathbf{\\Omega}$ represents a 5D angular space (_e.g._ two spherical coordinates for each body plus a dihedral angle around the connection line).\n\nThe osmotic second virial coefficient, which has dimensions of _volume_, reports on exactly two-body interactions:\n\n$$\n\\begin{align}\nB_2 \u0026 = -\\frac{1}{16\\pi^2} \\int_{\\mathbf{\\Omega}} \\int_0^{\\infty}\n\\left (\n  e^{-V(R,\\mathbf{\\Omega})/k_BT} - 1\n\\right )\nR^2 dR d\\mathbf{\\Omega}\\\\\n\u0026 =  -2\\pi \\int_0^{\\infty} \\left ( e^{-w(R)/k_BT} -1 \\right )R^2 dR \\\\\n\u0026 = B_2^{hs} -2\\pi \\int_{\\sigma}^{\\infty} \\left ( e^{-w(R)/k_BT} -1 \\right )R^2 dR\\\\\n\\end{align}\n$$\n\nwhere $B_2^{hs} = 2\\pi\\sigma^3/3$ is the hard-sphere contribution and $\\sigma$ is a distance\nof closest approach where $w(R\\lt \\sigma)=\\infty$ is assumed.\nFor systems with net attractive interactions, the dissociation constant, $K_d$, can be estimated by,\n\n$$\nK_d^{-1} = 2 N_A\\left (B_2^{hs} - B_2\\right )\n$$\n\n\u003cp align=\"center\"\u003e\n  \u003cimg height=\"200\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/8d68eb85-6aa1-49e9-9d8d-75f91cdf1687\" /\u003e\n\u003c/p\u003e\n\n\n# Installation\n\nBinary packages are available through PyPI.org:\n\n```console\npip install duello\n```\n\nIf you have a [Rust toolchain](https://www.rust-lang.org/learn/get-started) installed,\nyou may alternatively build and install from source:\n\n```sh\ncargo install --git https://github.com/mlund/duello\n```\n\n# Usage\n\nThe command-line tool `duello` does the 6D scanning and calculates\nthe angularly averaged potential of mean force, _A(R)_ which\nis used to derive the 2nd virial coefficient and twobody dissociation constant, $K_d$.\nThe two input structures should be in `.xyz` format and all particle names must\nbe defined in the topology file under `atoms`.\nThe topology also defines the particular pair-potential to use, see below.\nNote that currently, a coulomb potential is automatically added and should\nhence _not_ be specified in the topology.\n\n```sh\nduello scan \\\n    --mol1 cppm-p18.xyz \\\n    --mol2 cppm-p18.xyz \\\n    --rmin 37 --rmax 50 --dr 0.5 \\\n    --top topology.yaml \\\n    --resolution 0.8 \\\n    --cutoff 1000 \\\n    --molarity 0.05 \\\n    --temperature 298.15 \\\n    --backend auto \\\n    --grid \"type=powerlaw2,size=2000,shift=true\"\n```\n\n## Spline Grid Options\n\nThe `--grid` option controls interpolation of pair potentials:\n\n| Key     | Values               | Default     | Description                              |\n|---------|----------------------|-------------|------------------------------------------|\n| `type`  | `powerlaw2`, `invr2` | `powerlaw2` | Grid spacing (invr2 avoids sqrt in eval) |\n| `size`  | integer              | `2000`      | Number of grid points                    |\n| `shift` | `true`, `false`      | `true`      | Shift energy to zero at cutoff           |\n\nExample: `--grid \"type=invr2,size=1500,shift=false\"`\n\n## Backend Performance\n\nThe program is written in Rust and attempts to use either GPU or all available CPU cores.\nThe following backends are available, with performance measured on the Calvados3 lysozyme example\n(2.4M poses, 128 atoms per molecule, Apple M4):\n\n| Backend     | Description                    | Poses/ms | Speedup |\n|-------------|--------------------------------|----------|---------|\n| `reference` | Exact potentials (validation)  |       48 |    1.0x |\n| `cpu`       | Splined potentials             |      102 |    2.1x |\n| `simd`      | NEON (aarch64) / AVX2 (x86)    |      131 |    2.7x |\n| `gpu`       | wgpu compute shaders           |     1065 |     22x |\n\nThe `auto` backend (default) selects GPU if available, otherwise SIMD.\nAll but `reference` use Cubic Hermite splines for pair potentials.\n\n## Preparing PDB files\n\nThe following uses `pdb2xyz` to create a coarse grained XYZ file and Calvados topology for Duello:\n\n```sh\npip install pdb2xyz\npdb2xyz -i 4lzt.pdb -o 4lzt.xyz --pH 7.0 --sidechains\nduello scan \\\n  -1 4lzt.xyz -2 4lzt.xyz \\\n  --rmin 24 --rmax 80 --dr 0.5 \\\n  --resolution 0.6 \\\n  --top topology.yaml \\\n  --molarity 0.05\n```\n\nIf `pdb2xyz` give errors, you may be able to correct your PDB file with\n[pdbfixer](https://github.com/openmm/pdbfixer?tab=readme-ov-file).\n\n## Examples\n\nReady run scripts examples are provided in the `scripts/` directory:\n\nCommand                | Description\n---------------------- | ------------------------------------------------------------\n`scripts/cppm.sh`      | Spherical, multipolar particles using the CPPM model\n`scripts/calvados3.sh` | Two coarse grained lysozyme molecules w. Calvados3 interactions\n\n\n## Interaction models\n\nEach macromolecule is represented by a rigid constellation of beads with\nproperties defined under `atoms` in the topology file.\nThe inter-molecular energy, $V(R,\\Omega)$ is calculated by summing all pairwise interactions\nbetween beads using a customizable pair potential, $u_{ij}$.\nIf needed, different pair-potentials can be explicitly defined for\nspecific atom pairs.\n\nThe provided examples illustrate the following schemes:\n\n- Screened `Coulomb` + `AshbaughHatch`, for the Calvados model.\n- Screened `Coulomb` + `WeeksChandlerAndersen` for the CPPM model.\n\nMany more pair-potentials are available through the\n[`interatomic`](https://docs.rs/interatomic/latest/interatomic/twobody/index.html) library,\n_e.g._ `LennardJones`, `HardSphere` etc.\n\n__Warning:__ The electrostatic term, `Coulomb` is\nalways automatically added and should therefore _not_ be specified in the topology.\n\n# Development\n\nThis is for development purposes only and details how to create and publish a\nbinary package on pipy.org.\n\n## Create `pip` package using Maturin via a Docker image:\n\nRun this on MacOS, linux (x86 and arm) to get all architectures:\n\n```sh\ndocker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin::v1.11.5 publish -u __token__ -p PYPI_TOKEN\n```\n\n\nFor local Maturin installs, follow the steps below.\n\n```sh\npip install ziglang pipx\npipx install maturin # on ubuntu; then restart shell\nmaturin publish -u __token__ -p PYPI_TOKEN --target=x86_64-unknown-linux-gnu --zig\n```\n\nMacOS targets can be generated without `--zig` using the targets\n`x86_64-apple-darwin` and `aarch64-apple-darwin`.\n\n```sh\nrustup target list\nrustup target add x86_64-apple-darwin\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlund%2Fduello","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlund%2Fduello","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlund%2Fduello/lists"}