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