1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 import sys
40 import cgi as cgilib
41 import cgitb; cgitb.enable()
42
43 from StringIO import StringIO
44 from color import *
45 from colorscheme import ColorScheme, ColorGroup
46
47 import weblogolib
48 from corebio.utils import *
49 from string import Template
50
51
52
53
54
55
56
57
58
59
61 import os
62 fn = os.path.join(os.path.dirname(basefilename), resource)
63 return open( fn ).read()
64
65 mime_type = {
66 'eps': 'application/postscript',
67 'pdf': 'application/pdf',
68 'svg': 'image/svg+xml',
69 'png': 'image/png',
70 'png_print': 'image/png',
71 'logodata' : 'text/plain',
72 'jpeg' : 'image/jpeg',
73 }
74
75 extension = {
76 'eps': 'eps',
77 'pdf': 'pdf',
78 'png': 'png',
79 'svg': 'svg',
80 'png_print': 'png',
81 'logodata' : 'txt',
82 'jpeg' : 'jpeg'
83 }
84
85
86 alphabets = {
87 'alphabet_auto': None,
88 'alphabet_protein': weblogolib.unambiguous_protein_alphabet,
89 'alphabet_rna': weblogolib.unambiguous_rna_alphabet,
90 'alphabet_dna': weblogolib.unambiguous_dna_alphabet}
91
92 color_schemes = {}
93 for k in weblogolib.std_color_schemes.keys():
94 color_schemes[ 'color_'+k.replace(' ', '_')] = weblogolib.std_color_schemes[k]
95
96
97 composition = {'comp_none' : 'none',
98 'comp_auto' : 'auto',
99 'comp_equiprobable':'equiprobable',
100 'comp_CG': 'percentCG',
101 'comp_Celegans' : 'C. elegans',
102 'comp_Dmelanogaster' : 'D. melanogaster',
103 'comp_Ecoli' : 'E. coli',
104 'comp_Hsapiens': 'H. sapiens',
105 'comp_Mmusculus' : 'M. musculus',
106 'comp_Scerevisiae': 'S. cerevisiae'
107 }
108
110 """ A representation of an HTML form field."""
111 - def __init__(self, name, default=None, conversion= None, options=None, errmsg="Illegal value.") :
112 self.name = name
113 self.default = default
114 self.value = default
115 self.conversion = conversion
116 self.options = options
117 self.errmsg = errmsg
118
120 if self.options :
121 if not self.value in self.options :
122 raise ValueError, (self.name, self.errmsg)
123
124 if self.conversion :
125 try :
126 return self.conversion(self.value)
127 except ValueError, e :
128 raise ValueError, (self.name, self.errmsg)
129 else:
130 return self.value
131
132
134 if value is None or value == 'auto':
135 return None
136 return str(value)
137
139 if value== "true" : return True
140 return bool(value)
141
143 if value =='' or value is None or value == 'auto':
144 return None
145 return int(value)
146
148 if value =='' or value is None or value == 'auto':
149 return None
150 return float(value)
151
152
153 -def main(htdocs_directory = None) :
154
155 logooptions = weblogolib.LogoOptions()
156
157
158
159
160
161 controls = [
162 Field( 'sequences', ''),
163 Field( 'format', 'png', weblogolib.formatters.get ,
164 options=['png_print', 'png', 'jpeg', 'eps', 'pdf', 'svg', 'logodata'] ,
165 errmsg="Unknown format option."),
166 Field( 'stacks_per_line', logooptions.stacks_per_line , int,
167 errmsg='Invalid number of stacks per line.'),
168 Field( 'stack_width','medium', weblogolib.std_sizes.get,
169 options=['small', 'medium', 'large'], errmsg='Invalid logo size.'),
170 Field( 'alphabet','alphabet_auto', alphabets.get,
171 options=['alphabet_auto', 'alphabet_protein', 'alphabet_dna',
172 'alphabet_rna'],
173 errmsg="Unknown sequence type."),
174 Field( 'unit_name', 'bits',
175 options=[ 'probability', 'bits', 'nats', 'kT', 'kJ/mol',
176 'kcal/mol']),
177 Field( 'first_index', 1, int_or_none),
178 Field( 'logo_start', '', int_or_none),
179 Field( 'logo_end', '', int_or_none),
180 Field( 'composition', 'comp_auto', composition.get,
181 options=['comp_none','comp_auto','comp_equiprobable','comp_CG',
182 'comp_Celegans','comp_Dmelanogaster','comp_Ecoli',
183 'comp_Hsapiens','comp_Mmusculus','comp_Scerevisiae'],
184 errmsg= "Illegal sequence composition."),
185 Field( 'percentCG', '', float_or_none, errmsg="Invalid CG percentage."),
186 Field( 'show_errorbars', False , truth),
187 Field( 'logo_title', logooptions.logo_title ),
188 Field( 'logo_label', logooptions.logo_label ),
189 Field( 'show_xaxis', False, truth),
190 Field( 'xaxis_label', logooptions.xaxis_label ),
191 Field( 'show_yaxis', False, truth),
192 Field( 'yaxis_label', logooptions.yaxis_label, string_or_none ),
193 Field( 'yaxis_scale', logooptions.yaxis_scale , float_or_none,
194 errmsg="The yaxis scale must be a positive number." ),
195 Field( 'yaxis_tic_interval', logooptions.yaxis_tic_interval ,
196 float_or_none),
197 Field( 'show_ends', False, truth),
198 Field( 'show_fineprint', False , truth),
199 Field( 'color_scheme', 'color_auto', color_schemes.get,
200 options=color_schemes.keys() ,
201 errmsg = 'Unknown color scheme'),
202 Field( 'color0', ''),
203 Field( 'symbols0', ''),
204 Field( 'desc0', ''),
205 Field( 'color1', ''),
206 Field( 'symbols1', ''),
207 Field( 'desc1', ''),
208 Field( 'color2', ''),
209 Field( 'symbols2', ''),
210 Field( 'desc2', ''),
211 Field( 'color3', ''),
212 Field( 'symbols3', ''),
213 Field( 'desc3', ''),
214 Field( 'color4', ''),
215 Field( 'symbols4', ''),
216 Field( 'desc4', ''),
217 Field( 'ignore_lower_case', False, truth),
218 Field( 'scale_width', False, truth),
219 ]
220
221 form = {}
222 for c in controls :
223 form[c.name] = c
224
225
226 form_values = cgilib.FieldStorage()
227
228
229 if len(form_values) ==0 or form_values.has_key("cmd_reset"):
230
231 form['show_errorbars'].value = logooptions.show_errorbars
232 form['show_xaxis'].value = logooptions.show_xaxis
233 form['show_yaxis'].value = logooptions.show_yaxis
234 form['show_ends'].value = logooptions.show_ends
235 form['show_fineprint'].value = logooptions.show_fineprint
236 form['scale_width'].value = logooptions.scale_width
237
238 send_form(controls, htdocs_directory = htdocs_directory)
239 return
240
241
242 for c in controls :
243 c.value = form_values.getfirst( c.name, c.default)
244
245
246 options_from_form = ['format', 'stacks_per_line', 'stack_width',
247 'alphabet', 'unit_name', 'first_index', 'logo_start','logo_end',
248 'composition',
249 'show_errorbars', 'logo_title', 'logo_label', 'show_xaxis',
250 'xaxis_label',
251 'show_yaxis', 'yaxis_label', 'yaxis_scale', 'yaxis_tic_interval',
252 'show_ends', 'show_fineprint', 'scale_width']
253
254
255 errors = []
256 for optname in options_from_form :
257 try :
258 value = form[optname].get_value()
259 if value!=None : setattr(logooptions, optname, value)
260 except ValueError, err :
261 errors.append(err.args)
262
263
264
265 custom = ColorScheme()
266 for i in range(0,5) :
267 color = form["color%d"%i].get_value()
268 symbols = form["symbols%d"%i].get_value()
269 desc = form["desc%d"%i].get_value()
270
271 if color :
272 try :
273 custom.groups.append(weblogolib.ColorGroup(symbols, color, desc))
274 except ValueError, e :
275 errors.append( ('color%d'%i, "Invalid color: %s" % color) )
276
277 if form["color_scheme"].value == 'color_custom' :
278 logooptions.color_scheme = custom
279 else :
280 try :
281 logooptions.color_scheme = form["color_scheme"].get_value()
282 except ValueError, err :
283 errors.append(err.args)
284
285 sequences = None
286
287
288
289
290 if form_values.has_key("sequences_file") :
291 sequences = form_values.getvalue("sequences_file")
292 assert type(sequences) == str
293
294 if not sequences or len(sequences) ==0:
295 sequences = form["sequences"].get_value()
296
297 if not sequences or len(sequences) ==0:
298 errors.append( ("sequences", "Please enter a multiple-sequence alignment in the box above, or select a file to upload."))
299
300
301
302
303
304
305
306
307 if form_values.has_key("cmd_edit") or errors :
308 send_form(controls, errors, htdocs_directory)
309 return
310
311
312
313
314 logo = StringIO()
315 try :
316 comp = form["composition"].get_value()
317 percentCG = form["percentCG"].get_value()
318 ignore_lower_case = form_values.has_key("ignore_lower_case")
319 if comp=='percentCG': comp = str(percentCG/100)
320
321 from corebio.matrix import Motif
322
323 try:
324
325
326 motif = Motif.read_transfac(StringIO( sequences), alphabet=logooptions.alphabet)
327 prior = weblogolib.parse_prior( comp,motif.alphabet)
328 data = weblogolib.LogoData.from_counts(motif.alphabet, motif, prior)
329 except ValueError, motif_err :
330 seqs = weblogolib.read_seq_data(StringIO( sequences),
331 alphabet=logooptions.alphabet,
332 ignore_lower_case=ignore_lower_case
333 )
334 prior = weblogolib.parse_prior(comp, seqs.alphabet)
335 data = weblogolib.LogoData.from_seqs(seqs, prior)
336
337 logoformat = weblogolib.LogoFormat(data, logooptions)
338 format = form["format"].value
339 weblogolib.formatters[format](data, logoformat, logo)
340 except ValueError, err :
341 errors.append( err.args )
342 except IOError, err :
343 errors.append( err.args)
344 except RuntimeError, err :
345 errors.append( err.args )
346
347 if form_values.has_key("cmd_validate") or errors :
348 send_form(controls, errors, htdocs_directory)
349 return
350
351
352
353
354
355
356 print "Content-Type:", mime_type[format]
357
358
359 if form_values.has_key("download") :
360 print 'Content-Disposition: attachment; ' \
361 'filename="logo.%s"' % extension[format]
362 else :
363 print 'Content-Disposition: inline; ' \
364 'filename="logo.%s"' % extension[format]
365
366
367
368 print
369
370
371 print logo.getvalue()
372
373
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 if __name__=="__main__" :
466 import _cli
467 _cli.main()
468