Mercurial > repos > xuebing > sharplabtool
diff tools/mytools/dreme_out/dreme.html @ 0:9071e359b9a3
Uploaded
author | xuebing |
---|---|
date | Fri, 09 Mar 2012 19:37:19 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/mytools/dreme_out/dreme.html Fri Mar 09 19:37:19 2012 -0500 @@ -0,0 +1,3045 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>DREME</title> +<style type="text/css"> + + /* START INCLUDED FILE "meme.css" */ + /* The following is the content of meme.css */ + body { background-color:white; font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif;} + + div.help { + display: inline-block; + margin: 0px; + padding: 0px; + width: 12px; + height: 13px; + cursor: pointer; + background-image: url("help.gif"); + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAANAQMAAACn5x0BAAAAAXNSR0IArs4c6QAAAAZQTFRFAAAAnp6eqp814gAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gMJBQgGYqhNZQAAACZJREFUCNdj+P+BoUGAoV+AYeYEEGoWYGgTYGgRAAm2gRGQ8f8DAOnhC2lYnqs6AAAAAElFTkSuQmCC"); + } + + div.help2 { + color: #999; + display: inline-block; + width: 12px; + height: 12px; + border: 1px solid #999; + font-size: 13px; + line-height:12px; + font-family: Helvetica, sans-serif; + font-weight: bold; + font-style: normal; + cursor: pointer; + } + div.help2:hover { + color: #000; + border-color: #000; + } + + p.spaced { line-height: 1.8em;} + + span.citation { font-family: "Book Antiqua", "Palatino Linotype", serif; color: #004a4d;} + + p.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;} + + td.jump { font-size: 13px; color: #ffffff; background-color: #00666a; + font-family: Georgia, "Times New Roman", Times, serif;} + + a.jump { margin: 15px 0 0; font-style: normal; font-variant: small-caps; + font-weight: bolder; font-family: Georgia, "Times New Roman", Times, serif;} + + h2.mainh {font-size: 1.5em; font-style: normal; margin: 15px 0 0; + font-variant: small-caps; font-family: Georgia, "Times New Roman", Times, serif;} + + h2.line {border-bottom: 1px solid #CCCCCC; font-size: 1.5em; font-style: normal; + margin: 15px 0 0; padding-bottom: 3px; font-variant: small-caps; + font-family: Georgia, "Times New Roman", Times, serif;} + + h4 {border-bottom: 1px solid #CCCCCC; font-size: 1.2em; font-style: normal; + margin: 10px 0 0; padding-bottom: 3px; font-family: Georgia, "Times New Roman", Times, serif;} + + h5 {margin: 0px} + + a.help { font-size: 9px; font-style: normal; text-transform: uppercase; + font-family: Georgia, "Times New Roman", Times, serif;} + + div.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;} + + div.pad1 { margin: 10px 5px;} + + div.pad2 { margin: 25px 5px 5px;} + h2.pad2 { padding: 25px 5px 5px;} + + div.pad3 { padding: 5px 0px 10px 30px;} + + div.box { border: 2px solid #CCCCCC; padding:10px;} + + div.bar { border-left: 7px solid #00666a; padding:5px; margin-top:25px; } + + div.subsection {margin:25px 0px;} + + img {border:0px none;} + + th.majorth {text-align:left;} + th.minorth {font-weight:normal; text-align:left; width:8em; padding: 3px 0px;} + th.actionth {font-weight:normal; text-align:left;} + + .strand_name {text-align:left;} + .strand_side {padding:0px 10px;} + .strand_start {padding:0px 10px;} + .strand_pvalue {text-align:center; padding:0px 10px;} + .strand_lflank {text-align:right; padding-right:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;} + .strand_seq {text-align:center; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace;} + .strand_rflank {text-align:left; padding-left:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;} + + .block_td {height:25px;} + .block_container {position:relative; width:99%; height:25px; padding:0px; margin:0px;} + .block_motif {position:absolute; z-index:3; height:12px; top:0px; text-align:center; vertical-align:middle; background-color:cyan;} + .block_rule {position:absolute; z-index:2; width:100%; height:1px; top:12px; left:0px; background-color:gray;} + .block_plus_sym {position:absolute; z-index:4; width:12px; height:12px; top:0px; left:0px; color:gray;} + .block_minus_sym {position:absolute; z-index:4; width:12px; height:12px; top:13px; left:0px; color:gray;} + + .tic_major {position:absolute; border-left:2px solid blue; height:0.5em; top:0em;} + .tic_minor {position:absolute; border-left:1px solid blue; height:0.2em; top:0em;} + .tic_label {position:absolute; top:0.5em; height: 1em; text-align:center; vertical-align:middle} + + .explain h5 {font-size:1em; margin-left: 1em;} + + div.doc {margin-left: 2em; margin-bottom: 3em;} + + div.tabArea { + font-size: 80%; + font-weight: bold; + } + + a.tab { + background-color: #ddddff; + border: 1px solid #000000; + padding: 2px 1em 2px 1em; + text-decoration: none; + } + div.tabArea.base a.tab { + border-top-width: 0px; + } + div.tabArea.top a.tab { + border-bottom-width: 0px; + } + + a.tab, a.tab:visited { + color: #808080; + } + + a.tab:hover { + background-color: #d0d0d0; + color: #606060; + } + a.tab.activeTab, a.tab.activeTab:hover, a.tab.activeTab:visited { + background-color: #f0f0f0; + color: #000000; + } + div.tabMain { + border: 1px solid #000000; + background-color: #ffffff; + padding: 5px; + margin-right: 5px; + } + th.trainingset { + border-bottom: thin dashed black; + font-weight:normal; + padding:0px 10px; + } + .dnaseq { + font-weight: bold; + font-size: large; + font-family: 'Courier New', Courier, monospace; + } + .dna_A { + color: rgb(204,0,0); + } + .dna_C { + color: rgb(0,0,204); + } + .dna_G { + color: rgb(255,179,0); + } + .dna_T { + color: rgb(0,128,0); + } + /* END INCLUDED FILE "meme.css" */ + + + + /* START INCLUDED FILE "dreme-to-html.css" */ + table.dreme_motifs tr th, table.dreme_motifs tr td { + padding: 0px 10px; + } + + div.popup_wrapper { + position:fixed; + z-index:2; + width:100%; + height:0; + top:50%; + left:0; + } + + div.popup { + width: 400px; + z-index:2; + margin-left: auto; + margin-right: auto; + padding: 5px; + background: #FFF; + border-style: double; + border-width: 5px; + border-color: #00666a; + position:relative; + } + + div.grey_background { + position:fixed; + z-index: 1; + background-color: #000; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: 0.5; + left: 0; + top: 0; + width: 100%; + height: 100%; + + } + td.symaction { + text-align: center; + } + *.symaction { + font-size: 20px; + } + + div.close { + cursor: pointer; + border: 1px solid black; + width:15px; + height:15px; + line-height:15px; /* this causes vertical centering */ + text-align:center; + background-color:#FFF; + color:#000; + font-size:15px; + font-family:monospace; + } + + div.close:hover { + color:#FFF; + background-color:#000; + } + + div.navnum { + width:100%; + height:20px; + line-height:20px; + text-align:center; + font-size:medium; + } + + a.navarrow { + font-size: 30px; + text-decoration:none; + } + + a.inactive { + color:#CCC; + } + + div.actionbutton { + cursor: pointer; + font-size: 18px; + line-height:20px; + padding: 5px; + margin: 10px 0; + border: 1px solid black; + } + + div.actionbutton:hover { + color:#FFF; + background-color:#000; + } + + div.pop_content { + position:absolute; + z-index:1; + width:300px; + padding: 5px; + background: #E4ECEC; + font-size: 12px; + font-family: Arial; + border-style: double; + border-width: 3px; + border-color: #AA2244; + display:none; + } + span.sort_dir { + text-decoration: none; + } + + div.section_title { + font-weight: bold; + cursor: pointer; + } + + div.section_title.inactive { + color: #000; + } + + div.section_title.inactive:hover { + color: #000; + text-decoration:underline; + } + + div.section_title label { + cursor: pointer; + } + + span.ellipsis { + display: inline-block; + border: 1px solid black; + padding: 0 2px; + margin: 0 2px; + } + + div.section_title.inactive:hover span.ellipsis { + color: #FFF; + background-color: #000; + } + + div.section_title.inactive span.toggle { + color: #000; + } + + div.section_data { + margin-left: 20px; + } + tr.rule td, tr.rule th { + border-bottom: 1px solid #CCC; + } + + h1.compact, h2.compact, h3.compact, h4.compact, h5.compact, h6.compact { + margin:0; + padding:0; + } + + ul.programs { + margin-top: 0; + padding-top: 0; + margin-bottom: 0; + padding-bottom: 0; + margin-left: 0; + padding-left: 0; + list-style: none; + border-bottom: 1px solid black; + } + + ul.programs li { + border: 1px solid black; + border-bottom-width: 0; + background-color: #EFE; + cursor: default; + } + + ul.programs li.active { + background-color: #CFC; + } + + ul.programs li.selected { + background-color: #262; + color: #FFF; + } + + div.programs_scroll { + width: 100%; + height: 90px; + overflow-y: auto; + overflow-x: hidden; + margin: 0 auto; + } + /* END INCLUDED FILE "dreme-to-html.css" */ + + </style> +<script type="text/javascript"> + var pos_count = 3; + var neg_count = 3; + var motif_seqs = []; + + + /* START INCLUDED FILE "delay_draw.js" */ + // + // Functions to measure the position of page elements relative to the size of the page + // + + // gets the offset of the top of the page due to scrolling + // from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow + function get_scroll_xy() { + var scrOfX = 0, scrOfY = 0; + if( typeof( window.pageYOffset ) == 'number' ) { + //Netscape compliant + scrOfY = window.pageYOffset; + scrOfX = window.pageXOffset; + } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) { + //DOM compliant + scrOfY = document.body.scrollTop; + scrOfX = document.body.scrollLeft; + } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) { + //IE6 standards compliant mode + scrOfY = document.documentElement.scrollTop; + scrOfX = document.documentElement.scrollLeft; + } + return [ scrOfX, scrOfY ]; + } + + // gets the width and height of the visible page + // from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow + function get_page_size() { + var myWidth = 0, myHeight = 0; + if( typeof( window.innerWidth ) == 'number' ) { + //Non-IE + myWidth = window.innerWidth; + myHeight = window.innerHeight; + } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { + //IE 6+ in 'standards compliant mode' + myWidth = document.documentElement.clientWidth; + myHeight = document.documentElement.clientHeight; + } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { + //IE 4 compatible + myWidth = document.body.clientWidth; + myHeight = document.body.clientHeight; + } + return [myWidth, myHeight]; + } + + // gets the x and y offset of an element + // from http://www.quirksmode.org/js/findpos.html + function get_elem_xy(elem) { + var myX = myY = 0; + if (elem.offsetParent) { + do { + myX += elem.offsetLeft; + myY += elem.offsetTop; + } while (elem = elem.offsetParent); + } + return [myX, myY]; + } + + // + // Functions to delay a drawing task until it is required or it would not lag the display to do so + // + + // a list of items still to be drawn + var drawable_list = []; + // the delay between drawing objects that are not currently visible + var draw_delay = 1; + // the delay after a user interaction + var user_delay = 300; + // the delay after a user has stopped scrolling and is viewing the stuff drawn on the current page + var stop_delay = 2000; + // the timer handle; allows resetting of the timer after user interactions + var draw_timer = null; + + // + // Drawable + // + // elem - a page element which defines the position on the page that drawing is to be done + // task - an object with the method run which takes care of painting the object + // + function Drawable(elem, task) { + this.elem = elem; + this.task = task; + this.is_visible = Drawable_is_visible; + } + + // + // Drawable_is_visible + // + // Determines if the drawable object is in the visible part of the page. + // + // page_top - the distance to the top of the page for the visible region + // page_height - the height of the visible region + function Drawable_is_visible(page_top, page_height) { + var elem_top = get_elem_xy(this.elem)[1]; + var elem_height = this.elem.height; + if (typeof (elem_height) != 'number') elem_height = 1; + return ((elem_top + elem_height) >= page_top && elem_top <= (page_top + page_height)); + } + + // + // draw_on_screen + // + // Checks each drawable object and draws those on screen. + // + function draw_on_screen() { + var found = false; + var page_top = get_scroll_xy()[1]; + var page_height = get_page_size()[1]; + for (var i = 0; i < drawable_list.length; i++) { + var drawable = drawable_list[i]; + if (drawable.is_visible(page_top, page_height)) { + drawable.task.run(); + drawable_list.splice(i--, 1); + found = true; + } + } + return found; + } + + // + // process_draw_tasks + // + // Called on a delay to process the next avaliable + // draw task. + // + function process_draw_tasks() { + var delay = draw_delay; + draw_timer = null; + if (drawable_list.length == 0) return; //no more tasks + if (draw_on_screen()) { + delay = stop_delay; //give the user a chance to scroll + } else { + //get next task + var drawable = drawable_list.shift(); + drawable.task.run(); + } + //allow UI updates between tasks + draw_timer = window.setTimeout("process_draw_tasks()", draw_delay); + } + + // + // delayed_process_draw_tasks + // + // Call process_draw_tasks after a short delay. + // The delay serves to group multiple redundant events. + // Should be set as event handler for onscroll and onresize. + // + function delayed_process_draw_tasks() { + //reset the timer + if (drawable_list.length > 0) { + if (draw_timer != null) clearTimeout(draw_timer); + draw_timer = window.setTimeout("process_draw_tasks()", user_delay); + } + } + + // + // add_draw_task + // + // Add a drawing task to be called immediately if it is + // visible, or to be called on a delay to reduce stuttering + // effect on the web browser. + function add_draw_task(elem, task) { + var page_top = get_scroll_xy()[1]; + var page_height = get_page_size()[1]; + drawable = new Drawable(elem, task); + if (drawable.is_visible(page_top, page_height)) { + task.run(); + } else { + drawable_list.push(drawable); + //reset timer + if (draw_timer != null) clearTimeout(draw_timer); + draw_timer = window.setTimeout("process_draw_tasks()", user_delay); + } + } + + /* END INCLUDED FILE "delay_draw.js" */ + + + + /* START INCLUDED FILE "motif_logo.js" */ + //====================================================================== + // start Alphabet object + //====================================================================== + function Alphabet(alphabet, bg) { + //variable prototype + this.freqs = new Array(); + this.alphabet = new Array(); + this.letter_count = 0; + //method prototype + this.get_ic = Alphabet_get_ic; + this.get_size = Alphabet_get_size; + this.get_index = Alphabet_get_index; + this.get_letter = Alphabet_get_letter; + this.get_colour = Alphabet_get_colour; + this.get_bg_freq = Alphabet_get_bg_freq; + this.is_nucleotide = Alphabet_is_nucleotide; + this.is_ambig = Alphabet_is_ambig; + this.toString = Alphabet_to_string; + //construct + var is_letter = /^\w$/; + var is_prob = /^((1(\.0+)?)|(0(\.\d+)?))$/; + for (var pos = 0; pos < alphabet.length; pos++) { + var letter = alphabet.charAt(pos); + if (is_letter.test(letter)) { + this.alphabet[this.letter_count] = letter.toUpperCase(); + this.freqs[this.letter_count] = -1; + this.letter_count++; + } + } + if (!(bg === undefined)) { + var parts = bg.split(/\s+/); + for (var i = 0, pos = 0; (i + 1) < parts.length; i += 2) { + var letter = parts[i]; + var freq = parts[i+1]; + if (is_letter.test(letter) && is_prob.test(freq)) { + letter = letter.toUpperCase(); //find the letter it matches + for (;pos < this.letter_count; pos++) { + if (this.alphabet[pos] == letter) break; + } + if (pos >= this.letter_count) throw "NOT_IN_ALPHABET"; + this.freqs[pos] = (+freq); + } + } + } else { + //assume uniform background + var freq = 1.0 / this.letter_count; + for (var pos = 0; pos < this.letter_count; pos++) { + this.freqs[pos] = freq; + } + } + } + + + function Alphabet_get_ic() { + if (this.is_nucleotide()) { + return 2; + } else { + return Math.log(20) / Math.LN2; + } + } + + function Alphabet_get_size() { + return this.letter_count; + } + + function Alphabet_get_letter(alph_index) { + if (alph_index < 0 || alph_index >= this.letter_count) { + throw "BAD_ALPHABET_INDEX"; + } + return this.alphabet[alph_index]; + } + + function Alphabet_get_bg_freq(alph_index) { + if (alph_index < 0 || alph_index >= this.letter_count) { + throw "BAD_ALPHABET_INDEX"; + } + if (this.freqs[alph_index] == -1) throw "BG_FREQ_NOT_SET"; + return this.freqs[alph_index]; + } + + function Alphabet_get_colour(alph_index) { + var red = "rgb(204,0,0)"; + var blue = "rgb(0,0,204)"; + var orange = "rgb(255,179,0)"; + var green = "rgb(0,128,0)"; + var yellow = "rgb(255,255,0)"; + var purple = "rgb(204,0,204)"; + var magenta = "rgb(255,0,255)"; + var pink = "rgb(255,204,204)"; + var turquoise = "rgb(51,230,204)"; + if (alph_index < 0 || alph_index >= this.letter_count) { + throw "BAD_ALPHABET_INDEX"; + } + if (this.is_nucleotide()) { + switch (this.alphabet[alph_index]) { + case "A": + return red; + case "C": + return blue; + case "G": + return orange; + case "T": + return green; + } + } else { + switch (this.alphabet[alph_index]) { + case "A": + case "C": + case "F": + case "I": + case "L": + case "V": + case "W": + case "M": + return blue; + case "N": + case "Q": + case "S": + case "T": + return green; + case "D": + case "E": + return magenta; + case "K": + case "R": + return red; + case "H": + return pink; + case "G": + return orange; + case "P": + return yellow; + case "Y": + return turquoise; + } + } + return "black"; + } + + function Alphabet_is_ambig(alph_index) { + if (alph_index < 0 || alph_index >= this.letter_count) { + throw "BAD_ALPHABET_INDEX"; + } + if (this.is_nucleotide()) { + return ("ACGT".indexOf(this.alphabet[alph_index]) == -1); + } else { + return ("ACDEFGHIKLMNPQRSTVWY".indexOf(this.alphabet[alph_index]) == -1); + } + } + + function Alphabet_get_index(letter) { + for (i = 0; i < this.letter_count; i++) { + if (this.alphabet[i] == letter.toUpperCase()) return i; + } + throw "UNKNOWN_LETTER"; + } + + function Alphabet_is_nucleotide() { + //TODO basic method, make better + if (this.letter_count < 20) return true; + return false; + } + + function Alphabet_to_string() { + return (this.is_nucleotide() ? "Nucleotide" : "Protein") + " Alphabet " + (this.alphabet.join("")); + } + + //====================================================================== + // end Alphabet object + //====================================================================== + + //====================================================================== + // start Symbol object + //====================================================================== + function Symbol(alph_index, scale, alphabet) { + //variable prototype + this.symbol = alphabet.get_letter(alph_index); + this.scale = scale; + this.colour = alphabet.get_colour(alph_index); + //function prototype + this.get_symbol = Symbol_get_symbol; + this.get_scale = Symbol_get_scale; + this.get_colour = Symbol_get_colour; + this.toString = Symbol_to_string; + } + + function Symbol_get_symbol() { + return this.symbol; + } + + function Symbol_get_scale() { + return this.scale; + } + + function Symbol_get_colour() { + return this.colour; + } + + function Symbol_to_string() { + return this.symbol + " " + (Math.round(this.scale*1000)/10) + "%"; + } + + function compare_symbol(sym1, sym2) { + if (sym1.get_scale() < sym2.get_scale()) { + return -1; + } else if (sym1.get_scale() > sym2.get_scale()) { + return 1; + } else { + return 0; + } + } + //====================================================================== + // end Symbol object + //====================================================================== + + //====================================================================== + // start Pspm object + //====================================================================== + function Pspm(pspm, name, ltrim, rtrim, nsites, evalue) { + if (ltrim === undefined) ltrim = 0; + if (rtrim === undefined) rtrim = 0; + if (nsites === undefined) nsites = 0; + if (evalue === undefined) evalue = 0; + //variable prototype + this.alph_length = 0; + this.motif_length = 0; + this.pspm = null; + this.name = (typeof name == "string" ? name : ""); + this.nsites = nsites; + this.evalue = evalue; + this.ltrim = ltrim; + this.rtrim = rtrim; + //function prototype + this.copy = Pspm_copy; + this.reverse_complement = Pspm_reverse_complement; + this.get_stack = Pspm_get_stack; + this.get_stack_ic = Pspm_get_stack_ic; + this.get_motif_length = Pspm_get_motif_length; + this.get_alph_length = Pspm_get_alph_length; + this.get_left_trim = Pspm_get_left_trim; + this.get_right_trim = Pspm_get_right_trim; + this.as_pspm = Pspm_as_pspm; + this.as_pssm = Pspm_as_pssm; + this.toString = Pspm_to_string; + //construct + if (typeof pspm == "string") { + var pspm_header = /letter-probability matrix:\s+alength=\s+(\d+)\s+w=\s+(\d+)(\s+nsites=\s+(\S+))?(\s+E=\s+(\S+))?\s*/; + var lines = pspm.split(/\n/); + var read_pspm = false; + var line_num = 0; + var col_num = 0; + this.pspm = new Array(); + for (line_index in lines) { + //exclude inherited properties and undefined properties + if (!lines.hasOwnProperty(line_index) || lines[line_index] === undefined) continue; + + var line = trim(lines[line_index]); + if (line == '') { + continue; + } + if (!read_pspm) { + var header_match = pspm_header.exec(line); + if (header_match != null) { + read_pspm = true; + this.alph_length = (+header_match[1]); + this.motif_length = (+header_match[2]); + if (header_match[4]) this.nsites = parseFloat(header_match[4]);//not always an integer + if (header_match[6]) this.evalue = parseFloat(header_match[6]); + this.pspm = new Array(this.motif_length); + } + continue; + } + if (line_num >= this.motif_length) { + throw "TOO_MANY_ROWS"; + } + this.pspm[line_num] = new Array(this.alph_length); + col_num = 0; + var parts = line.split(/\s+/); + for (part_index in parts) { + //exclude inherited properties and undefined properties + if (!parts.hasOwnProperty(part_index) || parts[part_index] === undefined) continue; + + var prob = parts[part_index]; + if (col_num >= this.alph_length) { + throw "TOO_MANY_COLS"; + } + this.pspm[line_num][col_num] = (+prob); + //check the probability is within bounds + if (this.pspm[line_num][col_num] > 1 || this.pspm[line_num][col_num] < 0) { + throw "NUM_NOT_PROB"; + } + col_num++; + } + if (col_num != this.alph_length) { + throw "TOO_FEW_COLS"; + } + line_num++; + } + if (line_num != this.motif_length) { + throw "TOO_FEW_ROWS"; + } + } else { + // assume pspm is a nested array + this.motif_length = pspm.length; + this.alpha_length = (pspm.length > 0 ? pspm[0].length : 0); + this.pspm = new Array(this.motif_length); + // copy pspm and check + for (var row = 0; row < this.motif_length; row++) { + if (this.alpha_length != pspm[row].length) throw "COLUMN_MISMATCH"; + this.pspm[row] = new Array(this.alpha_length); + var row_sum = 0; + for (var col = 0; col < this.alpha_length; col++) { + row_sum += this.pspm[row][col]; + this.pspm[row][col] = 0 + pspm[row][col]; + } + var delta = 0.1 + if ((row_sum > 1 && (row_sum - 1) > delta) || + (row_sum < 1 && (1 - row_sum) > delta)) { + throw "INVALID_SUM"; + } + } + } + } + + function Clone() {} + + function Pspm_copy() { + Clone.prototype = this; + var clone = new Clone(); + //so far only a shallow copy, need to copy everything + clone.alph_length = (0+this.alph_length); + clone.motif_length = (0+this.motif_length); + clone.name = (""+this.name); + clone.nsites = (0+this.nsites); + clone.evalue = (0+this.evalue); + clone.ltrim = (0+this.ltrim); + clone.rtrim = (0+this.rtrim); + clone.pspm = new Array(this.motif_length); + for (row = 0; row < this.motif_length; row++) { + clone.pspm[row] = new Array(this.alph_length); + for (col = 0; col < this.alph_length; col++) { + clone.pspm[row][col] = (0+this.pspm[row][col]); + } + } + return clone; + } + + function Pspm_reverse_complement(alphabet) { + if (this.alph_length != alphabet.get_size()) { + throw "ALPHABET_MISMATCH"; + } + if (!alphabet.is_nucleotide()) { + throw "NO_PROTEIN_RC"; + } + //reverse + var x = 0; + var y = this.motif_length-1; + while (x < y) { + var temp = this.pspm[x]; + this.pspm[x] = this.pspm[y]; + this.pspm[y] = temp; + x++; + y--; + } + //complement + var a_index = alphabet.get_index("A"); + var c_index = alphabet.get_index("C"); + var g_index = alphabet.get_index("G"); + var t_index = alphabet.get_index("T"); + for (i = 0; i < this.motif_length; i++) { + var row = this.pspm[i]; + //swap A and T + var temp = row[a_index]; + row[a_index] = row[t_index]; + row[t_index] = temp; + //swap C and G + temp = row[c_index]; + row[c_index] = row[g_index]; + row[g_index] = temp; + } + //swap triming + var temp_trim = this.ltrim; + this.ltrim = this.rtrim; + this.rtrim = temp_trim; + //note that ambigs are ignored because they don't effect motifs + return this; //allow function chaining... + } + + function Pspm_get_stack(position, alphabet) { + if (this.alph_length != alphabet.get_size()) { + throw "ALPHABET_MISMATCH"; + } + var row = this.pspm[position]; + var stack_ic = this.get_stack_ic(position, alphabet); + var alphabet_ic = alphabet.get_ic(); + var stack = new Array(); + for (i = 0; i < this.alph_length; i++) { + if (alphabet.is_ambig(i)) continue; + var sym = new Symbol(i, row[i]*stack_ic/alphabet_ic, alphabet); + if (sym.get_scale() <= 0) continue; + stack.push(sym); + } + stack.sort(compare_symbol); + return stack; + } + + function Pspm_get_stack_ic(position, alphabet) { + if (this.alph_length != alphabet.get_size()) { + throw "ALPHABET_MISMATCH"; + } + var row = this.pspm[position]; + var H = 0; + for (var i = 0; i < this.alph_length; i++) { + if (alphabet.is_ambig(i)) continue; + if (row[i] == 0) continue; + H -= (row[i] * (Math.log(row[i]) / Math.LN2)); + } + return alphabet.get_ic() - H; + } + + function Pspm_get_error(alphabet) { + var asize; + if (this.nsites == 0) return 0; + if (alphabet.is_nucleotide()) { + asize = 4; + } else { + asize = 20; + } + return (asize-1) / (2 * Math.log(2)*this.nsites); + } + + function Pspm_get_motif_length() { + return this.motif_length; + } + + function Pspm_get_alph_length() { + return this.alph_length; + } + + function Pspm_get_left_trim() { + return this.ltrim; + } + + function Pspm_get_right_trim() { + return this.rtrim; + } + + function Pspm_as_pspm() { + var out = "letter-probability matrix: alength= " + this.alph_length + + " w= " + this.motif_length + " nsites= " + this.nsites + + " E= " + this.evalue.toExponential() + "\n"; + for (var row = 0; row < this.motif_length; row++) { + for (var col = 0; col < this.alph_length; col++) { + if (col != 0) out += " "; + out += this.pspm[row][col].toFixed(6); + } + out += "\n"; + } + return out; + } + + function Pspm_as_pssm(alphabet, pseudo) { + if (typeof pseudo != "number") pseudo = 0.1; + var out = "log-odds matrix: alength= " + this.alph_length + + " w= " + this.motif_length + + " E= " + this.evalue.toExponential() + "\n"; + var log2 = Math.log(2); + var total = this.nsites + pseudo; + for (var row = 0; row < this.motif_length; row++) { + for (var col = 0; col < this.alph_length; col++) { + if (col != 0) out += " "; + var p = this.pspm[row][col]; + // to avoid log of zero we add a pseudo count + var bg = alphabet.get_bg_freq(col); + var p2 = (p * this.nsites + bg * pseudo) / total; + // now calculate the score + var score = -10000; + if (p2 > 0) { + score = Math.round((Math.log(p2 / bg) / log2) * 100) + } + out += score; + } + out += "\n"; + } + return out; + } + + function Pspm_to_string() { + var str = ""; + for (row_index in this.pspm) { + //exclude inherited properties and undefined properties + if (!this.pspm.hasOwnProperty(row_index) || this.pspm[row_index] === undefined) continue; + + var row = this.pspm[row_index]; + str += row.join("\t") + "\n"; + } + return str; + } + //====================================================================== + // end Pspm object + //====================================================================== + + //====================================================================== + // start Logo object + //====================================================================== + function Logo(alphabet, fine_text) { + this.alphabet = alphabet; + this.fine_text = fine_text; + this.pspm_list = []; + this.pspm_column = []; + this.rows = 0; + this.columns = 0; + + //functions + this.add_pspm = Logo_add_pspm; + this.get_columns = Logo_get_columns; + this.get_rows = Logo_get_rows; + this.get_pspm = Logo_get_pspm; + this.get_offset = Logo_get_offset; + } + + function Logo_add_pspm(pspm, column) { + if (column === undefined) column = 0; + else if (column < 0) throw "COLUMN_OUT_OF_BOUNDS"; + this.pspm_list[this.rows] = pspm; + this.pspm_column[this.rows] = column; + this.rows++; + var col = column + pspm.get_motif_length(); + if (col > this.columns) this.columns = col; + } + + function Logo_get_columns() { + return this.columns; + } + + function Logo_get_rows() { + return this.rows; + } + + function Logo_get_pspm(row_index) { + if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS"; + return this.pspm_list[row_index]; + } + + function Logo_get_offset(row_index) { + if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS"; + return this.pspm_column[row_index]; + } + + //====================================================================== + // end Logo object + //====================================================================== + + //====================================================================== + // start RasterizedAlphabet + //====================================================================== + + // Rasterize Alphabet + // 1) Measure width of text at default font for all symbols in alphabet + // 2) sort in width ascending + // 3) Drop the top and bottom 10% (designed to ignore outliers like 'W' and 'I') + // 4) Calculate the average as the maximum scaling factor (designed to stop I becoming a rectangular blob). + // 5) Assume scale of zero would result in width of zero, interpolate scale required to make perfect width font + // 6) Draw text onto temp canvas at calculated scale + // 7) Find bounds of drawn text + // 8) Paint on to another canvas at the desired height (but only scaling width to fit if larger). + function RasterizedAlphabet(alphabet, font, target_width) { + //variable prototypes + this.lookup = []; //a map of letter to index + this.rasters = []; //a list of rasters + this.dimensions = []; //a list of dimensions + + //function prototypes + this.draw = RasterizedAlphabet_draw; + + //construct + var default_size = 60; // size of square to assume as the default width + var safety_pad = 20; // pixels to pad around so we don't miss the edges + // create a canvas to do our rasterizing on + var canvas = document.createElement("canvas"); + // assume the default font would fit in a canvas of 100 by 100 + canvas.width = default_size + 2 * safety_pad; + canvas.height = default_size + 2 * safety_pad; + // check for canvas support before attempting anything + if (!canvas.getContext) throw "NO_CANVAS_SUPPORT"; + var ctx = canvas.getContext('2d'); + // check for html5 text drawing support + if (!supports_text(ctx)) throw "NO_CANVAS_TEXT_SUPPORT"; + // calculate the middle + var middle = Math.round(canvas.width / 2); + // calculate the baseline + var baseline = Math.round(canvas.height - safety_pad); + // list of widths + var widths = []; + var count = 0; + var letters = []; + //now measure each letter in the alphabet + for (var i = 0; i < alphabet.get_size(); ++i) { + if (alphabet.is_ambig(i)) continue; //skip ambigs as they're never rendered + var letter = alphabet.get_letter(i); + letters.push(letter); + var pos = count++; + this.lookup[letter] = pos; + //clear the canvas + canvas.width = canvas.width; + // get the context and prepare to draw our width test + var ctx = canvas.getContext('2d'); + ctx.font = font; + ctx.fillStyle = alphabet.get_colour(i); + ctx.textAlign = "center"; + ctx.translate(middle, baseline); + // draw the test text + ctx.fillText(letter, 0, 0); + //measure + var size = RasterizedAlphabet_measure(ctx, canvas.width, canvas.height); + if (size.width == 0) throw "INVISIBLE_LETTER"; //maybe the fill was white on white? + widths.push(size.width); + this.dimensions[pos] = size; + } + //sort the widths + widths.sort(function(a,b) {return a - b;}); + //drop 10% of the items off each end + var tenpercent = Math.floor(widths.length / 10); + for (var i = 0; i < tenpercent; ++i) { + widths.pop(); + widths.shift(); + } + //calculate average width + var avg_width = 0; + for (var i = 0; i < widths.length; ++i) avg_width += widths[i]; + avg_width /= widths.length; + // calculate scales + for (var i = 0; i < this.dimensions.length; ++i) { + var size = this.dimensions[i]; + // calculate scale + var scale = target_width / Math.max(avg_width, size.width); + // estimate scaled height + var target_height = size.height * scale; + // create an approprately sized canvas + var raster = document.createElement("canvas"); + raster.width = target_width; // if it goes over the edge too bad... + raster.height = target_height + safety_pad * 2; + // calculate the middle + middle = Math.round(raster.width / 2); + // calculate the baseline + baseline = Math.round(raster.height - safety_pad); + // get the context and prepare to draw the rasterized text + ctx = raster.getContext('2d'); + ctx.font = font; + ctx.fillStyle = alphabet.get_colour(i); + ctx.textAlign = "center"; + ctx.translate(middle, baseline); + ctx.save(); + ctx.scale(scale, scale); + // draw the rasterized text + ctx.fillText(letters[i], 0, 0); + ctx.restore(); + this.rasters[i] = raster; + this.dimensions[i] = RasterizedAlphabet_measure(ctx, raster.width, raster.height); + } + } + + function RasterizedAlphabet_measure(ctx, cwidth, cheight) { + var data = ctx.getImageData(0, 0, cwidth, cheight).data; + var r = 0, c = 0;// r: row, c: column + var top_line = -1, bottom_line = -1, left_line = -1, right_line = -1; + var txt_width = 0, txt_height = 0; + // Find the top-most line with a non-white pixel + for (r = 0; r < cheight; r++) { + for (c = 0; c < cwidth; c++) { + if (data[r * cwidth * 4 + c * 4 + 3]) { + top_line = r; + break; + } + } + if (top_line != -1) break; + } + + //find the last line with a non-white pixel + if (top_line != -1) { + for (r = cheight-1; r >= top_line; r--) { + for(c = 0; c < cwidth; c++) { + if(data[r * cwidth * 4 + c * 4 + 3]) { + bottom_line = r; + break; + } + } + if (bottom_line != -1) break; + } + txt_height = bottom_line - top_line + 1; + } + + // Find the left-most line with a non-white pixel + for (c = 0; c < cwidth; c++) { + for (r = 0; r < cheight; r++) { + if (data[r * cwidth * 4 + c * 4 + 3]) { + left_line = c; + break; + } + } + if (left_line != -1) break; + } + + //find the right most line with a non-white pixel + if (left_line != -1) { + for (c = cwidth-1; c >= left_line; c--) { + for(r = 0; r < cheight; r++) { + if(data[r * cwidth * 4 + c * 4 + 3]) { + right_line = c; + break; + } + } + if (right_line != -1) break; + } + txt_width = right_line - left_line + 1; + } + + //return the bounds + return {bound_top: top_line, bound_bottom: bottom_line, bound_left: left_line, bound_right: right_line, width: txt_width, height: txt_height}; + } + + function RasterizedAlphabet_draw(ctx, letter, dx, dy, dWidth, dHeight) { + var index = this.lookup[letter]; + var raster = this.rasters[index]; + var size = this.dimensions[index]; + ctx.drawImage(raster, 0, size.bound_top -1, raster.width, size.height+1, dx, dy, dWidth, dHeight); + } + + //====================================================================== + // end RasterizedAlphabet + //====================================================================== + + //====================================================================== + // start LogoMetrics object + //====================================================================== + + function LogoMetrics(ctx, canvas_width, canvas_height, logo_columns, logo_rows, allow_space_for_names) { + if (allow_space_for_names === undefined) allow_space_for_names = false; + //variable prototypes + this.canvas_width = canvas_width; + this.canvas_height = canvas_height; + this.scale_x = 1; + this.scale_y = 1; + this.pad_top = 5; + this.pad_left = 10; + this.pad_right = 5; + this.pad_bottom = 0; + this.pad_middle = 20; + this.name_height = 14; + this.name_font = "bold " + this.name_height + "px Times, sans-serif"; + this.name_spacer = 0; + this.y_label = "bits" + this.y_label_height = 12; + this.y_label_font = "bold " + this.y_label_height + "px Helvetica, sans-serif"; + this.y_label_spacer = 3; + this.y_num_height = 12; + this.y_num_width = 0; + this.y_num_font = "bold " + this.y_num_height + "px Helvetica, sans-serif"; + this.y_tic_width = 5; + this.stack_pad_left = 0; + this.stack_font = "bold 25px Helvetica, sans-serif"; + this.stack_height = 90; + this.stack_width = 26; + this.stacks_pad_right = 5; + this.x_num_above = 2; + this.x_num_height = 12; + this.x_num_width = 0; + this.x_num_font = "bold " + this.x_num_height + "px Helvetica, sans-serif"; + this.fine_txt_height = 6; + this.fine_txt_above = 2; + this.fine_txt_font = "normal " + this.fine_txt_height + "px Helvetica, sans-serif"; + this.letter_metrics = new Array(); + this.summed_width = 0; + this.summed_height = 0; + //function prototypes + //none + //calculate the width of the y axis numbers + ctx.font = this.y_num_font; + for (var i = 0; i <= 2; i++) { + this.y_num_width = Math.max(this.y_num_width, ctx.measureText("" + i).width); + } + //calculate the width of the x axis numbers (but they are rotated so it becomes height) + ctx.font = this.x_num_font; + for (var i = 1; i <= logo_columns; i++) { + this.x_num_width = Math.max(this.x_num_width, ctx.measureText("" + i).width); + } + + //calculate how much vertical space we want to draw this + //first we add the padding at the top and bottom since that's always there + this.summed_height += this.pad_top + this.pad_bottom; + //all except the last row have the same amount of space allocated to them + if (logo_rows > 1) { + var row_height = this.stack_height + this.pad_middle; + if (allow_space_for_names) { + row_height += this.name_height; + //the label is allowed to overlap into the spacer + row_height += Math.max(this.y_num_height/2, this.name_spacer); + //the label is allowed to overlap the space used by the other label + row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above); + } else { + row_height += this.y_num_height/2; + //the label is allowed to overlap the space used by the other label + row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above); + } + this.summed_height += row_height * (logo_rows - 1); + } + //the last row has the name and fine text below it but no padding + this.summed_height += this.stack_height + this.y_num_height/2; + if (allow_space_for_names) { + this.summed_height += this.fine_txt_height + this.fine_txt_above + this.name_height; + this.summed_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above + this.name_spacer); + } else { + 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); + } + + //calculate how much horizontal space we want to draw this + //first add the padding at the left and right since that's always there + this.summed_width += this.pad_left + this.pad_right; + //add on the space for the y-axis label + this.summed_width += this.y_label_height + this.y_label_spacer; + //add on the space for the y-axis + this.summed_width += this.y_num_width + this.y_tic_width; + //add on the space for the stacks + this.summed_width += (this.stack_pad_left + this.stack_width) * logo_columns; + //add on the padding after the stacks (an offset from the fine text) + this.summed_width += this.stacks_pad_right; + + //calculate scaling factors + this.scale_y = this.canvas_height / this.summed_height; + this.scale_x = this.canvas_width / this.summed_width; + + //maintain aspect ratio + if (this.scale_y > this.scale_x) { + this.scale_y = this.scale_x; + } else { + this.scale_x = this.scale_y; + } + + + } + + //====================================================================== + // end LogoMetrics object + //====================================================================== + + + //found this trick at http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm + function image_ok(img) { + // During the onload event, IE correctly identifies any images that + // weren't downloaded as not complete. Others should too. Gecko-based + // browsers act like NS4 in that they report this incorrectly. + if (!img.complete) { + return false; + } + // However, they do have two very useful properties: naturalWidth and + // naturalHeight. These give the true size of the image. If it failed + // to load, either of these should be zero. + if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) { + return false; + } + // No other way of checking: assume it's ok. + return true; + } + + function supports_text(ctx) { + if (!ctx.fillText) return false; + if (!ctx.measureText) return false; + return true; + } + + //draws the scale, returns the width + function draw_scale(ctx, metrics, alphabet_ic) { + var tic_height = metrics.stack_height / alphabet_ic; + ctx.save(); + ctx.lineWidth = 1.5; + ctx.translate(metrics.y_label_height, metrics.y_num_height/2); + //draw the axis label + ctx.save(); + ctx.font = metrics.y_label_font; + ctx.translate(0, metrics.stack_height/2); + ctx.save(); + ctx.rotate(-(Math.PI / 2)); + ctx.textAlign = "center"; + ctx.fillText("bits", 0, 0); + ctx.restore(); + ctx.restore(); + + ctx.translate(metrics.y_label_spacer + metrics.y_num_width, 0); + + //draw the axis tics + ctx.save(); + ctx.translate(0, metrics.stack_height); + ctx.font = metrics.y_num_font; + ctx.textAlign = "right"; + ctx.textBaseline = "middle"; + for (var i = 0; i <= alphabet_ic; i++) { + //draw the number + ctx.fillText("" + i, 0, 0); + //draw the tic + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(metrics.y_tic_width, 0); + ctx.stroke(); + //prepare for next tic + ctx.translate(0, -tic_height); + } + ctx.restore(); + + ctx.translate(metrics.y_tic_width, 0); + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, metrics.stack_height); + ctx.stroke(); + + ctx.restore(); + } + + function draw_stack_num(ctx, metrics, row_index) { + ctx.save(); + ctx.font = metrics.x_num_font; + ctx.translate(metrics.stack_width / 2, metrics.stack_height + metrics.x_num_above); + ctx.save(); + ctx.rotate(-(Math.PI / 2)); + ctx.textBaseline = "middle" + ctx.textAlign = "right" + ctx.fillText("" + (row_index + 1), 0, 0); + ctx.restore(); + ctx.restore(); + } + + function draw_stack(ctx, metrics, symbols, raster) { + var preferred_pad = 0; + var sym_min = 5; + + ctx.save();//1 + ctx.translate(0, metrics.stack_height); + for (var i in symbols) { + //exclude inherited properties and undefined properties + if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue; + + var sym = symbols[i]; + var sym_height = metrics.stack_height * sym.get_scale(); + + var pad = preferred_pad; + if (sym_height - pad < sym_min) { + pad = Math.min(pad, Math.max(0, sym_height - sym_min)); + } + sym_height -= pad; + + //translate to the correct position + ctx.translate(0, -(pad/2 + sym_height)); + //draw + raster.draw(ctx, sym.get_symbol(), 0, 0, metrics.stack_width, sym_height); + //translate past the padding + ctx.translate(0, -(pad/2)); + } + ctx.restore();//1 + } + + //draws a stack of symbols + function draw_stack_old(ctx, metrics, symbols) { + var lpad = 2; + var sym_min = 5; + var pos = metrics.stack_height; + for (var i in symbols) { + //exclude inherited properties and undefined properties + if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue; + + var sym = symbols[i]; + var sym_height = metrics.stack_height*sym.get_scale(); + var letter = metrics.get_letter_metrics(sym.get_symbol()); + //attempting to draw something smaller than a pixel causes display corruption + if (sym_height >= 1) { + //it's better to see the letter than to pad it + var pad = lpad; + if (sym_height - pad < sym_min) { + pad = Math.min(pad, Math.max(0, sym_height - sym_min)); + } + //move to the correct drawing position + ctx.save();//s1 + ctx.translate(0, pos); + //create a clipping rectangle to ensure the letter doesn't overlap when it's distorted + ctx.save();//s2 + //ctx.beginPath(); //disabled clipping because after the improvements in the text metrics it looks better without + //ctx.moveTo(-metrics.stack_width/2,0); + //ctx.lineTo(metrics.stack_width/2, 0); + //ctx.lineTo(metrics.stack_width/2, -sym_height); + //ctx.lineTo(-metrics.stack_width/2, -sym_height); + //ctx.lineTo(-metrics.stack_width/2,0); + //ctx.clip(); + //now draw + ctx.translate(0, -(pad/2)); + ctx.translate(0, -letter.get_descent(sym_height - pad)); + ctx.fillStyle = sym.get_colour(); + ctx.textAlign = "center"; + ctx.save();//s3 + ctx.scale(letter.wscale, letter.get_hscale(sym_height - pad)); + ctx.fillText(sym.get_symbol(), 0, 0); + ctx.restore();//s3 + + ctx.restore();//s2 + ctx.restore();//s1 + } + + pos = pos - sym_height; + } + } + + function draw_dashed_line(ctx, pattern, start, x1, y1, x2, y2) { + var x, y, len, i; + var dx = x2 - x1; + var dy = y2 - y1; + var tlen = Math.pow(dx*dx + dy*dy, 0.5); + var theta = Math.atan2(dy,dx); + var mulx = Math.cos(theta); + var muly = Math.sin(theta); + var lx = []; + var ly = []; + for (i = 0; i < pattern; ++i) { + lx.push(pattern[i] * mulx); + ly.push(pattern[i] * muly); + } + i = start; + x = x1; + y = y1; + len = 0; + ctx.beginPath(); + while (len + pattern[i] < tlen) { + ctx.moveTo(x, y); + x += lx[i]; + y += ly[i]; + ctx.lineTo(x, y); + len += pattern[i]; + i = (i + 1) % pattern.length; + x += lx[i]; + y += ly[i]; + len += pattern[i]; + i = (i + 1) % pattern.length; + } + if (len < tlen) { + ctx.moveTo(x, y); + x += mulx * (tlen - len); + y += muly * (tlen - len); + ctx.lineTo(x, y); + } + ctx.stroke(); + } + + function draw_trim_background(ctx, metrics, pspm, offset) { + var lwidth = metrics.stack_width * pspm.get_left_trim(); + var rwidth = metrics.stack_width * pspm.get_right_trim(); + var mwidth = metrics.stack_width * pspm.get_motif_length(); + var rstart = mwidth - rwidth; + ctx.save();//s8 + ctx.translate(offset * metrics.stack_width, 0); + ctx.fillStyle = "rgb(240, 240, 240)"; + if (pspm.get_left_trim() > 0) ctx.fillRect(0, 0, lwidth, metrics.stack_height); + if (pspm.get_right_trim() > 0) ctx.fillRect(rstart, 0, rwidth, metrics.stack_height); + ctx.fillStyle = "rgb(51, 51, 51)"; + if (pspm.get_left_trim() > 0) draw_dashed_line(ctx, [3], 0, lwidth-0.5, 0, lwidth-0.5, metrics.stack_height); + if (pspm.get_right_trim() > 0) draw_dashed_line(ctx, [3], 0, rstart+0.5, 0, rstart+0.5, metrics.stack_height); + ctx.restore();//s8 + } + + function draw_logo_on_canvas(logo, canvas, show_names, scale) { + var draw_name = (typeof show_names == "boolean" ? show_names : (logo.get_rows() > 1)); + var cwidth = canvas.width; + var cheight = canvas.height; + //need a minimum 46 x 120 canvas to draw the font size checks on + if (canvas.width < 46) canvas.width = 46; + if (canvas.height < 120) canvas.height = 120; + var ctx = canvas.getContext('2d'); + //assume that the user wants the canvas scaled equally so calculate what the best width for this image should be + var metrics = new LogoMetrics(ctx, canvas.width, canvas.height, logo.get_columns(), logo.get_rows(), draw_name); + ctx.save();//s1 + if (typeof scale == "number") { + //resize the canvas to fit the scaled logo + cwidth = metrics.summed_width * scale; + cheight = metrics.summed_height * scale; + } else { + if (cwidth == 0 && cheight == 0) { + throw "CANVAS_MUST_HAVE_DIMENSIONS"; + } else if (cwidth == 0) { + scale = cheight / metrics.summed_height; + cwidth = metrics.summed_width * scale; + } else if (cheight == 0) { + scale = cwidth / metrics.summed_width; + cheight = metrics.summed_height * scale; + } else { + scale = Math.min(cwidth / metrics.summed_width, cheight / metrics.summed_height); + } + } + var raster = new RasterizedAlphabet(logo.alphabet, metrics.stack_font, metrics.stack_width * scale * 2); + if (cwidth != canvas.width || cheight != canvas.height) { + canvas.width = cwidth; + canvas.height = cheight; + //as the canvas has been resized the context is now out of date + ctx = canvas.getContext('2d'); + } + ctx.scale(scale, scale); + ctx.save();//s2 + ctx.save();//s7 + //create margin + ctx.translate(metrics.pad_left, metrics.pad_top); + for (var pspm_i = 0; pspm_i < logo.get_rows(); ++pspm_i) { + var pspm = logo.get_pspm(pspm_i); + var offset = logo.get_offset(pspm_i); + //optionally draw name if this isn't the last row or is the only row + if (draw_name && (logo.get_rows() == 1 || pspm_i != (logo.get_rows()-1))) { + ctx.save();//s4 + ctx.translate(metrics.summed_width/2, metrics.name_height); + ctx.font = metrics.name_font; + ctx.textAlign = "center"; + ctx.fillText(pspm.name, 0, 0); + ctx.restore();//s4 + ctx.translate(0, metrics.name_height + Math.min(0, metrics.name_spacer - metrics.y_num_height/2)); + } + //draw scale + draw_scale(ctx, metrics, logo.alphabet.get_ic()); + ctx.save();//s5 + //translate across past the scale + ctx.translate(metrics.y_label_height + metrics.y_label_spacer + + metrics.y_num_width + metrics.y_tic_width, 0); + //draw the trimming background + if (pspm.get_left_trim() > 0 || pspm.get_right_trim() > 0) { + draw_trim_background(ctx, metrics, pspm, offset); + } + //draw letters + ctx.translate(0, metrics.y_num_height / 2); + for (var col_index = 0; col_index < logo.get_columns(); col_index++) { + ctx.translate(metrics.stack_pad_left,0); + if (col_index >= offset && col_index < (offset + pspm.get_motif_length())) { + var motif_position = col_index - offset; + draw_stack_num(ctx, metrics, motif_position); + draw_stack(ctx, metrics, pspm.get_stack(motif_position, logo.alphabet), raster); + } + ctx.translate(metrics.stack_width, 0); + } + ctx.restore();//s5 + ////optionally draw name if this is the last row but isn't the only row + if (draw_name && (logo.get_rows() != 1 && pspm_i == (logo.get_rows()-1))) { + //translate vertically past the stack and axis's + 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 + metrics.name_spacer)); + + ctx.save();//s6 + ctx.translate(metrics.summed_width/2, metrics.name_height); + ctx.font = metrics.name_font; + ctx.textAlign = "center"; + ctx.fillText(pspm.name, 0, 0); + ctx.restore();//s6 + ctx.translate(0, metrics.name_height); + } else { + //translate vertically past the stack and axis's + 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)); + } + //if not the last row then add middle padding + if (pspm_i != (logo.get_rows() -1)) { + ctx.translate(0, metrics.pad_middle); + } + } + ctx.restore();//s7 + ctx.translate(metrics.summed_width - metrics.pad_right, metrics.summed_height - metrics.pad_bottom); + ctx.font = metrics.fine_txt_font; + ctx.textAlign = "right"; + ctx.fillText(logo.fine_text, 0,0); + ctx.restore();//s2 + ctx.restore();//s1 + } + + function create_canvas(c_width, c_height, c_id, c_title, c_display) { + var canvas = document.createElement("canvas"); + //check for canvas support before attempting anything + if (!canvas.getContext) return null; + var ctx = canvas.getContext('2d'); + //check for html5 text drawing support + if (!supports_text(ctx)) return null; + //size the canvas + canvas.width = c_width; + canvas.height = c_height; + canvas.id = c_id; + canvas.title = c_title; + canvas.style.display = c_display; + return canvas; + } + + function logo_1(alphabet, fine_text, pspm) { + var logo = new Logo(alphabet, fine_text); + logo.add_pspm(pspm); + return logo; + } + + function logo_2(alphabet, fine_text, target, query, query_offset) { + var logo = new Logo(alphabet, fine_text); + if (query_offset < 0) { + logo.add_pspm(target, -query_offset); + logo.add_pspm(query); + } else { + logo.add_pspm(target); + logo.add_pspm(query, query_offset); + } + return logo; + } + + /* + * Specifies an alternate source for an image. + * If the image with the image_id specified has + * not loaded then a generated logo will be used + * to replace it. + * + * Note that the image must either have dimensions + * or a scale must be set. + */ + function alternate_logo(logo, image_id, scale) { + var image = document.getElementById(image_id); + if (!image) { + alert("Can't find specified image id (" + image_id + ")"); + return; + } + //if the image has loaded then there is no reason to use the canvas + if (image_ok(image)) return; + //the image has failed to load so replace it with a canvas if we can. + var canvas = create_canvas(image.width, image.height, image_id, image.title, image.style.display); + if (canvas == null) return; + //draw the logo on the canvas + draw_logo_on_canvas(logo, canvas, undefined, scale); + //replace the image with the canvas + image.parentNode.replaceChild(canvas, image); + } + + /* + * Specifes that the element with the specified id + * should be replaced with a generated logo. + */ + function replace_logo(logo, replace_id, scale, title_txt, display_style) { + var element = document.getElementById(replace_id); + if (!replace_id) { + alert("Can't find specified id (" + replace_id + ")"); + return; + } + //found the element! + var canvas = create_canvas(50, 120, replace_id, title_txt, display_style); + if (canvas == null) return; + //draw the logo on the canvas + draw_logo_on_canvas(logo, canvas, undefined, scale); + //replace the element with the canvas + element.parentNode.replaceChild(canvas, element); + } + + /* + * Fast string trimming implementation found at + * http://blog.stevenlevithan.com/archives/faster-trim-javascript + * + * Note that regex is good at removing leading space but + * bad at removing trailing space as it has to first go through + * the whole string. + */ + function trim (str) { + str = str.replace(/^\s\s*/, ''); + var ws = /\s/, i = str.length; + while (ws.test(str.charAt(--i))); + return str.slice(0, i + 1); + } + /* END INCLUDED FILE "motif_logo.js" */ + + + + /* START INCLUDED FILE "dreme-to-html.js" */ + var expansion_lookup = []; + + /* + * show_hidden + * + * Looks for specially named elements and switches to the shown view + */ + function show_hidden(prefix) { + document.getElementById(prefix + '_activator').style.display = 'none'; + document.getElementById(prefix + '_deactivator').style.display = 'block'; + document.getElementById(prefix + '_data').style.display = 'block'; + } + /* + * hide_shown + * + * Looks for specially named elements and switches to the hidden view + */ + function hide_shown(prefix) { + document.getElementById(prefix + '_activator').style.display = 'block'; + document.getElementById(prefix + '_deactivator').style.display = 'none'; + document.getElementById(prefix + '_data').style.display = 'none'; + } + + function click_download_tab(tab) { + document.getElementById("download_tab_num").value = tab; + for (var i = 1; i <= 3; i++) { + document.getElementById('download_tab_'+i).className = "tab" + (i==tab ? " activeTab" : ""); + document.getElementById('download_pnl_'+i).style.display = (i==tab ? "block" : "none"); + } + document.getElementById('download_button').style.visibility = (tab==3 ? "visible" : "hidden"); + } + + + /* + * searches child nodes in depth first order and returns the + * first it finds with the className specified. + */ + function find_child_element_by_class(node, className) { + var patt = new RegExp("\\b" + className + "\\b"); + + if (node.nodeType == Node.ELEMENT_NODE && + patt.test(node.className)) { + return node; + } else { + var result = null; + for (var i = 0; i < node.childNodes.length; i++) { + result = find_child_element_by_class(node.childNodes[i], className); + if (result != null) break; + } + return result; + } + } + + function find_parent_element_by_class(node, className) { + var patt = new RegExp("\\b" + className + "\\b"); + if (node.nodeType == Node.ELEMENT_NODE && + patt.test(node.className)) { + return node; + } else if (node.parentNode != null) { + return find_parent_element_by_class(node.parentNode, className); + } + return null; + } + + /* + * expand + * + * Expand the extra data section for a motif. + */ + function expand(num) { + // get motif data + var motif_info = motif_seqs[num]; + var motif_id = motif_info[0]; + var seq = motif_info[1]; + var rcseq = motif_info[2]; + var length = motif_info[3]; + var nsites = motif_info[4]; + var p_hits = motif_info[5]; + var n_hits = motif_info[6]; + var pvalue = motif_info[7]; + var evalue = motif_info[8]; + var uevalue = motif_info[9]; + var matches = motif_info[10]; + // find the location to insert the expanded motif data + var table = document.getElementById('dreme_motifs'); + var motif_row = document.getElementById('motif_row_' + num); + var exp_row = table.insertRow(motif_row.rowIndex + 1); + exp_row.id = 'exp_row_' + num; + var cell = exp_row.insertCell(0); + cell.colSpan = 9; + // create the DOM to insert + var exp = document.getElementById('expanded_motif').firstChild.cloneNode(true); + // update fields + set_content_to_text(find_child_element_by_class(exp, 'name'), seq); + set_content_to_text(find_child_element_by_class(exp, 'num'), num); + var img = find_child_element_by_class(exp, 'img_nc'); + img.src = motif_id + "nc_" + seq + ".png"; + var imgrc = find_child_element_by_class(exp, 'img_rc'); + imgrc.src = motif_id + "rc_" + rcseq + ".png"; + // fill in the details + var details = find_child_element_by_class(exp, 'details'); + set_content_to_text(find_child_element_by_class(details, 'positives'), p_hits); + set_content_to_text(find_child_element_by_class(details, 'negatives'), n_hits); + set_content_to_text(find_child_element_by_class(details, 'pvalue'), pvalue); + set_content_to_text(find_child_element_by_class(details, 'evalue'), evalue); + set_content_to_text(find_child_element_by_class(details, 'uevalue'), uevalue); + + // fill in match table + var match_row = find_child_element_by_class(exp, 'match'); + var tbody = match_row.parentNode; + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + var cseq = match[0]; + var cpos = match[1]; + var cneg = match[2]; + var cpval = match[3].toExponential(1); + var ceval = match[4].toExponential(1); + var row = match_row.cloneNode(true); + var td_cseq = find_child_element_by_class(row, 'dnaseq'); + set_content_to_text(td_cseq, cseq); + colour_dna_seq(td_cseq); + set_content_to_text(find_child_element_by_class(row, 'positives'), cpos); + set_content_to_text(find_child_element_by_class(row, 'negatives'), cneg); + set_content_to_text(find_child_element_by_class(row, 'pvalue'), cpval); + set_content_to_text(find_child_element_by_class(row, 'evalue'), ceval); + tbody.appendChild(row); + } + tbody.removeChild(match_row); + // append the expanded information + cell.appendChild(exp); + // hide the old row + motif_row.style.display = 'none'; + update_headers(); + } + + function expanded_num(elem) { + var exp = find_parent_element_by_class(elem, 'expanded_motif'); + var num = parseInt(nodes_text(text_nodes(find_child_element_by_class(exp, 'num')))); + return num; + } + + function contract(contained_node) { + var table = document.getElementById('dreme_motifs'); + var num = expanded_num(contained_node); + var motif_row = document.getElementById('motif_row_' + num); + var exp_row = document.getElementById('exp_row_' + num); + + motif_row.style.display = 'table-row'; + table.deleteRow(exp_row.rowIndex); + update_headers(); + } + + function update_headers() { + var motif_row_patt = new RegExp("\\bmotif_row\\b"); + var motif_head_patt = new RegExp("\\bmotif_head\\b"); + var table = document.getElementById('dreme_motifs'); + var header = table.tHead.getElementsByTagName('tr')[0]; + header.style.display = 'none'; + var trs = table.tBodies[0].getElementsByTagName('tr'); + var needHeader = true; + for (var i = 0; i < trs.length; i++) { + var row = trs[i]; + if (row.style.display == 'none') continue; + if (motif_row_patt.test(row.className)) { + if (needHeader) { + var dupHeader = header.cloneNode(true); + dupHeader.style.display = 'table-row'; + row.parentNode.insertBefore(dupHeader, row); + needHeader = false; + i++; + } + } else if (motif_head_patt.test(row.className)) { + table.deleteRow(row.rowIndex); + i--; + } else { + needHeader = true; + } + } + } + + function set_content_to_text(ele, text) { + while(ele.hasChildNodes()) { + ele.removeChild(ele.firstChild); + } + ele.appendChild(document.createTextNode(text)); + } + + function both_setup(pos) { + // get the total number of motifs + var nmotifs = parseInt(document.getElementById('nmotifs').value, 10); + // set the motif that we're submitting + document.getElementById('submit_motif').value = (pos == 0 ? 'all' : pos); + document.getElementById('send_to_selector').style.display = (pos == 0 ? 'none' : 'block'); + document.getElementById('send_to_title_1').style.display = (pos == 0 ? 'none' : 'block'); + document.getElementById('send_to_title_2').style.display = (pos == 0 ? 'block' : 'none'); + + if (pos != 0) { + // get the information for the position + var motif_seq = motif_seqs[pos]; + var motif_id = motif_seq[0]; + var seq = motif_seq[1]; + var rcseq = motif_seq[2]; + // set the motif number + // set the titles of both popups + set_content_to_text(document.getElementById('send_to_name'), seq); + set_content_to_text(document.getElementById('download_name'), seq); + // set the images + var nc_img = "" + motif_id + "nc_" + seq + ".png"; + var rc_img = "" + motif_id + "rc_" + rcseq + ".png"; + var img; + img = document.getElementById('send_to_img'); + img.src = nc_img; + img.style.display = "inline"; + img = document.getElementById('send_to_rcimg'); + img.src = rc_img; + img.style.display = "inline"; + img = document.getElementById('download_img'); + img.src = nc_img; + img.style.display = "inline"; + img = document.getElementById('download_rcimg'); + img.src = rc_img; + img.style.display = "inline"; + // hide the canvas + document.getElementById('send_to_can').style.display = "none"; + document.getElementById('send_to_rccan').style.display = "none"; + document.getElementById('download_can').style.display = "none"; + document.getElementById('download_rccan').style.display = "none"; + // get some motif details + var pspm_text = document.getElementById("pspm"+ pos).value; + var pspm = new Pspm(pspm_text); + var alpha = new Alphabet(document.getElementById("alphabet").value, + document.getElementById("bgfreq").value); + document.getElementById('download_pspm').value = pspm.as_pspm(); + document.getElementById('download_pssm').value = pspm.as_pssm(alpha); + // set the width and height defaults + document.getElementById('logo_width').value = pspm.get_motif_length(); + document.getElementById('logo_height').value = 7.5; + // hide and show the arrows + var prevclass = (pos == 1 ? "navarrow inactive" : "navarrow"); + var nextclass = (pos == nmotifs ? "navarrow inactive" : "navarrow"); + document.getElementById('prev_arrow_1').className = prevclass; + document.getElementById('prev_arrow_2').className = prevclass; + document.getElementById('next_arrow_1').className = nextclass; + document.getElementById('next_arrow_2').className = nextclass; + set_content_to_text(document.getElementById('pop_num_1'), pos); + set_content_to_text(document.getElementById('pop_num_2'), pos); + } + } + + function both_change(inc) { + var motif_num = parseInt(document.getElementById('submit_motif').value, 10); + var nmotifs = parseInt(document.getElementById('nmotifs').value, 10); + var orig = motif_num; + motif_num += inc; + if (motif_num > nmotifs) motif_num = nmotifs; + else if (motif_num < 1) motif_num = 1; + if (orig != motif_num) both_setup(motif_num); + } + + function both_hide() { + document.getElementById('grey_out_page').style.display = 'none'; + document.getElementById('download').style.display = 'none'; + document.getElementById('send_to').style.display = 'none'; + } + + /* + * lookup the information on a motif and prepare the + * popup for sending it to another program + */ + function send_to_popup(pos) { + both_setup(pos); + var program = find_child_element_by_class(document.getElementById('programs'), 'selected').id; + var task = highlight_submit_task(null, submit_programs[program]); + highlight_submit_program(program, submit_tasks[task]); + update_submit_text(task, program); + // show the send to page + var grey_out = document.getElementById('grey_out_page'); + grey_out.style.display = 'block'; + var send_to_pop = document.getElementById('send_to'); + send_to_pop.style.display = 'block'; + } + + function send_to_popup2(elem) { + send_to_popup(expanded_num(elem)); + } + + function send_to_submit() { + var program = find_child_element_by_class(document.getElementById('programs'), 'selected').id; + // set the hidden fields on the form + document.getElementById('submit_program').value = program; + // send the form + document.getElementById('submit_form').submit(); + both_hide(); + } + + function download_popup(pos) { + both_setup(pos); + click_download_tab(document.getElementById("download_tab_num").value); + document.getElementById('submit_program').value = "LOGO"; + // show the download page + var grey_out = document.getElementById('grey_out_page'); + grey_out.style.display = 'block'; + var download_pop = document.getElementById('download'); + download_pop.style.display = 'block'; + } + + function download_popup2(elem) { + download_popup(expanded_num(elem)); + } + + function download_submit() { + var format = document.getElementById('logo_format').value; + var orient = document.getElementById('logo_rc').value; + var ssc = document.getElementById('logo_ssc').value; + var width = document.getElementById('logo_width').value; + var height = document.getElementById('logo_height').value; + document.getElementById('submit_format').value = format; + document.getElementById('submit_rc').value = orient; + document.getElementById('submit_ssc').value = ssc; + document.getElementById('submit_width').value = width; + document.getElementById('submit_height').value = height; + document.getElementById('submit_form').submit(); + both_hide(); + } + + function FixLogoTask(num, rc) { + this.num = num; + this.rc = rc; + this.run = FixLogoTask_run; + } + + function FixLogoTask_run() { + var pspm_text = document.getElementById("pspm" + this.num).value; + var alpha = new Alphabet("ACGT"); + var pspm = new Pspm(pspm_text); + if (this.rc) pspm = pspm.reverse_complement(alpha); + var imgid = "small_" + (this.rc ? "rc_" : "") + "logo_" + this.num; + + var image = document.getElementById(imgid); + + var canvas = create_canvas(pspm.get_motif_length() *15, 50, image.id, + image.title, image.style.display); + if (canvas == null) return; + + var logo = logo_1(alpha, "DREME", pspm); + draw_logo_on_canvas(logo, canvas); + image.parentNode.replaceChild(canvas, image); + } + + function fix_popup_logo(image, canvasid, rc) { + var motif_num = parseInt(document.getElementById('submit_motif').value, 10); + var pspm_text = document.getElementById("pspm" + motif_num).value; + var alpha = new Alphabet("ACGT"); + var pspm = new Pspm(pspm_text); + if (rc) pspm = pspm.reverse_complement(alpha); + image.style.display = "none"; + //check for canvas support before attempting anything + var canvas = document.getElementById(canvasid); + if (!canvas.getContext) return; + if (!supports_text(canvas.getContext('2d'))) return; + canvas.height = 90; + canvas.width = 170; + canvas.style.display = "inline"; + var logo = logo_1(alpha, "DREME", pspm); + draw_logo_on_canvas(logo, canvas, false); + } + + function fix_expanded_logo(image, rc) { + var motif_num = expanded_num(image); + var pspm_text = document.getElementById("pspm" + motif_num).value; + var alpha = new Alphabet("ACGT"); + var pspm = new Pspm(pspm_text); + if (rc) pspm = pspm.reverse_complement(alpha); + //check for canvas support before attempting anything + var canvas = document.createElement('canvas'); + if (!canvas.getContext) return; + if (!supports_text(canvas.getContext('2d'))) return; + canvas.height = 150; + canvas.width = 0; + draw_logo_on_canvas(logo_1(alpha, "DREME", pspm), canvas, false); + image.parentNode.replaceChild(canvas, image); + } + + function text_nodes(container) { + var textNodes = []; + var stack = [container]; + // depth first search to maintain ordering when flattened + while (stack.length > 0) { + var node = stack.pop(); + if (node.nodeType == Node.TEXT_NODE) { + textNodes.push(node); + } else { + for (var i = node.childNodes.length-1; i >= 0; i--) { + stack.push(node.childNodes[i]); + } + } + } + return textNodes; + } + + function node_text(node) { + if (node === undefined) { + return ''; + } else if (node.textContent) { + return node.textContent; + } else if (node.innerText) { + return node.innerText; + } else { + return ''; + } + } + + function nodes_text(nodes, separator) { + if (separator === undefined) separator = ''; + var text = ''; + if (nodes.length > 0) { + text += node_text(nodes[0]); + } + for (var i = 1; i < nodes.length; i++) { + text += separator + node_text(nodes[i]); + } + return text; + } + + function colour_dna_seq(container) { + var textnodes = text_nodes(container); + for (var i = 0; i < textnodes.length; i++) { + var node = textnodes[i]; + container.replaceChild(create_dna_seq(node_text(node)), node); + } + } + + function create_dna_seq(seq) { + var out = document.createElement('span'); + var last = 0; + for (var i = 0; i < seq.length; i++) { + var letter = seq.charAt(i); + if (letter == 'A' || letter == 'C' || letter == 'G' || letter == 'T') { + if (last < i) { + out.appendChild(document.createTextNode(seq.substring(last, i))); + } + var coloured_letter = document.createElement('span'); + coloured_letter.className = "dna_" + letter; + coloured_letter.appendChild(document.createTextNode(letter)); + out.appendChild(coloured_letter); + last = i + 1; + } + } + if (last < seq.length) { + out.appendChild(document.createTextNode(seq.substring(last))); + } + return out; + } + + function sort_table(colEle, compare_function) { + //find the parent of colEle that is either a td or th + var cell = colEle; + while (true) { + if (cell == null) return; + if (cell.nodeType == Node.ELEMENT_NODE && + (cell.tagName.toLowerCase() == "td" || cell.tagName.toLowerCase() == "th")) { + break; + } + cell = cell.parentNode; + } + //find the parent of cell that is a tr + var row = cell; + while (true) { + if (row == null) return; + if (row.nodeType == Node.ELEMENT_NODE && row.tagName.toLowerCase() == "tr") { + break; + } + row = row.parentNode; + } + //find the parent of row that is a table + var table = row; + while (true) { + if (table == null) return; + if (table.nodeType == Node.ELEMENT_NODE && table.tagName.toLowerCase() == "table") { + break; + } + table = table.parentNode; + } + var column_index = cell.cellIndex; + // do a bubble sort, because the tables are so small it doesn't matter + var change; + var trs = table.tBodies[0].getElementsByTagName('tr'); + var already_sorted = true; + var reverse = false; + while (true) { + do { + change = false; + for (var i = 0; i < trs.length -1; i++) { + var v1 = nodes_text(text_nodes(trs[i].cells[column_index])); + var v2 = nodes_text(text_nodes(trs[i+1].cells[column_index])); + if (reverse) { + var tmp = v1; + v1 = v2; + v2 = tmp; + } + if (compare_function(v1, v2) > 0) { + exchange(trs[i], trs[i+1], table); + change = true; + already_sorted = false; + trs = table.tBodies[0].getElementsByTagName('tr'); + } + } + } while (change); + if (reverse) break;// we've sorted twice so exit + if (!already_sorted) break;// sort did something so exit + // when it's sorted one way already then sort the opposite way + reverse = true; + } + update_sort_arrows(row, column_index, reverse); + } + + function update_sort_arrows(row, column_index, reverse) { + var ascending = "\u25BC"; + var descending = "\u25B2"; + var dir = (reverse ? descending : ascending); + for (var i = 0; i < row.cells.length; i++) { + var arrow = find_child_element_by_class(row.cells[i], "sort_dir"); + if (arrow == null) continue; + if (i == column_index) { + set_content_to_text(arrow, dir); + } else { + set_content_to_text(arrow, ""); + } + } + } + + function exchange(oRowI, oRowJ, oTable) { + var i = oRowI.rowIndex; + var j = oRowJ.rowIndex; + if (i == j+1) { + oTable.tBodies[0].insertBefore(oRowI, oRowJ); + } if (j == i+1) { + oTable.tBodies[0].insertBefore(oRowJ, oRowI); + } else { + var tmpNode = oTable.tBodies[0].replaceChild(oRowI, oRowJ); + if(typeof(oRowI) != "undefined") { + oTable.tBodies[0].insertBefore(tmpNode, oRowI); + } else { + oTable.appendChild(tmpNode); + } + } + } + + function compare_numbers(v1, v2) { + var f1 = parseFloat(v1); + var f2 = parseFloat(v2); + if (f1 < f2) { + return -1; + } else if (f1 > f2) { + return 1; + } else { + return 0; + } + } + + function compare_counts(v1, v2) { + var re = /(\d+)\/\d+/; + var m1 = re.exec(v1); + var m2 = re.exec(v2); + if (m1 == null && m2 == null) return 0; + if (m1 == null) return -1; + if (m2 == null) return 1; + return compare_numbers(m1[1], m2[1]); + } + + function compare_strings(v1, v2) { + return v1.localeCompare(v2); + } + /* + * help + * + * Moves around help pop-ups so they appear + * below an activator. + */ + function help(activator, popup_id) { + if (help.popup === undefined) { + help.popup = null; + } + if (help.activator === undefined) { + help.activator = null; + } + + if (typeof(activator) == 'undefined') { // no activator so hide + help.popup.style.display = 'none'; + help.popup = null; + return; + } + var pop = document.getElementById(popup_id); + if (pop == help.popup) { + if (activator == help.activator) { + //hide popup (as we've already shown it for the current help button) + help.popup.style.display = 'none'; + help.popup = null; + return; // toggling complete! + } + } else if (help.popup != null) { + //activating different popup so hide current one + help.popup.style.display = 'none'; + } + help.popup = pop; + help.activator = activator; + + //must make the popup visible to measure it or it has zero width + pop.style.display = 'block'; + var xy = get_elem_xy(activator); + var padding = 10; + var edge_padding = 15; + var scroll_padding = 15; + + var pop_left = (xy[0] + (activator.offsetWidth / 2) - (pop.offsetWidth / 2)); + var pop_top = (xy[1] + activator.offsetHeight + padding); + + // ensure the box is not past the top or left of the page + if (pop_left < 0) pop_left = edge_padding; + if (pop_top < 0) pop_top = edge_padding; + // ensure the box does not cause horizontal scroll bars + var page_width = null; + if (window.innerWidth) { + page_width = window.innerWidth; + } else if (document.body) { + page_width = document.body.clientWidth; + } + if (page_width) { + if (pop_left + pop.offsetWidth > page_width) { + pop_left = page_width - pop.offsetWidth - edge_padding - scroll_padding; //account for scrollbars + } + } + + pop.style.left = pop_left + "px"; + pop.style.top = pop_top + "px"; + } + + var submit_tasks = []; + submit_tasks['search_motifs'] = ['TOMTOM']; + submit_tasks['search_sequences'] = ['FIMO']; + submit_tasks['rank_sequences'] = ['MAST']; + submit_tasks['predict_go'] = ['GOMO']; + submit_tasks['infer_tf'] = ['SPAMO']; + var submit_programs = []; + submit_programs['TOMTOM'] = ['search_motifs']; + submit_programs['FIMO'] = ['search_sequences']; + submit_programs['MAST'] = ['rank_sequences']; + submit_programs['GOMO'] = ['predict_go']; + submit_programs['SPAMO'] = ['infer_tf']; + var submit_descriptions = []; + submit_descriptions['TOMTOM'] = "Find similar motifs in published " + + "libraries or a library you supply."; + submit_descriptions['FIMO'] = "Find motif occurences in sequence data."; + submit_descriptions['MAST'] = "Rank sequences by affinity to groups " + + "of motifs."; + submit_descriptions['GOMO'] = "Identify possible roles (Gene Ontology " + + "terms) for motifs."; + submit_descriptions['SPAMO'] = "Find other motifs that are enriched at " + + "specific close spacings which might imply the existance of a complex."; + + + function click_submit_task(ele) { + var task = ele.id; + var program = highlight_submit_program(null, submit_tasks[task]); + highlight_submit_task(task, submit_programs[program]); + update_submit_text(task, program); + } + + function click_submit_program(ele) { + var program = ele.id; + var task = highlight_submit_task(null, submit_programs[program]); + highlight_submit_program(program, submit_tasks[task]); + update_submit_text(task, program); + } + + function update_submit_text(task, program) { + var task_ele = document.getElementById(task); + var program_ele = document.getElementById(program); + set_content_to_text(document.getElementById('program_action'), + nodes_text(text_nodes(task_ele))); + set_content_to_text(document.getElementById('program_name'), + nodes_text(text_nodes(program_ele))); + set_content_to_text(document.getElementById('program_desc'), + submit_descriptions[program]); + } + + function highlight_submit_task(select, highlights) { + var tasks_ul = document.getElementById('tasks'); + var all_tasks = tasks_ul.getElementsByTagName('li'); + var li; + var originally_selected = null; + // deselect everything in the tasks list + for (var i = 0; i < all_tasks.length; i++) { + li = all_tasks[i]; + if (li.className == "selected") { + originally_selected = li; + } + li.className = ""; + } + // highlight everything in the highlights list + for (var i = 0; i < highlights.length; i++) { + var li = document.getElementById(highlights[i]); + li.className = "active"; + } + // check if we're setting the selected item specifically + if (select != null) { + li = document.getElementById(select); + li.className = "selected"; + return select; + } else { + // if the originally selected item is allowed then keep it + // otherwise move to the first element of the highlight list + if (originally_selected != null && + originally_selected.className == "active") { + originally_selected.className = "selected"; + return originally_selected.id; + } else if (highlights.length > 0) { + li = document.getElementById(highlights[0]); + li.className = "selected"; + return highlights[0]; + } + return null; + } + } + + + function highlight_submit_program(select, highlights) { + var programs_ul = document.getElementById('programs'); + var all_programs = programs_ul.getElementsByTagName('li'); + var li; + var originally_selected = null; + // deselect everything in the programs list + for (var i = 0; i < all_programs.length; i++) { + li = all_programs[i]; + if (li.className == "selected") { + originally_selected = li; + } + li.className = ""; + } + // highlight everything in the highlights list + for (var i = 0; i < highlights.length; i++) { + var li = document.getElementById(highlights[i]); + li.className = "active"; + } + // check if we're setting the selected item specifically + if (select != null) { + li = document.getElementById(select); + li.className = "selected"; + return select; + } else { + // if the originally selected item is allowed then keep it + // otherwise move to the first element of the highlight list + if (originally_selected != null && + originally_selected.className == "active") { + originally_selected.className = "selected"; + return originally_selected.id; + } else if (highlights.length > 0) { + li = document.getElementById(highlights[0]); + li.className = "selected"; + return highlights[0]; + } + return null; + } + } + /* END INCLUDED FILE "dreme-to-html.js" */ + + </script> +</head> +<body> +<form id="submit_form" method="post" action="http://Sharplab-G4-1.local/meme/cgi-bin/meme_request.cgi" target="_blank"> +<!--+++++++++++++++START DATA+++++++++++++++--> +<input type="hidden" name="version" value="MEME version 4.7.0"> +<input type="hidden" name="alphabet" id="alphabet" value="ACGT"> +<input type="hidden" name="strands" value="+ -"> +<input type="hidden" name="bgsrc" value="dataset"> +<input type="hidden" name="bgfreq" id="bgfreq" value="A 0.243 C 0.270 G 0.243 T 0.243"> +<input type="hidden" name="name" value="test"> +<input type="hidden" name="nmotifs" id="nmotifs" value="0"> +<!--+++++++++++++++FINISHED DATA++++++++++++--> +<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"> +</form> +<div class="pop_content" id="pop_motifs_name"> +<p> + The name of the motif uses the IUPAC codes for nucleotides which has + a different letter to represent each of the 15 possible combinations. + </p> +<p> + The name is itself a representation of the motif though the position + weight matrix is not directly equalivant as it is generated from the + sites found that matched the letters given in the name. + </p> +<p><a href="http://meme.nbcr.net/meme/doc/alphabets.html"> + Read more about the MEME suite's use of the IUPAC alphabets. + </a></p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motifs_logo"> +<p>The logo of the motif.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motifs_rc_logo"> +<p>The logo of the reverse complement motif.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motifs_evalue"> +<p>The E-value is the enrichment p-value times the number of candidate + motifs tested.</p> +<p>The enrichment p-value is calculated using the Fisher Exact Test for + enrichment of the motif in the positive sequences.</p> +<p>Note that the counts used in the Fisher Exact Test are made after + erasing sites that match previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motifs_uevalue"> +<p>The E-value of the motif calculated without erasing the sites of + previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_more"> +<p>Show more information on the motif.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_submit"> +<p>Submit your motif to another MEME Suite program.</p> +<h5>Supported Programs</h5> +<dl> +<dt>Tomtom</dt> +<dd>Tomtom is a tool for searching for similar known motifs. + [<a href="http://meme.nbcr.net/meme/tomtom-intro.html">manual</a>]</dd> +<dt>MAST</dt> +<dd>MAST is a tool for searching biological sequence databases for + sequences that contain one or more of a group of known motifs. + [<a href="http://meme.nbcr.net/meme/mast-intro.html">manual</a>]</dd> +<dt>FIMO</dt> +<dd>FIMO is a tool for searching biological sequence databases for + sequences that contain one or more known motifs. + [<a href="http://meme.nbcr.net/meme/fimo-intro.html">manual</a>]</dd> +<dt>GOMO</dt> +<dd>GOMO is a tool for identifying possible roles (Gene Ontology + terms) for DNA binding motifs. + [<a href="http://meme.nbcr.net/meme/gomo-intro.html">manual</a>]</dd> +<dt>SpaMo</dt> +<dd>SpaMo is a tool for inferring possible transcription factor + complexes by finding motifs with enriched spacings. + [<a href="http://meme.nbcr.net/meme/spamo-intro.html">manual</a>]</dd> +</dl> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_download"> +<p>Download your motif as a position weight matrix or a custom logo.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motif_positives"> +<p># positive sequences matching the motif / # positive sequences.</p> +<p>Note these counts are made after erasing sites that match previously + found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motif_negatives"> +<p># negative sequences matching the motif / # negative sequences.</p> +<p>Note these counts are made after erasing sites that match previously + found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motif_pvalue"> +<p>The p-value of the Fisher Exact Test for enrichment of the motif in + the positive sequences.</p> +<p>Note that the counts used in the Fisher Exact Test are made after + erasing sites that match previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motif_evalue"> +<p>The E-value is the motif p-value times the number of candidate motifs + tested.</p> +<p>Note that the p-value was calculated with counts made after + erasing sites that match previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_motif_uevalue"> +<p>The E-value of the motif calculated without erasing the sites of + previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_match_word"> +<p>All words matching the motif whose uncorrected p-value is less than + 0.01.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_match_pos"> +<p># positive sequences with matches to the word / # positive sequences.</p> +<p>Note these counts are made after erasing sites that match previously + found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_match_neg"> +<p># negative sequences with matches to the word / # negative sequences.</p> +<p>Note these counts are made after erasing sites that match previously + found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_match_pval"> +<p>The p-value of the Fisher Exact Test for enrichment of the word in + the positive sequences.</p> +<p>Note that the counts used in the Fisher Exact Test are made after + erasing sites that match previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div class="pop_content" id="pop_match_eval"> +<p>The word p-value times the number of candidates tested.</p> +<p>Note that the p-value was calculated with counts made after + erasing sites that match previously found motifs.</p> +<div style="float:right; bottom:0px;">[<a href="javascript:help()">close</a> ]</div> +</div> +<div id="expanded_motif" style="display:none"><div class="box expanded_motif" style="margin-bottom:5px;"> +<div> +<div style="float:left"><h2 class="mainh" style="margin:0; padding:0;"> +<span class="num"></span>. + <span class="name"></span> +</h2></div> +<div style="float:right; "><div class="close" onclick="contract(this);" title="Show less information.">↥</div></div> +<div style="clear:both"></div> +</div> +<div style="padding:0 5px;"> +<div style="float:left;"> +<img class="img_nc" onerror="fix_expanded_logo(this, false)"><img class="img_rc" onerror="fix_expanded_logo(this, true)"> +</div> +<div style="float:right; height:100px;"> +<div onclick="send_to_popup2(this);" class="actionbutton" title="Submit this motif to another MEME Suite program."> +<div style="float:left; margin-right:1em;">Submit</div> +<div style="float:right">⇢</div> +<div style="clear:both;"></div> +</div> +<div onclick="download_popup2(this);" class="actionbutton" title="Download this motif as a position weight matrix or a custom logo."> +<div style="float:left; margin-right:1em;">Download</div> +<div style="float:right">⟱</div> +<div style="clear:both;"></div> +</div> +</div> +<div style="clear:both;"></div> +</div> +<h4>Details</h4> +<table class="details"> +<thead><tr> +<th>Positives <div class="help2" onclick="help(this,'pop_motif_positives')">?</div> +</th> +<th>Negatives <div class="help2" onclick="help(this,'pop_motif_negatives')">?</div> +</th> +<th>P-value <div class="help2" onclick="help(this,'pop_motif_pvalue')">?</div> +</th> +<th>E-value <div class="help2" onclick="help(this,'pop_motif_evalue')">?</div> +</th> +<th>Unerased E-value <div class="help2" onclick="help(this,'pop_motif_uevalue')">?</div> +</th> +</tr></thead> +<tbody><tr> +<td> +<span class="positives"></span>/3</td> +<td> +<span class="negatives"></span>/3</td> +<td class="pvalue"></td> +<td class="evalue"></td> +<td class="uevalue"></td> +</tr></tbody> +</table> +<h4>Enriched Matching Words</h4> +<table> +<thead><tr> +<th> +<a href="javascript:;" onclick="sort_table(this, compare_strings)"><span class="sort_dir"></span>Word</a> + <div class="help2" onclick="help(this,'pop_match_word')">?</div> +</th> +<th> +<a href="javascript:;" onclick="sort_table(this, compare_counts)"><span class="sort_dir"></span>Positives</a> + <div class="help2" onclick="help(this,'pop_match_pos')">?</div> +</th> +<th> +<a href="javascript:;" onclick="sort_table(this, compare_counts)"><span class="sort_dir"></span>Negatives</a> + <div class="help2" onclick="help(this,'pop_match_neg')">?</div> +</th> +<th> +<a href="javascript:;" onclick="sort_table(this, compare_numbers)"><span class="sort_dir"></span>P-value</a> + <div class="help2" onclick="help(this,'pop_match_pval')">?</div> +</th> +<th> +<a href="javascript:;" onclick="sort_table(this, compare_numbers)"><span class="sort_dir">▼</span>E-value</a> + <div class="help2" onclick="help(this,'pop_match_eval')">?</div> +</th> +</tr></thead> +<tbody><tr class="match"> +<td class="dnaseq"></td> +<td> +<span class="positives"></span>/3</td> +<td> +<span class="negatives"></span>/3</td> +<td class="pvalue"></td> +<td class="evalue"></td> +</tr></tbody> +</table> +</div></div> +<div id="grey_out_page" class="grey_background" style="display:none;"></div> +<div class="popup_wrapper"><div id="send_to" class="popup" style="top:-150px; display:none"> +<div> +<div style="float:left" id="send_to_title_1"><h2 class="mainh compact">Submit "<span id="send_to_name"></span>"</h2></div> +<div style="float:left" id="send_to_title_2"><h2 class="mainh compact">Submit All Motifs</h2></div> +<div style="float:right; "><div class="close" onclick="both_hide();">x</div></div> +<div style="clear:both"></div> +</div> +<div style="padding:0 5px 5px 5px;"> +<div id="send_to_selector" style="height:100px;"> +<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;"> +<a id="prev_arrow_2" href="javascript:both_change(-1)" class="navarrow">⇧</a><div id="pop_num_2" class="navnum"></div> +<a id="next_arrow_2" href="javascript:both_change(1)" class="navarrow">⇩</a> +</div> +</div> +<form> +<div style=""> +<div style="float:left;"> +<h4 class="compact">Select what you want to do</h4> +<div class="programs_scroll"><ul id="tasks" class="programs"> +<li id="search_motifs" onclick="click_submit_task(this)" class="selected">Search Motifs</li> +<li id="search_sequences" onclick="click_submit_task(this)">Search Sequences</li> +<li id="rank_sequences" onclick="click_submit_task(this)">Rank Sequences</li> +<li id="predict_go" onclick="click_submit_task(this)">Predict Gene Ontology terms</li> +<li id="infer_tf" onclick="click_submit_task(this)">Infer TF Complexes</li> +</ul></div> +</div> +<div style="float:right;"> +<h4 class="compact">Select a program</h4> +<div class="programs_scroll"><ul id="programs" class="programs"> +<li id="TOMTOM" onclick="click_submit_program(this)" class="selected">Tomtom</li> +<li id="FIMO" onclick="click_submit_program(this)">FIMO</li> +<li id="MAST" onclick="click_submit_program(this)">MAST</li> +<li id="GOMO" onclick="click_submit_program(this)">GOMO</li> +<li id="SPAMO" onclick="click_submit_program(this)">SpaMo</li> +</ul></div> +</div> +<div style="font-weight:bold; display:inline-block; text-align:center; width:60px; height:100px; line-height:100px">Or</div> +<div style="clear:both;"></div> +</div> +<h4> +<span id="program_action">Search Motifs</span> with <span id="program_name">Tomtom</span> +</h4> +<p><span id="program_desc">Find similar motifs in published + libraries or a library you supply.</span></p> +<div style="margin-top:10px; height: 2em;"> +<div style="float:left;"><input type="button" value="Send" onclick="javascript:send_to_submit()"></div> +<div style="float:right;"><input type="button" value="Cancel" onclick="javascript:both_hide()"></div> +</div> +</form> +</div> +</div></div> +<div class="popup_wrapper"><div id="download" class="popup" style="top:-150px; display:none"> +<div> +<div style="float:left"><h2 class="mainh" style="margin:0; padding:0;">Download "<span id="download_name"></span>"</h2></div> +<div style="float:right; "><div class="close" onclick="both_hide();">x</div></div> +<div style="clear:both"></div> +</div> +<div style="padding:0 5px 5px 5px;"> +<div style="height:100px"> +<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;"> +<a id="prev_arrow_1" href="javascript:both_change(-1)" class="navarrow">⇧</a><div id="pop_num_1" class="navnum"></div> +<a id="next_arrow_1" href="javascript:both_change(1)" class="navarrow">⇩</a> +</div> +</div> +<form> +<input type="hidden" id="download_tab_num" value="1"><div style="padding:5px 0;"> +<div class="tabArea top"> +<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> +</div> +<div class="tabMain"> +<div id="download_pnl_1"><textarea id="download_pspm" style="width:99%" rows="10" readonly></textarea></div> +<div id="download_pnl_2"><textarea id="download_pssm" style="width:99%" rows="10" readonly></textarea></div> +<div id="download_pnl_3"><table> +<tr> +<td><label for="logo_format">Format:</label></td> +<td><select id="logo_format"><option value="png">PNG (for web)</option> +<option value="eps">EPS (for publication)</option></select></td> +</tr> +<tr> +<td><label for="logo_rc">Orientation:</label></td> +<td><select id="logo_rc"><option value="false">Normal</option> +<option value="true">Reverse Complement</option></select></td> +</tr> +<tr> +<td><label for="logo_ssc">Small Sample Correction:</label></td> +<td><select id="logo_ssc"><option value="false">Off</option> +<option value="true">On</option></select></td> +</tr> +<tr> +<td><label for="logo_width">Width:</label></td> +<td> +<input type="text" id="logo_width" size="4"> cm + </td> +</tr> +<tr> +<td><label for="logo_height">Height:</label></td> +<td> +<input type="text" id="logo_height" size="4"> cm + </td> +</tr> +</table></div> +<div style="margin-top:10px;"> +<div style="float:left;"><input type="button" id="download_button" value="Download" style="visibility:hidden;" onclick="javascript:download_submit()"></div> +<div style="float:right;"><input type="button" value="Cancel" onclick="javascript:both_hide()"></div> +<div style="clear:both;"></div> +</div> +</div> +</div> +</form> +</div> +</div></div> +<a name="top"></a><div class="pad1"> +<h1><img src="http://Sharplab-G4-1.local/meme/doc/images/dreme_logo.png" alt="Discriminative Regular Expression Motif Elicitation (DREME)"></h1> +<p class="spaced"> + For further information on how to interpret these results or to get a + copy of the MEME software please access + <a href="http://meme.nbcr.net/">http://meme.nbcr.net</a>. + </p> +<p> + If you use DREME in your research please cite the following paper:<br><span class="citation"> + Timothy L. Bailey, "DREME: Motif discovery in transcription factor ChIP-seq data", <i>Bioinformatics</i>, <b>27</b>(12):1653-1659, 2011. + </span></p> +</div> +<div class="pad2"> +<a class="jump" href="#description">Description</a> | <a class="jump" href="#motifs">Discovered motifs</a> | <a class="jump" href="#program">Program information</a> +</div> +<a name="description"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr> +<td><h2 class="mainh">Description</h2></td> +<td align="right" valign="bottom"> +<a href="#motifs">Next</a> <a href="#top">Top</a> +</td> +</tr></table> +<div class="box"><p>xxxx</p></div> +<a name="motifs"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr> +<td><h2 class="mainh">Discovered Motifs</h2></td> +<td align="right" valign="bottom"> +<a href="#description">Previous</a> <a href="#program">Next</a> <a href="#top">Top</a> +</td> +</tr></table> +<div class="box"> +<p><b>Click on the ↧</b> under the <b>More</b> column to show more + information about the motif.<br><b>Click on the ⇢</b> under the <b>Submit</b> column to send the + motif to another MEME suite program. Eg. Tomtom<br><b>Click on the ⟱</b> under the <b>Download</b> column to get + the position weight matrix of a motif or to download the logo image with + your chosen options. + </p> +<table id="dreme_motifs" class="dreme_motifs"> +<thead><tr class="motif_head"> +<td> </td> +<th>Motif <div class="help2" onclick="help(this,'pop_motifs_name')">?</div> +</th> +<th>Logo <div class="help2" onclick="help(this,'pop_motifs_logo')">?</div> +</th> +<th>RC Logo <div class="help2" onclick="help(this,'pop_motifs_rc_logo')">?</div> +</th> +<th>E-value <div class="help2" onclick="help(this,'pop_motifs_evalue')">?</div> +</th> +<th>Unerased E-value <div class="help2" onclick="help(this,'pop_motifs_uevalue')">?</div> +</th> +<th>More <div class="help2" onclick="help(this,'pop_more')">?</div> +</th> +<th>Submit <div class="help2" onclick="help(this,'pop_submit')">?</div> +</th> +<th>Download <div class="help2" onclick="help(this,'pop_download')">?</div> +</th> +</tr></thead> +<tbody></tbody> +<tfoot><tr class="rule"> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +<td> </td> +</tr></tfoot> +</table> +<div style="float:left"><div onclick="send_to_popup(0);" class="actionbutton" title="Submit all motifs to another program."> +<div style="float:left; margin-right:1em;">Submit All</div> +<div style="float:right">⇢</div> +<div style="clear:both;"></div> +</div></div> +<div style="clear:both;"></div> +</div> +<a name="program"></a><div class="bar"> +<div style="text-align:right;"> +<a href="#motifs">Previous</a> <a href="#top">Top</a> +</div> +<div class="subsection"> +<a name="version"></a><h5>DREME version</h5>4.7.0 (Release date: Wed Sep 28 17:30:10 EST 2011) + </div> +<div class="subsection"> +<a name="reference"></a><h5>Reference</h5> +<span class="citation"> + Timothy L. Bailey, "DREME: Motif discovery in transcription factor ChIP-seq data", <i>Bioinformatics</i>, <b>27</b>(12):1653-1659, 2011. + </span> +</div> +<div class="subsection"> +<a name="command"></a><h5>Command line summary</h5> +<textarea rows="1" style="width:100%;" readonly>dreme -p test.fa -desc xxxx</textarea><br>Result calculation took 0.01 seconds<br> +</div> +<a href="javascript:show_hidden('model')" id="model_activator">show model parameters...</a><div class="subsection" id="model_data" style="display:none;"> +<h5>Model parameters</h5> +<textarea style="width:100%;" rows="10" readonly> +positives = name: "test", count: "3", file: "test.fa", last_mod_date: "Sat Dec 10 12:52:18 EST 2011" +negatives = name: "shuffled positive sequences", count: "3", from: "shuffled" +background = type: "dna", A: "0.243", C: "0.270", G: "0.243", T: "0.243", from: "dataset" +stop = evalue: "0.05" +ngen = 100 +add_pv_thresh = 0.01 +seed = 1 +host = SHARPLAB.MIT.EDU +when = Sun Dec 11 09:26:43 EST 2011 +</textarea> +</div> +<a href="javascript:hide_shown('model')" style="display:none;" id="model_deactivator">hide model parameters...</a> +</div> +</body> +</html>