[med-svn] [Git][med-team/plip][upstream] New upstream version 1.4.3~b+dfsg

Alexandre Mestiashvili gitlab at salsa.debian.org
Tue Sep 25 10:42:44 BST 2018


Alexandre Mestiashvili pushed to branch upstream at Debian Med / plip


Commits:
175430d3 by Alexandre Mestiashvili at 2018-09-25T09:38:16Z
New upstream version 1.4.3~b+dfsg
- - - - -


11 changed files:

- CHANGES.txt
- DOCUMENTATION.md
- README.md
- plip/modules/detection.py
- plip/modules/plipxml.py
- plip/modules/report.py
- plip/plipcmd → plip/plipcmd.py
- plip/test/test_special_cases.py
- plip/test/test_xml_parser.py
- plip/test/xml/1vsn.report.xml
- setup.py


Changes:

=====================================
CHANGES.txt
=====================================
@@ -1,5 +1,8 @@
 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


=====================================
DOCUMENTATION.md
=====================================
@@ -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


=====================================
README.md
=====================================
@@ -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/modules/detection.py
=====================================
@@ -17,26 +17,25 @@ 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:
-        filtered1_pairings = [p for p in pairings if (p.resnr, p.reschain) != (p.resnr_l, p.reschain_l)]
-        already_considered = []
-        filtered2_pairings = []
-        for contact in filtered1_pairings:
+    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 = []
+    for contact in filtered1_pairings:
+        try:
+            dist = 'D{}'.format(round(contact.distance,2))
+        except AttributeError:
             try:
-                dist = 'D{}'.format(round(contact.distance,2))
+                dist = 'D{}'.format(round(contact.distance_ah,2))
             except AttributeError:
-                try:
-                    dist = 'D{}'.format(round(contact.distance_ah,2))
-                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])
-            if data not in already_considered:
-                filtered2_pairings.append(contact)
-                already_considered.append(data)
-        return filtered2_pairings
-    else:
-        return pairings
+                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 = {res1, res2, dist}
+        if data not in already_considered:
+            filtered2_pairings.append(contact)
+            already_considered.append(data)
+    return filtered2_pairings
 
 
 ##################################################
@@ -54,14 +53,15 @@ 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:
-            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,
-                           distance=e, restype=restype, resnr=resnr,
-                           reschain=reschain, restype_l=restype_l,
-                           resnr_l=resnr_l, reschain_l=reschain_l)
-            pairings.append(contact)
+        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,
+                       distance=e, restype=restype, resnr=resnr,
+                       reschain=reschain, restype_l=restype_l,
+                       resnr_l=resnr_l, reschain_l=reschain_l)
+        pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -75,32 +75,36 @@ 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
-            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:
-                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:
-                    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
-                    resnr = whichresnumber(don.d) if protisdon else whichresnumber(acc.a)
-                    resnr_l = whichresnumber(acc.a_orig_atom) if protisdon else whichresnumber(don.d_orig_atom)
-                    restype = whichrestype(don.d) if protisdon else whichrestype(acc.a)
-                    restype_l = whichrestype(acc.a_orig_atom) if protisdon else whichrestype(don.d_orig_atom)
-                    reschain = whichchain(don.d) if protisdon else whichchain(acc.a)
-                    rechain_l = whichchain(acc.a_orig_atom) if protisdon else whichchain(don.d_orig_atom)
-                    # Next line prevents H-Bonds within amino acids in intermolecular interactions
-                    if config.INTRA is not None and whichresnumber(don.d) == whichresnumber(acc.a): continue
-                    # Next line prevents backbone-backbone H-Bonds
-                    if config.INTRA is not None and protatom.GetResidue().GetAtomProperty(protatom, 8) and ligatom.GetResidue().GetAtomProperty(ligatom, 8): continue
-                    contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, d=don.d, d_orig_idx=don.d_orig_idx, h=don.h,
-                                   distance_ah=dist_ah, distance_ad=dist_ad, angle=v, type=typ, protisdon=protisdon,
-                                   resnr=resnr, restype=restype, reschain=reschain, resnr_l=resnr_l,
-                                   restype_l=restype_l, reschain_l=rechain_l, sidechain=is_sidechain_hbond,
-                                   atype=acc.a.type, dtype=don.d.type)
-                    pairings.append(contact)
+        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 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 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
+        resnr = whichresnumber(don.d) if protisdon else whichresnumber(acc.a)
+        resnr_l = whichresnumber(acc.a_orig_atom) if protisdon else whichresnumber(don.d_orig_atom)
+        restype = whichrestype(don.d) if protisdon else whichrestype(acc.a)
+        restype_l = whichrestype(acc.a_orig_atom) if protisdon else whichrestype(don.d_orig_atom)
+        reschain = whichchain(don.d) if protisdon else whichchain(acc.a)
+        rechain_l = whichchain(acc.a_orig_atom) if protisdon else whichchain(don.d_orig_atom)
+        # Next line prevents H-Bonds within amino acids in intermolecular interactions
+        if config.INTRA is not None and whichresnumber(don.d) == whichresnumber(acc.a): continue
+        # Next line prevents backbone-backbone H-Bonds
+        if config.INTRA is not None and protatom.GetResidue().GetAtomProperty(protatom, 8) and ligatom.GetResidue().GetAtomProperty(ligatom, 8): continue
+        contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, d=don.d, d_orig_idx=don.d_orig_idx, h=don.h,
+                       distance_ah=dist_ah, distance_ad=dist_ad, angle=v, type=typ, protisdon=protisdon,
+                       resnr=resnr, restype=restype, reschain=reschain, resnr_l=resnr_l,
+                       restype_l=restype_l, reschain_l=rechain_l, sidechain=is_sidechain_hbond,
+                       atype=acc.a.type, dtype=don.d.type)
+        pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -125,18 +129,19 @@ def pistacking(rings_bs, rings_lig):
 
         # SELECTION BY DISTANCE, ANGLE AND OFFSET
         passed = False
