# Copyright 2008 by Bartek Wilczynski.  All rights reserved.
# Revisions copyright 2019 by Victor Lin.
# 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

try:
    import numpy
except ImportError:
    from Bio import MissingExternalDependencyError

    raise MissingExternalDependencyError(
        "Install numpy if you want to use Bio.motifs."
    ) from None

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.PFMFOURCOLUMNSin = open("motifs/fourcolumns.pfm")
        self.PFMFOURROWSin = open("motifs/fourrows.pfm")
        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(record[0].instances[0], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[1], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[2], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[3], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[4], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[5], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[6], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[7], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[8], "TCTACGATTGAG")
        self.assertEqual(record[0].instances[9], "TCAAAGATAGAG")
        self.assertEqual(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(record[1].instances[0], "GCGAAGGAAGCAGCGCGTGTG")
        self.assertEqual(record[1].instances[1], "GGCACCGCCTCTACGATTGAG")
        self.assertEqual(record[1].instances[2], "CAGAGCTTAGCATTGAACGCG")
        self.assertEqual(record[1].instances[3], "CTAATGAAAGCAATGAGAGTG")
        self.assertEqual(record[1].instances[4], "CTTGTGCCCTCTAAGCGTCCG")
        self.assertEqual(record[1].instances[5], "GAGCACGACGCTTTGTACCTG")
        self.assertEqual(record[1].instances[6], "CGGCACTTAGCAGCGTATCGT")
        self.assertEqual(record[1].instances[7], "CTGGTTTCATCTACGATTGAG")
        self.assertEqual(record[1].instances[8], "GGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(record[1].instances[9], "GTGGAGTTATCTTAGTGCGCG")
        self.assertEqual(record[1].instances[10], "GAGAGGTTATCTACGATTGAG")
        self.assertEqual(record[1].instances[11], "CTGCTCCCCGCATACAGCGCG")
        self.assertEqual(record[1].instances[12], "CAGAACCGAGGTCCGGTACGG")
        self.assertEqual(record[1].instances[13], "GTGCCCCAAGCTTACCCAGGG")
        self.assertEqual(record[1].instances[14], "CGCCTCTGATCTACGATTGAG")
        self.assertEqual(record[1].instances[15], "GTGCTCATAGGGACGTCGCGG")
        self.assertEqual(record[1].instances[16], "CTGCCCCCCGCATAGTAGGGG")
        self.assertEqual(record[1].instances[17], "GTAAAGAAATCGATGTGCCAG")
        self.assertEqual(record[1].instances[18], "CACCTGCAATTGCTGGCAGCG")
        self.assertEqual(record[1].instances[19], "GGCGGGCCATCCCTGTATGAA")
        self.assertEqual(record[1].instances[20], "CTCCAGGTCGCATGGAGAGAG")
        self.assertEqual(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(record[2].instances[0], "GTGCGCGAAGGAAGCAGCGCG")
        self.assertEqual(record[2].instances[1], "CAGAGCTTAGCATTGAACGCG")
        self.assertEqual(record[2].instances[2], "GTGCCCGATGACCACCCGTCG")
        self.assertEqual(record[2].instances[3], "GCCCTCTAAGCGTCCGCGGAT")
        self.assertEqual(record[2].instances[4], "GAGCACGACGCTTTGTACCTG")
        self.assertEqual(record[2].instances[5], "CGGCACTTAGCAGCGTATCGT")
        self.assertEqual(record[2].instances[6], "GGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(record[2].instances[7], "GCGCACTAAGATAACTCCACG")
        self.assertEqual(record[2].instances[8], "CGGCCCGTTGTCCAGCAGACG")
        self.assertEqual(record[2].instances[9], "CTGCTCCCCGCATACAGCGCG")
        self.assertEqual(record[2].instances[10], "GTGCCCCAAGCTTACCCAGGG")
        self.assertEqual(record[2].instances[11], "GTGCTCATAGGGACGTCGCGG")
        self.assertEqual(record[2].instances[12], "CTGCCCCCCGCATAGTAGGGG")
        self.assertEqual(record[2].instances[13], "CGCCGCCATGCGACGCAGAGG")
        self.assertEqual(record[2].instances[14], "AACCTCTAAGCATACTCTACG")
        self.assertEqual(record[2].instances[15], "GACCTGGAGGCTTAGACTTGG")
        self.assertEqual(record[2].instances[16], "GCGCTCTTCCCAAGCGATCCG")
        self.assertEqual(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(record[3].instances[0], "GCCCCAAGCTTACCCAGGGAC")
        self.assertEqual(record[3].instances[1], "GCCGTCTGCTGGACAACGGGC")
        self.assertEqual(record[3].instances[2], "GCCGACGGGTGGTCATCGGGC")
        self.assertEqual(record[3].instances[3], "GCCAATAGCGGCGCCGGAGTC")
        self.assertEqual(record[3].instances[4], "GCCCCCCGCATAGTAGGGGGA")
        self.assertEqual(record[3].instances[5], "GCCCGTACCGGACCTCGGTTC")
        self.assertEqual(record[3].instances[6], "GCCTCATGTACCGGAAGGGAC")
        self.assertEqual(record[3].instances[7], "GACACGCGCCTGGGAGGGTTC")
        self.assertEqual(record[3].instances[8], "GCCTTTGGCCTTGGATGAGAA")
        self.assertEqual(record[3].instances[9], "GGCCCTCGGATCGCTTGGGAA")
        self.assertEqual(record[3].instances[10], "GCATGTTGGGAATCCGCGGAC")
        self.assertEqual(record[3].instances[11], "GACACGCGCTGTATGCGGGGA")
        self.assertEqual(record[3].instances[12], "GCCAGGTACAAAGCGTCGTGC")
        self.assertEqual(record[3].instances[13], "GCGATCAGCTTGTGGGCGTGC")
        self.assertEqual(record[3].instances[14], "GACAAATCGGATACTGGGGCA")
        self.assertEqual(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(record[4].instances[0], "CGGCACAGAGCTT")
        self.assertEqual(record[4].instances[1], "ATCCGCGGACGCT")
        self.assertEqual(record[4].instances[2], "CGCCTGGGAGGGT")
        self.assertEqual(record[4].instances[3], "CGGAAGGGACGTT")
        self.assertEqual(record[4].instances[4], "ACACACAGACGGT")
        self.assertEqual(record[4].instances[5], "TGCCAGAGAGGTT")
        self.assertEqual(record[4].instances[6], "AGACTGAGACGTT")
        self.assertEqual(record[4].instances[7], "AATCGTAGAGGAT")
        self.assertEqual(record[4].instances[8], "CGTCTCGTAGGGT")
        self.assertEqual(record[4].instances[9], "CGTCGCGGAGGAT")
        self.assertEqual(record[4].instances[10], "CTTCTTAGACGCT")
        self.assertEqual(record[4].instances[11], "CGACGCAGAGGAT")
        self.assertEqual(record[4].instances[12], "ATGCTTAGAGGTT")
        self.assertEqual(record[4].instances[13], "AGACTTGGGCGAT")
        self.assertEqual(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(record[5].instances[0], "GTGCGCGAAGGAAGCAGCGCGTG")
        self.assertEqual(record[5].instances[1], "TTGAGCCGAGTAAAGGGCTGGTG")
        self.assertEqual(record[5].instances[2], "CAATGCTAAGCTCTGTGCCGACG")
        self.assertEqual(record[5].instances[3], "CAACTCTCTATGTAGTGCCCGAG")
        self.assertEqual(record[5].instances[4], "CGACGCTTTGTACCTGGCTTGCG")
        self.assertEqual(record[5].instances[5], "CGAGTCAATGACACGCGCCTGGG")
        self.assertEqual(record[5].instances[6], "CGATACGCTGCTAAGTGCCGTCC")
        self.assertEqual(record[5].instances[7], "CCGGGCCAATAGCGGCGCCGGAG")
        self.assertEqual(record[5].instances[8], "CCACGCTTCGACACGTGGTATAG")
        self.assertEqual(record[5].instances[9], "CCGAGCCTCATGTACCGGAAGGG")
        self.assertEqual(record[5].instances[10], "CTGCTCCCCGCATACAGCGCGTG")
        self.assertEqual(record[5].instances[11], "CCGAGGTCCGGTACGGGCAAGCC")
        self.assertEqual(record[5].instances[12], "GTGCTCATAGGGACGTCGCGGAG")
        self.assertEqual(record[5].instances[13], "CCCTACTATGCGGGGGGCAGGTC")
        self.assertEqual(record[5].instances[14], "GCCAGCAATTGCAGGTGGTCGTG")
        self.assertEqual(record[5].instances[15], "CTCTGCGTCGCATGGCGGCGTGG")
        self.assertEqual(record[5].instances[16], "GGAGGCTTAGACTTGGGCGATAC")
        self.assertEqual(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(record[6].instances[0], "GCGCGTGTGTGTAAC")
        self.assertEqual(record[6].instances[1], "GCACAGAGCTTAGCA")
        self.assertEqual(record[6].instances[2], "GGTGGTCATCGGGCA")
        self.assertEqual(record[6].instances[3], "GCGCGTGTCATTGAC")
        self.assertEqual(record[6].instances[4], "GGACGGCACTTAGCA")
        self.assertEqual(record[6].instances[5], "GCGCGTCCCGGGCCA")
        self.assertEqual(record[6].instances[6], "GCTCGGCCCGTTGTC")
        self.assertEqual(record[6].instances[7], "GCGCGTGTCCTTTAA")
        self.assertEqual(record[6].instances[8], "GCTGATCGCTGCTCC")
        self.assertEqual(record[6].instances[9], "GCCCGTACCGGACCT")
        self.assertEqual(record[6].instances[10], "GGACGTCGCGGAGGA")
        self.assertEqual(record[6].instances[11], "GCGGGGGGCAGGTCA")
        self.assertEqual(record[6].instances[12], "GGACGTACTGGCACA")
        self.assertEqual(record[6].instances[13], "GCAGGTGGTCGTGCA")
        self.assertEqual(record[6].instances[14], "GCGCATACCTTAACA")
        self.assertEqual(record[6].instances[15], "GCACGGGACTTCAAC")
        self.assertEqual(record[6].instances[16], "GCACGTAGCTGGTAA")
        self.assertEqual(record[6].instances[17], "GCTCGTCTATGGTCA")
        self.assertEqual(record[6].instances[18], "GCGCATGCTGGATCC")
        self.assertEqual(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(record[7].instances[0], "GAACCGAGGTCCGGTACGGGC")
        self.assertEqual(record[7].instances[1], "GCCCCCCGCATAGTAGGGGGA")
        self.assertEqual(record[7].instances[2], "GTCCCTGGGTAAGCTTGGGGC")
        self.assertEqual(record[7].instances[3], "ACTCCACGCTTCGACACGTGG")
        self.assertEqual(record[7].instances[4], "ATCCTCTGCGTCGCATGGCGG")
        self.assertEqual(record[7].instances[5], "GTTCAATGCTAAGCTCTGTGC")
        self.assertEqual(record[7].instances[6], "GCTCATAGGGACGTCGCGGAG")
        self.assertEqual(record[7].instances[7], "GTCCCGGGCCAATAGCGGCGC")
        self.assertEqual(record[7].instances[8], "GCACTTAGCAGCGTATCGTTA")
        self.assertEqual(record[7].instances[9], "GGCCCTCGGATCGCTTGGGAA")
        self.assertEqual(record[7].instances[10], "CTGCTGGACAACGGGCCGAGC")
        self.assertEqual(record[7].instances[11], "GGGCACTACATAGAGAGTTGC")
        self.assertEqual(record[7].instances[12], "AGCCTCCAGGTCGCATGGAGA")
        self.assertEqual(record[7].instances[13], "AATCGTAGATCAGAGGCGAGA")
        self.assertEqual(record[7].instances[14], "GAACTCCACTAAGACTTGAGA")
        self.assertEqual(record[7].instances[15], "GAGCAGCGATCAGCTTGTGGG")
        self.assertEqual(record[7].instances[16], "GCCAGGTACAAAGCGTCGTGC")
        self.assertEqual(record[7].instances[17], "AGTCAATGACACGCGCCTGGG")
        self.assertEqual(record[7].instances[18], "GGTCATGGAATCTTATGTAGC")
        self.assertEqual(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(record[8].instances[0], "CCGAGTAAAGGGCTG")
        self.assertEqual(record[8].instances[1], "GTGGTCATCGGGCAC")
        self.assertEqual(record[8].instances[2], "GATAACAGAGGTCGG")
        self.assertEqual(record[8].instances[3], "CGGCGCCGGAGTCTG")
        self.assertEqual(record[8].instances[4], "GCGCGTCCCGGGCCA")
        self.assertEqual(record[8].instances[5], "CTGGACAACGGGCCG")
        self.assertEqual(record[8].instances[6], "CGGATACTGGGGCAG")
        self.assertEqual(record[8].instances[7], "GGGAGCAGCGATCAG")
        self.assertEqual(record[8].instances[8], "CAGAACCGAGGTCCG")
        self.assertEqual(record[8].instances[9], "GGGTCCCTGGGTAAG")
        self.assertEqual(record[8].instances[10], "GTGCTCATAGGGACG")
        self.assertEqual(record[8].instances[11], "GAGATCCGGAGGAGG")
        self.assertEqual(record[8].instances[12], "GCGATCCGAGGGCCG")
        self.assertEqual(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(record[9].instances[0], "TAGAGGCGGTG")
        self.assertEqual(record[9].instances[1], "GCTAAGCTCTG")
        self.assertEqual(record[9].instances[2], "TGGAAGCAGTG")
        self.assertEqual(record[9].instances[3], "GCGAGGCTGTG")
        self.assertEqual(record[9].instances[4], "ACGACGCTTTG")
        self.assertEqual(record[9].instances[5], "GGGACGCGCAC")
        self.assertEqual(record[9].instances[6], "TCGAAGCGTGG")
        self.assertEqual(record[9].instances[7], "TGTATGCGGGG")
        self.assertEqual(record[9].instances[8], "GGTAAGCTTGG")
        self.assertEqual(record[9].instances[9], "TGTACGCTGGG")
        self.assertEqual(record[9].instances[10], "ACTATGCGGGG")
        self.assertEqual(record[9].instances[11], "GGTATGCGCTG")
        self.assertEqual(record[9].instances[12], "GGTACCCGGAG")
        self.assertEqual(record[9].instances[13], "GCGACGCAGAG")
        self.assertEqual(record[9].instances[14], "TGGCGGCGTGG")
        self.assertEqual(record[9].instances[15], "TCTAGGCGGGC")
        self.assertEqual(record[9].instances[16], "AGTATGCTTAG")
        self.assertEqual(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(record[10].instances[0], "GCACAGAGCTTAGCATTGAAC")
        self.assertEqual(record[10].instances[1], "GTCCGCGGATTCCCAACATGC")
        self.assertEqual(record[10].instances[2], "ATACACAGCCTCGCAAGCCAG")
        self.assertEqual(record[10].instances[3], "GGCCCGGGACGCGCACTAAGA")
        self.assertEqual(record[10].instances[4], "GCCCGTTGTCCAGCAGACGGC")
        self.assertEqual(record[10].instances[5], "GAGCAGCGATCAGCTTGTGGG")
        self.assertEqual(record[10].instances[6], "GAACCGAGGTCCGGTACGGGC")
        self.assertEqual(record[10].instances[7], "GTCCCTGGGTAAGCTTGGGGC")
        self.assertEqual(record[10].instances[8], "GACCTGCCCCCCGCATAGTAG")
        self.assertEqual(record[10].instances[9], "AACCAGCGCATACCTTAACAG")
        self.assertEqual(record[10].instances[10], "ATCCTCTGCGTCGCATGGCGG")
        self.assertEqual(record[10].instances[11], "GACCATAGACGAGCATCAAAG")
        self.assertEqual(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(record[11].instances[0], "GCCGTCCGTC")
        self.assertEqual(record[11].instances[1], "GGCGTGCGCG")
        self.assertEqual(record[11].instances[2], "GGCGCGTGTC")
        self.assertEqual(record[11].instances[3], "AGCGCGTGTG")
        self.assertEqual(record[11].instances[4], "GCGGTGCGTG")
        self.assertEqual(record[11].instances[5], "AGCGCGTGTC")
        self.assertEqual(record[11].instances[6], "AGCGTCCGCG")
        self.assertEqual(record[11].instances[7], "ACCGTCTGTG")
        self.assertEqual(record[11].instances[8], "GCCATGCGAC")
        self.assertEqual(record[11].instances[9], "ACCACCCGTC")
        self.assertEqual(record[11].instances[10], "GGCGCCGGAG")
        self.assertEqual(record[11].instances[11], "ACCACGTGTC")
        self.assertEqual(record[11].instances[12], "GGCTTGCGAG")
        self.assertEqual(record[11].instances[13], "GCGATCCGAG")
        self.assertEqual(record[11].instances[14], "AGTGCGCGTC")
        self.assertEqual(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(record[12].instances[0], "GCCGACGGGTGGTCATCGGG")
        self.assertEqual(record[12].instances[1], "GCACGACGCTTTGTACCTGG")
        self.assertEqual(record[12].instances[2], "CCTGGGAGGGTTCAATAACG")
        self.assertEqual(record[12].instances[3], "GCGCGTCCCGGGCCAATAGC")
        self.assertEqual(record[12].instances[4], "GCCGTCTGCTGGACAACGGG")
        self.assertEqual(record[12].instances[5], "GTCCCTTCCGGTACATGAGG")
        self.assertEqual(record[12].instances[6], "GCTGCTCCCCGCATACAGCG")
        self.assertEqual(record[12].instances[7], "GCCCCAAGCTTACCCAGGGA")
        self.assertEqual(record[12].instances[8], "ACCGGCTGACGCTAATACGG")
        self.assertEqual(record[12].instances[9], "GCGGGGGGCAGGTCATTACA")
        self.assertEqual(record[12].instances[10], "GCTGGCAGCGTCTAAGAAGG")
        self.assertEqual(record[12].instances[11], "GCAGGTGGTCGTGCAATACG")
        self.assertEqual(record[12].instances[12], "GCTGGTTGAAGTCCCGTGCG")
        self.assertEqual(record[12].instances[13], "GCACGTAGCTGGTAAATAGG")
        self.assertEqual(record[12].instances[14], "GCGGCGTGGATTTCATACAG")
        self.assertEqual(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(record[13].instances[0], "GCCGACGGGTGGTCATCGGG")
        self.assertEqual(record[13].instances[1], "ATCCGCGGACGCTTAGAGGG")
        self.assertEqual(record[13].instances[2], "ACGCTTTGTACCTGGCTTGC")
        self.assertEqual(record[13].instances[3], "ACGGACGGCACTTAGCAGCG")
        self.assertEqual(record[13].instances[4], "GCCGTCTGCTGGACAACGGG")
        self.assertEqual(record[13].instances[5], "ACACACAGACGGTTGAAAGG")
        self.assertEqual(record[13].instances[6], "GCCGATAGTGCTTAAGTTCG")
        self.assertEqual(record[13].instances[7], "CTTGCCCGTACCGGACCTCG")
        self.assertEqual(record[13].instances[8], "ACCGGCTGACGCTAATACGG")
        self.assertEqual(record[13].instances[9], "GCCCCCCGCATAGTAGGGGG")
        self.assertEqual(record[13].instances[10], "GCTGGCAGCGTCTAAGAAGG")
        self.assertEqual(record[13].instances[11], "GCAGGTGGTCGTGCAATACG")
        self.assertEqual(record[13].instances[12], "ACGCACGGGACTTCAACCAG")
        self.assertEqual(record[13].instances[13], "GCACGTAGCTGGTAAATAGG")
        self.assertEqual(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(record[14].instances[0], "GAGGCTGTGTAT")
        self.assertEqual(record[14].instances[1], "GAGGTCGGGGGT")
        self.assertEqual(record[14].instances[2], "GACGGACGGCAC")
        self.assertEqual(record[14].instances[3], "TTGGCCCGGGAC")
        self.assertEqual(record[14].instances[4], "GAGGCTCGGCCC")
        self.assertEqual(record[14].instances[5], "CACGCGCTGTAT")
        self.assertEqual(record[14].instances[6], "TAGGCCAGGTAT")
        self.assertEqual(record[14].instances[7], "GAGGTCCGGTAC")
        self.assertEqual(record[14].instances[8], "TACGCTGGGGAT")
        self.assertEqual(record[14].instances[9], "GTCGCGGAGGAT")
        self.assertEqual(record[14].instances[10], "TACGCACGGGAC")
        self.assertEqual(record[14].instances[11], "TACTCCGGGTAC")
        self.assertEqual(record[14].instances[12], "GACGCAGAGGAT")
        self.assertEqual(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(record[15].instances[0], "CGGCTCAATCGTAGAGGC")
        self.assertEqual(record[15].instances[1], "CGACGGGTGGTCATCGGG")
        self.assertEqual(record[15].instances[2], "CGCTTAGAGGGCACAAGC")
        self.assertEqual(record[15].instances[3], "TGACACGCGCCTGGGAGG")
        self.assertEqual(record[15].instances[4], "CGATACGCTGCTAAGTGC")
        self.assertEqual(record[15].instances[5], "CGTCCCGGGCCAATAGCG")
        self.assertEqual(record[15].instances[6], "CCACGCTTCGACACGTGG")
        self.assertEqual(record[15].instances[7], "CGTCTGCTGGACAACGGG")
        self.assertEqual(record[15].instances[8], "ACACAGACGGTTGAAAGG")
        self.assertEqual(record[15].instances[9], "TGCTCCCCGCATACAGCG")
        self.assertEqual(record[15].instances[10], "TGAGGCTTGCCCGTACCG")
        self.assertEqual(record[15].instances[11], "TGCCCCAAGCTTACCCAG")
        self.assertEqual(record[15].instances[12], "CGGCTGACGCTAATACGG")
        self.assertEqual(record[15].instances[13], "CGCGACGTCCCTATGAGC")
        self.assertEqual(record[15].instances[14], "TGCCCCCCGCATAGTAGG")
        self.assertEqual(record[15].instances[15], "CGTTGCCTTCTTAGACGC")
        self.assertEqual(record[15].instances[16], "TGACTCAATCGTAGACCC")
        self.assertEqual(record[15].instances[17], "AGTCCCGTGCGTATGTGG")
        self.assertEqual(record[15].instances[18], "AGGCTCGCACGTAGCTGG")
        self.assertEqual(record[15].instances[19], "CCACGCCGCCATGCGACG")
        self.assertEqual(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_pfm_four_columns_parsing(self):
        """Test if Bio.motifs.pfm can parse motifs in position frequency matrix format (4 columns)."""
        record = motifs.parse(self.PFMFOURCOLUMNSin, "pfm-four-columns")
        self.assertEqual(len(record), 8)
        self.assertEqual(record[0].length, 8)
        self.assertEqual(record[1].length, 20)
        self.assertEqual(record[2].name, "M1734_0.90")
        self.assertEqual(record[2].length, 11)
        self.assertEqual(record[3].name, "AbdA_Cell_FBgn0000014")
        self.assertEqual(record[3].length, 7)
        self.assertEqual(record[4].length, 10)
        self.assertEqual(record[5].name, "AHR_si")
        self.assertEqual(record[5].length, 9)
        self.assertEqual(record[6].length, 8)
        self.assertEqual(record[7].length, 11)

    def test_pfm_four_rows_parsing(self):
        """Test if Bio.motifs.pfm can parse motifs in position frequency matrix format (4 rows)."""
        record = motifs.parse(self.PFMFOURROWSin, "pfm-four-rows")
        self.assertEqual(len(record), 8)
        self.assertEqual(record[0].length, 6)
        self.assertEqual(record[1].length, 15)
        self.assertEqual(record[2].length, 15)
        self.assertEqual(record[3].length, 6)
        self.assertEqual(record[4].length, 6)
        self.assertEqual(record[5].name, "abd-A")
        self.assertEqual(record[5].length, 8)
        self.assertEqual(record[6].name, "MA0001.1 AGL3")
        self.assertEqual(record[6].length, 10)
        self.assertEqual(record[7].name, "MA0001.1 AGL3")
        self.assertEqual(record[7].length, 10)

    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(self.m.format("transfac"))

    def test_format(self):
        self.m.name = "Foo"
        s1 = self.m.format("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 = self.m.format("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 = self.m.format("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, self.m.format, "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 = self.m.format("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 = m.format("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 = m.format("transfac")
        self.assertEqual(received_forward, expected_forward)
        self.assertEqual(str(m.pwm), expected_forward_pwm)
        m = m.reverse_complement()
        received_reverse = m.format("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):
        """Parse motifs/meme.INO_up800.classic.oops.xml file."""
        with open("motifs/meme.INO_up800.classic.oops.xml") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.datafile, "common/INO_up800.s")
        self.assertEqual(record.alphabet, "ACGT")
        self.assertEqual(len(record.sequences), 7)
        self.assertEqual(record.sequences[0], "sequence_0")
        self.assertEqual(record.sequences[1], "sequence_1")
        self.assertEqual(record.sequences[2], "sequence_2")
        self.assertEqual(record.sequences[3], "sequence_3")
        self.assertEqual(record.sequences[4], "sequence_4")
        self.assertEqual(record.sequences[5], "sequence_5")
        self.assertEqual(record.sequences[6], "sequence_6")
        self.assertEqual(
            record.command,
            "meme common/INO_up800.s -oc results/meme10 -mod oops -dna -revcomp -bfile common/yeast.nc.6.freq -nmotifs 2 -objfun classic -minw 8 -nostatus ",
        )
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "GSKGCATGTGAAA")
        self.assertEqual(record["GSKGCATGTGAAA"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 0.19)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 1.21e-08)
        self.assertAlmostEqual(motif.instances[1].pvalue, 1.87e-08)
        self.assertAlmostEqual(motif.instances[2].pvalue, 6.62e-08)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.05e-07)
        self.assertAlmostEqual(motif.instances[4].pvalue, 1.69e-07)
        self.assertAlmostEqual(motif.instances[5].pvalue, 5.62e-07)
        self.assertAlmostEqual(motif.instances[6].pvalue, 1.08e-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].sequence_id, "sequence_5")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_6")
        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, 13)
        self.assertEqual(motif.instances[1].length, 13)
        self.assertEqual(motif.instances[2].length, 13)
        self.assertEqual(motif.instances[3].length, 13)
        self.assertEqual(motif.instances[4].length, 13)
        self.assertEqual(motif.instances[5].length, 13)
        self.assertEqual(motif.instances[6].length, 13)
        self.assertEqual(motif.instances[0].start, 620)
        self.assertEqual(motif.instances[1].start, 94)
        self.assertEqual(motif.instances[2].start, 82)
        self.assertEqual(motif.instances[3].start, 353)
        self.assertEqual(motif.instances[4].start, 639)
        self.assertEqual(motif.instances[5].start, 566)
        self.assertEqual(motif.instances[6].start, 585)
        self.assertEqual(motif.instances[0], "GCGGCATGTGAAA")
        self.assertEqual(motif.instances[1], "GCGGCATGTGAAG")
        self.assertEqual(motif.instances[2], "GGGCCATGTGAAG")
        self.assertEqual(motif.instances[3], "GCGGCATGAGAAA")
        self.assertEqual(motif.instances[4], "GGTCCATGTGAAA")
        self.assertEqual(motif.instances[5], "GTAGCATGTGAAA")
        self.assertEqual(motif.instances[6], "AGTGCATGTGGAA")
        motif = record[1]
        self.assertEqual(motif.name, "TTGACWCYTGCYCWG")
        self.assertEqual(record["TTGACWCYTGCYCWG"], motif)
        self.assertEqual(motif.num_occurrences, 7)
        self.assertAlmostEqual(motif.evalue, 54)
        self.assertEqual(motif.alphabet, "ACGT")
        self.assertEqual(len(motif.instances), 7)
        self.assertAlmostEqual(motif.instances[0].pvalue, 7.2e-10)
        self.assertAlmostEqual(motif.instances[1].pvalue, 2.56e-08)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.59e-07)
        self.assertAlmostEqual(motif.instances[3].pvalue, 2.05e-07)
        self.assertAlmostEqual(motif.instances[4].pvalue, 3.85e-07)
        self.assertAlmostEqual(motif.instances[5].pvalue, 5.11e-07)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.01e-07)
        self.assertEqual(motif.instances[0].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_6")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_5")
        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, 15)
        self.assertEqual(motif.instances[1].length, 15)
        self.assertEqual(motif.instances[2].length, 15)
        self.assertEqual(motif.instances[3].length, 15)
        self.assertEqual(motif.instances[4].length, 15)
        self.assertEqual(motif.instances[5].length, 15)
        self.assertEqual(motif.instances[6].length, 15)
        self.assertEqual(motif.instances[0].start, 104)
        self.assertEqual(motif.instances[1].start, 566)
        self.assertEqual(motif.instances[2].start, 585)
        self.assertEqual(motif.instances[3].start, 30)
        self.assertEqual(motif.instances[4].start, 54)
        self.assertEqual(motif.instances[5].start, 272)
        self.assertEqual(motif.instances[6].start, 214)
        self.assertEqual(motif.instances[0], "TTGACACCTGCCCAG")
        self.assertEqual(motif.instances[1], "TTGACACCTACCCTG")
        self.assertEqual(motif.instances[2], "TTGTCTCTTGCTCTG")
        self.assertEqual(motif.instances[3], "TTGACACTTGATCAG")
        self.assertEqual(motif.instances[4], "TTCACTACTCCCCTG")
        self.assertEqual(motif.instances[5], "TTGACAACGGCTGGG")
        self.assertEqual(motif.instances[6], "TTCACGCTTGCTACG")

    def test_meme_parser_2(self):
        """Parsing motifs/meme.adh.classic.oops.xml file."""
        with open("motifs/meme.adh.classic.oops.xml") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.datafile, "common/adh.s")
        self.assertEqual(record.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(record.sequences), 33)
        self.assertEqual(record.sequences[0], "sequence_0")
        self.assertEqual(record.sequences[1], "sequence_1")
        self.assertEqual(record.sequences[2], "sequence_2")
        self.assertEqual(record.sequences[3], "sequence_3")
        self.assertEqual(record.sequences[4], "sequence_4")
        self.assertEqual(record.sequences[5], "sequence_5")
        self.assertEqual(record.sequences[6], "sequence_6")
        self.assertEqual(record.sequences[7], "sequence_7")
        self.assertEqual(record.sequences[8], "sequence_8")
        self.assertEqual(record.sequences[9], "sequence_9")
        self.assertEqual(record.sequences[10], "sequence_10")
        self.assertEqual(record.sequences[11], "sequence_11")
        self.assertEqual(record.sequences[12], "sequence_12")
        self.assertEqual(record.sequences[13], "sequence_13")
        self.assertEqual(record.sequences[14], "sequence_14")
        self.assertEqual(record.sequences[15], "sequence_15")
        self.assertEqual(record.sequences[16], "sequence_16")
        self.assertEqual(record.sequences[17], "sequence_17")
        self.assertEqual(record.sequences[18], "sequence_18")
        self.assertEqual(record.sequences[19], "sequence_19")
        self.assertEqual(record.sequences[20], "sequence_20")
        self.assertEqual(record.sequences[21], "sequence_21")
        self.assertEqual(record.sequences[22], "sequence_22")
        self.assertEqual(record.sequences[23], "sequence_23")
        self.assertEqual(record.sequences[24], "sequence_24")
        self.assertEqual(record.sequences[25], "sequence_25")
        self.assertEqual(record.sequences[26], "sequence_26")
        self.assertEqual(record.sequences[27], "sequence_27")
        self.assertEqual(record.sequences[28], "sequence_28")
        self.assertEqual(record.sequences[29], "sequence_29")
        self.assertEqual(record.sequences[30], "sequence_30")
        self.assertEqual(record.sequences[31], "sequence_31")
        self.assertEqual(record.sequences[32], "sequence_32")
        self.assertEqual(
            record.command,
            "meme common/adh.s -oc results/meme4 -mod oops -protein -nmotifs 2 -objfun classic -minw 8 -nostatus ",
        )
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.id, "motif_1")
        self.assertEqual(motif.name, "GKVALVTGAASGJGKATAKAL")
        self.assertEqual(motif.alt_id, "MEME-1")
        self.assertEqual(record["GKVALVTGAASGJGKATAKAL"], 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, 8.78e-18)
        self.assertAlmostEqual(motif.instances[1].pvalue, 1.41e-17)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.42e-16)
        self.assertAlmostEqual(motif.instances[3].pvalue, 2.75e-16)
        self.assertAlmostEqual(motif.instances[4].pvalue, 3.55e-16)
        self.assertAlmostEqual(motif.instances[5].pvalue, 3.55e-16)
        self.assertAlmostEqual(motif.instances[6].pvalue, 1.74e-15)
        self.assertAlmostEqual(motif.instances[7].pvalue, 3.87e-15)
        self.assertAlmostEqual(motif.instances[8].pvalue, 4.84e-15)
        self.assertAlmostEqual(motif.instances[9].pvalue, 1.04e-14)
        self.assertAlmostEqual(motif.instances[10].pvalue, 1.58e-14)
        self.assertAlmostEqual(motif.instances[11].pvalue, 1.76e-14)
        self.assertAlmostEqual(motif.instances[12].pvalue, 2.16e-14)
        self.assertAlmostEqual(motif.instances[13].pvalue, 2.94e-14)
        self.assertAlmostEqual(motif.instances[14].pvalue, 3.25e-14)
        self.assertAlmostEqual(motif.instances[15].pvalue, 3.98e-14)
        self.assertAlmostEqual(motif.instances[16].pvalue, 4.39e-14)
        self.assertAlmostEqual(motif.instances[17].pvalue, 4.39e-14)
        self.assertAlmostEqual(motif.instances[18].pvalue, 4.85e-14)
        self.assertAlmostEqual(motif.instances[19].pvalue, 6.52e-14)
        self.assertAlmostEqual(motif.instances[20].pvalue, 1.41e-13)
        self.assertAlmostEqual(motif.instances[21].pvalue, 1.55e-13)
        self.assertAlmostEqual(motif.instances[22].pvalue, 3.07e-12)
        self.assertAlmostEqual(motif.instances[23].pvalue, 5.43e-12)
        self.assertAlmostEqual(motif.instances[24].pvalue, 6.91e-12)
        self.assertAlmostEqual(motif.instances[25].pvalue, 8.76e-12)
        self.assertAlmostEqual(motif.instances[26].pvalue, 9.48e-12)
        self.assertAlmostEqual(motif.instances[27].pvalue, 1.2e-11)
        self.assertAlmostEqual(motif.instances[28].pvalue, 1.19e-09)
        self.assertAlmostEqual(motif.instances[29].pvalue, 1.54e-09)
        self.assertAlmostEqual(motif.instances[30].pvalue, 1.99e-09)
        self.assertAlmostEqual(motif.instances[31].pvalue, 1.42e-06)
        self.assertAlmostEqual(motif.instances[32].pvalue, 3.43e-06)
        self.assertEqual(motif.instances[0].sequence_name, "BUDC_KLETE")
        self.assertEqual(motif.instances[1].sequence_name, "YINL_LISMO")
        self.assertEqual(motif.instances[2].sequence_name, "DHII_HUMAN")
        self.assertEqual(motif.instances[3].sequence_name, "HDE_CANTR")
        self.assertEqual(motif.instances[4].sequence_name, "YRTP_BACSU")
        self.assertEqual(motif.instances[5].sequence_name, "ENTA_ECOLI")
        self.assertEqual(motif.instances[6].sequence_name, "HDHA_ECOLI")
        self.assertEqual(motif.instances[7].sequence_name, "RIDH_KLEAE")
        self.assertEqual(motif.instances[8].sequence_name, "DHB2_HUMAN")
        self.assertEqual(motif.instances[9].sequence_name, "FIXR_BRAJA")
        self.assertEqual(motif.instances[10].sequence_name, "PCR_PEA")
        self.assertEqual(motif.instances[11].sequence_name, "DHCA_HUMAN")
        self.assertEqual(motif.instances[12].sequence_name, "BDH_HUMAN")
        self.assertEqual(motif.instances[13].sequence_name, "3BHD_COMTE")
        self.assertEqual(motif.instances[14].sequence_name, "DHGB_BACME")
        self.assertEqual(motif.instances[15].sequence_name, "DHMA_FLAS1")
        self.assertEqual(motif.instances[16].sequence_name, "FVT1_HUMAN")
        self.assertEqual(motif.instances[17].sequence_name, "BA72_EUBSP")
        self.assertEqual(motif.instances[18].sequence_name, "BPHB_PSEPS")
        self.assertEqual(motif.instances[19].sequence_name, "DHB3_HUMAN")
        self.assertEqual(motif.instances[20].sequence_name, "DHES_HUMAN")
        self.assertEqual(motif.instances[21].sequence_name, "AP27_MOUSE")
        self.assertEqual(motif.instances[22].sequence_name, "2BHD_STREX")
        self.assertEqual(motif.instances[23].sequence_name, "NODG_RHIME")
        self.assertEqual(motif.instances[24].sequence_name, "HMTR_LEIMA")
        self.assertEqual(motif.instances[25].sequence_name, "LIGD_PSEPA")
        self.assertEqual(motif.instances[26].sequence_name, "MAS1_AGRRA")
        self.assertEqual(motif.instances[27].sequence_name, "RFBB_NEIGO")
        self.assertEqual(motif.instances[28].sequence_name, "GUTD_ECOLI")
        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, "CSGA_MYXXA")
        self.assertEqual(motif.instances[32].sequence_name, "YURA_MYXXA")
        self.assertEqual(motif.instances[0].sequence_id, "sequence_7")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_20")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_10")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_15")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_21")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_12")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_16")
        self.assertEqual(motif.instances[7].sequence_id, "sequence_19")
        self.assertEqual(motif.instances[8].sequence_id, "sequence_23")
        self.assertEqual(motif.instances[9].sequence_id, "sequence_13")
        self.assertEqual(motif.instances[10].sequence_id, "sequence_30")
        self.assertEqual(motif.instances[11].sequence_id, "sequence_25")
        self.assertEqual(motif.instances[12].sequence_id, "sequence_5")
        self.assertEqual(motif.instances[13].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[14].sequence_id, "sequence_9")
        self.assertEqual(motif.instances[15].sequence_id, "sequence_11")
        self.assertEqual(motif.instances[16].sequence_id, "sequence_27")
        self.assertEqual(motif.instances[17].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[18].sequence_id, "sequence_6")
        self.assertEqual(motif.instances[19].sequence_id, "sequence_24")
        self.assertEqual(motif.instances[20].sequence_id, "sequence_8")
        self.assertEqual(motif.instances[21].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[22].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[23].sequence_id, "sequence_18")
        self.assertEqual(motif.instances[24].sequence_id, "sequence_28")
        self.assertEqual(motif.instances[25].sequence_id, "sequence_17")
        self.assertEqual(motif.instances[26].sequence_id, "sequence_29")
        self.assertEqual(motif.instances[27].sequence_id, "sequence_31")
        self.assertEqual(motif.instances[28].sequence_id, "sequence_14")
        self.assertEqual(motif.instances[29].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[30].sequence_id, "sequence_26")
        self.assertEqual(motif.instances[31].sequence_id, "sequence_22")
        self.assertEqual(motif.instances[32].sequence_id, "sequence_32")
        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, 21)
        self.assertEqual(motif.instances[1].length, 21)
        self.assertEqual(motif.instances[2].length, 21)
        self.assertEqual(motif.instances[3].length, 21)
        self.assertEqual(motif.instances[4].length, 21)
        self.assertEqual(motif.instances[5].length, 21)
        self.assertEqual(motif.instances[6].length, 21)
        self.assertEqual(motif.instances[7].length, 21)
        self.assertEqual(motif.instances[8].length, 21)
        self.assertEqual(motif.instances[9].length, 21)
        self.assertEqual(motif.instances[10].length, 21)
        self.assertEqual(motif.instances[11].length, 21)
        self.assertEqual(motif.instances[12].length, 21)
        self.assertEqual(motif.instances[13].length, 21)
        self.assertEqual(motif.instances[14].length, 21)
        self.assertEqual(motif.instances[15].length, 21)
        self.assertEqual(motif.instances[16].length, 21)
        self.assertEqual(motif.instances[17].length, 21)
        self.assertEqual(motif.instances[18].length, 21)
        self.assertEqual(motif.instances[19].length, 21)
        self.assertEqual(motif.instances[20].length, 21)
        self.assertEqual(motif.instances[21].length, 21)
        self.assertEqual(motif.instances[22].length, 21)
        self.assertEqual(motif.instances[23].length, 21)
        self.assertEqual(motif.instances[24].length, 21)
        self.assertEqual(motif.instances[25].length, 21)
        self.assertEqual(motif.instances[26].length, 21)
        self.assertEqual(motif.instances[27].length, 21)
        self.assertEqual(motif.instances[28].length, 21)
        self.assertEqual(motif.instances[29].length, 21)
        self.assertEqual(motif.instances[30].length, 21)
        self.assertEqual(motif.instances[31].length, 21)
        self.assertEqual(motif.instances[32].length, 21)
        self.assertEqual(motif.instances[0].start, 2)
        self.assertEqual(motif.instances[1].start, 5)
        self.assertEqual(motif.instances[2].start, 34)
        self.assertEqual(motif.instances[3].start, 322)
        self.assertEqual(motif.instances[4].start, 6)
        self.assertEqual(motif.instances[5].start, 5)
        self.assertEqual(motif.instances[6].start, 11)
        self.assertEqual(motif.instances[7].start, 14)
        self.assertEqual(motif.instances[8].start, 82)
        self.assertEqual(motif.instances[9].start, 36)
        self.assertEqual(motif.instances[10].start, 86)
        self.assertEqual(motif.instances[11].start, 4)
        self.assertEqual(motif.instances[12].start, 55)
        self.assertEqual(motif.instances[13].start, 6)
        self.assertEqual(motif.instances[14].start, 7)
        self.assertEqual(motif.instances[15].start, 14)
        self.assertEqual(motif.instances[16].start, 32)
        self.assertEqual(motif.instances[17].start, 6)
        self.assertEqual(motif.instances[18].start, 5)
        self.assertEqual(motif.instances[19].start, 48)
        self.assertEqual(motif.instances[20].start, 2)
        self.assertEqual(motif.instances[21].start, 7)
        self.assertEqual(motif.instances[22].start, 6)
        self.assertEqual(motif.instances[23].start, 6)
        self.assertEqual(motif.instances[24].start, 6)
        self.assertEqual(motif.instances[25].start, 6)
        self.assertEqual(motif.instances[26].start, 245)
        self.assertEqual(motif.instances[27].start, 6)
        self.assertEqual(motif.instances[28].start, 2)
        self.assertEqual(motif.instances[29].start, 6)
        self.assertEqual(motif.instances[30].start, 6)
        self.assertEqual(motif.instances[31].start, 13)
        self.assertEqual(motif.instances[32].start, 116)
        self.assertEqual(motif.instances[0], "QKVALVTGAGQGIGKAIALRL")
        self.assertEqual(motif.instances[1], "NKVIIITGASSGIGKATALLL")
        self.assertEqual(motif.instances[2], "GKKVIVTGASKGIGREMAYHL")
        self.assertEqual(motif.instances[3], "DKVVLITGAGAGLGKEYAKWF")
        self.assertEqual(motif.instances[4], "HKTALITGGGRGIGRATALAL")
        self.assertEqual(motif.instances[5], "GKNVWVTGAGKGIGYATALAF")
        self.assertEqual(motif.instances[6], "GKCAIITGAGAGIGKEIAITF")
        self.assertEqual(motif.instances[7], "GKVAAITGAASGIGLECARTL")
        self.assertEqual(motif.instances[8], "QKAVLVTGGDCGLGHALCKYL")
        self.assertEqual(motif.instances[9], "PKVMLLTGASRGIGHATAKLF")
        self.assertEqual(motif.instances[10], "KGNVVITGASSGLGLATAKAL")
        self.assertEqual(motif.instances[11], "IHVALVTGGNKGIGLAIVRDL")
        self.assertEqual(motif.instances[12], "SKAVLVTGCDSGFGFSLAKHL")
        self.assertEqual(motif.instances[13], "GKVALVTGGASGVGLEVVKLL")
        self.assertEqual(motif.instances[14], "GKVVVITGSSTGLGKSMAIRF")
        self.assertEqual(motif.instances[15], "GKAAIVTGAAGGIGRATVEAY")
        self.assertEqual(motif.instances[16], "GAHVVVTGGSSGIGKCIAIEC")
        self.assertEqual(motif.instances[17], "DKVTIITGGTRGIGFAAAKIF")
        self.assertEqual(motif.instances[18], "GEAVLITGGASGLGRALVDRF")
        self.assertEqual(motif.instances[19], "GQWAVITGAGDGIGKAYSFEL")
        self.assertEqual(motif.instances[20], "RTVVLITGCSSGIGLHLAVRL")
        self.assertEqual(motif.instances[21], "GLRALVTGAGKGIGRDTVKAL")
        self.assertEqual(motif.instances[22], "GKTVIITGGARGLGAEAARQA")
        self.assertEqual(motif.instances[23], "GRKALVTGASGAIGGAIARVL")
        self.assertEqual(motif.instances[24], "VPVALVTGAAKRLGRSIAEGL")
        self.assertEqual(motif.instances[25], "DQVAFITGGASGAGFGQAKVF")
        self.assertEqual(motif.instances[26], "SPVILVSGSNRGVGKAIAEDL")
        self.assertEqual(motif.instances[27], "KKNILVTGGAGFIGSAVVRHI")
        self.assertEqual(motif.instances[28], "NQVAVVIGGGQTLGAFLCHGL")
        self.assertEqual(motif.instances[29], "NKNVIFVAGLGGIGLDTSKEL")
        self.assertEqual(motif.instances[30], "GKRILVTGVASKLSIAYGIAQ")
        self.assertEqual(motif.instances[31], "VDVLINNAGVSGLWCALGDVD")
        self.assertEqual(motif.instances[32], "IIDTNVTGAAATLSAVLPQMV")
        motif = record[1]
        self.assertEqual(motif.name, "VGNPGASAYSASKAAVRGLTESLALELAP")
        self.assertEqual(motif.alt_id, "MEME-2")
        self.assertEqual(record["VGNPGASAYSASKAAVRGLTESLALELAP"], motif)
        self.assertEqual(motif.num_occurrences, 33)
        self.assertAlmostEqual(motif.evalue, 3.1e-130)
        self.assertEqual(motif.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(motif.instances), 33)
        self.assertAlmostEqual(motif.instances[0].pvalue, 2.09e-21)
        self.assertAlmostEqual(motif.instances[1].pvalue, 7.63e-20)
        self.assertAlmostEqual(motif.instances[2].pvalue, 6.49e-19)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.92e-18)
        self.assertAlmostEqual(motif.instances[4].pvalue, 5.46e-18)
        self.assertAlmostEqual(motif.instances[5].pvalue, 6.21e-18)
        self.assertAlmostEqual(motif.instances[6].pvalue, 4.52e-17)
        self.assertAlmostEqual(motif.instances[7].pvalue, 4.52e-17)
        self.assertAlmostEqual(motif.instances[8].pvalue, 9.21e-17)
        self.assertAlmostEqual(motif.instances[9].pvalue, 1.65e-16)
        self.assertAlmostEqual(motif.instances[10].pvalue, 2.07e-16)
        self.assertAlmostEqual(motif.instances[11].pvalue, 3.65e-16)
        self.assertAlmostEqual(motif.instances[12].pvalue, 5.7e-16)
        self.assertAlmostEqual(motif.instances[13].pvalue, 5.7e-16)
        self.assertAlmostEqual(motif.instances[14].pvalue, 7.93e-16)
        self.assertAlmostEqual(motif.instances[15].pvalue, 8.85e-16)
        self.assertAlmostEqual(motif.instances[16].pvalue, 1.1e-15)
        self.assertAlmostEqual(motif.instances[17].pvalue, 1.69e-15)
        self.assertAlmostEqual(motif.instances[18].pvalue, 3.54e-15)
        self.assertAlmostEqual(motif.instances[19].pvalue, 4.83e-15)
        self.assertAlmostEqual(motif.instances[20].pvalue, 7.27e-15)
        self.assertAlmostEqual(motif.instances[21].pvalue, 9.85e-15)
        self.assertAlmostEqual(motif.instances[22].pvalue, 2.41e-14)
        self.assertAlmostEqual(motif.instances[23].pvalue, 2.66e-14)
        self.assertAlmostEqual(motif.instances[24].pvalue, 1.22e-13)
        self.assertAlmostEqual(motif.instances[25].pvalue, 5.18e-13)
        self.assertAlmostEqual(motif.instances[26].pvalue, 1.24e-12)
        self.assertAlmostEqual(motif.instances[27].pvalue, 1.35e-12)
        self.assertAlmostEqual(motif.instances[28].pvalue, 5.59e-12)
        self.assertAlmostEqual(motif.instances[29].pvalue, 1.44e-10)
        self.assertAlmostEqual(motif.instances[30].pvalue, 1.61e-08)
        self.assertAlmostEqual(motif.instances[31].pvalue, 4.26e-08)
        self.assertAlmostEqual(motif.instances[32].pvalue, 1.16e-07)
        self.assertEqual(motif.instances[0].sequence_name, "BUDC_KLETE")
        self.assertEqual(motif.instances[1].sequence_name, "NODG_RHIME")
        self.assertEqual(motif.instances[2].sequence_name, "FVT1_HUMAN")
        self.assertEqual(motif.instances[3].sequence_name, "DHES_HUMAN")
        self.assertEqual(motif.instances[4].sequence_name, "DHB3_HUMAN")
        self.assertEqual(motif.instances[5].sequence_name, "YRTP_BACSU")
        self.assertEqual(motif.instances[6].sequence_name, "HMTR_LEIMA")
        self.assertEqual(motif.instances[7].sequence_name, "HDE_CANTR")
        self.assertEqual(motif.instances[8].sequence_name, "DHGB_BACME")
        self.assertEqual(motif.instances[9].sequence_name, "GUTD_ECOLI")
        self.assertEqual(motif.instances[10].sequence_name, "3BHD_COMTE")
        self.assertEqual(motif.instances[11].sequence_name, "DHII_HUMAN")
        self.assertEqual(motif.instances[12].sequence_name, "BPHB_PSEPS")
        self.assertEqual(motif.instances[13].sequence_name, "AP27_MOUSE")
        self.assertEqual(motif.instances[14].sequence_name, "BDH_HUMAN")
        self.assertEqual(motif.instances[15].sequence_name, "YINL_LISMO")
        self.assertEqual(motif.instances[16].sequence_name, "FIXR_BRAJA")
        self.assertEqual(motif.instances[17].sequence_name, "2BHD_STREX")
        self.assertEqual(motif.instances[18].sequence_name, "RFBB_NEIGO")
        self.assertEqual(motif.instances[19].sequence_name, "YURA_MYXXA")
        self.assertEqual(motif.instances[20].sequence_name, "RIDH_KLEAE")
        self.assertEqual(motif.instances[21].sequence_name, "DHMA_FLAS1")
        self.assertEqual(motif.instances[22].sequence_name, "DHB2_HUMAN")
        self.assertEqual(motif.instances[23].sequence_name, "HDHA_ECOLI")
        self.assertEqual(motif.instances[24].sequence_name, "ENTA_ECOLI")
        self.assertEqual(motif.instances[25].sequence_name, "LIGD_PSEPA")
        self.assertEqual(motif.instances[26].sequence_name, "CSGA_MYXXA")
        self.assertEqual(motif.instances[27].sequence_name, "BA72_EUBSP")
        self.assertEqual(motif.instances[28].sequence_name, "ADH_DROME")
        self.assertEqual(motif.instances[29].sequence_name, "MAS1_AGRRA")
        self.assertEqual(motif.instances[30].sequence_name, "PCR_PEA")
        self.assertEqual(motif.instances[31].sequence_name, "FABI_ECOLI")
        self.assertEqual(motif.instances[32].sequence_name, "DHCA_HUMAN")
        self.assertEqual(motif.instances[0].sequence_id, "sequence_7")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_18")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_27")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_8")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_24")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_21")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_28")
        self.assertEqual(motif.instances[7].sequence_id, "sequence_15")
        self.assertEqual(motif.instances[8].sequence_id, "sequence_9")
        self.assertEqual(motif.instances[9].sequence_id, "sequence_14")
        self.assertEqual(motif.instances[10].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[11].sequence_id, "sequence_10")
        self.assertEqual(motif.instances[12].sequence_id, "sequence_6")
        self.assertEqual(motif.instances[13].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[14].sequence_id, "sequence_5")
        self.assertEqual(motif.instances[15].sequence_id, "sequence_20")
        self.assertEqual(motif.instances[16].sequence_id, "sequence_13")
        self.assertEqual(motif.instances[17].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[18].sequence_id, "sequence_31")
        self.assertEqual(motif.instances[19].sequence_id, "sequence_32")
        self.assertEqual(motif.instances[20].sequence_id, "sequence_19")
        self.assertEqual(motif.instances[21].sequence_id, "sequence_11")
        self.assertEqual(motif.instances[22].sequence_id, "sequence_23")
        self.assertEqual(motif.instances[23].sequence_id, "sequence_16")
        self.assertEqual(motif.instances[24].sequence_id, "sequence_12")
        self.assertEqual(motif.instances[25].sequence_id, "sequence_17")
        self.assertEqual(motif.instances[26].sequence_id, "sequence_22")
        self.assertEqual(motif.instances[27].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[28].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[29].sequence_id, "sequence_29")
        self.assertEqual(motif.instances[30].sequence_id, "sequence_30")
        self.assertEqual(motif.instances[31].sequence_id, "sequence_26")
        self.assertEqual(motif.instances[32].sequence_id, "sequence_25")
        self.assertEqual(motif.instances[0].start, 144)
        self.assertEqual(motif.instances[1].start, 144)
        self.assertEqual(motif.instances[2].start, 178)
        self.assertEqual(motif.instances[3].start, 147)
        self.assertEqual(motif.instances[4].start, 190)
        self.assertEqual(motif.instances[5].start, 147)
        self.assertEqual(motif.instances[6].start, 185)
        self.assertEqual(motif.instances[7].start, 459)
        self.assertEqual(motif.instances[8].start, 152)
        self.assertEqual(motif.instances[9].start, 146)
        self.assertEqual(motif.instances[10].start, 143)
        self.assertEqual(motif.instances[11].start, 175)
        self.assertEqual(motif.instances[12].start, 145)
        self.assertEqual(motif.instances[13].start, 141)
        self.assertEqual(motif.instances[14].start, 200)
        self.assertEqual(motif.instances[15].start, 146)
        self.assertEqual(motif.instances[16].start, 181)
        self.assertEqual(motif.instances[17].start, 144)
        self.assertEqual(motif.instances[18].start, 157)
        self.assertEqual(motif.instances[19].start, 152)
        self.assertEqual(motif.instances[20].start, 152)
        self.assertEqual(motif.instances[21].start, 157)
        self.assertEqual(motif.instances[22].start, 224)
        self.assertEqual(motif.instances[23].start, 151)
        self.assertEqual(motif.instances[24].start, 136)
        self.assertEqual(motif.instances[25].start, 149)
        self.assertEqual(motif.instances[26].start, 80)
        self.assertEqual(motif.instances[27].start, 149)
        self.assertEqual(motif.instances[28].start, 144)
        self.assertEqual(motif.instances[29].start, 384)
        self.assertEqual(motif.instances[30].start, 18)
        self.assertEqual(motif.instances[31].start, 177)
        self.assertEqual(motif.instances[32].start, 144)
        self.assertEqual(motif.instances[0], "VGNPELAVYSSSKFAVRGLTQTAARDLAP")
        self.assertEqual(motif.instances[1], "IGNPGQTNYCASKAGMIGFSKSLAQEIAT")
        self.assertEqual(motif.instances[2], "LGLFGFTAYSASKFAIRGLAEALQMEVKP")
        self.assertEqual(motif.instances[3], "MGLPFNDVYCASKFALEGLCESLAVLLLP")
        self.assertEqual(motif.instances[4], "FPWPLYSMYSASKAFVCAFSKALQEEYKA")
        self.assertEqual(motif.instances[5], "RGAAVTSAYSASKFAVLGLTESLMQEVRK")
        self.assertEqual(motif.instances[6], "QPLLGYTIYTMAKGALEGLTRSAALELAP")
        self.assertEqual(motif.instances[7], "YGNFGQANYSSSKAGILGLSKTMAIEGAK")
        self.assertEqual(motif.instances[8], "IPWPLFVHYAASKGGMKLMTETLALEYAP")
        self.assertEqual(motif.instances[9], "VGSKHNSGYSAAKFGGVGLTQSLALDLAE")
        self.assertEqual(motif.instances[10], "LPIEQYAGYSASKAAVSALTRAAALSCRK")
        self.assertEqual(motif.instances[11], "VAYPMVAAYSASKFALDGFFSSIRKEYSV")
        self.assertEqual(motif.instances[12], "YPNGGGPLYTAAKQAIVGLVRELAFELAP")
        self.assertEqual(motif.instances[13], "VTFPNLITYSSTKGAMTMLTKAMAMELGP")
        self.assertEqual(motif.instances[14], "MANPARSPYCITKFGVEAFSDCLRYEMYP")
        self.assertEqual(motif.instances[15], "KAYPGGAVYGATKWAVRDLMEVLRMESAQ")
        self.assertEqual(motif.instances[16], "VHPFAGSAYATSKAALASLTRELAHDYAP")
        self.assertEqual(motif.instances[17], "MGLALTSSYGASKWGVRGLSKLAAVELGT")
        self.assertEqual(motif.instances[18], "TPYAPSSPYSASKAAADHLVRAWQRTYRL")
        self.assertEqual(motif.instances[19], "FRGLPATRYSASKAFLSTFMESLRVDLRG")
        self.assertEqual(motif.instances[20], "VPVIWEPVYTASKFAVQAFVHTTRRQVAQ")
        self.assertEqual(motif.instances[21], "MAEPEAAAYVAAKGGVAMLTRAMAVDLAR")
        self.assertEqual(motif.instances[22], "APMERLASYGSSKAAVTMFSSVMRLELSK")
        self.assertEqual(motif.instances[23], "NKNINMTSYASSKAAASHLVRNMAFDLGE")
        self.assertEqual(motif.instances[24], "TPRIGMSAYGASKAALKSLALSVGLELAG")
        self.assertEqual(motif.instances[25], "MGSALAGPYSAAKAASINLMEGYRQGLEK")
        self.assertEqual(motif.instances[26], "NTDGGAYAYRMSKAALNMAVRSMSTDLRP")
        self.assertEqual(motif.instances[27], "FGSLSGVGYPASKASVIGLTHGLGREIIR")
        self.assertEqual(motif.instances[28], "NAIYQVPVYSGTKAAVVNFTSSLAKLAPI")
        self.assertEqual(motif.instances[29], "RVLNPLVGYNMTKHALGGLTKTTQHVGWD")
        self.assertEqual(motif.instances[30], "EGKIGASLKDSTLFGVSSLSDSLKGDFTS")
        self.assertEqual(motif.instances[31], "MGPEGVRVNAISAGPIRTLAASGIKDFRK")
        self.assertEqual(motif.instances[32], "RALKSCSPELQQKFRSETITEEELVGLMN")

    def test_meme_parser_3(self):
        """Parse motifs/meme.farntrans5.classic.anr.xml file."""
        with open("motifs/meme.farntrans5.classic.anr.xml") as handle:
            record = motifs.parse(handle, "meme")
        self.assertEqual(record.version, "5.0.1")
        self.assertEqual(record.datafile, "common/farntrans5.s")
        self.assertEqual(record.alphabet, "ACDEFGHIKLMNPQRSTVWY")
        self.assertEqual(len(record.sequences), 5)
        self.assertEqual(record.sequences[0], "sequence_0")
        self.assertEqual(record.sequences[1], "sequence_1")
        self.assertEqual(record.sequences[2], "sequence_2")
        self.assertEqual(record.sequences[3], "sequence_3")
        self.assertEqual(record.sequences[4], "sequence_4")
        self.assertEqual(
            record.command,
            "meme common/farntrans5.s -oc results/meme15 -mod anr -protein -nmotifs 2 -objfun classic -minw 8 -nostatus ",
        )
        self.assertEqual(len(record), 2)
        motif = record[0]
        self.assertEqual(motif.name, "GGFGGRPGKEVDLCYTYCALAALAJLGSLD")
        self.assertEqual(record["GGFGGRPGKEVDLCYTYCALAALAJLGSLD"], 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, 6.98e-22)
        self.assertAlmostEqual(motif.instances[1].pvalue, 4.67e-21)
        self.assertAlmostEqual(motif.instances[2].pvalue, 1.25e-19)
        self.assertAlmostEqual(motif.instances[3].pvalue, 1.56e-19)
        self.assertAlmostEqual(motif.instances[4].pvalue, 2.44e-19)
        self.assertAlmostEqual(motif.instances[5].pvalue, 6.47e-19)
        self.assertAlmostEqual(motif.instances[6].pvalue, 8.9e-19)
        self.assertAlmostEqual(motif.instances[7].pvalue, 2.53e-18)
        self.assertAlmostEqual(motif.instances[8].pvalue, 1.27e-17)
        self.assertAlmostEqual(motif.instances[9].pvalue, 2.77e-17)
        self.assertAlmostEqual(motif.instances[10].pvalue, 4.93e-17)
        self.assertAlmostEqual(motif.instances[11].pvalue, 7.19e-17)
        self.assertAlmostEqual(motif.instances[12].pvalue, 8.68e-17)
        self.assertAlmostEqual(motif.instances[13].pvalue, 2.62e-16)
        self.assertAlmostEqual(motif.instances[14].pvalue, 2.87e-16)
        self.assertAlmostEqual(motif.instances[15].pvalue, 7.66e-15)
        self.assertAlmostEqual(motif.instances[16].pvalue, 2.21e-14)
        self.assertAlmostEqual(motif.instances[17].pvalue, 3.29e-14)
        self.assertAlmostEqual(motif.instances[18].pvalue, 7.21e-14)
        self.assertAlmostEqual(motif.instances[19].pvalue, 1.14e-13)
        self.assertAlmostEqual(motif.instances[20].pvalue, 1.67e-13)
        self.assertAlmostEqual(motif.instances[21].pvalue, 4.42e-13)
        self.assertAlmostEqual(motif.instances[22].pvalue, 5.11e-13)
        self.assertAlmostEqual(motif.instances[23].pvalue, 2.82e-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, "CAL1_YEAST")
        self.assertEqual(motif.instances[22].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[23].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[0].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[7].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[8].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[9].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[10].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[11].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[12].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[13].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[14].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[15].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[16].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[17].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[18].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[19].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[20].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[21].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[22].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[23].sequence_id, "sequence_2")
        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, 327)
        self.assertEqual(motif.instances[22].start, 349)
        self.assertEqual(motif.instances[23].start, 24)
        self.assertEqual(motif.instances[0], "GGLNGRPSKLPDVCYSWWVLSSLAIIGRLD")
        self.assertEqual(motif.instances[1], "GGLNGRPEKLPDVCYSWWVLASLKIIGRLH")
        self.assertEqual(motif.instances[2], "GGFQGRENKFADTCYAFWCLNSLHLLTKDW")
        self.assertEqual(motif.instances[3], "GGIGGVPGMEAHGGYTFCGLAALVILKKER")
        self.assertEqual(motif.instances[4], "GGFGGGPGQYPHLAPTYAAVNALCIIGTEE")
        self.assertEqual(motif.instances[5], "GGFGCRPGSESHAGQIYCCTGFLAITSQLH")
        self.assertEqual(motif.instances[6], "GSFAGDIWGEIDTRFSFCAVATLALLGKLD")
        self.assertEqual(motif.instances[7], "GGFGLCPNAESHAAQAFTCLGALAIANKLD")
        self.assertEqual(motif.instances[8], "GGFADRPGDMVDPFHTLFGIAGLSLLGEEQ")
        self.assertEqual(motif.instances[9], "GSFQGDRFGEVDTRFVYTALSALSILGELT")
        self.assertEqual(motif.instances[10], "GFGSCPHVDEAHGGYTFCATASLAILRSMD")
        self.assertEqual(motif.instances[11], "GGISDRPENEVDVFHTVFGVAGLSLMGYDN")
        self.assertEqual(motif.instances[12], "GPFGGGPGQLSHLASTYAAINALSLCDNID")
        self.assertEqual(motif.instances[13], "GGFQGRCNKLVDGCYSFWQAGLLPLLHRAL")
        self.assertEqual(motif.instances[14], "RGFCGRSNKLVDGCYSFWVGGSAAILEAFG")
        self.assertEqual(motif.instances[15], "GGLLDKPGKSRDFYHTCYCLSGLSIAQHFG")
        self.assertEqual(motif.instances[16], "GGVSASIGHDPHLLYTLSAVQILTLYDSIH")
        self.assertEqual(motif.instances[17], "GSFLMHVGGEVDVRSAYCAASVASLTNIIT")
        self.assertEqual(motif.instances[18], "GAFAPFPRHDAHLLTTLSAVQILATYDALD")
        self.assertEqual(motif.instances[19], "YNGAFGAHNEPHSGYTSCALSTLALLSSLE")
        self.assertEqual(motif.instances[20], "GFKTCLEVGEVDTRGIYCALSIATLLNILT")
        self.assertEqual(motif.instances[21], "GGFSKNDEEDADLYHSCLGSAALALIEGKF")
        self.assertEqual(motif.instances[22], "PGLRDKPGAHSDFYHTNYCLLGLAVAESSY")
        self.assertEqual(motif.instances[23], "HNFEYWLTEHLRLNGIYWGLTALCVLDSPE")
        motif = record[1]
        self.assertEqual(motif.name, "JNKEKLLEYILSCQ")
        self.assertEqual(record["JNKEKLLEYILSCQ"], 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.71e-12)
        self.assertAlmostEqual(motif.instances[1].pvalue, 5.7e-12)
        self.assertAlmostEqual(motif.instances[2].pvalue, 6.43e-12)
        self.assertAlmostEqual(motif.instances[3].pvalue, 2.61e-11)
        self.assertAlmostEqual(motif.instances[4].pvalue, 6.3e-11)
        self.assertAlmostEqual(motif.instances[5].pvalue, 2.7e-10)
        self.assertAlmostEqual(motif.instances[6].pvalue, 4.03e-10)
        self.assertAlmostEqual(motif.instances[7].pvalue, 1.27e-09)
        self.assertAlmostEqual(motif.instances[8].pvalue, 3.17e-09)
        self.assertAlmostEqual(motif.instances[9].pvalue, 6.39e-09)
        self.assertAlmostEqual(motif.instances[10].pvalue, 6.96e-09)
        self.assertAlmostEqual(motif.instances[11].pvalue, 1.06e-08)
        self.assertAlmostEqual(motif.instances[12].pvalue, 1.26e-08)
        self.assertAlmostEqual(motif.instances[13].pvalue, 1.37e-08)
        self.assertAlmostEqual(motif.instances[14].pvalue, 2.07e-08)
        self.assertAlmostEqual(motif.instances[15].pvalue, 4.96e-08)
        self.assertAlmostEqual(motif.instances[16].pvalue, 1.15e-07)
        self.assertAlmostEqual(motif.instances[17].pvalue, 1.44e-07)
        self.assertAlmostEqual(motif.instances[18].pvalue, 1.55e-07)
        self.assertAlmostEqual(motif.instances[19].pvalue, 1.93e-07)
        self.assertAlmostEqual(motif.instances[20].pvalue, 5.2e-07)
        self.assertEqual(motif.instances[0].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[1].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[2].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[3].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[4].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[5].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[6].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[7].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[8].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[9].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[10].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[11].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[12].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[13].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[14].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[15].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[16].sequence_name, "RATRABGERB")
        self.assertEqual(motif.instances[17].sequence_name, "RAM1_YEAST")
        self.assertEqual(motif.instances[18].sequence_name, "PFTB_RAT")
        self.assertEqual(motif.instances[19].sequence_name, "BET2_YEAST")
        self.assertEqual(motif.instances[20].sequence_name, "CAL1_YEAST")
        self.assertEqual(motif.instances[0].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[1].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[2].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[3].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[4].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[5].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[6].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[7].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[8].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[9].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[10].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[11].sequence_id, "sequence_4")
        self.assertEqual(motif.instances[12].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[13].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[14].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[15].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[16].sequence_id, "sequence_3")
        self.assertEqual(motif.instances[17].sequence_id, "sequence_0")
        self.assertEqual(motif.instances[18].sequence_id, "sequence_1")
        self.assertEqual(motif.instances[19].sequence_id, "sequence_2")
        self.assertEqual(motif.instances[20].sequence_id, "sequence_4")
        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, 66)
        self.assertEqual(motif.instances[1].start, 254)
        self.assertEqual(motif.instances[2].start, 258)
        self.assertEqual(motif.instances[3].start, 162)
        self.assertEqual(motif.instances[4].start, 190)
        self.assertEqual(motif.instances[5].start, 278)
        self.assertEqual(motif.instances[6].start, 172)
        self.assertEqual(motif.instances[7].start, 114)
        self.assertEqual(motif.instances[8].start, 7)
        self.assertEqual(motif.instances[9].start, 268)
        self.assertEqual(motif.instances[10].start, 414)
        self.assertEqual(motif.instances[11].start, 126)
        self.assertEqual(motif.instances[12].start, 220)
        self.assertEqual(motif.instances[13].start, 55)
        self.assertEqual(motif.instances[14].start, 229)
        self.assertEqual(motif.instances[15].start, 330)
        self.assertEqual(motif.instances[16].start, 18)
        self.assertEqual(motif.instances[17].start, 180)
        self.assertEqual(motif.instances[18].start, 73)
        self.assertEqual(motif.instances[19].start, 107)
        self.assertEqual(motif.instances[20].start, 36)
        self.assertEqual(motif.instances[0], "MNKEEILVFIKSCQ")
        self.assertEqual(motif.instances[1], "INYEKLTEFILKCQ")
        self.assertEqual(motif.instances[2], "IDREKLRSFILACQ")
        self.assertEqual(motif.instances[3], "INVEKAIEFVLSCM")
        self.assertEqual(motif.instances[4], "IDTEKLLGYIMSQQ")
        self.assertEqual(motif.instances[5], "INVEKLLEWSSARQ")
        self.assertEqual(motif.instances[6], "INREKLLQYLYSLK")
        self.assertEqual(motif.instances[7], "INVDKVVAYVQSLQ")
        self.assertEqual(motif.instances[8], "LLKEKHIRYIESLD")
        self.assertEqual(motif.instances[9], "LNLKSLLQWVTSRQ")
        self.assertEqual(motif.instances[10], "ENVRKIIHYFKSNL")
        self.assertEqual(motif.instances[11], "LDKRSLARFVSKCQ")
        self.assertEqual(motif.instances[12], "DLFEGTAEWIARCQ")
        self.assertEqual(motif.instances[13], "FVKEEVISFVLSCW")
        self.assertEqual(motif.instances[14], "ELTEGVLNYLKNCQ")
        self.assertEqual(motif.instances[15], "FNKHALRDYILYCC")
        self.assertEqual(motif.instances[16], "LLLEKHADYIASYG")
        self.assertEqual(motif.instances[17], "IDRKGIYQWLISLK")
        self.assertEqual(motif.instances[18], "LQREKHFHYLKRGL")
        self.assertEqual(motif.instances[19], "DRKVRLISFIRGNQ")
        self.assertEqual(motif.instances[20], "VNRMAIIFYSISGL")

    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(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.assertIsNone(motif.instances)

    def test_meme_parser_rna(self):
        """Test if Bio.motifs can parse MEME output files using RNA."""
        pass


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(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(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 obtained from 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")

    def test_getitem(self):
        counts = self.m.counts
        python_integers = range(13)
        numpy_integers = numpy.array(python_integers)
        integers = {"python": python_integers, "numpy": numpy_integers}
        for int_type in ("python", "numpy"):
            i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12 = integers[int_type]
            msg = f"using {int_type} integers as indices"
            # slice, slice
            d = counts[i1::i2, i2:i12:i3]
            self.assertIsInstance(d, dict, msg=msg)
            self.assertEqual(len(d), 2, msg=msg)
            self.assertEqual(len(d["C"]), 4, msg=msg)
            self.assertEqual(len(d["T"]), 4, msg=msg)
            self.assertAlmostEqual(d["C"][i0], 45.0, msg=msg)
            self.assertAlmostEqual(d["C"][i1], 1.0, msg=msg)
            self.assertAlmostEqual(d["C"][i2], 0.0, msg=msg)
            self.assertAlmostEqual(d["C"][i3], 1.0, msg=msg)
            self.assertAlmostEqual(d["T"][i0], 0.0, msg=msg)
            self.assertAlmostEqual(d["T"][i1], 42.0, msg=msg)
            self.assertAlmostEqual(d["T"][i2], 3.0, msg=msg)
            self.assertAlmostEqual(d["T"][i3], 0.0, msg=msg)
            # slice, int
            d = counts[i1::i2, i4]
            self.assertIsInstance(d, dict, msg=msg)
            self.assertEqual(len(d), 2, msg=msg)
            self.assertAlmostEqual(d["C"], 1.0, msg=msg)
            self.assertAlmostEqual(d["T"], 13.0, msg=msg)
            # int, slice
            t = counts[i2, i3:i12:i2]
            self.assertIsInstance(t, tuple, msg=msg)
            self.assertAlmostEqual(t[i0], 0.0, msg=msg)
            self.assertAlmostEqual(t[i1], 0.0, msg=msg)
            self.assertAlmostEqual(t[i2], 0.0, msg=msg)
            self.assertAlmostEqual(t[i3], 0.0, msg=msg)
            self.assertAlmostEqual(t[i4], 43.0, msg=msg)
            # int, int
            v = counts[i1, i5]
            self.assertAlmostEqual(v, 1.0, msg=msg)
            # tuple, slice
            d = counts[(i0, i3), i3:i12:i2]
            self.assertIsInstance(d, dict, msg=msg)
            self.assertEqual(len(d), 2, msg=msg)
            self.assertEqual(len(d["A"]), 5, msg=msg)
            self.assertEqual(len(d["T"]), 5, msg=msg)
            self.assertAlmostEqual(d["A"][i0], 1.0, msg=msg)
            self.assertAlmostEqual(d["A"][i1], 3.0, msg=msg)
            self.assertAlmostEqual(d["A"][i2], 1.0, msg=msg)
            self.assertAlmostEqual(d["A"][i3], 15.0, msg=msg)
            self.assertAlmostEqual(d["A"][i4], 2.0, msg=msg)
            self.assertAlmostEqual(d["T"][i0], 0.0, msg=msg)
            self.assertAlmostEqual(d["T"][i1], 42.0, msg=msg)
            self.assertAlmostEqual(d["T"][i2], 45.0, msg=msg)
            self.assertAlmostEqual(d["T"][i3], 30.0, msg=msg)
            self.assertAlmostEqual(d["T"][i4], 0.0, msg=msg)
            # tuple, int
            d = counts[(i0, i3), i5]
            self.assertIsInstance(d, dict, msg=msg)
            self.assertEqual(len(d), 2, msg=msg)
            self.assertAlmostEqual(d["A"], 3.0, msg=msg)
            self.assertAlmostEqual(d["T"], 42.0, msg=msg)
            # str, slice
            t = counts["C", i2:i12:i4]
            self.assertIsInstance(t, tuple, msg=msg)
            self.assertAlmostEqual(t[i0], 45.0, msg=msg)
            self.assertAlmostEqual(t[i1], 0.0, msg=msg)
            self.assertAlmostEqual(t[i2], 0.0, msg=msg)
            # str, int
            self.assertAlmostEqual(counts["T", i4], 13.0, msg=msg)

    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_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()
        result = pssm.calculate(Seq("AcGTgTGCGtaGTGCGT"))
        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.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]), f"Expected nan, not {result[6]!r}")

    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)
