Skip to content
Commits on Source (6)
Changelog
---------
### Next version
-
# 1.4.0
* __Full Python 3 Compatibility__
* __Read PDB files from stdin with "-f -" and write to stdout with "-O" (capital "O")__
* Improves handling of fixed PDB files
* Option to turn off writing fixed PDB structures to a file ("--nofixfile")
### 1.3.5
* Preparation for Python 3: Imports
......
......@@ -87,7 +87,7 @@ plip -i 1vsn -v
The command above will fetch the PDB entry 1vsn from the server, analyze all interactions and print out the results (verbose mode).
No output files are produced at this point.
The same can be done for local PDB files.
The same can be done for local PDB files (-f <file>) or for reading from stdin (-f -).
```bash
wget http://files.rcsb.org/download/1EVE.pdb
......@@ -99,6 +99,7 @@ The output formats can be added in any combination, currently including:
* Text report files (`-t`, human-readable)
* PyMOL session files (`-y`)
* Ray-traced images (`-p`)
* writing to stdout (`-O`), to be used in combination with XML or text report files
```bash
plip -i 1osn -pyx
......@@ -278,7 +279,7 @@ The distance between the other ring center and the projected point (i.e. the off
This value corresponds approximately to the radius of benzene + 0.6 Å.
##### π-Cation Interactions
π-Cation interactions are reported for each pairing of a positive charge and an aromatic ring if the distance between the charge center and the aromatic ring center is less than PICATION_DIST_MAX.
π-Cation interactions are reported for each pairing of a positive charge and an aromatic ring if the distance between the charge center and the aromatic ring center is less than PICATION_DIST_MAX and the offset between the ring center and the charge is no larger than PISTACK_OFFSET_MAX.
In the case of a putative π-cation interaction with a tertiary amine of the ligand, an additional angle criterion is applied (see documentation in the source code).
##### Salt Bridges
......
Possible future features
========================
* Python 3 support
* support special characters in filenames (e.g. spanish accents), currently cause problems in XML report
* support for mmcif format
* support presets for hydrogenation
* detection of steric clashes
* detection of anion-pi interactions
* detection of electrostatic repulsion force_string
* detection of Keesom forces
* weak hydrogen bonding
* visualization: show hydrogen atoms in PyMOL for hydrogen bonds and adapt interaction vector accordingly
* use SMARTS for detection of chemical features (charged groups, etc.)
plip (1.4.0~b+dfsg-1) unstable; urgency=medium
[ Steffen Möller ]
* Updated RRID in d/u/metadata
[ Andreas Tille ]
* Remove invalid fields from debian/upstream/metadata
[ Alexandre Mestiashvili ]
* New upstream version 1.4.0~b+dfsg
* Update d/control:
- Add python-future build-dep
- Update uploader's email
- fix VCS-* fields to point to salsa
- Set debhelper and compat to 11
* Remove unused lintian override
-- Alexandre Mestiashvili <mestia@debian.org> Thu, 12 Apr 2018 12:51:07 +0200
plip (1.3.5+dfsg-1) unstable; urgency=medium
* Bump Standards-Version to 4.1.1
......
Source: plip
Maintainer: Debian Med Packaging Team <debian-med-packaging@lists.alioth.debian.org>
Uploaders: Alexandre Mestiashvili <alex@biotec.tu-dresden.de>
Uploaders: Alexandre Mestiashvili <mestia@debian.org>
Section: python
Priority: optional
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper (>= 11),
dh-python,
help2man,
pymol,
......@@ -11,10 +11,11 @@ Build-Depends: debhelper (>= 9),
python-lxml,
python-numpy,
python-openbabel,
python-setuptools
Standards-Version: 4.1.1
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/plip.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/plip.git
python-setuptools,
python-future
Standards-Version: 4.1.3
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/
Package: plip
......
plip: spelling-error-in-manpage
......@@ -10,12 +10,15 @@ XML = False
TXT = False
PICS = False
PYMOL = False
STDOUT = False
RAWSTRING = False # use raw strings for input / output
OUTPATH = './'
BASEPATH = './'
BREAKCOMPOSITE = False # Break up composite ligands with covalent bonds
ALTLOC = False # Consider alternate locations
PLUGIN_MODE = False # Special mode for PLIP in Plugins (e.g. PyMOL)
NOFIX = False # Turn off fixing of errors in PDB files
NOFIXFILE = False # Turn off writing to files for fixed PDB structures
PEPTIDES = [] # Definition which chains should be considered as peptide ligands
INTRA = None
KEEPMOD = False
......
......@@ -9,8 +9,8 @@ import itertools
from collections import defaultdict
# Own modules
from plip.modules.supplemental import *
import plip.modules.config
from .supplemental import *
from . import config
def filter_contacts(pairings):
......
......@@ -5,6 +5,7 @@ mp.py - Functions for parallel processing
# Python Standard Library
from __future__ import division
from builtins import zip
import multiprocessing
import itertools
from numpy import asarray
......@@ -28,7 +29,7 @@ def universal_worker(input_pair):
def pool_args(function, sequence, kwargs):
"""Return a single iterator of n elements of lists of length 3, given a sequence of len n."""
return itertools.izip(itertools.repeat(function), sequence, itertools.repeat(kwargs))
return zip(itertools.repeat(function), sequence, itertools.repeat(kwargs))
def parallel_fn(f):
......
......@@ -9,7 +9,11 @@ from lxml import etree
import itertools
from itertools import groupby
import sys
import urllib2
try: # Python 3
from urllib.request import urlopen
except ImportError: # Fallback Python 2.x
from urllib2 import urlopen
class XMLStorage:
......@@ -190,6 +194,7 @@ class BSite(XMLStorage):
self.longname = self.getdata(bindingsite, 'identifiers/longname')
self.ligtype = self.getdata(bindingsite, 'identifiers/ligtype')
self.smiles = self.getdata(bindingsite, 'identifiers/smiles')
self.inchikey = self.getdata(bindingsite, 'identifiers/inchikey')
# Information on binding site members
self.members = []
......@@ -298,7 +303,7 @@ class PLIPXMLREST(PLIPXML):
def load_data(self, pdbid):
"""Loads and parses an XML resource and saves it as a tree if successful"""
#TODO Implement error handling
f = urllib2.urlopen("http://projects.biotec.tu-dresden.de/plip-rest/pdb/%s?format=xml" % pdbid.lower())
f = urlopen("http://projects.biotec.tu-dresden.de/plip-rest/pdb/%s?format=xml" % pdbid.lower())
try:
self.doc = etree.parse(f)
except IOError:
......
......@@ -6,12 +6,13 @@ preparation.py - Prepare PDB input files for processing.
# Python Standard Library
from __future__ import absolute_import
from builtins import filter
from operator import itemgetter
# Own modules
from plip.modules.detection import *
from plip.modules.supplemental import *
import plip.modules.config
from .detection import *
from .supplemental import *
from . import config
################
......@@ -37,10 +38,11 @@ class PDBParser:
IV. Alternative conformations
"""
if self.as_string:
fil = self.pdbpath.split('\n')
fil = self.pdbpath.rstrip('\n').split('\n') # Removing trailing newline character
else:
fil = read(self.pdbpath).readlines()
# #@todo Also consider SSBOND entries here
f = read(self.pdbpath)
fil = f.readlines()
f.close()
corrected_lines = []
i, j = 0, 0 # idx and PDB numbering
d = {}
......@@ -75,7 +77,6 @@ class PDBParser:
corrected_pdb = self.pdbpath
corrected_lines = fil
for line in corrected_lines:
if line.startswith(("ATOM", "HETATM")):
# Retrieve alternate conformations
......@@ -293,7 +294,7 @@ class LigandFinder:
hetatoms = set()
for obresidue in kmer:
hetatoms_res = set([(obatom.GetIdx(), obatom) for obatom in pybel.ob.OBResidueAtomIter(obresidue)
if not obatom.IsHydrogen()])
if obatom.GetAtomicNum() != 1])
if not config.ALTLOC:
# Remove alternative conformations (standard -> True)
......@@ -488,7 +489,7 @@ class Mol:
"""Find all possible hydrogen bond acceptors"""
data = namedtuple('hbondacceptor', 'a a_orig_atom a_orig_idx type')
a_set = []
for atom in itertools.ifilter(lambda at: at.OBAtom.IsHbondAcceptor(), all_atoms):
for atom in filter(lambda at: at.OBAtom.IsHbondAcceptor(), all_atoms):
if atom.atomicnum not in [9, 17, 35, 53] and atom.idx not in self.altconf: # Exclude halogen atoms
a_orig_idx = self.Mapper.mapid(atom.idx, mtype=self.mtype, bsid=self.bsid)
a_orig_atom = self.Mapper.id_to_atom(a_orig_idx)
......@@ -978,6 +979,7 @@ class Ligand(Mol):
self.complex = cclass
self.molecule = ligand.mol # Pybel Molecule
self.smiles = self.molecule.write(format='can') # SMILES String
self.inchikey = self.molecule.write(format='inchikey')
self.can_to_pdb = ligand.can_to_pdb
if not len(self.smiles) == 0:
self.smiles = self.smiles.split()[0]
......@@ -1256,7 +1258,7 @@ class PDBComplex:
self.sourcefiles = {}
self.information = {}
self.corrected_pdb = ''
self.output_path = '/tmp'
self._output_path = '/tmp'
self.pymol_name = None
self.modres = set()
self.resis = []
......@@ -1284,7 +1286,7 @@ class PDBComplex:
pdbparser = PDBParser(pdbpath, as_string=as_string) # Parse PDB file to find errors and get additonal data
# #@todo Refactor and rename here
self.Mapper.proteinmap = pdbparser.proteinmap
self.Mapper.reversed_proteinmap = inv_map = {v: k for k, v in self.Mapper.proteinmap.iteritems()}
self.Mapper.reversed_proteinmap = inv_map = {v: k for k, v in self.Mapper.proteinmap.items()}
self.modres = pdbparser.modres
self.covalent = pdbparser.covalent
self.altconf = pdbparser.altconformations
......@@ -1294,20 +1296,23 @@ class PDBComplex:
if pdbparser.num_fixed_lines > 0:
write_message('%i lines automatically fixed in PDB input file.\n' % pdbparser.num_fixed_lines)
# Save modified PDB file
if not as_string:
basename = os.path.basename(pdbpath).split('.')[0]
else:
basename = "from_stdin"
pdbpath_fixed = tmpfile(prefix='plipfixed.' + basename + '_', direc=self.output_path)
create_folder_if_not_exists(self.output_path)
self.sourcefiles['pdbcomplex'] = pdbpath_fixed
self.corrected_pdb = re.sub(r'[^\x00-\x7F]+', ' ', self.corrected_pdb) # Strip non-unicode chars
if not config.NOFIXFILE: # Only write to file if this option is not activated
with open(pdbpath_fixed, 'w') as f:
f.write(self.corrected_pdb)
self.information['pdbfixes'] = True
if as_string:
self.protcomplex, self.filetype = read_pdb(self.sourcefiles['pdbstring'], as_string=as_string)
else:
if not as_string:
self.sourcefiles['filename'] = os.path.basename(self.sourcefiles['pdbcomplex'])
self.protcomplex, self.filetype = read_pdb(self.sourcefiles['pdbcomplex'], as_string=as_string)
self.protcomplex, self.filetype = read_pdb(self.corrected_pdb, as_string=True)
# Update the model in the Mapper class instance
self.Mapper.original_structure = self.protcomplex.OBMol
......@@ -1434,8 +1439,8 @@ class PDBComplex:
@property
def output_path(self):
return self.output_path
return self._output_path
@output_path.setter
def output_path(self, path):
self.output_path = tilde_expansion(path)
self._output_path = tilde_expansion(path)
......@@ -69,7 +69,7 @@ class PyMOLVisualizer:
idlist = list(set(idlist)) # Remove duplicates
if not selection_exists:
cmd.select(selname, 'None') # Empty selection first
idchunks = [idlist[i:i+chunksize] for i in xrange(0, len(idlist), chunksize)]
idchunks = [idlist[i:i+chunksize] for i in range(0, len(idlist), chunksize)]
for idchunk in idchunks:
cmd.select(selname, '%s or (id %s)' % (selname, '+'.join(map(str, idchunk))))
if restrict is not None:
......
......@@ -3,18 +3,23 @@ Protein-Ligand Interaction Profiler - Analyze and visualize protein-ligand inter
report.py - Write PLIP results to output files.
"""
# Compatibility
from __future__ import print_function
from __future__ import absolute_import
# Python Standard Library
import time
from operator import itemgetter
import sys
import config
# Own modules
from . import config
# External libraries
import lxml.etree as et
__version__ = '1.3.4'
__version__ = '1.4.0'
class StructureReport:
"""Creates reports (xml or txt) for one structure/"""
......@@ -50,7 +55,7 @@ class StructureReport:
pdbfixes = et.SubElement(report, 'pdbfixes')
pdbfixes.text = str(self.mol.information['pdbfixes'])
filename = et.SubElement(report, 'filename')
filename.text = str(self.mol.sourcefiles['filename'])
filename.text = str(self.mol.sourcefiles.get('filename') or None)
exligs = et.SubElement(report, 'excluded_ligands')
for i, exlig in enumerate(self.excluded):
e = et.SubElement(exligs, 'excluded_ligand', id=str(i + 1))
......@@ -92,7 +97,10 @@ class StructureReport:
if not as_string:
et.ElementTree(self.xmlreport).write('%s/report.xml' % self.outpath, pretty_print=True, xml_declaration=True)
else:
print et.tostring(self.xmlreport, pretty_print=True)
output = et.tostring(self.xmlreport, pretty_print=True)
if config.RAWSTRING:
output = repr(output)
print(output)
def write_txt(self, as_string=False):
"""Write the TXT report"""
......@@ -100,7 +108,10 @@ class StructureReport:
with open('%s/report.txt' % self.outpath, 'w') as f:
[f.write(textline + '\n') for textline in self.txtreport]
else:
print '\n'.join(self.txtreport)
output = '\n'.join(self.txtreport)
if config.RAWSTRING:
output = repr(output)
print(output)
class BindingSiteReport:
......@@ -350,6 +361,7 @@ class BindingSiteReport:
composite = et.SubElement(identifiers, 'composite')
members = et.SubElement(identifiers, 'members')
smiles = et.SubElement(identifiers, 'smiles')
inchikey = et.SubElement(identifiers, 'inchikey')
# Ligand properties. Number of (unpaired) functional atoms and rings.
lig_properties = et.SubElement(report, 'lig_properties')
......@@ -391,6 +403,7 @@ class BindingSiteReport:
longname.text = self.longname
ligtype.text = self.ligtype
smiles.text = self.ligand.smiles
inchikey.text = self.ligand.inchikey
num_heavy_atoms.text = str(self.ligand.heavy_atoms) # Number of heavy atoms in ligand
for i, member in enumerate(self.lig_members):
bsid = ":".join(str(element) for element in member)
......
......@@ -8,7 +8,7 @@ from __future__ import print_function
from __future__ import absolute_import
# PLIP Modules
import plip.modules.config as config
from . import config
# Python standard library
import re
......@@ -92,7 +92,7 @@ def vector(p1, p2):
:param p2: coordinates of point p2
:returns : numpy array with vector coordinates
"""
return None if len(p1) != len(p2) else np.array([p2[i] - p1[i] for i in xrange(len(p1))])
return None if len(p1) != len(p2) else np.array([p2[i] - p1[i] for i in range(len(p1))])
def vecangle(v1, v2, deg=True):
......@@ -123,7 +123,7 @@ def centroid(coo):
:param coo: Array of coordinate arrays
:returns : centroid coordinates as list
"""
return map(np.mean, (([c[0] for c in coo]), ([c[1] for c in coo]), ([c[2] for c in coo])))
return list(map(np.mean, (([c[0] for c in coo]), ([c[1] for c in coo]), ([c[2] for c in coo]))))
def projection(pnormal1, ppoint, tpoint):
......@@ -334,12 +334,13 @@ def get_isomorphisms(reference, lig):
return isomorphs
def canonicalize(lig):
def canonicalize(lig, preserve_bond_order=False):
"""Get the canonical atom order for the ligand."""
atomorder = None
# Get canonical atom order
lig = pybel.ob.OBMol(lig.OBMol)
if not preserve_bond_order:
for bond in pybel.ob.OBMolBondIter(lig):
if bond.GetBondOrder() != 1:
bond.SetBondOrder(1)
......@@ -398,31 +399,38 @@ def read(fil):
zf = zipfile.ZipFile(fil, 'r')
return zf.open(zf.infolist()[0].filename)
else:
try:
codecs.open(fil, 'r', 'utf-8').read()
return codecs.open(fil, 'r', 'utf-8')
except UnicodeDecodeError:
return open(fil, 'r')
#try:
# codecs.open(fil, 'r', 'utf-8').read()
# return codecs.open(fil, 'r', 'utf-8')
#except UnicodeDecodeError:
# return open(fil, 'r')
def readmol(path, as_string=False):
"""Reads the given molecule file and returns the corresponding Pybel molecule as well as the input file type.
In contrast to the standard Pybel implementation, the file is closed properly."""
supported_formats = ['pdb', 'mmcif']
obc = pybel.ob.OBConversion()
# Fix for Windows-generated files: Remove carriage return characters
if "\r" in path and as_string:
path = path.replace('\r', '')
for sformat in supported_formats:
obc = pybel.ob.OBConversion()
obc.SetInFormat(sformat)
write_message("Detected {} as format. Now trying to read file with OpenBabel...\n".format(sformat), mtype='debug')
mol = pybel.ob.OBMol()
# Read molecules with single bond information
if as_string:
read_file = pybel.readstring(format=sformat, filename=path, opt={"s": None})
try:
mymol = pybel.readstring(sformat, path)
except IOError:
sysexit(4, 'No valid file format provided.')
else:
read_file = pybel.readfile(format=sformat, filename=path, opt={"s": None})
try:
mymol = read_file.next()
mymol = next(read_file)
except StopIteration:
sysexit(4, 'File contains no valid molecules.\n')
......
......@@ -7,10 +7,10 @@ visualize.py - Visualization of PLIP results using PyMOL.
from __future__ import absolute_import
# Own modules
from plip.modules.supplemental import initialize_pymol, start_pymol, write_message, colorlog, sysexit
import plip.modules.config as config
from plip.modules.pymolplip import PyMOLVisualizer
from plip.modules.plipremote import VisualizerData
from .supplemental import initialize_pymol, start_pymol, write_message, colorlog, sysexit
from . import config
from .pymolplip import PyMOLVisualizer
from .plipremote import VisualizerData
# Python Standard Library
import json
......@@ -29,7 +29,7 @@ def select_by_ids(selname, idlist, selection_exists=False, chunksize=20, restric
idlist = list(set(idlist)) # Remove duplicates
if not selection_exists:
cmd.select(selname, 'None') # Empty selection first
idchunks = [idlist[i:i+chunksize] for i in xrange(0, len(idlist), chunksize)]
idchunks = [idlist[i:i+chunksize] for i in range(0, len(idlist), chunksize)]
for idchunk in idchunks:
cmd.select(selname, '%s or (id %s)' % (selname, '+'.join(map(str, idchunk))))
if restrict is not None:
......
......@@ -5,10 +5,15 @@ webservices.py - Connect to various webservices to retrieve data
# Python standard library
from __future__ import absolute_import
import urllib2
try: # Python 3
from urllib.request import urlopen
from urllib.error import HTTPError
except ImportError: # Fallback Python 2.x
from urllib2 import urlopen, HTTPError
# Own modules
from plip.modules.supplemental import write_message, sysexit
from .supplemental import write_message, sysexit
# External libraries
import lxml.etree as et
......@@ -18,7 +23,7 @@ import lxml.etree as et
def check_pdb_status(pdbid):
"""Returns the status and up-to-date entry in the PDB for a given PDB ID"""
url = 'http://www.rcsb.org/pdb/rest/idStatus?structureId=%s' % pdbid
xmlf = urllib2.urlopen(url)
xmlf = urlopen(url)
xml = et.parse(xmlf)
xmlf.close()
status = None
......@@ -45,11 +50,11 @@ def fetch_pdb(pdbid):
write_message('Downloading file from PDB ... ')
pdburl = 'http://www.rcsb.org/pdb/files/%s.pdb' % current_entry # Get URL for current entry
try:
pdbfile = urllib2.urlopen(pdburl).read()
pdbfile = urlopen(pdburl).read().decode()
# If no PDB file is available, a text is now shown with "We're sorry, but ..."
# Could previously be distinguished by an HTTP error
if 'sorry' in pdbfile:
sysexit(5, "No file in PDB format available from wwPDB for the given PDB ID.\n")
except urllib2.HTTPError:
except HTTPError:
sysexit(5, "No file in PDB format available from wwPDB for the given PDB ID.\n")
return [pdbfile, current_entry]
......@@ -9,13 +9,13 @@ from __future__ import print_function
from __future__ import absolute_import
# Own modules
from plip.modules.preparation import *
from plip.modules.visualize import visualize_in_pymol
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
from modules.preparation import *
from modules.visualize import visualize_in_pymol
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
......@@ -24,6 +24,7 @@ from argparse import ArgumentParser
import time
import multiprocessing
import json
# External libraries
import lxml.etree as et
......@@ -44,14 +45,17 @@ def threshold_limiter(aparser, arg):
def process_pdb(pdbfile, outpath):
def process_pdb(pdbfile, outpath, as_string=False):
"""Analysis of a single PDB file. Can generate textual reports XML, PyMOL session files and images as output."""
if not as_string:
startmessage = '\nStarting analysis of %s\n' % pdbfile.split('/')[-1]
else:
startmessage = "Starting analysis from stdin.\n"
write_message(startmessage)
write_message('='*len(startmessage)+'\n')
mol = PDBComplex()
mol.output_path = outpath
mol.load_pdb(pdbfile)
mol.load_pdb(pdbfile, as_string=as_string)
# #@todo Offers possibility for filter function from command line (by ligand chain, position, hetid)
for ligand in mol.ligands:
mol.characterize_complex(ligand)
......@@ -79,10 +83,10 @@ def process_pdb(pdbfile, outpath):
[visualize_in_pymol(plcomplex) for plcomplex in complexes]
if config.XML: # Generate report in xml format
streport.write_xml()
streport.write_xml(as_string=config.STDOUT)
if config.TXT: # Generate report in txt (rst) format
streport.write_txt()
streport.write_txt(as_string=config.STDOUT)
def download_structure(inputpdbid):
"""Given a PDB ID, downloads the corresponding PDB structure.
......@@ -127,13 +131,23 @@ def main(inputstructs, inputpdbids):
if inputstructs is not None: # Process PDB file(s)
num_structures = len(inputstructs)
inputstructs = remove_duplicates(inputstructs)
read_from_stdin = False
for inputstruct in inputstructs:
if inputstruct == '-':
inputstruct = sys.stdin.read()
read_from_stdin = True
if config.RAWSTRING:
if sys.version_info < (3,):
inputstruct = bytes(inputstruct).decode('unicode_escape')
else:
inputstruct = bytes(inputstruct, 'utf8').decode('unicode_escape')
else:
if os.path.getsize(inputstruct) == 0:
sysexit(2, 'Empty PDB file\n') # Exit if input file is empty
if num_structures > 1:
basename = inputstruct.split('.')[-2].split('/')[-1]
config.OUTPATH = '/'.join([config.BASEPATH, basename])
process_pdb(inputstruct, config.OUTPATH)
process_pdb(inputstruct, config.OUTPATH, as_string=read_from_stdin)
else: # Try to fetch the current PDB structure(s) directly from the RCBS server
num_pdbids = len(inputpdbids)
inputpdbids =remove_duplicates(inputpdbids)
......@@ -157,9 +171,12 @@ if __name__ == '__main__':
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="+")
pdbstructure.add_argument("-f", "--file", dest="input", nargs="+", help="Set input file, '-' reads from stdin") # '-' as file name reads from stdin
pdbstructure.add_argument("-i", "--input", dest="pdbid", nargs="+")
parser.add_argument("-o", "--out", dest="outpath", default="./")
outputgroup = parser.add_mutually_exclusive_group(required=False) # Needs either outpath or stdout
outputgroup.add_argument("-o", "--out", dest="outpath", default="./")
outputgroup.add_argument("-O", "--stdout", dest="stdout", action="store_true", default=False, help="Write to stdout instead of file")
parser.add_argument("--rawstring", dest="use_raw_string", default=False, action="store_true", help="Use Python raw strings for stdout and stdin")
parser.add_argument("-v", "--verbose", dest="verbose", default=False, help="Set verbose mode", action="store_true")
parser.add_argument("-p", "--pics", dest="pics", default=False, help="Additional pictures", action="store_true")
parser.add_argument("-x", "--xml", dest="xml", default=False, help="Generate report file in XML format",
......@@ -173,8 +190,7 @@ if __name__ == '__main__':
"If not set, PLIP uses all available CPUs if possible.",
type=int)
parser.add_argument("--breakcomposite", dest="breakcomposite", default=False,
help="Don't combine ligand fragments into with covalent bonds but treat them as single ligands"
"fot the analysis.",
help="Don't combine ligand fragments with covalent bonds but treat them as single ligands for the analysis.",
action="store_true")
parser.add_argument("--altlocation", dest="altlocation", default=False,
help="Also consider alternate locations for atoms (e.g. alternate conformations).",
......@@ -185,6 +201,9 @@ if __name__ == '__main__':
parser.add_argument("--nofix", dest="nofix", default=False,
help="Turns off fixing of PDB files.",
action="store_true")
parser.add_argument("--nofixfile", dest="nofixfile", default=False,
help="Turns off writing files for fixed PDB files.",
action="store_true")
parser.add_argument("--dnareceptor", dest="dnareceptor", default=False,
help="Uses the DNA instead of the protein as a receptor for interactions.",
action="store_true")
......@@ -220,6 +239,8 @@ if __name__ == '__main__':
config.TXT = arguments.txt
config.PICS = arguments.pics
config.PYMOL = arguments.pymol
config.STDOUT = arguments.stdout
config.RAWSTRING = arguments.use_raw_string
config.OUTPATH = arguments.outpath
config.OUTPATH = tilde_expansion("".join([config.OUTPATH, '/'])
if not config.OUTPATH.endswith('/') else config.OUTPATH)
......@@ -229,6 +250,7 @@ if __name__ == '__main__':
config.PEPTIDES = arguments.peptides
config.INTRA = arguments.intra
config.NOFIX = arguments.nofix
config.NOFIXFILE = arguments.nofixfile
config.KEEPMOD = arguments.keepmod
config.DNARECEPTOR = arguments.dnareceptor
# Assign values to global thresholds
......
......@@ -77,7 +77,7 @@ class GeometryTest(unittest.TestCase):
"""Generate random data for the tests"""
# Generate two random n-dimensional float vectors, with -100 <= n <= 100 and values 0 <= i <= 1
dim = random.randint(1, 100)
self.rnd_vec = [random.uniform(-100, 100) for i in xrange(dim)]
self.rnd_vec = [random.uniform(-100, 100) for i in range(dim)]
def test_euclidean(self):
"""Tests for mathematics.euclidean"""
......
......@@ -6,7 +6,7 @@ setup.py - Setup configuration file for pip, etc.
from setuptools import setup
setup(name='plip',
version='1.3.5',
version='1.4.0',
description='PLIP - Fully automated protein-ligand interaction profiler',
classifiers=[
'Development Status :: 5 - Production/Stable',
......@@ -14,17 +14,19 @@ setup(name='plip',
'Natural Language :: English',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.5',
'Topic :: Scientific/Engineering :: Bio-Informatics'
],
url='https://github.com/ssalentin/plip',
author='Sebastian Salentin',
author_email='sebastian.salentin@biotec.tu-dresden.de',
author_email='sebastian.salentin@tu-dresden.de',
license='GPLv2',
packages=['plip', 'plip/modules'],
scripts=['plip/plipcmd'],
install_requires=[
'openbabel',
'numpy',
'lxml'
'lxml',
'future'
],
zip_safe=False)