-        if config.MIN_DIST < d < config.PISTACK_DIST_MAX:
-            if 0 < a < config.PISTACK_ANG_DEV and offset < config.PISTACK_OFFSET_MAX:
-                ptype = 'P'
-                passed = True
-            if 90 - config.PISTACK_ANG_DEV < a < 90 + config.PISTACK_ANG_DEV and offset < config.PISTACK_OFFSET_MAX:
-                ptype = 'T'
-                passed = True
-            if passed:
-                contact = data(proteinring=r, ligandring=l, distance=d, angle=a, offset=offset,
-                               type=ptype, resnr=resnr, restype=restype, reschain=reschain,
-                               resnr_l=resnr_l, restype_l=restype_l, reschain_l=reschain_l)
-                pairings.append(contact)
+        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
+        if 90 - config.PISTACK_ANG_DEV < a < 90 + config.PISTACK_ANG_DEV and offset < config.PISTACK_OFFSET_MAX:
+            ptype = 'T'
+            passed = True
+        if passed:
+            contact = data(proteinring=r, ligandring=l, distance=d, angle=a, offset=offset,
+                           type=ptype, resnr=resnr, restype=restype, reschain=reschain,
+                           resnr_l=resnr_l, restype_l=restype_l, reschain_l=reschain_l)
+            pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -146,46 +151,48 @@ 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:
-        for ring in rings:
-            c = ring.center
-            for p in pos_charged:
-                d = euclidean3d(c, p.center)
-                # 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 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
-                        n_atoms = [a_neighbor for a_neighbor in OBAtomAtomIter(p.atoms[0].OBAtom)]
-                        n_atoms_coords = [(a.x(), a.y(), a.z()) for a in n_atoms]
-                        amine_normal = np.cross(vector(n_atoms_coords[0], n_atoms_coords[1]),
-                                                vector(n_atoms_coords[2], n_atoms_coords[0]))
-                        b = vecangle(ring.normal, amine_normal)
-                        # Smallest of two angles, depending on direction of normal
-                        a = min(b, 180 - b if not 180 - b < 0 else b)
-                        if not a > 30.0:
-                            resnr, restype = whichresnumber(ring.atoms[0]), whichrestype(ring.atoms[0])
-                            reschain = whichchain(ring.atoms[0])
-                            resnr_l, restype_l = whichresnumber(p.orig_atoms[0]), whichrestype(p.orig_atoms[0])
-                            reschain_l = whichchain(p.orig_atoms[0])
-                            contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular',
-                                           restype=restype, resnr=resnr, reschain=reschain,
-                                           restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l,
-                                           protcharged=protcharged)
-                            pairings.append(contact)
-                        break
-                    resnr = whichresnumber(p.atoms[0]) if protcharged else whichresnumber(ring.atoms[0])
-                    resnr_l = whichresnumber(ring.orig_atoms[0]) if protcharged else whichresnumber(p.orig_atoms[0])
-                    restype = whichrestype(p.atoms[0]) if protcharged else whichrestype(ring.atoms[0])
-                    restype_l = whichrestype(ring.orig_atoms[0]) if protcharged else whichrestype(p.orig_atoms[0])
-                    reschain = whichchain(p.atoms[0]) if protcharged else whichchain(ring.atoms[0])
-                    reschain_l = whichchain(ring.orig_atoms[0]) if protcharged else whichchain(p.orig_atoms[0])
-                    contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular', restype=restype,
-                                   resnr=resnr, reschain=reschain, restype_l=restype_l, resnr_l=resnr_l,
-                                   reschain_l=reschain_l, protcharged=protcharged)
+    if len(rings) == 0 or len(pos_charged) == 0:
+        return pairings
+    for ring in rings:
+        c = ring.center
+        for p in pos_charged:
+            d = euclidean3d(c, p.center)
+            # 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 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
+                n_atoms = [a_neighbor for a_neighbor in OBAtomAtomIter(p.atoms[0].OBAtom)]
+                n_atoms_coords = [(a.x(), a.y(), a.z()) for a in n_atoms]
+                amine_normal = np.cross(vector(n_atoms_coords[0], n_atoms_coords[1]),
+                                        vector(n_atoms_coords[2], n_atoms_coords[0]))
+                b = vecangle(ring.normal, amine_normal)
+                # Smallest of two angles, depending on direction of normal
+                a = min(b, 180 - b if not 180 - b < 0 else b)
+                if not a > 30.0:
+                    resnr, restype = whichresnumber(ring.atoms[0]), whichrestype(ring.atoms[0])
+                    reschain = whichchain(ring.atoms[0])
+                    resnr_l, restype_l = whichresnumber(p.orig_atoms[0]), whichrestype(p.orig_atoms[0])
+                    reschain_l = whichchain(p.orig_atoms[0])
+                    contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular',
+                                   restype=restype, resnr=resnr, reschain=reschain,
+                                   restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l,
+                                   protcharged=protcharged)
                     pairings.append(contact)
