diff openms_wrapper.py @ 2:cf0d72c7b482 draft

Update.
author galaxyp
date Fri, 10 May 2013 17:31:05 -0400
parents ba86fd127f5a
children 1183846e70a1
line wrap: on
line diff
--- a/openms_wrapper.py	Wed Dec 19 00:33:53 2012 -0500
+++ b/openms_wrapper.py	Fri May 10 17:31:05 2013 -0400
@@ -4,6 +4,7 @@
 from ConfigParser import SafeConfigParser
 from xml.etree import ElementTree
 import subprocess
+from re import compile
 
 DEBUG = False
 
@@ -11,7 +12,15 @@
 def main():
     (options, args) = _parse_args()
     for executable, config_path in zip(options.executables, options.configs):
-        _run_openms(executable, config_path)
+        command_handler = COMMAND_HANDLERS.get(executable, _run_openms)
+        command_handler(executable, config_path)
+
+
+def _run_shell(executable, config_path):
+    command = open(config_path, "r").read().strip()
+    if DEBUG:
+        print "Running shell command %s" % command
+    _exec(command)
 
 
 def _run_openms(executable, config_path):
@@ -24,18 +33,31 @@
         print 'With openms.ini as:\n%s\n, calling: %s -ini openms.ini' % (open("openms.ini", "r").read(), executable)
     _exec("%s -ini openms.ini" % executable)
 
+COMMAND_HANDLERS = {
+    "__SHELL__": _run_shell,
+}
+
+
+def _fail(message, return_code=1):
+    print message
+    sys.exit(return_code)
+
 
 def _exec(command):
     proc = subprocess.Popen(args=command, shell=True)
     return_code = proc.wait()
     if return_code != 0:
-        sys.exit(return_code)
+        _fail("Error executing command [%s], return code is %d" % (command, return_code), return_code)
 
 
 def _set_options(tree, executable, options):
     executable_node = tree.find("./NODE[@name='%s']" % executable)
+    if executable_node is None:
+        _fail("Could not find options for executable %s" % executable)
     options_node = executable_node.find("./NODE[@name='1']")
     for key, raw_value in options.items("simple_options"):
+        if raw_value is None:
+            _fail("No value found key %s" % key)
         value = _parse_value(raw_value)
         _set_option(options_node, key.split("!"), value)
     _set_option(options_node, ["no_progress"], "true", required=False)
@@ -44,26 +66,53 @@
 def _set_option(node, key_parts, value, required=True):
     key = key_parts[0]
     if len(key_parts) == 1:
-        item = node.find("./ITEM[@name='%s']" % key)
-        if item is not None:
-            item.set("value", value)
-        elif required:
-            raise Exception("Failed to find specific OpenMS option [%s] in node [%s]" % (key, node))
+        if not _set_item_value(node, key, value) and \
+           not _set_list_item_value(node, key, value) and \
+           required:
+            _fail("Failed to find specific OpenMS option [%s] in node [%s]" % (key, node))
     else:
+        if not node:
+            _fail("Failed to find specific OpenMS option [%s] in node [%s]" % (key, node))
         sub_node = node.find("./NODE[@name='%s']" % key)
+        if not sub_node:
+            _fail("Failed to find node for key %s" % key)
         _set_option(sub_node, key_parts[1:], value, required)
 
 
+def _set_item_value(node, key, value):
+    item = node.find("./ITEM[@name='%s']" % key)
+    if item is not None:
+        item.set("value", value)
+    return item is not None
+
+
+def _set_list_item_value(node, key, values):
+    item = node.find("./ITEMLIST[@name='%s']" % key)
+    if item is not None:
+        for value in values.split(","):
+            ElementTree.SubElement(item, "LISTITEM", {"value": value})
+    return item is not None
+
+
 def _parse_value(raw_value):
     value = raw_value
-    if raw_value in VALUE_FUNCTIONS:
-        value = VALUE_FUNCTIONS[raw_value](raw_value)
+    for pattern, function in VALUE_FUNCTIONS.iteritems():
+        try:
+            match = pattern.match(value)
+        except TypeError:
+            print "Invalid value found config file %s" % value
+            sys.exit(1)
+        if match:
+            value = function(*match.groups())
+    if value is None:
+        print "Failed to properly parse raw value %s" % raw_value
+        sys.exit(1)
     return value
 
 
 ## Special value parser for various OpenMS components
-def _get_pepnovo_models_path(_):
-    pepnovo_path = _get_pepnovo_executable_path(None)
+def _get_pepnovo_models_path():
+    pepnovo_path = _which('PepNovo')
     pepnovo_dir = os.path.split(pepnovo_path)[0]
     guesses = [os.path.join(pepnovo_dir, 'Models'),
                os.path.join(pepnovo_dir, '..', 'Models'),
@@ -76,13 +125,6 @@
     return models_dir
 
 
-def _get_pepnovo_executable_path(_):
-    return _which("PepNovo")
-
-VALUE_FUNCTIONS = {"@PEPNOVO_MODELS_PATH@": _get_pepnovo_models_path,
-                   "@PEPNOVO_EXECUTABLE_PATH@": _get_pepnovo_executable_path}
-
-
 # http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
 def _which(program):
 
@@ -96,12 +138,18 @@
     else:
         for path in os.environ["PATH"].split(os.pathsep):
             exe_file = os.path.join(path, program)
+            print path
             if is_exe(exe_file):
                 return exe_file
 
     return None
 
 
+VALUE_FUNCTIONS = {compile(r"\@WHICH\((.*)\)\@"): _which,
+                   compile(r"\@PEPNOVO_MODELS_PATH\@"): _get_pepnovo_models_path,
+                  }
+
+
 def _parse_args():
     parser = OptionParser()
     parser.add_option("-e", "--executable", dest="executables", default=[], action="append")
@@ -111,6 +159,7 @@
 
 def _load_options(config_path):
     config_parser = SafeConfigParser()
+    config_parser.optionxform = str
     config_parser.read(config_path)
     return config_parser