comparison rgToolFactory.py @ 9:e09c76551bed

Can run without input or output or either.. random heatmap (no inputs) example added to docs
author ross lazarus ross.lazarus@gmail.com
date Sat, 02 Jun 2012 21:08:57 +1000
parents 220885b2d7ee
children 71f2ac0eee95
comparison
equal deleted inserted replaced
8:220885b2d7ee 9:e09c76551bed
41 def timenow(): 41 def timenow():
42 """return current time as a string 42 """return current time as a string
43 """ 43 """
44 return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time())) 44 return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time()))
45 # characters that are allowed but need to be escaped 45 # characters that are allowed but need to be escaped
46 mapped_chars = { '>' :'__gt__', 46
47 '<' :'__lt__',
48 "'" :'__sq__',
49 '"' :'__dq__',
50 '{' :'__oc__',
51 '}' :'__cc__',
52 '@' : '__at__',
53 '\n' : '__cn__',
54 '\r' : '__cr__',
55 '\t' : '__tc__',
56 '#' : '__pd__',
57 '[' :'__ob__',
58 ']' :'__cb__',
59 '\t' : 'Xt',
60 'systemCallsAreNotAllowed' : 'system'
61 }
62
63 def restore_text(text):
64 """Restores sanitized text"""
65 if not text:
66 return text
67 for key, value in mapped_chars.items():
68 text = text.replace(value, key)
69 return text
70
71 class ScriptRunner: 47 class ScriptRunner:
72 """class is a wrapper for an arbitrary script 48 """class is a wrapper for an arbitrary script
73 """ 49 """
74 50
75 def __init__(self,opts=None): 51 def __init__(self,opts=None):
76 """ 52 """
77 run the script 53 run the script
78 cheetah/galaxy will provide an escaped string so 54
79 __pd__ your script goes here
80 __cr____cn__ourargs __lt__- commandArgs(TRUE)
81 __cr____cn__inf = ourargs[1]
82 __cr____cn__outf = ourargs[2]
83 __cr____cn__inp = read.table(inf,head=T,rownames=F,sep=__sq__Xt__sq__)
84 __cr____cn__ write.table(inp,outf, quote=FALSE, sep=__dq__Xt__dq__,row.names=F)
85 __cr____cn__sessionInfo()
86 __cr____cn__
87 """ 55 """
88 if opts.output_dir: # simplify for the tool tarball 56 if opts.output_dir: # simplify for the tool tarball
89 os.chdir(opts.output_dir) 57 os.chdir(opts.output_dir)
90 self.thumbformat = 'jpg' 58 self.thumbformat = 'jpg'
91 self.opts = opts 59 self.opts = opts
92 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) 60 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name)
93 self.toolid = self.toolname 61 self.toolid = self.toolname
94 s = open(self.opts.script_path,'r').read() 62 s = open(self.opts.script_path,'r').read()
95 self.script = restore_text(s) 63 self.script = s
96 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later 64 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later
97 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much 65 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much
98 self.xmlfile = '%s.xml' % self.toolname 66 self.xmlfile = '%s.xml' % self.toolname
99 self.sfile = '%s.%s' % (self.toolname,opts.interpreter) 67 self.sfile = '%s.%s' % (self.toolname,opts.interpreter)
100 localscript = open(self.sfile,'w') 68 if opts.output_dir or self.opts.make_Tool: # may not want these complexities
101 localscript.write(self.script)
102 localscript.close()
103 if opts.output_dir or self.opts.make_Tool: # may not want these complexities if a simple script
104 self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname) 69 self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname)
105 artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname) 70 artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname)
106 artifact = open(artifactpath,'w') 71 artifact = open(artifactpath,'w')
107 artifact.write(self.script) 72 artifact.write(self.script)
108 artifact.write('\n') 73 artifact.write('\n')
109 artifact.close() 74 artifact.close()
75 localscript = open(self.sfile,'w')
76 localscript.write(self.script)
77 localscript.close()
78 shutil.copyfile(self.myname,'%s.py' % self.toolname) # for tool and for user
79 localpy = open('%s.py' % self.toolname,'w')
80 localpy.write(open(self.myname,'r').read())
110 self.cl = [] 81 self.cl = []
111 self.html = [] 82 self.html = []
112 a = self.cl.append 83 a = self.cl.append
113 a(opts.interpreter) 84 a(opts.interpreter)
114 a('-') # use stdin 85 a('-') # use stdin
115 a(opts.input_tab) 86 if opts.input_tab:
116 a(opts.output_tab) 87 a(opts.input_tab)
88 if opts.output_tab:
89 a(opts.output_tab)
117 self.outFormats = 'tabular' # TODO make this an option at tool generation time 90 self.outFormats = 'tabular' # TODO make this an option at tool generation time
118 self.inputFormats = 'tabular' # TODO make this an option at tool generation time 91 self.inputFormats = 'tabular' # TODO make this an option at tool generation time
119 92
120 93
121 def makeXML(self): 94 def makeXML(self):
122 """ 95 """
123 Create a Galaxy xml tool wrapper for the new script as a string to write out 96 Create a Galaxy xml tool wrapper for the new script as a string to write out
97 fixme - use templating or something less fugly than this
124 """ 98 """
125 newXML="""<tool id="%(toolid)s" name="%(toolname)s" version="0.01"> 99 newXML="""<tool id="%(toolid)s" name="%(toolname)s" version="0.01">
126 %(tooldesc)s 100 %(tooldesc)s
127 %(command)s 101 %(command)s
128 <inputs> 102 <inputs>
145 %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s" 119 %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s"
146 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s 120 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s
147 </command>""" # may NOT be an input or htmlout 121 </command>""" # may NOT be an input or htmlout
148 122
149 xdict = {} 123 xdict = {}
150 xdict['script'] = self.script # we pass this as a configfile because it's less painful that galaxy_tool_data_dir 124 xdict['script'] = self.script # configfile is least painful way to embed script to avoid external dependencies
151 # embed script in tool - remove dependence on something else outside in the wilds
152 if self.opts.help_text: 125 if self.opts.help_text:
153 h = open(self.opts.help_text,'r').read() 126 xdict['help'] = open(self.opts.help_text,'r').read()
154 xdict['help'] = restore_text(h)
155 else: 127 else:
156 xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation' 128 xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation'
157 if self.opts.tool_desc: 129 if self.opts.tool_desc:
158 xdict['tooldesc'] = '<description>%s</description>' % self.opts.tool_desc 130 xdict['tooldesc'] = '<description>%s</description>' % self.opts.tool_desc
159 else: 131 else:
160 xdict['tooldesc'] = '' 132 xdict['tooldesc'] = ''
161 xdict['command_outputs'] = '' # will probably be some! 133 xdict['command_outputs'] = ''
162 xdict['outputs'] = '' # will probably be some! 134 xdict['outputs'] = ''
163 if self.opts.input_tab: 135 if self.opts.input_tab:
164 xdict['command_inputs'] = '--input_tab "$input1"' 136 xdict['command_inputs'] = '--input_tab "$input1"'
165 xdict['inputs'] = '<param name="input1" type="data" format="%s" label="Select a suitable input file from your history"/>' % self.inputFormats 137 xdict['inputs'] = '<param name="input1" type="data" format="%s" label="Select a suitable input file from your history"/>' % self.inputFormats
166 else: 138 else:
167 xdict['command_inputs'] = '' # assume no input - eg a random data generator 139 xdict['command_inputs'] = '' # assume no input - eg a random data generator
170 xdict['toolname'] = self.toolname 142 xdict['toolname'] = self.toolname
171 xdict['toolid'] = self.toolid 143 xdict['toolid'] = self.toolid
172 xdict['interpreter'] = self.opts.interpreter 144 xdict['interpreter'] = self.opts.interpreter
173 xdict['scriptname'] = self.sfile 145 xdict['scriptname'] = self.sfile
174 if self.opts.make_HTML: 146 if self.opts.make_HTML:
175 xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file"' 147 xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file" --make_HTML "yes"'
176 xdict['outputs'] += '<data format="html" name="html_file" label="${job_name}.html"/>\n' 148 xdict['outputs'] += '<data format="html" name="html_file" label="${job_name}.html"/>\n'
177 if self.opts.output_tab: 149 if self.opts.output_tab:
178 xdict['command_outputs'] += '--output_tab "$tab_file"' 150 xdict['command_outputs'] += '--output_tab "$tab_file"'
179 xdict['outputs'] += '<data format="%s" name="tab_file" label="${job_name}"/>\n' % self.outFormats 151 xdict['outputs'] += '<data format="%s" name="tab_file" label="${job_name}"/>\n' % self.outFormats
180 xdict['command'] = newCommand % xdict 152 xdict['command'] = newCommand % xdict
288 else: 260 else:
289 fhtml.append('<li><a href="%s">%s %s</a></li>' % (fname,fname,sfsize)) 261 fhtml.append('<li><a href="%s">%s %s</a></li>' % (fname,fname,sfsize))
290 html.append('</table>\n') 262 html.append('</table>\n')
291 if len(fhtml) > 0: 263 if len(fhtml) > 0:
292 fhtml.insert(0,'<ul>') 264 fhtml.insert(0,'<ul>')
293 fhtml.append('</ul>') 265 fhtml.append('</ul><br/>')
294 html += fhtml # add all non-pdf files to the end of the display 266 html += fhtml # add all non-pdf files to the end of the display
295 else: 267 else:
296 html.append('<h2>### Error - %s returned no files - please confirm that parameters are sane</h1>' % self.opts.interpreter) 268 html.append('<h2>### Error - %s returned no files - please confirm that parameters are sane</h1>' % self.opts.interpreter)
297 html.append('<h3>%s log follows below</h3><hr/><pre>\n' % self.opts.interpreter) 269 html.append('<h3>%s log follows below</h3><hr/><pre><br/>\n' % self.opts.interpreter)
298 rlog = open(self.tlog,'r').readlines() 270 rlog = open(self.tlog,'r').readlines()
299 html += rlog 271 html += rlog
300 html.append('%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv))) 272 html.append('<br/>%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv)))
301 html.append('</pre>\n') 273 html.append('</pre>\n')
302 html.append(galhtmlattr % (progname,timenow())) 274 html.append(galhtmlattr % (progname,timenow()))
303 html.append(galhtmlpostfix) 275 html.append(galhtmlpostfix)
304 htmlf = file(self.opts.output_html,'w') 276 htmlf = file(self.opts.output_html,'w')
305 htmlf.write('\n'.join(html)) 277 htmlf.write('\n'.join(html))