+                break
+            resnr = whichresnumber(p.atoms[0]) if protcharged else whichresnumber(ring.atoms[0])
+            resnr_l = whichresnumber(ring.orig_atoms[0]) if protcharged else whichresnumber(p.orig_atoms[0])
+            restype = whichrestype(p.atoms[0]) if protcharged else whichrestype(ring.atoms[0])
+            restype_l = whichrestype(ring.orig_atoms[0]) if protcharged else whichrestype(p.orig_atoms[0])
+            reschain = whichchain(p.atoms[0]) if protcharged else whichchain(ring.atoms[0])
+            reschain_l = whichchain(ring.orig_atoms[0]) if protcharged else whichchain(p.orig_atoms[0])
+            contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular', restype=restype,
+                           resnr=resnr, reschain=reschain, restype_l=restype_l, resnr_l=resnr_l,
+                           reschain_l=reschain_l, protcharged=protcharged)
+            pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -194,17 +201,18 @@ 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:
-            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
-            restype_l = whichrestype(nc.orig_atoms[0]) if protispos else whichrestype(pc.orig_atoms[0])
-            reschain = pc.reschain if protispos else nc.reschain
-            reschain_l = whichchain(nc.orig_atoms[0]) if protispos else whichchain(pc.orig_atoms[0])
-            contact = data(positive=pc, negative=nc, distance=euclidean3d(pc.center, nc.center), protispos=protispos,
-                           resnr=resnr, restype=restype, reschain=reschain, resnr_l=resnr_l, restype_l=restype_l,
-                           reschain_l=reschain_l)
-            pairings.append(contact)
+        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
+        restype_l = whichrestype(nc.orig_atoms[0]) if protispos else whichrestype(pc.orig_atoms[0])
+        reschain = pc.reschain if protispos else nc.reschain
+        reschain_l = whichchain(nc.orig_atoms[0]) if protispos else whichchain(pc.orig_atoms[0])
+        contact = data(positive=pc, negative=nc, distance=euclidean3d(pc.center, nc.center), protispos=protispos,
+                       resnr=resnr, restype=restype, reschain=reschain, resnr_l=resnr_l, restype_l=restype_l,
+                       reschain_l=reschain_l)
+        pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -215,24 +223,27 @@ 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:
-            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 \
-                    < config.HALOGEN_ACC_ANGLE + config.HALOGEN_ANGLE_DEV:
-                if config.HALOGEN_DON_ANGLE - config.HALOGEN_ANGLE_DEV < don_angle \
-                        < config.HALOGEN_DON_ANGLE + config.HALOGEN_ANGLE_DEV:
-                    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,
-                                   distance=dist, don_angle=don_angle, acc_angle=acc_angle,
-                                   restype=restype, resnr=resnr,
-                                   reschain=reschain, restype_l=restype_l,
-                                   reschain_l=reschain_l, resnr_l=resnr_l, donortype=don.x.OBAtom.GetType(), acctype=acc.o.type,
-                                   sidechain=is_sidechain_hal)
-                    pairings.append(contact)
+        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 not config.HALOGEN_ACC_ANGLE - config.HALOGEN_ANGLE_DEV < acc_angle \
+                < config.HALOGEN_ACC_ANGLE + config.HALOGEN_ANGLE_DEV:
+            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,
+                       distance=dist, don_angle=don_angle, acc_angle=acc_angle,
+                       restype=restype, resnr=resnr,
+                       reschain=reschain, restype_l=restype_l,
+                       reschain_l=reschain_l, resnr_l=resnr_l, donortype=don.x.OBAtom.GetType(), acctype=acc.o.type,
+                       sidechain=is_sidechain_hal)
+        pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -269,32 +280,38 @@ 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
-            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:
-                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,
-                               dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
-                               distance_aw=distance_aw, distance_dw=distance_dw, d_angle=d_angle, w_angle=w_angle,
-                               type='first_deg', resnr=resnr, restype=restype,
-                               reschain=reschain, restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l, protisdon=True)
-                pairings.append(contact)
+        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 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,
+                       dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
+                       distance_aw=distance_aw, distance_dw=distance_dw, d_angle=d_angle, w_angle=w_angle,
+                       type='first_deg', resnr=resnr, restype=restype,
+                       reschain=reschain, restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l, protisdon=True)
+        pairings.append(contact)
     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
