# Copyright 2008 by Bartek Wilczynski.  All rights reserved.
# Adapted from test_Mymodule.py by Jeff Chang
# This file is part of the Biopython distribution and governed by your
# choice of the "Biopython License Agreement" or the "BSD 3-Clause License".
# Please see the LICENSE file that should have been included as part of this
# package.

"""Tests for motifs module."""

import os
import unittest
import math

from Bio.Alphabet import generic_dna
from Bio.Alphabet import Gapped
from Bio.Alphabet import IUPAC
from Bio import motifs
from Bio.Seq import Seq


class MotifTestsBasic(unittest.TestCase):
    """Basic motif tests."""

    def setUp(self):
        self.PFMin = open("motifs/SRF.pfm")
        self.SITESin = open("motifs/Arnt.sites")
        self.CLUSTERBUSTERin = open("motifs/clusterbuster.pfm")
        self.XMSin = open("motifs/abdb.xms")
        self.TFout = "motifs/tf.out"
        self.FAout = "motifs/fa.out"
        self.PFMout = "motifs/fa.out"
        instance = Seq("ATATA")
        instances = [instance]
        self.m = motifs.create(instances)

    def tearDown(self):
        self.PFMin.close()
        self.SITESin.close()
        if os.path.exists(self.TFout):
            os.remove(self.TFout)
        if os.path.exists(self.FAout):
            os.remove(self.FAout)

    def test_alignace_parsing(self):
        """Test if Bio.motifs can parse AlignAce output files."""
        with open("motifs/alignace.out") as handle:
            record = motifs.parse(handle, "AlignAce")
        self.assertEqual(record.version, "AlignACE 4.0 05/13/04")
        self.assertEqual(record.command, "./AlignACE -i test.fa")
        self.assertEqual(len(record.parameters), 7)
        self.assertEqual(record.parameters["expect"], "10")
        self.assertEqual(record.parameters["gcback"], "0.38")
        self.assertEqual(record.parameters["minpass"], "200")
        self.assertEqual(record.parameters["seed"], "1227623309")
        self.assertEqual(record.parameters["numcols"], "10")
        self.assertEqual(record.parameters["undersample"], "1")
        self.assertEqual(record.parameters["oversample"], "1")
        self.assertEqual(len(record.sequences), 10)
        self.assertEqual(record.sequences[0], "SEQ1; M: CTCAATCGTAGA at 52")
        self.assertEqual(record.sequences[1], "SEQ2; M: CTCAATCGTAGA at 172")
        self.assertEqual(record.sequences[2], "SEQ3; M: CTCAATCGTAGA at 112")
        self.assertEqual(record.sequences[3], "SEQ4; M: CTCAATCGTAGA at 173")
        self.assertEqual(record.sequences[4], "SEQ5; M: CTCAATCGTAGA at 185")
        self.assertEqual(record.sequences[5], "SEQ6; M: CTCAATCGTAGA at 105")
        self.assertEqual(record.sequences[6], "SEQ7; M: CTCAATCGTAGA at 177")
        self.assertEqual(record.sequences[7], "SEQ8; M: CTCAATCGTAGA at 172")
        self.assertEqual(record.sequences[8], "SEQ9; M: CTCAATCGTAGA at 93")
        self.assertEqual(record.sequences[9], "SEQ10; M: CTCAATCGTAGA at 3")
        self.assertEqual(len(record), 16)
        self.assertEqual(record[0].alphabet, "ACGT")
        self.assertEqual(len(record[0].instances), 11)
        self.assertEqual(str(record[0].instances[0]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[1]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[2]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[3]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[4]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[5]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[6]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[7]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[8]), "TCTACGATTGAG")
        self.assertEqual(str(record[0].instances[9]), "TCAAAGATAGAG")
        self.assertEqual(str(record[0].instances[10]), "TCTACGATTGAG")
        self.assertEqual(record[0].mask, (1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1))
        self.assertAlmostEqual(record[0].score, 57.9079)
        self.assertEqual(record[1].alphabet, "ACGT")
        self.assertEqual(len(record[1].instances), 22)
        self.assertEqual(str(record[1].instances[0]), "GCGAAGGAAGCAGCGCGTGTG")
        self.assertEqual(str(record[1].instances[1]), "GGCACCGCCTCTACGATTGAG")
        self.assertEqual(str(record[1].instances[2]), "CAGAGCTTAGCATTGAACGCG")
        self.assertEqual(str(record[1].instances[3]), "CTAATGAAAGCAATGAGAGTG")
        self.assertEqual(str(record[1].instances[4]), "CTTGTGCCCTCTAAGCGTCCG")
        self.assertEqual(str(record[1].instances[5]), "GAGCACGACGCTTTGTACCTG")
        self.assertEqual(str(record[1].instances[6]), "CGGCACTTAGCAGCGTATCGT")
        self.assertEqual(str(record[1].instances[7]), "CTGGTTTCATCTACGATTGAG")
        self.assertEqual(str(record[1].instances[8]), "GGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(str(record[1].instances[9]), "GTGGAGTTATCTTAGTGCGCG")
        self.assertEqual(str(record[1].instances[10]), "GAGAGGTTATCTACGATTGAG")
        self.assertEqual(str(record[1].instances[11]), "CTGCTCCCCGCATACAGCGCG")
        self.assertEqual(str(record[1].instances[12]), "CAGAACCGAGGTCCGGTACGG")
        self.assertEqual(str(record[1].instances[13]), "GTGCCCCAAGCTTACCCAGGG")
        self.assertEqual(str(record[1].instances[14]), "CGCCTCTGATCTACGATTGAG")
        self.assertEqual(str(record[1].instances[15]), "GTGCTCATAGGGACGTCGCGG")
        self.assertEqual(str(record[1].instances[16]), "CTGCCCCCCGCATAGTAGGGG")
        self.assertEqual(str(record[1].instances[17]), "GTAAAGAAATCGATGTGCCAG")
        self.assertEqual(str(record[1].instances[18]), "CACCTGCAATTGCTGGCAGCG")
        self.assertEqual(str(record[1].instances[19]), "GGCGGGCCATCCCTGTATGAA")
        self.assertEqual(str(record[1].instances[20]), "CTCCAGGTCGCATGGAGAGAG")
        self.assertEqual(str(record[1].instances[21]), "CCTCGGATCGCTTGGGAAGAG")
        self.assertEqual(record[1].mask, (1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1))
        self.assertAlmostEqual(record[1].score, 19.6235)

        self.assertEqual(record[2].alphabet, "ACGT")
        self.assertEqual(len(record[2].instances), 18)
        self.assertEqual(str(record[2].instances[0]), "GTGCGCGAAGGAAGCAGCGCG")
        self.assertEqual(str(record[2].instances[1]), "CAGAGCTTAGCATTGAACGCG")
        self.assertEqual(str(record[2].instances[2]), "GTGCCCGATGACCACCCGTCG")
        self.assertEqual(str(record[2].instances[3]), "GCCCTCTAAGCGTCCGCGGAT")
        self.assertEqual(str(record[2].instances[4]), "GAGCACGACGCTTTGTACCTG")
        self.assertEqual(str(record[2].instances[5]), "CGGCACTTAGCAGCGTATCGT")
        self.assertEqual(str(record[2].instances[6]), "GGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(str(record[2].instances[7]), "GCGCACTAAGATAACTCCACG")
        self.assertEqual(str(record[2].instances[8]), "CGGCCCGTTGTCCAGCAGACG")
        self.assertEqual(str(record[2].instances[9]), "CTGCTCCCCGCATACAGCGCG")
        self.assertEqual(str(record[2].instances[10]), "GTGCCCCAAGCTTACCCAGGG")
        self.assertEqual(str(record[2].instances[11]), "GTGCTCATAGGGACGTCGCGG")
        self.assertEqual(str(record[2].instances[12]), "CTGCCCCCCGCATAGTAGGGG")
        self.assertEqual(str(record[2].instances[13]), "CGCCGCCATGCGACGCAGAGG")
        self.assertEqual(str(record[2].instances[14]), "AACCTCTAAGCATACTCTACG")
        self.assertEqual(str(record[2].instances[15]), "GACCTGGAGGCTTAGACTTGG")
        self.assertEqual(str(record[2].instances[16]), "GCGCTCTTCCCAAGCGATCCG")
        self.assertEqual(str(record[2].instances[17]), "GGGCCGTCAGCTCTCAAGTCT")
        self.assertEqual(record[2].mask, (1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1))
        self.assertAlmostEqual(record[2].score, 19.1804)

        self.assertEqual(record[3].alphabet, "ACGT")
        self.assertEqual(len(record[3].instances), 16)
        self.assertEqual(str(record[3].instances[0]), "GCCCCAAGCTTACCCAGGGAC")
        self.assertEqual(str(record[3].instances[1]), "GCCGTCTGCTGGACAACGGGC")
        self.assertEqual(str(record[3].instances[2]), "GCCGACGGGTGGTCATCGGGC")
        self.assertEqual(str(record[3].instances[3]), "GCCAATAGCGGCGCCGGAGTC")
        self.assertEqual(str(record[3].instances[4]), "GCCCCCCGCATAGTAGGGGGA")
        self.assertEqual(str(record[3].instances[5]), "GCCCGTACCGGACCTCGGTTC")
        self.assertEqual(str(record[3].instances[6]), "GCCTCATGTACCGGAAGGGAC")
        self.assertEqual(str(record[3].instances[7]), "GACACGCGCCTGGGAGGGTTC")
        self.assertEqual(str(record[3].instances[8]), "GCCTTTGGCCTTGGATGAGAA")
        self.assertEqual(str(record[3].instances[9]), "GGCCCTCGGATCGCTTGGGAA")
        self.assertEqual(str(record[3].instances[10]), "GCATGTTGGGAATCCGCGGAC")
        self.assertEqual(str(record[3].instances[11]), "GACACGCGCTGTATGCGGGGA")
        self.assertEqual(str(record[3].instances[12]), "GCCAGGTACAAAGCGTCGTGC")
        self.assertEqual(str(record[3].instances[13]), "GCGATCAGCTTGTGGGCGTGC")
        self.assertEqual(str(record[3].instances[14]), "GACAAATCGGATACTGGGGCA")
        self.assertEqual(str(record[3].instances[15]), "GCACTTAGCAGCGTATCGTTA")
        self.assertEqual(record[3].mask, (1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1))
        self.assertAlmostEqual(record[3].score, 18.0097)
        self.assertEqual(record[4].alphabet, "ACGT")
        self.assertEqual(len(record[4].instances), 15)
        self.assertEqual(str(record[4].instances[0]), "CGGCACAGAGCTT")
        self.assertEqual(str(record[4].instances[1]), "ATCCGCGGACGCT")
        self.assertEqual(str(record[4].instances[2]), "CGCCTGGGAGGGT")
        self.assertEqual(str(record[4].instances[3]), "CGGAAGGGACGTT")
        self.assertEqual(str(record[4].instances[4]), "ACACACAGACGGT")
        self.assertEqual(str(record[4].instances[5]), "TGCCAGAGAGGTT")
        self.assertEqual(str(record[4].instances[6]), "AGACTGAGACGTT")
        self.assertEqual(str(record[4].instances[7]), "AATCGTAGAGGAT")
        self.assertEqual(str(record[4].instances[8]), "CGTCTCGTAGGGT")
        self.assertEqual(str(record[4].instances[9]), "CGTCGCGGAGGAT")
        self.assertEqual(str(record[4].instances[10]), "CTTCTTAGACGCT")
        self.assertEqual(str(record[4].instances[11]), "CGACGCAGAGGAT")
        self.assertEqual(str(record[4].instances[12]), "ATGCTTAGAGGTT")
        self.assertEqual(str(record[4].instances[13]), "AGACTTGGGCGAT")
        self.assertEqual(str(record[4].instances[14]), "CGACCTGGAGGCT")
        self.assertEqual(record[4].mask, (1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1))
        self.assertAlmostEqual(record[4].score, 16.8287)
        self.assertEqual(record[5].alphabet, "ACGT")
        self.assertEqual(len(record[5].instances), 18)
        self.assertEqual(str(record[5].instances[0]), "GTGCGCGAAGGAAGCAGCGCGTG")
        self.assertEqual(str(record[5].instances[1]), "TTGAGCCGAGTAAAGGGCTGGTG")
        self.assertEqual(str(record[5].instances[2]), "CAATGCTAAGCTCTGTGCCGACG")
        self.assertEqual(str(record[5].instances[3]), "CAACTCTCTATGTAGTGCCCGAG")
        self.assertEqual(str(record[5].instances[4]), "CGACGCTTTGTACCTGGCTTGCG")
        self.assertEqual(str(record[5].instances[5]), "CGAGTCAATGACACGCGCCTGGG")
        self.assertEqual(str(record[5].instances[6]), "CGATACGCTGCTAAGTGCCGTCC")
        self.assertEqual(str(record[5].instances[7]), "CCGGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(str(record[5].instances[8]), "CCACGCTTCGACACGTGGTATAG")
        self.assertEqual(str(record[5].instances[9]), "CCGAGCCTCATGTACCGGAAGGG")
        self.assertEqual(str(record[5].instances[10]), "CTGCTCCCCGCATACAGCGCGTG")
        self.assertEqual(str(record[5].instances[11]), "CCGAGGTCCGGTACGGGCAAGCC")
        self.assertEqual(str(record[5].instances[12]), "GTGCTCATAGGGACGTCGCGGAG")
        self.assertEqual(str(record[5].instances[13]), "CCCTACTATGCGGGGGGCAGGTC")
        self.assertEqual(str(record[5].instances[14]), "GCCAGCAATTGCAGGTGGTCGTG")
        self.assertEqual(str(record[5].instances[15]), "CTCTGCGTCGCATGGCGGCGTGG")
        self.assertEqual(str(record[5].instances[16]), "GGAGGCTTAGACTTGGGCGATAC")
        self.assertEqual(str(record[5].instances[17]), "GCATGGAGAGAGATCCGGAGGAG")
        self.assertEqual(record[5].mask, (1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1))
        self.assertAlmostEqual(record[5].score, 15.0441)
        self.assertEqual(record[6].alphabet, "ACGT")
        self.assertEqual(len(record[6].instances), 20)
        self.assertEqual(str(record[6].instances[0]), "GCGCGTGTGTGTAAC")
        self.assertEqual(str(record[6].instances[1]), "GCACAGAGCTTAGCA")
        self.assertEqual(str(record[6].instances[2]), "GGTGGTCATCGGGCA")
        self.assertEqual(str(record[6].instances[3]), "GCGCGTGTCATTGAC")
        self.assertEqual(str(record[6].instances[4]), "GGACGGCACTTAGCA")
        self.assertEqual(str(record[6].instances[5]), "GCGCGTCCCGGGCCA")
        self.assertEqual(str(record[6].instances[6]), "GCTCGGCCCGTTGTC")
        self.assertEqual(str(record[6].instances[7]), "GCGCGTGTCCTTTAA")
        self.assertEqual(str(record[6].instances[8]), "GCTGATCGCTGCTCC")
        self.assertEqual(str(record[6].instances[9]), "GCCCGTACCGGACCT")
        self.assertEqual(str(record[6].instances[10]), "GGACGTCGCGGAGGA")
        self.assertEqual(str(record[6].instances[11]), "GCGGGGGGCAGGTCA")
        self.assertEqual(str(record[6].instances[12]), "GGACGTACTGGCACA")
        self.assertEqual(str(record[6].instances[13]), "GCAGGTGGTCGTGCA")
        self.assertEqual(str(record[6].instances[14]), "GCGCATACCTTAACA")
        self.assertEqual(str(record[6].instances[15]), "GCACGGGACTTCAAC")
        self.assertEqual(str(record[6].instances[16]), "GCACGTAGCTGGTAA")
        self.assertEqual(str(record[6].instances[17]), "GCTCGTCTATGGTCA")
        self.assertEqual(str(record[6].instances[18]), "GCGCATGCTGGATCC")
        self.assertEqual(str(record[6].instances[19]), "GGCCGTCAGCTCTCA")
        self.assertEqual(record[6].mask, (1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1))
        self.assertAlmostEqual(record[6].score, 13.3145)
        self.assertEqual(record[7].alphabet, "ACGT")
        self.assertEqual(len(record[7].instances), 20)
        self.assertEqual(str(record[7].instances[0]), "GAACCGAGGTCCGGTACGGGC")
        self.assertEqual(str(record[7].instances[1]), "GCCCCCCGCATAGTAGGGGGA")
        self.assertEqual(str(record[7].instances[2]), "GTCCCTGGGTAAGCTTGGGGC")
        self.assertEqual(str(record[7].instances[3]), "ACTCCACGCTTCGACACGTGG")
        self.assertEqual(str(record[7].instances[4]), "ATCCTCTGCGTCGCATGGCGG")
        self.assertEqual(str(record[7].instances[5]), "GTTCAATGCTAAGCTCTGTGC")
        self.assertEqual(str(record[7].instances[6]), "GCTCATAGGGACGTCGCGGAG")
        self.assertEqual(str(record[7].instances[7]), "GTCCCGGGCCAATAGCGGCGC")
        self.assertEqual(str(record[7].instances[8]), "GCACTTAGCAGCGTATCGTTA")
        self.assertEqual(str(record[7].instances[9]), "GGCCCTCGGATCGCTTGGGAA")
        self.assertEqual(str(record[7].instances[10]), "CTGCTGGACAACGGGCCGAGC")
        self.assertEqual(str(record[7].instances[11]), "GGGCACTACATAGAGAGTTGC")
        self.assertEqual(str(record[7].instances[12]), "AGCCTCCAGGTCGCATGGAGA")
        self.assertEqual(str(record[7].instances[13]), "AATCGTAGATCAGAGGCGAGA")
        self.assertEqual(str(record[7].instances[14]), "GAACTCCACTAAGACTTGAGA")
        self.assertEqual(str(record[7].instances[15]), "GAGCAGCGATCAGCTTGTGGG")
        self.assertEqual(str(record[7].instances[16]), "GCCAGGTACAAAGCGTCGTGC")
        self.assertEqual(str(record[7].instances[17]), "AGTCAATGACACGCGCCTGGG")
        self.assertEqual(str(record[7].instances[18]), "GGTCATGGAATCTTATGTAGC")
        self.assertEqual(str(record[7].instances[19]), "GTAGATAACAGAGGTCGGGGG")
        self.assertEqual(record[7].mask, (1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1))
        self.assertAlmostEqual(record[7].score, 11.6098)
        self.assertEqual(record[8].alphabet, "ACGT")
        self.assertEqual(len(record[8].instances), 14)
        self.assertEqual(str(record[8].instances[0]), "CCGAGTAAAGGGCTG")
        self.assertEqual(str(record[8].instances[1]), "GTGGTCATCGGGCAC")
        self.assertEqual(str(record[8].instances[2]), "GATAACAGAGGTCGG")
        self.assertEqual(str(record[8].instances[3]), "CGGCGCCGGAGTCTG")
        self.assertEqual(str(record[8].instances[4]), "GCGCGTCCCGGGCCA")
        self.assertEqual(str(record[8].instances[5]), "CTGGACAACGGGCCG")
        self.assertEqual(str(record[8].instances[6]), "CGGATACTGGGGCAG")
        self.assertEqual(str(record[8].instances[7]), "GGGAGCAGCGATCAG")
        self.assertEqual(str(record[8].instances[8]), "CAGAACCGAGGTCCG")
        self.assertEqual(str(record[8].instances[9]), "GGGTCCCTGGGTAAG")
        self.assertEqual(str(record[8].instances[10]), "GTGCTCATAGGGACG")
        self.assertEqual(str(record[8].instances[11]), "GAGATCCGGAGGAGG")
        self.assertEqual(str(record[8].instances[12]), "GCGATCCGAGGGCCG")
        self.assertEqual(str(record[8].instances[13]), "GAGTTCACATGGCTG")
        self.assertEqual(record[8].mask, (1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1))
        self.assertAlmostEqual(record[8].score, 11.2943)
        self.assertEqual(record[9].alphabet, "ACGT")
        self.assertEqual(len(record[9].instances), 18)
        self.assertEqual(str(record[9].instances[0]), "TAGAGGCGGTG")
        self.assertEqual(str(record[9].instances[1]), "GCTAAGCTCTG")
        self.assertEqual(str(record[9].instances[2]), "TGGAAGCAGTG")
        self.assertEqual(str(record[9].instances[3]), "GCGAGGCTGTG")
        self.assertEqual(str(record[9].instances[4]), "ACGACGCTTTG")
        self.assertEqual(str(record[9].instances[5]), "GGGACGCGCAC")
        self.assertEqual(str(record[9].instances[6]), "TCGAAGCGTGG")
        self.assertEqual(str(record[9].instances[7]), "TGTATGCGGGG")
        self.assertEqual(str(record[9].instances[8]), "GGTAAGCTTGG")
        self.assertEqual(str(record[9].instances[9]), "TGTACGCTGGG")
        self.assertEqual(str(record[9].instances[10]), "ACTATGCGGGG")
        self.assertEqual(str(record[9].instances[11]), "GGTATGCGCTG")
        self.assertEqual(str(record[9].instances[12]), "GGTACCCGGAG")
        self.assertEqual(str(record[9].instances[13]), "GCGACGCAGAG")
        self.assertEqual(str(record[9].instances[14]), "TGGCGGCGTGG")
        self.assertEqual(str(record[9].instances[15]), "TCTAGGCGGGC")
        self.assertEqual(str(record[9].instances[16]), "AGTATGCTTAG")
        self.assertEqual(str(record[9].instances[17]), "TGGAGGCTTAG")
        self.assertEqual(record[9].mask, (1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1))
        self.assertAlmostEqual(record[9].score, 9.7924)
        self.assertEqual(record[10].alphabet, "ACGT")
        self.assertEqual(len(record[10].instances), 13)
        self.assertEqual(str(record[10].instances[0]), "GCACAGAGCTTAGCATTGAAC")
        self.assertEqual(str(record[10].instances[1]), "GTCCGCGGATTCCCAACATGC")
        self.assertEqual(str(record[10].instances[2]), "ATACACAGCCTCGCAAGCCAG")
        self.assertEqual(str(record[10].instances[3]), "GGCCCGGGACGCGCACTAAGA")
        self.assertEqual(str(record[10].instances[4]), "GCCCGTTGTCCAGCAGACGGC")
        self.assertEqual(str(record[10].instances[5]), "GAGCAGCGATCAGCTTGTGGG")
        self.assertEqual(str(record[10].instances[6]), "GAACCGAGGTCCGGTACGGGC")
        self.assertEqual(str(record[10].instances[7]), "GTCCCTGGGTAAGCTTGGGGC")
        self.assertEqual(str(record[10].instances[8]), "GACCTGCCCCCCGCATAGTAG")
        self.assertEqual(str(record[10].instances[9]), "AACCAGCGCATACCTTAACAG")
        self.assertEqual(str(record[10].instances[10]), "ATCCTCTGCGTCGCATGGCGG")
        self.assertEqual(str(record[10].instances[11]), "GACCATAGACGAGCATCAAAG")
        self.assertEqual(str(record[10].instances[12]), "GGCCCTCGGATCGCTTGGGAA")
        self.assertEqual(record[10].mask, (1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1))
        self.assertAlmostEqual(record[10].score, 9.01393)
        self.assertEqual(record[11].alphabet, "ACGT")
        self.assertEqual(len(record[11].instances), 16)
        self.assertEqual(str(record[11].instances[0]), "GCCGTCCGTC")
        self.assertEqual(str(record[11].instances[1]), "GGCGTGCGCG")
        self.assertEqual(str(record[11].instances[2]), "GGCGCGTGTC")
        self.assertEqual(str(record[11].instances[3]), "AGCGCGTGTG")
        self.assertEqual(str(record[11].instances[4]), "GCGGTGCGTG")
        self.assertEqual(str(record[11].instances[5]), "AGCGCGTGTC")
        self.assertEqual(str(record[11].instances[6]), "AGCGTCCGCG")
        self.assertEqual(str(record[11].instances[7]), "ACCGTCTGTG")
        self.assertEqual(str(record[11].instances[8]), "GCCATGCGAC")
        self.assertEqual(str(record[11].instances[9]), "ACCACCCGTC")
        self.assertEqual(str(record[11].instances[10]), "GGCGCCGGAG")
        self.assertEqual(str(record[11].instances[11]), "ACCACGTGTC")
        self.assertEqual(str(record[11].instances[12]), "GGCTTGCGAG")
        self.assertEqual(str(record[11].instances[13]), "GCGATCCGAG")
        self.assertEqual(str(record[11].instances[14]), "AGTGCGCGTC")
        self.assertEqual(str(record[11].instances[15]), "AGTGCCCGAG")
        self.assertEqual(record[11].mask, (1, 1, 1, 1, 1, 1, 1, 1, 1, 1))
        self.assertAlmostEqual(record[11].score, 7.51121)
        self.assertEqual(record[12].alphabet, "ACGT")
        self.assertEqual(len(record[12].instances), 16)
        self.assertEqual(str(record[12].instances[0]), "GCCGACGGGTGGTCATCGGG")
        self.assertEqual(str(record[12].instances[1]), "GCACGACGCTTTGTACCTGG")
        self.assertEqual(str(record[12].instances[2]), "CCTGGGAGGGTTCAATAACG")
        self.assertEqual(str(record[12].instances[3]), "GCGCGTCCCGGGCCAATAGC")
        self.assertEqual(str(record[12].instances[4]), "GCCGTCTGCTGGACAACGGG")
        self.assertEqual(str(record[12].instances[5]), "GTCCCTTCCGGTACATGAGG")
        self.assertEqual(str(record[12].instances[6]), "GCTGCTCCCCGCATACAGCG")
        self.assertEqual(str(record[12].instances[7]), "GCCCCAAGCTTACCCAGGGA")
        self.assertEqual(str(record[12].instances[8]), "ACCGGCTGACGCTAATACGG")
        self.assertEqual(str(record[12].instances[9]), "GCGGGGGGCAGGTCATTACA")
        self.assertEqual(str(record[12].instances[10]), "GCTGGCAGCGTCTAAGAAGG")
        self.assertEqual(str(record[12].instances[11]), "GCAGGTGGTCGTGCAATACG")
        self.assertEqual(str(record[12].instances[12]), "GCTGGTTGAAGTCCCGTGCG")
        self.assertEqual(str(record[12].instances[13]), "GCACGTAGCTGGTAAATAGG")
        self.assertEqual(str(record[12].instances[14]), "GCGGCGTGGATTTCATACAG")
        self.assertEqual(str(record[12].instances[15]), "CCTGGAGGCTTAGACTTGGG")
        self.assertEqual(record[12].mask, (1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1))
        self.assertAlmostEqual(record[12].score, 5.63667)
        self.assertEqual(record[13].alphabet, "ACGT")
        self.assertEqual(len(record[13].instances), 15)
        self.assertEqual(str(record[13].instances[0]), "GCCGACGGGTGGTCATCGGG")
        self.assertEqual(str(record[13].instances[1]), "ATCCGCGGACGCTTAGAGGG")
        self.assertEqual(str(record[13].instances[2]), "ACGCTTTGTACCTGGCTTGC")
        self.assertEqual(str(record[13].instances[3]), "ACGGACGGCACTTAGCAGCG")
        self.assertEqual(str(record[13].instances[4]), "GCCGTCTGCTGGACAACGGG")
        self.assertEqual(str(record[13].instances[5]), "ACACACAGACGGTTGAAAGG")
        self.assertEqual(str(record[13].instances[6]), "GCCGATAGTGCTTAAGTTCG")
        self.assertEqual(str(record[13].instances[7]), "CTTGCCCGTACCGGACCTCG")
        self.assertEqual(str(record[13].instances[8]), "ACCGGCTGACGCTAATACGG")
        self.assertEqual(str(record[13].instances[9]), "GCCCCCCGCATAGTAGGGGG")
        self.assertEqual(str(record[13].instances[10]), "GCTGGCAGCGTCTAAGAAGG")
        self.assertEqual(str(record[13].instances[11]), "GCAGGTGGTCGTGCAATACG")
        self.assertEqual(str(record[13].instances[12]), "ACGCACGGGACTTCAACCAG")
        self.assertEqual(str(record[13].instances[13]), "GCACGTAGCTGGTAAATAGG")
        self.assertEqual(str(record[13].instances[14]), "ATCCTCTGCGTCGCATGGCG")
        self.assertEqual(record[13].mask, (1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1))
        self.assertAlmostEqual(record[13].score, 3.89842)
        self.assertEqual(record[14].alphabet, "ACGT")
        self.assertEqual(len(record[14].instances), 14)
        self.assertEqual(str(record[14].instances[0]), "GAGGCTGTGTAT")
        self.assertEqual(str(record[14].instances[1]), "GAGGTCGGGGGT")
        self.assertEqual(str(record[14].instances[2]), "GACGGACGGCAC")
        self.assertEqual(str(record[14].instances[3]), "TTGGCCCGGGAC")
        self.assertEqual(str(record[14].instances[4]), "GAGGCTCGGCCC")
        self.assertEqual(str(record[14].instances[5]), "CACGCGCTGTAT")
        self.assertEqual(str(record[14].instances[6]), "TAGGCCAGGTAT")
        self.assertEqual(str(record[14].instances[7]), "GAGGTCCGGTAC")
        self.assertEqual(str(record[14].instances[8]), "TACGCTGGGGAT")
        self.assertEqual(str(record[14].instances[9]), "GTCGCGGAGGAT")
        self.assertEqual(str(record[14].instances[10]), "TACGCACGGGAC")
        self.assertEqual(str(record[14].instances[11]), "TACTCCGGGTAC")
        self.assertEqual(str(record[14].instances[12]), "GACGCAGAGGAT")
        self.assertEqual(str(record[14].instances[13]), "TAGGCGGGCCAT")
        self.assertEqual(record[14].mask, (1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1))
        self.assertAlmostEqual(record[14].score, 3.33444)
        self.assertEqual(record[15].alphabet, "ACGT")
        self.assertEqual(len(record[15].instances), 21)
        self.assertEqual(str(record[15].instances[0]), "CGGCTCAATCGTAGAGGC")
        self.assertEqual(str(record[15].instances[1]), "CGACGGGTGGTCATCGGG")
        self.assertEqual(str(record[15].instances[2]), "CGCTTAGAGGGCACAAGC")
        self.assertEqual(str(record[15].instances[3]), "TGACACGCGCCTGGGAGG")
        self.assertEqual(str(record[15].instances[4]), "CGATACGCTGCTAAGTGC")
        self.assertEqual(str(record[15].instances[5]), "CGTCCCGGGCCAATAGCG")
        self.assertEqual(str(record[15].instances[6]), "CCACGCTTCGACACGTGG")
        self.assertEqual(str(record[15].instances[7]), "CGTCTGCTGGACAACGGG")
        self.assertEqual(str(record[15].instances[8]), "ACACAGACGGTTGAAAGG")
        self.assertEqual(str(record[15].instances[9]), "TGCTCCCCGCATACAGCG")
        self.assertEqual(str(record[15].instances[10]), "TGAGGCTTGCCCGTACCG")
        self.assertEqual(str(record[15].instances[11]), "TGCCCCAAGCTTACCCAG")
        self.assertEqual(str(record[15].instances[12]), "CGGCTGACGCTAATACGG")
        self.assertEqual(str(record[15].instances[13]), "CGCGACGTCCCTATGAGC")
        self.assertEqual(str(record[15].instances[14]), "TGCCCCCCGCATAGTAGG")
        self.assertEqual(str(record[15].instances[15]), "CGTTGCCTTCTTAGACGC")
        self.assertEqual(str(record[15].instances[16]), "TGACTCAATCGTAGACCC")
        self.assertEqual(str(record[15].instances[17]), "AGTCCCGTGCGTATGTGG")
        self.assertEqual(str(record[15].instances[18]), "AGGCTCGCACGTAGCTGG")
        self.assertEqual(str(record[15].instances[19]), "CCACGCCGCCATGCGACG")
        self.assertEqual(str(record[15].instances[20]), "AGCCTCCAGGTCGCATGG")
        self.assertEqual(record[15].mask, (1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1))
        self.assertAlmostEqual(record[15].score, 1.0395)

    def test_clusterbuster_parsing_and_output(self):
        """Test if Bio.motifs can parse and output Cluster Buster PFM files."""
        record = motifs.parse(self.CLUSTERBUSTERin, "clusterbuster")
        self.assertEqual(len(record), 3)
        self.assertEqual(record[0].name, "MA0004.1")
        self.assertEqual(record[1].name, "MA0006.1")
        self.assertEqual(record[2].name, "MA0008.1")
        self.assertEqual(record[0].degenerate_consensus, "CACGTG")
        self.assertEqual(record[1].degenerate_consensus, "YGCGTG")
        self.assertEqual(record[2].degenerate_consensus, "CAATTATT")

        self.CLUSTERBUSTERin.seek(0)
        self.assertEqual(motifs.write(record, "clusterbuster").split(), self.CLUSTERBUSTERin.read().split())

    def test_xms_parsing(self):
        """Test if Bio.motifs can parse and output xms PFM files."""
        record = motifs.parse(self.XMSin, "xms")
        self.assertEqual(len(record), 1)
        self.assertEqual(record[0].name, "Abd-B")
        self.assertEqual(record[0].length, 14)

    def test_pfm_parsing(self):
        """Test if Bio.motifs can parse JASPAR-style pfm files."""
        m = motifs.read(self.PFMin, "pfm")
        self.assertEqual(m.length, 12)

    def test_sites_parsing(self):
        """Test if Bio.motifs can parse JASPAR-style sites files."""
        m = motifs.read(self.SITESin, "sites")
        self.assertEqual(m.length, 6)

    def test_TFoutput(self):
        """Ensure that we can write proper TransFac output files."""
        with open(self.TFout, "w") as output_handle:
            output_handle.write(format(self.m, "transfac"))

    def test_format(self):
        self.m.name = "Foo"
        s1 = format(self.m, "pfm")
        expected_pfm = """  1.00   0.00   1.00   0.00  1.00
  0.00   0.00   0.00   0.00  0.00
  0.00   0.00   0.00   0.00  0.00
  0.00   1.00   0.00   1.00  0.00
"""
        s2 = format(self.m, "jaspar")
        expected_jaspar = """>None Foo
A [  1.00   0.00   1.00   0.00   1.00]
C [  0.00   0.00   0.00   0.00   0.00]
G [  0.00   0.00   0.00   0.00   0.00]
T [  0.00   1.00   0.00   1.00   0.00]
"""
        self.assertEqual(s2, expected_jaspar)
        s3 = format(self.m, "transfac")
        expected_transfac = """P0      A      C      G      T
01      1      0      0      0      A
02      0      0      0      1      T
03      1      0      0      0      A
04      0      0      0      1      T
05      1      0      0      0      A
XX
//
"""
        self.assertEqual(s3, expected_transfac)
        self.assertRaises(ValueError, format, self.m, "foo_bar")

    def test_reverse_complement(self):
        """Test if motifs can be reverse-complemented."""
        background = {"A": 0.3, "C": 0.2, "G": 0.2, "T": 0.3}
        pseudocounts = 0.5
        m = self.m
        m.background = background
        m.pseudocounts = pseudocounts
        received_forward = format(self.m, "transfac")
        expected_forward = """\
P0      A      C      G      T
01      1      0      0      0      A
02      0      0      0      1      T
03      1      0      0      0      A
04      0      0      0      1      T
05      1      0      0      0      A
XX
//
"""
        self.assertEqual(received_forward, expected_forward)
        expected_forward_pwm = """\
        0      1      2      3      4
A:   0.50   0.17   0.50   0.17   0.50
C:   0.17   0.17   0.17   0.17   0.17
G:   0.17   0.17   0.17   0.17   0.17
T:   0.17   0.50   0.17   0.50   0.17
"""
        self.assertEqual(str(m.pwm), expected_forward_pwm)
        m = m.reverse_complement()
        received_reverse = format(m, "transfac")
        expected_reverse = """\
P0      A      C      G      T
01      0      0      0      1      T
02      1      0      0      0      A
03      0      0      0      1      T
04      1      0      0      0      A
05      0      0      0      1      T
XX
//
"""
        self.assertEqual(received_reverse, expected_reverse)
        expected_reverse_pwm = """\
        0      1      2      3      4
A:   0.17   0.50   0.17   0.50   0.17
C:   0.17   0.17   0.17   0.17   0.17
G:   0.17   0.17   0.17   0.17   0.17
T:   0.50   0.17   0.50   0.17   0.50
"""
        self.assertEqual(str(m.pwm), expected_reverse_pwm)
        # Same thing, but now start with a motif calculated from a count matrix
        counts = self.m.counts
        m = motifs.Motif(counts=counts)
        m.background = background
        m.pseudocounts = pseudocounts
        received_forward = format(m, "transfac")
        self.assertEqual(received_forward, expected_forward)
        self.assertEqual(str(m.pwm), expected_forward_pwm)
        m = m.reverse_complement()
        received_reverse = format(m, "transfac")
        self.assertEqual(received_reverse, expected_reverse)
        self.assertEqual(str(m.pwm), expected_reverse_pwm)


class TestMEME(unittest.TestCase):

    def test_meme_parser_1(self):
        """Parsing motifs/meme.out file."""
        with open("motifs/meme.out") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "3.5.7")
        self.assertEqual(record.datafile, "test.fa")
        self.assertEqual(record.alphabet, "ACGT")
        self.assertEqual(len(record.sequences), 10)
        self.assertEqual(record.sequences[0], "SEQ1;")
        self.assertEqual(record.sequences[1], "SEQ2;")
        self.assertEqual(record.sequences[2], "SEQ3;")
        self.assertEqual(record.sequences[3], "SEQ4;")
        self.assertEqual(record.sequences[4], "SEQ5;")
        self.assertEqual(record.sequences[5], "SEQ6;")
        self.assertEqual(record.sequences[6], "SEQ7;")
        self.assertEqual(record.sequences[7], "SEQ8;")
        self.assertEqual(record.sequences[8], "SEQ9;")
        self.assertEqual(record.sequences[9], "SEQ10;")
        self.assertEqual(record.command, "meme test.fa -dna -w 10 -dir /home/bartek/MetaMotif/meme")
        self.assertEqual(len(record), 1)
        motif = record[0]
        self.assertEqual(motif.name, "Motif 1")
        self.assertEqual(record["Motif 1"], motif)
        self.assertEqual(motif.num_occurrences, 10)
        self.assertAlmostEqual(motif.evalue, 1.1e-22)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 10)
        self.assertAlmostEqual(motif.instances[0].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[1].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[2].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[3].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[4].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[5].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[7].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[8].pvalue, 8.71e-07)
        self.assertAlmostEqual(motif.instances[9].pvalue, 8.71e-07)
        self.assertEqual(motif.instances[0].sequence_name, "SEQ10;")
        self.assertEqual(motif.instances[1].sequence_name, "SEQ9;")
        self.assertEqual(motif.instances[2].sequence_name, "SEQ8;")
        self.assertEqual(motif.instances[3].sequence_name, "SEQ7;")
        self.assertEqual(motif.instances[4].sequence_name, "SEQ6;")
        self.assertEqual(motif.instances[5].sequence_name, "SEQ5;")
        self.assertEqual(motif.instances[6].sequence_name, "SEQ4;")
        self.assertEqual(motif.instances[7].sequence_name, "SEQ3;")
        self.assertEqual(motif.instances[8].sequence_name, "SEQ2;")
        self.assertEqual(motif.instances[9].sequence_name, "SEQ1;")
        self.assertEqual(motif.instances[0].start, 3)
        self.assertEqual(motif.instances[1].start, 93)
        self.assertEqual(motif.instances[2].start, 172)
        self.assertEqual(motif.instances[3].start, 177)
        self.assertEqual(motif.instances[4].start, 105)
        self.assertEqual(motif.instances[5].start, 185)
        self.assertEqual(motif.instances[6].start, 173)
        self.assertEqual(motif.instances[7].start, 112)
        self.assertEqual(motif.instances[8].start, 172)
        self.assertEqual(motif.instances[9].start, 52)
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[7].strand, "+")
        self.assertEqual(motif.instances[8].strand, "+")
        self.assertEqual(motif.instances[9].strand, "+")
        self.assertEqual(motif.instances[0].length, 10)
        self.assertEqual(motif.instances[1].length, 10)
        self.assertEqual(motif.instances[2].length, 10)
        self.assertEqual(motif.instances[3].length, 10)
        self.assertEqual(motif.instances[4].length, 10)
        self.assertEqual(motif.instances[5].length, 10)
        self.assertEqual(motif.instances[6].length, 10)
        self.assertEqual(motif.instances[7].length, 10)
        self.assertEqual(motif.instances[8].length, 10)
        self.assertEqual(motif.instances[9].length, 10)
        self.assertEqual(motif.instances[0].motif_name, "Motif 1")
        self.assertEqual(motif.instances[1].motif_name, "Motif 1")
        self.assertEqual(motif.instances[2].motif_name, "Motif 1")
        self.assertEqual(motif.instances[3].motif_name, "Motif 1")
        self.assertEqual(motif.instances[4].motif_name, "Motif 1")
        self.assertEqual(motif.instances[5].motif_name, "Motif 1")
        self.assertEqual(motif.instances[6].motif_name, "Motif 1")
        self.assertEqual(motif.instances[7].motif_name, "Motif 1")
        self.assertEqual(motif.instances[8].motif_name, "Motif 1")
        self.assertEqual(motif.instances[9].motif_name, "Motif 1")
        self.assertEqual(motif.instances[0].alphabet, "ACGT")
        self.assertEqual(motif.instances[1].alphabet, "ACGT")
        self.assertEqual(motif.instances[2].alphabet, "ACGT")
        self.assertEqual(motif.instances[3].alphabet, "ACGT")
        self.assertEqual(motif.instances[4].alphabet, "ACGT")
        self.assertEqual(motif.instances[5].alphabet, "ACGT")
        self.assertEqual(motif.instances[6].alphabet, "ACGT")
        self.assertEqual(motif.instances[7].alphabet, "ACGT")
        self.assertEqual(motif.instances[8].alphabet, "ACGT")
        self.assertEqual(motif.instances[9].alphabet, "ACGT")
        self.assertEqual(str(motif.instances[0]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[1]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[2]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[3]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[4]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[5]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[6]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[7]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[8]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[9]), "CTCAATCGTA")

    def test_meme_parser_2(self):
        """Parse motifs/meme.dna.oops.txt file."""
        with open("motifs/meme.dna.oops.txt") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "3.0")
        self.assertEqual(record.datafile, "INO_up800.s")
        self.assertEqual(record.alphabet, "ACGT")
        self.assertEqual(len(record.sequences), 7)
        self.assertEqual(record.sequences[0], "CHO1")
        self.assertEqual(record.sequences[1], "CHO2")
        self.assertEqual(record.sequences[2], "FAS1")
        self.assertEqual(record.sequences[3], "FAS2")
        self.assertEqual(record.sequences[4], "ACC1")
        self.assertEqual(record.sequences[5], "INO1")
        self.assertEqual(record.sequences[6], "OPI3")
        self.assertEqual(record.command, "meme -mod oops -dna -revcomp -nmotifs 2 -bfile yeast.nc.6.freq INO_up800.s")
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "Motif 1")
        self.assertEqual(record["Motif 1"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 0.2)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 1.85e-08)
        self.assertAlmostEqual(motif.instances[1].pvalue, 1.85e-08)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.52e-07)
        self.assertAlmostEqual(motif.instances[3].pvalue, 2.52e-07)
        self.assertAlmostEqual(motif.instances[4].pvalue, 4.23e-07)
        self.assertAlmostEqual(motif.instances[5].pvalue, 9.43e-07)
        self.assertAlmostEqual(motif.instances[6].pvalue, 3.32e-06)
        self.assertEqual(motif.instances[0].sequence_name, "INO1")
        self.assertEqual(motif.instances[1].sequence_name, "FAS1")
        self.assertEqual(motif.instances[2].sequence_name, "ACC1")
        self.assertEqual(motif.instances[3].sequence_name, "CHO2")
        self.assertEqual(motif.instances[4].sequence_name, "CHO1")
        self.assertEqual(motif.instances[5].sequence_name, "FAS2")
        self.assertEqual(motif.instances[6].sequence_name, "OPI3")
        self.assertEqual(motif.instances[0].strand, "-")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[0].length, 12)
        self.assertEqual(motif.instances[1].length, 12)
        self.assertEqual(motif.instances[2].length, 12)
        self.assertEqual(motif.instances[3].length, 12)
        self.assertEqual(motif.instances[4].length, 12)
        self.assertEqual(motif.instances[5].length, 12)
        self.assertEqual(motif.instances[6].length, 12)
        self.assertEqual(motif.instances[0].start, 620)
        self.assertEqual(motif.instances[1].start, 95)
        self.assertEqual(motif.instances[2].start, 83)
        self.assertEqual(motif.instances[3].start, 354)
        self.assertEqual(motif.instances[4].start, 611)
        self.assertEqual(motif.instances[5].start, 567)
        self.assertEqual(motif.instances[6].start, 340)
        self.assertEqual(str(motif.instances[0]), "TTCACATGCCGC")
        self.assertEqual(str(motif.instances[1]), "TTCACATGCCGC")
        self.assertEqual(str(motif.instances[2]), "TTCACATGGCCC")
        self.assertEqual(str(motif.instances[3]), "TTCTCATGCCGC")
        self.assertEqual(str(motif.instances[4]), "TTCACACGGCAC")
        self.assertEqual(str(motif.instances[5]), "TTCACATGCTAC")
        self.assertEqual(str(motif.instances[6]), "TTCAGATCGCTC")
        motif = record[1]
        self.assertEqual(motif.name, "Motif 2")
        self.assertEqual(record["Motif 2"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 110)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 3.24e-07)
        self.assertAlmostEqual(motif.instances[1].pvalue, 3.24e-07)
        self.assertAlmostEqual(motif.instances[2].pvalue, 3.24e-07)
        self.assertAlmostEqual(motif.instances[3].pvalue, 5.29e-06)
        self.assertAlmostEqual(motif.instances[4].pvalue, 6.25e-06)
        self.assertAlmostEqual(motif.instances[5].pvalue, 8.48e-06)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.48e-06)
        self.assertEqual(motif.instances[0].sequence_name, "OPI3")
        self.assertEqual(motif.instances[1].sequence_name, "ACC1")
        self.assertEqual(motif.instances[2].sequence_name, "CHO1")
        self.assertEqual(motif.instances[3].sequence_name, "INO1")
        self.assertEqual(motif.instances[4].sequence_name, "FAS1")
        self.assertEqual(motif.instances[5].sequence_name, "FAS2")
        self.assertEqual(motif.instances[6].sequence_name, "CHO2")
        self.assertEqual(motif.instances[0].strand, "-")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "-")
        self.assertEqual(motif.instances[3].strand, "-")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "-")
        self.assertEqual(motif.instances[6].strand, "-")
        self.assertEqual(motif.instances[0].length, 10)
        self.assertEqual(motif.instances[1].length, 10)
        self.assertEqual(motif.instances[2].length, 10)
        self.assertEqual(motif.instances[3].length, 10)
        self.assertEqual(motif.instances[4].length, 10)
        self.assertEqual(motif.instances[5].length, 10)
        self.assertEqual(motif.instances[6].length, 10)
        self.assertEqual(motif.instances[0].start, 186)
        self.assertEqual(motif.instances[1].start, 232)
        self.assertEqual(motif.instances[2].start, 559)
        self.assertEqual(motif.instances[3].start, 283)
        self.assertEqual(motif.instances[4].start, 44)
        self.assertEqual(motif.instances[5].start, 185)
        self.assertEqual(motif.instances[6].start, 413)
        self.assertEqual(str(motif.instances[0]), "TCTGGCACAG")
        self.assertEqual(str(motif.instances[1]), "TCTGGCACAG")
        self.assertEqual(str(motif.instances[2]), "TCTGGCACAG")
        self.assertEqual(str(motif.instances[3]), "GCGGGCGCAG")
        self.assertEqual(str(motif.instances[4]), "GCAGGCACGG")
        self.assertEqual(str(motif.instances[5]), "TCTGGCACTC")
        self.assertEqual(str(motif.instances[6]), "TCTGGCATCG")

    def test_meme_parser_3(self):
        """Parse motifs/meme.protein.oops.txt file."""
        with open("motifs/meme.protein.oops.txt") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "3.0")
        self.assertEqual(record.datafile, "adh.s")
        self.assertEqual(record.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(record.sequences), 33)
        self.assertEqual(record.sequences[0], "2BHD_STREX")
        self.assertEqual(record.sequences[1], "3BHD_COMTE")
        self.assertEqual(record.sequences[2], "ADH_DROME")
        self.assertEqual(record.sequences[3], "AP27_MOUSE")
        self.assertEqual(record.sequences[4], "BA72_EUBSP")
        self.assertEqual(record.sequences[5], "BDH_HUMAN")
        self.assertEqual(record.sequences[6], "BPHB_PSEPS")
        self.assertEqual(record.sequences[7], "BUDC_KLETE")
        self.assertEqual(record.sequences[8], "DHES_HUMAN")
        self.assertEqual(record.sequences[9], "DHGB_BACME")
        self.assertEqual(record.sequences[10], "DHII_HUMAN")
        self.assertEqual(record.sequences[11], "DHMA_FLAS1")
        self.assertEqual(record.sequences[12], "ENTA_ECOLI")
        self.assertEqual(record.sequences[13], "FIXR_BRAJA")
        self.assertEqual(record.sequences[14], "GUTD_ECOLI")
        self.assertEqual(record.sequences[15], "HDE_CANTR")
        self.assertEqual(record.sequences[16], "HDHA_ECOLI")
        self.assertEqual(record.sequences[17], "LIGD_PSEPA")
        self.assertEqual(record.sequences[18], "NODG_RHIME")
        self.assertEqual(record.sequences[19], "RIDH_KLEAE")
        self.assertEqual(record.sequences[20], "YINL_LISMO")
        self.assertEqual(record.sequences[21], "YRTP_BACSU")
        self.assertEqual(record.sequences[22], "CSGA_MYXXA")
        self.assertEqual(record.sequences[23], "DHB2_HUMAN")
        self.assertEqual(record.sequences[24], "DHB3_HUMAN")
        self.assertEqual(record.sequences[25], "DHCA_HUMAN")
        self.assertEqual(record.sequences[26], "FABI_ECOLI")
        self.assertEqual(record.sequences[27], "FVT1_HUMAN")
        self.assertEqual(record.sequences[28], "HMTR_LEIMA")
        self.assertEqual(record.sequences[29], "MAS1_AGRRA")
        self.assertEqual(record.sequences[30], "PCR_PEA")
        self.assertEqual(record.sequences[31], "RFBB_NEIGO")
        self.assertEqual(record.sequences[32], "YURA_MYXXA")
        self.assertEqual(record.command, "meme adh.s -mod oops -protein -nmotifs 2")
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "Motif 1")
        self.assertEqual(record["Motif 1"], motif)
        self.assertEqual(motif.num_occurrences, 33)
        self.assertAlmostEqual(motif.evalue, 3.6e-165)
        self.assertEqual(motif.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(motif.instances), 33)
        self.assertAlmostEqual(motif.instances[0].pvalue, 1.64e-22)
        self.assertAlmostEqual(motif.instances[1].pvalue, 6.32e-22)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.13e-21)
        self.assertAlmostEqual(motif.instances[3].pvalue, 4.04e-21)
        self.assertAlmostEqual(motif.instances[4].pvalue, 6.12e-21)
        self.assertAlmostEqual(motif.instances[5].pvalue, 7.52e-20)
        self.assertAlmostEqual(motif.instances[6].pvalue, 3.35e-19)
        self.assertAlmostEqual(motif.instances[7].pvalue, 4.82e-19)
        self.assertAlmostEqual(motif.instances[8].pvalue, 4.82e-19)
        self.assertAlmostEqual(motif.instances[9].pvalue, 1.11e-18)
        self.assertAlmostEqual(motif.instances[10].pvalue, 1.25e-18)
        self.assertAlmostEqual(motif.instances[11].pvalue, 2.23e-18)
        self.assertAlmostEqual(motif.instances[12].pvalue, 5.53e-18)
        self.assertAlmostEqual(motif.instances[13].pvalue, 9.65e-18)
        self.assertAlmostEqual(motif.instances[14].pvalue, 2.86e-17)
        self.assertAlmostEqual(motif.instances[15].pvalue, 8.20e-17)
        self.assertAlmostEqual(motif.instances[16].pvalue, 9.09e-17)
        self.assertAlmostEqual(motif.instances[17].pvalue, 1.37e-16)
        self.assertAlmostEqual(motif.instances[18].pvalue, 2.52e-16)
        self.assertAlmostEqual(motif.instances[19].pvalue, 1.21e-15)
        self.assertAlmostEqual(motif.instances[20].pvalue, 1.61e-15)
        self.assertAlmostEqual(motif.instances[21].pvalue, 1.77e-15)
        self.assertAlmostEqual(motif.instances[22].pvalue, 7.81e-15)
        self.assertAlmostEqual(motif.instances[23].pvalue, 8.55e-15)
        self.assertAlmostEqual(motif.instances[24].pvalue, 1.47e-14)
        self.assertAlmostEqual(motif.instances[25].pvalue, 3.24e-14)
        self.assertAlmostEqual(motif.instances[26].pvalue, 1.80e-12)
        self.assertAlmostEqual(motif.instances[27].pvalue, 2.10e-12)
        self.assertAlmostEqual(motif.instances[28].pvalue, 4.15e-12)
        self.assertAlmostEqual(motif.instances[29].pvalue, 5.20e-12)
        self.assertAlmostEqual(motif.instances[30].pvalue, 4.80e-10)
        self.assertAlmostEqual(motif.instances[31].pvalue, 2.77e-08)
        self.assertAlmostEqual(motif.instances[32].pvalue, 5.72e-08)
        self.assertEqual(motif.instances[0].sequence_name, "YRTP_BACSU")
        self.assertEqual(motif.instances[1].sequence_name, "AP27_MOUSE")
        self.assertEqual(motif.instances[2].sequence_name, "NODG_RHIME")
        self.assertEqual(motif.instances[3].sequence_name, "BUDC_KLETE")
        self.assertEqual(motif.instances[4].sequence_name, "FIXR_BRAJA")
        self.assertEqual(motif.instances[5].sequence_name, "DHGB_BACME")
        self.assertEqual(motif.instances[6].sequence_name, "HMTR_LEIMA")
        self.assertEqual(motif.instances[7].sequence_name, "YURA_MYXXA")
        self.assertEqual(motif.instances[8].sequence_name, "GUTD_ECOLI")
        self.assertEqual(motif.instances[9].sequence_name, "2BHD_STREX")
        self.assertEqual(motif.instances[10].sequence_name, "HDHA_ECOLI")
        self.assertEqual(motif.instances[11].sequence_name, "DHB2_HUMAN")
        self.assertEqual(motif.instances[12].sequence_name, "DHMA_FLAS1")
        self.assertEqual(motif.instances[13].sequence_name, "HDE_CANTR")
        self.assertEqual(motif.instances[14].sequence_name, "FVT1_HUMAN")
        self.assertEqual(motif.instances[15].sequence_name, "BDH_HUMAN")
        self.assertEqual(motif.instances[16].sequence_name, "RIDH_KLEAE")
        self.assertEqual(motif.instances[17].sequence_name, "DHES_HUMAN")
        self.assertEqual(motif.instances[18].sequence_name, "BA72_EUBSP")
        self.assertEqual(motif.instances[19].sequence_name, "LIGD_PSEPA")
        self.assertEqual(motif.instances[20].sequence_name, "DHII_HUMAN")
        self.assertEqual(motif.instances[21].sequence_name, "ENTA_ECOLI")
        self.assertEqual(motif.instances[22].sequence_name, "3BHD_COMTE")
        self.assertEqual(motif.instances[23].sequence_name, "DHB3_HUMAN")
        self.assertEqual(motif.instances[24].sequence_name, "RFBB_NEIGO")
        self.assertEqual(motif.instances[25].sequence_name, "YINL_LISMO")
        self.assertEqual(motif.instances[26].sequence_name, "BPHB_PSEPS")
        self.assertEqual(motif.instances[27].sequence_name, "CSGA_MYXXA")
        self.assertEqual(motif.instances[28].sequence_name, "FABI_ECOLI")
        self.assertEqual(motif.instances[29].sequence_name, "ADH_DROME")
        self.assertEqual(motif.instances[30].sequence_name, "DHCA_HUMAN")
        self.assertEqual(motif.instances[31].sequence_name, "PCR_PEA")
        self.assertEqual(motif.instances[32].sequence_name, "MAS1_AGRRA")
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[7].strand, "+")
        self.assertEqual(motif.instances[8].strand, "+")
        self.assertEqual(motif.instances[9].strand, "+")
        self.assertEqual(motif.instances[10].strand, "+")
        self.assertEqual(motif.instances[11].strand, "+")
        self.assertEqual(motif.instances[12].strand, "+")
        self.assertEqual(motif.instances[13].strand, "+")
        self.assertEqual(motif.instances[14].strand, "+")
        self.assertEqual(motif.instances[15].strand, "+")
        self.assertEqual(motif.instances[16].strand, "+")
        self.assertEqual(motif.instances[17].strand, "+")
        self.assertEqual(motif.instances[18].strand, "+")
        self.assertEqual(motif.instances[19].strand, "+")
        self.assertEqual(motif.instances[20].strand, "+")
        self.assertEqual(motif.instances[21].strand, "+")
        self.assertEqual(motif.instances[22].strand, "+")
        self.assertEqual(motif.instances[23].strand, "+")
        self.assertEqual(motif.instances[24].strand, "+")
        self.assertEqual(motif.instances[25].strand, "+")
        self.assertEqual(motif.instances[26].strand, "+")
        self.assertEqual(motif.instances[27].strand, "+")
        self.assertEqual(motif.instances[28].strand, "+")
        self.assertEqual(motif.instances[29].strand, "+")
        self.assertEqual(motif.instances[30].strand, "+")
        self.assertEqual(motif.instances[31].strand, "+")
        self.assertEqual(motif.instances[32].strand, "+")
        self.assertEqual(motif.instances[0].length, 29)
        self.assertEqual(motif.instances[1].length, 29)
        self.assertEqual(motif.instances[2].length, 29)
        self.assertEqual(motif.instances[3].length, 29)
        self.assertEqual(motif.instances[4].length, 29)
        self.assertEqual(motif.instances[5].length, 29)
        self.assertEqual(motif.instances[6].length, 29)
        self.assertEqual(motif.instances[7].length, 29)
        self.assertEqual(motif.instances[8].length, 29)
        self.assertEqual(motif.instances[9].length, 29)
        self.assertEqual(motif.instances[10].length, 29)
        self.assertEqual(motif.instances[11].length, 29)
        self.assertEqual(motif.instances[12].length, 29)
        self.assertEqual(motif.instances[13].length, 29)
        self.assertEqual(motif.instances[14].length, 29)
        self.assertEqual(motif.instances[15].length, 29)
        self.assertEqual(motif.instances[16].length, 29)
        self.assertEqual(motif.instances[17].length, 29)
        self.assertEqual(motif.instances[18].length, 29)
        self.assertEqual(motif.instances[19].length, 29)
        self.assertEqual(motif.instances[20].length, 29)
        self.assertEqual(motif.instances[21].length, 29)
        self.assertEqual(motif.instances[22].length, 29)
        self.assertEqual(motif.instances[23].length, 29)
        self.assertEqual(motif.instances[24].length, 29)
        self.assertEqual(motif.instances[25].length, 29)
        self.assertEqual(motif.instances[26].length, 29)
        self.assertEqual(motif.instances[27].length, 29)
        self.assertEqual(motif.instances[28].length, 29)
        self.assertEqual(motif.instances[29].length, 29)
        self.assertEqual(motif.instances[30].length, 29)
        self.assertEqual(motif.instances[31].length, 29)
        self.assertEqual(motif.instances[32].length, 29)
        self.assertEqual(motif.instances[0].start, 155)
        self.assertEqual(motif.instances[1].start, 149)
        self.assertEqual(motif.instances[2].start, 152)
        self.assertEqual(motif.instances[3].start, 152)
        self.assertEqual(motif.instances[4].start, 189)
        self.assertEqual(motif.instances[5].start, 160)
        self.assertEqual(motif.instances[6].start, 193)
        self.assertEqual(motif.instances[7].start, 160)
        self.assertEqual(motif.instances[8].start, 154)
        self.assertEqual(motif.instances[9].start, 152)
        self.assertEqual(motif.instances[10].start, 159)
        self.assertEqual(motif.instances[11].start, 232)
        self.assertEqual(motif.instances[12].start, 165)
        self.assertEqual(motif.instances[13].start, 467)
        self.assertEqual(motif.instances[14].start, 186)
        self.assertEqual(motif.instances[15].start, 208)
        self.assertEqual(motif.instances[16].start, 160)
        self.assertEqual(motif.instances[17].start, 155)
        self.assertEqual(motif.instances[18].start, 157)
        self.assertEqual(motif.instances[19].start, 157)
        self.assertEqual(motif.instances[20].start, 183)
        self.assertEqual(motif.instances[21].start, 144)
        self.assertEqual(motif.instances[22].start, 151)
        self.assertEqual(motif.instances[23].start, 198)
        self.assertEqual(motif.instances[24].start, 165)
        self.assertEqual(motif.instances[25].start, 154)
        self.assertEqual(motif.instances[26].start, 153)
        self.assertEqual(motif.instances[27].start, 88)
        self.assertEqual(motif.instances[28].start, 159)
        self.assertEqual(motif.instances[29].start, 152)
        self.assertEqual(motif.instances[30].start, 193)
        self.assertEqual(motif.instances[31].start, 26)
        self.assertEqual(motif.instances[32].start, 349)
        self.assertEqual(str(motif.instances[0]), "YSASKFAVLGLTESLMQEVRKHNIRVSAL")
        self.assertEqual(str(motif.instances[1]), "YSSTKGAMTMLTKAMAMELGPHKIRVNSV")
        self.assertEqual(str(motif.instances[2]), "YCASKAGMIGFSKSLAQEIATRNITVNCV")
        self.assertEqual(str(motif.instances[3]), "YSSSKFAVRGLTQTAARDLAPLGITVNGF")
        self.assertEqual(str(motif.instances[4]), "YATSKAALASLTRELAHDYAPHGIRVNAI")
        self.assertEqual(str(motif.instances[5]), "YAASKGGMKLMTETLALEYAPKGIRVNNI")
        self.assertEqual(str(motif.instances[6]), "YTMAKGALEGLTRSAALELAPLQIRVNGV")
        self.assertEqual(str(motif.instances[7]), "YSASKAFLSTFMESLRVDLRGTGVRVTCI")
        self.assertEqual(str(motif.instances[8]), "YSAAKFGGVGLTQSLALDLAEYGITVHSL")
        self.assertEqual(str(motif.instances[9]), "YGASKWGVRGLSKLAAVELGTDRIRVNSV")
        self.assertEqual(str(motif.instances[10]), "YASSKAAASHLVRNMAFDLGEKNIRVNGI")
        self.assertEqual(str(motif.instances[11]), "YGSSKAAVTMFSSVMRLELSKWGIKVASI")
        self.assertEqual(str(motif.instances[12]), "YVAAKGGVAMLTRAMAVDLARHGILVNMI")
        self.assertEqual(str(motif.instances[13]), "YSSSKAGILGLSKTMAIEGAKNNIKVNIV")
        self.assertEqual(str(motif.instances[14]), "YSASKFAIRGLAEALQMEVKPYNVYITVA")
        self.assertEqual(str(motif.instances[15]), "YCITKFGVEAFSDCLRYEMYPLGVKVSVV")
        self.assertEqual(str(motif.instances[16]), "YTASKFAVQAFVHTTRRQVAQYGVRVGAV")
        self.assertEqual(str(motif.instances[17]), "YCASKFALEGLCESLAVLLLPFGVHLSLI")
        self.assertEqual(str(motif.instances[18]), "YPASKASVIGLTHGLGREIIRKNIRVVGV")
        self.assertEqual(str(motif.instances[19]), "YSAAKAASINLMEGYRQGLEKYGIGVSVC")
        self.assertEqual(str(motif.instances[20]), "YSASKFALDGFFSSIRKEYSVSRVNVSIT")
        self.assertEqual(str(motif.instances[21]), "YGASKAALKSLALSVGLELAGSGVRCNVV")
        self.assertEqual(str(motif.instances[22]), "YSASKAAVSALTRAAALSCRKQGYAIRVN")
        self.assertEqual(str(motif.instances[23]), "YSASKAFVCAFSKALQEEYKAKEVIIQVL")
        self.assertEqual(str(motif.instances[24]), "YSASKAAADHLVRAWQRTYRLPSIVSNCS")
        self.assertEqual(str(motif.instances[25]), "YGATKWAVRDLMEVLRMESAQEGTNIRTA")
        self.assertEqual(str(motif.instances[26]), "YTAAKQAIVGLVRELAFELAPYVRVNGVG")
        self.assertEqual(str(motif.instances[27]), "YRMSKAALNMAVRSMSTDLRPEGFVTVLL")
        self.assertEqual(str(motif.instances[28]), "MGLAKASLEANVRYMANAMGPEGVRVNAI")
        self.assertEqual(str(motif.instances[29]), "YSGTKAAVVNFTSSLAKLAPITGVTAYTV")
        self.assertEqual(str(motif.instances[30]), "YGVTKIGVTVLSRIHARKLSEQRKGDKIL")
        self.assertEqual(str(motif.instances[31]), "KDSTLFGVSSLSDSLKGDFTSSALRCKEL")
        self.assertEqual(str(motif.instances[32]), "YINCVAPLRMTELCLPHLYETGSGRIVNI")
        motif = record[1]
        self.assertEqual(motif.name, "Motif 2")
        self.assertEqual(record["Motif 2"], motif)
        self.assertEqual(motif.num_occurrences, 33)
        self.assertAlmostEqual(motif.evalue, 2.3e-159)
        self.assertEqual(motif.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(motif.instances), 33)
        self.assertAlmostEqual(motif.instances[0].pvalue, 2.44e-23)
        self.assertAlmostEqual(motif.instances[1].pvalue, 5.50e-23)
        self.assertAlmostEqual(motif.instances[2].pvalue, 5.38e-22)
        self.assertAlmostEqual(motif.instances[3].pvalue, 5.65e-20)
        self.assertAlmostEqual(motif.instances[4].pvalue, 1.17e-19)
        self.assertAlmostEqual(motif.instances[5].pvalue, 1.17e-19)
        self.assertAlmostEqual(motif.instances[6].pvalue, 4.74e-19)
        self.assertAlmostEqual(motif.instances[7].pvalue, 9.31e-19)
        self.assertAlmostEqual(motif.instances[8].pvalue, 2.50e-18)
        self.assertAlmostEqual(motif.instances[9].pvalue, 3.45e-18)
        self.assertAlmostEqual(motif.instances[10].pvalue, 5.86e-18)
        self.assertAlmostEqual(motif.instances[11].pvalue, 9.86e-18)
        self.assertAlmostEqual(motif.instances[12].pvalue, 2.47e-17)
        self.assertAlmostEqual(motif.instances[13].pvalue, 3.01e-17)
        self.assertAlmostEqual(motif.instances[14].pvalue, 3.33e-17)
        self.assertAlmostEqual(motif.instances[15].pvalue, 4.06e-17)
        self.assertAlmostEqual(motif.instances[16].pvalue, 4.06e-17)
        self.assertAlmostEqual(motif.instances[17].pvalue, 8.05e-17)
        self.assertAlmostEqual(motif.instances[18].pvalue, 1.90e-16)
        self.assertAlmostEqual(motif.instances[19].pvalue, 2.77e-16)
        self.assertAlmostEqual(motif.instances[20].pvalue, 3.65e-16)
        self.assertAlmostEqual(motif.instances[21].pvalue, 8.31e-16)
        self.assertAlmostEqual(motif.instances[22].pvalue, 4.05e-15)
        self.assertAlmostEqual(motif.instances[23].pvalue, 5.24e-15)
        self.assertAlmostEqual(motif.instances[24].pvalue, 3.00e-14)
        self.assertAlmostEqual(motif.instances[25].pvalue, 8.47e-14)
        self.assertAlmostEqual(motif.instances[26].pvalue, 1.46e-13)
        self.assertAlmostEqual(motif.instances[27].pvalue, 1.46e-13)
        self.assertAlmostEqual(motif.instances[28].pvalue, 1.59e-12)
        self.assertAlmostEqual(motif.instances[29].pvalue, 6.97e-10)
        self.assertAlmostEqual(motif.instances[30].pvalue, 3.15e-09)
        self.assertAlmostEqual(motif.instances[31].pvalue, 2.77e-07)
        self.assertAlmostEqual(motif.instances[32].pvalue, 4.24e-07)
        self.assertEqual(motif.instances[0].sequence_name, "HDE_CANTR")
        self.assertEqual(motif.instances[1].sequence_name, "DHII_HUMAN")
        self.assertEqual(motif.instances[2].sequence_name, "YINL_LISMO")
        self.assertEqual(motif.instances[3].sequence_name, "HDHA_ECOLI")
        self.assertEqual(motif.instances[4].sequence_name, "RIDH_KLEAE")
        self.assertEqual(motif.instances[5].sequence_name, "BUDC_KLETE")
        self.assertEqual(motif.instances[6].sequence_name, "ENTA_ECOLI")
        self.assertEqual(motif.instances[7].sequence_name, "AP27_MOUSE")
        self.assertEqual(motif.instances[8].sequence_name, "DHMA_FLAS1")
        self.assertEqual(motif.instances[9].sequence_name, "YRTP_BACSU")
        self.assertEqual(motif.instances[10].sequence_name, "DHGB_BACME")
        self.assertEqual(motif.instances[11].sequence_name, "DHB3_HUMAN")
        self.assertEqual(motif.instances[12].sequence_name, "PCR_PEA")
        self.assertEqual(motif.instances[13].sequence_name, "BDH_HUMAN")
        self.assertEqual(motif.instances[14].sequence_name, "BA72_EUBSP")
        self.assertEqual(motif.instances[15].sequence_name, "FIXR_BRAJA")
        self.assertEqual(motif.instances[16].sequence_name, "3BHD_COMTE")
        self.assertEqual(motif.instances[17].sequence_name, "2BHD_STREX")
        self.assertEqual(motif.instances[18].sequence_name, "HMTR_LEIMA")
        self.assertEqual(motif.instances[19].sequence_name, "FVT1_HUMAN")
        self.assertEqual(motif.instances[20].sequence_name, "DHB2_HUMAN")
        self.assertEqual(motif.instances[21].sequence_name, "LIGD_PSEPA")
        self.assertEqual(motif.instances[22].sequence_name, "NODG_RHIME")
        self.assertEqual(motif.instances[23].sequence_name, "DHCA_HUMAN")
        self.assertEqual(motif.instances[24].sequence_name, "MAS1_AGRRA")
        self.assertEqual(motif.instances[25].sequence_name, "BPHB_PSEPS")
        self.assertEqual(motif.instances[26].sequence_name, "GUTD_ECOLI")
        self.assertEqual(motif.instances[27].sequence_name, "DHES_HUMAN")
        self.assertEqual(motif.instances[28].sequence_name, "RFBB_NEIGO")
        self.assertEqual(motif.instances[29].sequence_name, "ADH_DROME")
        self.assertEqual(motif.instances[30].sequence_name, "FABI_ECOLI")
        self.assertEqual(motif.instances[31].sequence_name, "YURA_MYXXA")
        self.assertEqual(motif.instances[32].sequence_name, "CSGA_MYXXA")
        self.assertEqual(motif.instances[0].start, 323)
        self.assertEqual(motif.instances[1].start, 35)
        self.assertEqual(motif.instances[2].start, 6)
        self.assertEqual(motif.instances[3].start, 12)
        self.assertEqual(motif.instances[4].start, 15)
        self.assertEqual(motif.instances[5].start, 3)
        self.assertEqual(motif.instances[6].start, 6)
        self.assertEqual(motif.instances[7].start, 8)
        self.assertEqual(motif.instances[8].start, 15)
        self.assertEqual(motif.instances[9].start, 7)
        self.assertEqual(motif.instances[10].start, 8)
        self.assertEqual(motif.instances[11].start, 49)
        self.assertEqual(motif.instances[12].start, 87)
        self.assertEqual(motif.instances[13].start, 56)
        self.assertEqual(motif.instances[14].start, 7)
        self.assertEqual(motif.instances[15].start, 37)
        self.assertEqual(motif.instances[16].start, 7)
        self.assertEqual(motif.instances[17].start, 7)
        self.assertEqual(motif.instances[18].start, 7)
        self.assertEqual(motif.instances[19].start, 33)
        self.assertEqual(motif.instances[20].start, 83)
        self.assertEqual(motif.instances[21].start, 7)
        self.assertEqual(motif.instances[22].start, 7)
        self.assertEqual(motif.instances[23].start, 5)
        self.assertEqual(motif.instances[24].start, 246)
        self.assertEqual(motif.instances[25].start, 6)
        self.assertEqual(motif.instances[26].start, 3)
        self.assertEqual(motif.instances[27].start, 3)
        self.assertEqual(motif.instances[28].start, 7)
        self.assertEqual(motif.instances[29].start, 7)
        self.assertEqual(motif.instances[30].start, 7)
        self.assertEqual(motif.instances[31].start, 117)
        self.assertEqual(motif.instances[32].start, 52)
        self.assertEqual(str(motif.instances[0]), "KVVLITGAGAGLGKEYAKWFAKYGAKVVV")
        self.assertEqual(str(motif.instances[1]), "KKVIVTGASKGIGREMAYHLAKMGAHVVV")
        self.assertEqual(str(motif.instances[2]), "KVIIITGASSGIGKATALLLAEKGAKLVL")
        self.assertEqual(str(motif.instances[3]), "KCAIITGAGAGIGKEIAITFATAGASVVV")
        self.assertEqual(str(motif.instances[4]), "KVAAITGAASGIGLECARTLLGAGAKVVL")
        self.assertEqual(str(motif.instances[5]), "KVALVTGAGQGIGKAIALRLVKDGFAVAI")
        self.assertEqual(str(motif.instances[6]), "KNVWVTGAGKGIGYATALAFVEAGAKVTG")
        self.assertEqual(str(motif.instances[7]), "LRALVTGAGKGIGRDTVKALHASGAKVVA")
        self.assertEqual(str(motif.instances[8]), "KAAIVTGAAGGIGRATVEAYLREGASVVA")
        self.assertEqual(str(motif.instances[9]), "KTALITGGGRGIGRATALALAKEGVNIGL")
        self.assertEqual(str(motif.instances[10]), "KVVVITGSSTGLGKSMAIRFATEKAKVVV")
        self.assertEqual(str(motif.instances[11]), "QWAVITGAGDGIGKAYSFELAKRGLNVVL")
        self.assertEqual(str(motif.instances[12]), "GNVVITGASSGLGLATAKALAESGKWHVI")
        self.assertEqual(str(motif.instances[13]), "KAVLVTGCDSGFGFSLAKHLHSKGFLVFA")
        self.assertEqual(str(motif.instances[14]), "KVTIITGGTRGIGFAAAKIFIDNGAKVSI")
        self.assertEqual(str(motif.instances[15]), "KVMLLTGASRGIGHATAKLFSEAGWRIIS")
        self.assertEqual(str(motif.instances[16]), "KVALVTGGASGVGLEVVKLLLGEGAKVAF")
        self.assertEqual(str(motif.instances[17]), "KTVIITGGARGLGAEAARQAVAAGARVVL")
        self.assertEqual(str(motif.instances[18]), "PVALVTGAAKRLGRSIAEGLHAEGYAVCL")
        self.assertEqual(str(motif.instances[19]), "AHVVVTGGSSGIGKCIAIECYKQGAFITL")
        self.assertEqual(str(motif.instances[20]), "KAVLVTGGDCGLGHALCKYLDELGFTVFA")
        self.assertEqual(str(motif.instances[21]), "QVAFITGGASGAGFGQAKVFGQAGAKIVV")
        self.assertEqual(str(motif.instances[22]), "RKALVTGASGAIGGAIARVLHAQGAIVGL")
        self.assertEqual(str(motif.instances[23]), "HVALVTGGNKGIGLAIVRDLCRLFSGDVV")
        self.assertEqual(str(motif.instances[24]), "PVILVSGSNRGVGKAIAEDLIAHGYRLSL")
        self.assertEqual(str(motif.instances[25]), "EAVLITGGASGLGRALVDRFVAEAKVAVL")
        self.assertEqual(str(motif.instances[26]), "QVAVVIGGGQTLGAFLCHGLAAEGYRVAV")
        self.assertEqual(str(motif.instances[27]), "TVVLITGCSSGIGLHLAVRLASDPSQSFK")
        self.assertEqual(str(motif.instances[28]), "KNILVTGGAGFIGSAVVRHIIQNTRDSVV")
        self.assertEqual(str(motif.instances[29]), "KNVIFVAGLGGIGLDTSKELLKRDLKNLV")
        self.assertEqual(str(motif.instances[30]), "KRILVTGVASKLSIAYGIAQAMHREGAEL")
        self.assertEqual(str(motif.instances[31]), "IDTNVTGAAATLSAVLPQMVERKRGHLVG")
        self.assertEqual(str(motif.instances[32]), "TSAMLPGLRQGALRRVAHVTSRMGSLAAN")

    def test_meme_parser_4(self):
        """Parse motifs/meme.protein.tcm.txt file."""
        with open("motifs/meme.protein.tcm.txt") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "3.0")
        self.assertEqual(record.datafile, "farntrans5.s")
        self.assertEqual(record.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(record.sequences), 5)
        self.assertEqual(record.sequences[0], "RAM1_YEAST")
        self.assertEqual(record.sequences[1], "PFTB_RAT")
        self.assertEqual(record.sequences[2], "BET2_YEAST")
        self.assertEqual(record.sequences[3], "RATRABGERB")
        self.assertEqual(record.sequences[4], "CAL1_YEAST")
        self.assertEqual(record.command, "meme farntrans5.s -mod tcm -protein -nmotifs 2")
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "Motif 1")
        self.assertEqual(record["Motif 1"], motif)
        self.assertEqual(motif.num_occurrences, 24)
        self.assertAlmostEqual(motif.evalue, 2.2e-94)
        self.assertEqual(motif.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(motif.instances), 24)
        self.assertAlmostEqual(motif.instances[0].pvalue, 7.28e-22)
        self.assertAlmostEqual(motif.instances[1].pvalue, 6.18e-21)
        self.assertAlmostEqual(motif.instances[2].pvalue, 9.17e-20)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.15e-19)
        self.assertAlmostEqual(motif.instances[4].pvalue, 4.30e-19)
        self.assertAlmostEqual(motif.instances[5].pvalue, 7.36e-19)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.19e-19)
        self.assertAlmostEqual(motif.instances[7].pvalue, 2.10e-18)
        self.assertAlmostEqual(motif.instances[8].pvalue, 1.43e-17)
        self.assertAlmostEqual(motif.instances[9].pvalue, 3.41e-17)
        self.assertAlmostEqual(motif.instances[10].pvalue, 5.00e-17)
        self.assertAlmostEqual(motif.instances[11].pvalue, 6.64e-17)
        self.assertAlmostEqual(motif.instances[12].pvalue, 1.27e-16)
        self.assertAlmostEqual(motif.instances[13].pvalue, 3.17e-16)
        self.assertAlmostEqual(motif.instances[14].pvalue, 3.47e-16)
        self.assertAlmostEqual(motif.instances[15].pvalue, 4.30e-15)
        self.assertAlmostEqual(motif.instances[16].pvalue, 2.40e-14)
        self.assertAlmostEqual(motif.instances[17].pvalue, 2.81e-14)
        self.assertAlmostEqual(motif.instances[18].pvalue, 7.78e-14)
        self.assertAlmostEqual(motif.instances[19].pvalue, 1.14e-13)
        self.assertAlmostEqual(motif.instances[20].pvalue, 1.33e-13)
        self.assertAlmostEqual(motif.instances[21].pvalue, 3.52e-13)
        self.assertAlmostEqual(motif.instances[22].pvalue, 5.47e-13)
        self.assertAlmostEqual(motif.instances[23].pvalue, 3.11e-10)
        self.assertEqual(motif.instances[0].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[1].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[2].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[3].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[4].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[5].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[6].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[7].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[8].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[9].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[10].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[11].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[12].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[13].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[14].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[15].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[16].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[17].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[18].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[19].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[20].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[21].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[22].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[23].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[7].strand, "+")
        self.assertEqual(motif.instances[8].strand, "+")
        self.assertEqual(motif.instances[9].strand, "+")
        self.assertEqual(motif.instances[10].strand, "+")
        self.assertEqual(motif.instances[11].strand, "+")
        self.assertEqual(motif.instances[12].strand, "+")
        self.assertEqual(motif.instances[13].strand, "+")
        self.assertEqual(motif.instances[14].strand, "+")
        self.assertEqual(motif.instances[15].strand, "+")
        self.assertEqual(motif.instances[16].strand, "+")
        self.assertEqual(motif.instances[17].strand, "+")
        self.assertEqual(motif.instances[18].strand, "+")
        self.assertEqual(motif.instances[19].strand, "+")
        self.assertEqual(motif.instances[20].strand, "+")
        self.assertEqual(motif.instances[21].strand, "+")
        self.assertEqual(motif.instances[22].strand, "+")
        self.assertEqual(motif.instances[23].strand, "+")
        self.assertEqual(motif.instances[0].length, 30)
        self.assertEqual(motif.instances[1].length, 30)
        self.assertEqual(motif.instances[2].length, 30)
        self.assertEqual(motif.instances[3].length, 30)
        self.assertEqual(motif.instances[4].length, 30)
        self.assertEqual(motif.instances[5].length, 30)
        self.assertEqual(motif.instances[6].length, 30)
        self.assertEqual(motif.instances[7].length, 30)
        self.assertEqual(motif.instances[8].length, 30)
        self.assertEqual(motif.instances[9].length, 30)
        self.assertEqual(motif.instances[10].length, 30)
        self.assertEqual(motif.instances[11].length, 30)
        self.assertEqual(motif.instances[12].length, 30)
        self.assertEqual(motif.instances[13].length, 30)
        self.assertEqual(motif.instances[14].length, 30)
        self.assertEqual(motif.instances[15].length, 30)
        self.assertEqual(motif.instances[16].length, 30)
        self.assertEqual(motif.instances[17].length, 30)
        self.assertEqual(motif.instances[18].length, 30)
        self.assertEqual(motif.instances[19].length, 30)
        self.assertEqual(motif.instances[20].length, 30)
        self.assertEqual(motif.instances[21].length, 30)
        self.assertEqual(motif.instances[22].length, 30)
        self.assertEqual(motif.instances[23].length, 30)
        self.assertEqual(motif.instances[0].start, 223)
        self.assertEqual(motif.instances[1].start, 227)
        self.assertEqual(motif.instances[2].start, 275)
        self.assertEqual(motif.instances[3].start, 237)
        self.assertEqual(motif.instances[4].start, 138)
        self.assertEqual(motif.instances[5].start, 179)
        self.assertEqual(motif.instances[6].start, 131)
        self.assertEqual(motif.instances[7].start, 172)
        self.assertEqual(motif.instances[8].start, 276)
        self.assertEqual(motif.instances[9].start, 124)
        self.assertEqual(motif.instances[10].start, 247)
        self.assertEqual(motif.instances[11].start, 272)
        self.assertEqual(motif.instances[12].start, 145)
        self.assertEqual(motif.instances[13].start, 286)
        self.assertEqual(motif.instances[14].start, 296)
        self.assertEqual(motif.instances[15].start, 348)
        self.assertEqual(motif.instances[16].start, 83)
        self.assertEqual(motif.instances[17].start, 189)
        self.assertEqual(motif.instances[18].start, 73)
        self.assertEqual(motif.instances[19].start, 205)
        self.assertEqual(motif.instances[20].start, 198)
        self.assertEqual(motif.instances[21].start, 349)
        self.assertEqual(motif.instances[22].start, 327)
        self.assertEqual(motif.instances[23].start, 24)
        self.assertEqual(str(motif.instances[0]), "GGLNGRPSKLPDVCYSWWVLSSLAIIGRLD")
        self.assertEqual(str(motif.instances[1]), "GGLNGRPEKLPDVCYSWWVLASLKIIGRLH")
        self.assertEqual(str(motif.instances[2]), "GGFQGRENKFADTCYAFWCLNSLHLLTKDW")
        self.assertEqual(str(motif.instances[3]), "GGIGGVPGMEAHGGYTFCGLAALVILKKER")
        self.assertEqual(str(motif.instances[4]), "GGFGGGPGQYPHLAPTYAAVNALCIIGTEE")
        self.assertEqual(str(motif.instances[5]), "GGFGCRPGSESHAGQIYCCTGFLAITSQLH")
        self.assertEqual(str(motif.instances[6]), "GSFAGDIWGEIDTRFSFCAVATLALLGKLD")
        self.assertEqual(str(motif.instances[7]), "GGFGLCPNAESHAAQAFTCLGALAIANKLD")
        self.assertEqual(str(motif.instances[8]), "GGFADRPGDMVDPFHTLFGIAGLSLLGEEQ")
        self.assertEqual(str(motif.instances[9]), "GSFQGDRFGEVDTRFVYTALSALSILGELT")
        self.assertEqual(str(motif.instances[10]), "GFGSCPHVDEAHGGYTFCATASLAILRSMD")
        self.assertEqual(str(motif.instances[11]), "GGISDRPENEVDVFHTVFGVAGLSLMGYDN")
        self.assertEqual(str(motif.instances[12]), "GPFGGGPGQLSHLASTYAAINALSLCDNID")
        self.assertEqual(str(motif.instances[13]), "GGFQGRCNKLVDGCYSFWQAGLLPLLHRAL")
        self.assertEqual(str(motif.instances[14]), "RGFCGRSNKLVDGCYSFWVGGSAAILEAFG")
        self.assertEqual(str(motif.instances[15]), "GGLLDKPGKSRDFYHTCYCLSGLSIAQHFG")
        self.assertEqual(str(motif.instances[16]), "GGVSASIGHDPHLLYTLSAVQILTLYDSIH")
        self.assertEqual(str(motif.instances[17]), "GSFLMHVGGEVDVRSAYCAASVASLTNIIT")
        self.assertEqual(str(motif.instances[18]), "GAFAPFPRHDAHLLTTLSAVQILATYDALD")
        self.assertEqual(str(motif.instances[19]), "YNGAFGAHNEPHSGYTSCALSTLALLSSLE")
        self.assertEqual(str(motif.instances[20]), "GFKTCLEVGEVDTRGIYCALSIATLLNILT")
        self.assertEqual(str(motif.instances[21]), "PGLRDKPGAHSDFYHTNYCLLGLAVAESSY")
        self.assertEqual(str(motif.instances[22]), "GGFSKNDEEDADLYHSCLGSAALALIEGKF")
        self.assertEqual(str(motif.instances[23]), "HNFEYWLTEHLRLNGIYWGLTALCVLDSPE")
        motif = record[1]
        self.assertEqual(motif.name, "Motif 2")
        self.assertEqual(record["Motif 2"], motif)
        self.assertEqual(motif.num_occurrences, 21)
        self.assertAlmostEqual(motif.evalue, 3.1e-19)
        self.assertEqual(motif.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(motif.instances), 21)
        self.assertAlmostEqual(motif.instances[0].pvalue, 2.24e-13)
        self.assertAlmostEqual(motif.instances[1].pvalue, 1.30e-12)
        self.assertAlmostEqual(motif.instances[2].pvalue, 4.20e-12)
        self.assertAlmostEqual(motif.instances[3].pvalue, 9.60e-12)
        self.assertAlmostEqual(motif.instances[4].pvalue, 5.08e-11)
        self.assertAlmostEqual(motif.instances[5].pvalue, 5.01e-10)
        self.assertAlmostEqual(motif.instances[6].pvalue, 6.90e-10)
        self.assertAlmostEqual(motif.instances[7].pvalue, 1.57e-09)
        self.assertAlmostEqual(motif.instances[8].pvalue, 2.34e-09)
        self.assertAlmostEqual(motif.instances[9].pvalue, 4.59e-09)
        self.assertAlmostEqual(motif.instances[10].pvalue, 1.65e-08)
        self.assertAlmostEqual(motif.instances[11].pvalue, 1.65e-08)
        self.assertAlmostEqual(motif.instances[12].pvalue, 1.65e-08)
        self.assertAlmostEqual(motif.instances[13].pvalue, 2.54e-08)
        self.assertAlmostEqual(motif.instances[14].pvalue, 4.58e-08)
        self.assertAlmostEqual(motif.instances[15].pvalue, 5.86e-08)
        self.assertAlmostEqual(motif.instances[16].pvalue, 1.52e-07)
        self.assertAlmostEqual(motif.instances[17].pvalue, 1.91e-07)
        self.assertAlmostEqual(motif.instances[18].pvalue, 4.34e-07)
        self.assertAlmostEqual(motif.instances[19].pvalue, 5.01e-07)
        self.assertAlmostEqual(motif.instances[20].pvalue, 5.78e-07)
        self.assertEqual(motif.instances[0].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[1].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[2].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[3].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[4].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[5].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[6].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[7].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[8].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[9].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[10].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[11].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[12].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[13].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[14].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[15].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[16].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[17].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[18].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[19].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[20].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[7].strand, "+")
        self.assertEqual(motif.instances[8].strand, "+")
        self.assertEqual(motif.instances[9].strand, "+")
        self.assertEqual(motif.instances[10].strand, "+")
        self.assertEqual(motif.instances[11].strand, "+")
        self.assertEqual(motif.instances[12].strand, "+")
        self.assertEqual(motif.instances[13].strand, "+")
        self.assertEqual(motif.instances[14].strand, "+")
        self.assertEqual(motif.instances[15].strand, "+")
        self.assertEqual(motif.instances[16].strand, "+")
        self.assertEqual(motif.instances[17].strand, "+")
        self.assertEqual(motif.instances[18].strand, "+")
        self.assertEqual(motif.instances[19].strand, "+")
        self.assertEqual(motif.instances[20].strand, "+")
        self.assertEqual(motif.instances[0].length, 14)
        self.assertEqual(motif.instances[1].length, 14)
        self.assertEqual(motif.instances[2].length, 14)
        self.assertEqual(motif.instances[3].length, 14)
        self.assertEqual(motif.instances[4].length, 14)
        self.assertEqual(motif.instances[5].length, 14)
        self.assertEqual(motif.instances[6].length, 14)
        self.assertEqual(motif.instances[7].length, 14)
        self.assertEqual(motif.instances[8].length, 14)
        self.assertEqual(motif.instances[9].length, 14)
        self.assertEqual(motif.instances[10].length, 14)
        self.assertEqual(motif.instances[11].length, 14)
        self.assertEqual(motif.instances[12].length, 14)
        self.assertEqual(motif.instances[13].length, 14)
        self.assertEqual(motif.instances[14].length, 14)
        self.assertEqual(motif.instances[15].length, 14)
        self.assertEqual(motif.instances[16].length, 14)
        self.assertEqual(motif.instances[17].length, 14)
        self.assertEqual(motif.instances[18].length, 14)
        self.assertEqual(motif.instances[19].length, 14)
        self.assertEqual(motif.instances[20].length, 14)
        self.assertEqual(motif.instances[0].start, 254)
        self.assertEqual(motif.instances[1].start, 258)
        self.assertEqual(motif.instances[2].start, 162)
        self.assertEqual(motif.instances[3].start, 66)
        self.assertEqual(motif.instances[4].start, 278)
        self.assertEqual(motif.instances[5].start, 190)
        self.assertEqual(motif.instances[6].start, 55)
        self.assertEqual(motif.instances[7].start, 114)
        self.assertEqual(motif.instances[8].start, 172)
        self.assertEqual(motif.instances[9].start, 330)
        self.assertEqual(motif.instances[10].start, 126)
        self.assertEqual(motif.instances[11].start, 268)
        self.assertEqual(motif.instances[12].start, 220)
        self.assertEqual(motif.instances[13].start, 229)
        self.assertEqual(motif.instances[14].start, 330)
        self.assertEqual(motif.instances[15].start, 239)
        self.assertEqual(motif.instances[16].start, 121)
        self.assertEqual(motif.instances[17].start, 362)
        self.assertEqual(motif.instances[18].start, 107)
        self.assertEqual(motif.instances[19].start, 155)
        self.assertEqual(motif.instances[20].start, 180)
        self.assertEqual(str(motif.instances[0]), "INYEKLTEFILKCQ")
        self.assertEqual(str(motif.instances[1]), "IDREKLRSFILACQ")
        self.assertEqual(str(motif.instances[2]), "INVEKAIEFVLSCM")
        self.assertEqual(str(motif.instances[3]), "MNKEEILVFIKSCQ")
        self.assertEqual(str(motif.instances[4]), "INVEKLLEWSSARQ")
        self.assertEqual(str(motif.instances[5]), "IDTEKLLGYIMSQQ")
        self.assertEqual(str(motif.instances[6]), "FVKEEVISFVLSCW")
        self.assertEqual(str(motif.instances[7]), "INVDKVVAYVQSLQ")
        self.assertEqual(str(motif.instances[8]), "INREKLLQYLYSLK")
        self.assertEqual(str(motif.instances[9]), "FNKHALRDYILYCC")
        self.assertEqual(str(motif.instances[10]), "LDKRSLARFVSKCQ")
        self.assertEqual(str(motif.instances[11]), "LNLKSLLQWVTSRQ")
        self.assertEqual(str(motif.instances[12]), "DLFEGTAEWIARCQ")
        self.assertEqual(str(motif.instances[13]), "ELTEGVLNYLKNCQ")
        self.assertEqual(str(motif.instances[14]), "FHQQALQEYILMCC")
        self.assertEqual(str(motif.instances[15]), "KFKEDTITWLLHRQ")
        self.assertEqual(str(motif.instances[16]), "IVATDVCQFLELCQ")
        self.assertEqual(str(motif.instances[17]), "IPQEIFNDFSKRCC")
        self.assertEqual(str(motif.instances[18]), "DRKVRLISFIRGNQ")
        self.assertEqual(str(motif.instances[19]), "EVVDPAVDFVLKCY")
        self.assertEqual(str(motif.instances[20]), "IDRKGIYQWLISLK")

    def test_meme_parser_4_11_4(self):
        """Parse motifs/meme_v_4_11_4.txt file."""
        with open("motifs/meme_v_4_11_4.txt") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "4.11.4")
        self.assertEqual(record.datafile, "example.fasta")
        self.assertEqual(record.alphabet, "ACGT")
        self.assertEqual(len(record.sequences), 10)
        self.assertEqual(record.sequences[0], "SEQ1;")
        self.assertEqual(record.sequences[1], "SEQ2;")
        self.assertEqual(record.sequences[2], "SEQ3;")
        self.assertEqual(record.sequences[3], "SEQ4;")
        self.assertEqual(record.sequences[4], "SEQ5;")
        self.assertEqual(record.sequences[5], "SEQ6;")
        self.assertEqual(record.sequences[6], "SEQ7;")
        self.assertEqual(record.sequences[7], "SEQ8;")
        self.assertEqual(record.sequences[8], "SEQ9;")
        self.assertEqual(record.sequences[9], "SEQ10;")
        self.assertEqual(record.command, "meme -dna example.fasta")
        self.assertEqual(len(record), 1)
        motif = record[0]
        self.assertEqual(motif.name, "Motif CTCAATCGTA")
        self.assertEqual(record["Motif CTCAATCGTA"], motif)
        self.assertEqual(motif.num_occurrences, 10)
        self.assertAlmostEqual(motif.evalue, 1.1e-22)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 10)
        self.assertAlmostEqual(motif.instances[0].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[1].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[4].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[5].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[6].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[7].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[8].pvalue, 1.96e-06)
        self.assertAlmostEqual(motif.instances[9].pvalue, 1.96e-06)
        self.assertEqual(motif.instances[0].sequence_name, "SEQ10;")
        self.assertEqual(motif.instances[1].sequence_name, "SEQ9;")
        self.assertEqual(motif.instances[2].sequence_name, "SEQ8;")
        self.assertEqual(motif.instances[3].sequence_name, "SEQ7;")
        self.assertEqual(motif.instances[4].sequence_name, "SEQ6;")
        self.assertEqual(motif.instances[5].sequence_name, "SEQ5;")
        self.assertEqual(motif.instances[6].sequence_name, "SEQ4;")
        self.assertEqual(motif.instances[7].sequence_name, "SEQ3;")
        self.assertEqual(motif.instances[8].sequence_name, "SEQ2;")
        self.assertEqual(motif.instances[9].sequence_name, "SEQ1;")
        self.assertEqual(motif.instances[0].start, 1)
        self.assertEqual(motif.instances[1].start, 1)
        self.assertEqual(motif.instances[2].start, 1)
        self.assertEqual(motif.instances[3].start, 1)
        self.assertEqual(motif.instances[4].start, 1)
        self.assertEqual(motif.instances[5].start, 1)
        self.assertEqual(motif.instances[6].start, 1)
        self.assertEqual(motif.instances[7].start, 1)
        self.assertEqual(motif.instances[8].start, 1)
        self.assertEqual(motif.instances[9].start, 1)
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[7].strand, "+")
        self.assertEqual(motif.instances[8].strand, "+")
        self.assertEqual(motif.instances[9].strand, "+")
        self.assertEqual(motif.instances[0].length, 10)
        self.assertEqual(motif.instances[1].length, 10)
        self.assertEqual(motif.instances[2].length, 10)
        self.assertEqual(motif.instances[3].length, 10)
        self.assertEqual(motif.instances[4].length, 10)
        self.assertEqual(motif.instances[5].length, 10)
        self.assertEqual(motif.instances[6].length, 10)
        self.assertEqual(motif.instances[7].length, 10)
        self.assertEqual(motif.instances[8].length, 10)
        self.assertEqual(motif.instances[9].length, 10)
        self.assertEqual(motif.instances[0].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[1].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[2].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[3].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[4].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[5].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[6].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[7].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[8].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[9].motif_name, "Motif CTCAATCGTA")
        self.assertEqual(motif.instances[0].alphabet, "ACGT")
        self.assertEqual(motif.instances[1].alphabet, "ACGT")
        self.assertEqual(motif.instances[2].alphabet, "ACGT")
        self.assertEqual(motif.instances[3].alphabet, "ACGT")
        self.assertEqual(motif.instances[4].alphabet, "ACGT")
        self.assertEqual(motif.instances[5].alphabet, "ACGT")
        self.assertEqual(motif.instances[6].alphabet, "ACGT")
        self.assertEqual(motif.instances[7].alphabet, "ACGT")
        self.assertEqual(motif.instances[8].alphabet, "ACGT")
        self.assertEqual(motif.instances[9].alphabet, "ACGT")
        self.assertEqual(str(motif.instances[0]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[1]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[2]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[3]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[4]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[5]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[6]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[7]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[8]), "CTCAATCGTA")
        self.assertEqual(str(motif.instances[9]), "CTCAATCGTA")

    def test_minimal_meme_parser(self):
        """Parse motifs/minimal_test.meme file."""
        with open("motifs/minimal_test.meme") as handle:
            record = motifs.parse(handle, "minimal")
        self.assertEqual(record.version, "4")
        self.assertEqual(record.alphabet, "ACGT")
        self.assertEqual(len(record.sequences), 0)
        self.assertEqual(record.command, "")
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "KRP")
        self.assertEqual(record["KRP"], motif)
        self.assertEqual(motif.num_occurrences, 17)
        self.assertEqual(motif.length, 19)
        self.assertEqual(str(motif.consensus), "TGTGATCGAGGTCACACTT")
        self.assertAlmostEqual(motif.background["A"], 0.30269730269730266)
        self.assertAlmostEqual(motif.background["C"], 0.1828171828171828)
        self.assertAlmostEqual(motif.background["G"], 0.20879120879120877)
        self.assertAlmostEqual(motif.background["T"], 0.30569430569430567)
        self.assertAlmostEqual(motif.evalue, 4.1e-09)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(motif.instances, None)

    def test_meme_parser_rna(self):
        """Test if Bio.motifs can parse MEME output files using RNA."""
        with open("motifs/meme.rna.oops.txt") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "4.11.0")
        self.assertEqual(record.datafile, "rna_samples.fa")
        self.assertEqual(record.alphabet, "ACGU")
        self.assertEqual(len(record.sequences), 7)
        self.assertEqual(record.sequences[0], "ce1cg")
        self.assertEqual(record.sequences[1], "ara")
        self.assertEqual(record.sequences[2], "bglr1")
        self.assertEqual(record.sequences[3], "crp")
        self.assertEqual(record.sequences[4], "cya")
        self.assertEqual(record.sequences[5], "deop2")
        self.assertEqual(record.sequences[6], "gale")
        self.assertEqual(record.command, "meme rna_samples.fa -nmotifs 2 -rna -mod oops")
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "Motif 1")
        self.assertEqual(record["Motif 1"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 0.0072)
        self.assertEqual(motif.alphabet, "ACGU")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 1.37e-09)
        self.assertAlmostEqual(motif.instances[1].pvalue, 3.90e-08)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.66e-07)
        self.assertAlmostEqual(motif.instances[3].pvalue, 2.14e-07)
        self.assertAlmostEqual(motif.instances[4].pvalue, 6.30e-07)
        self.assertAlmostEqual(motif.instances[5].pvalue, 6.75e-07)
        self.assertAlmostEqual(motif.instances[6].pvalue, 7.76e-07)
        self.assertEqual(motif.instances[0].sequence_name, "ara")
        self.assertEqual(motif.instances[1].sequence_name, "gale")
        self.assertEqual(motif.instances[2].sequence_name, "deop2")
        self.assertEqual(motif.instances[3].sequence_name, "crp")
        self.assertEqual(motif.instances[4].sequence_name, "bglr1")
        self.assertEqual(motif.instances[5].sequence_name, "ce1cg")
        self.assertEqual(motif.instances[6].sequence_name, "cya")
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[0].length, 19)
        self.assertEqual(motif.instances[1].length, 19)
        self.assertEqual(motif.instances[2].length, 19)
        self.assertEqual(motif.instances[3].length, 19)
        self.assertEqual(motif.instances[4].length, 19)
        self.assertEqual(motif.instances[5].length, 19)
        self.assertEqual(motif.instances[6].length, 19)
        self.assertEqual(motif.instances[0].start, 58)
        self.assertEqual(motif.instances[1].start, 45)
        self.assertEqual(motif.instances[2].start, 10)
        self.assertEqual(motif.instances[3].start, 66)
        self.assertEqual(motif.instances[4].start, 79)
        self.assertEqual(motif.instances[5].start, 64)
        self.assertEqual(motif.instances[6].start, 79)
        self.assertEqual(str(motif.instances[0]), "UUUGCACGGCGUCACACUU")
        self.assertEqual(str(motif.instances[1]), "UUUAUUCCAUGUCACACUU")
        self.assertEqual(str(motif.instances[2]), "UUUGAACCAGAUCGCAUUA")
        self.assertEqual(str(motif.instances[3]), "UGCAAAGGACGUCACAUUA")
        self.assertEqual(str(motif.instances[4]), "UGUGAGCAUGGUCAUAUUU")
        self.assertEqual(str(motif.instances[5]), "UUUGAUCGUUUUCACAAAA")
        self.assertEqual(str(motif.instances[6]), "UUUUUUCGUCGUGAAACUA")
        motif = record[1]
        self.assertEqual(motif.name, "Motif 2")
        self.assertEqual(record["Motif 2"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 760)
        self.assertEqual(motif.alphabet, "ACGU")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 7.14e-06)
        self.assertAlmostEqual(motif.instances[1].pvalue, 2.50e-05)
        self.assertAlmostEqual(motif.instances[2].pvalue, 3.26e-05)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.10e-04)
        self.assertAlmostEqual(motif.instances[4].pvalue, 1.73e-04)
        self.assertAlmostEqual(motif.instances[5].pvalue, 3.33e-04)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.67e-04)
        self.assertEqual(motif.instances[0].sequence_name, "crp")
        self.assertEqual(motif.instances[1].sequence_name, "gale")
        self.assertEqual(motif.instances[2].sequence_name, "ara")
        self.assertEqual(motif.instances[3].sequence_name, "deop2")
        self.assertEqual(motif.instances[4].sequence_name, "cya")
        self.assertEqual(motif.instances[5].sequence_name, "ce1cg")
        self.assertEqual(motif.instances[6].sequence_name, "bglr1")
        self.assertEqual(motif.instances[0].strand, "+")
        self.assertEqual(motif.instances[1].strand, "+")
        self.assertEqual(motif.instances[2].strand, "+")
        self.assertEqual(motif.instances[3].strand, "+")
        self.assertEqual(motif.instances[4].strand, "+")
        self.assertEqual(motif.instances[5].strand, "+")
        self.assertEqual(motif.instances[6].strand, "+")
        self.assertEqual(motif.instances[0].length, 9)
        self.assertEqual(motif.instances[1].length, 9)
        self.assertEqual(motif.instances[2].length, 9)
        self.assertEqual(motif.instances[3].length, 9)
        self.assertEqual(motif.instances[4].length, 9)
        self.assertEqual(motif.instances[5].length, 9)
        self.assertEqual(motif.instances[6].length, 9)
        self.assertEqual(motif.instances[0].start, 13)
        self.assertEqual(motif.instances[1].start, 75)
        self.assertEqual(motif.instances[2].start, 78)
        self.assertEqual(motif.instances[3].start, 31)
        self.assertEqual(motif.instances[4].start, 1)
        self.assertEqual(motif.instances[5].start, 44)
        self.assertEqual(motif.instances[6].start, 27)
        self.assertEqual(str(motif.instances[0]), "GCUAUGCUA")
        self.assertEqual(str(motif.instances[1]), "GUUAUGCUA")
        self.assertEqual(str(motif.instances[2]), "GCUAUGCCA")
        self.assertEqual(str(motif.instances[3]), "GUGAUGCAA")
        self.assertEqual(str(motif.instances[4]), "ACGGUGCUA")
        self.assertEqual(str(motif.instances[5]), "GUGGUGUGA")
        self.assertEqual(str(motif.instances[6]), "GAUUUGUUA")


