pharmai / plip

Protein-Ligand Interaction Profiler - Analyze and visualize non-covalent protein-ligand interactions in PDB files according to 📝 Adasme et al. (2021), https://doi.org/10.1093/nar/gkab294
http://plip.biotec.tu-dresden.de
GNU General Public License v2.0
463 stars 107 forks source link

Missing key hydrogen bond interaction in hinge region of kinases #108

Open jaimergp opened 3 years ago

jaimergp commented 3 years ago

Describe the bug

I am analyzing a set of kinases bound to ligand STU, as provided by KLIFS. In kinases, the hinge region is usually interacting with the ligand with hydrogen bonds. KLIFS reports that position 46 (a GLU residue) should have plenty of hydrogen bonds from STU to the backbone oxygen, but PLIP does not report it.

For example, in ALK structure 3LCS, hinge residue 46 corresponds to GLU 1197. See the missing cylinder between that N atom in the ligand and the O in the backbone:

image

To Reproduce Steps to reproduce the behavior:

  1. Go to '...' and start the analysis for PDB id = 3LCS. 30d URL
  2. Go the section corresponding for STU
  3. See how the hydrogen bonds table does not include any interactions with GLU 1197
  4. KLIFS does show a hydrogen bond in that position.

image

Expected behavior

I would expect that atom pair to be detected as a strong hydrogen bond. The distance is within the thresholds:

image

Interestingly, the N atom in the ligand is detected as an unpaired acceptor (it is contained in the PDBComplex.interaction_sets["STU:A:0"].unpaired_hba list).

Desktop (please complete the following information):

Additional context

I can reproduce the online version behavior locally with the following versions:

% conda list | grep -e "^python \|^openbabel \|^plip "
openbabel                 3.1.1            py37h200e996_1    conda-forge
plip                      2.1.6              pyhd8ed1ab_0    conda-forge
python                    3.7.8           hffdb5ce_3_cpython    conda-forge
fkaiserbio commented 3 years ago

Thanks for the report! This issue is caused by OpenBabel that PLIP is using to decide between acceptor and donor atoms for hydrogen bonds. OpenBabel does not recognize the backbone oxygen atom of GLU1197 as an hydrogen bond donor and hence it is not paired with the ligand nitrogen, which is classified as acceptor.

You can check this by calling OBAtom.IsHbondDonor() on the atom 795 of structure 3LCS after protonation.

The respective decicion is made in:

https://github.com/pharmai/plip/blob/b481cf70870f6f100037551861cef32adef99105/plip/structure/preparation.py#L513

jaimergp commented 3 years ago

Hi Florian! Thanks for your answer.

Looks like that function is defined here. I wonder which test the backbone oxygen is failing.

jaimergp commented 3 years ago

I have checked again, and I misunderstood your comment, sorry! Both atoms are being perceived as H-bond donors:

from plip.structure.preparation import PDBComplex
from openbabel import openbabel as ob

def check_for_donor_acceptor(pdbpath):
    obConversion = ob.OBConversion()
    obConversion.SetInAndOutFormats("pdb", "mol2")

    mol = ob.OBMol()
    obConversion.ReadFile(mol, pdbpath)   # Open Babel will uncompress automatically

    for r in ob.OBResidueIter(mol):
        if r.GetNum() == 1197 and r.GetName() == "GLU":
            for atom in ob.OBResidueAtomIter(r):
                if atom.GetAtomicNum() == 8 and atom.GetIdx() == 795:
                    print("Glu197, Oxygen 795... IsHbondAcceptor:", atom.IsHbondAcceptor())
                    print("Glu197, Oxygen 795... IsHbondDonor:", atom.IsHbondDonor())
        elif r.GetName() == "STU":
            for atom in ob.OBResidueAtomIter(r):
                if atom.GetAtomicNum() == 7 and atom.GetIdx() == 2442:
                    print("STU, Nitrogen 2442... IsHbondAcceptor:", atom.IsHbondAcceptor())
                    print("STU, Nitrogen 2442... IsHbondDonor:", atom.IsHbondDonor())

!wget -q https://files.rcsb.org/download/3LCS.pdb

check_for_donor_acceptor("3LCS.pdb")
# Glu197, Oxygen 795... IsHbondAcceptor: True
# Glu197, Oxygen 795... IsHbondDonor: False
# STU, Nitrogen 2442... IsHbondAcceptor: True
# STU, Nitrogen 2442... IsHbondDonor: False

check_for_donor_acceptor("/tmp/3LCS_protonated.pdb")
# Glu197, Oxygen 795... IsHbondAcceptor: True
# Glu197, Oxygen 795... IsHbondDonor: False
# STU, Nitrogen 2442... IsHbondAcceptor: True
# STU, Nitrogen 2442... IsHbondDonor: False

So maybe the issue has to do with protonation states? It looks like the nitrogen in that pyrrole should be protonated:

image

jaimergp commented 3 years ago

Some protonation tools, like Protoss, do add the hydrogen there: https://proteins.plus/3lcs

image


Other tools, like Chimera, do not add the hydrogen to N1, but do recognize the Hbond:

open 3lcs
addh
hbonds

More info on hbonds. See "Method and criteria" for maybe some hints on why they do consider this a H-bond. The source is here.

image


You can also see this in RCSB's Mol* viewer:

image

Their source for H-Bond detection.


I know this might be too much to ask, but would you be able to elaborate on the differences between what PLIP considers a H-bond and these other tools?

jaimergp commented 3 years ago

Do note that if PLIP is passed an already protonated structure that satisfies that STU.N1 hydrogen (like the one downloadable from Protoss server), then expected H-bond is detected with no issues!

fkaiserbio commented 3 years ago

Hi Jaime,

thanks for your elaborate reply and the very helpful resources. This will be definitely helpful to improve H-bond detection for PLIP.

Briefly, PLIP does the following:

For now, it seems that favourable protonation states are not correctly assigned for this example. I would recommend here to use a pre-protonated structure (as you already did) and use the --no-hydro flag of PLIP. Protonation has always been an issue and if one wants to achieve consistent results, using already protonated structures is the cleaner way. Sorry that I cannot help out here, but implementing a different protonation or recognition scheme is currently not in the scope. However, any contributions are welcome!

jaimergp commented 3 years ago

Thanks!

Yes, for now we will use Amber's reduce before running PLIP and that seems to fix the problem.

Thanks again for all the input!