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