Mercurial > repos > xuebing > sharplabtool
comparison tools/mytools/dreme_out/dreme.html @ 0:9071e359b9a3
Uploaded
| author | xuebing |
|---|---|
| date | Fri, 09 Mar 2012 19:37:19 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:9071e359b9a3 |
|---|---|
| 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |
| 2 <html> | |
| 3 <head> | |
| 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
| 5 <title>DREME</title> | |
| 6 <style type="text/css"> | |
| 7 | |
| 8 /* START INCLUDED FILE "meme.css" */ | |
| 9 /* The following is the content of meme.css */ | |
| 10 body { background-color:white; font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif;} | |
| 11 | |
| 12 div.help { | |
| 13 display: inline-block; | |
| 14 margin: 0px; | |
| 15 padding: 0px; | |
| 16 width: 12px; | |
| 17 height: 13px; | |
| 18 cursor: pointer; | |
| 19 background-image: url("help.gif"); | |
| 20 background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAANAQMAAACn5x0BAAAAAXNSR0IArs4c6QAAAAZQTFRFAAAAnp6eqp814gAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gMJBQgGYqhNZQAAACZJREFUCNdj+P+BoUGAoV+AYeYEEGoWYGgTYGgRAAm2gRGQ8f8DAOnhC2lYnqs6AAAAAElFTkSuQmCC"); | |
| 21 } | |
| 22 | |
| 23 div.help2 { | |
| 24 color: #999; | |
| 25 display: inline-block; | |
| 26 width: 12px; | |
| 27 height: 12px; | |
| 28 border: 1px solid #999; | |
| 29 font-size: 13px; | |
| 30 line-height:12px; | |
| 31 font-family: Helvetica, sans-serif; | |
| 32 font-weight: bold; | |
| 33 font-style: normal; | |
| 34 cursor: pointer; | |
| 35 } | |
| 36 div.help2:hover { | |
| 37 color: #000; | |
| 38 border-color: #000; | |
| 39 } | |
| 40 | |
| 41 p.spaced { line-height: 1.8em;} | |
| 42 | |
| 43 span.citation { font-family: "Book Antiqua", "Palatino Linotype", serif; color: #004a4d;} | |
| 44 | |
| 45 p.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;} | |
| 46 | |
| 47 td.jump { font-size: 13px; color: #ffffff; background-color: #00666a; | |
| 48 font-family: Georgia, "Times New Roman", Times, serif;} | |
| 49 | |
| 50 a.jump { margin: 15px 0 0; font-style: normal; font-variant: small-caps; | |
| 51 font-weight: bolder; font-family: Georgia, "Times New Roman", Times, serif;} | |
| 52 | |
| 53 h2.mainh {font-size: 1.5em; font-style: normal; margin: 15px 0 0; | |
| 54 font-variant: small-caps; font-family: Georgia, "Times New Roman", Times, serif;} | |
| 55 | |
| 56 h2.line {border-bottom: 1px solid #CCCCCC; font-size: 1.5em; font-style: normal; | |
| 57 margin: 15px 0 0; padding-bottom: 3px; font-variant: small-caps; | |
| 58 font-family: Georgia, "Times New Roman", Times, serif;} | |
| 59 | |
| 60 h4 {border-bottom: 1px solid #CCCCCC; font-size: 1.2em; font-style: normal; | |
| 61 margin: 10px 0 0; padding-bottom: 3px; font-family: Georgia, "Times New Roman", Times, serif;} | |
| 62 | |
| 63 h5 {margin: 0px} | |
| 64 | |
| 65 a.help { font-size: 9px; font-style: normal; text-transform: uppercase; | |
| 66 font-family: Georgia, "Times New Roman", Times, serif;} | |
| 67 | |
| 68 div.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;} | |
| 69 | |
| 70 div.pad1 { margin: 10px 5px;} | |
| 71 | |
| 72 div.pad2 { margin: 25px 5px 5px;} | |
| 73 h2.pad2 { padding: 25px 5px 5px;} | |
| 74 | |
| 75 div.pad3 { padding: 5px 0px 10px 30px;} | |
| 76 | |
| 77 div.box { border: 2px solid #CCCCCC; padding:10px;} | |
| 78 | |
| 79 div.bar { border-left: 7px solid #00666a; padding:5px; margin-top:25px; } | |
| 80 | |
| 81 div.subsection {margin:25px 0px;} | |
| 82 | |
| 83 img {border:0px none;} | |
| 84 | |
| 85 th.majorth {text-align:left;} | |
| 86 th.minorth {font-weight:normal; text-align:left; width:8em; padding: 3px 0px;} | |
| 87 th.actionth {font-weight:normal; text-align:left;} | |
| 88 | |
| 89 .strand_name {text-align:left;} | |
| 90 .strand_side {padding:0px 10px;} | |
| 91 .strand_start {padding:0px 10px;} | |
| 92 .strand_pvalue {text-align:center; padding:0px 10px;} | |
| 93 .strand_lflank {text-align:right; padding-right:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;} | |
| 94 .strand_seq {text-align:center; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace;} | |
| 95 .strand_rflank {text-align:left; padding-left:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;} | |
| 96 | |
| 97 .block_td {height:25px;} | |
| 98 .block_container {position:relative; width:99%; height:25px; padding:0px; margin:0px;} | |
| 99 .block_motif {position:absolute; z-index:3; height:12px; top:0px; text-align:center; vertical-align:middle; background-color:cyan;} | |
| 100 .block_rule {position:absolute; z-index:2; width:100%; height:1px; top:12px; left:0px; background-color:gray;} | |
| 101 .block_plus_sym {position:absolute; z-index:4; width:12px; height:12px; top:0px; left:0px; color:gray;} | |
| 102 .block_minus_sym {position:absolute; z-index:4; width:12px; height:12px; top:13px; left:0px; color:gray;} | |
| 103 | |
| 104 .tic_major {position:absolute; border-left:2px solid blue; height:0.5em; top:0em;} | |
| 105 .tic_minor {position:absolute; border-left:1px solid blue; height:0.2em; top:0em;} | |
| 106 .tic_label {position:absolute; top:0.5em; height: 1em; text-align:center; vertical-align:middle} | |
| 107 | |
| 108 .explain h5 {font-size:1em; margin-left: 1em;} | |
| 109 | |
| 110 div.doc {margin-left: 2em; margin-bottom: 3em;} | |
| 111 | |
| 112 div.tabArea { | |
| 113 font-size: 80%; | |
| 114 font-weight: bold; | |
| 115 } | |
| 116 | |
| 117 a.tab { | |
| 118 background-color: #ddddff; | |
| 119 border: 1px solid #000000; | |
| 120 padding: 2px 1em 2px 1em; | |
| 121 text-decoration: none; | |
| 122 } | |
| 123 div.tabArea.base a.tab { | |
| 124 border-top-width: 0px; | |
| 125 } | |
| 126 div.tabArea.top a.tab { | |
| 127 border-bottom-width: 0px; | |
| 128 } | |
| 129 | |
| 130 a.tab, a.tab:visited { | |
| 131 color: #808080; | |
| 132 } | |
| 133 | |
| 134 a.tab:hover { | |
| 135 background-color: #d0d0d0; | |
| 136 color: #606060; | |
| 137 } | |
| 138 a.tab.activeTab, a.tab.activeTab:hover, a.tab.activeTab:visited { | |
| 139 background-color: #f0f0f0; | |
| 140 color: #000000; | |
| 141 } | |
| 142 div.tabMain { | |
| 143 border: 1px solid #000000; | |
| 144 background-color: #ffffff; | |
| 145 padding: 5px; | |
| 146 margin-right: 5px; | |
| 147 } | |
| 148 th.trainingset { | |
| 149 border-bottom: thin dashed black; | |
| 150 font-weight:normal; | |
| 151 padding:0px 10px; | |
| 152 } | |
| 153 .dnaseq { | |
| 154 font-weight: bold; | |
| 155 font-size: large; | |
| 156 font-family: 'Courier New', Courier, monospace; | |
| 157 } | |
| 158 .dna_A { | |
| 159 color: rgb(204,0,0); | |
| 160 } | |
| 161 .dna_C { | |
| 162 color: rgb(0,0,204); | |
| 163 } | |
| 164 .dna_G { | |
| 165 color: rgb(255,179,0); | |
| 166 } | |
| 167 .dna_T { | |
| 168 color: rgb(0,128,0); | |
| 169 } | |
| 170 /* END INCLUDED FILE "meme.css" */ | |
| 171 | |
| 172 | |
| 173 | |
| 174 /* START INCLUDED FILE "dreme-to-html.css" */ | |
| 175 table.dreme_motifs tr th, table.dreme_motifs tr td { | |
| 176 padding: 0px 10px; | |
| 177 } | |
| 178 | |
| 179 div.popup_wrapper { | |
| 180 position:fixed; | |
| 181 z-index:2; | |
| 182 width:100%; | |
| 183 height:0; | |
| 184 top:50%; | |
| 185 left:0; | |
| 186 } | |
| 187 | |
| 188 div.popup { | |
| 189 width: 400px; | |
| 190 z-index:2; | |
| 191 margin-left: auto; | |
| 192 margin-right: auto; | |
| 193 padding: 5px; | |
| 194 background: #FFF; | |
| 195 border-style: double; | |
| 196 border-width: 5px; | |
| 197 border-color: #00666a; | |
| 198 position:relative; | |
| 199 } | |
| 200 | |
| 201 div.grey_background { | |
| 202 position:fixed; | |
| 203 z-index: 1; | |
| 204 background-color: #000; | |
| 205 -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; | |
| 206 filter: alpha(opacity=50); | |
| 207 opacity: 0.5; | |
| 208 left: 0; | |
| 209 top: 0; | |
| 210 width: 100%; | |
| 211 height: 100%; | |
| 212 | |
| 213 } | |
| 214 td.symaction { | |
| 215 text-align: center; | |
| 216 } | |
| 217 *.symaction { | |
| 218 font-size: 20px; | |
| 219 } | |
| 220 | |
| 221 div.close { | |
| 222 cursor: pointer; | |
| 223 border: 1px solid black; | |
| 224 width:15px; | |
| 225 height:15px; | |
| 226 line-height:15px; /* this causes vertical centering */ | |
| 227 text-align:center; | |
| 228 background-color:#FFF; | |
| 229 color:#000; | |
| 230 font-size:15px; | |
| 231 font-family:monospace; | |
| 232 } | |
| 233 | |
| 234 div.close:hover { | |
| 235 color:#FFF; | |
| 236 background-color:#000; | |
| 237 } | |
| 238 | |
| 239 div.navnum { | |
| 240 width:100%; | |
| 241 height:20px; | |
| 242 line-height:20px; | |
| 243 text-align:center; | |
| 244 font-size:medium; | |
| 245 } | |
| 246 | |
| 247 a.navarrow { | |
| 248 font-size: 30px; | |
| 249 text-decoration:none; | |
| 250 } | |
| 251 | |
| 252 a.inactive { | |
| 253 color:#CCC; | |
| 254 } | |
| 255 | |
| 256 div.actionbutton { | |
| 257 cursor: pointer; | |
| 258 font-size: 18px; | |
| 259 line-height:20px; | |
| 260 padding: 5px; | |
| 261 margin: 10px 0; | |
| 262 border: 1px solid black; | |
| 263 } | |
| 264 | |
| 265 div.actionbutton:hover { | |
| 266 color:#FFF; | |
| 267 background-color:#000; | |
| 268 } | |
| 269 | |
| 270 div.pop_content { | |
| 271 position:absolute; | |
| 272 z-index:1; | |
| 273 width:300px; | |
| 274 padding: 5px; | |
| 275 background: #E4ECEC; | |
| 276 font-size: 12px; | |
| 277 font-family: Arial; | |
| 278 border-style: double; | |
| 279 border-width: 3px; | |
| 280 border-color: #AA2244; | |
| 281 display:none; | |
| 282 } | |
| 283 span.sort_dir { | |
| 284 text-decoration: none; | |
| 285 } | |
| 286 | |
| 287 div.section_title { | |
| 288 font-weight: bold; | |
| 289 cursor: pointer; | |
| 290 } | |
| 291 | |
| 292 div.section_title.inactive { | |
| 293 color: #000; | |
| 294 } | |
| 295 | |
| 296 div.section_title.inactive:hover { | |
| 297 color: #000; | |
| 298 text-decoration:underline; | |
| 299 } | |
| 300 | |
| 301 div.section_title label { | |
| 302 cursor: pointer; | |
| 303 } | |
| 304 | |
| 305 span.ellipsis { | |
| 306 display: inline-block; | |
| 307 border: 1px solid black; | |
| 308 padding: 0 2px; | |
| 309 margin: 0 2px; | |
| 310 } | |
| 311 | |
| 312 div.section_title.inactive:hover span.ellipsis { | |
| 313 color: #FFF; | |
| 314 background-color: #000; | |
| 315 } | |
| 316 | |
| 317 div.section_title.inactive span.toggle { | |
| 318 color: #000; | |
| 319 } | |
| 320 | |
| 321 div.section_data { | |
| 322 margin-left: 20px; | |
| 323 } | |
| 324 tr.rule td, tr.rule th { | |
| 325 border-bottom: 1px solid #CCC; | |
| 326 } | |
| 327 | |
| 328 h1.compact, h2.compact, h3.compact, h4.compact, h5.compact, h6.compact { | |
| 329 margin:0; | |
| 330 padding:0; | |
| 331 } | |
| 332 | |
| 333 ul.programs { | |
| 334 margin-top: 0; | |
| 335 padding-top: 0; | |
| 336 margin-bottom: 0; | |
| 337 padding-bottom: 0; | |
| 338 margin-left: 0; | |
| 339 padding-left: 0; | |
| 340 list-style: none; | |
| 341 border-bottom: 1px solid black; | |
| 342 } | |
| 343 | |
| 344 ul.programs li { | |
| 345 border: 1px solid black; | |
| 346 border-bottom-width: 0; | |
| 347 background-color: #EFE; | |
| 348 cursor: default; | |
| 349 } | |
| 350 | |
| 351 ul.programs li.active { | |
| 352 background-color: #CFC; | |
| 353 } | |
| 354 | |
| 355 ul.programs li.selected { | |
| 356 background-color: #262; | |
| 357 color: #FFF; | |
| 358 } | |
| 359 | |
| 360 div.programs_scroll { | |
| 361 width: 100%; | |
| 362 height: 90px; | |
| 363 overflow-y: auto; | |
| 364 overflow-x: hidden; | |
| 365 margin: 0 auto; | |
| 366 } | |
| 367 /* END INCLUDED FILE "dreme-to-html.css" */ | |
| 368 | |
| 369 </style> | |
| 370 <script type="text/javascript"> | |
| 371 var pos_count = 3; | |
| 372 var neg_count = 3; | |
| 373 var motif_seqs = []; | |
| 374 | |
| 375 | |
| 376 /* START INCLUDED FILE "delay_draw.js" */ | |
| 377 // | |
| 378 // Functions to measure the position of page elements relative to the size of the page | |
| 379 // | |
| 380 | |
| 381 // gets the offset of the top of the page due to scrolling | |
| 382 // from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow | |
| 383 function get_scroll_xy() { | |
| 384 var scrOfX = 0, scrOfY = 0; | |
| 385 if( typeof( window.pageYOffset ) == 'number' ) { | |
| 386 //Netscape compliant | |
| 387 scrOfY = window.pageYOffset; | |
| 388 scrOfX = window.pageXOffset; | |
| 389 } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { | |
| 390 //DOM compliant | |
| 391 scrOfY = document.body.scrollTop; | |
| 392 scrOfX = document.body.scrollLeft; | |
| 393 } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { | |
| 394 //IE6 standards compliant mode | |
| 395 scrOfY = document.documentElement.scrollTop; | |
| 396 scrOfX = document.documentElement.scrollLeft; | |
| 397 } | |
| 398 return [ scrOfX, scrOfY ]; | |
| 399 } | |
| 400 | |
| 401 // gets the width and height of the visible page | |
| 402 // from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow | |
| 403 function get_page_size() { | |
| 404 var myWidth = 0, myHeight = 0; | |
| 405 if( typeof( window.innerWidth ) == 'number' ) { | |
| 406 //Non-IE | |
| 407 myWidth = window.innerWidth; | |
| 408 myHeight = window.innerHeight; | |
| 409 } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { | |
| 410 //IE 6+ in 'standards compliant mode' | |
| 411 myWidth = document.documentElement.clientWidth; | |
| 412 myHeight = document.documentElement.clientHeight; | |
| 413 } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { | |
| 414 //IE 4 compatible | |
| 415 myWidth = document.body.clientWidth; | |
| 416 myHeight = document.body.clientHeight; | |
| 417 } | |
| 418 return [myWidth, myHeight]; | |
| 419 } | |
| 420 | |
| 421 // gets the x and y offset of an element | |
| 422 // from http://www.quirksmode.org/js/findpos.html | |
| 423 function get_elem_xy(elem) { | |
| 424 var myX = myY = 0; | |
| 425 if (elem.offsetParent) { | |
| 426 do { | |
| 427 myX += elem.offsetLeft; | |
| 428 myY += elem.offsetTop; | |
| 429 } while (elem = elem.offsetParent); | |
| 430 } | |
| 431 return [myX, myY]; | |
| 432 } | |
| 433 | |
| 434 // | |
| 435 // Functions to delay a drawing task until it is required or it would not lag the display to do so | |
| 436 // | |
| 437 | |
| 438 // a list of items still to be drawn | |
| 439 var drawable_list = []; | |
| 440 // the delay between drawing objects that are not currently visible | |
| 441 var draw_delay = 1; | |
| 442 // the delay after a user interaction | |
| 443 var user_delay = 300; | |
| 444 // the delay after a user has stopped scrolling and is viewing the stuff drawn on the current page | |
| 445 var stop_delay = 2000; | |
| 446 // the timer handle; allows resetting of the timer after user interactions | |
| 447 var draw_timer = null; | |
| 448 | |
| 449 // | |
| 450 // Drawable | |
| 451 // | |
| 452 // elem - a page element which defines the position on the page that drawing is to be done | |
| 453 // task - an object with the method run which takes care of painting the object | |
| 454 // | |
| 455 function Drawable(elem, task) { | |
| 456 this.elem = elem; | |
| 457 this.task = task; | |
| 458 this.is_visible = Drawable_is_visible; | |
| 459 } | |
| 460 | |
| 461 // | |
| 462 // Drawable_is_visible | |
| 463 // | |
| 464 // Determines if the drawable object is in the visible part of the page. | |
| 465 // | |
| 466 // page_top - the distance to the top of the page for the visible region | |
| 467 // page_height - the height of the visible region | |
| 468 function Drawable_is_visible(page_top, page_height) { | |
| 469 var elem_top = get_elem_xy(this.elem)[1]; | |
| 470 var elem_height = this.elem.height; | |
| 471 if (typeof (elem_height) != 'number') elem_height = 1; | |
| 472 return ((elem_top + elem_height) >= page_top && elem_top <= (page_top + page_height)); | |
| 473 } | |
| 474 | |
| 475 // | |
| 476 // draw_on_screen | |
| 477 // | |
| 478 // Checks each drawable object and draws those on screen. | |
| 479 // | |
| 480 function draw_on_screen() { | |
| 481 var found = false; | |
| 482 var page_top = get_scroll_xy()[1]; | |
| 483 var page_height = get_page_size()[1]; | |
| 484 for (var i = 0; i < drawable_list.length; i++) { | |
| 485 var drawable = drawable_list[i]; | |
| 486 if (drawable.is_visible(page_top, page_height)) { | |
| 487 drawable.task.run(); | |
| 488 drawable_list.splice(i--, 1); | |
| 489 found = true; | |
| 490 } | |
| 491 } | |
| 492 return found; | |
| 493 } | |
| 494 | |
| 495 // | |
| 496 // process_draw_tasks | |
| 497 // | |
| 498 // Called on a delay to process the next avaliable | |
| 499 // draw task. | |
| 500 // | |
| 501 function process_draw_tasks() { | |
| 502 var delay = draw_delay; | |
| 503 draw_timer = null; | |
| 504 if (drawable_list.length == 0) return; //no more tasks | |
| 505 if (draw_on_screen()) { | |
| 506 delay = stop_delay; //give the user a chance to scroll | |
| 507 } else { | |
| 508 //get next task | |
| 509 var drawable = drawable_list.shift(); | |
| 510 drawable.task.run(); | |
| 511 } | |
| 512 //allow UI updates between tasks | |
| 513 draw_timer = window.setTimeout("process_draw_tasks()", draw_delay); | |
| 514 } | |
| 515 | |
| 516 // | |
| 517 // delayed_process_draw_tasks | |
| 518 // | |
| 519 // Call process_draw_tasks after a short delay. | |
| 520 // The delay serves to group multiple redundant events. | |
| 521 // Should be set as event handler for onscroll and onresize. | |
| 522 // | |
| 523 function delayed_process_draw_tasks() { | |
| 524 //reset the timer | |
| 525 if (drawable_list.length > 0) { | |
| 526 if (draw_timer != null) clearTimeout(draw_timer); | |
| 527 draw_timer = window.setTimeout("process_draw_tasks()", user_delay); | |
| 528 } | |
| 529 } | |
| 530 | |
| 531 // | |
| 532 // add_draw_task | |
| 533 // | |
| 534 // Add a drawing task to be called immediately if it is | |
| 535 // visible, or to be called on a delay to reduce stuttering | |
| 536 // effect on the web browser. | |
| 537 function add_draw_task(elem, task) { | |
| 538 var page_top = get_scroll_xy()[1]; | |
| 539 var page_height = get_page_size()[1]; | |
| 540 drawable = new Drawable(elem, task); | |
| 541 if (drawable.is_visible(page_top, page_height)) { | |
| 542 task.run(); | |
| 543 } else { | |
| 544 drawable_list.push(drawable); | |
| 545 //reset timer | |
| 546 if (draw_timer != null) clearTimeout(draw_timer); | |
| 547 draw_timer = window.setTimeout("process_draw_tasks()", user_delay); | |
| 548 } | |
| 549 } | |
| 550 | |
| 551 /* END INCLUDED FILE "delay_draw.js" */ | |
| 552 | |
| 553 | |
| 554 | |
| 555 /* START INCLUDED FILE "motif_logo.js" */ | |
| 556 //====================================================================== | |
| 557 // start Alphabet object | |
| 558 //====================================================================== | |
| 559 function Alphabet(alphabet, bg) { | |
| 560 //variable prototype | |
| 561 this.freqs = new Array(); | |
| 562 this.alphabet = new Array(); | |
| 563 this.letter_count = 0; | |
| 564 //method prototype | |
| 565 this.get_ic = Alphabet_get_ic; | |
| 566 this.get_size = Alphabet_get_size; | |
| 567 this.get_index = Alphabet_get_index; | |
| 568 this.get_letter = Alphabet_get_letter; | |
| 569 this.get_colour = Alphabet_get_colour; | |
| 570 this.get_bg_freq = Alphabet_get_bg_freq; | |
| 571 this.is_nucleotide = Alphabet_is_nucleotide; | |
| 572 this.is_ambig = Alphabet_is_ambig; | |
| 573 this.toString = Alphabet_to_string; | |
| 574 //construct | |
| 575 var is_letter = /^\w$/; | |
| 576 var is_prob = /^((1(\.0+)?)|(0(\.\d+)?))$/; | |
| 577 for (var pos = 0; pos < alphabet.length; pos++) { | |
| 578 var letter = alphabet.charAt(pos); | |
| 579 if (is_letter.test(letter)) { | |
| 580 this.alphabet[this.letter_count] = letter.toUpperCase(); | |
| 581 this.freqs[this.letter_count] = -1; | |
| 582 this.letter_count++; | |
| 583 } | |
| 584 } | |
| 585 if (!(bg === undefined)) { | |
| 586 var parts = bg.split(/\s+/); | |
| 587 for (var i = 0, pos = 0; (i + 1) < parts.length; i += 2) { | |
| 588 var letter = parts[i]; | |
| 589 var freq = parts[i+1]; | |
| 590 if (is_letter.test(letter) && is_prob.test(freq)) { | |
| 591 letter = letter.toUpperCase(); //find the letter it matches | |
| 592 for (;pos < this.letter_count; pos++) { | |
| 593 if (this.alphabet[pos] == letter) break; | |
| 594 } | |
| 595 if (pos >= this.letter_count) throw "NOT_IN_ALPHABET"; | |
| 596 this.freqs[pos] = (+freq); | |
| 597 } | |
| 598 } | |
| 599 } else { | |
| 600 //assume uniform background | |
| 601 var freq = 1.0 / this.letter_count; | |
| 602 for (var pos = 0; pos < this.letter_count; pos++) { | |
| 603 this.freqs[pos] = freq; | |
| 604 } | |
| 605 } | |
| 606 } | |
| 607 | |
| 608 | |
| 609 function Alphabet_get_ic() { | |
| 610 if (this.is_nucleotide()) { | |
| 611 return 2; | |
| 612 } else { | |
| 613 return Math.log(20) / Math.LN2; | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 function Alphabet_get_size() { | |
| 618 return this.letter_count; | |
| 619 } | |
| 620 | |
| 621 function Alphabet_get_letter(alph_index) { | |
| 622 if (alph_index < 0 || alph_index >= this.letter_count) { | |
| 623 throw "BAD_ALPHABET_INDEX"; | |
| 624 } | |
| 625 return this.alphabet[alph_index]; | |
| 626 } | |
| 627 | |
| 628 function Alphabet_get_bg_freq(alph_index) { | |
| 629 if (alph_index < 0 || alph_index >= this.letter_count) { | |
| 630 throw "BAD_ALPHABET_INDEX"; | |
| 631 } | |
| 632 if (this.freqs[alph_index] == -1) throw "BG_FREQ_NOT_SET"; | |
| 633 return this.freqs[alph_index]; | |
| 634 } | |
| 635 | |
| 636 function Alphabet_get_colour(alph_index) { | |
| 637 var red = "rgb(204,0,0)"; | |
| 638 var blue = "rgb(0,0,204)"; | |
| 639 var orange = "rgb(255,179,0)"; | |
| 640 var green = "rgb(0,128,0)"; | |
| 641 var yellow = "rgb(255,255,0)"; | |
| 642 var purple = "rgb(204,0,204)"; | |
| 643 var magenta = "rgb(255,0,255)"; | |
| 644 var pink = "rgb(255,204,204)"; | |
| 645 var turquoise = "rgb(51,230,204)"; | |
| 646 if (alph_index < 0 || alph_index >= this.letter_count) { | |
| 647 throw "BAD_ALPHABET_INDEX"; | |
| 648 } | |
| 649 if (this.is_nucleotide()) { | |
| 650 switch (this.alphabet[alph_index]) { | |
| 651 case "A": | |
| 652 return red; | |
| 653 case "C": | |
| 654 return blue; | |
| 655 case "G": | |
| 656 return orange; | |
| 657 case "T": | |
| 658 return green; | |
| 659 } | |
| 660 } else { | |
| 661 switch (this.alphabet[alph_index]) { | |
| 662 case "A": | |
| 663 case "C": | |
| 664 case "F": | |
| 665 case "I": | |
| 666 case "L": | |
| 667 case "V": | |
| 668 case "W": | |
| 669 case "M": | |
| 670 return blue; | |
| 671 case "N": | |
| 672 case "Q": | |
| 673 case "S": | |
| 674 case "T": | |
| 675 return green; | |
| 676 case "D": | |
| 677 case "E": | |
| 678 return magenta; | |
| 679 case "K": | |
| 680 case "R": | |
| 681 return red; | |
| 682 case "H": | |
| 683 return pink; | |
| 684 case "G": | |
| 685 return orange; | |
| 686 case "P": | |
| 687 return yellow; | |
| 688 case "Y": | |
| 689 return turquoise; | |
| 690 } | |
| 691 } | |
| 692 return "black"; | |
| 693 } | |
| 694 | |
| 695 function Alphabet_is_ambig(alph_index) { | |
| 696 if (alph_index < 0 || alph_index >= this.letter_count) { | |
| 697 throw "BAD_ALPHABET_INDEX"; | |
| 698 } | |
| 699 if (this.is_nucleotide()) { | |
| 700 return ("ACGT".indexOf(this.alphabet[alph_index]) == -1); | |
| 701 } else { | |
| 702 return ("ACDEFGHIKLMNPQRSTVWY".indexOf(this.alphabet[alph_index]) == -1); | |
| 703 } | |
| 704 } | |
| 705 | |
| 706 function Alphabet_get_index(letter) { | |
| 707 for (i = 0; i < this.letter_count; i++) { | |
| 708 if (this.alphabet[i] == letter.toUpperCase()) return i; | |
| 709 } | |
| 710 throw "UNKNOWN_LETTER"; | |
| 711 } | |
| 712 | |
| 713 function Alphabet_is_nucleotide() { | |
| 714 //TODO basic method, make better | |
| 715 if (this.letter_count < 20) return true; | |
| 716 return false; | |
| 717 } | |
| 718 | |
| 719 function Alphabet_to_string() { | |
| 720 return (this.is_nucleotide() ? "Nucleotide" : "Protein") + " Alphabet " + (this.alphabet.join("")); | |
| 721 } | |
| 722 | |
| 723 //====================================================================== | |
| 724 // end Alphabet object | |
| 725 //====================================================================== | |
| 726 | |
| 727 //====================================================================== | |
| 728 // start Symbol object | |
| 729 //====================================================================== | |
| 730 function Symbol(alph_index, scale, alphabet) { | |
| 731 //variable prototype | |
| 732 this.symbol = alphabet.get_letter(alph_index); | |
| 733 this.scale = scale; | |
| 734 this.colour = alphabet.get_colour(alph_index); | |
| 735 //function prototype | |
| 736 this.get_symbol = Symbol_get_symbol; | |
| 737 this.get_scale = Symbol_get_scale; | |
| 738 this.get_colour = Symbol_get_colour; | |
| 739 this.toString = Symbol_to_string; | |
| 740 } | |
| 741 | |
| 742 function Symbol_get_symbol() { | |
| 743 return this.symbol; | |
| 744 } | |
| 745 | |
| 746 function Symbol_get_scale() { | |
| 747 return this.scale; | |
| 748 } | |
| 749 | |
| 750 function Symbol_get_colour() { | |
| 751 return this.colour; | |
| 752 } | |
| 753 | |
| 754 function Symbol_to_string() { | |
| 755 return this.symbol + " " + (Math.round(this.scale*1000)/10) + "%"; | |
| 756 } | |
| 757 | |
| 758 function compare_symbol(sym1, sym2) { | |
| 759 if (sym1.get_scale() < sym2.get_scale()) { | |
| 760 return -1; | |
| 761 } else if (sym1.get_scale() > sym2.get_scale()) { | |
| 762 return 1; | |
| 763 } else { | |
| 764 return 0; | |
| 765 } | |
| 766 } | |
| 767 //====================================================================== | |
| 768 // end Symbol object | |
| 769 //====================================================================== | |
| 770 | |
| 771 //====================================================================== | |
| 772 // start Pspm object | |
| 773 //====================================================================== | |
| 774 function Pspm(pspm, name, ltrim, rtrim, nsites, evalue) { | |
| 775 if (ltrim === undefined) ltrim = 0; | |
| 776 if (rtrim === undefined) rtrim = 0; | |
| 777 if (nsites === undefined) nsites = 0; | |
| 778 if (evalue === undefined) evalue = 0; | |
| 779 //variable prototype | |
| 780 this.alph_length = 0; | |
| 781 this.motif_length = 0; | |
| 782 this.pspm = null; | |
| 783 this.name = (typeof name == "string" ? name : ""); | |
| 784 this.nsites = nsites; | |
| 785 this.evalue = evalue; | |
| 786 this.ltrim = ltrim; | |
| 787 this.rtrim = rtrim; | |
| 788 //function prototype | |
| 789 this.copy = Pspm_copy; | |
| 790 this.reverse_complement = Pspm_reverse_complement; | |
| 791 this.get_stack = Pspm_get_stack; | |
| 792 this.get_stack_ic = Pspm_get_stack_ic; | |
| 793 this.get_motif_length = Pspm_get_motif_length; | |
| 794 this.get_alph_length = Pspm_get_alph_length; | |
| 795 this.get_left_trim = Pspm_get_left_trim; | |
| 796 this.get_right_trim = Pspm_get_right_trim; | |
| 797 this.as_pspm = Pspm_as_pspm; | |
| 798 this.as_pssm = Pspm_as_pssm; | |
| 799 this.toString = Pspm_to_string; | |
| 800 //construct | |
| 801 if (typeof pspm == "string") { | |
| 802 var pspm_header = /letter-probability matrix:\s+alength=\s+(\d+)\s+w=\s+(\d+)(\s+nsites=\s+(\S+))?(\s+E=\s+(\S+))?\s*/; | |
| 803 var lines = pspm.split(/\n/); | |
| 804 var read_pspm = false; | |
| 805 var line_num = 0; | |
| 806 var col_num = 0; | |
| 807 this.pspm = new Array(); | |
| 808 for (line_index in lines) { | |
| 809 //exclude inherited properties and undefined properties | |
| 810 if (!lines.hasOwnProperty(line_index) || lines[line_index] === undefined) continue; | |
| 811 | |
| 812 var line = trim(lines[line_index]); | |
| 813 if (line == '') { | |
| 814 continue; | |
| 815 } | |
| 816 if (!read_pspm) { | |
| 817 var header_match = pspm_header.exec(line); | |
| 818 if (header_match != null) { | |
| 819 read_pspm = true; | |
| 820 this.alph_length = (+header_match[1]); | |
| 821 this.motif_length = (+header_match[2]); | |
| 822 if (header_match[4]) this.nsites = parseFloat(header_match[4]);//not always an integer | |
| 823 if (header_match[6]) this.evalue = parseFloat(header_match[6]); | |
| 824 this.pspm = new Array(this.motif_length); | |
| 825 } | |
| 826 continue; | |
| 827 } | |
| 828 if (line_num >= this.motif_length) { | |
| 829 throw "TOO_MANY_ROWS"; | |
| 830 } | |
| 831 this.pspm[line_num] = new Array(this.alph_length); | |
| 832 col_num = 0; | |
| 833 var parts = line.split(/\s+/); | |
| 834 for (part_index in parts) { | |
| 835 //exclude inherited properties and undefined properties | |
| 836 if (!parts.hasOwnProperty(part_index) || parts[part_index] === undefined) continue; | |
| 837 | |
| 838 var prob = parts[part_index]; | |
| 839 if (col_num >= this.alph_length) { | |
| 840 throw "TOO_MANY_COLS"; | |
| 841 } | |
| 842 this.pspm[line_num][col_num] = (+prob); | |
| 843 //check the probability is within bounds | |
| 844 if (this.pspm[line_num][col_num] > 1 || this.pspm[line_num][col_num] < 0) { | |
| 845 throw "NUM_NOT_PROB"; | |
| 846 } | |
| 847 col_num++; | |
| 848 } | |
| 849 if (col_num != this.alph_length) { | |
| 850 throw "TOO_FEW_COLS"; | |
| 851 } | |
| 852 line_num++; | |
| 853 } | |
| 854 if (line_num != this.motif_length) { | |
| 855 throw "TOO_FEW_ROWS"; | |
| 856 } | |
| 857 } else { | |
| 858 // assume pspm is a nested array | |
| 859 this.motif_length = pspm.length; | |
| 860 this.alpha_length = (pspm.length > 0 ? pspm[0].length : 0); | |
| 861 this.pspm = new Array(this.motif_length); | |
| 862 // copy pspm and check | |
| 863 for (var row = 0; row < this.motif_length; row++) { | |
| 864 if (this.alpha_length != pspm[row].length) throw "COLUMN_MISMATCH"; | |
| 865 this.pspm[row] = new Array(this.alpha_length); | |
| 866 var row_sum = 0; | |
| 867 for (var col = 0; col < this.alpha_length; col++) { | |
| 868 row_sum += this.pspm[row][col]; | |
| 869 this.pspm[row][col] = 0 + pspm[row][col]; | |
| 870 } | |
| 871 var delta = 0.1 | |
| 872 if ((row_sum > 1 && (row_sum - 1) > delta) || | |
| 873 (row_sum < 1 && (1 - row_sum) > delta)) { | |
| 874 throw "INVALID_SUM"; | |
| 875 } | |
| 876 } | |
| 877 } | |
| 878 } | |
| 879 | |
| 880 function Clone() {} | |
| 881 | |
| 882 function Pspm_copy() { | |
| 883 Clone.prototype = this; | |
| 884 var clone = new Clone(); | |
| 885 //so far only a shallow copy, need to copy everything | |
| 886 clone.alph_length = (0+this.alph_length); | |
| 887 clone.motif_length = (0+this.motif_length); | |
| 888 clone.name = (""+this.name); | |
| 889 clone.nsites = (0+this.nsites); | |
| 890 clone.evalue = (0+this.evalue); | |
| 891 clone.ltrim = (0+this.ltrim); | |
| 892 clone.rtrim = (0+this.rtrim); | |
| 893 clone.pspm = new Array(this.motif_length); | |
| 894 for (row = 0; row < this.motif_length; row++) { | |
| 895 clone.pspm[row] = new Array(this.alph_length); | |
| 896 for (col = 0; col < this.alph_length; col++) { | |
| 897 clone.pspm[row][col] = (0+this.pspm[row][col]); | |
| 898 } | |
| 899 } | |
| 900 return clone; | |
| 901 } | |
| 902 | |
| 903 function Pspm_reverse_complement(alphabet) { | |
| 904 if (this.alph_length != alphabet.get_size()) { | |
| 905 throw "ALPHABET_MISMATCH"; | |
| 906 } | |
| 907 if (!alphabet.is_nucleotide()) { | |
| 908 throw "NO_PROTEIN_RC"; | |
| 909 } | |
| 910 //reverse | |
| 911 var x = 0; | |
| 912 var y = this.motif_length-1; | |
| 913 while (x < y) { | |
| 914 var temp = this.pspm[x]; | |
| 915 this.pspm[x] = this.pspm[y]; | |
| 916 this.pspm[y] = temp; | |
| 917 x++; | |
| 918 y--; | |
| 919 } | |
| 920 //complement | |
| 921 var a_index = alphabet.get_index("A"); | |
| 922 var c_index = alphabet.get_index("C"); | |
| 923 var g_index = alphabet.get_index("G"); | |
| 924 var t_index = alphabet.get_index("T"); | |
| 925 for (i = 0; i < this.motif_length; i++) { | |
| 926 var row = this.pspm[i]; | |
| 927 //swap A and T | |
| 928 var temp = row[a_index]; | |
| 929 row[a_index] = row[t_index]; | |
| 930 row[t_index] = temp; | |
| 931 //swap C and G | |
| 932 temp = row[c_index]; | |
| 933 row[c_index] = row[g_index]; | |
| 934 row[g_index] = temp; | |
| 935 } | |
| 936 //swap triming | |
| 937 var temp_trim = this.ltrim; | |
| 938 this.ltrim = this.rtrim; | |
| 939 this.rtrim = temp_trim; | |
| 940 //note that ambigs are ignored because they don't effect motifs | |
| 941 return this; //allow function chaining... | |
| 942 } | |
| 943 | |
| 944 function Pspm_get_stack(position, alphabet) { | |
| 945 if (this.alph_length != alphabet.get_size()) { | |
| 946 throw "ALPHABET_MISMATCH"; | |
| 947 } | |
| 948 var row = this.pspm[position]; | |
| 949 var stack_ic = this.get_stack_ic(position, alphabet); | |
| 950 var alphabet_ic = alphabet.get_ic(); | |
| 951 var stack = new Array(); | |
| 952 for (i = 0; i < this.alph_length; i++) { | |
| 953 if (alphabet.is_ambig(i)) continue; | |
| 954 var sym = new Symbol(i, row[i]*stack_ic/alphabet_ic, alphabet); | |
| 955 if (sym.get_scale() <= 0) continue; | |
| 956 stack.push(sym); | |
| 957 } | |
| 958 stack.sort(compare_symbol); | |
| 959 return stack; | |
| 960 } | |
| 961 | |
| 962 function Pspm_get_stack_ic(position, alphabet) { | |
| 963 if (this.alph_length != alphabet.get_size()) { | |
| 964 throw "ALPHABET_MISMATCH"; | |
| 965 } | |
| 966 var row = this.pspm[position]; | |
| 967 var H = 0; | |
| 968 for (var i = 0; i < this.alph_length; i++) { | |
| 969 if (alphabet.is_ambig(i)) continue; | |
| 970 if (row[i] == 0) continue; | |
| 971 H -= (row[i] * (Math.log(row[i]) / Math.LN2)); | |
| 972 } | |
| 973 return alphabet.get_ic() - H; | |
| 974 } | |
| 975 | |
| 976 function Pspm_get_error(alphabet) { | |
| 977 var asize; | |
| 978 if (this.nsites == 0) return 0; | |
| 979 if (alphabet.is_nucleotide()) { | |
| 980 asize = 4; | |
| 981 } else { | |
| 982 asize = 20; | |
| 983 } | |
| 984 return (asize-1) / (2 * Math.log(2)*this.nsites); | |
| 985 } | |
| 986 | |
| 987 function Pspm_get_motif_length() { | |
| 988 return this.motif_length; | |
| 989 } | |
| 990 | |
| 991 function Pspm_get_alph_length() { | |
| 992 return this.alph_length; | |
| 993 } | |
| 994 | |
| 995 function Pspm_get_left_trim() { | |
| 996 return this.ltrim; | |
| 997 } | |
| 998 | |
| 999 function Pspm_get_right_trim() { | |
| 1000 return this.rtrim; | |
| 1001 } | |
| 1002 | |
| 1003 function Pspm_as_pspm() { | |
| 1004 var out = "letter-probability matrix: alength= " + this.alph_length + | |
| 1005 " w= " + this.motif_length + " nsites= " + this.nsites + | |
| 1006 " E= " + this.evalue.toExponential() + "\n"; | |
| 1007 for (var row = 0; row < this.motif_length; row++) { | |
| 1008 for (var col = 0; col < this.alph_length; col++) { | |
| 1009 if (col != 0) out += " "; | |
| 1010 out += this.pspm[row][col].toFixed(6); | |
| 1011 } | |
| 1012 out += "\n"; | |
| 1013 } | |
| 1014 return out; | |
| 1015 } | |
| 1016 | |
| 1017 function Pspm_as_pssm(alphabet, pseudo) { | |
| 1018 if (typeof pseudo != "number") pseudo = 0.1; | |
| 1019 var out = "log-odds matrix: alength= " + this.alph_length + | |
| 1020 " w= " + this.motif_length + | |
| 1021 " E= " + this.evalue.toExponential() + "\n"; | |
| 1022 var log2 = Math.log(2); | |
| 1023 var total = this.nsites + pseudo; | |
| 1024 for (var row = 0; row < this.motif_length; row++) { | |
| 1025 for (var col = 0; col < this.alph_length; col++) { | |
| 1026 if (col != 0) out += " "; | |
| 1027 var p = this.pspm[row][col]; | |
| 1028 // to avoid log of zero we add a pseudo count | |
| 1029 var bg = alphabet.get_bg_freq(col); | |
| 1030 var p2 = (p * this.nsites + bg * pseudo) / total; | |
| 1031 // now calculate the score | |
| 1032 var score = -10000; | |
| 1033 if (p2 > 0) { | |
| 1034 score = Math.round((Math.log(p2 / bg) / log2) * 100) | |
| 1035 } | |
| 1036 out += score; | |
| 1037 } | |
| 1038 out += "\n"; | |
| 1039 } | |
| 1040 return out; | |
| 1041 } | |
| 1042 | |
| 1043 function Pspm_to_string() { | |
| 1044 var str = ""; | |
| 1045 for (row_index in this.pspm) { | |
| 1046 //exclude inherited properties and undefined properties | |
| 1047 if (!this.pspm.hasOwnProperty(row_index) || this.pspm[row_index] === undefined) continue; | |
| 1048 | |
| 1049 var row = this.pspm[row_index]; | |
| 1050 str += row.join("\t") + "\n"; | |
| 1051 } | |
| 1052 return str; | |
| 1053 } | |
| 1054 //====================================================================== | |
| 1055 // end Pspm object | |
| 1056 //====================================================================== | |
| 1057 | |
| 1058 //====================================================================== | |
| 1059 // start Logo object | |
| 1060 //====================================================================== | |
| 1061 function Logo(alphabet, fine_text) { | |
| 1062 this.alphabet = alphabet; | |
| 1063 this.fine_text = fine_text; | |
| 1064 this.pspm_list = []; | |
| 1065 this.pspm_column = []; | |
| 1066 this.rows = 0; | |
| 1067 this.columns = 0; | |
| 1068 | |
| 1069 //functions | |
| 1070 this.add_pspm = Logo_add_pspm; | |
| 1071 this.get_columns = Logo_get_columns; | |
| 1072 this.get_rows = Logo_get_rows; | |
| 1073 this.get_pspm = Logo_get_pspm; | |
| 1074 this.get_offset = Logo_get_offset; | |
| 1075 } | |
| 1076 | |
| 1077 function Logo_add_pspm(pspm, column) { | |
| 1078 if (column === undefined) column = 0; | |
| 1079 else if (column < 0) throw "COLUMN_OUT_OF_BOUNDS"; | |
| 1080 this.pspm_list[this.rows] = pspm; | |
| 1081 this.pspm_column[this.rows] = column; | |
| 1082 this.rows++; | |
| 1083 var col = column + pspm.get_motif_length(); | |
| 1084 if (col > this.columns) this.columns = col; | |
| 1085 } | |
| 1086 | |
| 1087 function Logo_get_columns() { | |
| 1088 return this.columns; | |
| 1089 } | |
| 1090 | |
| 1091 function Logo_get_rows() { | |
| 1092 return this.rows; | |
| 1093 } | |
| 1094 | |
| 1095 function Logo_get_pspm(row_index) { | |
| 1096 if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS"; | |
| 1097 return this.pspm_list[row_index]; | |
| 1098 } | |
| 1099 | |
| 1100 function Logo_get_offset(row_index) { | |
| 1101 if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS"; | |
| 1102 return this.pspm_column[row_index]; | |
| 1103 } | |
| 1104 | |
| 1105 //====================================================================== | |
| 1106 // end Logo object | |
| 1107 //====================================================================== | |
| 1108 | |
| 1109 //====================================================================== | |
| 1110 // start RasterizedAlphabet | |
| 1111 //====================================================================== | |
| 1112 | |
| 1113 // Rasterize Alphabet | |
| 1114 // 1) Measure width of text at default font for all symbols in alphabet | |
| 1115 // 2) sort in width ascending | |
| 1116 // 3) Drop the top and bottom 10% (designed to ignore outliers like 'W' and 'I') | |
| 1117 // 4) Calculate the average as the maximum scaling factor (designed to stop I becoming a rectangular blob). | |
| 1118 // 5) Assume scale of zero would result in width of zero, interpolate scale required to make perfect width font | |
| 1119 // 6) Draw text onto temp canvas at calculated scale | |
| 1120 // 7) Find bounds of drawn text | |
| 1121 // 8) Paint on to another canvas at the desired height (but only scaling width to fit if larger). | |
| 1122 function RasterizedAlphabet(alphabet, font, target_width) { | |
| 1123 //variable prototypes | |
| 1124 this.lookup = []; //a map of letter to index | |
| 1125 this.rasters = []; //a list of rasters | |
| 1126 this.dimensions = []; //a list of dimensions | |
| 1127 | |
| 1128 //function prototypes | |
| 1129 this.draw = RasterizedAlphabet_draw; | |
| 1130 | |
| 1131 //construct | |
| 1132 var default_size = 60; // size of square to assume as the default width | |
| 1133 var safety_pad = 20; // pixels to pad around so we don't miss the edges | |
| 1134 // create a canvas to do our rasterizing on | |
| 1135 var canvas = document.createElement("canvas"); | |
| 1136 // assume the default font would fit in a canvas of 100 by 100 | |
| 1137 canvas.width = default_size + 2 * safety_pad; | |
| 1138 canvas.height = default_size + 2 * safety_pad; | |
| 1139 // check for canvas support before attempting anything | |
| 1140 if (!canvas.getContext) throw "NO_CANVAS_SUPPORT"; | |
| 1141 var ctx = canvas.getContext('2d'); | |
| 1142 // check for html5 text drawing support | |
| 1143 if (!supports_text(ctx)) throw "NO_CANVAS_TEXT_SUPPORT"; | |
| 1144 // calculate the middle | |
| 1145 var middle = Math.round(canvas.width / 2); | |
| 1146 // calculate the baseline | |
| 1147 var baseline = Math.round(canvas.height - safety_pad); | |
| 1148 // list of widths | |
| 1149 var widths = []; | |
| 1150 var count = 0; | |
| 1151 var letters = []; | |
| 1152 //now measure each letter in the alphabet | |
| 1153 for (var i = 0; i < alphabet.get_size(); ++i) { | |
| 1154 if (alphabet.is_ambig(i)) continue; //skip ambigs as they're never rendered | |
| 1155 var letter = alphabet.get_letter(i); | |
| 1156 letters.push(letter); | |
| 1157 var pos = count++; | |
| 1158 this.lookup[letter] = pos; | |
| 1159 //clear the canvas | |
| 1160 canvas.width = canvas.width; | |
| 1161 // get the context and prepare to draw our width test | |
| 1162 var ctx = canvas.getContext('2d'); | |
| 1163 ctx.font = font; | |
| 1164 ctx.fillStyle = alphabet.get_colour(i); | |
| 1165 ctx.textAlign = "center"; | |
| 1166 ctx.translate(middle, baseline); | |
| 1167 // draw the test text | |
| 1168 ctx.fillText(letter, 0, 0); | |
| 1169 //measure | |
| 1170 var size = RasterizedAlphabet_measure(ctx, canvas.width, canvas.height); | |
| 1171 if (size.width == 0) throw "INVISIBLE_LETTER"; //maybe the fill was white on white? | |
| 1172 widths.push(size.width); | |
| 1173 this.dimensions[pos] = size; | |
| 1174 } | |
| 1175 //sort the widths | |
| 1176 widths.sort(function(a,b) {return a - b;}); | |
| 1177 //drop 10% of the items off each end | |
| 1178 var tenpercent = Math.floor(widths.length / 10); | |
| 1179 for (var i = 0; i < tenpercent; ++i) { | |
| 1180 widths.pop(); | |
| 1181 widths.shift(); | |
| 1182 } | |
| 1183 //calculate average width | |
| 1184 var avg_width = 0; | |
| 1185 for (var i = 0; i < widths.length; ++i) avg_width += widths[i]; | |
| 1186 avg_width /= widths.length; | |
| 1187 // calculate scales | |
| 1188 for (var i = 0; i < this.dimensions.length; ++i) { | |
| 1189 var size = this.dimensions[i]; | |
| 1190 // calculate scale | |
| 1191 var scale = target_width / Math.max(avg_width, size.width); | |
| 1192 // estimate scaled height | |
| 1193 var target_height = size.height * scale; | |
| 1194 // create an approprately sized canvas | |
| 1195 var raster = document.createElement("canvas"); | |
| 1196 raster.width = target_width; // if it goes over the edge too bad... | |
| 1197 raster.height = target_height + safety_pad * 2; | |
| 1198 // calculate the middle | |
| 1199 middle = Math.round(raster.width / 2); | |
| 1200 // calculate the baseline | |
| 1201 baseline = Math.round(raster.height - safety_pad); | |
| 1202 // get the context and prepare to draw the rasterized text | |
| 1203 ctx = raster.getContext('2d'); | |
| 1204 ctx.font = font; | |
| 1205 ctx.fillStyle = alphabet.get_colour(i); | |
| 1206 ctx.textAlign = "center"; | |
| 1207 ctx.translate(middle, baseline); | |
| 1208 ctx.save(); | |
| 1209 ctx.scale(scale, scale); | |
| 1210 // draw the rasterized text | |
| 1211 ctx.fillText(letters[i], 0, 0); | |
| 1212 ctx.restore(); | |
| 1213 this.rasters[i] = raster; | |
| 1214 this.dimensions[i] = RasterizedAlphabet_measure(ctx, raster.width, raster.height); | |
| 1215 } | |
| 1216 } | |
| 1217 | |
| 1218 function RasterizedAlphabet_measure(ctx, cwidth, cheight) { | |
| 1219 var data = ctx.getImageData(0, 0, cwidth, cheight).data; | |
| 1220 var r = 0, c = 0;// r: row, c: column | |
| 1221 var top_line = -1, bottom_line = -1, left_line = -1, right_line = -1; | |
| 1222 var txt_width = 0, txt_height = 0; | |
| 1223 // Find the top-most line with a non-white pixel | |
| 1224 for (r = 0; r < cheight; r++) { | |
| 1225 for (c = 0; c < cwidth; c++) { | |
| 1226 if (data[r * cwidth * 4 + c * 4 + 3]) { | |
| 1227 top_line = r; | |
| 1228 break; | |
| 1229 } | |
| 1230 } | |
| 1231 if (top_line != -1) break; | |
| 1232 } | |
| 1233 | |
| 1234 //find the last line with a non-white pixel | |
| 1235 if (top_line != -1) { | |
| 1236 for (r = cheight-1; r >= top_line; r--) { | |
| 1237 for(c = 0; c < cwidth; c++) { | |
| 1238 if(data[r * cwidth * 4 + c * 4 + 3]) { | |
| 1239 bottom_line = r; | |
| 1240 break; | |
| 1241 } | |
| 1242 } | |
| 1243 if (bottom_line != -1) break; | |
| 1244 } | |
| 1245 txt_height = bottom_line - top_line + 1; | |
| 1246 } | |
| 1247 | |
| 1248 // Find the left-most line with a non-white pixel | |
| 1249 for (c = 0; c < cwidth; c++) { | |
| 1250 for (r = 0; r < cheight; r++) { | |
| 1251 if (data[r * cwidth * 4 + c * 4 + 3]) { | |
| 1252 left_line = c; | |
| 1253 break; | |
| 1254 } | |
| 1255 } | |
| 1256 if (left_line != -1) break; | |
| 1257 } | |
| 1258 | |
| 1259 //find the right most line with a non-white pixel | |
| 1260 if (left_line != -1) { | |
| 1261 for (c = cwidth-1; c >= left_line; c--) { | |
| 1262 for(r = 0; r < cheight; r++) { | |
| 1263 if(data[r * cwidth * 4 + c * 4 + 3]) { | |
| 1264 right_line = c; | |
| 1265 break; | |
| 1266 } | |
| 1267 } | |
| 1268 if (right_line != -1) break; | |
| 1269 } | |
| 1270 txt_width = right_line - left_line + 1; | |
| 1271 } | |
| 1272 | |
| 1273 //return the bounds | |
| 1274 return {bound_top: top_line, bound_bottom: bottom_line, bound_left: left_line, bound_right: right_line, width: txt_width, height: txt_height}; | |
| 1275 } | |
| 1276 | |
| 1277 function RasterizedAlphabet_draw(ctx, letter, dx, dy, dWidth, dHeight) { | |
| 1278 var index = this.lookup[letter]; | |
| 1279 var raster = this.rasters[index]; | |
| 1280 var size = this.dimensions[index]; | |
| 1281 ctx.drawImage(raster, 0, size.bound_top -1, raster.width, size.height+1, dx, dy, dWidth, dHeight); | |
| 1282 } | |
| 1283 | |
| 1284 //====================================================================== | |
| 1285 // end RasterizedAlphabet | |
| 1286 //====================================================================== | |
| 1287 | |
| 1288 //====================================================================== | |
| 1289 // start LogoMetrics object | |
| 1290 //====================================================================== | |
| 1291 | |
| 1292 function LogoMetrics(ctx, canvas_width, canvas_height, logo_columns, logo_rows, allow_space_for_names) { | |
| 1293 if (allow_space_for_names === undefined) allow_space_for_names = false; | |
| 1294 //variable prototypes | |
| 1295 this.canvas_width = canvas_width; | |
| 1296 this.canvas_height = canvas_height; | |
| 1297 this.scale_x = 1; | |
| 1298 this.scale_y = 1; | |
| 1299 this.pad_top = 5; | |
| 1300 this.pad_left = 10; | |
| 1301 this.pad_right = 5; | |
| 1302 this.pad_bottom = 0; | |
| 1303 this.pad_middle = 20; | |
| 1304 this.name_height = 14; | |
| 1305 this.name_font = "bold " + this.name_height + "px Times, sans-serif"; | |
| 1306 this.name_spacer = 0; | |
| 1307 this.y_label = "bits" | |
| 1308 this.y_label_height = 12; | |
| 1309 this.y_label_font = "bold " + this.y_label_height + "px Helvetica, sans-serif"; | |
| 1310 this.y_label_spacer = 3; | |
| 1311 this.y_num_height = 12; | |
| 1312 this.y_num_width = 0; | |
| 1313 this.y_num_font = "bold " + this.y_num_height + "px Helvetica, sans-serif"; | |
| 1314 this.y_tic_width = 5; | |
| 1315 this.stack_pad_left = 0; | |
| 1316 this.stack_font = "bold 25px Helvetica, sans-serif"; | |
| 1317 this.stack_height = 90; | |
| 1318 this.stack_width = 26; | |
| 1319 this.stacks_pad_right = 5; | |
| 1320 this.x_num_above = 2; | |
| 1321 this.x_num_height = 12; | |
| 1322 this.x_num_width = 0; | |
| 1323 this.x_num_font = "bold " + this.x_num_height + "px Helvetica, sans-serif"; | |
| 1324 this.fine_txt_height = 6; | |
| 1325 this.fine_txt_above = 2; | |
| 1326 this.fine_txt_font = "normal " + this.fine_txt_height + "px Helvetica, sans-serif"; | |
| 1327 this.letter_metrics = new Array(); | |
| 1328 this.summed_width = 0; | |
| 1329 this.summed_height = 0; | |
| 1330 //function prototypes | |
| 1331 //none | |
| 1332 //calculate the width of the y axis numbers | |
| 1333 ctx.font = this.y_num_font; | |
| 1334 for (var i = 0; i <= 2; i++) { | |
| 1335 this.y_num_width = Math.max(this.y_num_width, ctx.measureText("" + i).width); | |
| 1336 } | |
| 1337 //calculate the width of the x axis numbers (but they are rotated so it becomes height) | |
| 1338 ctx.font = this.x_num_font; | |
| 1339 for (var i = 1; i <= logo_columns; i++) { | |
| 1340 this.x_num_width = Math.max(this.x_num_width, ctx.measureText("" + i).width); | |
| 1341 } | |
| 1342 | |
| 1343 //calculate how much vertical space we want to draw this | |
| 1344 //first we add the padding at the top and bottom since that's always there | |
| 1345 this.summed_height += this.pad_top + this.pad_bottom; | |
| 1346 //all except the last row have the same amount of space allocated to them | |
| 1347 if (logo_rows > 1) { | |
| 1348 var row_height = this.stack_height + this.pad_middle; | |
| 1349 if (allow_space_for_names) { | |
| 1350 row_height += this.name_height; | |
| 1351 //the label is allowed to overlap into the spacer | |
| 1352 row_height += Math.max(this.y_num_height/2, this.name_spacer); | |
| 1353 //the label is allowed to overlap the space used by the other label | |
| 1354 row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above); | |
| 1355 } else { | |
| 1356 row_height += this.y_num_height/2; | |
| 1357 //the label is allowed to overlap the space used by the other label | |
| 1358 row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above); | |
| 1359 } | |
| 1360 this.summed_height += row_height * (logo_rows - 1); | |
| 1361 } | |
| 1362 //the last row has the name and fine text below it but no padding | |
| 1363 this.summed_height += this.stack_height + this.y_num_height/2; | |
| 1364 if (allow_space_for_names) { | |
| 1365 this.summed_height += this.fine_txt_height + this.fine_txt_above + this.name_height; | |
| 1366 this.summed_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above + this.name_spacer); | |
| 1367 } else { | |
| 1368 this.summed_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above + this.fine_txt_height + this.fine_txt_above); | |
| 1369 } | |
| 1370 | |
| 1371 //calculate how much horizontal space we want to draw this | |
| 1372 //first add the padding at the left and right since that's always there | |
| 1373 this.summed_width += this.pad_left + this.pad_right; | |
| 1374 //add on the space for the y-axis label | |
| 1375 this.summed_width += this.y_label_height + this.y_label_spacer; | |
| 1376 //add on the space for the y-axis | |
| 1377 this.summed_width += this.y_num_width + this.y_tic_width; | |
| 1378 //add on the space for the stacks | |
| 1379 this.summed_width += (this.stack_pad_left + this.stack_width) * logo_columns; | |
| 1380 //add on the padding after the stacks (an offset from the fine text) | |
| 1381 this.summed_width += this.stacks_pad_right; | |
| 1382 | |
| 1383 //calculate scaling factors | |
| 1384 this.scale_y = this.canvas_height / this.summed_height; | |
| 1385 this.scale_x = this.canvas_width / this.summed_width; | |
| 1386 | |
| 1387 //maintain aspect ratio | |
| 1388 if (this.scale_y > this.scale_x) { | |
| 1389 this.scale_y = this.scale_x; | |
| 1390 } else { | |
| 1391 this.scale_x = this.scale_y; | |
| 1392 } | |
| 1393 | |
| 1394 | |
| 1395 } | |
| 1396 | |
| 1397 //====================================================================== | |
| 1398 // end LogoMetrics object | |
| 1399 //====================================================================== | |
| 1400 | |
| 1401 | |
| 1402 //found this trick at http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm | |
| 1403 function image_ok(img) { | |
| 1404 // During the onload event, IE correctly identifies any images that | |
| 1405 // weren't downloaded as not complete. Others should too. Gecko-based | |
| 1406 // browsers act like NS4 in that they report this incorrectly. | |
| 1407 if (!img.complete) { | |
| 1408 return false; | |
| 1409 } | |
| 1410 // However, they do have two very useful properties: naturalWidth and | |
| 1411 // naturalHeight. These give the true size of the image. If it failed | |
| 1412 // to load, either of these should be zero. | |
| 1413 if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) { | |
| 1414 return false; | |
| 1415 } | |
| 1416 // No other way of checking: assume it's ok. | |
| 1417 return true; | |
| 1418 } | |
| 1419 | |
| 1420 function supports_text(ctx) { | |
| 1421 if (!ctx.fillText) return false; | |
| 1422 if (!ctx.measureText) return false; | |
| 1423 return true; | |
| 1424 } | |
| 1425 | |
| 1426 //draws the scale, returns the width | |
| 1427 function draw_scale(ctx, metrics, alphabet_ic) { | |
| 1428 var tic_height = metrics.stack_height / alphabet_ic; | |
| 1429 ctx.save(); | |
| 1430 ctx.lineWidth = 1.5; | |
| 1431 ctx.translate(metrics.y_label_height, metrics.y_num_height/2); | |
| 1432 //draw the axis label | |
| 1433 ctx.save(); | |
| 1434 ctx.font = metrics.y_label_font; | |
| 1435 ctx.translate(0, metrics.stack_height/2); | |
| 1436 ctx.save(); | |
| 1437 ctx.rotate(-(Math.PI / 2)); | |
| 1438 ctx.textAlign = "center"; | |
| 1439 ctx.fillText("bits", 0, 0); | |
| 1440 ctx.restore(); | |
| 1441 ctx.restore(); | |
| 1442 | |
| 1443 ctx.translate(metrics.y_label_spacer + metrics.y_num_width, 0); | |
| 1444 | |
| 1445 //draw the axis tics | |
| 1446 ctx.save(); | |
| 1447 ctx.translate(0, metrics.stack_height); | |
| 1448 ctx.font = metrics.y_num_font; | |
| 1449 ctx.textAlign = "right"; | |
| 1450 ctx.textBaseline = "middle"; | |
| 1451 for (var i = 0; i <= alphabet_ic; i++) { | |
| 1452 //draw the number | |
| 1453 ctx.fillText("" + i, 0, 0); | |
| 1454 //draw the tic | |
| 1455 ctx.beginPath(); | |
| 1456 ctx.moveTo(0, 0); | |
| 1457 ctx.lineTo(metrics.y_tic_width, 0); | |
| 1458 ctx.stroke(); | |
| 1459 //prepare for next tic | |
| 1460 ctx.translate(0, -tic_height); | |
| 1461 } | |
| 1462 ctx.restore(); | |
| 1463 | |
| 1464 ctx.translate(metrics.y_tic_width, 0); | |
| 1465 | |
| 1466 ctx.beginPath(); | |
| 1467 ctx.moveTo(0, 0); | |
| 1468 ctx.lineTo(0, metrics.stack_height); | |
| 1469 ctx.stroke(); | |
| 1470 | |
| 1471 ctx.restore(); | |
| 1472 } | |
| 1473 | |
| 1474 function draw_stack_num(ctx, metrics, row_index) { | |
| 1475 ctx.save(); | |
| 1476 ctx.font = metrics.x_num_font; | |
| 1477 ctx.translate(metrics.stack_width / 2, metrics.stack_height + metrics.x_num_above); | |
| 1478 ctx.save(); | |
| 1479 ctx.rotate(-(Math.PI / 2)); | |
| 1480 ctx.textBaseline = "middle" | |
| 1481 ctx.textAlign = "right" | |
| 1482 ctx.fillText("" + (row_index + 1), 0, 0); | |
| 1483 ctx.restore(); | |
| 1484 ctx.restore(); | |
| 1485 } | |
| 1486 | |
| 1487 function draw_stack(ctx, metrics, symbols, raster) { | |
| 1488 var preferred_pad = 0; | |
| 1489 var sym_min = 5; | |
| 1490 | |
| 1491 ctx.save();//1 | |
| 1492 ctx.translate(0, metrics.stack_height); | |
| 1493 for (var i in symbols) { | |
| 1494 //exclude inherited properties and undefined properties | |
| 1495 if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue; | |
| 1496 | |
| 1497 var sym = symbols[i]; | |
| 1498 var sym_height = metrics.stack_height * sym.get_scale(); | |
| 1499 | |
| 1500 var pad = preferred_pad; | |
| 1501 if (sym_height - pad < sym_min) { | |
| 1502 pad = Math.min(pad, Math.max(0, sym_height - sym_min)); | |
| 1503 } | |
| 1504 sym_height -= pad; | |
| 1505 | |
| 1506 //translate to the correct position | |
| 1507 ctx.translate(0, -(pad/2 + sym_height)); | |
| 1508 //draw | |
| 1509 raster.draw(ctx, sym.get_symbol(), 0, 0, metrics.stack_width, sym_height); | |
| 1510 //translate past the padding | |
| 1511 ctx.translate(0, -(pad/2)); | |
| 1512 } | |
| 1513 ctx.restore();//1 | |
| 1514 } | |
| 1515 | |
| 1516 //draws a stack of symbols | |
| 1517 function draw_stack_old(ctx, metrics, symbols) { | |
| 1518 var lpad = 2; | |
| 1519 var sym_min = 5; | |
| 1520 var pos = metrics.stack_height; | |
| 1521 for (var i in symbols) { | |
| 1522 //exclude inherited properties and undefined properties | |
| 1523 if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue; | |
| 1524 | |
| 1525 var sym = symbols[i]; | |
| 1526 var sym_height = metrics.stack_height*sym.get_scale(); | |
| 1527 var letter = metrics.get_letter_metrics(sym.get_symbol()); | |
| 1528 //attempting to draw something smaller than a pixel causes display corruption | |
| 1529 if (sym_height >= 1) { | |
| 1530 //it's better to see the letter than to pad it | |
| 1531 var pad = lpad; | |
| 1532 if (sym_height - pad < sym_min) { | |
| 1533 pad = Math.min(pad, Math.max(0, sym_height - sym_min)); | |
| 1534 } | |
| 1535 //move to the correct drawing position | |
| 1536 ctx.save();//s1 | |
| 1537 ctx.translate(0, pos); | |
| 1538 //create a clipping rectangle to ensure the letter doesn't overlap when it's distorted | |
| 1539 ctx.save();//s2 | |
| 1540 //ctx.beginPath(); //disabled clipping because after the improvements in the text metrics it looks better without | |
| 1541 //ctx.moveTo(-metrics.stack_width/2,0); | |
| 1542 //ctx.lineTo(metrics.stack_width/2, 0); | |
| 1543 //ctx.lineTo(metrics.stack_width/2, -sym_height); | |
| 1544 //ctx.lineTo(-metrics.stack_width/2, -sym_height); | |
| 1545 //ctx.lineTo(-metrics.stack_width/2,0); | |
| 1546 //ctx.clip(); | |
| 1547 //now draw | |
| 1548 ctx.translate(0, -(pad/2)); | |
| 1549 ctx.translate(0, -letter.get_descent(sym_height - pad)); | |
| 1550 ctx.fillStyle = sym.get_colour(); | |
| 1551 ctx.textAlign = "center"; | |
| 1552 ctx.save();//s3 | |
| 1553 ctx.scale(letter.wscale, letter.get_hscale(sym_height - pad)); | |
| 1554 ctx.fillText(sym.get_symbol(), 0, 0); | |
| 1555 ctx.restore();//s3 | |
| 1556 | |
| 1557 ctx.restore();//s2 | |
| 1558 ctx.restore();//s1 | |
| 1559 } | |
| 1560 | |
| 1561 pos = pos - sym_height; | |
| 1562 } | |
| 1563 } | |
| 1564 | |
| 1565 function draw_dashed_line(ctx, pattern, start, x1, y1, x2, y2) { | |
| 1566 var x, y, len, i; | |
| 1567 var dx = x2 - x1; | |
| 1568 var dy = y2 - y1; | |
| 1569 var tlen = Math.pow(dx*dx + dy*dy, 0.5); | |
| 1570 var theta = Math.atan2(dy,dx); | |
| 1571 var mulx = Math.cos(theta); | |
| 1572 var muly = Math.sin(theta); | |
| 1573 var lx = []; | |
| 1574 var ly = []; | |
| 1575 for (i = 0; i < pattern; ++i) { | |
| 1576 lx.push(pattern[i] * mulx); | |
| 1577 ly.push(pattern[i] * muly); | |
| 1578 } | |
| 1579 i = start; | |
| 1580 x = x1; | |
| 1581 y = y1; | |
| 1582 len = 0; | |
| 1583 ctx.beginPath(); | |
| 1584 while (len + pattern[i] < tlen) { | |
| 1585 ctx.moveTo(x, y); | |
| 1586 x += lx[i]; | |
| 1587 y += ly[i]; | |
| 1588 ctx.lineTo(x, y); | |
| 1589 len += pattern[i]; | |
| 1590 i = (i + 1) % pattern.length; | |
| 1591 x += lx[i]; | |
| 1592 y += ly[i]; | |
| 1593 len += pattern[i]; | |
| 1594 i = (i + 1) % pattern.length; | |
| 1595 } | |
| 1596 if (len < tlen) { | |
| 1597 ctx.moveTo(x, y); | |
| 1598 x += mulx * (tlen - len); | |
| 1599 y += muly * (tlen - len); | |
| 1600 ctx.lineTo(x, y); | |
| 1601 } | |
| 1602 ctx.stroke(); | |
| 1603 } | |
| 1604 | |
| 1605 function draw_trim_background(ctx, metrics, pspm, offset) { | |
| 1606 var lwidth = metrics.stack_width * pspm.get_left_trim(); | |
| 1607 var rwidth = metrics.stack_width * pspm.get_right_trim(); | |
| 1608 var mwidth = metrics.stack_width * pspm.get_motif_length(); | |
| 1609 var rstart = mwidth - rwidth; | |
| 1610 ctx.save();//s8 | |
| 1611 ctx.translate(offset * metrics.stack_width, 0); | |
| 1612 ctx.fillStyle = "rgb(240, 240, 240)"; | |
| 1613 if (pspm.get_left_trim() > 0) ctx.fillRect(0, 0, lwidth, metrics.stack_height); | |
| 1614 if (pspm.get_right_trim() > 0) ctx.fillRect(rstart, 0, rwidth, metrics.stack_height); | |
| 1615 ctx.fillStyle = "rgb(51, 51, 51)"; | |
| 1616 if (pspm.get_left_trim() > 0) draw_dashed_line(ctx, [3], 0, lwidth-0.5, 0, lwidth-0.5, metrics.stack_height); | |
| 1617 if (pspm.get_right_trim() > 0) draw_dashed_line(ctx, [3], 0, rstart+0.5, 0, rstart+0.5, metrics.stack_height); | |
| 1618 ctx.restore();//s8 | |
| 1619 } | |
| 1620 | |
| 1621 function draw_logo_on_canvas(logo, canvas, show_names, scale) { | |
| 1622 var draw_name = (typeof show_names == "boolean" ? show_names : (logo.get_rows() > 1)); | |
| 1623 var cwidth = canvas.width; | |
| 1624 var cheight = canvas.height; | |
| 1625 //need a minimum 46 x 120 canvas to draw the font size checks on | |
| 1626 if (canvas.width < 46) canvas.width = 46; | |
| 1627 if (canvas.height < 120) canvas.height = 120; | |
| 1628 var ctx = canvas.getContext('2d'); | |
| 1629 //assume that the user wants the canvas scaled equally so calculate what the best width for this image should be | |
| 1630 var metrics = new LogoMetrics(ctx, canvas.width, canvas.height, logo.get_columns(), logo.get_rows(), draw_name); | |
| 1631 ctx.save();//s1 | |
| 1632 if (typeof scale == "number") { | |
| 1633 //resize the canvas to fit the scaled logo | |
| 1634 cwidth = metrics.summed_width * scale; | |
| 1635 cheight = metrics.summed_height * scale; | |
| 1636 } else { | |
| 1637 if (cwidth == 0 && cheight == 0) { | |
| 1638 throw "CANVAS_MUST_HAVE_DIMENSIONS"; | |
| 1639 } else if (cwidth == 0) { | |
| 1640 scale = cheight / metrics.summed_height; | |
| 1641 cwidth = metrics.summed_width * scale; | |
| 1642 } else if (cheight == 0) { | |
| 1643 scale = cwidth / metrics.summed_width; | |
| 1644 cheight = metrics.summed_height * scale; | |
| 1645 } else { | |
| 1646 scale = Math.min(cwidth / metrics.summed_width, cheight / metrics.summed_height); | |
| 1647 } | |
| 1648 } | |
| 1649 var raster = new RasterizedAlphabet(logo.alphabet, metrics.stack_font, metrics.stack_width * scale * 2); | |
| 1650 if (cwidth != canvas.width || cheight != canvas.height) { | |
| 1651 canvas.width = cwidth; | |
| 1652 canvas.height = cheight; | |
| 1653 //as the canvas has been resized the context is now out of date | |
| 1654 ctx = canvas.getContext('2d'); | |
| 1655 } | |
| 1656 ctx.scale(scale, scale); | |
| 1657 ctx.save();//s2 | |
| 1658 ctx.save();//s7 | |
| 1659 //create margin | |
| 1660 ctx.translate(metrics.pad_left, metrics.pad_top); | |
| 1661 for (var pspm_i = 0; pspm_i < logo.get_rows(); ++pspm_i) { | |
| 1662 var pspm = logo.get_pspm(pspm_i); | |
| 1663 var offset = logo.get_offset(pspm_i); | |
| 1664 //optionally draw name if this isn't the last row or is the only row | |
| 1665 if (draw_name && (logo.get_rows() == 1 || pspm_i != (logo.get_rows()-1))) { | |
| 1666 ctx.save();//s4 | |
| 1667 ctx.translate(metrics.summed_width/2, metrics.name_height); | |
| 1668 ctx.font = metrics.name_font; | |
| 1669 ctx.textAlign = "center"; | |
| 1670 ctx.fillText(pspm.name, 0, 0); | |
| 1671 ctx.restore();//s4 | |
| 1672 ctx.translate(0, metrics.name_height + Math.min(0, metrics.name_spacer - metrics.y_num_height/2)); | |
| 1673 } | |
| 1674 //draw scale | |
| 1675 draw_scale(ctx, metrics, logo.alphabet.get_ic()); | |
| 1676 ctx.save();//s5 | |
| 1677 //translate across past the scale | |
| 1678 ctx.translate(metrics.y_label_height + metrics.y_label_spacer + | |
| 1679 metrics.y_num_width + metrics.y_tic_width, 0); | |
| 1680 //draw the trimming background | |
| 1681 if (pspm.get_left_trim() > 0 || pspm.get_right_trim() > 0) { | |
| 1682 draw_trim_background(ctx, metrics, pspm, offset); | |
| 1683 } | |
| 1684 //draw letters | |
| 1685 ctx.translate(0, metrics.y_num_height / 2); | |
| 1686 for (var col_index = 0; col_index < logo.get_columns(); col_index++) { | |
| 1687 ctx.translate(metrics.stack_pad_left,0); | |
| 1688 if (col_index >= offset && col_index < (offset + pspm.get_motif_length())) { | |
| 1689 var motif_position = col_index - offset; | |
| 1690 draw_stack_num(ctx, metrics, motif_position); | |
| 1691 draw_stack(ctx, metrics, pspm.get_stack(motif_position, logo.alphabet), raster); | |
| 1692 } | |
| 1693 ctx.translate(metrics.stack_width, 0); | |
| 1694 } | |
| 1695 ctx.restore();//s5 | |
| 1696 ////optionally draw name if this is the last row but isn't the only row | |
| 1697 if (draw_name && (logo.get_rows() != 1 && pspm_i == (logo.get_rows()-1))) { | |
| 1698 //translate vertically past the stack and axis's | |
| 1699 ctx.translate(0, metrics.y_num_height/2 + metrics.stack_height + | |
| 1700 Math.max(metrics.y_num_height/2, metrics.x_num_above + metrics.x_num_width + metrics.name_spacer)); | |
| 1701 | |
| 1702 ctx.save();//s6 | |
| 1703 ctx.translate(metrics.summed_width/2, metrics.name_height); | |
| 1704 ctx.font = metrics.name_font; | |
| 1705 ctx.textAlign = "center"; | |
| 1706 ctx.fillText(pspm.name, 0, 0); | |
| 1707 ctx.restore();//s6 | |
| 1708 ctx.translate(0, metrics.name_height); | |
| 1709 } else { | |
| 1710 //translate vertically past the stack and axis's | |
| 1711 ctx.translate(0, metrics.y_num_height/2 + metrics.stack_height + Math.max(metrics.y_num_height/2, metrics.x_num_above + metrics.x_num_width)); | |
| 1712 } | |
| 1713 //if not the last row then add middle padding | |
| 1714 if (pspm_i != (logo.get_rows() -1)) { | |
| 1715 ctx.translate(0, metrics.pad_middle); | |
| 1716 } | |
| 1717 } | |
| 1718 ctx.restore();//s7 | |
| 1719 ctx.translate(metrics.summed_width - metrics.pad_right, metrics.summed_height - metrics.pad_bottom); | |
| 1720 ctx.font = metrics.fine_txt_font; | |
| 1721 ctx.textAlign = "right"; | |
| 1722 ctx.fillText(logo.fine_text, 0,0); | |
| 1723 ctx.restore();//s2 | |
| 1724 ctx.restore();//s1 | |
| 1725 } | |
| 1726 | |
| 1727 function create_canvas(c_width, c_height, c_id, c_title, c_display) { | |
| 1728 var canvas = document.createElement("canvas"); | |
| 1729 //check for canvas support before attempting anything | |
| 1730 if (!canvas.getContext) return null; | |
| 1731 var ctx = canvas.getContext('2d'); | |
| 1732 //check for html5 text drawing support | |
| 1733 if (!supports_text(ctx)) return null; | |
| 1734 //size the canvas | |
| 1735 canvas.width = c_width; | |
| 1736 canvas.height = c_height; | |
| 1737 canvas.id = c_id; | |
| 1738 canvas.title = c_title; | |
| 1739 canvas.style.display = c_display; | |
| 1740 return canvas; | |
| 1741 } | |
| 1742 | |
| 1743 function logo_1(alphabet, fine_text, pspm) { | |
| 1744 var logo = new Logo(alphabet, fine_text); | |
| 1745 logo.add_pspm(pspm); | |
| 1746 return logo; | |
| 1747 } | |
| 1748 | |
| 1749 function logo_2(alphabet, fine_text, target, query, query_offset) { | |
| 1750 var logo = new Logo(alphabet, fine_text); | |
| 1751 if (query_offset < 0) { | |
| 1752 logo.add_pspm(target, -query_offset); | |
| 1753 logo.add_pspm(query); | |
| 1754 } else { | |
| 1755 logo.add_pspm(target); | |
| 1756 logo.add_pspm(query, query_offset); | |
| 1757 } | |
| 1758 return logo; | |
| 1759 } | |
| 1760 | |
| 1761 /* | |
| 1762 * Specifies an alternate source for an image. | |
| 1763 * If the image with the image_id specified has | |
| 1764 * not loaded then a generated logo will be used | |
| 1765 * to replace it. | |
| 1766 * | |
| 1767 * Note that the image must either have dimensions | |
| 1768 * or a scale must be set. | |
| 1769 */ | |
| 1770 function alternate_logo(logo, image_id, scale) { | |
| 1771 var image = document.getElementById(image_id); | |
| 1772 if (!image) { | |
| 1773 alert("Can't find specified image id (" + image_id + ")"); | |
| 1774 return; | |
| 1775 } | |
| 1776 //if the image has loaded then there is no reason to use the canvas | |
| 1777 if (image_ok(image)) return; | |
| 1778 //the image has failed to load so replace it with a canvas if we can. | |
| 1779 var canvas = create_canvas(image.width, image.height, image_id, image.title, image.style.display); | |
| 1780 if (canvas == null) return; | |
| 1781 //draw the logo on the canvas | |
| 1782 draw_logo_on_canvas(logo, canvas, undefined, scale); | |
| 1783 //replace the image with the canvas | |
| 1784 image.parentNode.replaceChild(canvas, image); | |
| 1785 } | |
| 1786 | |
| 1787 /* | |
| 1788 * Specifes that the element with the specified id | |
| 1789 * should be replaced with a generated logo. | |
| 1790 */ | |
| 1791 function replace_logo(logo, replace_id, scale, title_txt, display_style) { | |
| 1792 var element = document.getElementById(replace_id); | |
| 1793 if (!replace_id) { | |
| 1794 alert("Can't find specified id (" + replace_id + ")"); | |
| 1795 return; | |
| 1796 } | |
| 1797 //found the element! | |
| 1798 var canvas = create_canvas(50, 120, replace_id, title_txt, display_style); | |
| 1799 if (canvas == null) return; | |
| 1800 //draw the logo on the canvas | |
| 1801 draw_logo_on_canvas(logo, canvas, undefined, scale); | |
| 1802 //replace the element with the canvas | |
| 1803 element.parentNode.replaceChild(canvas, element); | |
| 1804 } | |
| 1805 | |
| 1806 /* | |
| 1807 * Fast string trimming implementation found at | |
| 1808 * http://blog.stevenlevithan.com/archives/faster-trim-javascript | |
| 1809 * | |
| 1810 * Note that regex is good at removing leading space but | |
| 1811 * bad at removing trailing space as it has to first go through | |
| 1812 * the whole string. | |
| 1813 */ | |
| 1814 function trim (str) { | |
| 1815 str = str.replace(/^\s\s*/, ''); | |
| 1816 var ws = /\s/, i = str.length; | |
| 1817 while (ws.test(str.charAt(--i))); | |
| 1818 return str.slice(0, i + 1); | |
| 1819 } | |
| 1820 /* END INCLUDED FILE "motif_logo.js" */ | |
| 1821 | |
| 1822 | |
| 1823 | |
| 1824 /* START INCLUDED FILE "dreme-to-html.js" */ | |
| 1825 var expansion_lookup = []; | |
| 1826 | |
| 1827 /* | |
| 1828 * show_hidden | |
| 1829 * | |
| 1830 * Looks for specially named elements and switches to the shown view | |
| 1831 */ | |
| 1832 function show_hidden(prefix) { | |
| 1833 document.getElementById(prefix + '_activator').style.display = 'none'; | |
| 1834 document.getElementById(prefix + '_deactivator').style.display = 'block'; | |
| 1835 document.getElementById(prefix + '_data').style.display = 'block'; | |
| 1836 } | |
| 1837 /* | |
| 1838 * hide_shown | |
| 1839 * | |
| 1840 * Looks for specially named elements and switches to the hidden view | |
| 1841 */ | |
| 1842 function hide_shown(prefix) { | |
| 1843 document.getElementById(prefix + '_activator').style.display = 'block'; | |
| 1844 document.getElementById(prefix + '_deactivator').style.display = 'none'; | |
| 1845 document.getElementById(prefix + '_data').style.display = 'none'; | |
| 1846 } | |
| 1847 | |
| 1848 function click_download_tab(tab) { | |
| 1849 document.getElementById("download_tab_num").value = tab; | |
| 1850 for (var i = 1; i <= 3; i++) { | |
| 1851 document.getElementById('download_tab_'+i).className = "tab" + (i==tab ? " activeTab" : ""); | |
| 1852 document.getElementById('download_pnl_'+i).style.display = (i==tab ? "block" : "none"); | |
| 1853 } | |
| 1854 document.getElementById('download_button').style.visibility = (tab==3 ? "visible" : "hidden"); | |
| 1855 } | |
| 1856 | |
| 1857 | |
| 1858 /* | |
| 1859 * searches child nodes in depth first order and returns the | |
| 1860 * first it finds with the className specified. | |
| 1861 */ | |
| 1862 function find_child_element_by_class(node, className) { | |
| 1863 var patt = new RegExp("\\b" + className + "\\b"); | |
| 1864 | |
| 1865 if (node.nodeType == Node.ELEMENT_NODE && | |
| 1866 patt.test(node.className)) { | |
| 1867 return node; | |
| 1868 } else { | |
| 1869 var result = null; | |
| 1870 for (var i = 0; i < node.childNodes.length; i++) { | |
| 1871 result = find_child_element_by_class(node.childNodes[i], className); | |
| 1872 if (result != null) break; | |
| 1873 } | |
| 1874 return result; | |
| 1875 } | |
| 1876 } | |
| 1877 | |
| 1878 function find_parent_element_by_class(node, className) { | |
| 1879 var patt = new RegExp("\\b" + className + "\\b"); | |
| 1880 if (node.nodeType == Node.ELEMENT_NODE && | |
| 1881 patt.test(node.className)) { | |
| 1882 return node; | |
| 1883 } else if (node.parentNode != null) { | |
| 1884 return find_parent_element_by_class(node.parentNode, className); | |
| 1885 } | |
| 1886 return null; | |
| 1887 } | |
| 1888 | |
| 1889 /* | |
| 1890 * expand | |
| 1891 * | |
| 1892 * Expand the extra data section for a motif. | |
| 1893 */ | |
| 1894 function expand(num) { | |
| 1895 // get motif data | |
| 1896 var motif_info = motif_seqs[num]; | |
| 1897 var motif_id = motif_info[0]; | |
| 1898 var seq = motif_info[1]; | |
| 1899 var rcseq = motif_info[2]; | |
| 1900 var length = motif_info[3]; | |
| 1901 var nsites = motif_info[4]; | |
| 1902 var p_hits = motif_info[5]; | |
| 1903 var n_hits = motif_info[6]; | |
| 1904 var pvalue = motif_info[7]; | |
| 1905 var evalue = motif_info[8]; | |
| 1906 var uevalue = motif_info[9]; | |
| 1907 var matches = motif_info[10]; | |
| 1908 // find the location to insert the expanded motif data | |
| 1909 var table = document.getElementById('dreme_motifs'); | |
| 1910 var motif_row = document.getElementById('motif_row_' + num); | |
| 1911 var exp_row = table.insertRow(motif_row.rowIndex + 1); | |
| 1912 exp_row.id = 'exp_row_' + num; | |
| 1913 var cell = exp_row.insertCell(0); | |
| 1914 cell.colSpan = 9; | |
| 1915 // create the DOM to insert | |
| 1916 var exp = document.getElementById('expanded_motif').firstChild.cloneNode(true); | |
| 1917 // update fields | |
| 1918 set_content_to_text(find_child_element_by_class(exp, 'name'), seq); | |
| 1919 set_content_to_text(find_child_element_by_class(exp, 'num'), num); | |
| 1920 var img = find_child_element_by_class(exp, 'img_nc'); | |
| 1921 img.src = motif_id + "nc_" + seq + ".png"; | |
| 1922 var imgrc = find_child_element_by_class(exp, 'img_rc'); | |
| 1923 imgrc.src = motif_id + "rc_" + rcseq + ".png"; | |
| 1924 // fill in the details | |
| 1925 var details = find_child_element_by_class(exp, 'details'); | |
| 1926 set_content_to_text(find_child_element_by_class(details, 'positives'), p_hits); | |
| 1927 set_content_to_text(find_child_element_by_class(details, 'negatives'), n_hits); | |
| 1928 set_content_to_text(find_child_element_by_class(details, 'pvalue'), pvalue); | |
| 1929 set_content_to_text(find_child_element_by_class(details, 'evalue'), evalue); | |
| 1930 set_content_to_text(find_child_element_by_class(details, 'uevalue'), uevalue); | |
| 1931 | |
| 1932 // fill in match table | |
| 1933 var match_row = find_child_element_by_class(exp, 'match'); | |
| 1934 var tbody = match_row.parentNode; | |
| 1935 for (var i = 0; i < matches.length; i++) { | |
| 1936 var match = matches[i]; | |
| 1937 var cseq = match[0]; | |
| 1938 var cpos = match[1]; | |
| 1939 var cneg = match[2]; | |
| 1940 var cpval = match[3].toExponential(1); | |
| 1941 var ceval = match[4].toExponential(1); | |
| 1942 var row = match_row.cloneNode(true); | |
| 1943 var td_cseq = find_child_element_by_class(row, 'dnaseq'); | |
| 1944 set_content_to_text(td_cseq, cseq); | |
| 1945 colour_dna_seq(td_cseq); | |
| 1946 set_content_to_text(find_child_element_by_class(row, 'positives'), cpos); | |
| 1947 set_content_to_text(find_child_element_by_class(row, 'negatives'), cneg); | |
| 1948 set_content_to_text(find_child_element_by_class(row, 'pvalue'), cpval); | |
| 1949 set_content_to_text(find_child_element_by_class(row, 'evalue'), ceval); | |
| 1950 tbody.appendChild(row); | |
| 1951 } | |
| 1952 tbody.removeChild(match_row); | |
| 1953 // append the expanded information | |
| 1954 cell.appendChild(exp); | |
| 1955 // hide the old row | |
| 1956 motif_row.style.display = 'none'; | |
| 1957 update_headers(); | |
| 1958 } | |
| 1959 | |
| 1960 function expanded_num(elem) { | |
| 1961 var exp = find_parent_element_by_class(elem, 'expanded_motif'); | |
| 1962 var num = parseInt(nodes_text(text_nodes(find_child_element_by_class(exp, 'num')))); | |
| 1963 return num; | |
| 1964 } | |
| 1965 | |
| 1966 function contract(contained_node) { | |
| 1967 var table = document.getElementById('dreme_motifs'); | |
| 1968 var num = expanded_num(contained_node); | |
| 1969 var motif_row = document.getElementById('motif_row_' + num); | |
| 1970 var exp_row = document.getElementById('exp_row_' + num); | |
| 1971 | |
| 1972 motif_row.style.display = 'table-row'; | |
| 1973 table.deleteRow(exp_row.rowIndex); | |
| 1974 update_headers(); | |
| 1975 } | |
| 1976 | |
| 1977 function update_headers() { | |
| 1978 var motif_row_patt = new RegExp("\\bmotif_row\\b"); | |
| 1979 var motif_head_patt = new RegExp("\\bmotif_head\\b"); | |
| 1980 var table = document.getElementById('dreme_motifs'); | |
| 1981 var header = table.tHead.getElementsByTagName('tr')[0]; | |
| 1982 header.style.display = 'none'; | |
| 1983 var trs = table.tBodies[0].getElementsByTagName('tr'); | |
| 1984 var needHeader = true; | |
| 1985 for (var i = 0; i < trs.length; i++) { | |
| 1986 var row = trs[i]; | |
| 1987 if (row.style.display == 'none') continue; | |
| 1988 if (motif_row_patt.test(row.className)) { | |
| 1989 if (needHeader) { | |
| 1990 var dupHeader = header.cloneNode(true); | |
| 1991 dupHeader.style.display = 'table-row'; | |
| 1992 row.parentNode.insertBefore(dupHeader, row); | |
| 1993 needHeader = false; | |
| 1994 i++; | |
| 1995 } | |
| 1996 } else if (motif_head_patt.test(row.className)) { | |
| 1997 table.deleteRow(row.rowIndex); | |
| 1998 i--; | |
| 1999 } else { | |
| 2000 needHeader = true; | |
| 2001 } | |
| 2002 } | |
| 2003 } | |
| 2004 | |
| 2005 function set_content_to_text(ele, text) { | |
| 2006 while(ele.hasChildNodes()) { | |
| 2007 ele.removeChild(ele.firstChild); | |
| 2008 } | |
| 2009 ele.appendChild(document.createTextNode(text)); | |
| 2010 } | |
| 2011 | |
| 2012 function both_setup(pos) { | |
| 2013 // get the total number of motifs | |
| 2014 var nmotifs = parseInt(document.getElementById('nmotifs').value, 10); | |
| 2015 // set the motif that we're submitting | |
| 2016 document.getElementById('submit_motif').value = (pos == 0 ? 'all' : pos); | |
| 2017 document.getElementById('send_to_selector').style.display = (pos == 0 ? 'none' : 'block'); | |
| 2018 document.getElementById('send_to_title_1').style.display = (pos == 0 ? 'none' : 'block'); | |
| 2019 document.getElementById('send_to_title_2').style.display = (pos == 0 ? 'block' : 'none'); | |
| 2020 | |
| 2021 if (pos != 0) { | |
| 2022 // get the information for the position | |
| 2023 var motif_seq = motif_seqs[pos]; | |
| 2024 var motif_id = motif_seq[0]; | |
| 2025 var seq = motif_seq[1]; | |
| 2026 var rcseq = motif_seq[2]; | |
| 2027 // set the motif number | |
| 2028 // set the titles of both popups | |
| 2029 set_content_to_text(document.getElementById('send_to_name'), seq); | |
| 2030 set_content_to_text(document.getElementById('download_name'), seq); | |
| 2031 // set the images | |
| 2032 var nc_img = "" + motif_id + "nc_" + seq + ".png"; | |
| 2033 var rc_img = "" + motif_id + "rc_" + rcseq + ".png"; | |
| 2034 var img; | |
| 2035 img = document.getElementById('send_to_img'); | |
| 2036 img.src = nc_img; | |
| 2037 img.style.display = "inline"; | |
| 2038 img = document.getElementById('send_to_rcimg'); | |
| 2039 img.src = rc_img; | |
| 2040 img.style.display = "inline"; | |
| 2041 img = document.getElementById('download_img'); | |
| 2042 img.src = nc_img; | |
| 2043 img.style.display = "inline"; | |
| 2044 img = document.getElementById('download_rcimg'); | |
| 2045 img.src = rc_img; | |
| 2046 img.style.display = "inline"; | |
| 2047 // hide the canvas | |
| 2048 document.getElementById('send_to_can').style.display = "none"; | |
| 2049 document.getElementById('send_to_rccan').style.display = "none"; | |
| 2050 document.getElementById('download_can').style.display = "none"; | |
| 2051 document.getElementById('download_rccan').style.display = "none"; | |
| 2052 // get some motif details | |
| 2053 var pspm_text = document.getElementById("pspm"+ pos).value; | |
| 2054 var pspm = new Pspm(pspm_text); | |
| 2055 var alpha = new Alphabet(document.getElementById("alphabet").value, | |
| 2056 document.getElementById("bgfreq").value); | |
| 2057 document.getElementById('download_pspm').value = pspm.as_pspm(); | |
| 2058 document.getElementById('download_pssm').value = pspm.as_pssm(alpha); | |
| 2059 // set the width and height defaults | |
| 2060 document.getElementById('logo_width').value = pspm.get_motif_length(); | |
| 2061 document.getElementById('logo_height').value = 7.5; | |
| 2062 // hide and show the arrows | |
| 2063 var prevclass = (pos == 1 ? "navarrow inactive" : "navarrow"); | |
| 2064 var nextclass = (pos == nmotifs ? "navarrow inactive" : "navarrow"); | |
| 2065 document.getElementById('prev_arrow_1').className = prevclass; | |
| 2066 document.getElementById('prev_arrow_2').className = prevclass; | |
| 2067 document.getElementById('next_arrow_1').className = nextclass; | |
| 2068 document.getElementById('next_arrow_2').className = nextclass; | |
| 2069 set_content_to_text(document.getElementById('pop_num_1'), pos); | |
| 2070 set_content_to_text(document.getElementById('pop_num_2'), pos); | |
| 2071 } | |
| 2072 } | |
| 2073 | |
| 2074 function both_change(inc) { | |
| 2075 var motif_num = parseInt(document.getElementById('submit_motif').value, 10); | |
| 2076 var nmotifs = parseInt(document.getElementById('nmotifs').value, 10); | |
| 2077 var orig = motif_num; | |
| 2078 motif_num += inc; | |
| 2079 if (motif_num > nmotifs) motif_num = nmotifs; | |
| 2080 else if (motif_num < 1) motif_num = 1; | |
| 2081 if (orig != motif_num) both_setup(motif_num); | |
| 2082 } | |
| 2083 | |
| 2084 function both_hide() { | |
| 2085 document.getElementById('grey_out_page').style.display = 'none'; | |
| 2086 document.getElementById('download').style.display = 'none'; | |
| 2087 document.getElementById('send_to').style.display = 'none'; | |
| 2088 } | |
| 2089 | |
| 2090 /* | |
| 2091 * lookup the information on a motif and prepare the | |
| 2092 * popup for sending it to another program | |
| 2093 */ | |
| 2094 function send_to_popup(pos) { | |
| 2095 both_setup(pos); | |
| 2096 var program = find_child_element_by_class(document.getElementById('programs'), 'selected').id; | |
| 2097 var task = highlight_submit_task(null, submit_programs[program]); | |
| 2098 highlight_submit_program(program, submit_tasks[task]); | |
| 2099 update_submit_text(task, program); | |
| 2100 // show the send to page | |
| 2101 var grey_out = document.getElementById('grey_out_page'); | |
| 2102 grey_out.style.display = 'block'; | |
| 2103 var send_to_pop = document.getElementById('send_to'); | |
| 2104 send_to_pop.style.display = 'block'; | |
| 2105 } | |
| 2106 | |
| 2107 function send_to_popup2(elem) { | |
| 2108 send_to_popup(expanded_num(elem)); | |
| 2109 } | |
| 2110 | |
| 2111 function send_to_submit() { | |
| 2112 var program = find_child_element_by_class(document.getElementById('programs'), 'selected').id; | |
| 2113 // set the hidden fields on the form | |
| 2114 document.getElementById('submit_program').value = program; | |
| 2115 // send the form | |
| 2116 document.getElementById('submit_form').submit(); | |
| 2117 both_hide(); | |
| 2118 } | |
| 2119 | |
| 2120 function download_popup(pos) { | |
| 2121 both_setup(pos); | |
| 2122 click_download_tab(document.getElementById("download_tab_num").value); | |
| 2123 document.getElementById('submit_program').value = "LOGO"; | |
| 2124 // show the download page | |
| 2125 var grey_out = document.getElementById('grey_out_page'); | |
| 2126 grey_out.style.display = 'block'; | |
| 2127 var download_pop = document.getElementById('download'); | |
| 2128 download_pop.style.display = 'block'; | |
| 2129 } | |
| 2130 | |
| 2131 function download_popup2(elem) { | |
| 2132 download_popup(expanded_num(elem)); | |
| 2133 } | |
| 2134 | |
| 2135 function download_submit() { | |
| 2136 var format = document.getElementById('logo_format').value; | |
| 2137 var orient = document.getElementById('logo_rc').value; | |
| 2138 var ssc = document.getElementById('logo_ssc').value; | |
| 2139 var width = document.getElementById('logo_width').value; | |
| 2140 var height = document.getElementById('logo_height').value; | |
| 2141 document.getElementById('submit_format').value = format; | |
| 2142 document.getElementById('submit_rc').value = orient; | |
| 2143 document.getElementById('submit_ssc').value = ssc; | |
| 2144 document.getElementById('submit_width').value = width; | |
| 2145 document.getElementById('submit_height').value = height; | |
| 2146 document.getElementById('submit_form').submit(); | |
| 2147 both_hide(); | |
| 2148 } | |
| 2149 | |
| 2150 function FixLogoTask(num, rc) { | |
| 2151 this.num = num; | |
| 2152 this.rc = rc; | |
| 2153 this.run = FixLogoTask_run; | |
| 2154 } | |
| 2155 | |
| 2156 function FixLogoTask_run() { | |
| 2157 var pspm_text = document.getElementById("pspm" + this.num).value; | |
| 2158 var alpha = new Alphabet("ACGT"); | |
| 2159 var pspm = new Pspm(pspm_text); | |
| 2160 if (this.rc) pspm = pspm.reverse_complement(alpha); | |
| 2161 var imgid = "small_" + (this.rc ? "rc_" : "") + "logo_" + this.num; | |
| 2162 | |
| 2163 var image = document.getElementById(imgid); | |
| 2164 | |
| 2165 var canvas = create_canvas(pspm.get_motif_length() *15, 50, image.id, | |
| 2166 image.title, image.style.display); | |
| 2167 if (canvas == null) return; | |
| 2168 | |
| 2169 var logo = logo_1(alpha, "DREME", pspm); | |
| 2170 draw_logo_on_canvas(logo, canvas); | |
| 2171 image.parentNode.replaceChild(canvas, image); | |
| 2172 } | |
| 2173 | |
| 2174 function fix_popup_logo(image, canvasid, rc) { | |
| 2175 var motif_num = parseInt(document.getElementById('submit_motif').value, 10); | |
| 2176 var pspm_text = document.getElementById("pspm" + motif_num).value; | |
| 2177 var alpha = new Alphabet("ACGT"); | |
| 2178 var pspm = new Pspm(pspm_text); | |
| 2179 if (rc) pspm = pspm.reverse_complement(alpha); | |
| 2180 image.style.display = "none"; | |
| 2181 //check for canvas support before attempting anything | |
| 2182 var canvas = document.getElementById(canvasid); | |
| 2183 if (!canvas.getContext) return; | |
| 2184 if (!supports_text(canvas.getContext('2d'))) return; | |
| 2185 canvas.height = 90; | |
| 2186 canvas.width = 170; | |
| 2187 canvas.style.display = "inline"; | |
| 2188 var logo = logo_1(alpha, "DREME", pspm); | |
| 2189 draw_logo_on_canvas(logo, canvas, false); | |
| 2190 } | |
| 2191 | |
| 2192 function fix_expanded_logo(image, rc) { | |
| 2193 var motif_num = expanded_num(image); | |
| 2194 var pspm_text = document.getElementById("pspm" + motif_num).value; | |
| 2195 var alpha = new Alphabet("ACGT"); | |
| 2196 var pspm = new Pspm(pspm_text); | |
| 2197 if (rc) pspm = pspm.reverse_complement(alpha); | |
| 2198 //check for canvas support before attempting anything | |
| 2199 var canvas = document.createElement('canvas'); | |
| 2200 if (!canvas.getContext) return; | |
| 2201 if (!supports_text(canvas.getContext('2d'))) return; | |
| 2202 canvas.height = 150; | |
| 2203 canvas.width = 0; | |
| 2204 draw_logo_on_canvas(logo_1(alpha, "DREME", pspm), canvas, false); | |
| 2205 image.parentNode.replaceChild(canvas, image); | |
| 2206 } | |
| 2207 | |
| 2208 function text_nodes(container) { | |
| 2209 var textNodes = []; | |
| 2210 var stack = [container]; | |
| 2211 // depth first search to maintain ordering when flattened | |
| 2212 while (stack.length > 0) { | |
| 2213 var node = stack.pop(); | |
| 2214 if (node.nodeType == Node.TEXT_NODE) { | |
| 2215 textNodes.push(node); | |
| 2216 } else { | |
| 2217 for (var i = node.childNodes.length-1; i >= 0; i--) { | |
| 2218 stack.push(node.childNodes[i]); | |
| 2219 } | |
| 2220 } | |
| 2221 } | |
| 2222 return textNodes; | |
| 2223 } | |
| 2224 | |
| 2225 function node_text(node) { | |
| 2226 if (node === undefined) { | |
| 2227 return ''; | |
| 2228 } else if (node.textContent) { | |
| 2229 return node.textContent; | |
| 2230 } else if (node.innerText) { | |
| 2231 return node.innerText; | |
| 2232 } else { | |
| 2233 return ''; | |
| 2234 } | |
| 2235 } | |
| 2236 | |
| 2237 function nodes_text(nodes, separator) { | |
| 2238 if (separator === undefined) separator = ''; | |
| 2239 var text = ''; | |
| 2240 if (nodes.length > 0) { | |
| 2241 text += node_text(nodes[0]); | |
| 2242 } | |
| 2243 for (var i = 1; i < nodes.length; i++) { | |
| 2244 text += separator + node_text(nodes[i]); | |
| 2245 } | |
| 2246 return text; | |
| 2247 } | |
| 2248 | |
| 2249 function colour_dna_seq(container) { | |
| 2250 var textnodes = text_nodes(container); | |
| 2251 for (var i = 0; i < textnodes.length; i++) { | |
| 2252 var node = textnodes[i]; | |
| 2253 container.replaceChild(create_dna_seq(node_text(node)), node); | |
| 2254 } | |
| 2255 } | |
| 2256 | |
| 2257 function create_dna_seq(seq) { | |
| 2258 var out = document.createElement('span'); | |
| 2259 var last = 0; | |
| 2260 for (var i = 0; i < seq.length; i++) { | |
| 2261 var letter = seq.charAt(i); | |
| 2262 if (letter == 'A' || letter == 'C' || letter == 'G' || letter == 'T') { | |
| 2263 if (last < i) { | |
| 2264 out.appendChild(document.createTextNode(seq.substring(last, i))); | |
| 2265 } | |
| 2266 var coloured_letter = document.createElement('span'); | |
| 2267 coloured_letter.className = "dna_" + letter; | |
| 2268 coloured_letter.appendChild(document.createTextNode(letter)); | |
| 2269 out.appendChild(coloured_letter); | |
| 2270 last = i + 1; | |
| 2271 } | |
| 2272 } | |
| 2273 if (last < seq.length) { | |
| 2274 out.appendChild(document.createTextNode(seq.substring(last))); | |
| 2275 } | |
| 2276 return out; | |
| 2277 } | |
| 2278 | |
| 2279 function sort_table(colEle, compare_function) { | |
| 2280 //find the parent of colEle that is either a td or th | |
| 2281 var cell = colEle; | |
| 2282 while (true) { | |
| 2283 if (cell == null) return; | |
| 2284 if (cell.nodeType == Node.ELEMENT_NODE && | |
| 2285 (cell.tagName.toLowerCase() == "td" || cell.tagName.toLowerCase() == "th")) { | |
| 2286 break; | |
| 2287 } | |
| 2288 cell = cell.parentNode; | |
| 2289 } | |
| 2290 //find the parent of cell that is a tr | |
| 2291 var row = cell; | |
| 2292 while (true) { | |
| 2293 if (row == null) return; | |
| 2294 if (row.nodeType == Node.ELEMENT_NODE && row.tagName.toLowerCase() == "tr") { | |
| 2295 break; | |
| 2296 } | |
| 2297 row = row.parentNode; | |
| 2298 } | |
| 2299 //find the parent of row that is a table | |
| 2300 var table = row; | |
| 2301 while (true) { | |
| 2302 if (table == null) return; | |
| 2303 if (table.nodeType == Node.ELEMENT_NODE && table.tagName.toLowerCase() == "table") { | |
| 2304 break; | |
| 2305 } | |
| 2306 table = table.parentNode; | |
| 2307 } | |
| 2308 var column_index = cell.cellIndex; | |
| 2309 // do a bubble sort, because the tables are so small it doesn't matter | |
| 2310 var change; | |
| 2311 var trs = table.tBodies[0].getElementsByTagName('tr'); | |
| 2312 var already_sorted = true; | |
| 2313 var reverse = false; | |
| 2314 while (true) { | |
| 2315 do { | |
| 2316 change = false; | |
| 2317 for (var i = 0; i < trs.length -1; i++) { | |
| 2318 var v1 = nodes_text(text_nodes(trs[i].cells[column_index])); | |
| 2319 var v2 = nodes_text(text_nodes(trs[i+1].cells[column_index])); | |
| 2320 if (reverse) { | |
| 2321 var tmp = v1; | |
| 2322 v1 = v2; | |
| 2323 v2 = tmp; | |
| 2324 } | |
| 2325 if (compare_function(v1, v2) > 0) { | |
| 2326 exchange(trs[i], trs[i+1], table); | |
| 2327 change = true; | |
| 2328 already_sorted = false; | |
| 2329 trs = table.tBodies[0].getElementsByTagName('tr'); | |
| 2330 } | |
| 2331 } | |
| 2332 } while (change); | |
| 2333 if (reverse) break;// we've sorted twice so exit | |
| 2334 if (!already_sorted) break;// sort did something so exit | |
| 2335 // when it's sorted one way already then sort the opposite way | |
| 2336 reverse = true; | |
| 2337 } | |
| 2338 update_sort_arrows(row, column_index, reverse); | |
| 2339 } | |
| 2340 | |
| 2341 function update_sort_arrows(row, column_index, reverse) { | |
| 2342 var ascending = "\u25BC"; | |
| 2343 var descending = "\u25B2"; | |
| 2344 var dir = (reverse ? descending : ascending); | |
| 2345 for (var i = 0; i < row.cells.length; i++) { | |
| 2346 var arrow = find_child_element_by_class(row.cells[i], "sort_dir"); | |
| 2347 if (arrow == null) continue; | |
| 2348 if (i == column_index) { | |
| 2349 set_content_to_text(arrow, dir); | |
| 2350 } else { | |
| 2351 set_content_to_text(arrow, ""); | |
| 2352 } | |
| 2353 } | |
| 2354 } | |
| 2355 | |
| 2356 function exchange(oRowI, oRowJ, oTable) { | |
| 2357 var i = oRowI.rowIndex; | |
| 2358 var j = oRowJ.rowIndex; | |
| 2359 if (i == j+1) { | |
| 2360 oTable.tBodies[0].insertBefore(oRowI, oRowJ); | |
| 2361 } if (j == i+1) { | |
| 2362 oTable.tBodies[0].insertBefore(oRowJ, oRowI); | |
| 2363 } else { | |
| 2364 var tmpNode = oTable.tBodies[0].replaceChild(oRowI, oRowJ); | |
| 2365 if(typeof(oRowI) != "undefined") { | |
| 2366 oTable.tBodies[0].insertBefore(tmpNode, oRowI); | |
| 2367 } else { | |
| 2368 oTable.appendChild(tmpNode); | |
| 2369 } | |
| 2370 } | |
| 2371 } | |
| 2372 | |
| 2373 function compare_numbers(v1, v2) { | |
| 2374 var f1 = parseFloat(v1); | |
| 2375 var f2 = parseFloat(v2); | |
| 2376 if (f1 < f2) { | |
| 2377 return -1; | |
| 2378 } else if (f1 > f2) { | |
| 2379 return 1; | |
| 2380 } else { | |
| 2381 return 0; | |
| 2382 } | |
| 2383 } | |
| 2384 | |
| 2385 function compare_counts(v1, v2) { | |
| 2386 var re = /(\d+)\/\d+/; | |
| 2387 var m1 = re.exec(v1); | |
| 2388 var m2 = re.exec(v2); | |
| 2389 if (m1 == null && m2 == null) return 0; | |
| 2390 if (m1 == null) return -1; | |
| 2391 if (m2 == null) return 1; | |
| 2392 return compare_numbers(m1[1], m2[1]); | |
| 2393 } | |
| 2394 | |
| 2395 function compare_strings(v1, v2) { | |
| 2396 return v1.localeCompare(v2); | |
| 2397 } | |
| 2398 /* | |
| 2399 * help | |
| 2400 * | |
| 2401 * Moves around help pop-ups so they appear | |
| 2402 * below an activator. | |
| 2403 */ | |
| 2404 function help(activator, popup_id) { | |
| 2405 if (help.popup === undefined) { | |
| 2406 help.popup = null; | |
| 2407 } | |
| 2408 if (help.activator === undefined) { | |
| 2409 help.activator = null; | |
| 2410 } | |
| 2411 | |
| 2412 if (typeof(activator) == 'undefined') { // no activator so hide | |
| 2413 help.popup.style.display = 'none'; | |
| 2414 help.popup = null; | |
| 2415 return; | |
| 2416 } | |
| 2417 var pop = document.getElementById(popup_id); | |
| 2418 if (pop == help.popup) { | |
| 2419 if (activator == help.activator) { | |
| 2420 //hide popup (as we've already shown it for the current help button) | |
| 2421 help.popup.style.display = 'none'; | |
| 2422 help.popup = null; | |
| 2423 return; // toggling complete! | |
| 2424 } | |
| 2425 } else if (help.popup != null) { | |
| 2426 //activating different popup so hide current one | |
| 2427 help.popup.style.display = 'none'; | |
| 2428 } | |
| 2429 help.popup = pop; | |
| 2430 help.activator = activator; | |
| 2431 | |
| 2432 //must make the popup visible to measure it or it has zero width | |
| 2433 pop.style.display = 'block'; | |
| 2434 var xy = get_elem_xy(activator); | |
| 2435 var padding = 10; | |
| 2436 var edge_padding = 15; | |
| 2437 var scroll_padding = 15; | |
| 2438 | |
| 2439 var pop_left = (xy[0] + (activator.offsetWidth / 2) - (pop.offsetWidth / 2)); | |
| 2440 var pop_top = (xy[1] + activator.offsetHeight + padding); | |
| 2441 | |
| 2442 // ensure the box is not past the top or left of the page | |
| 2443 if (pop_left < 0) pop_left = edge_padding; | |
| 2444 if (pop_top < 0) pop_top = edge_padding; | |
| 2445 // ensure the box does not cause horizontal scroll bars | |
| 2446 var page_width = null; | |
| 2447 if (window.innerWidth) { | |
| 2448 page_width = window.innerWidth; | |
| 2449 } else if (document.body) { | |
| 2450 page_width = document.body.clientWidth; | |
| 2451 } | |
| 2452 if (page_width) { | |
| 2453 if (pop_left + pop.offsetWidth > page_width) { | |
| 2454 pop_left = page_width - pop.offsetWidth - edge_padding - scroll_padding; //account for scrollbars | |
| 2455 } | |
| 2456 } | |
| 2457 | |
| 2458 pop.style.left = pop_left + "px"; | |
| 2459 pop.style.top = pop_top + "px"; | |
| 2460 } | |
| 2461 | |
| 2462 var submit_tasks = []; | |
| 2463 submit_tasks['search_motifs'] = ['TOMTOM']; | |
| 2464 submit_tasks['search_sequences'] = ['FIMO']; | |
| 2465 submit_tasks['rank_sequences'] = ['MAST']; | |
| 2466 submit_tasks['predict_go'] = ['GOMO']; | |
| 2467 submit_tasks['infer_tf'] = ['SPAMO']; | |
| 2468 var submit_programs = []; | |
| 2469 submit_programs['TOMTOM'] = ['search_motifs']; | |
| 2470 submit_programs['FIMO'] = ['search_sequences']; | |
| 2471 submit_programs['MAST'] = ['rank_sequences']; | |
| 2472 submit_programs['GOMO'] = ['predict_go']; | |
| 2473 submit_programs['SPAMO'] = ['infer_tf']; | |
| 2474 var submit_descriptions = []; | |
| 2475 submit_descriptions['TOMTOM'] = "Find similar motifs in published " + | |
| 2476 "libraries or a library you supply."; | |
| 2477 submit_descriptions['FIMO'] = "Find motif occurences in sequence data."; | |
| 2478 submit_descriptions['MAST'] = "Rank sequences by affinity to groups " + | |
| 2479 "of motifs."; | |
| 2480 submit_descriptions['GOMO'] = "Identify possible roles (Gene Ontology " + | |
| 2481 "terms) for motifs."; | |
| 2482 submit_descriptions['SPAMO'] = "Find other motifs that are enriched at " + | |
| 2483 "specific close spacings which might imply the existance of a complex."; | |
| 2484 | |
| 2485 | |
| 2486 function click_submit_task(ele) { | |
| 2487 var task = ele.id; | |
| 2488 var program = highlight_submit_program(null, submit_tasks[task]); | |
| 2489 highlight_submit_task(task, submit_programs[program]); | |
| 2490 update_submit_text(task, program); | |
| 2491 } | |
| 2492 | |
| 2493 function click_submit_program(ele) { | |
| 2494 var program = ele.id; | |
| 2495 var task = highlight_submit_task(null, submit_programs[program]); | |
| 2496 highlight_submit_program(program, submit_tasks[task]); | |
| 2497 update_submit_text(task, program); | |
| 2498 } | |
| 2499 | |
| 2500 function update_submit_text(task, program) { | |
| 2501 var task_ele = document.getElementById(task); | |
| 2502 var program_ele = document.getElementById(program); | |
| 2503 set_content_to_text(document.getElementById('program_action'), | |
| 2504 nodes_text(text_nodes(task_ele))); | |
| 2505 set_content_to_text(document.getElementById('program_name'), | |
| 2506 nodes_text(text_nodes(program_ele))); | |
| 2507 set_content_to_text(document.getElementById('program_desc'), | |
| 2508 submit_descriptions[program]); | |
| 2509 } | |
| 2510 | |
| 2511 function highlight_submit_task(select, highlights) { | |
| 2512 var tasks_ul = document.getElementById('tasks'); | |
| 2513 var all_tasks = tasks_ul.getElementsByTagName('li'); | |
| 2514 var li; | |
| 2515 var originally_selected = null; | |
| 2516 // deselect everything in the tasks list | |
| 2517 for (var i = 0; i < all_tasks.length; i++) { | |
| 2518 li = all_tasks[i]; | |
| 2519 if (li.className == "selected") { | |
| 2520 originally_selected = li; | |
| 2521 } | |
| 2522 li.className = ""; | |
| 2523 } | |
| 2524 // highlight everything in the highlights list | |
| 2525 for (var i = 0; i < highlights.length; i++) { | |
| 2526 var li = document.getElementById(highlights[i]); | |
| 2527 li.className = "active"; | |
| 2528 } | |
| 2529 // check if we're setting the selected item specifically | |
| 2530 if (select != null) { | |
| 2531 li = document.getElementById(select); | |
| 2532 li.className = "selected"; | |
| 2533 return select; | |
| 2534 } else { | |
| 2535 // if the originally selected item is allowed then keep it | |
| 2536 // otherwise move to the first element of the highlight list | |
| 2537 if (originally_selected != null && | |
| 2538 originally_selected.className == "active") { | |
| 2539 originally_selected.className = "selected"; | |
| 2540 return originally_selected.id; | |
| 2541 } else if (highlights.length > 0) { | |
| 2542 li = document.getElementById(highlights[0]); | |
| 2543 li.className = "selected"; | |
| 2544 return highlights[0]; | |
| 2545 } | |
| 2546 return null; | |
| 2547 } | |
| 2548 } | |
| 2549 | |
| 2550 | |
| 2551 function highlight_submit_program(select, highlights) { | |
| 2552 var programs_ul = document.getElementById('programs'); | |
| 2553 var all_programs = programs_ul.getElementsByTagName('li'); | |
| 2554 var li; | |
| 2555 var originally_selected = null; | |
| 2556 // deselect everything in the programs list | |
| 2557 for (var i = 0; i < all_programs.length; i++) { | |
| 2558 li = all_programs[i]; | |
| 2559 if (li.className == "selected") { | |
| 2560 originally_selected = li; | |
| 2561 } | |
| 2562 li.className = ""; | |
| 2563 } | |
| 2564 // highlight everything in the highlights list | |
| 2565 for (var i = 0; i < highlights.length; i++) { | |
| 2566 var li = document.getElementById(highlights[i]); | |
| 2567 li.className = "active"; | |
| 2568 } | |
| 2569 // check if we're setting the selected item specifically | |
| 2570 if (select != null) { | |
| 2571 li = document.getElementById(select); | |
| 2572 li.className = "selected"; | |
| 2573 return select; | |
| 2574 } else { | |
| 2575 // if the originally selected item is allowed then keep it | |
| 2576 // otherwise move to the first element of the highlight list | |
| 2577 if (originally_selected != null && | |
| 2578 originally_selected.className == "active") { | |
| 2579 originally_selected.className = "selected"; | |
| 2580 return originally_selected.id; | |
| 2581 } else if (highlights.length > 0) { | |
| 2582 li = document.getElementById(highlights[0]); | |
| 2583 li.className = "selected"; | |
| 2584 return highlights[0]; | |
| 2585 } | |
| 2586 return null; | |
| 2587 } | |
| 2588 } | |
| 2589 /* END INCLUDED FILE "dreme-to-html.js" */ | |
| 2590 | |
| 2591 </script> | |
| 2592 </head> | |
| 2593 <body> | |
| 2594 <form id="submit_form" method="post" action="http://Sharplab-G4-1.local/meme/cgi-bin/meme_request.cgi" target="_blank"> | |
| 2595 <!--+++++++++++++++START DATA+++++++++++++++--> | |
| 2596 <input type="hidden" name="version" value="MEME version 4.7.0"> | |
| 2597 <input type="hidden" name="alphabet" id="alphabet" value="ACGT"> | |
| 2598 <input type="hidden" name="strands" value="+ -"> | |
| 2599 <input type="hidden" name="bgsrc" value="dataset"> | |
| 2600 <input type="hidden" name="bgfreq" id="bgfreq" value="A 0.243 C 0.270 G 0.243 T 0.243"> | |
| 2601 <input type="hidden" name="name" value="test"> | |
| 2602 <input type="hidden" name="nmotifs" id="nmotifs" value="0"> | |
| 2603 <!--+++++++++++++++FINISHED DATA++++++++++++--> | |
| 2604 <input type="hidden" name="program" id="submit_program" value="TOMTOM"><input type="hidden" name="motif" id="submit_motif" value="all"><input type="hidden" name="logoformat" id="submit_format" value="png"><input type="hidden" name="logorc" id="submit_rc" value="false"><input type="hidden" name="logossc" id="submit_ssc" value="false"><input type="hidden" name="logowidth" id="submit_width" value=""><input type="hidden" name="logoheight" id="submit_height" value="7.5"> | |
| 2605 </form> | |
| 2606 <div class="pop_content" id="pop_motifs_name"> | |
| 2607 <p> | |
| 2608 The name of the motif uses the IUPAC codes for nucleotides which has | |
| 2609 a different letter to represent each of the 15 possible combinations. | |
| 2610 </p> | |
| 2611 <p> | |
| 2612 The name is itself a representation of the motif though the position | |
| 2613 weight matrix is not directly equalivant as it is generated from the | |
| 2614 sites found that matched the letters given in the name. | |
| 2615 </p> | |
| 2616 <p><a href="http://meme.nbcr.net/meme/doc/alphabets.html"> | |
| 2617 Read more about the MEME suite's use of the IUPAC alphabets. | |
| 2618 </a></p> | |
| 2619 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2620 </div> | |
| 2621 <div class="pop_content" id="pop_motifs_logo"> | |
| 2622 <p>The logo of the motif.</p> | |
| 2623 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2624 </div> | |
| 2625 <div class="pop_content" id="pop_motifs_rc_logo"> | |
| 2626 <p>The logo of the reverse complement motif.</p> | |
| 2627 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2628 </div> | |
| 2629 <div class="pop_content" id="pop_motifs_evalue"> | |
| 2630 <p>The E-value is the enrichment p-value times the number of candidate | |
| 2631 motifs tested.</p> | |
| 2632 <p>The enrichment p-value is calculated using the Fisher Exact Test for | |
| 2633 enrichment of the motif in the positive sequences.</p> | |
| 2634 <p>Note that the counts used in the Fisher Exact Test are made after | |
| 2635 erasing sites that match previously found motifs.</p> | |
| 2636 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2637 </div> | |
| 2638 <div class="pop_content" id="pop_motifs_uevalue"> | |
| 2639 <p>The E-value of the motif calculated without erasing the sites of | |
| 2640 previously found motifs.</p> | |
| 2641 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2642 </div> | |
| 2643 <div class="pop_content" id="pop_more"> | |
| 2644 <p>Show more information on the motif.</p> | |
| 2645 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2646 </div> | |
| 2647 <div class="pop_content" id="pop_submit"> | |
| 2648 <p>Submit your motif to another MEME Suite program.</p> | |
| 2649 <h5>Supported Programs</h5> | |
| 2650 <dl> | |
| 2651 <dt>Tomtom</dt> | |
| 2652 <dd>Tomtom is a tool for searching for similar known motifs. | |
| 2653 [<a href="http://meme.nbcr.net/meme/tomtom-intro.html">manual</a>]</dd> | |
| 2654 <dt>MAST</dt> | |
| 2655 <dd>MAST is a tool for searching biological sequence databases for | |
| 2656 sequences that contain one or more of a group of known motifs. | |
| 2657 [<a href="http://meme.nbcr.net/meme/mast-intro.html">manual</a>]</dd> | |
| 2658 <dt>FIMO</dt> | |
| 2659 <dd>FIMO is a tool for searching biological sequence databases for | |
| 2660 sequences that contain one or more known motifs. | |
| 2661 [<a href="http://meme.nbcr.net/meme/fimo-intro.html">manual</a>]</dd> | |
| 2662 <dt>GOMO</dt> | |
| 2663 <dd>GOMO is a tool for identifying possible roles (Gene Ontology | |
| 2664 terms) for DNA binding motifs. | |
| 2665 [<a href="http://meme.nbcr.net/meme/gomo-intro.html">manual</a>]</dd> | |
| 2666 <dt>SpaMo</dt> | |
| 2667 <dd>SpaMo is a tool for inferring possible transcription factor | |
| 2668 complexes by finding motifs with enriched spacings. | |
| 2669 [<a href="http://meme.nbcr.net/meme/spamo-intro.html">manual</a>]</dd> | |
| 2670 </dl> | |
| 2671 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2672 </div> | |
| 2673 <div class="pop_content" id="pop_download"> | |
| 2674 <p>Download your motif as a position weight matrix or a custom logo.</p> | |
| 2675 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2676 </div> | |
| 2677 <div class="pop_content" id="pop_motif_positives"> | |
| 2678 <p># positive sequences matching the motif / # positive sequences.</p> | |
| 2679 <p>Note these counts are made after erasing sites that match previously | |
| 2680 found motifs.</p> | |
| 2681 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2682 </div> | |
| 2683 <div class="pop_content" id="pop_motif_negatives"> | |
| 2684 <p># negative sequences matching the motif / # negative sequences.</p> | |
| 2685 <p>Note these counts are made after erasing sites that match previously | |
| 2686 found motifs.</p> | |
| 2687 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2688 </div> | |
| 2689 <div class="pop_content" id="pop_motif_pvalue"> | |
| 2690 <p>The p-value of the Fisher Exact Test for enrichment of the motif in | |
| 2691 the positive sequences.</p> | |
| 2692 <p>Note that the counts used in the Fisher Exact Test are made after | |
| 2693 erasing sites that match previously found motifs.</p> | |
| 2694 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2695 </div> | |
| 2696 <div class="pop_content" id="pop_motif_evalue"> | |
| 2697 <p>The E-value is the motif p-value times the number of candidate motifs | |
| 2698 tested.</p> | |
| 2699 <p>Note that the p-value was calculated with counts made after | |
| 2700 erasing sites that match previously found motifs.</p> | |
| 2701 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2702 </div> | |
| 2703 <div class="pop_content" id="pop_motif_uevalue"> | |
| 2704 <p>The E-value of the motif calculated without erasing the sites of | |
| 2705 previously found motifs.</p> | |
| 2706 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2707 </div> | |
| 2708 <div class="pop_content" id="pop_match_word"> | |
| 2709 <p>All words matching the motif whose uncorrected p-value is less than | |
| 2710 0.01.</p> | |
| 2711 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2712 </div> | |
| 2713 <div class="pop_content" id="pop_match_pos"> | |
| 2714 <p># positive sequences with matches to the word / # positive sequences.</p> | |
| 2715 <p>Note these counts are made after erasing sites that match previously | |
| 2716 found motifs.</p> | |
| 2717 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2718 </div> | |
| 2719 <div class="pop_content" id="pop_match_neg"> | |
| 2720 <p># negative sequences with matches to the word / # negative sequences.</p> | |
| 2721 <p>Note these counts are made after erasing sites that match previously | |
| 2722 found motifs.</p> | |
| 2723 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2724 </div> | |
| 2725 <div class="pop_content" id="pop_match_pval"> | |
| 2726 <p>The p-value of the Fisher Exact Test for enrichment of the word in | |
| 2727 the positive sequences.</p> | |
| 2728 <p>Note that the counts used in the Fisher Exact Test are made after | |
| 2729 erasing sites that match previously found motifs.</p> | |
| 2730 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2731 </div> | |
| 2732 <div class="pop_content" id="pop_match_eval"> | |
| 2733 <p>The word p-value times the number of candidates tested.</p> | |
| 2734 <p>Note that the p-value was calculated with counts made after | |
| 2735 erasing sites that match previously found motifs.</p> | |
| 2736 <div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> | |
| 2737 </div> | |
| 2738 <div id="expanded_motif" style="display:none"><div class="box expanded_motif" style="margin-bottom:5px;"> | |
| 2739 <div> | |
| 2740 <div style="float:left"><h2 class="mainh" style="margin:0; padding:0;"> | |
| 2741 <span class="num"></span>. | |
| 2742 <span class="name"></span> | |
| 2743 </h2></div> | |
| 2744 <div style="float:right; "><div class="close" onclick="contract(this);" title="Show less information.">↥</div></div> | |
| 2745 <div style="clear:both"></div> | |
| 2746 </div> | |
| 2747 <div style="padding:0 5px;"> | |
| 2748 <div style="float:left;"> | |
| 2749 <img class="img_nc" onerror="fix_expanded_logo(this, false)"><img class="img_rc" onerror="fix_expanded_logo(this, true)"> | |
| 2750 </div> | |
| 2751 <div style="float:right; height:100px;"> | |
| 2752 <div onclick="send_to_popup2(this);" class="actionbutton" title="Submit this motif to another MEME Suite program."> | |
| 2753 <div style="float:left; margin-right:1em;">Submit</div> | |
| 2754 <div style="float:right">⇢</div> | |
| 2755 <div style="clear:both;"></div> | |
| 2756 </div> | |
| 2757 <div onclick="download_popup2(this);" class="actionbutton" title="Download this motif as a position weight matrix or a custom logo."> | |
| 2758 <div style="float:left; margin-right:1em;">Download</div> | |
| 2759 <div style="float:right">⟱</div> | |
| 2760 <div style="clear:both;"></div> | |
| 2761 </div> | |
| 2762 </div> | |
| 2763 <div style="clear:both;"></div> | |
| 2764 </div> | |
| 2765 <h4>Details</h4> | |
| 2766 <table class="details"> | |
| 2767 <thead><tr> | |
| 2768 <th>Positives <div class="help2" onclick="help(this,'pop_motif_positives')">?</div> | |
| 2769 </th> | |
| 2770 <th>Negatives <div class="help2" onclick="help(this,'pop_motif_negatives')">?</div> | |
| 2771 </th> | |
| 2772 <th>P-value <div class="help2" onclick="help(this,'pop_motif_pvalue')">?</div> | |
| 2773 </th> | |
| 2774 <th>E-value <div class="help2" onclick="help(this,'pop_motif_evalue')">?</div> | |
| 2775 </th> | |
| 2776 <th>Unerased E-value <div class="help2" onclick="help(this,'pop_motif_uevalue')">?</div> | |
| 2777 </th> | |
| 2778 </tr></thead> | |
| 2779 <tbody><tr> | |
| 2780 <td> | |
| 2781 <span class="positives"></span>/3</td> | |
| 2782 <td> | |
| 2783 <span class="negatives"></span>/3</td> | |
| 2784 <td class="pvalue"></td> | |
| 2785 <td class="evalue"></td> | |
| 2786 <td class="uevalue"></td> | |
| 2787 </tr></tbody> | |
| 2788 </table> | |
| 2789 <h4>Enriched Matching Words</h4> | |
| 2790 <table> | |
| 2791 <thead><tr> | |
| 2792 <th> | |
| 2793 <a href="javascript:;" onclick="sort_table(this, compare_strings)"><span class="sort_dir"></span>Word</a> | |
| 2794 <div class="help2" onclick="help(this,'pop_match_word')">?</div> | |
| 2795 </th> | |
| 2796 <th> | |
| 2797 <a href="javascript:;" onclick="sort_table(this, compare_counts)"><span class="sort_dir"></span>Positives</a> | |
| 2798 <div class="help2" onclick="help(this,'pop_match_pos')">?</div> | |
| 2799 </th> | |
| 2800 <th> | |
| 2801 <a href="javascript:;" onclick="sort_table(this, compare_counts)"><span class="sort_dir"></span>Negatives</a> | |
| 2802 <div class="help2" onclick="help(this,'pop_match_neg')">?</div> | |
| 2803 </th> | |
| 2804 <th> | |
| 2805 <a href="javascript:;" onclick="sort_table(this, compare_numbers)"><span class="sort_dir"></span>P-value</a> | |
| 2806 <div class="help2" onclick="help(this,'pop_match_pval')">?</div> | |
| 2807 </th> | |
| 2808 <th> | |
| 2809 <a href="javascript:;" onclick="sort_table(this, compare_numbers)"><span class="sort_dir">▼</span>E-value</a> | |
| 2810 <div class="help2" onclick="help(this,'pop_match_eval')">?</div> | |
| 2811 </th> | |
| 2812 </tr></thead> | |
| 2813 <tbody><tr class="match"> | |
| 2814 <td class="dnaseq"></td> | |
| 2815 <td> | |
| 2816 <span class="positives"></span>/3</td> | |
| 2817 <td> | |
| 2818 <span class="negatives"></span>/3</td> | |
| 2819 <td class="pvalue"></td> | |
| 2820 <td class="evalue"></td> | |
| 2821 </tr></tbody> | |
| 2822 </table> | |
| 2823 </div></div> | |
| 2824 <div id="grey_out_page" class="grey_background" style="display:none;"></div> | |
| 2825 <div class="popup_wrapper"><div id="send_to" class="popup" style="top:-150px; display:none"> | |
| 2826 <div> | |
| 2827 <div style="float:left" id="send_to_title_1"><h2 class="mainh compact">Submit "<span id="send_to_name"></span>"</h2></div> | |
| 2828 <div style="float:left" id="send_to_title_2"><h2 class="mainh compact">Submit All Motifs</h2></div> | |
| 2829 <div style="float:right; "><div class="close" onclick="both_hide();">x</div></div> | |
| 2830 <div style="clear:both"></div> | |
| 2831 </div> | |
| 2832 <div style="padding:0 5px 5px 5px;"> | |
| 2833 <div id="send_to_selector" style="height:100px;"> | |
| 2834 <img id="send_to_img" height="90" style="max-width:170px;" onerror="fix_popup_logo(this, 'send_to_can', false)"><canvas id="send_to_can" width="10" height="100" style="display:none;"></canvas><img id="send_to_rcimg" height="90" style="max-width:170px;" onerror="fix_popup_logo(this, 'send_to_rccan', true);"><canvas id="send_to_rccan" width="10" height="100" style="display:none"></canvas><div style="float:right;"> | |
| 2835 <a id="prev_arrow_2" href="javascript:both_change(-1)" class="navarrow">⇧</a><div id="pop_num_2" class="navnum"></div> | |
| 2836 <a id="next_arrow_2" href="javascript:both_change(1)" class="navarrow">⇩</a> | |
| 2837 </div> | |
| 2838 </div> | |
| 2839 <form> | |
| 2840 <div style=""> | |
| 2841 <div style="float:left;"> | |
| 2842 <h4 class="compact">Select what you want to do</h4> | |
| 2843 <div class="programs_scroll"><ul id="tasks" class="programs"> | |
| 2844 <li id="search_motifs" onclick="click_submit_task(this)" class="selected">Search Motifs</li> | |
| 2845 <li id="search_sequences" onclick="click_submit_task(this)">Search Sequences</li> | |
| 2846 <li id="rank_sequences" onclick="click_submit_task(this)">Rank Sequences</li> | |
| 2847 <li id="predict_go" onclick="click_submit_task(this)">Predict Gene Ontology terms</li> | |
| 2848 <li id="infer_tf" onclick="click_submit_task(this)">Infer TF Complexes</li> | |
| 2849 </ul></div> | |
| 2850 </div> | |
| 2851 <div style="float:right;"> | |
| 2852 <h4 class="compact">Select a program</h4> | |
| 2853 <div class="programs_scroll"><ul id="programs" class="programs"> | |
| 2854 <li id="TOMTOM" onclick="click_submit_program(this)" class="selected">Tomtom</li> | |
| 2855 <li id="FIMO" onclick="click_submit_program(this)">FIMO</li> | |
| 2856 <li id="MAST" onclick="click_submit_program(this)">MAST</li> | |
| 2857 <li id="GOMO" onclick="click_submit_program(this)">GOMO</li> | |
| 2858 <li id="SPAMO" onclick="click_submit_program(this)">SpaMo</li> | |
| 2859 </ul></div> | |
| 2860 </div> | |
| 2861 <div style="font-weight:bold; display:inline-block; text-align:center; width:60px; height:100px; line-height:100px">Or</div> | |
| 2862 <div style="clear:both;"></div> | |
| 2863 </div> | |
| 2864 <h4> | |
| 2865 <span id="program_action">Search Motifs</span> with <span id="program_name">Tomtom</span> | |
| 2866 </h4> | |
| 2867 <p><span id="program_desc">Find similar motifs in published | |
| 2868 libraries or a library you supply.</span></p> | |
| 2869 <div style="margin-top:10px; height: 2em;"> | |
| 2870 <div style="float:left;"><input type="button" value="Send" onclick="javascript:send_to_submit()"></div> | |
| 2871 <div style="float:right;"><input type="button" value="Cancel" onclick="javascript:both_hide()"></div> | |
| 2872 </div> | |
| 2873 </form> | |
| 2874 </div> | |
| 2875 </div></div> | |
| 2876 <div class="popup_wrapper"><div id="download" class="popup" style="top:-150px; display:none"> | |
| 2877 <div> | |
| 2878 <div style="float:left"><h2 class="mainh" style="margin:0; padding:0;">Download "<span id="download_name"></span>"</h2></div> | |
| 2879 <div style="float:right; "><div class="close" onclick="both_hide();">x</div></div> | |
| 2880 <div style="clear:both"></div> | |
| 2881 </div> | |
| 2882 <div style="padding:0 5px 5px 5px;"> | |
| 2883 <div style="height:100px"> | |
| 2884 <img id="download_img" height="90" style="max-width:170px;" onerror="fix_popup_logo(this, 'download_can', false)"><canvas id="download_can" width="10" height="100" style="display:none;"></canvas><img id="download_rcimg" height="90" style="max-width:170px;" onerror="fix_popup_logo(this, 'download_rccan', true)"><canvas id="download_rccan" width="10" height="100" style="display:none;"></canvas><div style="float:right;"> | |
| 2885 <a id="prev_arrow_1" href="javascript:both_change(-1)" class="navarrow">⇧</a><div id="pop_num_1" class="navnum"></div> | |
| 2886 <a id="next_arrow_1" href="javascript:both_change(1)" class="navarrow">⇩</a> | |
| 2887 </div> | |
| 2888 </div> | |
| 2889 <form> | |
| 2890 <input type="hidden" id="download_tab_num" value="1"><div style="padding:5px 0;"> | |
| 2891 <div class="tabArea top"> | |
| 2892 <a id="download_tab_1" href="javascript:click_download_tab(1)" class="tab activeTab">PSPM Format</a><a id="download_tab_2" href="javascript:click_download_tab(2)" class="tab">PSSM Format</a><a id="download_tab_3" href="javascript:click_download_tab(3)" class="tab">Logo</a> | |
| 2893 </div> | |
| 2894 <div class="tabMain"> | |
| 2895 <div id="download_pnl_1"><textarea id="download_pspm" style="width:99%" rows="10" readonly></textarea></div> | |
| 2896 <div id="download_pnl_2"><textarea id="download_pssm" style="width:99%" rows="10" readonly></textarea></div> | |
| 2897 <div id="download_pnl_3"><table> | |
| 2898 <tr> | |
| 2899 <td><label for="logo_format">Format:</label></td> | |
| 2900 <td><select id="logo_format"><option value="png">PNG (for web)</option> | |
| 2901 <option value="eps">EPS (for publication)</option></select></td> | |
| 2902 </tr> | |
| 2903 <tr> | |
| 2904 <td><label for="logo_rc">Orientation:</label></td> | |
| 2905 <td><select id="logo_rc"><option value="false">Normal</option> | |
| 2906 <option value="true">Reverse Complement</option></select></td> | |
| 2907 </tr> | |
| 2908 <tr> | |
| 2909 <td><label for="logo_ssc">Small Sample Correction:</label></td> | |
| 2910 <td><select id="logo_ssc"><option value="false">Off</option> | |
| 2911 <option value="true">On</option></select></td> | |
| 2912 </tr> | |
| 2913 <tr> | |
| 2914 <td><label for="logo_width">Width:</label></td> | |
| 2915 <td> | |
| 2916 <input type="text" id="logo_width" size="4"> cm | |
| 2917 </td> | |
| 2918 </tr> | |
| 2919 <tr> | |
| 2920 <td><label for="logo_height">Height:</label></td> | |
| 2921 <td> | |
| 2922 <input type="text" id="logo_height" size="4"> cm | |
| 2923 </td> | |
| 2924 </tr> | |
| 2925 </table></div> | |
| 2926 <div style="margin-top:10px;"> | |
| 2927 <div style="float:left;"><input type="button" id="download_button" value="Download" style="visibility:hidden;" onclick="javascript:download_submit()"></div> | |
| 2928 <div style="float:right;"><input type="button" value="Cancel" onclick="javascript:both_hide()"></div> | |
| 2929 <div style="clear:both;"></div> | |
| 2930 </div> | |
| 2931 </div> | |
| 2932 </div> | |
| 2933 </form> | |
| 2934 </div> | |
| 2935 </div></div> | |
| 2936 <a name="top"></a><div class="pad1"> | |
| 2937 <h1><img src="http://Sharplab-G4-1.local/meme/doc/images/dreme_logo.png" alt="Discriminative Regular Expression Motif Elicitation (DREME)"></h1> | |
| 2938 <p class="spaced"> | |
| 2939 For further information on how to interpret these results or to get a | |
| 2940 copy of the MEME software please access | |
| 2941 <a href="http://meme.nbcr.net/">http://meme.nbcr.net</a>. | |
| 2942 </p> | |
| 2943 <p> | |
| 2944 If you use DREME in your research please cite the following paper:<br><span class="citation"> | |
| 2945 Timothy L. Bailey, "DREME: Motif discovery in transcription factor ChIP-seq data", <i>Bioinformatics</i>, <b>27</b>(12):1653-1659, 2011. | |
| 2946 </span></p> | |
| 2947 </div> | |
| 2948 <div class="pad2"> | |
| 2949 <a class="jump" href="#description">Description</a> | <a class="jump" href="#motifs">Discovered motifs</a> | <a class="jump" href="#program">Program information</a> | |
| 2950 </div> | |
| 2951 <a name="description"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr> | |
| 2952 <td><h2 class="mainh">Description</h2></td> | |
| 2953 <td align="right" valign="bottom"> | |
| 2954 <a href="#motifs">Next</a> <a href="#top">Top</a> | |
| 2955 </td> | |
| 2956 </tr></table> | |
| 2957 <div class="box"><p>xxxx</p></div> | |
| 2958 <a name="motifs"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr> | |
| 2959 <td><h2 class="mainh">Discovered Motifs</h2></td> | |
| 2960 <td align="right" valign="bottom"> | |
| 2961 <a href="#description">Previous</a> <a href="#program">Next</a> <a href="#top">Top</a> | |
| 2962 </td> | |
| 2963 </tr></table> | |
| 2964 <div class="box"> | |
| 2965 <p><b>Click on the ↧</b> under the <b>More</b> column to show more | |
| 2966 information about the motif.<br><b>Click on the ⇢</b> under the <b>Submit</b> column to send the | |
| 2967 motif to another MEME suite program. Eg. Tomtom<br><b>Click on the ⟱</b> under the <b>Download</b> column to get | |
| 2968 the position weight matrix of a motif or to download the logo image with | |
| 2969 your chosen options. | |
| 2970 </p> | |
| 2971 <table id="dreme_motifs" class="dreme_motifs"> | |
| 2972 <thead><tr class="motif_head"> | |
| 2973 <td> </td> | |
| 2974 <th>Motif <div class="help2" onclick="help(this,'pop_motifs_name')">?</div> | |
| 2975 </th> | |
| 2976 <th>Logo <div class="help2" onclick="help(this,'pop_motifs_logo')">?</div> | |
| 2977 </th> | |
| 2978 <th>RC Logo <div class="help2" onclick="help(this,'pop_motifs_rc_logo')">?</div> | |
| 2979 </th> | |
| 2980 <th>E-value <div class="help2" onclick="help(this,'pop_motifs_evalue')">?</div> | |
| 2981 </th> | |
| 2982 <th>Unerased E-value <div class="help2" onclick="help(this,'pop_motifs_uevalue')">?</div> | |
| 2983 </th> | |
| 2984 <th>More <div class="help2" onclick="help(this,'pop_more')">?</div> | |
| 2985 </th> | |
| 2986 <th>Submit <div class="help2" onclick="help(this,'pop_submit')">?</div> | |
| 2987 </th> | |
| 2988 <th>Download <div class="help2" onclick="help(this,'pop_download')">?</div> | |
| 2989 </th> | |
| 2990 </tr></thead> | |
| 2991 <tbody></tbody> | |
| 2992 <tfoot><tr class="rule"> | |
| 2993 <td> </td> | |
| 2994 <td> </td> | |
| 2995 <td> </td> | |
| 2996 <td> </td> | |
| 2997 <td> </td> | |
| 2998 <td> </td> | |
| 2999 <td> </td> | |
| 3000 <td> </td> | |
| 3001 <td> </td> | |
| 3002 </tr></tfoot> | |
| 3003 </table> | |
| 3004 <div style="float:left"><div onclick="send_to_popup(0);" class="actionbutton" title="Submit all motifs to another program."> | |
| 3005 <div style="float:left; margin-right:1em;">Submit All</div> | |
| 3006 <div style="float:right">⇢</div> | |
| 3007 <div style="clear:both;"></div> | |
| 3008 </div></div> | |
| 3009 <div style="clear:both;"></div> | |
| 3010 </div> | |
| 3011 <a name="program"></a><div class="bar"> | |
| 3012 <div style="text-align:right;"> | |
| 3013 <a href="#motifs">Previous</a> <a href="#top">Top</a> | |
| 3014 </div> | |
| 3015 <div class="subsection"> | |
| 3016 <a name="version"></a><h5>DREME version</h5>4.7.0 (Release date: Wed Sep 28 17:30:10 EST 2011) | |
| 3017 </div> | |
| 3018 <div class="subsection"> | |
| 3019 <a name="reference"></a><h5>Reference</h5> | |
| 3020 <span class="citation"> | |
| 3021 Timothy L. Bailey, "DREME: Motif discovery in transcription factor ChIP-seq data", <i>Bioinformatics</i>, <b>27</b>(12):1653-1659, 2011. | |
| 3022 </span> | |
| 3023 </div> | |
| 3024 <div class="subsection"> | |
| 3025 <a name="command"></a><h5>Command line summary</h5> | |
| 3026 <textarea rows="1" style="width:100%;" readonly>dreme -p test.fa -desc xxxx</textarea><br>Result calculation took 0.01 seconds<br> | |
| 3027 </div> | |
| 3028 <a href="javascript:show_hidden('model')" id="model_activator">show model parameters...</a><div class="subsection" id="model_data" style="display:none;"> | |
| 3029 <h5>Model parameters</h5> | |
| 3030 <textarea style="width:100%;" rows="10" readonly> | |
| 3031 positives = name: "test", count: "3", file: "test.fa", last_mod_date: "Sat Dec 10 12:52:18 EST 2011" | |
| 3032 negatives = name: "shuffled positive sequences", count: "3", from: "shuffled" | |
| 3033 background = type: "dna", A: "0.243", C: "0.270", G: "0.243", T: "0.243", from: "dataset" | |
| 3034 stop = evalue: "0.05" | |
| 3035 ngen = 100 | |
| 3036 add_pv_thresh = 0.01 | |
| 3037 seed = 1 | |
| 3038 host = SHARPLAB.MIT.EDU | |
| 3039 when = Sun Dec 11 09:26:43 EST 2011 | |
| 3040 </textarea> | |
| 3041 </div> | |
| 3042 <a href="javascript:hide_shown('model')" style="display:none;" id="model_deactivator">hide model parameters...</a> | |
| 3043 </div> | |
| 3044 </body> | |
| 3045 </html> |
