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>