Repository: chemosim-lab/ProLIF
Pull request #253: add uncommon elements usage for vdwcontact in ligand-protein tutorial
Author: login: yuyuan871111
Created: 2025-03-24T18:24:31Z | Merged: 2025-03-30T15:47:14Z

add information in the ligand-protein tutorial to highlight alternative preset for the vdwcontact
related to #222 #223


Diff:
diff --git a/docs/notebooks/advanced.ipynb b/docs/notebooks/advanced.ipynb
index 79306e6e..958e7272 100644
--- a/docs/notebooks/advanced.ipynb
+++ b/docs/notebooks/advanced.ipynb
@@ -36,7 +36,11 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "metadata": {"tags": ["remove-cell"]},
+   "metadata": {
+    "tags": [
+     "remove-cell"
+    ]
+   },
    "outputs": [],
    "source": [
     "# Hidden cell to ensure we can run the example with a custom interaction on Windows\n",
@@ -89,18 +93,22 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "These method will yield all occurences for that specific interaction between 2 residues (1 for the ligand and 1 for the protein).\n",
-    "\n",
-    "In this example, we'll reparametrize the hydrophobic interaction with a shorter\n",
-    "distance and see how this affects the number of occurences of an interaction for a\n",
-    "given pair of residues. \n",
+    "These methods will yield all occurences for that specific interaction between 2 residues (1 for the ligand and 1 for the protein).\n",
     "\n",
     ":::{note}\n",
     "To know which parameters are available for interactions, see the\n",
-    "{mod}`prolif.interactions` module.\n",
-    ":::\n",
+    "{mod}`~prolif.interactions.interactions` module.\n",
+    ":::\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Example 1: modifying `distance` in `Hydrophobic`\n",
+    "In this example, we'll reparametrize the hydrophobic interaction with a shorter distance and see how this affects the number of occurences of an interaction for a given pair of residues.\n",
     "\n",
-    "Let's start with a test case. With the default parameters, TYR109 is interacting with our ligand in 4 different occasions:"
+    "Let’s start with a test case. With the default parameters in {class}`~prolif.interactions.interactions.Hydrophobic` class, TYR109 is interacting with our ligand in 4 different occasions:"
    ]
   },
   {
@@ -110,9 +118,13 @@
    "outputs": [],
    "source": [
     "fp = plf.Fingerprint()\n",
+    "\n",
+    "# calculate hydrophobic interactions betweem first ligand pose and TYR109\n",
     "hydrophobic_interactions_tyr109 = list(\n",
     "    fp.hydrophobic(ligand_mol[0], protein_mol[\"TYR109.A\"])\n",
     ")\n",
+    "\n",
+    "# print the number of hydrophobic interactions\n",
     "len(hydrophobic_interactions_tyr109)"
    ]
   },
@@ -120,10 +132,9 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Now we'll simply change the distance threshold to `4.0` instead of the default `4.5`. To do this we simply provide the `parameters` argument with a dictionnary mapping the name of the interaction to reconfigure with updated parameters.\n",
+    "Now, we’ll simply change the distance threshold to `4.0` instead of the default `4.5`. To do this, we simply provide the `parameters` argument with a dictionary mapping the name of the interaction to reconfigure with updated parameters.\n",
     "\n",
-    "This modification will affect all the interaction analysis code run by the fingerprint object, i.e. when using\n",
-    "`run` or `run_from_iterable`."
+    "This modification will affect all the interaction analysis code run by the fingerprint object, i.e. when using `run` or `run_from_iterable`."
    ]
   },
   {
@@ -133,9 +144,13 @@
    "outputs": [],
    "source": [
     "fp = plf.Fingerprint(parameters={\"Hydrophobic\": {\"distance\": 4.0}})\n",
+    "\n",
+    "# calculate hydrophobic interactions betweem first ligand pose and TYR109\n",
     "hydrophobic_interactions_tyr109 = list(\n",
     "    fp.hydrophobic(ligand_mol[0], protein_mol[\"TYR109.A\"])\n",
     ")\n",
+    "\n",
+    "# print the number of hydrophobic interactions\n",
     "len(hydrophobic_interactions_tyr109)"
    ]
   },
