Skip to content

Enabling automatic param/top generation for ligands embedded in a larger system and multiple ligands - #1646

Open
amjjbonvin wants to merge 13 commits into
mainfrom
prodrg
Open

Enabling automatic param/top generation for ligands embedded in a larger system and multiple ligands#1646
amjjbonvin wants to merge 13 commits into
mainfrom
prodrg

Conversation

@amjjbonvin

Copy link
Copy Markdown
Member

What does this PR do and why?

topoaa's autotoppar path calls libligand.run_prodrg(model, ...) on the entire PDB. When an unknown ligand is embedded in a larger system (protein/ligand complex, or e.g. a protein in a membrane with many lipid copies), PRODRG received the whole system and failed to generate topology/parameter files.

src/haddock/libs/libligand.py was modified to deal with this cases.

  1. New extract_ligand() — strips out everything except the requested ligand residues, and keeps only the first copy of each residue name (a ligand present in N copies, e.g. 434× DPP, shares one topology, so only one copy is sent to PRODRG).
  2. Refactored run_prodrg() — now accepts ligand_resnames:
    - Extracted the single-molecule PRODRG execution into a _run_prodrg_single() helper.
    - When multiple distinct ligands are present (e.g. DPP + DPC), PRODRG runs once per ligand and the resulting .top files are concatenated into one, and the .param files into one.
    - De-duplicates resnames so a repeated ligand triggers a single run.
    - With ligand_resnames=None, behavior is unchanged (whole file → PRODRG).
  3. topoaa/init.py — passes the already-computed unknown resnames into run_prodrg(..., ligand_resnames=unknown).
  4. to avoid overlap in parameters, each ligand parametrised receives a unique one character identifier (also not overlapping with what is used in cofactors.top. This uses the CNSSEP option of PRODRG
  5. modified the haddock3-score cli to have autotoppar=true by default in order to be able to handle ligands.
    Verification
  • Added tests in tests/test_libligand.py (extraction, single-copy, complex success, multi-ligand concatenation, dedup) — 22 passed, ruff clean, topoaa tests still pass.
  • CHANGELOG.md updated.

How was this tested?

Tested using examples of proteins contain a ligand (e.g. 1AZS_l_u.pdb from the BM5 benchmark).

AI assistance

Claude was used to modify the ligand handling machinery and add tests.

Checklist

  • Tests cover the new and/or changed code
  • Documentation updated if needed (also in the haddock3 user-manual
  • CHANGELOG.md updated for user-facing changes

Related issues

#1645

Notes for reviewers

You can test it using for example haddock3-score

amjjbonvin and others added 7 commits August 1, 2026 23:10
When an unknown ligand is embedded in a larger system (e.g. a
protein/ligand complex or a membrane with many lipid copies), the whole
PDB was passed to PRODRG, which only handles a single small molecule and
failed to generate topology/parameter files.

- extract_ligand(): strip everything except the ligand residues, keeping
  only the first copy of each residue name (copies share one topology).
- run_prodrg(): accept ligand_resnames and run PRODRG once per distinct
  ligand, concatenating the resulting .top and .param files. Factored the
  single-molecule execution into _run_prodrg_single().
- topoaa: pass the detected unknown residue names to run_prodrg().
- Tests for extraction, single-copy, complex success, multi-ligand
  concatenation, and resname de-duplication.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set autotoppar=true for the topoaa step run by haddock3-score so that a
complex containing an unknown ligand has its topology and parameters
generated on-the-fly with PRODRG, instead of failing topology generation.
When ligand_top_fname/ligand_param_fname are supplied they still take
precedence, and standard systems are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply ruff format and fix E721 (use `is` for the bool type comparison).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A missing comma had merged "-k" "--keep-all" into a single option string
"-k--keep-all", so the -k short flag was never registered. Split into two
separate option strings so -k works as documented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PRODRG encodes its CNSSEP character as the second character of every atom
type name it generates. When several distinct ligands are auto-generated,
each is now run with a unique CNSSEP character so their atom types do not
overlap once the topologies/parameters are concatenated.

The characters are drawn from a pool of uppercase letters and digits that
excludes the separators already used by the built-in cofactors.top
topology (computed at runtime), so auto-generated ligand atom types can no
longer clash with the cofactor ones.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Single auto-generated ligands are now also assigned a CNSSEP character from
the cofactor-safe pool, so their prodrg atom types cannot clash with the
built-in cofactors.top topology either.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@amjjbonvin amjjbonvin self-assigned this Aug 2, 2026
@amjjbonvin amjjbonvin added enhancement Improving something in the codebase m|topoaa topoaa module python Pull requests that update python code AI Changes authored or assisted by AI labels Aug 2, 2026
amjjbonvin and others added 4 commits August 2, 2026 10:56
Switch the new run_prodrg/extract_ligand complex tests to the 1AZS_l_u.pdb
protein-ligand complex (unknown ligand GSP) and add it to the golden data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
haddock3-score now runs topoaa with autotoppar=true, and alascan scores via
cli_score.main. A protein-ligand complex scored without user-provided
topo/param therefore now keeps the ligand (topology generated by PRODRG)
instead of dropping it, so the test asserts the ligand is retained.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CNS can write a ligand atom's element as a two-letter metal: a phosphate
beta-phosphorus named PB ends up with element Pb (lead), which PRODRG
rejects. When extracting a ligand, atoms whose element is an unsupported
two-letter metal symbol (read from ion.top, excluding the PRODRG-supported
halides Cl/Br) are collapsed back to their real single-letter element and
their name re-justified. Isolated ions never reach PRODRG, so such a metal
element on a ligand atom is always a mislabelling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
amjjbonvin and others added 2 commits August 3, 2026 16:59
Replace magic PDB column slices in _demetalise_atom and extract_ligand
with the named slc_* constants from libpdb (matching gear/preprocessing),
and collapse the first-copy insert-then-compare into a single setdefault.
No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Changes authored or assisted by AI enhancement Improving something in the codebase m|topoaa topoaa module python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant