Skip to content
Commits on Source (6)
Changelog
---------
# Next version
* Adds information on covalent linkages to XML files
* __Anaconda package__ (provided by `Ikagami`)
# 1.4.2
* Adds "--name" option to change name of output files
......
......@@ -44,7 +44,7 @@ and should be executed with Python 2.7.x.
Example command for Ubuntu using apt-get
```bash
sudo apt-get install pymol openbabel python-openbabel imagemagick
sudo apt-get install pymol openbabel python-openbabel imagemagick swig
```
......@@ -67,7 +67,7 @@ You can use any other user directory, but we will use the one given above for th
The package manager `pip` will create symlinks for you so you can call PLIP using `plip` in the command line. If you cloned from Github, use the following command to do the same:
```bash
alias plip='~/pliptool/plip/plipcmd'
alias plip='python ~/pliptool/plip/plipcmd.py'
```
## Analyze a PDB structure with PLIP
......
......@@ -18,11 +18,11 @@ git clone https://github.com/ssalentin/plip.git ~/pliptool
##### As a command line tool
Run the `plipcmd` script inside the PLIP folder to detect, report, and visualize interactions. The following example creates a PYMOL visualization for the interactions
Run the `plipcmd.py` script inside the PLIP folder to detect, report, and visualize interactions. The following example creates a PYMOL visualization for the interactions
between the inhibitor NFT and its target protein in the PDB structure 1VSN.
```bash
alias plip='~/pliptool/plip/plipcmd'
alias plip='python ~/pliptool/plip/plipcmd.py'
mkdir /tmp/1vsn && cd /tmp/1vsn
plip -i 1vsn -yv
pymol 1VSN_NFT_A_283.pse
......@@ -61,7 +61,7 @@ For a full documentation of running options and output formats, please refear to
## Versions and Branches
For production environments, you should use the latest versioned commit from the stable branch.
Newer commits from the stable and development branch may contains new but untested and not documented features.
Newer commits from the stable and development branch may contain new but untested and not documented features.
## Requirements
Previous to using PLIP, make sure you have the following tools and libraries installed:
......@@ -93,3 +93,11 @@ If you are unsure about usage options, don't hesitate to contact me.
If you are using PLIP in your work, please cite
> Salentin,S. et al. PLIP: fully automated protein-ligand interaction profiler.
> Nucl. Acids Res. (1 July 2015) 43 (W1): W443-W447. doi: 10.1093/nar/gkv315
## FAQ
> I try to run PLIP, but I'm getting an error message saying:
> ValueError: [...] is not a recognised Open Babel descriptor type
Make sure Open Babel is correctly installed. This error can occur if the installed Python bindings don't match the OpenBabel version on your machine.
We don't offer technical support for installation of third-party packages.
For an instruction how to install Open Babel, please refer to their [website](https://openbabel.org/docs/dev/Installation/install.html).
plip (1.4.3~b+dfsg-1) unstable; urgency=medium
* Update Files-Excluded section in d/copyright
* New upstream version 1.4.3~b+dfsg
* Check for nocheck in DEB_BUILD_OPTIONS for tests, s/plipcmd.py/plipcmd/
* Bump Policy to 4.2.1
-- Alexandre Mestiashvili <mestia@debian.org> Tue, 25 Sep 2018 09:38:55 +0000
plip (1.4.2+dfsg-1) unstable; urgency=medium
* New upstream version 1.4.2+dfsg
......
......@@ -12,7 +12,7 @@ Build-Depends: debhelper (>= 11),
python-openbabel,
python-setuptools,
python-future
Standards-Version: 4.1.4
Standards-Version: 4.2.1
Vcs-Browser: https://salsa.debian.org/med-team/plip
Vcs-Git: https://salsa.debian.org/med-team/plip.git
Homepage: https://projects.biotec.tu-dresden.de/plip-web/plip/
......
......@@ -4,6 +4,8 @@ Source: https://github.com/ssalentin/plip
Files-Excluded:
plip/test/pdb/*
pliplogo*
setup_conda.py
recipe/*
Files: *
Copyright: 2016 Sebastian Salentin <sebastian.salentin@biotec.tu-dresden.de>
......
......@@ -12,6 +12,8 @@ PYTHON_DEFAULT_VERSION := $(shell pyversions -d)
override_dh_auto_install:
dh_auto_install
mv $(CURDIR)/debian/$(PYBUILD_NAME)/usr/bin/plipcmd.py \
$(CURDIR)/debian/$(PYBUILD_NAME)/usr/bin/plipcmd
mkdir -p $(mandir)
export PYTHONPATH=$(CURDIR)/debian/$(PYBUILD_NAME)/usr/lib/$(PYTHON_DEFAULT_VERSION)/dist-packages/:\
$(CURDIR)/plip/modules; \
......@@ -19,4 +21,6 @@ override_dh_auto_install:
$(CURDIR)/debian/$(PYBUILD_NAME)/usr/bin/plipcmd > $(mandir)/plipcmd.1
override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
debian/tests/special-cases
endif
......@@ -17,7 +17,8 @@ def filter_contacts(pairings):
"""Filter interactions by two criteria:
1. No interactions between the same residue (important for intra mode).
2. No duplicate interactions (A with B and B with A, also important for intra mode)."""
if config.INTRA:
if not config.INTRA:
return pairings
filtered1_pairings = [p for p in pairings if (p.resnr, p.reschain) != (p.resnr_l, p.reschain_l)]
already_considered = []
filtered2_pairings = []
......@@ -30,13 +31,11 @@ def filter_contacts(pairings):
except AttributeError:
dist = 'D{}'.format(round(contact.distance_aw,2))
res1, res2 = ''.join([str(contact.resnr), contact.reschain]), ''.join([str(contact.resnr_l), contact.reschain_l])
data = set([res1, res2, dist])
data = {res1, res2, dist}
if data not in already_considered:
filtered2_pairings.append(contact)
already_considered.append(data)
return filtered2_pairings
else:
return pairings
##################################################
......@@ -54,7 +53,8 @@ def hydrophobic_interactions(atom_set_a, atom_set_b):
if a.orig_idx == b.orig_idx:
continue
e = euclidean3d(a.atom.coords, b.atom.coords)
if config.MIN_DIST < e < config.HYDROPH_DIST_MAX:
if not config.MIN_DIST < e < config.HYDROPH_DIST_MAX:
continue
restype, resnr, reschain = whichrestype(a.atom), whichresnumber(a.atom), whichchain(a.atom)
restype_l, resnr_l, reschain_l = whichrestype(b.orig_atom), whichresnumber(b.orig_atom), whichchain(b.orig_atom)
contact = data(bsatom=a.atom, bsatom_orig_idx=a.orig_idx, ligatom=b.atom, ligatom_orig_idx=b.orig_idx,
......@@ -75,13 +75,17 @@ def hbonds(acceptors, donor_pairs, protisdon, typ):
'restype reschain resnr_l restype_l reschain_l sidechain atype dtype')
pairings = []
for acc, don in itertools.product(acceptors, donor_pairs):
if typ == 'strong': # Regular (strong) hydrogen bonds
if not typ == 'strong':
continue
# Regular (strong) hydrogen bonds
dist_ah = euclidean3d(acc.a.coords, don.h.coords)
dist_ad = euclidean3d(acc.a.coords, don.d.coords)
if config.MIN_DIST < dist_ad < config.HBOND_DIST_MAX:
if not config.MIN_DIST < dist_ad < config.HBOND_DIST_MAX:
continue
vec1, vec2 = vector(don.h.coords, don.d.coords), vector(don.h.coords, acc.a.coords)
v = vecangle(vec1, vec2)
if v > config.HBOND_DON_ANGLE_MIN:
if not v > config.HBOND_DON_ANGLE_MIN:
continue
protatom = don.d.OBAtom if protisdon else acc.a.OBAtom
ligatom = don.d.OBAtom if not protisdon else acc.a.OBAtom
is_sidechain_hbond = protatom.GetResidue().GetAtomProperty(protatom, 8) # Check if sidechain atom
......@@ -125,7 +129,8 @@ def pistacking(rings_bs, rings_lig):
# SELECTION BY DISTANCE, ANGLE AND OFFSET
passed = False
if config.MIN_DIST < d < config.PISTACK_DIST_MAX:
if not config.MIN_DIST < d < config.PISTACK_DIST_MAX:
continue
if 0 < a < config.PISTACK_ANG_DEV and offset < config.PISTACK_OFFSET_MAX:
ptype = 'P'
passed = True
......@@ -146,7 +151,8 @@ def pication(rings, pos_charged, protcharged):
"""
data = namedtuple('pication', 'ring charge distance offset type restype resnr reschain restype_l resnr_l reschain_l protcharged')
pairings = []
if not len(rings) == 0 and not len(pos_charged) == 0:
if len(rings) == 0 or len(pos_charged) == 0:
return pairings
for ring in rings:
c = ring.center
for p in pos_charged:
......@@ -154,7 +160,8 @@ def pication(rings, pos_charged, protcharged):
# Project the center of charge into the ring and measure distance to ring center
proj = projection(ring.normal, ring.center, p.center)
offset = euclidean3d(proj, ring.center)
if config.MIN_DIST < d < config.PICATION_DIST_MAX and offset < config.PISTACK_OFFSET_MAX:
if not config.MIN_DIST < d < config.PICATION_DIST_MAX or not offset < config.PISTACK_OFFSET_MAX:
continue
if type(p).__name__ == 'lcharge' and p.fgroup == 'tertamine':
# Special case here if the ligand has a tertiary amine, check an additional angle
# Otherwise, we might have have a pi-cation interaction 'through' the ligand
......@@ -194,7 +201,8 @@ def saltbridge(poscenter, negcenter, protispos):
data = namedtuple('saltbridge', 'positive negative distance protispos resnr restype reschain resnr_l restype_l reschain_l')
pairings = []
for pc, nc in itertools.product(poscenter, negcenter):
if config.MIN_DIST < euclidean3d(pc.center, nc.center) < config.SALTBRIDGE_DIST_MAX:
if not config.MIN_DIST < euclidean3d(pc.center, nc.center) < config.SALTBRIDGE_DIST_MAX:
continue
resnr = pc.resnr if protispos else nc.resnr
resnr_l = whichresnumber(nc.orig_atoms[0]) if protispos else whichresnumber(pc.orig_atoms[0])
restype = pc.restype if protispos else nc.restype
......@@ -215,15 +223,18 @@ def halogen(acceptor, donor):
pairings = []
for acc, don in itertools.product(acceptor, donor):
dist = euclidean3d(acc.o.coords, don.x.coords)
if config.MIN_DIST < dist < config.HALOGEN_DIST_MAX:
if not config.MIN_DIST < dist < config.HALOGEN_DIST_MAX:
continue
vec1, vec2 = vector(acc.o.coords, acc.y.coords), vector(acc.o.coords, don.x.coords)
vec3, vec4 = vector(don.x.coords, acc.o.coords), vector(don.x.coords, don.c.coords)
acc_angle, don_angle = vecangle(vec1, vec2), vecangle(vec3, vec4)
is_sidechain_hal = acc.o.OBAtom.GetResidue().GetAtomProperty(acc.o.OBAtom, 8) # Check if sidechain atom
if config.HALOGEN_ACC_ANGLE - config.HALOGEN_ANGLE_DEV < acc_angle \
if not config.HALOGEN_ACC_ANGLE - config.HALOGEN_ANGLE_DEV < acc_angle \
< config.HALOGEN_ACC_ANGLE + config.HALOGEN_ANGLE_DEV:
if config.HALOGEN_DON_ANGLE - config.HALOGEN_ANGLE_DEV < don_angle \
continue
if not config.HALOGEN_DON_ANGLE - config.HALOGEN_ANGLE_DEV < don_angle \
< config.HALOGEN_DON_ANGLE + config.HALOGEN_ANGLE_DEV:
continue
restype, reschain, resnr = whichrestype(acc.o), whichchain(acc.o), whichresnumber(acc.o)
restype_l, reschain_l, resnr_l = whichrestype(don.orig_x), whichchain(don.orig_x), whichresnumber(don.orig_x)
contact = data(acc=acc, acc_orig_idx=acc.o_orig_idx, don=don, don_orig_idx=don.x_orig_idx,
......@@ -269,9 +280,12 @@ def water_bridges(bs_hba, lig_hba, bs_hbd, lig_hbd, water):
for l, p in itertools.product(lig_aw, prot_hw):
acc, wl, distance_aw = l
don, wd, distance_dw, d_angle = p
if wl.oxy == wd.oxy: # Same water molecule and angle within omega
if not wl.oxy == wd.oxy:
continue
# Same water molecule and angle within omega
w_angle = vecangle(vector(acc.a.coords, wl.oxy.coords), vector(wl.oxy.coords, don.h.coords))
if config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
if not config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
continue
resnr, reschain, restype = whichresnumber(don.d), whichchain(don.d), whichrestype(don.d)
resnr_l, reschain_l, restype_l = whichresnumber(acc.a_orig_atom), whichchain(acc.a_orig_atom), whichrestype(acc.a_orig_atom)
contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, atype=acc.a.type, d=don.d, d_orig_idx=don.d_orig_idx,
......@@ -283,9 +297,12 @@ def water_bridges(bs_hba, lig_hba, bs_hbd, lig_hbd, water):
for p, l in itertools.product(prot_aw, lig_dw):
acc, wl, distance_aw = p
don, wd, distance_dw, d_angle = l
if wl.oxy == wd.oxy: # Same water molecule and angle within omega
if not wl.oxy == wd.oxy:
continue
# Same water molecule and angle within omega
w_angle = vecangle(vector(acc.a.coords, wl.oxy.coords), vector(wl.oxy.coords, don.h.coords))
if config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
if not config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
continue
resnr, reschain, restype = whichresnumber(acc.a), whichchain(acc.a), whichrestype(acc.a)
resnr_l, reschain_l, restype_l = whichresnumber(don.d_orig_atom), whichchain(don.d_orig_atom), whichrestype(don.d_orig_atom)
contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, atype=acc.a.type, d=don.d, d_orig_idx=don.d_orig_idx,
......@@ -310,7 +327,8 @@ def metal_complexation(metals, metal_binding_lig, metal_binding_bs):
metal_to_orig_atom = {}
for metal, target in itertools.product(metals, metal_binding_lig + metal_binding_bs):
distance = euclidean3d(metal.m.coords, target.atom.coords)
if distance < config.METAL_DIST_MAX:
if not distance < config.METAL_DIST_MAX:
continue
if metal.m not in pairings_dict:
pairings_dict[metal.m] = [(target, distance), ]
metal_to_id[metal.m] = metal.m_orig_idx
......
......@@ -22,7 +22,7 @@ class XMLStorage:
def getdata(self, tree, location, force_string=False):
"""Gets XML data from a specific element and handles types."""
found = tree.xpath('%s/text()' % location)
if found == []:
if not found:
return None
else:
data = found[0]
......@@ -244,7 +244,7 @@ class BSite(XMLStorage):
self.halogens = [HalogenBond(x) for x in interactions.xpath('halogen_bonds/halogen_bond')]
self.metal_complexes = [MetalComplex(x) for x in interactions.xpath('metal_complexes/metal_complex')]
self.num_contacts = len(self.hydrophobics) + len(self.hbonds) + len(self.wbridges) + len(self.sbridges) + len(self.pi_stacks) + len(self.pi_cations) + len(self.halogens) + len(self.metal_complexes)
self.has_interactions = True if self.num_contacts > 0 else False
self.has_interactions = self.num_contacts > 0
self.get_atom_mapping()
self.counts = self.get_counts()
......@@ -282,7 +282,7 @@ class PLIPXML(XMLStorage):
self.filetype = self.getdata(self.doc, '/report/filetype')
self.fixed = self.getdata(self.doc, '/report/pdbfixes/')
self.filename = self.getdata(self.doc, '/report/filename')
self.excluded = self.getdata(self.doc, '/report/excluded_ligands')
self.excluded = self.doc.xpath('/report/excluded_ligands/excluded_ligand/text()')
# Parse binding site information
self.bsites = {BSite(bs, self.pdbid).bsid: BSite(bs, self.pdbid) for bs in self.doc.xpath('//bindingsite')}
......
......@@ -19,7 +19,7 @@ from . import config
# External libraries
import lxml.etree as et
__version__ = '1.4.2'
__version__ = '1.4.3'
class StructureReport:
"""Creates reports (xml or txt) for one structure/"""
......@@ -61,6 +61,13 @@ class StructureReport:
for i, exlig in enumerate(self.excluded):
e = et.SubElement(exligs, 'excluded_ligand', id=str(i + 1))
e.text = exlig
covalent = et.SubElement(report, 'covlinkages')
for i, covlinkage in enumerate(self.mol.covalent):
e = et.SubElement(covalent, 'covlinkage', id=str(i + 1))
f1 = et.SubElement(e, 'res1')
f2 = et.SubElement(e, 'res2')
f1.text = ":".join([covlinkage.id1, covlinkage.chain1, str(covlinkage.pos1)])
f2.text = ":".join([covlinkage.id2, covlinkage.chain2, str(covlinkage.pos2)])
return report
def construct_txt_file(self):
......
#! /usr/bin/env python
"""
Protein-Ligand Interaction Profiler - Analyze and visualize protein-ligand interactions in PDB files.
plipcmd - Main script for PLIP command line execution.
plipcmd.py - Main script for PLIP command line execution.
"""
# Compatibility
......@@ -9,12 +9,20 @@ from __future__ import print_function
from __future__ import absolute_import
# Own modules
try:
from plip.modules.preparation import *
from plip.modules.plipremote import VisualizerData
from plip.modules.report import StructureReport,__version__
from plip.modules import config
from plip.modules.mp import parallel_fn
from plip.modules.webservices import check_pdb_status, fetch_pdb
except ImportError:
from modules.preparation import *
from modules.plipremote import VisualizerData
from modules.report import StructureReport,__version__
from modules import config
from modules.mp import parallel_fn
from modules.webservices import check_pdb_status, fetch_pdb
# Python standard library
import sys
......@@ -72,7 +80,10 @@ def process_pdb(pdbfile, outpath, as_string=False, outputprefix='report'):
######################################
if config.PYMOL or config.PICS:
try:
from plip.modules.visualize import visualize_in_pymol
except ImportError:
from modules.visualize import visualize_in_pymol
complexes = [VisualizerData(mol, site) for site in sorted(mol.interaction_sets)
if not len(mol.interaction_sets[site].interacting_res) == 0]
if config.MAXTHREADS > 1:
......@@ -166,12 +177,12 @@ def main(inputstructs, inputpdbids):
else:
write_message('\nFinished analysis. Find the result files in %s\n\n' % config.BASEPATH)
if __name__ == '__main__':
##############################
# Parse command line arguments
##############################
def main_init():
"""Parse command line arguments and start main script for analysis."""
parser = ArgumentParser(prog="PLIP", description=descript)
pdbstructure = parser.add_mutually_exclusive_group(required=True) # Needs either PDB ID or file
pdbstructure.add_argument("-f", "--file", dest="input", nargs="+", help="Set input file, '-' reads from stdin") # '-' as file name reads from stdin
......@@ -293,3 +304,5 @@ if __name__ == '__main__':
parser.error("The water bridge omega minimum angle has to be smaller than the water bridge omega maximum angle")
expanded_path = tilde_expansion(arguments.input) if arguments.input is not None else None
main(expanded_path, arguments.pdbid) # Start main script
if __name__ == '__main__':
main_init()
......@@ -14,20 +14,20 @@ class SpecialCasesTest(unittest.TestCase):
def test_empty_input_file(self):
"""Input file is empty."""
exitcode = subprocess.call('../plipcmd -f ./special/empty.pdb -o /tmp', shell=True)
exitcode = subprocess.call('python ../plipcmd.py -f ./special/empty.pdb -o /tmp', shell=True)
self.assertEqual(exitcode, 2) # Specific exitcode 2
def test_invalid_pdb_id(self):
"""A PDB ID with no valid PDB record is provided."""
exitcode = subprocess.call('../plipcmd -i xx1x -o /tmp', shell=True)
exitcode = subprocess.call('python ../plipcmd.py -i xx1x -o /tmp', shell=True)
self.assertEqual(exitcode, 3) # Specific exitcode 3
def test_invalid_input_file(self):
"""A file is provided which is not a PDB file."""
exitcode = subprocess.call('../plipcmd -f ./special/non-pdb.pdb -o /tmp', shell=True)
exitcode = subprocess.call('python ../plipcmd.py -f ./special/non-pdb.pdb -o /tmp', shell=True)
self.assertEqual(exitcode, 4) # Specific exitcode 4
def test_pdb_format_not_available(self):
"""A valid PDB ID is provided, but there is no entry in PDB format from wwPDB"""
exitcode1 = subprocess.call('../plipcmd -i 4v59 -o /tmp', shell=True)
exitcode1 = subprocess.call('python ../plipcmd.py -i 4v59 -o /tmp', shell=True)
self.assertEqual(exitcode1, 5) # Specific exitcode 5
......@@ -15,16 +15,15 @@ class XMLParserTest(unittest.TestCase):
def setUp(self):
self.px = PLIPXML('./xml/1vsn.report.xml')
self.bsite = self.px.bsites['NFT:A:283']
self.smiles = 'N=CCNC(=O)[C@H](CC(C)C)N[C@H](C(F)(F)F)c1ccc(cc1)c1ccc(cc1)S(=O)(=O)N'
self.smiles = 'CC(C)CC(NC(c1ccc(cc1)c1ccc(cc1)S(N)(=O)=O)C(F)(F)F)C(=O)NCC=N'
def test_general_information(self):
"""Test if general information is correctly parsed."""
self.assertEqual(self.px.version, '1.3.2')
self.assertEqual(self.px.version, '1.4.2')
self.assertEqual(self.px.pdbid, '1VSN')
self.assertEqual(self.px.filetype, 'PDB')
self.assertFalse(self.px.fixed)
self.assertEqual(self.px.filename, '1vsn.pdb')
self.assertEqual(self.px.excluded, None)
self.assertEqual(self.px.excluded, [])
def test_bsite_information(self):
"""Test if the binding site information is correctly parsed."""
......@@ -47,17 +46,17 @@ class XMLParserTest(unittest.TestCase):
self.assertEqual(self.bsite.unpaired_hal, 1)
self.assertEqual(self.bsite.rings, 2)
self.assertEqual(self.bsite.rotatable_bonds, 12)
self.assertEqual(self.bsite.molweight, 484.5349896)
self.assertEqual(self.bsite.logp, 6.0371)
self.assertAlmostEqual(self.bsite.molweight, 484, 0)
self.assertAlmostEqual(self.bsite.logp, 6, 0)
# Atom mappings (non-exhaustive test)
lmap = self.bsite.mappings['pdb_to_smiles']
self.assertEqual(lmap[1625], 9)
self.assertEqual(lmap[1649], 1)
self.assertEqual(lmap[1617], 19)
self.assertEqual(lmap[1625], 24)
self.assertEqual(lmap[1649], 33)
self.assertEqual(lmap[1617], 14)
# Binding site residues
self.assertEqual(len(self.bsite.bs_res), 36)
self.assertEqual(len(self.bsite.bs_res), 35)
# Interacting chains
self.assertEqual(self.bsite.interacting_chains, ['A'])
......@@ -82,7 +81,7 @@ class XMLParserTest(unittest.TestCase):
# Hydrogen Bonds
self.assertEqual(len(self.bsite.hbonds), 7)
self.assertEqual(len(self.bsite.hbonds), 6)
hbond1 = self.bsite.hbonds[0]
self.assertEqual(hbond1.resnr, 19)
self.assertEqual(hbond1.restype, 'GLN')
......@@ -100,7 +99,7 @@ class XMLParserTest(unittest.TestCase):
self.assertEqual(hbond1.protcoo, (3.976, 15.409, 7.712))
# Water Bridges
self.assertEqual(len(self.bsite.wbridges), 2)
self.assertEqual(len(self.bsite.wbridges), 1)
wbridge1 = self.bsite.wbridges[0]
self.assertEqual(wbridge1.resnr, 159)
self.assertEqual(wbridge1.restype, 'HIS')
......
<?xml version='1.0' encoding='ASCII'?>
<report>
<plipversion>1.3.2</plipversion>
<plipversion>1.4.2</plipversion>
<bindingsite id="1" has_interactions="True">
<identifiers>
<longname>NFT</longname>
......@@ -12,7 +12,8 @@
<members>
<member id="1">NFT:A:283</member>
</members>
<smiles>N=CCNC(=O)[C@H](CC(C)C)N[C@H](C(F)(F)F)c1ccc(cc1)c1ccc(cc1)S(=O)(=O)N</smiles>
<smiles>CC(C)CC(NC(c1ccc(cc1)c1ccc(cc1)S(N)(=O)=O)C(F)(F)F)C(=O)NCC=N</smiles>
<inchikey>LUFZQYFBEDDLGO-UHFFFAOYSA-N</inchikey>
</identifiers>
<lig_properties>
<num_heavy_atoms>33</num_heavy_atoms>
......@@ -24,8 +25,8 @@
<num_unpaired_hal>1</num_unpaired_hal>
<num_aromatic_rings>2</num_aromatic_rings>
<num_rotatable_bonds>12</num_rotatable_bonds>
<molweight>484.5349896</molweight>
<logp>6.0371</logp>
<molweight>483.5270496</molweight>
<logp>5.9141</logp>
</lig_properties>
<interacting_chains>
<interacting_chain id="1">A</interacting_chain>
......@@ -50,23 +51,22 @@
<bs_residue aa="PHE" contact="False" id="17" min_dist="7.4">28A</bs_residue>
<bs_residue aa="LEU" contact="False" id="18" min_dist="4.2">205A</bs_residue>
<bs_residue aa="THR" contact="False" id="19" min_dist="7.3">69A</bs_residue>
<bs_residue aa="TRP" contact="True" id="20" min_dist="5.8">177A</bs_residue>
<bs_residue aa="TRP" contact="False" id="20" min_dist="5.8">177A</bs_residue>
<bs_residue aa="HIS" contact="True" id="21" min_dist="4.0">159A</bs_residue>
<bs_residue aa="ASN" contact="True" id="22" min_dist="2.9">158A</bs_residue>
<bs_residue aa="VAL" contact="False" id="23" min_dist="6.9">161A</bs_residue>
<bs_residue aa="ALA" contact="False" id="24" min_dist="6.8">27A</bs_residue>
<bs_residue aa="ALA" contact="False" id="25" min_dist="6.8">1156A</bs_residue>
<bs_residue aa="CYS" contact="True" id="26" min_dist="1.7">25A</bs_residue>
<bs_residue aa="GLY" contact="False" id="27" min_dist="3.4">23A</bs_residue>
<bs_residue aa="GLU" contact="False" id="28" min_dist="3.3">59A</bs_residue>
<bs_residue aa="GLY" contact="False" id="29" min_dist="5.8">62A</bs_residue>
<bs_residue aa="VAL" contact="False" id="30" min_dist="6.0">132A</bs_residue>
<bs_residue aa="ASN" contact="False" id="31" min_dist="3.0">60A</bs_residue>
<bs_residue aa="ILE" contact="False" id="32" min_dist="5.7">134A</bs_residue>
<bs_residue aa="VAL" contact="False" id="33" min_dist="6.3">57A</bs_residue>
<bs_residue aa="GLN" contact="True" id="34" min_dist="3.1">19A</bs_residue>
<bs_residue aa="ASN" contact="False" id="35" min_dist="5.9">70A</bs_residue>
<bs_residue aa="GLY" contact="True" id="36" min_dist="2.9">66A</bs_residue>
<bs_residue aa="GLY" contact="False" id="26" min_dist="3.4">23A</bs_residue>
<bs_residue aa="GLU" contact="False" id="27" min_dist="3.3">59A</bs_residue>
<bs_residue aa="GLY" contact="False" id="28" min_dist="5.8">62A</bs_residue>
<bs_residue aa="VAL" contact="False" id="29" min_dist="6.0">132A</bs_residue>
<bs_residue aa="ASN" contact="False" id="30" min_dist="3.0">60A</bs_residue>
<bs_residue aa="ILE" contact="False" id="31" min_dist="5.7">134A</bs_residue>
<bs_residue aa="VAL" contact="False" id="32" min_dist="6.3">57A</bs_residue>
<bs_residue aa="GLN" contact="True" id="33" min_dist="3.1">19A</bs_residue>
<bs_residue aa="ASN" contact="False" id="34" min_dist="5.9">70A</bs_residue>
<bs_residue aa="GLY" contact="True" id="35" min_dist="2.9">66A</bs_residue>
</bs_residues>
<interactions>
<hydrophobic_interactions>
......@@ -74,6 +74,9 @@
<resnr>61</resnr>
<restype>ASP</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<dist>3.67</dist>
<ligcarbonidx>1639</ligcarbonidx>
<protcarbonidx>448</protcarbonidx>
......@@ -92,6 +95,9 @@
<resnr>67</resnr>
<restype>TYR</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<dist>3.73</dist>
<ligcarbonidx>1622</ligcarbonidx>
<protcarbonidx>482</protcarbonidx>
......@@ -110,6 +116,9 @@
<resnr>67</resnr>
<restype>TYR</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<dist>3.84</dist>
<ligcarbonidx>1636</ligcarbonidx>
<protcarbonidx>481</protcarbonidx>
......@@ -128,6 +137,9 @@
<resnr>133</resnr>
<restype>ALA</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<dist>3.97</dist>
<ligcarbonidx>1636</ligcarbonidx>
<protcarbonidx>994</protcarbonidx>
......@@ -148,6 +160,9 @@
<resnr>19</resnr>
<restype>GLN</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>True</sidechain>
<dist_h-a>2.16</dist_h-a>
<dist_d-a>3.11</dist_d-a>
......@@ -169,33 +184,12 @@
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="2">
<resnr>25</resnr>
<restype>CYS</restype>
<reschain>A</reschain>
<sidechain>False</sidechain>
<dist_h-a>2.21</dist_h-a>
<dist_d-a>3.09</dist_d-a>
<don_angle>146.90</don_angle>
<protisdon>True</protisdon>
<donoridx>183</donoridx>
<donortype>Nam</donortype>
<acceptoridx>1649</acceptoridx>
<acceptortype>N2</acceptortype>
<ligcoo>
<x>2.820</x>
<y>18.145</y>
<z>6.806</z>
</ligcoo>
<protcoo>
<x>3.306</x>
<y>18.620</y>
<z>9.817</z>
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="3">
<resnr>61</resnr>
<restype>ASP</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>True</sidechain>
<dist_h-a>2.26</dist_h-a>
<dist_d-a>2.99</dist_d-a>
......@@ -216,10 +210,13 @@
<z>9.223</z>
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="4">
<hydrogen_bond id="3">
<resnr>61</resnr>
<restype>ASP</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>True</sidechain>
<dist_h-a>1.98</dist_h-a>
<dist_d-a>2.99</dist_d-a>
......@@ -240,10 +237,13 @@
<z>9.223</z>
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="5">
<hydrogen_bond id="4">
<resnr>66</resnr>
<restype>GLY</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>False</sidechain>
<dist_h-a>2.33</dist_h-a>
<dist_d-a>3.18</dist_d-a>
......@@ -264,10 +264,13 @@
<z>8.576</z>
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="6">
<hydrogen_bond id="5">
<resnr>66</resnr>
<restype>GLY</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>False</sidechain>
<dist_h-a>2.05</dist_h-a>
<dist_d-a>2.95</dist_d-a>
......@@ -288,10 +291,13 @@
<z>8.621</z>
</protcoo>
</hydrogen_bond>
<hydrogen_bond id="7">
<hydrogen_bond id="6">
<resnr>158</resnr>
<restype>ASN</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>False</sidechain>
<dist_h-a>1.95</dist_h-a>
<dist_d-a>2.92</dist_d-a>
......@@ -318,6 +324,9 @@
<resnr>159</resnr>
<restype>HIS</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<dist_a-w>3.67</dist_a-w>
<dist_d-w>3.13</dist_d-w>
<don_angle>126.73</don_angle>
......@@ -344,36 +353,6 @@
<z>3.309</z>
</watercoo>
</water_bridge>
<water_bridge id="2">
<resnr>177</resnr>
<restype>TRP</restype>
<reschain>A</reschain>
<dist_a-w>3.96</dist_a-w>
<dist_d-w>3.04</dist_d-w>
<don_angle>125.14</don_angle>
<water_angle>84.15</water_angle>
<protisdon>True</protisdon>
<donor_idx>1380</donor_idx>
<donortype>Nar</donortype>
<acceptor_idx>1649</acceptor_idx>
<acceptortype>N2</acceptortype>
<water_idx>1735</water_idx>
<ligcoo>
<x>2.820</x>
<y>18.145</y>
<z>6.806</z>
</ligcoo>
<protcoo>
<x>7.577</x>
<y>15.116</y>
<z>5.463</z>
</protcoo>
<watercoo>
<x>4.665</x>
<y>15.397</y>
<z>4.635</z>
</watercoo>
</water_bridge>
</water_bridges>
<salt_bridges/>
<pi_stacks/>
......@@ -383,6 +362,9 @@
<resnr>67</resnr>
<restype>TYR</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>True</sidechain>
<dist>3.37</dist>
<don_angle>156.70</don_angle>
......@@ -406,6 +388,9 @@
<resnr>157</resnr>
<restype>LEU</restype>
<reschain>A</reschain>
<resnr_lig>283</resnr_lig>
<restype_lig>NFT</restype_lig>
<reschain_lig>A</reschain_lig>
<sidechain>False</sidechain>
<dist>3.24</dist>
<don_angle>141.32</don_angle>
......@@ -429,12 +414,14 @@
<metal_complexes/>
</interactions>
<mappings>
<smiles_to_pdb>1:1649,2:1648,3:1630,4:1629,5:1637,6:1632,7:1631,8:1624,9:1625,10:1626,11:1627,12:1628,13:1623,14:1621,15:1620,16:1619,17:1618,18:1622,19:1617,20:1639,21:1640,22:1641,23:1642,24:1643,25:1644,26:1645,27:1646,28:1647,29:1633,30:1634,31:1635,32:1636,33:1638</smiles_to_pdb>
<smiles_to_pdb>1:1636,2:1634,3:1635,4:1633,5:1632,6:1631,7:1624,8:1623,9:1621,10:1620,11:1619,12:1618,13:1622,14:1617,15:1639,16:1640,17:1641,18:1642,19:1643,20:1644,21:1645,22:1646,23:1647,24:1625,25:1626,26:1627,27:1628,28:1637,29:1638,30:1629,31:1630,32:1648,33:1649</smiles_to_pdb>
</mappings>
</bindingsite>
<date_of_creation>2018/08/07</date_of_creation>
<citation_information>Salentin,S. et al. PLIP: fully automated protein-ligand interaction profiler. Nucl. Acids Res. (1 July 2015) 43 (W1): W443-W447. doi: 10.1093/nar/gkv315</citation_information>
<mode>default</mode>
<pdbid>1VSN</pdbid>
<filetype>PDB</filetype>
<pdbfile>1vsn.pdb</pdbfile>
<pdbfile>./1vsn.pdb</pdbfile>
<pdbfixes>False</pdbfixes>
<filename>1vsn.pdb</filename>
<excluded_ligands/>
......
......@@ -22,7 +22,7 @@ setup(name='plip',
author_email='sebastian.salentin@tu-dresden.de',
license='GPLv2',
packages=['plip', 'plip/modules'],
scripts=['plip/plipcmd'],
scripts=['plip/plipcmd.py'],
install_requires=[
'openbabel',
'numpy',
......