@@ -143,8 +158,159 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "As you can see, by reducing the distance threshold the interaction between our ligand\n",
-    "and TYR109 is now ignored."
+    "As you can see, by reducing the distance threshold, the hydrophobic interaction between our ligand and TYR109 is now ignored."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Example 2: modifying `preset` in `VdWContact`\n",
+    "Here, we show another example to modify the `preset` parameter within the {class}`~prolif.interactions.interactions.VdWContact` class to use a different set of van der Waals radii definitions. This example is particularly useful when your topology includes transition metals or other less common elements (such as cobalt in vitamin B12) that are not covered by the default preset (`mdanalysis`).\n",
+    "\n",
+    "Let's start with a test case. First, we check the default preset of the `vdwradii`.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"VdWContact\"])\n",
+    "\n",
+    "default_vdwradii = fp.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(default_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the preset\n",
+    "default_vdw_elements = set(default_vdwradii.keys())\n",
+    "print(len(default_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next, we create a new fingerprint object with the `preset` of `rdkit` and check its `vdwradii`. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp_modified = plf.Fingerprint(\n",
+    "    [\"VdWContact\"], parameters={\"VdWContact\": {\"preset\": \"rdkit\"}}\n",
+    ")\n",
+    "\n",
+    "rdkit_vdwradii = fp_modified.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(rdkit_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the rdkit preset\n",
+    "rdkit_vdw_elements = set(rdkit_vdwradii.keys())\n",
+    "print(len(rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As you can see, the values and the number of the `vdwradii` in two presets are different.  The default preset (`mdanalysis`) has merely 54 elements whereas the `rdkit` preset defines the van der Waals radii for 118 elements. \n",
+    "\n",
+    "Furthermore, we can look at the defined elements in two presets."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the default preset but not in the rdkit preset\n",
+    "print(sorted(default_vdw_elements - rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the rdkit preset but not in the default preset\n",
+    "print(sorted(rdkit_vdw_elements - default_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "From this example, you can see most of the transition metals are not in the default preset, so you might consider to use alternative presets for your calculation.  \n",
+    "\n",
+    ":::{note}\n",
+    "To know which alternative presets are available now, see the `preset` parameter in \n",
+    "{class}`~prolif.interactions.interactions.VdWContact` class. You can also manually update the `vdwradii` certain atoms by the following example:\n",
+    "\n",
+    "```python\n",
+    "fp = plf.Fingerprint(\n",
+    "    [\"VdWContact\"],\n",
+    "    parameters={\n",
+    "        \"VdWContact\": {\n",
+    "            \"vdwradii\": {\"C\": 1.65, \"H\": 1.13}\n",
+    "            }})\n",
+    ">>> fp.vdwcontact.vdwradii  # {'H': 1.13, ..., 'C': 1.65, ...}\n",
+    "```\n",
+    "\n",
+    "**However, it is recommended to select an preset rather than to define the `vdwradii` manually or to mix different presets (see issue [#222 (comment)](https://github.com/chemosim-lab/ProLIF/issues/222#issuecomment-2433671386)).**\n",
+    ":::\n",
+    "\n",
+    "Finally, let's run the fingerprint by using different presets and compare the results."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# run fingerprint\n",
+    "fp.run_from_iterable(pose_iterable, protein_mol)\n",
+    "fp_modified.run_from_iterable(pose_iterable, protein_mol)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "By comparing two results in the same view, you can see how the values of the preset affect the calculation of van der Waals contacts."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from prolif.plotting.complex3d import Complex3D\n",
+    "\n",
+    "pose_index = 4  # change this to see different poses\n",
+    "\n",
+    "# create Complex3D objects (default)\n",
+    "comp3D = Complex3D.from_fingerprint(\n",
+    "    fp, pose_iterable[pose_index], protein_mol, frame=pose_index\n",
+    ")\n",
+    "# (modified)\n",
+    "other_comp3D = Complex3D.from_fingerprint(\n",
+    "    fp_modified, pose_iterable[pose_index], protein_mol, frame=pose_index\n",
+    ")\n",
+    "\n",
+    "# compare the two Complex3D objects\n",
+    "view = comp3D.compare(other_comp3D)\n",
+    "view"
    ]
   },
   {
@@ -155,7 +321,7 @@
     "\n",
     "In case you want to reuse an existing class for a different type of interaction, the\n",
     "easiest way is to define an interaction class that inherits one of the classes listed\n",
-    "in the {mod}`prolif.interactions` module, and just update its `__init__` method with the\n",
+    "in the {mod}`~prolif.interactions.interactions` module, and just update its `__init__` method with the\n",
     "appropriate parameters.\n",
     "\n",
     "There are some generic interactions, like the {class}`~prolif.interactions.base.Distance`\n",
@@ -240,7 +406,7 @@
     "Before you dive into this section, make sure that there isn't already an interaction\n",
     "that could just be **repurposed** to do what you want!\n",
     "\n",
-    "For this, the best is to check the {mod}`prolif.interactions` module.\n",
+    "For this, the best is to check the {mod}`~prolif.interactions.interactions` module.\n",
     ":::\n",
     "\n",
     "With that being said, there are a few rules that you must respect when writing your own\n",
@@ -453,7 +619,7 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "prolif",
+   "display_name": ".venv",
    "language": "python",
    "name": "python3"
   },
