annotate openms_wrapper.py @ 4:1183846e70a1 draft

Uploaded
author galaxyp
date Wed, 19 Jun 2013 13:15:44 -0400
parents cf0d72c7b482
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
1 import os
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
2 import sys
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
3 from optparse import OptionParser
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
4 from ConfigParser import SafeConfigParser
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
5 from xml.etree import ElementTree
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
6 import subprocess
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
7 from re import compile
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
8
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
9 DEBUG = False
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
10
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
11
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
12 def main():
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
13 (options, args) = _parse_args()
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
14 for executable, config_path in zip(options.executables, options.configs):
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
15 command_handler = COMMAND_HANDLERS.get(executable, _run_openms)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
16 command_handler(executable, config_path)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
17
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
18
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
19 def _run_shell(executable, config_path):
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
20 command = open(config_path, "r").read().strip()
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
21 if DEBUG:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
22 print "Running shell command %s" % command
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
23 _exec(command)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
24
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
25
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
26 def _run_openms(executable, config_path):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
27 _exec("%s -write_ini openms.ini" % executable)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
28 tree = ElementTree.parse("openms.ini")
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
29 options = _load_options(config_path)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
30 _set_options(tree, executable, options)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
31 tree.write("openms.ini")
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
32 if DEBUG:
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
33 print 'With openms.ini as:\n%s\n, calling: %s -ini openms.ini' % (open("openms.ini", "r").read(), executable)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
34 _exec("%s -ini openms.ini" % executable)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
35
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
36 COMMAND_HANDLERS = {
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
37 "__SHELL__": _run_shell,
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
38 }
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
39
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
40
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
41 def _fail(message, return_code=1):
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
42 print message
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
43 sys.exit(return_code)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
44
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
45
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
46 def _exec(command):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
47 proc = subprocess.Popen(args=command, shell=True)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
48 return_code = proc.wait()
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
49 if return_code != 0:
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
50 _fail("Error executing command [%s], return code is %d" % (command, return_code), return_code)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
51
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
52
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
53 def _set_options(tree, executable, options):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
54 executable_node = tree.find("./NODE[@name='%s']" % executable)
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
55 if executable_node is None:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
56 _fail("Could not find options for executable %s" % executable)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
57 options_node = executable_node.find("./NODE[@name='1']")
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
58 for key, raw_value in options.items("simple_options"):
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
59 if raw_value is None:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
60 _fail("No value found key %s" % key)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
61 value = _parse_value(raw_value)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
62 _set_option(options_node, key.split("!"), value)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
63 _set_option(options_node, ["no_progress"], "true", required=False)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
64
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
65
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
66 def _set_option(node, key_parts, value, required=True):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
67 key = key_parts[0]
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
68 if len(key_parts) == 1:
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
69 if not _set_item_value(node, key, value) and \
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
70 not _set_list_item_value(node, key, value) and \
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
71 required:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
72 _fail("Failed to find specific OpenMS option [%s] in node [%s]" % (key, node))
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
73 else:
4
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
74 if node is None:
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
75 _fail("Failed to find specific OpenMS option [%s] in node [%s]" % (key, node))
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
76 sub_node = node.find("./NODE[@name='%s']" % key)
4
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
77 if sub_node is None:
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
78 _fail("Failed to find node for key %s" % key)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
79 _set_option(sub_node, key_parts[1:], value, required)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
80
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
81
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
82 def _set_item_value(node, key, value):
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
83 item = node.find("./ITEM[@name='%s']" % key)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
84 if item is not None:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
85 item.set("value", value)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
86 return item is not None
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
87
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
88
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
89 def _set_list_item_value(node, key, values):
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
90 item = node.find("./ITEMLIST[@name='%s']" % key)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
91 if item is not None:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
92 for value in values.split(","):
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
93 ElementTree.SubElement(item, "LISTITEM", {"value": value})
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
94 return item is not None
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
95
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
96
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
97 def _parse_value(raw_value):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
98 value = raw_value
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
99 for pattern, function in VALUE_FUNCTIONS.iteritems():
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
100 try:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
101 match = pattern.match(value)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
102 except TypeError:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
103 print "Invalid value found config file %s" % value
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
104 sys.exit(1)
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
105 if match:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
106 value = function(*match.groups())
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
107 if value is None:
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
108 print "Failed to properly parse raw value %s" % raw_value
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
109 sys.exit(1)
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
110 return value
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
111
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
112
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
113 ## Special value parser for various OpenMS components
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
114 def _get_pepnovo_models_path():
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
115 pepnovo_path = _which('PepNovo')
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
116 pepnovo_dir = os.path.split(pepnovo_path)[0]
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
117 guesses = [os.path.join(pepnovo_dir, 'Models'),
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
118 os.path.join(pepnovo_dir, '..', 'Models'),
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
119 os.path.join(pepnovo_dir, '..', 'share', 'pepnovo', 'Models')]
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
120 models_dir = None
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
121 for guess in guesses:
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
122 if os.path.isdir(guess):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
123 models_dir = guess
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
124 break
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
125 return models_dir
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
126
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
127
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
128 # http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
129 def _which(program):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
130
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
131 def is_exe(fpath):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
132 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
133
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
134 fpath, fname = os.path.split(program)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
135 if fpath:
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
136 if is_exe(program):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
137 return program
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
138 else:
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
139 for path in os.environ["PATH"].split(os.pathsep):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
140 exe_file = os.path.join(path, program)
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
141 print path
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
142 if is_exe(exe_file):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
143 return exe_file
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
144
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
145 return None
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
146
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
147
4
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
148 def _mapped_outputs(output_directory, inputs):
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
149 inputs = inputs.split(",")
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
150 os.makedirs(output_directory)
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
151 outputs = [os.path.join(output_directory, os.path.basename(input)) for input in inputs]
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
152 return ",".join(outputs)
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
153
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
154
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
155 VALUE_FUNCTIONS = {compile(r"\@WHICH\((.*)\)\@"): _which,
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
156 compile(r"\@PEPNOVO_MODELS_PATH\@"): _get_pepnovo_models_path,
4
1183846e70a1 Uploaded
galaxyp
parents: 2
diff changeset
157 compile(r"\@MULTI_OUTPUT\(([^,]*),(.*)\)\@"): _mapped_outputs,
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
158 }
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
159
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
160
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
161 def _parse_args():
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
162 parser = OptionParser()
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
163 parser.add_option("-e", "--executable", dest="executables", default=[], action="append")
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
164 parser.add_option("-c", "--config", dest="configs", default=[], action="append")
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
165 return parser.parse_args()
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
166
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
167
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
168 def _load_options(config_path):
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
169 config_parser = SafeConfigParser()
2
cf0d72c7b482 Update.
galaxyp
parents: 0
diff changeset
170 config_parser.optionxform = str
0
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
171 config_parser.read(config_path)
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
172 return config_parser
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
173
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
174 if __name__ == "__main__":
ba86fd127f5a Uploaded
galaxyp
parents:
diff changeset
175 main()