Quickstart
Installation
pip install -e ".[all]"
Core dependencies are only rdkit, networkx, numpy, and scipy. The
amber, kartograf, and amber-mol2 extras pull in optional backends.
Example data
No binary files are checked in. Regenerate the benzamide example ligands from their SMILES:
python examples/data/make_conformers.py
The 16-ligand Tyk2 series used by The Tyk2 variant matrix is checked in directly, as
co-posed mol2 under examples/data/tyk2/, because the comparison it supports is only
meaningful on a real, consistently posed set.
Plan a network
rbfenet plan --ligands examples/data/benzamides.sdf \
--edges-per-ligand 2 --min-cycle-coverage 1.0 \
--max-softcore-atoms 12 --show-rejected \
--out network.json
From Python:
from rbfenetmap.core.options import NetworkOptions, SoftcorePolicy
from rbfenetmap.core.pipeline import build_network
from rbfenetmap.io.loaders import load_ligands
network = build_network(
load_ligands(["examples/data/benzamides.sdf"]),
mapper="mcss-e2",
network_options=NetworkOptions(
edges_per_ligand=2, softcore=SoftcorePolicy(max_softcore_atoms=12)
),
)
network.validate()
Ligands must be co-posed
Warning
Ligands must be supplied in a common binding-site frame. The core_rmsd
descriptor measures in-place deviation without superposition, precisely so that it
detects a mapping pairing atoms that occupy different parts of the pocket.
Independently embedded conformers share no frame, so every candidate edge between them
is rejected with core_geometry_mismatch – correctly, but uselessly.
examples/data/make_conformers.py shows the constrained-embedding pattern.
If your structures were prepared separately – set up individually for ABFE runs, say, and written to mol2 from their own Amber topologies – then their conformers are real bound poses and only the frames disagree. Aligning ligands recovers the common frame rather than asking you to re-prepare them.
Aligning ligands
--align rigidly superposes the set into a common frame before anything is mapped. It is
off by default, and should stay off for ligands that were prepared together: those are
already co-posed, and aligning them would paper over a genuine pose problem instead of
revealing it.
rbfenet plan --ligands prepared_from_abfe/ --align \
--write-aligned aligned/ --out network.json
Each ligand is fitted onto an already-aligned neighbour through their maximum common
substructure and moved there rigidly. Neighbour rather than root: the walk order is a
maximum spanning tree over fingerprint similarity, so a ligand is fitted onto the one it
most resembles. For a set too diverse for any substructure to bite on, --align o3a
switches to Open3DAlign, which needs no shared substructure but gives no auditable set of
paired atoms in exchange.
The report tells you whether it worked, and goes to stderr so a --format json run stays
machine-readable:
ligand reference fit atoms rmsd note
------- --------- --------- ----- ---------
bza_CF3 - 0 - reference
bza_Cl bza_F 10 0.132
bza_H bza_Cl 9 0.030
Read both columns. A small fit atoms count deserves suspicion even when the RMSD looks
good – three atoms determine a rigid body, but only just – and a ligand that could not be
fitted at all is reported separately and left in its own frame, where its edges will still
be rejected for geometry.
Then look at the structures, because a plausible table can still hide a flipped ring:
pymol aligned/*.sdf # one object per ligand, not one object with N states
Note
Rigid alignment recovers a common frame. It cannot recover a common
conformation. Each independently relaxed structure keeps its own ring puckers,
exocyclic torsions, and bond-length noise, so a residual core_rmsd survives alignment
and should – expect more of it than a constrained-embedded series would show, and expect
the default --core-rmsd-threshold 2.0 to be doing real work rather than waving
everything through. Raise it only after looking at the actual distribution:
rbfenet score --ligands prepared_from_abfe/ --align --show-rejected --explain
What alignment does not touch is the atom mapping. Mappings are index-based, so Amber
masks, exported edge lists, and every depiction are identical with and without --align;
it cannot corrupt a downstream setup. What it does change is every quantity measured from
coordinates – core_rmsd, the geometry gate, the RMSD terms in both scorers – and the
molecules embedded in network.json, which carry the aligned frame from then on. Each
ligand records what was done to it under metadata["alignment"], and that survives the
network round trip.