@@ -467,7 +633,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.6"
+   "version": "3.11.11"
   },
   "orig_nbformat": 4
  },
diff --git a/docs/notebooks/md-ligand-protein.ipynb b/docs/notebooks/md-ligand-protein.ipynb
index abb75e24..431ebeb5 100644
--- a/docs/notebooks/md-ligand-protein.ipynb
+++ b/docs/notebooks/md-ligand-protein.ipynb
@@ -171,6 +171,23 @@
     "protein_selection.guess_bonds()\n",
     "```\n",
     "\n",
+    "Also, check the elements in your selection if you have transition metal (or uncommon element) in your topology (e.g., Cobalt in vitamin B12, Iron in heme). Please modify them to the correct elements in your selection. For instance:\n",
+    "\n",
+    "```python\n",
+    "# original elements\n",
+    "ligand_selection.atoms.elements\n",
+    ">>> array(['', 'N', 'N', ...], dtype=object)\n",
+    "\n",
+    "# modify to the correct elements\n",
+    "correct_atomwise_elements = ['Co', 'N', 'N', ...]\n",
+    "ligand_selection.atoms.elements = correct_atomwise_elements\n",
+    "\n",
+    "# corrected elements\n",
+    "ligand_selection.atoms.elements\n",
+    ">>> array(['Co', 'N', 'N', ...], dtype=object)\n",
+    "```\n",
+    "\n",
+    "\n",
     "In some cases, some atomic clashes may be incorrectly classified as bonds and will prevent the conversion of MDAnalysis molecules to RDKit. Since MDAnalysis uses van der Waals radii for bond detection, one can modify the default radii that are used:\n",
     "\n",
     "```python\n",
@@ -231,13 +248,17 @@
    "metadata": {},
    "source": [
     ":::{tip}\n",
-    "The `run` method will automatically select residues that are close to the ligand (6.0 Å) when computing the fingerprint. You can modify the 6.0 Å cutoff by specifying `plf.Fingerprint(vicinity_cutoff=7.0)`, but this is only useful if you decide to change the distance parameters for an interaction class (see in the advanced section of the tutorials).\n",
+    "The `run` method will automatically select residues that are close to the ligand (6.0 Å) when computing the fingerprint. You can modify the 6.0 Å cutoff by specifying `plf.Fingerprint(vicinity_cutoff=7.0)`, but this is only useful if you decide to change the distance parameters for an interaction class (see *modifying interaction parameters (example 1)* in the {doc}`advanced </notebooks/advanced>` tutorial).\n",
     "\n",
     "Alternatively, you can pass a list of residues like so:\n",
     "\n",
     "```python\n",
     "fp.run(<other parameters>, residues=[\"TYR38.A\", \"ASP129.A\"])\n",
     "```\n",
+    ":::\n",
+    "\n",
+    ":::{tip}\n",
+    "Also, if you have transition metal (or uncommon element) in your topology, you might consider to use different preset parameters for {class}`~prolif.interactions.interactions.VdWContact` calculation (see *modifying interaction parameters (example 2)* in the {doc}`advanced </notebooks/advanced>` tutorial).\n",
     ":::"
    ]
   },