class TestMAST(unittest.TestCase):
    """MAST format tests."""

    def test_mast_parser_1(self):
        """Parse motifs/mast.crp0.de.oops.txt.xml file."""
        with open("motifs/mast.crp0.de.oops.txt.xml") as handle:
            record = motifs.parse(handle, "MAST")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.database, "common/crp0.s")
        self.assertEqual(record.alphabet, "DNA")
        self.assertEqual(len(record), 2)
        self.assertEqual(record["1"].name, "1")
        self.assertEqual(record["2"].name, "2")
        self.assertEqual(record[0].alphabet, "DNA")
        self.assertEqual(record[0].length, 12)
        self.assertEqual(record[0].name, "1")
        self.assertEqual(record[1].alphabet, "DNA")
        self.assertEqual(record[1].length, 12)
        self.assertEqual(record[1].name, "2")
        self.assertEqual(len(record.sequences), 18)
        self.assertEqual(record.sequences[0], "lac")
        self.assertEqual(record.sequences[1], "bglr1")
        self.assertEqual(record.sequences[2], "tdc")
        self.assertEqual(record.sequences[3], "deop2")
        self.assertEqual(record.sequences[4], "pbr322")
        self.assertEqual(record.sequences[5], "malk")
        self.assertEqual(record.sequences[6], "tnaa")
        self.assertEqual(record.sequences[7], "male")
        self.assertEqual(record.sequences[8], "ara")
        self.assertEqual(record.sequences[9], "cya")
        self.assertEqual(record.sequences[10], "ompa")
        self.assertEqual(record.sequences[11], "ilv")
        self.assertEqual(record.sequences[12], "gale")
        self.assertEqual(record.sequences[13], "malt")
        self.assertEqual(record.sequences[14], "crp")
        self.assertEqual(record.sequences[15], "ce1cg")
        self.assertEqual(record.sequences[16], "trn9cat")
        self.assertEqual(record.sequences[17], "uxu1")
        self.assertEqual(record.diagrams["lac"], "[+1]-2-[-2]-79")
        self.assertEqual(record.diagrams["bglr1"], "79-[+2]-14")
        self.assertEqual(record.diagrams["tdc"], "30-[+1]-39-[+2]-12")
        self.assertEqual(record.diagrams["deop2"], "19-[+1]-74")
        self.assertEqual(record.diagrams["pbr322"], "58-[-2]-35")
        self.assertEqual(record.diagrams["malk"], "32-[+2]-61")
        self.assertEqual(record.diagrams["tnaa"], "105")
        self.assertEqual(record.diagrams["male"], "105")
        self.assertEqual(record.diagrams["ara"], "105")
        self.assertEqual(record.diagrams["cya"], "105")
        self.assertEqual(record.diagrams["ompa"], "105")
        self.assertEqual(record.diagrams["ilv"], "105")
        self.assertEqual(record.diagrams["gale"], "105")
        self.assertEqual(record.diagrams["malt"], "105")
        self.assertEqual(record.diagrams["crp"], "105")
        self.assertEqual(record.diagrams["ce1cg"], "105")
        self.assertEqual(record.diagrams["trn9cat"], "105")
        self.assertEqual(record.diagrams["uxu1"], "105")

    def test_mast_parser_2(self):
        """Parse motifs/mast.adh.de.oops.html.xml file."""
        with open("motifs/mast.adh.de.oops.html.xml") as handle:
            record = motifs.parse(handle, "MAST")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.database, "common/adh.s")
        self.assertEqual(record.alphabet, "Protein")
        self.assertEqual(len(record), 2)
        self.assertEqual(record["1"].name, "1")
        self.assertEqual(record["2"].name, "2")
        self.assertEqual(record[0].alphabet, "Protein")
        self.assertEqual(record[0].length, 12)
        self.assertEqual(record[0].name, "1")
        self.assertEqual(record[1].alphabet, "Protein")
        self.assertEqual(record[1].length, 12)
        self.assertEqual(record[1].name, "2")
        self.assertEqual(len(record.sequences), 33)
        self.assertEqual(record.sequences[0], "ENTA_ECOLI")
        self.assertEqual(record.sequences[1], "DHII_HUMAN")
        self.assertEqual(record.sequences[2], "YINL_LISMO")
        self.assertEqual(record.sequences[3], "FIXR_BRAJA")
        self.assertEqual(record.sequences[4], "HDHA_ECOLI")
        self.assertEqual(record.sequences[5], "BUDC_KLETE")
        self.assertEqual(record.sequences[6], "AP27_MOUSE")
        self.assertEqual(record.sequences[7], "FVT1_HUMAN")
        self.assertEqual(record.sequences[8], "YRTP_BACSU")
        self.assertEqual(record.sequences[9], "DHMA_FLAS1")
        self.assertEqual(record.sequences[10], "HDE_CANTR")
        self.assertEqual(record.sequences[11], "3BHD_COMTE")
        self.assertEqual(record.sequences[12], "BDH_HUMAN")
        self.assertEqual(record.sequences[13], "2BHD_STREX")
        self.assertEqual(record.sequences[14], "BA72_EUBSP")
        self.assertEqual(record.sequences[15], "RIDH_KLEAE")
        self.assertEqual(record.sequences[16], "DHGB_BACME")
        self.assertEqual(record.sequences[17], "PCR_PEA")
        self.assertEqual(record.sequences[18], "RFBB_NEIGO")
        self.assertEqual(record.sequences[19], "BPHB_PSEPS")
        self.assertEqual(record.sequences[20], "DHB2_HUMAN")
        self.assertEqual(record.sequences[21], "NODG_RHIME")
        self.assertEqual(record.sequences[22], "MAS1_AGRRA")
        self.assertEqual(record.sequences[23], "DHCA_HUMAN")
        self.assertEqual(record.sequences[24], "DHES_HUMAN")
        self.assertEqual(record.sequences[25], "DHB3_HUMAN")
        self.assertEqual(record.sequences[26], "HMTR_LEIMA")
        self.assertEqual(record.sequences[27], "ADH_DROME")
        self.assertEqual(record.sequences[28], "YURA_MYXXA")
        self.assertEqual(record.sequences[29], "LIGD_PSEPA")
        self.assertEqual(record.sequences[30], "FABI_ECOLI")
        self.assertEqual(record.sequences[31], "GUTD_ECOLI")
        self.assertEqual(record.sequences[32], "CSGA_MYXXA")
        self.assertEqual(record.diagrams["ENTA_ECOLI"], "[1]-[2]-224")
        self.assertEqual(record.diagrams["DHII_HUMAN"], "29-[1]-[2]-239")
        self.assertEqual(record.diagrams["YINL_LISMO"], "[1]-[2]-224")
        self.assertEqual(record.diagrams["FIXR_BRAJA"], "43-[2]-149-[1]-62")
        self.assertEqual(record.diagrams["HDHA_ECOLI"], "6-[1]-[2]-144-[1]-69")
        self.assertEqual(record.diagrams["BUDC_KLETE"], "9-[2]-53-[1]-81-[1]-62")
        self.assertEqual(record.diagrams["AP27_MOUSE"], "2-[1]-[2]-138-[1]-68")
        self.assertEqual(record.diagrams["FVT1_HUMAN"], "39-[2]-150-[1]-119")
        self.assertEqual(record.diagrams["YRTP_BACSU"], "1-[1]-[2]-145-[1]-56")
        self.assertEqual(record.diagrams["DHMA_FLAS1"], "9-[1]-[2]-147-[1]-78")
        self.assertEqual(record.diagrams["HDE_CANTR"], "3-[1]-[2]-290-[1]-[2]-565")
        self.assertEqual(record.diagrams["3BHD_COMTE"], "1-[1]-[2]-50-[1]-166")
        self.assertEqual(record.diagrams["BDH_HUMAN"], "50-[1]-[2]-269")
        self.assertEqual(record.diagrams["2BHD_STREX"], "1-[1]-[2]-142-[1]-76")
        self.assertEqual(record.diagrams["BA72_EUBSP"], "1-[1]-[2]-125-[2]-10-[1]-65")
        self.assertEqual(record.diagrams["RIDH_KLEAE"], "9-[1]-[2]-216")
        self.assertEqual(record.diagrams["DHGB_BACME"], "2-[1]-[2]-149-[1]-75")
        self.assertEqual(record.diagrams["PCR_PEA"], "81-[1]-[2]-108-[1]-174")
        self.assertEqual(record.diagrams["RFBB_NEIGO"], "1-[1]-[2]-321")
        self.assertEqual(record.diagrams["BPHB_PSEPS"], "[1]-[2]-251")
        self.assertEqual(record.diagrams["DHB2_HUMAN"], "77-[1]-[2]-286")
        self.assertEqual(record.diagrams["NODG_RHIME"], "1-[1]-[2]-142-[1]-66")
        self.assertEqual(record.diagrams["MAS1_AGRRA"], "252-[2]-36-[1]-164")
        self.assertEqual(record.diagrams["DHCA_HUMAN"], "11-[2]-54-[1]-101-[1]-74")
        self.assertEqual(record.diagrams["DHES_HUMAN"], "9-[2]-108-[1]-186")
        self.assertEqual(record.diagrams["DHB3_HUMAN"], "55-[2]-146-[1]-85")
        self.assertEqual(record.diagrams["HMTR_LEIMA"], "24-[2]-172-[1]-67")
        self.assertEqual(record.diagrams["ADH_DROME"], "13-[2]-217-[1]-1")
        self.assertEqual(record.diagrams["YURA_MYXXA"], "94-[2]-69-[1]-71")
        self.assertEqual(record.diagrams["LIGD_PSEPA"], "1-[1]-[2]-280")
        self.assertEqual(record.diagrams["FABI_ECOLI"], "1-[1]-161-[1]-76")
        self.assertEqual(record.diagrams["GUTD_ECOLI"], "147-[2]-10-[1]-78")
        self.assertEqual(record.diagrams["CSGA_MYXXA"], "12-[1]-53-[2]-77")

    def test_mast_parser_3(self):
        """Parse motifs/mast.Klf1-200.cd.oops.xml.xml file."""
        with open("motifs/mast.Klf1-200.cd.oops.xml.xml") as handle:
            record = motifs.parse(handle, "MAST")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.database, "common/Klf1-200.fa")
        self.assertEqual(record.alphabet, "DNA")
        self.assertEqual(len(record), 2)
        self.assertEqual(record["1"].name, "1")
        self.assertEqual(record["2"].name, "2")
        self.assertEqual(record[0].alphabet, "DNA")
        self.assertEqual(record[0].length, 20)
        self.assertEqual(record[0].name, "1")
        self.assertEqual(record[1].alphabet, "DNA")
        self.assertEqual(record[1].length, 30)
        self.assertEqual(record[1].name, "2")
        self.assertEqual(len(record.sequences), 113)
        self.assertEqual(record.sequences[0], "chr3:104843905-104844405")
        self.assertEqual(record.sequences[1], "chr12:114390660-114391160")
        self.assertEqual(record.sequences[2], "chr12:27135944-27136444")
        self.assertEqual(record.sequences[3], "chr10:59256089-59256589")
        self.assertEqual(record.sequences[4], "chr4:135733850-135734350")
        self.assertEqual(record.sequences[5], "chr1:137838164-137838664")
        self.assertEqual(record.sequences[6], "chr17:47735006-47735506")
        self.assertEqual(record.sequences[7], "chr6:72223026-72223526")
        self.assertEqual(record.sequences[8], "chr13:3866266-3866766")
        self.assertEqual(record.sequences[9], "chr1:133343883-133344383")
        self.assertEqual(record.sequences[10], "chr11:117187372-117187872")
        self.assertEqual(record.sequences[11], "chr13:76003199-76003699")
        self.assertEqual(record.sequences[12], "chr5:65202593-65203093")
        self.assertEqual(record.sequences[13], "chr14:79702844-79703344")
        self.assertEqual(record.sequences[14], "chr12:112796794-112797294")
        self.assertEqual(record.sequences[15], "chr13:112863645-112864145")
        self.assertEqual(record.sequences[16], "chr7:111007530-111008030")
        self.assertEqual(record.sequences[17], "chr1:43307690-43308190")
        self.assertEqual(record.sequences[18], "chr14:47973722-47974222")
        self.assertEqual(record.sequences[19], "chr9:120025371-120025871")
        self.assertEqual(record.sequences[20], "chr7:105490727-105491227")
        self.assertEqual(record.sequences[21], "chr5:37127175-37127675")
        self.assertEqual(record.sequences[22], "chr5:45951565-45952065")
        self.assertEqual(record.sequences[23], "chr7:91033422-91033922")
        self.assertEqual(record.sequences[24], "chr4:154285745-154286245")
        self.assertEqual(record.sequences[25], "chr13:100518008-100518508")
        self.assertEqual(record.sequences[26], "chr1:36977019-36977519")
        self.assertEqual(record.sequences[27], "chr7:151917814-151918314")
        self.assertEqual(record.sequences[28], "chr7:110976195-110976695")
        self.assertEqual(record.sequences[29], "chr15:58719281-58719781")
        self.assertEqual(record.sequences[30], "chr11:57590460-57590960")
        self.assertEqual(record.sequences[31], "chr8:83025150-83025650")
        self.assertEqual(record.sequences[32], "chr13:54345922-54346422")
        self.assertEqual(record.sequences[33], "chr12:82044358-82044858")
        self.assertEqual(record.sequences[34], "chr11:105013714-105014214")
        self.assertEqual(record.sequences[35], "chr10:93585404-93585904")
        self.assertEqual(record.sequences[36], "chr7:19832207-19832707")
        self.assertEqual(record.sequences[37], "chr8:97323995-97324495")
        self.assertEqual(record.sequences[38], "chr10:126642277-126642777")
        self.assertEqual(record.sequences[39], "chr1:156887119-156887619")
        self.assertEqual(record.sequences[40], "chr15:81700367-81700867")
        self.assertEqual(record.sequences[41], "chr6:121187425-121187925")
        self.assertEqual(record.sequences[42], "chr4:43977111-43977611")
        self.assertEqual(record.sequences[43], "chr11:102236405-102236905")
        self.assertEqual(record.sequences[44], "chr17:5112057-5112557")
        self.assertEqual(record.sequences[45], "chr10:110604369-110604869")
        self.assertEqual(record.sequences[46], "chr1:169314208-169314708")
        self.assertEqual(record.sequences[47], "chr9:57618594-57619094")
        self.assertEqual(record.sequences[48], "chr10:128184604-128185104")
        self.assertEqual(record.sequences[49], "chr4:109112541-109113041")
        self.assertEqual(record.sequences[50], "chr3:97461668-97462168")
        self.assertEqual(record.sequences[51], "chr9:102674395-102674895")
        self.assertEqual(record.sequences[52], "chr17:24289205-24289705")
        self.assertEqual(record.sequences[53], "chr17:28960252-28960752")
        self.assertEqual(record.sequences[54], "chr2:73323093-73323593")
        self.assertEqual(record.sequences[55], "chr11:32150818-32151318")
        self.assertEqual(record.sequences[56], "chr7:103853792-103854292")
        self.assertEqual(record.sequences[57], "chr16:49839621-49840121")
        self.assertEqual(record.sequences[58], "chr6:135115628-135116128")
        self.assertEqual(record.sequences[59], "chr3:88305500-88306000")
        self.assertEqual(record.sequences[60], "chr18:57137388-57137888")
        self.assertEqual(record.sequences[61], "chr5:97380648-97381148")
        self.assertEqual(record.sequences[62], "chr15:91082416-91082916")
        self.assertEqual(record.sequences[63], "chr14:61272713-61273213")
        self.assertEqual(record.sequences[64], "chr5:33616214-33616714")
        self.assertEqual(record.sequences[65], "chr18:23982470-23982970")
        self.assertEqual(record.sequences[66], "chr9:24715045-24715545")
        self.assertEqual(record.sequences[67], "chr10:116195445-116195945")
        self.assertEqual(record.sequences[68], "chr11:77795184-77795684")
        self.assertEqual(record.sequences[69], "chr16:32508975-32509475")
        self.assertEqual(record.sequences[70], "chr18:80416880-80417380")
        self.assertEqual(record.sequences[71], "chr10:57252236-57252736")
        self.assertEqual(record.sequences[72], "chr5:34915767-34916267")
        self.assertEqual(record.sequences[73], "chr9:98389943-98390443")
        self.assertEqual(record.sequences[74], "chr19:5845899-5846399")
        self.assertEqual(record.sequences[75], "chr3:151777796-151778296")
        self.assertEqual(record.sequences[76], "chr4:76585120-76585620")
        self.assertEqual(record.sequences[77], "chr7:104332488-104332988")
        self.assertEqual(record.sequences[78], "chr5:138127197-138127697")
        self.assertEqual(record.sequences[79], "chr11:60988820-60989320")
        self.assertEqual(record.sequences[80], "chr8:19984030-19984530")
        self.assertEqual(record.sequences[81], "chr11:31712262-31712762")
        self.assertEqual(record.sequences[82], "chr15:41338514-41339014")
        self.assertEqual(record.sequences[83], "chr9:21362671-21363171")
        self.assertEqual(record.sequences[84], "chr18:58822702-58823202")
        self.assertEqual(record.sequences[85], "chr1:173447614-173448114")
        self.assertEqual(record.sequences[86], "chr6:81915769-81916269")
        self.assertEqual(record.sequences[87], "chr1:169322898-169323398")
        self.assertEqual(record.sequences[88], "chr12:70860461-70860961")
        self.assertEqual(record.sequences[89], "chr9:59598186-59598686")
        self.assertEqual(record.sequences[90], "chr3:19550495-19550995")
        self.assertEqual(record.sequences[91], "chr7:36132953-36133453")
        self.assertEqual(record.sequences[92], "chr7:38970375-38970875")
        self.assertEqual(record.sequences[93], "chr15:78243390-78243890")
        self.assertEqual(record.sequences[94], "chr7:87847381-87847881")
        self.assertEqual(record.sequences[95], "chr1:33631214-33631714")
        self.assertEqual(record.sequences[96], "chr4:135407873-135408373")
        self.assertEqual(record.sequences[97], "chr7:101244829-101245329")
        self.assertEqual(record.sequences[98], "chr10:60612190-60612690")
        self.assertEqual(record.sequences[99], "chr19:56465963-56466463")
        self.assertEqual(record.sequences[100], "chr4:41334759-41335259")
        self.assertEqual(record.sequences[101], "chr8:92969521-92970021")
        self.assertEqual(record.sequences[102], "chr6:145703215-145703715")
        self.assertEqual(record.sequences[103], "chr13:57679178-57679678")
        self.assertEqual(record.sequences[104], "chr19:45121628-45122128")
        self.assertEqual(record.sequences[105], "chr15:79757891-79758391")
        self.assertEqual(record.sequences[106], "chr1:134264178-134264678")
        self.assertEqual(record.sequences[107], "chr13:81067500-81068000")
        self.assertEqual(record.sequences[108], "chr11:69714224-69714724")
        self.assertEqual(record.sequences[109], "chr2:103728071-103728571")
        self.assertEqual(record.sequences[110], "chr5:105994747-105995247")
        self.assertEqual(record.sequences[111], "chr17:84209565-84210065")
        self.assertEqual(record.sequences[112], "chr7:16507689-16508189")
        self.assertEqual(record.diagrams["chr3:104843905-104844405"], "115-[-1]-209-[-2]-126")
        self.assertEqual(record.diagrams["chr12:114390660-114391160"], "3-[+2]-[+2]-3-[+1]-173-[+1]-3-[-2]-188")
        self.assertEqual(record.diagrams["chr12:27135944-27136444"], "275-[-1]-89-[+2]-4-[+2]-52")
        self.assertEqual(record.diagrams["chr10:59256089-59256589"], "247-[+2]-17-[-1]-186")
        self.assertEqual(record.diagrams["chr4:135733850-135734350"], "183-[-1]-263-[+2]-4")
        self.assertEqual(record.diagrams["chr1:137838164-137838664"], "192-[-2]-1-[+1]-44-[-1]-193")
        self.assertEqual(record.diagrams["chr17:47735006-47735506"], "203-[+2]-15-[+1]-97-[-1]-115")
        self.assertEqual(record.diagrams["chr6:72223026-72223526"], "52-[-2]-7-[+2]-162-[-1]-42-[-1]-137")
        self.assertEqual(record.diagrams["chr13:3866266-3866766"], "241-[+1]-2-[-1]-217")
        self.assertEqual(record.diagrams["chr1:133343883-133344383"], "190-[+2]-15-[+1]-245")
        self.assertEqual(record.diagrams["chr11:117187372-117187872"], "242-[+1]-46-[-2]-71-[+1]-71")
        self.assertEqual(record.diagrams["chr13:76003199-76003699"], "230-[+2]-15-[+2]-60-[-1]-115")
        self.assertEqual(record.diagrams["chr5:65202593-65203093"], "24-[-2]-36-[+2]-193-[-1]-11-[+1]-10-[+1]-106")
        self.assertEqual(record.diagrams["chr14:79702844-79703344"], "247-[-1]-46-[-2]-157")
        self.assertEqual(record.diagrams["chr12:112796794-112797294"], "232-[+1]-41-[+1]-187")
        self.assertEqual(record.diagrams["chr13:112863645-112864145"], "228-[+1]-20-[-1]-212")
        self.assertEqual(record.diagrams["chr7:111007530-111008030"], "217-[+1]-83-[+2]-150")
        self.assertEqual(record.diagrams["chr1:43307690-43308190"], "164-[-2]-52-[-2]-224")
        self.assertEqual(record.diagrams["chr14:47973722-47974222"], "21-[+1]-181-[+1]-20-[-2]-208")
        self.assertEqual(record.diagrams["chr9:120025371-120025871"], "110-[-2]-58-[+1]-282")
        self.assertEqual(record.diagrams["chr7:105490727-105491227"], "100-[-2]-111-[-1]-239")
        self.assertEqual(record.diagrams["chr5:37127175-37127675"], "234-[-2]-24-[+1]-192")
        self.assertEqual(record.diagrams["chr5:45951565-45952065"], "261-[-1]-219")
        self.assertEqual(record.diagrams["chr7:91033422-91033922"], "465-[-1]-15")
        self.assertEqual(record.diagrams["chr4:154285745-154286245"], "235-[+1]-20-[-2]-195")
        self.assertEqual(record.diagrams["chr13:100518008-100518508"], "226-[-2]-18-[-1]-206")
        self.assertEqual(record.diagrams["chr1:36977019-36977519"], "88-[+1]-187-[+2]-60-[-1]-95")
        self.assertEqual(record.diagrams["chr7:151917814-151918314"], "219-[+1]-80-[+2]-151")
        self.assertEqual(record.diagrams["chr7:110976195-110976695"], "287-[+2]-12-[+1]-151")
        self.assertEqual(record.diagrams["chr15:58719281-58719781"], "212-[-2]-258")
        self.assertEqual(record.diagrams["chr11:57590460-57590960"], "56-[-1]-271-[-1]-75-[+2]-28")
        self.assertEqual(record.diagrams["chr8:83025150-83025650"], "219-[+1]-87-[+2]-144")
        self.assertEqual(record.diagrams["chr13:54345922-54346422"], "283-[-2]-161-[+1]-6")
        self.assertEqual(record.diagrams["chr12:82044358-82044858"], "50-[+2]-160-[+1]-39-[+2]-171")
        self.assertEqual(record.diagrams["chr11:105013714-105014214"], "115-[-2]-160-[+1]-26-[-1]-129")
        self.assertEqual(record.diagrams["chr10:93585404-93585904"], "141-[+2]-48-[+1]-261")
        self.assertEqual(record.diagrams["chr7:19832207-19832707"], "229-[-1]-251")
        self.assertEqual(record.diagrams["chr8:97323995-97324495"], "177-[-1]-40-[-2]-139-[+1]-74")
        self.assertEqual(record.diagrams["chr10:126642277-126642777"], "252-[-1]-92-[-2]-106")
        self.assertEqual(record.diagrams["chr1:156887119-156887619"], "189-[-2]-78-[-1]-183")
        self.assertEqual(record.diagrams["chr15:81700367-81700867"], "109-[-1]-99-[-1]-252")
        self.assertEqual(record.diagrams["chr6:121187425-121187925"], "29-[+2]-313-[-1]-108")
        self.assertEqual(record.diagrams["chr4:43977111-43977611"], "60-[+1]-148-[+1]-252")
        self.assertEqual(record.diagrams["chr11:102236405-102236905"], "10-[+2]-145-[-1]-3-[-1]-6-[+2]-60-[+1]-156")
        self.assertEqual(record.diagrams["chr17:5112057-5112557"], "249-[+1]-231")
        self.assertEqual(record.diagrams["chr10:110604369-110604869"], "232-[+1]-248")
        self.assertEqual(record.diagrams["chr1:169314208-169314708"], "192-[-1]-[-1]-11-[-2]-227")
        self.assertEqual(record.diagrams["chr9:57618594-57619094"], "125-[+2]-151-[-1]-4-[-1]-150")
        self.assertEqual(record.diagrams["chr10:128184604-128185104"], "30-[-2]-128-[+1]-292")
        self.assertEqual(record.diagrams["chr4:109112541-109113041"], "21-[-1]-13-[+1]-94-[+2]-302")
        self.assertEqual(record.diagrams["chr3:97461668-97462168"], "18-[+2]-256-[-1]-81-[+1]-21-[+1]-34")
        self.assertEqual(record.diagrams["chr9:102674395-102674895"], "372-[+2]-98")
        self.assertEqual(record.diagrams["chr17:24289205-24289705"], "262-[-1]-218")
        self.assertEqual(record.diagrams["chr17:28960252-28960752"], "221-[+1]-81-[+1]-158")
        self.assertEqual(record.diagrams["chr2:73323093-73323593"], "49-[-2]-421")
        self.assertEqual(record.diagrams["chr11:32150818-32151318"], "151-[-1]-27-[-1]-118-[-2]-134")
        self.assertEqual(record.diagrams["chr7:103853792-103854292"], "212-[-2]-42-[+1]-196")
        self.assertEqual(record.diagrams["chr16:49839621-49840121"], "192-[+2]-47-[-1]-17-[+2]-164")
        self.assertEqual(record.diagrams["chr6:135115628-135116128"], "231-[-1]-249")
        self.assertEqual(record.diagrams["chr3:88305500-88306000"], "229-[+1]-251")
        self.assertEqual(record.diagrams["chr18:57137388-57137888"], "296-[+2]-174")
        self.assertEqual(record.diagrams["chr5:97380648-97381148"], "188-[-2]-282")
        self.assertEqual(record.diagrams["chr15:91082416-91082916"], "239-[-1]-104-[-1]-73-[+2]-14")
        self.assertEqual(record.diagrams["chr14:61272713-61273213"], "216-[+2]-104-[+1]-130")
        self.assertEqual(record.diagrams["chr5:33616214-33616714"], "247-[-1]-233")
        self.assertEqual(record.diagrams["chr18:23982470-23982970"], "285-[-1]-195")
        self.assertEqual(record.diagrams["chr9:24715045-24715545"], "214-[-1]-153-[+1]-93")
        self.assertEqual(record.diagrams["chr10:116195445-116195945"], "400-[+2]-70")
        self.assertEqual(record.diagrams["chr11:77795184-77795684"], "247-[+1]-42-[-2]-67-[-2]-64")
        self.assertEqual(record.diagrams["chr16:32508975-32509475"], "213-[+2]-29-[-1]-208")
        self.assertEqual(record.diagrams["chr18:80416880-80417380"], "239-[-1]-241")
        self.assertEqual(record.diagrams["chr10:57252236-57252736"], "155-[+1]-158-[+2]-137")
        self.assertEqual(record.diagrams["chr5:34915767-34916267"], "179-[+2]-29-[-1]-242")
        self.assertEqual(record.diagrams["chr9:98389943-98390443"], "252-[-1]-228")
        self.assertEqual(record.diagrams["chr19:5845899-5846399"], "136-[+1]-193-[+1]-131")
        self.assertEqual(record.diagrams["chr3:151777796-151778296"], "30-[-2]-58-[-1]-362")
        self.assertEqual(record.diagrams["chr4:76585120-76585620"], "329-[+2]-141")
        self.assertEqual(record.diagrams["chr7:104332488-104332988"], "164-[+2]-23-[-1]-222-[+1]-21")
        self.assertEqual(record.diagrams["chr5:138127197-138127697"], "238-[+1]-242")
        self.assertEqual(record.diagrams["chr11:60988820-60989320"], "115-[+1]-68-[+1]-47-[+1]-210")
        self.assertEqual(record.diagrams["chr8:19984030-19984530"], "103-[-1]-81-[+2]-266")
        self.assertEqual(record.diagrams["chr11:31712262-31712762"], "118-[+2]-53-[+2]-269")
        self.assertEqual(record.diagrams["chr15:41338514-41339014"], "173-[+2]-75-[+2]-192")
        self.assertEqual(record.diagrams["chr9:21362671-21363171"], "105-[+1]-131-[+1]-224")
        self.assertEqual(record.diagrams["chr18:58822702-58823202"], "467-[-2]-3")
        self.assertEqual(record.diagrams["chr1:173447614-173448114"], "369-[-1]-111")
        self.assertEqual(record.diagrams["chr6:81915769-81916269"], "197-[+1]-283")
        self.assertEqual(record.diagrams["chr1:169322898-169323398"], "253-[-1]-227")
        self.assertEqual(record.diagrams["chr12:70860461-70860961"], "197-[+2]-22-[-1]-231")
        self.assertEqual(record.diagrams["chr9:59598186-59598686"], "163-[-2]-10-[-1]-277")
        self.assertEqual(record.diagrams["chr3:19550495-19550995"], "452-[-2]-18")
        self.assertEqual(record.diagrams["chr7:36132953-36133453"], "157-[-1]-323")
        self.assertEqual(record.diagrams["chr7:38970375-38970875"], "49-[+1]-114-[+1]-297")
        self.assertEqual(record.diagrams["chr15:78243390-78243890"], "234-[+1]-246")
        self.assertEqual(record.diagrams["chr7:87847381-87847881"], "99-[+2]-2-[-1]-230-[-1]-99")
        self.assertEqual(record.diagrams["chr1:33631214-33631714"], "358-[-1]-122")
        self.assertEqual(record.diagrams["chr4:135407873-135408373"], "116-[-1]-64-[+2]-270")
        self.assertEqual(record.diagrams["chr7:101244829-101245329"], "311-[-2]-159")
        self.assertEqual(record.diagrams["chr10:60612190-60612690"], "215-[+1]-265")
        self.assertEqual(record.diagrams["chr19:56465963-56466463"], "306-[+1]-36-[+1]-18-[+1]-80")
        self.assertEqual(record.diagrams["chr4:41334759-41335259"], "204-[+1]-276")
        self.assertEqual(record.diagrams["chr8:92969521-92970021"], "453-[+2]-17")
        self.assertEqual(record.diagrams["chr6:145703215-145703715"], "154-[-2]-58-[+2]-228")
        self.assertEqual(record.diagrams["chr13:57679178-57679678"], "217-[-1]-263")
        self.assertEqual(record.diagrams["chr19:45121628-45122128"], "35-[-2]-435")
        self.assertEqual(record.diagrams["chr15:79757891-79758391"], "310-[+1]-170")
        self.assertEqual(record.diagrams["chr1:134264178-134264678"], "23-[+2]-447")
        self.assertEqual(record.diagrams["chr13:81067500-81068000"], "252-[+1]-228")
        self.assertEqual(record.diagrams["chr11:69714224-69714724"], "145-[+2]-325")
        self.assertEqual(record.diagrams["chr2:103728071-103728571"], "369-[+1]-111")
        self.assertEqual(record.diagrams["chr5:105994747-105995247"], "93-[+2]-153-[-2]-194")
        self.assertEqual(record.diagrams["chr17:84209565-84210065"], "64-[-2]-406")
        self.assertEqual(record.diagrams["chr7:16507689-16508189"], "231-[+2]-239")


