From f17fc9acfe2aee7c8daa38eefeea64685ce4b6df Mon Sep 17 00:00:00 2001 From: Oliver Beckstein Date: Mon, 9 Jun 2014 11:58:13 -0700 Subject: [PATCH 1/2] file open/close functions can process any stream *filename* --- propka/lib.py | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/propka/lib.py b/propka/lib.py index 0bbb0a6..caa62ff 100644 --- a/propka/lib.py +++ b/propka/lib.py @@ -9,18 +9,49 @@ import pkg_resources # file I/O # def open_file_for_reading(filename): + """Open file or file-like stream *filename* for reading. + + *filename* may be a string and then it is opened but if it is a + file-like object (such as an open :class:`file` or + :class:`StringIO.StringIO` --- really anything with ``next()``, + ``read()``, ``readlines()``, ``readline``, ``close`` methods) then + the object is just passed through (the stream is attempted to be + reset to the beginning with ``fseek(0)``). + """ + if hasattr(filename, 'next') and hasattr(filename, 'read') \ + and hasattr(filename, 'readline') and hasattr(filename, 'readlines') \ + and hasattr(filename, 'close'): + # already a stream + try: + filename.fseek(0) + except AttributeError: + pass + return filename + try: f = open(filename,'r') except: - raise Exception('Cannot find file %s' %filename) + raise IOError('Cannot find file %s' %filename) return f def open_file_for_writing(filename): + """Open file or file-like stream for writing""" + if hasattr(filename, 'write') and hasattr(filename, 'writeline') and hasattr(filename, 'writelines') \ + and hasattr(filename, 'close'): + # already a stream + try: + mode = filename.mode + except AttributeError: + mode = "w" + if not ("w" in mode or "a" in mode or "+" in mode): + raise IOError("File/stream not open for writing") + return filename + try: - res = open(filename,'w') + f = open(filename,'w') except: raise Exception('Could not open %s'%filename) - return res + return f # # bookkeeping etc. @@ -193,10 +224,10 @@ def writeFile(filename, lines): """ Writes a new file """ - file = open(filename, 'w') + f = open_file_for_writing(filename) for line in lines: - file.write( "%s\n" % (line) ) - file.close() + f.write( "%s\n" % (line) ) + f.close() From ddaf27dea83985a6e52308ba13f456c653652069 Mon Sep 17 00:00:00 2001 From: Oliver Beckstein Date: Tue, 10 Jun 2014 14:12:24 -0700 Subject: [PATCH 2/2] run.single() to run a propka calculation without script - can pass a single pdffile (or stream(!)) - added options lib.loadOptions() to pass opt string --- propka/lib.py | 8 ++++++-- propka/run.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/propka/lib.py b/propka/lib.py index caa62ff..88f2ba9 100644 --- a/propka/lib.py +++ b/propka/lib.py @@ -107,7 +107,7 @@ def make_combination(combis, interaction): -def loadOptions(): +def loadOptions(*args): """ load the arguments parser with options """ @@ -166,7 +166,11 @@ def loadOptions(): # parsing and returning options and arguments - options, args = parser.parse_args() + if len(args) == 0: + # command line + options, args = parser.parse_args() + else: + options, args = parser.parse_args(list(args)) # adding specified filenames to arguments if options.filenames: diff --git a/propka/run.py b/propka/run.py index 867a000..7eb13a5 100644 --- a/propka/run.py +++ b/propka/run.py @@ -13,3 +13,21 @@ def main(): my_molecule = propka.molecular_container.Molecular_container(pdbfile, options) my_molecule.calculate_pka() my_molecule.write_pka() + +def single(pdbfile, optargs=None): + """Run a single PROPKA calculation using *pdbfile* as input. + + Commandline options can be passed as a **list** in *optargs*. + + .. rubric:: Example + + :: + single("protein.pdb", optargs=["--mutation=N25R/N181D", "-v", "--pH=7.2"]) + """ + optargs = optargs if optargs is not None else [] + options, ignored_pdbfiles = propka.lib.loadOptions(*optargs) + + my_molecule = propka.molecular_container.Molecular_container(pdbfile, options) + my_molecule.calculate_pka() + my_molecule.write_pka() + return my_molecule