diff --git a/prolif/fingerprint.py b/prolif/fingerprint.py
index 68f325dd..0650a392 100644
--- a/prolif/fingerprint.py
+++ b/prolif/fingerprint.py
@@ -77,12 +77,14 @@ class Fingerprint:
     ----------
     interactions : list
         List of names (str) of interaction classes as found in the
-        :mod:`prolif.interactions` module. Defaults to Hydrophobic, HBDonor, HBAcceptor,
-        PiStacking, Anionic, Cationic, CationPi, PiCation, VdWContact.
+        :mod:`~prolif.interactions.interactions` module. Defaults to Hydrophobic,
+        HBDonor, HBAcceptor, 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 (see the
-        :mod:`prolif.interactions` module's documentation for all classes parameters)::
+        :mod:`~prolif.interactions.interactions` module's documentation for
+        all classes parameters)::
 
             >>> fp = plf.Fingerprint(parameters={"Hydrophobic": {"distance": 3.8}})
 


Reviews:
user: login: cbouysset
body: Nice, just some nitpicky comments and a formatting issue in the notebook, should be all good after that, thanks!
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-28T18:42:47Z
user: login: yuyuan871111
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-28T19:10:14Z
user: login: cbouy
body: All good for me! Did you have any other changes you wanted to do or are we good to merge here?
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-30T00:39:04Z

Review comments:
diff_hunk: @@ -246,6 +246,19 @@
     "print(list(rdkit_vdw_elements - default_vdw_elements))"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"],)\n",