class TestTransfac(unittest.TestCase):
    """Transfac format tests."""

    def test_transfac_parser(self):
        """Parse motifs/transfac.dat file."""
        with open("motifs/transfac.dat") as handle:
            record = motifs.parse(handle, "TRANSFAC")
        motif = record[0]
        self.assertEqual(motif["ID"], "motif1")
        self.assertEqual(len(motif.counts), 4)
        self.assertEqual(motif.counts.length, 12)
        self.assertEqual(motif.counts["A", 0], 1)
        self.assertEqual(motif.counts["A", 1], 2)
        self.assertEqual(motif.counts["A", 2], 3)
        self.assertEqual(motif.counts["A", 3], 0)
        self.assertEqual(motif.counts["A", 4], 5)
        self.assertEqual(motif.counts["A", 5], 0)
        self.assertEqual(motif.counts["A", 6], 0)
        self.assertEqual(motif.counts["A", 7], 0)
        self.assertEqual(motif.counts["A", 8], 0)
        self.assertEqual(motif.counts["A", 9], 0)
        self.assertEqual(motif.counts["A", 10], 0)
        self.assertEqual(motif.counts["A", 11], 1)
        self.assertEqual(motif.counts["C", 0], 2)
        self.assertEqual(motif.counts["C", 1], 1)
        self.assertEqual(motif.counts["C", 2], 0)
        self.assertEqual(motif.counts["C", 3], 5)
        self.assertEqual(motif.counts["C", 4], 0)
        self.assertEqual(motif.counts["C", 5], 0)
        self.assertEqual(motif.counts["C", 6], 1)
        self.assertEqual(motif.counts["C", 7], 0)
        self.assertEqual(motif.counts["C", 8], 0)
        self.assertEqual(motif.counts["C", 9], 1)
        self.assertEqual(motif.counts["C", 10], 2)
        self.assertEqual(motif.counts["C", 11], 0)
        self.assertEqual(motif.counts["G", 0], 2)
        self.assertEqual(motif.counts["G", 1], 2)
        self.assertEqual(motif.counts["G", 2], 1)
        self.assertEqual(motif.counts["G", 3], 0)
        self.assertEqual(motif.counts["G", 4], 0)
        self.assertEqual(motif.counts["G", 5], 4)
        self.assertEqual(motif.counts["G", 6], 4)
        self.assertEqual(motif.counts["G", 7], 0)
        self.assertEqual(motif.counts["G", 8], 5)
        self.assertEqual(motif.counts["G", 9], 2)
        self.assertEqual(motif.counts["G", 10], 0)
        self.assertEqual(motif.counts["G", 11], 3)
        self.assertEqual(motif.counts["T", 0], 0)
        self.assertEqual(motif.counts["T", 1], 0)
        self.assertEqual(motif.counts["T", 2], 1)
        self.assertEqual(motif.counts["T", 3], 0)
        self.assertEqual(motif.counts["T", 4], 0)
        self.assertEqual(motif.counts["T", 5], 1)
        self.assertEqual(motif.counts["T", 6], 0)
        self.assertEqual(motif.counts["T", 7], 5)
        self.assertEqual(motif.counts["T", 8], 0)
        self.assertEqual(motif.counts["T", 9], 2)
        self.assertEqual(motif.counts["T", 10], 3)
        self.assertEqual(motif.counts["T", 11], 1)
        self.assertEqual(str(motif.counts.degenerate_consensus), "SRACAGGTGKYG")
        motif = record[1]
        self.assertEqual(motif["ID"], "motif2")
        self.assertEqual(len(motif.counts), 4)
        self.assertEqual(motif.counts.length, 10)
        self.assertEqual(motif.counts["A", 0], 2)
        self.assertEqual(motif.counts["A", 1], 1)
        self.assertEqual(motif.counts["A", 2], 0)
        self.assertEqual(motif.counts["A", 3], 3)
        self.assertEqual(motif.counts["A", 4], 0)
        self.assertEqual(motif.counts["A", 5], 5)
        self.assertEqual(motif.counts["A", 6], 0)
        self.assertEqual(motif.counts["A", 7], 0)
        self.assertEqual(motif.counts["A", 8], 0)
        self.assertEqual(motif.counts["A", 9], 0)
        self.assertEqual(motif.counts["C", 0], 1)
        self.assertEqual(motif.counts["C", 1], 2)
        self.assertEqual(motif.counts["C", 2], 5)
        self.assertEqual(motif.counts["C", 3], 0)
        self.assertEqual(motif.counts["C", 4], 0)
        self.assertEqual(motif.counts["C", 5], 0)
        self.assertEqual(motif.counts["C", 6], 1)
        self.assertEqual(motif.counts["C", 7], 0)
        self.assertEqual(motif.counts["C", 8], 0)
        self.assertEqual(motif.counts["C", 9], 2)
        self.assertEqual(motif.counts["G", 0], 2)
        self.assertEqual(motif.counts["G", 1], 2)
        self.assertEqual(motif.counts["G", 2], 0)
        self.assertEqual(motif.counts["G", 3], 1)
        self.assertEqual(motif.counts["G", 4], 4)
        self.assertEqual(motif.counts["G", 5], 0)
        self.assertEqual(motif.counts["G", 6], 4)
        self.assertEqual(motif.counts["G", 7], 5)
        self.assertEqual(motif.counts["G", 8], 0)
        self.assertEqual(motif.counts["G", 9], 0)
        self.assertEqual(motif.counts["T", 0], 0)
        self.assertEqual(motif.counts["T", 1], 0)
        self.assertEqual(motif.counts["T", 2], 0)
        self.assertEqual(motif.counts["T", 3], 1)
        self.assertEqual(motif.counts["T", 4], 1)
        self.assertEqual(motif.counts["T", 5], 0)
        self.assertEqual(motif.counts["T", 6], 0)
        self.assertEqual(motif.counts["T", 7], 0)
        self.assertEqual(motif.counts["T", 8], 5)
        self.assertEqual(motif.counts["T", 9], 3)
        self.assertEqual(str(motif.counts.degenerate_consensus), "RSCAGAGGTY")

    def test_permissive_transfac_parser(self):
        """Parse the TRANSFAC-like file motifs/MA0056.1.transfac."""
        # The test file MA0056.1.transfac was provided by the JASPAR database
        # in a TRANSFAC-like format
        # Khan, A. et al. JASPAR 2018: update of the open-access database of
        # transcription factor binding profiles and its web framework.
        # Nucleic Acids Res. 2018; 46:D260-D266,
        path = "motifs/MA0056.1.transfac"
        with open(path) as handle:
            self.assertRaises(ValueError, motifs.parse, handle, "TRANSFAC")
        with open(path) as handle:
            records = motifs.parse(handle, "TRANSFAC", strict=False)
        motif = records[0]
        self.assertEqual(sorted(motif.keys()), ["AC", "DE", "ID"])
        self.assertEqual(motif["AC"], "MA0056.1")
        self.assertEqual(motif["DE"], "MA0056.1 MZF1 ; From JASPAR 2018")
        self.assertEqual(motif["ID"], "MZF1")
        self.assertEqual(motif.counts.length, 6)
        self.assertEqual(len(motif.counts), 4)
        self.assertEqual(motif.counts["A", 0], 3.0)
        self.assertEqual(motif.counts["A", 1], 0.0)
        self.assertEqual(motif.counts["A", 2], 2.0)
        self.assertEqual(motif.counts["A", 3], 0.0)
        self.assertEqual(motif.counts["A", 4], 0.0)
        self.assertEqual(motif.counts["A", 5], 18.0)
        self.assertEqual(motif.counts["C", 0], 5.0)
        self.assertEqual(motif.counts["C", 1], 0.0)
        self.assertEqual(motif.counts["C", 2], 0.0)
        self.assertEqual(motif.counts["C", 3], 0.0)
        self.assertEqual(motif.counts["C", 4], 0.0)
        self.assertEqual(motif.counts["C", 5], 0.0)
        self.assertEqual(motif.counts["G", 0], 4.0)
        self.assertEqual(motif.counts["G", 1], 19.0)
        self.assertEqual(motif.counts["G", 2], 18.0)
        self.assertEqual(motif.counts["G", 3], 19.0)
        self.assertEqual(motif.counts["G", 4], 20.0)
        self.assertEqual(motif.counts["G", 5], 2.0)
        self.assertEqual(motif.counts["T", 0], 8.0)
        self.assertEqual(motif.counts["T", 1], 1.0)
        self.assertEqual(motif.counts["T", 2], 0.0)
        self.assertEqual(motif.counts["T", 3], 1.0)
        self.assertEqual(motif.counts["T", 4], 0.0)
        self.assertEqual(motif.counts["T", 5], 0.0)


