MolecularDiffusion.modules.models.ligandiff_multi.utils¶
Geometry helpers for multi-LigandDiff’s 20-metal scaffold decomposition.
Everything else multi-LigandDiff needs at runtime – EDM, Dynamics,
remove_partial_mean_with_mask, FoundNaNException – is imported
unchanged from MolecularDiffusion.modules.models.ligandiff.
This module exists for one reason: models/ligandiff/utils.py pins
METAL_Z to LigandDiff’s ten metals as a module constant, and its
ligand_groups_from_geometry reads it with no override parameter.
multi-LigandDiff supports twenty (src/const.py:15), so the
decomposition is reimplemented here against the wider set rather than by
editing a file the already-working ligandiff integration depends on.
coord_sites_from_geometry is genuinely new: multi-LigandDiff adds a
per-atom “coordinates the metal” flag (coord_site) that LigandDiff has no
analogue for. Upstream derives it from molSimplify’s ligcon
(generate.py:101-106); molSimplify is not a dependency here and generation
input is a bare .xyz, so it is recovered from the covalent-contact
criterion instead – the same substitution ligandiff already validated for
ligand_group.
Attributes¶
Functions¶
|
Recover the per-atom |
|
Split |
|
Recover the |
Module Contents¶
- MolecularDiffusion.modules.models.ligandiff_multi.utils.coord_sites_from_geometry(coords: torch.Tensor, charges: torch.Tensor, scale_factor: float = 1.25) torch.Tensor¶
Recover the per-atom
coord_siteflag from geometry alone.coord_site[i] == 1iff atomiis a non-metal in covalent contact with a metal, i.e. it occupies one of the metal’s coordination sites. Upstream gets the same set from molSimplify’sligcon(generate.py:101-106).Returns
(N,)float 0/1; metal rows are always 0.
- MolecularDiffusion.modules.models.ligandiff_multi.utils.distribute_atoms(n_new: int, denticities: List[int]) List[int]¶
Split
n_newnew atoms across ligands of the given denticities.Each ligand gets at least
datoms (it has to supplyddonor atoms); the surplus is dealt out round-robin. Upstream instead draws each ligand’s size independently (generate.py:187-192) and lets the total fall out; the platform fixes the total viamol_size/ the node-size distribution, so the split is derived from it rather than the reverse.
- MolecularDiffusion.modules.models.ligandiff_multi.utils.ligand_groups_from_geometry(coords: torch.Tensor, charges: torch.Tensor, n_slots: int = 6, scale_factor: float = 1.25) torch.Tensor¶
Recover the
ligand_groupone-hot from geometry alone.Same construction as
models/ligandiff/utils.py’s function of the same name, over the 20-metalMETAL_Zabove: delete the metal(s), take the connected components of the covalent-radius contact graph, one slot per component. Components beyondn_slotsfold into the last slot.Returns
(N, n_slots)float one-hot; metal rows are all zero. A metal-only scaffold (upstream’s[]_[...]total-generation case) correctly yields the all-zero matrix, leaving every slot free.