+    "                    #  parameters={\n",
path: docs/notebooks/advanced.ipynb
user: login: cbouysset
body: could you remove the commented lines? also there's an extra comma at the end of the line above before closing the parenthesis
created_at: 2025-03-28T18:29:20Z
author_association: COLLABORATOR
diff_hunk: @@ -231,13 +246,15 @@
    "metadata": {},
    "source": [
     ":::{tip}\n",
-    "The `run` method will automatically select residues that are close to the ligand (6.0 Å) when computing the fingerprint. You can modify the 6.0 Å cutoff by specifying `plf.Fingerprint(vicinity_cutoff=7.0)`, but this is only useful if you decide to change the distance parameters for an interaction class (see in the advanced section of the tutorials).\n",
+    "The `run` method will automatically select residues that are close to the ligand (6.0 Å) when computing the fingerprint. You can modify the 6.0 Å cutoff by specifying `plf.Fingerprint(vicinity_cutoff=7.0)`, but this is only useful if you decide to change the distance parameters for an interaction class (see *modifying interaction parameters (example 1)* in the {doc}`advanced </notebooks/advanced>` tutorial).\n",
     "\n",
     "Alternatively, you can pass a list of residues like so:\n",
     "\n",
     "```python\n",
     "fp.run(<other parameters>, residues=[\"TYR38.A\", \"ASP129.A\"])\n",
     "```\n",
+    "\n",
+    "Also, if you have transition metal (or uncommon element) in your topology, you might consider to use different preset parameters for {class}`~prolif.interactions.interactions.VdWContact` calculation (see *modifying interaction parameters (example 2)* in the {doc}`advanced </notebooks/advanced>` tutorial).\n",
path: docs/notebooks/md-ligand-protein.ipynb
user: login: cbouysset
body: this comment should be in a separate `:::{tip}` cell as it doesn't concern the `residues` parameter in any way. 
created_at: 2025-03-28T18:35:38Z
author_association: COLLABORATOR
diff_hunk: @@ -133,18 +144,183 @@
    "outputs": [],
    "source": [
     "fp = plf.Fingerprint(parameters={\"Hydrophobic\": {\"distance\": 4.0}})\n",
+    "\n",
+    "# calculate hydrophobic interactions betweem first ligand pose and TYR109\n",
     "hydrophobic_interactions_tyr109 = list(\n",
     "    fp.hydrophobic(ligand_mol[0], protein_mol[\"TYR109.A\"])\n",
     ")\n",
+    "\n",
+    "# print the number of hydrophobic interactions\n",
     "len(hydrophobic_interactions_tyr109)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "As you can see, by reducing the distance threshold the interaction between our ligand\n",
-    "and TYR109 is now ignored."
+    "As you can see, by reducing the distance threshold, the hydrophobic interaction between our ligand and TYR109 is now ignored."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Example 2: modifying `preset` in `VdWContact`\n",
+    "Here, we show another example to modify the `preset` parameter within the {class}`~prolif.interactions.interactions.VdWContact` class to use a different set of van der Waals radii definitions. This example is particularly useful when your topology includes transition metals or other less common elements (such as cobalt in vitamin B12) that are not covered by the default preset (`mdanalysis`).\n",
+    "\n",
+    "Let's start with a test case. First, we check the default preset of the `vdwradii`.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"])\n",
+    "\n",
+    "default_vdwradii = fp.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(default_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the preset\n",
+    "default_vdw_elements = set(default_vdwradii.keys())\n",
+    "print(len(default_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next, we create a new fingerprint object with the `preset` of `rdkit` and check its `vdwradii`. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp_modified = plf.Fingerprint(\n",
+    "    [\"HBDonor\", \"HBAcceptor\", \"VdWContact\"],\n",
+    "    parameters={\"VdWContact\": {\"preset\": \"rdkit\"}}\n",
+    "    )\n",
+    "\n",
+    "rdkit_vdwradii = fp_modified.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(rdkit_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the rdkit preset\n",
+    "rdkit_vdw_elements = set(rdkit_vdwradii.keys())\n",
+    "print(len(rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As you can see, the values and the number of the `vdwradii` in two presets are different.  The default preset (`mdanalysis`) has merely 54 elements whereas the `rdkit` preset defines the van der Waals radii for 118 elements. \n",
+    "\n",
+    "Furthermore, we can look at the defined elements in two presets."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the default preset but not in the rdkit preset\n",
+    "print(list(default_vdw_elements - rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the rdkit preset but not in the default preset\n",
+    "print(list(rdkit_vdw_elements - default_vdw_elements))"
path: docs/notebooks/advanced.ipynb
user: login: cbouysset
body: use `sorted` instead of `list` so that it's easier for people reading this to quickly check if they need to switch the `preset` or not.
created_at: 2025-03-28T18:39:15Z
author_association: COLLABORATOR
diff_hunk: @@ -133,18 +144,183 @@
    "outputs": [],
    "source": [
     "fp = plf.Fingerprint(parameters={\"Hydrophobic\": {\"distance\": 4.0}})\n",
+    "\n",
+    "# calculate hydrophobic interactions betweem first ligand pose and TYR109\n",
     "hydrophobic_interactions_tyr109 = list(\n",
     "    fp.hydrophobic(ligand_mol[0], protein_mol[\"TYR109.A\"])\n",
     ")\n",
+    "\n",
+    "# print the number of hydrophobic interactions\n",
     "len(hydrophobic_interactions_tyr109)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "As you can see, by reducing the distance threshold the interaction between our ligand\n",
-    "and TYR109 is now ignored."
+    "As you can see, by reducing the distance threshold, the hydrophobic interaction between our ligand and TYR109 is now ignored."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Example 2: modifying `preset` in `VdWContact`\n",
+    "Here, we show another example to modify the `preset` parameter within the {class}`~prolif.interactions.interactions.VdWContact` class to use a different set of van der Waals radii definitions. This example is particularly useful when your topology includes transition metals or other less common elements (such as cobalt in vitamin B12) that are not covered by the default preset (`mdanalysis`).\n",
+    "\n",
+    "Let's start with a test case. First, we check the default preset of the `vdwradii`.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"])\n",
+    "\n",
+    "default_vdwradii = fp.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(default_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the preset\n",
+    "default_vdw_elements = set(default_vdwradii.keys())\n",
+    "print(len(default_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next, we create a new fingerprint object with the `preset` of `rdkit` and check its `vdwradii`. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp_modified = plf.Fingerprint(\n",
+    "    [\"HBDonor\", \"HBAcceptor\", \"VdWContact\"],\n",
+    "    parameters={\"VdWContact\": {\"preset\": \"rdkit\"}}\n",
+    "    )\n",
+    "\n",
+    "rdkit_vdwradii = fp_modified.vdwcontact.vdwradii\n",
+    "\n",
+    "# show the first 5 vdwradii of the dictionary\n",
+    "print(dict(list(rdkit_vdwradii.items())[:5]))\n",
+    "\n",
+    "# show the number of elements in the rdkit preset\n",
+    "rdkit_vdw_elements = set(rdkit_vdwradii.keys())\n",
+    "print(len(rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As you can see, the values and the number of the `vdwradii` in two presets are different.  The default preset (`mdanalysis`) has merely 54 elements whereas the `rdkit` preset defines the van der Waals radii for 118 elements. \n",
+    "\n",
+    "Furthermore, we can look at the defined elements in two presets."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the default preset but not in the rdkit preset\n",
+    "print(list(default_vdw_elements - rdkit_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the elements that are in the rdkit preset but not in the default preset\n",
+    "print(list(rdkit_vdw_elements - default_vdw_elements))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"],)\n",
+    "                    #  parameters={\n",
+    "                    #     \"VdWContact\": {\n",
+    "                    #         \"vdwradii\": {\"C\": 1.65, \"H\": 1.13}\n",
+    "                    #         }})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "From this example, you can see most of the transition metals are not in the default preset, so you might consider to use alternative presets for your calculation.  \n",
+    "\n",
+    ":::{note}\n",
+    "To know which alternative presets are available now, see the `preset` parameter in \n",
+    "{class}`~prolif.interactions.interactions.VdWContact` class. You can also manually update the `vdwradii` certain atoms by the following example:\n",
+    "\n",
+    "```python\n",
+    "fp = plf.Fingerprint(\n",
+    "    [\"VdWContact\"],\n",
+    "    parameters={\n",
+    "        \"VdWContact\": {\n",
+    "            \"vdwradii\": {\"C\": 1.65, \"H\": 1.13}\n",
+    "            }})\n",
+    ">>> fp.vdwcontact.vdwradii  # {'H': 1.13, ..., 'C': 1.65, ...}\n",
+    "```\n",
+    "\n",
+    "**However, it is recommended to select an preset rather than to define the `vdwradii` manually or to mix different presets (see issue [#222 (comment)](https://github.com/chemosim-lab/ProLIF/issues/222#issuecomment-2433671386)).**\n",
+    ":::\n",
+    "\n",
+    "Finally, let's run the fingerprint by using different presets and compare the results."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# run fingerprint\n",
+    "fp.run_from_iterable(pose_iterable, protein_mol)\n",
+    "fp_modified.run_from_iterable(pose_iterable, protein_mol)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "By comparing two results in the same view, you can see how the values of the preset affect the calculation of van der Waals contacts."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from prolif.plotting.complex3d import Complex3D\n",
+    "\n",
+    "pose_index = 4  # change this to see different poses\n",
+    "\n",
+    "# create Complex3D objects (default)\n",
+    "comp3D = Complex3D.from_fingerprint(fp, pose_iterable[pose_index], protein_mol, frame=pose_index)\n",
+    "# (modified)\n",
+    "other_comp3D = Complex3D.from_fingerprint(fp_modified, pose_iterable[pose_index], protein_mol, frame=pose_index)\n",
+    "\n",
+    "# compare the two Complex3D objects\n",
+    "view = comp3D.compare(other_comp3D)\n",
path: docs/notebooks/advanced.ipynb
user: login: cbouysset
body: nice!
created_at: 2025-03-28T18:40:12Z
author_association: COLLABORATOR
diff_hunk: @@ -133,18 +144,183 @@
    "outputs": [],
    "source": [
     "fp = plf.Fingerprint(parameters={\"Hydrophobic\": {\"distance\": 4.0}})\n",
+    "\n",
+    "# calculate hydrophobic interactions betweem first ligand pose and TYR109\n",
     "hydrophobic_interactions_tyr109 = list(\n",
     "    fp.hydrophobic(ligand_mol[0], protein_mol[\"TYR109.A\"])\n",
     ")\n",
+    "\n",
+    "# print the number of hydrophobic interactions\n",
     "len(hydrophobic_interactions_tyr109)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "As you can see, by reducing the distance threshold the interaction between our ligand\n",
-    "and TYR109 is now ignored."
+    "As you can see, by reducing the distance threshold, the hydrophobic interaction between our ligand and TYR109 is now ignored."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Example 2: modifying `preset` in `VdWContact`\n",
+    "Here, we show another example to modify the `preset` parameter within the {class}`~prolif.interactions.interactions.VdWContact` class to use a different set of van der Waals radii definitions. This example is particularly useful when your topology includes transition metals or other less common elements (such as cobalt in vitamin B12) that are not covered by the default preset (`mdanalysis`).\n",
+    "\n",
+    "Let's start with a test case. First, we check the default preset of the `vdwradii`.  "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"])\n",
path: docs/notebooks/advanced.ipynb
user: login: cbouysset
body: I'd remove the `HBDonor` and `HBAcceptor` here and in `fp_modified` just for clarity since we're only looking at vdW contacts
created_at: 2025-03-28T18:41:55Z
author_association: COLLABORATOR
diff_hunk: @@ -246,6 +246,19 @@
     "print(list(rdkit_vdw_elements - default_vdw_elements))"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fp = plf.Fingerprint([\"HBDonor\", \"HBAcceptor\", \"VdWContact\"],)\n",
+    "                    #  parameters={\n",
path: docs/notebooks/advanced.ipynb
user: login: yuyuan871111
body: I think this cell is my personal test for the below note. I will remove it. Thanks for pointing this out.
created_at: 2025-03-28T19:10:14Z
author_association: COLLABORATOR

PR comments:
user: login: codecov[bot]
created_at: 2025-03-26T22:29:38Z
body: ## [Codecov](https://app.codecov.io/gh/chemosim-lab/ProLIF/pull/253?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chemosim-lab) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 94.47%. Comparing base [(`c2daf57`)](https://app.codecov.io/gh/chemosim-lab/ProLIF/commit/c2daf5738ae528c067d95ed401fe8c6c83d74a98?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chemosim-lab) to head [(`1b8091d`)](https://app.codecov.io/gh/chemosim-lab/ProLIF/commit/1b8091db0a04a0005132356bb351c61de880ac13?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chemosim-lab).
> Report is 13 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master     #253   +/-   ##
=======================================
  Coverage   94.47%   94.47%           
=======================================
  Files          21       21           
  Lines        1520     1520           
=======================================
  Hits         1436     1436           
  Misses         84       84           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/chemosim-lab/ProLIF/pull/253?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chemosim-lab).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chemosim-lab).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: cbouy
created_at: 2025-03-26T22:54:34Z
body: Nice addition @yuyuan871111, thanks!

For the second troubleshooting note that you're adding, I'm not sure if we want to have the full example in the ligand-protein tutorial. I'd move the content to the advanced tutorial (there's already a section on modifying interaction parameters there but it's not great as it doesn't use the `run` method that most users will be familiar with), and just refer to it in the ligand-protein tutorial.