class MotifTestPWM(unittest.TestCase):
    """PWM motif tests."""

    def setUp(self):
        """Define motif and sequence for tests."""
        with open("motifs/SRF.pfm") as handle:
            self.m = motifs.read(handle, "pfm")
        self.s = Seq("ACGTGTGCGTAGTGCGT", self.m.alphabet)

    def test_simple(self):
        """Test if Bio.motifs PWM scoring works."""
        counts = self.m.counts
        pwm = counts.normalize(pseudocounts=0.25)
        pssm = pwm.log_odds()
        result = pssm.calculate(self.s)
        self.assertEqual(6, len(result))
        # The fast C-code in Bio/motifs/_pwm.c stores all results as 32-bit
        # floats; the slower Python code in Bio/motifs/__init__.py uses 64-bit
        # doubles. The C-code and Python code results will therefore not be
        # exactly equal. Test the first 5 decimal places only to avoid either
        # the C-code or the Python code to inadvertently fail this test.
        self.assertAlmostEqual(result[0], -29.18363571, places=5)
        self.assertAlmostEqual(result[1], -38.3365097, places=5)
        self.assertAlmostEqual(result[2], -29.17756271, places=5)
        self.assertAlmostEqual(result[3], -38.04542542, places=5)
        self.assertAlmostEqual(result[4], -20.3014183, places=5)
        self.assertAlmostEqual(result[5], -25.18009186, places=5)

    def test_with_alt_alphabet(self):
        """Test motif search using alternative instance of alphabet."""
        self.s = Seq(str(self.s), IUPAC.IUPACUnambiguousDNA())
        self.test_simple()

    def test_with_mixed_case(self):
        """Test if Bio.motifs PWM scoring works with mixed case."""
        counts = self.m.counts
        pwm = counts.normalize(pseudocounts=0.25)
        pssm = pwm.log_odds()
        # Note we're breaking Seq/Alphabet expectations here:
        result = pssm.calculate(Seq("AcGTgTGCGtaGTGCGT", self.m.alphabet))
        self.assertEqual(6, len(result))
        self.assertAlmostEqual(result[0], -29.18363571, places=5)
        self.assertAlmostEqual(result[1], -38.3365097, places=5)
        self.assertAlmostEqual(result[2], -29.17756271, places=5)
        self.assertAlmostEqual(result[3], -38.04542542, places=5)
        self.assertAlmostEqual(result[4], -20.3014183, places=5)
        self.assertAlmostEqual(result[5], -25.18009186, places=5)

    def test_with_bad_char(self):
        """Test if Bio.motifs PWM scoring works with unexpected letters like N."""
        counts = self.m.counts
        pwm = counts.normalize(pseudocounts=0.25)
        pssm = pwm.log_odds()
        result = pssm.calculate(Seq("ACGTGTGCGTAGTGCGTN", self.m.alphabet))
        self.assertEqual(7, len(result))
        self.assertAlmostEqual(result[0], -29.18363571, places=5)
        self.assertAlmostEqual(result[1], -38.3365097, places=5)
        self.assertAlmostEqual(result[2], -29.17756271, places=5)
        self.assertAlmostEqual(result[3], -38.04542542, places=5)
        self.assertAlmostEqual(result[4], -20.3014183, places=5)
        self.assertAlmostEqual(result[5], -25.18009186, places=5)
        self.assertTrue(math.isnan(result[6]), "Expected nan, not %r" % result[6])

    def test_mixed_alphabets(self):
        """Test creating motif with mixed alphabets."""
        # TODO - Can we support this?
        seqs = [Seq("TACAA", IUPAC.unambiguous_dna),
                Seq("TACGC", IUPAC.ambiguous_dna),
                Seq("TACAC", IUPAC.extended_dna),
                Seq("TACCC", Gapped(IUPAC.unambiguous_dna)),
                Seq("AACCC", IUPAC.unambiguous_dna),
                Seq("AATGC", IUPAC.unambiguous_dna),
                Seq("AATGC", generic_dna)]
        # ValueError: Alphabets are inconsistent
        self.assertRaises(ValueError, motifs.create, seqs)

    def test_calculate_pseudocounts(self):
        pseudocounts = motifs.jaspar.calculate_pseudocounts(self.m)
        self.assertAlmostEqual(pseudocounts["A"], 1.695582495781317, places=5)
        self.assertAlmostEqual(pseudocounts["C"], 1.695582495781317, places=5)
        self.assertAlmostEqual(pseudocounts["G"], 1.695582495781317, places=5)
        self.assertAlmostEqual(pseudocounts["T"], 1.695582495781317, places=5)


if __name__ == "__main__":
    runner = unittest.TextTestRunner(verbosity=2)
    unittest.main(testRunner=runner)
