Skip to content

Commit

Permalink
document vdwradii preset and how to change parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
cbouy committed Oct 24, 2024
1 parent 026a865 commit fd3dac7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `VdWContact` now accepts a `preset` parameter to easily use different van der Waals radii values:
one of `mdanalysis` (default), `rdkit`, or `csd`.
- `IFP.interactions()` iterator that yields all interaction data for a given frame in
a single flat structure. This makes iterating over the `fp.ifp` results a bit
easier / less nested.
Expand Down
6 changes: 5 additions & 1 deletion prolif/fingerprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ class Fingerprint:
PiStacking, Anionic, Cationic, CationPi, PiCation, VdWContact.
parameters : dict, optional
New parameters for the interactions. Mapping between an interaction name and a
dict of parameters as they appear in the interaction class.
dict of parameters as they appear in the interaction class (see the
:mod:`prolif.interactions` module's documentation for all classes parameters)::
>>> fp = plf.Fingerprint(parameters={"Hydrophobic": {"distance": 3.8}})
count : bool
For a given interaction class and pair of residues, there might be multiple
combinations of atoms that satisfy the interaction constraints. This parameter
Expand Down
21 changes: 19 additions & 2 deletions prolif/interactions/interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,26 @@ def __init__(
else:
raise ValueError("`tolerance` must be 0 or positive")
self._vdw_cache = {}
preset_vdw = VDW_PRESETS[preset.lower()]
self.preset = preset.lower()
preset_vdw = VDW_PRESETS[self.preset]
self.vdwradii = {**preset_vdw, **vdwradii} if vdwradii else preset_vdw

def _get_radii_sum(self, atom1: str, atom2: str) -> float:
try:
return self.vdwradii[atom1] + self.vdwradii[atom2]
except KeyError:
missing = []
if atom1 not in self.vdwradii:
missing.append(f"{atom1!r}")
if atom2 not in self.vdwradii:
missing.append(f"{atom2!r}")
raise ValueError(
f"van der Waals radius for atom {' and '.join(missing)} not found."
" Either specify the missing radii in the `vdwradii` parameter for the"
" VdWContact interaction, or use a preset different from the current"
f" {self.preset!r}."
) from None

def detect(self, ligand, residue):
lxyz = ligand.GetConformer()
rxyz = residue.GetConformer()
Expand All @@ -490,7 +507,7 @@ def detect(self, ligand, residue):
try:
vdw = self._vdw_cache[elements]
except KeyError:
vdw = self.vdwradii[lig] + self.vdwradii[res] + self.tolerance
vdw = self._get_radii_sum(lig, res) + self.tolerance
self._vdw_cache[elements] = vdw
dist = lxyz.GetAtomPosition(la.GetIdx()).Distance(
rxyz.GetAtomPosition(ra.GetIdx()),
Expand Down
7 changes: 7 additions & 0 deletions tests/test_interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@ def test_vdwcontact_preset(self, any_mol, any_other_mol, preset):
assert next(metadata, None) is not None
assert vdw.vdwradii == VDW_PRESETS[preset]

def test_vdwcontact_radii_missing(self):
vdw = VdWContact(preset="mdanalysis")
with pytest.raises(
ValueError, match=r"van der Waals radius for atom .+ not found"
):
vdw._get_radii_sum("X", "Y")

@pytest.mark.parametrize(
("interaction_qmol", "smiles", "expected"),
[
Expand Down

0 comments on commit fd3dac7

Please sign in to comment.