-            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:
-                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,
-                               dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
-                               distance_aw=distance_aw, distance_dw=distance_dw,
-                               d_angle=d_angle, w_angle=w_angle, type='first_deg', resnr=resnr,
-                               restype=restype, reschain=reschain,
-                               restype_l=restype_l, reschain_l=reschain_l, resnr_l=resnr_l, protisdon=False)
-                pairings.append(contact)
+        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 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,
+                       dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
+                       distance_aw=distance_aw, distance_dw=distance_dw,
+                       d_angle=d_angle, w_angle=w_angle, type='first_deg', resnr=resnr,
+                       restype=restype, reschain=reschain,
+                       restype_l=restype_l, reschain_l=reschain_l, resnr_l=resnr_l, protisdon=False)
+        pairings.append(contact)
     return filter_contacts(pairings)
 
 
@@ -310,13 +327,14 @@ 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 metal.m not in pairings_dict:
-                pairings_dict[metal.m] = [(target, distance), ]
-                metal_to_id[metal.m] = metal.m_orig_idx
-                metal_to_orig_atom[metal.m] = metal.orig_m
-            else:
-                pairings_dict[metal.m].append((target, distance))
+        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
+            metal_to_orig_atom[metal.m] = metal.orig_m
+        else:
+            pairings_dict[metal.m].append((target, distance))
     for cnum, metal in enumerate(pairings_dict):
         rms = 0.0
         excluded = []


=====================================
plip/modules/plipxml.py
=====================================
@@ -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')}


=====================================
plip/modules/report.py
=====================================
@@ -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):


=====================================
plip/plipcmd → plip/plipcmd.py
=====================================
@@ -1,7 +1,7 @@
 #! /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
-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
+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:
-        from plip.modules.visualize import visualize_in_pymol
+        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()


=====================================
plip/test/test_special_cases.py
=====================================
@@ -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


=====================================
plip/test/test_xml_parser.py
=====================================
@@ -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 at H](CC(C)C)N[C at 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')


=====================================
plip/test/xml/1vsn.report.xml
=====================================
@@ -1,6 +1,6 @@
 <?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 at H](CC(C)C)N[C at 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/>


=====================================
setup.py
=====================================
@@ -22,7 +22,7 @@ setup(name='plip',
       author_email='sebastian.salentin at tu-dresden.de',
       license='GPLv2',
       packages=['plip', 'plip/modules'],
-      scripts=['plip/plipcmd'],
+      scripts=['plip/plipcmd.py'],
       install_requires=[
           'openbabel',
           'numpy',



View it on GitLab: https://salsa.debian.org/med-team/plip/commit/175430d3ec44ef096c06082e18cd3f2ad0256bd8

-- 
View it on GitLab: https://salsa.debian.org/med-team/plip/commit/175430d3ec44ef096c06082e18cd3f2ad0256bd8
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20180925/6f89abd9/attachment-0001.html>


More information about the debian-med-commit mailing list