Mercurial > repos > iuc > meme_fimo
changeset 20:613c75eee7bd draft default tip
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/meme commit 89ee0af6e955ff964b7984d77ad536e0a9154278
line wrap: on
line diff
--- a/macros.xml Thu Aug 29 10:19:40 2024 +0000 +++ b/macros.xml Mon Jul 14 21:33:56 2025 +0000 @@ -1,6 +1,6 @@ <macros> <token name="@VERSION_SUFFIX@">0</token> - <token name="@TOOL_VERSION@">5.5.6</token> + <token name="@TOOL_VERSION@">5.5.8</token> <token name="@PROFILE@">23.0</token> <xml name="requirements"> <requirements>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/alphabet.txt Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,13 @@ +ALPHABET "DNA with covalent modifications" DNA-LIKE + +# Core uppercase symbols +A "Adenine" 8510A8 ~ T "Thymine" A89610 +C "Cytosine" A50026 ~ G "Guanine" 313695 + +# Covalent modifications +m "5-Methylcytosine" D73027 ~ 1 "Guanine:5-Methylcytosine" 4575B4 +h "5-Hydroxymethylcytosine" F46D43 ~ 2 "Guanine:5-Hydroxymethylcytosine" 74ADD1 +f "5-Formylcytosine" FDAE61 ~ 3 "Guanine:5-Formylcytosine" ABD9E9 +c "5-Carboxylcytosine" FEE090 ~ 4 "Guanine:5-Carboxylcytosine" E0F3F8 +a "N6-methyladenine" 8510A8 ~ t "Thymine_lowercase" 756BB1 +g "modified_g" 00897B ~ 5 "cytosine_lowercase" 53698A
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/meme_input_m.fasta Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,66 @@ +>chr21_19617074_19617124_+ +AAAAATTATTACTAGGGAGGGGGCCGGAACCTCGGGACGTGGGTATATAA +>chr21_26934381_26934431_+ +GCGCCTGGTCGGTTATGAGTCACAAGTGAGTTATAAAAGGGTCGCACGTT +>chr21_28217753_28217803_- +CAAAGGGGAGGAGTGGGGTGGGGGTGGGGGTTTCACTGGTmCACTATAAA +>chr21_31710037_31710087_- +AACACCCAGGTTTCTGAGTATATAATCGCCGCACCAAAGAATTTAATTTT +>chr21_31744582_31744632_- +CCmAGGTCTAAGAGCATATATAACTTGGAGTCCAGACTATGACATTCAAA +>chr21_31768316_31768366_+ +AACGTATATAAATGGTCCTGTCCAGATGTGGCATGCAAACTmAGAATCTT +>chr21_31914206_31914256_- +TGACACCCACTACTTAGAGTATAAAATCATTCTGAGAAGTTAGAGACACC +>chr21_31933633_31933683_- +TCAGAGTATATATAAATGTTCCTGTCCAGTCACAGTCACCAAACTGACCT +>chr21_31962741_31962791_- +ACATATAACTCAGGTTGGATAAAATAATTTGTACAAATCAGGAGAGTCAA +>chr21_31964683_31964733_+ +TCTGATTCACTGAGGCATATAAAAGGCCCTCTGCGGAGAAGTGTCCATAC +>chr21_31973364_31973414_+ +aaacttaaaactctataaacttaaaactCTAGAATCTGATCCTGCTATAC +>chr21_31992870_31992920_+ +CTCATACACTATTGAAGATGTATAAAATTTCATTTGCAGATGGTGACATT +>chr21_32185595_32185645_- +TCACCACCCACCAGAGCTGGGATATATAAAGAAGGTTCTGAGACTAGGAA +>chr21_32202076_32202126_- +TGCCCACCAGCTTGAGGTATAAAAAGCCCTGTACGGGAAGAGACCTTCAT +>chr21_32253899_32253949_- +AGCCCCACCCACCAGCAAGGATATATAAAAGCTCAGGAGTCTGGAGTGAC +>chr21_32410820_32410870_- +TCTACCCCACTAATCACTGAGGATGTATAAAAGTCCCAGGGAAGCTGGTG +>chr21_36411748_36411798_- +ATAGTTCTGTATAGTTTCAGTTGGCATCtaaaaattatataactttattt +>chr21_37838750_37838800_- +gatggttttataaggggcctcaccctcggctcagccctcattcttctcct +>chr21_45705687_45705737_+ +CCGGGGCGGAGCGGCCTTTGCTCTTTGCGTGGTCGCGGGGGTATAACAGC +>chr21_45971413_45971463_- +CAGGCCCTGGGCATATAAAAGCCCCAGCAGCCAACAGGctcacacacaca +>chr21_45978668_45978718_- +CAGAGGGGTATAAAGGTTCCGACCACTCAGAGGCCTGGCACGAtcactca +>chr21_45993530_45993580_+ +CCAAGGAGGAGTATAAAAGCCCCACAAACCCGAGCACCTCACTCACTCGC +>chr21_46020421_46020471_+ +GAGACATATAAAAGCCAACATCCCTGAGCACCTAACACACGGactcactc +>chr21_46031920_46031970_+ +GGAAAATACCCAGGGAGGGTATAAAACCTCAGCAGCCAGGGCACACAAAC +>chr21_46046964_46047014_+ +ACAAGGCCAGGAGGGGTATAAAAGCCTGAGAGCCCCAAGAACctcacaca +>chr21_46057197_46057247_+ +ATTGCTGAGTCTCCTGCTGGGAAAACACAGGCCCTGGGCATATAAAAGCC +>chr21_46086869_46086919_- +GACAGGTGTGCTTCTGTGCTGTGGGGATGCCTGGGCCCAGGTATAAAGGC +>chr21_46102103_46102153_- +AGGTGTGTGCTTCTGTGCTGTGGGGATGCCTGGGTCCAGGTATAAAGGCT +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGmGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGGAGGTGmTGCCGGTGAGCGTATAAAGGCCCTGGCG +>chr21_47575506_47575556_- +TGAGAAGCmGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/meme_output_custom.html Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,276 @@ + "options": { + "mod": "zoops", + "revcomp": false, + "nmotifs": 1, + "objfun": "E-value of product of p-values", + "spfun": "E-value of product of p-values", + "minw": 8, + "maxw": 50, + "minsites": 2, + "maxsites": 30, + "wnsites": 0.8, + "spmap": "uni", + "spfuzz": 0.5, + "searchsize": 1500, + "maxsize": 1000000, + "norand": "no", + "csites": 1000, + "hsfrac": 0, + "prior": "dirichlet", + "b": 0.01, + "maxiter": 50, + "distance": 0.001, + "wg": 11, + "ws": 1, + "noendgaps": false, + "substring": true, + "seed": 0, + "brief": 1000 + }, + "alphabet": { + "name": "DNA with covalent modifications", + "like": "dna", + "ncore": 16, + "symbols": [ + { + "symbol": "A", + "name": "Adenine", + "colour": "8510A8", + "complement": "T" + }, { + "symbol": "C", + "name": "Cytosine", + "colour": "A50026", + "complement": "G" + }, { + "symbol": "G", + "name": "Guanine", + "colour": "313695", + "complement": "C" + }, { + "symbol": "T", + "name": "Thymine", + "colour": "A89610", + "complement": "A" + }, { + "symbol": "a", + "name": "N6-methyladenine", + "colour": "8510A8", + "complement": "t" + }, { + "symbol": "c", + "name": "5-Carboxylcytosine", + "colour": "FEE090", + "complement": "4" + }, { + "symbol": "f", + "name": "5-Formylcytosine", + "colour": "FDAE61", + "complement": "3" + }, { + "symbol": "g", + "name": "modified_g", + "colour": "00897B", + "complement": "5" + }, { + "symbol": "h", + "name": "5-Hydroxymethylcytosine", + "colour": "F46D43", + "complement": "2" + }, { + "symbol": "m", + "name": "5-Methylcytosine", + "colour": "D73027", + "complement": "1" + }, { + "symbol": "t", + "name": "Thymine_lowercase", + "colour": "756BB1", + "complement": "a" + }, { + "symbol": "1", + "name": "Guanine:5-Methylcytosine", + "colour": "4575B4", + "complement": "m" + }, { + "symbol": "2", + "name": "Guanine:5-Hydroxymethylcytosine", + "colour": "74ADD1", + "complement": "h" + }, { + "symbol": "3", + "name": "Guanine:5-Formylcytosine", + "colour": "ABD9E9", + "complement": "f" + }, { + "symbol": "4", + "name": "Guanine:5-Carboxylcytosine", + "colour": "E0F3F8", + "complement": "c" + }, { + "symbol": "5", + "name": "cytosine_lowercase", + "colour": "53698A", + "complement": "g" + }, { + "symbol": "?", + "equals": "ACGTacfghmt12345" + } + ] + }, + "background": { + "source": "--sequences--", + "order": 0, + "freqs": [ + 0.263, 0.2, 0.249, 0.189, 0.0297, 0.027, 0.00066, 0.00726, + 0.00066, 0.00396, 0.0277, 0.00066, 0.00066, 0.00066, 0.00066, + 0.00066 + ] + }, + "sequence_db": { + "primary_source": "Galaxy_FASTA_Input", + "primary_count": 30, + "primary_positions": 1500, + "control_source": "--none--", + "control_count": 0, + "control_positions": 0, + "freqs": [ + 0.265, 0.201, 0.251, 0.19, 0.0293, 0.0267, 0, 0.00667, 0, 0.00333, + 0.0273, 0, 0, 0, 0, 0 + ], + "sequences": [ + { + "name": "chr21_19617074_19617124_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_26934381_26934431_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_28217753_28217803_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31710037_31710087_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31744582_31744632_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31768316_31768366_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31914206_31914256_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31933633_31933683_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31962741_31962791_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31964683_31964733_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31973364_31973414_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31992870_31992920_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32185595_32185645_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32202076_32202126_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32253899_32253949_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32410820_32410870_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_36411748_36411798_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_37838750_37838800_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45705687_45705737_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45971413_45971463_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45978668_45978718_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45993530_45993580_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46020421_46020471_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46031920_46031970_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46046964_46047014_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46057197_46057247_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46086869_46086919_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46102103_46102153_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_47517957_47518007_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_47575506_47575556_-", + "length": 50, + "weight": 1.000000 + } + ] + }, + "motifs": [ + { + "db": 0, + "id": "taCaaACAGtataactctcac", + "alt": "MEME-1", + "len": 21, + "nsites": 5, + "evalue": "4.6e-028", + "ic": 55.7, + "re": 68.0, + "llr": 236, + "bt": 7.73664, \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/meme_output_custom.txt Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,61 @@ +******************************************************************************** +MEME - Motif discovery tool +******************************************************************************** +MEME version 5.5.8 (Release date: Thu May 15 15:01:46 2025 -0700) + +For further information on how to interpret these results please access https://meme-suite.org/meme. +To get a copy of the MEME Suite software please access https://meme-suite.org. + +******************************************************************************** + + +******************************************************************************** +REFERENCE +******************************************************************************** +If you use this program in your research, please cite: + +Timothy L. Bailey and Charles Elkan, +"Fitting a mixture model by expectation maximization to +discover motifs in biopolymers", +Proceedings of the Second International Conference on Intelligent Systems +for Molecular Biology, pp. 28-36, AAAI Press, Menlo Park, California, 1994. +******************************************************************************** + + +******************************************************************************** +ALPHABET "DNA with covalent modifications" DNA-LIKE +******************************************************************************** +A "Adenine" 8510A8 ~ T "Thymine" A89610 +C "Cytosine" A50026 ~ G "Guanine" 313695 +a "N6-methyladenine" 8510A8 ~ t "Thymine_lowercase" 756BB1 +c "5-Carboxylcytosine" FEE090 ~ 4 "Guanine:5-Carboxylcytosine" E0F3F8 +f "5-Formylcytosine" FDAE61 ~ 3 "Guanine:5-Formylcytosine" ABD9E9 +g "modified_g" 00897B ~ 5 "cytosine_lowercase" 53698A +h "5-Hydroxymethylcytosine" F46D43 ~ 2 "Guanine:5-Hydroxymethylcytosine" 74ADD1 +m "5-Methylcytosine" D73027 ~ 1 "Guanine:5-Methylcytosine" 4575B4 +? = ACGTacfghmt12345 +******************************************************************************** + +******************************************************************************** +TRAINING SET +******************************************************************************** +PRIMARY SEQUENCES= Galaxy_FASTA_Input +CONTROL SEQUENCES= --none-- +Sequence name Weight Length Sequence name Weight Length +------------- ------ ------ ------------- ------ ------ +chr21_19617074_19617124_ 1.0000 50 chr21_26934381_26934431_ 1.0000 50 +chr21_28217753_28217803_ 1.0000 50 chr21_31710037_31710087_ 1.0000 50 +chr21_31744582_31744632_ 1.0000 50 chr21_31768316_31768366_ 1.0000 50 +chr21_31914206_31914256_ 1.0000 50 chr21_31933633_31933683_ 1.0000 50 +chr21_31962741_31962791_ 1.0000 50 chr21_31964683_31964733_ 1.0000 50 +chr21_31973364_31973414_ 1.0000 50 chr21_31992870_31992920_ 1.0000 50 +chr21_32185595_32185645_ 1.0000 50 chr21_32202076_32202126_ 1.0000 50 +chr21_32253899_32253949_ 1.0000 50 chr21_32410820_32410870_ 1.0000 50 +chr21_36411748_36411798_ 1.0000 50 chr21_37838750_37838800_ 1.0000 50 +chr21_45705687_45705737_ 1.0000 50 chr21_45971413_45971463_ 1.0000 50 +chr21_45978668_45978718_ 1.0000 50 chr21_45993530_45993580_ 1.0000 50 +chr21_46020421_46020471_ 1.0000 50 chr21_46031920_46031970_ 1.0000 50 +chr21_46046964_46047014_ 1.0000 50 chr21_46057197_46057247_ 1.0000 50 +chr21_46086869_46086919_ 1.0000 50 chr21_46102103_46102153_ 1.0000 50 +chr21_47517957_47518007_ 1.0000 50 chr21_47575506_47575556_ 1.0000 50 +******************************************************************************** \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/meme_output_custom.xml Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,946 @@ +<alphabet_matrix> +<alphabet_array> +<value letter_id="A">61</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">443</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">0</value> +<value letter_id="G">-31</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">285</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">100</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">285</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">0</value> +<value letter_id="G">-897</value> +<value letter_id="T">8</value> +<value letter_id="a">433</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">61</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">433</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">61</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">100</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">288</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">285</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">61</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">385</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">0</value> +<value letter_id="G">-31</value> +<value letter_id="T">-897</value> +<value letter_id="a">275</value> +<value letter_id="c">288</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-39</value> +<value letter_id="C">-897</value> +<value letter_id="G">-31</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">288</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">385</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">0</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">388</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-31</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">485</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-31</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">388</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">507</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">275</value> +<value letter_id="c">488</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">275</value> +<value letter_id="c">388</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">385</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">-897</value> +<value letter_id="c">447</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">385</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">443</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">447</value> +<value letter_id="f">-897</value> +<value letter_id="g">-897</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">-897</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">375</value> +<value letter_id="c">-897</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">385</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-897</value> +<value letter_id="C">-897</value> +<value letter_id="G">-897</value> +<value letter_id="T">-897</value> +<value letter_id="a">275</value> +<value letter_id="c">388</value> +<value letter_id="f">-897</value> +<value letter_id="g">478</value> +<value letter_id="h">-897</value> +<value letter_id="m">-897</value> +<value letter_id="t">285</value> +<value letter_id="n1">-897</value> +<value letter_id="n2">-897</value> +<value letter_id="n3">-897</value> +<value letter_id="n4">-897</value> +<value letter_id="n5">-897</value> +</alphabet_array> +</alphabet_matrix> +</scores> +<probabilities> +<alphabet_matrix> +<alphabet_array> +<value letter_id="A">0.400000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.600000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.200000</value> +<value letter_id="G">0.200000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.200000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.400000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.200000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.200000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.200000</value> +<value letter_id="a">0.600000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.400000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.600000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.400000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.400000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.200000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.200000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.400000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.400000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.200000</value> +<value letter_id="G">0.200000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.200000</value> +<value letter_id="c">0.200000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.200000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.200000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.200000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.400000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.200000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.400000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.200000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.800000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.200000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.400000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">1.000000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.200000</value> +<value letter_id="c">0.800000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.200000</value> +<value letter_id="c">0.400000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.400000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.000000</value> +<value letter_id="c">0.600000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.400000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.600000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.600000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.000000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.000000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.400000</value> +<value letter_id="c">0.000000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.400000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="a">0.200000</value> +<value letter_id="c">0.400000</value> +<value letter_id="f">0.000000</value> +<value letter_id="g">0.200000</value> +<value letter_id="h">0.000000</value> +<value letter_id="m">0.000000</value> +<value letter_id="t">0.200000</value> +<value letter_id="n1">0.000000</value> +<value letter_id="n2">0.000000</value> +<value letter_id="n3">0.000000</value> +<value letter_id="n4">0.000000</value> +<value letter_id="n5">0.000000</value> +</alphabet_array> +</alphabet_matrix> +</probabilities> +<regular_expression> +[tA][aCGt][Cat][aCT][aA][Aag][Ccgt][Atg][CGacg][tAGc][acC][tG][acG]a[ca][cta][ct][ta][ca][atg][cagt] +</regular_expression> +<contributing_sites> +<contributing_site sequence_id="sequence_17" position="8" strand="plus" pvalue="1.01e-33" > +<left_flank>gatggttt</left_flank> +<site> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="g"/> +<letter_ref letter_id="g"/> +<letter_ref letter_id="g"/> +<letter_ref letter_id="g"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="g"/> +<letter_ref letter_id="g"/> +</site> +<right_flank>ctcagccctc</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_16" position="28" strand="plus" pvalue="7.62e-28" > +<left_flank>AGTTGGCATC</left_flank> +<site> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +</site> +<right_flank>t</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_10" position="4" strand="plus" pvalue="2.07e-26" > +<left_flank>aaac</left_flank> +<site> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="a"/> +</site> +<right_flank>actCTAGAAT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_19" position="28" strand="plus" pvalue="8.19e-18" > +<left_flank>AAGCCCCAGC</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +</site> +<right_flank>a</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_22" position="29" strand="plus" pvalue="9.00e-16" > +<left_flank>ATCCCTGAGC</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="a"/> +<letter_ref letter_id="c"/> +<letter_ref letter_id="t"/> +<letter_ref letter_id="c"/> +</site> +<right_flank></right_flank> +</contributing_site> +</contributing_sites> +</motif> +</motifs> +<scanned_sites_summary p_thresh="0.0001"> +<scanned_sites sequence_id="sequence_0" pvalue="9.99e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_1" pvalue="9.78e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_2" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_3" pvalue="9.99e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_4" pvalue="9.99e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_5" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_6" pvalue="9.61e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_7" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_8" pvalue="9.65e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_9" pvalue="9.67e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_10" pvalue="6.20e-25" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="4" pvalue="2.07e-26"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_11" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_12" pvalue="7.25e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_13" pvalue="9.59e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_14" pvalue="7.20e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_15" pvalue="9.99e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_16" pvalue="2.29e-26" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="28" pvalue="7.62e-28"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_17" pvalue="3.02e-32" num_sites="2"><scanned_site motif_id="motif_1" strand="plus" position="8" pvalue="1.01e-33"/> +<scanned_site motif_id="motif_1" strand="plus" position="29" pvalue="1.08e-05"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_18" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_19" pvalue="2.46e-16" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="28" pvalue="8.19e-18"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_20" pvalue="1.27e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="28" pvalue="4.22e-05"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_21" pvalue="9.58e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_22" pvalue="2.70e-14" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="29" pvalue="9.00e-16"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_23" pvalue="9.69e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_24" pvalue="2.53e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="28" pvalue="8.43e-05"/> +</scanned_sites> +<scanned_sites sequence_id="sequence_25" pvalue="9.67e-01" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_26" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_27" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_28" pvalue="1.00e+00" num_sites="0"></scanned_sites> +<scanned_sites sequence_id="sequence_29" pvalue="1.00e+00" num_sites="0"></scanned_sites> +</scanned_sites_summary> +</MEME>
--- a/test-data/meme_output_test1.html Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test1.html Mon Jul 14 21:33:56 2025 +0000 @@ -1,73 +1,124 @@ - <script> - { - $("opt_mod").className = data.options.mod; - $("opt_objfun").textContent = data.options.objfun; - $("opt_spfun").textContent = data.options.spfun; - $("opt_strand").className = (current_alphabet.has_complement() ? (data.options.revcomp ? "both" : "given") : "none"); - $("opt_nmotifs").textContent = data.options.nmotifs; - $("opt_evt").textContent = (typeof data.options.evt === "number" ? data.options.evt : "no limit"); - $("opt_minw").textContent = data.options.minw; - $("opt_maxw").textContent = data.options.maxw; - $("opt_minsites").textContent = data.options.minsites; - $("opt_maxsites").textContent = data.options.maxsites; - $("opt_wnsites").textContent = data.options.wnsites; - $("opt_spmap").className = data.options.spmap; - $("opt_spfuzz").textContent = data.options.spfuzz; - $("opt_prior").className = data.options.prior; - if (data.options.prior == "dirichlet") { - $("opt_prior_source").textContent = make_background_source("Source", data.background.source, true); - } else { - $("opt_prior_source").textContent = (data.options.prior == "addone") ? "motif observed frequencies" : data.options.priors_source; - } - $("opt_b").textContent = (data.options.b < 0) ? "not applicable" : (data.options.b == 0) ? "intrinsic strength" : data.options.b; - $("opt_maxiter").textContent = data.options.maxiter; - $("opt_distance").textContent = data.options.distance; - $("opt_searchsize").textContent = data.options.searchsize; - if (typeof data.options.csites != "undefined") { - $("opt_csites").textContent = data.options.csites; - } else { - $("opt_csites").parentElement.style.display = "none" - } - if (typeof data.options.wg != "undefined") { - $("opt_wg").textContent = data.options.wg; - } else { - $("opt_wg").parentElement.style.display = "none" - } - if (typeof data.options.ws != "undefined") { - $("opt_ws").textContent = data.options.ws; - } - else { - $("opt_ws").parentElement.style.display = "none" - } - if (typeof data.options.noendgaps != "undefined") { - $("opt_noendgaps").className = (data.options.noendgaps ? "on" : "off"); - } - else { - $("opt_noendgaps").parentElement.style.display = "none" - } - $("opt_substring").className = (data.options.substring ? "on" : "off"); - } - </script> - </div> - <!-- list information on this program --> - <div id="info_sec" class="bar"> - <div class="subsection"> - <h5 id="version">MEME version</h5> - <span id="ins_version"></span> - (Release date: <span id="ins_release"></span>)<br> - </div> - <script> - $("ins_version").innerHTML = data["version"]; - $("ins_release").innerHTML = data["release"]; - </script> - <div class="subsection" id="reference"> <script>print_citation("reference", "MEME");</script></div> - <div class="subsection"> - <h5 id="command">Command line</h5> - <textarea id="cmd" rows="5" style="width:100%;" readonly="readonly"> - </textarea> - <script>$("cmd").value = data["cmd"].join(" ");</script> - </div> - </div> - - </body> -</html> + "sequences": [ + { + "name": "chr21_19617074_19617124_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_26934381_26934431_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_28217753_28217803_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31710037_31710087_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31744582_31744632_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31768316_31768366_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31914206_31914256_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31933633_31933683_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31962741_31962791_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31964683_31964733_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31973364_31973414_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_31992870_31992920_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32185595_32185645_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32202076_32202126_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32253899_32253949_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_32410820_32410870_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_36411748_36411798_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_37838750_37838800_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45705687_45705737_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45971413_45971463_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45978668_45978718_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_45993530_45993580_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46020421_46020471_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46031920_46031970_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46046964_46047014_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46057197_46057247_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46086869_46086919_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_46102103_46102153_-", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_47517957_47518007_+", + "length": 50, + "weight": 1.000000 + }, { + "name": "chr21_47575506_47575556_-", + "length": 50, + "weight": 1.000000 + } + ] + }, \ No newline at end of file
--- a/test-data/meme_output_test1.txt Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test1.txt Mon Jul 14 21:33:56 2025 +0000 @@ -1,39 +1,207 @@ +model: mod= zoops nmotifs= 1 evt= inf +objective function: em= E-value of product of p-values + starts= E-value of product of p-values +width: minw= 8 maxw= 50 +nsites: minsites= 2 maxsites= 30 wnsites= 0.8 +theta: spmap= pam spfuzz= 120 +em: prior= megap b= 7500 maxiter= 50 + distance= 1e-05 +trim: wg= 11 ws= 1 endgaps= yes +data: n= 1500 N= 30 +sample: seed= 0 hsfrac= 0 + searchsize= 1500 norand= no csites= 1000 +Dirichlet mixture priors file: prior30.plib +Letter frequencies in dataset: +A 0.294 C 0.231 D 0 E 0 F 0 G 0.257 H 0 I 0 K 0 +L 0 M 0 N 0 P 0 Q 0 R 0 S 0 T 0.217 V 0 +W 0 Y 0 +Background letter frequencies (from file dataset with add-one prior applied): +A 0.291 C 0.229 D 0.000658 E 0.000658 F 0.000658 G 0.255 H 0.000658 I 0.000658 K 0.000658 +L 0.000658 M 0.000658 N 0.000658 P 0.000658 Q 0.000658 R 0.000658 S 0.000658 T 0.215 V 0.000658 +W 0.000658 Y 0.000658 +Background model order: 0 ******************************************************************************** -SUMMARY OF MOTIFS + + +******************************************************************************** +MOTIF GGGGTATAAAA MEME-1 width = 11 sites = 25 llr = 239 E-value = 2.4e-011 ******************************************************************************** +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 Description +-------------------------------------------------------------------------------- +Simplified A 2323:a:a8a8 +pos.-specific C ::3:::::::: +probability D ::::::::::: +matrix E ::::::::::: + F ::::::::::: + G 7746::::::1 + H ::::::::::: + I ::::::::::: + K ::::::::::: + L ::::::::::: + M ::::::::::: + N ::::::::::: + P ::::::::::: + Q ::::::::::: + R ::::::::::: + S ::::::::::: + T 1:2:a:a:2:: + V ::::::::::: + W ::::::::::: + Y ::::::::::: + + bits 10.6 + 9.5 + 8.5 + 7.4 +Relative 6.3 +Entropy 5.3 +(13.8 bits) 4.2 + 3.2 + 2.1 * ** + 1.1 ** ******** + 0.0 ----------- + +Multilevel GGGGTATAAAA +consensus AACA T +sequence + + +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 sites sorted by position p-value +-------------------------------------------------------------------------------- +Sequence name Start P-value Site +------------- ----- --------- ----------- +chr21_46046964_46047014_ 13 1.06e-06 AAGGCCAGGA GGGGTATAAAA GCCTGAGAGC +chr21_46057197_46057247_ 37 3.41e-06 ACAGGCCCTG GGCATATAAAA GCC +chr21_45971413_45971463_ 10 3.41e-06 CAGGCCCTG GGCATATAAAA GCCCCAGCAG +chr21_31964683_31964733_ 14 3.41e-06 GATTCACTGA GGCATATAAAA GGCCCTCTGC +chr21_45993530_45993580_ 8 4.00e-06 CCAAGGA GGAGTATAAAA GCCCCACAAA +chr21_32202076_32202126_ 14 5.01e-06 CCACCAGCTT GAGGTATAAAA AGCCCTGTAC +chr21_46031920_46031970_ 16 6.06e-06 ATACCCAGGG AGGGTATAAAA CCTCAGCAGC +chr21_32410820_32410870_ 22 8.67e-06 AATCACTGAG GATGTATAAAA GTCCCAGGGA +chr21_32185595_32185645_ 19 8.67e-06 CACCAGAGCT GGGATATATAA AGAAGGTTCT +chr21_31992870_31992920_ 17 8.67e-06 CACTATTGAA GATGTATAAAA TTTCATTTGC +chr21_46020421_46020471_ 3 1.21e-05 GA GACATATAAAA GCCAACATCC +chr21_47517957_47518007_ 33 1.59e-05 CCGGCGGGGC GGGGTATAAAG GGGGCGG +chr21_45978668_45978718_ 5 1.59e-05 CAGA GGGGTATAAAG GTTCCGACCA +chr21_31914206_31914256_ 16 1.68e-05 CCCACTACTT AGAGTATAAAA TCATTCTGAG +chr21_32253899_32253949_ 20 2.03e-05 CACCAGCAAG GATATATAAAA GCTCAGGAGT +chr21_31744582_31744632_ 13 3.06e-05 CAGGTCTAAG AGCATATATAA CTTGGAGTCC +chr21_19617074_19617124_ 40 3.06e-05 CCTCGGGACG TGGGTATATAA +chr21_45705687_45705737_ 38 3.82e-05 CGTGGTCGCG GGGGTATAACA GC +chr21_31768316_31768366_ 1 3.82e-05 . AACGTATATAA ATGGTCCTGT +chr21_47575506_47575556_ 31 4.02e-05 GCTGCCGGTG AGCGTATAAAG GCCCTGGCG +chr21_26934381_26934431_ 28 5.52e-05 AGTCACAAGT GAGTTATAAAA GGGTCGCACG +chr21_31710037_31710087_ 15 5.94e-05 CCCAGGTTTC TGAGTATATAA TCGCCGCACC +chr21_36411748_36411798_ 23 6.78e-05 AGTTTCAGTT GGCATCtaaaa attatataac +chr21_31933633_31933683_ 3 2.08e-04 TC AGAGTATATAT AAATGTTCCT +chr21_31962741_31962791_ 14 4.05e-04 TATAACTCAG GTTGGATAAAA TAATTTGTAC +-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- - Combined block diagrams: non-overlapping sites with p-value < 0.0001 + Motif GGGGTATAAAA MEME-1 block diagrams -------------------------------------------------------------------------------- -SEQUENCE NAME COMBINED P-VALUE MOTIF DIAGRAM +SEQUENCE NAME POSITION P-VALUE MOTIF DIAGRAM ------------- ---------------- ------------- -chr21_19617074_19617124_ 1.22e-03 39_[1(3.06e-05)] -chr21_26934381_26934431_ 2.21e-03 27_[1(5.52e-05)]_12 -chr21_28217753_28217803_ 7.29e-01 50 -chr21_31710037_31710087_ 2.37e-03 14_[1(5.94e-05)]_25 -chr21_31744582_31744632_ 1.22e-03 12_[1(3.06e-05)]_27 -chr21_31768316_31768366_ 1.53e-03 [1(3.82e-05)]_39 -chr21_31914206_31914256_ 6.70e-04 15_[1(1.68e-05)]_24 -chr21_31933633_31933683_ 1.81e-03 4_[1(4.54e-05)]_35 -chr21_31962741_31962791_ 1.61e-02 50 -chr21_31964683_31964733_ 1.36e-04 13_[1(3.41e-06)]_26 -chr21_31973364_31973414_ 1.99e-01 50 -chr21_31992870_31992920_ 3.47e-04 16_[1(8.67e-06)]_23 -chr21_32185595_32185645_ 3.47e-04 18_[1(8.67e-06)]_21 -chr21_32202076_32202126_ 2.01e-04 13_[1(5.01e-06)]_26 -chr21_32253899_32253949_ 8.11e-04 19_[1(2.03e-05)]_20 -chr21_32410820_32410870_ 3.47e-04 21_[1(8.67e-06)]_18 -chr21_36411748_36411798_ 2.71e-03 22_[1(6.78e-05)]_17 -chr21_37838750_37838800_ 8.23e-02 50 -chr21_45705687_45705737_ 1.53e-03 37_[1(3.82e-05)]_2 -chr21_45971413_45971463_ 1.36e-04 9_[1(3.41e-06)]_30 -chr21_45978668_45978718_ 6.37e-04 4_[1(1.59e-05)]_35 -chr21_45993530_45993580_ 1.60e-04 7_[1(4.00e-06)]_32 -chr21_46020421_46020471_ 4.83e-04 2_[1(1.21e-05)]_37 -chr21_46031920_46031970_ 2.43e-04 15_[1(6.06e-06)]_24 -chr21_46046964_46047014_ 4.26e-05 12_[1(1.06e-06)]_27 -chr21_46057197_46057247_ 1.36e-04 36_[1(3.41e-06)]_3 -chr21_46086869_46086919_ 4.30e-02 50 -chr21_46102103_46102153_ 4.30e-02 50 -chr21_47517957_47518007_ 6.37e-04 32_[1(1.59e-05)]_7 -chr21_47575506_47575556_ 1.61e-03 30_[1(4.02e-05)]_9 +chr21_46046964_46047014_ 1.1e-06 12_[1]_27 +chr21_46057197_46057247_ 3.4e-06 36_[1]_3 +chr21_45971413_45971463_ 3.4e-06 9_[1]_30 +chr21_31964683_31964733_ 3.4e-06 13_[1]_26 +chr21_45993530_45993580_ 4e-06 7_[1]_32 +chr21_32202076_32202126_ 5e-06 13_[1]_26 +chr21_46031920_46031970_ 6.1e-06 15_[1]_24 +chr21_32410820_32410870_ 8.7e-06 21_[1]_18 +chr21_32185595_32185645_ 8.7e-06 18_[1]_21 +chr21_31992870_31992920_ 8.7e-06 16_[1]_23 +chr21_46020421_46020471_ 1.2e-05 2_[1]_37 +chr21_47517957_47518007_ 1.6e-05 32_[1]_7 +chr21_45978668_45978718_ 1.6e-05 4_[1]_35 +chr21_31914206_31914256_ 1.7e-05 15_[1]_24 +chr21_32253899_32253949_ 2e-05 19_[1]_20 +chr21_31744582_31744632_ 3.1e-05 12_[1]_27 +chr21_19617074_19617124_ 3.1e-05 39_[1] +chr21_45705687_45705737_ 3.8e-05 37_[1]_2 +chr21_31768316_31768366_ 3.8e-05 [1]_39 +chr21_47575506_47575556_ 4e-05 30_[1]_9 +chr21_26934381_26934431_ 5.5e-05 27_[1]_12 +chr21_31710037_31710087_ 5.9e-05 14_[1]_25 +chr21_36411748_36411798_ 6.8e-05 22_[1]_17 +chr21_31933633_31933683_ 0.00021 2_[1]_37 +chr21_31962741_31962791_ 0.0004 13_[1]_26 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 in BLOCKS format +-------------------------------------------------------------------------------- +BL MOTIF GGGGTATAAAA width=11 seqs=25 +chr21_46046964_46047014_ ( 13) GGGGTATAAAA 1 +chr21_46057197_46057247_ ( 37) GGCATATAAAA 1 +chr21_45971413_45971463_ ( 10) GGCATATAAAA 1 +chr21_31964683_31964733_ ( 14) GGCATATAAAA 1 +chr21_45993530_45993580_ ( 8) GGAGTATAAAA 1 +chr21_32202076_32202126_ ( 14) GAGGTATAAAA 1 +chr21_46031920_46031970_ ( 16) AGGGTATAAAA 1 +chr21_32410820_32410870_ ( 22) GATGTATAAAA 1 +chr21_32185595_32185645_ ( 19) GGGATATATAA 1 +chr21_31992870_31992920_ ( 17) GATGTATAAAA 1 +chr21_46020421_46020471_ ( 3) GACATATAAAA 1 +chr21_47517957_47518007_ ( 33) GGGGTATAAAG 1 +chr21_45978668_45978718_ ( 5) GGGGTATAAAG 1 +chr21_31914206_31914256_ ( 16) AGAGTATAAAA 1 +chr21_32253899_32253949_ ( 20) GATATATAAAA 1 +chr21_31744582_31744632_ ( 13) AGCATATATAA 1 +chr21_19617074_19617124_ ( 40) TGGGTATATAA 1 +chr21_45705687_45705737_ ( 38) GGGGTATAACA 1 +chr21_31768316_31768366_ ( 1) AACGTATATAA 1 +chr21_47575506_47575556_ ( 31) AGCGTATAAAG 1 +chr21_26934381_26934431_ ( 28) GAGTTATAAAA 1 +chr21_31710037_31710087_ ( 15) TGAGTATATAA 1 +chr21_36411748_36411798_ ( 23) GGCATCTAAAA 1 +chr21_31933633_31933683_ ( 3) AGAGTATATAT 1 +chr21_31962741_31962791_ ( 14) GTTGGATAAAA 1 +// + +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 position-specific scoring matrix +-------------------------------------------------------------------------------- +log-odds matrix: alength= 20 w= 11 n= 1200 bayes= 5.33554 E= 2.4e-011 + -32 -680 91 77 7 138 -20 55 64 107 11 150 142 72 87 396 -148 221 -140 -36 + -11 -680 89 76 7 137 -21 55 63 107 10 149 141 71 87 396 -239 220 -140 -36 + -79 41 4 21 -7 44 -62 42 -5 99 0 99 138 52 42 399 -46 223 -173 -68 + 11 -677 48 47 -2 127 -43 46 27 101 3 124 138 60 62 397 -235 220 -160 -55 + -596 -820 12 -21 -53 -267 -74 37 16 44 -37 98 31 9 19 319 212 127 -193 -95 + 165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8 + -838 -990 -89 -149 -151 -841 -161 -117 -113 -66 -209 -68 -69 -129 -91 111 221 -55 -255 -173 + 176 -858 -79 -103 -115 -717 -148 -95 -108 -17 -162 -61 -12 -95 -69 193 -737 52 -240 -153 + 134 -686 0 16 -12 -553 -68 44 -8 96 -9 88 124 41 36 384 11 216 -177 -71 + 165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8 + 147 -614 89 129 93 -121 12 160 113 217 108 144 144 111 125 447 -241 332 -81 22 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 position-specific probability matrix +-------------------------------------------------------------------------------- +letter-probability matrix: alength= 20 w= 11 nsites= 25 E= 2.4e-011 + 0.240000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.080000 0.000000 0.000000 0.000000 + 0.280000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 + 0.160000 0.320000 0.000000 0.000000 0.000000 0.360000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.160000 0.000000 0.000000 0.000000 + 0.320000 0.000000 0.000000 0.000000 0.000000 0.640000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.960000 0.000000 0.000000 0.000000 + 0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 + 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 + 0.760000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.240000 0.000000 0.000000 0.000000 + 0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 + 0.840000 0.000000 0.000000 0.000000 0.000000 0.120000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGGGTATAAAA MEME-1 regular expression +-------------------------------------------------------------------------------- +[GA][GA][GC][GA]TATA[AT]AA +-------------------------------------------------------------------------------- \ No newline at end of file
--- a/test-data/meme_output_test1.xml Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test1.xml Mon Jul 14 21:33:56 2025 +0000 @@ -1,3 +1,924 @@ +<alphabet_array> +<value letter_id="A">-32</value> +<value letter_id="C">-680</value> +<value letter_id="D">91</value> +<value letter_id="E">77</value> +<value letter_id="F">7</value> +<value letter_id="G">138</value> +<value letter_id="H">-20</value> +<value letter_id="I">55</value> +<value letter_id="K">64</value> +<value letter_id="L">107</value> +<value letter_id="M">11</value> +<value letter_id="N">150</value> +<value letter_id="P">142</value> +<value letter_id="Q">72</value> +<value letter_id="R">87</value> +<value letter_id="S">396</value> +<value letter_id="T">-148</value> +<value letter_id="V">221</value> +<value letter_id="W">-140</value> +<value letter_id="Y">-36</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-11</value> +<value letter_id="C">-680</value> +<value letter_id="D">89</value> +<value letter_id="E">76</value> +<value letter_id="F">7</value> +<value letter_id="G">137</value> +<value letter_id="H">-21</value> +<value letter_id="I">55</value> +<value letter_id="K">63</value> +<value letter_id="L">107</value> +<value letter_id="M">10</value> +<value letter_id="N">149</value> +<value letter_id="P">141</value> +<value letter_id="Q">71</value> +<value letter_id="R">87</value> +<value letter_id="S">396</value> +<value letter_id="T">-239</value> +<value letter_id="V">220</value> +<value letter_id="W">-140</value> +<value letter_id="Y">-36</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-79</value> +<value letter_id="C">41</value> +<value letter_id="D">4</value> +<value letter_id="E">21</value> +<value letter_id="F">-7</value> +<value letter_id="G">44</value> +<value letter_id="H">-62</value> +<value letter_id="I">42</value> +<value letter_id="K">-5</value> +<value letter_id="L">99</value> +<value letter_id="M">0</value> +<value letter_id="N">99</value> +<value letter_id="P">138</value> +<value letter_id="Q">52</value> +<value letter_id="R">42</value> +<value letter_id="S">399</value> +<value letter_id="T">-46</value> +<value letter_id="V">223</value> +<value letter_id="W">-173</value> +<value letter_id="Y">-68</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">11</value> +<value letter_id="C">-677</value> +<value letter_id="D">48</value> +<value letter_id="E">47</value> +<value letter_id="F">-2</value> +<value letter_id="G">127</value> +<value letter_id="H">-43</value> +<value letter_id="I">46</value> +<value letter_id="K">27</value> +<value letter_id="L">101</value> +<value letter_id="M">3</value> +<value letter_id="N">124</value> +<value letter_id="P">138</value> +<value letter_id="Q">60</value> +<value letter_id="R">62</value> +<value letter_id="S">397</value> +<value letter_id="T">-235</value> +<value letter_id="V">220</value> +<value letter_id="W">-160</value> +<value letter_id="Y">-55</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-596</value> +<value letter_id="C">-820</value> +<value letter_id="D">12</value> +<value letter_id="E">-21</value> +<value letter_id="F">-53</value> +<value letter_id="G">-267</value> +<value letter_id="H">-74</value> +<value letter_id="I">37</value> +<value letter_id="K">16</value> +<value letter_id="L">44</value> +<value letter_id="M">-37</value> +<value letter_id="N">98</value> +<value letter_id="P">31</value> +<value letter_id="Q">9</value> +<value letter_id="R">19</value> +<value letter_id="S">319</value> +<value letter_id="T">212</value> +<value letter_id="V">127</value> +<value letter_id="W">-193</value> +<value letter_id="Y">-95</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">165</value> +<value letter_id="C">-261</value> +<value letter_id="D">70</value> +<value letter_id="E">110</value> +<value letter_id="F">77</value> +<value letter_id="G">-521</value> +<value letter_id="H">-4</value> +<value letter_id="I">147</value> +<value letter_id="K">95</value> +<value letter_id="L">201</value> +<value letter_id="M">90</value> +<value letter_id="N">121</value> +<value letter_id="P">124</value> +<value letter_id="Q">91</value> +<value letter_id="R">107</value> +<value letter_id="S">425</value> +<value letter_id="T">-527</value> +<value letter_id="V">314</value> +<value letter_id="W">-95</value> +<value letter_id="Y">8</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-838</value> +<value letter_id="C">-990</value> +<value letter_id="D">-89</value> +<value letter_id="E">-149</value> +<value letter_id="F">-151</value> +<value letter_id="G">-841</value> +<value letter_id="H">-161</value> +<value letter_id="I">-117</value> +<value letter_id="K">-113</value> +<value letter_id="L">-66</value> +<value letter_id="M">-209</value> +<value letter_id="N">-68</value> +<value letter_id="P">-69</value> +<value letter_id="Q">-129</value> +<value letter_id="R">-91</value> +<value letter_id="S">111</value> +<value letter_id="T">221</value> +<value letter_id="V">-55</value> +<value letter_id="W">-255</value> +<value letter_id="Y">-173</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">176</value> +<value letter_id="C">-858</value> +<value letter_id="D">-79</value> +<value letter_id="E">-103</value> +<value letter_id="F">-115</value> +<value letter_id="G">-717</value> +<value letter_id="H">-148</value> +<value letter_id="I">-95</value> +<value letter_id="K">-108</value> +<value letter_id="L">-17</value> +<value letter_id="M">-162</value> +<value letter_id="N">-61</value> +<value letter_id="P">-12</value> +<value letter_id="Q">-95</value> +<value letter_id="R">-69</value> +<value letter_id="S">193</value> +<value letter_id="T">-737</value> +<value letter_id="V">52</value> +<value letter_id="W">-240</value> +<value letter_id="Y">-153</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">134</value> +<value letter_id="C">-686</value> +<value letter_id="D">0</value> +<value letter_id="E">16</value> +<value letter_id="F">-12</value> +<value letter_id="G">-553</value> +<value letter_id="H">-68</value> +<value letter_id="I">44</value> +<value letter_id="K">-8</value> +<value letter_id="L">96</value> +<value letter_id="M">-9</value> +<value letter_id="N">88</value> +<value letter_id="P">124</value> +<value letter_id="Q">41</value> +<value letter_id="R">36</value> +<value letter_id="S">384</value> +<value letter_id="T">11</value> +<value letter_id="V">216</value> +<value letter_id="W">-177</value> +<value letter_id="Y">-71</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">165</value> +<value letter_id="C">-261</value> +<value letter_id="D">70</value> +<value letter_id="E">110</value> +<value letter_id="F">77</value> +<value letter_id="G">-521</value> +<value letter_id="H">-4</value> +<value letter_id="I">147</value> +<value letter_id="K">95</value> +<value letter_id="L">201</value> +<value letter_id="M">90</value> +<value letter_id="N">121</value> +<value letter_id="P">124</value> +<value letter_id="Q">91</value> +<value letter_id="R">107</value> +<value letter_id="S">425</value> +<value letter_id="T">-527</value> +<value letter_id="V">314</value> +<value letter_id="W">-95</value> +<value letter_id="Y">8</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">147</value> +<value letter_id="C">-614</value> +<value letter_id="D">89</value> +<value letter_id="E">129</value> +<value letter_id="F">93</value> +<value letter_id="G">-121</value> +<value letter_id="H">12</value> +<value letter_id="I">160</value> +<value letter_id="K">113</value> +<value letter_id="L">217</value> +<value letter_id="M">108</value> +<value letter_id="N">144</value> +<value letter_id="P">144</value> +<value letter_id="Q">111</value> +<value letter_id="R">125</value> +<value letter_id="S">447</value> +<value letter_id="T">-241</value> +<value letter_id="V">332</value> +<value letter_id="W">-81</value> +<value letter_id="Y">22</value> +</alphabet_array> +</alphabet_matrix> +</scores> +<probabilities> +<alphabet_matrix> +<alphabet_array> +<value letter_id="A">0.240000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.680000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.080000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.280000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.680000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.040000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.160000</value> +<value letter_id="C">0.320000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.360000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.160000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.320000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.640000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.040000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.040000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.960000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.960000</value> +<value letter_id="C">0.040000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">1.000000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">1.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.760000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.240000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.960000</value> +<value letter_id="C">0.040000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.000000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.840000</value> +<value letter_id="C">0.000000</value> +<value letter_id="D">0.000000</value> +<value letter_id="E">0.000000</value> +<value letter_id="F">0.000000</value> +<value letter_id="G">0.120000</value> +<value letter_id="H">0.000000</value> +<value letter_id="I">0.000000</value> +<value letter_id="K">0.000000</value> +<value letter_id="L">0.000000</value> +<value letter_id="M">0.000000</value> +<value letter_id="N">0.000000</value> +<value letter_id="P">0.000000</value> +<value letter_id="Q">0.000000</value> +<value letter_id="R">0.000000</value> +<value letter_id="S">0.000000</value> +<value letter_id="T">0.040000</value> +<value letter_id="V">0.000000</value> +<value letter_id="W">0.000000</value> +<value letter_id="Y">0.000000</value> +</alphabet_array> +</alphabet_matrix> +</probabilities> +<regular_expression> +[GA][GA][GC][GA]TATA[AT]AA +</regular_expression> +<contributing_sites> +<contributing_site sequence_id="sequence_24" position="12" strand="none" pvalue="1.06e-06" > +<left_flank>AAGGCCAGGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCTGAGAGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_25" position="36" strand="none" pvalue="3.41e-06" > +<left_flank>ACAGGCCCTG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_19" position="9" strand="none" pvalue="3.41e-06" > +<left_flank>CAGGCCCTG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCCCAGCAG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_9" position="13" strand="none" pvalue="3.41e-06" > +<left_flank>GATTCACTGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GGCCCTCTGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_21" position="7" strand="none" pvalue="4.00e-06" > +<left_flank>CCAAGGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCCCACAAA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_13" position="13" strand="none" pvalue="5.01e-06" > +<left_flank>CCACCAGCTT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>AGCCCTGTAC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_23" position="15" strand="none" pvalue="6.06e-06" > +<left_flank>ATACCCAGGG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>CCTCAGCAGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_15" position="21" strand="none" pvalue="8.67e-06" > +<left_flank>AATCACTGAG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GTCCCAGGGA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_12" position="18" strand="none" pvalue="8.67e-06" > +<left_flank>CACCAGAGCT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>AGAAGGTTCT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_11" position="16" strand="none" pvalue="8.67e-06" > +<left_flank>CACTATTGAA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TTTCATTTGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_22" position="2" strand="none" pvalue="1.21e-05" > +<left_flank>GA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCAACATCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_28" position="32" strand="none" pvalue="1.59e-05" > +<left_flank>CCGGCGGGGC</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GGGGCGG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_20" position="4" strand="none" pvalue="1.59e-05" > +<left_flank>CAGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GTTCCGACCA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_6" position="15" strand="none" pvalue="1.68e-05" > +<left_flank>CCCACTACTT</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TCATTCTGAG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_14" position="19" strand="none" pvalue="2.03e-05" > +<left_flank>CACCAGCAAG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCTCAGGAGT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_4" position="12" strand="none" pvalue="3.06e-05" > +<left_flank>CAGGTCTAAG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>CTTGGAGTCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_0" position="39" strand="none" pvalue="3.06e-05" > +<left_flank>CCTCGGGACG</left_flank> +<site> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank></right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_18" position="37" strand="none" pvalue="3.82e-05" > +<left_flank>CGTGGTCGCG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_5" position="0" strand="none" pvalue="3.82e-05" > +<left_flank></left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>ATGGTCCTGT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_29" position="30" strand="none" pvalue="4.02e-05" > +<left_flank>GCTGCCGGTG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GCCCTGGCG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_1" position="27" strand="none" pvalue="5.52e-05" > +<left_flank>AGTCACAAGT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GGGTCGCACG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_3" position="14" strand="none" pvalue="5.94e-05" > +<left_flank>CCCAGGTTTC</left_flank> +<site> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TCGCCGCACC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_16" position="22" strand="none" pvalue="6.78e-05" > +<left_flank>AGTTTCAGTT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>attatataac</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_7" position="2" strand="none" pvalue="2.08e-04" > +<left_flank>TC</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +</site> +<right_flank>AAATGTTCCT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_8" position="13" strand="none" pvalue="4.05e-04" > +<left_flank>TATAACTCAG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TAATTTGTAC</right_flank> +</contributing_site> +</contributing_sites> +</motif> </motifs> <scanned_sites_summary p_thresh="0.0001"> <scanned_sites sequence_id="sequence_0" pvalue="1.22e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="39" pvalue="3.06e-05"/>
--- a/test-data/meme_output_test2.html Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test2.html Mon Jul 14 21:33:56 2025 +0000 @@ -1,3 +1,9508 @@ + * See http://stackoverflow.com/a/5450113/66387 + * Does string multiplication like the perl x operator. + */ +function string_mult(pattern, count) { + if (count < 1) return ''; + var result = ''; + while (count > 1) { + if (count & 1) result += pattern; + count >>= 1, pattern += pattern; + } + return result + pattern; +} + +/* + * See http://stackoverflow.com/questions/814613/how-to-read-get-data-from-a-url-using-javascript + * Slightly modified with information from + * https://developer.mozilla.org/en/DOM/window.location + */ +function parse_params() { + "use strict"; + var search, queryStart, queryEnd, query, params, nvPairs, i, nv, n, v; + search = window.location.search; + queryStart = search.indexOf("?") + 1; + queryEnd = search.indexOf("#") + 1 || search.length + 1; + query = search.slice(queryStart, queryEnd - 1); + + if (query === search || query === "") return {}; + + params = {}; + nvPairs = query.replace(/\+/g, " ").split("&"); + + for (i = 0; i < nvPairs.length; i++) { + nv = nvPairs[i].split("="); + n = decodeURIComponent(nv[0]); + v = decodeURIComponent(nv[1]); + // allow a name to be used multiple times + // storing each value in the array + if (!(n in params)) { + params[n] = []; + } + params[n].push(nv.length === 2 ? v : null); + } + return params; +} + +/* + * coords + * + * Calculates the x and y offset of an element. + * From http://www.quirksmode.org/js/findpos.html + * with alterations to take into account scrolling regions + */ +function coords(elem) { + var myX = myY = 0; + if (elem.getBoundingClientRect) { + var rect; + rect = elem.getBoundingClientRect(); + myX = rect.left + ((typeof window.pageXOffset !== "undefined") ? + window.pageXOffset : document.body.scrollLeft); + myY = rect.top + ((typeof window.pageYOffset !== "undefined") ? + window.pageYOffset : document.body.scrollTop); + } else { + // this fall back doesn't properly handle absolutely positioned elements + // inside a scrollable box + var node; + if (elem.offsetParent) { + // subtract all scrolling + node = elem; + do { + myX -= node.scrollLeft ? node.scrollLeft : 0; + myY -= node.scrollTop ? node.scrollTop : 0; + } while (node = node.parentNode); + // this will include the page scrolling (which is unwanted) so add it back on + myX += (typeof window.pageXOffset !== "undefined") ? window.pageXOffset : document.body.scrollLeft; + myY += (typeof window.pageYOffset !== "undefined") ? window.pageYOffset : document.body.scrollTop; + // sum up offsets + node = elem; + do { + myX += node.offsetLeft; + myY += node.offsetTop; + } while (node = node.offsetParent); + } + } + return [myX, myY]; +} + +/* + * position_popup + * + * Positions a popup relative to an anchor element. + * + * The available positions are: + * 0 - Centered below the anchor. + */ +function position_popup(anchor, popup, position) { + "use strict"; + var a_x, a_y, a_w, a_h, p_x, p_y, p_w, p_h; + var a_xy, spacer, margin, scrollbar, page_w; + // define constants + spacer = 5; + margin = 15; + scrollbar = 15; + // define the positions and widths + a_xy = coords(anchor); + a_x = a_xy[0]; + a_y = a_xy[1]; + a_w = anchor.offsetWidth; + a_h = anchor.offsetHeight; + p_w = popup.offsetWidth; + p_h = popup.offsetHeight; + page_w = null; + if (window.innerWidth) { + page_w = window.innerWidth; + } else if (document.body) { + page_w = document.body.clientWidth; + } + // check the position type is defined + if (typeof position !== "number") { + position = 0; + } + // calculate the popup position + switch (position) { + case 1: + p_x = a_x + a_w + spacer; + p_y = a_y + (a_h / 2) - (p_h / 2); + break; + case 0: + default: + p_x = a_x + (a_w / 2) - (p_w / 2); + p_y = a_y + a_h + spacer; + break; + } + // constrain the popup position + if (p_x < margin) { + p_x = margin; + } else if (page_w != null && (p_x + p_w) > (page_w - margin - scrollbar)) { + p_x = page_w - margin - scrollbar - p_w; + } + if (p_y < margin) { + p_y = margin; + } + // position the popup + popup.style.left = p_x + "px"; + popup.style.top = p_y + "px"; +} + +function lookup_help_popup(popup_id) { + var _body, pop, info; + pop = document.getElementById(popup_id); + if (pop == null) { + _body = document.getElementsByTagName("body")[0]; + pop = document.createElement("div"); + pop.className = "pop_content"; + pop.id = popup_id; + pop.style.backgroundColor = "#FFC"; + pop.style.borderColor = "black"; + info = document.createElement("p"); + info.style.fontWeight = "bold"; + info.appendChild(document.createTextNode("Error: No popup for topic \"" + popup_id + "\".")); + pop.appendChild(info); + // this might cause problems with the menu, but as this only happens + // when something is already wrong I don't think that's too much of a problem + _body.insertBefore(pop, _body.firstChild); + } + if (document.getElementsByTagName('body')[0].hasAttribute("data-autobtns")) { + if (!/\bauto_buttons\b/.test(pop.className)) { + pop.className += " auto_buttons"; + var back_btn_sec = document.createElement("div"); + back_btn_sec.className = "nested_only pop_back_sec"; + var back_btn = document.createElement("span"); + back_btn.className = "pop_back"; + back_btn.appendChild(document.createTextNode("<< back")); + back_btn.addEventListener("click", function(e) { + help_return(); + }, false); + back_btn_sec.appendChild(back_btn); + pop.insertBefore(back_btn_sec, pop.firstChild); + var close_btn_sec = document.createElement("div"); + close_btn_sec.className = "pop_close_sec"; + var close_btn = document.createElement("span"); + close_btn.className = "pop_close"; + close_btn.appendChild(document.createTextNode("close")); + close_btn.addEventListener("click", function(e) { + help_popup(); + }, false); + close_btn_sec.appendChild(close_btn); + pop.appendChild(close_btn_sec); + } + } + return pop; +} + +/* + * help_popup + * + * Moves around help pop-ups so they appear + * below an activator. + */ +function help_popup(activator, popup_id) { + "use strict"; + var pop; + // set default values + if (typeof help_popup.popup === "undefined") { + help_popup.popup = []; + } + if (typeof help_popup.activator === "undefined") { + help_popup.activator = null; + } + var last_pop = (help_popup.popup.length > 0 ? help_popup.popup[help_popup.popup.length - 1] : null); + if (typeof(activator) == "undefined") { // no activator so hide + if (last_pop != null) { + last_pop.style.display = 'none'; + help_popup.popup = []; + } + return; + } + pop = lookup_help_popup(popup_id); + if (pop == last_pop) { + if (activator == help_popup.activator) { + //hide popup (as we've already shown it for the current help button) + last_pop.style.display = 'none'; + help_popup.popup = []; + return; // toggling complete! + } + } else if (last_pop != null) { + //activating different popup so hide current one + last_pop.style.display = 'none'; + } + help_popup.popup = [pop]; + help_popup.activator = activator; + toggle_class(pop, "nested", false); + //must make the popup visible to measure it or it has zero width + pop.style.display = 'block'; + position_popup(activator, pop); +} + +/* + * help_refine + * + * Intended for links within a help popup. Stores a stack of state so + * you can go back. + */ +function help_refine(popup_id) { + if (help_popup.popup == null || help_popup.popup.length == 0 || help_popup.activator == null) { + //throw new Error("Cannot refine a help popup when one is not shown!"); + var pop = lookup_help_popup(popup_id); + var act_id = popup_id + '_act'; + var activator = document.getElementById(act_id); + help_popup(activator, popup_id); + } + var pop = lookup_help_popup(popup_id); + var last_pop = help_popup.popup[help_popup.popup.length - 1]; + if (pop == last_pop) return; // slightly odd, but no real cause for alarm + help_popup.popup.push(pop); + toggle_class(pop, "nested", true); + last_pop.style.display = "none"; + //must make the popup visible to measure it or it has zero width + pop.style.display = "block"; + position_popup(help_popup.activator, pop); +} + +/* + * help_return + * + * Intended for links within a help popup. Stores a stack of state so + * you can go back. + */ +function help_return() { + if (help_popup.popup == null || help_popup.popup.length == 0 || help_popup.activator == null) { + throw new Error("Can not return to a earlier help popup when one is not shown!"); + } + var last_pop = help_popup.popup.pop(); + last_pop.style.display = "none"; + var pop = (help_popup.popup.length > 0 ? help_popup.popup[help_popup.popup.length - 1] : null); + if (pop != null) { + toggle_class(pop, "nested", help_popup.popup.length > 1); + pop.style.display = "block"; + position_popup(help_popup.activator, pop); + } else { + help_popup.activator = null; + } +} + +/* + * update_scroll_pad + * + * Creates padding at the bottom of the page to allow + * scrolling of anything into view. + */ +function update_scroll_pad() { + var page, pad; + page = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body; + pad = $("scrollpad"); + if (pad === null) { + pad = document.createElement("div"); + pad.id = 'scrollpad'; + document.getElementsByTagName('body')[0].appendChild(pad); + } + pad.style.height = Math.abs(page.clientHeight - 100) + "px"; +} + +function substitute_classes(node, remove, add) { + "use strict"; + var list, all, i, cls, classes; + list = node.className.split(/\s+/); + all = {}; + for (i = 0; i < list.length; i++) { + if (list[i].length > 0) all[list[i]] = true; + } + for (i = 0; i < remove.length; i++) { + if (all.hasOwnProperty(remove[i])) { + delete all[remove[i]]; + } + } + for (i = 0; i < add.length; i++) { + all[add[i]] = true; + } + classes = ""; + for (cls in all) { + classes += cls + " "; + } + node.className = classes; +} + +/* + * toggle_class + * + * Adds or removes a class from the node. If the parameter 'enabled' is not + * passed then the existence of the class will be toggled, otherwise it will be + * included if enabled is true. + */ +function toggle_class(node, cls, enabled) { + var classes = node.className; + var list = classes.replace(/^\s+/, '').replace(/\s+$/, '').split(/\s+/); + var found = false; + for (var i = 0; i < list.length; i++) { + if (list[i] == cls) { + list.splice(i, 1); + i--; + found = true; + } + } + if (typeof enabled == "undefined") { + if (!found) list.push(cls); + } else { + if (enabled) list.push(cls); + } + node.className = list.join(" "); +} + +/* + * find_child + * + * Searches child nodes in depth first order and returns the first it finds + * with the className specified. + * TODO replace with querySelector + */ +function find_child(node, className) { + var pattern; + if (node == null || typeof node !== "object") { + return null; + } + if (typeof className === "string") { + pattern = new RegExp("\\b" + className + "\\b"); + } else { + pattern = className; + } + if (node.nodeType == Node.ELEMENT_NODE && + pattern.test(node.className)) { + return node; + } else { + var result = null; + for (var i = 0; i < node.childNodes.length; i++) { + result = find_child(node.childNodes[i], pattern); + if (result != null) break; + } + return result; + } +} + +/* + * find_parent + * + * Searches parent nodes outwards from the node and returns the first it finds + * with the className specified. + */ +function find_parent(node, className) { + var pattern; + pattern = new RegExp("\\b" + className + "\\b"); + do { + if (node.nodeType == Node.ELEMENT_NODE && + pattern.test(node.className)) { + return node; + } + } while (node = node.parentNode); + return null; +} + +/* + * find_parent_tag + * + * Searches parent nodes outwards from the node and returns the first it finds + * with the tag name specified. HTML tags should be specified in upper case. + */ +function find_parent_tag(node, tag_name) { + do { + if (node.nodeType == Node.ELEMENT_NODE && node.tagName == tag_name) { + return node; + } + } while (node = node.parentNode); + return null; +} + +/* + * __toggle_help + * + * Uses the 'topic' property of the this object to + * toggle display of a help topic. + * + * This function is not intended to be called directly. + */ +function __toggle_help(e) { + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + + help_popup(this, this.getAttribute("data-topic")); +} + +function setup_help_button(button) { + "use strict"; + var topic; + if (button.hasAttribute("data-topic")) { + topic = button.getAttribute("data-topic"); + if (document.getElementById(topic) != null) { + button.tabIndex = "0"; // make keyboard selectable + button.addEventListener("click", function() { + help_popup(button, topic); + }, false); + button.addEventListener("keydown", function(e) { + // toggle only on Enter or Spacebar, let other keys do their thing + if (e.keyCode !== 13 && e.keyCode !== 32) return; + // stop a submit or something like that + e.preventDefault(); + help_popup(button, topic); + }, false); + } else { + button.style.visibility = "hidden"; + } + } + button.className += " active"; +} + +/* + * help_button + * + * Makes a help button for the passed topic. + */ +function help_button(topic) { + var btn = document.createElement("div"); + btn.className = "help"; + btn.setAttribute("data-topic", topic); + setup_help_button(btn); + return btn; +} + +/* + * prepare_download + * + * Sets the attributes of a link to setup a file download using the given content. + * If no link is provided then create one and click it. + */ +function prepare_download(content, mimetype, filename, link) { + "use strict"; + // if no link is provided then create one and click it + var click_link = false; + if (!link) { + link = document.createElement("a"); + click_link = true; + } + try { + // Use a BLOB to convert the text into a data URL. + // We could do this manually with a base 64 conversion. + // This will only be supported on modern browsers, + // hence the try block. + var blob = new Blob([content], {type: mimetype}); + var reader = new FileReader(); + reader.onloadend = function() { + // If we're lucky the browser will also support the download + // attribute which will let us suggest a file name to save the link. + // Otherwise it is likely that the filename will be unintelligible. + link.setAttribute("download", filename); + link.href = reader.result; + if (click_link) { + // must add the link to click it + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + } + reader.readAsDataURL(blob); + } catch (error) { + if (console && console.log) console.log(error); + // probably an old browser + link.href = ""; + link.visible = false; + } +} + +/* + * add_cell + * + * Add a cell to the table row. + */ +function add_cell(row, node, cls, click_action) { + var cell = row.insertCell(row.cells.length); + if (node) cell.appendChild(node); + if (cls && cls !== "") cell.className = cls; + if (click_action) cell.addEventListener("click", click_action, false); +} + +/* + * add_header_cell + * + * Add a header cell to the table row. + */ +function add_header_cell(row, node, help_topic, cls, colspan, is_new) { + var th = document.createElement("th"); + if (node) th.appendChild(node); + if (help_topic && help_topic !== "") th.appendChild(help_button(help_topic)); + if (is_new && is_new !== "") { + var br = document.createElement("span"); + br.innerHTML = "<br>"; + th.appendChild(br); + var new_icon = document.createElement("img"); + new_icon.src = new_icon_src; + new_icon.alt = "NEW"; + th.appendChild(new_icon); + } + if (cls && cls !== "") th.className = cls; + if (typeof colspan == "number" && colspan > 1) th.colSpan = colspan; + row.appendChild(th); +} + +/* + * add_text_cell + * + * Add a text cell to the table row. + */ +function add_text_cell(row, text, cls, action) { + var node = null; + if (typeof(text) != 'undefined') node = document.createTextNode(text); + add_cell(row, node, cls, action); +} + +/* + * add_text_header_cell + * + * Add a text header cell to the table row. + */ +function add_text_header_cell(row, text, help_topic, cls, action, colspan, is_new) { + var node = null; + if (typeof(text) != 'undefined') { + var nbsp = (help_topic ? "\u00A0" : ""); + var str = "" + text; + var parts = str.split(/\n/); + if (parts.length === 1) { + if (action) { + node = document.createElement("span"); + node.appendChild(document.createTextNode(str + nbsp)); + } else { + node = document.createTextNode(str + nbsp); + } + } else { + node = document.createElement("span"); + for (var i = 0; i < parts.length; i++) { + if (i !== 0) { + node.appendChild(document.createElement("br")); + } + node.appendChild(document.createTextNode(parts[i])); + } + } + if (action) { + node.addEventListener("click", action, false); + node.style.cursor = "pointer"; + } + } + add_header_cell(row, node, help_topic, cls, colspan, is_new); +} + +function setup_help() { + "use strict"; + var help_buttons, i; + help_buttons = document.querySelectorAll(".help:not(.active)"); + for (i = 0; i < help_buttons.length; i++) { + setup_help_button(help_buttons[i]); + } +} + +function setup_scrollpad() { + "use strict"; + if (document.getElementsByTagName('body')[0].hasAttribute("data-scrollpad") && document.getElementById("scrollpad") == null) { + window.addEventListener("resize", update_scroll_pad, false); + update_scroll_pad(); + } +} + +// anon function to avoid polluting global scope +(function() { + "use strict"; + window.addEventListener("load", function load(evt) { + window.removeEventListener("load", load, false); + setup_help(); + setup_scrollpad(); + }, false); +})(); + +/* + * make_link + * + * Creates a text node and if a URL is specified it surrounds it with a link. + * If the URL doesn't begin with "http://" it automatically adds it, as + * relative links don't make much sense in this context. + */ +function make_link(text, url) { + var textNode = null; + var link = null; + if (typeof text !== "undefined" && text !== null) textNode = document.createTextNode(text); + if (typeof url === "string") { + if (url.indexOf("//") == -1) { + url = "http://" + url; + } + link = document.createElement('a'); + link.href = url; + if (textNode) link.appendChild(textNode); + return link; + } + return textNode; +} + +// +// Function to create an HTML paragraph describing the +// MEME Suite background model source. +// +function make_background_source(title, source, text) { + var paraNode = document.createElement("P"); + var titleNode = document.createElement("B"); + var textNode1 = document.createTextNode("\u00A0\u00A0\u00A0\u00A0" + title + ": "); + titleNode.appendChild(textNode1); + var source_text = ((source == "--motif--") ? "the (first) motif file" : (source == "--nrdb--") ? "an old version of the NCBI non-redundant database" : (source == "--uniform--") ? "the uniform model" : (source == "--query--") ? "the query file" : (source == "--sequences--") ? "built from the (primary) sequences" : (source == "--control--") ? "built from the control (negative) sequences" : ((source == "--negatives--") ? "built from the negative (control) sequences" : "the file '" + source + "'")); + if (text) { return source_text; } + var textNode2 = document.createTextNode(source_text); + paraNode.appendChild(titleNode); + paraNode.appendChild(textNode2); + return paraNode; +} + +// Function to create a help button +function make_help_button(container, help_topic) { + container.appendChild(help_button(help_topic)); +} + +// Function to toggle display. +function change_display(id) { + var element=document.getElementById(id); + element.style.display=(element.style.display=='none') ? element.style.display='inline' : element.style.display='none'; +} +</script> + <script> + // + // return true if any part of the passed element is visible in the viewport + // + function element_in_viewport(elem) { + var rect; + try { + rect = elem.getBoundingClientRect(); + } catch (e) { + return false; + } + return ( + rect.top < (window.innerHeight || document.body.clientHeight) && + rect.bottom > 0 && + rect.left < (window.innerWidth || document.body.clientWidth) && + rect.right > 0 + ); + } + + // + // 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 = 300; + // 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 + // + var Drawable = function(elem, task) { + this.elem = elem; + this.task = task; + } + + // + // Drawable.is_visible + // + // Determines if the element is visible in the viewport + // + Drawable.prototype.is_visible = function() { + return element_in_viewport(this.elem); + } + + // + // Drawable.run + // + // Run the task held by the drawable + Drawable.prototype.run = function() { + if (this.task) this.task.run(); + this.task = null; + } + + // + // Drawable.run + // + // Run the task iff visible + // returns true if the task ran or has already run + Drawable.prototype.run_visible = function() { + if (this.task) { + if (element_in_viewport(this.elem)) { + this.task.run(); + this.task = null; + return true; + } + return false; + } else { + return true; + } + } + + // + // draw_on_screen + // + // Checks each drawable object and draws those on screen. + // + function draw_on_screen() { + var found = false; + for (var i = 0; i < drawable_list.length; i++) { + if (drawable_list[i].run_visible()) { + drawable_list.splice(i--, 1); + found = true; + } + } + return found; + } + + // + // process_draw_tasks + // + // Called on a delay to process the next available + // 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()", 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) { + drawable = new Drawable(elem, task); + if (drawable.is_visible()) { + 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); + } + } + +</script> + <script> +function motif_logo_template(inputs) { + function _input(name) { + if (typeof inputs[name] === "undefined") { + throw new Error("Missing template variable: " + name); + } + return inputs[name]; + } + return ( +"%!PS-Adobe-3.0 EPSF-3.0\n" + +"%%Title: Sequence Logo : " + _input("TITLE") + "\n" + +"%%Creator: " + _input("CREATOR") + "\n" + +"%%CreationDate: " + _input("CREATIONDATE") + "\n" + +"%%BoundingBox: 0 0 " + _input("BOUNDINGWIDTH") + " " + _input("BOUNDINGHEIGHT") + " \n" + +"%%Pages: 0\n" + +"%%DocumentFonts: \n" + +"%%EndComments\n" + +"\n" + +"% ---- CONSTANTS ----\n" + +"\/cmfactor 72 2.54 div def % defines points -> cm conversion\n" + +"\/cm {cmfactor mul} bind def % defines centimeters\n" + +"\n" + +"% ---- VARIABLES ----\n" + +"\n" + +"% NA = Nucleic Acid, AA = Amino Acid\n" + +"\/logoType (" + _input("LOGOTYPE") + ") def \n" + +"\n" + +"\/logoTitle (" + _input("TITLE") + ") def\n" + +"\n" + +"% Dimensions in cm\n" + +"\/logoWidth " + _input("LOGOWIDTH") + " cm def\n" + +"\/logoHeight " + _input("LOGOLINEHEIGHT") + " cm def\n" + +"\/totalHeight " + _input("LOGOHEIGHT") + " cm def\n" + +"\n" + +"\/yaxis " + _input("YAXIS") + " def\n" + +"\/yaxisLabel (" + _input("YAXISLABEL") + ") def\n" + +"\/yaxisBits " + _input("BARBITS") + " def % bits\n" + +"\/yaxisTicBits " + _input("TICBITS") + " def\n" + +"\n" + +"\/xaxis " + _input("NUMBERING") + " def\n" + +"\/xaxisLabel (" + _input("XAXISLABEL") + ") def\n" + +"\/showEnds (" + _input("SHOWENDS") + ") def \n" + +"\n" + +"\/showFineprint true def\n" + +"\/fineprint (" + _input("FINEPRINT") + ") def\n" + +"\n" + +"\/charsPerLine " + _input("CHARSPERLINE") + " def\n" + +"\n" + +"\/showingBox " + _input("SHOWINGBOX") + " def \n" + +"\/shrinking false def % true falses\n" + +"\/shrink 1.0 def\n" + +"\/outline " + _input("OUTLINE") + " def\n" + +"\n" + +"\/IbeamFraction " + _input("ERRORBARFRACTION") + " def\n" + +"\/IbeamGray 0.50 def\n" + +"\/IbeamLineWidth 0.5 def\n" + +"\n" + +"\/fontsize " + _input("FONTSIZE") + " def\n" + +"\/titleFontsize " + _input("TITLEFONTSIZE") + " def\n" + +"\/smallFontsize " + _input("SMALLFONTSIZE") + " def\n" + +"\n" + +"\/topMargin " + _input("TOPMARGIN") + " cm def\n" + +"\/bottomMargin " + _input("BOTTOMMARGIN") + " cm def\n" + +"\n" + +"\/defaultColor [0 0 0] def \n" + +"\n" + +_input("COLORDICT") + "\n" + +"\n" + +"\/colorDict fullColourDict def\n" + +"\n" + +"% ---- DERIVED PARAMETERS ----\n" + +"\n" + +"\/leftMargin\n" + +" fontsize 3.5 mul\n" + +"\n" + +"def \n" + +"\n" + +"\/rightMargin \n" + +" %Add extra room if showing ends\n" + +" showEnds (false) eq { fontsize}{fontsize 1.5 mul} ifelse\n" + +"def\n" + +"\n" + +"\/yaxisHeight \n" + +" logoHeight \n" + +" bottomMargin sub \n" + +" topMargin sub\n" + +"def\n" + +"\n" + +"\/ticWidth fontsize 2 div def\n" + +"\n" + +"\/pointsPerBit yaxisHeight yaxisBits div def\n" + +"\n" + +"\/stackMargin 1 def\n" + +"\n" + +"% Do not add space aroung characters if characters are boxed\n" + +"\/charRightMargin \n" + +" showingBox { 0.0 } {stackMargin} ifelse\n" + +"def\n" + +"\n" + +"\/charTopMargin \n" + +" showingBox { 0.0 } {stackMargin} ifelse\n" + +"def\n" + +"\n" + +"\/charWidth\n" + +" logoWidth\n" + +" leftMargin sub\n" + +" rightMargin sub\n" + +" charsPerLine div\n" + +" charRightMargin sub\n" + +"def\n" + +"\n" + +"\/charWidth4 charWidth 4 div def\n" + +"\/charWidth2 charWidth 2 div def\n" + +"\n" + +"\/stackWidth \n" + +" charWidth charRightMargin add\n" + +"def\n" + +" \n" + +"\/numberFontsize \n" + +" fontsize charWidth lt {fontsize}{charWidth} ifelse\n" + +"def\n" + +"\n" + +"% movements to place 5'\/N and 3'\/C symbols\n" + +"\/leftEndDeltaX fontsize neg def\n" + +"\/leftEndDeltaY fontsize 1.5 mul neg def\n" + +"\/rightEndDeltaX fontsize 0.25 mul def\n" + +"\/rightEndDeltaY leftEndDeltaY def\n" + +"\n" + +"% Outline width is proporional to charWidth, \n" + +"% but no less that 1 point\n" + +"\/outlinewidth \n" + +" charWidth 32 div dup 1 gt {}{pop 1} ifelse\n" + +"def\n" + +"\n" + +"\n" + +"% ---- PROCEDURES ----\n" + +"\n" + +"\/StartLogo { \n" + +" % Save state\n" + +" save \n" + +" gsave \n" + +"\n" + +" % Print Logo Title, top center \n" + +" gsave \n" + +" SetStringFont\n" + +"\n" + +" logoWidth 2 div\n" + +" logoTitle\n" + +" stringwidth pop 2 div sub\n" + +" totalHeight\n" + +" titleFontsize sub\n" + +" moveto\n" + +"\n" + +" logoTitle\n" + +" show\n" + +" grestore\n" + +"\n" + +" % Print X-axis label, bottom center\n" + +" gsave\n" + +" SetStringFont\n" + +"\n" + +" logoWidth 2 div\n" + +" xaxisLabel\n" + +" stringwidth pop 2 div sub\n" + +" 0\n" + +" titleFontsize 3 div\n" + +" add\n" + +" moveto\n" + +"\n" + +" xaxisLabel\n" + +" show\n" + +" grestore\n" + +"\n" + +" % Show Fine Print\n" + +" showFineprint {\n" + +" gsave\n" + +" SetSmallFont\n" + +" logoWidth\n" + +" fineprint stringwidth pop sub\n" + +" smallFontsize sub\n" + +" smallFontsize 3 div\n" + +" moveto\n" + +" \n" + +" fineprint show\n" + +" grestore\n" + +" } if\n" + +"\n" + +" % Move to lower left corner of last line, first stack\n" + +" leftMargin bottomMargin translate\n" + +"\n" + +" % Move above first line ready for StartLine \n" + +" 0 totalHeight translate\n" + +"\n" + +" SetLogoFont\n" + +"} bind def\n" + +"\n" + +"\/EndLogo { \n" + +" grestore \n" + +" showpage \n" + +" restore \n" + +"} bind def\n" + +"\n" + +"\n" + +"\/StartLine { \n" + +" % move down to the bottom of the line:\n" + +" 0 logoHeight neg translate\n" + +" \n" + +" gsave \n" + +" yaxis { MakeYaxis } if\n" + +" xaxis { showEnds (true) eq {ShowLeftEnd} if } if\n" + +"} bind def\n" + +"\n" + +"\/EndLine{ \n" + +" xaxis { showEnds (true) eq {ShowRightEnd} if } if\n" + +" grestore \n" + +"} bind def\n" + +"\n" + +"\n" + +"\/MakeYaxis {\n" + +" gsave \n" + +" stackMargin neg 0 translate\n" + +" ShowYaxisBar\n" + +" ShowYaxisLabel\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowYaxisBar { \n" + +" gsave \n" + +" SetStringFont\n" + +"\n" + +" \/str 10 string def % string to hold number \n" + +" \/smallgap stackMargin 2 div def\n" + +"\n" + +" % Draw first tic and bar\n" + +" gsave \n" + +" ticWidth neg 0 moveto \n" + +" ticWidth 0 rlineto \n" + +" 0 yaxisHeight rlineto\n" + +" stroke\n" + +" grestore\n" + +"\n" + +" \n" + +" % Draw the tics\n" + +" % initial increment limit proc for\n" + +" 0 yaxisTicBits yaxisBits abs %cvi\n" + +" {\/loopnumber exch def\n" + +"\n" + +" % convert the number coming from the loop to a string\n" + +" % and find its width\n" + +" loopnumber 10 str cvrs\n" + +" \/stringnumber exch def % string representing the number\n" + +"\n" + +" stringnumber stringwidth pop\n" + +" \/numberwidth exch def % width of number to show\n" + +"\n" + +" \/halfnumberheight\n" + +" stringnumber CharBoxHeight 2 div\n" + +" def\n" + +"\n" + +" numberwidth % move back width of number\n" + +" neg loopnumber pointsPerBit mul % shift on y axis\n" + +" halfnumberheight sub % down half the digit\n" + +"\n" + +" moveto % move back the width of the string\n" + +"\n" + +" ticWidth neg smallgap sub % Move back a bit more \n" + +" 0 rmoveto % move back the width of the tic \n" + +"\n" + +" stringnumber show\n" + +" smallgap 0 rmoveto % Make a small gap \n" + +"\n" + +" % now show the tic mark\n" + +" 0 halfnumberheight rmoveto % shift up again\n" + +" ticWidth 0 rlineto\n" + +" stroke\n" + +" } for\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\/ShowYaxisLabel {\n" + +" gsave\n" + +" SetStringFont\n" + +"\n" + +" % How far we move left depends on the size of\n" + +" % the tic labels.\n" + +" \/str 10 string def % string to hold number \n" + +" yaxisBits yaxisTicBits div cvi yaxisTicBits mul \n" + +" str cvs stringwidth pop\n" + +" ticWidth 1.5 mul add neg \n" + +"\n" + +"\n" + +" yaxisHeight\n" + +" yaxisLabel stringwidth pop\n" + +" sub 2 div\n" + +"\n" + +" translate\n" + +" 90 rotate\n" + +" 0 0 moveto\n" + +" yaxisLabel show\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/StartStack { % <stackNumber> startstack\n" + +" xaxis {MakeNumber}{pop} ifelse\n" + +" gsave\n" + +"} bind def\n" + +"\n" + +"\/EndStack {\n" + +" grestore\n" + +" stackWidth 0 translate\n" + +"} bind def\n" + +"\n" + +"\n" + +"% Draw a character whose height is proportional to symbol bits\n" + +"\/MakeSymbol{ % charbits character MakeSymbol\n" + +" gsave\n" + +" \/char exch def\n" + +" \/bits exch def\n" + +"\n" + +" \/bitsHeight \n" + +" bits pointsPerBit mul \n" + +" def\n" + +"\n" + +" \/charHeight \n" + +" bitsHeight charTopMargin sub\n" + +" dup \n" + +" 0.0 gt {}{pop 0.0} ifelse % if neg replace with zero \n" + +" def \n" + +" \n" + +" charHeight 0.0 gt {\n" + +" char SetColor\n" + +" charWidth charHeight char ShowChar\n" + +"\n" + +" showingBox { % Unfilled box\n" + +" 0 0 charWidth charHeight false ShowBox\n" + +" } if\n" + +"\n" + +"\n" + +" } if\n" + +"\n" + +" grestore\n" + +"\n" + +" 0 bitsHeight translate \n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowChar { % <width> <height> <char> ShowChar\n" + +" gsave\n" + +" \/tc exch def % The character\n" + +" \/ysize exch def % the y size of the character\n" + +" \/xsize exch def % the x size of the character\n" + +"\n" + +" \/xmulfactor 1 def \n" + +" \/ymulfactor 1 def\n" + +" \/limmulfactor 0.01 def\n" + +" \/drawable true def\n" + +"\n" + +" \n" + +" % if ysize is negative, make everything upside down!\n" + +" ysize 0 lt {\n" + +" % put ysize normal in this orientation\n" + +" \/ysize ysize abs def\n" + +" xsize ysize translate\n" + +" 180 rotate\n" + +" } if\n" + +"\n" + +" shrinking {\n" + +" xsize 1 shrink sub 2 div mul\n" + +" ysize 1 shrink sub 2 div mul translate \n" + +"\n" + +" shrink shrink scale\n" + +" } if\n" + +"\n" + +" % Calculate the font scaling factors\n" + +" % Loop twice to catch small correction due to first scaling\n" + +" 2 {\n" + +" gsave\n" + +" xmulfactor ymulfactor scale\n" + +" \n" + +" ysize % desired size of character in points\n" + +" tc CharBoxHeight \n" + +" dup 0.0 ne {\n" + +" div % factor by which to scale up the character\n" + +" \/ymulfactor exch def\n" + +" } % end if\n" + +" {pop pop}\n" + +" ifelse\n" + +"\n" + +" xsize % desired size of character in points\n" + +" tc CharBoxWidth \n" + +" dup 0.0 ne {\n" + +" div % factor by which to scale up the character\n" + +" \/xmulfactor exch def\n" + +" } % end if\n" + +" {pop pop}\n" + +" ifelse\n" + +" grestore\n" + +" % if the multiplication factors get too small we need to avoid a crash\n" + +" xmulfactor limmulfactor lt {\n" + +" \/xmulfactor 1 def\n" + +" \/drawable false def\n" + +" } if\n" + +" ymulfactor limmulfactor lt {\n" + +" \/ymulfactor 1 def\n" + +" \/drawable false def\n" + +" } if\n" + +" } repeat\n" + +"\n" + +" % Adjust horizontal position if the symbol is an I\n" + +" tc (I) eq {\n" + +" charWidth 2 div % half of requested character width\n" + +" tc CharBoxWidth 2 div % half of the actual character\n" + +" sub 0 translate\n" + +" % Avoid x scaling for I \n" + +" \/xmulfactor 1 def \n" + +" } if\n" + +"\n" + +"\n" + +" % ---- Finally, draw the character\n" + +" drawable { \n" + +" newpath\n" + +" xmulfactor ymulfactor scale\n" + +"\n" + +" % Move lower left corner of character to start point\n" + +" tc CharBox pop pop % llx lly : Lower left corner\n" + +" exch neg exch neg\n" + +" moveto\n" + +"\n" + +" outline { % outline characters:\n" + +" outlinewidth setlinewidth\n" + +" tc true charpath\n" + +" gsave 1 setgray fill grestore\n" + +" clip stroke\n" + +" } { % regular characters\n" + +" tc show\n" + +" } ifelse\n" + +" } if\n" + +"\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowBox { % x1 y1 x2 y2 filled ShowBox\n" + +" gsave\n" + +" \/filled exch def \n" + +" \/y2 exch def\n" + +" \/x2 exch def\n" + +" \/y1 exch def\n" + +" \/x1 exch def\n" + +" newpath\n" + +" x1 y1 moveto\n" + +" x2 y1 lineto\n" + +" x2 y2 lineto\n" + +" x1 y2 lineto\n" + +" closepath\n" + +"\n" + +" clip\n" + +" \n" + +" filled {\n" + +" fill\n" + +" }{ \n" + +" 0 setgray stroke \n" + +" } ifelse\n" + +"\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/MakeNumber { % number MakeNumber\n" + +" gsave\n" + +" SetNumberFont\n" + +" stackWidth 0 translate\n" + +" 90 rotate % rotate so the number fits\n" + +" dup stringwidth pop % find the length of the number\n" + +" neg % prepare for move\n" + +" stackMargin sub % Move back a bit\n" + +" charWidth (0) CharBoxHeight % height of numbers\n" + +" sub 2 div %\n" + +" moveto % move back to provide space\n" + +" show\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/Ibeam{ % heightInBits Ibeam\n" + +" gsave\n" + +" % Make an Ibeam of twice the given height in bits\n" + +" \/height exch pointsPerBit mul def \n" + +" \/heightDRAW height IbeamFraction mul def\n" + +"\n" + +" IbeamLineWidth setlinewidth\n" + +" IbeamGray setgray \n" + +"\n" + +" charWidth2 height neg translate\n" + +" ShowIbar\n" + +" newpath\n" + +" 0 0 moveto\n" + +" 0 heightDRAW rlineto\n" + +" stroke\n" + +" newpath\n" + +" 0 height moveto\n" + +" 0 height rmoveto\n" + +" currentpoint translate\n" + +" ShowIbar\n" + +" newpath\n" + +" 0 0 moveto\n" + +" 0 heightDRAW neg rlineto\n" + +" currentpoint translate\n" + +" stroke\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowIbar { % make a horizontal bar\n" + +" gsave\n" + +" newpath\n" + +" charWidth4 neg 0 moveto\n" + +" charWidth4 0 lineto\n" + +" stroke\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowLeftEnd {\n" + +" gsave\n" + +" SetStringFont\n" + +" leftEndDeltaX leftEndDeltaY moveto\n" + +" logoType (NA) eq {(5) show ShowPrime} if\n" + +" logoType (AA) eq {(N) show} if\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowRightEnd { \n" + +" gsave\n" + +" SetStringFont\n" + +" rightEndDeltaX rightEndDeltaY moveto\n" + +" logoType (NA) eq {(3) show ShowPrime} if\n" + +" logoType (AA) eq {(C) show} if\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"\/ShowPrime {\n" + +" gsave\n" + +" SetPrimeFont\n" + +" (\\242) show \n" + +" grestore\n" + +"} bind def\n" + +"\n" + +" \n" + +"\/SetColor{ % <char> SetColor\n" + +" dup colorDict exch known {\n" + +" colorDict exch get aload pop setrgbcolor\n" + +" } {\n" + +" pop\n" + +" defaultColor aload pop setrgbcolor\n" + +" } ifelse \n" + +"} bind def\n" + +"\n" + +"% define fonts\n" + +"\/SetTitleFont {\/Times-Bold findfont titleFontsize scalefont setfont} bind def\n" + +"\/SetLogoFont {\/Helvetica-Bold findfont charWidth scalefont setfont} bind def\n" + +"\/SetStringFont{\/Helvetica-Bold findfont fontsize scalefont setfont} bind def\n" + +"\/SetPrimeFont {\/Symbol findfont fontsize scalefont setfont} bind def\n" + +"\/SetSmallFont {\/Helvetica findfont smallFontsize scalefont setfont} bind def\n" + +"\n" + +"\/SetNumberFont {\n" + +" \/Helvetica-Bold findfont \n" + +" numberFontsize\n" + +" scalefont\n" + +" setfont\n" + +"} bind def\n" + +"\n" + +"%Take a single character and return the bounding box\n" + +"\/CharBox { % <char> CharBox <lx> <ly> <ux> <uy>\n" + +" gsave\n" + +" newpath\n" + +" 0 0 moveto\n" + +" % take the character off the stack and use it here:\n" + +" true charpath \n" + +" flattenpath \n" + +" pathbbox % compute bounding box of 1 pt. char => lx ly ux uy\n" + +" % the path is here, but toss it away ...\n" + +" grestore\n" + +"} bind def\n" + +"\n" + +"\n" + +"% The height of a characters bounding box\n" + +"\/CharBoxHeight { % <char> CharBoxHeight <num>\n" + +" CharBox\n" + +" exch pop sub neg exch pop\n" + +"} bind def\n" + +"\n" + +"\n" + +"% The width of a characters bounding box\n" + +"\/CharBoxWidth { % <char> CharBoxHeight <num>\n" + +" CharBox\n" + +" pop exch pop sub neg \n" + +"} bind def\n" + +"\n" + +"% Set the colour scheme to be faded to indicate trimming\n" + +"\/MuteColour {\n" + +" \/colorDict mutedColourDict def\n" + +"} def\n" + +"\n" + +"% Restore the colour scheme to the normal colours\n" + +"\/RestoreColour {\n" + +" \/colorDict fullColourDict def\n" + +"} def\n" + +"\n" + +"% Draw the background for a trimmed section\n" + +"% takes the number of columns as a parameter\n" + +"\/DrawTrimBg { % <num> DrawTrimBox\n" + +" \/col exch def\n" + +" \n" + +" \/boxwidth \n" + +" col stackWidth mul \n" + +" def\n" + +" \n" + +" gsave\n" + +" 0.97 setgray\n" + +"\n" + +" newpath\n" + +" 0 0 moveto\n" + +" boxwidth 0 rlineto\n" + +" 0 yaxisHeight rlineto\n" + +" 0 yaxisHeight lineto\n" + +" closepath\n" + +" \n" + +" fill\n" + +" grestore\n" + +"} def\n" + +"\n" + +"\/DrawTrimEdge {\n" + +" gsave\n" + +" 0.2 setgray\n" + +" [2] 0 setdash\n" + +"\n" + +" newpath\n" + +" 0 0 moveto\n" + +" 0 yaxisHeight lineto\n" + +" \n" + +" stroke\n" + +"\n" + +"} def\n" + +"\n" + +"\n" + +"% Deprecated names\n" + +"\/startstack {StartStack} bind def\n" + +"\/endstack {EndStack} bind def\n" + +"\/makenumber {MakeNumber} bind def\n" + +"\/numchar { MakeSymbol } bind def\n" + +"\n" + +"%%EndProlog\n" + +"\n" + +"%%Page: 1 1\n" + +"StartLogo\n" + +"\n" + +_input("DATA") + "\n" + +"\n" + +"EndLogo\n" + +"\n" + +"%%EOF\n" + ); +}</script> + <script> +//====================================================================== +// start Alphabet object +//====================================================================== +var Alphabet = function(alphabet, background) { + "use strict"; + var i, j, sym, aliases, complement, comp_e_sym, ambigs, generate_background; + generate_background = (background == null); + if (generate_background) { + background = []; + for (i = 0; i < alphabet.ncore; i++) background[i] = 1.0 / alphabet.ncore; + } else if (alphabet.ncore != background.length) { + throw new Error("The background length does not match the alphabet length."); + } + this.name = alphabet.name; + this.like = (alphabet.like != null ? alphabet.like.toUpperCase() : null); + this.ncore = alphabet.ncore; + this.symbols = alphabet.symbols; + this.background = background; + this.genbg = generate_background; + this.encode = {}; + this.encode2core = {}; + this.complement = {}; + // check if all symbols are same case + var seen_uc = false; + var seen_lc = false; + var check_case = function (syms) { + var s, sym; + if (typeof syms === "string") { + for (s = 0; s < syms.length; s++) { + sym = syms.charAt(s); + if (sym >= 'a' && sym <= 'z') seen_lc = true; + else if (sym >= 'A' && sym <= 'Z') seen_uc = true; + } + } + }; + for (i = 0; i < this.symbols.length; i++) { + check_case(this.symbols[i].symbol); + check_case(this.symbols[i].aliases); + } + // now map symbols to indexes + var update_array = function(array, syms, index) { + var s, sym; + if (typeof syms === "string") { + for (s = 0; s < syms.length; s++) { + sym = syms.charAt(s); + array[sym] = index; + // when only a single case is used, then encode as case insensitive + if (seen_uc != seen_lc) { + if (sym >= 'a' && sym <= 'z') { + array[sym.toUpperCase()] = index; + } else if (sym >= 'A' && sym <= 'Z') { + array[sym.toLowerCase()] = index; + } + } + } + } + } + // map core symbols to index + for (i = 0; i < this.ncore; i++) { + update_array(this.encode2core, this.symbols[i].symbol, i); + update_array(this.encode, this.symbols[i].symbol, i); + update_array(this.encode2core, this.symbols[i].aliases, i); + update_array(this.encode, this.symbols[i].aliases, i); + } + // map ambiguous symbols to index + ambigs = {}; + for (i = this.ncore; i < this.symbols.length; i++) { + update_array(this.encode, this.symbols[i].symbol, i); + update_array(this.encode, this.symbols[i].aliases, i); + ambigs[this.symbols[i].equals] = i; + } + // determine complements + for (i = 0; i < this.ncore; i++) { + complement = this.symbols[i].complement; + if (typeof complement === "string") { + this.complement[i] = this.encode2core[complement]; + } + } + next_symbol: + for (i = this.ncore; i < this.symbols.length; i++) { + complement = ""; + for (j = 0; j < this.symbols[i].equals.length; j++) { + comp_e_sym = this.complement[this.encode2core[this.symbols[i].equals.charAt(j)]]; + if (typeof comp_e_sym !== "number") continue next_symbol; + complement += this.symbols[comp_e_sym].symbol; + } + complement = complement.split("").sort().join(""); + if (typeof ambigs[complement] === "number") { + this.complement[i] = ambigs[complement]; + } + } + // determine case insensitivity + this.case_insensitive = true; + if (seen_uc == seen_lc) { + // when there is a mixture of cases it probably won't + // be case insensitive but we still need to check + loop: + for (i = 0; i < this.symbols.length; i++) { + sym = this.symbols[i].symbol; + if (sym >= 'A' && sym <= 'Z') { + if (this.encode[sym.toLowerCase()] != i) { + this.case_insensitive = false; + break loop; + } + } else if (sym >= 'a' && sym <= 'z') { + if (this.encode[sym.toUpperCase()] != i) { + this.case_insensitive = false; + break loop; + } + } + aliases = this.symbols[i].aliases; + if (aliases != null) { + for (j = 0; j < aliases.length; j++) { + sym = aliases.charAt(j); + if (sym >= 'A' && sym <= 'Z') { + if (this.encode[sym.toLowerCase()] != i) { + this.case_insensitive = false; + break loop; + } + } else if (sym >= 'a' && sym <= 'z') { + if (this.encode[sym.toUpperCase()] != i) { + this.case_insensitive = false; + break loop; + } + } + } + } + } + } + // normalise aliases to remove the prime symbol and eliminate + // the alternate cases when the alphabet is case insensitive + var seen, out; + for (i = 0; i < this.symbols.length; i++) { + sym = this.symbols[i].symbol; + aliases = this.symbols[i].aliases; + if (typeof aliases != "string") aliases = ""; + seen = {}; + out = []; + if (this.case_insensitive) { + sym = sym.toUpperCase(); + aliases = aliases.toUpperCase(); + } + seen[sym] = true; + for (j = 0; j < aliases.length; j++) { + if (!seen[aliases.charAt(j)]) { + seen[aliases.charAt(j)] = true; + out.push(aliases.charAt(j)); + } + } + this.symbols[i].aliases = out.sort().join(""); + } +}; +// return the name of the alphabet +Alphabet.prototype.get_alphabet_name = function() { + return this.name; +}; +// return if the alphabet can be complemented +Alphabet.prototype.has_complement = function() { + return (typeof this.symbols[0].complement === "string"); +}; +// return true if an uppercase letter has the same meaning as the lowercase form +Alphabet.prototype.is_case_insensitive = function() { + return this.case_insensitive; +}; +// return the information content of an alphabet letter +Alphabet.prototype.get_ic = function() { + return Math.log(this.ncore) / Math.LN2; +}; +// return the count of the core alphabet symbols +Alphabet.prototype.get_size_core = function() { + return this.ncore; +}; +// return the count of all alphabet symbols +Alphabet.prototype.get_size_full = function() { + return this.symbols.length; +}; +// return the symbol for the given alphabet index +Alphabet.prototype.get_symbol = function(alph_index) { + "use strict"; + if (alph_index < 0 || alph_index >= this.symbols.length) { + throw new Error("Alphabet index out of bounds"); + } + return this.symbols[alph_index].symbol; +}; +// return the aliases for the given alphabet index +Alphabet.prototype.get_aliases = function(alph_index) { + "use strict"; + if (alph_index < 0 || alph_index >= this.symbols.length) { + throw new Error("Alphabet index out of bounds"); + } + var sym_obj = this.symbols[alph_index]; + return (sym_obj.aliases != null ? sym_obj.aliases : ""); +}; +// return the name for the given alphabet index +Alphabet.prototype.get_name = function(alph_index) { + "use strict"; + var sym; + if (alph_index < 0 || alph_index >= this.symbols.length) { + throw new Error("Alphabet index out of bounds"); + } + sym = this.symbols[alph_index]; + return (typeof sym.name === "string" ? sym.name : sym.symbol); +}; +// return the alphabet it is like or null +Alphabet.prototype.get_like = function() { + "use strict"; + return this.like; +}; +// return the index of the complement for the given alphabet index +Alphabet.prototype.get_complement = function(alph_index) { + var comp_e_sym = this.complement[alph_index]; + if (typeof comp_e_sym === "number") { + return comp_e_sym; + } else { + return -1; + } +}; +// return a string containing the core symbols +Alphabet.prototype.get_symbols = function() { + "use strict"; + var i, core_symbols; + core_symbols = ""; + for (i = 0; i < this.ncore; i++) { + core_symbols += this.symbols[i].symbol; + } + return core_symbols; +}; +// return if the background was not a uniform generated background +Alphabet.prototype.has_bg = function() { + "use strict"; + return !this.genbg; +}; +// get the background frequency for the index +Alphabet.prototype.get_bg_freq = function(alph_index) { + "use strict"; + var freq, i, symbols; + if (alph_index >= 0) { + if (alph_index < this.ncore) { + return this.background[alph_index]; + } else if (alph_index < this.symbols.length) { + freq = 0; + symbols = this.symbols[alph_index].equals; + for (i = 0; i < symbols.length; i++) { + freq += this.background[this.encode2core[symbols.charAt(i)]]; + } + return freq; + } + } + throw new Error("The alphabet index is out of range."); +}; +// get the colour of the index +Alphabet.prototype.get_colour = function(alph_index) { + "use strict"; + if (alph_index < 0 || alph_index >= this.symbols.length) { + throw new Error("BAD_ALPHABET_INDEX"); + } + if (typeof this.symbols[alph_index].colour != "string") { + return "black"; + } + return "#" + this.symbols[alph_index].colour; +}; +// get the rgb components of the colour at the index +Alphabet.prototype.get_rgb = function(alph_index) { + "use strict"; + if (alph_index < 0 || alph_index >= this.symbols.length) { + throw new Error("BAD_ALPHABET_INDEX"); + } + if (typeof this.symbols[alph_index].colour != "string") { + return {"red": 0, "green": 0, "blue": 0}; + } + var colour = this.symbols[alph_index].colour; + var red = parseInt(colour.substr(0, 2), 16) / 255; + var green = parseInt(colour.substr(2, 2), 16) / 255; + var blue = parseInt(colour.substr(4, 2), 16) / 255; + return {"red": red, "green": green, "blue": blue}; +}; +// convert a symbol into the index +Alphabet.prototype.get_index = function(letter) { + "use strict"; + var alph_index; + alph_index = this.encode[letter]; + if (typeof alph_index === "undefined") { + return -1; + } + return alph_index; +}; +// convert a symbol into the list of core indexes that it equals +Alphabet.prototype.get_indexes = function(letter) { + "use strict"; + var alph_index, comprise_str, i, comprise_list; + alph_index = this.encode[letter]; + if (typeof alph_index === "undefined") { + throw new Error("Unknown letter"); + } + comprise_str = this.symbols[alph_index].equals; + comprise_list = []; + if (typeof comprise_str == "string") { + for (i = 0; i < comprise_str.length; i++) { + comprise_list.push(this.encode2core[comprise_str.charAt(i)]); + } + } else { + comprise_list.push(alph_index); + } + return comprise_list; +}; +// check if a symbol is the primary way of representing the symbol in the alphabet +Alphabet.prototype.is_prime_symbol = function(letter) { + var alph_index; + alph_index = this.encode[letter]; + if (alph_index == null) return false; + if (this.is_case_insensitive()) { + return (this.symbols[alph_index].symbol.toUpperCase() == letter.toUpperCase()); + } else { + return (this.symbols[alph_index].symbol == letter); + } +}; +// compare 2 alphabets +Alphabet.prototype.equals = function(other) { + "use strict"; + var i, sym1, sym2; + // first check that it's actually an alphabet object + if (!(typeof other === "object" && other != null && other instanceof Alphabet)) { + return false; + } + // second shortcircuit if it's the same object + if (this === other) return true; + // compare + if (this.name !== other.name) return false; + if (this.ncore !== other.ncore) return false; + if (this.symbols.length !== other.symbols.length) return false; + for (i = 0; i < this.symbols.length; i++) { + sym1 = this.symbols[i]; + sym2 = other.symbols[i]; + if (sym1.symbol !== sym2.symbol) return false; + if (sym1.aliases !== sym2.aliases) return false; + if (sym1.name !== sym2.name) return false; + if (typeof sym1.colour !== typeof sym2.colour || + (typeof sym1.colour === "string" && typeof sym2.colour === "string" && + parseInt(sym1.colour, 16) != parseInt(sym2.colour, 16))) { + return false; + } + if (sym1.complement !== sym2.complement) return false; + if (sym1.equals !== sym2.equals) return false; + } + return true; +}; +Alphabet.prototype.check_core_subset = function(super_alph) { + var complement_same = true; + var seen_set = {}; + var sub_i, sub_symbol, super_i, super_symbol; + for (sub_i = 0; sub_i < this.ncore; sub_i++) { + sub_symbol = this.symbols[sub_i]; + super_i = super_alph.encode[sub_symbol.symbol]; + if (super_i == null) return 0; + super_symbol = super_alph.symbols[super_i]; + if (seen_set[super_i]) return 0; + seen_set[super_i] = true; + // check complement + if (sub_symbol.complement != null && super_symbol.complement != null) { + if (super_alph.encode[sub_symbol.complement] != super_alph.encode[super_symbol.complement]) { + complement_same = false; + } + } else if (sub_symbol.complement != null || super_symbol.complement != null) { + complement_same = false; + } + } + return (complement_same ? 1 : -1); +}; +// convert a sequence to its reverse complement +Alphabet.prototype.invcomp_seq = function(seq) { + "use strict"; + var syms, i, e_sym, comp_e_sym; + if (!this.has_complement()) throw new Error("Alphabet must be complementable"); + syms = seq.split(""); + for (i = 0; i < syms.length; i++) { + e_sym = this.encode[syms[i]]; + if (typeof e_sym === "undefined") { + e_sym = this.ncore; // wildcard + } + comp_e_sym = this.complement[e_sym]; + if (typeof comp_e_sym === "undefined") { + comp_e_sym = e_sym; // not complementable + } + syms[i] = this.symbols[comp_e_sym].symbol; + } + return syms.reverse().join(""); +}; +// convert the alphabet to the text version +Alphabet.prototype.as_text = function() { + "use strict"; + function name_as_text(name) { + var i, c, out; + out = "\""; + for (i = 0; i < name.length; i++) { + c = name.charAt(i); + if (c == "\"") { + out += "\\\""; + } else if (c == "/") { + out += "\\/"; + } else if (c == "\\") { + out += "\\\\"; + } else { + out += c; + } + } + out += "\""; + return out; + } + function symbol_as_text(sym) { + var out; + out = sym.symbol; + if (typeof sym.name === "string" && sym.name != sym.symbol) { + out += " " + name_as_text(sym.name); + } + if (typeof sym.colour === "string") { + out += " " + sym.colour; + } + return out; + } + var out, i, j, c, sym; + out = ""; + // output core symbols with 2 way complements + for (i = 0; i < this.ncore; i++) { + c = this.complement[i]; + if (typeof c === "number" && i < c && this.complement[c] === i) { + out += symbol_as_text(this.symbols[i]) + " ~ " + symbol_as_text(this.symbols[c]) + "\n"; + } + } + // output core symbols with no complement + for (i = 0; i < this.ncore; i++) { + if (typeof this.complement[i] === "undefined") { + out += symbol_as_text(this.symbols[i]) + "\n"; + } + } + // output ambiguous symbols that have comprising characters + for (i = this.ncore; i < this.symbols.length; i++) { + if (this.symbols[i].equals.length == 0) break; + out += symbol_as_text(this.symbols[i]) + " = " + this.symbols[i].equals + "\n"; + if (typeof this.symbols[i].aliases === "string") { + for (j = 0; j < this.symbols[i].aliases.length; j++) { + if (this.symbols[i].aliases.charAt(j) == this.symbols[i].symbol) continue; + out += this.symbols[i].aliases.charAt(j) + " = " + this.symbols[i].equals + "\n"; + } + } + } + // output aliases of core symbols + for (i = 0; i < this.ncore; i++) { + if (typeof this.symbols[i].aliases === "string") { + for (j = 0; j < this.symbols[i].aliases.length; j++) { + if (this.symbols[i].aliases.charAt(j) == this.symbols[i].symbol) continue; + out += this.symbols[i].aliases.charAt(j) + " = " + this.symbols[i].symbol + "\n"; + } + } + } + // output gap symbols + i = this.symbols.length - 1; + if (this.symbols[i].equals.length == 0) { + out += symbol_as_text(this.symbols[i]) + " =\n"; + if (typeof this.symbols[i].aliases === "string") { + for (j = 0; j < this.symbols[i].aliases.length; j++) { + if (this.symbols[i].aliases.charAt(j) == this.symbols[i].symbol) continue; + out += this.symbols[i].aliases.charAt(j) + " =\n"; + } + } + } + return out; +}; +// output the alphabet as it appears in minimal MEME format +Alphabet.prototype.as_meme = function() { + "use strict"; + function name_as_text(name) { + var i, c, out; + out = "\""; + for (i = 0; i < name.length; i++) { + c = name.charAt(i); + if (c == "\"") { + out += "\\\""; + } else if (c == "/") { + out += "\\/"; + } else if (c == "\\") { + out += "\\\\"; + } else { + out += c; + } + } + out += "\""; + return out; + } + if (this.equals(AlphStd.DNA)) { + return "ALPHABET= ACGT\n"; + } else if (this.equals(AlphStd.PROTEIN)) { + return "ALPHABET= ACDEFGHIKLMNPQRSTVWY\n"; + } else { + return "ALPHABET" + + (this.name != null ? " " + name_as_text(this.name) : "") + + (this.like != null ? " " + this.like + "-LIKE" : "") + "\n" + + this.as_text() + "END ALPHABET\n"; + } +}; + +// Returns a table showing all the letters in the alphabet +Alphabet.prototype.as_table = function() { + "use strict"; + var i, j, row, th, td, aliases, equals, sym; + var table = document.createElement("table"); + // create the core symbol header + row = table.insertRow(table.rows.length); + th = document.createElement("th"); + th.appendChild(document.createTextNode("Symbol(s)")); + row.appendChild(th); + th = document.createElement("th"); + th.appendChild(document.createTextNode("Name")); + row.appendChild(th); + th = document.createElement("th"); + if (this.has_complement()) { + th.appendChild(document.createTextNode("Complement")); + } + row.appendChild(th); + // list the core symbols + for (i = 0; i < this.ncore; i++) { + row = table.insertRow(table.rows.length); + td = document.createElement("td"); + if (this.symbols[i].colour != null) { + td.style.color = '#' + this.symbols[i].colour; + } + td.appendChild(document.createTextNode(this.symbols[i].symbol)); + aliases = this.get_aliases(i); + if (aliases.length > 0) { + td.appendChild(document.createTextNode(' ' + aliases.split('').join(' '))); + } + row.appendChild(td); + td = document.createElement("td"); + if (this.symbols[i].name != null) { + td.appendChild(document.createTextNode(this.symbols[i].name)); + } + row.appendChild(td); + td = document.createElement("td"); + if (this.symbols[i].complement != null) { + td.style.color = this.get_colour(this.get_index(this.symbols[i].complement)); + td.appendChild(document.createTextNode(this.symbols[i].complement)); + } + row.appendChild(td); + } + // create the ambiguous symbol header + row = table.insertRow(table.rows.length); + th = document.createElement("th"); + th.appendChild(document.createTextNode("Symbol(s)")); + row.appendChild(th); + th = document.createElement("th"); + th.appendChild(document.createTextNode("Name")); + row.appendChild(th); + th = document.createElement("th"); + th.appendChild(document.createTextNode("Matches")); + row.appendChild(th); + // list the ambiguous symbols + for (i = this.ncore; i < this.symbols.length; i++) { + row = table.insertRow(table.rows.length); + td = document.createElement("td"); + if (this.symbols[i].colour != null) { + td.style.color = '#' + this.symbols[i].colour; + } + td.appendChild(document.createTextNode(this.symbols[i].symbol)); + aliases = this.get_aliases(i); + if (aliases.length > 0) { + td.appendChild(document.createTextNode(' ' + aliases.split('').join(' '))); + } + row.appendChild(td); + td = document.createElement("td"); + if (this.symbols[i].name != null) { + td.appendChild(document.createTextNode(this.symbols[i].name)); + } + row.appendChild(td); + td = document.createElement("td"); + equals = this.symbols[i].equals.split(''); + for (j = 0; j < equals.length; j++) { + if (j != 0) td.appendChild(document.createTextNode(' ')); + sym = document.createElement("span"); + sym.style.color = this.get_colour(this.get_index(equals[j])); + sym.appendChild(document.createTextNode(equals[j])); + td.appendChild(sym); + } + row.appendChild(td); + } + return table; +}; + +// returns a dictionary of the colours for EPS +Alphabet.prototype._as_eps_dict = function() { + "use strict"; + var i, sym, rgb; + var out = "/fullColourDict <<\n"; + for (i = 0; i < this.ncore; i++) { + sym = this.get_symbol(i); + sym = sym.replace(/\\/g, "\\\\"); + sym = sym.replace(/\(/g, "\\("); + sym = sym.replace(/\)/g, "\\)"); + rgb = this.get_rgb(i); + out += " (" + sym + ") [" + rgb.red.toFixed(4) + " " + rgb.green.toFixed(4) + " " + rgb.blue.toFixed(4) + "]\n"; + } + out += ">> def\n"; + out += "/mutedColourDict <<\n"; + for (i = 0; i < this.ncore; i++) { + sym = this.get_symbol(i); + sym = sym.replace(/\\/g, "\\\\"); + sym = sym.replace(/\(/g, "\\("); + sym = sym.replace(/\)/g, "\\)"); + rgb = Alphabet.lighten_colour(this.get_rgb(i)); + out += " (" + sym + ") [" + rgb.red.toFixed(4) + " " + rgb.green.toFixed(4) + " " + rgb.blue.toFixed(4) + "]\n"; + } + out += ">> def\n"; + return out; +}; + +// return the alphabet name or a list of primary symbols +Alphabet.prototype.toString = function() { + "use strict"; + if (this.name != null) { + return this.name; + } else { + return this.get_symbols(); + } +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Helper functions +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// Convert a colour specified in RGB colourspace values into LAB colourspace +Alphabet.rgb2lab = function(rgb) { + "use strict"; + var xyzHelper, labHelper; + // XYZ helper + xyzHelper = function(value) { + if (value > 0.0445) { + value = (value + 0.055) / 1.055; + value = Math.pow(value, 2.4); + } else { + value /= 12.92; + } + value *= 100; + return value; + }; + // lab helper + labHelper = function(value) { + if (value > 0.008856) { + value = Math.pow(value, 1.0 / 3.0); + } else { + value = (7.787 * value) + (16.0 / 116.0); + } + return value; + }; + // convert into XYZ colourspace + var c1, c2, c3; + if (typeof rgb == "number") { + c1 = xyzHelper(((rgb >> 16) & 0xFF) / 255.0); + c2 = xyzHelper(((rgb >> 8) & 0xFF) / 255.0); + c3 = xyzHelper((rgb & 0xFF) / 255.0); + } else { + c1 = xyzHelper(rgb.red); + c2 = xyzHelper(rgb.green); + c3 = xyzHelper(rgb.blue); + } + var x = (c1 * 0.4124) + (c2 * 0.3576) + (c3 * 0.1805); + var y = (c1 * 0.2126) + (c2 * 0.7152) + (c3 * 0.0722); + var z = (c1 * 0.0193) + (c2 * 0.1192) + (c3 * 0.9505); + // convert into Lab colourspace + c1 = labHelper(x / 95.047); + c2 = labHelper(y / 100.0); + c3 = labHelper(z / 108.883); + var l = (116.0 * c2) - 16; + var a = 500.0 * (c1 - c2); + var b = 200.0 * (c2 - c3); + return {"l": l, "a": a, "b": b}; +}; + +// Convert a colour specified in HSV colourspace into RGB colourspace +Alphabet.hsv2rgb = function(hue, sat, value, output_object) { + // achromatic (grey) + var r = value; + var g = value; + var b = value; + if (sat != 0) { + var h = hue / 60.0; + var i = Math.floor(h); + var f = h - i; + var p = value * (1.0 - sat); + var q = value * (1.0 - (sat * f)); + var t = value * (1.0 - (sat * (1.0 - f))); + if (i == 0) { + r = value; + g = t; + b = p; + } else if (i == 1) { + r = q; + g = value; + b = p; + } else if (i == 2) { + r = p; + g = value; + b = t; + } else if (i == 3) { + r = p; + g = q; + b = value; + } else if (i == 4) { + r = t; + g = p; + b = value; + } else { + r = value; + g = p; + b = q; + } + } + if (output_object) { + return {"red": r, "green": g, "blue": b}; + } else { + return (Math.floor(r * 255) << 15) | (Math.floor(g * 255) << 8) | (Math.floor(b * 255)); + } +}; + +// Calculate a distance score between two colours in LAB colourspace +Alphabet.lab_dist = function(lab1, lab2) { + var c1 = Math.sqrt((lab1.l * lab1.l) + (lab1.a * lab1.a)); + var c2 = Math.sqrt((lab2.l * lab2.l) + (lab2.a * lab2.a)); + var dc = c1 - c2; + var dl = lab1.l - lab2.l; + var da = lab1.a - lab2.a; + var db = lab1.b - lab2.b; + // we don't want NaN due to rounding errors so fudge things a bit... + var dh = 0; + var dh_squared = (da * da) + (db * db) - (dc * dc); + if (dh_squared > 0) { + dh = Math.sqrt(dh_squared); + } + var first = dl; + var second = dc / (1.0 + (0.045 * c1)); + var third = dh / (1.0 + (0.015 * c1)); + return Math.sqrt((first * first) + (second * second) + (third * third)); +}; + +// convert an RGB value into a HSL value +Alphabet.rgb2hsl = function(rgb) { + "use strict"; + var min, max, delta, h, s, l, r, g, b; + if (typeof rgb == "number") { + r = ((rgb >> 16) & 0xFF) / 255.0; + g = ((rgb >> 8) & 0xFF) / 255.0; + b = (rgb & 0xFF) / 255.0; + } else { + r = rgb.red; + g = rgb.green; + b = rgb.blue; + } + min = Math.min(r, g, b); + max = Math.max(r, g, b); + delta = max - min; + l = min + (delta / 2); + if (max == min) { + h = 0; // achromatic (grayscale) + s = 0; + } else { + if (l > 0.5) { + s = delta / (2 - max - min); + } else { + s = delta / (max + min); + } + if (max == r) { + h = (g - b) / delta; + if (g < b) h += 6; + } else if (max == g) { + h = ((b - r) / delta) + 2; + } else { + h = ((r - g) / delta) + 4; + } + h /= 6; + } + return {"h": h, "s": s, "l": l}; +}; + +// convert a HSL value into an RGB value +Alphabet.hsl2rgb = function(hsl, output_object) { + "use strict"; + function _hue(p, q, t) { + "use strict"; + if (t < 0) t += 1; + else if (t > 1) t -= 1; + if (t < (1.0 / 6.0)) { + return p + ((q - p) * 6.0 * t); + } else if (t < 0.5) { + return q; + } else if (t < (2.0 / 3.0)) { + return p + ((q - p) * ((2.0 / 3.0) - t) * 6.0); + } else { + return p; + } + } + var r, g, b, p, q; + if (hsl.s == 0) { + // achromatic (grayscale) + r = hsl.l; + g = hsl.l; + b = hsl.l; + } else { + if (hsl.l < 0.5) { + q = hsl.l * (1 + hsl.s); + } else { + q = hsl.l + hsl.s - (hsl.l * hsl.s); + } + p = (2 * hsl.l) - q; + r = _hue(p, q, hsl.h + (1.0 / 3.0)); + g = _hue(p, q, hsl.h); + b = _hue(p, q, hsl.h - (1.0 / 3.0)); + } + if (output_object) { + return {"red": r, "green": g, "blue": b}; + } else { + return (Math.floor(r * 255) << 15) | (Math.floor(g * 255) << 8) | (Math.floor(b * 255)); + } +}; + +Alphabet.lighten_colour = function(rgb) { + "use strict"; + var hsl = Alphabet.rgb2hsl(rgb); + hsl.l += (1.0 - hsl.l) * 2 / 3; + return Alphabet.hsl2rgb(hsl, typeof rgb != "number"); +}; + +//====================================================================== +// end Alphabet object +//====================================================================== + +//====================================================================== +// start StandardAlphabet object +//====================================================================== + +// an extension of the alphabet object to support some additional fields +// only present in standard alphabets. +var StandardAlphabet = function(enum_code, enum_name, alphabet_data) { + Alphabet.apply(this, [alphabet_data]); + this.enum_code = enum_code; + this.enum_name = enum_name; +}; +StandardAlphabet.prototype = Alphabet.prototype; +StandardAlphabet.prototype.constructor = StandardAlphabet; + +// A unique code for this standard alphabet. +// This code will be a power of 2 to enable creation of bitsets for +// a selection of standard alphabets. +StandardAlphabet.prototype.get_code = function() { + return this.enum_code; +}; + +// A unique name for this standard alphabet. +// this name will be all upper case and the same as the property that +// refers to this alphabet in the AlphStd collection. +StandardAlphabet.prototype.get_enum = function() { + return this.enum_name; +}; + +//====================================================================== +// end StandardAlphabet object +//====================================================================== + +// A collection of standard alphabets. +var AlphStd = { + RNA: new StandardAlphabet(1, "RNA", { + "name": "RNA", + "like": "RNA", + "ncore": 4, + "symbols": [ + {"symbol": "A", "name": "Adenine", "colour": "CC0000"}, + {"symbol": "C", "name": "Cytosine", "colour": "0000CC"}, + {"symbol": "G", "name": "Guanine", "colour": "FFB300"}, + {"symbol": "U", "name": "Uracil", "colour": "008000", + "aliases": "T"}, + {"symbol": "N", "name": "Any base", "equals": "ACGU", "aliases": "X."}, + {"symbol": "V", "name": "Not U", "equals": "ACG"}, + {"symbol": "H", "name": "Not G", "equals": "ACU"}, + {"symbol": "D", "name": "Not C", "equals": "AGU"}, + {"symbol": "B", "name": "Not A", "equals": "CGU"}, + {"symbol": "M", "name": "Amino", "equals": "AC"}, + {"symbol": "R", "name": "Purine", "equals": "AG"}, + {"symbol": "W", "name": "Weak", "equals": "AU"}, + {"symbol": "S", "name": "Strong", "equals": "CG"}, + {"symbol": "Y", "name": "Pyrimidine", "equals": "CU"}, + {"symbol": "K", "name": "Keto", "equals": "GU"} + ] + }), + DNA: new StandardAlphabet(2, "DNA", { + "name": "DNA", + "like": "DNA", + "ncore": 4, + "symbols": [ + {"symbol": "A", "name": "Adenine", "colour": "CC0000", "complement": "T"}, + {"symbol": "C", "name": "Cytosine", "colour": "0000CC", "complement": "G"}, + {"symbol": "G", "name": "Guanine", "colour": "FFB300", "complement": "C"}, + {"symbol": "T", "name": "Thymine", "colour": "008000", "complement": "A", + "aliases": "U"}, + {"symbol": "N", "name": "Any base", "equals": "ACGT", "aliases": "X."}, + {"symbol": "V", "name": "Not T", "equals": "ACG"}, + {"symbol": "H", "name": "Not G", "equals": "ACT"}, + {"symbol": "D", "name": "Not C", "equals": "AGT"}, + {"symbol": "B", "name": "Not A", "equals": "CGT"}, + {"symbol": "M", "name": "Amino", "equals": "AC"}, + {"symbol": "R", "name": "Purine", "equals": "AG"}, + {"symbol": "W", "name": "Weak", "equals": "AT"}, + {"symbol": "S", "name": "Strong", "equals": "CG"}, + {"symbol": "Y", "name": "Pyrimidine", "equals": "CT"}, + {"symbol": "K", "name": "Keto", "equals": "GT"} + ] + }), + PROTEIN: new StandardAlphabet(4, "PROTEIN", { + "name": "Protein", + "like": "PROTEIN", + "ncore": 20, + "symbols": [ + {"symbol": "A", "name": "Alanine", "colour": "0000CC"}, + {"symbol": "C", "name": "Cysteine", "colour": "0000CC"}, + {"symbol": "D", "name": "Aspartic acid", "colour": "FF00FF"}, + {"symbol": "E", "name": "Glutamic acid", "colour": "FF00FF"}, + {"symbol": "F", "name": "Phenylalanine", "colour": "0000CC"}, + {"symbol": "G", "name": "Glycine", "colour": "FFB300"}, + {"symbol": "H", "name": "Histidine", "colour": "FFCCCC"}, + {"symbol": "I", "name": "Isoleucine", "colour": "0000CC"}, + {"symbol": "K", "name": "Lysine", "colour": "CC0000"}, + {"symbol": "L", "name": "Leucine", "colour": "0000CC"}, + {"symbol": "M", "name": "Methionine", "colour": "0000CC"}, + {"symbol": "N", "name": "Asparagine", "colour": "008000"}, + {"symbol": "P", "name": "Proline", "colour": "FFFF00"}, + {"symbol": "Q", "name": "Glutamine", "colour": "008000"}, + {"symbol": "R", "name": "Arginine", "colour": "CC0000"}, + {"symbol": "S", "name": "Serine", "colour": "008000"}, + {"symbol": "T", "name": "Threonine", "colour": "008000"}, + {"symbol": "V", "name": "Valine", "colour": "0000CC"}, + {"symbol": "W", "name": "Tryptophan", "colour": "0000CC"}, + {"symbol": "Y", "name": "Tyrosine", "colour": "33E6CC"}, + {"symbol": "X", "name": "Any amino acid", "equals": "ACDEFGHIKLMNPQRSTVWY", "aliases": "*."}, + {"symbol": "B", "name": "Asparagine or Aspartic acid", "equals": "DN"}, + {"symbol": "Z", "name": "Glutamine or Glutamic acid", "equals": "EQ"}, + {"symbol": "J", "name": "Leucine or Isoleucine", "equals": "IL"} + ] + }) +}; + +//====================================================================== +// start Symbol object +//====================================================================== +var Symbol = function(alph_index, scale, alphabet) { + "use strict"; + //variable prototype + this.symbol = alphabet.get_symbol(alph_index); + this.scale = scale; + this.colour = alphabet.get_colour(alph_index); +}; + +Symbol.prototype.get_symbol = function() { + "use strict"; + return this.symbol; +}; + +Symbol.prototype.get_scale = function() { + "use strict"; + return this.scale; +}; + +Symbol.prototype.get_colour = function() { + "use strict"; + return this.colour; +}; + +Symbol.prototype.toString = function() { + "use strict"; + return this.symbol + " " + (Math.round(this.scale*1000)/10) + "%"; +}; + +function compare_symbol(sym1, sym2) { + "use strict"; + 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 +//====================================================================== +var Pspm = function(matrix, name, ltrim, rtrim, nsites, evalue, pssm, alt, pgm) { + "use strict"; + var row, col, data, row_sum, delta, evalue_re; + if (typeof name !== "string") { + name = ""; + } + this.name = name; + //construct + if (matrix instanceof Pspm) { + // copy constructor + this.alph_length = matrix.alph_length; + this.motif_length = matrix.motif_length; + this.name = matrix.name; + this.alt = matrix.alt; + this.nsites = matrix.nsites; + this.evalue = matrix.evalue; + this.ltrim = matrix.ltrim; + this.rtrim = matrix.rtrim; + this.pspm = []; + this.pgm = matrix.pgm; + for (row = 0; row < matrix.motif_length; row++) { + this.pspm[row] = []; + for (col = 0; col < matrix.alph_length; col++) { + this.pspm[row][col] = matrix.pspm[row][col]; + } + } + if (matrix.pssm != null) { + this.pssm = []; + for (row = 0; row < matrix.motif_length; row++) { + this.pspm[row] = []; + for (col = 0; col < matrix.alph_length; col++) { + this.pssm[row][col] = matrix.pssm[row][col]; + } + } + } + } else { + // check parameters + if (ltrim == null) { + ltrim = 0; + } else if (typeof ltrim !== "number" || ltrim % 1 !== 0 || ltrim < 0) { + throw new Error("ltrim must be a non-negative integer, got: " + ltrim); + } + if (rtrim == null) { + rtrim = 0; + } else if (typeof rtrim !== "number" || rtrim % 1 !== 0 || rtrim < 0) { + throw new Error("rtrim must be a non-negative integer, got: " + rtrim); + } + if (nsites != null) { + if (typeof nsites !== "number" || nsites < 0) { + throw new Error("nsites must be a positive number, got: " + nsites); + } else if (nsites == 0) { + nsites = null; + } + } + if (evalue != null) { + if (typeof evalue === "number") { + if (evalue < 0) { + throw new Error("evalue must be a non-negative number, got: " + evalue); + } + } else if (typeof evalue === "string") { + evalue_re = /^((?:[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)|inf)$/; + if (!evalue_re.test(evalue)) { + throw new Error("evalue must be a non-negative number, got: " + evalue); + } + } else { + throw new Error("evalue must be a non-negative number, got: " + evalue); + } + } + // set properties + this.name = name; + this.alt = alt; + this.nsites = nsites; + this.evalue = evalue; + this.ltrim = ltrim; + this.rtrim = rtrim; + this.pgm = pgm; + if (typeof matrix === "string") { + // string constructor + data = parse_pspm_string(matrix); + this.alph_length = data["alph_length"]; + this.motif_length = data["motif_length"]; + this.pspm = data["pspm"]; + if (this.evalue == null) { + if (data["evalue"] != null) { + this.evalue = data["evalue"]; + } else { + this.evalue = 0; + } + } + if (this.nsites == null) { + if (typeof data["nsites"] === "number") { + this.nsites = data["nsites"]; + } else { + this.nsites = 20; + } + } + } else { + // assume pspm is a nested array + this.motif_length = matrix.length; + this.alph_length = (matrix.length > 0 ? matrix[0].length : 0); + if (this.nsites == null) { + this.nsites = 20; + } + if (this.evalue == null) { + this.evalue = 0; + } + this.pspm = []; + // copy pspm and check + for (row = 0; row < this.motif_length; row++) { + if (this.alph_length != matrix[row].length) { + throw new Error("COLUMN_MISMATCH"); + } + this.pspm[row] = []; + row_sum = 0; + for (col = 0; col < this.alph_length; col++) { + this.pspm[row][col] = matrix[row][col]; + row_sum += this.pspm[row][col]; + } + delta = 0.1; + if (isNaN(row_sum) || (row_sum > 1 && (row_sum - 1) > delta) || + (row_sum < 1 && (1 - row_sum) > delta)) { + throw new Error("INVALID_SUM"); + } + } + // copy pssm + if (pssm != null) { + this.pssm = []; + for (row = 0; row < this.motif_length; row++) { + this.pssm[row] = []; + for (col = 0; col < this.alph_length; col++) { + this.pssm[row][col] = pssm[row][col]; + } + } + } + } + } +}; + +Pspm.prototype.copy = function() { + "use strict"; + return new Pspm(this); +}; + +Pspm.prototype.reverse = function() { + "use strict"; + var x, y, temp, temp_trim; + //reverse + x = 0; + y = this.motif_length-1; + while (x < y) { + temp = this.pspm[x]; + this.pspm[x] = this.pspm[y]; + this.pspm[y] = temp; + x++; + y--; + } + // reverse pssm (if defined) + if (typeof this.pssm !== "undefined") { + //reverse + x = 0; + y = this.motif_length-1; + while (x < y) { + temp = this.pssm[x]; + this.pspm[x] = this.pssm[y]; + this.pssm[y] = temp; + x++; + y--; + } + } + //swap triming + temp_trim = this.ltrim; + this.ltrim = this.rtrim; + this.rtrim = temp_trim; + return this; //allow function chaining... +}; + +Pspm.prototype.reverse_complement = function(alphabet) { + "use strict"; + var x, y, temp, i, row, c, temp_trim; + if (this.alph_length != alphabet.get_size_core()) { + throw new Error("The alphabet size does not match the size of the pspm."); + } + if (!alphabet.has_complement()) { + throw new Error("The specified alphabet can not be complemented."); + } + // reverse motif + this.reverse(); + //complement + for (x = 0; x < this.motif_length; x++) { + row = this.pspm[x]; + for (i = 0; i < row.length; i++) { + c = alphabet.get_complement(i); + if (c < i) continue; + temp = row[i]; + row[i] = row[c]; + row[c] = temp; + } + } + // complement pssm (if defined) + if (typeof this.pssm !== "undefined") { + //complement + for (x = 0; x < this.motif_length; x++) { + row = this.pssm[x]; + for (i = 0; i < row.length; i++) { + c = alphabet.get_complement(i); + if (c < i) continue; + temp = row[i]; + row[i] = row[c]; + row[c] = temp; + } + } + } + return this; //allow function chaining... +}; + +Pspm.prototype.get_stack = function(position, alphabet, ssc) { + "use strict"; + var row, stack_ic, alphabet_ic, stack, i, sym; + if (this.alph_length != alphabet.get_size_core()) { + throw new Error("The alphabet size does not match the size of the pspm."); + } + row = this.pspm[position]; + stack_ic = this.get_stack_ic(position, alphabet); + if (ssc) stack_ic -= this.get_error(alphabet); + alphabet_ic = alphabet.get_ic(); + stack = []; + for (i = 0; i < this.alph_length; i++) { + 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; +}; + +Pspm.prototype.get_stack_ic = function(position, alphabet) { + "use strict"; + var row, H, i; + if (this.alph_length != alphabet.get_size_core()) { + throw new Error("The alphabet size does not match the size fo the pspm."); + } + row = this.pspm[position]; + H = 0; + for (i = 0; i < this.alph_length; i++) { + if (row[i] === 0) { + continue; + } + H -= (row[i] * (Math.log(row[i]) / Math.LN2)); + } + return alphabet.get_ic() - H; +}; + +Pspm.prototype.get_error = function(alphabet) { + "use strict"; + if (this.nsites === 0) { + return 0; + } + return (alphabet.get_size_core()-1) / (2 * Math.LN2 * this.nsites); +}; + +Pspm.prototype.get_motif_length = function() { + "use strict"; + return this.motif_length; +}; + +Pspm.prototype.get_alph_length = function() { + "use strict"; + return this.alph_length; +}; + +Pspm.prototype.get_left_trim = function() { + "use strict"; + return this.ltrim; +}; + +Pspm.prototype.get_right_trim = function() { + "use strict"; + return this.rtrim; +}; + +Pspm.prototype.as_best_match = function(alphabet) { + "use strict"; + var match, odds, best_odds, best_index; + var i, j; + match = ""; + for (i = 0; i < this.motif_length; i++) { + best_index = 0; + best_odds = this.pspm[i][0] / alphabet.get_bg_freq(0); + for (j = 1; j < this.alph_length; j++) { + odds = this.pspm[i][j] / alphabet.get_bg_freq(j); + if (odds > best_odds) { + best_odds = odds; + best_index = j; + } + } + match += alphabet.get_symbol(best_index); + } + return match; +}; + +Pspm.prototype.as_count_matrix = function() { + "use strict"; + var count, count_text, text; + var i, j; + text = ""; + for (i = 0; i < this.motif_length; i++) { + if (i !== 0) { + text += "\n"; + } + for (j = 0; j < this.alph_length; j++) { + if (j !== 0) { + text += " "; + } + count = Math.round(this.nsites * this.pspm[i][j]); + count_text = "" + count; + // pad up to length of 4 + if (count_text.length < 4) { + text += (new Array(5 - count_text.length)).join(" ") + count_text; + } else { + text += count_text; + } + } + } + return text; +}; + +Pspm.prototype.as_probability_matrix = function() { + "use strict"; + var text; + var i, j; + text = ""; + for (i = 0; i < this.motif_length; i++) { + if (i !== 0) { + text += "\n"; + } + for (j = 0; j < this.alph_length; j++) { + if (j !== 0) { + text += " "; + } + text += this.pspm[i][j].toFixed(6); + } + } + return text; +}; + +Pspm.prototype.as_score_matrix = function(alphabet, pseudo) { + "use strict"; + var me, score, out, row, col, score_text; + me = this; + if (typeof this.pssm === "undefined") { + if (!(typeof alphabet === "object" && alphabet != null && alphabet instanceof Alphabet)) { + throw new Error("The alphabet is required to generate the pssm."); + } + if (typeof pseudo === "undefined") { + pseudo = 0.01; + } else if (typeof pseudo !== "number" || pseudo < 0) { + throw new Error("Expected positive number for pseudocount"); + } + score = function(row, col) { + "use strict"; + var p, bg, p2; + p = me.pspm[row][col]; + bg = alphabet.get_bg_freq(col); + p2 = (p * me.nsites + bg * pseudo) / (me.nsites + pseudo); + return (p2 > 0 ? Math.round((Math.log(p2 / bg) / Math.LN2) * 100) : -10000); + }; + } else { + score = function(row, col) { + "use strict"; + return me.pssm[row][col]; + }; + } + out = ""; + for (row = 0; row < this.motif_length; row++) { + for (col = 0; col < this.alph_length; col++) { + if (col !== 0) { + out += " "; + } + score_text = "" + score(row, col); + // pad out to 6 characters + if (score_text.length < 6) { + out += (new Array(7 - score_text.length)).join(" ") + score_text; + } else { + out += score_text; + } + } + out += "\n"; + } + return out; +} + +Pspm.prototype.as_pspm = function() { + "use strict"; + return "letter-probability matrix: alength= " + this.alph_length + + " w= " + this.motif_length + " nsites= " + this.nsites + + (this.pgm === "STREME" ? " P= " : " E= ") + + (typeof this.evalue === "number" ? + this.evalue.toExponential() : this.evalue) + "\n" + + this.as_probability_matrix(); +}; + +Pspm.prototype.as_pssm = function(alphabet, pseudo) { + "use strict"; + return "log-odds matrix: alength= " + this.alph_length + + " w= " + this.motif_length + + " E= " + (typeof this.evalue == "number" ? + this.evalue.toExponential() : this.evalue) + "\n" + + this.as_score_matrix(alphabet, pseudo); +}; + +Pspm.prototype.as_meme = function(options) { + var with_header, with_pspm, with_pssm, version, alphabet, bg_source, pseudocount, strands; + var out, alen, i; + // get the options + if (typeof options !== "object" || options === null) { + options = {}; + } + with_header = (typeof options["with_header"] === "boolean" ? options["with_header"] : false); + with_pspm = (typeof options["with_pspm"] === "boolean" ? options["with_pspm"] : false); + with_pssm = (typeof options["with_pssm"] === "boolean" ? options["with_pssm"] : false); + if (!with_pspm && !with_pssm) with_pspm = true; + if (with_header) { + if (typeof options["version"] === "string" && /^\d+(?:\.\d+){0,2}$/.test(options["version"])) { + version = options["version"]; + } else if (typeof options["version"] === "number") { + version = options["version"].toFixed(0); + } else { + version = "4"; + } + if (typeof options["strands"] === "number" && options["strands"] === 1) { + strands = 1; + } else { + strands = 2; + } + if (typeof options["bg_source"] === "string") { + bg_source = options["bg_source"]; + } else { + bg_source = "unknown source"; + } + if (typeof options["alphabet"] === "object" && options["alphabet"] != null + && options["alphabet"] instanceof Alphabet) { + alphabet = options["alphabet"]; + } else { + throw new Error("The alphabet is required to generate the header."); + } + } + // now create the output + out = ""; + if (with_header) { + out = "MEME version " + version + "\n\n"; + out += alphabet.as_meme() + "\n"; + if (alphabet.has_complement()) { // assume DNA has both strands unless otherwise specified + out += "strands: " + (strands === 1 ? "+" : "+ -") + "\n\n"; + } + out += "Background letter frequencies (from " + bg_source + "):\n"; + alen = alphabet.get_size_core(); + for (i = 0; i < alen; i++) { + if (i !== 0) { + if (i % 9 === 0) { // maximum of nine entries per line + out += "\n"; + } else { + out += " "; + } + } + out += alphabet.get_symbol(i) + " " + alphabet.get_bg_freq(i).toFixed(3); + } + } + out += "\n\n"; + out += "MOTIF " + this.name + (this.alt == null ? "" : " " + this.alt); + if (with_pssm) { + out += "\n\n"; + out += this.as_pssm(options["alphabet"], options["pseudocount"]); + } + if (with_pspm) { + out += "\n\n"; + out += this.as_pspm(); + } + return out; +} + +Pspm.prototype.toString = function() { + "use strict"; + var str, i, row; + str = ""; + for (i = 0; i < this.pspm.length; i++) { + row = this.pspm[i]; + str += row.join("\t") + "\n"; + } + return str; +}; + +function parse_pspm_properties(str) { + "use strict"; + var parts, i, eqpos, before, after, properties, prop, num, num_re; + num_re = /^((?:[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)|inf)$/; + parts = trim(str).split(/\s+/); + // split up words containing = + for (i = 0; i < parts.length;) { + eqpos = parts[i].indexOf("="); + if (eqpos != -1) { + before = parts[i].substr(0, eqpos); + after = parts[i].substr(eqpos+1); + if (before.length > 0 && after.length > 0) { + parts.splice(i, 1, before, "=", after); + i += 3; + } else if (before.length > 0) { + parts.splice(i, 1, before, "="); + i += 2; + } else if (after.length > 0) { + parts.splice(i, 1, "=", after); + i += 2; + } else { + parts.splice(i, 1, "="); + i++; + } + } else { + i++; + } + } + properties = {}; + for (i = 0; i < parts.length; i += 3) { + if (parts.length - i < 3) { + throw new Error("Expected PSPM property was incomplete. "+ + "Remaing parts are: " + parts.slice(i).join(" ")); + } + if (parts[i+1] !== "=") { + throw new Error("Expected '=' in PSPM property between key and " + + "value but got " + parts[i+1]); + } + prop = parts[i].toLowerCase(); + num = parts[i+2]; + if (!num_re.test(num)) { + throw new Error("Expected numeric value for PSPM property '" + + prop + "' but got '" + num + "'"); + } + properties[prop] = num; + } + return properties; +} + +function parse_pspm_string(pspm_string) { + "use strict"; + var header_re, lines, first_line, line_num, col_num, alph_length, + motif_length, nsites, evalue, pspm, i, line, match, props, parts, + j, prob; + header_re = /^letter-probability\s+matrix:(.*)$/i; + lines = pspm_string.split(/\n/); + first_line = true; + line_num = 0; + col_num = 0; + alph_length; + motif_length; + nsites; + evalue; + pspm = []; + for (i = 0; i < lines.length; i++) { + line = trim(lines[i]); + if (line.length === 0) { + continue; + } + // check the first line for a header though allow matrices without it + if (first_line) { + first_line = false; + match = header_re.exec(line); + if (match !== null) { + props = parse_pspm_properties(match[1]); + if (props.hasOwnProperty("alength")) { + alph_length = parseFloat(props["alength"]); + if (alph_length != 4 && alph_length != 20) { + throw new Error("PSPM property alength should be 4 or 20" + + " but got " + alph_length); + } + } + if (props.hasOwnProperty("w")) { + motif_length = parseFloat(props["w"]); + if (motif_length % 1 !== 0 || motif_length < 1) { + throw new Error("PSPM property w should be an integer larger " + + "than zero but got " + motif_length); + } + } + if (props.hasOwnProperty("nsites")) { + nsites = parseFloat(props["nsites"]); + if (nsites <= 0) { + throw new Error("PSPM property nsites should be larger than " + + "zero but got " + nsites); + } + } + if (props.hasOwnProperty("e")) { + evalue = props["e"]; + if (evalue < 0) { + throw new Error("PSPM property evalue should be " + + "non-negative but got " + evalue); + } + } + continue; + } + } + pspm[line_num] = []; + col_num = 0; + parts = line.split(/\s+/); + for (j = 0; j < parts.length; j++) { + prob = parseFloat(parts[j]); + if (prob != parts[j] || prob < 0 || prob > 1) { + throw new Error("Expected probability but got '" + parts[j] + "'"); + } + pspm[line_num][col_num] = prob; + col_num++; + } + line_num++; + } + if (typeof motif_length === "number") { + if (pspm.length != motif_length) { + throw new Error("Expected PSPM to have a motif length of " + + motif_length + " but it was actually " + pspm.length); + } + } else { + motif_length = pspm.length; + } + if (typeof alph_length !== "number") { + alph_length = pspm[0].length; + if (alph_length != 4 && alph_length != 20) { + throw new Error("Expected length of first row in the PSPM to be " + + "either 4 or 20 but got " + alph_length); + } + } + for (i = 0; i < pspm.length; i++) { + if (pspm[i].length != alph_length) { + throw new Error("Expected PSPM row " + i + " to have a length of " + + alph_length + " but the length was " + pspm[i].length); + } + } + return {"pspm": pspm, "motif_length": motif_length, + "alph_length": alph_length, "nsites": nsites, "evalue": evalue}; +} +//====================================================================== +// end Pspm object +//====================================================================== + +//====================================================================== +// start Logo object +//====================================================================== + +var Logo = function(alphabet, options) { + "use strict"; + this.alphabet = alphabet; + this.fine_text = ""; + this.x_axis = 1; + this.y_axis = true; + this.xlate_nsyms = 1; + this.xlate_start = null; + this.xlate_end = null; + this.pspm_list = []; + this.pspm_column = []; + this.rows = 0; + this.columns = 0; + if (typeof options === "string") { + // the old method signature had fine_text here so we support that + this.fine_text = options; + } else if (typeof options === "object" && options != null) { + this.fine_text = (typeof options.fine_text === "string" ? options.fine_text : ""); + this.x_axis = (typeof options.x_axis === "boolean" ? (options.x_axis ? 1 : 0) : 1); + if (options.x_axis_hidden != null && options.x_axis_hidden) this.x_axis = -1; + this.y_axis = (typeof options.y_axis === "boolean" ? options.y_axis : true); + this.xlate_nsyms = (typeof options.xlate_nsyms === "number" ? options.xlate_nsyms : this.xlate_nsyms); + this.xlate_start = (typeof options.xlate_start === "number" ? options.xlate_start : this.xlate_start); + this.xlate_end = (typeof options.xlate_end === "number" ? options.xlate_end : this.xlate_end); + } +}; + +Logo.prototype.add_pspm = function(pspm, column) { + "use strict"; + var col; + if (typeof column === "undefined") { + column = 0; + } else if (column < 0) { + throw new Error("Column index out of bounds."); + } + this.pspm_list[this.rows] = pspm; + this.pspm_column[this.rows] = column; + this.rows++; + col = column + pspm.get_motif_length(); + if (col > this.columns) { + this.columns = col; + } +}; + +Logo.prototype.get_columns = function() { + "use strict"; + return this.columns; +}; + +Logo.prototype.get_xlate_nsyms = function() { + "use strict"; + return this.xlate_nsyms; +}; + +Logo.prototype.get_xlate_start = function() { + "use strict"; + return (this.xlate_start != null ? this.xlate_start : 0); +}; + +Logo.prototype.get_xlate_end = function() { + "use strict"; + return (this.xlate_end != null ? this.xlate_end : this.columns * this.xlate_nsyms); +}; + +Logo.prototype.get_xlate_columns = function() { + "use strict"; + return this.get_xlate_end() - this.get_xlate_start(); +}; + +Logo.prototype.get_rows = function() { + "use strict"; + return this.rows; +}; + +Logo.prototype.get_pspm = function(row_index) { + "use strict"; + if (row_index < 0 || row_index >= this.rows) { + throw new Error("INDEX_OUT_OF_BOUNDS"); + } + return this.pspm_list[row_index]; +}; + +Logo.prototype.get_offset = function(row_index) { + "use strict"; + if (row_index < 0 || row_index >= this.rows) { + throw new Error("INDEX_OUT_OF_BOUNDS"); + } + return this.pspm_column[row_index]; +}; + +Logo.prototype._as_eps_data = function(ssc, errbars) { + var i, j, pos, stack_pos, pspm, stack, sym, out; + out = ""; + for (i = 0; i < this.rows; i++) { + out += "\nStartLine\n"; + // Indent + for (j = 0; j < this.pspm_column[i]; j++) { + out += "() startstack\nendstack\n\n"; + } + pspm = this.pspm_list[i]; + if (pspm.get_left_trim() > 0) { + out += "MuteColour\nDrawTrimEdge\n" + pspm.get_left_trim() + " DrawTrimBg\n"; + } + for (pos = 0; pos < pspm.get_motif_length(); pos++) { + if (pos != 0 && pos == pspm.get_left_trim()) { // enable full colour + out += "DrawTrimEdge\nRestoreColour\n"; + } else if (pos == (pspm.get_motif_length() - pspm.get_right_trim())) { + out += "MuteColour\n" + pspm.get_right_trim() + " DrawTrimBg\n"; + } + out += "(" + (pos + 1) + ") startstack\n"; + stack = pspm.get_stack(pos, this.alphabet, ssc); + for (stack_pos = 0; stack_pos < stack.length; stack_pos++) { + sym = stack[stack_pos]; + out += " " + (sym.get_scale() * this.alphabet.get_ic()) + " (" + sym.get_symbol() + ") numchar\n"; + } + if (errbars) { + out += " " + pspm.get_error(this.alphabet) + " Ibeam\n"; + } + out += "endstack\n\n"; + } + if (pspm.get_right_trim() > 0 || pspm.get_left_trim() == pspm.get_motif_length()) { + out += "RestoreColour\n"; + } + out += "EndLine\n"; + } + return out; +}; + +Logo.prototype.as_eps = function(options) { + "use strict"; + if (this.xlate_nsyms != 1) throw new Error("Unsupported setting xlate_nsyms for EPS"); + if (this.xlate_start != null) throw new Error("Unsupported setting xlate_start for EPS"); + if (this.xlate_end != null) throw new Error("Unsupported setting xlate_end for EPS"); + + var LOGOHEIGHT = 7.5; // default height of line in cm + var cm2pts, height, width, now, ssc, errbars; + if (typeof options === "undefined") { + options = {}; + } + cm2pts = 72 / 2.54; + if (typeof options.logo_height == "number") { + height = options.logo_height; + } else { + height = LOGOHEIGHT * this.rows; + } + if (typeof options.logo_width == "number") { + width = options.logo_width; + } else { + width = this.columns + 2; + } + now = new Date(); + ssc = (typeof options.ssc == "boolean" ? options.ssc : false); + errbars = (typeof options.show_error_bar == "boolean" ? options.show_error_bar : ssc); + var values = { + "LOGOHEIGHT": height, + "LOGOWIDTH": width, + "BOUNDINGHEIGHT": Math.round(height * cm2pts), + "BOUNDINGWIDTH": Math.round(width * cm2pts), + "LOGOLINEHEIGHT": (height / this.rows), + "CHARSPERLINE": this.columns, + "BARBITS": this.alphabet.get_ic(), + "LOGOTYPE": (this.alphabet.has_complement() ? "NA" : "AA"), + "CREATIONDATE": now.getDate() + "." + (now.getMonth() + 1) + "." + now.getFullYear() + " " + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds(), + "ERRORBARFRACTION": (typeof options.error_bar_fraction == "number" ? options.error_bar_fraction : 1.0), + "TICBITS": (typeof options.ticbits == "number" ? options.ticbits : 1.0), + "TITLE": (typeof options.title == "string" ? options.title : ""), + "FINEPRINT": (typeof options.fineprint == "string" ? options.fineprint : this.fine_text), + "XAXISLABEL": (typeof options.xaxislabel == "string" ? options.xaxislabel : ""), + "YAXISLABEL": (typeof options.yaxislabel == "string" ? options.yaxislabel : "bits"), + "SSC": ssc, + "YAXIS": (typeof options.show_y_axis == "boolean" ? options.show_y_axis : this.y_axis), + "SHOWENDS": (typeof options.show_ends == "boolean" ? options.show_ends : false), + "ERRBAR": errbars, + "OUTLINE": (typeof options.show_outline == "boolean" ? options.show_outline : false), + "NUMBERING": (typeof options.show_numbering == "boolean" ? options.show_numbering : this.x_axis != 0), + "SHOWINGBOX": (typeof options.show_box == "boolean" ? options.show_box : false), + "CREATOR": (typeof options.creator == "string" ? options.creator : "motif_logo.js"), + "FONTSIZE": (typeof options.label_font_size == "number" ? options.label_font_size : 12), + "TITLEFONTSIZE": (typeof options.title_font_size == "number" ? options.title_font_size : 12), + "SMALLFONTSIZE": (typeof options.small_font_size == "number" ? options.small_font_size : 6), + "TOPMARGIN" : (typeof options.top_margin == "number" ? options.top_margin : 0.9), + "BOTTOMMARGIN": (typeof options.bottom_margin == "number" ? options.bottom_margin : 0.9), + "COLORDICT": this.alphabet._as_eps_dict(), + "DATA": this._as_eps_data(ssc, errbars) + }; + // now this requires that the script containing the template has been imported! + return motif_logo_template(values); +}; + +//====================================================================== +// end Logo object +//====================================================================== + +// calculate the exact size (in pixels) of an object drawn on the +// canvas assuming that the background of the canvas is transparent. +function canvas_bounds(ctx, cwidth, cheight) { + "use strict"; + var data, r, c, top_line, bottom_line, left_line, right_line, + txt_width, txt_height; + + // extract the image data + data = ctx.getImageData(0, 0, cwidth, cheight).data; + + // set initial values + top_line = -1; bottom_line = -1; left_line = -1; right_line = -1; + txt_width = 0; txt_height = 0; + + // Find the top-most line with a non-transparent 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; + } + } + + // Only bother looking if we found at least one set pixel... + if (top_line != -1) { + + //find the last line with a non-transparent pixel + 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; + } + } + // calculate height + txt_height = bottom_line - top_line + 1; + + // Find the left-most line with a non-transparent pixel + for (c = 0; c < cwidth; c++) { + for (r = top_line; r <= bottom_line; 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-transparent pixel + for (c = cwidth-1; c >= left_line; c--) { + for(r = top_line; r <= bottom_line; 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}; +} + +//====================================================================== +// 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). +var RasterizedAlphabet = function(alphabet, logo_scale, font, width) { + "use strict"; + var default_size, safety_pad, canvas, ctx, middle, baseline, widths, sizes, + i, sym, size, tenpercent, avg_width, scale, + target_width, target_height; + //variable prototypes + this.alphabet = alphabet; + this.scale = logo_scale; + this.sym_cache = {}; + this.stack_num_cache = []; + this.scale_num_cache = []; + // size of canvas + default_size = 60; // size of measuring canvas + safety_pad = 20; // pixels to pad around so we don't miss the edges + // create a canvas to do our measuring + canvas = document.createElement("canvas"); + if (!canvas.getContext) throw new Error("No canvas support"); + canvas.width = default_size + 2 * safety_pad; + canvas.height = default_size + 2 * safety_pad; + middle = Math.round(canvas.width / 2); + baseline = Math.round(canvas.height - safety_pad); + ctx = canvas.getContext('2d'); + if (!supports_text(ctx)) throw new Error("Canvas does not support text"); + ctx.font = font; + ctx.textAlign = "center"; + ctx.translate(middle, baseline); + // list of widths + widths = []; + sizes = []; + //now measure each letter in the alphabet + for (i = 0; i < alphabet.get_size_core(); ++i) { + // reset the canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = alphabet.get_colour(i); + // draw the test text + ctx.fillText(alphabet.get_symbol(i), 0, 0); + //measure + size = canvas_bounds(ctx, canvas.width, canvas.height); + if (size.width === 0) throw new Error("Invisible symbol!"); + widths.push(size.width); + sizes[i] = size; + } + //sort the widths + widths.sort(function(a,b) {return a - b;}); + //drop 10% of the items off each end + tenpercent = Math.floor(widths.length / 10); + for (i = 0; i < tenpercent; ++i) { + widths.pop(); + widths.shift(); + } + //calculate average width + avg_width = 0; + for (i = 0; i < widths.length; ++i) { + avg_width += widths[i]; + } + avg_width /= widths.length; + // calculate the target width + target_width = width * this.scale * 2; + // calculate scales + for (i = 0; i < alphabet.get_size_core(); ++i) { + sym = alphabet.get_symbol(i); + size = sizes[i]; + // calculate scale + scale = target_width / Math.max(avg_width, size.width); + // estimate scaled height + target_height = size.height * scale; + // create an appropriately sized canvas + canvas = document.createElement("canvas"); + canvas.width = target_width; + canvas.height = target_height + safety_pad * 2; + // calculate the middle + middle = Math.round(canvas.width / 2); + // calculate the baseline + baseline = Math.round(canvas.height - safety_pad); + // get the context and prepare to draw the rasterized text + ctx = canvas.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 text + ctx.fillText(sym, 0, 0); + ctx.restore(); + this.sym_cache[sym] = {"image": canvas, "size": canvas_bounds(ctx, canvas.width, canvas.height)}; + } +}; + +RasterizedAlphabet.prototype.get_alphabet = function() { + return this.alphabet; +}; + +RasterizedAlphabet.prototype.get_scale = function() { + return this.scale; +}; + +RasterizedAlphabet.prototype.draw_stack_sym = function(ctx, letter, dx, dy, dWidth, dHeight) { + "use strict"; + var entry, image, size; + entry = this.sym_cache[letter]; + image = entry.image; + size = entry.size; + ctx.drawImage(image, 0, size.bound_top -1, image.width, size.height+1, dx, dy, dWidth, dHeight); +}; + +RasterizedAlphabet.prototype.draw_stack_num = function(ctx, font, stack_width, index) { + var image, image_ctx, text_length; + if (index >= this.stack_num_cache.length) { + image = document.createElement("canvas"); + // measure the text + image_ctx = image.getContext('2d'); + image_ctx.save(); + image_ctx.font = font; + text_length = image_ctx.measureText("" + (index + 1)).width; + image_ctx.restore(); + // resize the canvas to fit + image.width = Math.ceil(stack_width); + image.height = Math.ceil(text_length); + // draw the text + image_ctx = image.getContext('2d'); + image_ctx.translate(Math.round(stack_width / 2), 0); + image_ctx.font = font; + image_ctx.textBaseline = "middle"; + image_ctx.textAlign = "right"; + image_ctx.rotate(-(Math.PI / 2)); + image_ctx.fillText("" + (index + 1), 0, 0); + this.stack_num_cache[index] = image; + } else { + image = this.stack_num_cache[index]; + } + ctx.drawImage(image, 0, 0); +} + +RasterizedAlphabet.prototype.draw_scale_num = function(ctx, font, num) { + var image, image_ctx, text_size, m_length; + if (num >= this.scale_num_cache.length) { + image = document.createElement("canvas"); + // measure the text + image_ctx = image.getContext('2d'); + image_ctx.font = font; + text_size = image_ctx.measureText("" + num); + if (text_size.actualBoundingBoxAscent && text_size.actualBoundingBoxDesent) { + // resize the canvas to fit + image.width = Math.ceil(text_size.width); + image.height = Math.ceil(text_size.actualBoundingBoxAscent + text_size.actualBoundingBoxDesent); + // draw the text + image_ctx = image.getContext('2d'); + image_ctx.font = font; + image_ctx.textAlign = "right"; + image_ctx.fillText("" + num, image.width, text_size.actualBoundingBoxAscent); + } else { + // measure width of 'm' to approximate height, we double it later anyway + m_length = image_ctx.measureText("m").width; + // resize the canvas to fit + image.width = Math.ceil(text_size.width); + image.height = Math.ceil(2 * m_length); + // draw the text + image_ctx = image.getContext('2d'); + image_ctx.font = font; + image_ctx.textAlign = "right"; + image_ctx.textBaseline = "middle"; + image_ctx.fillText("" + num, image.width, m_length); + } + this.scale_num_cache[num] = image; + } else { + image = this.scale_num_cache[num]; + } + ctx.drawImage(image, -image.width, -Math.round(image.height / 2)) +} + +//====================================================================== +// end RasterizedAlphabet +//====================================================================== + +//====================================================================== +// start LogoMetrics object +//====================================================================== + +var LogoMetrics = function(ctx, logo_columns, logo_rows, has_names, has_finetext, x_axis, y_axis) { + "use strict"; + var i, row_height; + //variable prototypes + this.pad_top = (has_names ? 5 : 0); + this.pad_left = (y_axis ? 10 : 0); + this.pad_right = (has_finetext ? 15 : 0); + 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_axis = y_axis; + 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_axis = x_axis; + 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; + //calculate the width of the y axis numbers + ctx.font = this.y_num_font; + for (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) + if (x_axis == 1) { + ctx.font = this.x_num_font; + for (i = 1; i <= logo_columns; i++) { + this.x_num_width = Math.max(this.x_num_width, ctx.measureText("" + i).width); + } + } else if (x_axis == 0) { + this.x_num_height = 4; + this.x_num_width = 4; + } else { + this.x_num_height = 0; + this.x_num_width = 0; + } + + //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) { + row_height = this.stack_height + this.pad_middle; + if (has_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_axis ? this.y_num_height/2 : 0); + + var fine_txt_total = (has_finetext ? this.fine_txt_height + this.fine_txt_above : 0); + if (has_names) { + this.summed_height += fine_txt_total + this.name_height; + this.summed_height += Math.max((this.y_axis ? this.y_num_height/2 : 0), + this.x_num_height + this.x_num_above + this.name_spacer); + } else { + this.summed_height += Math.max((this.y_axis ? this.y_num_height/2 : 0), + this.x_num_height + this.x_num_above + fine_txt_total); + } + + //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; + if (this.y_axis) { + //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; + +}; + +//====================================================================== +// end LogoMetrics object +//====================================================================== + +//found this trick at http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm +function image_ok(img) { + "use strict"; + // 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) { + "use strict"; + 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, raster) { + "use strict"; + var tic_height, i; + tic_height = metrics.stack_height / alphabet_ic; + ctx.save(); + 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.rotate(-(Math.PI / 2)); + ctx.textAlign = "center"; + ctx.fillText("bits", 0, 0); + 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); + for (i = 0; i <= alphabet_ic; i++) { + //draw the number + ctx.save(); + ctx.translate(-1, 0); + raster.draw_scale_num(ctx, metrics.y_num_font, i); + ctx.restore(); + //draw the tic + ctx.fillRect(0, -1, metrics.y_tic_width, 2); + //prepare for next tic + ctx.translate(0, -tic_height); + } + ctx.restore(); + + ctx.fillRect(metrics.y_tic_width - 2, 0, 2, metrics.stack_height) + + ctx.restore(); +} + +function draw_stack_num(ctx, metrics, row_index, raster) { + "use strict"; + ctx.save(); + ctx.translate(0, Math.round(metrics.stack_height + metrics.x_num_above)); + if (metrics.x_axis == 1) { + raster.draw_stack_num(ctx, metrics.x_num_font, metrics.stack_width, row_index); + } else if (metrics.x_axis == 0) { + // draw dots instead of the numbers (good for small logos) + ctx.beginPath(); + var radius = Math.round(metrics.x_num_height / 2); + ctx.arc(Math.round(metrics.stack_width / 2), radius, radius, 0, 2 * Math.PI, false); + ctx.fill(); + } + ctx.restore(); +} + +function draw_stack(ctx, metrics, symbols, raster) { + "use strict"; + var preferred_pad, sym_min, i, sym, sym_height, pad; + preferred_pad = 0; + sym_min = 5; + + ctx.save();//1 + ctx.translate(0, metrics.stack_height); + for (i = 0; i < symbols.length; i++) { + sym = symbols[i]; + sym_height = metrics.stack_height * sym.get_scale(); + + 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_stack_sym(ctx, sym.get_symbol(), 0, 0, metrics.stack_width, sym_height); + //translate past the padding + ctx.translate(0, -(pad/2)); + } + ctx.restore();//1 +} + +function draw_dashed_line(ctx, pattern, start, x1, y1, x2, y2) { + "use strict"; + var x, y, len, i, dx, dy, tlen, theta, mulx, muly, lx, ly; + dx = x2 - x1; + dy = y2 - y1; + tlen = Math.pow(dx*dx + dy*dy, 0.5); + theta = Math.atan2(dy,dx); + mulx = Math.cos(theta); + muly = Math.sin(theta); + lx = []; + 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, left_start, left_end, left_divider, right_start, right_end, right_divider) { + "use strict"; + var left_size = left_end - left_start; + var right_size = right_end - right_start; + var line_x; + + ctx.save();//s8 + ctx.fillStyle = "rgb(240, 240, 240)"; + if (left_size > 0) { + ctx.fillRect(left_start * metrics.stack_width, 0, left_size * metrics.stack_width, metrics.stack_height); + } + if (right_size > 0) { + ctx.fillRect(right_start * metrics.stack_width, 0, right_size * metrics.stack_width, metrics.stack_height); + } + ctx.fillStyle = "rgb(51, 51, 51)"; + if (left_size > 0 && left_divider) { + line_x = (left_end * metrics.stack_width) - 0.5; + draw_dashed_line(ctx, [3], 0, line_x, 0, line_x, metrics.stack_height); + } + if (right_size > 0 && right_divider) { + line_x = (right_start * metrics.stack_width) + 0.5; + draw_dashed_line(ctx, [3], 0, line_x, 0, line_x, metrics.stack_height); + } + ctx.restore();//s8 +} + +function size_logo_on_canvas(logo, canvas, show_names, scale) { + "use strict"; + var draw_name, draw_finetext, metrics; + draw_name = (typeof show_names === "boolean" ? show_names : (logo.get_rows() > 1)); + draw_finetext = (logo.fine_text.length > 0); + if (canvas.width !== 0 && canvas.height !== 0) { + return; + } + metrics = new LogoMetrics(canvas.getContext('2d'), + logo.get_xlate_columns(), logo.get_rows(), draw_name, draw_finetext, logo.x_axis, logo.y_axis); + if (typeof scale == "number") { + //resize the canvas to fit the scaled logo + canvas.width = metrics.summed_width * scale; + canvas.height = metrics.summed_height * scale; + } else { + if (canvas.width === 0 && canvas.height === 0) { + canvas.width = metrics.summed_width; + canvas.height = metrics.summed_height; + } else if (canvas.width === 0) { + canvas.width = metrics.summed_width * (canvas.height / metrics.summed_height); + } else if (canvas.height === 0) { + canvas.height = metrics.summed_height * (canvas.width / metrics.summed_width); + } + } +} + +function draw_logo_on_canvas(logo, canvas, show_names, scale) { + "use strict"; + var i, draw_name, draw_finetext, ctx, metrics, raster, pspm_i, pspm, + offset, col_index, motif_position, ssc; + ssc = false; + draw_name = (typeof show_names === "boolean" ? show_names : (logo.get_rows() > 1)); + draw_finetext = (logo.fine_text.length > 0); + ctx = canvas.getContext('2d'); + //assume that the user wants the canvas scaled equally so calculate what the best width for this image should be + metrics = new LogoMetrics(ctx, logo.get_xlate_columns(), logo.get_rows(), draw_name, draw_finetext, logo.x_axis, logo.y_axis); + if (typeof scale == "number") { + //resize the canvas to fit the scaled logo + canvas.width = metrics.summed_width * scale; + canvas.height = metrics.summed_height * scale; + } else { + if (canvas.width === 0 && canvas.height === 0) { + scale = 1; + canvas.width = metrics.summed_width; + canvas.height = metrics.summed_height; + } else if (canvas.width === 0) { + scale = canvas.height / metrics.summed_height; + canvas.width = metrics.summed_width * scale; + } else if (canvas.height === 0) { + scale = canvas.width / metrics.summed_width; + canvas.height = metrics.summed_height * scale; + } else { + scale = Math.min(canvas.width / metrics.summed_width, canvas.height / metrics.summed_height); + } + } + // cache the raster based on the assumption that we will be drawing a lot + // of logos the same size and alphabet + if (typeof draw_logo_on_canvas.raster_cache === "undefined") { + draw_logo_on_canvas.raster_cache = []; + } + for (i = 0; i < draw_logo_on_canvas.raster_cache.length; i++) { + raster = draw_logo_on_canvas.raster_cache[i]; + if (raster.get_alphabet().equals(logo.alphabet) && + Math.abs(raster.get_scale() - scale) < 0.1) break; + raster = null; + } + if (raster == null) { + raster = new RasterizedAlphabet(logo.alphabet, scale, metrics.stack_font, metrics.stack_width); + draw_logo_on_canvas.raster_cache.push(raster); + } + ctx = canvas.getContext('2d'); + ctx.save();//s1 + ctx.scale(scale, scale); + ctx.save();//s2 + ctx.save();//s7 + //create margin + ctx.translate(Math.round(metrics.pad_left), Math.round(metrics.pad_top)); + for (pspm_i = 0; pspm_i < logo.get_rows(); ++pspm_i) { + pspm = logo.get_pspm(pspm_i); + 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(Math.round(metrics.summed_width/2), Math.round(metrics.name_height)); + ctx.font = metrics.name_font; + ctx.textAlign = "center"; + ctx.fillText(pspm.name, 0, 0); + ctx.restore();//s4 + ctx.translate(0, Math.round(metrics.name_height + + Math.min(0, metrics.name_spacer - metrics.y_num_height/2))); + } + //draw scale + if (logo.y_axis) draw_scale(ctx, metrics, logo.alphabet.get_ic(), raster); + ctx.save();//s5 + //translate across past the scale + if (logo.y_axis) { + ctx.translate(Math.round(metrics.y_label_height + metrics.y_label_spacer + + metrics.y_num_width + metrics.y_tic_width), Math.round(metrics.y_num_height / 2)); + } + //draw the trimming background + if (pspm.get_left_trim() > 0 || pspm.get_right_trim() > 0) { + var left_start = offset * logo.get_xlate_nsyms(); + var left_end = (offset + pspm.get_left_trim()) * logo.get_xlate_nsyms(); + var left_divider = true; + if (left_end < logo.get_xlate_start() || left_start > logo.get_xlate_end()) { + // no overlap + left_start = 0; + left_end = 0; + left_divider = false; + } else { + if (left_start < logo.get_xlate_start()) { + left_start = logo.get_xlate_start(); + } + if (left_end > logo.get_xlate_end()) { + left_end = logo.get_xlate_end(); + left_divider = false; + } + left_start -= logo.get_xlate_start(); + left_end -= logo.get_xlate_start(); + if (left_end < left_start) { + left_start = 0; + left_end = 0; + left_divider = false; + } + } + var right_end = (offset + pspm.get_motif_length()) * logo.get_xlate_nsyms(); + //var right_start = right_end - (pspm.get_left_trim() * logo.get_xlate_nsyms()); + var right_start = right_end - (pspm.get_right_trim() * logo.get_xlate_nsyms()); + var right_divider = true; + if (right_end < logo.get_xlate_start() || right_start > logo.get_xlate_end()) { + // no overlap + right_start = 0; + right_end = 0; + right_divider = false; + } else { + if (right_start < logo.get_xlate_start()) { + right_start = logo.get_xlate_start(); + right_divider = false; + } + if (right_end > logo.get_xlate_end()) { + right_end = logo.get_xlate_end(); + } + right_start -= logo.get_xlate_start(); + right_end -= logo.get_xlate_start(); + if (right_end < right_start) { + right_start = 0; + right_end = 0; + right_divider = false; + } + } + draw_trim_background(ctx, metrics, left_start, left_end, left_divider, right_start, right_end, right_divider); + } + //draw letters + var xlate_col; + for (xlate_col = logo.get_xlate_start(); xlate_col < logo.get_xlate_end(); xlate_col++) { + ctx.translate(metrics.stack_pad_left,0); + col_index = Math.floor(xlate_col / logo.get_xlate_nsyms()); + if (xlate_col % logo.get_xlate_nsyms() == 0) { + if (col_index >= offset && col_index < (offset + pspm.get_motif_length())) { + motif_position = col_index - offset; + draw_stack_num(ctx, metrics, motif_position, raster); + draw_stack(ctx, metrics, pspm.get_stack(motif_position, logo.alphabet, ssc), raster); + } + } else { + if (col_index >= offset && col_index < (offset + pspm.get_motif_length())) { + ctx.save();// s5.1 + ctx.translate(0, Math.round(metrics.stack_height)); + // TODO draw a dot or dash or something to indicate continuity of the motif + ctx.restore(); //s5.1 + } + } + ctx.translate(Math.round(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 + if (logo.fine_text.length > 0) { + 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) { + "use strict"; + 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) { + "use strict"; + var logo = new Logo(alphabet, fine_text); + logo.add_pspm(pspm); + return logo; +} + +function logo_2(alphabet, fine_text, target, query, query_offset) { + "use strict"; + 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) { + "use strict"; + 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, null, scale); + //replace the image with the canvas + image.parentNode.replaceChild(canvas, image); +} + +/* + * Specifies 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) { + "use strict"; + 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, null, 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) { + "use strict"; + var ws, i; + str = str.replace(/^\s\s*/, ''); + ws = /\s/; i = str.length; + while (ws.test(str.charAt(--i))); + return str.slice(0, i + 1); +} + +// +// Delay drawing a logo +// +var DelayLogoTask = function(logo, canvas) { + "use strict"; + canvas.width = canvas.width; // clear canvas + this.logo = logo; + this.canvas = canvas; +}; + +DelayLogoTask.prototype.run = function () { + "use strict"; + this.canvas.width = this.canvas.width; // clear canvas + draw_logo_on_canvas(this.logo, this.canvas, false); +}; + +/* + * Make a canvas with the motif logo drawn on it. + */ +function make_logo(alphabet, pspm, height, rc, offset, className) { + if (rc) pspm = pspm.copy().reverse_complement(alphabet); + var logo = new Logo(alphabet); + logo.add_pspm(pspm, offset); + var canvas = document.createElement('canvas'); + var sizeit = (height < 0); + canvas.height = (sizeit ? -height : height); + canvas.width = 0; + canvas.className = className; + if (sizeit) size_logo_on_canvas(logo, canvas, false); + add_draw_task(canvas, new DelayLogoTask(logo, canvas)); + return canvas; +} +</script> + <script> + +// PRIVATE GLOBAL (uhoh) +var _block_colour_lookup = {}; + +function block_colour(index) { + function hsl2rgb(hue, saturation, lightness) { + "use strict"; + function _hue(p, q, t) { + "use strict"; + if (t < 0) t += 1; + else if (t > 1) t -= 1; + if (t < (1.0 / 6.0)) { + return p + ((q - p) * 6.0 * t); + } else if (t < 0.5) { + return q; + } else if (t < (2.0 / 3.0)) { + return p + ((q - p) * ((2.0 / 3.0) - t) * 6.0); + } else { + return p; + } + } + function _pad_hex(value) { + var hex = Math.round(value * 255).toString(16); + if (hex.length < 2) hex = "0" + hex; + return hex; + } + var r, g, b, p, q; + if (saturation == 0) { + // achromatic (grayscale) + r = lightness; + g = lightness; + b = lightness; + } else { + if (lightness < 0.5) { + q = lightness * (1 + saturation); + } else { + q = lightness + saturation - (lightness * saturation); + } + p = (2 * lightness) - q; + r = _hue(p, q, hue + (1.0 / 3.0)); + g = _hue(p, q, hue); + b = _hue(p, q, hue - (1.0 / 3.0)); + } + return "#" + _pad_hex(r) + _pad_hex(g) + _pad_hex(b); + } + if (typeof index !== "number" || index % 1 !== 0 || index < 0) return "#000000"; + // check for override + if (_block_colour_lookup[index] == null) { + var start = 0; //red + var sat = 100; + var light = 50; + var divisions = 1 << Math.ceil(Math.log(index + 1) / Math.LN2); + hue = start + (360 / divisions) * ((index - (divisions >> 1)) * 2 + 1); + // colour input fields only support values in the form #RRGGBB + _block_colour_lookup[index] = hsl2rgb(hue / 360, sat / 100, light / 100); + } + return _block_colour_lookup[index]; +} + +function set_block_colour(index, new_colour) { + _block_colour_lookup[index] = new_colour; + var blocks = document.querySelectorAll("div.block_motif[data-colour-index=\"" + index + "\"]"); + var i; + for (i = 0; i < blocks.length; i++) { + blocks[i].style.backgroundColor = new_colour; + } + var swatches = document.querySelectorAll("div.legend_swatch[data-colour-index=\"" + index + "\"]"); + var picker; + for (i = 0; i < swatches.length; i++) { + swatches[i].style.backgroundColor = new_colour; + picker = swatches[i].querySelector("input[type=\"color\"]"); + if (picker != null) picker.value = new_colour; + } +} + +function make_block_legend_entry(motif_name, motif_colour_index) { + if (typeof make_block_legend_entry.has_colour_picker !== "boolean") { + // test if colour picker is supported, based off Modernizer + // see http://stackoverflow.com/a/7787648/66387 + make_block_legend_entry.has_colour_picker = (function() { + var doc_ele = document.documentElement; + // We first check to see if the type we give it sticks.. + var input_ele = document.createElement('input'); + input_ele.setAttribute('type', 'color'); + var value_ok = input_ele.type !== 'text'; + if (value_ok) { + // If the type does, we feed it a textual value, which shouldn't be valid. + // If the value doesn't stick, we know there's input sanitization which infers a custom UI + var smile = ':)'; + input_ele.value = smile; + input_ele.style.cssText = 'position:absolute;visibility:hidden;'; + // chuck into DOM and force reflow for Opera bug in 11.00 + // github.com/Modernizr/Modernizr/issues#issue/159 + doc_ele.appendChild(input_ele); + doc_ele.offsetWidth; + value_ok = input_ele.value != smile; + doc_ele.removeChild(input_ele); + } + return value_ok; + })(); + } + var entry = document.createElement("div"); + entry.className = "legend_entry"; + var swatch; + swatch = document.createElement("div"); + swatch.className = "legend_swatch"; + swatch.setAttribute("data-colour-index", motif_colour_index); + swatch.style.backgroundColor = block_colour(motif_colour_index); + if (make_block_legend_entry.has_colour_picker) { + var picker = document.createElement("input"); + picker.type = "color"; + picker.value = block_colour(motif_colour_index); + picker.addEventListener("change", function(e) { + set_block_colour(motif_colour_index, picker.value); + }, false); + swatch.addEventListener("click", function(e) { + picker.click(); + }, false); + swatch.appendChild(picker); + } + entry.appendChild(swatch); + var name = document.createElement("div"); + name.className = "legend_text"; + name.appendChild(document.createTextNode(motif_name)); + entry.appendChild(name); + return entry; +} + +function make_block_ruler(max_len) { + var container = document.createElement("div"); + container.className = "block_container"; + var step; + if (max_len < 50) { + step = 1; + } else if (max_len < 100) { + step = 2; + } else if (max_len < 200) { + step = 4; + } else if (max_len < 500) { + step = 10; + } else if (max_len < 1000) { + step = 20; + } else if (max_len < 2000) { + step = 40; + } else if (max_len < 5000) { + step = 100; + } else if (max_len < 10000) { + step = 200; + } else if (max_len < 20000) { + step = 400; + } else { + step = Math.floor(max_len / 20000) * 400; + } + var peroid; + if (max_len < 10) { + peroid = 1; + } else if (max_len < 20) { + peroid = 2; + } else { + peroid = 5; + } + var i, cycle, offset, tic, label; + for (i = 0, cycle = 0; i < max_len; i += step, cycle = (cycle + 1) % peroid) { + offset = "" + ((i / max_len) * 100) + "%"; + tic = document.createElement("div"); + tic.style.left = offset; + tic.className = (cycle == 0 ? "tic_major" : "tic_minor"); + container.appendChild(tic); + if (cycle == 0) { + label = document.createElement("div"); + label.className = "tic_label"; + label.style.left = offset; + label.appendChild(document.createTextNode(i)); + container.appendChild(label); + } + } + return container; +} + +function _calculate_block_needle_drag_pos(e, data) { + var mouse; + e = e || window.event; + if (e.pageX || ev.pageY) { + mouse = {"x": e.pageX, "y": e.pageY}; + } else { + mouse = { + x:e.clientX + document.body.scrollLeft - document.body.clientLeft, + y:e.clientY + document.body.scrollTop - document.body.clientTop + }; + } + var cont = data.container; + var dragable_length = cont.clientWidth - + (cont.style.paddingLeft ? cont.style.paddingLeft : 0) - + (cont.style.paddingRight ? cont.style.paddingRight : 0); + //I believe that the offset parent is the body + //otherwise I would need to make this recursive + //maybe clientLeft would work, but the explanation of + //it is hard to understand and it apparently doesn't work + //in firefox 2. + var diff = mouse.x - cont.offsetLeft; + if (diff < 0) diff = 0; + if (diff > dragable_length) diff = dragable_length; + var pos = Math.round(diff / dragable_length * data.max); + if (pos > data.len) pos = data.len; + return pos; +} + +function _update_block_needle_drag(e, data, done) { + "use strict"; + var pos = _calculate_block_needle_drag_pos(e, data); + // read the needle positions + var left = parseInt(data.llabel.textContent, 10) - data.off - 1; + var right = parseInt(data.rlabel.textContent, 10) - data.off; + // validate needle positions + if (left >= data.len) left = data.len - 1; + if (left < 0) left = 0; + if (right > data.len) right = data.len; + if (right <= left) right = left + 1; + // calculate the new needle positions + if (data.moveboth) { + var size = right - left; + if (data.isleft) { + if ((pos + size) > data.len) pos = data.len - size; + left = pos; + right = pos + size; + } else { + if ((pos - size) < 0) pos = size; + left = pos - size; + right = pos; + } + } else { + if (data.isleft) { + if (pos >= right) pos = right - 1; + left = pos; + } else { + if (pos <= left) pos = left + 1; + right = pos; + } + } + // update the needle positions + data.lneedle.style.left = "" + (left / data.max * 100) + "%"; + data.llabel.textContent = "" + (left + data.off + 1); + data.rneedle.style.left = "" + (right / data.max * 100) + "%"; + data.rlabel.textContent = "" + (right + data.off); + data.handler(left, right, done); +} + +function _make_block_needle_drag_start_handler(isleft, data) { + return function (e) { + data.isleft = isleft; + data.moveboth = !(e.shiftKey); + document.addEventListener("mousemove", data.drag_during, false); + document.addEventListener("mouseup", data.drag_end, false); + }; +} + +function _make_block_needle_drag_end_handler(data) { + return function (e) { + document.removeEventListener("mousemove", data.drag_during, false); + document.removeEventListener("mouseup", data.drag_end, false); + _update_block_needle_drag(e, data, true); + }; +} + +function _make_block_needle_drag_during_handler(data) { + return function (e) { + _update_block_needle_drag(e, data, false); + }; +} + +// private function used by make_block_container +function _make_block_needle(isleft, value, data) { + var vbar = document.createElement('div'); + vbar.className = "block_needle " + (isleft ? "left" : "right"); + vbar.style.left = "" + (value / data.max * 100)+ "%"; + var label = document.createElement('div'); + label.className = "block_handle " + (isleft ? "left" : "right"); + // The needles sit between the sequence positions, so the left one sits at the + // start and the right at the end. This is why 1 is added to the displayed + // value for a left handle as the user doesn't need to know about this detail + label.textContent = "" + (isleft ? value + data.off + 1 : value + data.off); + label.unselectable = "on"; // so IE and Opera don't select the text, others are done in css + label.title = "Drag to move the displayed range. Hold shift and drag to change " + (isleft ? "lower" : "upper") + " bound of the range."; + vbar.appendChild(label); + if (isleft) { + data.lneedle = vbar; + data.llabel = label; + } else { + data.rneedle = vbar; + data.rlabel = label; + } + label.addEventListener("mousedown", _make_block_needle_drag_start_handler(isleft, data), false); + return vbar; +} + +function make_block_container(is_stranded, has_both_strands, max_len, show_len, offset, range_handler) { + offset = (offset != null ? offset : 0); + // make the container for the block diagram + var container = document.createElement("div"); + container.className = "block_container"; + container.setAttribute("data-max", max_len); + container.setAttribute("data-off", offset); + if (is_stranded) { + var plus = document.createElement("div"); + plus.appendChild(document.createTextNode("+")); + plus.className = "block_plus_sym"; + container.appendChild(plus); + if (has_both_strands) { + var minus = document.createElement("div"); + minus.appendChild(document.createTextNode("-")); + minus.className = "block_minus_sym"; + container.appendChild(minus); + } + } + var rule = document.createElement("div"); + rule.className = "block_rule"; + rule.style.width = ((show_len / max_len) * 100) + "%"; + container.appendChild(rule); + if (range_handler != null) { + var range_data = { + "max": max_len, + "len": show_len, + "off": offset, + "handler": range_handler, + "container": container, + "lneedle": null, "llabel": null, + "rneedle": null, "rlabel": null, + "isleft": false, "moveboth" : false + }; + range_data.drag_during = _make_block_needle_drag_during_handler(range_data); + range_data.drag_end = _make_block_needle_drag_end_handler(range_data); + container.appendChild(_make_block_needle(false, 1, range_data)); // add right first so z-index works + container.appendChild(_make_block_needle(true, 0, range_data)); + } + return container; +} + +function make_block_label(container, max_len, pos, length, message) { + "use strict"; + var label = document.createElement("div"); + label.className = "block_label"; + label.style.left = (((pos + (length / 2)) / max_len) * 100) + "%"; + label.appendChild(document.createTextNode(message)); + container.appendChild(label); +} + +function make_block(container, max_len, + site_pos, site_len, site_pvalue, site_rc, site_colour_index, site_secondary) { + "use strict"; + var block_height, block, block_region1, block_region2; + var max_block_height = 12; + var max_pvalue = 1e-10; + // calculate the height of the block + block_height = (site_pvalue < max_pvalue ? max_block_height : + (Math.log(site_pvalue) / Math.log(max_pvalue)) * max_block_height); + if (block_height < 1) block_height = 1; + // create a block to represent the motif + block = document.createElement("div"); + block.className = "block_motif" + (site_secondary ? " scanned_site" : "") + (site_rc ? " bottom" : " top"); + block.style.left = ((site_pos / max_len) * 100) + "%"; + block.style.top = (!site_rc ? max_block_height - block_height : + max_block_height + 1) + "px"; + block.style.width = ((site_len / max_len) * 100) + "%"; + block.style.height = block_height + "px"; + block.style.backgroundColor = block_colour(site_colour_index); + block.setAttribute("data-colour-index", site_colour_index); + // add to container + container.appendChild(block); + var activator = function (e) { + toggle_class(block, "active", true); + var new_e = new e.constructor(e.type, e); + block.dispatchEvent(new_e); + }; + var deactivator = function (e) { + toggle_class(block, "active", false); + var new_e = new e.constructor(e.type, e); + block.dispatchEvent(new_e); + } + // create a larger region to detect mouseover for the block + block_region1 = document.createElement("div"); + block_region1.className = "block_region top" + + (site_secondary ? " scanned_site" : "") + (site_rc ? "" : " main"); + block_region1.style.left = block.style.left; + block_region1.style.width = block.style.width; + block_region1.addEventListener('mouseover', activator, false); + block_region1.addEventListener('mouseout', deactivator, false); + container.appendChild(block_region1); + block_region2 = document.createElement("div"); + block_region2.className = "block_region bottom" + + (site_secondary ? " scanned_site" : "") + (site_rc ? " main" : ""); + block_region2.style.left = block.style.left; + block_region2.style.width = block.style.width; + block_region2.addEventListener('mouseover', activator, false); + block_region2.addEventListener('mouseout', deactivator, false); + container.appendChild(block_region2); + return block; +} + +function set_block_needle_positions(containingNode, start, end) { + var container, lneedle, llabel, rneedle, rlabel, max, off, left, right; + container = (/\bblock_container\b/.test(containingNode.className) ? containingNode : containingNode.querySelector(".block_container")); + max = parseInt(container.getAttribute("data-max"), 10); + off = parseInt(container.getAttribute("data-off"), 10); + left = start - off; + right = end - off; + lneedle = containingNode.querySelector(".block_needle.left"); + llabel = lneedle.querySelector(".block_handle.left"); + rneedle = containingNode.querySelector(".block_needle.right"); + rlabel = rneedle.querySelector(".block_handle.right"); + // update the needle positions + lneedle.style.left = "" + (left / max * 100) + "%"; + llabel.textContent = "" + (left + off + 1); + rneedle.style.left = "" + (right / max * 100) + "%"; + rlabel.textContent = "" + (right + off); +} + +function get_block_needle_positions(containingNode) { + var container, llabel, rlabel, max, off, left, right; + container = (/\bblock_container\b/.test(containingNode.className) ? containingNode : containingNode.querySelector(".block_container")); + max = parseInt(container.getAttribute("data-max"), 10); + off = parseInt(container.getAttribute("data-off"), 10); + llabel = containingNode.querySelector(".block_needle.left > .block_handle.left"); + rlabel = containingNode.querySelector(".block_needle.right > .block_handle.right"); + left = parseInt(llabel.textContent, 10) - off - 1; + right = parseInt(rlabel.textContent, 10) - off; + return {"start": left + off, "end": right + off}; +} +</script> + <script> +function make_alpha_bg_table(alph, freqs) { + function colour_symbol(index) { + var span = document.createElement("span"); + span.appendChild(document.createTextNode(alph.get_symbol(index))); + span.style.color = alph.get_colour(index); + span.className = "alpha_symbol"; + return span; + } + var table, thead, tbody, row, th, span, i; + // create table + table = document.createElement("table"); + table.className = "alpha_bg_table"; + // create header + thead = document.createElement("thead"); + table.appendChild(thead); + row = thead.insertRow(thead.rows.length); + if (alph.has_complement()) { + add_text_header_cell(row, "Name", "pop_alph_name"); + if (freqs != null) add_text_header_cell(row, "Freq.", "pop_alph_freq"); + if (alph.has_bg()) add_text_header_cell(row, "Bg.", "pop_alph_bg"); + add_text_header_cell(row, ""); + add_text_header_cell(row, ""); + add_text_header_cell(row, ""); + if (alph.has_bg()) add_text_header_cell(row, "Bg.", "pop_alph_bg"); + if (freqs != null) add_text_header_cell(row, "Freq.", "pop_alph_freq"); + add_text_header_cell(row, "Name", "pop_alph_name"); + } else { + add_text_header_cell(row, ""); + add_text_header_cell(row, "Name", "pop_alph_name"); + if (freqs != null) add_text_header_cell(row, "Freq.", "pop_alph_freq"); + if (alph.has_bg()) add_text_header_cell(row, "Bg.", "pop_alph_bg"); + } + // add alphabet entries + tbody = document.createElement("tbody"); + table.appendChild(tbody); + if (alph.has_complement()) { + for (i = 0; i < alph.get_size_core(); i++) { + var c = alph.get_complement(i); + if (i > c) continue; + row = tbody.insertRow(tbody.rows.length); + add_text_cell(row, alph.get_name(i)); + if (freqs != null) add_text_cell(row, "" + freqs[i]); + if (alph.has_bg()) add_text_cell(row, "" + alph.get_bg_freq(i)); + add_cell(row, colour_symbol(i)); + add_text_cell(row, "~"); + add_cell(row, colour_symbol(c)); + if (alph.has_bg()) add_text_cell(row, "" + alph.get_bg_freq(c)); + if (freqs != null) add_text_cell(row, "" + freqs[c]); + add_text_cell(row, alph.get_name(c)); + } + } else { + for (i = 0; i < alph.get_size_core(); i++) { + row = tbody.insertRow(tbody.rows.length); + add_cell(row, colour_symbol(i)); + add_text_cell(row, alph.get_name(i)); + if (freqs != null) add_text_cell(row, "" + freqs[i]); + if (alph.has_bg()) add_text_cell(row, "" + alph.get_bg_freq(i)); + } + } + return table; +} + +</script> + <script> +// +// simple-shared-doc.js +// + +// +// Function to redirect to appropriate doc file. +// +function get_doc_text(pgm, doc_type, extra, extra2) { + switch (pgm) { + case 'shared': + return(get_shared_doc_text(doc_type, extra, extra2)); + case 'ame': + return(get_ame_doc_text(doc_type, extra, extra2)); + case 'centrimo': + return(get_centrimo_doc_text(doc_type, extra, extra2)); + case 'discovery': + return(get_discovery_doc_text(doc_type, extra, extra2)); + case 'fimo': + return(get_fimo_doc_text(doc_type, extra, extra2)); + case 'gomo': + return(get_gomo_doc_text(doc_type, extra, extra2)); + case 'mcast': + return(get_mcast_doc_text(doc_type, extra, extra2)); + case 'meme-chip': + return(get_meme_chip_doc_text(doc_type, extra, extra2)); + case 'momo': + return(get_momo_doc_text(doc_type, extra, extra2)); + case 'sea': + return(get_sea_doc_text(doc_type, extra, extra2)); + case 'spamo': + return(get_spamo_doc_text(doc_type, extra, extra2)); + case 'streme': + return(get_streme_doc_text(doc_type, extra, extra2)); + case 'tgene': + return(get_tgene_doc_text(doc_type, extra, extra2)); + case 'tomtom': + return(get_tomtom_doc_text(doc_type, extra, extra2)); + case 'xstreme': + return(get_xstreme_doc_text(doc_type, extra, extra2)); + default: + return("<b>Unknown program type: <font color=red>" + pgm + "</font></b>"); + } +} // get_doc_text + +// +// Function to replace the innerHTML of element "id" with the HTML indicated by "doc_type". +// Easier to read and update than the more flexible approach in shared-doc.js. +// +function print_doc(id, pgm, doc_type, extra) { + document.getElementById(id).insertAdjacentHTML('beforeend', get_doc_text(pgm, doc_type, extra)); +} // print_doc + +// +// Function to replace the innerHTML of element "id" with an HTML paragraph +// containing the text for 'pgm' and 'doc_type'. +// This function can be used in help pop-ups. +// +function print_doc_para(id, pgm, doc_type, extra, extra2) { + html = "<p>" + get_doc_text(pgm, doc_type, extra, extra2) + "</p>"; + document.getElementById(id).insertAdjacentHTML('beforeend', html); +} // print_doc_para + +// +// Function to return the Shared HTML text of a given type. +// This function can be used directly to document the output format (xx-output-format.html) +// and indirectly via print_doc_para for help pop-ups in the actual output HTML, +// to prevent duplication of documentation. +// +function get_shared_doc_text(doc_type, extra, extra2) { + if (extra == undefined) {extra = ""}; + if (extra2 == undefined) {extra2 = ""}; + switch (doc_type) { + case 'fasta-coordinates-name': + return(` + The sequence IDs in the FASTA header lines are used as the source of sequence names. + The sequence ID is the string following the initial '>' up to the first white space character. + If the sequence ID is in an accepted <a href="` + site_url + `/doc/fasta-coordinates-format.html">FASTA Coordinates Format</a> + (e.g., UCSC or Galaxy format), and you did NOT specify the <code>` + extra + `-no-pgc</code> option, + then the coordinates are removed from the sequence ID to create the sequence name. + `); + case 'fasta-coordinates-brief': + return(` + The sequence IDs in the FASTA header lines are used as the source of sequence names. + The sequence ID is the string following the initial '>' up to the first white space character. + If the sequence ID is in an accepted <a href="` + site_url + `/doc/fasta-coordinates-format.html">FASTA Coordinates Format</a> + (e.g., UCSC or Galaxy format), and you did NOT specify the <code>` + extra + `-no-pgc</code> option, + then the coordinates are removed from the sequence ID to create the sequence name, + and the starting coordinate given in the sequence ID will be used as the + coordinate of the first position of the sequence. + Otherwise, the coordinate of the first position of the sequence is taken as 1 and the entire + sequence ID is used as the sequence name. + `); + case 'fasta-coordinates': + return(` + For sequence coordinates embedded in FASTA sequence headers to be parsed + correctly by MEME Suite programs, the sequence ID in the FASTA header should have one of the two + following formats: + + <h4>UCSC Format</h4> + <div style='margin: 5px 0'> + ><span class='pdat'>sequence name</span>:<span class='pdat' + >starting position</span>-<span class='pdat'>ending position</span> + </div> + where + <ul style='margin-top: 0; margin-bottom: 5px'> + <li><span class='pdat'>sequence name</span> is the name of the genomic sequence,</li> + <li><span class='pdat'>starting position</span> is the genomic position of the first base and</li> + <li><span class='pdat'>ending position</span> is the genomic position of the final base.</li> + </ul> + <b>Example:</b> <span class="pdata">chr1:156887119-156887619</span> + + <h4>Galaxy Format</h4> + <div style='margin: 5px 0'> + ><span class='pdat'>assembly name</span>_<span class='pdat' + >sequence name</span>_<span class='pdat' + >starting position</span>_<span class='pdat' + >ending position</span>_<span class='pdat' + >strand</span> + </div> + where + <ul style='margin-top: 0; margin-bottom: 5px'> + <li><span class='pdat'>assembly name</span> is the name of the genomic assembly,</li> + <li><span class='pdat'>sequence name</span> is the name of the genomic sequence,</li> + <li><span class='pdat'>starting position</span> is the genomic position of the first base and</li> + <li><span class='pdat'>ending position</span> is the genomic position of the final base.</li> + </ul> + <b>Example:</b> <span class="pdata">>mm9_chr18_75759530_7575972_-</span> + + <p> + For both formats, the following rules also apply: + <ul> + <li>The the coordinates are 1-start, fully-closed. This means + that the first base of the chromosome is position "1", and the bases at the + first and last positions of the given range are included.</li> + <li>The <span class='pdat'>sequence name</span> may not contain any white space.</li> + <li>The <span class='pdat'>assembly name</span> is not optional.</li> + <li>The <span class='pdat'>strand</span> is ignored.</li> + <li>When no valid genomic coordinates are found in a FASTA sequence header, the starting + position of the sequence is taken to be position 1.</li> + </ul> + </p> + `); + case 'motif-db': + return(` + The name of ` + extra2 + ` a file of motifs ("motif database file") that contains ` + extra + ` + `); + case 'motif-id': + return(` + The name of the ` + extra + ` motif, which is unique ` + extra2 + ` in the motif database file. + `); + case 'motif-alt-id': + return(` + An alternate name for the ` + extra + ` motif that may be provided ` + extra2 + ` in the motif database file. + `); + case 'motif-width': + return(` + The width of the motif. No gaps are allowed in motifs supplied to ` + extra + ` + as it only works for motifs of a fixed width. + `); + case 'motif-cons': + return(` + A consensus sequence computed from the ` + extra + ` motif (as described <a href="#consensus_doc">below</a>). + `); + case 'motif-match-score': + return(` + ` + extra2 + ` The motif match score of a position in a sequence is + computed by summing the appropriate entry from each column of the + position-dependent scoring matrix that represents the motif. ` + extra + ` + `); + case 'motif-match-p-value': + return(` + The <i>p</i>-value of a motif match is the probability of a single random + subsequence of the length of the motif <a href="javascript:help_refine('pop_motif_match_score')">scoring</a> + at least as well as the observed match. + `); + case 'bh-q-value': + if (extra2 == "") extra2 = "match"; + return(` + The q-value is the minimum False Discovery Rate (FDR) required to consider this + ` + extra2 + ` significant.</br>` + + get_shared_doc_text('bh-q-value-method', extra, extra2) + ` + `); + case 'bh-q-value-method': + return(` + <br>` + extra + ` estimates q-values from all the ` + extra2 + ` <i>p</i>-values + using the method proposed by Benjamini & Hochberg (<i>Journal of the Royal Statistical Society B</i>, 57:289-300, 1995). + See also Storey JD, Tibshirani R. Statistical significance for + genome-wide studies, <i>Proc. Natl. Acad. Sci. USA</i> (2003) <b>100</b>:9440–9445. + `); + case 'sdb-name': + return(` + The name of the (FASTA) sequence database file. + `); + case 'sdb-psp': + return(` + The name of the position specific priors (PSP) file. + `); + case 'sdb-dist': + return(` + The name of the binned distribution of priors file. + `); + case 'sdb-count': + return(` + The number of sequences in the database. + `); + case 'sdb-letters': + return(` + The number of letters in the sequence database. + `); + case 'lastmod': + return(` + The date of the last modification to the ` + extra + ` database. + `); + case 'sequence-id': + return(` + The identifier of the sequence (from the FASTA sequence header line)` + extra + ` + `); + case 'sequence-desc': + return(` + The description appearing after the identifier of the sequence in the FASTA header line. + `); + case 'alph-name': + return(` + The name of the alphabet symbol. + `); + case 'alph-bg': + return(` + The frequency of the alphabet symbol as defined by the background model. + `); + case 'match-start': + return(` + The start position of the ` + extra + `. + `); + case 'match-stop': + return(` + The end position of the ` + extra + `. + `); + case 'match-start-seq': + return(` + The start position of the ` + extra + `; 1-based sequence coordinates. + `); + case 'match-stop-seq': + return(` + The end position of the ` + extra + `; 1-based sequence coordinates. + `); + case 'match-start-genomic': + return(` + The start position of the ` + extra + `; genomic coordinates. + `); + case 'match-stop-genomic': + return(` + The end position of the ` + extra + `; genomic coordinates. + `); + case 'motif-consensus': + return(` + <p id="consensus_doc"> + A <b>consensus sequence</b> is constructed from each column in a + motif's frequency matrix using the <b>"50% rule"</b> + as follows: + </p> + <ol> + <li>The letter frequencies in the column are sorted in decreasing order.</li> + <li>Letters with frequency less 50% of the maximum are discarded.</li> + <li>The letter used in this position in the consensus sequence is determined + by the first rule below that applies:</li> + <ul> + <li>If there is only one letter left, or if the remaining letters exactly match + an ambiguous symbol in the alphabet, the <b>letter</b> or <b>ambiguous symbol</b>, + respectively, is used.</li> + <li>Otherwise, if the remaining set contains at least 50% of the core + symbols in the alphabet, the alphabet's <b>wildcard</b> + (e.g., "N" for DNA or RNA, and "X" for protein) is used.</li> + <li>Otherwise, the letter with the <b>maximum frequency</b> is used.</li> + </ul> + </ol> + `); + default: + return("Error--Unrecognized shared doc_type: " + doc_type); + } +} // get_shared_doc_text +</script> + <script> +// +// discovery_doc.js +// Documentation common to motif discovery tools. +// + +// +// Function to return the HTML text of a given type. +// This function can be used directly to document the output format (xx-output-format.html) +// and indirectly via print_doc_para for help pop-ups in the actual output HTML, +// to prevent duplication of documentation. +// +function get_discovery_doc_text(doc_type, extra, extra2) { + if (extra == undefined) {extra = ""}; + if (extra2 == undefined) {extra2 = ""}; + + switch (doc_type) { + case 'motif_logo': + return(` + The sequence logo of the motif. + The rules for construction logos are given in + the <i>Description</i> section of the documentation for the MEME Suite utility + <a href="` + extra + `/doc/ceqlogo.html#description">ceqlogo</a>. + `); + case 'motif_rc_logo': + return(` + The sequence logo of the reverse complement motif. + The rules for construction logos are given in + the <i>Description</i> section of the documentation for the MEME Suite utility + <a href="` + extra + `/doc/ceqlogo.html#description">ceqlogo</a>. + `); + case 'more': + return(` + Click on the blue symbol below to reveal detailed information about the motif. + `); + case 'submit_dl': + return(` + Click on the blue symbol below to reveal options allowing you + to submit this motif to another MEME Suite motif analysis program, to download this + motif in various text formats, or to download a sequence "logo" of + this motif PNG or EPS format.</p> + <h5>Supported Programs</h5> + <dl> + <dt>Tomtom</dt> + <dd>Tomtom is a tool for searching for similar known motifs. + [<a href="` + extra + `/doc/tomtom.html?man_type=web">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="` + extra + `/doc/mast.html?man_type=web">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="` + extra + `/doc/fimo.html?man_type=web">manual</a>]</dd> + <dt>GOMo</dt> + <dd>GOMo is a tool for identifying possible roles (Gene Ontology + terms) for DNA binding motifs. + [<a href="` + extra + `/doc/gomo.html?man_type=web">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="` + extra + `/doc/spamo.html?man_type=web">manual</a>]</dd> + </dl> + `); + case 'site_distr': + return(` + This plot shows the positional distribution of the best match to the motif in the ` + + extra + ` sequences. + Only matches with scores at least the ` + + extra2 + ` score threshold are considered. + The plot is smoothed with a triangular function whose width is 5% of the maximum ` + + extra + ` sequence length. + The position of the dotted vertical line indicates whether the sequences were + aligned on their left ends, centers, or right ends, respectively. + `); + case 'site_hist': + return(` + This histogram shows the distribution of the <b>number</b> of matches to the motif in the ` + + extra + ` sequences with at least one match. + Only matches with scores at least the ` + + extra2 + ` score threshold are considered. + `); + default: + return("Error--Unrecognized discovery doc_type: " + doc_type); + } +} // get_discovery_doc_text +</script> + <script> +// +// submit_or_download_motif.js +// + +function make_submit_or_download_motif_form(id, site_url, program) { + var html = ` + <div class="popup_wrapper"> + <div class="popup" style="display:none; top: -150px;" id="download"> + <div> + <div style="float:right; "> + <div id="outpop_close" class="close" tabindex="0">x</div> + </div> + <h2 class="mainh" style="margin:0; padding:0;">Submit or Download</h2> + <div style="clear:both"></div> + </div> + <div style="height:100px"> + <div style="float:right; width: 30px;"> + <div id="outpop_prev" class="navarrow" tabindex="0"> + <span class="inactive">⇧</span><span class="active">⬆</span> + </div> + <div id="outpop_num" class="navnum"></div> + <div id="outpop_next" class="navarrow" tabindex="0"> + <span class="inactive">⇩</span><span class="active">⬇</span> + </div> + </div> + <div id="logo_box" style="height: 100px; margin-right: 40px;"> + <canvas id="outpop_logo" height="100" width="250"></canvas> + <canvas id="outpop_logo_rc" height="100" width="250"></canvas> + </div> + </div> + <!-- tabs start --> + <div class="tabArea top"> + <span id="outpop_tab_1" class="tab">Submit Motif</span><span + id="outpop_tab_2" class="tab middle">Download Motif</span><span + id="outpop_tab_3" class="tab middle">Download Logo</span> + </div> + <div class="tabMain top"> + <!-- Submit to another program --> + <div id="outpop_pnl_1"> + <h4 class="compact">Submit to program</h4> + <table id="programs" class="programs"> + <tr> + <td><input type="radio" name="program" value="tomtom" id="submit_tomtom"></td> + <td><label for="submit_tomtom">Tomtom</label></td> + <td><label for="submit_tomtom">Find similar motifs in + published libraries or a library you supply.</label></td> + </tr> + <tr> + <td><input type="radio" name="program" value="fimo" id="submit_fimo"></td> + <td><label for="submit_fimo">FIMO</label></td> + <td><label for="submit_fimo">Find motif occurrences in + sequence data.</label></td> + </tr> + <tr> + <td><input type="radio" name="program" value="mast" id="submit_mast"></td> + <td><label for="submit_mast">MAST</label></td> + <td><label for="submit_mast">Rank sequences by affinity to + groups of motifs.</label></td> + </tr> + <tr class="dna_only"> + <td><input type="radio" name="program" value="gomo" id="submit_gomo"></td> + <td><label for="submit_gomo">GOMo</label></td> + <td><label for="submit_gomo">Identify possible roles (Gene + Ontology terms) for motifs.</label></td> + </tr> + <tr class="dna_only"> + <td><input type="radio" name="program" value="spamo" id="submit_spamo"></td> + <td><label for="submit_spamo">SpaMo</label></td> + <td><label for="submit_spamo">Find other motifs that are + enriched at specific close spacings which might imply the existence of a complex.</label></td> + </tr> + </table> + </div> + <!-- download text format --> + <div id="outpop_pnl_2"> + <div> + <label for="text_format">Format:</label> + <select id="text_format"> + <option value="0">Count Matrix</option> + <option value="1">Probability Matrix</option> + <option value="2">Minimal MEME</option> ` + + (program == "MEME" ? ` + <option value="3">FASTA</option> + <option value="4">Raw</option> ` : ``) + ` + </select> + </div> + <textarea id="outpop_text" name="content" + style="width:99%; white-space: pre; word-wrap: normal; overflow-x: scroll;" + rows="8" readonly="readonly" wrap="off"></textarea> + <a id="outpop_text_dl" download="meme.txt" href=""></a> + </div> + <!-- download logo format --> + <div id="outpop_pnl_3"> + <form id="logo_form" method="post" action=""> + <input type="hidden" name="program" value=" ` + program + `"/> + <input type="hidden" id="logo_motifs" name="motifs" value=""/> + <input type="hidden" id="logo_id1" name="id1" value=""/> + <table> + <tr> + <td><label for="logo_format">Format:</label></td> + <td> + <select id="logo_format" name="png"> + <option value="1">PNG (for web)</option> + <option value="0">EPS (for publication)</option> + </select> + </td> + </tr> + <tr> + <td><label for="logo_rc">Orientation:</label></td> + <td> + <select id="logo_rc" name="rc1"> + <option value="0">Normal</option> + <option value="1" id="logo_rc_option">Reverse Complement</option> + </select> + </td> + </tr> + <tr> + <td><label for="logo_ssc">Small Sample Correction:</label></td> + <td> + <input type="hidden" id="logo_err" name="errbars" value="0"/> + <select id="logo_ssc" name="ssc"> + <option value="0">Off</option> + <option value="1">On</option> + </select> + </td> + </tr> + <tr> + <td><label for="logo_width">Width:</label></td> + <td> + <input type="text" id="logo_width" size="4" placeholder="default" name="width"/> cm + </td> + </tr> + <tr> + <td><label for="logo_height">Height:</label></td> + <td> + <input type="text" id="logo_height" size="4" placeholder="default" name="height"/> cm + </td> + </tr> + </table> + </form> + </div> + <!-- Buttons --> + <div> + <div style="float:left;"> + <input type="button" id="outpop_do" value="Submit" /> + </div> + <div style="float:right;"> + <input id="outpop_cancel" type="button" value="Cancel" /> + </div> + <div style="clear:both;"></div> + </div> + </div> + </div> + </div> + `; + document.getElementById(id).insertAdjacentHTML('beforeend', html); + $("logo_form").action = site_url + "/utilities/generate_logo"; +} // make_submit_or_download_motif_form + +// +// Functions to update the submit_or_download_motif form. +// + +// +// Initialise and display the download popup. +// +function action_show_outpop(e, ordinal) { + "use strict"; + function init() { + "use strict"; + var close_btn, next_btn, prev_btn, cancel_btn, do_btn; + var tab1, tab2, tab3; + var pnl1, pnl2, pnl3; + var format_list; + var tbl_submit, inputs, i, default_prog; + close_btn = $("outpop_close"); + close_btn.addEventListener("click", action_hide_outpop, false); + close_btn.addEventListener("keydown", action_hide_outpop, false); + next_btn = $("outpop_next"); + next_btn.addEventListener("click", action_outpop_next, false); + next_btn.addEventListener("keydown", action_outpop_next, false); + prev_btn = $("outpop_prev"); + prev_btn.addEventListener("click", action_outpop_prev, false); + prev_btn.addEventListener("keydown", action_outpop_prev, false); + cancel_btn = $("outpop_cancel"); + cancel_btn.addEventListener("click", action_hide_outpop, false); + do_btn = $("outpop_do"); + do_btn.addEventListener("click", action_outpop_submit, false); + tab1 = $("outpop_tab_1"); + tab1.tabIndex = 0; + tab1.addEventListener("click", action_outpop_tab, false); + tab1.addEventListener("keydown", action_outpop_tab, false); + tab2 = $("outpop_tab_2"); + tab2.tabIndex = 0; + tab2.addEventListener("click", action_outpop_tab, false); + tab2.addEventListener("keydown", action_outpop_tab, false); + tab3 = $("outpop_tab_3"); + tab3.tabIndex = 0; + tab3.addEventListener("click", action_outpop_tab, false); + tab3.addEventListener("keydown", action_outpop_tab, false); + pnl1 = $("outpop_pnl_1"); + pnl2 = $("outpop_pnl_2"); + pnl3 = $("outpop_pnl_3"); + toggle_class(tab1, "activeTab", true); + toggle_class(tab2, "activeTab", false); + toggle_class(tab3, "activeTab", false); + pnl1.style.display = "block"; + pnl2.style.display = "none"; + pnl3.style.display = "none"; + format_list = $("text_format"); + format_list.addEventListener("change", action_outpop_format, false); + // setup program selection + tbl_submit = $("programs"); + // when not dna, hide the inputs for programs that require dna motifs + toggle_class(tbl_submit, "alphabet_dna", current_alphabet.has_complement());//TODO alphabet_dna is a bad name for a field when allowing custom alphabets + // add a click listener for the radio buttons + inputs = tbl_submit.querySelectorAll("input[type='radio']"); + for (i = 0; i < inputs.length; i++) { + inputs[i].addEventListener("click", action_outpop_program, false); + } + // ensure that a default program option is selected for DNA and Protein + default_prog = document.getElementById(current_alphabet.has_complement() ? "submit_tomtom" : "submit_fimo"); //TODO Tomtom might require a more strict definition of DNA + default_prog.checked = true; + action_outpop_program.call(default_prog); + // disable reverse-complement when not DNA + $("logo_rc_option").disabled = !current_alphabet.has_complement(); + // set errorbars on when ssc is on + $("logo_ssc").addEventListener("change", action_outpop_ssc, false); + } + // store the focused element + action_hide_outpop.last_active = document.activeElement; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + // hide the help popup + help_popup(); + // on first load initilize the popup + if (!action_show_outpop.ready) { + init(); + action_show_outpop.ready = true; + } + update_outpop_motif(ordinal - 1); + // display the download popup + $("grey_out_page").style.display = "block"; + $("download").style.display = "block"; + $("outpop_close").focus(); +} // action_show_output + +// +// Hide the submit or download popup. +// +function action_hide_outpop(e) { + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + $("download").style.display = "none"; + $("grey_out_page").style.display = "none"; + if (typeof action_hide_outpop.last_active !== "undefined") { + action_hide_outpop.last_active.focus(); + } +} // action_hide_outpop + +/* + * Show the next motif in the download popup. + */ +function action_outpop_next(e) { + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + update_outpop_motif(current_motif + 1); +} // action_outpop_next + +/* + * Show the previous motif in the download popup. + */ +function action_outpop_prev(e) { + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + update_outpop_motif(current_motif - 1); +} // action_outpop_prev + +/* + * Highlight the selected row in the program list. + */ +function action_outpop_program() { + "use strict"; + var table, tr, rows, i; + tr = find_parent_tag(this, "TR"); + table = find_parent_tag(tr, "TABLE"); + rows = table.querySelectorAll("tr"); + for (i = 0; i < rows.length; i++) { + toggle_class(rows[i], "selected", rows[i] === tr); + } +} // action_outpop_program + +/* + * Submit the motif to the selected program. + */ +function action_outpop_submit(e) { + "use strict"; + var form, input, program, motifs; + // find out which program is selected + var radios, i; + radios = document.getElementsByName("program"); + program = "fimo"; // default to fimo, since it works with all alphabet types + for (i = 0; i < radios.length; i++) { + if (radios[i].checked) program = radios[i].value; + } + + motifs = motif_minimal_meme(data.motifs[current_motif]); + form = document.createElement("form"); + form.setAttribute("method", "post"); + form.setAttribute("action", site_url + "/tools/" + program); + + input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "motifs_embed"); + input.setAttribute("value", motifs); + form.appendChild(input); + + var current_file = location.pathname.substring(location.pathname.lastIndexOf('/')+1); + input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", "motifs_name"); + input.setAttribute("value", "motif number " + (current_motif+1) + " from " + current_file); + form.appendChild(input); + + document.body.appendChild(form); + form.submit(); + document.body.removeChild(form); +} // action_outpop_submit(e) + +/* + * Enable error bars when small sample correction is enabled. + */ +function action_outpop_ssc() { + "use strict"; + $("logo_err").value = $("logo_ssc").value; +} // action_outpop_ssc + +// +// Update the motif logos and format download text in the popup. +// This is called whenever the current motif changes. +// +function update_outpop_motif(index) { + "use strict"; + var motifs, motif, pspm, logo, canvas, num; + motifs = data["motifs"]; + if (index < 0 || index >= motifs.length) {return;} + current_motif = index; + motif = motifs[index]; + pspm = new Pspm(motif["pwm"]); + logo = new Logo(current_alphabet, ""); + logo.add_pspm(pspm, 0); + canvas = $("outpop_logo"); + canvas.width = canvas.width; // clear canvas + draw_logo_on_canvas(logo, canvas, false); + canvas = $("outpop_logo_rc"); + canvas.width = canvas.width; // clear rc canvas + if (data.options.strands === "both" || data.options.revcomp) { + pspm.reverse_complement(current_alphabet); + logo = new Logo(current_alphabet, ""); + logo.add_pspm(pspm, 0); + draw_logo_on_canvas(logo, canvas, false); + } + num = $("outpop_num"); + num.innerHTML = ""; + num.appendChild(document.createTextNode("" + (index + 1))); + update_outpop_format(index); +} // action_outpop_motif + +// +// Create the download menu. +// +function update_outpop_format(index) { + var motif = data.motifs[index]; + var fn = [motif_count_matrix, motif_prob_matrix, motif_minimal_meme, motif_fasta, motif_raw]; + var suffix = ["_counts.txt", "_freqs.txt", ".meme", "_fasta.txt", "_raw.txt"]; + var format = parseInt($("text_format").value); + var text = fn[format](motif); + prepare_download(text, "text/plain", motif.id + suffix[format], $("outpop_text_dl")); + $("outpop_text").value = text; +} // update_outpop_format + +/* + * Update the text in the download format popup. + */ +function action_outpop_format() { + update_outpop_format(current_motif); +} // action_outpop_format + +/* + * Download the format text. + * Wire the link containing the data URI text to a download button so it looks + * the same as the server submit stuff. + */ +function action_outpop_download_motif(e) { + $("outpop_text_dl").click(); +} // action_outpop_download_motif + +/* + * Download the motif logo. + * The EPS format can be calculated locally in Javascript + */ +function action_outpop_download_logo(e) { + "use strict"; + var motif = data.motifs[current_motif]; + if ($("logo_format").value === "0") { // EPS + var pspm, logo, eps; + var logo_rc, logo_ssc, logo_width, logo_height; + logo_rc = ($("logo_rc").value === "1"); + logo_ssc = ($("logo_ssc").value === "1"); + logo_width = parseFloat($("logo_width").value); + if (isNaN(logo_width) || !isFinite(logo_width) || logo_width <= 0) logo_width = null; + logo_height = parseFloat($("logo_height").value); + if (isNaN(logo_height) || !isFinite(logo_height) || logo_height <= 0) logo_height = null; + // create a PSPM from the motif + pspm = motif_pspm(motif); + if (logo_rc) pspm.reverse_complement(current_alphabet); + logo = new Logo(current_alphabet); + logo.add_pspm(pspm, 0); + eps = logo.as_eps({"ssc": logo_ssc, "logo_width": logo_width, "logo_height": logo_height}); + prepare_download(eps, "application/postscript", motif.id + (logo_rc ? "_rc" : "") + ".eps"); + } else { + $("logo_motifs").value = motif_minimal_meme(motif); + $("logo_id1").value = motif.id; + $("logo_form").submit(); + } +} // action_outpop_download_logo + +/* + * Change the selected tab in the download popup. + */ +function action_outpop_tab(e) { + "use strict"; + var tab1, tab2, tab3, pnl1, pnl2, pnl3, do_btn; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + tab1 = $("outpop_tab_1"); + tab2 = $("outpop_tab_2"); + tab3 = $("outpop_tab_3"); + pnl1 = $("outpop_pnl_1"); + pnl2 = $("outpop_pnl_2"); + pnl3 = $("outpop_pnl_3"); + do_btn = $("outpop_do"); + + toggle_class(tab1, "activeTab", (this === tab1)); + toggle_class(tab2, "activeTab", (this === tab2)); + toggle_class(tab3, "activeTab", (this === tab3)); + pnl1.style.display = ((this === tab1) ? "block" : "none"); + pnl2.style.display = ((this === tab2) ? "block" : "none"); + pnl3.style.display = ((this === tab3) ? "block" : "none"); + do_btn.value = ((this === tab1) ? "Submit" : "Download"); + do_btn.removeEventListener("click", action_outpop_submit, false); + do_btn.removeEventListener("click", action_outpop_download_logo, false); + do_btn.removeEventListener("click", action_outpop_download_motif, false); + if (this === tab1) { + do_btn.addEventListener("click", action_outpop_submit, false); + } else if (this === tab2) { + do_btn.addEventListener("click", action_outpop_download_motif, false); + } else { + do_btn.addEventListener("click", action_outpop_download_logo, false); + } +} // action_outpop_tab + +function motif_fasta(motif) { + "use strict"; + var sites, site, seq, sequences, sequence, i, num, counter, out; + counter = {}; + sequences = data["sequence_db"]["sequences"]; + sites = motif["sites"]; + out = ""; + for (i = 0; i < sites.length; i++) { + site = sites[i]; + seq = site["seq"]; + sequence = sequences[seq]; + counter[seq] = (num = counter[seq]) ? (++num) : (num = 1); // inc counter + if (i !== 0) {out += "\n";} + out += ">" + sequence["name"] + "_site_" + num + " offset= " + site["pos"] + + (site["rc"] ? " RC\n" : "\n"); + out += site["match"]; + } + return out; +} // motif_fasta + +function motif_raw(motif) { + "use strict"; + var sites, i, out; + sites = motif["sites"]; + out = ""; + for (i = 0; i < sites.length; i++) { + if (i !== 0) {out += "\n";} + out += sites[i]["match"]; + } + return out; +} // motif_raw + +/* + * Create a pspm for the given motif data + */ +function motif_pspm(motif) { + var pwm = motif.pwm; + var name = motif.id; + var ltrim = 0; + var rtrim = 0; + var nsites = motif.nsites; + var sig = (current_program === "STREME" ? motif.test_pvalue : motif.evalue); + return new Pspm(pwm, name, ltrim, rtrim, nsites, sig, null, motif.alt, current_program); +} // motif_pspm + +/* + * Create a count matrix from the given motif data + */ +function motif_count_matrix(motif) { + return motif_pspm(motif).as_count_matrix(); +} // motif_count_matrix + +/* + * Create a probablity matrix from the given motif data + */ +function motif_prob_matrix(motif) { + return motif_pspm(motif).as_probability_matrix(); +} // motif_prob_matrix + +function motif_minimal_meme(motif) { + var strands; + if (current_program === "STREME") { + strands = (data.options.strands === "both" ? 2 : 1); + } else { + strands = (data.options.revcomp ? 2 : 1); + } + return motif_pspm(motif).as_meme({ + "with_header": true, + "with_pspm": true, + "with_pssm": (current_program === "MEME" ? true : false), + "version": data["version"], + "alphabet": current_alphabet, + "strands": strands + }); +} +</script> + <script> +var current_program = "MEME"; +var current_alphabet = new Alphabet(data.alphabet, data.background.freqs); +var current_motif = 0; +//var new_icon_src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAQCAMAAAAyEe/dAAAACVBMVEX//wAAAAD////s2cV/AAAAdUlEQVQYlXVRBxLAIAhL+P+jC2HZhXcBZEWEldDsZcLIcAhHWWnK8SDcWQhMFUHdAQ1CqQ5+CWPmlHojl+nCJNRtzu4qRc3IUzmTVpXYK0nox0z0PI1stgchdK7lEv7ekhvalw8WW547Gyzedt/2/gLx8WXjXF/1AYFriNAWAAAAAElFTkSuQmCC"; + +var DelayLogoTask = function(logo, canvas) { + this.logo = logo; + this.canvas = canvas; +}; + +DelayLogoTask.prototype.run = function () { + draw_logo_on_canvas(this.logo, this.canvas, false); +}; + +function clone_template(template) { + "use strict"; + var node, help_btns, i, button; + node = $(template).cloneNode(true); + toggle_class(node, "template", false); + node.id = ""; + help_btns = node.querySelectorAll(".help"); + for (i = 0; i < help_btns.length; i++) { + button = help_btns[i]; + if (button.hasAttribute("data-topic")) { + button.tabIndex = "0"; + button.addEventListener("click", __toggle_help, false); + button.addEventListener("keydown", __toggle_help, false); + } + } + return node; +} + +function make_small_logo(alphabet, pspm, options) { + if (typeof options === "undefined") options = {}; + if (options.rc) pspm = pspm.copy().reverse_complement(alphabet); + var logo = new Logo(alphabet, {x_axis: false, y_axis: false}); + logo.add_pspm(pspm, (typeof options.offset === "number" ? options.offset : 0)); + var canvas = document.createElement('canvas'); + if (typeof options.className === "string") canvas.className = options.className; + if (typeof options.width === "number" && options.width > 0) { + canvas.height = 0; + canvas.width = options.width; + draw_logo_on_canvas(logo, canvas, false); + } else { + draw_logo_on_canvas(logo, canvas, false, 1/3); + } + return canvas; +} + +function make_large_logo(alphabet, pspm, rc, offset, className) { + if (rc) pspm = pspm.copy().reverse_complement(alphabet); + var logo = new Logo(alphabet, ""); + logo.add_pspm(pspm, offset); + var canvas = document.createElement('canvas'); + canvas.height = 200; + canvas.width = 0; + canvas.className = className; + size_logo_on_canvas(logo, canvas, false); + add_draw_task(canvas, new DelayLogoTask(logo, canvas)); + return canvas; +} + +function make_sym_btn(symbol, title, action) { + var box; + box = document.createElement("div"); + box.tabIndex = 0; + box.className = "sym_btn"; + box.appendChild(document.createTextNode(symbol)); + box.title = title; + box.addEventListener('click', action, false); + box.addEventListener('keydown', action, false); + return box; +} + +function make_seq(alphabet, seq) { + var i, j, letter, lbox, sbox; + sbox = document.createElement("span"); + for (i = 0; i < seq.length; i = j) { + letter = seq.charAt(i); + for (j = i+1; j < seq.length; j++) { + if (seq.charAt(j) !== letter) { + break; + } + } + lbox = document.createElement("span"); + lbox.style.color = alphabet.get_colour(alphabet.get_index(letter)); + lbox.appendChild(document.createTextNode(seq.substring(i, j))); + sbox.appendChild(lbox); + } + return sbox; +} + +// +// make_pv_text +// +// Returns the string p-value, with the p italicised. +/// +function make_pv_text() { + var pv_text = document.createElement("span"); + var pv_italic_text = document.createElement("span"); + pv_italic_text.appendChild(document.createTextNode("p")); + pv_italic_text.style.fontStyle = "italic"; + pv_text.appendChild(pv_italic_text); + pv_text.appendChild(document.createTextNode("-value")); + return pv_text; +} + +function append_site_entries(tbody, motif, site_index, count) { + "use strict"; + var i, end; + var sites, site, sequences, sequence; + var rbody; + if (typeof count !== "number") { + count = 20; + } + sequences = data["sequence_db"]["sequences"]; + sites = motif["sites"]; + end = Math.min(site_index + count, sites.length); + for (i = site_index; i < end; i++) { + site = sites[i]; + sequence = sequences[site["seq"]]; + + rbody = tbody.insertRow(tbody.rows.length); + add_text_cell(rbody, "" + (site["seq"] + 1) + ".", "site_num"); + add_text_cell(rbody, sequence["name"], "site_name"); + add_text_cell(rbody, site["rc"] ? "-" : "+", "site_strand"); + add_text_cell(rbody, site["pos"] + 1, "site_start"); + add_text_cell(rbody, site["pvalue"].toExponential(2), "site_pvalue"); + add_text_cell(rbody, site["lflank"], "site lflank"); + add_cell(rbody, make_seq(current_alphabet, site["match"]), "site match"); + add_text_cell(rbody, site["rflank"], "site rflank"); + } + return i; +} + +function make_site_entries() { + "use strict"; + var region; + region = this; + if (region.data_site_index >= region.data_motif["sites"].length) { + // all sites created + region.removeEventListener('scroll', make_site_entries, false); + return; + } + // if there's still 100 pixels to scroll than don't do anything yet + if (region.scrollHeight - (region.scrollTop + region.offsetHeight) > 100) { + return; + } + + region.data_site_index = append_site_entries( + find_child(region, "sites_tbl").tBodies[0], + region.data_motif, region.data_site_index, 20 + ); +} + +function make_sites(motif) { + "use strict"; + function add_site_header(row, title, nopad, help_topic, tag_class) { + var div, divcp, th; + th = document.createElement("th"); + div = document.createElement("div"); + div.className = "sites_th_inner"; + if (typeof title !== "object") { + title = document.createTextNode("" + title); + } + div.appendChild(title); + if (help_topic) { + div.appendChild(document.createTextNode("\xA0")); + div.appendChild(help_button(help_topic)); + } + divcp = div.cloneNode(true); + divcp.className = "sites_th_hidden"; + th.appendChild(div); + th.appendChild(divcp); + if (nopad) { + th.className = "nopad"; + } + if (tag_class) { + th.className += " " + tag_class; + } + row.appendChild(th); + } + var outer_tbl, inner_tbl, tbl, thead, tbody, rhead; + + outer_tbl = document.createElement("div"); + outer_tbl.className = "sites_outer"; + + inner_tbl = document.createElement("div"); + inner_tbl.className = "sites_inner"; + outer_tbl.appendChild(inner_tbl); + + tbl = document.createElement("table"); + tbl.className = "sites_tbl"; + inner_tbl.appendChild(tbl); + + thead = document.createElement("thead"); + tbl.appendChild(thead); + tbody = document.createElement("tbody"); + tbl.appendChild(tbody); + + rhead = thead.insertRow(thead.rows.length); + add_site_header(rhead, "", true); + add_site_header(rhead, "Name", false, "pop_seq_name"); + add_site_header(rhead, "Strand", false, "pop_site_strand", "site_strand_title"); + add_site_header(rhead, "Start", false, "pop_site_start"); + add_site_header(rhead, make_pv_text(), false, "pop_site_pvalue"); + add_site_header(rhead, "", false); + add_site_header(rhead, "Sites", true, "pop_site_match"); + add_site_header(rhead, "", false); + + inner_tbl.data_motif = motif; + inner_tbl.data_site_index = append_site_entries(tbody, motif, 0, 20); + if (inner_tbl.data_site_index < motif["sites"].length) { + inner_tbl.addEventListener('scroll', make_site_entries, false); + } + return outer_tbl; +} + +function make_motif_table_entry(row, alphabet, ordinal, motif, colw) { + "use strict"; + function ev_sig(evalue_str) { + "use strict"; + var ev_re, match, sig, exp, num; + ev_re = /^(.*)e(.*)$/; + if (match = ev_re.exec(evalue_str)) { + sig = parseFloat(match[1]); + exp = parseInt(match[2]); + if (exp >= 0) { + return false; + } else if (exp <= -3) { + return true; + } else { + return sig * Math.pow(10, exp) <= 0.05; + } + } + return true; + } + function make_preview(alphabet, motif) { + "use strict"; + var pspm, preview, preview_rc; + var box, btn_box, logo_box, btn_plus, btn_minus; + if (motif["preview_logo"]) { + preview = motif["preview_logo"]; + preview_rc = motif["preview_logo_rc"]; + } else { + pspm = new Pspm(motif["pwm"]); + preview = make_logo(alphabet, pspm, 50, false, 0); + motif["preview_logo"] = preview; + if (alphabet.has_complement()) { + preview_rc = make_logo(alphabet, pspm, 50, true, 0, "logo_rc"); + motif["preview_logo_rc"] = preview_rc; + } + } + if (preview_rc) { + btn_plus = document.createElement("div"); + btn_plus.appendChild(document.createTextNode("+")); + btn_plus.className = "preview_btn plus"; + btn_plus.tabIndex = "0"; + btn_plus.addEventListener("click", action_btn_rc, false); + btn_plus.addEventListener("keydown", action_btn_rc, false); + btn_minus = document.createElement("div"); + btn_minus.appendChild(document.createTextNode("-")); + btn_minus.className = "preview_btn minus"; + btn_minus.tabIndex = "0"; + btn_minus.addEventListener("click", action_btn_rc, false); + btn_minus.addEventListener("keydown", action_btn_rc, false); + btn_box = document.createElement("div"); + btn_box.className = "preview_btn_box"; + btn_box.appendChild(btn_plus); + btn_box.appendChild(btn_minus); + } + logo_box = document.createElement("div"); + logo_box.className = "preview_logo_box"; + logo_box.appendChild(preview); + if (preview_rc) logo_box.appendChild(preview_rc); + box = document.createElement("div"); + box.className = "preview_box"; + if (preview_rc) box.appendChild(btn_box); + box.appendChild(logo_box); + if (preview_rc) { + if (motif["rc"]) { + btn_minus.className += " active"; + logo_box.className += " show_rc_logo"; + } else { + btn_plus.className += " active"; + } + } + return box; + } + var pspm, preview, preview_rc, c; + row.data_motif = motif; + row.id = motif["alt"]; + row.data_ordinal = ordinal; + if (!ev_sig(motif["evalue"])) { + row.style.opacity = 0.4; + } + add_text_cell(row, "" + ordinal + ".", "motif_ordinal"); + add_cell(row, make_preview(alphabet, motif), "motif_logo"); + add_text_cell(row, motif["evalue"], "motif_evalue"); + add_text_cell(row, motif["nsites"], "motif_nsites"); + add_text_cell(row, motif["len"], "motif_width"); + add_cell(row, make_sym_btn("\u21A7", "Show more information.", + action_show_more), "motif_more"); + add_cell(row, make_sym_btn("\u21E2", "Submit the motif to another MEME Suite program or download it.", function(e) { action_show_outpop(e, ordinal); }), "motif_submit"); + if (colw) { + for (c = 0; c < row.cells.length; c++) { + row.cells[c].style.minWidth = colw[c] + "px"; + } + } +} + +function make_motifs_table(alphabet, start_ordinal, motifs, colw, stop_reason) { + var i, j; + var tbl, thead, tbody, tfoot, row, preview; + var motif, pspm; + + tbl = document.createElement("table"); + + thead = document.createElement("thead"); + tbl.appendChild(thead); + tbody = document.createElement("tbody"); + tbl.appendChild(tbody); + tfoot = document.createElement("tfoot"); + tbl.appendChild(tfoot); + + row = thead.insertRow(thead.rows.length); + add_text_header_cell(row, "", "", "motif_ordinal"); + add_text_header_cell(row, "Logo", "pop_logo", "motif_logo"); + add_text_header_cell(row, "E-value", "pop_ev", "motif_evalue"); + add_text_header_cell(row, "Sites", "pop_sites", "motif_nsites"); + add_text_header_cell(row, "Width", "pop_width", "motif_width"); + add_text_header_cell(row, "More", "pop_more", "motif_more"); + add_text_header_cell(row, "Submit/Download", "pop_submit_dl", "motif_submit"); + + for (i = 0; i < motifs.length; i++) { + row = tbody.insertRow(tbody.rows.length); + make_motif_table_entry(row, alphabet, start_ordinal + i, motifs[i], colw); + } + + row = tfoot.insertRow(tfoot.rows.length); + add_text_header_cell(row, stop_reason, "", "stop_reason", "", 6); + + return tbl; +} + +function make_expanded_motif(alphabet, ordinal, motif, less_x, submit_x) { + "use strict"; + var box, pspm, logo_box, large_logo, large_logo_rc, tab_logo, tab_logo_rc; + var btn, offset, norc; + + box = clone_template("tmpl_motif_expanded"); + box.data_motif = motif; + box.data_ordinal = ordinal; + + pspm = new Pspm(motif["pwm"]); + if (typeof motif["rc"] !== "boolean") { + motif["rc"] = false; + } + if (motif["large_logo"]) { + large_logo = motif["large_logo"]; + large_logo_rc = motif["large_logo_rc"]; + } else { + large_logo = make_large_logo(alphabet, pspm, false, 0); + motif["large_logo"] = large_logo; + if (alphabet.has_complement()) { + large_logo_rc = make_large_logo(alphabet, pspm, true, 0, "logo_rc"); + motif["large_logo_rc"] = large_logo_rc; + } + } + norc = (large_logo_rc == null); + toggle_class(box, "norc", norc); + + logo_box = find_child(box, "tvar_logo"); + logo_box.appendChild(large_logo); + if (large_logo_rc) logo_box.appendChild(large_logo_rc); + toggle_class(logo_box, "show_rc_logo", motif["rc"]); + + tab_logo = find_child(box, "tvar_tab"); + tab_logo_rc = find_child(box, "tvar_tab_rc"); + + toggle_class(tab_logo, "activeTab", !motif["rc"]); + toggle_class(tab_logo_rc, "activeTab", motif["rc"]); + + tab_logo.addEventListener('click', action_rc_tab, false); + tab_logo.addEventListener('keydown', action_rc_tab, false); + tab_logo_rc.addEventListener('click', action_rc_tab, false); + tab_logo_rc.addEventListener('keydown', action_rc_tab, false); + + set_tvar(box, "tvar_ordinal", ordinal); + set_tvar(box, "tvar_evalue", motif["evalue"]); + set_tvar(box, "tvar_width", motif["len"]); + set_tvar(box, "tvar_site_count", motif["nsites"]); + set_tvar(box, "tvar_llr", motif["llr"]); + set_tvar(box, "tvar_ic", motif["ic"]); + set_tvar(box, "tvar_re", motif["re"]); + set_tvar(box, "tvar_bt", motif["bt"]); + if (data.sequence_db.primary_count > data.options.brief) { + if (data.options.brief == 1000) { + set_tvar(box, "tvar_sites", "Output of sites suppressed because there were more than 1000 (primary) sequences."); + } else { + set_tvar(box, "tvar_sites", "Output of sites suppressed by -brief option."); + } + } else { + set_tvar(box, "tvar_sites", make_sites(motif)); + } + + offset = 32; // 1* 5px padding + 2 * 10px padding + 2 * 2px border + 3px ?? + + btn = find_child(box, "tvar_less"); + btn.style.left = (less_x - offset) + "px"; + btn.addEventListener('click', action_show_less, false); + btn.addEventListener('keydown', action_show_less, false); + btn = find_child(box, "tvar_submit"); + btn.style.left = (submit_x - offset) + "px"; + btn.addEventListener('click', action_show_outpop, false); + btn.addEventListener('keydown', action_show_outpop, false); + return box; +} + +// +// +// +function make_motifs() { + "use strict"; + function pixel_value(str_in) { + "use strict"; + var px_re, match; + px_re = /^(\d+)px$/; + if (match = px_re.exec(str_in)) { + return parseInt(match[1], 10); + } + return 0; + } + var container, tbl; + var colw, r, row, c, cell, cell_style, pad_left, pad_right; + + // make the motifs table + container = $("motifs"); + container.innerHTML = ""; // clear content + + tbl = make_motifs_table(current_alphabet, 1, data["motifs"], colw, data["stop_reason"]); + container.appendChild(tbl); + + // measure table column widths + colw = []; + row = tbl.tBodies[0].rows[0]; + for (c = 0; c < row.cells.length; c++) { + var padLeft, padRight; + cell = row.cells[c]; + cell_style = window.getComputedStyle(cell, null); + pad_left = pixel_value(cell_style.getPropertyValue("padding-left")); + pad_right = pixel_value(cell_style.getPropertyValue("padding-right")); + colw[c] = cell.clientWidth - pad_left - pad_right; + if (typeof colw[c] !== "number" || colw[c] < 0) { + colw[c] = 1; + } + } + + // set minimum table column widths on each row so later when we remove rows it still aligns + for (r = 0; r < tbl.tBodies[0].rows.length; r++) { + row = tbl.tBodies[0].rows[r]; + for (c = 0; c < row.cells.length; c++) { + row.cells[c].style.minWidth = colw[c] + "px"; + } + } + + // store the table column widths so we can create rows latter with the same minimums + container.data_colw = colw; + + // calculate the x offset for the buttons + row = tbl.tBodies[0].rows[0]; + container.data_more_x = coords(find_child(find_child(row, "motif_more"), "sym_btn"))[0]; + container.data_submit_x = coords(find_child(find_child(row, "motif_submit"), "sym_btn"))[0]; + + draw_on_screen(); +} + +function make_meme_block(container, max_seq_len, is_scan, site) { + "use strict"; + var motif = data.motifs[site.motif]; + var block = make_block(container, max_seq_len, site.pos, motif.len, + site.pvalue, site.rc, site.motif, is_scan); + var handler = (is_scan ? + make_scan_popup(site, motif, block) : + make_block_popup(site, motif, block)); + block.addEventListener("mouseover", handler, false); + block.addEventListener("mouseout", handler, false); +} + +function append_blocks_entries(tbody, seq_index, count) { + "use strict"; + var i, end, j; + var max_pvalue, max_block_height, max_seq_len, sequences; + var sequence, sites, scans, scan; + var container, plus, minus, rule, row; + // define some constants + max_seq_len = data.sequence_db.max_length; + // determine how many to load + end = Math.min(seq_index + count, data.sequence_db.sequences.length); + for (i = seq_index; i < end; i++) { + // get the sequence + sequence = data.sequence_db.sequences[i]; + // make the containers for the block diagram + container = make_block_container(current_alphabet.has_complement(), + data.options.revcomp, max_seq_len, sequence.length); + // create blocks for the motif sites + sites = sequence["sites"]; + for (j = 0; j < sites.length; j++) + make_meme_block(container, max_seq_len, false, sites[j]); + // create blocks for the scanned sites + scan = data.scan[i]; + for (j = 0; j < scan.sites.length; j++) + make_meme_block(container, max_seq_len, true, scan.sites[j]); + // create a row for the sequence + row = tbody.insertRow(tbody.rows.length); + toggle_class(row, "empty_seq", sites.length == 0 && scan.sites.length == 0); + toggle_class(row, "only_scan", sites.length == 0 && scan.sites.length > 0); + add_text_cell(row, (i + 1) + ".", "blockdiag_num"); + add_text_cell(row, sequence["name"], "blockdiag_name"); + add_text_cell(row, scan["pvalue"].toExponential(2), "blockdiag_pvalue"); + add_cell(row, container, "block_td"); + } + return end; +} + +function make_blocks_entries() { + "use strict"; + var region; + region = this; + if (region.data_blocks_index >= data["sequence_db"]["sequences"].length) { + // all sites created + region.removeEventListener('scroll', make_blocks_entries, false); + return; + } + // if there's still 100 pixels to scroll then don't do anything yet + if (region.scrollHeight - (region.scrollTop + region.offsetHeight) > 100) { + return; + } + + region.data_blocks_index = append_blocks_entries( + find_child(region, "blocks_tbl").tBodies[0], + region.data_blocks_index, 20 + ); +} + +// Apply opacity alpha to color rgb with backrgound bkg. +function RGBAtoRGB(rgb, bkg, opacity) { + var i; + var rgb_new = []; + for (i=0; i<3; i++) { + rgb_new[i] = Math.round(((1-opacity) * bkg[i]) + (opacity * rgb[i])); + } + return rgb_new; +} + +// Function to measure the size of text on a canvas. +var MeasureText = function(font, text) { + var image = document.createElement("canvas"); + var image_ctx = image.getContext('2d'); + image_ctx.save(); + image_ctx.font = font; + var text_length = image_ctx.measureText(text).width; + image.remove(); + return text_length; +} // MeasureText + +// Functions to download the motif block diagram as a PDF or SVG file. +function download_PDF_block_diagram() { + downloadBlockDiagram(true, 'bitbucket'); +} +function download_SVG_block_diagram() { + downloadBlockDiagram(false, 'bitbucket'); +} + +// Helper function to create a script element for downloading javascript. +function createScriptElement(url, file, integrity) +{ + console.log('Downloading ' + file + ' from ' + url + '.'); + const script = document.createElement('script'); + script.setAttribute('src', url + '/' + file); + if (integrity) script.setAttribute('integrity', integrity); + script.setAttribute('crossorigin', 'anonymous'); + script.setAttribute('async', ''); + document.head.appendChild(script); +} + +// Helper function to download the motif block diagram as a PDF or SVG file. +var downloadBlockDiagram = function( + make_pdf, + next_source +) { + var script_file, integrity_key; + // Check if necessary javascript has been loaded. + if ( (make_pdf && typeof jsPDF === 'undefined') || + (!make_pdf && typeof d3 === 'undefined') ) { + if (next_source === 'bitbucket') { + if (make_pdf) { + script_file = 'jspdf.min.js'; + } else { + script_file = 'd3.v5.min.js'; + } + createScriptElement('https://memesuite.bitbucket.io/javascript', script_file); + // Wait 3 seconds and then try to create the diagram. + setTimeout(downloadBlockDiagram, 3000, make_pdf, 'cloudflare'); + } else if (next_source === 'cloudflare') { + if (make_pdf) { + script_file = 'jspdf/1.5.3/jspdf.min.js'; + integrity_key = 'sha512-ToRWKKOvhBSS8EtqSflysM/S7v9bB9V0X3B1+E7xo7XZBEZCPL3VX5SFIp8zxY19r7Sz0svqQVbAOx+QcLQSAQ==' + } else { + script_file = 'd3/5.16.0/d3.min.js'; + integrity_key = 'sha512-FHsFVKQ/T1KWJDGSbrUhTJyS1ph3eRrxI228ND0EGaEp6v4a/vGwPWd3Dtd/+9cI7ccofZvl/wulICEurHN1pg=='; + } + createScriptElement('https://cdnjs.cloudflare.com/ajax/libs', script_file, integrity_key); + // Wait 3 seconds and then try to create the diagram. + setTimeout(downloadBlockDiagram, 3000, make_pdf, 'none'); + } else { + // No more sources for javascript. Call so error message will be shown. + downloadBlockDiagramMain(make_pdf); + } + } else { + // Create the diagram. + downloadBlockDiagramMain(make_pdf); + } +} + +// Main function to download the motif block diagram as a PDF or SVG file. +var downloadBlockDiagramMain= function( + make_pdf +) { + // Check that necessary javascript was downloaded. + if ( (make_pdf && typeof jsPDF === 'undefined') || + (!make_pdf && typeof d3 === 'undefined') ) { + var id = make_pdf ? $("pdfButton") : $("svgButton"); + help_popup(id, "pop_offline"); + return; + } + + // Determine which lines are visible in the HTML inner scroll window. + var inner_tbl = $("blocks_scroll"); + var pix_per_sequence = 27; // (vertical) pixels per sequence diagram line + var first = Math.round(inner_tbl.scrollTop / pix_per_sequence) + 1; + var last = first + Math.round(inner_tbl.offsetHeight / pix_per_sequence) - 1; + + // Get the contents of the HTML inner scroll window while saving the sequences to be printed. + var numbers = document.getElementsByClassName("blockdiag_num"); + var bars = {}; + var visible_motifs = {}; + var seq_index = 0; + var rgb; + for (var i=0; i<numbers.length && seq_index < last; i++) { + var row_node = numbers[i].parentNode; + // Check if the sequence is displayed in the outer scrolling window. + var seq_name = numbers[i].nextSibling.innerHTML; + if ( + ($("rdo_sites_only").checked && row_node.getAttribute("class").includes("only_scan")) + || + (! $("rdo_all_seqs").checked && row_node.getAttribute("class").includes("empty_seq")) + ) { continue; } + seq_index++; + + if (seq_index < first) { continue; } // sequence not in HTML inner scrolling window + + var pvalue = numbers[i].nextSibling.nextSibling.innerHTML; + var far = numbers[i].nextSibling.nextSibling.nextSibling.children[0].children; + var seq_length = data.sequence_db.sequences[i].length; + + var seqObj = []; + seqObj["length"] = seq_length; + seqObj["pvalue"] = pvalue; + seqObj["pn"] = []; + seqObj["width"] = []; + seqObj["left"] = []; + seqObj["height"] = []; + seqObj["color"] = []; + seqObj["opacity"] = []; + for (var x = 0; x < far.length; x++) { + if ((far[x].getAttribute("style") != null) + && ( + ( $("rdo_sites_only").checked && ! far[x].getAttribute("class").includes("scanned")) + || ( $("rdo_sites_and_scan").checked || $("rdo_all_seqs").checked ) + ) + ) { + if (far[x].getAttribute("style").includes("rgb")) { + var compStyles = far[x].style; + // Make scanned sites get displayed first so they will not "cover" regular sites. + var site_pn = far[x].getAttribute("class").includes("top") ? "+" : "-"; + var site_width = parseFloat(compStyles.width.slice(0, -1)); + var site_left = parseFloat(compStyles.left.slice(0, -1)); + var site_height = parseFloat(compStyles.height.slice(0, -2)); + var site_color = compStyles.backgroundColor.slice(4, -1).replace(/ /g, ""); + if (far[x].getAttribute("class").includes("scanned")) { + seqObj["pn"].unshift(site_pn); + seqObj["width"].unshift(site_width); + seqObj["left"].unshift(site_left); + seqObj["height"].unshift(site_height); + seqObj["color"].unshift(site_color); + seqObj["opacity"].unshift(0.3); + } else { + seqObj["pn"].push(site_pn); + seqObj["width"].push(site_width); + seqObj["left"].push(site_left); + seqObj["height"].push(site_height); + seqObj["color"].push(site_color); + seqObj["opacity"].push(1); + } + visible_motifs[far[x].getAttribute("data-colour-index")] = site_color; + } + } + } + // Save the sequence data if it has motifs (or rdo_all_seqs is checked) + if ($("rdo_all_seqs").checked || seqObj["width"].length > 0) { + bars[seq_name] = seqObj; + } + } + + // jsPDF coordinates are always in points. + var font_size = 13; + var nbars = Object.keys(bars).length; + var legend_font_size = 0.8 * font_size; + + // Initialize field widths in points by measuring header text. + var font = "bold " + font_size + "pt Helvetica, sans-serif"; + var max_name_width = MeasureText(font, "Name"); + var max_pvalue_width = MeasureText(font, "p-value"); + + var max_seq_length = 0; // in characters + var has_complement = current_alphabet.has_complement(); + var revcomp = data.options["revcomp"]; + + // Measure text of numbers, names and p-values, convert to points and save the max. + font = font_size + "pt Helvetica, sans-serif"; + var seq_name; + for (seq_name in bars) { + var seq_name_width = MeasureText(font, seq_name); + var pvalue_width = MeasureText(font, pvalue); + var seq_length = bars[seq_name]["length"]; + if (seq_length > max_seq_length) { max_seq_length = seq_length; } + if (seq_name_width > max_name_width) { max_name_width = seq_name_width; } + if (pvalue_width > max_pvalue_width) { max_pvalue_width = pvalue_width; } + } + + // Get the length in characters of the longest visible motif. + var max_motif_length = 0; + var motif_index, motif_length; + for (motif_index in visible_motifs) { + motif_length = data.motifs[motif_index].len; + if (motif_length > max_motif_length) { max_motif_length = motif_length; } + } + + // Sort the motif indices. + var motif_indices = []; + var sorted_motif_indices = []; + for (motif_index in visible_motifs) { + motif_indices.push(Number(motif_index)); + } + sorted_motif_indices = motif_indices.sort(function(a, b){return a-b;}); + + // Set up values for main section. + var height = (nbars+1) * (2.6*font_size); + var nmotifs = Object.keys(visible_motifs).length; + var name_field_width = max_name_width + font_size; + var pvalue_field_width = max_pvalue_width + font_size; + var plus_minus_field_width = has_complement ? 2*font_size : font_size; + var non_diagram_width = name_field_width + pvalue_field_width + plus_minus_field_width; + var diagram_width = 47 * font_size; + var pix_per_char = diagram_width/max_seq_length; + var x_scale_factor = data.sequence_db.max_length/100; // Scale factor comes from function make_block(). + var diagram_line_height = (height-2*font_size)/nbars; + var doc_width = diagram_width + non_diagram_width + 2*font_size; + var doc_height = height + 0.5*font_size; + + // Set up values for the legend. + var tmp_font = legend_font_size + "pt Courier, normal"; + var courier_width = MeasureText(tmp_font, "A"); + + var legend_line_height = 1.2 * legend_font_size; + var index_field_width = 3 * legend_font_size; + var symbol_field_width = 5 * legend_font_size; + var legend_non_consensus_width = index_field_width + symbol_field_width + 3*legend_font_size; + var legend_hdr_font = legend_font_size + "pt Helvetica, sans-serif"; + var consensus_hdr_width = MeasureText(legend_hdr_font, "Motif Consensus"); + var consensus_field_width = doc_width - legend_non_consensus_width - legend_font_size; + // Get number of characters that will fit in legend consensus field. + var legend_split_length = Math.floor(consensus_field_width/courier_width); + // Get number of lines in legend. + var n_legend_lines = 0; + for (motif_index in visible_motifs) { + motif_length = data.motifs[motif_index].len; + n_legend_lines += Math.ceil(motif_length/legend_split_length); + } + if (n_legend_lines > 0) { n_legend_lines += 3; } // header line + 2*space + var legend_width = legend_non_consensus_width + Math.min(legend_split_length, max_motif_length)*courier_width; + var legend_height = n_legend_lines * legend_line_height; + doc_height += legend_height + 1*font_size; + + if (make_pdf) { + // Now create the PDF document. + // This next line is necessary because jsPDF silently swaps width and height. + var orient = doc_width > doc_height ? 'landscape' : 'portrait'; + doc = new jsPDF( + { + orientation: orient, + unit: 'pt', + format: [doc_width, doc_height] + } + ); + + // Set the font size for the PDF. + doc.setFontSize(1.33*font_size); + + // Create the header. + var offset = font_size; + var liney = 1.5*font_size; + // .. Name hdr .. + doc.setFont("Helvetica", "bold"); + doc.text("Name", offset, liney); + offset += name_field_width; + + // p-value hdr + doc.setFont("Helvetica", "bolditalic"); + doc.text("p", offset + font_size, liney); + doc.setFont("Helvetica", "bold"); + doc.text("-value", offset + 2*font_size, liney); + offset += pvalue_field_width + plus_minus_field_width; + + // Motif Location hdr + doc.text("Motif Locations", offset, liney); + + // Generate the data object for the PDF. + liney -= 0.5*font_size; + var dy = font_size/3.5; + for (var seq_name in bars) { + liney += diagram_line_height; + offset = font_size; + + // + // Generate the text fields. + // + doc.setFont("Helvetica", "normal"); + + // Sequence name text + doc.text(seq_name, offset, liney + dy); + offset += name_field_width; + + // p-value text + doc.text(bars[seq_name]["pvalue"], offset + pvalue_field_width, liney + dy, {align: "right"}); + offset += pvalue_field_width; + + // +/- text (optional) + if (has_complement) { + doc.text("+", offset+font_size, liney + dy - font_size/2); + if (revcomp) { + doc.text("-", offset+1.15*font_size, liney + dy + font_size/2); + } + } + offset += plus_minus_field_width; + + // Generate the base line. + doc.setLineWidth(0.35); + doc.line(offset, liney, offset + (bars[seq_name]["length"] * pix_per_char), liney); + + // Generate the blocks. + for (var i = 0; i < bars[seq_name]["width"].length; i++) { + if (bars[seq_name]["pn"][i] == undefined) { continue; } + rgb = bars[seq_name]["color"][i].split(",").map(Number); + var opacity = bars[seq_name]["opacity"][i]; + if (opacity != 1) { rgb = RGBAtoRGB(rgb, [255,255,255], opacity); } + var bar_x = offset + (bars[seq_name]["left"][i] * x_scale_factor * pix_per_char); + var bar_y = (bars[seq_name]["pn"][i] == "+") ? (liney - 0.1*font_size*bars[seq_name]["height"][i]) : liney; + doc.setFillColor(rgb[0], rgb[1], rgb[2]); + doc.rect(bar_x, bar_y, bars[seq_name]["width"][i] * x_scale_factor * pix_per_char, 0.1*font_size*bars[seq_name]["height"][i], 'FD'); + } + } + + // + // Generate the legend. + // + if (n_legend_lines > 0) { + doc.setFontSize(1.33*legend_font_size); + dy = 0.8 * legend_font_size; + + // The legend header. + var legend_top = liney + 2*legend_font_size; + liney += 4.5*legend_font_size; + offset = legend_font_size; + doc.setFont("Helvetica", "bold"); + doc.text("Motif", offset, liney); + offset += index_field_width + legend_font_size; + doc.text("Symbol", offset, liney); + offset += symbol_field_width + legend_font_size; + doc.text("Motif Consensus", offset, liney); + liney -= 0.5*legend_font_size; + liney += legend_line_height; + + for (var i=0; i<motif_indices.length; i++) { + motif_index = sorted_motif_indices[i]; + offset = legend_font_size; + + // Motif Name + doc.setFont("Helvetica", "normal"); + var motif_index_string = (motif_index+1).toString(); + motif_index_string = motif_index_string + "."; + var dx = 3 * legend_font_size; + doc.text(motif_index_string, offset+dx, liney+dy, {align: "right"}); + offset += index_field_width + legend_font_size; + + // Motif Symbol + motif_length = data.motifs[motif_index].len; + rgb = visible_motifs[motif_index].split(",").map(Number); + var bar_x = offset; + var bar_y = liney; + doc.setFillColor(rgb[0], rgb[1], rgb[2]); + doc.rect(bar_x, bar_y, symbol_field_width*(motif_length/max_motif_length), legend_font_size, 'FD'); + offset += symbol_field_width + legend_font_size; + + // Motif Consensus Sequence + doc.setFont("Courier", "normal"); + var motif_consensus = data.motifs[motif_index].id; + doc.text(motif_consensus, offset, liney+dy, {maxWidth: legend_split_length*courier_width}); + liney += Math.ceil(motif_length/legend_split_length) * legend_line_height; + } + + // Draw box around legend. + doc.rect( + 0.5*legend_font_size, + legend_top + 0.5*legend_font_size, + Math.max(legend_width, legend_non_consensus_width + consensus_hdr_width + courier_width), + legend_height + ); + } // legend + + doc.save('motif_locations.pdf'); + + } else { + // Download an SVG document. + var body = d3.select("#blocks").append("svg") + .attr("width", (diagram_width + non_diagram_width) + "pt") + .attr("height", (doc_height+legend_font_size).toString()) + .attr("background-color", "lightgrey") + .attr("id", "memeSVG") + .attr("xmlns", "http://www.w3.org/2000/svg"); + + // Create the header. + var x = 0; + var offset = font_size; + var liney = 1.5*font_size; + + // .. Name hdr .. + body.append("text") + .attr("x", offset) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .attr("font-weight", "bold") + .text("Name"); + offset += name_field_width; + + // p-value hdr + body.append("text") + .attr("x", offset + 2*font_size) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .attr("font-weight", "bold") + .attr("font-style", "italic") + .text("p"); + body.append("text") + .attr("x", offset + 3*font_size) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .attr("font-weight", "bold") + .text("-value"); + offset += pvalue_field_width + plus_minus_field_width + font_size; + + // Motif Location hdr + body.append("text") + .attr("x", offset) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .attr("font-weight", "bold") + .text("Motif Locations"); + + // Generate the data for the SVG. + liney -= 0.5*font_size; + var dy = font_size/3.5; + for (var seq_name in bars) { + liney += diagram_line_height; + offset = font_size; + + // + // Generate the text fields. + // + + // Sequence name text + body.append("text") + .attr("x", offset) + .attr("y", liney + dy) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .text(seq_name); + offset += name_field_width; + + // p-value text + body.append("text") + .attr("x", offset + font_size+ pvalue_field_width) + .attr("y", liney + dy) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .attr("text-anchor", "end") + .text(bars[seq_name]["pvalue"]); + offset += pvalue_field_width + font_size; + + // +/- text (optional) + if (has_complement) { + body.append("text") + .attr("x", offset+font_size) + .attr("y", liney + dy - font_size/2) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .text("+"); + if (revcomp) { + body.append("text") + .attr("x", offset+1.15*font_size) + .attr("y", liney + dy + font_size/2) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", font_size+"pt") + .text("-"); + } + } + offset += plus_minus_field_width; + + // Generate the base line. + body.append("line") + .attr("x1", offset) + .attr("x2", offset + (bars[seq_name]["length"] * pix_per_char)) + .attr("y1", liney) + .attr("y2", liney) + .attr("stroke-width", 0.5) + .attr("stroke","black"); + + // Generate the blocks. + for (var i = 0; i < bars[seq_name]["width"].length; i++) { + if (bars[seq_name]["pn"][i] == undefined) { continue; } + body.append("rect") + .attr("x", offset + (bars[seq_name]["left"][i] * x_scale_factor * pix_per_char) ) + .attr("y", (bars[seq_name]["pn"][i] == "+") ? (liney - 0.1*font_size*bars[seq_name]["height"][i]) : liney) + .attr("width", bars[seq_name]["width"][i] * x_scale_factor * pix_per_char) + .attr("height", 0.1*font_size*bars[seq_name]["height"][i]) + .attr("fill", "rgb("+bars[seq_name]["color"][i] + ")") + .attr("fill-opacity", bars[seq_name]["opacity"][i]) + .attr("stroke-width", 0.5) + .attr("stroke","black"); + } + } + + // + // Generate the legend. + // + if (n_legend_lines > 0) { + dy = 0.8 * legend_font_size; + + // The legend header. + var legend_top = liney + 2*legend_font_size; + liney += 4.5*legend_font_size; + offset = legend_font_size; + body.append("text") + .attr("x", offset) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", legend_font_size+"pt") + .attr("font-weight", "bold") + .text("Motif"); + offset += index_field_width + legend_font_size; + body.append("text") + .attr("x", offset) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", legend_font_size+"pt") + .attr("font-weight", "bold") + .text("Symbol"); + offset += symbol_field_width + legend_font_size; + body.append("text") + .attr("x", offset) + .attr("y", liney) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", legend_font_size+"pt") + .attr("font-weight", "bold") + .text("Motif Consensus"); + liney -= 0.5*legend_font_size; + liney += legend_line_height; + + for (var i=0; i<motif_indices.length; i++) { + motif_index = sorted_motif_indices[i]; + offset = legend_font_size; + + // Motif Name + var motif_index_string = (motif_index+1).toString(); + motif_index_string = motif_index_string + "."; + var dx = 3.3 * legend_font_size; + body.append("text") + .attr("x", offset+dx) + .attr("y", liney+dy) + .attr("font-family", "Helvetica, sans-serif") + .attr("font-size", legend_font_size+"pt") + .attr("text-anchor", "end") + .text(motif_index_string); + offset += index_field_width + legend_font_size; + + // Motif Symbol + motif_length = data.motifs[motif_index].len; + var bar_x = offset; + var bar_y = liney; + body.append("rect") + .attr("x", bar_x ) + .attr("y", liney) + .attr("width", symbol_field_width*(motif_length/max_motif_length)) + .attr("height", legend_font_size) + .attr("fill", "rgb("+ visible_motifs[motif_index] + ")") + .attr("stroke-width", 0.5) + .attr("stroke","black"); + offset += symbol_field_width + legend_font_size; + + // Motif Consensus Sequence + var motif_consensus = data.motifs[motif_index].id; + var cons_length = motif_consensus.length; + var start_index = 0; + while (start_index < cons_length) { + body.append("text") + .attr("x", offset) + .attr("y", liney+dy) + .attr("font-family", "Courier") + .attr("font-size", legend_font_size+"pt") + .text(motif_consensus.slice(start_index, Math.min(cons_length, start_index+legend_split_length))) + liney += legend_line_height; + start_index += legend_split_length; + } + } + + // Draw box around legend. + body.append("rect") + .attr("x", 0.5*legend_font_size) + .attr("y", legend_top + 0.5*legend_font_size) + .attr("width", Math.max(legend_width, legend_non_consensus_width + consensus_hdr_width + courier_width)) + .attr("height", legend_height) + .attr("fill", "none") + .attr("stroke-width", 1) + .attr("stroke", "black"); + + } // legend + + var svg = document.getElementsByTagName("svg")[0].outerHTML; + var svgBlob = new Blob([svg], {type:"image/svg+xml;charset=utf-8"}); + var svgUrl = URL.createObjectURL(svgBlob); + var downloadLink = document.createElement("a"); + downloadLink.href = svgUrl; + downloadLink.download = "meme-motif-locations.svg"; + document.getElementById("sites_sec").appendChild(downloadLink); + downloadLink.click(); + downloadLink.remove(); + document.getElementById("memeSVG").remove(); + + } // SVG + +}; + +function make_blocks() { + "use strict"; + function add_seqs_filter(container, id, checked, label_text, help_topic) { + "use strict"; + var label, radio; + radio = document.createElement("input"); + radio.type = "radio"; + radio.name = "seqs_display"; + radio.id = id; + radio.checked = checked; + radio.addEventListener('click', action_seqs_filter, false); + label = document.createElement("label"); + label.appendChild(document.createTextNode(label_text)); + label.htmlFor = id; + container.appendChild(radio); + container.appendChild(label); + if (help_topic) { + container.appendChild(document.createTextNode("\xA0")); + container.appendChild(help_button(help_topic)); + } + } + function add_block_diagram_button(container, id, buttonText, help_topic) { + var button, label; + button = document.createElement("button"); + button.id = id; + label = document.createTextNode(buttonText); + button.appendChild(label); + button.onclick = (id === "pdfButton") ? download_PDF_block_diagram : download_SVG_block_diagram; + container.appendChild(document.createTextNode(" ")); + container.appendChild(button); + if (help_topic) { + container.appendChild(document.createTextNode("\xA0")); + container.appendChild(help_button(help_topic)); + } + //var new_icon = document.createElement("img"); + //new_icon.src = new_icon_src; + //new_icon.alt = "NEW"; + //container.appendChild(document.createTextNode(" ")); + //container.appendChild(new_icon); + } + function add_blocks_header(row, title, nopad, help_topic) { + "use strict"; + var div, divcp, th; + th = document.createElement("th"); + div = document.createElement("div"); + div.className = "blocks_th_inner"; + if (typeof title !== "object") { + title = document.createTextNode("" + title); + } + div.appendChild(title); + if (help_topic) { + div.appendChild(document.createTextNode("\xA0")); + div.appendChild(help_button(help_topic)); + } + divcp = div.cloneNode(true); + divcp.className = "blocks_th_hidden"; + th.appendChild(div); + th.appendChild(divcp); + if (nopad) { + th.className = "nopad"; + } + row.appendChild(th); + } + var container; + var page, view_height, outer_tbl, inner_tbl, tbl, thead, tbody, rhead; + var in_view, i, seq_count; + + page = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body; + view_height = Math.max(page.clientHeight - 300, 300); + + container = $("blocks"); + toggle_class(container, "hide_empty_seqs", true); + toggle_class(container, "hide_only_scan", true); + container.innerHTML = ""; + add_seqs_filter(container, "rdo_sites_only", true, "Only Motif Sites", "pop_motif_sites"); + add_seqs_filter(container, "rdo_sites_and_scan", false, "Motif Sites+Scanned Sites", "pop_scanned_sites"); + add_seqs_filter(container, "rdo_all_seqs", false, "All Sequences", "pop_all_sequences"); + add_block_diagram_button(container, "pdfButton", "Download PDF", "pop_download_pdf_motif_locations"); + add_block_diagram_button(container, "svgButton", "Download SVG", "pop_download_svg_motif_locations"); + + outer_tbl = document.createElement("div"); + outer_tbl.className = "blocks_outer"; + + inner_tbl = document.createElement("div"); + inner_tbl.id = "blocks_scroll"; + inner_tbl.className = "blocks_inner"; + inner_tbl.style.maxHeight = view_height + "px"; + outer_tbl.appendChild(inner_tbl); + + tbl = document.createElement("table"); + tbl.className = "blocks_tbl"; + inner_tbl.appendChild(tbl); + + thead = document.createElement("thead"); + tbl.appendChild(thead); + tbody = document.createElement("tbody"); + tbl.appendChild(tbody); + + rhead = thead.insertRow(thead.rows.length); + add_blocks_header(rhead, "", true); + add_blocks_header(rhead, "Name", false, "pop_seq_name"); + add_blocks_header(rhead, make_pv_text(), false, "pop_seq_pvalue"); + add_blocks_header(rhead, "Motif Locations", false, "pop_motif_location"); + + container.appendChild(outer_tbl); + + seq_count = data["sequence_db"]["sequences"].length; + in_view = Math.max(Math.ceil(view_height / 25), 1); + i = append_blocks_entries(tbody, 0, in_view); + + while (i < seq_count && inner_tbl.scrollHeight - (inner_tbl.scrollTop + inner_tbl.offsetHeight) < 400) { + i = append_blocks_entries(tbody, i, 20); + } + inner_tbl.data_blocks_index = i; + if (i < seq_count) { + inner_tbl.addEventListener('scroll', make_blocks_entries, false); + } +} + +function make_scan_popup(site, motif) { + return function (e) { + "use strict"; + var pop, xy, padding, edge_padding, pop_left, pop_top, page_width; + var lflank, match, rflank, pspm; + if (!e) var e = window.event; + pop = make_scan_popup.pop; + if (e.type === "mouseover") { + if (pop) return; + pop = clone_template("tmpl_scan_info"); + pspm = new Pspm(motif.pwm); + if (site.rc) pspm.reverse_complement(current_alphabet); + set_tvar(pop, "tvar_logo", make_small_logo(current_alphabet, pspm, {"className": "scan_logo"})); + set_tvar(pop, "tvar_motif", motif.id); + set_tvar(pop, "tvar_pvalue", site.pvalue.toExponential(2)); + set_tvar(pop, "tvar_start", site.pos + 1); + set_tvar(pop, "tvar_end", site.pos + motif.len); + + document.body.appendChild(pop); + position_popup(this, pop); + make_scan_popup.pop = pop; + } else if (e.type === "mouseout") { + if (pop) { + pop.parentNode.removeChild(pop); + make_scan_popup.pop = null; + } + } + }; +} + +function make_block_popup(site, motif, block) { + return function (e) { + "use strict"; + var pop; + var lflank, match, rflank, pspm, ruler, match_seq, match_width; + if (!e) var e = window.event; + pop = make_block_popup.pop; + if (e.type === "mouseover") { + if (pop) return; + pop = clone_template("tmpl_block_info"); + pspm = new Pspm(motif.pwm); + if (site.rc) { // must be dna + pspm.reverse_complement(current_alphabet); + lflank = current_alphabet.invcomp_seq(site.rflank); + match = current_alphabet.invcomp_seq(site.match); + rflank = current_alphabet.invcomp_seq(site.lflank); + } else { + lflank = site.lflank; + match = site.match; + rflank = site.rflank; + } + ruler = document.getElementById("measure_match"); + match_seq = make_seq(current_alphabet, match); + ruler.innerHTML = ""; + ruler.appendChild(match_seq); + match_width = ruler.clientWidth; + ruler.removeChild(match_seq); + set_tvar(pop, "tvar_lflank", lflank); + set_tvar(pop, "tvar_match", match_seq); + set_tvar(pop, "tvar_rflank", rflank); + set_tvar(pop, "tvar_logo_pad", lflank); + set_tvar(pop, "tvar_logo", make_small_logo(current_alphabet, pspm, {"width": match_width})); + set_tvar(pop, "tvar_motif", motif.id); + set_tvar(pop, "tvar_pvalue", site.pvalue.toExponential(2)); + set_tvar(pop, "tvar_start", site.pos + 1); + set_tvar(pop, "tvar_end", site.pos + motif.len); + + document.body.appendChild(pop); + position_popup(block, pop); + make_block_popup.pop = pop; + } else if (e.type === "mouseout") { + if (pop) { + pop.parentNode.removeChild(pop); + make_block_popup.pop = null; + } + } + }; +} + +// +// action_show_more +// +// Show more information on the motif. +/// +function action_show_more(e) { + var node, tr, tbody, table, container, motif, ordinal; + var expanded_motif; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + // find the row that contains the cell + node = this; + do { + if (node.tagName === "TR") break; + } while (node = node.parentNode); + if (!node) throw new Error("Expected to find row!?"); + tr = node; + // get info + motif = tr.data_motif; + ordinal = tr.data_ordinal; + // find tbody + do { + if (node.tagName === "TBODY") break; + } while (node = node.parentNode); + if (!node) throw new Error("Expected to find tbody!?"); + tbody = node; + // find table + do { + if (node.tagName === "TABLE") break; + } while (node = node.parentNode); + if (!node) throw new Error("Expected to find table!?"); + table = node; + // find container + container = node.parentNode; + // make a expanded motif + motif["expanded"] = true; + expanded_motif = make_expanded_motif(current_alphabet, ordinal, motif, + container.data_more_x, container.data_submit_x); + // now determine how to place it + if (tbody.rows.length === 1) { + // only us in the table so the table can be replaced + container.replaceChild(expanded_motif, table); + } else if (tbody.rows[0] === tr) { + // first row, so remove and insert an expanded motif before + table.deleteRow(tr.rowIndex); + container.insertBefore(expanded_motif, table); + } else if (tbody.rows[tbody.rows.length - 1] === tr) { + // last row, so remove and insert an expanded motif after + table.deleteRow(tr.rowIndex); + container.insertBefore(expanded_motif, table.nextSibling); + } else { + var table2, tbody2; + table2 = table.cloneNode(false); + table2.appendChild(table.tHead.cloneNode(true)); + tbody2 = table.tBodies[0].cloneNode(false); + table2.appendChild(tbody2); + container.insertBefore(table2, table.nextSibling); + for (i = tbody.rows.length - 1; i >= 0; i--) { + row = tbody.rows[i]; + row.parentNode.removeChild(row); + if (row === tr) { + break; + } + tbody2.insertBefore(row, tbody2.rows[0]); + } + container.insertBefore(expanded_motif, table2); + } + find_child(expanded_motif, "tvar_less").focus(); +} + +// +// action_show_less +// +// Show less information on the motif. +/// +function action_show_less(e) { + var btn; + var expanded_motif, container, motif, ordinal, colw, focus_target; + var table, tbody, tbody2, row, table_before, table_after; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + btn = this; + // find expanded motif + expanded_motif = find_parent(btn, "expanded_motif"); + if (!expanded_motif) throw new Error("Expected expanded motif."); + // find the container + container = expanded_motif.parentNode; + // get data + motif = expanded_motif.data_motif; + ordinal = expanded_motif.data_ordinal; + colw = container.data_colw; + // get the table before + table_before = expanded_motif.previousSibling; + if (table_before && table_before.tagName !== "TABLE") { + table_before = null; + } + // get the table after + table_after = expanded_motif.nextSibling; + if (table_after && table_after.tagName !== "TABLE") { + table_after = null; + } + // see if there is a table below or above that we can put this in. + // if there is a table both below and above then add this motif and + // all ones below to the above table + motif["expanded"] = false; + if (table_before && table_after) { + tbody = table_before.tBodies[0]; + row = tbody.insertRow(tbody.rows.length); + make_motif_table_entry(row, current_alphabet, ordinal, motif, colw); + focus_target = find_child(row.cells[5], "sym_btn"); + container.removeChild(expanded_motif); + tbody2 = table_after.tBodies[0]; + while (tbody2.rows.length > 0) { + row = tbody2.rows[0]; + row.parentNode.removeChild(row); + tbody.appendChild(row); + } + container.removeChild(table_after); + } else if (table_before) { + tbody = table_before.tBodies[0]; + row = tbody.insertRow(tbody.rows.length); + make_motif_table_entry(row, current_alphabet, ordinal, motif, colw); + focus_target = find_child(row.cells[5], "sym_btn"); + container.removeChild(expanded_motif); + } else if (table_after) { + tbody = table_after.tBodies[0]; + row = tbody.insertRow(0); + make_motif_table_entry(row, current_alphabet, ordinal, motif, colw); + focus_target = find_child(row.cells[5], "sym_btn"); + container.removeChild(expanded_motif); + } else { + //no table above or below! + // make a new table + table = make_motifs_table(current_alphabet, ordinal, [motif], colw, data["stop_reason"]); + focus_target = find_child(table.tBodies[0].rows[0].cells[5], "sym_btn"); + container.replaceChild(table, expanded_motif); + } + focus_target.focus(); +} + +//TODO -- can we delete this junk? +//function action_show_outpop(e) { +function fred_action_show_outpop(e) { + "use strict"; + function init() { + "use strict"; + var close_btn, next_btn, prev_btn, cancel_btn, do_btn; + var tab1, tab2, tab3; + var pnl1, pnl2, pnl3; + var format_list; + var tbl_submit, inputs, i, default_prog; + close_btn = $("outpop_close"); + close_btn.addEventListener("click", action_hide_outpop, false); + close_btn.addEventListener("keydown", action_hide_outpop, false); + next_btn = $("outpop_next"); + next_btn.addEventListener("click", action_outpop_next, false); + next_btn.addEventListener("keydown", action_outpop_next, false); + prev_btn = $("outpop_prev"); + prev_btn.addEventListener("click", action_outpop_prev, false); + prev_btn.addEventListener("keydown", action_outpop_prev, false); + cancel_btn = $("outpop_cancel"); + cancel_btn.addEventListener("click", action_hide_outpop, false); + do_btn = $("outpop_do"); + do_btn.addEventListener("click", action_outpop_submit, false); + tab1 = $("outpop_tab_1"); + tab1.tabIndex = 0; + tab1.addEventListener("click", action_outpop_tab, false); + tab1.addEventListener("keydown", action_outpop_tab, false); + tab2 = $("outpop_tab_2"); + tab2.tabIndex = 0; + tab2.addEventListener("click", action_outpop_tab, false); + tab2.addEventListener("keydown", action_outpop_tab, false); + tab3 = $("outpop_tab_3"); + tab3.tabIndex = 0; + tab3.addEventListener("click", action_outpop_tab, false); + tab3.addEventListener("keydown", action_outpop_tab, false); + pnl1 = $("outpop_pnl_1"); + pnl2 = $("outpop_pnl_2"); + pnl3 = $("outpop_pnl_3"); + toggle_class(tab1, "activeTab", true); + toggle_class(tab2, "activeTab", false); + toggle_class(tab3, "activeTab", false); + pnl1.style.display = "block"; + pnl2.style.display = "none"; + pnl3.style.display = "none"; + format_list = $("text_format"); + format_list.addEventListener("change", action_outpop_format, false); + // setup program selection + tbl_submit = $("programs"); + // when not dna, hide the inputs for programs that require dna motifs + toggle_class(tbl_submit, "alphabet_dna", current_alphabet.has_complement());//TODO alphabet_dna is a bad name for a field when allowing custom alphabets + // add a click listener for the radio buttons + inputs = tbl_submit.querySelectorAll("input[type='radio']"); + for (i = 0; i < inputs.length; i++) { + inputs[i].addEventListener("click", action_outpop_program, false); + } + // ensure that a default program option is selected for DNA and Protein + default_prog = document.getElementById(current_alphabet.has_complement() ? "submit_tomtom" : "submit_fimo"); //TODO Tomtom might require a more strict definition of DNA + default_prog.checked = true; + action_outpop_program.call(default_prog); + // disable reverse-complement when not DNA + $("logo_rc_option").disabled = !current_alphabet.has_complement(); + // set errorbars on when ssc is on + $("logo_ssc").addEventListener("change", action_outpop_ssc, false); + } + var node; + // store the focused element + action_hide_outpop.last_active = document.activeElement; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + // hide the help popup + help_popup(); + // on first load initilize the popup + if (!action_show_outpop.ready) { + init(); + action_show_outpop.ready = true; + } + // load the motif logo + node = this; + do { + if (/\bexpanded_motif\b/.test(node.className) || node.tagName === "TR") break; + } while (node = node.parentNode); + if (node === null) throw new Error("Expected node!"); + update_outpop_motif(node.data_ordinal - 1); + // display the download popup + $("grey_out_page").style.display = "block"; + $("download").style.display = "block"; + $("outpop_close").focus(); +} // fred_action_show_outpop + +function action_btn_rc(e) { + "use strict"; + var node, tr, motif, box, logo_box, tab_st, tab_rc, rc; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + node = this; + do { + if (node.tagName === "TR") break; + } while (node = node.parentNode); + if (!node) throw new Error("Expected to find row!?"); + tr = node; + // get info + motif = tr.data_motif; + box = find_parent(this, "preview_box"); + logo_box = find_child(box, "preview_logo_box"); + tab_st = find_child(box, "plus"); + tab_rc = find_child(box, "minus"); + rc = (this === tab_rc); + motif["rc"] = rc; + toggle_class(logo_box, "show_rc_logo", rc); + toggle_class(tab_st, "active", !rc); + toggle_class(tab_rc, "active", rc); +} + +function action_rc_tab(e) { + "use strict"; + var box, logo_box, tab_st, tab_rc, rc; + if (!e) e = window.event; + if (e.type === "keydown") { + if (e.keyCode !== 13 && e.keyCode !== 32) { + return; + } + // stop a submit or something like that + e.preventDefault(); + } + box = find_parent(this, "expanded_motif"); + logo_box = find_child(box, "tvar_logo"); + tab_st = find_child(box, "tvar_tab"); + tab_rc = find_child(box, "tvar_tab_rc"); + rc = (this === tab_rc); + box.data_motif["rc"] = rc; + toggle_class(logo_box, "show_rc_logo", rc); + toggle_class(tab_st, "activeTab", !rc); + toggle_class(tab_rc, "activeTab", rc); +} + +function action_seqs_filter() { + "use strict"; + var block_container; + block_container = $("blocks"); + if ($("rdo_all_seqs").checked) { + toggle_class(block_container, "hide_empty_seqs", false); + toggle_class(block_container, "hide_only_scan", false); + } else if ($("rdo_sites_and_scan").checked) { + toggle_class(block_container, "hide_empty_seqs", true); + toggle_class(block_container, "hide_only_scan", false); + } else if ($("rdo_sites_only").checked) { + toggle_class(block_container, "hide_empty_seqs", true); + toggle_class(block_container, "hide_only_scan", true); + } +} + +// +// page_loaded +// +// Called when the page has loaded for the first time. +/// +function page_loaded() { + post_load_setup(); +} + +// +// page_loaded +// +// Called when a cached page is reshown. +/// +function page_shown(e) { + if (e.persisted) post_load_setup(); +} + +// +// page_loaded +// +// Called when the page is resized +/// +function page_resized() { + var page, blocks_scroll; + update_scroll_pad(); + page = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body; + blocks_scroll = $("blocks_scroll"); + if (blocks_scroll) { + blocks_scroll.style.maxHeight = Math.max(page.clientHeight - 300, 300) + "px"; + } +} + +// +// pre_load_setup +// +// Run before the page is displayed +/// +function pre_load_setup() { + var start, hue, sat, light, divisions; + var i, j, motifs, motif, sites, site, sequences, sequence; + var max_seq_len; + motifs = data["motifs"]; + sequences = data["sequence_db"]["sequences"]; + max_seq_len = 1; + if (sequences) { // no sequences if -brief + for (i = 0; i < sequences.length; i++) { + sequence = sequences[i]; + sequence["sites"] = []; + if (sequence["length"] > max_seq_len) { + max_seq_len = sequence["length"]; + } + } + } + data["sequence_db"]["max_length"] = max_seq_len; + // use hsl colours + start = 0; //red + sat = 100; + light = 50; + for (i = 0; i < motifs.length; i++) { + motif = motifs[i]; + // give the motif a colour + divisions = 1 << Math.ceil(Math.log(i + 1) / Math.LN2); + hue = start + (360 / divisions) * ((i - (divisions >> 1)) * 2 + 1); + motif["colour"] = "hsl(" + hue + ", " + sat + "%, " + light + "%)"; + // associate sites with sequences as well + // to make generating the block diagram easier + sites = motif["sites"]; + for (j = 0; j < sites.length; j++) { + site = sites[j]; + sequence = sequences[site["seq"]]; + // record the motif index + site["motif"] = i; + // add the site to the sequence + sequence["sites"].push(site); + } + } +} + +// +// post_load_setup +// +// Run when the page has loaded, or been reloaded. +// +function post_load_setup() { + update_scroll_pad(); + if (data["motifs"].length > 0) { + make_motifs(); + if (data.sequence_db.primary_count > data.options.brief) { + if (data.options.brief == 1000) { + $("blocks").innerHTML = "<p>Output of sites suppressed because there were more than 1000 (primary) sequences.</p>"; + } else { + $("blocks").innerHTML = "<p>Output of motif locations suppressed by -brief option.</p>"; + } + } else { + make_blocks(); + } + } else { + $("motifs").innerHTML = "<p>No significant motifs found!</p>"; // clear content + $("motifs").innerHTML += "<p><b>" + data["stop_reason"] + "</b></p>"; + $("blocks").innerHTML = "<p>No significant motifs found!</p>"; + } +} + +pre_load_setup(); +</script> + <script> +// +// template.js +// + +/* + * Fill in a template variable + */ +function set_tvar(template, tvar, value) { + var node; + node = find_child(template, tvar); + if (node === null) { + throw new Error("Template does not contain variable " + tvar); + } + node.innerHTML = ""; + if (typeof value !== "object") { + node.appendChild(document.createTextNode(value)); + } else { + node.appendChild(value); + } +} // set_tvar + +/* + * Get the text contained within the element. + */ +function elem_text(elem, separator) { + if (separator === undefined) separator = ''; + return text_nodes(elem).map(node_text).join(separator); +} + +/* + * Get the text out of a specific text node. + */ +function node_text(node) { + if (node === undefined) { + return ''; + } else if (node.textContent) { + return node.textContent; + } else if (node.innerText) { + return node.innerText; + } else { + return ''; + } +} + +/* + * Find all text nodes in the given container. + */ +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; +} + +/* + * Create a button designed to contain a single symbol + */ +function make_sym_btn(symbol, title, action) { + var box, sbox; + box = document.createElement("div"); + box.tabIndex = 0; + box.className = "sym_btn"; + sbox = document.createElement("span"); + if (typeof symbol === "string") { + sbox.appendChild(document.createTextNode(symbol)); + } else { + sbox.appendChild(symbol); + } + box.appendChild(sbox); + box.title = title; + box.addEventListener('click', action, false); + box.addEventListener('keydown', action, false); + return box; +} + +/* + * Create a pair of text spans with different classes. + * This is useful when using CSS to only display one of them. + */ +function text_pair(txt1, cls1, txt2, cls2) { + var container, part1, part2; + container = document.createElement("span"); + part1 = document.createElement("span"); + part1.appendChild(document.createTextNode(txt1)); + part1.className = cls1; + container.appendChild(part1); + part2 = document.createElement("span"); + part2.appendChild(document.createTextNode(txt2)); + part2.className = cls2; + container.appendChild(part2); + return container; +} +</script> + <script> +// +// citation.js +// +function get_citation_text(doc_type, extra) { + var html; + + switch (doc_type) { + case 'AMA': + return(get_citation_text("GOMo", extra)); + case 'AME': + return(extra + ` + <span class="citation"> + Robert C. McLeay and Timothy L. Bailey, + "Motif Enrichment Analysis: a unified framework and an evaluation on ChIP data", + <i>BMC Bioinformatics</i>, <b>11</b>:165, 2010. + <a href="http://www.biomedcentral.com/1471-2105/11/165">[full text]</a> + </span> + `); + case 'CentriMo': + return(extra + ` + <span class="citation"> + Timothy L. Bailey and Philip Machanick, + "Inferring direct DNA binding from ChIP-seq", + <i>Nucleic Acids Research</i>, <b>40</b>:e128, 2012. + <a href="http://nar.oxfordjournals.org/content/40/17/e128">[Full Text]</a> + </span> + `); + case 'DREME': + return(extra + ` + <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. + <a href="http://bioinformatics.oxfordjournals.org/content/27/12/1653">[full text]</a> + </span> + `); + case 'FIMO': + return(extra + ` + <span class="citation"> + Charles E. Grant, Timothy L. Bailey and William Stafford Noble, + "FIMO: Scanning for occurrences of a given motif", + <i>Bioinformatics</i> <b>27</b>(7):1017-1018, 2011. + <a href="http://bioinformatics.oxfordjournals.org/content/27/7/1017">[full text]</a> + </span> + `); + case 'GLAM2': + case 'GLAM2SCAN': + return(extra + ` + <span class="citation"> + Martin C. Frith, Neil F. W. Saunders, Bostjan Kobe and Timothy L. Bailey, + "Discovering sequence motifs with arbitrary insertions and deletions", + <i>PLoS Computational Biology</i>, <b>4</b>(5):e1000071, 2008. + <a href="https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1000071">[full text]</a> + </span> + `); + case 'GOMo': + return(extra + ` + <span class="citation"> + Fabian A. Buske, Mikael Bodén, Denis C. Bauer and Timothy L. Bailey, + "Assigning roles to DNA regulatory motifs using comparative genomics", + <i>Bioinformatics</i>, <b>26</b>(7), 860-866, 2010. + <a href="http://bioinformatics.oxfordjournals.org/cgi/content/full/26/7/860">[full text]</a> + </span> + `); + case 'MAST': + return(extra + ` + <span class="citation"> + Timothy L. Bailey and Michael Gribskov, + "Combining evidence using p-values: application to sequence homology searches", + <i>Bioinformatics</i>, <b>14</b>(1):48-54, 1998. + <a href="http://bioinformatics.oxfordjournals.org/content/14/1/48">[full text]</a> + </span> + `); + case 'MCAST': + return(extra + ` + <span class="citation"> + Timothy Bailey and William Stafford Noble, + "Searching for statistically significant regulatory modules", + <i>Bioinformatics (Proceedings of the European Conference on Computational Biology)</i>, + <b>19</b>(Suppl. 2):ii16-ii25, 2003. + <a href="http://bioinformatics.oxfordjournals.org/cgi/content/abstract/19/suppl_2/ii16">[full text]</a> + </span> + `); + case 'Meta-MEME': + return(extra + ` + <span class="citation"> + William N. Grundy, Timothy L. Bailey, Charles P. Elkan and Michael E. Baker. + "Meta-MEME: Motif-based Hidden Markov Models of Protein Families" + <i>Computer Applications in the Biological Sciences (CABIOS)</i>, + <b>13</b>(4):397-406, 1997. + <a href="http://bioinformatics.oxfordjournals.org/content/13/4/397">[full text]</a> + </span> + `); + case 'MEME': + return(extra + ` + <span class="citation"> + Timothy L. Bailey and Charles Elkan, + "Fitting a mixture model by expectation maximization to + discover motifs in biopolymers", + <em>Proceedings of the Second International Conference on Intelligent Systems + for Molecular Biology</em>, pp. 28-36, AAAI Press, Menlo Park, California, 1994. + <a href="http://www.aaai.org/Papers/ISMB/1994/ISMB94-004.pdf">[full text]</a> + </span> + `); + case 'MEME-ChIP': + return(extra + ` + <span class="citation"> + Philip Machanick and Timothy L. Bailey, + "MEME-ChIP: motif analysis of large DNA datasets", + <i>Bioinformatics</i> <b>27</b>(12):1696-1697, 2011. + <a href="http://bioinformatics.oxfordjournals.org/content/27/12/1696.full">[full text]</a> + </span> + `); + case 'MEME_SUITE': + return(extra + ` + <span class="citation"> + Timothy L. Bailey, James Johnson, Charles E. Grant, William S. Noble, + "The MEME Suite", + <i>Nucleic Acids Research</i>, <b>43</b>(W1):W39-W49, 2015. + <a href="https://academic.oup.com/nar/article/43/W1/W39/2467905">[full text]</a> + </span> + `); + case 'MoMo': + return(extra + ` + <span class="citation"> + Alice Cheng, Charles Grant, Timothy L. Bailey and William Noble, + "MoMo: Discovery of statistically significant post-translational modification motifs", + <i>Bioinformatics</i>, <b>35</b>(16):2774-2782, 2018. + <a href="https://doi.org/10.1093/bioinformatics/bty1058">[full text]</a> + </span> + `); + case 'PSPs': + return(extra + ` + <span class="citation"> + Timothy L. Bailey, Mikael Bodén, Tom Whitington and Philip Machanick, + "The value of position-specific priors in motif discovery using MEME", + <i>BMC Bioinformatics</i>, <b>11</b>(1):179, 2010. + <a href="http://www.biomedcentral.com/1471-2105/11/179">[full text]</a> + </span> + `); + case 'SEA': + return(extra + ` + <span class="citation"> + Timothy L. Bailey and Charles E. Grant, "SEA: Simple Enrichment Analysis of motifs", + <i>BioRxiv</i>, August 24, 2021. + <a href="https://www.biorxiv.org/content/10.1101/2021.08.23.457422v1">[full text]</a> + </span> + `); + case 'SpaMo': + return(extra + ` + <span class="citation"> + Tom Whitington, Martin C. Frith, James Johnson and Timothy L. Bailey + "Inferring transcription factor complexes from ChIP-seq data", + <i>Nucleic Acids Res.</i> <b>39</b>(15):e98, 2011. + <a href="http://nar.oxfordjournals.org/content/39/15/e98">[full text]</a> + </span> + `); + case 'STREME': + return(extra + ` + <span class="citation"> + Timothy L. Bailey, + "STREME: accurate and versatile sequence motif discovery", + <i>Bioinformatics</i>, Mar. 24, 2021. + <a href="https://academic.oup.com/bioinformatics/advance-article-abstract/doi/10.1093/bioinformatics/btab203/6184861" >[full text]</a> + </span> + `); + case 'Tomtom': + return(extra + ` + <span class="citation"> + Shobhit Gupta, JA Stamatoyannopolous, Timothy Bailey and William Stafford Noble, + "Quantifying similarity between motifs", + <i>Genome Biology</i>, <b>8</b>(2):R24, 2007. + <a href="http://genomebiology.com/2007/8/2/R24">[full text]</a> + </span> + `); + case 'T-Gene': + return(extra + ` + <span class="citation"> + Timothy O'Connor, Charles E. Grant, Mikael Bodén, Timothy L. Bailey, + "T-Gene: Improved target gene prediction", + <i>Bioinformatics</i>, <b>36</b>(12):3902-3904, 2020. + <a href="https://academic.oup.com/bioinformatics/article/36/12/3902/5815978?guestAccessKey=aa625a49-a2aa-4d7a-858e-8bc82867a534">[Full Text]</a> + </span> + `); + case 'XSTREME': + return(extra + ` + <span class="citation"> + Charles E. Grant and Timothy L. Bailey, "XSTREME: comprehensive motif analysis of biological sequence datasets", + <i>BioRxiv</i>, September 3, 2021. + <a href="https://www.biorxiv.org/content/10.1101/2021.09.02.458722v1">[full text]</a> + </span> + `); + default: + return("Unknown program: " + doc_type); + } +} // get_citation_text + +// +// Function to replace the innerHTML of element "id" with an HTML paragraph +// containing the text for 'program', which is known to function get_citation_text. +// If "id" is either "citation" or "reference" some extra text is printed. +// +function print_citation(id, program) { + var extra; + switch (id) { + case 'citation': + extra = "If you use " + program + " in your research, please cite the following paper:<br>"; + break; + case 'reference': + extra = "<h5>Reference</h5>"; + break; + default: + extra = ""; + break; + }; + var html = get_citation_text(program, extra); + document.getElementById(id).insertAdjacentHTML('beforeend', html); +} // print_citation + +// +// Function to convert a citation for a program to a C #define statement. +// +function print_citation_define(lang, pgm) { + var citation = get_citation_text(pgm, ''); + citation = citation.replace(/<[^>]*>/g, ''); + citation = citation.replace(/\[.*\]/g, ''); + citation = citation.replace(/\n\s*/g, '\\n'); + citation = citation.replace(/"/g, '\\"'); + citation = citation.replace(/é/g, 'e'); + citation = citation.replace(/^\\n/, ''); + pgm = pgm.replace(/-/, ''); + citation = "If you use this program in your research, please cite:\\n\\n" + citation; + if (lang == "C") { + citation = "#define " + pgm + '_CITE "' + citation + '"'; + } else if (lang == "perl") { + citation = '"' + pgm + '" => "' + citation + '",'; + } + return(citation); +} // print_citation_define + +// +// Main program (for use with nodejs "node" javascript engine) +// to create citation.js.h and citation.pm from citation.js. +// The command line: +// node citation.js C > citation.js.h +// will output the C #define statements for each of the +// programs listed below, defining macros <program>_CITE. +// The command line: +// node citation.js perl > citation.js.pm +// will output perl hash <program> => text +// +// +if (typeof process !== 'undefined') { + var lang = process.argv[2]; + var programs = ['AMA', 'AME', 'CentriMo', 'DREME', 'FIMO', 'GLAM2', + 'GLAM2SCAN', 'GOMo', 'MAST', 'MCAST', 'Meta-MEME', 'MEME', + 'MEME-ChIP', 'MEME_SUITE', 'MoMo', 'PSPs', 'SEA', 'SpaMo', + 'STREME', 'Tomtom', 'T-Gene', 'XSTREME']; + + if (lang == "C") { + console.log("// Do not edit this file. It is created from etc/citation.js."); + console.log("#ifndef citation_js_h\n#define citation_js_h\n"); + for (var i=0; i<programs.length; i++) { + console.log(print_citation_define(lang, programs[i])); + } + console.log("\n#endif"); + } else if (lang == "perl") { + console.log("# Do not edit this file. It is created from etc/citation.js."); + console.log("package Citation;"); + console.log("sub cite {\n my ($pgm) = @_;\n return $citation{$pgm};\n}"); + console.log("%citation = ("); + for (var i=0; i<programs.length; i++) { + console.log(print_citation_define(lang, programs[i])); + } + console.log(");"); + } +} +</script> + <style> +/* 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(data:image/gif;base64,R0lGODlhDAANAIABANR0AP///yH5BAEAAAEALAAAAAAMAA0AAAIdhI8Xy22MIFgv1DttrrJ7mlGNNo4c+aFg6SQuUAAAOw==); +} + +div.help:hover { + background-image: url(data:image/gif;base64,R0lGODlhDAANAKEAANR0AP///9R0ANR0ACH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEAAAIALAAAAAAMAA0AAAIdDGynCe3PgoxONntvwqz2/z2K2ImjR0KhmSIZUgAAOw==); +} + +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; overflow: hidden;} + +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;} + +.explain h5 {font-size:1em; margin-left: 1em;} + +div.doc {margin-left: 2em; margin-bottom: 3em;} + +th.trainingset { + border-bottom: thin dashed black; + font-weight:normal; + padding:0px 10px; +} +div.pop_content { + position:absolute; + z-index:50; + width:300px; + padding: 5px; + background: #E4ECEC; + font-size: 12px; + font-family: Arial; + border-style: double; + border-width: 3px; + border-color: #AA2244; + display:none; +} +div.pop_content_wide { + position:absolute; + z-index:1; + width:700px; + padding: 5px; + background: #E4ECEC; + font-size: 12px; + font-family: Arial; + border-style: double; + border-width: 3px; + border-color: #AA2244; + display:none; +} + +div.pop_content > *:first-child { + margin-top: 0px; +} + +div.pop_content h1, div.pop_content h2, div.pop_content h3, div.pop_content h4, +div.pop_content h5, div.pop_content h6, div.pop_content p { + margin: 0px; +} + +div.pop_content p + h1, div.pop_content p + h2, div.pop_content p + h3, +div.pop_content p + h4, div.pop_content p + h5, div.pop_content p + h6 { + margin-top: 5px; +} + +div.pop_content p + p { + margin-top: 5px; +} + +div.pop_content > *:last-child { + margin-bottom: 0px; +} + +div.pop_content div.pop_close { + /* old definition */ + float:right; + bottom: 0; +} + +div.pop_content span.pop_close, div.pop_content span.pop_back { + display: inline-block; + border: 2px outset #661429; + background-color: #CCC; + padding-left: 1px; + padding-right: 1px; + padding-top: 0px; + padding-bottom: 0px; + cursor: pointer; + color: #AA2244; /*#661429;*/ + font-weight: bold; +} + +div.pop_content span.pop_close:active, div.pop_content span.pop_back:active { + border-style: inset; +} + +div.pop_content span.pop_close { + float:right; + /*border: 2px outset #AA002B;*/ + /*color: #AA2244;*/ +} + +div.pop_content:not(.nested) .nested_only { + display: none; +} + +div.pop_back_sec { + margin-bottom: 5px; +} + +div.pop_close_sec { + margin-top: 5px; +} + +table.hide_advanced tr.advanced { + display: none; +} +span.show_more { + display: none; +} +table.hide_advanced span.show_more { + display: inline; +} +table.hide_advanced span.show_less { + display: none; +} + + +/***************************************************************************** + * Program logo styling + ****************************************************************************/ +div.prog_logo { + border-bottom: 0.25em solid #0f5f60; + height: 4.5em; + width: 25em; + display:inline-block; +} +div.prog_logo img { + float:left; + width: 4em; + border-style: none; + margin-right: 0.2em; +} +div.prog_logo h1, div.prog_logo h1:hover, div.prog_logo h1:active, div.prog_logo h1:visited { + margin:0; + padding:0; + font-family: Arial, Helvetica, sans-serif; + font-size: 3.2em; + line-height: 1em; + vertical-align: top; + display: block; + color: #026666; + letter-spacing: -0.06em; + text-shadow: 0.04em 0.06em 0.05em #666; +} +div.prog_logo h2, div.prog_logo h2:hover, div.prog_logo h2:active, div.prog_logo h2:visited { + display: block; + margin:0; + padding:0; + font-family: Helvetica, sans-serif; + font-size: 0.9em; + line-height: 1em; + letter-spacing: -0.06em; + color: black; +} +div.prog_logo h3, div.prog_logo h3:hover, div.prog_logo h3:active, div.prog_logo h3:visited { + display: block; + margin:0; + padding:0; + font-family: Helvetica, sans-serif; + font-size: 0.9em; + line-height: 1.5em; + letter-spacing: -0.06em; + color: black; +} + +div.big.prog_logo { + font-size: 18px; +} + +/* These are for centered columns in tables */ +td.ctr { + text-align: center; +} + +/* These are for the navigation bars at the top of outputs. */ +table.navigation { + margin-top: 0px; + border-collapse:collapse; +} +table.navigation * td +{ + padding-left: 0px; + padding-right: 10px; + padding-top: 0px; + padding-bottom: 0px; +} +</style> + <style> +.block_td { + height:25px; +} +.block_container { + position:relative; + box-sizing: border-box; + height: 25px; + padding: 0px; + margin: 0px; + margin-left: 1em; +} +.block_label { + position: absolute; + display: inline-block; + padding: 3px; + z-index: 4; + top: 6px; + height: 12px; + line-height: 12px; + font-size: 12px; + background-color: white; + border: 1px solid black; + -moz-border-radius: 12px; + -webkit-border-radius: 12px; + border-radius: 12px; + transform: translateX(-50%); +} +.block_motif { + position: absolute; + z-index: 3; + top: 0px; + box-sizing: border-box; + border: 1px solid black; + height: 12px; + background-color: cyan; +} +.block_motif.top { + border-bottom-width: 0; +} +.block_motif.bottom { + border-top-width: 0; +} +.block_motif.scanned_site { + opacity: 0.3; +} +.block_motif.scanned_site.active { + opacity: 0.9; +} +.block_region { + position:absolute; + z-index:6; + height:25px; + top:0px; +} +.block_region.main { + z-index:8; +} +.block_region.scanned_site { + z-index:5; +} +.block_region.scanned_site.main { + z-index:7; +} +.block_region.top { + height:13px; +} +.block_region.bottom { + height:13px; + top:12px; +} +.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; + line-height:12px; + top:0px; + left:-1em; +} +.block_minus_sym { + position:absolute; + z-index:4; + line-height:12px; + top:13px; + left:-1em; +} + +.tic_major { + position:absolute; + top:0em; + height:0.5em; + width: 2px; + margin-left: -1px; + background-color: blue; +} +.tic_minor { + position:absolute; + top:0em; + height:0.2em; + width: 1px; + margin-left: -0.5px; + background-color: blue; +} +.tic_label { + position:absolute; + display: inline-block; + top:0.5em; + height: 1em; + color: blue; + transform: translateX(-50%); +} + +.block_needle { + position:absolute; + z-index:4; + height:30px; + width:1px; + top:-2px; + background-color:gray; +} +.block_needle.right { + height: 60px; +} +.block_handle { + position: absolute; + display: inline-block; + z-index: 5; + top: 27px; + min-width: 3ex; + text-align: center; + font-size: 12px; + line-height: 12px; + transform: translateX(-50%); + background-color: LightGrey; + border:3px outset grey; + cursor: pointer; + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ + /* Rules below not implemented in browsers yet */ + -o-user-select: none; + user-select: none; +} +.block_handle.right { + top: 47px; +} + +.legend_container { + text-align: right; +} +.legend_entry { + display: inline-block; + padding: 5px; +} +div.legend_swatch { + box-sizing: border-box; + width: 15px; + height: 15px; + border: 1px solid black; + background-color: cyan; + float: left; +} +div.legend_swatch input { + display: none; +} +.legend_text { + line-height: 15px; + margin-left: 20px; +} +</style> + <style> +/* meme output specific css */ + +div.pop_block { + position:absolute; + z-index:5; + padding: 5px; + border: 1px solid black; + display: inline-block; + background-color: white; +} + +#measure_match { + position: absolute; + visibility: hidden; + height: auto; + width: auto; + white-space: nowrap; +} + +div.template { + position: absolute; + z-index: 1; + left: 0; + top: 0; + visibility: hidden; +} + +table.block_information { + margin-left: auto; + margin-right: auto; +} + +table.block_information * th { + text-align: right; +} + +*.hide_empty_seqs * tr.empty_seq { + display: none; +} + +*.hide_only_scan * tr.only_scan { + display: none; +} + +*.hide_only_scan * div.scanned_site { + display: none; +} + +td.symaction { + text-align: center; + text-decoration: underline; + font-size: 20px; + cursor: pointer; +} +div.sym_btn { + display:inline-block; + text-decoration: underline; + cursor: pointer; + font-size: 20px; + line-height:20px; + text-align: center; + width: 20px; + height: 20px; + color: blue; +} +div.sym_btn:hover { + color: white; + background-color: blue; +} + +div.sym_btn.positioned { + position: absolute; + top: 0px; +} + +div.actionbutton { + display:inline-block; + 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.param_box { + display: inline-block; + margin-right: 20px; +} + +span.param { + font-weight: bold; +} + +div.box + div.box { + margin-top: 5px; +} + +div.sites_outer { + position: relative; + padding-top: 20px; /* height of header */ + display: inline-block; +} + +div.sites_inner { + overflow-x: hidden; + overflow-y: auto; + max-height: 200px; +} +table.sites_tbl { + border-collapse: collapse; +} + +div.sites_th_inner { + position: absolute; + top: 0; + line-height: 20px; /* height of header */ + text-align: left; + padding-left: 5px; +} +th.nopad div.sites_th_inner { + padding-left: 0; +} +div.sites_th_hidden { + visibility: hidden; + height: 0; + padding: 0 10px; +} +th.nopad div.sites_th_hidden { + padding: 0; +} +div.sites_inner * th { + height: 0; +} + +table.sites_tbl { + overflow-x: hidden; + overflow-y: auto; +} + +.site_num { + text-align: right; +} +.site_name { + padding:0px 5px; + text-align:left; +} +.site_strand { + padding:0px 5px; + text-align:center; +} +.norc .site_strand, .norc .site_strand_title { + display: none; +} +.site_start { + padding:0px 15px; + text-align: right; +} +.site_pvalue { + text-align:center; + padding:0px 15px; + text-align:right; + white-space: nowrap; +} +.lflank, .rflank, .match, .alpha_symbol { + font-weight:bold; + font-size:15px; + font-family: 'Courier New', Courier, monospace; + color:gray; +} + +.site.lflank { + text-align:right; + padding-right:5px; + color:gray; +} +.site.match { + text-align:center; +} +.site.rflank { + text-align:left; + padding-left:5px; + padding-right: 20px; +} + +th.stop_reason { + text-align: left; + padding-right: 10px; +} + +th.motif_ordinal { + +} +td.motif_ordinal { + text-align: right; + padding-right: 10px; +} +th.motif_logo { + padding-right: 10px; +} +td.motif_logo { + padding-right: 10px; +} +th.motif_evalue { + text-align:right; + padding-right: 10px; +} +td.motif_evalue { + text-align: right; + white-space: nowrap; + padding-right: 20px; +} +th.motif_nsites { + text-align: right; + padding-right: 10px; +} +td.motif_nsites { + text-align: right; + padding-right: 20px; +} +th.motif_width { + text-align: right; + padding-right: 5px; +} +td.motif_width { + text-align: right; + padding-right: 15px; +} +th.motif_more { + padding: 0 5px; +} +td.motif_more { + text-align: center; + padding: 0 5px; +} +th.motif_submit { + padding: 0 5px; +} +td.motif_submit { + text-align: center; + padding: 0 5px; +} +th.motif_download { + padding-left: 5px; +} +td.motif_download { + text-align: center; + padding-left: 5px; +} + + +div.tabArea { + font-size: 80%; + font-weight: bold; +} + +.norc div.tabArea { + display: none; +} + +span.tab, span.tab:visited { + cursor: pointer; + color: #888; + background-color: #ddd; + border: 2px solid #ccc; + padding: 2px 1em; + text-decoration: none; +} +span.tab.middle { + border-left-width: 0px; +} +div.tabArea.base span.tab { + border-top-width: 0px; +} +div.tabArea.top span.tab { + border-bottom-width: 0px; +} + +span.tab:hover { + background-color: #bbb; + border-color: #bbb; + color: #666; +} +span.tab.activeTab, span.tab.activeTab:hover, span.tab.activeTab:visited { + background-color: white; + color: black; + cursor: default; +} +div.tabMain { + border: 2px solid #ccc; + background-color: white; + padding: 10px; +} +div.tabMain.base { + margin-top: 5px; + display: inline-block; + max-width: 98%; +} + +div.tabMain.top { + margin-bottom: 5px; +} + +div.tabCenter { + max-width: 100%; + overflow-x: auto; + height: 200px; + overflow-y: hidden; +} + +canvas.logo_rc { + display:none; +} +.show_rc_logo > canvas { + display: none; +} +.show_rc_logo > canvas.logo_rc { + display: block; +} + +canvas.scan_logo { + margin-left: 10px; +} + +div.blocks_outer { + position: relative; + padding-top: 20px; /* height of header */ +} + +div.blocks_inner { + overflow-x: hidden; + overflow-y: auto; + max-height: 200px; +} +table.blocks_tbl { + border-collapse: collapse; + width: 100%; +} + +table.blocks_tbl .blockdiag_name { + white-space: nowrap +} + +div.blocks_th_inner { + position: absolute; + top: 0; + line-height: 20px; /* height of header */ + text-align: left; + padding-left: 5px; +} +th.nopad div.blocks_th_inner { + padding-left: 0; +} +div.blocks_th_hidden { + visibility: hidden; + height: 0; + padding: 0 10px; +} +th.nopad div.blocks_th_hidden { + padding: 0; +} +div.blocks_inner * th { + height: 0; +} + +table.blocks_tbl { + overflow-x: hidden; + overflow-y: auto; +} +td.block_td { + width: 99%; +} + +*.blockdiag_num { + text-align: right; +} + +td.blockdiag_name { + text-align: left; + padding:0px 10px; +} + +td.blockdiag_pvalue { + padding:0px 10px; + text-align:right; + white-space: nowrap; +} + +div.preview_btn { + border: 2px solid white; + height: 16px; + width: 16px; + font-size: 12px; + line-height: 16px; + text-align: center; + cursor: pointer; +} +div.preview_btn + div.preview_btn { + margin-top: 3px; +} + +div.preview_btn.active { + border: 2px solid black; + cursor: default; +} + +div.preview_btn:hover { + background-color: black; + color: white; + border-color: black; +} + +div.preview_btn.active:hover { + background-color: white; + color: black; + border-color: black; +} + + +div.preview_btn_box { + position: absolute; + left: 0px; + top: 0px; + padding: 3px; +} + +div.preview_logo_box { + height: 50px; + overflow-y: hidden; +} + +div.preview_btn_box + div.preview_logo_box { + margin-left: 25px; +} + +div.preview_box { + position: relative; +} + +div.grey_background { + position:fixed; + z-index: 8; + background-color: #000; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + opacity: 0.5; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +div.popup_wrapper { + position:fixed; + z-index:9; + width:100%; + height:0; + top:50%; + left:0; +} + +div.popup { + width: 600px; + z-index:9; + margin-left: auto; + margin-right: auto; + padding: 5px; + background-color: #FFF; + border-style: double; + border-width: 5px; + border-color: #00666a; + position:relative; +} +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; +} + +div.navarrow { + font-size: 30px; + text-decoration:none; + cursor: pointer; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +div.navarrow > span.inactive { + display: inline; +} +div.navarrow > span.active { + display: none; +} + +div.navarrow:hover > span.active { + display: inline; +} +div.navarrow:hover > span.inactive { + display: none; +} + +table.programs { + width: 100%; +} + +table.programs tr { + background-color: #EFE; +} + +table.programs tr.selected { + background-color: #262; + color: #FFF; +} + +table.programs tr.dna_only { + display: none; +} + +table.programs.alphabet_dna tr.dna_only { + display: table-row; +} + +div.programs_scroll { + width: 100%; + height: 90px; + overflow-y: auto; + overflow-x: hidden; + margin: 0 auto; +} +table.inputs, table.alpha_bg_table { + margin-top: 20px; + border-collapse:collapse; +} +table.inputs * td, table.inputs * th, table.alpha_bg_table * td, table.alpha_bg_table * th { + padding-left: 15px; + padding-right: 15px; + padding-top: 1px; + padding-bottom: 1px; +} + +table.hide_psp td.col_psp, table.hide_psp th.col_psp { + display: none; +} + +table.hide_control td.col_control, table.hide_control th.col_control { + display: none; +} + +/* program settings */ +span.mod_oops, span.mod_zoops, span.mod_anr { + display: none; +} +td.oops span.mod_oops,td.zoops span.mod_zoops, td.anr span.mod_anr { + display: inline; +} +span.strand_none, span.strand_given, span.strand_both { + display: none; +} +td.none span.strand_none, td.given span.strand_given, td.both span.strand_both { + display: inline; +} +span.spmap_uni, span.spmap_pam { + display: none; +} +td.uni span.spmap_uni, td.pam span.spmap_pam { + display: inline; +} +span.prior_dirichlet, span.prior_dmix, span.prior_mega, span.prior_megap, span.prior_addone { + display: none; +} +td.dirichlet span.prior_dirichlet, td.dmix span.prior_dmix, td.mega span.prior_mega, +td.megap span.prior_megap, td.addone span.prior_addone { + display: inline; +} +span.noendgaps_on, span.noendgaps_off { + display: none; +} +td.on span.noendgaps_on, td.off span.noendgaps_off { + display: inline; +} +span.substring_on, span.substring_off { + display: none; +} +td.on span.substring_on, td.off span.substring_off { + display: inline; +} +</style> + </head> + <body onload="page_loaded()" onpageshow="page_shown(event)" onresize="page_resized()"> + <!-- --> + <div id="grey_out_page" class="grey_background" style="display:none;"> + </div> + <!-- Help popups --> + <div class="pop_content" id="pop_results_txt"> + <p>MEME results in plain text format.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_results_xml"> + <p>MEME results in XML format.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_"> + <p>Help poup.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_logo"> + <script>print_doc_para("pop_logo", "discovery", "motif_logo", site_url);</script> + Click on the "+" or "-" buttons to the left of the motif to see + the forward or reverse complement of the motif if available. + <div class="pop_close">[<a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_ev"> + <p>The statistical significance of the motif. MEME usually finds the most + statistically significant (low E-value) motifs first. It is unusual to + consider a motif with an E-value larger than 0.05 significant so, as an + additional indicator, MEME displays these greyed out.</p> + <p>The E-value of a motif is based on its log likelihood ratio, width, + sites, the background letter frequencies (given in the command line + summary), and the size of the training set.</p> + <p>The E-value is an estimate of the expected number of motifs with the + given log likelihood ratio (or higher), and with the same width and site + count, that one would find in a similarly sized set of random + sequences (sequences where each position is independent and letters are + chosen according to the background letter frequencies).</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_sites"> + <p>The number of sites contributing to the construction of the motif.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_width"> + <p>The width of the motif. Each motif describes a pattern of a fixed + width, as no gaps are allowed in MEME motifs.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_more"> + <script>print_doc_para("pop_more", "discovery", "more");</script> + <div class="pop_close">[<a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_submit_dl"> + <script>print_doc_para("pop_submit_dl", "discovery", "submit_dl", "https://meme-suite.org/meme");</script> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_llr"> + <p>The log likelihood ratio of the motif. The log likelihood ratio is the + logarithm of the ratio of the probability of the occurrences of the motif + given the motif model (likelihood given the motif) versus their + probability given the background model (likelihood given the null model). + (Normally the background model is a 0-order Markov model using the + background letter frequencies, but higher order Markov models may be + specified via the -bfile option to MEME.).</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_ic"> + <p>The information content of the motif in bits. It is equal to the sum + of the uncorrected information content, R(), in the columns of the motif. + This is equal relative entropy of the motif relative to a uniform + background frequency model.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_re"> + <p>The relative entropy of the motif.</p> + + <p style="font-family: monospace;">re = llr / (sites * ln(2))</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_bt"> + <p>The Bayes Threshold.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_site_strand"> + <p>The strand used for the motif site.</p> + <dl> + <dt>+</dt> + <dd>The motif site was found in the sequence as it was supplied.</dd> + <dt>-</dt> + <dd>The motif site was found in the reverse complement of the supplied sequence.</dd> + </dl> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_site_start"> + <p>The position in the sequence where the motif site starts. If a motif + started right at the beginning of a sequence it would be described as + starting at position 1.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_site_pvalue"> + <p>The probability that an equal or better site would be found in a + random sequence of the same length conforming to the background letter + frequencies.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_site_match"> + <p>A motif site with the 10 flanking letters on either side.</p> + <p>When the site is not on the given strand then the site + and both flanks are reverse complemented so they align.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_seq_name"> + <p>The name of the sequences as given in the FASTA file.</p> + <p>The number to the left of the sequence name is the position + of the sequence in the input sequence file.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_motif_sites"> + <p>These are the motif sites predicted by MEME and used to build the motif.</p> + <p>These sites are shown in solid color and hovering the cursor + over a site will reveal details about the site. Only sequences + that contain a motif site are shown.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_scanned_sites"> + <p>These are the motif sites predicted by MEME plus + any additional sites detected using a motif scanning + algorithm.</p> + <p>These MEME sites are shown in solid color and + additional scanned sites are shown greyed out. + Hovering the cursor over a site will reveal details about the site. + Only sequences containing a predicted or scanned motif site are shown.</p> + <p>The scanned sites are predicted using a + log-odds scoring matrix constructed from the MEME sites. + Only scanned sites with position <i>p</i>-values less + than 0.0001 are shown.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_all_sequences"> + <p>These are the same sites as shown by selecting the + "Motif Sites + Scanned Sites" button except that all + sequences, including those with no sites, are included + in the diagram.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_seq_pvalue"> + <p>This is the combined match <i>p</i>-value.</p> + <p>The combined match <i>p</i>-value is defined as the probability that a + random sequence (with the same length and conforming to the background) + would have position <i>p</i>-values such that the product is smaller + or equal to the value calculated for the sequence under test.</p> + <p>The position <i>p</i>-value is defined as the probability that a + random sequence (with the same length and conforming to the background) + would have a match to the motif under test with a score greater or equal + to the largest found in the sequence under test.</p> + <p>Hovering your mouse over a motif site in the motif location + block diagram will show its position <i>p</i>-value and other information + about the site.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_download_pdf_motif_locations"> + <p>Use this button to download the "Motif Locations" block diagrams + as a PDF image suitable for publication. + </p> + <p> + Only the block diagrams currently visible in the inner scrolling + window (below) will be included in the image, and the numbers to + the left of each sequence name will not be included in the image. + You can change the size of the inner scrolling by moving the bottom + of the main document window up and down. You can display more + diagrams by making your browser's font size smaller. + </p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_download_svg_motif_locations"> + <p>Use this button to download the "Motif Locations" block diagrams + as a SVG image use in HTML documents. + </p> + <p> + Only the block diagrams currently visible in the inner scrolling + window (below) will be included in the image, and the numbers to + the left of each sequence name will not be included in the image. + You can change the size of the inner scrolling by moving the bottom + of the main document window up and down. You can display more + diagrams by making your browser's font size smaller. + </p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_offline"> + <p> + This button will only function if your browser was + connected to the internet when you loaded this page. + </p> + <p> + To use this button, make sure your browser is connected to the internet + and then reload this page. (You may need to do a "hard refresh" to clear the cache. + On Mac, hold down the Shift key and click the Reload button. + On Windows/Linux, hold down Ctrl and press F5.) + </p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_motif_location"> + <p>This diagram shows the location of motif sites.</p> + <p>Each block shows the position and strength of a motif + site. The height of a block gives an indication of the + significance of the site as taller blocks are more significant. + The height is calculated to be proportional to the negative + logarithm of the <i>p</i>-value of the site, truncated at + the height for a <i>p</i>-value of 1e-10.</p> + <p>For complementable alphabets (like DNA), sites on the + positive strand are shown above the line, + sites on the negative strand are shown below.</p> + <p>Placing the cursor + over a motif site will reveal more information about the site + including its position <i>p</i>-value. (See the help + for the <i>p</i>-value column for an explanation of position + <i>p</i>-values.)</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_seq_source"> + <p>The name of the file(s) of sequences input to MEME.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_psp_source"> + <p>The position specific priors file used by MEME to find the motifs.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_seq_alph"> + <p>The alphabet used by the sequences.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_seq_count"> + <p>The number of FASTA sequences provided in this input file.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_num_positions"> + <p>The number of characters in the sequences provided in this FASTA input file.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <div class="pop_content" id="pop_alph_name"> + <p>The name of the alphabet symbol.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_alph_freq"> + <p>The frequency of the alphabet symbol in the dataset.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + <div class="pop_content" id="pop_alph_bg"> + <p>The frequency of the alphabet symbol as defined by the background model.</p> + <div style="float:right; bottom:0px;">[ + <a href="javascript:help_popup()">close</a> ]</div> + </div> + + <!-- templates --> + <div id="measure_match" class="match"></div> + <div class="template pop_block" id="tmpl_block_info"> + <div> + <span class="tvar_logo_pad lflank" style="visibility:hidden;"></span> + <span class="tvar_logo"></span> + </div> + <div class="block_sequence_fragment"> + <span class="tvar_lflank lflank"></span> + <span class="tvar_match match"></span> + <span class="tvar_rflank rflank"></span> + </div> + <table class="block_information"> + <tr><th>Motif</th><td class="tvar_motif">1</td></tr> + <tr><th><i>p</i>-value</th><td class="tvar_pvalue">8.23e-7</td></tr> + <tr><th>Start</th><td class="tvar_start">23</td></tr> + <tr><th>End</th><td class="tvar_end">33</td></tr> + </table> + </div> + + <div class="template pop_block" id="tmpl_scan_info"> + <h5>Scanned Site</h5> + <div class="tvar_logo"></div> + <table class="block_information"> + <tr><th>Motif</th><td class="tvar_motif">1</td></tr> + <tr><th><i>p</i>-value</th><td class="tvar_pvalue">8.23e-7</td></tr> + <tr><th>Start</th><td class="tvar_start">23</td></tr> + <tr><th>End</th><td class="tvar_end">33</td></tr> + </table> + </div> + + <div class="template box expanded_motif" id="tmpl_motif_expanded"> + <div style="position: relative; min-height: 20px"> + <div class="param_box"> + <span class="param"><span class="tvar_ordinal"></span>.</span> + </div> + <div class="sym_btn positioned tvar_less" tabindex="0" + title="Show less information.">↥</div> + <div class="sym_btn positioned tvar_submit" tabindex="0" + title="Submit the motif to another MEME Suite program or download it.">⇢</div> + </div> + <div> + <div class="param_box"> + <span class="param"><i>E</i>-value:</span> + <span class="tvar_evalue"></span> + <div class="help" data-topic="pop_ev"></div> + </div> + <div class="param_box"> + <span class="param">Site Count:</span> + <span class="tvar_site_count"></span> + <div class="help" data-topic="pop_sites"></div> + </div> + <div class="param_box"> + <span class="param">Width:</span> + <span class="tvar_width"></span> + <div class="help" data-topic="pop_width"></div> + </div> + </div> + <div class="tabMain base"> + <div class="tabCenter tvar_logo"></div> + </div> + <div class="tabArea base"> + <span class="tvar_tab tab" tabindex="0">Standard</span><span + class="tvar_tab_rc tab middle" tabindex="0">Reverse + Complement</span> + </div> + <div style="padding: 10px 0"> + <div class="param_box"> + <span class="param">Log Likelihood Ratio:</span> + <span class="tvar_llr"></span> + <div class="help" data-topic="pop_llr"></div> + </div> + <div class="param_box"> + <span class="param">Information Content:</span> + <span class="tvar_ic"></span> + <div class="help" data-topic="pop_ic"></div> + </div> + <div class="param_box"> + <span class="param">Relative Entropy:</span> + <span class="tvar_re"></span> + <div class="help" data-topic="pop_re"></div> + </div> + <div class="param_box"> + <span class="param">Bayes Threshold:</span> + <span class="tvar_bt"></span> + <div class="help" data-topic="pop_bt"></div> + </div> + </div> + <div class="tvar_sites"></div> + </div> + + <div id="tab_submit_or_download_motif"></div> + <script> make_submit_or_download_motif_form("tab_submit_or_download_motif", site_url, "MEME"); </script> + + <!-- Page starts here --> + <div id="top" class="pad1"> + <div class="prog_logo big"> + <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABGCAYAAACUsCfoAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9wLHAInL7an9JAAAA8eSURBVHja7ZpZbxv3ucZ/s3AZ7qQkypZELZS3WHKiRJbTFnHqOjZcGzCQBf0A7cUB8glOb89dz30vChRp7xK0aZo4TYq6dtKqSew6iuJWpmPJlrVFFCmKI+7LLJw5F81MFZyec5rTILJaP8AAnAty+Pzf933ebeAhHuIhHuIhHmJPo6TpaeGLfimTydhLS0sUCgWazSbVahXDMOh0Ong8HiKRCAMDAxw+fJhHH31UeFDJ/91/bHp62r558ya6rmOaJuvr6+TzeYrFIoZhAOD1epFlmWAwSDqdZnR0lCNHjjA+Ps7+/fuFPUU8k8nYV69epVKpEA6HuXPnDrOzs7RaLbxeL93d3fj9foLBIB6Ph0ajQaVSAUBRFNLpNI888ggHDhzg3Llzwp4g/vbbb9szMzPE43FyuRwffPAB2WyWnp4ehoaGiMVi2LZNvV6n3W7j8/mIRqN4vV4ajQa1Wo2trS0OHTqEaZo89dRTfO973xMeaOKvvfaaffv2bcLhMCsrK/z+979HVVWOHz/O0NAQxWIRVVVRVRW/348oihiGgSiKxGIxurq6CAQCBINB3n//fcbGxiiXyxw7dowXX3yx1Nvbm3igiBcKhY9u3rw5OTMzQzgc5vbt23zwwQfIsszExAS2bZPP55EkiVAoRCQSIRwOI8sy5XKZ7e1tWq0WnU6HTqfD4OAggUAAVVXpdDo0m01GRkb44Q9/KDxQxH/729/as7Oz+Hw+Pv30U37zm9/g9Xrp6emht7eXYDCI3+/H6/UiCALtdhvLsuh0OkiSRCAQQJZl6vU65XKZ1dVV+vv7SSQS5PN5vF4vhUKBgwcP8qMf/WjXyIs7b+7cuWMvLi4iCAL1ep133nkHXdcZHh4mlUoRDofp7+8nHo9jGAaCIBCPx+nr6yOdTtPX14fH40HTNGRZpqenh76+PrLZLMVikYGBARRFwTRN5ubm+PGPf2zvFnF5583c3BzlchlZlrl16xa1Wo2xsTGi0SiDg4OutUzTJBKJIIoiXq+XQCBAIpEgFAphmiaqqlIoFKjVaoyOjhKJRFhfXycajRKNRunp6WFhYYG33nqLQqHwUTKZPP5VE5ecD5cvX7bv37+Poijkcjl++ctfMjo6ytDQEMlkEo/HQ7lcpt1u4/F4kGUZQRDw+Xz09fVx4MABRkZGSKVSdHV10el0KJVK1Ot14vE4kiRRKpVQFIV4PI5t23z66ad0Op2+K1eu/MeuWVxVVUzTRNd17t27RzKZJJFIEI1GEUWRdruNaZqIoogkSYiiiCiK+P1+AoEA0WiUQ4cOCQCbm5vb5XI5Xi6XWVtbw7ZtZFnG7/e7D1YUhWAwSLVaJZvN2v39/cJXHuOLi4t2sVhEEAS2t7eZn59n//79JBIJwuEwlmXRbDbRdR1BEBAEAcuysCwL2/5LmIriX+Wit7c3EY/HSSQSeDweDMPA4/EQCoWwbRvbtgmFQoTDYUqlErlcbnfE7f79+64gbWxs0G63icViRCIRBEHANE0Mw0CSJLxer0vSUfVKpUKxWGRtbc12UmKr1cI0TQD3t4PBoHtwgUAAv99Ps9kkn8/vjrjlcjlkWabdbrO8vEx3dzfhcJhoNEq9XkfTNERRxOfz4fV6sW0bSZJcBS+VSqytrdFqtbh+/bq9sLBALpdje3sbXddd4jutLwh/8WzLslBVdXeI12o1RFFkc3PTLTFjsRixWAxVVbEsC1mWkSTJdVXnMgyDarWKrusUi0X8fj+WZVGtVimXyxiGgW3bblh4PB78fj/tdhvbthFF0a3tv3Liuq4jiiKFQgFZlolEInR3d6MoConEXytLp1Bx0Ol0sG0bXdfRdZ1arYYgCNi2jaZptFot1zOcQ3LSnxMGzsHvCnHH/RqNBtFoFEmSCIfDAAwNDWFZFu12m0ajgaZpWJbl/oDH4/ncoTii5xBz1N+2bTqdDrIs4/P53MxgWRaapu2exQOBgHsAnU6HdrvN5uYmgUCASCRCJBIhkUhgmibNZpNarUaj0XAt71jfET1RFN1YliTJfUa73SaZTLK1tUWtVkPTNKampnaHuFNGyrKM1+t141bTNGq1GrVazS1EIpEI8XjcLWJqtdrnYthNF58pv23beL1eJEly1VzXder1Oq1Wi2AwiK7ru0PcSSs73bBYLBIMBpEkCdM0qVQq6LpOq9UiHA673Vmn08E0TfdyRM85CNM08Xq9bkoMhULugRqGgd/v3z1Xl2X5c24aDodRVZV4PO7W406/raoqtVqNYDCIz+dDURQ3vp3LuXeEz4nlTqdDOBxG13U3TBRF2b0mJRAI0Gg0EAQBTdPw+/2Uy2VXoJzRkkPEifNWq0UgEHCLEsedLcty1X1nzIdCIRRFoVQqUSqVsCyLYDBIPB7fncotlUq5JaWu6xiGgWmabG1tuanINE0EQXAPwSlk6vU6zWaTdruNpmnud3eWsk6fnkwmMU2Tzc1NVFVFURSi0SjpdHp3iB89ehRRFOnt7XWHCNFolFwu58ar08AYhuEWNH6/H4/H8zlL71R4J5XJskwgECAWi5HP51lZWaHVajE8PEw8Hufw4cO7Q3zfvn0C4E5MNU2jq6uLarVKPp//nPA5hYgzcYlEIoRCIfcQHLd3SDvEPR4PHo+HfD5PPp9HEARGRkYIhUIMDQ0Ju0Ic4NixY3g8Hnp7e8lms8RiMcLhMNlsFk3TXHW3bZtgMOjmfScEvF6vW8s7qczxgGazSSAQ4M9//jOqqlKpVHj88cfx+XyMjY3t7ujp1KlTQrlcdicupVKJkZER1tbWuHfvHqqqEolEiMVitNtt6vW6q+iNRoNms4kkSfh8PtfC0WgURVHo7+9nc3OTjY0N3n33XQYGBkilUiSTSU6ePCnsKnGA559/nkqlwtGjR8nn8/j9fh5//HEsy+LWrVvMz8+j6zqhUAifz4dhGG7z0mq1UFUVXdeJRCIEg0F32loqlbh37x53796lq6sLRVGIRCJMTEzs2pT1c8Qfe+wxYWpqyv1j2WyWVCpFIpGgUqkwNzfHnTt33JTnDCUlSaK7u5v+/n66u7vxeDxun16r1SgUCly/fp3bt29z+vRpBgcHqdVqRKPRB2uh8LOf/cyemZlhYWGBYDBIJBIBoFgs0mw2CYfDxONxfD4fg4ODros7vXWhUKDT6bg5/v3332dlZYWhoSHS6TSnTp1i3759VKtVzpw5w1c9dvpfNymvvPKKff36dbLZLIqiuBVWs9mk0WhgWZbbn4fDYURRRNM0AoEAvb29+Hw+Go0Gly9fZmNjg4mJCcbGxti/f787mJyfn6darTI5OcmJEyeEB4J4sVj8wfT09L/Pzs6SzWbdpWEikXBJGoZBs9kkGo0iyzKmabrLhtXVVTKZDJubm5w9e5YjR44wMDDAd7/7XWF2dtZeXFzkyJEj7pZm//79pFIpenp6vhIP+D8f8NZbb9nr6+ssLy+ztbXl1t5er9fdhxeLRSRJoquri0qlQiaTYXt7m0gkwpkzZ5BlmbGxMV544QX3eR9//LE9Pz/PsWPHuHHjBouLi0iSxMDAAMePH2dqakrYVeIAKysr9u3bt1leXnZn65qmoeu6W9AYhkGj0aBYLGKaJocOHeLRRx8lkUgwOTnpjp4d5HI5++OPP6ZcLjM+Ps61a9dYWFig2Wzi9Xp5/vnnOX36tLCrxHfi1q1b9tLSkuv+9XrdbTEVRSEWi5FMJhkdHWV4eJiDBw/+j8/Y2tr6+WuvvfYdwzBIpVJIkoSqqszPz1Ov17lw4QJf+9rXziYSiau7TvxvoVQqpUul0n2n2/oibz+899579k9/+lPC4TCnTp3i61//Orlcjp/85CdomsbTTz/NiRMn/pvH/CMotrQfyF/GD8Xj8aX/7yEePnx4dnx8fPJ3v/sdiqIwODjI5OSkcOPGDfvNN9/kypUr5PN5MpmMPT4+/qWQ71Z835fZZSSTyeMrKyt2vV7n7t27vPrqq1y7ds1+8sknhT/+8Y/2pUuXuHnzJs1mk6WlJTudTn8p5EUeAAwPDwvPPfccBw4cYHV1lc+KJ3t0dPTVixcvcvDgQebn53n55ZeZmZn5h1fLalv/twfqTaRMJmP/4he/YH19nSNHjnDhwgVisRj37t3jnXfeYWFhgQMHDnD+/HmeeuopYc9b3MH4+LjwrW99C0EQuHXrFtPT09RqNfr7+zlx4gTpdJqNjQ3efPNN3njjDbtYLP5gV1X9y8bly5ft119/nUqlwsmTJzl9+jQej4ePPvqITz75hLW1NYLBIJOTk5w7d46+vr4vzEN+EImfO3dOuHr1qv3666/z3nvvoWkaZ8+e5YknnnBXU5qmcfPmTQzDYG1tzR4cHBT2vMUdTE9P25cuXaJQKDA5OcmFCxfQdZ3Z2VkWFhbY2NhAURRSqRTPPvssY2Njwp62uINvfvObwp/+9Cf7V7/6FTdu3KDT6XD+/HmmpqbcoaaqqszOzmIYxhfK9Q80cYCJiQlhbm7OFgSBubk5vF4vzzzzDBMTE+7CMRgMsrCwwEsvvcS1a9fsb3zjG8KedvWd+OSTT+y3336bubk5JicnOXnyJJZl8eGHH7K2tkahUKDRaLBv3z4uXrzI2bNnhT1tcQdHjx4VMpmM3el0WFxcJBQKMTU1xbFjx6hWqwC0221WVlb49a9/zY0bN+wnn3xS2BN5/O/J88899xzDw8NkMhnm5uaIx+M8/fTT9PT0YFkWg4ODrK6u8sorrzA/P2/veVffidXVVfvdd99lenqa8+fPMzo6iqZp/OEPf2BhYYFWq4Usy4yMjHDx4kX+luXlvUh8aGhImJmZsS3L4vr165imSSqVYt++fbTbbWq1GtVqlWq1yt27d7l//749Ojoq7HniAFNTU8LS0pJdLpe5e/cu6+vrRCIRhoeHqVarrK6uous66+vrZLNZSqVS+rP2eW8TB0in00I2m3XVHqCvr49YLEYikXBfRiqXy+Ryufs7Q1tkj6O/v1/49re/zTPPPIMgCMzPz7sraJ/Ph9/vd/d3pVIp/U9hcQdOnX7p0iU7k8kgiqK76lIUxX19dKerC/wTYXt7+8zm5uaV5eVlNjY2iMfj+P1+hoeH6enpmd35evg/FXEHm1uF7ZXltXgg6EcSPSR7u/+zO9H1ff6VsFWq/pyHeIiHeIh/FfwXjVDdIW9O2PAAAAAASUVORK5CYII=" alt="MEME Logo"> + <h1>MEME</h1> + <h2>Multiple Em for Motif Elicitation</h2> + </div> + <p> + For further information on how to interpret these results please access + <a href="https://meme-suite.org/meme/doc/meme.html">https://meme-suite.org/meme/doc/meme.html</a>. <br /> + To get a copy of the MEME software please access + <a href="https://meme-suite.org">https://meme-suite.org</a>. + </p> + <p id="citation"> <script>print_citation("citation", "MEME");</script></p> + </div> + <!-- navigation --> + <div class="pad2"> + <a class="jump" href="#motifs_sec">Discovered Motifs</a> + | + <a class="jump" href="#sites_sec">Motif Locations</a> + | + <a class="jump" href="#inputs_sec">Inputs & Settings</a> + | + <a class="jump" href="#info_sec">Program Information</a> + | + <a class="jump" href="meme.txt">Results in Text Format</a> <span id="results_txt_help"></span> + | + <a class="jump" href="meme.xml">Results in XML Format</a> <span id="results_xml_help"></span> + <script> + make_help_button($("results_txt_help"), "pop_results_txt"); + make_help_button($("results_xml_help"), "pop_results_xml"); + </script> + </div> + <!-- alert the user when their browser is not up to the task --> + <noscript><h1 style="color:red">Javascript is required to view these results!</h1></noscript> + <h1 id="html5_warning" style="color:red; display:none;">Your browser does not support canvas!</h1> + <script> + if (!window.HTMLCanvasElement) $("html5_warning").style.display = "block"; + </script> + <h2 class="mainh pad2" id="motifs_sec">Discovered Motifs</h2> + <div id="motifs" class="box"> + <p>Please wait... Loading...</p> + <p>If the page has fully loaded and this message does not disappear then an error may have occurred.</p> + </div> + <h2 class="mainh pad2" id="sites_sec">Motif Locations</h2> + <div id="blocks" class="box"> + <p>Please wait... Loading...</p> + <p>If the page has fully loaded and this message does not disappear then an error may have occurred.</p> + </div> + <h2 class="mainh pad2" id="inputs_sec">Inputs & Settings</h2> + <div class="box"> + <h4>Sequences</h4> + <table id="seq_info" class="inputs"> + <tr> + <th>Role <div class="help" data-topic="pop_seq_role"></div></th> + <th>Source <div class="help" data-topic="pop_seq_source"></div></th> + <th class="col_psp">PSP Source <div class="help" data-topic="pop_psp_source"></div></th> + <th>Alphabet <div class="help" data-topic="pop_seq_alph"></div></th> + <th>Sequence Count <div class="help" data-topic="pop_seq_count"></div></th> + <th>Total Size <div class="help" data-topic="pop_num_positions"></div></th> + </tr> + <tr> + <td>Primary Sequences</td> + <td id="ins_seq_source"></td> + <td id="ins_seq_psp" class="col_psp"></td> + <td id="ins_seq_alphabet"></td> + <td id="ins_seq_count"></td> + <td id="ins_num_positions"></td> + </tr> + <tr class="col_control"> + <td class="col_control">Control Sequences</td> + <td id="ins_control_source" class="col_control"></td> + <td id="ins_control_psp" class="col_control col_psp"></td> + <td id="ins_control_alphabet" class="col_control"></td> + <td id="ins_control_count" class="col_control"></td> + <td id="ins_control_positions" class="col_control"></td> + </tr> + </table> + <script> + { + var db = data.sequence_db; + $("ins_seq_source").innerHTML = db.primary_source; + $("ins_seq_alphabet").innerHTML = current_alphabet.get_alphabet_name(); + $("ins_seq_count").innerHTML = db.primary_count; + $("ins_num_positions").innerHTML = db.primary_positions; + $("ins_control_source").innerHTML = db.control_source; + $("ins_control_alphabet").innerHTML = current_alphabet.get_alphabet_name(); + $("ins_control_count").innerHTML = db.control_count; + $("ins_control_positions").innerHTML = db.control_positions; + if (db.psp_source) { + $("ins_seq_psp").innerHTML = db.psp_source; + } + toggle_class($("seq_info"), "hide_psp", !(db.psp_source)); + toggle_class($("seq_info"), "hide_control", (db.control_source == "--none--")); + } + </script> + <h4>Background Model</h4> + <span id="bg_source"></span> + <span id="bg_order"></span> + <span id="alpha_bg"></span> + <script> + { + $("bg_source").appendChild(make_background_source("Source", data.background.source, false)); + $("bg_order").innerHTML = " <b>Order:</b> " + data.background.order + + (data.background.order>0 ? " (only order-0 shown)" : ""); + $("alpha_bg").appendChild(make_alpha_bg_table(current_alphabet, data.sequence_db.freqs)); + } + </script> + <h4>Other Settings</h4> + <table id="tbl_settings" class="inputs hide_advanced"> + <tr> + <th>Motif Site Distribution</th> + <td id="opt_mod"> + <span class="mod_zoops">ZOOPS: Zero or one site per sequence</span> + <span class="mod_oops">OOPS: Exactly one site per sequence</span> + <span class="mod_anr">ANR: Any number of sites per sequence</span> + </td> + </tr> + <tr> + <th>Objective Function</th> + <td id=opt_objfun></td> + </tr> + <tr> + <th>Starting Point Function</th> + <td id=opt_spfun></td> + </tr> + <tr> + <th>Site Strand Handling</th> + <td id="opt_strand"> + <span class="strand_none">This alphabet only has one strand</span> + <span class="strand_given">Sites must be on the given strand</span> + <span class="strand_both">Sites may be on either strand</span> + </td> + </tr> + <tr> + <th>Maximum Number of Motifs</th> + <td id="opt_nmotifs"></td> + </tr> + <tr> + <th>Motif E-value Threshold</th> + <td id="opt_evt"></td> + </tr> + <tr> + <th>Minimum Motif Width</th> + <td id="opt_minw"></td> + </tr> + <tr> + <th>Maximum Motif Width</th> + <td id="opt_maxw"></td> + </tr> + <tr> + <th>Minimum Sites per Motif</th> + <td id="opt_minsites"></td> + </tr> + <tr> + <th>Maximum Sites per Motif</th> + <td id="opt_maxsites"></td> + </tr> + <tr class="advanced"> + <th>Bias on Number of Sites</th> + <td id="opt_wnsites"></td> + </tr> + <tr class="advanced"> + <th>Sequence Prior</th> + <td id="opt_prior"> + <span class="prior_dirichlet">Simple Dirichlet</span> + <span class="prior_dmix">Dirichlet Mixture</span> + <span class="prior_mega">Mega-weight Dirichlet Mixture</span> + <span class="prior_megap">Mega-weight Dirichlet Mixture Plus</span> + <span class="prior_addone">Add One</span> + </td> + </tr> + <tr class="advanced"> + <th>Sequence Prior Source</th> + <td id="opt_prior_source"></td> + </tr> + <tr class="advanced"> + <th>Sequence Prior Strength</th> + <td id="opt_b"></td> + </tr> + <tr class="advanced"> + <th>EM Starting Point Source</th> + <td id="opt_substring"> + <span class="substring_on">From substrings in input sequences</span> + <span class="substring_off">From strings on command line (-cons)</span> + </td> + </tr> + <tr class="advanced"> + <th>EM Starting Point Map Type</th> + <td id="opt_spmap"> + <span class="spmap_uni">Uniform</span> + <span class="spmap_pam">Point Accepted Mutation</span> + </td> + </tr> + <tr class="advanced"> + <th>EM Starting Point Fuzz</th> + <td id="opt_spfuzz"></td> + </tr> + <tr class="advanced"> + <th>EM Maximum Iterations</th> + <td id="opt_maxiter"></td> + </tr> + <tr class="advanced"> + <th>EM Improvement Threshold</th> + <td id="opt_distance"></td> + </tr> + <tr class="advanced"> + <th>Maximum Search Size</th> + <td id="opt_searchsize"></td> + </tr> + <tr class="advanced"> + <th>Maximum Number of Sites for E-values</th> + <td id="opt_csites"></td> + </tr> + <tr class="advanced"> + <th>Trim Gap Open Cost</th> + <td id="opt_wg"></td> + </tr> + <tr class="advanced"> + <th>Trim Gap Extend Cost</th> + <td id="opt_ws"></td> + </tr> + <tr class="advanced"> + <th>End Gap Treatment</th> + <td id="opt_noendgaps"> + <span class="noendgaps_on">No cost</span> + <span class="noendgaps_off">Same cost as other gaps</span> + </td> + </tr> + <tr> + <td colspan="2" style="text-align: center"> + <a href="javascript:toggle_class(document.getElementById('tbl_settings'), 'hide_advanced')"> + <span class="show_more">Show Advanced Settings</span> + <span class="show_less">Hide Advanced Settings</span> + </a> + </td> + </tr> + </table> <script> { $("opt_mod").className = data.options.mod;
--- a/test-data/meme_output_test2.txt Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test2.txt Mon Jul 14 21:33:56 2025 +0000 @@ -1,40 +1,180 @@ ******************************************************************************** -SUMMARY OF MOTIFS +MOTIF GGSRTATAAAA MEME-1 width = 11 sites = 30 llr = 254 E-value = 5.1e-040 ******************************************************************************** +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 Description +-------------------------------------------------------------------------------- +Simplified A 3313:9:a798 +pos.-specific C 1:3::1:::1: +probability G 6756::::::2 +matrix T 1:11a1a:3:: + + bits 2.2 * + 2.0 * * + 1.8 * * + 1.5 * ** * +Relative 1.3 * ** * +Entropy 1.1 ****** +(12.2 bits) 0.9 * ******* + 0.7 * ******* + 0.4 ** ******** + 0.2 *********** + 0.0 ----------- + +Multilevel GGGGTATAAAA +consensus AACA T +sequence + +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 sites sorted by position p-value +-------------------------------------------------------------------------------- +Sequence name Start P-value Site +------------- ----- --------- ----------- +chr21_46046964_46047014_ 13 4.51e-07 AAGGCCAGGA GGGGTATAAAA GCCTGAGAGC +chr21_46031920_46031970_ 16 2.22e-06 ATACCCAGGG AGGGTATAAAA CCTCAGCAGC +chr21_32202076_32202126_ 14 2.74e-06 CCACCAGCTT GAGGTATAAAA AGCCCTGTAC +chr21_46057197_46057247_ 37 4.86e-06 ACAGGCCCTG GGCATATAAAA GCC +chr21_45993530_45993580_ 8 4.86e-06 CCAAGGA GGAGTATAAAA GCCCCACAAA +chr21_45971413_45971463_ 10 4.86e-06 CAGGCCCTG GGCATATAAAA GCCCCAGCAG +chr21_31964683_31964733_ 14 4.86e-06 GATTCACTGA GGCATATAAAA GGCCCTCTGC +chr21_47517957_47518007_ 33 6.48e-06 CCGGCGGGGC GGGGTATAAAG GGGGCGG +chr21_45978668_45978718_ 5 6.48e-06 CAGA GGGGTATAAAG GTTCCGACCA +chr21_32185595_32185645_ 19 6.48e-06 CACCAGAGCT GGGATATATAA AGAAGGTTCT +chr21_32410820_32410870_ 22 1.38e-05 AATCACTGAG GATGTATAAAA GTCCCAGGGA +chr21_31992870_31992920_ 17 1.38e-05 CACTATTGAA GATGTATAAAA TTTCATTTGC +chr21_19617074_19617124_ 40 1.41e-05 CCTCGGGACG TGGGTATATAA +chr21_31914206_31914256_ 16 1.61e-05 CCCACTACTT AGAGTATAAAA TCATTCTGAG +chr21_46020421_46020471_ 3 1.95e-05 GA GACATATAAAA GCCAACATCC +chr21_32253899_32253949_ 18 1.95e-05 CCCACCAGCA AGGATATATAA AAGCTCAGGA +chr21_45705687_45705737_ 38 2.16e-05 CGTGGTCGCG GGGGTATAACA GC +chr21_47575506_47575556_ 31 3.04e-05 GCTGCCGGTG AGCGTATAAAG GCCCTGGCG +chr21_31744582_31744632_ 13 3.04e-05 CAGGTCTAAG AGCATATATAA CTTGGAGTCC +chr21_31768316_31768366_ 1 3.67e-05 . AACGTATATAA ATGGTCCTGT +chr21_26934381_26934431_ 28 3.93e-05 AGTCACAAGT GAGTTATAAAA GGGTCGCACG +chr21_31933633_31933683_ 5 5.65e-05 TCAG AGTATATATAA ATGTTCCTGT +chr21_31710037_31710087_ 15 6.24e-05 CCCAGGTTTC TGAGTATATAA TCGCCGCACC +chr21_36411748_36411798_ 23 7.15e-05 AGTTTCAGTT GGCATCtaaaa attatataac +chr21_46102103_46102153_ 37 1.39e-04 TGCCTGGGTC CAGGTATAAAG GCT +chr21_46086869_46086919_ 38 1.39e-04 TGCCTGGGCC CAGGTATAAAG GC +chr21_37838750_37838800_ 3 4.81e-04 ga tggttttataa ggggcctcac +chr21_31962741_31962791_ 14 8.57e-04 TATAACTCAG GTTGGATAAAA TAATTTGTAC +chr21_31973364_31973414_ 8 1.47e-03 aaactta aaactctataa acttaaaact +chr21_28217753_28217803_ 27 2.64e-03 GGTGGGGGTG GGGGTTTCACT GGTCCACTAT +-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- - Combined block diagrams: non-overlapping sites with p-value < 0.0001 + Motif GGSRTATAAAA MEME-1 block diagrams -------------------------------------------------------------------------------- -SEQUENCE NAME COMBINED P-VALUE MOTIF DIAGRAM +SEQUENCE NAME POSITION P-VALUE MOTIF DIAGRAM ------------- ---------------- ------------- -chr21_19617074_19617124_ 5.63e-04 39_[+1(1.41e-05)] -chr21_26934381_26934431_ 1.57e-03 27_[+1(3.93e-05)]_12 -chr21_28217753_28217803_ 1.00e-01 50 -chr21_31710037_31710087_ 2.49e-03 14_[+1(6.24e-05)]_25 -chr21_31744582_31744632_ 1.22e-03 12_[+1(3.04e-05)]_27 -chr21_31768316_31768366_ 1.47e-03 [+1(3.67e-05)]_39 -chr21_31914206_31914256_ 6.45e-04 15_[+1(1.61e-05)]_24 -chr21_31933633_31933683_ 2.26e-03 4_[+1(5.65e-05)]_35 -chr21_31962741_31962791_ 3.37e-02 50 -chr21_31964683_31964733_ 1.95e-04 13_[+1(4.86e-06)]_26 -chr21_31973364_31973414_ 5.73e-02 50 -chr21_31992870_31992920_ 5.52e-04 16_[+1(1.38e-05)]_23 -chr21_32185595_32185645_ 2.59e-04 18_[+1(6.48e-06)]_21 -chr21_32202076_32202126_ 1.10e-04 13_[+1(2.74e-06)]_26 -chr21_32253899_32253949_ 7.78e-04 17_[+1(1.95e-05)]_22 -chr21_32410820_32410870_ 5.52e-04 21_[+1(1.38e-05)]_18 -chr21_36411748_36411798_ 2.85e-03 22_[+1(7.15e-05)]_17 -chr21_37838750_37838800_ 1.90e-02 50 -chr21_45705687_45705737_ 8.63e-04 37_[+1(2.16e-05)]_2 -chr21_45971413_45971463_ 1.95e-04 9_[+1(4.86e-06)]_30 -chr21_45978668_45978718_ 2.59e-04 4_[+1(6.48e-06)]_35 -chr21_45993530_45993580_ 1.95e-04 7_[+1(4.86e-06)]_32 -chr21_46020421_46020471_ 7.78e-04 2_[+1(1.95e-05)]_37 -chr21_46031920_46031970_ 8.89e-05 15_[+1(2.22e-06)]_24 -chr21_46046964_46047014_ 1.80e-05 12_[+1(4.51e-07)]_27 -chr21_46057197_46057247_ 1.95e-04 36_[+1(4.86e-06)]_3 -chr21_46086869_46086919_ 5.54e-03 50 -chr21_46102103_46102153_ 5.54e-03 50 -chr21_47517957_47518007_ 2.59e-04 32_[+1(6.48e-06)]_7 -chr21_47575506_47575556_ 1.22e-03 30_[+1(3.04e-05)]_9 +chr21_46046964_46047014_ 4.5e-07 12_[+1]_27 +chr21_46031920_46031970_ 2.2e-06 15_[+1]_24 +chr21_32202076_32202126_ 2.7e-06 13_[+1]_26 +chr21_46057197_46057247_ 4.9e-06 36_[+1]_3 +chr21_45993530_45993580_ 4.9e-06 7_[+1]_32 +chr21_45971413_45971463_ 4.9e-06 9_[+1]_30 +chr21_31964683_31964733_ 4.9e-06 13_[+1]_26 +chr21_47517957_47518007_ 6.5e-06 32_[+1]_7 +chr21_45978668_45978718_ 6.5e-06 4_[+1]_35 +chr21_32185595_32185645_ 6.5e-06 18_[+1]_21 +chr21_32410820_32410870_ 1.4e-05 21_[+1]_18 +chr21_31992870_31992920_ 1.4e-05 16_[+1]_23 +chr21_19617074_19617124_ 1.4e-05 39_[+1] +chr21_31914206_31914256_ 1.6e-05 15_[+1]_24 +chr21_46020421_46020471_ 1.9e-05 2_[+1]_37 +chr21_32253899_32253949_ 1.9e-05 17_[+1]_22 +chr21_45705687_45705737_ 2.2e-05 37_[+1]_2 +chr21_47575506_47575556_ 3e-05 30_[+1]_9 +chr21_31744582_31744632_ 3e-05 12_[+1]_27 +chr21_31768316_31768366_ 3.7e-05 [+1]_39 +chr21_26934381_26934431_ 3.9e-05 27_[+1]_12 +chr21_31933633_31933683_ 5.6e-05 4_[+1]_35 +chr21_31710037_31710087_ 6.2e-05 14_[+1]_25 +chr21_36411748_36411798_ 7.1e-05 22_[+1]_17 +chr21_46102103_46102153_ 0.00014 36_[+1]_3 +chr21_46086869_46086919_ 0.00014 37_[+1]_2 +chr21_37838750_37838800_ 0.00048 2_[+1]_37 +chr21_31962741_31962791_ 0.00086 13_[+1]_26 +chr21_31973364_31973414_ 0.0015 7_[+1]_32 +chr21_28217753_28217803_ 0.0026 26_[+1]_13 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 in BLOCKS format +-------------------------------------------------------------------------------- +BL MOTIF GGSRTATAAAA width=11 seqs=30 +chr21_46046964_46047014_ ( 13) GGGGTATAAAA 1 +chr21_46031920_46031970_ ( 16) AGGGTATAAAA 1 +chr21_32202076_32202126_ ( 14) GAGGTATAAAA 1 +chr21_46057197_46057247_ ( 37) GGCATATAAAA 1 +chr21_45993530_45993580_ ( 8) GGAGTATAAAA 1 +chr21_45971413_45971463_ ( 10) GGCATATAAAA 1 +chr21_31964683_31964733_ ( 14) GGCATATAAAA 1 +chr21_47517957_47518007_ ( 33) GGGGTATAAAG 1 +chr21_45978668_45978718_ ( 5) GGGGTATAAAG 1 +chr21_32185595_32185645_ ( 19) GGGATATATAA 1 +chr21_32410820_32410870_ ( 22) GATGTATAAAA 1 +chr21_31992870_31992920_ ( 17) GATGTATAAAA 1 +chr21_19617074_19617124_ ( 40) TGGGTATATAA 1 +chr21_31914206_31914256_ ( 16) AGAGTATAAAA 1 +chr21_46020421_46020471_ ( 3) GACATATAAAA 1 +chr21_32253899_32253949_ ( 18) AGGATATATAA 1 +chr21_45705687_45705737_ ( 38) GGGGTATAACA 1 +chr21_47575506_47575556_ ( 31) AGCGTATAAAG 1 +chr21_31744582_31744632_ ( 13) AGCATATATAA 1 +chr21_31768316_31768366_ ( 1) AACGTATATAA 1 +chr21_26934381_26934431_ ( 28) GAGTTATAAAA 1 +chr21_31933633_31933683_ ( 5) AGTATATATAA 1 +chr21_31710037_31710087_ ( 15) TGAGTATATAA 1 +chr21_36411748_36411798_ ( 23) GGCATCTAAAA 1 +chr21_46102103_46102153_ ( 37) CAGGTATAAAG 1 +chr21_46086869_46086919_ ( 38) CAGGTATAAAG 1 +chr21_37838750_37838800_ ( 3) TGGTTTTATAA 1 +chr21_31962741_31962791_ ( 14) GTTGGATAAAA 1 +chr21_31973364_31973414_ ( 8) AAACTCTATAA 1 +chr21_28217753_28217803_ ( 27) GGGGTTTCACT 1 +// + +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 position-specific scoring matrix +-------------------------------------------------------------------------------- +log-odds matrix: alength= 4 w= 11 n= 1200 bayes= 5.2854 E= 5.1e-040 + -14 -179 114 -112 + 3 -1155 137 -270 + -114 20 86 -71 + 3 -279 122 -170 + -1155 -1155 -295 215 + 156 -179 -1155 -170 + -1155 -1155 -1155 220 + 172 -279 -1155 -1155 + 125 -1155 -1155 46 + 167 -179 -1155 -1155 + 144 -1155 -63 -270 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 position-specific probability matrix +-------------------------------------------------------------------------------- +letter-probability matrix: alength= 4 w= 11 nsites= 30 E= 5.1e-040 + 0.266667 0.066667 0.566667 0.100000 + 0.300000 0.000000 0.666667 0.033333 + 0.133333 0.266667 0.466667 0.133333 + 0.300000 0.033333 0.600000 0.066667 + 0.000000 0.000000 0.033333 0.966667 + 0.866667 0.066667 0.000000 0.066667 + 0.000000 0.000000 0.000000 1.000000 + 0.966667 0.033333 0.000000 0.000000 + 0.700000 0.000000 0.000000 0.300000 + 0.933333 0.066667 0.000000 0.000000 + 0.800000 0.000000 0.166667 0.033333 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + Motif GGSRTATAAAA MEME-1 regular expression +-------------------------------------------------------------------------------- +[GA][GA][GC][GA]TATA[AT]AA -------------------------------------------------------------------------------- \ No newline at end of file
--- a/test-data/meme_output_test2.xml Thu Aug 29 10:19:40 2024 +0000 +++ b/test-data/meme_output_test2.xml Mon Jul 14 21:33:56 2025 +0000 @@ -1,3 +1,658 @@ +<alphabet_matrix> +<alphabet_array> +<value letter_id="A">-14</value> +<value letter_id="C">-179</value> +<value letter_id="G">114</value> +<value letter_id="T">-112</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">3</value> +<value letter_id="C">-1155</value> +<value letter_id="G">137</value> +<value letter_id="T">-270</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-114</value> +<value letter_id="C">20</value> +<value letter_id="G">86</value> +<value letter_id="T">-71</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">3</value> +<value letter_id="C">-279</value> +<value letter_id="G">122</value> +<value letter_id="T">-170</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-1155</value> +<value letter_id="C">-1155</value> +<value letter_id="G">-295</value> +<value letter_id="T">215</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">156</value> +<value letter_id="C">-179</value> +<value letter_id="G">-1155</value> +<value letter_id="T">-170</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">-1155</value> +<value letter_id="C">-1155</value> +<value letter_id="G">-1155</value> +<value letter_id="T">220</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">172</value> +<value letter_id="C">-279</value> +<value letter_id="G">-1155</value> +<value letter_id="T">-1155</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">125</value> +<value letter_id="C">-1155</value> +<value letter_id="G">-1155</value> +<value letter_id="T">46</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">167</value> +<value letter_id="C">-179</value> +<value letter_id="G">-1155</value> +<value letter_id="T">-1155</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">144</value> +<value letter_id="C">-1155</value> +<value letter_id="G">-63</value> +<value letter_id="T">-270</value> +</alphabet_array> +</alphabet_matrix> +</scores> +<probabilities> +<alphabet_matrix> +<alphabet_array> +<value letter_id="A">0.266667</value> +<value letter_id="C">0.066667</value> +<value letter_id="G">0.566667</value> +<value letter_id="T">0.100000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.300000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.666667</value> +<value letter_id="T">0.033333</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.133333</value> +<value letter_id="C">0.266667</value> +<value letter_id="G">0.466667</value> +<value letter_id="T">0.133333</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.300000</value> +<value letter_id="C">0.033333</value> +<value letter_id="G">0.600000</value> +<value letter_id="T">0.066667</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.033333</value> +<value letter_id="T">0.966667</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.866667</value> +<value letter_id="C">0.066667</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.066667</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.000000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">1.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.966667</value> +<value letter_id="C">0.033333</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.700000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.300000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.933333</value> +<value letter_id="C">0.066667</value> +<value letter_id="G">0.000000</value> +<value letter_id="T">0.000000</value> +</alphabet_array> +<alphabet_array> +<value letter_id="A">0.800000</value> +<value letter_id="C">0.000000</value> +<value letter_id="G">0.166667</value> +<value letter_id="T">0.033333</value> +</alphabet_array> +</alphabet_matrix> +</probabilities> +<regular_expression> +[GA][GA][GC][GA]TATA[AT]AA +</regular_expression> +<contributing_sites> +<contributing_site sequence_id="sequence_24" position="12" strand="plus" pvalue="4.51e-07" > +<left_flank>AAGGCCAGGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCTGAGAGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_23" position="15" strand="plus" pvalue="2.22e-06" > +<left_flank>ATACCCAGGG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>CCTCAGCAGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_13" position="13" strand="plus" pvalue="2.74e-06" > +<left_flank>CCACCAGCTT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>AGCCCTGTAC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_25" position="36" strand="plus" pvalue="4.86e-06" > +<left_flank>ACAGGCCCTG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_21" position="7" strand="plus" pvalue="4.86e-06" > +<left_flank>CCAAGGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCCCACAAA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_19" position="9" strand="plus" pvalue="4.86e-06" > +<left_flank>CAGGCCCTG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCCCAGCAG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_9" position="13" strand="plus" pvalue="4.86e-06" > +<left_flank>GATTCACTGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GGCCCTCTGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_28" position="32" strand="plus" pvalue="6.48e-06" > +<left_flank>CCGGCGGGGC</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GGGGCGG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_20" position="4" strand="plus" pvalue="6.48e-06" > +<left_flank>CAGA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GTTCCGACCA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_12" position="18" strand="plus" pvalue="6.48e-06" > +<left_flank>CACCAGAGCT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>AGAAGGTTCT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_15" position="21" strand="plus" pvalue="1.38e-05" > +<left_flank>AATCACTGAG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GTCCCAGGGA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_11" position="16" strand="plus" pvalue="1.38e-05" > +<left_flank>CACTATTGAA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TTTCATTTGC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_0" position="39" strand="plus" pvalue="1.41e-05" > +<left_flank>CCTCGGGACG</left_flank> +<site> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank></right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_6" position="15" strand="plus" pvalue="1.61e-05" > +<left_flank>CCCACTACTT</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TCATTCTGAG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_22" position="2" strand="plus" pvalue="1.95e-05" > +<left_flank>GA</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GCCAACATCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_14" position="17" strand="plus" pvalue="1.95e-05" > +<left_flank>CCCACCAGCA</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>AAGCTCAGGA</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_18" position="37" strand="plus" pvalue="2.16e-05" > +<left_flank>CGTGGTCGCG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_29" position="30" strand="plus" pvalue="3.04e-05" > +<left_flank>GCTGCCGGTG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GCCCTGGCG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_4" position="12" strand="plus" pvalue="3.04e-05" > +<left_flank>CAGGTCTAAG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>CTTGGAGTCC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_5" position="0" strand="plus" pvalue="3.67e-05" > +<left_flank></left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>ATGGTCCTGT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_1" position="27" strand="plus" pvalue="3.93e-05" > +<left_flank>AGTCACAAGT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>GGGTCGCACG</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_7" position="4" strand="plus" pvalue="5.65e-05" > +<left_flank>TCAG</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>ATGTTCCTGT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_3" position="14" strand="plus" pvalue="6.24e-05" > +<left_flank>CCCAGGTTTC</left_flank> +<site> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TCGCCGCACC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_16" position="22" strand="plus" pvalue="7.15e-05" > +<left_flank>AGTTTCAGTT</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>attatataac</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_27" position="36" strand="plus" pvalue="1.39e-04" > +<left_flank>TGCCTGGGTC</left_flank> +<site> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GCT</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_26" position="37" strand="plus" pvalue="1.39e-04" > +<left_flank>TGCCTGGGCC</left_flank> +<site> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="G"/> +</site> +<right_flank>GC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_17" position="2" strand="plus" pvalue="4.81e-04" > +<left_flank>ga</left_flank> +<site> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>ggggcctcac</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_8" position="13" strand="plus" pvalue="8.57e-04" > +<left_flank>TATAACTCAG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>TAATTTGTAC</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_10" position="7" strand="plus" pvalue="1.47e-03" > +<left_flank>aaactta</left_flank> +<site> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="A"/> +</site> +<right_flank>acttaaaact</right_flank> +</contributing_site> +<contributing_site sequence_id="sequence_2" position="26" strand="plus" pvalue="2.64e-03" > +<left_flank>GGTGGGGGTG</left_flank> +<site> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="G"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="T"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="A"/> +<letter_ref letter_id="C"/> +<letter_ref letter_id="T"/> +</site> +<right_flank>GGTCCACTAT</right_flank> +</contributing_site> +</contributing_sites> +</motif> </motifs> <scanned_sites_summary p_thresh="0.0001"> <scanned_sites sequence_id="sequence_0" pvalue="5.63e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="plus" position="39" pvalue="1.41e-05"/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_input_neg2.fasta Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,66 @@ +>chr21_19617074_19617124_+ +AAAAATTATTACTAGGGAGGGGGCCGGAAAAACCTCGGGACGTGGGTATATAA +>chr21_26934381_26934431_+ +GCGCCTGGTCGGTTATGAGTCACAAGTGAGTTTTCCmATAAAAGGGTCGCACGTT +>chr21_28217753_28217803_- +CAAAGGGGAGGAGTGmGGGTGGGGGTGGGGGTTTCACTGGTCCACTATAAA +>chr21_31710037_31710087_- +AACACCCAGGTTTCTGAGTATATAATCGCCGCACCAAAGAATTTAATTTT +>chr21_31744582_31744632_- +CCCAGGTCTAAGAGCATATATAmACTTGGAGTCCAGACTATGACATTCAAA +>chr21_31768316_31768366_+ +AACGTATATAAATGGTCCTGTCCAGATGTGGCATGCAmAACTCAGAATCTT +>chr21_31914206_31914256_- +TGACACCCACTACTTAGAGTATAAAmATCATTCTGAGAAGTTAGAGACACC +>chr21_31933633_31933683_- +TCAGAGTATATATAAATGTTCCTGTCCAGTCACAAAGTCACCAAACTGACCT +>chr21_31962741_31962791_- +ACATATAACTCAGGTTGGATAAAATAATTTGTATCAGmCAAATCAGGAGAGTCAA +>chr21_31964683_31964733_+ +TCTGATTCACTGAGGCATATAAAAGGCCCTCTGCGGAGAmAGTGTCCATAC +>chr21_31973364_31973414_+ +aaacttaaaactctataaacttaaaactCTAGAATCCTGCTATAC +>chr21_31992870_31992920_+ +CTCATACACTATTGAAGATGTATAAAATTTCATTTGmGATGGTGACATT +>chr21_32185595_32185645_- +TCACCACCCACCAmAGCTGGGATATATAAAGAAGGTTCTGAGACTAGGAA +>chr21_32202076_32202126_- +TGCCCACCAGCTATmGTGAGGTATAAAAAGCCCTGTACGGGAAGAGACCTTCAT +>chr21_32253899_32253949_- +AGCCCCACCCACCAGCAAGGATATATAAAAGCTCAGGAGTCTGGAGTGAC +>chr21_32410820_32410870_- +TCTACCCCACTAATCACTGAGGATGTATAAAAGTCCCAGGGAAGCTGGTG +>chr21_36411748_36411798_- +ATAGTTCTGTATAAmGAGTTTCAGTTGGCATCtaaaaattatataactttattt +>chr21_37838750_37838800_- +gatggttttataaggggcctcaccctcggctcagccctcattcttctcct +>chr21_45705687_45705737_+ +CCGGGGCGGAGCGGCCTTTGCTCTTTGCGTGGTCGCGGGGGTATAACAGC +>chr21_45971413_45971463_- +CAGGCCCTGGGCATATAAAAGCCCCAGCAGmCCAACAGGctcacacacaca +>chr21_45978668_45978718_- +CAGAGGGGTATAAAGGTTCCGACCACTCAGAGGCCTGGCACGAtcactca +>chr21_45993530_45993580_+ +CCAAGGAGGAGTATAAAAGCCCCACAAACCCGAGCACCTCACTCTCGC +>chr21_46020421_46020471_+ +GAGACATATAAAAGCCAACATCCCTGAGCACCTAAACGGactcactc +>chr21_46031920_46031970_+ +GGAAAATACCCAGGGAGGGTATAAATCAGCAGCCAGGGCACACAAAC +>chr21_46046964_46047014_+ +ACAAGGCCAGGAGGGGTATAAAACTGAGAGCCCCAAGAACctcacaca +>chr21_46057197_46057247_+ +ATTGCTGAGTCTCCTGCTGGGAAAACACAGGCCCTGGGCATATAAAAGCC +>chr21_46086869_46086919_- +GACGTGTGCTTCTGTGCTGTGGGGATGCCTGGGCCCAGGTATAAAGGC +>chr21_46102103_46102153_- +AGGTGTGCTTCTGTGCTGTGGGGATGCCTGGGTCCAGGTATAAAGGCT +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTGGCCGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCGCCGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGCGGGGTATAAAGGGGGCGG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGGAGGTGCTGCGTGAGCGTATAAAGGCCCTGGCG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGAGmGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_input_pos.fasta Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,66 @@ +>chr21_19617074_19617124_+ +AAAAATTATTACTAGGGAGGGGGCCGGAACCTCGGGACGTGGGTATATAA +>chr21_26934381_26934431_+ +GCGCCTGGTCGGTTATGAGTCACAAGTGAGTTATAAAAGGGTCGCACGTT +>chr21_28217753_28217803_- +CAAAGGGGAGGAGTGGGGTGGGGGTGGGGGTTTCACTGGTCCTATAAA +>chr21_31710037_31710087_- +AACACCCAGGTTTCTGAGTATATAATCGCCGCACCAAAGAATTTAATTTT +>chr21_31744582_31744632_- +CCCAGGTCTAAGAGCATATATAACTTGGAGTCCAGACTATGACATTCAAA +>chr21_31768316_31768366_+ +AACGTATATAAATGGTCCTGTCCAGATGTG +>chr21_31914206_31914256_- +TGACACCCACTACTTAGAGTATAAAATCATTCTGAGAAGTTAGAGACACC +>chr21_31933633_31933683_- +TCAGAGTATATATAAATGTTCCTGTCCAGTCACAGTCACCAATGACCT +>chr21_31962741_31962791_- +ACATATAACTCAGGTTGGATAAAATAATTTGTACAAATCAGGAGAGTCAA +>chr21_31964683_31964733_+ +TCTGATTCACTGAGGCATATAAAAGGCCCTCTGCGGAGAAGTTAC +>chr21_31973364_31973414_+ +aaacttaaaactctataaacttaaaactCTAGAATCTGATCCTGCTATAC +>chr21_31992870_31992920_+ +CTCATACACTATTGAAGATGTATAAAATTTCATTTGCAGATGGTGACATT +>chr21_32185595_32185645_- +TCACCACCCACCAGAGCTGGGATATATAAAGAAGGTTCTAGGAA +>chr21_32202076_32202126_- +TGCCCACCAGCTTGAGGTATAAAAAGCCCTGTACGGGAAGAGACCTTCAT +>chr21_32253899_32253949_- +AGCCCCACCCACCAGCAAGGATATATAAAAGCTCAGGAGTCTGGAGTGAC +>chr21_32410820_32410870_- +TCTACCCCACTAATCACTGAGGATGTATAAAAGTCCCAGGGAAGCTGGTG +>chr21_36411748_36411798_- +ATAGTTCTGTATAGTTTCAGTTGGCATCtaaaaattatataactttattt +>chr21_37838750_37838800_- +gatggttttataaggggcctcaccctcggctcagccctcattcttctcct +>chr21_45705687_45705737_+ +CCGGGGCGGAGCGGCCTTTGCTCTTTGCGTGGTCGGGGTATAACAGC +>chr21_45971413_45971463_- +CAGGCCCTGGGCATATAAAAGCCCCAGCAGCCAACAGGctcacacacaca +>chr21_45978668_45978718_- +CAGAGGGGTATAAAGGTTCCGACCACTCCTGGCACGAtcactca +>chr21_45993530_45993580_+ +CCAAGGAGGAGTATAAAAGCCCCACAAACCCGAGCACCTCACTCACTCGC +>chr21_46020421_46020471_+ +GAGACATATAAAAGCCAACATCCCTGAGCACCTAACACACGGactcactc +>chr21_46031920_46031970_+ +GGAAAATACCCAGGGAGGGTATAAAACCTCAGCAGCCAGGGCACACAAAC +>chr21_46046964_46047014_+ +ACAAGGCCAGGAGGGGTATAAAAGCCTGAGAGCCCCAAGAACctcacaca +>chr21_46057197_46057247_+ +ATTGCTGAGTCTCCTGCTGGGAAAACACAGGCCCTGGGCATATAAAAGCC +>chr21_46086869_46086919_- +GACAGGTGTGCTTCTGTGCTGTGGGGATGCCTGGGCCCAGGTATAAAGGC +>chr21_46102103_46102153_- +AGGTGTGTGCTTCTGTGCTGTGGGGATGCCTGGGTCCAGGTATAAAGGCT +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCGGGGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGTATAAAGGGGGCGG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_input_pos2.fasta Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,66 @@ +>chr21_19617074_19617124_+ +AAAAATTATTACTAGGGAGGGGGCmGGAACCTCGGGACGTGGGTmATATAA +>chr21_26934381_26934431_+ +GCGCCTGGTCGGTTATGAGTCACAAGTGAGTTATAAAAGGGTCGCACGTT +>chr21_28217753_28217803_- +CAAAGGGGAGGAGTGGGGTGGGGGTGGGGGTTTCACTGGTmCACTATAAA +>chr21_31710037_31710087_- +AACACCCAGGTTTCTGAGTATATAATCGCCGCACCAAAGAATTTAATTTTTT +>chr21_31744582_31744632_- +CCmAGGTCTAAGAGCATATATTAACTTGGAGTCCAGACTATGACATTCAAA +>chr21_31768316_31768366_+ +AACGTATATAAATGGTCCTGTCCAGATGTGGCATGCAAACTmAGAATCTT +>chr21_31914206_31914256_- +TGACACCCACTACTTAGAGTATAAAATCATTCTGAGAAGTTAGAGA +>chr21_31933633_31933683_- +TCAGAGTATATATAAATGTTCCTGTCCAGTCACAGTCACCAAACTGACCT +>chr21_31962741_31962791_- +ACATATAACTCAGGTTGGATAAAATAATTTGTACAAATCAGG +>chr21_31964683_31964733_+ +TCTGATTCACTGAGGCATATAAAAGGCCCTCTGCGGAGAAGTGTCCATAC +>chr21_31973364_31973414_+ +aaacttaaaactctataaacttaaaactCTAGAATCTGATCCTGCTATAC +>chr21_31992870_31992920_+ +CTCATACACTATTGAAGATGTATAAAATTTCATTTGCAGATGGTGACATT +>chr21_32185595_32185645_- +TCACCACCCACCAGAGCTGGGATATATAAAGAAGGTTCTGAGACTAGGAA +>chr21_32202076_32202126_- +TGCCCACCAGCTTGAGGTATAAAAAGCCCTGTACGGGAAGAGACCTTCAT +>chr21_32253899_32253949_- +AGCCCCACCCACCAGCAAGGATATATAAAAGCTCAGGAGTCTGGAGTGAC +>chr21_32410820_32410870_- +TCTACCCCACTAATCACTGAGGATGTATAAAAGTCCCAGGGAAGCTGGTG +>chr21_36411748_36411798_- +ATAGTTCTGTATAGTTTCAGTTGGCATCtaaaaattatataactttattt +>chr21_37838750_37838800_- +gatggttttataaggggcctcaccctcggctcagccctcattcttctcct +>chr21_45705687_45705737_+ +CCGGGGCGGAGCGGCCTTTGCTCTTTGCGTGGTCGCGGGmGGTATAACAGC +>chr21_45971413_45971463_- +CAGGCCCTGGGCATATAAAAGCCCCAGCAGCCAACAGGctcacacacaca +>chr21_45978668_45978718_- +CAGAGGGGTATAAAGGTTCCGACCACTCAGAGGCCTGGCACGAtcactca +>chr21_45993530_45993580_+ +CCAAGGAGGAGTATAAAAGCCCCACAAACCCGAGCACCmTCACTCACTCGC +>chr21_46020421_46020471_+ +GAGACATATAAAAGCCAACATCCCTGAGCACCTAACACACGGactcactc +>chr21_46031920_46031970_+ +GGAAAATACCCAGGGAGGGTATAAAACCTCAGCAGCCAGGGCACACAAAC +>chr21_46046964_46047014_+ +ACAAGGCCAGGAGGGGTATAAAAGCCTGAGAGCCCCAAGAACctcacaca +>chr21_46057197_46057247_+ +ATTGCTGAGTCTCCTGCTGGGAAAACACAGGCCCTGGGCAT +>chr21_46086869_46086919_- +GACAGGTGTGCTTCTGTGCTGTGGGGATGCCTGGGCCCAGGTATAAAGGC +>chr21_46102103_46102153_- +AGGTGTGTGCTTCTGTGCTGTGGGGATGCCTCCAGGTATAAAGGCT +>chr21_47517957_47518007_+ +CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGmGG +>chr21_47517957_47518007_+ +CCTGGCGGCGmGGGCGGGTCAGGCCGGCGGGmGCGGGGTATAAAGGGGGCGG +>chr21_47517957_47518007_+ +CCTGGCGGCGGGmGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGmGCGG +>chr21_47575506_47575556_- +TGAGAAGCCGGTGGGGAGGTGmTGCCGGTGAGCmGTATAAAGGCCCTGGCG +>chr21_47575506_47575556_- +TGAGAAGCmGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGmGCCCTGGCG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test1.html Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,39 @@ + "train_negatives": { + "from": "shuffled", + "count": 33, + "positions": 1597 + }, + "test_positives": { + "count": 0, + "positions": 0 + }, + "test_negatives": { + "count": 0, + "positions": 0 + }, + "sequence_db": { + "freqs": [0.245, 0.255, 0.255, 0.245] + }, + "motifs": [ + { + "db": 0, + "id": "1-CTTTTATAYRCCY", + "alt": "STREME-1", + "width": 13, + "initial_width": 8, + "seed": "CTTTTATATGCCT", + "score_threshold": 10.1927, + "npassing": 18, + "train_pos_count": 18, + "train_neg_count": 0, + "train_log_pvalue": -6.81978, + "train_pvalue": "1.5e-007", + "train_dtc": -1.0, + "train_bernoulli": -1, + "test_pos_count": 0, + "test_neg_count": 0, + "test_log_pvalue": 0, + "test_pvalue": "1.0e+000", + "test_log_evalue": 0.69897, + "test_evalue": "5.0e+000", + "test_dtc": -1.0, \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test1.txt Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,93 @@ +******************************************************************************** +STREME - Sensitive, Thorough, Rapid, Enriched Motif Elicitation +******************************************************************************** +MEME version 5.5.8 (Release date: Thu May 15 15:01:46 2025 -0700) + +For further information on how to interpret these results please access https://meme-suite.org/meme. +To get a copy of the MEME Suite software please access https://meme-suite.org. + +******************************************************************************** + + +******************************************************************************** +REFERENCE +******************************************************************************** +If you use this program in your research, please cite: + +Timothy L. Bailey, +"STREME: accurate and versatile sequence motif discovery", +Bioinformatics, Mar. 24, 2021. +******************************************************************************** + + +ALPHABET= ACGT + +strands: + - + +Background letter frequencies +A 0.244 C 0.256 G 0.256 T 0.244 + +MOTIF 1-CTTTTATAYRCCY STREME-1 +letter-probability matrix: alength= 4 w= 13 nsites= 18 S= 1.5e-007 + 0.072963 0.851476 0.002598 0.072963 + 0.072963 0.145128 0.002598 0.779311 + 0.002486 0.002598 0.073075 0.921841 + 0.002486 0.002598 0.002598 0.992318 + 0.002486 0.002598 0.002598 0.992318 + 0.992318 0.002598 0.002598 0.002486 + 0.002486 0.002598 0.073075 0.921841 + 0.992318 0.002598 0.002598 0.002486 + 0.002486 0.497514 0.002598 0.497402 + 0.284394 0.143552 0.499090 0.072963 + 0.002486 0.710522 0.002598 0.284394 + 0.002486 0.779422 0.073075 0.145017 + 0.072963 0.428613 0.073075 0.425349 + +MOTIF 2-CCCCACCRSC STREME-2 +letter-probability matrix: alength= 4 w= 10 nsites= 12 S= 7.2e-005 + 0.139001 0.787776 0.070814 0.002409 + 0.070705 0.924368 0.002517 0.002409 + 0.002409 0.924368 0.070814 0.002409 + 0.002409 0.992664 0.002517 0.002409 + 0.716267 0.002517 0.210510 0.070705 + 0.002409 0.856072 0.070814 0.070705 + 0.208825 0.786248 0.002517 0.002409 + 0.343890 0.030359 0.555046 0.070705 + 0.070705 0.376471 0.550414 0.002409 + 0.208825 0.786248 0.002517 0.002409 + +MOTIF 3-RCAGAAKCA STREME-3 +letter-probability matrix: alength= 4 w= 9 nsites= 10 S= 4.4e-004 + 0.595835 0.003626 0.397069 0.003470 + 0.003470 0.694352 0.298708 0.003470 + 0.792557 0.003626 0.101987 0.101831 + 0.003470 0.101987 0.891074 0.003470 + 0.694196 0.003626 0.298708 0.003470 + 0.694196 0.298708 0.003626 0.003470 + 0.003470 0.101987 0.300909 0.593635 + 0.101831 0.792713 0.003626 0.101831 + 0.989279 0.003626 0.003626 0.003470 + +MOTIF 4-RAGTTATAAA STREME-4 +letter-probability matrix: alength= 4 w= 10 nsites= 8 S= 2.4e-003 + 0.333562 0.113112 0.440386 0.112939 + 0.988110 0.004021 0.004021 0.003848 + 0.003848 0.004021 0.879191 0.112939 + 0.003848 0.004021 0.222204 0.769927 + 0.112939 0.004021 0.004021 0.879018 + 0.769927 0.004021 0.113112 0.112939 + 0.003848 0.004021 0.113112 0.879018 + 0.988110 0.004021 0.004021 0.003848 + 0.549304 0.113112 0.113112 0.224471 + 0.769927 0.004021 0.113112 0.112939 + +MOTIF 5-AACCTCGG STREME-5 +letter-probability matrix: alength= 4 w= 8 nsites= 7 S= 5.5e-003 + 0.973700 0.008894 0.008894 0.008511 + 0.732403 0.250191 0.008894 0.008511 + 0.008511 0.974083 0.008894 0.008511 + 0.008511 0.974083 0.008894 0.008511 + 0.008511 0.008894 0.008894 0.973700 + 0.008511 0.732786 0.250191 0.008511 + 0.249809 0.008894 0.732786 0.008511 + 0.008511 0.008894 0.974083 0.008511 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test1.xml Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,26 @@ + <letter id="A" symbol="A" complement="T" name="Adenine" colour="CC0000"/> + <letter id="C" symbol="C" complement="G" name="Cytosine" colour="0000CC"/> + <letter id="G" symbol="G" complement="C" name="Guanine" colour="FFB300"/> + <letter id="T" symbol="T" aliases="U" complement="A" name="Thymine" colour="008000"/> + <letter id="N" symbol="N" aliases="X." equals="ACGT" name="Any base"/> + <letter id="V" symbol="V" equals="ACG" name="Not T"/> + <letter id="H" symbol="H" equals="ACT" name="Not G"/> + <letter id="D" symbol="D" equals="AGT" name="Not C"/> + <letter id="B" symbol="B" equals="CGT" name="Not A"/> + <letter id="M" symbol="M" equals="AC" name="Amino"/> + <letter id="R" symbol="R" equals="AG" name="Purine"/> + <letter id="W" symbol="W" equals="AT" name="Weak"/> + <letter id="S" symbol="S" equals="CG" name="Strong"/> + <letter id="Y" symbol="Y" equals="CT" name="Pyrimidine"/> + <letter id="K" symbol="K" equals="GT" name="Keto"/> + </alphabet> + <strands>both</strands> + <sequence_db A="0.245" C="0.255" G="0.255" T="0.245"/> + <background_frequencies source="--negatives--" order="2"> + <alphabet_array> + <value letter_id="A">0.244</value> + <value letter_id="C">0.256</value> + <value letter_id="G">0.256</value> + <value letter_id="T">0.244</value> + </alphabet_array> + </background_frequencies> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test2.html Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,43 @@ + "train_negatives": { + "from": "shuffled", + "count": 33, + "positions": 1597 + }, + "test_positives": { + "count": 0, + "positions": 0 + }, + "test_negatives": { + "count": 0, + "positions": 0 + }, + "sequence_db": { + "freqs": [ + 0.218, 0.24, 0.24, 0.218, 0.0266, 0.0125, 0, 0.00313, 0, 0, + 0.0266, 0, 0, 0, 0.0125, 0.00313 + ] + }, + "motifs": [ + { + "db": 0, + "id": "1-GTATAAAAGC", + "alt": "STREME-1", + "width": 10, + "initial_width": 5, + "seed": "GTATAAAGGC", + "score_threshold": 9.73039, + "npassing": 28, + "train_pos_count": 28, + "train_neg_count": 0, + "train_log_pvalue": -13.1578, + "train_pvalue": "7.0e-014", + "train_dtc": -1.0, + "train_bernoulli": -1, + "test_pos_count": 0, + "test_neg_count": 0, + "test_log_pvalue": 0, + "test_pvalue": "1.0e+000", + "test_log_evalue": 0.477121, + "test_evalue": "3.0e+000", + "test_dtc": -1.0, + "test_bernoulli": -1, \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test2.txt Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,78 @@ +******************************************************************************** +STREME - Sensitive, Thorough, Rapid, Enriched Motif Elicitation +******************************************************************************** +MEME version 5.5.8 (Release date: Thu May 15 15:01:46 2025 -0700) + +For further information on how to interpret these results please access https://meme-suite.org/meme. +To get a copy of the MEME Suite software please access https://meme-suite.org. + +******************************************************************************** + + +******************************************************************************** +REFERENCE +******************************************************************************** +If you use this program in your research, please cite: + +Timothy L. Bailey, +"STREME: accurate and versatile sequence motif discovery", +Bioinformatics, Mar. 24, 2021. +******************************************************************************** + + +******************************************************************************** +ALPHABET "DNA with covalent modifications" DNA-LIKE +******************************************************************************** +A "Adenine" 8510A8 ~ T "Thymine" A89610 +C "Cytosine" A50026 ~ G "Guanine" 313695 +a "N6-methyladenine" 8510A8 ~ t "Thymine_lowercase" 756BB1 +c "5-Carboxylcytosine" FEE090 ~ 4 "Guanine:5-Carboxylcytosine" E0F3F8 +f "5-Formylcytosine" FDAE61 ~ 3 "Guanine:5-Formylcytosine" ABD9E9 +g "modified_g" 00897B ~ 5 "cytosine_lowercase" 53698A +h "5-Hydroxymethylcytosine" F46D43 ~ 2 "Guanine:5-Hydroxymethylcytosine" 74ADD1 +m "5-Methylcytosine" D73027 ~ 1 "Guanine:5-Methylcytosine" 4575B4 +? = ACGTacfghmt12345 +******************************************************************************** + +strands: + - + +Background letter frequencies +A 0.218 C 0.24 G 0.24 T 0.218 a 0.0266 c 0.0125 f 1.96e-05 g 0.00315 h 1.96e-05 m 1.96e-05 t 0.0266 1 1.96e-05 2 1.96e-05 3 1.96e-05 4 0.0125 5 0.00315 + +MOTIF 1-GTATAAAAGC STREME-1 +letter-probability matrix: alength= 16 w= 10 nsites= 28 S= 7.0e-014 + 0.344606 0.001172 0.618858 0.034950 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.001065 0.001172 0.001172 0.996177 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.996177 0.001172 0.001172 0.001065 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.001065 0.001172 0.001172 0.996177 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.996177 0.001172 0.001172 0.001065 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.928407 0.001172 0.035057 0.034950 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.860638 0.136711 0.001172 0.001065 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.548672 0.001172 0.313139 0.136603 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.068834 0.068941 0.725207 0.136603 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + 0.068834 0.485705 0.308443 0.136603 0.000130 0.000061 0.000000 0.000015 0.000000 0.000000 0.000130 0.000000 0.000000 0.000000 0.000061 0.000015 + +MOTIF 2-CCCACCAGA STREME-2 +letter-probability matrix: alength= 16 w= 9 nsites= 20 S= 2.2e-007 + 0.001482 0.947685 0.048775 0.001482 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.143970 0.805197 0.048775 0.001482 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.095771 0.711962 0.143064 0.048626 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.947536 0.001631 0.048775 0.001482 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.095771 0.710908 0.191263 0.001482 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.001482 0.900540 0.001631 0.095771 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.663614 0.095920 0.096974 0.142915 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.095771 0.332697 0.569474 0.001482 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + 0.473982 0.239462 0.143064 0.142915 0.000181 0.000085 0.000000 0.000021 0.000000 0.000000 0.000181 0.000000 0.000000 0.000000 0.000085 0.000021 + +MOTIF 3-4a4t4a4a4T STREME-3 +letter-probability matrix: alength= 16 w= 10 nsites= 7 S= 5.5e-003 + 0.004400 0.004842 0.004842 0.004400 0.140510 0.000253 0.000000 0.000064 0.000000 0.000000 0.000537 0.000000 0.000000 0.000000 0.840087 0.000064 + 0.004400 0.004842 0.004842 0.004400 0.700399 0.000253 0.000000 0.000064 0.000000 0.000000 0.280482 0.000000 0.000000 0.000000 0.000253 0.000064 + 0.004400 0.004842 0.004842 0.004400 0.000537 0.000253 0.000000 0.000064 0.000000 0.000000 0.000537 0.000000 0.000000 0.000000 0.980059 0.000064 + 0.004400 0.004842 0.004842 0.004400 0.000537 0.000253 0.000000 0.000064 0.000000 0.000000 0.840371 0.000000 0.000000 0.000000 0.140226 0.000064 + 0.004400 0.004842 0.004842 0.004400 0.000537 0.000253 0.000000 0.000064 0.000000 0.000000 0.280482 0.000000 0.000000 0.000000 0.700115 0.000064 + 0.004400 0.004842 0.004842 0.004400 0.560427 0.000253 0.000000 0.000064 0.000000 0.000000 0.420454 0.000000 0.000000 0.000000 0.000253 0.000064 + 0.004400 0.004842 0.004842 0.144372 0.000537 0.000253 0.000000 0.000064 0.000000 0.000000 0.280482 0.000000 0.000000 0.000000 0.560142 0.000064 + 0.004400 0.144814 0.144814 0.004400 0.420454 0.000253 0.000000 0.000064 0.000000 0.000000 0.280482 0.000000 0.000000 0.000000 0.000253 0.000064 + 0.004400 0.144814 0.144814 0.144372 0.140510 0.000253 0.000000 0.000064 0.000000 0.000000 0.140510 0.000000 0.000000 0.000000 0.280198 0.000064 + 0.004400 0.144814 0.004842 0.284344 0.280482 0.000253 0.000000 0.000064 0.000000 0.000000 0.000537 0.000000 0.000000 0.000000 0.280198 0.000064 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test2.xml Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,39 @@ + <alphabet name="DNA with covalent modifications" like="dna"> + <letter id="A" symbol="A" complement="T" name="Adenine" colour="8510A8"/> + <letter id="C" symbol="C" complement="G" name="Cytosine" colour="A50026"/> + <letter id="G" symbol="G" complement="C" name="Guanine" colour="313695"/> + <letter id="T" symbol="T" complement="A" name="Thymine" colour="A89610"/> + <letter id="a" symbol="a" complement="t" name="N6-methyladenine" colour="8510A8"/> + <letter id="c" symbol="c" complement="4" name="5-Carboxylcytosine" colour="FEE090"/> + <letter id="f" symbol="f" complement="3" name="5-Formylcytosine" colour="FDAE61"/> + <letter id="g" symbol="g" complement="5" name="modified_g" colour="00897B"/> + <letter id="h" symbol="h" complement="2" name="5-Hydroxymethylcytosine" colour="F46D43"/> + <letter id="m" symbol="m" complement="1" name="5-Methylcytosine" colour="D73027"/> + <letter id="t" symbol="t" complement="a" name="Thymine_lowercase" colour="756BB1"/> + <letter id="n1" symbol="1" complement="m" name="Guanine:5-Methylcytosine" colour="4575B4"/> + <letter id="n2" symbol="2" complement="h" name="Guanine:5-Hydroxymethylcytosine" colour="74ADD1"/> + <letter id="n3" symbol="3" complement="f" name="Guanine:5-Formylcytosine" colour="ABD9E9"/> + <letter id="n4" symbol="4" complement="c" name="Guanine:5-Carboxylcytosine" colour="E0F3F8"/> + <letter id="n5" symbol="5" complement="g" name="cytosine_lowercase" colour="53698A"/> + <letter id="x3F" symbol="?" equals="ACGTacfghmt12345"/> + </alphabet> + <strands>both</strands> + <sequence_db A="0.218" C="0.24" G="0.24" T="0.218" a="0.0266" c="0.0125" f="0" g="0.00313" h="0" m="0" t="0.0266" n1="0" n2="0" n3="0" n4="0.0125" n5="0.00313"/> + <background_frequencies source="--negatives--" order="0"> + <alphabet_array> + <value letter_id="A">0.218</value> + <value letter_id="C">0.24</value> + <value letter_id="G">0.24</value> + <value letter_id="T">0.218</value> + <value letter_id="a">0.0266</value> + <value letter_id="c">0.0125</value> + <value letter_id="f">1.96e-05</value> + <value letter_id="g">0.00315</value> + <value letter_id="h">1.96e-05</value> + <value letter_id="m">1.96e-05</value> + <value letter_id="t">0.0266</value> + <value letter_id="n1">1.96e-05</value> + <value letter_id="n2">1.96e-05</value> + <value letter_id="n3">1.96e-05</value> + <value letter_id="n4">0.0125</value> + <value letter_id="n5">0.00315</value> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test3.html Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,38 @@ + "max_sites": 2, + "site_hist": [0, 6, 1], + "len": 5, + "nsites": 7, + "evalue": "0", + "pwm": [ + [ + 0.00775938, 0.00626088, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.979973, 8.41549e-07, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.000219631, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 8.41549e-07, 0.00577435, 8.41549e-07, + 8.41549e-07, 8.41549e-07 + ], [ + 0.00775938, 0.588717, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.397517, 8.41549e-07, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.000219631, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 8.41549e-07, 0.00577435, 8.41549e-07, + 8.41549e-07, 8.41549e-07 + ], [ + 0.00775938, 0.00626088, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.00777606, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 0.972417, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 8.41549e-07, 0.00577435, 8.41549e-07, + 8.41549e-07, 8.41549e-07 + ], [ + 0.00775938, 0.00626088, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.979973, 8.41549e-07, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.000219631, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 8.41549e-07, 0.00577435, 8.41549e-07, + 8.41549e-07, 8.41549e-07 + ], [ + 0.00775938, 0.00626088, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.787258, 8.41549e-07, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 0.000219631, 8.41549e-07, 8.41549e-07, 8.41549e-07, + 8.41549e-07, 8.41549e-07, 0.19849, 8.41549e-07, 8.41549e-07, + 8.41549e-07 + ] + ] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test3.txt Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,79 @@ +******************************************************************************** +STREME - Sensitive, Thorough, Rapid, Enriched Motif Elicitation +******************************************************************************** +MEME version 5.5.8 (Release date: Thu May 15 15:01:46 2025 -0700) + +For further information on how to interpret these results please access https://meme-suite.org/meme. +To get a copy of the MEME Suite software please access https://meme-suite.org. + +******************************************************************************** + + +******************************************************************************** +REFERENCE +******************************************************************************** +If you use this program in your research, please cite: + +Timothy L. Bailey, +"STREME: accurate and versatile sequence motif discovery", +Bioinformatics, Mar. 24, 2021. +******************************************************************************** + + +ALPHABET= ACDEFGHIKLMNPQRSTVWY + +strands: + + +Background letter frequencies +A 0.279 C 0.225 D 3.03e-05 E 3.03e-05 F 3.03e-05 G 0.28 H 3.03e-05 I 3.03e-05 K 3.03e-05 L 3.03e-05 M 0.0079 N 3.03e-05 P 3.03e-05 Q 3.03e-05 R 3.03e-05 S 3.03e-05 T 0.208 V 3.03e-05 W 3.03e-05 Y 3.03e-05 + +MOTIF 1-GCMGG STREME-1 +letter-probability matrix: alength= 20 w= 5 nsites= 7 S= 5.5e-003 + 0.007759 0.006261 0.000001 0.000001 0.000001 0.979973 0.000001 0.000001 0.000001 0.000001 0.000220 0.000001 0.000001 0.000001 0.000001 0.000001 0.005774 0.000001 0.000001 0.000001 + 0.007759 0.588717 0.000001 0.000001 0.000001 0.397517 0.000001 0.000001 0.000001 0.000001 0.000220 0.000001 0.000001 0.000001 0.000001 0.000001 0.005774 0.000001 0.000001 0.000001 + 0.007759 0.006261 0.000001 0.000001 0.000001 0.007776 0.000001 0.000001 0.000001 0.000001 0.972417 0.000001 0.000001 0.000001 0.000001 0.000001 0.005774 0.000001 0.000001 0.000001 + 0.007759 0.006261 0.000001 0.000001 0.000001 0.979973 0.000001 0.000001 0.000001 0.000001 0.000220 0.000001 0.000001 0.000001 0.000001 0.000001 0.005774 0.000001 0.000001 0.000001 + 0.007759 0.006261 0.000001 0.000001 0.000001 0.787258 0.000001 0.000001 0.000001 0.000001 0.000220 0.000001 0.000001 0.000001 0.000001 0.000001 0.198490 0.000001 0.000001 0.000001 + +MOTIF 2-GGTMA STREME-2 +letter-probability matrix: alength= 20 w= 5 nsites= 6 S= 5.2e-002 + 0.166242 0.005192 0.000001 0.000001 0.000001 0.823585 0.000001 0.000001 0.000001 0.000001 0.000182 0.000001 0.000001 0.000001 0.000001 0.000001 0.004788 0.000001 0.000001 0.000001 + 0.006434 0.164999 0.000001 0.000001 0.000001 0.823585 0.000001 0.000001 0.000001 0.000001 0.000182 0.000001 0.000001 0.000001 0.000001 0.000001 0.004788 0.000001 0.000001 0.000001 + 0.006434 0.005192 0.000001 0.000001 0.000001 0.006448 0.000001 0.000001 0.000001 0.000001 0.000182 0.000001 0.000001 0.000001 0.000001 0.000001 0.981733 0.000001 0.000001 0.000001 + 0.006434 0.277760 0.000001 0.000001 0.000001 0.166256 0.000001 0.000001 0.000001 0.000001 0.479605 0.000001 0.000001 0.000001 0.000001 0.000001 0.069935 0.000001 0.000001 0.000001 + 0.823572 0.164999 0.000001 0.000001 0.000001 0.006448 0.000001 0.000001 0.000001 0.000001 0.000182 0.000001 0.000001 0.000001 0.000001 0.000001 0.004788 0.000001 0.000001 0.000001 + +MOTIF 3-GTATAAAATCA STREME-3 +letter-probability matrix: alength= 20 w= 11 nsites= 8 S= 9.3e-002 + 0.008845 0.007137 0.000001 0.000001 0.000001 0.977170 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.006583 0.000001 0.000001 0.000001 + 0.008845 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.974888 0.000001 0.000001 0.000001 + 0.977151 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.006583 0.000001 0.000001 0.000001 + 0.008845 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.974888 0.000001 0.000001 0.000001 + 0.977151 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.006583 0.000001 0.000001 0.000001 + 0.757464 0.007137 0.000001 0.000001 0.000001 0.228552 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.006583 0.000001 0.000001 0.000001 + 0.757464 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.226270 0.000001 0.000001 0.000001 + 0.757464 0.007137 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.226270 0.000001 0.000001 0.000001 + 0.008845 0.226824 0.000001 0.000001 0.000001 0.228552 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.535514 0.000001 0.000001 0.000001 + 0.008845 0.885886 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.096140 0.000001 0.000001 0.000001 + 0.448220 0.226824 0.000001 0.000001 0.000001 0.008864 0.000001 0.000001 0.000001 0.000001 0.000250 0.000001 0.000001 0.000001 0.000001 0.000001 0.315827 0.000001 0.000001 0.000001 + +MOTIF 4-GAGGTG STREME-4 +letter-probability matrix: alength= 20 w= 6 nsites= 5 S= 9.8e-002 + 0.007829 0.200766 0.000001 0.000001 0.000001 0.785344 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.005826 0.000001 0.000001 0.000001 + 0.979776 0.006317 0.000001 0.000001 0.000001 0.007846 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.005826 0.000001 0.000001 0.000001 + 0.202278 0.041933 0.000001 0.000001 0.000001 0.670460 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.085095 0.000001 0.000001 0.000001 + 0.007829 0.200766 0.000001 0.000001 0.000001 0.785344 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.005826 0.000001 0.000001 0.000001 + 0.007829 0.006317 0.000001 0.000001 0.000001 0.007846 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.977773 0.000001 0.000001 0.000001 + 0.087098 0.006317 0.000001 0.000001 0.000001 0.900525 0.000001 0.000001 0.000001 0.000001 0.000222 0.000001 0.000001 0.000001 0.000001 0.000001 0.005826 0.000001 0.000001 0.000001 + +MOTIF 5-TCACACACA STREME-5 +letter-probability matrix: alength= 20 w= 9 nsites= 5 S= 9.8e-002 + 0.007502 0.192368 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.792388 0.000001 0.000001 0.000001 + 0.193817 0.716905 0.000001 0.000001 0.000001 0.083471 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.005583 0.000001 0.000001 0.000001 + 0.794307 0.006053 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.191898 0.000001 0.000001 0.000001 + 0.007502 0.903220 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.081536 0.000001 0.000001 0.000001 + 0.794307 0.006053 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.191898 0.000001 0.000001 0.000001 + 0.007502 0.792858 0.000001 0.000001 0.000001 0.193833 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.005583 0.000001 0.000001 0.000001 + 0.718354 0.082006 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.191898 0.000001 0.000001 0.000001 + 0.007502 0.979173 0.000001 0.000001 0.000001 0.007518 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.005583 0.000001 0.000001 0.000001 + 0.532038 0.006053 0.000001 0.000001 0.000001 0.193833 0.000001 0.000001 0.000001 0.000001 0.000212 0.000001 0.000001 0.000001 0.000001 0.000001 0.267851 0.000001 0.000001 0.000001
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/streme_output_test3.xml Mon Jul 14 21:33:56 2025 +0000 @@ -0,0 +1,73 @@ + <letter id="A" symbol="A" name="Alanine" colour="0000CC"/> + <letter id="C" symbol="C" name="Cysteine" colour="0000CC"/> + <letter id="D" symbol="D" name="Aspartic acid" colour="FF00FF"/> + <letter id="E" symbol="E" name="Glutamic acid" colour="FF00FF"/> + <letter id="F" symbol="F" name="Phenylalanine" colour="0000CC"/> + <letter id="G" symbol="G" name="Glycine" colour="FFB300"/> + <letter id="H" symbol="H" name="Histidine" colour="FFCCCC"/> + <letter id="I" symbol="I" name="Isoleucine" colour="0000CC"/> + <letter id="K" symbol="K" name="Lysine" colour="CC0000"/> + <letter id="L" symbol="L" name="Leucine" colour="0000CC"/> + <letter id="M" symbol="M" name="Methionine" colour="0000CC"/> + <letter id="N" symbol="N" name="Asparagine" colour="008000"/> + <letter id="P" symbol="P" name="Proline" colour="FFFF00"/> + <letter id="Q" symbol="Q" name="Glutamine" colour="008000"/> + <letter id="R" symbol="R" name="Arginine" colour="CC0000"/> + <letter id="S" symbol="S" name="Serine" colour="008000"/> + <letter id="T" symbol="T" name="Threonine" colour="008000"/> + <letter id="V" symbol="V" name="Valine" colour="0000CC"/> + <letter id="W" symbol="W" name="Tryptophan" colour="0000CC"/> + <letter id="Y" symbol="Y" name="Tyrosine" colour="33E6CC"/> + <letter id="X" symbol="X" aliases="*." equals="ACDEFGHIKLMNPQRSTVWY" name="Any amino acid"/> + <letter id="B" symbol="B" equals="DN" name="Asparagine or Aspartic acid"/> + <letter id="Z" symbol="Z" equals="EQ" name="Glutamine or Glutamic acid"/> + <letter id="J" symbol="J" equals="IL" name="Leucine or Isoleucine"/> + </alphabet> + <strands>none</strands> + <sequence_db A="0.275" C="0.224" D="0" E="0" F="0" G="0.283" H="0" I="0" K="0" L="0" M="0.00977" N="0" P="0" Q="0" R="0" S="0" T="0.209" V="0" W="0" Y="0"/> + <background_frequencies source="--negatives--" order="0"> + <alphabet_array> + <value letter_id="A">0.279</value> + <value letter_id="C">0.225</value> + <value letter_id="D">3.03e-05</value> + <value letter_id="E">3.03e-05</value> + <value letter_id="F">3.03e-05</value> + <value letter_id="G">0.28</value> + <value letter_id="H">3.03e-05</value> + <value letter_id="I">3.03e-05</value> + <value letter_id="K">3.03e-05</value> + <value letter_id="L">3.03e-05</value> + <value letter_id="M">0.0079</value> + <value letter_id="N">3.03e-05</value> + <value letter_id="P">3.03e-05</value> + <value letter_id="Q">3.03e-05</value> + <value letter_id="R">3.03e-05</value> + <value letter_id="S">3.03e-05</value> + <value letter_id="T">0.208</value> + <value letter_id="V">3.03e-05</value> + <value letter_id="W">3.03e-05</value> + <value letter_id="Y">3.03e-05</value> + </alphabet_array> + </background_frequencies> + <stop nmotifs="5"/> + <objfun>Differential Enrichment</objfun> + <test>Fisher Exact Test</test> + <minw>5</minw> + <maxw>20</maxw> + <kmer>1</kmer> + <hofract>0.1</hofract> + <neval>25</neval> + <nref>4</nref> + <niter>20</niter> + <patience>3</patience> + <seed>0</seed> + <notrim>no</notrim> + <useer>no</useer> + <minscore>0</minscore> + <ignore_depth>5</ignore_depth> + <nsubsets>1</nsubsets> + <min_pal_ratio>0.85</min_pal_ratio> + <max_pal_ed>5</max_pal_ed> + <cand>no</cand> + <experimental>no</experimental> + <totallength>0</totallength> \ No newline at end of file