So I would:
- Replace my confusing section showcasing how to modify the parameters in the advanced tutorial with your more relevant example.
- Add in that same section that you can also directly provide your own radii with `vdwradii` (and mention that they should use a radii that is consistent with the other radii in the selected preset).
- I just noticed that the note linking to the `prolif.interactions` module is actually broken, it should be `prolif.interactions.interactions` instead, could you please fix it here as well?
- Reference to the advanced tutorial in that second note you added in the ligand-protein tutorial.

I think being able to view the radii in the docs would be useful as well, but for now let's start with this!
author_association: MEMBER
user: login: yuyuan871111
created_at: 2025-03-27T12:58:18Z
body: Hi @cbouy, I believe all suggested tasks are completed. Please check it. I am happy to help improving the documentation.
author_association: COLLABORATOR
user: login: cbouy
created_at: 2025-03-29T18:22:36Z
body: You can run `uv run poe style-fix` to fix the remaining formatting issue and we should be good to merge after that!
author_association: MEMBER
user: login: yuyuan871111
created_at: 2025-03-29T18:43:14Z
body: Thanks @cbouy for reminding me,

I should recheck the style after I revised the code.
author_association: COLLABORATOR
user: login: yuyuan871111
created_at: 2025-03-30T07:30:44Z
body: All go for me as well! I think it is clear for the user to know how to modify their parameters with different vdwradii preset.
author_association: COLLABORATOR