Changeset 269
- Timestamp:
- 01/19/08 02:51:20 (10 months ago)
- Files:
-
- trunk/cartwheel-server/lib/cartwheel/website/IUPACMotif.py (modified) (1 diff)
- trunk/cartwheel-server/lib/cartwheel/website/NamedMotif.py (modified) (1 diff)
- trunk/cartwheel-server/lib/cartwheel/website/PWMMotif.py (modified) (2 diffs)
- trunk/cartwheel-server/tests/functional-tests/test-with-user/test-web/test-folder-motifs.py (modified) (1 diff)
- trunk/cartwheel-server/website/canal/motif/__init__.py (modified) (1 diff)
- trunk/cartwheel-server/website/canal/motif/analyze.ptl (modified) (1 diff)
- trunk/cartwheel-server/website/canal/motif/pages.ptl (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cartwheel-server/lib/cartwheel/website/IUPACMotif.py
r266 r269 16 16 return "motif: %s; match %d/%d by default" % \ 17 17 (self.motif, len(self.motif) - self.mismatches, len(self.motif)) 18 19 def simple_key(self): 20 return self.motif trunk/cartwheel-server/lib/cartwheel/website/NamedMotif.py
r266 r269 5 5 mymembers = ('name', 'motif_type', 'folder_id', 'visible') 6 6 7 def search(self, sequence): 7 def search(self, sequence): # actually runs the search 8 8 raise NotImplementedError 9 9 10 def extra_information(self): 10 def extra_information(self): # info box output 11 11 raise NotImplementedError 12 13 def simple_key(self): # key for display tagging 14 raise NotImplementedError trunk/cartwheel-server/lib/cartwheel/website/PWMMotif.py
r261 r269 1 """ 2 A PWM motif created from a list of sites. 3 """ 1 4 from cartwheel.website.NamedMotif import NamedMotif 2 5 … … 4 7 table = 'pwm_motifs' 5 8 mymembers = ('source_motifs', 'default_threshold') 9 10 def search(self, sequence): 11 """ 12 sequence is FolderSequence. 13 """ 14 import motility 15 16 sites = self.source_motifs.split("\n") 17 pwm = motility.make_pwm(sites) 18 19 return pwm.find(sequence.seq, self.default_threshold) 20 21 def extra_information(self): 22 import motility 23 24 sites = self.source_motifs.split("\n") 25 consensus = motility.make_iupac_motif(sites) 26 27 return "PWM consensus: %s; default threshold %f" % (consensus, 28 self.default_threshold) 29 def simple_key(self): 30 import motility 31 32 sites = self.source_motifs.split("\n") 33 consensus = motility.make_iupac_motif(sites) 34 return consensus trunk/cartwheel-server/tests/functional-tests/test-with-user/test-web/test-folder-motifs.py
r268 r269 167 167 find('18 matches, sorted by position.') 168 168 back() 169 170 ## end 171 back() 172 follow('Return to folder menu') 173 174 def test_add_pwm_motif(): 175 show() 176 follow("manage motifs") 177 follow("build_pwm_from_list") 178 179 fv('1', 'name', 'test_pwm_gata') 180 fv('1', 'aligned', 'AGATAG\nTGATAG\nTGATAA') 181 182 submit() 183 184 show() 185 186 find("Matrix motif 'test_pwm_gata' created.") 187 find("lowest recommended threshold: 10.58") 188 find("prob/base with this score: 7.324219e-04") 189 190 follow("Return to motif list") 191 192 ## end 193 follow('Return to folder menu') trunk/cartwheel-server/website/canal/motif/__init__.py
r266 r269 5 5 import cartwheel.website 6 6 from canal.motif.analyze import AnalyzeSequenceHandler 7 from pages import add_iupac, _q_index 7 from pages import add_iupac, _q_index, build_pwm_from_list 8 8 9 _q_exports = ['add_iupac', 'delete', 'edit', 'go_analyze' ] 9 _q_exports = ['add_iupac', 'delete', 'edit', 'go_analyze', 10 'build_pwm_from_list'] 10 11 11 12 def edit(request): trunk/cartwheel-server/website/canal/motif/analyze.ptl
r268 r269 26 26 for motif in motifs: 27 27 motif = self.manager.load(motif.id) 28 key = motif.simple_key() 29 28 30 """ 29 31 %s: %d matches <a href='matches_detail?motif_id=%d' 30 32 id='detail-%s'>detail</a><br> 31 33 """ % (motif.name, len(motif.search(self.seq)), motif.id, 32 motif.motif)34 key) 33 35 34 36 template matches_detail(self, request): trunk/cartwheel-server/website/canal/motif/pages.ptl
r266 r269 2 2 from canal.templates import header, footer 3 3 from cartwheel.website.IUPACMotif import IUPACMotif 4 from cartwheel.website.PWMMotif import PWMMotif 4 5 from canal.group.utils import make_sequence_list_widget 5 6 … … 7 8 import motility 8 9 9 nice_motif_types = dict(IUPAC='simple motif (IUPAC notation)') 10 nice_motif_types = dict(IUPAC='simple motif (IUPAC notation)', 11 PWM='matrix motif (PWM)') 10 12 11 13 template _q_index(request): … … 38 40 <td align='right'> 39 41 <font size='-1'> 40 <a href='delete?motif_id=%d' >delete</a> |41 <a href='edit?motif_id=%d' >edit</a>42 <a href='delete?motif_id=%d' id='delete-%s'>delete</a> | 43 <a href='edit?motif_id=%d' id='edit-%s'>edit</a> 42 44 </font> 43 45 </td> … … 46 48 nice_motif_types[motif.motif_type], 47 49 motif.extra_information(), 48 motif.id, motif.id) 50 motif.id, motif.simple_key(), 51 motif.id, motif.simple_key()) 49 52 50 53 """ … … 58 61 """ 59 62 <hr> 60 61 <A href="add_iupac">Add a simple motif</a> 63 <A href="add_iupac">Add a simple motif</a> | 64 <a href="build_pwm_from_list">build a matrix (PWM) 65 from a list of known sites</a> | 66 <font color='red'>import a matrix from JASPAR (not yet!)</font> 62 67 <p> 63 68 """ … … 155 160 156 161 return d 162 163 def build_pwm_from_list(request): 164 if not request.form: 165 return """\ 166 <form method="POST"> 167 <h3>Build a matrix motif (PWM) from a list of known sites</h3> 168 Name: <input type='text' name='name'> 169 <p> 170 Aligned sequences:<br> 171 <textarea name='aligned' rows='5' cols='30'></textarea> 172 <p> 173 <input type='submit' value='build PWM'> 174 </form> 175 <hr> 176 <b>Instructions:</b> 177 <p> 178 To build a matrix motif (a.k.a. Position-Weight Matrix, or PWM), 179 enter a list of ungapped, aligned sequences. For example, here is a list 180 of GATA-type motifs: 181 <pre> 182 AGATAG 183 TGATAG 184 TGATAA 185 </pre> 186 187 After submitting this list, a matrix motif will be built and you can 188 then define a threshold for searches. 189 """ 190 191 errors = [] 192 193 name = request.form['name'].strip() 194 195 if not name: 196 errors.append("you must enter a name!") 197 198 sequences = request.form['aligned'].split('\n') 199 sequences = [ s.strip().upper() for s in sequences ] 200 sequences = [ s for s in sequences if len(s) ] 201 202 if len(sequences) <= 1: 203 errors.append('you must enter at least two sequences') 204 205 lens = [ len(s) for s in sequences ] 206 if max(lens) != min(lens): 207 errors.append('all sequences must be the same length') 208 209 for s in sequences: 210 if '-' in s: 211 errors.append('one or more of your sequences contains a gap!') 212 break 213 214 # check for only ATCG 215 d = {} 216 for s in sequences: 217 for ch in s: 218 d[ch] = 1 219 220 for ch in 'A', 'T', 'C', 'G', '-': # already covered gap error, above 221 if ch in d: 222 del d[ch] 223 224 if len(d): 225 errors.append("there is at least one non-DNA character in your sequences; here's a list: %s" % (", ".join(d.keys()))) 226 227 if errors: 228 return "ERROR:<p><ul><li> %s</ul>" % ("<li>".join(errors,)) 229 230 ### ok, validation good so far. build the PWM & display... 231 232 return display_pwm_from_sites(request, name, sequences) 233 234 template display_pwm_from_sites(request, name, sequences): 235 header("Motif '%s' created" % (name,)) 236 237 "<h2>Matrix motif '%s' created.</h2>" % (name,) 238 239 pwm = motility.make_pwm(sequences) 240 241 x = [] 242 243 # build index header 244 xx = [] 245 for i in range(len(pwm)): 246 xx.append("<td align='center'><i><font size='-1'>%d</font></i></td>" % (i + 1,)) 247 x.append("<tr><td></td>" + "".join(xx) + "</tr>") 248 249 dna = 'A', 'C', 'G', 'T' 250 maxes = [ max(pwm.matrix[j]) for j in range(len(pwm)) ] 251 252 for i in range(4): 253 xx = ["<td><font size='-1'><i>%s</i></font></td>" % (dna[i],)] 254 255 for j in range(len(pwm)): 256 val = pwm.matrix[j][i] 257 if val == maxes[j]: 258 xx.append("<td align='center'><b>%.2f</b></td>" % (val,)) 259 elif val == 0: 260 xx.append("<td align='center'>-</td>") 261 else: 262 xx.append("<td align='center'>%.2f</td>" % (val,)) 263 264 x.append("<tr>" + "".join(xx) + "</tr>") 265 266 # display table 267 "<h3>Matrix:</h3>" 268 "<table border='1'>" + "\n".join(x) + "</table>" 269 270 ### 271 272 min_score = pwm.min_score() 273 max_score = pwm.max_score() 274 275 site_scores = [ (pwm.calc_score(s),s) for s in sequences ] 276 site_scores.sort() 277 site_scores.reverse() 278 279 x = [] 280 for score, site in site_scores: 281 x.append('<tr><td>%s:</td><td>%.2f</td>' % (site, score,)) 282 283 284 ### 285 286 "<p>" 287 """ 288 <table border='1'> 289 <tr><th>Input site</th><th>PWM score</th></tr> 290 """ 291 292 "".join(x) 293 294 "</table>" 295 296 ### 297 298 lowest_score = site_scores[-1][0] 299 300 """ 301 <p> 302 lowest recommended threshold: %.2f; 303 prob/base with this score: %e 304 """ % (lowest_score, pwm.weight_sites_over(lowest_score)) 305 306 ### 307 308 manager = cartwheel.website.get_object_manager() 309 310 folder_id = request.session.get_current_folder().id 311 312 manager.create(PWMMotif, name=name, source_motifs="\n".join(sequences), 313 motif_type='PWM', 314 default_threshold=lowest_score, 315 folder_id=folder_id) 316 317 manager.commit() 318 319 """ 320 <p> 321 <a href='./'>Return to motif list</a> 322 """ 323 324 footer()
